Fil-C on Nix

Filnix wiki

the formal campaign

rocq/theories/Identity.v

Objects last: what a run of Machine R, the machine over a runtime R, leaves of the objects it finds (docs/formal.md, Campaign 3; docs/rocq.md, Identities persist).

The reuse forms trust a check that passed earlier, as long as the names it read are unchanged. That is sound only if the object it checked is still there when the reuse comes: as it was, so the check passes again, or freed, so it traps out of bounds. A run must never lose the object, or a new one could take its base and an old capability would name the new object. This file proves that memory persists over every run that starts ready (mreachable_persists): every object keeps its identity.

Decisions

DecisionWhy
free_ids follows from an axiomthe module type's free_lifetime says each identity after a free was one before, not the reverse; free_keeps_ids (mbrock's decision, with axiom-identity.c) says the reverse, as rooting does at safepoints
an allocation's base was no object'sfresh says so, which is what keeps an old capability from naming the new object
the regions of a step are compared, not its byteskept already says where a step writes; identity is about the region list alone
From Stdlib Require Import String ZArith List Bool Lia
From Nanofil Require Import Term Syntax Values Memory Runtime Ops Semantics Machine
Import ListNotations
Open Scope Z_scope

Identities persist

Every object of memory m is still an object of memory m': each base that names a region in m (object_region) names one in m', possibly changed. A step that satisfies this keeps every identity.

33Definition idsm m′ : Memory.mem : Prop ≔
∀b reg, object_regionb m_regionsm = Somereg → ∃reg′, object_regionb m_regionsm′ = Somereg′

The region reg as a free, or the end of its frame, leaves it: the same base and kind, its bounds emptied (its end at its base), and marked Freed, so that every access to it traps out of bounds.

39Definition freed_regionreg : region : region ≔

Each object of memory m is in memory m' as it was, or as its freed_region: nothing is lost, and no base is given to another object. This is how memory persists along a run, and why a check that passed in m passes again in m' or traps (persists_access).

46Definition persistsm m′ : Memory.mem : Prop ≔
∀b reg, object_regionb m_regionsm = Somereg → object_regionb m_regionsm′ = Somereg ∨ object_regionb m_regionsm′ = Somefreed_regionreg

The region object_region finds for base b in a region list rs has base b.

52Lemma object_region_base
∀ b rs reg
object_regionb rs = Somereg
r_basereg = b
Explore proof 3 tactics

Initial goal

⊢
∀b : Z rs : listregion reg : region, object_regionb rs = Somereg → r_basereg = b

intros b rs reg

b :
Z
rs :
listregion
reg :
⊢
object_regionb rs = Somereg → r_basereg = b

induction rs as | r rs IH ; simpl ; discriminate |

b :
Z
rs :
listregion
reg :
IH :
object_regionb rs = Somereg → r_basereg = b
⊢
r_baser =? b
→
Somer
=
Somereg
→
r_basereg = b

destruct Z.eqbr_baser b eqn: E ; intros H ; injection H as ← ; apply Z.eqb_eq ; exact E | exact IH

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros b rs reg
induction rs as | r rs IH ; simpl ; discriminate |
destruct Z.eqbr_baser b eqn: E ; intros H ; injection H as ← ; apply Z.eqb_eq ; exact E | exact IH

A memory persists from itself.

59Lemma persists_refl
∀ m
Explore proof 3 tactics

Initial goal

⊢
∀m : mem, persistsm m

intros m b reg H

m :
b :
Z
reg :
H :

left

m :
b :
Z
reg :
H :
⊢

exact H

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m b reg H
left
exact H

Persistence composes: if m2 persists from m1 and m3 from m2, then m3 persists from m1.

64Lemma persists_trans
∀ m1 m2 m3
Explore proof 5 tactics

Initial goal

⊢
∀m1 m2 m3 : mem, persistsm1 m2 → persistsm2 m3 → persistsm1 m3

intros m1 m2 m3 H12 H23 b reg H1

m1, m2, m3 :
H12 :
H23 :
b :
Z
reg :
H1 :
object_regionb m_regionsm1 = Somereg
⊢

destruct H12_ _ H1 as H2 | H2

2 open

m1, m2, m3 :
H12 :
H23 :
b :
Z
reg :
H1 :
object_regionb m_regionsm1 = Somereg
H2 :
object_regionb m_regionsm2 = Somereg
⊢
focused goal
m1, m2, m3 :
H12 :
H23 :
b :
Z
reg :
H1 :
object_regionb m_regionsm1 = Somereg
⊢

–exact H23_ _ H2

deferred goal
m1, m2, m3 :
H12 :
H23 :
b :
Z
reg :
H1 :
object_regionb m_regionsm1 = Somereg
⊢

–right

m1, m2, m3 :
H12 :
H23 :
b :
Z
reg :
H1 :
object_regionb m_regionsm1 = Somereg

destruct H23_ _ H2 as H3 | H3 ; exact H3

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m1 m2 m3 H12 H23 b reg H1
destruct H12_ _ H1 as H2 | H2
–exact H23_ _ H2
–right
destruct H23_ _ H2 as H3 | H3 ; exact H3

A memory m' with the same region list as m persists from m.

72Lemma persists_same
∀ m m′
persistsm m′
Explore proof 4 tactics

Initial goal

⊢
∀m m′ : mem, m_regionsm′ = m_regionsm → persistsm m′

intros m m′ E b reg H

m, m′ :
E :
b :
Z
reg :
H :
⊢
object_regionb m_regionsm′ = Somereg ∨ object_regionb m_regionsm′ = Somefreed_regionreg

left

m, m′ :
E :
b :
Z
reg :
H :
⊢
object_regionb m_regionsm′ = Somereg

rewrite E

m, m′ :
E :
b :
Z
reg :
H :
⊢

exact H

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m m′ E b reg H
left
rewrite E
exact H

A change of memory from m to m' persists where it is a region_step (each object of m' was one of m, unchanged or ended in place) and loses no identity (ids). These are what the program and the runtime may do to regions.

79Lemma region_ids_persists
∀ m m′
idsm m′
persistsm m′
Explore proof 10 tactics

Initial goal

⊢
∀m m′ : mem, region_stepm m′ → idsm m′ → persistsm m′

intros m m′ Hr Hi b reg H

m, m′ :
Hr :
Hi :
idsm m′
b :
Z
reg :
H :
⊢
object_regionb m_regionsm′ = Somereg ∨ object_regionb m_regionsm′ = Somefreed_regionreg

destruct Hi_ _ H as reg′ H′

m, m′ :
Hr :
Hi :
idsm m′
b :
Z
reg :
H :
reg′ :
H′ :
object_regionb m_regionsm′ = Somereg′
⊢
object_regionb m_regionsm′ = Somereg ∨ object_regionb m_regionsm′ = Somefreed_regionreg

destruct Hr_ _ H′ as reg0 & E0 & → | _ & → ; rewrite H in E0 ; injection E0 as ←

2 open

m, m′ :
Hr :
Hi :
idsm m′
b :
Z
reg :
H :
H′ :
object_regionb m_regionsm′ = Somereg
⊢
object_regionb m_regionsm′ = Somereg ∨ object_regionb m_regionsm′ = Somefreed_regionreg
focused goal
m, m′ :
Hr :
Hi :
idsm m′
b :
Z
reg :
H :
H′ :
object_regionb m_regionsm′ = Somer_base ≔ b; r_end ≔ b; r_kind ≔ r_kindreg; r_life ≔ Freed
⊢
object_regionb m_regionsm′ = Somereg ∨ object_regionb m_regionsm′ = Somefreed_regionreg

–left

2 open

m, m′ :
Hr :
Hi :
idsm m′
b :
Z
reg :
H :
H′ :
object_regionb m_regionsm′ = Somereg
⊢
object_regionb m_regionsm′ = Somereg
deferred goal
m, m′ :
Hr :
Hi :
idsm m′
b :
Z
reg :
H :
H′ :
object_regionb m_regionsm′ = Somer_base ≔ b; r_end ≔ b; r_kind ≔ r_kindreg; r_life ≔ Freed
⊢
object_regionb m_regionsm′ = Somereg ∨ object_regionb m_regionsm′ = Somefreed_regionreg

exact H′

deferred goal
m, m′ :
Hr :
Hi :
idsm m′
b :
Z
reg :
H :
H′ :
object_regionb m_regionsm′ = Somer_base ≔ b; r_end ≔ b; r_kind ≔ r_kindreg; r_life ≔ Freed
⊢
object_regionb m_regionsm′ = Somereg ∨ object_regionb m_regionsm′ = Somefreed_regionreg

–right

m, m′ :
Hr :
Hi :
idsm m′
b :
Z
reg :
H :
H′ :
object_regionb m_regionsm′ = Somer_base ≔ b; r_end ≔ b; r_kind ≔ r_kindreg; r_life ≔ Freed

rewrite H′

m, m′ :
Hr :
Hi :
idsm m′
b :
Z
reg :
H :
H′ :
object_regionb m_regionsm′ = Somer_base ≔ b; r_end ≔ b; r_kind ≔ r_kindreg; r_life ≔ Freed
⊢
Somer_base ≔ b; r_end ≔ b; r_kind ≔ r_kindreg; r_life ≔ Freed = Somefreed_regionreg

unfold freed_region

m, m′ :
Hr :
Hi :
idsm m′
b :
Z
reg :
H :
H′ :
object_regionb m_regionsm′ = Somer_base ≔ b; r_end ≔ b; r_kind ≔ r_kindreg; r_life ≔ Freed
⊢
Somer_base ≔ b; r_end ≔ b; r_kind ≔ r_kindreg; r_life ≔ Freed = Somer_base ≔ r_basereg; r_end ≔ r_basereg; r_kind ≔ r_kindreg; r_life ≔ Freed

rewrite object_region_base_ _ _ H

m, m′ :
Hr :
Hi :
idsm m′
b :
Z
reg :
H :
H′ :
object_regionb m_regionsm′ = Somer_base ≔ b; r_end ≔ b; r_kind ≔ r_kindreg; r_life ≔ Freed
⊢
Somer_base ≔ b; r_end ≔ b; r_kind ≔ r_kindreg; r_life ≔ Freed = Somer_base ≔ b; r_end ≔ b; r_kind ≔ r_kindreg; r_life ≔ Freed

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m m′ Hr Hi b reg H
destruct Hi_ _ H as reg′ H′
destruct Hr_ _ H′ as reg0 & E0 & → | _ & → ; rewrite H in E0 ; injection E0 as ←
–left
exact H′
–right
rewrite H′
rewrite object_region_base_ _ _ H
reflexivity

The same for a lifetime_step, what the runtime's free and its safepoint action may do: with no identity lost, memory persists.

89Lemma lifetime_ids_persists
∀ m m′
idsm m′
persistsm m′
Explore proof 2 tactics

Initial goal

⊢
∀m m′ : mem, lifetime_stepm m′ → idsm m′ → persistsm m′

intros m m′ Hl Hi

m, m′ :
Hl :
Hi :
idsm m′
⊢
persistsm m′

exact region_ids_persists_ _ lifetime_region_step_ _ Hl Hi

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m m′ Hl Hi

The same for kept, what the program's own steps between allocations may do to memory.

94Lemma kept_ids_persists
∀ m m′
keptm m′
idsm m′
persistsm m′
Explore proof 2 tactics

Initial goal

⊢
∀m m′ : mem, keptm m′ → idsm m′ → persistsm m′

intros m m′ Hr _ Hi

m, m′ :
Hr :
Hi :
idsm m′
⊢
persistsm m′

exact region_ids_persists_ _ Hr Hi

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m m′ Hr _ Hi
exact region_ids_persists_ _ Hr Hi

Adding a new object for the allocation request q at a base that no object of m has (allocated m q base) persists from m: no old object is touched. The runtime's fresh allocation gives such a base.

100Lemma allocated_persists
∀ m q base
Explore proof 8 tactics

Initial goal

⊢
∀m : mem q : alloc_req base : Z, object_regionbase m_regionsm = None → persistsm allocatedm q base

intros m q base Hn b reg H

m :
base :
Z
Hn :
b :
Z
reg :
H :
⊢

left

m :
base :
Z
Hn :
b :
Z
reg :
H :
⊢
object_regionb m_regionsallocatedm q base = Somereg

simpl

m :
base :
Z
Hn :
b :
Z
reg :
H :
⊢
base =? b
→
Somer_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live
=
Somereg

destruct Z.eqbbase b eqn: E ; | exact H

m :
base :
Z
Hn :
b :
Z
reg :
H :
E :
base =? b = true
⊢
Somer_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live = Somereg

apply Z.eqb_eq in E

m :
base :
Z
Hn :
b :
Z
reg :
H :
E :
base = b
⊢
Somer_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live = Somereg

subst

m :
b :
Z
Hn :
reg :
H :
⊢
Somer_base ≔ b; r_end ≔ b + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live = Somereg

rewrite Hn in H

m :
b :
Z
Hn :
reg :
H :
None = Somereg
⊢
Somer_base ≔ b; r_end ≔ b + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live = Somereg

discriminate H

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m q base Hn b reg H
left
simpl
destruct Z.eqbbase b eqn: E ; | exact H
apply Z.eqb_eq in E
subst
rewrite Hn in H
discriminate H

Steps that write keep the regions

A store (store_res, store_res/7) writes bytes but leaves the region list unchanged.

111Lemma store_res_regions
∀ w m a c x r m′
store_resw m a c x = Somer, m′
Explore proof 3 tactics

Initial goal

⊢
∀w : width m : mem a : Z c : cap x : word r : resunit m′ : mem, store_resw m a c x = Somer, m′ → m_regionsm′ = m_regionsm

unfold store_res

⊢
∀ w : width m : mem a : Z c : cap x : word r : resunit m′ : mem  ,
match w with
⇒
match x with
⇒
let* chk ≔ access_resm a c width_bytesw Write 8 in
Some
chk
match chk with
_
⇒
None
_
⇒
match x with
⇒
let* chk ≔
match w with
⇒
8
_
⇒
1
in
Some
chk
match chk with
_
⇒
None
=
Somer, m′
→

intros w m a c x r m′ H

m :
a :
Z
c :
x :
r :
resunit
m′ :
H :
match w with
⇒
match x with
⇒
let* chk ≔ access_resm a c width_bytesw Write 8 in
Some
chk
match chk with
_
⇒
None
_
⇒
match x with
⇒
let* chk ≔
match w with
⇒
8
_
⇒
1
in
Some
chk
match chk with
_
⇒
None
=
Somer, m′
⊢

destruct w , x ; try discriminate ; cases H ; inversion H ; reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
unfold store_res
intros w m a c x r m′ H
destruct w , x ; try discriminate ; cases H ; inversion H ; reflexivity

Folding a memory update f over a list xs leaves the region list unchanged where each application of f does. A helper for lists of store effects.

117Lemma fold_regions
∀ A : Type f : Memory.mem → A → optionMemory.mem xs m0 m′
∀m1 : Memory.mem x m2, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
fold_left
λ acc x  ⇒
let* m1 ≔ acc in
fm1 x
xs
Somem0
=
Somem′
Explore proof 9 tactics

Initial goal

⊢
∀ A : Type f : mem → A → optionmem xs : listA m0 m′ : mem  ,
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
→
fold_left
λ acc : optionmem x : A  ⇒
let* m1 ≔ acc in
fm1 x
xs
Somem0
=
Somem′
→

intros A f xs

A :
Type
f :
mem → A → optionmem
xs :
listA
⊢
∀ m0 m′ : mem  ,
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
→
fold_left
λ acc : optionmem x : A  ⇒
let* m1 ≔ acc in
fm1 x
xs
Somem0
=
Somem′
→

induction xs as | x xs IH ; simpl ; intros m0 m′ Hf H

2 open

A :
Type
f :
mem → A → optionmem
m0, m′ :
Hf :
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
H :
Somem0 = Somem′
⊢
focused goal
A :
Type
f :
mem → A → optionmem
x :
A
xs :
listA
IH :
∀ m0 m′ : mem  ,
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
→
fold_left
λ acc : optionmem x : A  ⇒
let* m1 ≔ acc in
fm1 x
xs
Somem0
=
Somem′
→
m0, m′ :
Hf :
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
H :
fold_left
λ acc : optionmem x : A  ⇒
let* m1 ≔ acc in
fm1 x
xs
fm0 x
=
Somem′
⊢

–injection H as ←

2 open

A :
Type
f :
mem → A → optionmem
m0 :
Hf :
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
deferred goal
A :
Type
f :
mem → A → optionmem
x :
A
xs :
listA
IH :
∀ m0 m′ : mem  ,
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
→
fold_left
λ acc : optionmem x : A  ⇒
let* m1 ≔ acc in
fm1 x
xs
Somem0
=
Somem′
→
m0, m′ :
Hf :
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
H :
fold_left
λ acc : optionmem x : A  ⇒
let* m1 ≔ acc in
fm1 x
xs
fm0 x
=
Somem′
⊢

reflexivity

deferred goal
A :
Type
f :
mem → A → optionmem
x :
A
xs :
listA
IH :
∀ m0 m′ : mem  ,
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
→
fold_left
λ acc : optionmem x : A  ⇒
let* m1 ≔ acc in
fm1 x
xs
Somem0
=
Somem′
→
m0, m′ :
Hf :
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
H :
fold_left
λ acc : optionmem x : A  ⇒
let* m1 ≔ acc in
fm1 x
xs
fm0 x
=
Somem′
⊢

–destruct fm0 x as m1 | eqn: E

2 open

A :
Type
f :
mem → A → optionmem
x :
A
xs :
listA
IH :
∀ m0 m′ : mem  ,
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
→
fold_left
λ acc : optionmem x : A  ⇒
let* m1 ≔ acc in
fm1 x
xs
Somem0
=
Somem′
→
m0, m′ :
Hf :
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
m1 :
E :
fm0 x = Somem1
H :
fold_left
λ acc : optionmem x : A  ⇒
let* m1 ≔ acc in
fm1 x
xs
Somem1
=
Somem′
⊢
focused goal
A :
Type
f :
mem → A → optionmem
x :
A
xs :
listA
IH :
∀ m0 m′ : mem  ,
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
→
fold_left
λ acc : optionmem x : A  ⇒
let* m1 ≔ acc in
fm1 x
xs
Somem0
=
Somem′
→
m0, m′ :
Hf :
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
E :
fm0 x = None
H :
fold_left
λ acc : optionmem x : A  ⇒
let* m1 ≔ acc in
fm1 x
xs
None
=
Somem′
⊢

+rewrite IH_ _ Hf H

2 open

A :
Type
f :
mem → A → optionmem
x :
A
xs :
listA
IH :
∀ m0 m′ : mem  ,
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
→
fold_left
λ acc : optionmem x : A  ⇒
let* m1 ≔ acc in
fm1 x
xs
Somem0
=
Somem′
→
m0, m′ :
Hf :
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
m1 :
E :
fm0 x = Somem1
H :
fold_left
λ acc : optionmem x : A  ⇒
let* m1 ≔ acc in
fm1 x
xs
Somem1
=
Somem′
deferred goal
A :
Type
f :
mem → A → optionmem
x :
A
xs :
listA
IH :
∀ m0 m′ : mem  ,
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
→
fold_left
λ acc : optionmem x : A  ⇒
let* m1 ≔ acc in
fm1 x
xs
Somem0
=
Somem′
→
m0, m′ :
Hf :
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
E :
fm0 x = None
H :
fold_left
λ acc : optionmem x : A  ⇒
let* m1 ≔ acc in
fm1 x
xs
None
=
Somem′
⊢

exact Hf_ _ _ E

deferred goal
A :
Type
f :
mem → A → optionmem
x :
A
xs :
listA
IH :
∀ m0 m′ : mem  ,
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
→
fold_left
λ acc : optionmem x : A  ⇒
let* m1 ≔ acc in
fm1 x
xs
Somem0
=
Somem′
→
m0, m′ :
Hf :
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
E :
fm0 x = None
H :
fold_left
λ acc : optionmem x : A  ⇒
let* m1 ≔ acc in
fm1 x
xs
None
=
Somem′
⊢

+rewrite fold_left_none in H

A :
Type
f :
mem → A → optionmem
x :
A
xs :
listA
IH :
∀ m0 m′ : mem  ,
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
→
fold_left
λ acc : optionmem x : A  ⇒
let* m1 ≔ acc in
fm1 x
xs
Somem0
=
Somem′
→
m0, m′ :
Hf :
∀m1 : mem x : A m2 : mem, fm1 x = Somem2 → m_regionsm2 = m_regionsm1
E :
fm0 x = None
H :
None = Somem′
⊢

discriminate H

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros A f xs
induction xs as | x xs IH ; simpl ; intros m0 m′ Hf H
–injection H as ←
reflexivity
–destruct fm0 x as m1 | eqn: E
+rewrite IH_ _ Hf H
exact Hf_ _ _ E
+rewrite fold_left_none in H
discriminate H

The effects of storing the pointer x at address a (pointer_store_effects, pointer_store_effects//6) leave the region list unchanged.

131Lemma pointer_store_effects_regions
∀ a x m es m′
pointer_store_effectsa x m es = Somem′
Explore proof 4 tactics

Initial goal

⊢
∀a : Z x : ptr m : mem es : listeffect m′ : mem, pointer_store_effectsa x m es = Somem′ → m_regionsm′ = m_regionsm

intros a x m es m′ H

a :
Z
x :
m :
es :
listeffect
m′ :
H :
pointer_store_effectsa x m es = Somem′
⊢

apply fold_regionseffect pointer_store_effecta x es m m′ ; | exact H

a :
Z
x :
m :
es :
listeffect
m′ :
H :
pointer_store_effectsa x m es = Somem′
⊢
∀m1 : mem x0 : effect m2 : mem, pointer_store_effecta x m1 x0 = Somem2 → m_regionsm2 = m_regionsm1

intros m1 e m2 E

a :
Z
x :
m :
es :
listeffect
m′ :
H :
pointer_store_effectsa x m es = Somem′
m1 :
m2 :
E :
pointer_store_effecta x m1 e = Somem2

destruct e ; simpl in E ; try discriminate E ; injection E as ← ; reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros a x m es m′ H
apply fold_regionseffect pointer_store_effecta x es m m′ ; | exact H
intros m1 e m2 E
destruct e ; simpl in E ; try discriminate E ; injection E as ← ; reflexivity

Reading a variadic argument through the argument pointer p (va_arg_res) leaves the region list unchanged, though it may write memory.

141Lemma va_arg_res_regions
∀ k p m r m′
va_arg_resk p m = Somer, m′
Explore proof 3 tactics

Initial goal

⊢
∀k : class p : ptr m : mem r : resword m′ : mem, va_arg_resk p m = Somer, m′ → m_regionsm′ = m_regionsm

unfold va_arg_res

⊢
∀ k : class p : ptr m : mem r : resword m′ : mem  ,
match access_resm ptr_addrp ptr_capp 8 Read 8 with
SomeRVal_
⇒
match va_cellk with
Somestep, align
⇒
let* w ≔ class_widthk in
match access_resm ptr_addrptr_addr ≔ load_bytesm ptr_addrp 8; ptr_cap ≔ aux_atm ptr_addrp + align − 1 / align × align ptr_capptr_addr ≔ load_bytesm ptr_addrp 8; ptr_cap ≔ aux_atm ptr_addrp step Read 8 with
SomeRVal_
⇒
match store_resWl m ptr_addrp ptr_capp WIntptr_addrptr_addr ≔ load_bytesm ptr_addrp 8; ptr_cap ≔ aux_atm ptr_addrp + align − 1 / align × align + step with
SomeRVal_, m1
⇒
match k with
⇒
SomeRValWPtrptr_addr ≔ load_bytesm1 ptr_addrptr_addr ≔ load_bytesm ptr_addrp 8; ptr_cap ≔ aux_atm ptr_addrp + align − 1 / align × align 8; ptr_cap ≔ aux_atm1 ptr_addrptr_addr ≔ load_bytesm ptr_addrp 8; ptr_cap ≔ aux_atm ptr_addrp + align − 1 / align × align, m1
_
⇒
SomeRValWIntload_bytesm1 ptr_addrptr_addr ≔ load_bytesm ptr_addrp 8; ptr_cap ≔ aux_atm ptr_addrp + align − 1 / align × align width_bytesw, m1
SomeRTrapwhy, m1
⇒
SomeRTrapwhy, m1
_
⇒
None
SomeRTrapwhy
⇒
SomeRTrapwhy, m
_
⇒
None
None
⇒
None
SomeRTrapwhy
⇒
SomeRTrapwhy, m
_
⇒
None
=
Somer, m′
→

intros k p m r m′ H

p :
m :
m′ :
H :
match access_resm ptr_addrp ptr_capp 8 Read 8 with
SomeRVal_
⇒
match va_cellk with
Somestep, align
⇒
let* w ≔ class_widthk in
match access_resm ptr_addrptr_addr ≔ load_bytesm ptr_addrp 8; ptr_cap ≔ aux_atm ptr_addrp + align − 1 / align × align ptr_capptr_addr ≔ load_bytesm ptr_addrp 8; ptr_cap ≔ aux_atm ptr_addrp step Read 8 with
SomeRVal_
⇒
match store_resWl m ptr_addrp ptr_capp WIntptr_addrptr_addr ≔ load_bytesm ptr_addrp 8; ptr_cap ≔ aux_atm ptr_addrp + align − 1 / align × align + step with
SomeRVal_, m1
⇒
match k with
⇒
SomeRValWPtrptr_addr ≔ load_bytesm1 ptr_addrptr_addr ≔ load_bytesm ptr_addrp 8; ptr_cap ≔ aux_atm ptr_addrp + align − 1 / align × align 8; ptr_cap ≔ aux_atm1 ptr_addrptr_addr ≔ load_bytesm ptr_addrp 8; ptr_cap ≔ aux_atm ptr_addrp + align − 1 / align × align, m1
_
⇒
SomeRValWIntload_bytesm1 ptr_addrptr_addr ≔ load_bytesm ptr_addrp 8; ptr_cap ≔ aux_atm ptr_addrp + align − 1 / align × align width_bytesw, m1
SomeRTrapwhy, m1
⇒
SomeRTrapwhy, m1
_
⇒
None
SomeRTrapwhy
⇒
SomeRTrapwhy, m
_
⇒
None
None
⇒
None
SomeRTrapwhy
⇒
SomeRTrapwhy, m
_
⇒
None
=
Somer, m′
⊢

cases H;match type of H withSome_, ?x = Some_, ?y⇒assert x = y as ← by congruenceend;first|reflexivity|match goal withE : store_res_ _ _ _ _ = Some_ |- _⇒exact store_res_regions_ _ _ _ _ _ _ Eend

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
unfold va_arg_res
intros k p m r m′ H
cases H;match type of H withSome_, ?x = Some_, ?y⇒assert x = y as ← by congruenceend;first|reflexivity|match goal withE : store_res_ _ _ _ _ = Some_ |- _⇒exact store_res_regions_ _ _ _ _ _ _ Eend

An op o that gives a result (op_res returning OpRes) leaves the region list unchanged: only allocation, free and the end of an invocation change regions.

152Lemma op_res_regions
∀ o k xs m r m′
op_reso k xs m = SomeOpResr m′
Explore proof 3 tactics

Initial goal

⊢
∀o : op k : class xs : listword m : mem r : resword m′ : mem, op_reso k xs m = SomeOpResr m′ → m_regionsm′ = m_regionsm

unfold op_res , float_integer

⊢
∀ o : op k : class xs : listword m : mem r : resword m′ : mem  ,
match o with
Add | Sub | Mul | Div | Neg | Copy
⇒
match fmt_ofk with
Somef
⇒
let* r0 ≔ float_arithmetico f xs in
None
⇒
op_res_into k xs m
Cmpc ck
⇒
match xs with
⇒
match fmt_ofck with
Somef
⇒
None
⇒
op_res_into k xs m
WInta :: WIntb :: _ :: _
⇒
match fmt_ofck with
Some_
⇒
None
None
⇒
op_res_into k xs m
WInta | WInta :: WPtr_ :: _ | WInta :: WLimit_ _ :: _
⇒
match fmt_ofck with
Some_
⇒
None
None
⇒
op_res_into k xs m
_
⇒
match fmt_ofck with
Some_
⇒
None
None
⇒
op_res_into k xs m
⇒
match xs with
⇒
let* from ≔ fmt_offk in
let* m0 ≔ modulusk in
let 'lo, hi ≔
match sg with
⇒
−m0 / 2, m0 / 2 − 1
⇒
0, m0 − 1
in
match Ieee.ieee_to_intfrom x with
Somen
⇒
lo ≤? n && n ≤? hi
→
SomeOpResRValWIntn mod m0 m
else
SomeOpUBTAtom"float_conversion"
None
⇒
SomeOpUBTAtom"float_conversion"
WIntx :: _ :: _
⇒
op_res_into k xs m
_
⇒
op_res_into k xs m
⇒
match fmt_ofk with
Somef
⇒
match xs with
⇒
let* n ≔ integer_sourceik sg x in
WIntx :: _ :: _
⇒
op_res_into k xs m
_
⇒
op_res_into k xs m
None
⇒
op_res_into k xs m
⇒
match xs with
WIntx :: _ :: _
⇒
op_res_into k xs m
_
⇒
op_res_into k xs m
⇒
match xs with
⇒
let* r0 ≔ float_converto k x in
WIntx :: _ :: _
⇒
op_res_into k xs m
_
⇒
op_res_into k xs m
⇒
match xs with
⇒
let* rm ≔ va_arg_resk p m in
SomeOpResfstrm sndrm
WPtrp :: _ :: _
⇒
op_res_into k xs m
_
⇒
op_res_into k xs m
_
⇒
op_res_into k xs m
=
SomeOpResr m′
→

intros o k xs m r m′ H

o :
xs :
listword
m :
m′ :
H :
match o with
Add | Sub | Mul | Div | Neg | Copy
⇒
match fmt_ofk with
Somef
⇒
let* r ≔ float_arithmetico f xs in
None
⇒
op_res_into k xs m
Cmpc ck
⇒
match xs with
⇒
match fmt_ofck with
Somef
⇒
None
⇒
op_res_into k xs m
WInta :: WIntb :: _ :: _
⇒
match fmt_ofck with
Some_
⇒
None
None
⇒
op_res_into k xs m
WInta | WInta :: WPtr_ :: _ | WInta :: WLimit_ _ :: _
⇒
match fmt_ofck with
Some_
⇒
None
None
⇒
op_res_into k xs m
_
⇒
match fmt_ofck with
Some_
⇒
None
None
⇒
op_res_into k xs m
⇒
match xs with
⇒
let* from ≔ fmt_offk in
let* m0 ≔ modulusk in
let 'lo, hi ≔
match sg with
⇒
−m0 / 2, m0 / 2 − 1
⇒
0, m0 − 1
in
match Ieee.ieee_to_intfrom x with
Somen
⇒
lo ≤? n && n ≤? hi
→
SomeOpResRValWIntn mod m0 m
else
SomeOpUBTAtom"float_conversion"
None
⇒
SomeOpUBTAtom"float_conversion"
WIntx :: _ :: _
⇒
op_res_into k xs m
_
⇒
op_res_into k xs m
⇒
match fmt_ofk with
Somef
⇒
match xs with
⇒
let* n ≔ integer_sourceik sg x in
WIntx :: _ :: _
⇒
op_res_into k xs m
_
⇒
op_res_into k xs m
None
⇒
op_res_into k xs m
⇒
match xs with
WIntx :: _ :: _
⇒
op_res_into k xs m
_
⇒
op_res_into k xs m
⇒
match xs with
⇒
let* r ≔ float_converto k x in
WIntx :: _ :: _
⇒
op_res_into k xs m
_
⇒
op_res_into k xs m
⇒
match xs with
⇒
let* rm ≔ va_arg_resk p m in
SomeOpResfstrm sndrm
WPtrp :: _ :: _
⇒
op_res_into k xs m
_
⇒
op_res_into k xs m
_
⇒
op_res_into k xs m
=
SomeOpResr m′
⊢

destruct o ; cases H ; inversion H ; subst;first|reflexivity|match goal withE : op_res_int_ _ _ _ = Some_ |- _⇒rewrite op_res_int_mem_ _ _ _ _ _ E ; reflexivityend|match goal withE : va_arg_res_ _ _ = Some?rm |- _⇒destruct rm ; exact va_arg_res_regions_ _ _ _ _ Eend

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros o k xs m r m′ H
destruct o ; cases H ; inversion H ; subst;first|reflexivity|match goal withE : op_res_int_ _ _ _ = Some_ |- _⇒rewrite op_res_int_mem_ _ _ _ _ _ E ; reflexivityend|match goal withE : va_arg_res_ _ _ = Some?rm |- _⇒destruct rm ; exact va_arg_res_regions_ _ _ _ _ Eend

A memory keeps its own identities.

164Lemma ids_refl
∀ m
idsm m
Explore proof 2 tactics

Initial goal

⊢
∀m : mem, idsm m

intros m b reg H

m :
b :
Z
reg :
H :
⊢
∃reg′ : region, object_regionb m_regionsm = Somereg′

eauto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m b reg H
eauto

Keeping identities composes, from m1 to m2 to m3.

168Lemma ids_trans
∀ m1 m2 m3
idsm1 m2
idsm2 m3
idsm1 m3
Explore proof 3 tactics

Initial goal

⊢
∀m1 m2 m3 : mem, idsm1 m2 → idsm2 m3 → idsm1 m3

intros m1 m2 m3 H12 H23 b reg H

m1, m2, m3 :
H12 :
idsm1 m2
H23 :
idsm2 m3
b :
Z
reg :
H :
object_regionb m_regionsm1 = Somereg
⊢
∃reg′ : region, object_regionb m_regionsm3 = Somereg′

destruct H12_ _ H as reg2 H2

m1, m2, m3 :
H12 :
idsm1 m2
H23 :
idsm2 m3
b :
Z
reg :
H :
object_regionb m_regionsm1 = Somereg
reg2 :
H2 :
object_regionb m_regionsm2 = Somereg2
⊢
∃reg′ : region, object_regionb m_regionsm3 = Somereg′

exact H23_ _ H2

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m1 m2 m3 H12 H23 b reg H
destruct H12_ _ H as reg2 H2
exact H23_ _ H2

A memory with the same region list as m keeps every identity of m.

173Lemma ids_same
∀ m m′
idsm m′
Explore proof 3 tactics

Initial goal

⊢
∀m m′ : mem, m_regionsm′ = m_regionsm → idsm m′

intros m m′ E b reg H

m, m′ :
E :
b :
Z
reg :
H :
⊢
∃reg′ : region, object_regionb m_regionsm′ = Somereg′

rewrite E

m, m′ :
E :
b :
Z
reg :
H :
⊢
∃reg′ : region, object_regionb m_regionsm = Somereg′

eauto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m m′ E b reg H
rewrite E
eauto

Ending an invocation's named locals as it returns, as invalidate_locals/3 does, frees each in place and drops no object: every identity is kept.

179Lemma invalidate_locals_ids
∀ locals m m′
invalidate_localslocals m = Somem′
idsm m′
Explore proof 14 tactics

Initial goal

⊢
∀locals : listname × optionZ m m′ : mem, invalidate_localslocals m = Somem′ → idsm m′

unfold invalidate_locals

⊢
∀ locals : listname × optionZ m m′ : mem  ,
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m0 ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm0 in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm0 in
Somem_bytes ≔ m_bytesm0; m_regions ≔ rs; m_aux ≔ m_auxm0
⇒
None
_
⇒
None
None
⇒
Somem0
locals
Somem
=
Somem′
→
idsm m′

intros locals

locals :
listname × optionZ
⊢
∀ m m′ : mem  ,
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m0 ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm0 in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm0 in
Somem_bytes ≔ m_bytesm0; m_regions ≔ rs; m_aux ≔ m_auxm0
⇒
None
_
⇒
None
None
⇒
Somem0
locals
Somem
=
Somem′
→
idsm m′

induction locals as | x slot ls IH ; simpl ; intros m m′ H

2 open

m, m′ :
H :
Somem = Somem′
⊢
idsm m′
focused goal
x :
slot :
optionZ
ls :
listname × optionZ
IH :
∀ m m′ : mem  ,
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m0 ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm0 in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm0 in
Somem_bytes ≔ m_bytesm0; m_regions ≔ rs; m_aux ≔ m_auxm0
⇒
None
_
⇒
None
None
⇒
Somem0
ls
Somem
=
Somem′
→
idsm m′
m, m′ :
H :
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm in
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
⇒
None
_
⇒
None
None
⇒
Somem
ls
match slot with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm in
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
⇒
None
_
⇒
None
None
⇒
Somem
=
Somem′
⊢
idsm m′

–injection H as ←

2 open

m :
⊢
idsm m
deferred goal
x :
slot :
optionZ
ls :
listname × optionZ
IH :
∀ m m′ : mem  ,
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m0 ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm0 in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm0 in
Somem_bytes ≔ m_bytesm0; m_regions ≔ rs; m_aux ≔ m_auxm0
⇒
None
_
⇒
None
None
⇒
Somem0
ls
Somem
=
Somem′
→
idsm m′
m, m′ :
H :
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm in
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
⇒
None
_
⇒
None
None
⇒
Somem
ls
match slot with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm in
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
⇒
None
_
⇒
None
None
⇒
Somem
=
Somem′
⊢
idsm m′

apply ids_refl

deferred goal
x :
slot :
optionZ
ls :
listname × optionZ
IH :
∀ m m′ : mem  ,
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m0 ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm0 in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm0 in
Somem_bytes ≔ m_bytesm0; m_regions ≔ rs; m_aux ≔ m_auxm0
⇒
None
_
⇒
None
None
⇒
Somem0
ls
Somem
=
Somem′
→
idsm m′
m, m′ :
H :
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm in
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
⇒
None
_
⇒
None
None
⇒
Somem
ls
match slot with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm in
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
⇒
None
_
⇒
None
None
⇒
Somem
=
Somem′
⊢
idsm m′

–destruct slot as base | ; | exact IH_ _ H

x :
base :
Z
ls :
listname × optionZ
IH :
∀ m m′ : mem  ,
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m0 ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm0 in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm0 in
Somem_bytes ≔ m_bytesm0; m_regions ≔ rs; m_aux ≔ m_auxm0
⇒
None
_
⇒
None
None
⇒
Somem0
ls
Somem
=
Somem′
→
idsm m′
m, m′ :
H :
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm in
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
⇒
None
_
⇒
None
None
⇒
Somem
ls
let* reg ≔ object_regionbase m_regionsm in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm in
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
⇒
None
_
⇒
None
=
Somem′
⊢
idsm m′

destruct object_regionbase m_regionsm as reg | eqn: Er ; simpl in H ; | rewrite fold_left_none in H ; discriminate H

x :
base :
Z
ls :
listname × optionZ
IH :
∀ m m′ : mem  ,
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m0 ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm0 in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm0 in
Somem_bytes ≔ m_bytesm0; m_regions ≔ rs; m_aux ≔ m_auxm0
⇒
None
_
⇒
None
None
⇒
Somem0
ls
Somem
=
Somem′
→
idsm m′
m, m′ :
reg :
Er :
object_regionbase m_regionsm = Somereg
H :
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm in
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
⇒
None
_
⇒
None
None
⇒
Somem
ls
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm in
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
⇒
None
_
⇒
None
=
Somem′
⊢
idsm m′

destruct r_kindreg , r_lifereg ; simpl in H ; try rewrite fold_left_none in H ; discriminate H

x :
base :
Z
ls :
listname × optionZ
IH :
∀ m m′ : mem  ,
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m0 ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm0 in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm0 in
Somem_bytes ≔ m_bytesm0; m_regions ≔ rs; m_aux ≔ m_auxm0
⇒
None
_
⇒
None
None
⇒
Somem0
ls
Somem
=
Somem′
→
idsm m′
m, m′ :
reg :
Er :
object_regionbase m_regionsm = Somereg
H :
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm in
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
⇒
None
_
⇒
None
None
⇒
Somem
ls
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm in
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
=
Somem′
⊢
idsm m′

destruct replace_regionbase _ m_regionsm as rs | eqn: Ers ; simpl in H ; | rewrite fold_left_none in H ; discriminate H

x :
base :
Z
ls :
listname × optionZ
IH :
∀ m m′ : mem  ,
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m0 ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm0 in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm0 in
Somem_bytes ≔ m_bytesm0; m_regions ≔ rs; m_aux ≔ m_auxm0
⇒
None
_
⇒
None
None
⇒
Somem0
ls
Somem
=
Somem′
→
idsm m′
m, m′ :
reg :
Er :
object_regionbase m_regionsm = Somereg
rs :
listregion
Ers :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm = Somers
H :
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm in
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
⇒
None
_
⇒
None
None
⇒
Somem
ls
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
=
Somem′
⊢
idsm m′

eapply ids_trans ; | exact IH_ _ H

x :
base :
Z
ls :
listname × optionZ
IH :
∀ m m′ : mem  ,
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m0 ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm0 in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm0 in
Somem_bytes ≔ m_bytesm0; m_regions ≔ rs; m_aux ≔ m_auxm0
⇒
None
_
⇒
None
None
⇒
Somem0
ls
Somem
=
Somem′
→
idsm m′
m, m′ :
reg :
Er :
object_regionbase m_regionsm = Somereg
rs :
listregion
Ers :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm = Somers
H :
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm in
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
⇒
None
_
⇒
None
None
⇒
Somem
ls
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
=
Somem′
⊢
idsm m_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm

intros b r0 Hb

x :
base :
Z
ls :
listname × optionZ
IH :
∀ m m′ : mem  ,
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m0 ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm0 in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm0 in
Somem_bytes ≔ m_bytesm0; m_regions ≔ rs; m_aux ≔ m_auxm0
⇒
None
_
⇒
None
None
⇒
Somem0
ls
Somem
=
Somem′
→
idsm m′
m, m′ :
reg :
Er :
object_regionbase m_regionsm = Somereg
rs :
listregion
Ers :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm = Somers
H :
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm in
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
⇒
None
_
⇒
None
None
⇒
Somem
ls
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
=
Somem′
b :
Z
r0 :
Hb :
⊢
∃reg′ : region, object_regionb m_regionsm_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm = Somereg′

simpl

x :
base :
Z
ls :
listname × optionZ
IH :
∀ m m′ : mem  ,
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m0 ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm0 in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm0 in
Somem_bytes ≔ m_bytesm0; m_regions ≔ rs; m_aux ≔ m_auxm0
⇒
None
_
⇒
None
None
⇒
Somem0
ls
Somem
=
Somem′
→
idsm m′
m, m′ :
reg :
Er :
object_regionbase m_regionsm = Somereg
rs :
listregion
Ers :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm = Somers
H :
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm in
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
⇒
None
_
⇒
None
None
⇒
Somem
ls
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
=
Somem′
b :
Z
r0 :
Hb :
⊢
∃reg′ : region, object_regionb rs = Somereg′

rewrite object_region_replace_ _ _ _ b Ers eq_refl

x :
base :
Z
ls :
listname × optionZ
IH :
∀ m m′ : mem  ,
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m0 ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm0 in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm0 in
Somem_bytes ≔ m_bytesm0; m_regions ≔ rs; m_aux ≔ m_auxm0
⇒
None
_
⇒
None
None
⇒
Somem0
ls
Somem
=
Somem′
→
idsm m′
m, m′ :
reg :
Er :
object_regionbase m_regionsm = Somereg
rs :
listregion
Ers :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm = Somers
H :
fold_left
λ acc : optionmem l : name × optionZ  ⇒
let* m ≔ acc in
match sndl with
Somebase
⇒
let* reg ≔ object_regionbase m_regionsm in
match r_kindreg with
⇒
match r_lifereg with
⇒
let* rs ≔ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed m_regionsm in
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
⇒
None
_
⇒
None
None
⇒
Somem
ls
Somem_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
=
Somem′
b :
Z
r0 :
Hb :
⊢
∃ reg′ : region  ,
b =? base
→
Somer_base ≔ base; r_end ≔ base; r_kind ≔ Stack; r_life ≔ Freed
=
Somereg′

destruct Z.eqbb base ; eauto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros locals
induction locals as | x slot ls IH ; simpl ; intros m m′ H
–injection H as ←
apply ids_refl
–destruct slot as base | ; | exact IH_ _ H
destruct object_regionbase m_regionsm as reg | eqn: Er ; simpl in H ; | rewrite fold_left_none in H ; discriminate H
destruct r_kindreg , r_lifereg ; simpl in H ; try rewrite fold_left_none in H ; discriminate H
destruct replace_regionbase _ m_regionsm as rs | eqn: Ers ; simpl in H ; | rewrite fold_left_none in H ; discriminate H
eapply ids_trans ; | exact IH_ _ H
intros b r0 Hb
simpl
rewrite object_region_replace_ _ _ _ b Ers eq_refl
destruct Z.eqbb base ; eauto

A step keeps every identity

A free function (from a pointer word and a memory to a result and a new memory) keeps every identity: what it frees stays an object, freed in place. The runtime axiom free_keeps_ids gives this of R's free (R_free_ids).

199Definition free_idsfree : word → Memory.mem → optionresunit × Memory.mem : Prop ≔
∀x m r m′, freex m = Somer, m′ → idsm m′

An instruction i of the frame fr that continues (IContinue) with memory m' keeps every identity of m, where the free of the global environment ge (ge_free) does.

205Lemma inst_step_ids
∀ ge fr m i e l m′
inst_stepge fr m i = SomeIContinuee l m′
idsm m′
Explore proof 4 tactics

Initial goal

⊢
∀ge : genv fr : frame m : mem i : inst e : env l : listname × optionZ m′ : mem, free_idsge_freege → inst_stepge fr m i = SomeIContinuee l m′ → idsm m′

intros ge fr m i e l m′ Hfree H

ge :
fr :
m :
i :
e :
l :
listname × optionZ
m′ :
H :
inst_stepge fr m i = SomeIContinuee l m′
⊢
idsm m′

destruct i

9 open

ge :
fr :
m :
d :
o :
args :
listvalue
e :
l :
listname × optionZ
m′ :
H :
inst_stepge fr m Letd k o args = SomeIContinuee l m′
⊢
idsm m′
focused goal
ge :
fr :
m :
d :
o :
args :
e :
l :
listname × optionZ
m′ :
H :
inst_stepge fr m Flightd o args lower = SomeIContinuee l m′
⊢
idsm m′
focused goal
ge :
fr :
m :
off :
Z
v, a :
e :
l :
listname × optionZ
m′ :
H :
inst_stepge fr m RawStorew off v a = SomeIContinuee l m′
⊢
idsm m′
focused goal
ge :
fr :
m :
off :
Z
v, a :
es :
listeffect
e :
l :
listname × optionZ
m′ :
H :
inst_stepge fr m RawStorePointeroff v a es = SomeIContinuee l m′
⊢
idsm m′
focused goal
ge :
fr :
m :
callee :
args :
listarg
e :
l :
listname × optionZ
m′ :
H :
inst_stepge fr m Callr callee args = SomeIContinuee l m′
⊢
idsm m′
focused goal
ge :
fr :
m :
callee :
args :
listarg
e :
l :
listname × optionZ
m′ :
H :
inst_stepge fr m RawCallr callee args = SomeIContinuee l m′
⊢
idsm m′
focused goal
ge :
fr :
m :
x :
size :
Z
e :
l :
listname × optionZ
m′ :
H :
inst_stepge fr m LocalAllocx size = SomeIContinuee l m′
⊢
idsm m′
focused goal
ge :
fr :
m :
file :
line :
Z
e :
l :
listname × optionZ
m′ :
H :
inst_stepge fr m Locfile line = SomeIContinuee l m′
⊢
idsm m′
focused goal
ge :
fr :
m :
q :
e :
l :
listname × optionZ
m′ :
H :
inst_stepge fr m Touchq = SomeIContinuee l m′
⊢
idsm m′

1: destruct special_leto eqn: Es ; destruct o ; try discriminate Es | rewrite inst_step_let_ _ _ _ _ _ _ Es in H

12 open

ge :
fr :
m :
d :
x :
off, bytes :
Z
align :
Z
args :
listvalue
e :
l :
listname × optionZ
m′ :
H :
inst_stepge fr m Letd k CheckLocalx off bytes r align args = SomeIContinuee l m′
Es :
special_letCheckLocalx off bytes r align = true
⊢
idsm m′
focused goal
ge :
fr :
m :
d :
args :
listvalue
e :
l :
listname × optionZ
m′ :
H :
inst_stepge fr m Letd k CheckFunction args = SomeIContinuee l m′
⊢
idsm m′
focused goal
ge :
fr :
m :
d :
args :
listvalue
e :
l :
listname × optionZ
m′ :
H :
inst_stepge fr m Letd k VaArgs args = SomeIContinuee l m′
Es :
⊢
idsm m′
focused goal
ge :
fr :
m :
d :
o :
args :
listvalue
e :
l :
listname × optionZ
m′ :
H :
let e ≔ fr_envfr in
let locals ≔ fr_localsfr in
let* classes ≔ op_arg_classeso k in
let* xs ≔ map2_optionvalue_xge e classes args in
match op_reso k xs m with
SomeOpResr m′
⇒
Somebind_resd r e locals m′
SomeOpUBwhy
⇒
SomeIStopUBwhy
SomeOpAllocq kont
⇒
Some
λ base : Z  ⇒
let x, m′ ≔ kontbase in
putd x e, locals, m′
None
⇒
None
=
SomeIContinuee l m′
Es :
special_leto = false
⊢
idsm m′
focused goal
ge :
fr :
m :
d :
o :
args :
e :
l :
listname × optionZ
m′ :
H :
inst_stepge fr m Flightd o args lower = SomeIContinuee l m′
⊢
idsm m′
focused goal
ge :
fr :
m :
off :
Z
v, a :
e :
l :
listname × optionZ
m′ :
H :
inst_stepge fr m RawStorew off v a = SomeIContinuee l m′
⊢
idsm m′
focused goal
ge :
fr :
m :
off :
Z
v, a :
es :
listeffect
e :
l :
listname × optionZ
m′ :
H :
inst_stepge fr m RawStorePointeroff v a es = SomeIContinuee l m′
⊢
idsm m′
focused goal
ge :
fr :
m :
callee :
args :
listarg
e :
l :
listname × optionZ
m′ :
H :
inst_stepge fr m Callr callee args = SomeIContinuee l m′
⊢
idsm m′
focused goal
ge :
fr :
m :
callee :
args :
listarg
e :
l :
listname × optionZ
m′ :
H :
inst_stepge fr m RawCallr callee args = SomeIContinuee l m′
⊢
idsm m′
focused goal
ge :
fr :
m :
x :
size :
Z
e :
l :
listname × optionZ
m′ :
H :
inst_stepge fr m LocalAllocx size = SomeIContinuee l m′
⊢
idsm m′
focused goal
ge :
fr :
m :
file :
line :
Z
e :
l :
listname × optionZ
m′ :
H :
inst_stepge fr m Locfile line = SomeIContinuee l m′
⊢
idsm m′
focused goal
ge :
fr :
m :
q :
e :
l :
listname × optionZ
m′ :
H :
inst_stepge fr m Touchq = SomeIContinuee l m′
⊢
idsm m′

all: unfold inst_step , external_call , bind_res , store_out in H ; cases H ; inversion H ; subst;first|apply ids_refl|match goal withE : op_res_ _ _ _ = SomeOpRes_ _ |- _⇒exact ids_same_ _ op_res_regions_ _ _ _ _ _ Eend|match goal withE : ge_free_ _ _ = Some_, _ |- _⇒exact Hfree_ _ _ _ Eend|match goal withE : store_res_ _ _ _ _ = Some_, _ |- _⇒exact ids_same_ _ store_res_regions_ _ _ _ _ _ _ Eend|match goal withE : pointer_store_effects_ _ _ _ = Some_ |- _⇒exact ids_same_ _ pointer_store_effects_regions_ _ _ _ _ Eend

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge fr m i e l m′ Hfree H
destruct i
1: destruct special_leto eqn: Es ; destruct o ; try discriminate Es | rewrite inst_step_let_ _ _ _ _ _ _ Es in H
all: unfold inst_step , external_call , bind_res , store_out in H ; cases H ; inversion H ; subst;first|apply ids_refl|match goal withE : op_res_ _ _ _ = SomeOpRes_ _ |- _⇒exact ids_same_ _ op_res_regions_ _ _ _ _ _ Eend|match goal withE : ge_free_ _ _ = Some_, _ |- _⇒exact Hfree_ _ _ _ Eend|match goal withE : store_res_ _ _ _ _ = Some_, _ |- _⇒exact ids_same_ _ store_res_regions_ _ _ _ _ _ _ Eend|match goal withE : pointer_store_effects_ _ _ _ = Some_ |- _⇒exact ids_same_ _ pointer_store_effects_regions_ _ _ _ _ Eend

A return (return_step) from configuration c to c' keeps every identity: it only ends the returning frame's locals.

224Lemma return_step_ids
∀ c o c′
return_stepc o = Nextc′
Explore proof 5 tactics

Initial goal

⊢
∀c : config o : outcome c′ : config, return_stepc o = Nextc′ → idsc_memc c_memc′

unfold return_step

⊢
∀ c : config o : outcome c′ : config  ,
or_stuck"return"
match c_callersc with
[ ]
⇒
SomeDoneo
caller, pd :: callers
⇒
let* o′ ≔
match pd_convpd with
Somecw, kw
⇒
None
⇒
Someo
in
let* e ≔ returned_envpd_respd o′ fr_envcaller in
SomeNextc_frame ≔ fr_fn ≔ fr_fncaller; fr_env ≔ e; fr_locals ≔ fr_localscaller; fr_doomed ≔ fr_doomedcaller; fr_at ≔ fr_atcaller; c_callers ≔ callers; c_mem ≔ m; c_fuel ≔ c_fuelc
=
Nextc′
→

intros c o c′ H

c′ :
H :
or_stuck"return"
match c_callersc with
[ ]
⇒
SomeDoneo
caller, pd :: callers
⇒
let* o′ ≔
match pd_convpd with
Somecw, kw
⇒
None
⇒
Someo
in
let* e ≔ returned_envpd_respd o′ fr_envcaller in
SomeNextc_frame ≔ fr_fn ≔ fr_fncaller; fr_env ≔ e; fr_locals ≔ fr_localscaller; fr_doomed ≔ fr_doomedcaller; fr_at ≔ fr_atcaller; c_callers ≔ callers; c_mem ≔ m; c_fuel ≔ c_fuelc
=
Nextc′
⊢

apply or_stuck_next in H

c′ :
H :
match c_callersc with
[ ]
⇒
SomeDoneo
caller, pd :: callers
⇒
let* o′ ≔
match pd_convpd with
Somecw, kw
⇒
None
⇒
Someo
in
let* e ≔ returned_envpd_respd o′ fr_envcaller in
SomeNextc_frame ≔ fr_fn ≔ fr_fncaller; fr_env ≔ e; fr_locals ≔ fr_localscaller; fr_doomed ≔ fr_doomedcaller; fr_at ≔ fr_atcaller; c_callers ≔ callers; c_mem ≔ m; c_fuel ≔ c_fuelc
=
SomeNextc′
⊢

cases H ; inversion H ; subst ; simpl

m :
l :
listframe × pending
Heql :
c_callersc = f, p0 :: l
Heqo1 :
match pd_convp0 with
Somecw, kw
⇒
None
⇒
Someo
=
Someo0
e :
Heqo2 :
returned_envpd_resp0 o0 fr_envf = Somee
H :
SomeNextc_frame ≔ fr_fn ≔ fr_fnf; fr_env ≔ e; fr_locals ≔ fr_localsf; fr_doomed ≔ fr_doomedf; fr_at ≔ fr_atf; c_callers ≔ l; c_mem ≔ m; c_fuel ≔ c_fuelc = SomeNextc_frame ≔ fr_fn ≔ fr_fnf; fr_env ≔ e; fr_locals ≔ fr_localsf; fr_doomed ≔ fr_doomedf; fr_at ≔ fr_atf; c_callers ≔ l; c_mem ≔ m; c_fuel ≔ c_fuelc
⊢

match goal withE : invalidate_locals_ _ = Some_ |- _⇒exact invalidate_locals_ids_ _ _ Eend

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros c o c′ H
apply or_stuck_next in H
cases H ; inversion H ; subst ; simpl
match goal withE : invalidate_locals_ _ = Some_ |- _⇒exact invalidate_locals_ids_ _ _ Eend

A jump at the end of block l (jump_step) keeps every identity: it takes an edge, which leaves memory alone, or returns.

233Lemma jump_step_ids
∀ ge c l j c′
jump_stepge c l j = Nextc′
Explore proof 4 tactics

Initial goal

⊢
∀ge : genv c : config l : name j : jump c′ : config, jump_stepge c l j = Nextc′ → idsc_memc c_memc′

unfold jump_step , edge_step

⊢
∀ ge : genv c : config l : name j : jump c′ : config  ,
match fr_doomedc_framec with
Somewhy
⇒
match j with
JBranchv t1 t2
⇒
or_stuck"branch"
match value_xge fr_envc_framec W v with
SomeWIntn
⇒
Some
match if n =? 0 then t2 else t1 with
_
⇒
None
None
⇒
match j with
JBranchv t1 t2
⇒
or_stuck"branch"
match value_xge fr_envc_framec W v with
SomeWIntn
⇒
Some
match if n =? 0 then t2 else t1 with
_
⇒
None
⇒
match fn_retfr_fnc_framec with
⇒
let* x ≔ value_xge fr_envc_framec k v in
_
⇒
None
⇒
or_stuck"rets"
match fn_retfr_fnc_framec with
⇒
let* xs ≔ map2_optionvalue_xge fr_envc_framec ks vs in
_
⇒
None
=
Nextc′
→

intros ge c l j c′ H

ge :
l :
j :
c′ :
H :
match fr_doomedc_framec with
Somewhy
⇒
match j with
JBranchv t1 t2
⇒
or_stuck"branch"
match value_xge fr_envc_framec W v with
SomeWIntn
⇒
Some
match if n =? 0 then t2 else t1 with
_
⇒
None
None
⇒
match j with
JBranchv t1 t2
⇒
or_stuck"branch"
match value_xge fr_envc_framec W v with
SomeWIntn
⇒
Some
match if n =? 0 then t2 else t1 with
_
⇒
None
⇒
match fn_retfr_fnc_framec with
⇒
let* x ≔ value_xge fr_envc_framec k v in
_
⇒
None
⇒
or_stuck"rets"
match fn_retfr_fnc_framec with
⇒
let* xs ≔ map2_optionvalue_xge fr_envc_framec ks vs in
_
⇒
None
=
Nextc′
⊢

cases H ; unstuck H

9 open

ge :
l :
j :
c′ :
Heqo :
l0 :
Heqt0 :
t = Tol0
Heqj0 :
j = JGotoTol0
⊢
focused goal
ge :
l :
j :
c′ :
Heqo :
t1, t2 :
Heqj0 :
j = JBranchv t1 t2
w :
n :
Z
Heqw0 :
w = WIntn
Heqo0 :
l0 :
Heqt :
n =? 0
→
t2
else
t1
=
Tol0
⊢
focused goal
ge :
l :
j :
c′ :
Heqo :
l0 :
Heqt0 :
t = Tol0
Heqj0 :
j = JGotoTol0
⊢
focused goal
ge :
l :
j :
c′ :
Heqo :
l0 :
Heqt0 :
t = Polll0
Heqj0 :
j = JGotoPolll0
⊢
focused goal
ge :
l :
j :
c′ :
Heqo :
t1, t2 :
Heqj0 :
j = JBranchv t1 t2
w :
n :
Z
Heqw0 :
w = WIntn
Heqo0 :
l0 :
Heqt :
n =? 0
→
t2
else
t1
=
Tol0
⊢
focused goal
ge :
l :
j :
c′ :
Heqo :
t1, t2 :
Heqj0 :
j = JBranchv t1 t2
w :
n :
Z
Heqw0 :
w = WIntn
Heqo0 :
l0 :
Heqt :
n =? 0
→
t2
else
t1
=
⊢
focused goal
ge :
l :
j :
c′ :
Heqo :
Heqj0 :
j = JRetv
w :
Heqo0 :
value_xge fr_envc_framec k v = Somew
H :
Somereturn_stepc Retw = SomeNextc′
⊢
focused goal
ge :
l :
j :
c′ :
Heqo :
vs :
listvalue
Heqj0 :
j = JRetsvs
ks :
listclass
l0 :
listword
Heqo0 :
H :
Somereturn_stepc Retsl0 = SomeNextc′
⊢
focused goal
ge :
l :
j :
c′ :
Heqo :
Heqj0 :
⊢

all: first|match goal withE : return_step_ _ = Next_ |- _⇒exact return_step_ids_ _ _ Eend|inversion H ; subst;first|exact ids_refl_|match goal withE : return_step_ _ = Next_ |- _⇒exact return_step_ids_ _ _ Eend

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge c l j c′ H
all: first|match goal withE : return_step_ _ = Next_ |- _⇒exact return_step_ids_ _ _ Eend|inversion H ; subst;first|exact ids_refl_|match goal withE : return_step_ _ = Next_ |- _⇒exact return_step_ids_ _ _ Eend

A step of configuration c that allocates nothing (Next c') keeps every identity of its memory, where ge's free does. Allocations are step_fresh_regions.

247Lemma step_next_ids
∀ ge c c′
Explore proof 4 tactics

Initial goal

⊢
∀ge : genv c c′ : config, free_idsge_freege → stepge c = Nextc′ → idsc_memc c_memc′

unfold step , inst_next

⊢
∀ ge : genv c c′ : config  ,
→
match fr_atc_framec with
Snapshot_ :: _ as xs l
⇒
negbforallbsnapshot_word xs
→
Stuck"snapshot"
else
Freshheap_req16 8 × Z.of_natDatatypes.lengthxs λbase : Z ⇒ c_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ putva_snapshot WPtrptr_addr ≔ base; ptr_cap ≔ Robase fr_envc_framec; fr_locals ≔ fr_localsc_framec; fr_doomed ≔ fr_doomedc_framec; fr_at ≔ Enterl None; c_callers ≔ c_callersc; c_mem ≔ snapshot_valuesxs base allocatedc_memc heap_req16 8 × Z.of_natDatatypes.lengthxs base; c_fuel ≔ c_fuelc
Enterl from
⇒
else
or_stuck"block"
Execl [ ] j
⇒
jump_stepge c l j
Execl i :: rest j
⇒
match let* why ≔ fr_doomedc_framec in if ahead_transparenti then None else Somewhy with
Somewhy
⇒
None
⇒
or_stuck"instruction"
let* out0 ≔ inst_stepge c_framec c_memc i in
let* od ≔ doomed_resultge c_framec c_memc i out0 in
Some
match fstod with
IContinuee locals m′
⇒
Nextc_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ e; fr_locals ≔ locals; fr_doomed ≔ sndod; fr_at ≔ Execl rest j; c_callers ≔ c_callersc; c_mem ≔ m′; c_fuel ≔ c_fuelc
ICallg xs pd
⇒
match call_frameg xs with
Somecallee
⇒
Nextc_frame ≔ callee; c_callers ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ fr_envc_framec; fr_locals ≔ fr_localsc_framec; fr_doomed ≔ sndod; fr_at ≔ Execl rest j, pd :: c_callersc; c_mem ≔ c_memc; c_fuel ≔ c_fuelc
None
⇒
Stuck"call"
⇒
λ base : Z  ⇒
let p, m′ ≔ kbase in
let e, locals ≔ p in
c_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ e; fr_locals ≔ locals; fr_doomed ≔ sndod; fr_at ≔ Execl rest j; c_callers ≔ c_callersc; c_mem ≔ m′; c_fuel ≔ c_fuelc
⇒
Stuck"outside the core subset"
=
Nextc′
→

intros ge c c′ Hfree H

ge :
c, c′ :
H :
match fr_atc_framec with
Snapshot_ :: _ as xs l
⇒
negbforallbsnapshot_word xs
→
Stuck"snapshot"
else
Freshheap_req16 8 × Z.of_natDatatypes.lengthxs λbase : Z ⇒ c_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ putva_snapshot WPtrptr_addr ≔ base; ptr_cap ≔ Robase fr_envc_framec; fr_locals ≔ fr_localsc_framec; fr_doomed ≔ fr_doomedc_framec; fr_at ≔ Enterl None; c_callers ≔ c_callersc; c_mem ≔ snapshot_valuesxs base allocatedc_memc heap_req16 8 × Z.of_natDatatypes.lengthxs base; c_fuel ≔ c_fuelc
Enterl from
⇒
else
or_stuck"block"
Execl [ ] j
⇒
jump_stepge c l j
Execl i :: rest j
⇒
match let* why ≔ fr_doomedc_framec in if ahead_transparenti then None else Somewhy with
Somewhy
⇒
None
⇒
or_stuck"instruction"
let* out0 ≔ inst_stepge c_framec c_memc i in
let* od ≔ doomed_resultge c_framec c_memc i out0 in
Some
match fstod with
IContinuee locals m′
⇒
Nextc_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ e; fr_locals ≔ locals; fr_doomed ≔ sndod; fr_at ≔ Execl rest j; c_callers ≔ c_callersc; c_mem ≔ m′; c_fuel ≔ c_fuelc
ICallg xs pd
⇒
match call_frameg xs with
Somecallee
⇒
Nextc_frame ≔ callee; c_callers ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ fr_envc_framec; fr_locals ≔ fr_localsc_framec; fr_doomed ≔ sndod; fr_at ≔ Execl rest j, pd :: c_callersc; c_mem ≔ c_memc; c_fuel ≔ c_fuelc
None
⇒
Stuck"call"
⇒
λ base : Z  ⇒
let p, m′ ≔ kbase in
let e, locals ≔ p in
c_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ e; fr_locals ≔ locals; fr_doomed ≔ sndod; fr_at ≔ Execl rest j; c_callers ≔ c_callersc; c_mem ≔ m′; c_fuel ≔ c_fuelc
⇒
Stuck"outside the core subset"
=
Nextc′
⊢

cases H ; unstuck H

5 open

ge :
c, c′ :
xs :
listword
l :
Heql0 :
xs = [ ]
Heqp :
⊢
focused goal
ge :
c, c′ :
l :
from :
optionname
Heqp :
Heqb :
c_fuelc =? 0 = false
e :
Heqo0 :
phis_envge b_phisb from fr_envc_framec = Somee
H :
SomeNextc_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ e; fr_locals ≔ fr_localsc_framec; fr_doomed ≔ fr_doomedc_framec; fr_at ≔ Execl b_instsb b_jumpb; c_callers ≔ c_callersc; c_mem ≔ c_memc; c_fuel ≔ c_fuelc − 1 = SomeNextc′
⊢
focused goal
ge :
c, c′ :
l :
insts :
listinst
j :
Heql0 :
insts = [ ]
Heqp :
fr_atc_framec = Execl [ ] j
H :
jump_stepge c l j = Nextc′
⊢
focused goal
ge :
c, c′ :
l :
insts :
listinst
j :
i :
l0 :
listinst
Heql0 :
insts = i :: l0
Heqp :
fr_atc_framec = Execl i :: l0 j
Heqo :
let* why ≔ fr_doomedc_framec in
else
Somewhy
=
None
Heqo0 :
inst_stepge c_framec c_memc i = Somei0
p :
inst_out × optionreason
Heqo1 :
doomed_resultge c_framec c_memc i i0 = Somep
e :
locals :
listname × optionZ
m :
Heqi1 :
fstp = IContinuee locals m
H :
SomeNextc_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ e; fr_locals ≔ locals; fr_doomed ≔ sndp; fr_at ≔ Execl l0 j; c_callers ≔ c_callersc; c_mem ≔ m; c_fuel ≔ c_fuelc = SomeNextc′
⊢
focused goal
ge :
c, c′ :
l :
insts :
listinst
j :
i :
l0 :
listinst
Heql0 :
insts = i :: l0
Heqp :
fr_atc_framec = Execl i :: l0 j
Heqo :
let* why ≔ fr_doomedc_framec in
else
Somewhy
=
None
Heqo0 :
inst_stepge c_framec c_memc i = Somei0
p :
inst_out × optionreason
Heqo1 :
doomed_resultge c_framec c_memc i i0 = Somep
f :
xs :
listword
Heqi1 :
fstp = ICallf xs pd
f0 :
Heqo2 :
call_framef xs = Somef0
H :
SomeNextc_frame ≔ f0; c_callers ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ fr_envc_framec; fr_locals ≔ fr_localsc_framec; fr_doomed ≔ sndp; fr_at ≔ Execl l0 j, pd :: c_callersc; c_mem ≔ c_memc; c_fuel ≔ c_fuelc = SomeNextc′
⊢

all: first|match goal withE : jump_step_ _ _ _ = Next_ |- _⇒exact jump_step_ids_ _ _ _ _ Eend|inversion H ; subst ; simpl;first|exact ids_refl_|match goal withE : doomed_result_ _ _ _ _ = Some?od , Hc : fst?od = IContinue_ _ _ |- _⇒destruct doomed_result_out_ _ _ _ _ _ E as Ho | e′ & l′ & Ho | o′ & Ho ; rewrite Ho in Hc ; try discriminate Hc;|subst;match goal withE2 : inst_step_ _ _ _ = SomeIContinue_ _ _ |- _⇒exact inst_step_ids_ _ _ _ _ _ _ Hfree E2end|inversion Hc ; subst ; apply ids_reflend

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
unfold step , inst_next
intros ge c c′ Hfree H
all: first|match goal withE : jump_step_ _ _ _ = Next_ |- _⇒exact jump_step_ids_ _ _ _ _ Eend|inversion H ; subst ; simpl;first|exact ids_refl_|match goal withE : doomed_result_ _ _ _ _ = Some?od , Hc : fst?od = IContinue_ _ _ |- _⇒destruct doomed_result_out_ _ _ _ _ _ E as Ho | e′ & l′ & Ho | o′ & Ho ; rewrite Ho in Hc ; try discriminate Hc;|subst;match goal withE2 : inst_step_ _ _ _ = SomeIContinue_ _ _ |- _⇒exact inst_step_ids_ _ _ _ _ _ _ Hfree E2end|inversion Hc ; subst ; apply ids_reflend

Storing the variadic arguments xs from address a (snapshot_values, snapshot_values/5), as a variadic function's entry does into its new snapshot object, leaves the region list unchanged.

271Lemma snapshot_values_regions
Explore proof 2 tactics

Initial goal

⊢
∀xs : listword a : Z m : mem, m_regionssnapshot_valuesxs a m = m_regionsm

induction xs as | x xs IH ; intros a m ; simpl ; reflexivity |

x :
xs :
listword
IH :
∀a : Z m : mem, m_regionssnapshot_valuesxs a m = m_regionsm
a :
Z
m :

destruct x ; rewrite IH ; reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
induction xs as | x xs IH ; intros a m ; simpl ; reflexivity |
destruct x ; rewrite IH ; reflexivity

An op that allocates (OpAlloc with request q and continuation kont) leaves, for each base, exactly the memory allocated m q base: the new object, and no other change of memory.

280Lemma op_res_alloc_exact
∀ o k xs m q kont base
op_reso k xs m = SomeOpAllocq kont
sndkontbase = allocatedm q base
Proof 5 steps Qed
intros o k xs m q kont H
destruct o ; cases H ; inversion H ; subst
intros base
reflexivity

An instruction that allocates (IFresh q k) leaves, for whatever base the runtime picks, the region list of allocated m q base: the old objects and the new one.

290Lemma inst_step_fresh_regions
∀ ge fr m i q k base
inst_stepge fr m i = SomeIFreshq k
m_regionssndkbase = m_regionsallocatedm q base
Explore proof 5 tactics

Initial goal

⊢
∀ge : genv fr : frame m : mem i : inst q : alloc_req k : Z → env × listname × optionZ × mem, inst_stepge fr m i = SomeIFreshq k → ∀base : Z, m_regionssndkbase = m_regionsallocatedm q base

intros ge fr m i q k H

ge :
fr :
m :
i :
k :
Z → env × listname × optionZ × mem
H :
inst_stepge fr m i = SomeIFreshq k
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base

destruct i

9 open

ge :
fr :
m :
d :
k0 :
o :
args :
listvalue
k :
Z → env × listname × optionZ × mem
H :
inst_stepge fr m Letd k0 o args = SomeIFreshq k
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base
focused goal
ge :
fr :
m :
d :
o :
args :
k :
Z → env × listname × optionZ × mem
H :
inst_stepge fr m Flightd o args lower = SomeIFreshq k
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base
focused goal
ge :
fr :
m :
off :
Z
v, a :
k :
Z → env × listname × optionZ × mem
H :
inst_stepge fr m RawStorew off v a = SomeIFreshq k
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base
focused goal
ge :
fr :
m :
off :
Z
v, a :
es :
listeffect
k :
Z → env × listname × optionZ × mem
H :
inst_stepge fr m RawStorePointeroff v a es = SomeIFreshq k
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base
focused goal
ge :
fr :
m :
callee :
args :
listarg
k :
Z → env × listname × optionZ × mem
H :
inst_stepge fr m Callr callee args = SomeIFreshq k
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base
focused goal
ge :
fr :
m :
callee :
args :
listarg
k :
Z → env × listname × optionZ × mem
H :
inst_stepge fr m RawCallr callee args = SomeIFreshq k
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base
focused goal
ge :
fr :
m :
x :
size :
Z
k :
Z → env × listname × optionZ × mem
H :
inst_stepge fr m LocalAllocx size = SomeIFreshq k
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base
focused goal
ge :
fr :
m :
file :
line :
Z
k :
Z → env × listname × optionZ × mem
H :
inst_stepge fr m Locfile line = SomeIFreshq k
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base
focused goal
ge :
fr :
m :
q0 :
k :
Z → env × listname × optionZ × mem
H :
inst_stepge fr m Touchq0 = SomeIFreshq k
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base

1: destruct special_leto eqn: Es ; destruct o ; try discriminate Es | rewrite inst_step_let_ _ _ _ _ _ _ Es in H

12 open

ge :
fr :
m :
d :
k0 :
x :
off, bytes :
Z
align :
Z
args :
listvalue
k :
Z → env × listname × optionZ × mem
H :
inst_stepge fr m Letd k0 CheckLocalx off bytes r align args = SomeIFreshq k
Es :
special_letCheckLocalx off bytes r align = true
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base
focused goal
ge :
fr :
m :
d :
k0 :
args :
listvalue
k :
Z → env × listname × optionZ × mem
H :
inst_stepge fr m Letd k0 CheckFunction args = SomeIFreshq k
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base
focused goal
ge :
fr :
m :
d :
k0 :
args :
listvalue
k :
Z → env × listname × optionZ × mem
H :
inst_stepge fr m Letd k0 VaArgs args = SomeIFreshq k
Es :
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base
focused goal
ge :
fr :
m :
d :
k0 :
o :
args :
listvalue
k :
Z → env × listname × optionZ × mem
H :
let e ≔ fr_envfr in
let locals ≔ fr_localsfr in
let* classes ≔ op_arg_classeso k0 in
let* xs ≔ map2_optionvalue_xge e classes args in
match op_reso k0 xs m with
SomeOpResr m′
⇒
Somebind_resd r e locals m′
SomeOpUBwhy
⇒
SomeIStopUBwhy
SomeOpAllocq kont
⇒
Some
λ base : Z  ⇒
let x, m′ ≔ kontbase in
putd x e, locals, m′
None
⇒
None
=
SomeIFreshq k
Es :
special_leto = false
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base
focused goal
ge :
fr :
m :
d :
o :
args :
k :
Z → env × listname × optionZ × mem
H :
inst_stepge fr m Flightd o args lower = SomeIFreshq k
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base
focused goal
ge :
fr :
m :
off :
Z
v, a :
k :
Z → env × listname × optionZ × mem
H :
inst_stepge fr m RawStorew off v a = SomeIFreshq k
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base
focused goal
ge :
fr :
m :
off :
Z
v, a :
es :
listeffect
k :
Z → env × listname × optionZ × mem
H :
inst_stepge fr m RawStorePointeroff v a es = SomeIFreshq k
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base
focused goal
ge :
fr :
m :
callee :
args :
listarg
k :
Z → env × listname × optionZ × mem
H :
inst_stepge fr m Callr callee args = SomeIFreshq k
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base
focused goal
ge :
fr :
m :
callee :
args :
listarg
k :
Z → env × listname × optionZ × mem
H :
inst_stepge fr m RawCallr callee args = SomeIFreshq k
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base
focused goal
ge :
fr :
m :
x :
size :
Z
k :
Z → env × listname × optionZ × mem
H :
inst_stepge fr m LocalAllocx size = SomeIFreshq k
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base
focused goal
ge :
fr :
m :
file :
line :
Z
k :
Z → env × listname × optionZ × mem
H :
inst_stepge fr m Locfile line = SomeIFreshq k
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base
focused goal
ge :
fr :
m :
q0 :
k :
Z → env × listname × optionZ × mem
H :
inst_stepge fr m Touchq0 = SomeIFreshq k
⊢
∀base : Z, m_regionssndkbase = m_regionsallocatedm q base

all: unfold inst_step , external_call , bind_res , store_out in H ; cases H ; inversion H ; subst ; intros base

2 open

ge :
fr :
m :
d :
k0 :
o :
args :
listvalue
l :
listclass
Heqo0 :
op_arg_classeso k0 = Somel
l0 :
listword
Heqo1 :
map2_optionvalue_xge fr_envfr l args = Somel0
k1 :
Z → word × mem
H :
Some
λ base : Z  ⇒
let x, m′ ≔ k1base in
putd x fr_envfr, fr_localsfr, m′
=
Some
λ base : Z  ⇒
let x, m′ ≔ k1base in
putd x fr_envfr, fr_localsfr, m′
Heqo2 :
op_reso k0 l0 m = SomeOpAllocq k1
Es :
special_leto = false
base :
Z
⊢
snd
let x, m′ ≔ k1base in
putd x fr_envfr, fr_localsfr, m′
=
focused goal
ge :
fr :
m :
x :
size :
Z
Heqo :
lookupx fr_localsfr = SomeNone
H :
SomeIFreshlocal_reqsize λbase : Z ⇒ fr_envfr, putx Somebase fr_localsfr, allocatedm local_reqsize base = SomeIFreshlocal_reqsize λbase : Z ⇒ fr_envfr, putx Somebase fr_localsfr, allocatedm local_reqsize base
base :
Z
⊢
m_regionssndfr_envfr, putx Somebase fr_localsfr, allocatedm local_reqsize base = m_regionsallocatedm local_reqsize base

all: first|reflexivity|match goal withE : op_res_ _ _ _ = SomeOpAlloc_ ?kont |- _⇒pose proof op_res_alloc_exact_ _ _ _ _ _ E base as Ek ; destruct kontbase as x m′ ; simpl in Ek |- * ; rewrite Ek ; reflexivityend

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge fr m i q k H
destruct i
1: destruct special_leto eqn: Es ; destruct o ; try discriminate Es | rewrite inst_step_let_ _ _ _ _ _ _ Es in H
all: unfold inst_step , external_call , bind_res , store_out in H ; cases H ; inversion H ; subst ; intros base
all: first|reflexivity|match goal withE : op_res_ _ _ _ = SomeOpAlloc_ ?kont |- _⇒pose proof op_res_alloc_exact_ _ _ _ _ _ E base as Ek ; destruct kontbase as x m′ ; simpl in Ek |- * ; rewrite Ek ; reflexivityend

A step that allocates (Fresh q k) does the same: whatever base the runtime gives, the next configuration's regions are the old ones with the new object added. An allocation adds one identity and drops none.

309Lemma step_fresh_regions
∀ ge c q k base
stepge c = Freshq k
Explore proof 11 tactics

Initial goal

⊢
∀ge : genv c : config q : alloc_req k : Z → config, stepge c = Freshq k → ∀base : Z, m_regionsc_memkbase = m_regionsallocatedc_memc q base

unfold step , inst_next

⊢
∀ ge : genv c : config q : alloc_req k : Z → config  ,
match fr_atc_framec with
Snapshot_ :: _ as xs l
⇒
negbforallbsnapshot_word xs
→
Stuck"snapshot"
else
Freshheap_req16 8 × Z.of_natDatatypes.lengthxs λbase : Z ⇒ c_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ putva_snapshot WPtrptr_addr ≔ base; ptr_cap ≔ Robase fr_envc_framec; fr_locals ≔ fr_localsc_framec; fr_doomed ≔ fr_doomedc_framec; fr_at ≔ Enterl None; c_callers ≔ c_callersc; c_mem ≔ snapshot_valuesxs base allocatedc_memc heap_req16 8 × Z.of_natDatatypes.lengthxs base; c_fuel ≔ c_fuelc
Enterl from
⇒
else
or_stuck"block"
Execl [ ] j
⇒
jump_stepge c l j
Execl i :: rest j
⇒
match let* why ≔ fr_doomedc_framec in if ahead_transparenti then None else Somewhy with
Somewhy
⇒
None
⇒
or_stuck"instruction"
let* out0 ≔ inst_stepge c_framec c_memc i in
let* od ≔ doomed_resultge c_framec c_memc i out0 in
Some
match fstod with
IContinuee locals m′
⇒
Nextc_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ e; fr_locals ≔ locals; fr_doomed ≔ sndod; fr_at ≔ Execl rest j; c_callers ≔ c_callersc; c_mem ≔ m′; c_fuel ≔ c_fuelc
ICallg xs pd
⇒
match call_frameg xs with
Somecallee
⇒
Nextc_frame ≔ callee; c_callers ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ fr_envc_framec; fr_locals ≔ fr_localsc_framec; fr_doomed ≔ sndod; fr_at ≔ Execl rest j, pd :: c_callersc; c_mem ≔ c_memc; c_fuel ≔ c_fuelc
None
⇒
Stuck"call"
IFreshq0 k0
⇒
λ base : Z  ⇒
let p, m′ ≔ k0base in
let e, locals ≔ p in
c_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ e; fr_locals ≔ locals; fr_doomed ≔ sndod; fr_at ≔ Execl rest j; c_callers ≔ c_callersc; c_mem ≔ m′; c_fuel ≔ c_fuelc
⇒
Stuck"outside the core subset"
=
→
∀base : Z, m_regionsc_memkbase = m_regionsallocatedc_memc q base

intros ge c q k H

ge :
k :
Z → config
H :
match fr_atc_framec with
Snapshot_ :: _ as xs l
⇒
negbforallbsnapshot_word xs
→
Stuck"snapshot"
else
Freshheap_req16 8 × Z.of_natDatatypes.lengthxs λbase : Z ⇒ c_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ putva_snapshot WPtrptr_addr ≔ base; ptr_cap ≔ Robase fr_envc_framec; fr_locals ≔ fr_localsc_framec; fr_doomed ≔ fr_doomedc_framec; fr_at ≔ Enterl None; c_callers ≔ c_callersc; c_mem ≔ snapshot_valuesxs base allocatedc_memc heap_req16 8 × Z.of_natDatatypes.lengthxs base; c_fuel ≔ c_fuelc
Enterl from
⇒
else
or_stuck"block"
Execl [ ] j
⇒
jump_stepge c l j
Execl i :: rest j
⇒
match let* why ≔ fr_doomedc_framec in if ahead_transparenti then None else Somewhy with
Somewhy
⇒
None
⇒
or_stuck"instruction"
let* out0 ≔ inst_stepge c_framec c_memc i in
let* od ≔ doomed_resultge c_framec c_memc i out0 in
Some
match fstod with
IContinuee locals m′
⇒
Nextc_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ e; fr_locals ≔ locals; fr_doomed ≔ sndod; fr_at ≔ Execl rest j; c_callers ≔ c_callersc; c_mem ≔ m′; c_fuel ≔ c_fuelc
ICallg xs pd
⇒
match call_frameg xs with
Somecallee
⇒
Nextc_frame ≔ callee; c_callers ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ fr_envc_framec; fr_locals ≔ fr_localsc_framec; fr_doomed ≔ sndod; fr_at ≔ Execl rest j, pd :: c_callersc; c_mem ≔ c_memc; c_fuel ≔ c_fuelc
None
⇒
Stuck"call"
⇒
λ base : Z  ⇒
let p, m′ ≔ kbase in
let e, locals ≔ p in
c_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ e; fr_locals ≔ locals; fr_doomed ≔ sndod; fr_at ≔ Execl rest j; c_callers ≔ c_callersc; c_mem ≔ m′; c_fuel ≔ c_fuelc
⇒
Stuck"outside the core subset"
=
⊢
∀base : Z, m_regionsc_memkbase = m_regionsallocatedc_memc q base

cases H ; unstuck H ; try exfalso ; exact jump_step_not_fresh_ _ _ _ _ _ H

2 open

ge :
k :
Z → config
xs :
listword
l :
w :
l0 :
listword
Heql0 :
xs = w :: l0
Heqp :
fr_atc_framec = Snapshotw :: l0 l
Heqb :
negbforallbsnapshot_word w :: l0 = false
H :
Freshheap_req16 8 × Z.of_natDatatypes.lengthw :: l0 λbase : Z ⇒ c_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ putva_snapshot WPtrptr_addr ≔ base; ptr_cap ≔ Robase fr_envc_framec; fr_locals ≔ fr_localsc_framec; fr_doomed ≔ fr_doomedc_framec; fr_at ≔ Enterl None; c_callers ≔ c_callersc; c_mem ≔ snapshot_valuesw :: l0 base allocatedc_memc heap_req16 8 × Z.of_natDatatypes.lengthw :: l0 base; c_fuel ≔ c_fuelc = Freshq k
⊢
∀base : Z, m_regionsc_memkbase = m_regionsallocatedc_memc q base
focused goal
ge :
k :
Z → config
l :
insts :
listinst
j :
i :
l0 :
listinst
Heql0 :
insts = i :: l0
Heqp :
fr_atc_framec = Execl i :: l0 j
Heqo :
let* why ≔ fr_doomedc_framec in
else
Somewhy
=
None
Heqo0 :
inst_stepge c_framec c_memc i = Somei0
p :
inst_out × optionreason
Heqo1 :
doomed_resultge c_framec c_memc i i0 = Somep
k0 :
Z → env × listname × optionZ × mem
Heqi1 :
fstp = IFreshq0 k0
H :
Some
λ base : Z  ⇒
let p0, m′ ≔ k0base in
let e, locals ≔ p0 in
c_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ e; fr_locals ≔ locals; fr_doomed ≔ sndp; fr_at ≔ Execl l0 j; c_callers ≔ c_callersc; c_mem ≔ m′; c_fuel ≔ c_fuelc
=
SomeFreshq k
⊢
∀base : Z, m_regionsc_memkbase = m_regionsallocatedc_memc q base

all: injection H as Hq Hk ; subst q k ; intros base

2 open

ge :
xs :
listword
l :
w :
l0 :
listword
Heql0 :
xs = w :: l0
Heqp :
fr_atc_framec = Snapshotw :: l0 l
Heqb :
negbforallbsnapshot_word w :: l0 = false
base :
Z
⊢
m_regionsc_memc_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ putva_snapshot WPtrptr_addr ≔ base; ptr_cap ≔ Robase fr_envc_framec; fr_locals ≔ fr_localsc_framec; fr_doomed ≔ fr_doomedc_framec; fr_at ≔ Enterl None; c_callers ≔ c_callersc; c_mem ≔ match w with WIntn ⇒ snapshot_valuesl0 base + 8 store_bytesallocatedc_memc heap_req16 Z.posPosDef.Pos.of_succ_natDatatypes.lengthl0~0~0~0 base base 8 n | WPtrp ⇒ snapshot_valuesl0 base + 8 store_auxstore_bytesallocatedc_memc heap_req16 Z.posPosDef.Pos.of_succ_natDatatypes.lengthl0~0~0~0 base base 8 ptr_addrp base ptr_capp | WLimit_ _ ⇒ snapshot_valuesl0 base + 8 allocatedc_memc heap_req16 Z.posPosDef.Pos.of_succ_natDatatypes.lengthl0~0~0~0 base end; c_fuel ≔ c_fuelc = m_regionsallocatedc_memc heap_req16 Z.posPosDef.Pos.of_succ_natDatatypes.lengthl0~0~0~0 base
focused goal
ge :
l :
insts :
listinst
j :
i :
l0 :
listinst
Heql0 :
insts = i :: l0
Heqp :
fr_atc_framec = Execl i :: l0 j
Heqo :
let* why ≔ fr_doomedc_framec in
else
Somewhy
=
None
Heqo0 :
inst_stepge c_framec c_memc i = Somei0
p :
inst_out × optionreason
Heqo1 :
doomed_resultge c_framec c_memc i i0 = Somep
k0 :
Z → env × listname × optionZ × mem
Heqi1 :
fstp = IFreshq0 k0
base :
Z
⊢
let p0, m′ ≔ k0base in
let e, locals ≔ p0 in
c_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ e; fr_locals ≔ locals; fr_doomed ≔ sndp; fr_at ≔ Execl l0 j; c_callers ≔ c_callersc; c_mem ≔ m′; c_fuel ≔ c_fuelc
=

–match goal withHp : fr_at_ = Snapshot?xs _ |- _⇒exact snapshot_values_regionsxs base _end

deferred goal
ge :
l :
insts :
listinst
j :
i :
l0 :
listinst
Heql0 :
insts = i :: l0
Heqp :
fr_atc_framec = Execl i :: l0 j
Heqo :
let* why ≔ fr_doomedc_framec in
else
Somewhy
=
None
Heqo0 :
inst_stepge c_framec c_memc i = Somei0
p :
inst_out × optionreason
Heqo1 :
doomed_resultge c_framec c_memc i i0 = Somep
k0 :
Z → env × listname × optionZ × mem
Heqi1 :
fstp = IFreshq0 k0
base :
Z
⊢
let p0, m′ ≔ k0base in
let e, locals ≔ p0 in
c_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ e; fr_locals ≔ locals; fr_doomed ≔ sndp; fr_at ≔ Execl l0 j; c_callers ≔ c_callersc; c_mem ≔ m′; c_fuel ≔ c_fuelc
=

–match goal withE : doomed_result_ _ _ _ _ = Some?od , Hc : fst?od = IFresh_ _ |- _⇒destruct doomed_result_out_ _ _ _ _ _ E as Ho | e′ & l′ & Ho | o′ & Ho ; rewrite Ho in Hc ; try discriminate Hcend

ge :
l :
insts :
listinst
j :
i :
l0 :
listinst
Heql0 :
insts = i :: l0
Heqp :
fr_atc_framec = Execl i :: l0 j
Heqo :
let* why ≔ fr_doomedc_framec in
else
Somewhy
=
None
Heqo0 :
inst_stepge c_framec c_memc i = Somei0
p :
inst_out × optionreason
Heqo1 :
doomed_resultge c_framec c_memc i i0 = Somep
k0 :
Z → env × listname × optionZ × mem
Heqi1 :
i0 = IFreshq0 k0
base :
Z
Ho :
fstp = i0
⊢
let p0, m′ ≔ k0base in
let e, locals ≔ p0 in
c_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ e; fr_locals ≔ locals; fr_doomed ≔ sndp; fr_at ≔ Execl l0 j; c_callers ≔ c_callersc; c_mem ≔ m′; c_fuel ≔ c_fuelc
=

subst

ge :
l :
j :
i :
l0 :
listinst
Heqp :
fr_atc_framec = Execl i :: l0 j
Heqo :
let* why ≔ fr_doomedc_framec in
else
Somewhy
=
None
k0 :
Z → env × listname × optionZ × mem
Heqo0 :
inst_stepge c_framec c_memc i = SomeIFreshq0 k0
p :
inst_out × optionreason
Heqo1 :
doomed_resultge c_framec c_memc i IFreshq0 k0 = Somep
base :
Z
Ho :
fstp = IFreshq0 k0
⊢
let p0, m′ ≔ k0base in
let e, locals ≔ p0 in
c_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ e; fr_locals ≔ locals; fr_doomed ≔ sndp; fr_at ≔ Execl l0 j; c_callers ≔ c_callersc; c_mem ≔ m′; c_fuel ≔ c_fuelc
=

match goal withE2 : inst_step_ _ _ _ = SomeIFresh_ ?k0 |- _⇒pose proof inst_step_fresh_regions_ _ _ _ _ _ E2 base as Hkend

ge :
l :
j :
i :
l0 :
listinst
Heqp :
fr_atc_framec = Execl i :: l0 j
Heqo :
let* why ≔ fr_doomedc_framec in
else
Somewhy
=
None
k0 :
Z → env × listname × optionZ × mem
Heqo0 :
inst_stepge c_framec c_memc i = SomeIFreshq0 k0
p :
inst_out × optionreason
Heqo1 :
doomed_resultge c_framec c_memc i IFreshq0 k0 = Somep
base :
Z
Ho :
fstp = IFreshq0 k0
Hk :
m_regionssndk0base = m_regionsallocatedc_memc q0 base
⊢
let p0, m′ ≔ k0base in
let e, locals ≔ p0 in
c_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ e; fr_locals ≔ locals; fr_doomed ≔ sndp; fr_at ≔ Execl l0 j; c_callers ≔ c_callersc; c_mem ≔ m′; c_fuel ≔ c_fuelc
=

simpl

ge :
l :
j :
i :
l0 :
listinst
Heqp :
fr_atc_framec = Execl i :: l0 j
Heqo :
let* why ≔ fr_doomedc_framec in
else
Somewhy
=
None
k0 :
Z → env × listname × optionZ × mem
Heqo0 :
inst_stepge c_framec c_memc i = SomeIFreshq0 k0
p :
inst_out × optionreason
Heqo1 :
doomed_resultge c_framec c_memc i IFreshq0 k0 = Somep
base :
Z
Ho :
fstp = IFreshq0 k0
Hk :
m_regionssndk0base = m_regionsallocatedc_memc q0 base
⊢
let p0, m′ ≔ k0base in
let e, locals ≔ p0 in
c_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ e; fr_locals ≔ locals; fr_doomed ≔ sndp; fr_at ≔ Execl l0 j; c_callers ≔ c_callersc; c_mem ≔ m′; c_fuel ≔ c_fuelc
=
r_base ≔ base; r_end ≔ base + req_extentq0; r_kind ≔ req_kindq0; r_life ≔ Live :: m_regionsc_memc

match goal withHk : m_regionssnd?t = _ |- _⇒destruct t as e1 l1 m1end

ge :
l :
j :
i :
l0 :
listinst
Heqp :
fr_atc_framec = Execl i :: l0 j
Heqo :
let* why ≔ fr_doomedc_framec in
else
Somewhy
=
None
k0 :
Z → env × listname × optionZ × mem
Heqo0 :
inst_stepge c_framec c_memc i = SomeIFreshq0 k0
p :
inst_out × optionreason
Heqo1 :
doomed_resultge c_framec c_memc i IFreshq0 k0 = Somep
base :
Z
Ho :
fstp = IFreshq0 k0
e1 :
l1 :
listname × optionZ
m1 :
Hk :
m_regionssnde1, l1, m1 = m_regionsallocatedc_memc q0 base
⊢
m_regionsc_memc_frame ≔ fr_fn ≔ fr_fnc_framec; fr_env ≔ e1; fr_locals ≔ l1; fr_doomed ≔ sndp; fr_at ≔ Execl l0 j; c_callers ≔ c_callersc; c_mem ≔ m1; c_fuel ≔ c_fuelc = r_base ≔ base; r_end ≔ base + req_extentq0; r_kind ≔ req_kindq0; r_life ≔ Live :: m_regionsc_memc

exact Hk

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
unfold step , inst_next
intros ge c q k H
cases H ; unstuck H ; try exfalso ; exact jump_step_not_fresh_ _ _ _ _ _ H
all: injection H as Hq Hk ; subst q k ; intros base
–match goal withHp : fr_at_ = Snapshot?xs _ |- _⇒exact snapshot_values_regionsxs base _end
–match goal withE : doomed_result_ _ _ _ _ = Some?od , Hc : fst?od = IFresh_ _ |- _⇒destruct doomed_result_out_ _ _ _ _ _ E as Ho | e′ & l′ & Ho | o′ & Ho ; rewrite Ho in Hc ; try discriminate Hcend
subst
match goal withE2 : inst_step_ _ _ _ = SomeIFresh_ ?k0 |- _⇒pose proof inst_step_fresh_regions_ _ _ _ _ _ E2 base as Hkend
simpl
match goal withHk : m_regionssnd?t = _ |- _⇒destruct t as e1 l1 m1end
exact Hk

A check that passed passes again, or its object was freed

Where an access check of a nonempty range (size bytes at address a, through the capability c, with rights r and alignment al) passed in memory m, it passes the same way in any memory m' that persists from m, or traps out of bounds because the object was freed. This is what makes it sound to reuse a check.

335Lemma persists_access
∀ m m′ a c size r al u
persistsm m′
0 < size
access_resm a c size r al = SomeRValu
access_resm′ a c size r al = SomeRValu ∨ access_resm′ a c size r al = SomeRTrapOutOfBounds
Explore proof 3 tactics

Initial goal

⊢
∀m m′ : mem a : Z c : cap size : Z r : rights al : Z u : unit, persistsm m′ → 0 < size → access_resm a c size r al = SomeRValu → access_resm′ a c size r al = SomeRValu ∨ access_resm′ a c size r al = SomeRTrapOutOfBounds

unfold access_res , cap_access_res

⊢
∀ m m′ : mem a : Z c : cap size : Z r : rights al : Z u : unit  ,
persistsm m′
→
0 < size
→
match c with
Objbase
⇒
let* reg ≔ object_regionbase m_regionsm in
Some
base ≤? a && a + size ≤? r_endreg
→
Robase
⇒
let* reg ≔ object_regionbase m_regionsm in
Some
base ≤? a && a + size ≤? r_endreg
→
⇒
None
=
SomeRValu
→
match c with
Objbase
⇒
let* reg ≔ object_regionbase m_regionsm′ in
Some
base ≤? a && a + size ≤? r_endreg
→
Robase
⇒
let* reg ≔ object_regionbase m_regionsm′ in
Some
base ≤? a && a + size ≤? r_endreg
→
⇒
None
=
SomeRValu
∨
match c with
Objbase
⇒
let* reg ≔ object_regionbase m_regionsm′ in
Some
base ≤? a && a + size ≤? r_endreg
→
Robase
⇒
let* reg ≔ object_regionbase m_regionsm′ in
Some
base ≤? a && a + size ≤? r_endreg
→
⇒
None
=

intros m m′ a c size r al u Hp Hs H

m, m′ :
a :
Z
c :
size :
Z
al :
Z
u :
unit
Hp :
persistsm m′
Hs :
0 < size
H :
match c with
Objbase
⇒
let* reg ≔ object_regionbase m_regionsm in
Some
base ≤? a && a + size ≤? r_endreg
→
Robase
⇒
let* reg ≔ object_regionbase m_regionsm in
Some
base ≤? a && a + size ≤? r_endreg
→
⇒
None
=
SomeRValu
⊢
match c with
Objbase
⇒
let* reg ≔ object_regionbase m_regionsm′ in
Some
base ≤? a && a + size ≤? r_endreg
→
Robase
⇒
let* reg ≔ object_regionbase m_regionsm′ in
Some
base ≤? a && a + size ≤? r_endreg
→
⇒
None
=
SomeRValu
∨
match c with
Objbase
⇒
let* reg ≔ object_regionbase m_regionsm′ in
Some
base ≤? a && a + size ≤? r_endreg
→
Robase
⇒
let* reg ≔ object_regionbase m_regionsm′ in
Some
base ≤? a && a + size ≤? r_endreg
→
⇒
None
=

destruct c as | base | base | f | n ; try discriminate H ; destruct object_regionbase m_regionsm as reg | eqn: E ; try discriminate H ; destruct Hp_ _ E as E′ | E′ ; rewrite E' ; left ; exact H | right | left ; exact H | right ; pose proof object_region_base_ _ _ E as Hb ; simpl ; rewrite Hb ; destruct base ≤? a && a + size ≤? base eqn: Eb ; try reflexivity ; apply andb_true_iff in Eb as E1 E2 ; apply Z.leb_le in E1 ; apply Z.leb_le in E2 ; lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m m′ a c size r al u Hp Hs H
destruct c as | base | base | f | n ; try discriminate H ; destruct object_regionbase m_regionsm as reg | eqn: E ; try discriminate H ; destruct Hp_ _ E as E′ | E′ ; rewrite E' ; left ; exact H | right | left ; exact H | right ; pose proof object_region_base_ _ _ E as Hb ; simpl ; rewrite Hb ; destruct base ≤? a && a + size ≤? base eqn: Eb ; try reflexivity ; apply andb_true_iff in Eb as E1 E2 ; apply Z.leb_le in E1 ; apply Z.leb_le in E2 ; lia

Over runs

Over the runs of Machine R, for any runtime R: each step from a ready state, and so each run that starts ready, persists memory.

353Module Identity R : Runtime
355Module RM ≔ Machine R
Import RM

R's free keeps every identity, by the runtime axiom free_keeps_ids: free reclaims nothing; only the collector does, at a safepoint.

361Lemma R_free_ids
free_idsR.free
Explore proof 5 tactics

Initial goal

⊢
free_idsR.free

intros x m r m′ H b reg Hb

x :
m :
r :
resunit
m′ :
H :
R.freex m = Somer, m′
b :
Z
reg :
Hb :
⊢
∃reg′ : region, object_regionb m_regionsm′ = Somereg′

pose proof R.free_keeps_ids_ _ _ _ H b as Hk

x :
m :
r :
resunit
m′ :
H :
R.freex m = Somer, m′
b :
Z
reg :
Hb :
Hk :
object_regionb m_regionsm ≠ None → object_regionb m_regionsm′ ≠ None
⊢
∃reg′ : region, object_regionb m_regionsm′ = Somereg′

destruct object_regionb m_regionsm′ as reg′ | ; eauto |

x :
m :
r :
resunit
m′ :
H :
R.freex m = Somer, m′
b :
Z
reg :
Hb :
Hk :
object_regionb m_regionsm ≠ None → None ≠ None
⊢
∃reg′ : region, None = Somereg′

exfalso

x :
m :
r :
resunit
m′ :
H :
R.freex m = Somer, m′
b :
Z
reg :
Hb :
Hk :
object_regionb m_regionsm ≠ None → None ≠ None
⊢
False

apply Hk ; rewrite Hb ; discriminate | reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros x m r m′ H b reg Hb
pose proof R.free_keeps_ids_ _ _ _ H b as Hk
destruct object_regionb m_regionsm′ as reg′ | ; eauto |
exfalso
apply Hk ; rewrite Hb ; discriminate | reflexivity

Each machine step (mstep) from a state where R is ready (ready_state) persists memory, where the genv's free is R's: a step that allocates nothing ends objects in place, an allocation adds one at a fresh base, and R's safepoint action keeps every identity (rooting).

373Theorem mstep_persists
∀ ge st st′
ge_freege = R.free
mstepge st st′
persistsc_memfstst c_memfstst′
Explore proof 17 tactics

Initial goal

⊢
∀ge : genv st st′ : mstate, ge_freege = R.free → ready_statest → mstepge st st′ → persistsc_memfstst c_memfstst′

unfold ready_state

⊢
∀ge : genv st st′ : mstate, ge_freege = R.free → R.readysndst c_memfstst → mstepge st st′ → persistsc_memfstst c_memfstst′

intros ge st st′ Hge Hr Hs

ge :
st, st′ :
Hge :
ge_freege = R.free
Hr :
R.readysndst c_memfstst
Hs :
mstepge st st′
⊢
persistsc_memfstst c_memfstst′

destruct Hs as c c′ s E | c q k s base s′ E He Hal | c s s′ m′ _ Hsp ; simpl in *

3 open

ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
c′ :
E :
stepge c = Nextc′
focused goal
ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
k :
Z → config
base :
Z
s′ :
R.state
E :
stepge c = Freshq k
He :
0 ≤ req_extentq
Hal :
R.allocs q = Somebase, s′
focused goal
ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
s′ :
R.state
m′ :
Hsp :
R.safepoints c_memc s′ m′
⊢

–apply kept_ids_persists

4 open

ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
c′ :
E :
stepge c = Nextc′
focused goal
ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
c′ :
E :
stepge c = Nextc′
⊢
deferred goal
ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
k :
Z → config
base :
Z
s′ :
R.state
E :
stepge c = Freshq k
He :
0 ≤ req_extentq
Hal :
R.allocs q = Somebase, s′
deferred goal
ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
s′ :
R.state
m′ :
Hsp :
R.safepoints c_memc s′ m′
⊢

+eapply step_next_kept ; rewrite Hge ; exact free_kept | exact E

3 open

deferred goal
ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
c′ :
E :
stepge c = Nextc′
⊢
deferred goal
ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
k :
Z → config
base :
Z
s′ :
R.state
E :
stepge c = Freshq k
He :
0 ≤ req_extentq
Hal :
R.allocs q = Somebase, s′
deferred goal
ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
s′ :
R.state
m′ :
Hsp :
R.safepoints c_memc s′ m′
⊢

+eapply step_next_ids ; rewrite Hge ; exact R_free_ids | exact E

2 open

deferred goal
ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
k :
Z → config
base :
Z
s′ :
R.state
E :
stepge c = Freshq k
He :
0 ≤ req_extentq
Hal :
R.allocs q = Somebase, s′
deferred goal
ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
s′ :
R.state
m′ :
Hsp :
R.safepoints c_memc s′ m′
⊢

–destruct step_fresh_kept_ _ _ _ E as Ha _

2 open

ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
k :
Z → config
base :
Z
s′ :
R.state
E :
stepge c = Freshq k
He :
0 ≤ req_extentq
Hal :
R.allocs q = Somebase, s′
Ha :
0 < req_alignq
deferred goal
ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
s′ :
R.state
m′ :
Hsp :
R.safepoints c_memc s′ m′
⊢

destruct R.fresh_allocation_ _ _ _ _ Hr Ha He Hal as _ & _ & _ & Hnone & _ _

2 open

ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
k :
Z → config
base :
Z
s′ :
R.state
E :
stepge c = Freshq k
He :
0 ≤ req_extentq
Hal :
R.allocs q = Somebase, s′
Ha :
0 < req_alignq
Hnone :
deferred goal
ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
s′ :
R.state
m′ :
Hsp :
R.safepoints c_memc s′ m′
⊢

eapply persists_trans ; exact allocated_persists_ q _ Hnone |

2 open

ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
k :
Z → config
base :
Z
s′ :
R.state
E :
stepge c = Freshq k
He :
0 ≤ req_extentq
Hal :
R.allocs q = Somebase, s′
Ha :
0 < req_alignq
Hnone :
deferred goal
ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
s′ :
R.state
m′ :
Hsp :
R.safepoints c_memc s′ m′
⊢

apply persists_same

2 open

ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
k :
Z → config
base :
Z
s′ :
R.state
E :
stepge c = Freshq k
He :
0 ≤ req_extentq
Hal :
R.allocs q = Somebase, s′
Ha :
0 < req_alignq
Hnone :
deferred goal
ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
s′ :
R.state
m′ :
Hsp :
R.safepoints c_memc s′ m′
⊢

exact step_fresh_regions_ _ _ _ E base

deferred goal
ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
s′ :
R.state
m′ :
Hsp :
R.safepoints c_memc s′ m′
⊢

–apply lifetime_ids_persists ; exact R.safepoint_lifetime_ _ _ _ Hsp |

ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
s′ :
R.state
m′ :
Hsp :
R.safepoints c_memc s′ m′
⊢
idsc_memc m′

intros b reg H

ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
s′ :
R.state
m′ :
Hsp :
R.safepoints c_memc s′ m′
b :
Z
reg :
⊢
∃reg′ : region, object_regionb m_regionsm′ = Somereg′

pose proof R.rooting_ _ _ _ Hsp b as Hroot

ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
s′ :
R.state
m′ :
Hsp :
R.safepoints c_memc s′ m′
b :
Z
reg :
Hroot :
object_regionb m_regionsc_memc ≠ None → object_regionb m_regionsm′ ≠ None
⊢
∃reg′ : region, object_regionb m_regionsm′ = Somereg′

destruct object_regionb m_regionsm′ as reg′ | eqn: E′ ; eauto |

ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
s′ :
R.state
m′ :
Hsp :
R.safepoints c_memc s′ m′
b :
Z
reg :
E′ :
Hroot :
object_regionb m_regionsc_memc ≠ None → None ≠ None
⊢
∃reg′ : region, None = Somereg′

exfalso

ge :
Hge :
ge_freege = R.free
s :
R.state
Hr :
R.readys c_memc
s′ :
R.state
m′ :
Hsp :
R.safepoints c_memc s′ m′
b :
Z
reg :
E′ :
Hroot :
object_regionb m_regionsc_memc ≠ None → None ≠ None
⊢
False

apply Hroot ; rewrite H ; discriminate | reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge st st′ Hge Hr Hs
destruct Hs as c c′ s E | c q k s base s′ E He Hal | c s s′ m′ _ Hsp ; simpl in *
+eapply step_next_kept ; rewrite Hge ; exact free_kept | exact E
+eapply step_next_ids ; rewrite Hge ; exact R_free_ids | exact E
–destruct step_fresh_kept_ _ _ _ E as Ha _
destruct R.fresh_allocation_ _ _ _ _ Hr Ha He Hal as _ & _ & _ & Hnone & _ _
eapply persists_trans ; exact allocated_persists_ q _ Hnone |
exact step_fresh_regions_ _ _ _ E base
–apply lifetime_ids_persists ; exact R.safepoint_lifetime_ _ _ _ Hsp |
intros b reg H
pose proof R.rooting_ _ _ _ Hsp b as Hroot
destruct object_regionb m_regionsm′ as reg′ | eqn: E′ ; eauto |
exfalso
apply Hroot ; rewrite H ; discriminate | reflexivity

Over a run that starts ready, the memory of every later state (mreachable: any number of machine steps) persists from the first: each object is in every later state as it was, or freed.

395Theorem mreachable_persists
∀ ge st st′
ge_freege = R.free
mreachablege st st′
persistsc_memfstst c_memfstst′
Explore proof 5 tactics

Initial goal

⊢
∀ge : genv st st′ : mstate, ge_freege = R.free → mreachablege st st′ → ready_statest → persistsc_memfstst c_memfstst′

intros ge st st′ Hge H

ge :
st, st′ :
Hge :
ge_freege = R.free
H :
mreachablege st st′
⊢
ready_statest → persistsc_memfstst c_memfstst′

induction H as st st′ Hs | st | st1 st2 st3 H12 IH1 _ IH2 ; intros Hr

3 open

ge :
Hge :
ge_freege = R.free
st, st′ :
Hs :
mstepge st st′
⊢
persistsc_memfstst c_memfstst′
focused goal
ge :
Hge :
ge_freege = R.free
st :
⊢
focused goal
ge :
Hge :
ge_freege = R.free
st1, st2, st3 :
H12 :
Relation_Operators.clos_refl_transmstate mstepge st1 st2
IH1 :
ready_statest1 → persistsc_memfstst1 c_memfstst2
IH2 :
ready_statest2 → persistsc_memfstst2 c_memfstst3
⊢
persistsc_memfstst1 c_memfstst3

–eapply mstep_persists ; eauto

2 open

deferred goal
ge :
Hge :
ge_freege = R.free
st :
⊢
deferred goal
ge :
Hge :
ge_freege = R.free
st1, st2, st3 :
H12 :
Relation_Operators.clos_refl_transmstate mstepge st1 st2
IH1 :
ready_statest1 → persistsc_memfstst1 c_memfstst2
IH2 :
ready_statest2 → persistsc_memfstst2 c_memfstst3
⊢
persistsc_memfstst1 c_memfstst3

–apply persists_refl

deferred goal
ge :
Hge :
ge_freege = R.free
st1, st2, st3 :
H12 :
Relation_Operators.clos_refl_transmstate mstepge st1 st2
IH1 :
ready_statest1 → persistsc_memfstst1 c_memfstst2
IH2 :
ready_statest2 → persistsc_memfstst2 c_memfstst3
⊢
persistsc_memfstst1 c_memfstst3

–eapply persists_trans ; exact IH1Hr | apply IH2 ; exact mreachable_ready_ _ _ Hge H12 Hr

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge st st′ Hge H
induction H as st st′ Hs | st | st1 st2 st3 H12 IH1 _ IH2 ; intros Hr
–eapply mstep_persists ; eauto
–apply persists_refl
–eapply persists_trans ; exact IH1Hr | apply IH2 ; exact mreachable_ready_ _ _ Hge H12 Hr

The same for the interpreter's runtime InterpRuntime, which proves every runtime axiom.

409Module InterpIdentity ≔ Identity InterpRuntime

Under the interpreter's runtime, every run that starts ready persists memory, with no hypothesis but that the genv's free is the interpreter's.

414Corollary interp_persists
Explore proof 2 tactics

Initial goal

intros ge st st′ Hge H Hr

exact InterpIdentity.mreachable_persists_ _ _ Hge H Hr

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge st st′ Hge H Hr