rocq/theories/Chain.v
Campaign 3's reuse forms, part one: what a frame may read off the single definitions that dominate its point (formal.md, Campaign 3; rocq.md, Reading single definitions).
Single.v proves that every replayable single definition whose site dominates a frame's point replays: the name still holds what its instruction made. This file turns that into the facts the reuse forms' rules need: offset intervals, the elements of a guard chain, and the distance between two pointers. From them it proves the first reuse form, a raw access covered by the hull of two live facts, never unchecked along any run.
Decisions
| Decision | Why |
|---|---|
| "dominates the point" is the predicate Interval.v walks | it is closed under single-definition operands (use_dominated), and what dominates replays (scope_holds) |
Interval.v's hypothesis speaks of iv_op lets at an integer class | a check's proof or a float sum does not compute by alu; no derivation walks through one |
guard_chain and pointer_distance are rewritten by equations, never unfolded in a hypothesis | unfolding makes the kernel compare two 64-deep unfoldings, and Qed takes minutes |
| a write through the hull needs some write check of the capability, not of the two bounding spans | hull_covered/7 takes write rights from any span; a passed write check means the capability is not read-only |
the facts' pointers dominating the point is Invariant.v's (live_dom), not a hypothesis | inside a block it is use_dominated; over a block's entry it is dom_meet |
HullR carries runs between two instances of MachineR | Persistence.v and Single.v each instantiate it, and mstep is an inductive, new in each instance |
A replayed definition holds
A let n of an op o that intervals walk through (iv_op), at an integer class k, that steps and continues, computed its result from its operands as let_holds says, reading them in the frame where it ran (inst_result/5, op_res/7).
Explore proof 17 tactics
Initial goal
intros ge fr m n k o args e1 l1 m1 Ho Hk H
assert Hs : special_leto = false by destruct o ; try discriminate Ho ; reflexivity
rewrite inst_step_let_ _ _ _ _ _ _ Hs in H
cbv zeta in H
destruct op_arg_classeso k as cls | eqn: Ec ; | discriminate H
destruct map2_option_ cls args as xs | eqn: Ex ; | discriminate H
destruct op_reso k xs m as r m′ | why | q kont | eqn: Er ; try discriminate H
destruct r as x | why | why ; simpl in H ; try discriminate H
injection H as ← _ _
assert Hn : lookupn putn x fr_envfr = Somex by rewrite lookup_put , name_eqb_refl ; reflexivity
destruct k ; try exfalso ; apply Hk ; reflexivity ; destruct o ; try discriminate Ho ; unfold op_res , op_res_int in Er ; simpl in Er ; cases Er ; inversion Er ; subst
18 openfocused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
all: unfold let_holds
18 openfocused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
all: first exists cls, xs, x ; auto | idtac
2 openfocused goal
all: destruct t ; try discriminate Ho
2 openfocused goal
all: match goal withHl : int_load_res_ _ _ _ _ = Some_ |- _⇒unfold int_load_res in Hl ; cases Hl ; inversion Hl ; substend
6 openfocused goal
focused goal
focused goal
focused goal
focused goal
all: simpl in * ; try discriminate
2 openfocused goal
all: match goal withH0 : RVal_ = RVal_ |- _⇒injection H0 as ←end;eauto
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
let_holds reads the defined name n only in the later environment, so it survives a change of environment that keeps n.
Explore proof 4 tactics
Initial goal
intros ge e0 e e′ n k o args E H
unfold let_holds in *
rewrite E
exact H
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Definitions that dominate a point
Dominance of sites composes: a site s that dominates index j of block d, where that site dominates index k of block l, dominates index k of block l.
Explore proof 23 tactics
Initial goal
intros b0 rest doms l k d j s Hd H1 H2
destruct s as | d′ j′ ; reflexivity |
simpl in *
destruct name_eqbd l eqn: Edl ; destruct name_eqbd′ d eqn: Edd
4 openfocused goal
focused goal
–apply name_eqb_true in Edl , Edd
4 opendeferred goal
deferred goal
subst
4 opendeferred goal
deferred goal
rewrite name_eqb_refl
4 opendeferred goal
deferred goal
apply Z.ltb_lt in H1 , H2
4 opendeferred goal
deferred goal
apply Z.ltb_lt
4 opendeferred goal
deferred goal
lia
3 opendeferred goal
deferred goal
–apply name_eqb_true in Edl
3 opendeferred goal
subst
3 opendeferred goal
rewrite Edd
3 opendeferred goal
exact H2
2 opendeferred goal
–apply name_eqb_true in Edd
2 opensubst
2 openrewrite Edl
2 openexact H1
–destruct name_eqbd′ l eqn: Edl′ ; exfalso | exact dominates_trans_ _ _ Hd _ _ _ H2 H1
apply name_eqb_true in Edl′
subst d′
rewrite dom_antisym_ _ _ Hd _ _ H1 H2 , name_eqb_refl in Edl
discriminate Edl
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
In a checked_module md, a single-definition operand a of the instruction i that defines n, where n dominates index k of a reachable block l, dominates it too: the validator requires an operand's definition to dominate its use.
Explore proof 19 tactics
Initial goal
intros md f l k n i a Hmd Hin Hr Hn s & D & Hn′ & Hpos & Hsd Hu Ho
rewrite Hn in Hn′
injection Hn′ as ←
destruct func_facts_ _ Hmd Hin as b0 & rest & Hf & Hd & _ & Hdd
destruct dinst_site_ _ _ _ Hpos as d & j & →
destruct position_inst_ _ _ _ _ Hpos as b & kk & Hb & Hl & Hk & → & _
unfold once_has in Ho
destruct lookupa single_definitionsf as Da | eqn: Ea ; | discriminate Ho
assert Hrb : is_reachablefn_domsf b_labelb = true
2 openfocused goal
{rewrite Hl
2 opendeferred goal
simpl in Hsd
2 opendeferred goal
destruct name_eqbd l eqn: E ; apply name_eqb_true in E ; subst ; exact Hr |
2 opendeferred goal
exact proj1dominates_reachable_ _ _ Hd _ _ Hsd
deferred goal
destruct use_dominated_ _ _ _ _ _ _ Hdd Hb Hrb Hk Hu Ea as sa & Hsa & Hsda
exists sa, Da
split ; exact Ea |
split ; exact Hsa |
rewrite Hl in Hsda
exact site_dominates_trans_ _ _ _ _ _ _ _ Hd Hsd Hsda
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Where every replayable single definition in scope replays (scope_holds), a replayable definition i of n that dominates the frame's point replays: scope_holds read at one name.
Explore proof 4 tactics
Initial goal
intros ge fr m l k n i Hs Hpt Hn Hrp s & D & Hn′ & Hpos & Hsd
rewrite Hn in Hn′
injection Hn′ as ←
exact Hs_ _ _ _ _ Hpt Hn Hrp Hpos Hsd
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
dominating_replays where only definitions that are not a check_ahead need to replay (scope_plain), for a definition that is not one (ahead_free).
Explore proof 4 tactics
Initial goal
intros ge fr m l k n i Hs Hpt Hn Hrp Ha s & D & Hn′ & Hpos & Hsd
rewrite Hn in Hn′
injection Hn′ as ←
exact Hs_ _ _ _ _ Hpt Hn Hrp Hpos Hsd Ha
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Offset intervals at a point
An offset interval from lo to hi that the validator derives for a value v at class k' (iv, offset_interval/8) holds of the value the frame reads (in_iv), where v's name dominates the frame's point and every single definition in scope but a check_ahead replays.
Explore proof 15 tactics
Initial goal
intros ge md fr m l k v k′ lo hi Hmd Hin Hr Hs Hpt Hiv Hv
refine iv_sound_ ge fr_envfr dominatingfr_fnfr l k _ _ _ _ _ Hiv Hv
intros n k0 o args n′ & Hn & Ene Hop Hk Hdom
apply name_eqb_true in Ene
subst n′
assert Hrp : replayableLetn k0 o args = true by destruct o ; try discriminate Hop ; reflexivity
assert Haf : ahead_freeLetn k0 o args = true by destruct o ; try discriminate Hop ; reflexivity
destruct plain_replays_ _ _ _ _ _ _ Hs Hpt Hn Hrp Haf Hdom as fr0 & m0 & e1 & l1 & m1 & Hst & Hn1 & Ha & _
exists fr_envfr0
split
2 openfocused goal
–exact let_holds_name_ _ _ _ _ _ _ _ eq_symHn1 step_let_holds_ _ _ _ _ _ _ _ _ _ Hop Hk Hst
deferred goal
–intros a Hin′ Ho
split
2 openfocused goal
+exact operand_dominating_ _ _ _ _ _ _ Hmd Hin Hr Hn Hdom value_temps_in_ _ Hin′ Ho
deferred goal
+exact Ha_ value_temps_in_ _ Hin′ Ho
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
The hull of two checks
An access check that passes (cap_access_res) is at an address aligned to its alignment al.
Explore proof 5 tactics
Initial goal
unfold cap_access_res
intros c rs a size r al H
destruct c as | base | base | f | n ; try discriminate H ; destruct object_regionbase rs as reg | ; try discriminate H ; destruct base ≤? a && a + size ≤? r_endreg ; try discriminate H ; injection H as H
2 openfocused goal
–exact aligned_res_mod_ _ H
deferred goal
–destruct r ; exact aligned_res_mod_ _ H | discriminate H
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Every raw access's alignment divides 2^64, so an address modulo 2^64 is aligned as the address is.
Explore proof 1 tactics
Initial goal
intros | | | | t | w | ; try destruct w ; simpl ; first exists 2 ^ 64 ; reflexivity | exists 2 ^ 61 ; reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
An access between two passed checks of one capability c, at addresses of one pointer A that are near offsets apart, passes too (the arithmetic of hull_covered/7). The first check's span ends at or above -2^62 and starts at or below the access; the second's starts at or below 2^62 and ends at or above it. A read needs nothing more; a write needs some write check of the capability to have passed.
The two checks compare addresses taken modulo 2^64. They are A+l1 and A+l2 exactly, not merely congruent to them, only because the object ends at or below 2^48 (objects_fit): addresses inside it that are congruent and less than 2^63 apart are equal.
Explore proof 16 tactics
Initial goal
intros c rs A l1 s1 r1 al1 l2 s2 r2 al2 off size need aa Hfit H1 H2 Hh1 Hl2 Hoff Hend Hs Hal Hr
assert Hpos : ∀a, 0 ≤ raw_addressA a < 2 ^ 64 by intros a ; apply Z.mod_pos_bound ; lia
assert Hdiv : ∀a, A + a = 2 ^ 64 × A + a / 2 ^ 64 + raw_addressA a by intros a ; apply Z.div_mod ; lia
unfold cap_access_res in *
destruct c as | base | base | f | n ; try discriminate H1
2 openfocused goal
all: destruct object_regionbase rs as reg | eqn: E ; try discriminate H1
2 openfocused goal
all: pose proof Hfit_ _ E as Hend′ ; destruct base ≤? raw_addressA l1 && raw_addressA l1 + s1 ≤? r_endreg eqn: B1 ; | discriminate H1 ; destruct base ≤? raw_addressA l2 && raw_addressA l2 + s2 ≤? r_endreg eqn: B2 ; | discriminate H2 ; apply andb_true_iff in B1 as B1 B1′ ; apply andb_true_iff in B2 as B2 B2′ ; apply Z.leb_le in B1 , B1′ , B2 , B2′
2 openfocused goal
all: pose proof Hposl1 ; pose proof Hposl2 ; pose proof Hposoff ; pose proof Hdivl1 ; pose proof Hdivl2 ; pose proof Hdivoff
2 openfocused goal
all: replace base ≤? raw_addressA off && raw_addressA off + size ≤? r_endreg with true by symmetry ; apply andb_true_iff ; split ; apply Z.leb_le ; lia
2 openfocused goal
–f_equal
2 opendeferred goal
apply aligned_res_ok
2 opendeferred goal
exact Hal
deferred goal
–destruct need ; simpl ; f_equal ; apply aligned_res_ok ; exact Hal |
exfalso
destruct Hr as Hr | a3 & s3 & al3 & Hw ; discriminate Hr |
destruct _ && _ ; discriminate Hw
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Guard chains
What first_some finds is f of some element of the list.
Explore proof 3 tactics
Initial goal
intros X Y f xs y
induction xs as | x xs IH ; simpl ; intros H ; discriminate H |
destruct fx eqn: E ; injection H as ← ; eauto | destruct IHH as x′ & Hin & Hx ; eauto
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A flight that is the single definition of y defines y.
Explore proof 7 tactics
Initial goal
intros f y d o args lw H
destruct once_position_ _ _ H as s & Hpos & _
destruct dinst_site_ _ _ _ Hpos as dd & j & →
destruct position_inst_ _ _ _ _ Hpos as _ & _ & _ & _ & _ & _ & Hy
simpl in Hy
destruct Hy as → |
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A value v reads alike (value_x) in two environments e0 and e that agree on its name.
Explore proof 2 tactics
Initial goal
intros ge e0 e k v H
destruct v as y | c | g ; simpl ; rewrite Hy eq_refl | | ; reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
What a guard chain element (b, lo, hi) says of a pointer pp0: the value b reads in the environment e as a pointer with pp0's capability, and pp0's address is b's plus some x between lo and hi, modulo 2^64.
A value v is not a name defined more than once: a constant, a global, or a single-definition name in once.
The address arithmetic of an add flight: shifting by z and then by xo is shifting by xo + z, modulo 2^64.
Explore proof 4 tactics
Initial goal
intros a z xo
rewrite <- Z.add_mod , Z.add_mod_idemp_l by lia
f_equal
lia
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
The same for a sub flight: shifting by -z and then xo.
Explore proof 4 tactics
Initial goal
intros a z xo
rewrite <- Zminus_mod , Z.add_mod_idemp_l by lia
f_equal
lia
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
The same for a copy flight, whose shift z is 0 modulo 2^64.
Explore proof 4 tactics
Initial goal
intros a z xo Hz
replace a + xo + z with a + xo + z by lia
rewrite Z.add_moda + xo z , Hz , Z.add_0_r , Z.mod_mod , Z.add_mod_idemp_l by lia
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Lemmas for a frame fr of a checked_module md, in memory m, at index k of a reachable block l, where every single definition in scope but a check_ahead replays (scope_plain).
Every stable element of a guard chain walked from p with fuel steps (guard_chain/3) holds of the pointer pp0 (offset_rel), where p's single definition dominates the point and p's own element holds. The induction behind guard_chain_sound.
Proof 76 steps Qed
guard_chain as an equation. Unfolding it in a hypothesis instead makes the kernel compare two unfoldings of guard_chain_go, which recurses twice per level, 64 levels deep.
Explore proof 2 tactics
Initial goal
intros once p
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Each stable element of the guard chain of a value p (guard_chain/3) holds of the pointer pp that p reads (offset_rel), where p's single definition dominates the point.
Explore proof 10 tactics
Initial goal
intros p pp b blo bhi Hp Hdom Hb Hst
rewrite guard_chain_eq in Hb
refine chain_go_sound64 p 0 0 pp Hdom _ b blo bhi Hb Hst
intros _
exists pp, 0
split ; exact Hp |
split ; reflexivity |
split ; lia |
rewrite Z.add_0_r
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
pointer_distance as an equation, for the same reason as guard_chain_eq.
Explore proof 2 tactics
Initial goal
intros once p p1
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Two values p and p1 that read as pointers pp and pp1, whose guard chains share an exact base d apart (pointer_distance/4), have one capability, and addresses d apart, modulo 2^64, where their single definitions dominate the point. The reuse forms use it to give a renewed pointer its source's capability.
Explore proof 28 tactics
Initial goal
intros p p1 pp pp1 d Hp Hp1 Hd Hd1 H
rewrite pointer_distance_eq in H
destruct first_some_in_ _ _ _ _ H as el & Hel & Hf
destruct el as n0 | c0 | g0 k0 k0′ ; unfold exact_base in Hf ; try discriminate Hf
destruct k0 =? k0′ && once_hassingle_definitionsfr_fnfr n0 eqn: E0 ; | discriminate Hf
apply andb_true_iff in E0 as Ek0 Ho
apply Z.eqb_eq in Ek0
subst k0′
destruct first_some_in_ _ _ _ _ Hf as el1 & Hel1 & Hf1
destruct el1 as n1 | c1 | g1 k1 k1′ ; try discriminate Hf1
destruct name_eqbn1 n0 && k1 =? k1′ eqn: E1 ; | discriminate Hf1
injection Hf1 as ←
apply andb_true_iff in E1 as En Ek
apply name_eqb_true in En
apply Z.eqb_eq in Ek
subst n1 k1′
assert Hst : stablesingle_definitionsfr_fnfr Tmpn0 by intros y E ; injection E as ← ; exact Ho
destruct guard_chain_sound_ _ _ _ _ Hp Hd Hel Hst as pb & x & Hpb & Hc & Hx & Ha
destruct guard_chain_sound_ _ _ _ _ Hp1 Hd1 Hel1 Hst as pb′ & x1 & Hpb′ & Hc1 & Hx1 & Ha1
rewrite Hpb in Hpb′
injection Hpb′ as ←
assert x = k0 by lia
assert x1 = k1 by lia
subst x x1
split ; congruence |
rewrite Ha , <- Z.add_mod_idemp_lptr_addrpp1 , Ha1 , Z.add_mod_idemp_l by lia
f_equal
lia
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
The hull of a pointer's live facts
Each span from l1 to h1 that hull_covered/7 reads off a live fact is a check that passed, of the capability of the access pointer pp, at its address plus the span's bounds, where the live facts hold (facts_hold) and their pointers dominate the point. The fact's pointer and the access's are a known distance apart (pointer_distance_sound).
Explore proof 23 tactics
Initial goal
intros live p pp l1 h1 r1 Hl Hdom Hp Hdp Hsp
apply in_flat_map in Hsp as f & Hf & Hsp
destruct pointer_distancesingle_definitionsfr_fnfr f_pf p as d | eqn: Ed ; | contradiction
cbv zeta in Hsp
destruct near_offsetd && near_offsetf_lof + d && near_offsetf_hif + d eqn: En ; | contradiction
destruct Hsp as E |
injection E as ← ← ←
apply andb_true_iff in En as En Eh
apply andb_true_iff in En as _ El
split ; exact El |
split ; exact Eh |
destruct Hlf Hf as pf & _ & Hpf & Hc
destruct pointer_distance_sound_ _ _ _ _ Hpf Hp λy ⇒ Hdomf y Hf Hdp Ed as Hcap Haddr
exists f_alf
unfold check_passes in Hc
replace f_hif + d − f_lof + d with f_hif − f_lof by lia
replace raw_addressptr_addrpp f_lof + d with raw_addressptr_addrpf f_lof
2 openfocused goal
–rewrite <- Hcap
2 opendeferred goal
exact Hc
deferred goal
–unfold raw_address
rewrite <- Z.add_mod_idemp_l , Haddr , Z.add_mod_idemp_l by lia
f_equal
lia
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A raw access i through the proof q that the pass accepts by hull_covered/7 does not step to unchecked, where memory lies in the address space, the live facts hold and their pointers' single definitions dominate the point. The span starting at or below the access and the span ending at or above it are checks of one capability that passed (hull_span_passes), so the access's own check passes (cap_access_hull).
Proof 45 steps Qed
The access is aligned: the fact's check was, at an alignment aa divides.
The rights: a read, or a write some span's write check allows.
No unchecked access through the hull, along every run
The frame lemmas carried along every run of the machine of a runtime R. It joins Persistence.v's invariant, which says the hull's facts hold and dominate the point, with Single.v's, which says the single definitions there replay. Each instantiates MachineR on its own, and an instance's mstep is an inductive of its own, so a run of one is carried over to the other (mreachable_same).
A step of Persistence.v's machine instance is a step of Single.v's.
Explore proof 2 tactics
Initial goal
intros ge st st′ H
destruct H ; econstructor ; eassumption
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A run of Persistence.v's machine instance is a run of Single.v's, so both invariants hold of every state it reaches.
Explore proof 6 tactics
Initial goal
intros ge st st′ H
induction H as st st′ H | st | st1 st2 st3 _ IH1 _ IH2
3 openfocused goal
focused goal
–apply rt_step
3 opendeferred goal
deferred goal
exact mstep_same_ _ _ H
2 opendeferred goal
deferred goal
–apply rt_refl
deferred goal
–exact rt_trans_ _ _ _ _ IH1 IH2
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
In every state c a run reaches from a call of a function f of a checked_module md, started in a memory where the runtime is ready, a frame that is not doomed runs no raw access, and no raw call, to an unchecked outcome, hull_covered/7 included. Every runtime spares the pass's facts at safepoints (spares_any; see The evidence invariant over runs).
Explore proof 13 tactics
Initial goal
intros ge md f xs fr m fuel s0 c s l i rest j why Hmd Hge Hfree Hin Hcf H0 Hreach Hd Ha Hi
destruct P.run_access_not_unchecked_ _ _ _ _ _ _ _ _ _ _ _ _ _ why Hmd Hge Hfree Hin Hcf H0 Hreach Hd Ha Hi as Hn | b & k & live & fa & q & Hb & Hk & Hl & Hdom & Hfa & Hh ; exact Hn |
pose proof S.run_sinv_ _ _ _ _ _ _ _ _ Hmd Hge Hfree Hin Hcf H0 mreachable_same_ _ _ Hreach as Hsh Hsc _
simpl in Hsh , Hsc
destruct Hsc as Hsc | Hsc ; congruence |
destruct Hsh as Hinf Hsh
rewrite Ha in Hsh
destruct Hsh as Hr _
pose proof P.I.RM.mreachable_ready_ _ _ Hfree Hreach H0 as Hready
pose proof R.address_space_ _ Hready as Hfit
destruct skipn_cons_ _ _ _ _ eq_symHk as _ & _ & Hlen
assert Hpt : point_sitefr_fnc_framec fr_atc_framec = Somel, Z.of_natk by rewrite Ha , Hk ; apply point_site_exec ; exact Hb | lia
exact hull_access_not_uncheckedge md c_framec c_memc l Z.of_natk Hmd Hinf Hr scope_plain_of_ _ _ Hsc Hpt i q fa live why Hfit Hl HdomHr Hfa Hh
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
The interpreter's runtime
run_access_checked for the interpreter's runtime: in every state of a run of a checked module's function that starts ready, a frame that is not doomed runs no raw access or raw call to unchecked. No hypothesis remains but the ready start.
Explore proof 2 tactics
Initial goal
intros md globals f xs fr m fuel s0 c s l i rest j why ge Hmd Hin Hcf H0 Hreach Hd Ha Hi
exact InterpHull.run_access_checkedge md f xs fr m fuel s0 c s l i rest j why Hmd eq_refl eq_refl Hin Hcf H0 Hreach Hd Ha Hi
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.