Fil-C on Nix

Filnix wiki

the formal campaign

rocq/theories/Single.v

Campaign 3's single-definition invariant over runs (docs/formal.md, Campaign 3; docs/rocq.md, The single-definition invariant).

The reuse forms' rules read relations between the values of names that have one definition each: a flight and its base, a proof and the pointer it checked, a span test or a limit and the pointer it read. Such a relation holds at a point of a run only where the name's definition dominates the point, and only while the definition's operands hold the values it read. This file states that for every frame of every run (sinv), and proves that every machine step keeps it (mreachable_sinv).

At a frame's point, each single definition whose site dominates the point replays (replays): the name holds what its instruction made in some earlier frame and memory, that frame agrees with the current environment on the instruction's single-definition operands, and the current memory persists from the memory the instruction left (Identity.v), which lay in the address space. A check that passed then passes again or traps; a flight's capability is its lower donor's.

Decisions

DecisionWhy
the relation is the instruction's own step, replayedone statement covers every op; each reuse form reads off what it needs from inst_step
the operands a replay fixes are the single definitionsno_use_redefined (Sites.v) keeps exactly those; a name defined twice may change, and no reuse rule follows one
a call and an alloc do not replaytheir step is not one that continues; no reuse rule reads through them
a doomed frame claims nothingits check_ahead did not pass; a doomed frame never returns to a caller or calls one
memory is handled once, for every stepeach step's memory persists (mstep_persists), so the step lemmas carry frames and a replay's memory follows by scope_mem
a replay keeps that the memory it left fit the address space (objects_fit)the object of a check that passed then ended below 2^48; once the object is freed, the current memory no longer says where it ended
free keeps identities by Runtime.v's axiom free_keeps_idsmbrock's decision (docs/rocq.md, Identities persist)
From Stdlib Require Import String ZArith List Bool Lia Relations
From Nanofil Require Import Term Maps Syntax Cfg Values Memory Runtime Ops Semantics Machine Validate Dominance Sites Identity Walk Steps Invariant
Import ListNotations
Open Scope Z_scope

The invariant

The instructions a replay speaks of: a let that is not an alloc, and a flight. Their step continues and defines a name; a call's or an allocation's does not continue with a value, and no reuse rule reads through one.

47Definition replayablei : inst : bool ≔
match i with
Let_ _ Alloc_ _
⇒
false
Let_ _ _ _ | Flight_ _ _ _
⇒
true
_
⇒
false

The name n, defined by the instruction i, replays in the environment e and memory m: in some earlier frame fr0 and memory m0, i's step continued and gave n the value it has in e; fr0 agrees with e on i's single-definition operands (once being the function's single_definitions); and m persists from the memory m1 the step left, whose objects fit the address space (objects_fit).

60Definition replaysge : genv once : listname × def e : env m : Memory.mem n : name i : inst : Prop ≔
∃fr0 m0 e1 l1 m1, inst_stepge fr0 m0 i = SomeIContinuee1 l1 m1 ∧ lookupn e1 = lookupn e ∧ ∀a, Ina inst_usesi → once_hasonce a = true → lookupa fr_envfr0 = lookupa e ∧ persistsm1 m ∧ objects_fitm_regionsm1

The block and index of the point pt of f, as site_dominates/4 reads them: a block's entry is before its phis, at index -1; a snapshot has none.

70Definition point_sitef : func pt : point : optionname × Z ≔
match pt with
⇒
None
⇒
Somel, −1
Execl is _
⇒
match find_blockl fn_blocksf with
Someb
⇒
Somel, Z.of_natlengthb_instsb − lengthis
None
⇒
None

At the point of the frame fr, each replayable single definition (the name n, defined by i at the site s) whose site dominates the point satisfies the property rp in fr's environment and the memory m. scope_holds takes replays for rp; scope_plain a weaker one.

86Definition scope_withrp : listname × def → env → Memory.mem → name → inst → Prop fr : frame m : Memory.mem : Prop ≔
let f ≔ fr_fnfr in
∀l k n s i, point_sitef fr_atfr = Somel, k → lookupn single_definitionsf = SomeDInsti → replayablei = true → Inn, s, DInsti def_positionsf → site_dominatesfn_domsf l k s = true → rpsingle_definitionsf fr_envfr m n i

At the point of the frame fr, each replayable single definition whose site dominates the point replays in fr's environment and the memory m: fr holds its scope.

98Definition scope_holdsge : genv fr : frame m : Memory.mem : Prop ≔

The frame fr runs a function of the module md, at a point of a reachable block: a snapshot that leads to the entry, a block's entry (from no block only at the function's entry), or a suffix of a block's instructions before its jump.

105Definition shapedmd : module fr : frame : Prop ≔
let f ≔ fr_fnfr in
InIFuncf md
∧
match fr_atfr with
⇒
entry_labelf = Somel
Enterl from
⇒
is_reachablefn_domsf l = true ∧ from = None → entry_labelf = Somel
Execl is j
⇒
is_reachablefn_domsf l = true ∧ ∃b k, find_blockl fn_blocksf = Someb ∧ k ≤ lengthb_instsb%nat ∧ is = skipnk b_instsb ∧ j = b_jumpb

The names a call's result r defines.

118Definition result_namesr : call_result : listname ≔
match r with
⇒
[ ]
⇒
d
⇒
mapfst rs

The frame fr is just after a call or raw call whose result is the pending result pd's: it waits for its callee to return.

123Definition waitsfr : frame pd : pending : Prop ≔
∃l rest j b k ci, fr_atfr = Execl rest j ∧ find_blockl fn_blocksfr_fnfr = Someb ∧ nth_errorb_instsb k = Someci ∧ rest = skipnSk b_instsb ∧ ∃cl args, ci = Callpd_respd cl args ∨ ∃cl args, ci = RawCallpd_respd cl args

The running frame fr is shaped and, unless doomed, holds its scope in the memory m.

131Definition runningge : genv md : module m : Memory.mem fr : frame : Prop ≔
shapedmd fr ∧ fr_doomedfr ≠ None ∨ scope_holdsge fr m

A waiting caller fp, its frame and the result it waits for, is shaped, not doomed, just after the call it waits on (waits), and holds its scope in the memory m.

137Definition waitingge : genv md : module m : Memory.mem fp : frame × pending : Prop ≔
shapedmd fstfp ∧ fr_doomedfstfp = None ∧ waitsfstfp sndfp ∧ scope_holdsge fstfp m

The single-definition invariant of a configuration c: in c's memory, the running frame is running and every waiting caller is waiting.

143Definition sinvge : genv md : module c : config : Prop ≔
runningge md c_memc c_framec ∧ Forallwaitingge md c_memc c_callersc

Sites

A name an instruction defines (DInst) is at an instruction's site SAt d j, not at a parameter's (SParam).

150Lemma dinst_site
∀ f n s i
∃d j, s = SAtd j
Explore proof 12 tactics

Initial goal

⊢
∀f : func n : name s : site i : inst, Inn, s, DInsti def_positionsf → ∃d : name j : Z, s = SAtd j

intros f n s i H

f :
n :
s :
i :
H :
⊢
∃d : name j : Z, s = SAtd j

unfold def_positions in H

f :
n :
s :
i :
H :
Inn, s, DInsti mapλp : class × name ⇒ sndp, SParam, DParam fn_paramsf ++ flat_mapblock_positions fn_blocksf
⊢
∃d : name j : Z, s = SAtd j

apply in_app_or in H as H | H

2 open

f :
n :
s :
i :
H :
Inn, s, DInsti mapλp : class × name ⇒ sndp, SParam, DParam fn_paramsf
⊢
∃d : name j : Z, s = SAtd j
focused goal
f :
n :
s :
i :
H :
Inn, s, DInsti flat_mapblock_positions fn_blocksf
⊢
∃d : name j : Z, s = SAtd j

–apply in_map_iff in H as p & E & _

2 open

f :
n :
s :
i :
p :
E :
sndp, SParam, DParam = n, s, DInsti
⊢
∃d : name j : Z, s = SAtd j
deferred goal
f :
n :
s :
i :
H :
Inn, s, DInsti flat_mapblock_positions fn_blocksf
⊢
∃d : name j : Z, s = SAtd j

discriminate E

deferred goal
f :
n :
s :
i :
H :
Inn, s, DInsti flat_mapblock_positions fn_blocksf
⊢
∃d : name j : Z, s = SAtd j

–apply in_flat_map in H as b & _ & H

f :
n :
s :
i :
H :
⊢
∃d : name j : Z, s = SAtd j

unfold block_positions in H

f :
n :
s :
i :
H :
Inn, s, DInsti
map
λ ph : phi  ⇒
match ph with
Phid _ _
⇒
d, SAtb_labelb −1, DPhiph
++
⊢
∃d : name j : Z, s = SAtd j

apply in_app_or in H as H | H

2 open

f :
n :
s :
i :
H :
Inn, s, DInsti
map
λ ph : phi  ⇒
match ph with
Phid _ _
⇒
d, SAtb_labelb −1, DPhiph
⊢
∃d : name j : Z, s = SAtd j
focused goal
⊢
∃d : name j : Z, s = SAtd j

+apply in_map_iff in H as d′ k′ pairs & E & _

2 open

f :
n :
s :
i :
d′ :
k′ :
pairs :
listname × value
E :
d′, SAtb_labelb −1, DPhiPhid′ k′ pairs = n, s, DInsti
⊢
∃d : name j : Z, s = SAtd j
deferred goal
⊢
∃d : name j : Z, s = SAtd j

discriminate E

deferred goal
⊢
∃d : name j : Z, s = SAtd j

+destruct inst_positions_in_ _ _ _ _ _ H as k & i′ & _ & → & _

f :
n :
i :
k :
nat
H :
Inn, SAtb_labelb 0 + Z.of_natk, DInsti inst_positionsb_labelb 0 b_instsb
i′ :
⊢
∃d : name j : Z, SAtb_labelb 0 + Z.of_natk = SAtd j

eauto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros f n s i H
unfold def_positions in H
apply in_app_or in H as H | H
–apply in_map_iff in H as p & E & _
discriminate E
–apply in_flat_map in H as b & _ & H
unfold block_positions in H
apply in_app_or in H as H | H
+apply in_map_iff in H as d′ k′ pairs & E & _
discriminate E
+destruct inst_positions_in_ _ _ _ _ _ H as k & i′ & _ & → & _
eauto

One step on in a block: what dominates index k+1 is index k's instruction, or dominates index k.

161Lemma site_next
∀ doms l k s
site_dominatesdoms l k + 1 s = true
s = SAtl k ∨ site_dominatesdoms l k s = true
Explore proof 13 tactics

Initial goal

⊢
∀doms : nmapZ × Z l : name k : Z s : site, site_dominatesdoms l k + 1 s = true → s = SAtl k ∨ site_dominatesdoms l k s = true

intros doms l k s H

doms :
nmapZ × Z
l :
k :
Z
s :
H :
site_dominatesdoms l k + 1 s = true
⊢
s = SAtl k ∨ site_dominatesdoms l k s = true

destruct s as | d j ; right ; reflexivity |

doms :
nmapZ × Z
l :
k :
Z
d :
j :
Z
H :
site_dominatesdoms l k + 1 SAtd j = true
⊢
SAtd j = SAtl k ∨ site_dominatesdoms l k SAtd j = true

simpl in *

doms :
nmapZ × Z
l :
k :
Z
d :
j :
Z
H :
→
j <? k + 1
else
dominatesdoms d l
=
true
⊢
SAtd j = SAtl k
∨
→
j <? k
else
dominatesdoms d l
=
true

destruct name_eqbd l eqn: E ; | right ; exact H

doms :
nmapZ × Z
l :
k :
Z
d :
j :
Z
E :
name_eqbd l = true
H :
j <? k + 1 = true
⊢
SAtd j = SAtl k ∨ j <? k = true

apply Z.ltb_lt in H

doms :
nmapZ × Z
l :
k :
Z
d :
j :
Z
E :
name_eqbd l = true
H :
j < k + 1
⊢
SAtd j = SAtl k ∨ j <? k = true

destruct Z.eq_decj k as → | Hne

2 open

doms :
nmapZ × Z
l :
k :
Z
d :
E :
name_eqbd l = true
H :
k < k + 1
⊢
SAtd k = SAtl k ∨ k <? k = true
focused goal
doms :
nmapZ × Z
l :
k :
Z
d :
j :
Z
E :
name_eqbd l = true
H :
j < k + 1
Hne :
j ≠ k
⊢
SAtd j = SAtl k ∨ j <? k = true

–left

2 open

doms :
nmapZ × Z
l :
k :
Z
d :
E :
name_eqbd l = true
H :
k < k + 1
⊢
SAtd k = SAtl k
deferred goal
doms :
nmapZ × Z
l :
k :
Z
d :
j :
Z
E :
name_eqbd l = true
H :
j < k + 1
Hne :
j ≠ k
⊢
SAtd j = SAtl k ∨ j <? k = true

apply name_eqb_true in E

2 open

doms :
nmapZ × Z
l :
k :
Z
d :
E :
d = l
H :
k < k + 1
⊢
SAtd k = SAtl k
deferred goal
doms :
nmapZ × Z
l :
k :
Z
d :
j :
Z
E :
name_eqbd l = true
H :
j < k + 1
Hne :
j ≠ k
⊢
SAtd j = SAtl k ∨ j <? k = true

subst

2 open

doms :
nmapZ × Z
l :
k :
Z
H :
k < k + 1
⊢
SAtl k = SAtl k
deferred goal
doms :
nmapZ × Z
l :
k :
Z
d :
j :
Z
E :
name_eqbd l = true
H :
j < k + 1
Hne :
j ≠ k
⊢
SAtd j = SAtl k ∨ j <? k = true

reflexivity

deferred goal
doms :
nmapZ × Z
l :
k :
Z
d :
j :
Z
E :
name_eqbd l = true
H :
j < k + 1
Hne :
j ≠ k
⊢
SAtd j = SAtl k ∨ j <? k = true

–right

doms :
nmapZ × Z
l :
k :
Z
d :
j :
Z
E :
name_eqbd l = true
H :
j < k + 1
Hne :
j ≠ k
⊢
j <? k = true

apply Z.ltb_lt

doms :
nmapZ × Z
l :
k :
Z
d :
j :
Z
E :
name_eqbd l = true
H :
j < k + 1
Hne :
j ≠ k
⊢
j < k

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros doms l k s H
destruct s as | d j ; right ; reflexivity |
simpl in *
destruct name_eqbd l eqn: E ; | right ; exact H
apply Z.ltb_lt in H
destruct Z.eq_decj k as → | Hne
–left
apply name_eqb_true in E
subst
reflexivity
–right
apply Z.ltb_lt
lia

An instruction's site dominates a block's first instruction where it dominates the block's entry.

173Lemma site_first
∀ f doms l n s i
site_dominatesdoms l 0 s = true
site_dominatesdoms l −1 s = true
Explore proof 5 tactics

Initial goal

⊢
∀f : func doms : nmapZ × Z l n : name s : site i : inst, Inn, s, DInsti def_positionsf → site_dominatesdoms l 0 s = true → site_dominatesdoms l −1 s = true

intros f doms l n s i Hp H

f :
doms :
nmapZ × Z
l, n :
s :
i :
Hp :
H :
site_dominatesdoms l 0 s = true
⊢
site_dominatesdoms l −1 s = true

destruct dinst_site_ _ _ _ Hp as d & j & →

f :
doms :
nmapZ × Z
l, n :
i :
d :
j :
Z
H :
site_dominatesdoms l 0 SAtd j = true
Hp :
⊢
site_dominatesdoms l −1 SAtd j = true

destruct position_inst_ _ _ _ _ Hp as b & kk & _ & _ & _ & → & _

f :
doms :
nmapZ × Z
l, n :
i :
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
H :
site_dominatesdoms l 0 SAtd Z.of_natkk = true
⊢
site_dominatesdoms l −1 SAtd Z.of_natkk = true

simpl in *

f :
doms :
nmapZ × Z
l, n :
i :
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
H :
→
Z.of_natkk <? 0
else
dominatesdoms d l
=
true
⊢
→
Z.of_natkk <? −1
else
dominatesdoms d l
=
true

destruct name_eqbd l ; apply Z.ltb_lt in H ; lia | exact H

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros f doms l n s i Hp H
destruct dinst_site_ _ _ _ Hp as d & j & →
destruct position_inst_ _ _ _ _ Hp as b & kk & _ & _ & _ & → & _
simpl in *
destruct name_eqbd l ; apply Z.ltb_lt in H ; lia | exact H

Across an edge from a reachable block p: what dominates the entry of s dominated the end of p.

184Lemma site_edge
∀ f b0 rest doms bp l n s i
fn_blocksf = b0 :: rest
block_intervalsb0 :: rest = Somedoms
is_reachabledoms b_labelbp = true
site_dominatesdoms l −1 s = true
site_dominatesdoms b_labelbp Z.of_natlengthb_instsbp s = true
Explore proof 21 tactics

Initial goal

⊢
∀f : func b0 : block rest : listblock doms : nmapZ × Z bp : block l n : name s : site i : inst, fn_blocksf = b0 :: rest → block_intervalsb0 :: rest = Somedoms → no_dupsmapb_label fn_blocksf = true → find_blockb_labelbp fn_blocksf = Somebp → is_reachabledoms b_labelbp = true → Inl jump_succsb_jumpbp → Inn, s, DInsti def_positionsf → site_dominatesdoms l −1 s = true → site_dominatesdoms b_labelbp Z.of_natDatatypes.lengthb_instsbp s = true

intros f b0 rest doms bp l n s i Hf Hd Hnd Hbp Hr Hl Hp H

f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
s :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
Hbp :
Hr :
is_reachabledoms b_labelbp = true
Hp :
H :
site_dominatesdoms l −1 s = true
⊢
site_dominatesdoms b_labelbp Z.of_natDatatypes.lengthb_instsbp s = true

destruct dinst_site_ _ _ _ Hp as d & j & →

f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
j :
Z
H :
site_dominatesdoms l −1 SAtd j = true
Hp :
⊢
site_dominatesdoms b_labelbp Z.of_natDatatypes.lengthb_instsbp SAtd j = true

destruct position_inst_ _ _ _ _ Hp as b & kk & Hb & Hlb & Hk & → & _

f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
H :
site_dominatesdoms l −1 SAtd Z.of_natkk = true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsb kk = Somei
⊢
site_dominatesdoms b_labelbp Z.of_natDatatypes.lengthb_instsbp SAtd Z.of_natkk = true

simpl in *

f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
H :
→
Z.of_natkk <? −1
else
dominatesdoms d l
=
true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsb kk = Somei
⊢
→
Z.of_natkk <? Z.of_natDatatypes.lengthb_instsbp
else
=
true

destruct name_eqbd l eqn: Edl ; apply Z.ltb_lt in H ; lia |

f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
Edl :
name_eqbd l = false
H :
dominatesdoms d l = true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsb kk = Somei
⊢
→
Z.of_natkk <? Z.of_natDatatypes.lengthb_instsbp
else
=
true

assert He : edgeb0 :: rest b_labelbp l

2 open

f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
Edl :
name_eqbd l = false
H :
dominatesdoms d l = true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsb kk = Somei
⊢
edgeb0 :: rest b_labelbp l
focused goal
f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
Edl :
name_eqbd l = false
H :
dominatesdoms d l = true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsb kk = Somei
He :
edgeb0 :: rest b_labelbp l
⊢
→
Z.of_natkk <? Z.of_natDatatypes.lengthb_instsbp
else
=
true

{exists bp

2 open

f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
Edl :
name_eqbd l = false
H :
dominatesdoms d l = true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsb kk = Somei
⊢
Inbp b0 :: rest ∧ b_labelbp = b_labelbp ∧ Inl jump_succsb_jumpbp
deferred goal
f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
Edl :
name_eqbd l = false
H :
dominatesdoms d l = true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsb kk = Somei
He :
edgeb0 :: rest b_labelbp l
⊢
→
Z.of_natkk <? Z.of_natDatatypes.lengthb_instsbp
else
=
true

rewrite <- Hf

2 open

f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
Edl :
name_eqbd l = false
H :
dominatesdoms d l = true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsb kk = Somei
⊢
Inbp fn_blocksf ∧ b_labelbp = b_labelbp ∧ Inl jump_succsb_jumpbp
deferred goal
f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
Edl :
name_eqbd l = false
H :
dominatesdoms d l = true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsb kk = Somei
He :
edgeb0 :: rest b_labelbp l
⊢
→
Z.of_natkk <? Z.of_natDatatypes.lengthb_instsbp
else
=
true

split ; exact proj1find_block_in_ _ _ Hbp | auto

deferred goal
f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
Edl :
name_eqbd l = false
H :
dominatesdoms d l = true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsb kk = Somei
He :
edgeb0 :: rest b_labelbp l
⊢
→
Z.of_natkk <? Z.of_natDatatypes.lengthb_instsbp
else
=
true

rewrite Hf in Hnd

f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
no_dupsmapb_label b0 :: rest = true
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
Edl :
name_eqbd l = false
H :
dominatesdoms d l = true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsb kk = Somei
He :
edgeb0 :: rest b_labelbp l
⊢
→
Z.of_natkk <? Z.of_natDatatypes.lengthb_instsbp
else
=
true

destruct dom_edge_ _ _ Hd _ _ _ Hnd Hr He H as E | Hdp

2 open

f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
no_dupsmapb_label b0 :: rest = true
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
Edl :
name_eqbd l = false
H :
dominatesdoms d l = true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsb kk = Somei
He :
edgeb0 :: rest b_labelbp l
E :
d = l
⊢
→
Z.of_natkk <? Z.of_natDatatypes.lengthb_instsbp
else
=
true
focused goal
f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
no_dupsmapb_label b0 :: rest = true
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
Edl :
name_eqbd l = false
H :
dominatesdoms d l = true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsb kk = Somei
He :
edgeb0 :: rest b_labelbp l
Hdp :
dominatesdoms d b_labelbp = true
⊢
→
Z.of_natkk <? Z.of_natDatatypes.lengthb_instsbp
else
=
true

–subst d

2 open

f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
no_dupsmapb_label b0 :: rest = true
Hbp :
Hr :
is_reachabledoms b_labelbp = true
kk :
nat
H :
dominatesdoms b_labelb l = true
Edl :
name_eqbb_labelb l = false
Hp :
Inn, SAtb_labelb Z.of_natkk, DInsti def_positionsf
Hb :
Hk :
nth_errorb_instsb kk = Somei
He :
edgeb0 :: rest b_labelbp l
E :
b_labelb = l
⊢
→
Z.of_natkk <? Z.of_natDatatypes.lengthb_instsbp
=
true
deferred goal
f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
no_dupsmapb_label b0 :: rest = true
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
Edl :
name_eqbd l = false
H :
dominatesdoms d l = true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsb kk = Somei
He :
edgeb0 :: rest b_labelbp l
Hdp :
dominatesdoms d b_labelbp = true
⊢
→
Z.of_natkk <? Z.of_natDatatypes.lengthb_instsbp
else
=
true

apply name_eqb_false in Edl

2 open

f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
no_dupsmapb_label b0 :: rest = true
Hbp :
Hr :
is_reachabledoms b_labelbp = true
kk :
nat
H :
dominatesdoms b_labelb l = true
Edl :
b_labelb ≠ l
Hp :
Inn, SAtb_labelb Z.of_natkk, DInsti def_positionsf
Hb :
Hk :
nth_errorb_instsb kk = Somei
He :
edgeb0 :: rest b_labelbp l
E :
b_labelb = l
⊢
→
Z.of_natkk <? Z.of_natDatatypes.lengthb_instsbp
=
true
deferred goal
f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
no_dupsmapb_label b0 :: rest = true
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
Edl :
name_eqbd l = false
H :
dominatesdoms d l = true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsb kk = Somei
He :
edgeb0 :: rest b_labelbp l
Hdp :
dominatesdoms d b_labelbp = true
⊢
→
Z.of_natkk <? Z.of_natDatatypes.lengthb_instsbp
else
=
true

contradiction

deferred goal
f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
no_dupsmapb_label b0 :: rest = true
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
Edl :
name_eqbd l = false
H :
dominatesdoms d l = true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsb kk = Somei
He :
edgeb0 :: rest b_labelbp l
Hdp :
dominatesdoms d b_labelbp = true
⊢
→
Z.of_natkk <? Z.of_natDatatypes.lengthb_instsbp
else
=
true

–destruct name_eqbd b_labelbp eqn: E ; | exact Hdp

f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
no_dupsmapb_label b0 :: rest = true
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
Edl :
name_eqbd l = false
H :
dominatesdoms d l = true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsb kk = Somei
He :
edgeb0 :: rest b_labelbp l
Hdp :
dominatesdoms d b_labelbp = true
E :
name_eqbd b_labelbp = true
⊢
Z.of_natkk <? Z.of_natDatatypes.lengthb_instsbp = true

apply name_eqb_true in E

f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
no_dupsmapb_label b0 :: rest = true
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
Edl :
name_eqbd l = false
H :
dominatesdoms d l = true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsb kk = Somei
He :
edgeb0 :: rest b_labelbp l
Hdp :
dominatesdoms d b_labelbp = true
E :
d = b_labelbp
⊢
Z.of_natkk <? Z.of_natDatatypes.lengthb_instsbp = true

rewrite <- Hf in Hnd

f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
Edl :
name_eqbd l = false
H :
dominatesdoms d l = true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsb kk = Somei
He :
edgeb0 :: rest b_labelbp l
Hdp :
dominatesdoms d b_labelbp = true
E :
d = b_labelbp
⊢
Z.of_natkk <? Z.of_natDatatypes.lengthb_instsbp = true

rewrite find_block_unique_ _ _ _ Hnd Hbp Hb eq_transHlb E in Hk

f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
Edl :
name_eqbd l = false
H :
dominatesdoms d l = true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsbp kk = Somei
He :
edgeb0 :: rest b_labelbp l
Hdp :
dominatesdoms d b_labelbp = true
E :
d = b_labelbp
⊢
Z.of_natkk <? Z.of_natDatatypes.lengthb_instsbp = true

assert Hlt : kk < lengthb_instsbp%nat by apply nth_error_Some ; rewrite Hk ; discriminate

f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
Edl :
name_eqbd l = false
H :
dominatesdoms d l = true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsbp kk = Somei
He :
edgeb0 :: rest b_labelbp l
Hdp :
dominatesdoms d b_labelbp = true
E :
d = b_labelbp
Hlt :
kk < Datatypes.lengthb_instsbp%nat
⊢
Z.of_natkk <? Z.of_natDatatypes.lengthb_instsbp = true

apply Z.ltb_lt

f :
b0 :
rest :
listblock
doms :
nmapZ × Z
bp :
l, n :
i :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somedoms
Hnd :
Hbp :
Hr :
is_reachabledoms b_labelbp = true
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
Edl :
name_eqbd l = false
H :
dominatesdoms d l = true
Hb :
Hlb :
b_labelb = d
Hk :
nth_errorb_instsbp kk = Somei
He :
edgeb0 :: rest b_labelbp l
Hdp :
dominatesdoms d b_labelbp = true
E :
d = b_labelbp
Hlt :
kk < Datatypes.lengthb_instsbp%nat
⊢
Z.of_natkk < Z.of_natDatatypes.lengthb_instsbp

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros f b0 rest doms bp l n s i Hf Hd Hnd Hbp Hr Hl Hp H
destruct dinst_site_ _ _ _ Hp as d & j & →
destruct position_inst_ _ _ _ _ Hp as b & kk & Hb & Hlb & Hk & → & _
simpl in *
destruct name_eqbd l eqn: Edl ; apply Z.ltb_lt in H ; lia |
assert He : edgeb0 :: rest b_labelbp l
{exists bp
rewrite <- Hf
split ; exact proj1find_block_in_ _ _ Hbp | auto
rewrite Hf in Hnd
destruct dom_edge_ _ _ Hd _ _ _ Hnd Hr He H as E | Hdp
–subst d
apply name_eqb_false in Edl
contradiction
–destruct name_eqbd b_labelbp eqn: E ; | exact Hdp
apply name_eqb_true in E
rewrite <- Hf in Hnd
rewrite find_block_unique_ _ _ _ Hnd Hbp Hb eq_transHlb E in Hk
assert Hlt : kk < lengthb_instsbp%nat by apply nth_error_Some ; rewrite Hk ; discriminate
apply Z.ltb_lt
lia

What a step changes in the environment

Putting d leaves the value of every name a not among d :: ds.

211Lemma lookup_put_not
∀ A : Type a d v : A ds e
¬Ina d :: ds
lookupa putd v e = lookupa e
Explore proof 9 tactics

Initial goal

⊢
∀A : Type a d : name v : A ds : listname e : listname × A, ¬Ina d :: ds → lookupa putd v e = lookupa e

intros A a d v ds e H

A :
Type
a, d :
v :
A
ds :
listname
e :
listname × A
H :
¬Ina d :: ds
⊢
lookupa putd v e = lookupa e

rewrite lookup_put

A :
Type
a, d :
v :
A
ds :
listname
e :
listname × A
H :
¬Ina d :: ds
⊢
→
Somev
else
=

destruct name_eqba d eqn: E ; | reflexivity

A :
Type
a, d :
v :
A
ds :
listname
e :
listname × A
H :
¬Ina d :: ds
E :
name_eqba d = true
⊢
Somev = lookupa e

apply name_eqb_true in E

A :
Type
a, d :
v :
A
ds :
listname
e :
listname × A
H :
¬Ina d :: ds
E :
a = d
⊢
Somev = lookupa e

subst

A :
Type
d :
v :
A
ds :
listname
e :
listname × A
H :
¬Ind d :: ds
⊢
Somev = lookupd e

exfalso

A :
Type
d :
v :
A
ds :
listname
e :
listname × A
H :
¬Ind d :: ds
⊢
False

apply H

A :
Type
d :
v :
A
ds :
listname
e :
listname × A
H :
¬Ind d :: ds
⊢
Ind d :: ds

left

A :
Type
d :
v :
A
ds :
listname
e :
listname × A
H :
¬Ind d :: ds
⊢
d = d

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros A a d v ds e H
rewrite lookup_put
destruct name_eqba d eqn: E ; | reflexivity
apply name_eqb_true in E
subst
exfalso
apply H
left
reflexivity

An instruction that continues changes only the names it defines (inst_temp_defs).

219Lemma inst_step_env
∀ ge fr m i e1 l1 m1 a
inst_stepge fr m i = SomeIContinuee1 l1 m1
¬Ina mapfst inst_temp_defsi
lookupa e1 = lookupa fr_envfr
Explore proof 4 tactics

Initial goal

⊢
∀ge : genv fr : frame m : Memory.mem i : inst e1 : env l1 : listname × optionZ m1 : Memory.mem, inst_stepge fr m i = SomeIContinuee1 l1 m1 → ∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa e1 = lookupa fr_envfr

intros ge fr m i e1 l1 m1 H a Ha

ge :
fr :
m :
Memory.mem
i :
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
H :
inst_stepge fr m i = SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsi
⊢
lookupa e1 = lookupa fr_envfr

destruct i

9 open

ge :
fr :
m :
Memory.mem
d :
o :
args :
listvalue
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
H :
inst_stepge fr m Letd k o args = SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsLetd k o args
⊢
lookupa e1 = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
d :
o :
args :
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
H :
inst_stepge fr m Flightd o args lower = SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsFlightd o args lower
⊢
lookupa e1 = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
off :
Z
v, a0 :
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
H :
inst_stepge fr m RawStorew off v a0 = SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsRawStorew off v a0
⊢
lookupa e1 = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
off :
Z
v, a0 :
es :
listeffect
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
H :
inst_stepge fr m RawStorePointeroff v a0 es = SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsRawStorePointeroff v a0 es
⊢
lookupa e1 = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
callee :
args :
listarg
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
H :
inst_stepge fr m Callr callee args = SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsCallr callee args
⊢
lookupa e1 = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
callee :
args :
listarg
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
H :
inst_stepge fr m RawCallr callee args = SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsRawCallr callee args
⊢
lookupa e1 = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
x :
size :
Z
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
H :
inst_stepge fr m LocalAllocx size = SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsLocalAllocx size
⊢
lookupa e1 = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
file :
line :
Z
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
H :
inst_stepge fr m Locfile line = SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsLocfile line
⊢
lookupa e1 = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
q :
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
H :
inst_stepge fr m Touchq = SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsTouchq
⊢
lookupa e1 = lookupa fr_envfr

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

12 open

ge :
fr :
m :
Memory.mem
d :
x :
off, bytes :
Z
align :
Z
args :
listvalue
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
H :
inst_stepge fr m Letd k CheckLocalx off bytes r align args = SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsLetd k CheckLocalx off bytes r align args
Es :
special_letCheckLocalx off bytes r align = true
⊢
lookupa e1 = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
d :
args :
listvalue
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
H :
inst_stepge fr m Letd k CheckFunction args = SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsLetd k CheckFunction args
⊢
lookupa e1 = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
d :
args :
listvalue
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
H :
inst_stepge fr m Letd k VaArgs args = SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsLetd k VaArgs args
Es :
⊢
lookupa e1 = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
d :
o :
args :
listvalue
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
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
=
SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsLetd k o args
Es :
special_leto = false
⊢
lookupa e1 = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
d :
o :
args :
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
H :
inst_stepge fr m Flightd o args lower = SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsFlightd o args lower
⊢
lookupa e1 = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
off :
Z
v, a0 :
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
H :
inst_stepge fr m RawStorew off v a0 = SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsRawStorew off v a0
⊢
lookupa e1 = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
off :
Z
v, a0 :
es :
listeffect
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
H :
inst_stepge fr m RawStorePointeroff v a0 es = SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsRawStorePointeroff v a0 es
⊢
lookupa e1 = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
callee :
args :
listarg
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
H :
inst_stepge fr m Callr callee args = SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsCallr callee args
⊢
lookupa e1 = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
callee :
args :
listarg
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
H :
inst_stepge fr m RawCallr callee args = SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsRawCallr callee args
⊢
lookupa e1 = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
x :
size :
Z
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
H :
inst_stepge fr m LocalAllocx size = SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsLocalAllocx size
⊢
lookupa e1 = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
file :
line :
Z
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
H :
inst_stepge fr m Locfile line = SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsLocfile line
⊢
lookupa e1 = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
q :
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
H :
inst_stepge fr m Touchq = SomeIContinuee1 l1 m1
a :
Ha :
¬Ina mapfst inst_temp_defsTouchq
⊢
lookupa e1 = lookupa fr_envfr

all: simpl in Ha ; unfold inst_step , external_call , bind_res , store_out in H ; cases H ; inversion H ; subst ; first reflexivity | exact lookup_put_not_ _ _ _ [ ] _ Ha

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge fr m i e1 l1 m1 H a Ha
destruct i
1: destruct special_leto eqn: Es ; destruct o ; try discriminate Es | rewrite inst_step_let_ _ _ _ _ _ _ Es in H
all: simpl in Ha ; unfold inst_step , external_call , bind_res , store_out in H ; cases H ; inversion H ; subst ; first reflexivity | exact lookup_put_not_ _ _ _ [ ] _ Ha

An allocation's continuation changes only the names it defines.

231Lemma inst_step_fresh_env
∀ ge fr m i q k base a
inst_stepge fr m i = SomeIFreshq k
¬Ina mapfst inst_temp_defsi
lookupa fstfstkbase = lookupa fr_envfr
Explore proof 5 tactics

Initial goal

⊢
∀ge : genv fr : frame m : Memory.mem i : inst q : alloc_req k : Z → env × listname × optionZ × Memory.mem, inst_stepge fr m i = SomeIFreshq k → ∀base : Z a : name, ¬Ina mapfst inst_temp_defsi → lookupa fstfstkbase = lookupa fr_envfr

intros ge fr m i q k H base a Ha

ge :
fr :
m :
Memory.mem
i :
k :
Z → env × listname × optionZ × Memory.mem
H :
inst_stepge fr m i = SomeIFreshq k
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsi
⊢
lookupa fstfstkbase = lookupa fr_envfr

destruct i

9 open

ge :
fr :
m :
Memory.mem
d :
k0 :
o :
args :
listvalue
k :
Z → env × listname × optionZ × Memory.mem
H :
inst_stepge fr m Letd k0 o args = SomeIFreshq k
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsLetd k0 o args
⊢
lookupa fstfstkbase = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
d :
o :
args :
k :
Z → env × listname × optionZ × Memory.mem
H :
inst_stepge fr m Flightd o args lower = SomeIFreshq k
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsFlightd o args lower
⊢
lookupa fstfstkbase = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
off :
Z
v, a0 :
k :
Z → env × listname × optionZ × Memory.mem
H :
inst_stepge fr m RawStorew off v a0 = SomeIFreshq k
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsRawStorew off v a0
⊢
lookupa fstfstkbase = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
off :
Z
v, a0 :
es :
listeffect
k :
Z → env × listname × optionZ × Memory.mem
H :
inst_stepge fr m RawStorePointeroff v a0 es = SomeIFreshq k
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsRawStorePointeroff v a0 es
⊢
lookupa fstfstkbase = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
callee :
args :
listarg
k :
Z → env × listname × optionZ × Memory.mem
H :
inst_stepge fr m Callr callee args = SomeIFreshq k
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsCallr callee args
⊢
lookupa fstfstkbase = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
callee :
args :
listarg
k :
Z → env × listname × optionZ × Memory.mem
H :
inst_stepge fr m RawCallr callee args = SomeIFreshq k
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsRawCallr callee args
⊢
lookupa fstfstkbase = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
x :
size :
Z
k :
Z → env × listname × optionZ × Memory.mem
H :
inst_stepge fr m LocalAllocx size = SomeIFreshq k
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsLocalAllocx size
⊢
lookupa fstfstkbase = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
file :
line :
Z
k :
Z → env × listname × optionZ × Memory.mem
H :
inst_stepge fr m Locfile line = SomeIFreshq k
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsLocfile line
⊢
lookupa fstfstkbase = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
q0 :
k :
Z → env × listname × optionZ × Memory.mem
H :
inst_stepge fr m Touchq0 = SomeIFreshq k
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsTouchq0
⊢
lookupa fstfstkbase = lookupa fr_envfr

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

12 open

ge :
fr :
m :
Memory.mem
d :
k0 :
x :
off, bytes :
Z
align :
Z
args :
listvalue
k :
Z → env × listname × optionZ × Memory.mem
H :
inst_stepge fr m Letd k0 CheckLocalx off bytes r align args = SomeIFreshq k
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsLetd k0 CheckLocalx off bytes r align args
Es :
special_letCheckLocalx off bytes r align = true
⊢
lookupa fstfstkbase = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
d :
k0 :
args :
listvalue
k :
Z → env × listname × optionZ × Memory.mem
H :
inst_stepge fr m Letd k0 CheckFunction args = SomeIFreshq k
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsLetd k0 CheckFunction args
⊢
lookupa fstfstkbase = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
d :
k0 :
args :
listvalue
k :
Z → env × listname × optionZ × Memory.mem
H :
inst_stepge fr m Letd k0 VaArgs args = SomeIFreshq k
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsLetd k0 VaArgs args
Es :
⊢
lookupa fstfstkbase = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
d :
k0 :
o :
args :
listvalue
k :
Z → env × listname × optionZ × Memory.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
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsLetd k0 o args
Es :
special_leto = false
⊢
lookupa fstfstkbase = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
d :
o :
args :
k :
Z → env × listname × optionZ × Memory.mem
H :
inst_stepge fr m Flightd o args lower = SomeIFreshq k
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsFlightd o args lower
⊢
lookupa fstfstkbase = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
off :
Z
v, a0 :
k :
Z → env × listname × optionZ × Memory.mem
H :
inst_stepge fr m RawStorew off v a0 = SomeIFreshq k
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsRawStorew off v a0
⊢
lookupa fstfstkbase = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
off :
Z
v, a0 :
es :
listeffect
k :
Z → env × listname × optionZ × Memory.mem
H :
inst_stepge fr m RawStorePointeroff v a0 es = SomeIFreshq k
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsRawStorePointeroff v a0 es
⊢
lookupa fstfstkbase = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
callee :
args :
listarg
k :
Z → env × listname × optionZ × Memory.mem
H :
inst_stepge fr m Callr callee args = SomeIFreshq k
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsCallr callee args
⊢
lookupa fstfstkbase = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
callee :
args :
listarg
k :
Z → env × listname × optionZ × Memory.mem
H :
inst_stepge fr m RawCallr callee args = SomeIFreshq k
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsRawCallr callee args
⊢
lookupa fstfstkbase = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
x :
size :
Z
k :
Z → env × listname × optionZ × Memory.mem
H :
inst_stepge fr m LocalAllocx size = SomeIFreshq k
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsLocalAllocx size
⊢
lookupa fstfstkbase = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
file :
line :
Z
k :
Z → env × listname × optionZ × Memory.mem
H :
inst_stepge fr m Locfile line = SomeIFreshq k
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsLocfile line
⊢
lookupa fstfstkbase = lookupa fr_envfr
focused goal
ge :
fr :
m :
Memory.mem
q0 :
k :
Z → env × listname × optionZ × Memory.mem
H :
inst_stepge fr m Touchq0 = SomeIFreshq k
base :
Z
a :
Ha :
¬Ina mapfst inst_temp_defsTouchq0
⊢
lookupa fstfstkbase = lookupa fr_envfr

all: simpl in Ha ; unfold inst_step , external_call , bind_res , store_out in H ; cases H ; inversion H ; subst

2 open

ge :
fr :
m :
Memory.mem
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 × Memory.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
base :
Z
a :
Ha :
¬d = a ∨ False
Es :
special_leto = false
⊢
fst
fst
let x, m′ ≔ k1base in
putd x fr_envfr, fr_localsfr, m′
=
focused goal
ge :
fr :
m :
Memory.mem
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
a :
Ha :
¬False
⊢
lookupa fstfstfr_envfr, putx Somebase fr_localsfr, allocatedm local_reqsize base = lookupa fr_envfr

all: first|reflexivity|match goal with|- ?g⇒match g withcontext [match ?t with pair_ _ ⇒ _ end]⇒destruct t as x m′endend;simpl;exact lookup_put_not_ _ _ _ [ ] _ Ha

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge fr m i q k H base a Ha
destruct i
1: destruct special_leto eqn: Es ; destruct o ; try discriminate Es | rewrite inst_step_let_ _ _ _ _ _ _ Es in H
all: simpl in Ha ; unfold inst_step , external_call , bind_res , store_out in H ; cases H ; inversion H ; subst
all: first|reflexivity|match goal with|- ?g⇒match g withcontext [match ?t with pair_ _ ⇒ _ end]⇒destruct t as x m′endend;simpl;exact lookup_put_not_ _ _ _ [ ] _ Ha

A fold of environment updates that starts from failure fails.

247Lemma fold_env_none
∀ A : Type g : env → A → optionenv xs
fold_left
λ acc x  ⇒
let* e ≔ acc in
ge x
xs
None
=
None
Explore proof 2 tactics

Initial goal

⊢
∀ A : Type g : env → A → optionenv xs : listA  ,
fold_left
λ acc : optionenv x : A  ⇒
let* e ≔ acc in
ge x
xs
None
=
None

intros A g xs

A :
Type
g :
env → A → optionenv
xs :
listA
⊢
fold_left
λ acc : optionenv x : A  ⇒
let* e ≔ acc in
ge x
xs
None
=
None

induction xs ; simpl ; auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros A g xs
induction xs ; simpl ; auto

A fold of puts changes only the names it puts.

252Lemma fold_env_other
∀ A : Type key : A → name g : env → A → optionenv xs a e0 e
∀ e x e′  ,
ge x = Somee′
→
lookupa e′
=
name_eqba keyx
→
lookupa e′
else
¬Ina mapkey xs
fold_left
λ acc x  ⇒
let* e ≔ acc in
ge x
xs
Somee0
=
Somee
lookupa e = lookupa e0
Explore proof 14 tactics

Initial goal

⊢
∀ A : Type key : A → name g : env → A → optionenv xs : listA a : name  ,
∀ e : env x : A e′ : env  ,
ge x = Somee′
→
lookupa e′
=
name_eqba keyx
→
lookupa e′
else
→
¬Ina mapkey xs
→
∀ e0 e : env  ,
fold_left
λ acc : optionenv x : A  ⇒
let* e1 ≔ acc in
ge1 x
xs
Somee0
=
Somee
→
lookupa e = lookupa e0

intros A key g xs a Hg

A :
Type
key :
A → name
g :
env → A → optionenv
xs :
listA
a :
Hg :
∀ e : env x : A e′ : env  ,
ge x = Somee′
→
lookupa e′
=
name_eqba keyx
→
lookupa e′
else
⊢
¬Ina mapkey xs
→
∀ e0 e : env  ,
fold_left
λ acc : optionenv x : A  ⇒
let* e1 ≔ acc in
ge1 x
xs
Somee0
=
Somee
→
lookupa e = lookupa e0

induction xs as | x xs IH ; simpl ; intros Ha e0 e H

2 open

A :
Type
key :
A → name
g :
env → A → optionenv
a :
Hg :
∀ e : env x : A e′ : env  ,
ge x = Somee′
→
lookupa e′
=
name_eqba keyx
→
lookupa e′
else
Ha :
¬False
e0, e :
H :
Somee0 = Somee
⊢
lookupa e = lookupa e0
focused goal
A :
Type
key :
A → name
g :
env → A → optionenv
x :
A
xs :
listA
a :
Hg :
∀ e : env x : A e′ : env  ,
ge x = Somee′
→
lookupa e′
=
name_eqba keyx
→
lookupa e′
else
IH :
¬Ina mapkey xs
→
∀ e0 e : env  ,
fold_left
λ acc : optionenv x : A  ⇒
let* e1 ≔ acc in
ge1 x
xs
Somee0
=
Somee
→
lookupa e = lookupa e0
Ha :
¬keyx = a ∨ Ina mapkey xs
e0, e :
H :
fold_left
λ acc : optionenv x : A  ⇒
let* e ≔ acc in
ge x
xs
ge0 x
=
Somee
⊢
lookupa e = lookupa e0

–injection H as ←

2 open

A :
Type
key :
A → name
g :
env → A → optionenv
a :
Hg :
∀ e : env x : A e′ : env  ,
ge x = Somee′
→
lookupa e′
=
name_eqba keyx
→
lookupa e′
else
Ha :
¬False
e0 :
⊢
lookupa e0 = lookupa e0
deferred goal
A :
Type
key :
A → name
g :
env → A → optionenv
x :
A
xs :
listA
a :
Hg :
∀ e : env x : A e′ : env  ,
ge x = Somee′
→
lookupa e′
=
name_eqba keyx
→
lookupa e′
else
IH :
¬Ina mapkey xs
→
∀ e0 e : env  ,
fold_left
λ acc : optionenv x : A  ⇒
let* e1 ≔ acc in
ge1 x
xs
Somee0
=
Somee
→
lookupa e = lookupa e0
Ha :
¬keyx = a ∨ Ina mapkey xs
e0, e :
H :
fold_left
λ acc : optionenv x : A  ⇒
let* e ≔ acc in
ge x
xs
ge0 x
=
Somee
⊢
lookupa e = lookupa e0

reflexivity

deferred goal
A :
Type
key :
A → name
g :
env → A → optionenv
x :
A
xs :
listA
a :
Hg :
∀ e : env x : A e′ : env  ,
ge x = Somee′
→
lookupa e′
=
name_eqba keyx
→
lookupa e′
else
IH :
¬Ina mapkey xs
→
∀ e0 e : env  ,
fold_left
λ acc : optionenv x : A  ⇒
let* e1 ≔ acc in
ge1 x
xs
Somee0
=
Somee
→
lookupa e = lookupa e0
Ha :
¬keyx = a ∨ Ina mapkey xs
e0, e :
H :
fold_left
λ acc : optionenv x : A  ⇒
let* e ≔ acc in
ge x
xs
ge0 x
=
Somee
⊢
lookupa e = lookupa e0

–destruct ge0 x as e1 | eqn: E ; | rewrite fold_env_none in H ; discriminate H

A :
Type
key :
A → name
g :
env → A → optionenv
x :
A
xs :
listA
a :
Hg :
∀ e : env x : A e′ : env  ,
ge x = Somee′
→
lookupa e′
=
name_eqba keyx
→
lookupa e′
else
IH :
¬Ina mapkey xs
→
∀ e0 e : env  ,
fold_left
λ acc : optionenv x : A  ⇒
let* e1 ≔ acc in
ge1 x
xs
Somee0
=
Somee
→
lookupa e = lookupa e0
Ha :
¬keyx = a ∨ Ina mapkey xs
e0, e, e1 :
E :
ge0 x = Somee1
H :
fold_left
λ acc : optionenv x : A  ⇒
let* e ≔ acc in
ge x
xs
Somee1
=
Somee
⊢
lookupa e = lookupa e0

rewrite IHλHin ⇒ Haor_introrHin _ _ H

A :
Type
key :
A → name
g :
env → A → optionenv
x :
A
xs :
listA
a :
Hg :
∀ e : env x : A e′ : env  ,
ge x = Somee′
→
lookupa e′
=
name_eqba keyx
→
lookupa e′
else
IH :
¬Ina mapkey xs
→
∀ e0 e : env  ,
fold_left
λ acc : optionenv x : A  ⇒
let* e1 ≔ acc in
ge1 x
xs
Somee0
=
Somee
→
lookupa e = lookupa e0
Ha :
¬keyx = a ∨ Ina mapkey xs
e0, e, e1 :
E :
ge0 x = Somee1
H :
fold_left
λ acc : optionenv x : A  ⇒
let* e ≔ acc in
ge x
xs
Somee1
=
Somee
⊢
lookupa e1 = lookupa e0

rewrite Hg_ _ _ E

A :
Type
key :
A → name
g :
env → A → optionenv
x :
A
xs :
listA
a :
Hg :
∀ e : env x : A e′ : env  ,
ge x = Somee′
→
lookupa e′
=
name_eqba keyx
→
lookupa e′
else
IH :
¬Ina mapkey xs
→
∀ e0 e : env  ,
fold_left
λ acc : optionenv x : A  ⇒
let* e1 ≔ acc in
ge1 x
xs
Somee0
=
Somee
→
lookupa e = lookupa e0
Ha :
¬keyx = a ∨ Ina mapkey xs
e0, e, e1 :
E :
ge0 x = Somee1
H :
fold_left
λ acc : optionenv x : A  ⇒
let* e ≔ acc in
ge x
xs
Somee1
=
Somee
⊢
name_eqba keyx
→
lookupa e1
else
lookupa e0
=
lookupa e0

destruct name_eqba keyx eqn: Ek ; | reflexivity

A :
Type
key :
A → name
g :
env → A → optionenv
x :
A
xs :
listA
a :
Hg :
∀ e : env x : A e′ : env  ,
ge x = Somee′
→
lookupa e′
=
name_eqba keyx
→
lookupa e′
else
IH :
¬Ina mapkey xs
→
∀ e0 e : env  ,
fold_left
λ acc : optionenv x : A  ⇒
let* e1 ≔ acc in
ge1 x
xs
Somee0
=
Somee
→
lookupa e = lookupa e0
Ha :
¬keyx = a ∨ Ina mapkey xs
e0, e, e1 :
E :
ge0 x = Somee1
H :
fold_left
λ acc : optionenv x : A  ⇒
let* e ≔ acc in
ge x
xs
Somee1
=
Somee
Ek :
name_eqba keyx = true
⊢
lookupa e1 = lookupa e0

apply name_eqb_true in Ek

A :
Type
key :
A → name
g :
env → A → optionenv
x :
A
xs :
listA
a :
Hg :
∀ e : env x : A e′ : env  ,
ge x = Somee′
→
lookupa e′
=
name_eqba keyx
→
lookupa e′
else
IH :
¬Ina mapkey xs
→
∀ e0 e : env  ,
fold_left
λ acc : optionenv x : A  ⇒
let* e1 ≔ acc in
ge1 x
xs
Somee0
=
Somee
→
lookupa e = lookupa e0
Ha :
¬keyx = a ∨ Ina mapkey xs
e0, e, e1 :
E :
ge0 x = Somee1
H :
fold_left
λ acc : optionenv x : A  ⇒
let* e ≔ acc in
ge x
xs
Somee1
=
Somee
Ek :
a = keyx
⊢
lookupa e1 = lookupa e0

subst

A :
Type
key :
A → name
g :
env → A → optionenv
x :
A
xs :
listA
Ha :
¬keyx = keyx ∨ Inkeyx mapkey xs
IH :
¬Inkeyx mapkey xs
→
∀ e0 e : env  ,
fold_left
λ acc : optionenv x : A  ⇒
let* e1 ≔ acc in
ge1 x
xs
Somee0
=
Somee
→
lookupkeyx e = lookupkeyx e0
Hg :
∀ e : env x0 : A e′ : env  ,
ge x0 = Somee′
→
lookupkeyx e′
=
name_eqbkeyx keyx0
→
lookupkeyx e′
else
lookupkeyx e
e0, e, e1 :
E :
ge0 x = Somee1
H :
fold_left
λ acc : optionenv x : A  ⇒
let* e ≔ acc in
ge x
xs
Somee1
=
Somee
⊢
lookupkeyx e1 = lookupkeyx e0

exfalso

A :
Type
key :
A → name
g :
env → A → optionenv
x :
A
xs :
listA
Ha :
¬keyx = keyx ∨ Inkeyx mapkey xs
IH :
¬Inkeyx mapkey xs
→
∀ e0 e : env  ,
fold_left
λ acc : optionenv x : A  ⇒
let* e1 ≔ acc in
ge1 x
xs
Somee0
=
Somee
→
lookupkeyx e = lookupkeyx e0
Hg :
∀ e : env x0 : A e′ : env  ,
ge x0 = Somee′
→
lookupkeyx e′
=
name_eqbkeyx keyx0
→
lookupkeyx e′
else
lookupkeyx e
e0, e, e1 :
E :
ge0 x = Somee1
H :
fold_left
λ acc : optionenv x : A  ⇒
let* e ≔ acc in
ge x
xs
Somee1
=
Somee
⊢
False

apply Ha

A :
Type
key :
A → name
g :
env → A → optionenv
x :
A
xs :
listA
Ha :
¬keyx = keyx ∨ Inkeyx mapkey xs
IH :
¬Inkeyx mapkey xs
→
∀ e0 e : env  ,
fold_left
λ acc : optionenv x : A  ⇒
let* e1 ≔ acc in
ge1 x
xs
Somee0
=
Somee
→
lookupkeyx e = lookupkeyx e0
Hg :
∀ e : env x0 : A e′ : env  ,
ge x0 = Somee′
→
lookupkeyx e′
=
name_eqbkeyx keyx0
→
lookupkeyx e′
else
lookupkeyx e
e0, e, e1 :
E :
ge0 x = Somee1
H :
fold_left
λ acc : optionenv x : A  ⇒
let* e ≔ acc in
ge x
xs
Somee1
=
Somee
⊢
keyx = keyx ∨ Inkeyx mapkey xs

left

A :
Type
key :
A → name
g :
env → A → optionenv
x :
A
xs :
listA
Ha :
¬keyx = keyx ∨ Inkeyx mapkey xs
IH :
¬Inkeyx mapkey xs
→
∀ e0 e : env  ,
fold_left
λ acc : optionenv x : A  ⇒
let* e1 ≔ acc in
ge1 x
xs
Somee0
=
Somee
→
lookupkeyx e = lookupkeyx e0
Hg :
∀ e : env x0 : A e′ : env  ,
ge x0 = Somee′
→
lookupkeyx e′
=
name_eqbkeyx keyx0
→
lookupkeyx e′
else
lookupkeyx e
e0, e, e1 :
E :
ge0 x = Somee1
H :
fold_left
λ acc : optionenv x : A  ⇒
let* e ≔ acc in
ge x
xs
Somee1
=
Somee
⊢
keyx = keyx

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros A key g xs a Hg
induction xs as | x xs IH ; simpl ; intros Ha e0 e H
–injection H as ←
reflexivity
–destruct ge0 x as e1 | eqn: E ; | rewrite fold_env_none in H ; discriminate H
rewrite IHλHin ⇒ Haor_introrHin _ _ H
rewrite Hg_ _ _ E
destruct name_eqba keyx eqn: Ek ; | reflexivity
apply name_eqb_true in Ek
subst
exfalso
apply Ha
left
reflexivity

The name a phi defines.

266Definition phi_nameph : phi : name ≔
match ph with
Phid _ _
⇒
d

Putting d leaves the value of every other name a.

269Lemma lookup_put_ne
∀ A : Type a d v : A e
a ≠ d
lookupa putd v e = lookupa e
Explore proof 4 tactics

Initial goal

⊢
∀A : Type a d : name v : A e : listname × A, a ≠ d → lookupa putd v e = lookupa e

intros A a d v e H

A :
Type
a, d :
v :
A
e :
listname × A
H :
a ≠ d
⊢
lookupa putd v e = lookupa e

apply lookup_put_not_ _ _ _ [ ]

A :
Type
a, d :
v :
A
e :
listname × A
H :
a ≠ d
⊢
¬Ina d

intros E |

A :
Type
a, d :
v :
A
e :
listname × A
H :
a ≠ d
E :
d = a
⊢
False

exact Heq_symE

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros A a d v e H
apply lookup_put_not_ _ _ _ [ ]
intros E |
exact Heq_symE

A block's phis change only the names they define.

273Lemma phis_env_other
∀ ge phis from e0 e a
phis_envge phis from e0 = Somee
¬Ina mapphi_name phis
lookupa e = lookupa e0
Explore proof 19 tactics

Initial goal

⊢
∀ge : genv phis : listphi from : optionname e0 e : env a : name, phis_envge phis from e0 = Somee → ¬Ina mapphi_name phis → lookupa e = lookupa e0

intros ge phis from e0 e a H Ha

ge :
phis :
listphi
from :
optionname
e0, e :
a :
H :
phis_envge phis from e0 = Somee
Ha :
¬Ina mapphi_name phis
⊢
lookupa e = lookupa e0

unfold phis_env in H

ge :
phis :
listphi
from :
optionname
e0, e :
a :
H :
match from with
Somepred
⇒
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
None
⇒
match phis with
[ ]
⇒
Somee0
_ :: _
⇒
None
=
Somee
Ha :
¬Ina mapphi_name phis
⊢
lookupa e = lookupa e0

destruct from as pred | ; | destruct phis ; injection H as ← ; reflexivity | discriminate H

ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
⊢
lookupa e = lookupa e0

assert G : ∀ps acc e′, ¬Ina mapphi_name ps → ∀ea, acc = Someea → lookupa ea = lookupa e0 → fold_leftλacc ph ⇒ let* e ≔ acc in match ph with Phid k pairs ⇒ let* v ≔ lookuppred pairs in let* x ≔ value_xge e0 k v in Someputd x e end ps acc = Somee′ → lookupa e′ = lookupa e0

2 open

ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
⊢
∀ ps : listphi acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e1 ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e1
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
focused goal
ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
G :
∀ ps : listphi acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
⊢
lookupa e = lookupa e0

{intros ps

2 open

ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
ps :
listphi
⊢
∀ acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e1 ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e1
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
deferred goal
ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
G :
∀ ps : listphi acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
⊢
lookupa e = lookupa e0

induction ps as | d k pairs ps IH ; intros acc e1 Hn Hacc Hf ; simpl in Hf

3 open

ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
acc :
optionlistname × word
e1 :
listname × word
Hn :
¬Ina mapphi_name [ ]
Hacc :
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
Hf :
acc = Somee1
⊢
lookupa e1 = lookupa e0
focused goal
ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
d :
pairs :
listname × value
ps :
listphi
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
acc :
optionlistname × word
e1 :
listname × word
Hn :
¬Ina mapphi_name Phid k pairs :: ps
Hacc :
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
Hf :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
let* e ≔ acc in
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
=
Somee1
⊢
lookupa e1 = lookupa e0
deferred goal
ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
G :
∀ ps : listphi acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
⊢
lookupa e = lookupa e0

–exact Hacc_ Hf

2 open

deferred goal
ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
d :
pairs :
listname × value
ps :
listphi
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
acc :
optionlistname × word
e1 :
listname × word
Hn :
¬Ina mapphi_name Phid k pairs :: ps
Hacc :
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
Hf :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
let* e ≔ acc in
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
=
Somee1
⊢
lookupa e1 = lookupa e0
deferred goal
ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
G :
∀ ps : listphi acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
⊢
lookupa e = lookupa e0

–eapply IH_ e1 λHin ⇒ Hnor_introrHin ; | exact Hf

2 open

ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
d :
pairs :
listname × value
ps :
listphi
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
acc :
optionlistname × word
e1 :
listname × word
Hn :
¬Ina mapphi_name Phid k pairs :: ps
Hacc :
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
Hf :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
let* e ≔ acc in
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
=
Somee1
⊢
∀ ea : listname × word  ,
let* e2 ≔ acc in
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e2
=
Someea
→
lookupa ea = lookupa e0
deferred goal
ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
G :
∀ ps : listphi acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
⊢
lookupa e = lookupa e0

intros ea Ea

2 open

ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
d :
pairs :
listname × value
ps :
listphi
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
acc :
optionlistname × word
e1 :
listname × word
Hn :
¬Ina mapphi_name Phid k pairs :: ps
Hacc :
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
Hf :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
let* e ≔ acc in
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
=
Somee1
ea :
listname × word
Ea :
let* e ≔ acc in
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
=
Someea
⊢
lookupa ea = lookupa e0
deferred goal
ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
G :
∀ ps : listphi acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
⊢
lookupa e = lookupa e0

destruct acc as eb | ; | discriminate Ea

2 open

ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
d :
pairs :
listname × value
ps :
listphi
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
eb, e1 :
listname × word
Hn :
¬Ina mapphi_name Phid k pairs :: ps
Hacc :
∀ea : listname × word, Someeb = Someea → lookupa ea = lookupa e0
Hf :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x eb
=
Somee1
ea :
listname × word
Ea :
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x eb
=
Someea
⊢
lookupa ea = lookupa e0
deferred goal
ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
G :
∀ ps : listphi acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
⊢
lookupa e = lookupa e0

simpl in Ea

2 open

ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
d :
pairs :
listname × value
ps :
listphi
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
eb, e1 :
listname × word
Hn :
¬Ina mapphi_name Phid k pairs :: ps
Hacc :
∀ea : listname × word, Someeb = Someea → lookupa ea = lookupa e0
Hf :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x eb
=
Somee1
ea :
listname × word
Ea :
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x eb
=
Someea
⊢
lookupa ea = lookupa e0
deferred goal
ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
G :
∀ ps : listphi acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
⊢
lookupa e = lookupa e0

destruct lookuppred pairs as v | ; | discriminate Ea

2 open

ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
d :
pairs :
listname × value
ps :
listphi
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
eb, e1 :
listname × word
Hn :
¬Ina mapphi_name Phid k pairs :: ps
Hacc :
∀ea : listname × word, Someeb = Someea → lookupa ea = lookupa e0
Hf :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
let* x ≔ value_xge e0 k v in
Someputd x eb
=
Somee1
ea :
listname × word
Ea :
let* x ≔ value_xge e0 k v in
Someputd x eb
=
Someea
⊢
lookupa ea = lookupa e0
deferred goal
ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
G :
∀ ps : listphi acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
⊢
lookupa e = lookupa e0

simpl in Ea

2 open

ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
d :
pairs :
listname × value
ps :
listphi
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
eb, e1 :
listname × word
Hn :
¬Ina mapphi_name Phid k pairs :: ps
Hacc :
∀ea : listname × word, Someeb = Someea → lookupa ea = lookupa e0
Hf :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
let* x ≔ value_xge e0 k v in
Someputd x eb
=
Somee1
ea :
listname × word
Ea :
let* x ≔ value_xge e0 k v in
Someputd x eb
=
Someea
⊢
lookupa ea = lookupa e0
deferred goal
ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
G :
∀ ps : listphi acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
⊢
lookupa e = lookupa e0

destruct value_xge e0 k v ; | discriminate Ea

2 open

ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
d :
pairs :
listname × value
ps :
listphi
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
eb, e1 :
listname × word
Hn :
¬Ina mapphi_name Phid k pairs :: ps
Hacc :
∀ea : listname × word, Someeb = Someea → lookupa ea = lookupa e0
w :
Hf :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
Someputd w eb
=
Somee1
ea :
listname × word
Ea :
Someputd w eb = Someea
⊢
lookupa ea = lookupa e0
deferred goal
ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
G :
∀ ps : listphi acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
⊢
lookupa e = lookupa e0

simpl in Ea

2 open

ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
d :
pairs :
listname × value
ps :
listphi
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
eb, e1 :
listname × word
Hn :
¬Ina mapphi_name Phid k pairs :: ps
Hacc :
∀ea : listname × word, Someeb = Someea → lookupa ea = lookupa e0
w :
Hf :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
Someputd w eb
=
Somee1
ea :
listname × word
Ea :
Someputd w eb = Someea
⊢
lookupa ea = lookupa e0
deferred goal
ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
G :
∀ ps : listphi acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
⊢
lookupa e = lookupa e0

injection Ea as ←

2 open

ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
d :
pairs :
listname × value
ps :
listphi
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
eb, e1 :
listname × word
Hn :
¬Ina mapphi_name Phid k pairs :: ps
Hacc :
∀ea : listname × word, Someeb = Someea → lookupa ea = lookupa e0
w :
Hf :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
Someputd w eb
=
Somee1
⊢
lookupa putd w eb = lookupa e0
deferred goal
ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
G :
∀ ps : listphi acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
⊢
lookupa e = lookupa e0

rewrite lookup_put_ne by intros → ; apply Hn ; left ; reflexivity

2 open

ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
d :
pairs :
listname × value
ps :
listphi
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
eb, e1 :
listname × word
Hn :
¬Ina mapphi_name Phid k pairs :: ps
Hacc :
∀ea : listname × word, Someeb = Someea → lookupa ea = lookupa e0
w :
Hf :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
Someputd w eb
=
Somee1
⊢
lookupa eb = lookupa e0
deferred goal
ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
G :
∀ ps : listphi acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
⊢
lookupa e = lookupa e0

exact Hacc_ eq_refl

deferred goal
ge :
phis :
listphi
pred :
e0, e :
a :
H :
fold_left
λ acc : optionlistname × word ph : phi  ⇒
let* e ≔ acc in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
phis
Somee0
=
Somee
Ha :
¬Ina mapphi_name phis
G :
∀ ps : listphi acc : optionlistname × word e′ : listname × word  ,
¬Ina mapphi_name ps
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e0
→
fold_left
λ acc0 : optionlistname × word ph : phi  ⇒
let* e ≔ acc0 in
match ph with
Phid k pairs
⇒
let* v ≔ lookuppred pairs in
let* x ≔ value_xge e0 k v in
Someputd x e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e0
⊢
lookupa e = lookupa e0

apply Gphis Somee0 e Ha ; intros ea E ; injection E as ← ; reflexivity | exact H

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge phis from e0 e a H Ha
unfold phis_env in H
destruct from as pred | ; | destruct phis ; injection H as ← ; reflexivity | discriminate H
assert G : ∀ps acc e′, ¬Ina mapphi_name ps → ∀ea, acc = Someea → lookupa ea = lookupa e0 → fold_leftλacc ph ⇒ let* e ≔ acc in match ph with Phid k pairs ⇒ let* v ≔ lookuppred pairs in let* x ≔ value_xge e0 k v in Someputd x e end ps acc = Somee′ → lookupa e′ = lookupa e0
{intros ps
induction ps as | d k pairs ps IH ; intros acc e1 Hn Hacc Hf ; simpl in Hf
–exact Hacc_ Hf
–eapply IH_ e1 λHin ⇒ Hnor_introrHin ; | exact Hf
intros ea Ea
destruct acc as eb | ; | discriminate Ea
simpl in Ea
destruct lookuppred pairs as v | ; | discriminate Ea
simpl in Ea
destruct value_xge e0 k v ; | discriminate Ea
simpl in Ea
injection Ea as ←
rewrite lookup_put_ne by intros → ; apply Hn ; left ; reflexivity
exact Hacc_ eq_refl
apply Gphis Somee0 e Ha ; intros ea E ; injection E as ← ; reflexivity | exact H

A call's result changes only the names it defines.

297Lemma returned_env_other
∀ r o e e′ a
returned_envr o e = Somee′
lookupa e′ = lookupa e
Explore proof 29 tactics

Initial goal

⊢
∀r : call_result o : outcome e e′ : env a : name, returned_envr o e = Somee′ → ¬Ina result_namesr → lookupa e′ = lookupa e

intros r o e e′ a H Ha

e, e′ :
a :
H :
returned_envr o e = Somee′
Ha :
⊢
lookupa e′ = lookupa e

unfold returned_env in H

e, e′ :
a :
H :
match o with
⇒
match r with
⇒
Somee
⇒
let* y ≔ word_at_classk x in
Someputd y e
⇒
None
⇒
match r with
⇒
Somee
⇒
None
⇒
negbDatatypes.lengthxs =? Datatypes.lengthrs%nat
→
None
else
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
⇒
match r with
⇒
Somee
_
⇒
None
_
⇒
None
=
Somee′
Ha :
⊢
lookupa e′ = lookupa e

destruct o as x | xs | | | | | | ; destruct r as | d k | rs ; try discriminate H ; try injection H as ← ; reflexivity

2 open

d :
x :
e, e′ :
a :
H :
let* y ≔ word_at_classk x in
Someputd y e
=
Somee′
Ha :
⊢
lookupa e′ = lookupa e
focused goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
negbDatatypes.lengthxs =? Datatypes.lengthrs%nat
→
None
else
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
⊢
lookupa e′ = lookupa e

–destruct word_at_classk x ; | discriminate H

2 open

d :
x :
e, e′ :
a :
w :
H :
Someputd w e = Somee′
Ha :
⊢
lookupa e′ = lookupa e
deferred goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
negbDatatypes.lengthxs =? Datatypes.lengthrs%nat
→
None
else
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
⊢
lookupa e′ = lookupa e

injection H as ←

2 open

d :
x :
e :
a :
w :
Ha :
⊢
lookupa putd w e = lookupa e
deferred goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
negbDatatypes.lengthxs =? Datatypes.lengthrs%nat
→
None
else
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
⊢
lookupa e′ = lookupa e

apply lookup_put_ne

2 open

d :
x :
e :
a :
w :
Ha :
⊢
a ≠ d
deferred goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
negbDatatypes.lengthxs =? Datatypes.lengthrs%nat
→
None
else
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
⊢
lookupa e′ = lookupa e

intros →

2 open

d :
x :
e :
w :
Ha :
⊢
False
deferred goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
negbDatatypes.lengthxs =? Datatypes.lengthrs%nat
→
None
else
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
⊢
lookupa e′ = lookupa e

apply Ha

2 open

deferred goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
negbDatatypes.lengthxs =? Datatypes.lengthrs%nat
→
None
else
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
⊢
lookupa e′ = lookupa e

left

2 open

d :
x :
e :
w :
Ha :
⊢
d = d
deferred goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
negbDatatypes.lengthxs =? Datatypes.lengthrs%nat
→
None
else
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
⊢
lookupa e′ = lookupa e

reflexivity

deferred goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
negbDatatypes.lengthxs =? Datatypes.lengthrs%nat
→
None
else
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
⊢
lookupa e′ = lookupa e

–destruct negb_ ; discriminate H |

rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
⊢
lookupa e′ = lookupa e

assert G : ∀ps acc e′, ∀p, Inp ps → Infstfstp mapfst rs → ∀ea, acc = Someea → lookupa ea = lookupa e → fold_leftλacc rx ⇒ let* e ≔ acc in let* y ≔ word_at_classsndfstrx sndrx in Someputfstfstrx y e ps acc = Somee′ → lookupa e′ = lookupa e

2 open

rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
⊢
∀ ps : listname × class × word acc : optionlistname × word e'0 : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e0 ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e0
ps
acc
=
Somee'0
→
lookupa e'0 = lookupa e
focused goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
G :
∀ ps : listname × class × word acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
⊢
lookupa e′ = lookupa e

{intros ps

2 open

rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
ps :
listname × class × word
⊢
∀ acc : optionlistname × word e'0 : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e0 ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e0
ps
acc
=
Somee'0
→
lookupa e'0 = lookupa e
deferred goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
G :
∀ ps : listname × class × word acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
⊢
lookupa e′ = lookupa e

induction ps as | p ps IH ; intros acc e1 Hps Hacc Hf ; simpl in Hf

3 open

rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
acc :
optionlistname × word
e1 :
listname × word
Hps :
∀p : name × class × word, Inp [ ] → Infstfstp mapfst rs
Hacc :
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
Hf :
acc = Somee1
⊢
lookupa e1 = lookupa e
focused goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
p :
name × class × word
ps :
listname × class × word
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
acc :
optionlistname × word
e1 :
listname × word
Hps :
∀p0 : name × class × word, Inp0 p :: ps → Infstfstp0 mapfst rs
Hacc :
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
Hf :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
let* e ≔ acc in
let* y ≔ word_at_classsndfstp sndp in
Someputfstfstp y e
=
Somee1
⊢
lookupa e1 = lookupa e
deferred goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
G :
∀ ps : listname × class × word acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
⊢
lookupa e′ = lookupa e

–exact Hacc_ Hf

2 open

deferred goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
p :
name × class × word
ps :
listname × class × word
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
acc :
optionlistname × word
e1 :
listname × word
Hps :
∀p0 : name × class × word, Inp0 p :: ps → Infstfstp0 mapfst rs
Hacc :
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
Hf :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
let* e ≔ acc in
let* y ≔ word_at_classsndfstp sndp in
Someputfstfstp y e
=
Somee1
⊢
lookupa e1 = lookupa e
deferred goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
G :
∀ ps : listname × class × word acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
⊢
lookupa e′ = lookupa e

–eapply IH_ e1 λq Hq ⇒ Hpsq or_introrHq ; | exact Hf

2 open

rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
p :
name × class × word
ps :
listname × class × word
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
acc :
optionlistname × word
e1 :
listname × word
Hps :
∀p0 : name × class × word, Inp0 p :: ps → Infstfstp0 mapfst rs
Hacc :
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
Hf :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
let* e ≔ acc in
let* y ≔ word_at_classsndfstp sndp in
Someputfstfstp y e
=
Somee1
⊢
∀ ea : listname × word  ,
let* e0 ≔ acc in
let* y ≔ word_at_classsndfstp sndp in
Someputfstfstp y e0
=
Someea
→
lookupa ea = lookupa e
deferred goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
G :
∀ ps : listname × class × word acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
⊢
lookupa e′ = lookupa e

intros ea Ea

2 open

rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
p :
name × class × word
ps :
listname × class × word
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
acc :
optionlistname × word
e1 :
listname × word
Hps :
∀p0 : name × class × word, Inp0 p :: ps → Infstfstp0 mapfst rs
Hacc :
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
Hf :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
let* e ≔ acc in
let* y ≔ word_at_classsndfstp sndp in
Someputfstfstp y e
=
Somee1
ea :
listname × word
Ea :
let* e ≔ acc in
let* y ≔ word_at_classsndfstp sndp in
Someputfstfstp y e
=
Someea
⊢
lookupa ea = lookupa e
deferred goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
G :
∀ ps : listname × class × word acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
⊢
lookupa e′ = lookupa e

destruct acc as eb | ; | discriminate Ea

2 open

rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
p :
name × class × word
ps :
listname × class × word
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
eb, e1 :
listname × word
Hps :
∀p0 : name × class × word, Inp0 p :: ps → Infstfstp0 mapfst rs
Hacc :
∀ea : listname × word, Someeb = Someea → lookupa ea = lookupa e
Hf :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
let* y ≔ word_at_classsndfstp sndp in
Someputfstfstp y eb
=
Somee1
ea :
listname × word
Ea :
let* y ≔ word_at_classsndfstp sndp in
Someputfstfstp y eb
=
Someea
⊢
lookupa ea = lookupa e
deferred goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
G :
∀ ps : listname × class × word acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
⊢
lookupa e′ = lookupa e

simpl in Ea

2 open

rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
p :
name × class × word
ps :
listname × class × word
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
eb, e1 :
listname × word
Hps :
∀p0 : name × class × word, Inp0 p :: ps → Infstfstp0 mapfst rs
Hacc :
∀ea : listname × word, Someeb = Someea → lookupa ea = lookupa e
Hf :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
let* y ≔ word_at_classsndfstp sndp in
Someputfstfstp y eb
=
Somee1
ea :
listname × word
Ea :
let* y ≔ word_at_classsndfstp sndp in
Someputfstfstp y eb
=
Someea
⊢
lookupa ea = lookupa e
deferred goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
G :
∀ ps : listname × class × word acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
⊢
lookupa e′ = lookupa e

destruct word_at_class_ _ ; | discriminate Ea

2 open

rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
p :
name × class × word
ps :
listname × class × word
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
eb, e1 :
listname × word
Hps :
∀p0 : name × class × word, Inp0 p :: ps → Infstfstp0 mapfst rs
Hacc :
∀ea : listname × word, Someeb = Someea → lookupa ea = lookupa e
w :
Hf :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
Someputfstfstp w eb
=
Somee1
ea :
listname × word
Ea :
Someputfstfstp w eb = Someea
⊢
lookupa ea = lookupa e
deferred goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
G :
∀ ps : listname × class × word acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
⊢
lookupa e′ = lookupa e

simpl in Ea

2 open

rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
p :
name × class × word
ps :
listname × class × word
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
eb, e1 :
listname × word
Hps :
∀p0 : name × class × word, Inp0 p :: ps → Infstfstp0 mapfst rs
Hacc :
∀ea : listname × word, Someeb = Someea → lookupa ea = lookupa e
w :
Hf :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
Someputfstfstp w eb
=
Somee1
ea :
listname × word
Ea :
Someputfstfstp w eb = Someea
⊢
lookupa ea = lookupa e
deferred goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
G :
∀ ps : listname × class × word acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
⊢
lookupa e′ = lookupa e

injection Ea as ←

2 open

rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
p :
name × class × word
ps :
listname × class × word
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
eb, e1 :
listname × word
Hps :
∀p0 : name × class × word, Inp0 p :: ps → Infstfstp0 mapfst rs
Hacc :
∀ea : listname × word, Someeb = Someea → lookupa ea = lookupa e
w :
Hf :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
Someputfstfstp w eb
=
Somee1
⊢
lookupa putfstfstp w eb = lookupa e
deferred goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
G :
∀ ps : listname × class × word acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
⊢
lookupa e′ = lookupa e

rewrite lookup_put_ne by intros E ; apply Ha ; rewrite E ; exact Hpsp or_introleq_refl

2 open

rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
p :
name × class × word
ps :
listname × class × word
IH :
∀ acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
eb, e1 :
listname × word
Hps :
∀p0 : name × class × word, Inp0 p :: ps → Infstfstp0 mapfst rs
Hacc :
∀ea : listname × word, Someeb = Someea → lookupa ea = lookupa e
w :
Hf :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
Someputfstfstp w eb
=
Somee1
⊢
lookupa eb = lookupa e
deferred goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
G :
∀ ps : listname × class × word acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
⊢
lookupa e′ = lookupa e

exact Hacc_ eq_refl

deferred goal
rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
G :
∀ ps : listname × class × word acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
⊢
lookupa e′ = lookupa e

apply Gcombiners xs Somee e′ ; | intros ea E ; injection E as ← ; reflexivity | exact H

rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
G :
∀ ps : listname × class × word acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
⊢
∀p : name × class × word, Inp combiners xs → Infstfstp mapfst rs

intros n k y Hp

rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
G :
∀ ps : listname × class × word acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
n :
y :
Hp :
Inn, k, y combiners xs
⊢
Infstfstn, k, y mapfst rs

apply in_map_iff

rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
G :
∀ ps : listname × class × word acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
n :
y :
Hp :
Inn, k, y combiners xs
⊢
∃x : name × class, fstx = fstfstn, k, y ∧ Inx rs

exists n, k

rs :
listname × class
xs :
listword
e, e′ :
a :
H :
fold_left
λ acc : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
combiners xs
Somee
=
Somee′
Ha :
G :
∀ ps : listname × class × word acc : optionlistname × word e′ : listname × word  ,
∀p : name × class × word, Inp ps → Infstfstp mapfst rs
→
∀ea : listname × word, acc = Someea → lookupa ea = lookupa e
→
fold_left
λ acc0 : optionlistname × word rx : name × class × word  ⇒
let* e ≔ acc0 in
let* y ≔ word_at_classsndfstrx sndrx in
Someputfstfstrx y e
ps
acc
=
Somee′
→
lookupa e′ = lookupa e
n :
y :
Hp :
Inn, k, y combiners xs
⊢
fstn, k = fstfstn, k, y ∧ Inn, k rs

split ; reflexivity | exact in_combine_l_ _ _ _ Hp

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros r o e e′ a H Ha
unfold returned_env in H
destruct o as x | xs | | | | | | ; destruct r as | d k | rs ; try discriminate H ; try injection H as ← ; reflexivity
–destruct word_at_classk x ; | discriminate H
injection H as ←
intros →
apply Ha
left
reflexivity
–destruct negb_ ; discriminate H |
assert G : ∀ps acc e′, ∀p, Inp ps → Infstfstp mapfst rs → ∀ea, acc = Someea → lookupa ea = lookupa e → fold_leftλacc rx ⇒ let* e ≔ acc in let* y ≔ word_at_classsndfstrx sndrx in Someputfstfstrx y e ps acc = Somee′ → lookupa e′ = lookupa e
{intros ps
induction ps as | p ps IH ; intros acc e1 Hps Hacc Hf ; simpl in Hf
–exact Hacc_ Hf
–eapply IH_ e1 λq Hq ⇒ Hpsq or_introrHq ; | exact Hf
intros ea Ea
destruct acc as eb | ; | discriminate Ea
simpl in Ea
destruct word_at_class_ _ ; | discriminate Ea
simpl in Ea
injection Ea as ←
rewrite lookup_put_ne by intros E ; apply Ha ; rewrite E ; exact Hpsp or_introleq_refl
exact Hacc_ eq_refl
apply Gcombiners xs Somee e′ ; | intros ea E ; injection E as ← ; reflexivity | exact H
intros n k y Hp
apply in_map_iff
exists n, k
split ; reflexivity | exact in_combine_l_ _ _ _ Hp

A call's result names are the names it defines.

322Lemma call_defs
∀ r cl args
mapfst inst_temp_defsCallr cl args = result_namesr
Explore proof 2 tactics

Initial goal

⊢
∀r : call_result cl : value args : listarg, mapfst inst_temp_defsCallr cl args = result_namesr

intros r cl args

cl :
args :
listarg
⊢
mapfst inst_temp_defsCallr cl args = result_namesr

destruct r ; reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros r cl args
destruct r ; reflexivity

So are a raw call's.

326Lemma raw_call_defs
∀ r cl args
Explore proof 2 tactics

Initial goal

⊢
∀r : call_result cl : value args : listarg, mapfst inst_temp_defsRawCallr cl args = result_namesr

intros r cl args

cl :
args :
listarg
⊢

destruct r ; reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros r cl args
destruct r ; reflexivity

A call's pending result is the call's.

330Lemma inst_step_call_pending
∀ ge fr m i g xs pd
inst_stepge fr m i = SomeICallg xs pd
∃cl args, i = Callpd_respd cl args ∨ ∃cl args, i = RawCallpd_respd cl args
Explore proof 4 tactics

Initial goal

⊢
∀ge : genv fr : frame m : Memory.mem i : inst g : func xs : listword pd : pending, inst_stepge fr m i = SomeICallg xs pd → ∃cl : value args : listarg, i = Callpd_respd cl args ∨ ∃cl : value args : listarg, i = RawCallpd_respd cl args

intros ge fr m i g xs pd H

ge :
fr :
m :
Memory.mem
i :
g :
xs :
listword
H :
inst_stepge fr m i = SomeICallg xs pd
⊢
∃cl : value args : listarg, i = Callpd_respd cl args ∨ ∃cl : value args : listarg, i = RawCallpd_respd cl args

destruct i

9 open

ge :
fr :
m :
Memory.mem
d :
o :
args :
listvalue
g :
xs :
listword
H :
inst_stepge fr m Letd k o args = SomeICallg xs pd
⊢
∃cl : value args0 : listarg, Letd k o args = Callpd_respd cl args0 ∨ ∃cl : value args0 : listarg, Letd k o args = RawCallpd_respd cl args0
focused goal
ge :
fr :
m :
Memory.mem
d :
o :
args :
g :
xs :
listword
H :
inst_stepge fr m Flightd o args lower = SomeICallg xs pd
⊢
∃cl : value args0 : listarg, Flightd o args lower = Callpd_respd cl args0 ∨ ∃cl : value args0 : listarg, Flightd o args lower = RawCallpd_respd cl args0
focused goal
ge :
fr :
m :
Memory.mem
off :
Z
v, a :
g :
xs :
listword
H :
inst_stepge fr m RawStorew off v a = SomeICallg xs pd
⊢
∃cl : value args : listarg, RawStorew off v a = Callpd_respd cl args ∨ ∃cl : value args : listarg, RawStorew off v a = RawCallpd_respd cl args
focused goal
ge :
fr :
m :
Memory.mem
off :
Z
v, a :
es :
listeffect
g :
xs :
listword
H :
inst_stepge fr m RawStorePointeroff v a es = SomeICallg xs pd
⊢
∃cl : value args : listarg, RawStorePointeroff v a es = Callpd_respd cl args ∨ ∃cl : value args : listarg, RawStorePointeroff v a es = RawCallpd_respd cl args
focused goal
ge :
fr :
m :
Memory.mem
callee :
args :
listarg
g :
xs :
listword
H :
inst_stepge fr m Callr callee args = SomeICallg xs pd
⊢
∃cl : value args0 : listarg, Callr callee args = Callpd_respd cl args0 ∨ ∃cl : value args0 : listarg, Callr callee args = RawCallpd_respd cl args0
focused goal
ge :
fr :
m :
Memory.mem
callee :
args :
listarg
g :
xs :
listword
H :
inst_stepge fr m RawCallr callee args = SomeICallg xs pd
⊢
∃cl : value args0 : listarg, RawCallr callee args = Callpd_respd cl args0 ∨ ∃cl : value args0 : listarg, RawCallr callee args = RawCallpd_respd cl args0
focused goal
ge :
fr :
m :
Memory.mem
x :
size :
Z
g :
xs :
listword
H :
inst_stepge fr m LocalAllocx size = SomeICallg xs pd
⊢
∃cl : value args : listarg, LocalAllocx size = Callpd_respd cl args ∨ ∃cl : value args : listarg, LocalAllocx size = RawCallpd_respd cl args
focused goal
ge :
fr :
m :
Memory.mem
file :
line :
Z
g :
xs :
listword
H :
inst_stepge fr m Locfile line = SomeICallg xs pd
⊢
∃cl : value args : listarg, Locfile line = Callpd_respd cl args ∨ ∃cl : value args : listarg, Locfile line = RawCallpd_respd cl args
focused goal
ge :
fr :
m :
Memory.mem
q :
g :
xs :
listword
H :
inst_stepge fr m Touchq = SomeICallg xs pd
⊢
∃cl : value args : listarg, Touchq = Callpd_respd cl args ∨ ∃cl : value args : listarg, Touchq = RawCallpd_respd cl args

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

12 open

ge :
fr :
m :
Memory.mem
d :
x :
off, bytes :
Z
align :
Z
args :
listvalue
g :
xs :
listword
H :
inst_stepge fr m Letd k CheckLocalx off bytes r align args = SomeICallg xs pd
Es :
special_letCheckLocalx off bytes r align = true
⊢
∃cl : value args0 : listarg, Letd k CheckLocalx off bytes r align args = Callpd_respd cl args0 ∨ ∃cl : value args0 : listarg, Letd k CheckLocalx off bytes r align args = RawCallpd_respd cl args0
focused goal
ge :
fr :
m :
Memory.mem
d :
args :
listvalue
g :
xs :
listword
H :
inst_stepge fr m Letd k CheckFunction args = SomeICallg xs pd
⊢
∃cl : value args0 : listarg, Letd k CheckFunction args = Callpd_respd cl args0 ∨ ∃cl : value args0 : listarg, Letd k CheckFunction args = RawCallpd_respd cl args0
focused goal
ge :
fr :
m :
Memory.mem
d :
args :
listvalue
g :
xs :
listword
H :
inst_stepge fr m Letd k VaArgs args = SomeICallg xs pd
Es :
⊢
∃cl : value args0 : listarg, Letd k VaArgs args = Callpd_respd cl args0 ∨ ∃cl : value args0 : listarg, Letd k VaArgs args = RawCallpd_respd cl args0
focused goal
ge :
fr :
m :
Memory.mem
d :
o :
args :
listvalue
g :
xs :
listword
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
=
SomeICallg xs pd
Es :
special_leto = false
⊢
∃cl : value args0 : listarg, Letd k o args = Callpd_respd cl args0 ∨ ∃cl : value args0 : listarg, Letd k o args = RawCallpd_respd cl args0
focused goal
ge :
fr :
m :
Memory.mem
d :
o :
args :
g :
xs :
listword
H :
inst_stepge fr m Flightd o args lower = SomeICallg xs pd
⊢
∃cl : value args0 : listarg, Flightd o args lower = Callpd_respd cl args0 ∨ ∃cl : value args0 : listarg, Flightd o args lower = RawCallpd_respd cl args0
focused goal
ge :
fr :
m :
Memory.mem
off :
Z
v, a :
g :
xs :
listword
H :
inst_stepge fr m RawStorew off v a = SomeICallg xs pd
⊢
∃cl : value args : listarg, RawStorew off v a = Callpd_respd cl args ∨ ∃cl : value args : listarg, RawStorew off v a = RawCallpd_respd cl args
focused goal
ge :
fr :
m :
Memory.mem
off :
Z
v, a :
es :
listeffect
g :
xs :
listword
H :
inst_stepge fr m RawStorePointeroff v a es = SomeICallg xs pd
⊢
∃cl : value args : listarg, RawStorePointeroff v a es = Callpd_respd cl args ∨ ∃cl : value args : listarg, RawStorePointeroff v a es = RawCallpd_respd cl args
focused goal
ge :
fr :
m :
Memory.mem
callee :
args :
listarg
g :
xs :
listword
H :
inst_stepge fr m Callr callee args = SomeICallg xs pd
⊢
∃cl : value args0 : listarg, Callr callee args = Callpd_respd cl args0 ∨ ∃cl : value args0 : listarg, Callr callee args = RawCallpd_respd cl args0
focused goal
ge :
fr :
m :
Memory.mem
callee :
args :
listarg
g :
xs :
listword
H :
inst_stepge fr m RawCallr callee args = SomeICallg xs pd
⊢
∃cl : value args0 : listarg, RawCallr callee args = Callpd_respd cl args0 ∨ ∃cl : value args0 : listarg, RawCallr callee args = RawCallpd_respd cl args0
focused goal
ge :
fr :
m :
Memory.mem
x :
size :
Z
g :
xs :
listword
H :
inst_stepge fr m LocalAllocx size = SomeICallg xs pd
⊢
∃cl : value args : listarg, LocalAllocx size = Callpd_respd cl args ∨ ∃cl : value args : listarg, LocalAllocx size = RawCallpd_respd cl args
focused goal
ge :
fr :
m :
Memory.mem
file :
line :
Z
g :
xs :
listword
H :
inst_stepge fr m Locfile line = SomeICallg xs pd
⊢
∃cl : value args : listarg, Locfile line = Callpd_respd cl args ∨ ∃cl : value args : listarg, Locfile line = RawCallpd_respd cl args
focused goal
ge :
fr :
m :
Memory.mem
q :
g :
xs :
listword
H :
inst_stepge fr m Touchq = SomeICallg xs pd
⊢
∃cl : value args : listarg, Touchq = Callpd_respd cl args ∨ ∃cl : value args : listarg, Touchq = RawCallpd_respd cl args

all: unfold inst_step , external_call , bind_res , store_out in H ; cases H ; inversion H ; subst ; simpl ; eauto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge fr m i g xs pd 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 ; simpl ; eauto

Points

Where dropping k elements of l, with k at most l's length, leaves nothing, k is l's length.

344Lemma skipn_nil_length
∀ A : Type k l : listA
skipnk l = [ ]
k ≤ lengthl%nat
k = lengthl
Explore proof 5 tactics

Initial goal

⊢
∀A : Type k : nat l : listA, skipnk l = [ ] → k ≤ Datatypes.lengthl%nat → k = Datatypes.lengthl

intros A k l H Hk

A :
Type
k :
nat
l :
listA
H :
skipnk l = [ ]
Hk :
k ≤ Datatypes.lengthl%nat
⊢
k = Datatypes.lengthl

pose proof length_skipnk l as E

A :
Type
k :
nat
l :
listA
H :
skipnk l = [ ]
Hk :
k ≤ Datatypes.lengthl%nat
E :
Datatypes.lengthskipnk l = Datatypes.lengthl − k%nat
⊢
k = Datatypes.lengthl

rewrite H in E

A :
Type
k :
nat
l :
listA
H :
skipnk l = [ ]
Hk :
k ≤ Datatypes.lengthl%nat
E :
Datatypes.length[ ] = Datatypes.lengthl − k%nat
⊢
k = Datatypes.lengthl

simpl in E

A :
Type
k :
nat
l :
listA
H :
skipnk l = [ ]
Hk :
k ≤ Datatypes.lengthl%nat
E :
0%nat = Datatypes.lengthl − k%nat
⊢
k = Datatypes.lengthl

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros A k l H Hk
pose proof length_skipnk l as E
rewrite H in E
simpl in E
lia

The point k instructions into a block is at index k.

350Lemma point_site_exec
∀ f l b k j
k ≤ lengthb_instsb%nat
point_sitef Execl skipnk b_instsb j = Somel, Z.of_natk
Explore proof 6 tactics

Initial goal

⊢
∀f : func l : name b : block k : nat j : jump, find_blockl fn_blocksf = Someb → k ≤ Datatypes.lengthb_instsb%nat → point_sitef Execl skipnk b_instsb j = Somel, Z.of_natk

intros f l b k j Hb Hk

f :
l :
k :
nat
j :
Hb :
Hk :
k ≤ Datatypes.lengthb_instsb%nat
⊢
point_sitef Execl skipnk b_instsb j = Somel, Z.of_natk

simpl

f :
l :
k :
nat
j :
Hb :
Hk :
k ≤ Datatypes.lengthb_instsb%nat
⊢
let* b0 ≔ find_blockl fn_blocksf in
Somel, Z.of_natDatatypes.lengthb_instsb0 − Datatypes.lengthskipnk b_instsb
=
Somel, Z.of_natk

rewrite Hb , length_skipn

f :
l :
k :
nat
j :
Hb :
Hk :
k ≤ Datatypes.lengthb_instsb%nat
⊢
Somel, Z.of_natDatatypes.lengthb_instsb − Datatypes.lengthb_instsb − k = Somel, Z.of_natk

f_equal

f :
l :
k :
nat
j :
Hb :
Hk :
k ≤ Datatypes.lengthb_instsb%nat
⊢
l, Z.of_natDatatypes.lengthb_instsb − Datatypes.lengthb_instsb − k = l, Z.of_natk

f_equal

f :
l :
k :
nat
j :
Hb :
Hk :
k ≤ Datatypes.lengthb_instsb%nat
⊢
Z.of_natDatatypes.lengthb_instsb − Datatypes.lengthb_instsb − k = Z.of_natk

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros f l b k j Hb Hk
simpl
rewrite Hb , length_skipn
f_equal
f_equal
lia

Nothing is in scope at a function's entry.

358Lemma scope_entry
∀ md f l n s i
site_dominatesfn_domsf l −1 s = false
Explore proof 12 tactics

Initial goal

⊢
∀md : module f : func l n : name s : site i : inst, checked_modulemd → InIFuncf md → entry_labelf = Somel → Inn, s, DInsti def_positionsf → site_dominatesfn_domsf l −1 s = false

intros md f l n s i Hmd Hin He Hp

md :
f :
l, n :
s :
i :
Hin :
InIFuncf md
He :
entry_labelf = Somel
Hp :
⊢
site_dominatesfn_domsf l −1 s = false

destruct func_facts_ _ Hmd Hin as b0 & rest & Hf & Hd & _ & _

md :
f :
l, n :
s :
i :
Hin :
InIFuncf md
He :
entry_labelf = Somel
Hp :
b0 :
rest :
listblock
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
⊢
site_dominatesfn_domsf l −1 s = false

unfold entry_label in He

md :
f :
l, n :
s :
i :
Hin :
InIFuncf md
He :
match fn_blocksf with
[ ]
⇒
None
b :: _
⇒
Someb_labelb
=
Somel
Hp :
b0 :
rest :
listblock
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
⊢
site_dominatesfn_domsf l −1 s = false

rewrite Hf in He

md :
f :
l, n :
s :
i :
Hin :
InIFuncf md
b0 :
He :
Someb_labelb0 = Somel
Hp :
rest :
listblock
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
⊢
site_dominatesfn_domsf l −1 s = false

injection He as ←

md :
f :
n :
s :
i :
Hin :
InIFuncf md
b0 :
Hp :
rest :
listblock
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
⊢
site_dominatesfn_domsf b_labelb0 −1 s = false

destruct dinst_site_ _ _ _ Hp as d & j & →

md :
f :
n :
i :
Hin :
InIFuncf md
b0 :
d :
j :
Z
Hp :
rest :
listblock
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
⊢
site_dominatesfn_domsf b_labelb0 −1 SAtd j = false

destruct position_inst_ _ _ _ _ Hp as b & kk & _ & _ & _ & → & _

md :
f :
n :
i :
Hin :
InIFuncf md
b0 :
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
rest :
listblock
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
⊢
site_dominatesfn_domsf b_labelb0 −1 SAtd Z.of_natkk = false

simpl

md :
f :
n :
i :
Hin :
InIFuncf md
b0 :
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
rest :
listblock
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
⊢
→
Z.of_natkk <? −1
=
false

destruct name_eqbd b_labelb0 eqn: E ; apply Z.ltb_ge ; lia |

md :
f :
n :
i :
Hin :
InIFuncf md
b0 :
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
rest :
listblock
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
E :
name_eqbd b_labelb0 = false
⊢

destruct dominatesfn_domsf d b_labelb0 eqn: Ed ; | reflexivity

md :
f :
n :
i :
Hin :
InIFuncf md
b0 :
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
rest :
listblock
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
E :
name_eqbd b_labelb0 = false
Ed :
⊢
true = false

rewrite dom_entry_top_ _ _ Hd _ Ed , name_eqb_refl in E

md :
f :
n :
i :
Hin :
InIFuncf md
b0 :
d :
kk :
nat
Hp :
Inn, SAtd Z.of_natkk, DInsti def_positionsf
rest :
listblock
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
E :
true = false
Ed :
⊢
true = false

discriminate E

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros md f l n s i Hmd Hin He Hp
destruct func_facts_ _ Hmd Hin as b0 & rest & Hf & Hd & _ & _
unfold entry_label in He
rewrite Hf in He
injection He as ←
destruct dinst_site_ _ _ _ Hp as d & j & →
destruct position_inst_ _ _ _ _ Hp as b & kk & _ & _ & _ & → & _
simpl
destruct name_eqbd b_labelb0 eqn: E ; apply Z.ltb_ge ; lia |
destruct dominatesfn_domsf d b_labelb0 eqn: Ed ; | reflexivity
rewrite dom_entry_top_ _ _ Hd _ Ed , name_eqb_refl in E
discriminate E

A single definition's relation survives a step

A replay holds of any environment e' that agrees with e on the name n and its single-definition operands, in any memory m' that persists from m.

376Lemma replays_change
∀ ge once e e′ m m′ n i
replaysge once e m n i
lookupn e′ = lookupn e
∀a, Ina inst_usesi → once_hasonce a = true → lookupa e′ = lookupa e
persistsm m′
replaysge once e′ m′ n i
Explore proof 6 tactics

Initial goal

⊢
∀ge : genv once : listname × def e : env e′ : listname × word m m′ : Memory.mem n : name i : inst, replaysge once e m n i → lookupn e′ = lookupn e → ∀a : name, Ina inst_usesi → once_hasonce a = true → lookupa e′ = lookupa e → persistsm m′ → replaysge once e′ m′ n i

intros ge once e e′ m m′ n i fr0 & m0 & e1 & l1 & m1 & Hs & Hn & Ha & Hp & Hfit Hn′ Ha′ Hp′

ge :
once :
listname × def
e :
e′ :
listname × word
m, m′ :
Memory.mem
n :
i :
fr0 :
m0 :
Memory.mem
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
Hs :
inst_stepge fr0 m0 i = SomeIContinuee1 l1 m1
Hn :
lookupn e1 = lookupn e
Ha :
∀a : name, Ina inst_usesi → once_hasonce a = true → lookupa fr_envfr0 = lookupa e
Hp :
Hn′ :
lookupn e′ = lookupn e
Ha′ :
∀a : name, Ina inst_usesi → once_hasonce a = true → lookupa e′ = lookupa e
Hp′ :
persistsm m′
⊢
replaysge once e′ m′ n i

exists fr0, m0, e1, l1, m1

ge :
once :
listname × def
e :
e′ :
listname × word
m, m′ :
Memory.mem
n :
i :
fr0 :
m0 :
Memory.mem
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
Hs :
inst_stepge fr0 m0 i = SomeIContinuee1 l1 m1
Hn :
lookupn e1 = lookupn e
Ha :
∀a : name, Ina inst_usesi → once_hasonce a = true → lookupa fr_envfr0 = lookupa e
Hp :
Hn′ :
lookupn e′ = lookupn e
Ha′ :
∀a : name, Ina inst_usesi → once_hasonce a = true → lookupa e′ = lookupa e
Hp′ :
persistsm m′
⊢
inst_stepge fr0 m0 i = SomeIContinuee1 l1 m1 ∧ lookupn e1 = lookupn e′ ∧ ∀a : name, Ina inst_usesi → once_hasonce a = true → lookupa fr_envfr0 = lookupa e′ ∧ persistsm1 m′ ∧ objects_fitm_regionsm1

split ; exact Hs |

ge :
once :
listname × def
e :
e′ :
listname × word
m, m′ :
Memory.mem
n :
i :
fr0 :
m0 :
Memory.mem
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
Hs :
inst_stepge fr0 m0 i = SomeIContinuee1 l1 m1
Hn :
lookupn e1 = lookupn e
Ha :
∀a : name, Ina inst_usesi → once_hasonce a = true → lookupa fr_envfr0 = lookupa e
Hp :
Hn′ :
lookupn e′ = lookupn e
Ha′ :
∀a : name, Ina inst_usesi → once_hasonce a = true → lookupa e′ = lookupa e
Hp′ :
persistsm m′
⊢
lookupn e1 = lookupn e′ ∧ ∀a : name, Ina inst_usesi → once_hasonce a = true → lookupa fr_envfr0 = lookupa e′ ∧ persistsm1 m′ ∧ objects_fitm_regionsm1

split ; congruence |

ge :
once :
listname × def
e :
e′ :
listname × word
m, m′ :
Memory.mem
n :
i :
fr0 :
m0 :
Memory.mem
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
Hs :
inst_stepge fr0 m0 i = SomeIContinuee1 l1 m1
Hn :
lookupn e1 = lookupn e
Ha :
∀a : name, Ina inst_usesi → once_hasonce a = true → lookupa fr_envfr0 = lookupa e
Hp :
Hn′ :
lookupn e′ = lookupn e
Ha′ :
∀a : name, Ina inst_usesi → once_hasonce a = true → lookupa e′ = lookupa e
Hp′ :
persistsm m′
⊢
∀a : name, Ina inst_usesi → once_hasonce a = true → lookupa fr_envfr0 = lookupa e′ ∧ persistsm1 m′ ∧ objects_fitm_regionsm1

split ; intros a Hu Ho ; rewrite Ha′_ Hu Ho ; exact Ha_ Hu Ho |

ge :
once :
listname × def
e :
e′ :
listname × word
m, m′ :
Memory.mem
n :
i :
fr0 :
m0 :
Memory.mem
e1 :
l1 :
listname × optionZ
m1 :
Memory.mem
Hs :
inst_stepge fr0 m0 i = SomeIContinuee1 l1 m1
Hn :
lookupn e1 = lookupn e
Ha :
∀a : name, Ina inst_usesi → once_hasonce a = true → lookupa fr_envfr0 = lookupa e
Hp :
Hn′ :
lookupn e′ = lookupn e
Ha′ :
∀a : name, Ina inst_usesi → once_hasonce a = true → lookupa e′ = lookupa e
Hp′ :
persistsm m′

exact conjpersists_trans_ _ _ Hp Hp′ Hfit

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge once e e′ m m′ n i fr0 & m0 & e1 & l1 & m1 & Hs & Hn & Ha & Hp & Hfit Hn′ Ha′ Hp′
exists fr0, m0, e1, l1, m1
split ; exact Hs |
split ; congruence |
split ; intros a Hu Ho ; rewrite Ha′_ Hu Ho ; exact Ha_ Hu Ho |
exact conjpersists_trans_ _ _ Hp Hp′ Hfit

The property rp of a name survives what replays_change allows: an environment that keeps the name and its single-definition operands, and a memory that persists. The scope lemmas hold of any such rp.

390Definition movesrp : listname × def → env → Memory.mem → name → inst → Prop : Prop ≔
∀once e e′ m m′ n i, rponce e m n i → lookupn e′ = lookupn e → ∀a, Ina inst_usesi → once_hasonce a = true → lookupa e′ = lookupa e → persistsm m′ → rponce e′ m′ n i

A frame's scope of a property rp that moves holds in any memory m' that persists from m.

398Lemma scope_with_mem
∀ rp fr m m′
scope_withrp fr m′
Explore proof 2 tactics

Initial goal

⊢
∀rp : listname × def → env → Memory.mem → name → inst → Prop fr : frame m m′ : Memory.mem, movesrp → scope_withrp fr m → persistsm m′ → scope_withrp fr m′

intros rp fr m m′ Hmv H Hp l k n s i Hpt Hn Hr Hpos Hsd

rp :
listname × def → env → Memory.mem → name → inst → Prop
fr :
m, m′ :
Memory.mem
Hmv :
H :
scope_withrp fr m
Hp :
persistsm m′
l :
k :
Z
n :
s :
i :
Hpt :
point_sitefr_fnfr fr_atfr = Somel, k
Hr :
replayablei = true
Hpos :
Hsd :

exact Hmv_ _ _ _ _ _ _ H_ _ _ _ _ Hpt Hn Hr Hpos Hsd eq_refl λ_ _ _ ⇒ eq_refl Hp

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros rp fr m m′ Hmv H Hp l k n s i Hpt Hn Hr Hpos Hsd
exact Hmv_ _ _ _ _ _ _ H_ _ _ _ _ Hpt Hn Hr Hpos Hsd eq_refl λ_ _ _ ⇒ eq_refl Hp

So scope_holds holds in any memory that persists.

406Lemma scope_mem
∀ ge fr m m′
persistsm m′
scope_holdsge fr m′
Explore proof 2 tactics

Initial goal

⊢
∀ge : genv fr : frame m m′ : Memory.mem, scope_holdsge fr m → persistsm m′ → scope_holdsge fr m′

intros ge

ge :
⊢
∀fr : frame m m′ : Memory.mem, scope_holdsge fr m → persistsm m′ → scope_holdsge fr m′

exact λfr m m′ ⇒ scope_with_mem_ fr m m′ replays_changege

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge
exact λfr m m′ ⇒ scope_with_mem_ fr m m′ replays_changege

The instruction i is not a check_ahead, whose result a doomed frame holds though its check did not pass.

411Definition ahead_freei : inst : bool ≔
match i with
Let_ _ CheckAhead_ _ _ _ _ _
⇒
false
_
⇒
true

Each single definition in scope at fr's point that is not a check_ahead replays. Guard chains, offset intervals and pointer distances read only such definitions.

417Definition scope_plainge : genv fr : frame m : Memory.mem : Prop ≔
scope_withλonce e m n i ⇒ ahead_freei = true → replaysge once e m n i fr m

A frame that holds its scope holds its plain scope.

421Lemma scope_plain_of
∀ ge fr m
Explore proof 2 tactics

Initial goal

⊢
∀ge : genv fr : frame m : Memory.mem, scope_holdsge fr m → scope_plainge fr m

intros ge fr m H l k n s i Hpt Hn Hr Hpos Hsd _

ge :
fr :
m :
Memory.mem
H :
l :
k :
Z
n :
s :
i :
Hpt :
point_sitefr_fnfr fr_atfr = Somel, k
Hr :
replayablei = true
Hpos :
Hsd :

exact H_ _ _ _ _ Hpt Hn Hr Hpos Hsd

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge fr m H l k n s i Hpt Hn Hr Hpos Hsd _
exact H_ _ _ _ _ Hpt Hn Hr Hpos Hsd

The names X defined at index k of a reachable block l change neither a single definition n in scope there nor its single-definition operands: where the environment e' differs from e only on X, both read the same values. This rests on no_use_redefined.

429Lemma scope_moves
∀ f b0 rest l k X : listname n s i e e′ : env
fn_blocksf = b0 :: rest
block_intervalsb0 :: rest = Somefn_domsf
∀x, Inx X → ∃D, Inx, SAtl k, D def_positionsf
∀a, ¬Ina X → lookupa e′ = lookupa e
site_dominatesfn_domsf l k s = true
lookupn e′ = lookupn e ∧ ∀a, Ina inst_usesi → once_hassingle_definitionsf a = true → lookupa e′ = lookupa e
Explore proof 18 tactics

Initial goal

⊢
∀f : func b0 : block rest : listblock l : name k : Z X : listname n : name s : site i : inst e e′ : env, fn_blocksf = b0 :: rest → block_intervalsb0 :: rest = Somefn_domsf → definitions_dominatef fn_domsf = true → is_reachablefn_domsf l = true → ∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf → ∀a : name, ¬Ina X → lookupa e′ = lookupa e → lookupn single_definitionsf = SomeDInsti → Inn, s, DInsti def_positionsf → site_dominatesfn_domsf l k s = true → lookupn e′ = lookupn e ∧ ∀a : name, Ina inst_usesi → once_hassingle_definitionsf a = true → lookupa e′ = lookupa e

intros f b0 rest l k X n s i e e′ Hf Hd Hdd Hr HX He Hn Hp Hs

f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
⊢
lookupn e′ = lookupn e ∧ ∀a : name, Ina inst_usesi → once_hassingle_definitionsf a = true → lookupa e′ = lookupa e

split

2 open

f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
⊢
lookupn e′ = lookupn e
focused goal
f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
⊢
∀a : name, Ina inst_usesi → once_hassingle_definitionsf a = true → lookupa e′ = lookupa e

–apply He

2 open

f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
⊢
¬Inn X
deferred goal
f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
⊢
∀a : name, Ina inst_usesi → once_hassingle_definitionsf a = true → lookupa e′ = lookupa e

intros Hin

2 open

f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
Hin :
Inn X
⊢
False
deferred goal
f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
⊢
∀a : name, Ina inst_usesi → once_hassingle_definitionsf a = true → lookupa e′ = lookupa e

destruct HX_ Hin as D HD

2 open

f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
Hin :
Inn X
D :
HD :
Inn, SAtl k, D def_positionsf
⊢
False
deferred goal
f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
⊢
∀a : name, Ina inst_usesi → once_hassingle_definitionsf a = true → lookupa e′ = lookupa e

destruct once_position_ _ _ Hn as s0 & _ & Hu

2 open

f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
Hin :
Inn X
D :
HD :
Inn, SAtl k, D def_positionsf
s0 :
Hu :
∀s′ : site d′ : def, Inn, s′, d′ def_positionsf → s′ = s0 ∧ d′ = DInsti
⊢
False
deferred goal
f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
⊢
∀a : name, Ina inst_usesi → once_hassingle_definitionsf a = true → lookupa e′ = lookupa e

destruct Hu_ _ HD as E1 _

2 open

f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
Hin :
Inn X
D :
HD :
Inn, SAtl k, D def_positionsf
s0 :
Hu :
∀s′ : site d′ : def, Inn, s′, d′ def_positionsf → s′ = s0 ∧ d′ = DInsti
E1 :
SAtl k = s0
⊢
False
deferred goal
f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
⊢
∀a : name, Ina inst_usesi → once_hassingle_definitionsf a = true → lookupa e′ = lookupa e

destruct Hu_ _ Hp as E2 _

2 open

f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
Hin :
Inn X
D :
HD :
Inn, SAtl k, D def_positionsf
s0 :
Hu :
∀s′ : site d′ : def, Inn, s′, d′ def_positionsf → s′ = s0 ∧ d′ = DInsti
E1 :
SAtl k = s0
E2 :
s = s0
⊢
False
deferred goal
f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
⊢
∀a : name, Ina inst_usesi → once_hassingle_definitionsf a = true → lookupa e′ = lookupa e

rewrite E2 , <- E1 in Hs

2 open

f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
s0 :
Hs :
site_dominatesfn_domsf l k SAtl k = true
Hin :
Inn X
D :
HD :
Inn, SAtl k, D def_positionsf
Hu :
∀s′ : site d′ : def, Inn, s′, d′ def_positionsf → s′ = s0 ∧ d′ = DInsti
E1 :
SAtl k = s0
E2 :
s = s0
⊢
False
deferred goal
f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
⊢
∀a : name, Ina inst_usesi → once_hassingle_definitionsf a = true → lookupa e′ = lookupa e

simpl in Hs

2 open

f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
s0 :
Hs :
→
k <? k
=
true
Hin :
Inn X
D :
HD :
Inn, SAtl k, D def_positionsf
Hu :
∀s′ : site d′ : def, Inn, s′, d′ def_positionsf → s′ = s0 ∧ d′ = DInsti
E1 :
SAtl k = s0
E2 :
s = s0
⊢
False
deferred goal
f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
⊢
∀a : name, Ina inst_usesi → once_hassingle_definitionsf a = true → lookupa e′ = lookupa e

rewrite name_eqb_refl , Z.ltb_irrefl in Hs

2 open

f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
s0 :
Hs :
false = true
Hin :
Inn X
D :
HD :
Inn, SAtl k, D def_positionsf
Hu :
∀s′ : site d′ : def, Inn, s′, d′ def_positionsf → s′ = s0 ∧ d′ = DInsti
E1 :
SAtl k = s0
E2 :
s = s0
⊢
False
deferred goal
f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
⊢
∀a : name, Ina inst_usesi → once_hassingle_definitionsf a = true → lookupa e′ = lookupa e

discriminate Hs

deferred goal
f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
⊢
∀a : name, Ina inst_usesi → once_hassingle_definitionsf a = true → lookupa e′ = lookupa e

–intros a Hu Ho

f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
a :
Hu :
⊢
lookupa e′ = lookupa e

apply He

f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
a :
Hu :
⊢
¬Ina X

intros Hin

f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
a :
Hu :
Hin :
Ina X
⊢
False

destruct HX_ Hin as D HD

f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
s :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
Hp :
Hs :
site_dominatesfn_domsf l k s = true
a :
Hu :
Hin :
Ina X
D :
HD :
Ina, SAtl k, D def_positionsf
⊢
False

destruct dinst_site_ _ _ _ Hp as d & j & →

f :
b0 :
rest :
listblock
l :
k :
Z
X :
listname
n :
i :
e, e′ :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hr :
HX :
∀x : name, Inx X → ∃D : def, Inx, SAtl k, D def_positionsf
He :
∀a : name, ¬Ina X → lookupa e′ = lookupa e
d :
j :
Z
Hs :
site_dominatesfn_domsf l k SAtd j = true
Hp :
a :
Hu :
Hin :
Ina X
D :
HD :
Ina, SAtl k, D def_positionsf
⊢
False

exact no_use_redefined_ _ _ _ _ _ _ _ _ _ _ D Hf Hd Hdd Hn Hp Hr Hs HD Ho Hu

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros f b0 rest l k X n s i e e′ Hf Hd Hdd Hr HX He Hn Hp Hs
split
–apply He
intros Hin
destruct HX_ Hin as D HD
destruct once_position_ _ _ Hn as s0 & _ & Hu
destruct Hu_ _ HD as E1 _
destruct Hu_ _ Hp as E2 _
rewrite E2 , <- E1 in Hs
simpl in Hs
rewrite name_eqb_refl , Z.ltb_irrefl in Hs
discriminate Hs
–intros a Hu Ho
apply He
intros Hin
destruct HX_ Hin as D HD
destruct dinst_site_ _ _ _ Hp as d & j & →
exact no_use_redefined_ _ _ _ _ _ _ _ _ _ _ D Hf Hd Hdd Hn Hp Hr Hs HD Ho Hu

An instruction defines its names at its own index.

450Lemma inst_defs_here
∀ f b k i x
nth_errorb_instsb k = Somei
Inx mapfst inst_temp_defsi
∃D, Inx, SAtb_labelb Z.of_natk, D def_positionsf
Explore proof 4 tactics

Initial goal

⊢
∀f : func b : block k : nat i : inst, Inb fn_blocksf → nth_errorb_instsb k = Somei → ∀x : name, Inx mapfst inst_temp_defsi → ∃D : def, Inx, SAtb_labelb Z.of_natk, D def_positionsf

intros f b k i Hb Hk x Hx

f :
k :
nat
i :
Hb :
Hk :
nth_errorb_instsb k = Somei
x :
Hx :
Inx mapfst inst_temp_defsi
⊢
∃D : def, Inx, SAtb_labelb Z.of_natk, D def_positionsf

apply in_map_iff in Hx as dk & ← & Hdk

f :
k :
nat
i :
Hb :
Hk :
nth_errorb_instsb k = Somei
dk :
Hdk :
⊢
∃D : def, Infstdk, SAtb_labelb Z.of_natk, D def_positionsf

exists DInsti

f :
k :
nat
i :
Hb :
Hk :
nth_errorb_instsb k = Somei
dk :
Hdk :
⊢
Infstdk, SAtb_labelb Z.of_natk, DInsti def_positionsf

exact inst_position_ _ _ _ _ Hb Hk Hdk

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros f b k i Hb Hk x Hx
apply in_map_iff in Hx as dk & ← & Hdk
exists DInsti
exact inst_position_ _ _ _ _ Hb Hk Hdk

A block's phis define their names before its first instruction.

459Lemma phi_defs_here
∀ f b x
∃D, Inx, SAtb_labelb −1, D def_positionsf
Explore proof 4 tactics

Initial goal

⊢
∀f : func b : block, Inb fn_blocksf → ∀x : name, Inx mapphi_name b_phisb → ∃D : def, Inx, SAtb_labelb −1, D def_positionsf

intros f b Hb x Hx

f :
Hb :
x :
Hx :
⊢
∃D : def, Inx, SAtb_labelb −1, D def_positionsf

apply in_map_iff in Hx as d k pairs & ← & Hph

f :
Hb :
d :
pairs :
listname × value
Hph :
InPhid k pairs b_phisb
⊢
∃D : def, Inphi_namePhid k pairs, SAtb_labelb −1, D def_positionsf

exists DPhiPhid k pairs

f :
Hb :
d :
pairs :
listname × value
Hph :
InPhid k pairs b_phisb
⊢
Inphi_namePhid k pairs, SAtb_labelb −1, DPhiPhid k pairs def_positionsf

exact phi_position_ _ _ _ _ Hb Hph

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros f b Hb x Hx
apply in_map_iff in Hx as d k pairs & ← & Hph
exists DPhiPhid k pairs
exact phi_position_ _ _ _ _ Hb Hph

An instruction's single-definition operand is not one of the names it defines.

469Lemma operand_not_defined
∀ f b0 rest b k i a
fn_blocksf = b0 :: rest
block_intervalsb0 :: rest = Somefn_domsf
nth_errorb_instsb k = Somei
¬Ina mapfst inst_temp_defsi
Explore proof 12 tactics

Initial goal

⊢
∀f : func b0 : block rest : listblock b : block k : nat i : inst a : name, fn_blocksf = b0 :: rest → block_intervalsb0 :: rest = Somefn_domsf → definitions_dominatef fn_domsf = true → Inb fn_blocksf → is_reachablefn_domsf b_labelb = true → nth_errorb_instsb k = Somei → Ina inst_usesi → once_hassingle_definitionsf a = true → ¬Ina mapfst inst_temp_defsi

intros f b0 rest b k i a Hf Hd Hdd Hb Hr Hk Hu Ho Hin

f :
b0 :
rest :
listblock
k :
nat
i :
a :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hb :
Hk :
nth_errorb_instsb k = Somei
Hu :
Hin :
Ina mapfst inst_temp_defsi
⊢
False

unfold once_has in Ho

f :
b0 :
rest :
listblock
k :
nat
i :
a :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hb :
Hk :
nth_errorb_instsb k = Somei
Hu :
Ho :
Some_
⇒
true
None
⇒
false
=
true
Hin :
Ina mapfst inst_temp_defsi
⊢
False

destruct lookupa single_definitionsf as D | eqn: Ea ; | discriminate Ho

f :
b0 :
rest :
listblock
k :
nat
i :
a :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hb :
Hk :
nth_errorb_instsb k = Somei
Hu :
D :
Ea :
Ho :
true = true
Hin :
Ina mapfst inst_temp_defsi
⊢
False

destruct use_dominated_ _ _ _ _ _ _ Hdd Hb Hr Hk Hu Ea as s & Hs & Hsd

f :
b0 :
rest :
listblock
k :
nat
i :
a :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hb :
Hk :
nth_errorb_instsb k = Somei
Hu :
D :
Ea :
Ho :
true = true
Hin :
Ina mapfst inst_temp_defsi
s :
Hs :
Ina, s, D def_positionsf
Hsd :
site_dominatesfn_domsf b_labelb Z.of_natk s = true
⊢
False

destruct inst_defs_here_ _ _ _ Hb Hk _ Hin as D′ HD′

f :
b0 :
rest :
listblock
k :
nat
i :
a :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hb :
Hk :
nth_errorb_instsb k = Somei
Hu :
D :
Ea :
Ho :
true = true
Hin :
Ina mapfst inst_temp_defsi
s :
Hs :
Ina, s, D def_positionsf
Hsd :
site_dominatesfn_domsf b_labelb Z.of_natk s = true
D′ :
HD′ :
Ina, SAtb_labelb Z.of_natk, D′ def_positionsf
⊢
False

destruct once_position_ _ _ Ea as s0 & _ & Hun

f :
b0 :
rest :
listblock
k :
nat
i :
a :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hb :
Hk :
nth_errorb_instsb k = Somei
Hu :
D :
Ea :
Ho :
true = true
Hin :
Ina mapfst inst_temp_defsi
s :
Hs :
Ina, s, D def_positionsf
Hsd :
site_dominatesfn_domsf b_labelb Z.of_natk s = true
D′ :
HD′ :
Ina, SAtb_labelb Z.of_natk, D′ def_positionsf
s0 :
Hun :
∀s′ : site d′ : def, Ina, s′, d′ def_positionsf → s′ = s0 ∧ d′ = D
⊢
False

destruct Hun_ _ Hs as → _

f :
b0 :
rest :
listblock
k :
nat
i :
a :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hb :
Hk :
nth_errorb_instsb k = Somei
Hu :
D :
Ea :
Ho :
true = true
Hin :
Ina mapfst inst_temp_defsi
s0 :
Hsd :
site_dominatesfn_domsf b_labelb Z.of_natk s0 = true
Hs :
Ina, s0, D def_positionsf
D′ :
HD′ :
Ina, SAtb_labelb Z.of_natk, D′ def_positionsf
Hun :
∀s′ : site d′ : def, Ina, s′, d′ def_positionsf → s′ = s0 ∧ d′ = D
⊢
False

destruct Hun_ _ HD′ as E _

f :
b0 :
rest :
listblock
k :
nat
i :
a :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hb :
Hk :
nth_errorb_instsb k = Somei
Hu :
D :
Ea :
Ho :
true = true
Hin :
Ina mapfst inst_temp_defsi
s0 :
Hsd :
site_dominatesfn_domsf b_labelb Z.of_natk s0 = true
Hs :
Ina, s0, D def_positionsf
D′ :
HD′ :
Ina, SAtb_labelb Z.of_natk, D′ def_positionsf
Hun :
∀s′ : site d′ : def, Ina, s′, d′ def_positionsf → s′ = s0 ∧ d′ = D
E :
SAtb_labelb Z.of_natk = s0
⊢
False

rewrite <- E in Hsd

f :
b0 :
rest :
listblock
k :
nat
i :
a :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hb :
Hk :
nth_errorb_instsb k = Somei
Hu :
D :
Ea :
Ho :
true = true
Hin :
Ina mapfst inst_temp_defsi
s0 :
Hsd :
site_dominatesfn_domsf b_labelb Z.of_natk SAtb_labelb Z.of_natk = true
Hs :
Ina, s0, D def_positionsf
D′ :
HD′ :
Ina, SAtb_labelb Z.of_natk, D′ def_positionsf
Hun :
∀s′ : site d′ : def, Ina, s′, d′ def_positionsf → s′ = s0 ∧ d′ = D
E :
SAtb_labelb Z.of_natk = s0
⊢
False

simpl in Hsd

f :
b0 :
rest :
listblock
k :
nat
i :
a :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hb :
Hk :
nth_errorb_instsb k = Somei
Hu :
D :
Ea :
Ho :
true = true
Hin :
Ina mapfst inst_temp_defsi
s0 :
Hsd :
→
Z.of_natk <? Z.of_natk
=
true
Hs :
Ina, s0, D def_positionsf
D′ :
HD′ :
Ina, SAtb_labelb Z.of_natk, D′ def_positionsf
Hun :
∀s′ : site d′ : def, Ina, s′, d′ def_positionsf → s′ = s0 ∧ d′ = D
E :
SAtb_labelb Z.of_natk = s0
⊢
False

rewrite name_eqb_refl , Z.ltb_irrefl in Hsd

f :
b0 :
rest :
listblock
k :
nat
i :
a :
Hf :
fn_blocksf = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsf
Hb :
Hk :
nth_errorb_instsb k = Somei
Hu :
D :
Ea :
Ho :
true = true
Hin :
Ina mapfst inst_temp_defsi
s0 :
Hsd :
false = true
Hs :
Ina, s0, D def_positionsf
D′ :
HD′ :
Ina, SAtb_labelb Z.of_natk, D′ def_positionsf
Hun :
∀s′ : site d′ : def, Ina, s′, d′ def_positionsf → s′ = s0 ∧ d′ = D
E :
SAtb_labelb Z.of_natk = s0
⊢
False

discriminate Hsd

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros f b0 rest b k i a Hf Hd Hdd Hb Hr Hk Hu Ho Hin
unfold once_has in Ho
destruct lookupa single_definitionsf as D | eqn: Ea ; | discriminate Ho
destruct use_dominated_ _ _ _ _ _ _ Hdd Hb Hr Hk Hu Ea as s & Hs & Hsd
destruct inst_defs_here_ _ _ _ Hb Hk _ Hin as D′ HD′
destruct once_position_ _ _ Ea as s0 & _ & Hun
destruct Hun_ _ Hs as → _
destruct Hun_ _ HD′ as E _
rewrite <- E in Hsd
simpl in Hsd
rewrite name_eqb_refl , Z.ltb_irrefl in Hsd
discriminate Hsd

Scope along a block

A shaped frame inside block l: its function is the module's, l is reachable, and its instructions are the suffix of l's block b from an index k, before b's jump.

489Lemma shaped_exec
∀ md fr l is j
shapedmd fr
fr_atfr = Execl is j
InIFuncfr_fnfr md ∧ is_reachablefn_domsfr_fnfr l = true ∧ ∃b k, find_blockl fn_blocksfr_fnfr = Someb ∧ k ≤ lengthb_instsb%nat ∧ is = skipnk b_instsb ∧ j = b_jumpb
Explore proof 5 tactics

Initial goal

⊢
∀md : module fr : frame l : name is : listinst j : jump, shapedmd fr → fr_atfr = Execl is j → InIFuncfr_fnfr md ∧ is_reachablefn_domsfr_fnfr l = true ∧ ∃b : block k : nat, find_blockl fn_blocksfr_fnfr = Someb ∧ k ≤ Datatypes.lengthb_instsb%nat ∧ is = skipnk b_instsb ∧ j = b_jumpb

intros md fr l is j H Ha

md :
fr :
l :
is :
listinst
j :
H :
shapedmd fr
Ha :
fr_atfr = Execl is j
⊢
InIFuncfr_fnfr md ∧ is_reachablefn_domsfr_fnfr l = true ∧ ∃b : block k : nat, find_blockl fn_blocksfr_fnfr = Someb ∧ k ≤ Datatypes.lengthb_instsb%nat ∧ is = skipnk b_instsb ∧ j = b_jumpb

unfold shaped in H

md :
fr :
l :
is :
listinst
j :
H :
InIFuncfr_fnfr md
∧
match fr_atfr with
⇒
entry_labelfr_fnfr = Somel
Enterl from
⇒
is_reachablefn_domsfr_fnfr l = true ∧ from = None → entry_labelfr_fnfr = Somel
Execl is j
⇒
is_reachablefn_domsfr_fnfr l = true ∧ ∃b : block k : nat, find_blockl fn_blocksfr_fnfr = Someb ∧ k ≤ Datatypes.lengthb_instsb%nat ∧ is = skipnk b_instsb ∧ j = b_jumpb
Ha :
fr_atfr = Execl is j
⊢
InIFuncfr_fnfr md ∧ is_reachablefn_domsfr_fnfr l = true ∧ ∃b : block k : nat, find_blockl fn_blocksfr_fnfr = Someb ∧ k ≤ Datatypes.lengthb_instsb%nat ∧ is = skipnk b_instsb ∧ j = b_jumpb

cbv zeta in H

md :
fr :
l :
is :
listinst
j :
H :
InIFuncfr_fnfr md
∧
match fr_atfr with
⇒
entry_labelfr_fnfr = Somel
Enterl from
⇒
is_reachablefn_domsfr_fnfr l = true ∧ from = None → entry_labelfr_fnfr = Somel
Execl is j
⇒
is_reachablefn_domsfr_fnfr l = true ∧ ∃b : block k : nat, find_blockl fn_blocksfr_fnfr = Someb ∧ k ≤ Datatypes.lengthb_instsb%nat ∧ is = skipnk b_instsb ∧ j = b_jumpb
Ha :
fr_atfr = Execl is j
⊢
InIFuncfr_fnfr md ∧ is_reachablefn_domsfr_fnfr l = true ∧ ∃b : block k : nat, find_blockl fn_blocksfr_fnfr = Someb ∧ k ≤ Datatypes.lengthb_instsb%nat ∧ is = skipnk b_instsb ∧ j = b_jumpb

rewrite Ha in H

md :
fr :
l :
is :
listinst
j :
H :
InIFuncfr_fnfr md ∧ is_reachablefn_domsfr_fnfr l = true ∧ ∃b : block k : nat, find_blockl fn_blocksfr_fnfr = Someb ∧ k ≤ Datatypes.lengthb_instsb%nat ∧ is = skipnk b_instsb ∧ j = b_jumpb
Ha :
fr_atfr = Execl is j
⊢
InIFuncfr_fnfr md ∧ is_reachablefn_domsfr_fnfr l = true ∧ ∃b : block k : nat, find_blockl fn_blocksfr_fnfr = Someb ∧ k ≤ Datatypes.lengthb_instsb%nat ∧ is = skipnk b_instsb ∧ j = b_jumpb

exact H

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros md fr l is j H Ha
unfold shaped in H
cbv zeta in H
rewrite Ha in H
exact H

The instruction at index k of block l is i.

497Lemma site_inst
∀ md f l b k s n i′
InIFuncf md
Inn, s, DInsti′ def_positionsf
s = SAtl Z.of_natk
nth_errorb_instsb k = Somei′
Explore proof 7 tactics

Initial goal

⊢
∀md : module f : func l : name b : block k : nat s : site n : name i′ : inst, checked_modulemd → InIFuncf md → find_blockl fn_blocksf = Someb → Inn, s, DInsti′ def_positionsf → s = SAtl Z.of_natk → nth_errorb_instsb k = Somei′

intros md f l b k s n i′ Hmd Hin Hb Hp →

md :
f :
l :
k :
nat
n :
i′ :
Hin :
InIFuncf md
Hb :
Hp :
Inn, SAtl Z.of_natk, DInsti′ def_positionsf
⊢
nth_errorb_instsb k = Somei′

destruct func_facts_ _ Hmd Hin as _ & _ & _ & _ & Hnd & _

md :
f :
l :
k :
nat
n :
i′ :
Hin :
InIFuncf md
Hb :
Hp :
Inn, SAtl Z.of_natk, DInsti′ def_positionsf
Hnd :
⊢
nth_errorb_instsb k = Somei′

destruct position_inst_ _ _ _ _ Hp as b′ & kk & Hb′ & Hl & Hk & Ej & _

md :
f :
l :
k :
nat
n :
i′ :
Hin :
InIFuncf md
Hb :
Hp :
Inn, SAtl Z.of_natk, DInsti′ def_positionsf
Hnd :
b′ :
kk :
nat
Hb′ :
Inb′ fn_blocksf
Hl :
b_labelb′ = l
Hk :
nth_errorb_instsb′ kk = Somei′
Ej :
Z.of_natk = Z.of_natkk
⊢
nth_errorb_instsb k = Somei′

rewrite find_block_unique_ _ _ _ Hnd Hb Hb′ Hl in Hk

md :
f :
l :
k :
nat
n :
i′ :
Hin :
InIFuncf md
Hb :
Hp :
Inn, SAtl Z.of_natk, DInsti′ def_positionsf
Hnd :
b′ :
kk :
nat
Hb′ :
Inb′ fn_blocksf
Hl :
b_labelb′ = l
Hk :
nth_errorb_instsb kk = Somei′
Ej :
Z.of_natk = Z.of_natkk
⊢
nth_errorb_instsb k = Somei′

apply Nat2Z.inj in Ej

md :
f :
l :
k :
nat
n :
i′ :
Hin :
InIFuncf md
Hb :
Hp :
Inn, SAtl Z.of_natk, DInsti′ def_positionsf
Hnd :
b′ :
kk :
nat
Hb′ :
Inb′ fn_blocksf
Hl :
b_labelb′ = l
Hk :
nth_errorb_instsb kk = Somei′
Ej :
k = kk
⊢
nth_errorb_instsb k = Somei′

subst

md :
f :
n :
i′ :
Hin :
InIFuncf md
b′ :
kk :
nat
Hp :
Inn, SAtb_labelb′ Z.of_natkk, DInsti′ def_positionsf
Hb :
Hnd :
Hb′ :
Inb′ fn_blocksf
Hk :
nth_errorb_instsb kk = Somei′
⊢
nth_errorb_instsb kk = Somei′

exact Hk

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros md f l b k s n i′ Hmd Hin Hb Hp →
destruct func_facts_ _ Hmd Hin as _ & _ & _ & _ & Hnd & _
destruct position_inst_ _ _ _ _ Hp as b′ & kk & Hb′ & Hl & Hk & Ej & _
rewrite find_block_unique_ _ _ _ Hnd Hb Hb′ Hl in Hk
apply Nat2Z.inj in Ej
subst
exact Hk

From index k to k + 1 of block l, over the instruction i at k: where the next frame fr' differs from fr only on i's names and memory persists from m to m', a scope of a property rp that moves holds at fr' if it held at fr, provided i's own name satisfies rp when i is replayable.

512Lemma scope_step_with
∀ rp md fr fr′ m m′ l b k i
InIFuncfr_fnfr md
fr_fnfr′ = fr_fnfr
nth_errorb_instsb k = Somei
point_sitefr_fnfr fr_atfr = Somel, Z.of_natk
point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk
∀a, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
persistsm m′
∀n, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i
scope_withrp fr m
scope_withrp fr′ m′
Explore proof 16 tactics

Initial goal

⊢
∀rp : listname × def → env → Memory.mem → name → inst → Prop md : module fr fr′ : frame m m′ : Memory.mem l : name b : block k : nat i : inst, movesrp → checked_modulemd → InIFuncfr_fnfr md → fr_fnfr′ = fr_fnfr → is_reachablefn_domsfr_fnfr l = true → find_blockl fn_blocksfr_fnfr = Someb → nth_errorb_instsb k = Somei → point_sitefr_fnfr fr_atfr = Somel, Z.of_natk → point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk → ∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr → persistsm m′ → ∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i → scope_withrp fr m → scope_withrp fr′ m′

intros rp md fr fr′ m m′ l b k i Hmv Hmd Hin Hf′ Hr Hb Hk Hpt0 Hpt1 He Hp Hself Hold l′ k′ n s i′ Hpt Hn Hrp Hpos Hsd

rp :
listname × def → env → Memory.mem → name → inst → Prop
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hmv :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natk
Hpt1 :
point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hself :
∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i
Hold :
scope_withrp fr m
l′ :
k′ :
Z
n :
s :
i′ :
Hpt :
point_sitefr_fnfr′ fr_atfr′ = Somel′, k′
Hn :
Hrp :
replayablei′ = true
Hpos :
Inn, s, DInsti′ def_positionsfr_fnfr′
Hsd :
site_dominatesfn_domsfr_fnfr′ l′ k′ s = true
⊢
rpsingle_definitionsfr_fnfr′ fr_envfr′ m′ n i′

rewrite Hf′ in *

rp :
listname × def → env → Memory.mem → name → inst → Prop
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hmv :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natk
Hpt1 :
point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hself :
∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i
Hold :
scope_withrp fr m
l′ :
k′ :
Z
n :
s :
i′ :
Hpt :
point_sitefr_fnfr fr_atfr′ = Somel′, k′
Hrp :
replayablei′ = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l′ k′ s = true
⊢
rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i′

rewrite Hpt1 in Hpt

rp :
listname × def → env → Memory.mem → name → inst → Prop
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hmv :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natk
Hpt1 :
point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hself :
∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i
Hold :
scope_withrp fr m
l′ :
k′ :
Z
n :
s :
i′ :
Hpt :
Somel, Z.of_natSk = Somel′, k′
Hrp :
replayablei′ = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l′ k′ s = true
⊢
rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i′

injection Hpt as ← ←

rp :
listname × def → env → Memory.mem → name → inst → Prop
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hmv :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natk
Hpt1 :
point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hself :
∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i
Hold :
scope_withrp fr m
n :
s :
i′ :
Hrp :
replayablei′ = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l Z.posPosDef.Pos.of_succ_natk s = true
⊢
rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i′

assert Hsd1 : site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true by rewrite <- Hsd ; f_equal ; lia

rp :
listname × def → env → Memory.mem → name → inst → Prop
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hmv :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natk
Hpt1 :
point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hself :
∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i
Hold :
scope_withrp fr m
n :
s :
i′ :
Hrp :
replayablei′ = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l Z.posPosDef.Pos.of_succ_natk s = true
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
⊢
rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i′

clear Hsd

rp :
listname × def → env → Memory.mem → name → inst → Prop
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hmv :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natk
Hpt1 :
point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hself :
∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i
Hold :
scope_withrp fr m
n :
s :
i′ :
Hrp :
replayablei′ = true
Hpos :
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
⊢
rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i′

destruct site_next_ _ _ _ Hsd1 as Es | Hsd0

2 open

rp :
listname × def → env → Memory.mem → name → inst → Prop
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hmv :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natk
Hpt1 :
point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hself :
∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i
Hold :
scope_withrp fr m
n :
s :
i′ :
Hrp :
replayablei′ = true
Hpos :
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Es :
s = SAtl Z.of_natk
⊢
rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i′
focused goal
rp :
listname × def → env → Memory.mem → name → inst → Prop
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hmv :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natk
Hpt1 :
point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hself :
∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i
Hold :
scope_withrp fr m
n :
s :
i′ :
Hrp :
replayablei′ = true
Hpos :
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Hsd0 :
site_dominatesfn_domsfr_fnfr l Z.of_natk s = true
⊢
rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i′

–pose proof site_inst_ _ _ _ _ _ _ _ Hmd Hin Hb Hpos Es as Hk′

2 open

rp :
listname × def → env → Memory.mem → name → inst → Prop
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hmv :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natk
Hpt1 :
point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hself :
∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i
Hold :
scope_withrp fr m
n :
s :
i′ :
Hrp :
replayablei′ = true
Hpos :
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Es :
s = SAtl Z.of_natk
Hk′ :
nth_errorb_instsb k = Somei′
⊢
rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i′
deferred goal
rp :
listname × def → env → Memory.mem → name → inst → Prop
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hmv :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natk
Hpt1 :
point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hself :
∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i
Hold :
scope_withrp fr m
n :
s :
i′ :
Hrp :
replayablei′ = true
Hpos :
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Hsd0 :
site_dominatesfn_domsfr_fnfr l Z.of_natk s = true
⊢
rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i′

rewrite Hk in Hk′

2 open

rp :
listname × def → env → Memory.mem → name → inst → Prop
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hmv :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natk
Hpt1 :
point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hself :
∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i
Hold :
scope_withrp fr m
n :
s :
i′ :
Hrp :
replayablei′ = true
Hpos :
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Es :
s = SAtl Z.of_natk
Hk′ :
Somei = Somei′
⊢
rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i′
deferred goal
rp :
listname × def → env → Memory.mem → name → inst → Prop
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hmv :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natk
Hpt1 :
point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hself :
∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i
Hold :
scope_withrp fr m
n :
s :
i′ :
Hrp :
replayablei′ = true
Hpos :
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Hsd0 :
site_dominatesfn_domsfr_fnfr l Z.of_natk s = true
⊢
rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i′

injection Hk′ as ←

2 open

rp :
listname × def → env → Memory.mem → name → inst → Prop
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hmv :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natk
Hpt1 :
point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hself :
∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i
Hold :
scope_withrp fr m
n :
s :
Hpos :
Hrp :
replayablei = true
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Es :
s = SAtl Z.of_natk
⊢
deferred goal
rp :
listname × def → env → Memory.mem → name → inst → Prop
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hmv :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natk
Hpt1 :
point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hself :
∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i
Hold :
scope_withrp fr m
n :
s :
i′ :
Hrp :
replayablei′ = true
Hpos :
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Hsd0 :
site_dominatesfn_domsfr_fnfr l Z.of_natk s = true
⊢
rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i′

exact Hself_ Hrp Hn

deferred goal
rp :
listname × def → env → Memory.mem → name → inst → Prop
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hmv :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natk
Hpt1 :
point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hself :
∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i
Hold :
scope_withrp fr m
n :
s :
i′ :
Hrp :
replayablei′ = true
Hpos :
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Hsd0 :
site_dominatesfn_domsfr_fnfr l Z.of_natk s = true
⊢
rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i′

–destruct func_facts_ _ Hmd Hin as b0 & rest & Hf & Hd & _ & Hdd

rp :
listname × def → env → Memory.mem → name → inst → Prop
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hmv :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natk
Hpt1 :
point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hself :
∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i
Hold :
scope_withrp fr m
n :
s :
i′ :
Hrp :
replayablei′ = true
Hpos :
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Hsd0 :
site_dominatesfn_domsfr_fnfr l Z.of_natk s = true
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
⊢
rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i′

destruct find_block_in_ _ _ Hb as Hbin Hl

rp :
listname × def → env → Memory.mem → name → inst → Prop
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hmv :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natk
Hpt1 :
point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hself :
∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i
Hold :
scope_withrp fr m
n :
s :
i′ :
Hrp :
replayablei′ = true
Hpos :
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Hsd0 :
site_dominatesfn_domsfr_fnfr l Z.of_natk s = true
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hbin :
Hl :
b_labelb = l
⊢
rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i′

assert HX : ∀x, Inx mapfst inst_temp_defsi → ∃D, Inx, SAtl Z.of_natk, D def_positionsfr_fnfr by intros x Hx ; rewrite <- Hl ; exact inst_defs_here_ _ _ _ Hbin Hk _ Hx

rp :
listname × def → env → Memory.mem → name → inst → Prop
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hmv :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natk
Hpt1 :
point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hself :
∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i
Hold :
scope_withrp fr m
n :
s :
i′ :
Hrp :
replayablei′ = true
Hpos :
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Hsd0 :
site_dominatesfn_domsfr_fnfr l Z.of_natk s = true
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hbin :
Hl :
b_labelb = l
HX :
∀x : name, Inx mapfst inst_temp_defsi → ∃D : def, Inx, SAtl Z.of_natk, D def_positionsfr_fnfr
⊢
rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i′

destruct scope_moves_ _ _ _ _ _ _ _ _ _ _ Hf Hd Hdd Hr HX He Hn Hpos Hsd0 as Hn′ Ha′

rp :
listname × def → env → Memory.mem → name → inst → Prop
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hmv :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natk
Hpt1 :
point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hself :
∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i
Hold :
scope_withrp fr m
n :
s :
i′ :
Hrp :
replayablei′ = true
Hpos :
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Hsd0 :
site_dominatesfn_domsfr_fnfr l Z.of_natk s = true
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hbin :
Hl :
b_labelb = l
HX :
∀x : name, Inx mapfst inst_temp_defsi → ∃D : def, Inx, SAtl Z.of_natk, D def_positionsfr_fnfr
Hn′ :
Ha′ :
∀a : name, Ina inst_usesi′ → once_hassingle_definitionsfr_fnfr a = true → lookupa fr_envfr′ = lookupa fr_envfr
⊢
rpsingle_definitionsfr_fnfr fr_envfr′ m′ n i′

exact Hmv_ _ _ _ _ _ _ Hold_ _ _ _ _ Hpt0 Hn Hrp Hpos Hsd0 Hn′ Ha′ Hp

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros rp md fr fr′ m m′ l b k i Hmv Hmd Hin Hf′ Hr Hb Hk Hpt0 Hpt1 He Hp Hself Hold l′ k′ n s i′ Hpt Hn Hrp Hpos Hsd
rewrite Hf′ in *
rewrite Hpt1 in Hpt
injection Hpt as ← ←
assert Hsd1 : site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true by rewrite <- Hsd ; f_equal ; lia
clear Hsd
destruct site_next_ _ _ _ Hsd1 as Es | Hsd0
–pose proof site_inst_ _ _ _ _ _ _ _ Hmd Hin Hb Hpos Es as Hk′
rewrite Hk in Hk′
injection Hk′ as ←
exact Hself_ Hrp Hn
–destruct func_facts_ _ Hmd Hin as b0 & rest & Hf & Hd & _ & Hdd
destruct find_block_in_ _ _ Hb as Hbin Hl
assert HX : ∀x, Inx mapfst inst_temp_defsi → ∃D, Inx, SAtl Z.of_natk, D def_positionsfr_fnfr by intros x Hx ; rewrite <- Hl ; exact inst_defs_here_ _ _ _ Hbin Hk _ Hx
destruct scope_moves_ _ _ _ _ _ _ _ _ _ _ Hf Hd Hdd Hr HX He Hn Hpos Hsd0 as Hn′ Ha′
exact Hmv_ _ _ _ _ _ _ Hold_ _ _ _ _ Hpt0 Hn Hrp Hpos Hsd0 Hn′ Ha′ Hp

scope_step_with for replays: the step lemma of scope_holds.

542Lemma scope_step
∀ ge md fr fr′ m m′ l b k i
InIFuncfr_fnfr md
fr_fnfr′ = fr_fnfr
nth_errorb_instsb k = Somei
point_sitefr_fnfr fr_atfr = Somel, Z.of_natk
point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk
∀a, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
persistsm m′
∀n, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → replaysge single_definitionsfr_fnfr fr_envfr′ m′ n i
scope_holdsge fr′ m′
Explore proof 2 tactics

Initial goal

⊢
∀ge : genv md : module fr fr′ : frame m m′ : Memory.mem l : name b : block k : nat i : inst, checked_modulemd → InIFuncfr_fnfr md → fr_fnfr′ = fr_fnfr → is_reachablefn_domsfr_fnfr l = true → find_blockl fn_blocksfr_fnfr = Someb → nth_errorb_instsb k = Somei → point_sitefr_fnfr fr_atfr = Somel, Z.of_natk → point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk → ∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr → persistsm m′ → ∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → replaysge single_definitionsfr_fnfr fr_envfr′ m′ n i → scope_holdsge fr m → scope_holdsge fr′ m′

intros ge md fr fr′ m m′ l b k i

ge :
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
⊢
checked_modulemd → InIFuncfr_fnfr md → fr_fnfr′ = fr_fnfr → is_reachablefn_domsfr_fnfr l = true → find_blockl fn_blocksfr_fnfr = Someb → nth_errorb_instsb k = Somei → point_sitefr_fnfr fr_atfr = Somel, Z.of_natk → point_sitefr_fnfr fr_atfr′ = Somel, Z.of_natSk → ∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr → persistsm m′ → ∀n : name, replayablei = true → lookupn single_definitionsfr_fnfr = SomeDInsti → replaysge single_definitionsfr_fnfr fr_envfr′ m′ n i → scope_holdsge fr m → scope_holdsge fr′ m′

exact scope_step_withreplaysge md fr fr′ m m′ l b k i replays_changege

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge md fr fr′ m m′ l b k i
exact scope_step_withreplaysge md fr fr′ m m′ l b k i replays_changege

Just after the instruction i at index k, whose own names do not replay (a call, an allocation), a frame whose environment changed only on i's names keeps the scope it had there, in a memory that persists.

561Lemma scope_after
∀ ge md fr fr′ m m′ l b k i
InIFuncfr_fnfr md
fr_fnfr′ = fr_fnfr
fr_atfr′ = fr_atfr
nth_errorb_instsb k = Somei
replayablei = false
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
∀a, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
persistsm m′
scope_holdsge fr′ m′
Explore proof 16 tactics

Initial goal

⊢
∀ge : genv md : module fr fr′ : frame m m′ : Memory.mem l : name b : block k : nat i : inst, checked_modulemd → InIFuncfr_fnfr md → fr_fnfr′ = fr_fnfr → fr_atfr′ = fr_atfr → is_reachablefn_domsfr_fnfr l = true → find_blockl fn_blocksfr_fnfr = Someb → nth_errorb_instsb k = Somei → replayablei = false → point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk → ∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr → persistsm m′ → scope_holdsge fr m → scope_holdsge fr′ m′

intros ge md fr fr′ m m′ l b k i Hmd Hin Hf′ Ha′ Hr Hb Hk Hrp Hpt0 He Hp Hold l′ k′ n s i′ Hpt Hn Hrp′ Hpos Hsd

ge :
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Ha′ :
fr_atfr′ = fr_atfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hrp :
replayablei = false
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hold :
l′ :
k′ :
Z
n :
s :
i′ :
Hpt :
point_sitefr_fnfr′ fr_atfr′ = Somel′, k′
Hn :
Hrp′ :
replayablei′ = true
Hpos :
Inn, s, DInsti′ def_positionsfr_fnfr′
Hsd :
site_dominatesfn_domsfr_fnfr′ l′ k′ s = true
⊢
replaysge single_definitionsfr_fnfr′ fr_envfr′ m′ n i′

rewrite Hf′ in *

ge :
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Ha′ :
fr_atfr′ = fr_atfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hrp :
replayablei = false
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hold :
l′ :
k′ :
Z
n :
s :
i′ :
Hpt :
point_sitefr_fnfr fr_atfr′ = Somel′, k′
Hrp′ :
replayablei′ = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l′ k′ s = true
⊢

rewrite Ha′ , Hpt0 in Hpt

ge :
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Ha′ :
fr_atfr′ = fr_atfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hrp :
replayablei = false
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hold :
l′ :
k′ :
Z
n :
s :
i′ :
Hpt :
Somel, Z.of_natSk = Somel′, k′
Hrp′ :
replayablei′ = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l′ k′ s = true
⊢

injection Hpt as ← ←

ge :
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Ha′ :
fr_atfr′ = fr_atfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hrp :
replayablei = false
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hold :
n :
s :
i′ :
Hrp′ :
replayablei′ = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l Z.posPosDef.Pos.of_succ_natk s = true
⊢

assert Hsd1 : site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true by rewrite <- Hsd ; f_equal ; lia

ge :
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Ha′ :
fr_atfr′ = fr_atfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hrp :
replayablei = false
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hold :
n :
s :
i′ :
Hrp′ :
replayablei′ = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l Z.posPosDef.Pos.of_succ_natk s = true
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
⊢

destruct site_next_ _ _ _ Hsd1 as Es | Hsd0

2 open

ge :
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Ha′ :
fr_atfr′ = fr_atfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hrp :
replayablei = false
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hold :
n :
s :
i′ :
Hrp′ :
replayablei′ = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l Z.posPosDef.Pos.of_succ_natk s = true
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Es :
s = SAtl Z.of_natk
⊢
focused goal
ge :
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Ha′ :
fr_atfr′ = fr_atfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hrp :
replayablei = false
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hold :
n :
s :
i′ :
Hrp′ :
replayablei′ = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l Z.posPosDef.Pos.of_succ_natk s = true
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Hsd0 :
site_dominatesfn_domsfr_fnfr l Z.of_natk s = true
⊢

–pose proof site_inst_ _ _ _ _ _ _ _ Hmd Hin Hb Hpos Es as Hk′

2 open

ge :
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Ha′ :
fr_atfr′ = fr_atfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hrp :
replayablei = false
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hold :
n :
s :
i′ :
Hrp′ :
replayablei′ = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l Z.posPosDef.Pos.of_succ_natk s = true
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Es :
s = SAtl Z.of_natk
Hk′ :
nth_errorb_instsb k = Somei′
⊢
deferred goal
ge :
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Ha′ :
fr_atfr′ = fr_atfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hrp :
replayablei = false
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hold :
n :
s :
i′ :
Hrp′ :
replayablei′ = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l Z.posPosDef.Pos.of_succ_natk s = true
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Hsd0 :
site_dominatesfn_domsfr_fnfr l Z.of_natk s = true
⊢

rewrite Hk in Hk′

2 open

ge :
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Ha′ :
fr_atfr′ = fr_atfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hrp :
replayablei = false
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hold :
n :
s :
i′ :
Hrp′ :
replayablei′ = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l Z.posPosDef.Pos.of_succ_natk s = true
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Es :
s = SAtl Z.of_natk
Hk′ :
Somei = Somei′
⊢
deferred goal
ge :
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Ha′ :
fr_atfr′ = fr_atfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hrp :
replayablei = false
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hold :
n :
s :
i′ :
Hrp′ :
replayablei′ = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l Z.posPosDef.Pos.of_succ_natk s = true
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Hsd0 :
site_dominatesfn_domsfr_fnfr l Z.of_natk s = true
⊢

injection Hk′ as ←

2 open

ge :
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Ha′ :
fr_atfr′ = fr_atfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hrp :
replayablei = false
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hold :
n :
s :
Hpos :
Hrp′ :
replayablei = true
Hsd :
site_dominatesfn_domsfr_fnfr l Z.posPosDef.Pos.of_succ_natk s = true
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Es :
s = SAtl Z.of_natk
deferred goal
ge :
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Ha′ :
fr_atfr′ = fr_atfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hrp :
replayablei = false
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hold :
n :
s :
i′ :
Hrp′ :
replayablei′ = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l Z.posPosDef.Pos.of_succ_natk s = true
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Hsd0 :
site_dominatesfn_domsfr_fnfr l Z.of_natk s = true
⊢

rewrite Hrp in Hrp′

2 open

ge :
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Ha′ :
fr_atfr′ = fr_atfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hrp :
replayablei = false
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hold :
n :
s :
Hpos :
Hrp′ :
false = true
Hsd :
site_dominatesfn_domsfr_fnfr l Z.posPosDef.Pos.of_succ_natk s = true
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Es :
s = SAtl Z.of_natk
deferred goal
ge :
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Ha′ :
fr_atfr′ = fr_atfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hrp :
replayablei = false
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hold :
n :
s :
i′ :
Hrp′ :
replayablei′ = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l Z.posPosDef.Pos.of_succ_natk s = true
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Hsd0 :
site_dominatesfn_domsfr_fnfr l Z.of_natk s = true
⊢

discriminate Hrp′

deferred goal
ge :
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Ha′ :
fr_atfr′ = fr_atfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hrp :
replayablei = false
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hold :
n :
s :
i′ :
Hrp′ :
replayablei′ = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l Z.posPosDef.Pos.of_succ_natk s = true
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Hsd0 :
site_dominatesfn_domsfr_fnfr l Z.of_natk s = true
⊢

–destruct func_facts_ _ Hmd Hin as b0 & rest & Hf & Hd & _ & Hdd

ge :
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Ha′ :
fr_atfr′ = fr_atfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hrp :
replayablei = false
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hold :
n :
s :
i′ :
Hrp′ :
replayablei′ = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l Z.posPosDef.Pos.of_succ_natk s = true
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Hsd0 :
site_dominatesfn_domsfr_fnfr l Z.of_natk s = true
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
⊢

destruct find_block_in_ _ _ Hb as Hbin Hl

ge :
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Ha′ :
fr_atfr′ = fr_atfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hrp :
replayablei = false
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hold :
n :
s :
i′ :
Hrp′ :
replayablei′ = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l Z.posPosDef.Pos.of_succ_natk s = true
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Hsd0 :
site_dominatesfn_domsfr_fnfr l Z.of_natk s = true
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hbin :
Hl :
b_labelb = l
⊢

assert HX : ∀x, Inx mapfst inst_temp_defsi → ∃D, Inx, SAtl Z.of_natk, D def_positionsfr_fnfr by intros x Hx ; rewrite <- Hl ; exact inst_defs_here_ _ _ _ Hbin Hk _ Hx

ge :
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Ha′ :
fr_atfr′ = fr_atfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hrp :
replayablei = false
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hold :
n :
s :
i′ :
Hrp′ :
replayablei′ = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l Z.posPosDef.Pos.of_succ_natk s = true
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Hsd0 :
site_dominatesfn_domsfr_fnfr l Z.of_natk s = true
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hbin :
Hl :
b_labelb = l
HX :
∀x : name, Inx mapfst inst_temp_defsi → ∃D : def, Inx, SAtl Z.of_natk, D def_positionsfr_fnfr
⊢

destruct scope_moves_ _ _ _ _ _ _ _ _ _ _ Hf Hd Hdd Hr HX He Hn Hpos Hsd0 as Hn′ Ha′′

ge :
md :
fr, fr′ :
m, m′ :
Memory.mem
l :
k :
nat
i :
Hin :
InIFuncfr_fnfr md
Hf′ :
fr_fnfr′ = fr_fnfr
Ha′ :
fr_atfr′ = fr_atfr
Hr :
Hb :
Hk :
nth_errorb_instsb k = Somei
Hrp :
replayablei = false
Hpt0 :
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
He :
∀a : name, ¬Ina mapfst inst_temp_defsi → lookupa fr_envfr′ = lookupa fr_envfr
Hp :
persistsm m′
Hold :
n :
s :
i′ :
Hrp′ :
replayablei′ = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l Z.posPosDef.Pos.of_succ_natk s = true
Hsd1 :
site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true
Hsd0 :
site_dominatesfn_domsfr_fnfr l Z.of_natk s = true
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hbin :
Hl :
b_labelb = l
HX :
∀x : name, Inx mapfst inst_temp_defsi → ∃D : def, Inx, SAtl Z.of_natk, D def_positionsfr_fnfr
Hn′ :
Ha′′ :
∀a : name, Ina inst_usesi′ → once_hassingle_definitionsfr_fnfr a = true → lookupa fr_envfr′ = lookupa fr_envfr
⊢

exact replays_change_ _ _ _ _ _ _ _ Hold_ _ _ _ _ Hpt0 Hn Hrp′ Hpos Hsd Hn′ Ha′′ Hp

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge md fr fr′ m m′ l b k i Hmd Hin Hf′ Ha′ Hr Hb Hk Hrp Hpt0 He Hp Hold l′ k′ n s i′ Hpt Hn Hrp′ Hpos Hsd
rewrite Hf′ in *
rewrite Ha′ , Hpt0 in Hpt
injection Hpt as ← ←
assert Hsd1 : site_dominatesfn_domsfr_fnfr l Z.of_natk + 1 s = true by rewrite <- Hsd ; f_equal ; lia
destruct site_next_ _ _ _ Hsd1 as Es | Hsd0
–pose proof site_inst_ _ _ _ _ _ _ _ Hmd Hin Hb Hpos Es as Hk′
rewrite Hk in Hk′
injection Hk′ as ←
rewrite Hrp in Hrp′
discriminate Hrp′
–destruct func_facts_ _ Hmd Hin as b0 & rest & Hf & Hd & _ & Hdd
destruct find_block_in_ _ _ Hb as Hbin Hl
assert HX : ∀x, Inx mapfst inst_temp_defsi → ∃D, Inx, SAtl Z.of_natk, D def_positionsfr_fnfr by intros x Hx ; rewrite <- Hl ; exact inst_defs_here_ _ _ _ Hbin Hk _ Hx
destruct scope_moves_ _ _ _ _ _ _ _ _ _ _ Hf Hd Hdd Hr HX He Hn Hpos Hsd0 as Hn′ Ha′′
exact replays_change_ _ _ _ _ _ _ _ Hold_ _ _ _ _ Hpt0 Hn Hrp′ Hpos Hsd Hn′ Ha′′ Hp

Frames a step makes

What a jump can take is among the block's successors.

588Lemma target_succ
Explore proof 2 tactics

Initial goal

⊢
∀j : jump t : target, Int jump_targetsj → Inedge_labelt jump_succsj

intros j t H

destruct j ; simpl in * ; intuition subst ; simpl ; auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros j t H
destruct j ; simpl in * ; intuition subst ; simpl ; auto

A call's new frame is not doomed, at its function's entry.

592Lemma call_frame_entry
∀ g xs fr
call_frameg xs = Somefr
fr_fnfr = g ∧ fr_doomedfr = None ∧ ∃l, entry_labelg = Somel ∧ fr_atfr = Enterl None ∨ ∃ys, fr_atfr = Snapshotys l
Explore proof 12 tactics

Initial goal

⊢
∀g : func xs : listword fr : frame, call_frameg xs = Somefr → fr_fnfr = g ∧ fr_doomedfr = None ∧ ∃l : name, entry_labelg = Somel ∧ fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l

intros g xs fr H

g :
xs :
listword
fr :
H :
call_frameg xs = Somefr
⊢
fr_fnfr = g ∧ fr_doomedfr = None ∧ ∃l : name, entry_labelg = Somel ∧ fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l

unfold call_frame in H

g :
xs :
listword
fr :
H :
Datatypes.lengthxs <? Datatypes.lengthfn_paramsg%nat
→
None
else
match fn_blocksg with
[ ]
⇒
None
b :: _
⇒
Somefr_fn ≔ g; fr_env ≔ fold_leftλe : listname × word px : class × name × word ⇒ putsndfstpx sndpx e combinefn_paramsg firstnDatatypes.lengthfn_paramsg xs [ ]; fr_locals ≔ mapλxs : name × Z ⇒ fstxs, None local_objectsg; fr_doomed ≔ None; fr_at ≔ if variadic_funcg then Snapshotxs b_labelb else Enterb_labelb None
=
Somefr
⊢
fr_fnfr = g ∧ fr_doomedfr = None ∧ ∃l : name, entry_labelg = Somel ∧ fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l

destruct lengthxs <? lengthfn_paramsg%nat ; discriminate H |

g :
xs :
listword
fr :
H :
match fn_blocksg with
[ ]
⇒
None
b :: _
⇒
Somefr_fn ≔ g; fr_env ≔ fold_leftλe : listname × word px : class × name × word ⇒ putsndfstpx sndpx e combinefn_paramsg firstnDatatypes.lengthfn_paramsg xs [ ]; fr_locals ≔ mapλxs : name × Z ⇒ fstxs, None local_objectsg; fr_doomed ≔ None; fr_at ≔ if variadic_funcg then Snapshotxs b_labelb else Enterb_labelb None
=
Somefr
⊢
fr_fnfr = g ∧ fr_doomedfr = None ∧ ∃l : name, entry_labelg = Somel ∧ fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l

unfold entry_label

g :
xs :
listword
fr :
H :
match fn_blocksg with
[ ]
⇒
None
b :: _
⇒
Somefr_fn ≔ g; fr_env ≔ fold_leftλe : listname × word px : class × name × word ⇒ putsndfstpx sndpx e combinefn_paramsg firstnDatatypes.lengthfn_paramsg xs [ ]; fr_locals ≔ mapλxs : name × Z ⇒ fstxs, None local_objectsg; fr_doomed ≔ None; fr_at ≔ if variadic_funcg then Snapshotxs b_labelb else Enterb_labelb None
=
Somefr
⊢
fr_fnfr = g
∧
fr_doomedfr = None
∧
∃ l : name  ,
match fn_blocksg with
[ ]
⇒
None
b :: _
⇒
Someb_labelb
=
Somel
∧
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l

destruct fn_blocksg as | b bs ; discriminate H |

g :
xs :
listword
fr :
bs :
listblock
H :
Somefr_fn ≔ g; fr_env ≔ fold_leftλe : listname × word px : class × name × word ⇒ putsndfstpx sndpx e combinefn_paramsg firstnDatatypes.lengthfn_paramsg xs [ ]; fr_locals ≔ mapλxs : name × Z ⇒ fstxs, None local_objectsg; fr_doomed ≔ None; fr_at ≔ if variadic_funcg then Snapshotxs b_labelb else Enterb_labelb None = Somefr
⊢
fr_fnfr = g ∧ fr_doomedfr = None ∧ ∃l : name, Someb_labelb = Somel ∧ fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l

injection H as ←

g :
xs :
listword
bs :
listblock
⊢
fr_fnfr_fn ≔ g; fr_env ≔ fold_leftλe : listname × word px : class × name × word ⇒ putsndfstpx sndpx e combinefn_paramsg firstnDatatypes.lengthfn_paramsg xs [ ]; fr_locals ≔ mapλxs0 : name × Z ⇒ fstxs0, None local_objectsg; fr_doomed ≔ None; fr_at ≔ if variadic_funcg then Snapshotxs b_labelb else Enterb_labelb None = g ∧ fr_doomedfr_fn ≔ g; fr_env ≔ fold_leftλe : listname × word px : class × name × word ⇒ putsndfstpx sndpx e combinefn_paramsg firstnDatatypes.lengthfn_paramsg xs [ ]; fr_locals ≔ mapλxs0 : name × Z ⇒ fstxs0, None local_objectsg; fr_doomed ≔ None; fr_at ≔ if variadic_funcg then Snapshotxs b_labelb else Enterb_labelb None = None ∧ ∃l : name, Someb_labelb = Somel ∧ fr_atfr_fn ≔ g; fr_env ≔ fold_leftλe : listname × word px : class × name × word ⇒ putsndfstpx sndpx e combinefn_paramsg firstnDatatypes.lengthfn_paramsg xs [ ]; fr_locals ≔ mapλxs0 : name × Z ⇒ fstxs0, None local_objectsg; fr_doomed ≔ None; fr_at ≔ if variadic_funcg then Snapshotxs b_labelb else Enterb_labelb None = Enterl None ∨ ∃ys : listword, fr_atfr_fn ≔ g; fr_env ≔ fold_leftλe : listname × word px : class × name × word ⇒ putsndfstpx sndpx e combinefn_paramsg firstnDatatypes.lengthfn_paramsg xs [ ]; fr_locals ≔ mapλxs0 : name × Z ⇒ fstxs0, None local_objectsg; fr_doomed ≔ None; fr_at ≔ if variadic_funcg then Snapshotxs b_labelb else Enterb_labelb None = Snapshotys l

simpl

g :
xs :
listword
bs :
listblock
⊢
g = g
∧
None = None
∧
∃ l : name  ,
Someb_labelb = Somel
∧
∨
∃ ys : listword  ,

split ; reflexivity |

g :
xs :
listword
bs :
listblock
⊢
None = None
∧
∃ l : name  ,
Someb_labelb = Somel
∧
∨
∃ ys : listword  ,

split ; reflexivity |

g :
xs :
listword
bs :
listblock
⊢
∃ l : name  ,
Someb_labelb = Somel
∧
∨
∃ ys : listword  ,

exists b_labelb

g :
xs :
listword
bs :
listblock
⊢
Someb_labelb = Someb_labelb
∧

split ; reflexivity |

g :
xs :
listword
bs :
listblock

destruct variadic_funcg ; eauto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros g xs fr H
unfold call_frame in H
destruct lengthxs <? lengthfn_paramsg%nat ; discriminate H |
destruct fn_blocksg as | b bs ; discriminate H |
injection H as ←
simpl
split ; reflexivity |
split ; reflexivity |
exists b_labelb
split ; reflexivity |
destruct variadic_funcg ; eauto

A frame at its function's entry, entered or about to take its snapshot, is shaped, with nothing in scope.

605Lemma at_entry
∀ ge md fr m l
InIFuncfr_fnfr md
entry_labelfr_fnfr = Somel
fr_atfr = Enterl None ∨ ∃ys, fr_atfr = Snapshotys l
shapedmd fr ∧ scope_holdsge fr m
Explore proof 17 tactics

Initial goal

⊢
∀ge : genv md : module fr : frame m : Memory.mem l : name, checked_modulemd → InIFuncfr_fnfr md → entry_labelfr_fnfr = Somel → fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l → shapedmd fr ∧ scope_holdsge fr m

intros ge md fr m l Hmd Hin He Ha

ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
⊢
shapedmd fr ∧ scope_holdsge fr m

destruct func_facts_ _ Hmd Hin as b0 & rest & Hf & Hd & _ & _

ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
⊢
shapedmd fr ∧ scope_holdsge fr m

assert Hr : is_reachablefn_domsfr_fnfr l = true

2 open

ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
focused goal
ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hr :
⊢
shapedmd fr ∧ scope_holdsge fr m

{unfold entry_label in He

2 open

ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
match fn_blocksfr_fnfr with
[ ]
⇒
None
b :: _
⇒
Someb_labelb
=
Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
deferred goal
ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hr :
⊢
shapedmd fr ∧ scope_holdsge fr m

rewrite Hf in He

2 open

ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
b0 :
He :
Someb_labelb0 = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
deferred goal
ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hr :
⊢
shapedmd fr ∧ scope_holdsge fr m

injection He as ←

2 open

ge :
md :
fr :
m :
Memory.mem
Hin :
InIFuncfr_fnfr md
b0 :
Ha :
fr_atfr = Enterb_labelb0 None ∨ ∃ys : listword, fr_atfr = Snapshotys b_labelb0
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
deferred goal
ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hr :
⊢
shapedmd fr ∧ scope_holdsge fr m

exact dom_entry_ _ _ Hd

deferred goal
ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hr :
⊢
shapedmd fr ∧ scope_holdsge fr m

split

2 open

ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hr :
⊢
shapedmd fr
focused goal
ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hr :
⊢

–unfold shaped

2 open

ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hr :
⊢
InIFuncfr_fnfr md
∧
match fr_atfr with
⇒
entry_labelfr_fnfr = Somel0
Enterl0 from
⇒
is_reachablefn_domsfr_fnfr l0 = true ∧ from = None → entry_labelfr_fnfr = Somel0
Execl0 is j
⇒
is_reachablefn_domsfr_fnfr l0 = true ∧ ∃b : block k : nat, find_blockl0 fn_blocksfr_fnfr = Someb ∧ k ≤ Datatypes.lengthb_instsb%nat ∧ is = skipnk b_instsb ∧ j = b_jumpb
deferred goal
ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hr :
⊢

cbv zeta

2 open

ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hr :
⊢
InIFuncfr_fnfr md
∧
match fr_atfr with
⇒
entry_labelfr_fnfr = Somel0
Enterl0 from
⇒
is_reachablefn_domsfr_fnfr l0 = true ∧ from = None → entry_labelfr_fnfr = Somel0
Execl0 is j
⇒
is_reachablefn_domsfr_fnfr l0 = true ∧ ∃b : block k : nat, find_blockl0 fn_blocksfr_fnfr = Someb ∧ k ≤ Datatypes.lengthb_instsb%nat ∧ is = skipnk b_instsb ∧ j = b_jumpb
deferred goal
ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hr :
⊢

split ; exact Hin |

2 open

ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hr :
⊢
match fr_atfr with
⇒
entry_labelfr_fnfr = Somel0
Enterl0 from
⇒
is_reachablefn_domsfr_fnfr l0 = true ∧ from = None → entry_labelfr_fnfr = Somel0
Execl0 is j
⇒
is_reachablefn_domsfr_fnfr l0 = true ∧ ∃b : block k : nat, find_blockl0 fn_blocksfr_fnfr = Someb ∧ k ≤ Datatypes.lengthb_instsb%nat ∧ is = skipnk b_instsb ∧ j = b_jumpb
deferred goal
ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hr :
⊢

destruct Ha as Ha | ys & Ha ; rewrite Ha ; split ; exact Hr | intros _ ; exact He | exact He

deferred goal
ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hr :
⊢

–intros l′ k n s i Hpt Hn Hrp Hpos Hsd

ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hr :
l′ :
k :
Z
n :
s :
i :
Hpt :
point_sitefr_fnfr fr_atfr = Somel′, k
Hrp :
replayablei = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l′ k s = true

destruct Ha as Ha | ys & Ha ; rewrite Ha in Hpt ; simpl in Hpt ; | discriminate Hpt

ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hr :
l′ :
k :
Z
n :
s :
i :
Hpt :
Somel, −1 = Somel′, k
Hrp :
replayablei = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l′ k s = true

injection Hpt as ← ←

ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hr :
n :
s :
i :
Hrp :
replayablei = true
Hpos :
Hsd :
site_dominatesfn_domsfr_fnfr l −1 s = true

rewrite scope_entry_ _ _ _ _ _ Hmd Hin He Hpos in Hsd

ge :
md :
fr :
m :
Memory.mem
l :
Hin :
InIFuncfr_fnfr md
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None
b0 :
rest :
listblock
Hf :
fn_blocksfr_fnfr = b0 :: rest
Hd :
block_intervalsb0 :: rest = Somefn_domsfr_fnfr
Hr :
n :
s :
i :
Hrp :
replayablei = true
Hpos :
Hsd :
false = true

discriminate Hsd

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge md fr m l Hmd Hin He Ha
destruct func_facts_ _ Hmd Hin as b0 & rest & Hf & Hd & _ & _
assert Hr : is_reachablefn_domsfr_fnfr l = true
{unfold entry_label in He
rewrite Hf in He
injection He as ←
exact dom_entry_ _ _ Hd
split
–unfold shaped
cbv zeta
split ; exact Hin |
destruct Ha as Ha | ys & Ha ; rewrite Ha ; split ; exact Hr | intros _ ; exact He | exact He
–intros l′ k n s i Hpt Hn Hrp Hpos Hsd
destruct Ha as Ha | ys & Ha ; rewrite Ha in Hpt ; simpl in Hpt ; | discriminate Hpt
injection Hpt as ← ←
rewrite scope_entry_ _ _ _ _ _ Hmd Hin He Hpos in Hsd
discriminate Hsd

A return resumes the waiting caller at its point, with the call's result in its environment.

624Lemma return_step_env
∀ c o c′
return_stepc o = Nextc′
∃caller pd callers o′ e, c_callersc = caller, pd :: callers ∧ returned_envpd_respd o′ fr_envcaller = Somee ∧ c′ = mkConfigmkFramefr_fncaller e fr_localscaller fr_doomedcaller fr_atcaller callers c_memc′ c_fuelc
Explore proof 10 tactics

Initial goal

⊢
∀c : config o : outcome c′ : config, return_stepc o = Nextc′ → ∃caller : frame pd : pending callers : listframe × pending o′ : outcome e : env, c_callersc = caller, pd :: callers ∧ returned_envpd_respd o′ fr_envcaller = Somee ∧ c′ = c_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 ≔ c_memc′; c_fuel ≔ c_fuelc

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′
→
∃caller : frame pd : pending callers : listframe × pending o′ : outcome e : env, c_callersc = caller, pd :: callers ∧ returned_envpd_respd o′ fr_envcaller = Somee ∧ c′ = c_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 ≔ c_memc′; c_fuel ≔ c_fuelc

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′
⊢
∃caller : frame pd : pending callers : listframe × pending o′ : outcome e : env, c_callersc = caller, pd :: callers ∧ returned_envpd_respd o′ fr_envcaller = Somee ∧ c′ = c_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 ≔ c_memc′; c_fuel ≔ c_fuelc

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′
⊢
∃caller : frame pd : pending callers : listframe × pending o′ : outcome e : env, c_callersc = caller, pd :: callers ∧ returned_envpd_respd o′ fr_envcaller = Somee ∧ c′ = c_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 ≔ c_memc′; c_fuel ≔ c_fuelc

destruct invalidate_locals_ _ as m | ; | discriminate H

c′ :
m :
Memory.mem
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′
⊢
∃caller : frame pd : pending callers : listframe × pending o′ : outcome e : env, c_callersc = caller, pd :: callers ∧ returned_envpd_respd o′ fr_envcaller = Somee ∧ c′ = c_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 ≔ c_memc′; c_fuel ≔ c_fuelc

destruct c_callersc as | caller pd callers ; discriminate H |

c′ :
m :
Memory.mem
caller :
callers :
listframe × pending
H :
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′
⊢
∃caller0 : frame pd0 : pending callers0 : listframe × pending o′ : outcome e : env, caller, pd :: callers = caller0, pd0 :: callers0 ∧ returned_envpd_respd0 o′ fr_envcaller0 = Somee ∧ c′ = c_frame ≔ fr_fn ≔ fr_fncaller0; fr_env ≔ e; fr_locals ≔ fr_localscaller0; fr_doomed ≔ fr_doomedcaller0; fr_at ≔ fr_atcaller0; c_callers ≔ callers0; c_mem ≔ c_memc′; c_fuel ≔ c_fuelc

destruct match pd_convpd with None ⇒ Someo | Somecw, kw ⇒ converted_outcomecw kw o end as o′ | ; | discriminate H

c′ :
m :
Memory.mem
caller :
callers :
listframe × pending
o′ :
H :
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′
⊢
∃caller0 : frame pd0 : pending callers0 : listframe × pending o'0 : outcome e : env, caller, pd :: callers = caller0, pd0 :: callers0 ∧ returned_envpd_respd0 o'0 fr_envcaller0 = Somee ∧ c′ = c_frame ≔ fr_fn ≔ fr_fncaller0; fr_env ≔ e; fr_locals ≔ fr_localscaller0; fr_doomed ≔ fr_doomedcaller0; fr_at ≔ fr_atcaller0; c_callers ≔ callers0; c_mem ≔ c_memc′; c_fuel ≔ c_fuelc

destruct returned_env_ _ _ as e | eqn: Ee ; | discriminate H

c′ :
m :
Memory.mem
caller :
callers :
listframe × pending
o′ :
e :
Ee :
returned_envpd_respd o′ fr_envcaller = Somee
H :
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′
⊢
∃caller0 : frame pd0 : pending callers0 : listframe × pending o'0 : outcome e0 : env, caller, pd :: callers = caller0, pd0 :: callers0 ∧ returned_envpd_respd0 o'0 fr_envcaller0 = Somee0 ∧ c′ = c_frame ≔ fr_fn ≔ fr_fncaller0; fr_env ≔ e0; fr_locals ≔ fr_localscaller0; fr_doomed ≔ fr_doomedcaller0; fr_at ≔ fr_atcaller0; c_callers ≔ callers0; c_mem ≔ c_memc′; c_fuel ≔ c_fuelc

injection H as ←

m :
Memory.mem
caller :
callers :
listframe × pending
o′ :
e :
Ee :
returned_envpd_respd o′ fr_envcaller = Somee
⊢
∃caller0 : frame pd0 : pending callers0 : listframe × pending o'0 : outcome e0 : env, caller, pd :: callers = caller0, pd0 :: callers0 ∧ returned_envpd_respd0 o'0 fr_envcaller0 = Somee0 ∧ c_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 = c_frame ≔ fr_fn ≔ fr_fncaller0; fr_env ≔ e0; fr_locals ≔ fr_localscaller0; fr_doomed ≔ fr_doomedcaller0; fr_at ≔ fr_atcaller0; c_callers ≔ callers0; c_mem ≔ c_memc_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; c_fuel ≔ c_fuelc

simpl

m :
Memory.mem
caller :
callers :
listframe × pending
o′ :
e :
Ee :
returned_envpd_respd o′ fr_envcaller = Somee
⊢
∃caller0 : frame pd0 : pending callers0 : listframe × pending o'0 : outcome e0 : env, caller, pd :: callers = caller0, pd0 :: callers0 ∧ returned_envpd_respd0 o'0 fr_envcaller0 = Somee0 ∧ c_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 = c_frame ≔ fr_fn ≔ fr_fncaller0; fr_env ≔ e0; fr_locals ≔ fr_localscaller0; fr_doomed ≔ fr_doomedcaller0; fr_at ≔ fr_atcaller0; c_callers ≔ callers0; c_mem ≔ m; c_fuel ≔ c_fuelc

eauto 10

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros c o c′ H
apply or_stuck_next in H
destruct invalidate_locals_ _ as m | ; | discriminate H
destruct c_callersc as | caller pd callers ; discriminate H |
destruct match pd_convpd with None ⇒ Someo | Somecw, kw ⇒ converted_outcomecw kw o end as o′ | ; | discriminate H
destruct returned_env_ _ _ as e | eqn: Ee ; | discriminate H
injection H as ←
simpl
eauto 10

A caller that waits resumes with its scope, in a memory that persists, the call's result names being the only ones that changed.

642Lemma scope_return
∀ ge md fr e m m′ pd
shapedmd fr
waitsfr pd
∀a, ¬Ina result_namespd_respd → lookupa e = lookupa fr_envfr
persistsm m′
Explore proof 12 tactics

Initial goal

⊢
∀ge : genv md : module fr : frame e : listname × word m m′ : Memory.mem pd : pending, checked_modulemd → shapedmd fr → waitsfr pd → ∀a : name, ¬Ina result_namespd_respd → lookupa e = lookupa fr_envfr → persistsm m′ → scope_holdsge fr m → scope_holdsge fr_fn ≔ fr_fnfr; fr_env ≔ e; fr_locals ≔ fr_localsfr; fr_doomed ≔ fr_doomedfr; fr_at ≔ fr_atfr m′

intros ge md fr e m m′ pd Hmd Hsh l & rest & j & b & k & ci & Ha & Hb & Hk & Hrest & Hci He Hp Hold

ge :
md :
fr :
e :
listname × word
m, m′ :
Memory.mem
Hsh :
shapedmd fr
l :
rest :
listinst
j :
k :
nat
ci :
Ha :
fr_atfr = Execl rest j
Hb :
Hk :
nth_errorb_instsb k = Someci
Hrest :
rest = skipnSk b_instsb
Hci :
∃cl : value args : listarg, ci = Callpd_respd cl args ∨ ∃cl : value args : listarg, ci = RawCallpd_respd cl args
He :
∀a : name, ¬Ina result_namespd_respd → lookupa e = lookupa fr_envfr
Hp :
persistsm m′
Hold :
⊢
scope_holdsge fr_fn ≔ fr_fnfr; fr_env ≔ e; fr_locals ≔ fr_localsfr; fr_doomed ≔ fr_doomedfr; fr_at ≔ fr_atfr m′

unfold shaped in Hsh

ge :
md :
fr :
e :
listname × word
m, m′ :
Memory.mem
Hsh :
InIFuncfr_fnfr md
∧
match fr_atfr with
⇒
entry_labelfr_fnfr = Somel
Enterl from
⇒
is_reachablefn_domsfr_fnfr l = true ∧ from = None → entry_labelfr_fnfr = Somel
Execl is j
⇒
is_reachablefn_domsfr_fnfr l = true ∧ ∃b : block k : nat, find_blockl fn_blocksfr_fnfr = Someb ∧ k ≤ Datatypes.lengthb_instsb%nat ∧ is = skipnk b_instsb ∧ j = b_jumpb
l :
rest :
listinst
j :
k :
nat
ci :
Ha :
fr_atfr = Execl rest j
Hb :
Hk :
nth_errorb_instsb k = Someci
Hrest :
rest = skipnSk b_instsb
Hci :
∃cl : value args : listarg, ci = Callpd_respd cl args ∨ ∃cl : value args : listarg, ci = RawCallpd_respd cl args
He :
∀a : name, ¬Ina result_namespd_respd → lookupa e = lookupa fr_envfr
Hp :
persistsm m′
Hold :
⊢
scope_holdsge fr_fn ≔ fr_fnfr; fr_env ≔ e; fr_locals ≔ fr_localsfr; fr_doomed ≔ fr_doomedfr; fr_at ≔ fr_atfr m′

cbv zeta in Hsh

ge :
md :
fr :
e :
listname × word
m, m′ :
Memory.mem
Hsh :
InIFuncfr_fnfr md
∧
match fr_atfr with
⇒
entry_labelfr_fnfr = Somel
Enterl from
⇒
is_reachablefn_domsfr_fnfr l = true ∧ from = None → entry_labelfr_fnfr = Somel
Execl is j
⇒
is_reachablefn_domsfr_fnfr l = true ∧ ∃b : block k : nat, find_blockl fn_blocksfr_fnfr = Someb ∧ k ≤ Datatypes.lengthb_instsb%nat ∧ is = skipnk b_instsb ∧ j = b_jumpb
l :
rest :
listinst
j :
k :
nat
ci :
Ha :
fr_atfr = Execl rest j
Hb :
Hk :
nth_errorb_instsb k = Someci
Hrest :
rest = skipnSk b_instsb
Hci :
∃cl : value args : listarg, ci = Callpd_respd cl args ∨ ∃cl : value args : listarg, ci = RawCallpd_respd cl args
He :
∀a : name, ¬Ina result_namespd_respd → lookupa e = lookupa fr_envfr
Hp :
persistsm m′
Hold :
⊢
scope_holdsge fr_fn ≔ fr_fnfr; fr_env ≔ e; fr_locals ≔ fr_localsfr; fr_doomed ≔ fr_doomedfr; fr_at ≔ fr_atfr m′

rewrite Ha in Hsh

ge :
md :
fr :
e :
listname × word
m, m′ :
Memory.mem
l :
rest :
listinst
j :
Hsh :
InIFuncfr_fnfr md ∧ is_reachablefn_domsfr_fnfr l = true ∧ ∃b : block k : nat, find_blockl fn_blocksfr_fnfr = Someb ∧ k ≤ Datatypes.lengthb_instsb%nat ∧ rest = skipnk b_instsb ∧ j = b_jumpb
k :
nat
ci :
Ha :
fr_atfr = Execl rest j
Hb :
Hk :
nth_errorb_instsb k = Someci
Hrest :
rest = skipnSk b_instsb
Hci :
∃cl : value args : listarg, ci = Callpd_respd cl args ∨ ∃cl : value args : listarg, ci = RawCallpd_respd cl args
He :
∀a : name, ¬Ina result_namespd_respd → lookupa e = lookupa fr_envfr
Hp :
persistsm m′
Hold :
⊢
scope_holdsge fr_fn ≔ fr_fnfr; fr_env ≔ e; fr_locals ≔ fr_localsfr; fr_doomed ≔ fr_doomedfr; fr_at ≔ fr_atfr m′

destruct Hsh as Hin & Hr & _

ge :
md :
fr :
e :
listname × word
m, m′ :
Memory.mem
l :
rest :
listinst
j :
Hin :
InIFuncfr_fnfr md
Hr :
k :
nat
ci :
Ha :
fr_atfr = Execl rest j
Hb :
Hk :
nth_errorb_instsb k = Someci
Hrest :
rest = skipnSk b_instsb
Hci :
∃cl : value args : listarg, ci = Callpd_respd cl args ∨ ∃cl : value args : listarg, ci = RawCallpd_respd cl args
He :
∀a : name, ¬Ina result_namespd_respd → lookupa e = lookupa fr_envfr
Hp :
persistsm m′
Hold :
⊢
scope_holdsge fr_fn ≔ fr_fnfr; fr_env ≔ e; fr_locals ≔ fr_localsfr; fr_doomed ≔ fr_doomedfr; fr_at ≔ fr_atfr m′

assert Hlen : Sk ≤ lengthb_instsb%nat by apply nth_error_Some ; rewrite Hk ; discriminate

ge :
md :
fr :
e :
listname × word
m, m′ :
Memory.mem
l :
rest :
listinst
j :
Hin :
InIFuncfr_fnfr md
Hr :
k :
nat
ci :
Ha :
fr_atfr = Execl rest j
Hb :
Hk :
nth_errorb_instsb k = Someci
Hrest :
rest = skipnSk b_instsb
Hci :
∃cl : value args : listarg, ci = Callpd_respd cl args ∨ ∃cl : value args : listarg, ci = RawCallpd_respd cl args
He :
∀a : name, ¬Ina result_namespd_respd → lookupa e = lookupa fr_envfr
Hp :
persistsm m′
Hold :
Hlen :
Sk ≤ Datatypes.lengthb_instsb%nat
⊢
scope_holdsge fr_fn ≔ fr_fnfr; fr_env ≔ e; fr_locals ≔ fr_localsfr; fr_doomed ≔ fr_doomedfr; fr_at ≔ fr_atfr m′

refine scope_after_ _ fr mkFramefr_fnfr e fr_localsfr fr_doomedfr fr_atfr _ _ _ _ _ ci Hmd Hin eq_refl eq_refl Hr Hb Hk _ _ _ Hp Hold

3 open

ge :
md :
fr :
e :
listname × word
m, m′ :
Memory.mem
l :
rest :
listinst
j :
Hin :
InIFuncfr_fnfr md
Hr :
k :
nat
ci :
Ha :
fr_atfr = Execl rest j
Hb :
Hk :
nth_errorb_instsb k = Someci
Hrest :
rest = skipnSk b_instsb
Hci :
∃cl : value args : listarg, ci = Callpd_respd cl args ∨ ∃cl : value args : listarg, ci = RawCallpd_respd cl args
He :
∀a : name, ¬Ina result_namespd_respd → lookupa e = lookupa fr_envfr
Hp :
persistsm m′
Hold :
Hlen :
Sk ≤ Datatypes.lengthb_instsb%nat
⊢
replayableci = false
focused goal
ge :
md :
fr :
e :
listname × word
m, m′ :
Memory.mem
l :
rest :
listinst
j :
Hin :
InIFuncfr_fnfr md
Hr :
k :
nat
ci :
Ha :
fr_atfr = Execl rest j
Hb :
Hk :
nth_errorb_instsb k = Someci
Hrest :
rest = skipnSk b_instsb
Hci :
∃cl : value args : listarg, ci = Callpd_respd cl args ∨ ∃cl : value args : listarg, ci = RawCallpd_respd cl args
He :
∀a : name, ¬Ina result_namespd_respd → lookupa e = lookupa fr_envfr
Hp :
persistsm m′
Hold :
Hlen :
Sk ≤ Datatypes.lengthb_instsb%nat
⊢
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
focused goal
ge :
md :
fr :
e :
listname × word
m, m′ :
Memory.mem
l :
rest :
listinst
j :
Hin :
InIFuncfr_fnfr md
Hr :
k :
nat
ci :
Ha :
fr_atfr = Execl rest j
Hb :
Hk :
nth_errorb_instsb k = Someci
Hrest :
rest = skipnSk b_instsb
Hci :
∃cl : value args : listarg, ci = Callpd_respd cl args ∨ ∃cl : value args : listarg, ci = RawCallpd_respd cl args
He :
∀a : name, ¬Ina result_namespd_respd → lookupa e = lookupa fr_envfr
Hp :
persistsm m′
Hold :
Hlen :
Sk ≤ Datatypes.lengthb_instsb%nat
⊢
∀a : name, ¬Ina mapfst inst_temp_defsci → lookupa fr_envfr_fn ≔ fr_fnfr; fr_env ≔ e; fr_locals ≔ fr_localsfr; fr_doomed ≔ fr_doomedfr; fr_at ≔ fr_atfr = lookupa fr_envfr

–destruct Hci as cl & args & → | cl & args & → ; reflexivity

2 open

deferred goal
ge :
md :
fr :
e :
listname × word
m, m′ :
Memory.mem
l :
rest :
listinst
j :
Hin :
InIFuncfr_fnfr md
Hr :
k :
nat
ci :
Ha :
fr_atfr = Execl rest j
Hb :
Hk :
nth_errorb_instsb k = Someci
Hrest :
rest = skipnSk b_instsb
Hci :
∃cl : value args : listarg, ci = Callpd_respd cl args ∨ ∃cl : value args : listarg, ci = RawCallpd_respd cl args
He :
∀a : name, ¬Ina result_namespd_respd → lookupa e = lookupa fr_envfr
Hp :
persistsm m′
Hold :
Hlen :
Sk ≤ Datatypes.lengthb_instsb%nat
⊢
point_sitefr_fnfr fr_atfr = Somel, Z.of_natSk
deferred goal
ge :
md :
fr :
e :
listname × word
m, m′ :
Memory.mem
l :
rest :
listinst
j :
Hin :
InIFuncfr_fnfr md
Hr :
k :
nat
ci :
Ha :
fr_atfr = Execl rest j
Hb :
Hk :
nth_errorb_instsb k = Someci
Hrest :
rest = skipnSk b_instsb
Hci :
∃cl : value args : listarg, ci = Callpd_respd cl args ∨ ∃cl : value args : listarg, ci = RawCallpd_respd cl args
He :
∀a : name, ¬Ina result_namespd_respd → lookupa e = lookupa fr_envfr
Hp :
persistsm m′
Hold :
Hlen :
Sk ≤ Datatypes.lengthb_instsb%nat
⊢
∀a : name, ¬Ina mapfst inst_temp_defsci → lookupa fr_envfr_fn ≔ fr_fnfr; fr_env ≔ e; fr_locals ≔ fr_localsfr; fr_doomed ≔ fr_doomedfr; fr_at ≔ fr_atfr = lookupa fr_envfr

–rewrite Ha , Hrest

2 open

ge :
md :
fr :
e :
listname × word
m, m′ :
Memory.mem
l :
rest :
listinst
j :
Hin :
InIFuncfr_fnfr md
Hr :
k :
nat
ci :
Ha :
fr_atfr = Execl rest j
Hb :
Hk :
nth_errorb_instsb k = Someci
Hrest :
rest = skipnSk b_instsb
Hci :
∃cl : value args : listarg, ci = Callpd_respd cl args ∨ ∃cl : value args : listarg, ci = RawCallpd_respd cl args
He :
∀a : name, ¬Ina result_namespd_respd → lookupa e = lookupa fr_envfr
Hp :
persistsm m′
Hold :
Hlen :
Sk ≤ Datatypes.lengthb_instsb%nat
⊢
point_sitefr_fnfr Execl skipnSk b_instsb j = Somel, Z.of_natSk
deferred goal
ge :
md :
fr :
e :
listname × word
m, m′ :
Memory.mem
l :
rest :
listinst
j :
Hin :
InIFuncfr_fnfr md
Hr :
k :
nat
ci :
Ha :
fr_atfr = Execl rest j
Hb :
Hk :
nth_errorb_instsb k = Someci
Hrest :
rest = skipnSk b_instsb
Hci :
∃cl : value args : listarg, ci = Callpd_respd cl args ∨ ∃cl : value args : listarg, ci = RawCallpd_respd cl args
He :
∀a : name, ¬Ina result_namespd_respd → lookupa e = lookupa fr_envfr
Hp :
persistsm m′
Hold :
Hlen :
Sk ≤ Datatypes.lengthb_instsb%nat
⊢
∀a : name, ¬Ina mapfst inst_temp_defsci → lookupa fr_envfr_fn ≔ fr_fnfr; fr_env ≔ e; fr_locals ≔ fr_localsfr; fr_doomed ≔ fr_doomedfr; fr_at ≔ fr_atfr = lookupa fr_envfr

exact point_site_exec_ _ _ _ _ Hb Hlen

deferred goal
ge :
md :
fr :
e :
listname × word
m, m′ :
Memory.mem
l :
rest :
listinst
j :
Hin :
InIFuncfr_fnfr md
Hr :
k :
nat
ci :
Ha :
fr_atfr = Execl rest j
Hb :
Hk :
nth_errorb_instsb k = Someci
Hrest :
rest = skipnSk b_instsb
Hci :
∃cl : value args : listarg, ci = Callpd_respd cl args ∨ ∃cl : value args : listarg, ci = RawCallpd_respd cl args
He :
∀a : name, ¬Ina result_namespd_respd → lookupa e = lookupa fr_envfr
Hp :
persistsm m′
Hold :
Hlen :
Sk ≤ Datatypes.lengthb_instsb%nat
⊢
∀a : name, ¬Ina mapfst inst_temp_defsci → lookupa fr_envfr_fn ≔ fr_fnfr; fr_env ≔ e; fr_locals ≔ fr_localsfr; fr_doomed ≔ fr_doomedfr; fr_at ≔ fr_atfr = lookupa fr_envfr

–simpl

ge :
md :
fr :
e :
listname × word
m, m′ :
Memory.mem
l :
rest :
listinst
j :
Hin :
InIFuncfr_fnfr md
Hr :
k :
nat
ci :
Ha :
fr_atfr = Execl rest j
Hb :
Hk :
nth_errorb_instsb k = Someci
Hrest :
rest = skipnSk b_instsb
Hci :
∃cl : value args : listarg, ci = Callpd_respd cl args ∨ ∃cl : value args : listarg, ci = RawCallpd_respd cl args
He :
∀a : name, ¬Ina result_namespd_respd → lookupa e = lookupa fr_envfr
Hp :
persistsm m′
Hold :
Hlen :
Sk ≤ Datatypes.lengthb_instsb%nat
⊢
∀a : name, ¬Ina mapfst inst_temp_defsci → lookupa e = lookupa fr_envfr

destruct Hci as cl & args & → | cl & args & → ; rewrite call_defs | rewrite raw_call_defs ; exact He

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge md fr e m m′ pd Hmd Hsh l & rest & j & b & k & ci & Ha & Hb & Hk & Hrest & Hci He Hp Hold
unfold shaped in Hsh
cbv zeta in Hsh
rewrite Ha in Hsh
destruct Hsh as Hin & Hr & _
assert Hlen : Sk ≤ lengthb_instsb%nat by apply nth_error_Some ; rewrite Hk ; discriminate
refine scope_after_ _ fr mkFramefr_fnfr e fr_localsfr fr_doomedfr fr_atfr _ _ _ _ _ ci Hmd Hin eq_refl eq_refl Hr Hb Hk _ _ _ Hp Hold
–destruct Hci as cl & args & → | cl & args & → ; reflexivity
–rewrite Ha , Hrest
exact point_site_exec_ _ _ _ _ Hb Hlen
–simpl
destruct Hci as cl & args & → | cl & args & → ; rewrite call_defs | rewrite raw_call_defs ; exact He

Waiting callers keep their scope in a memory that persists.

659Lemma callers_mem
∀ ge md cs m m′
Forallwaitingge md m cs
persistsm m′
Forallwaitingge md m′ cs
Explore proof 4 tactics

Initial goal

⊢
∀ge : genv md : module cs : listframe × pending m m′ : Memory.mem, Forallwaitingge md m cs → persistsm m′ → Forallwaitingge md m′ cs

intros ge md cs m m′ H Hp

ge :
md :
cs :
listframe × pending
m, m′ :
Memory.mem
H :
Forallwaitingge md m cs
Hp :
persistsm m′
⊢
Forallwaitingge md m′ cs

eapply Forall_impl ; | exact H

ge :
md :
cs :
listframe × pending
m, m′ :
Memory.mem
H :
Forallwaitingge md m cs
Hp :
persistsm m′
⊢
∀a : frame × pending, waitingge md m a → waitingge md m′ a

intros fp Hs & Hd & Hw & Hsc

ge :
md :
cs :
listframe × pending
m, m′ :
Memory.mem
H :
Forallwaitingge md m cs
Hp :
persistsm m′
fp :
Hs :
shapedmd fstfp
Hd :
fr_doomedfstfp = None
Hw :
waitsfstfp sndfp
Hsc :
scope_holdsge fstfp m
⊢
waitingge md m′ fp

exact conjHs conjHd conjHw scope_mem_ _ _ _ Hsc Hp

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge md cs m m′ H Hp
eapply Forall_impl ; | exact H
intros fp Hs & Hd & Hw & Hsc
exact conjHs conjHd conjHw scope_mem_ _ _ _ Hsc Hp

The running frame keeps its scope in a memory that persists.

667Lemma running_mem
∀ ge md fr m m′
runningge md m fr
persistsm m′
runningge md m′ fr
Explore proof 3 tactics

Initial goal

⊢
∀ge : genv md : module fr : frame m m′ : Memory.mem, runningge md m fr → persistsm m′ → runningge md m′ fr

intros ge md fr m m′ Hs Hsc Hp

ge :
md :
fr :
m, m′ :
Memory.mem
Hs :
shapedmd fr
Hsc :
fr_doomedfr ≠ None ∨ scope_holdsge fr m
Hp :
persistsm m′
⊢
runningge md m′ fr

split ; exact Hs |

ge :
md :
fr :
m, m′ :
Memory.mem
Hs :
shapedmd fr
Hsc :
fr_doomedfr ≠ None ∨ scope_holdsge fr m
Hp :
persistsm m′
⊢
fr_doomedfr ≠ None ∨ scope_holdsge fr m′

destruct Hsc as Hd | Hsc ; left ; exact Hd | right ; exact scope_mem_ _ _ _ Hsc Hp

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge md fr m m′ Hs Hsc Hp
split ; exact Hs |
destruct Hsc as Hd | Hsc ; left ; exact Hd | right ; exact scope_mem_ _ _ _ Hsc Hp

After an instruction, the frame is doomed, or it was not doomed and the instruction's result is its own.

675Lemma doomed_cases
∀ ge fr m i out od
doomed_resultge fr m i out = Someod
sndod ≠ None ∨ fr_doomedfr = None ∧ od = out, None
Explore proof 6 tactics

Initial goal

⊢
∀ge : genv fr : frame m : Memory.mem i : inst out : inst_out od : inst_out × optionreason, doomed_resultge fr m i out = Someod → sndod ≠ None ∨ fr_doomedfr = None ∧ od = out, None

intros ge fr m i out od H

ge :
fr :
m :
Memory.mem
i :
od :
inst_out × optionreason
H :
doomed_resultge fr m i out = Someod
⊢
sndod ≠ None ∨ fr_doomedfr = None ∧ od = out, None

destruct fr_doomedfr as w | eqn: Ew

2 open

ge :
fr :
m :
Memory.mem
i :
od :
inst_out × optionreason
H :
doomed_resultge fr m i out = Someod
Ew :
fr_doomedfr = Somew
⊢
sndod ≠ None ∨ Somew = None ∧ od = out, None
focused goal
ge :
fr :
m :
Memory.mem
i :
od :
inst_out × optionreason
H :
doomed_resultge fr m i out = Someod
Ew :
fr_doomedfr = None
⊢
sndod ≠ None ∨ None = None ∧ od = out, None

–left

2 open

ge :
fr :
m :
Memory.mem
i :
od :
inst_out × optionreason
H :
doomed_resultge fr m i out = Someod
Ew :
fr_doomedfr = Somew
⊢
sndod ≠ None
deferred goal
ge :
fr :
m :
Memory.mem
i :
od :
inst_out × optionreason
H :
doomed_resultge fr m i out = Someod
Ew :
fr_doomedfr = None
⊢
sndod ≠ None ∨ None = None ∧ od = out, None

assert Hnd : fr_doomedfr ≠ None by rewrite Ew ; discriminate

2 open

ge :
fr :
m :
Memory.mem
i :
od :
inst_out × optionreason
H :
doomed_resultge fr m i out = Someod
Ew :
fr_doomedfr = Somew
Hnd :
fr_doomedfr ≠ None
⊢
sndod ≠ None
deferred goal
ge :
fr :
m :
Memory.mem
i :
od :
inst_out × optionreason
H :
doomed_resultge fr m i out = Someod
Ew :
fr_doomedfr = None
⊢
sndod ≠ None ∨ None = None ∧ od = out, None

exact proj1doomed_result_doomed_ _ _ _ _ _ Hnd H

deferred goal
ge :
fr :
m :
Memory.mem
i :
od :
inst_out × optionreason
H :
doomed_resultge fr m i out = Someod
Ew :
fr_doomedfr = None
⊢
sndod ≠ None ∨ None = None ∧ od = out, None

–destruct doomed_result_fresh_ _ _ _ _ _ Ew H as → | e & w & → ; right ; auto | left ; simpl ; discriminate

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge fr m i out od H
destruct fr_doomedfr as w | eqn: Ew
–left
assert Hnd : fr_doomedfr ≠ None by rewrite Ew ; discriminate
exact proj1doomed_result_doomed_ _ _ _ _ _ Hnd H
–destruct doomed_result_fresh_ _ _ _ _ _ Ew H as → | e & w & → ; right ; auto | left ; simpl ; discriminate

Every step keeps the invariant

The invariant over the runs of Machine R, for any runtime R.

689Module Single R : Runtime
691Module ID ≔ Identity R
692Module I ≔ Invariant R
Import ID
Import RM

A snapshot step keeps sinv: it enters the entry block, where nothing is in scope.

698Lemma next_sinv_snapshot
∀ ge md c c′ xs l
sinvge md c′
Explore proof 9 tactics

Initial goal

⊢
∀ge : genv md : module c c′ : config xs : listword l : name, checked_modulemd → fr_atc_framec = Snapshotxs l → stepge c = Nextc′ → persistsc_memc c_memc′ → sinvge md c → sinvge md c′

intros ge md c c′ xs l Hmd Ha Hs Hp Hsh _ Hcall

ge :
md :
c, c′ :
xs :
listword
l :
Hs :
stepge c = Nextc′
Hsh :
Hcall :
Forallwaitingge md c_memc c_callersc
⊢
sinvge md c′

destruct step_snapshot_ _ _ _ _ Ha Hs as Hc & Hf & _ & _ & Ha′

ge :
md :
c, c′ :
xs :
listword
l :
Hs :
stepge c = Nextc′
Hsh :
Hcall :
Forallwaitingge md c_memc c_callersc
Hc :
Ha′ :
fr_atc_framec′ = Enterl None
⊢
sinvge md c′

unfold shaped in Hsh

ge :
md :
c, c′ :
xs :
listword
l :
Hs :
stepge c = Nextc′
Hsh :
∧
match fr_atc_framec with
Enterl from
⇒
is_reachablefn_domsfr_fnc_framec l = true ∧ from = None → entry_labelfr_fnc_framec = Somel
Execl is j
⇒
is_reachablefn_domsfr_fnc_framec l = true ∧ ∃b : block k : nat, find_blockl fn_blocksfr_fnc_framec = Someb ∧ k ≤ Datatypes.lengthb_instsb%nat ∧ is = skipnk b_instsb ∧ j = b_jumpb
Hcall :
Forallwaitingge md c_memc c_callersc
Hc :
Ha′ :
fr_atc_framec′ = Enterl None
⊢
sinvge md c′

cbv zeta in Hsh

ge :
md :
c, c′ :
xs :
listword
l :
Hs :
stepge c = Nextc′
Hsh :
∧
match fr_atc_framec with
Enterl from
⇒
is_reachablefn_domsfr_fnc_framec l = true ∧ from = None → entry_labelfr_fnc_framec = Somel
Execl is j
⇒
is_reachablefn_domsfr_fnc_framec l = true ∧ ∃b : block k : nat, find_blockl fn_blocksfr_fnc_framec = Someb ∧ k ≤ Datatypes.lengthb_instsb%nat ∧ is = skipnk b_instsb ∧ j = b_jumpb
Hcall :
Forallwaitingge md c_memc c_callersc
Hc :
Ha′ :
fr_atc_framec′ = Enterl None
⊢
sinvge md c′

rewrite Ha in Hsh

ge :
md :
c, c′ :
xs :
listword
l :
Hs :
stepge c = Nextc′
Hsh :
Hcall :
Forallwaitingge md c_memc c_callersc
Hc :
Ha′ :
fr_atc_framec′ = Enterl None
⊢
sinvge md c′

destruct Hsh as Hin He

ge :
md :
c, c′ :
xs :
listword
l :
Hs :
stepge c = Nextc′
Hcall :
Forallwaitingge md c_memc c_callersc
Hc :
Ha′ :
fr_atc_framec′ = Enterl None
⊢
sinvge md c′

rewrite <- Hf in Hin , He

ge :
md :
c, c′ :
xs :
listword
l :
Hs :
stepge c = Nextc′
Hin :
He :
Hcall :
Forallwaitingge md c_memc c_callersc
Hc :
Ha′ :
fr_atc_framec′ = Enterl None
⊢
sinvge md c′

destruct at_entryge _ _ c_memc′ _ Hmd Hin He or_introlHa′ as Hsh′ Hsc′

ge :
md :
c, c′ :
xs :
listword
l :
Hs :
stepge c = Nextc′
Hin :
He :
Hcall :
Forallwaitingge md c_memc c_callersc
Hc :
Ha′ :
fr_atc_framec′ = Enterl None
Hsh′ :
Hsc′ :
⊢
sinvge md c′

split ; split ; exact Hsh′ | right ; exact Hsc′ | rewrite Hc ; exact callers_mem_ _ _ _ _ Hcall Hp

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge md c c′ xs l Hmd Ha Hs Hp Hsh _ Hcall
destruct step_snapshot_ _ _ _ _ Ha Hs as Hc & Hf & _ & _ & Ha′
unfold shaped in Hsh
cbv zeta in Hsh
rewrite Ha in Hsh
destruct Hsh as Hin He
rewrite <- Hf in Hin , He
destruct at_entryge _ _ c_memc′ _ Hmd Hin He or_introlHa′ as Hsh′ Hsc′
split ; split ; exact Hsh′ | right ; exact Hsc′ | rewrite Hc ; exact callers_mem_ _ _ _ _ Hcall Hp

Entering a block keeps sinv: its phis define their names at index -1, and its first instruction is at index 0.

712Lemma next_sinv_enter
∀ ge md c c′ l from
sinvge md c′
Proof 29 steps Qed
intros ge md c c′ l from Hmd Ha Hs Hp Hsh Hsc Hcall
destruct step_enter_ _ _ _ _ Ha Hs as b & e & Hb & Hphi & →
simpl in Hp |- *
unfold shaped in Hsh
cbv zeta in Hsh
rewrite Ha in Hsh
destruct Hsh as Hin & Hr & _
split ; | exact callers_mem_ _ _ _ _ Hcall Hp
split
–unfold shaped
cbv zeta
simpl
split ; exact Hin |
split ; exact Hr |
exists b, O
split ; exact Hb |
split ; lia | split ; reflexivity
–destruct Hsc as Hd | Hsc ; left ; exact Hd | right
destruct func_facts_ _ Hmd Hin as b0 & rest & Hf & Hd & _ & Hdd
destruct find_block_in_ _ _ Hb as Hbin Hl
intros l′ k n s i Hpt Hn Hrp Hpos Hsd
simpl in Hpt
rewrite Hb in Hpt
injection Hpt as ← ←
rewrite Nat.sub_diag in Hsd
pose proof site_first_ _ _ _ _ _ Hpos Hsd as Hsd0
assert HX : ∀x, Inx mapphi_name b_phisb → ∃D, Inx, SAtl −1, D def_positionsfr_fnc_framec by rewrite <- Hl ; exact phi_defs_here_ _ Hbin
destruct scope_moves_ _ _ _ _ _ _ _ _ _ _ Hf Hd Hdd Hr HX λa Ha ⇒ phis_env_other_ _ _ _ _ _ Hphi Ha Hn Hpos Hsd0 as Hn′ Ha′
exact replays_change_ _ _ _ _ _ _ _ Hscl −1 n s i ltac:rewrite Ha ; reflexivity Hn Hrp Hpos Hsd0 Hn' Ha' Hp

A jump keeps sinv: it takes an edge, to the entry of a block whose dominators dominated the jump (site_edge); or it returns to a waiting caller, which resumes with its scope (scope_return).

740Lemma next_sinv_jump
∀ ge md c c′ l j
sinvge md c′
Proof 41 steps Qed
intros ge md c c′ l j Hmd Ha Hs Hp Hsh Hsc Hcall
pose proof Hs as Hs0
unfold step in Hs
rewrite Ha in Hs
unfold shaped in Hsh
cbv zeta in Hsh
rewrite Ha in Hsh
destruct Hsh as Hin & Hr & b & k & Hb & Hk & Hnil & Hj
destruct func_facts_ _ Hmd Hin as b0 & rest & Hf & Hd & Hnd & Hdd
destruct find_block_in_ _ _ Hb as Hbin Hl
subst l
pose proof skipn_nil_length_ _ _ eq_symHnil Hk as Hkl
destruct I.jump_step_next_ _ _ _ _ Hs as t & Ht & → | Hdn & o & Hret
–simpl in Hp |- *
assert Hsucc : Inedge_labelt jump_succsb_jumpb by rewrite <- Hj ; exact target_succ_ _ I.taken_target_in_ _ _ _ Ht
assert He : edgeb0 :: rest b_labelb edge_labelt by exists b ; rewrite <- Hf ; repeat split ; assumption
split ; | exact callers_mem_ _ _ _ _ Hcall Hp
split
+unfold shaped
cbv zeta
simpl
split ; exact Hin |
split ; | discriminate
rewrite Hf in Hnd
exact dom_closed_ _ _ Hd _ _ Hnd Hr He
+destruct Hsc as Hdm | Hsc ; left ; exact Hdm | right
intros l′ k′ n s i Hpt Hn Hrp Hpos Hsd
simpl in Hpt
injection Hpt as ← ←
pose proof site_edge_ _ _ _ _ _ _ _ _ Hf Hd Hnd Hb Hr Hsucc Hpos Hsd as Hsd0
refine replays_change_ _ _ _ _ _ _ _ Hsc_ _ _ _ _ _ Hn Hrp Hpos Hsd0 eq_refl λ_ _ _ ⇒ eq_refl Hp
rewrite Ha , Hnil , Hkl
exact point_site_exec_ _ _ _ _ Hb le_n_
–destruct return_step_env_ _ _ Hret as caller & pd & callers & o′ & e & Hcs & Hre & →
rewrite Hcs in Hcall
inversion Hcall as | fp fps Hw Hrest ; subst
simpl in Hp |- *
destruct Hw as Hshc & Hdc & Hwt & Hscc
split ; | exact callers_mem_ _ _ _ _ Hrest Hp
split ; exact Hshc | right
exact scope_return_ _ _ _ _ _ _ Hmd Hshc Hwt λa Ha ⇒ returned_env_other_ _ _ _ _ Hre Ha Hp Hscc

An instruction keeps sinv: it continues, and its own name replays from where it ran; or it calls, the callee starting with nothing in scope and the caller waiting.

776Lemma next_sinv_inst
∀ ge md c c′ l i rest j
sinvge md c′
Proof 71 steps Qed
intros ge md c c′ l i rest j Hge Hmd Ha Hs Hp Hfit Hsh Hsc Hcall
destruct step_exec_cons_ _ _ _ _ _ _ Ha Hs ltac:discriminate ltac:discriminate as Hdoom & out0 & od & Hi & Hdr & Hn
unfold shaped in Hsh
cbv zeta in Hsh
rewrite Ha in Hsh
destruct Hsh as Hin & Hr & b & k & Hb & Hk & Hsk & Hj
destruct skipn_cons_ _ _ _ _ eq_symHsk as Hki & Hrest & Hlen
assert Hpt0 : point_sitefr_fnc_framec fr_atc_framec = Somel, Z.of_natk by rewrite Ha , Hsk ; exact point_site_exec_ _ _ _ _ Hb Hk
assert Hpt1 : point_sitefr_fnc_framec Execl rest j = Somel, Z.of_natSk by rewrite <- Hrest ; exact point_site_exec_ _ _ _ _ Hb Hlen
assert Hsh1 : ∀e1 l1 d, shapedmd mkFramefr_fnc_framec e1 l1 d Execl rest j
{intros e1 l1 d
unfold shaped
cbv zeta
simpl
split ; exact Hin |
split ; exact Hr |
exists b, Sk
split ; exact Hb |
split ; exact Hlen |
split ; symmetry ; exact Hrest | exact Hj
destruct inst_next_next_ _ _ _ _ _ _ Hn as e1 & l1 & m1 & Ho & → | g & xs & pd & callee & Ho & Hcf & → ; simpl in Hp |- *
–split ; | exact callers_mem_ _ _ _ _ Hcall Hp
split ; apply Hsh1 |
destruct doomed_cases_ _ _ _ _ _ Hdr as Hdn | Hfd & → ; left ; exact Hdn | right
simpl in Ho |- *
subst out0
destruct Hsc as Hdm | Hsc ; contradiction |
destruct func_facts_ _ Hmd Hin as b0 & rs & Hf & Hd & _ & Hdd
destruct find_block_in_ _ _ Hb as Hbin Hl
refine scope_step_ _ c_framec mkFramefr_fnc_framec e1 l1 None Execl rest j _ _ _ _ _ i Hmd Hin eq_refl Hr Hb Hki Hpt0 Hpt1 inst_step_env_ _ _ _ _ _ _ Hi Hp _ Hsc
intros n Hrp Hn1
exists c_framec, c_memc, e1, l1, m1
split ; exact Hi |
split ; reflexivity |
split ; | exact conjpersists_refl_ Hfit
intros a Hu Ho1
symmetry
apply inst_step_env_ _ _ _ _ _ _ Hi
rewrite <- Hl in Hr
exact operand_not_defined_ _ _ _ _ _ _ Hf Hd Hdd Hbin Hr Hki Hu Ho1
–assert Hd : fr_doomedc_framec = None ∧ out0 = ICallg xs pd ∧ sndod = None
{destruct doomed_cases_ _ _ _ _ _ Hdr as Hdn | Hfd & → ; exfalso | auto
destruct fr_doomedc_framec as w | eqn: Ew
–assert Hnd : fr_doomedc_framec ≠ None by rewrite Ew ; discriminate
destruct doomed_result_doomed_ _ _ _ _ _ Hnd Hdr as _ & Ho′ | e′ & Ho′ | o′ & Ho′ ; rewrite Ho in Ho' ; try discriminate Ho'
subst out0
destruct inst_step_call_shape_ _ _ _ _ _ _ Hi as _ & r & cl & args & → | r & cl & args & → ; destruct Hdoom as Hdoom | Hdoom ; simpl in Hdoom ; discriminate Hdoom
–destruct doomed_result_fresh_ _ _ _ _ _ Ew Hdr as → | e′ & w & → ; exact Hdneq_refl | discriminate Ho
destruct Hd as Hfd & → & Hsd
rewrite Hsd
destruct inst_step_call_shape_ _ _ _ _ _ _ Hi as Hg & _
rewrite Hge in Hg
destruct call_frame_entry_ _ _ Hcf as Hfg & _ & le & He & Hat
rewrite <- Hfg in Hg , He
destruct at_entryge md callee c_memc le Hmd Hg He Hat as Hsh′ Hsc′
split ; split ; exact Hsh' | right ; exact Hsc' |
destruct Hsc as Hdm | Hsc ; contradiction |
pose proof inst_step_call_pending_ _ _ _ _ _ _ Hi as Hpd
constructor ; | exact Hcall
split ; apply Hsh1 |
split ; reflexivity |
split
+exists l, rest, j, b, k, i
simpl
split ; reflexivity |
split ; exact Hb |
split ; exact Hki |
split ; symmetry ; exact Hrest | exact Hpd
+refine scope_step_ _ c_framec mkFramefr_fnc_framec fr_envc_framec fr_localsc_framec None Execl rest j _ _ _ _ _ i Hmd Hin eq_refl Hr Hb Hki Hpt0 Hpt1 λa _ ⇒ eq_refl persists_refl_ _ Hsc
intros n Hrp
destruct Hpd as cl & args & → | cl & args & → ; discriminate Hrp

A step that allocates nothing keeps sinv, where memory persists across it and fits the address space after it.

838Lemma next_sinv
∀ ge md c c′
sinvge md c′
Explore proof 6 tactics

Initial goal

⊢
∀ge : genv md : module c c′ : config, ge_modulege = md → checked_modulemd → stepge c = Nextc′ → persistsc_memc c_memc′ → objects_fitm_regionsc_memc′ → sinvge md c → sinvge md c′

intros ge md c c′ Hge Hmd Hs Hp Hfit H

ge :
md :
c, c′ :
Hge :
ge_modulege = md
Hs :
stepge c = Nextc′
H :
sinvge md c
⊢
sinvge md c′

destruct fr_atc_framec as xs l | l from | l | i rest j eqn: Ha

4 open

ge :
md :
c, c′ :
Hge :
ge_modulege = md
Hs :
stepge c = Nextc′
H :
sinvge md c
xs :
listword
l :
⊢
sinvge md c′
focused goal
ge :
md :
c, c′ :
Hge :
ge_modulege = md
Hs :
stepge c = Nextc′
H :
sinvge md c
l :
from :
optionname
Ha :
⊢
sinvge md c′
focused goal
ge :
md :
c, c′ :
Hge :
ge_modulege = md
Hs :
stepge c = Nextc′
H :
sinvge md c
l :
j :
Ha :
fr_atc_framec = Execl [ ] j
⊢
sinvge md c′
focused goal
ge :
md :
c, c′ :
Hge :
ge_modulege = md
Hs :
stepge c = Nextc′
H :
sinvge md c
l :
i :
rest :
listinst
j :
Ha :
fr_atc_framec = Execl i :: rest j
⊢
sinvge md c′

–exact next_sinv_snapshot_ _ _ _ _ _ Hmd Ha Hs Hp H

3 open

deferred goal
ge :
md :
c, c′ :
Hge :
ge_modulege = md
Hs :
stepge c = Nextc′
H :
sinvge md c
l :
from :
optionname
Ha :
⊢
sinvge md c′
deferred goal
ge :
md :
c, c′ :
Hge :
ge_modulege = md
Hs :
stepge c = Nextc′
H :
sinvge md c
l :
j :
Ha :
fr_atc_framec = Execl [ ] j
⊢
sinvge md c′
deferred goal
ge :
md :
c, c′ :
Hge :
ge_modulege = md
Hs :
stepge c = Nextc′
H :
sinvge md c
l :
i :
rest :
listinst
j :
Ha :
fr_atc_framec = Execl i :: rest j
⊢
sinvge md c′

–exact next_sinv_enter_ _ _ _ _ _ Hmd Ha Hs Hp H

2 open

deferred goal
ge :
md :
c, c′ :
Hge :
ge_modulege = md
Hs :
stepge c = Nextc′
H :
sinvge md c
l :
j :
Ha :
fr_atc_framec = Execl [ ] j
⊢
sinvge md c′
deferred goal
ge :
md :
c, c′ :
Hge :
ge_modulege = md
Hs :
stepge c = Nextc′
H :
sinvge md c
l :
i :
rest :
listinst
j :
Ha :
fr_atc_framec = Execl i :: rest j
⊢
sinvge md c′

–exact next_sinv_jump_ _ _ _ _ _ Hmd Ha Hs Hp H

deferred goal
ge :
md :
c, c′ :
Hge :
ge_modulege = md
Hs :
stepge c = Nextc′
H :
sinvge md c
l :
i :
rest :
listinst
j :
Ha :
fr_atc_framec = Execl i :: rest j
⊢
sinvge md c′

–exact next_sinv_inst_ _ _ _ _ _ _ _ Hge Hmd Ha Hs Hp Hfit H

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge md c c′ Hge Hmd Hs Hp Hfit H
destruct fr_atc_framec as xs l | l from | l | i rest j eqn: Ha
–exact next_sinv_snapshot_ _ _ _ _ _ Hmd Ha Hs Hp H
–exact next_sinv_enter_ _ _ _ _ _ Hmd Ha Hs Hp H
–exact next_sinv_jump_ _ _ _ _ _ Hmd Ha Hs Hp H
–exact next_sinv_inst_ _ _ _ _ _ _ _ Hge Hmd Ha Hs Hp Hfit H

An allocation keeps sinv: it defines names that do not replay, and memory persists across it.

852Lemma fresh_sinv
∀ ge md c q k base
sinvge md kbase
Proof 49 steps Qed
intros ge md c q k base Hmd Hs Hp Hsh Hsc Hcall
destruct fr_atc_framec as xs l | l from | l | i rest j eqn: Ha
–destruct step_snapshot_fresh_ _ _ _ _ _ Ha Hs base as Hc & Hf & _ & _ & Ha′
unfold shaped in Hsh
cbv zeta in Hsh
rewrite Ha in Hsh
destruct Hsh as Hin He
rewrite <- Hf in Hin , He
destruct at_entryge _ _ c_memkbase _ Hmd Hin He or_introlHa' as Hsh′ Hsc′
split ; split ; exact Hsh' | right ; exact Hsc' | rewrite Hc ; exact callers_mem_ _ _ _ _ Hcall Hp
–exfalso
exact step_enter_fresh_ _ _ _ _ _ Ha Hs
–exfalso
unfold step in Hs
rewrite Ha in Hs
exact jump_step_not_fresh_ _ _ _ _ _ Hs
–destruct step_exec_cons_ _ _ _ _ _ _ Ha Hs ltac:discriminate ltac:discriminate as _ & out0 & od & Hi & Hdr & Hn
destruct inst_next_fresh_ _ _ _ _ _ _ _ Hn as k0 & Ho & Hk
unfold shaped in Hsh
cbv zeta in Hsh
rewrite Ha in Hsh
destruct Hsh as Hin & Hr & b & ix & Hb & Hix & Hsk & Hj
destruct skipn_cons_ _ _ _ _ eq_symHsk as Hki & Hrest & Hlen
rewrite Hk in Hp |- *
destruct k0base as e locals m′ eqn: Ek
simpl in Hp |- *
split ; | exact callers_mem_ _ _ _ _ Hcall Hp
split
{unfold shaped
cbv zeta
simpl
split ; exact Hin |
split ; exact Hr |
exists b, Six
split ; exact Hb |
split ; exact Hlen |
split ; symmetry ; exact Hrest | exact Hj
destruct doomed_cases_ _ _ _ _ _ Hdr as Hdn | Hfd & → ; left ; exact Hdn | right
simpl in Ho |- *
subst out0
destruct Hsc as Hdm | Hsc ; contradiction |
pose proof inst_step_fresh_env_ _ _ _ _ _ Hi base as He
rewrite Ek in He
simpl in He
assert Hpt0 : point_sitefr_fnc_framec fr_atc_framec = Somel, Z.of_natix by rewrite Ha , Hsk ; exact point_site_exec_ _ _ _ _ Hb Hix
assert Hpt1 : point_sitefr_fnc_framec Execl rest j = Somel, Z.of_natSix by rewrite <- Hrest ; exact point_site_exec_ _ _ _ _ Hb Hlen
refine scope_step_ _ c_framec mkFramefr_fnc_framec e locals None Execl rest j _ _ _ _ _ i Hmd Hin eq_refl Hr Hb Hki Hpt0 Hpt1 He Hp _ Hsc
intros n Hrp
destruct inst_step_fresh_shape_ _ _ _ _ _ Hi as d & cl & al & args & → & _ | x & size & → & _ ; discriminate Hrp

The runtime's action at a safepoint keeps sinv: it changes only the memory, which persists.

890Lemma mem_sinv
∀ ge md c m′
sinvge md c
sinvge md with_memc m′
Explore proof 2 tactics

Initial goal

⊢
∀ge : genv md : module c : config m′ : Memory.mem, persistsc_memc m′ → sinvge md c → sinvge md with_memc m′

intros ge md c m′ Hp Hrun Hcall

ge :
md :
m′ :
Memory.mem
Hp :
Hrun :
Hcall :
Forallwaitingge md c_memc c_callersc
⊢
sinvge md with_memc m′

exact conjrunning_mem_ _ _ _ _ Hrun Hp callers_mem_ _ _ _ _ Hcall Hp

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge md c m′ Hp Hrun Hcall
exact conjrunning_mem_ _ _ _ _ Hrun Hp callers_mem_ _ _ _ _ Hcall Hp

Every machine step from a ready state keeps sinv, where the genv's free is R's, so keeps identities (mstep_persists).

898Theorem mstep_sinv
∀ ge md st st′
ge_modulege = md
ge_freege = R.free
mstepge st st′
sinvge md fstst
sinvge md fstst′
Explore proof 7 tactics

Initial goal

⊢
∀ge : genv md : module st st′ : mstate, ge_modulege = md → checked_modulemd → ge_freege = R.free → ready_statest → mstepge st st′ → sinvge md fstst → sinvge md fstst′

intros ge md st st′ Hge Hmd Hfree Hr Hs H

ge :
md :
st, st′ :
Hge :
ge_modulege = md
Hfree :
ge_freege = R.free
Hs :
mstepge st st′
H :
sinvge md fstst
⊢
sinvge md fstst′

pose proof mstep_persists_ _ _ Hfree Hr Hs as Hp

ge :
md :
st, st′ :
Hge :
ge_modulege = md
Hfree :
ge_freege = R.free
Hs :
mstepge st st′
H :
sinvge md fstst
Hp :
persistsc_memfstst c_memfstst′
⊢
sinvge md fstst′

pose proof R.address_space_ _ mstep_ready_ _ _ Hfree Hs Hr as Hfit

ge :
md :
st, st′ :
Hge :
ge_modulege = md
Hfree :
ge_freege = R.free
Hs :
mstepge st st′
H :
sinvge md fstst
Hp :
persistsc_memfstst c_memfstst′
⊢
sinvge md fstst′

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

3 open

ge :
md :
Hge :
ge_modulege = md
Hfree :
ge_freege = R.free
s :
R.state
Hr :
c′ :
E :
stepge c = Nextc′
H :
sinvge md c
⊢
sinvge md c′
focused goal
ge :
md :
Hge :
ge_modulege = md
Hfree :
ge_freege = R.free
s :
R.state
Hr :
k :
Z → config
base :
Z
s′ :
R.state
E :
stepge c = Freshq k
He :
0 ≤ req_extentq
Hal :
R.allocs q = Somebase, s′
H :
sinvge md c
⊢
sinvge md kbase
focused goal
ge :
md :
Hge :
ge_modulege = md
Hfree :
ge_freege = R.free
s :
R.state
Hr :
s′ :
R.state
m′ :
Memory.mem
Hd :
safepoint_duege c = true
Hact :
R.safepoints c_memc s′ m′
H :
sinvge md c
Hp :
⊢
sinvge md with_memc m′

–exact next_sinv_ _ _ _ Hge Hmd E Hp Hfit H

2 open

deferred goal
ge :
md :
Hge :
ge_modulege = md
Hfree :
ge_freege = R.free
s :
R.state
Hr :
k :
Z → config
base :
Z
s′ :
R.state
E :
stepge c = Freshq k
He :
0 ≤ req_extentq
Hal :
R.allocs q = Somebase, s′
H :
sinvge md c
⊢
sinvge md kbase
deferred goal
ge :
md :
Hge :
ge_modulege = md
Hfree :
ge_freege = R.free
s :
R.state
Hr :
s′ :
R.state
m′ :
Memory.mem
Hd :
safepoint_duege c = true
Hact :
R.safepoints c_memc s′ m′
H :
sinvge md c
Hp :
⊢
sinvge md with_memc m′

–exact fresh_sinv_ _ _ _ _ base Hmd E Hp H

deferred goal
ge :
md :
Hge :
ge_modulege = md
Hfree :
ge_freege = R.free
s :
R.state
Hr :
s′ :
R.state
m′ :
Memory.mem
Hd :
safepoint_duege c = true
Hact :
R.safepoints c_memc s′ m′
H :
sinvge md c
Hp :
⊢
sinvge md with_memc m′

–exact mem_sinv_ _ _ _ Hp H

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge md st st′ Hge Hmd Hfree Hr Hs H
pose proof mstep_persists_ _ _ Hfree Hr Hs as Hp
pose proof R.address_space_ _ mstep_ready_ _ _ Hfree Hs Hr as Hfit
destruct Hs as c c′ s E | c q k s base s′ E He Hal | c s s′ m′ Hd Hact ; simpl in *
–exact next_sinv_ _ _ _ Hge Hmd E Hp Hfit H
–exact fresh_sinv_ _ _ _ _ base Hmd E Hp H
–exact mem_sinv_ _ _ _ Hp H

From a ready start where it holds, sinv holds in every state a run reaches.

913Theorem mreachable_sinv
∀ ge md st st′
ge_modulege = md
ge_freege = R.free
mreachablege st st′
sinvge md fstst
sinvge md fstst′
Explore proof 4 tactics

Initial goal

⊢
∀ge : genv md : module st st′ : mstate, ge_modulege = md → checked_modulemd → ge_freege = R.free → mreachablege st st′ → ready_statest → sinvge md fstst → sinvge md fstst′

intros ge md st st′ Hge Hmd Hfree H

ge :
md :
st, st′ :
Hge :
ge_modulege = md
Hfree :
ge_freege = R.free
H :
mreachablege st st′
⊢
ready_statest → sinvge md fstst → sinvge md fstst′

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

2 open

ge :
md :
Hge :
ge_modulege = md
Hfree :
ge_freege = R.free
st, st′ :
Hs :
mstepge st st′
Hi :
sinvge md fstst
⊢
sinvge md fstst′
focused goal
ge :
md :
Hge :
ge_modulege = md
Hfree :
ge_freege = R.free
st1, st2, st3 :
H12 :
clos_refl_transmstate mstepge st1 st2
H23 :
clos_refl_transmstate mstepge st2 st3
IH1 :
ready_statest1 → sinvge md fstst1 → sinvge md fstst2
IH2 :
ready_statest2 → sinvge md fstst2 → sinvge md fstst3
Hi :
sinvge md fstst1
⊢
sinvge md fstst3

–eapply mstep_sinv ; eauto

deferred goal
ge :
md :
Hge :
ge_modulege = md
Hfree :
ge_freege = R.free
st1, st2, st3 :
H12 :
clos_refl_transmstate mstepge st1 st2
H23 :
clos_refl_transmstate mstepge st2 st3
IH1 :
ready_statest1 → sinvge md fstst1 → sinvge md fstst2
IH2 :
ready_statest2 → sinvge md fstst2 → sinvge md fstst3
Hi :
sinvge md fstst1
⊢
sinvge md fstst3

–apply IH2 ; exact mreachable_ready_ _ _ Hfree H12 Hr | exact IH1Hr Hi

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge md st st′ Hge Hmd Hfree H
induction H as st st′ Hs | st | st1 st2 st3 H12 IH1 H23 IH2 ; intros Hr Hi ; auto
–eapply mstep_sinv ; eauto
–apply IH2 ; exact mreachable_ready_ _ _ Hfree H12 Hr | exact IH1Hr Hi

sinv holds where a run starts: at the entry of a checked module's function, with no caller.

925Lemma start_sinv
∀ ge md f xs fr m fuel
InIFuncf md
call_framef xs = Somefr
sinvge md mkConfigfr [ ] m fuel
Explore proof 5 tactics

Initial goal

⊢
∀ge : genv md : module f : func xs : listword fr : frame m : Memory.mem fuel : Z, checked_modulemd → InIFuncf md → call_framef xs = Somefr → sinvge md c_frame ≔ fr; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel

intros ge md f xs fr m fuel Hmd Hin Hc

ge :
md :
f :
xs :
listword
fr :
m :
Memory.mem
fuel :
Z
Hin :
InIFuncf md
Hc :
call_framef xs = Somefr
⊢
sinvge md c_frame ≔ fr; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel

destruct call_frame_entry_ _ _ Hc as Hf & _ & l & He & Ha

ge :
md :
f :
xs :
listword
fr :
m :
Memory.mem
fuel :
Z
Hin :
InIFuncf md
Hc :
call_framef xs = Somefr
Hf :
fr_fnfr = f
l :
He :
entry_labelf = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
⊢
sinvge md c_frame ≔ fr; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel

rewrite <- Hf in Hin , He

ge :
md :
f :
xs :
listword
fr :
m :
Memory.mem
fuel :
Z
Hin :
InIFuncfr_fnfr md
Hc :
call_framef xs = Somefr
Hf :
fr_fnfr = f
l :
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
⊢
sinvge md c_frame ≔ fr; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel

destruct at_entryge md fr m l Hmd Hin He Ha as Hsh Hsc

ge :
md :
f :
xs :
listword
fr :
m :
Memory.mem
fuel :
Z
Hin :
InIFuncfr_fnfr md
Hc :
call_framef xs = Somefr
Hf :
fr_fnfr = f
l :
He :
entry_labelfr_fnfr = Somel
Ha :
fr_atfr = Enterl None ∨ ∃ys : listword, fr_atfr = Snapshotys l
Hsh :
shapedmd fr
Hsc :
⊢
sinvge md c_frame ≔ fr; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel

split ; split ; exact Hsh | right ; exact Hsc | constructor

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge md f xs fr m fuel Hmd Hin Hc
destruct call_frame_entry_ _ _ Hc as Hf & _ & l & He & Ha
rewrite <- Hf in Hin , He
destruct at_entryge md fr m l Hmd Hin He Ha as Hsh Hsc
split ; split ; exact Hsh | right ; exact Hsc | constructor

In every state of a run of a checked module's function that starts ready, sinv holds.

936Corollary run_sinv
∀ ge md f xs fr m fuel s0 st
ge_modulege = md
ge_freege = R.free
InIFuncf md
call_framef xs = Somefr
R.readys0 m
mreachablege mkConfigfr [ ] m fuel, s0 st
sinvge md fstst
Explore proof 2 tactics

Initial goal

⊢
∀ge : genv md : module f : func xs : listword fr : frame m : Memory.mem fuel : Z s0 : R.state st : mstate, checked_modulemd → ge_modulege = md → ge_freege = R.free → InIFuncf md → call_framef xs = Somefr → R.readys0 m → mreachablege c_frame ≔ fr; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel, s0 st → sinvge md fstst

intros ge md f xs fr m fuel s0 st Hmd Hge Hfree Hin Hcf H0 Hreach

ge :
md :
f :
xs :
listword
fr :
m :
Memory.mem
fuel :
Z
s0 :
R.state
st :
Hge :
ge_modulege = md
Hfree :
ge_freege = R.free
Hin :
InIFuncf md
Hcf :
call_framef xs = Somefr
H0 :
R.readys0 m
Hreach :
mreachablege c_frame ≔ fr; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel, s0 st
⊢
sinvge md fstst

exact mreachable_sinv_ _ _ _ Hge Hmd Hfree Hreach H0 start_sinv_ _ _ _ _ _ _ Hmd Hin Hcf

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros ge md f xs fr m fuel s0 st Hmd Hge Hfree Hin Hcf H0 Hreach
exact mreachable_sinv_ _ _ _ Hge Hmd Hfree Hreach H0 start_sinv_ _ _ _ _ _ _ Hmd Hin Hcf

The interpreter's runtime

The same for the interpreter's runtime.

950Module InterpSingle ≔ Single InterpRuntime

Under the interpreter's runtime, whose free keeps identities, sinv needs no hypothesis but a ready start.

954Corollary interp_sinv
∀ md globals f xs fr m fuel s0 st
let ge ≔ mkGenvmd globals InterpRuntime.free in
checked_modulemd → InIFuncf md → call_framef xs = Somefr → InterpRuntime.readys0 m → InterpSingle.ID.RM.mreachablege mkConfigfr [ ] m fuel, s0 st → sinvge md fstst
Explore proof 2 tactics

Initial goal

⊢
∀ md : module globals : listname × ptr f : func xs : listword fr : frame m : Memory.mem fuel : Z s0 : InterpRuntime.state st : InterpSingle.ID.RM.mstate  ,
let ge ≔ ge_module ≔ md; ge_globals ≔ globals; ge_free ≔ InterpRuntime.free in
checked_modulemd → InIFuncf md → call_framef xs = Somefr → InterpRuntime.readys0 m → InterpSingle.ID.RM.mreachablege c_frame ≔ fr; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel, s0 st → sinvge md fstst

intros md globals f xs fr m fuel s0 st ge Hmd Hin Hcf H0 Hreach

md :
globals :
listname × ptr
f :
xs :
listword
fr :
m :
Memory.mem
fuel :
Z
ge :=
ge_module ≔ md; ge_globals ≔ globals; ge_free ≔ InterpRuntime.free : genv
Hin :
InIFuncf md
Hcf :
call_framef xs = Somefr
Hreach :
InterpSingle.ID.RM.mreachablege c_frame ≔ fr; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel, s0 st
⊢
sinvge md fstst

exact InterpSingle.run_sinvge md f xs fr m fuel s0 st Hmd eq_refl eq_refl Hin Hcf H0 Hreach

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros md globals f xs fr m fuel s0 st ge Hmd Hin Hcf H0 Hreach
exact InterpSingle.run_sinvge md f xs fr m fuel s0 st Hmd eq_refl eq_refl Hin Hcf H0 Hreach