rocq/theories/Walk.v
The evidence pass read back for Campaign 3's run-level invariant (Persistence.v; rocq.md, The evidence invariant over runs).
Validate.v's evidence_pass transcribes ir.pl's pass as it runs: a fold over the blocks, and within each block checked_insts/5. The invariant needs to know what the pass said at each point a run can reach, so this file reads the pass back: the facts each block was passed from (pass_fold), where the pass is within a block (walks), and the instructions before which it keeps its facts (relies).
A block reached by a back edge saw nothing on that edge (the fold had not reached its source), and the meet over an empty set is empty: a back edge without a poll gives no fact the proof must justify.
Names
Every name equals itself by name_eqb.
Explore proof 1 tactics
Source script
name_eqb is symmetric.
Explore proof 10 tactics
Initial goal
intros a b
destruct name_eqba b eqn: E , name_eqbb a eqn: E′ ; auto
2 open–apply term_eqb_eq in E
2 opensubst
2 openrewrite name_eqb_refl in E′
2 opendiscriminate E′
–apply term_eqb_eq in E′
subst
rewrite name_eqb_refl in E
discriminate E
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Explore proof 7 tactics
Looking k up after put k' v answers v if k is k', and otherwise what it answered before.
Explore proof 7 tactics
Initial goal
intros A k k′ v ps
destruct name_eqbk k′ eqn: E
2 open–apply term_eqb_eq in E
2 opensubst
2 openapply lookup_put_same
–apply lookup_put_other
exact E
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
The block that the label l finds in the blocks bs (find_block) is one of bs and is labelled l.
Explore proof 6 tactics
Initial goal
induction bs as | b0 bs IH ; simpl ; intros b H ; discriminate H |
destruct name_eqbb_labelb0 l eqn: E
2 open–injection H as ←
2 opensplit ; left ; reflexivity | apply term_eqb_eq ; exact E
–destruct IH_ H
split ; right | ; auto
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
The pass, block by block
evidence_pass folds pass_block over the blocks in order. Each block's entry facts are the meet of the sets on its incoming edges (edge_set): nothing over a poll edge, the exit facts of a block the fold has passed, and nothing for one it has not reached yet, a back edge.
The facts the pass carries along the incoming edge e, a source label and whether it is a poll edge: none over a poll edge, else the exit facts exits gives the source, or none if the fold has not passed the source yet.
The live facts at the entry of the block b of f, given the exit facts so far: the meet of the sets on b's incoming edges (evidence_meet), less the facts about b's phi temporaries (entry_kill).
One step of the pass's fold over the blocks: run checked_insts/5 over b's instructions from b's entry facts, and record what it ends with as b's exit facts. Fails where the pass fails.
The exit facts of every block of the function f, as the pass, with the sources s of the function, leaves them.
The evidence pass accepts a function exactly when pass_exits computes its exit facts.
Explore proof 1 tactics
Initial goal
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A failed fold of pass_block stays failed.
Explore proof 2 tactics
Initial goal
intros s f bs
induction bs ; simpl ; auto
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
One unfolding of pass_block from the exit facts ex.
Explore proof 1 tactics
Initial goal
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
The exit facts the fold ends with, E, give a label n that no block of bs carries what they gave it before the fold, in ex.
Explore proof 9 tactics
Initial goal
intros s f
induction bs as | b bs IH ; cbn [ fold_left ] ; intros ex E n H Hn
2 openfocused goal
–injection H as ←
2 opendeferred goal
reflexivity
deferred goal
–rewrite pass_block_some in H
destruct checked_insts_ _ _ _ as out | ; | rewrite pass_fold_none in H ; discriminate H
rewrite IH_ _ _ H by intros b′ Hb′ ; apply Hn ; right ; exact Hb'
rewrite lookup_put , Hnb by left ; reflexivity
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Folding pass_block over blocks bs with distinct labels, none of which had exit facts in ex yet, passes each block b of bs from the exit facts the fold had when it reached b, all of which it keeps to the end E, and records b's exit facts out in E.
Proof 39 steps Qed
Explore proof 12 tactics
Initial goal
unfold incoming
intros bs bp t Hb Ht
apply proj1in_rev_ _
apply proj2in_flat_map_ _ _
exists bp
split ; exact Hb |
apply proj2in_flat_map_ _ _
exists t
split ; exact Ht |
rewrite name_eqb_refl
left
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A label that no jump of bs can go to has no incoming edges; the entry is such a label.
Explore proof 15 tactics
Initial goal
unfold incoming
intros bs l H
assert flat_mapλb ⇒ flat_mapλt ⇒ if name_eqbedge_labelt l then b_labelb, is_pollt else [ ] jump_targetsb_jumpb bs = [ ] as → ; | reflexivity
induction bs as | b bs IH ; simpl in * ; auto
apply orb_false_iff in H as Hb Hbs
rewrite IH by exact Hbs
rewrite app_nil_r
unfold succ_labels in Hb
induction jump_targetsb_jumpb as | t ts IHt ; simpl in * ; auto
unfold mem in Hb
simpl in Hb
apply orb_false_iff in Hb as Ht Hts
rewrite name_eqb_sym , Ht
apply IHt
exact Hts
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Where the pass is within a block
From the facts live before the instructions is, the pass, with fuel enough, reaches the block's end with the facts out (checked_insts/5).
With no instructions left, the pass ends with the facts it had.
Explore proof 2 tactics
Initial goal
intros s live out n H
destruct n ; cbn [ checked_insts ] in H ; congruence
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A walk over i :: rest takes i with what follows it by checked_inst_rest/7, which may consume the next instructions too, and walks on over what is left.
Explore proof 5 tactics
Initial goal
intros s i rest live out n H
destruct n as | n ; cbn [ checked_insts ] in H ; discriminate H |
destruct checked_inst_rests i rest live as rest′ live′ | ; | discriminate H
exists rest′, live′
split ; reflexivity | exists n ; exact H
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Where the pass relies on facts
The pass reads its live facts at a raw access (its coverage), and keeps them across an evidence-preserving instruction, a check_local and a repeated getter. Before any other instruction it keeps none: what it says after does not depend on them.
The instruction i copies a global g into a temporary d that the sources s record as a getter of g (getter): a repeated getter, after which the pass keeps its facts.
The instruction i is a check_local, an access check of a named local.
The instructions before which the pass keeps its live facts: an evidence-preserving one (evidence_preserving), a check_local, a repeated getter, or a raw access, which reads them as its coverage.
An instruction after which the pass adds a fact (check_fact) is evidence preserving.
Explore proof 3 tactics
Initial goal
intros i fa H
destruct i as q k o args | | | | | | | ; try discriminate H
destruct o ; try destruct k ; discriminate H ; destruct k ; try discriminate H ; destruct args as | a1 | a2 | a3 | a4 args ; try discriminate H ; reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Before an instruction it does not rely on facts for (relies), the pass keeps none: it goes on with no live facts.
Explore proof 28 tactics
Initial goal
intros s i rest live rest′ live′ Hr Hc
unfold relies in Hr
apply orb_false_iff in Hr as Hr _
apply orb_false_iff in Hr as Hr Hg
apply orb_false_iff in Hr as Hp Hl
destruct check_facti as fa | eqn: Hf
2 openfocused goal
–rewrite check_fact_preserving_ _ Hf in Hp
2 opendeferred goal
discriminate Hp
deferred goal
–destruct pass_speciali eqn: Hs
2 openfocused goal
+unfold pass_special in Hs
2 opendeferred goal
rewrite Hf in Hs
2 opendeferred goal
destruct i as q k o args | | | | | | | ; try discriminate Hs
2 opendeferred goal
destruct k ; try discriminate Hs ; destruct o ; try discriminate Hs
3 openfocused goal
deferred goal
∗destruct args ; discriminate Hl | discriminate Hs
2 opendeferred goal
deferred goal
∗exact checked_inst_rest_function_ _ _ _ _ _ _ Hc
deferred goal
+rewrite checked_inst_rest_generic_ _ _ _ Hs in Hc
unfold generic_rest in Hc
cbn zeta in Hc
match type of Hc withif then _ else _ = _⇒destruct b ; | discriminate Hcend
injection Hc as _ ←
unfold evidence_after
rewrite Hp
destruct i as d k o args | | | | | | | ; try reflexivity
destruct o ; try reflexivity ; destruct k ; try reflexivity ; destruct args as | n | c | g | a2 args ; try reflexivity
unfold repeated_getter in Hg
destruct lookupd s_getterss as g1 | ; | reflexivity
rewrite Hg
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
The forms the pass pairs with their access
A check_local of the local x that continues binds its result q to the pointer at offset off of x's object, changes no memory, and its access check passed (access_res).
Explore proof 7 tactics
Initial goal
intros ge fr m q x off bytes r al e1 l1 m1 H
unfold inst_step in H
cbn iota beta zeta in H
destruct lookupx fr_localsfr as base | | ; try discriminate H
destruct access_resm base + off Objbase bytes r al as | w | w | eqn: E ; try discriminate H
injection H as ← ← ←
eauto
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A check_function that continues binds its result q to a pointer p whose function check passed (function_check_res).
Explore proof 6 tactics
Initial goal
intros ge fr m q args e1 l1 m1 H
destruct args as | v | v′ args ; unfold inst_step in H ; cbn iota beta zeta in H ; try discriminate H
destruct value_xge fr_envfr P v as n | p | c size | ; try discriminate H
destruct function_check_resge p as | w | w | eqn: E ; try discriminate H
injection H as ← ← ←
eauto
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
An access check that passes on the object at base, for size bytes at address a, finds base's region in memory and the bytes inside it, from base up to its end.
Explore proof 8 tactics
Initial goal
unfold access_res , cap_access_res
intros m a base size r al H
destruct object_regionbase m_regionsm as reg | ; | discriminate H
destruct base ≤? a && a + size ≤? r_endreg eqn: E ; | discriminate H
apply andb_true_iff in E as E1 E2
apply Z.leb_le in E1
apply Z.leb_le in E2
eauto
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A covered access lies inside the checked range, from lo up to hi, so that range is not empty.
Explore proof 9 tactics
Initial goal
unfold covered_access
intros i q lo hi r al H
destruct raw_accessi as q′ x off need | ; | discriminate H
pose proof access_size_align_posx as Hs _
destruct access_size_alignx as size aa
simpl in Hs
repeat match goal withHb : _ && _ = true |- _⇒apply andb_true_iff in Hb as ? ?end
repeat match goal withHb : _ ≤? _ = true |- _⇒apply Z.leb_le in Hbend
lia
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
The pass takes a check_local together with the access after it: that access is covered by the check's range, from 0 up to bytes, and the facts after are what the access (evidence_after) leaves of the live facts less those about q (kill).
Explore proof 11 tactics
Initial goal
intros s q x off bytes r al rest live rest′ live′ H
unfold checked_inst_rest in H
cbn zeta in H
destruct rest as | access rest0 ; discriminate H |
destruct raw_accessaccess as q′ xa o need | ; | discriminate H
destruct o ; try discriminate H
destruct name_eqbq′ q && covered_accessaccess q 0 bytes r al && storage_effectsaccess Local' eqn: E ; | discriminate H
injection H as ← ←
apply andb_true_iff in E as E _
apply andb_true_iff in E as _ E
eauto
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
After a check_local q of the local x that continues, in a memory whose objects fit (objects_fit) and a frame whose locals lie above address 0, the memory is unchanged, the environment changed only at q, and the check's access holds as a fact of q (fact_holds).
Explore proof 17 tactics
Initial goal
intros ge fr m q x off bytes r al e1 l1 m1 access Hfit Hpos Hcov H
destruct check_local_step_ _ _ _ _ _ _ _ _ _ _ _ H as base & Hl & → & → & Hc
split ; reflexivity |
split ; apply env_agree_put |
pose proof covered_nonempty_ _ _ _ _ _ Hcov as Hb
pose proof Hpos_ _ Hl as Hbase
destruct access_res_obj_ _ _ _ _ _ Hc as reg & Er & H1 & H2
pose proof Hfit_ _ Er as Hend
exists mkPtrbase + off Objbase
cbn [ f_q f_p f_lo f_hi f_r f_al ]
split ; apply lookup_put_same |
split ; unfold value_x ; rewrite lookup_put_same ; reflexivity |
unfold check_passes , raw_address
simpl ptr_addr
simpl ptr_cap
rewrite Z.sub_0_r , Z.add_0_r , Z.mod_small by lia
exact Hc
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
The pass's sources of a function
The sources (src) the pass reads for the function f of the module md: what stage_sources/4 computes from f's dominator intervals, or from no intervals where there are none.
The label of the function f's entry block, its first, if it has blocks.
md is valid and in the checked stage, so each of its functions passed the evidence pass.
Every function f of a checked_module md has distinct block labels and an entry block that no jump goes to, and the pass computes its exit facts.
Explore proof 24 tactics
Initial goal
unfold checked_module , valid
intros md f Hv Hc Hin
destruct existsb_ md ; discriminate Hv |
injection Hv as Hv
unfold valid_items in Hv
apply andb_true_iff in Hv as _ Hv
rewrite forallb_forall in Hv
specialize Hv_ Hin
simpl in Hv
unfold valid_func , fn_src in *
destruct fn_blocksf as | b0 bs eqn: Eb ; discriminate Hv |
destruct block_intervalsb0 :: bs as doms | ; | discriminate Hv
rewrite Hc in Hv
unfold stage_func in Hv
cbn [ negb orb ] in Hv
repeat match goal withHb : _ && _ = true |- _⇒apply andb_true_iff in Hb as ? ?end
split ; assumption |
split
2 openfocused goal
–exists b0, bs
2 opendeferred goal
split ; reflexivity |
2 opendeferred goal
apply negb_true_iff
2 opendeferred goal
assumption
deferred goal
–match goal withHb : evidence_pass_ _ = true |- _⇒rewrite evidence_pass_exits in Hbend
destruct pass_exits_ _ ; eauto | discriminate
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A local of a frame's starting locals, each object paired with none, has no base: none is allocated yet.
Explore proof 3 tactics
Initial goal
intros x base
induction objs as | y z objs IH ; simpl ; discriminate |
destruct name_eqbx y ; discriminate | exact IH
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
The pass's own forms
The instruction i is a check_function, the check that a pointer designates a function.
An instruction the pass treats apart (pass_special) that adds no fact is a check_local or a check_function.
Explore proof 3 tactics
Initial goal
intros i H Hf
destruct i as q k o args | | | | | | | ; try discriminate H
destruct o ; destruct k ; try discriminate H ; try discriminate Hf ; auto ; destruct args as | a1 | a2 | a3 | a4 args ; auto ; discriminate
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
An instruction the pass does not rely on facts for is not evidence preserving.
Explore proof 6 tactics
Initial goal
unfold relies
intros s i H
apply orb_false_iff in H as H _
apply orb_false_iff in H as H _
apply orb_false_iff in H as H _
exact H
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
An instruction the pass does not rely on facts for is not a check_local.
Explore proof 6 tactics
Initial goal
unfold relies
intros s i H
apply orb_false_iff in H as H _
apply orb_false_iff in H as H _
apply orb_false_iff in H as _ H
exact H
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Where the pass relies on nothing, it goes on to the next instruction with no facts, but after a check_function, which takes the raw call after it too.
Explore proof 14 tactics
Initial goal
intros s i rest live rest′ live′ Hr Hcf Hc
split ; | exact relies_false_ _ _ _ _ _ Hr Hc
destruct check_facti as fa | eqn: Hf
2 openfocused goal
{pose proof check_fact_preserving_ _ Hf as Hp
2 opendeferred goal
rewrite relies_preserving_ _ Hr in Hp
2 opendeferred goal
discriminate Hp
deferred goal
destruct pass_speciali eqn: Hs
2 openfocused goal
–destruct pass_special_cases_ Hs Hf as Hl | Hl
3 openfocused goal
deferred goal
+rewrite relies_local_ _ Hr in Hl
3 opendeferred goal
deferred goal
discriminate Hl
2 opendeferred goal
deferred goal
+rewrite Hcf in Hl
2 opendeferred goal
discriminate Hl
deferred goal
–rewrite checked_inst_rest_generic_ _ _ _ Hs in Hc
exact proj1generic_rest_shape_ _ _ _ _ _ Hc
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
The pass takes a check_function q together with the raw call through q after it, and goes on with no facts.
Explore proof 9 tactics
Initial goal
intros s q args rest live rest′ live′ H
unfold checked_inst_rest in H
destruct rest as | rest0 ; try discriminate H ; cbn iota beta in H
destruct callee as q′ | | ; try discriminate H
destruct name_eqbq′ q eqn: E ; | discriminate H
injection H as ← ←
apply term_eqb_eq in E
subst q′
eauto
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A raw access is not one of the instructions the pass treats apart.
Explore proof 3 tactics
Initial goal
intros i a H
destruct i as q k o args | | | | | | | ; try reflexivity
destruct o ; simpl in H ; try discriminate H ; destruct k ; reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
The pass never takes a raw call on its own: only after the check_function of its callee.
Explore proof 3 tactics
Initial goal
intros s r cl args rest live
rewrite checked_inst_rest_generic by reflexivity
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.