rocq/theories/Language.v
Nanofil's machine, with the external calls of a contract registry, as an Iris language whose evaluation context is the stack of callers, and Iris adequacy as a proof of never_panics and of the labelled machine's safety.
The first logic spike's IrisLang.v made the whole configuration one expression, so a call was just another step and a function could have no specification of its own. Here the callers are Iris's evaluation context, so a call is wp_bind and a function's specification is an ordinary Hoare triple that hands resources back to its caller:
- an expression is a running frame (
ERun), the outcome an invocation returned (EEnd, the value), an expression running as the callee of a suspended caller frame (EWait), or the bad return of an external call (EBad); the one context itemKWaitis that caller; - the Iris state is the memory, the runtime's state, the fuel and the world of libc state the contracts speak of: the machine has one fuel counter for the whole stack, so it belongs to the state, not to a frame;
- a head step of
ERunfris the step of fr with no caller.step_callersshows that the callers are passive: they change only what a return does, which becomeshs_return(the value) and thenhs_resume(the caller reads it); - an ending that is neither a failure nor a return (running out of fuel, a refusal trap) and an allocation the runtime refuses are stalls:
ERunfrsteps to itself. The machine has stopped without failing, and to Iris that is a run that never ends, which is safe. A failing frame has no head step at all, not even a safepoint.
The language is over a world type and a contract registry, the labelled machine's (ExternalMachine.v). A call at an external_site is stuck to the core step; here it is:
- admissible (a contract, arguments that evaluate, its ABI and its precondition): it may return (
hs_call_return, the frame resumed with the call's memory, runtime state and world), and it may also stall (hs_call_wait). The stall stands for everything the call does that is not a return: it may block, it may exit the process or end for lack of resources (the labelled machine stops there without failing), and the labelled machine makes no step where an admissible call has no completed invocation. None of these is a failure, and to Iris each is a run that never ends, so a stall is safe; and it makes an admissible call always reducible, whether or not the contract allows any return; - returning words the call site cannot take (
hs_call_bad): the expression becomesEBad, which is no value and has no step, so adequacy rules it out; - rejected: no head step, so adequacy rules it out too.
With the empty registry (no_contracts) no call is admissible and the language is the core machine's.
run_reducible, admissible_reducible and head_step_run_inv say a frame that does not fail, or whose external call is admissible, is always head-reducible, and how. wp_never_panics proves Panics.v's never_panics from a NotStuck weakest precondition of the entry's ERun in the language with no contracts, for every fuel; adequate_labelled and wp_labelled_safe prove that no labelled run stops with a failure_ending, and that a returned value satisfies the postcondition.
The outcome o returns to a caller: a return of one word, of several, or of none.
Whether an outcome returns is decided by its constructor.
Explore proof 1 tactics
The configuration c' run as the callee of the callers cs: c''s own callers, then cs below them.
An instruction never stops with a returning outcome: only a jump returns, through return_step.
Explore proof 4 tactics
Initial goal
intros H
destruct i
9 openfocused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
1: destruct special_leto0 eqn: Es ; destruct o0 ; try discriminate Es | rewrite inst_step_let_ _ _ _ _ _ _ Es in H
12 openfocused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
focused goal
all: unfold inst_step , external_call , bind_res , store_out in H ; cases H ; inversion H ; subst ; cbn ; tauto
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
doomed_result/5 makes no returning stop of its own: a returning stop after it is the instruction's.
Explore proof 10 tactics
Initial goal
intros H Hf Hr
destruct ahead_insti eqn: Ea
2 open–destruct i as d k op args | | | | | | | | ; try discriminate Ea
2 opendestruct k ; try discriminate Ea
2 opendestruct op ; try discriminate Ea
2 opendestruct args as | v | v′ args ; try discriminate Ea
2 openunfold doomed_result in H
2 opencases H ; inversion H ; subst ; cbn in Hf ; try discriminate Hf ; try injection Hf as ← ; cbn in Hr ; tauto ; auto
–rewrite doomed_result_other_ _ _ _ _ Ea in H
cases H ; inversion H ; subst ; cbn in Hf ; try discriminate Hf ; try injection Hf as ← ; cbn in Hr ; tauto ; auto
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A step that stops at an instruction, after doomed_result, stops with an outcome that does not return.
Explore proof 3 tactics
Initial goal
intros H1 H2 H3 Hr
pose proof doomed_result_stop_ _ _ _ _ _ _ H2 H3 Hr as →
exact inst_step_stop_ _ _ _ _ H1 Hr
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A return with no caller ends the run with o once the locals end, and is stuck where they cannot.
Explore proof 3 tactics
Initial goal
unfold return_step
cbn
destruct invalidate_locals_ _ ; reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
How the step r of a frame with the callers cs (the configuration c) follows from the step r0 of the same frame with none: the same next configuration or allocation with cs below its callers, the same ending where it does not return, the same return_step (now to a caller) where it returns and the locals can end, and stuck where r0 is stuck.
A tactic: succeed only if the term x contains no match.
Proof 5 steps Qed
A next configuration of fr alone, with cs below its callers, is the next configuration of fr with the callers cs.
Explore proof 4 tactics
Initial goal
intros E
pose proof step_callersge fr cs m fuel as H
rewrite E in H
exact H
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
An allocation of fr alone is the same request with the callers cs, each base's configuration with cs below its callers.
Explore proof 4 tactics
Initial goal
intros E
pose proof step_callersge fr cs m fuel as H
rewrite E in H
exact H
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
An ending of fr alone that does not return is the same ending with any callers.
Explore proof 4 tactics
Initial goal
intros E Hr
pose proof step_callersge fr cs m fuel as H
rewrite E in H
destruct H as _ H | H _ ; exact H | contradiction
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A returning ending of fr alone is, with the callers cs, the return to them, and the locals of fr can end.
Explore proof 4 tactics
Initial goal
intros E Hr
pose proof step_callersge fr cs m fuel as H
rewrite E in H
destruct H as H _ | _ H ; contradiction | exact H
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A stuck step of fr alone is stuck with any callers.
Explore proof 4 tactics
Initial goal
intros E
pose proof step_callersge fr cs m fuel as H
rewrite E in H
exact H
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Whether a safepoint is due reads only the running frame.
Explore proof 1 tactics
Source script
The suspended caller frame cf, which reads its callee's result as pd says, resumed with the callee's returning outcome o: the tail of return_step (call_outcome_result/5), converting o by pd's convention and binding it in cf's environment. None where the result cannot be read so.
A return to the caller cf, where the locals of fr end in m', is the caller resumed, with the callers below it, or stuck where it cannot resume.
Explore proof 6 tactics
Initial goal
intros E
unfold return_step , resume
cbn
rewrite E
destruct match pd_convpd with None ⇒ Someo Somecw, kw ⇒ converted_outcomecw kw o end ; | reflexivity
destruct returned_env_ _ _ ; reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A return with no caller, where the locals end, ends the run.
Explore proof 3 tactics
Initial goal
intros E
rewrite return_nil E
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
External calls
Whether a configuration is at an external_site reads only its running frame: the frame alone is at the same site, in any memory and fuel.
Explore proof 2 tactics
Initial goal
intros H
exact H
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A frame is at most at one external_site: its next instruction fixes every part of the site.
Explore proof 10 tactics
Initial goal
unfold external_site
cbv zeta
intros Hf _ & Ha & _ _ & Ha′ & _
destruct site , site′
cbn in *
rewrite Hf Ha′ in Ha
injection Ha
intros
subst
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A completed call was admissible: its ABI and its precondition hold, whatever its ending.
Explore proof 2 tactics
Initial goal
intros H
destruct H ; auto
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A call's resource ending is no failure: resource_failure is out of memory or too big, both refusals.
Explore proof 5 tactics
Initial goal
intros H
inversion H ; subst
2 openfocused goal
–match goal withHn : ∀why′, CallResource ≠ CallResourcewhy′ |- _⇒exfalso ; exact Hn_ eq_reflend
deferred goal
–apply resource_not_failure
match goal withHf : M.E.resource_failure_ _ _ |- _⇒destruct Hfend;unfold resource_reason;auto
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A core machine step of the labelled machine's copy of Machine.v is a step of this file's: the two functor instances share their definitions, and only the inductive relation is generative.
Explore proof 2 tactics
Initial goal
intros H
destruct H ; eapply RM.mstep_next | eapply RM.mstep_alloc | eapply RM.mstep_safepoint ; eassumption
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
The language
An expression: a running invocation ERunfr; the outcome EEndo an invocation returned, which is the value; EWaite cf pd, the expression e running as the callee of the suspended caller frame cf, which reads its result as pd says; or EBad, an external call that returned words its call site cannot take, which is no value and takes no step.
An evaluation context item: one suspended caller and how it reads its callee's result.
The expression e as the callee of the context item Ki.
A value is an outcome, written as the ended expression.
The outcome of an ended expression; None otherwise.
The Iris state over the world type world: the memory, the runtime's state, the fuel left, one counter for the whole stack, and the world of libc state the contracts speak of.
| ls_mem | : mem | |
| ls_rt | : R.state | |
| ls_fuel | : Z | |
| ls_world | : world |
The expression e under the callers cs, innermost first.
The callers cs as an Iris evaluation context, innermost first.
The expression of the configuration c: its running frame under its callers.
The Iris state of the configuration c with the runtime state s and the world w.
The frame fr after its external call at site returned, with the environment e: at the instruction after the call.
resume_external resumes the running frame as resumed_frame.
Explore proof 1 tactics
Initial goal
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
What ERunfr becomes when its external call at site, of the contract spec, returns the words values: the resumed_frame where the site's result takes them (external_env), EBad where it cannot.
The empty registry, over the world unit: no external function has a contract, so no external call is admissible.
The language over the registry, whose contracts share the world type world, in the genv ge.
The frame fr, alone in the memory, fuel and world of σ, is at an external_site whose call is M.admissible: a contract is registered, the arguments evaluate, the ABI and the precondition hold.
The frame fr can go on in σ: alone it does not fails, or it is at an external call that is admissible. ERunfr is head-reducible in σ exactly then (run_proceeds, proceeds_reducible).
A head step, with no observations and no forks. The running frame fr steps as fr alone would (mkConfigfr [ ] m fuel):
hs_next: a step that allocates nothing; a call yields the callee with fr suspended as its one caller, anEWait;hs_alloc: an allocation R grants;hs_refused: an allocation R refuses stalls: the run has stopped with a refusal, which is not a failure;hs_return: a returning ending, once the locals end, is the value;hs_stop: any other ending that is not afailure(running out of fuel, a refusal trap) stalls;hs_safepoint: R's action at a due safepoint, only where frproceeds, so that a failing frame or a rejected call is never reducible;hs_resume: a returned outcome resumes the caller waiting on it;hs_call_return: an external call whose contract's invocation returns words the call site takes resumes after the call, with the invocation's memory, runtime state and world;hs_call_bad: one that returns words the site cannot take isEBad;hs_call_wait: an admissible call stalls: it may block, exit, end for lack of resources, or have no completed invocation.
The context-item language laws: values round-trip, a value takes no step, filling is injective and never makes a value, and a head step of a filled context is hs_resume, whose callee is a value.
Explore proof 18 tactics
Initial goal
split
7 openfocused goal
focused goal
focused goal
focused goal
focused goal
–reflexivity
6 opendeferred goal
deferred goal
deferred goal
deferred goal
deferred goal
–intros e o H
6 opendeferred goal
deferred goal
deferred goal
deferred goal
destruct e ; inversion H ; reflexivity
5 opendeferred goal
deferred goal
deferred goal
deferred goal
–intros e1 σ1 κ e2 σ2 efs H
5 opendeferred goal
deferred goal
deferred goal
destruct H ; reflexivity
4 opendeferred goal
deferred goal
deferred goal
–intros cf pd e o H
4 opendeferred goal
deferred goal
discriminate H
3 opendeferred goal
deferred goal
–intros cf pd e1 e2 H
3 opendeferred goal
injection H as H
3 opendeferred goal
exact H
2 opendeferred goal
–intros cf1 pd1 cf2 pd2 e1 e2 _ _ H
2 openinjection H as _ → →
2 openreflexivity
–intros cf pd e σ1 κ e2 σ2 efs H
inversion H ; subst
eexists
2 openreflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Nanofil's machine with the contracts of registry, in the genv ge, as an Iris language with context items, contexts, and as a plain language.
The same language with evaluation contexts.
The same language, plain.
The expression under the callers cs1 then cs2 is under cs1, and that under cs2.
Explore proof 4 tactics
Initial goal
revert e
induction cs1 as | cf pd cs1 IH ; intros e ; reflexivity |
cbn
apply IH
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
An expression that is not a value is not one under any callers.
Explore proof 5 tactics
Initial goal
revert e
induction cs as | cf pd cs IH ; intros e H ; exact H |
cbn
apply IH
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Facts of the language with the contracts of registry, in the genv ge.
The expression e under the callers cs is Iris's fill of their context, foldlflipfill_item, innermost first.
Explore proof 5 tactics
Initial goal
revert e
induction cs as | cf pd cs IH ; intros e ; reflexivity |
cbn [ stack_expr ]
rewrite IH
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A head step under the callers cs is an Iris step of the thread pool of that one expression.
Explore proof 5 tactics
Initial goal
intros H
exists [ ]
apply step_atomicstack_expre1 cs σ1 stack_expre2 cs σ2 [ ] [ ] [ ] ; reflexivity | reflexivity |
rewrite ! stack_expr_fill
exact Ectx_step'Λ ≔ nanofil_ectx_langregistry ge _ _ _ _ _ _ _ H
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Where e is not a value and has only values as sub-redexes, e under any callers is reducible only if e is head-reducible.
Explore proof 13 tactics
Initial goal
intros Hv Hsub κ & e2 & σ2 & efs & Hs
rewrite stack_expr_fill in Hs
destruct Hs as K e1′ e2′ HK _ Hb
destruct step_by_valΛ ≔ nanofil_ectx_langregistry ge ctx_ofcs K e e1′ _ _ _ _ _ HK Hv Hb as K′′ →
rewrite <- fill_comp in HK
apply inj_ in HK
assert Hs : @sub_redexes_are_valuesnanofil_ectx_langregistry ge e
2 openfocused goal
{exact ectxi_language_sub_redexes_are_valuesΛ ≔ nanofil_ectxi_langregistry ge e Hsub
deferred goal
pose proof HsK′′ e1′ HK val_base_stuck_ _ _ _ _ _ Hb as →
rewrite fill_empty in HK
subst e1′
do 4 eexists
5 openshelved goal
shelved goal
shelved goal
shelved goal
exact Hb
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
The inversion of a head step from ERunfr in the state σ: no observations or forks, and one of the cases of head_step, each stated of fr alone; an external call's return is one case, the frame resumed or EBad (returned_expr). Weakest-precondition rules are stated per case.
Proof 34 steps Qed
Proof 31 steps Qed
Explore proof 20 tactics
Initial goal
destruct σ as m s fuel w
cbn
intros Hf
unfold fails in Hf
destruct Semantics.stepge mkConfigfr [ ] m fuel as c′ | o | q k | w′ eqn: E
4 openfocused goal
focused goal
–do 4 eexists
8 opendeferred goal
deferred goal
deferred goal
shelved goal
shelved goal
shelved goal
eapply hs_next
5 opendeferred goal
deferred goal
deferred goal
exact E
3 opendeferred goal
deferred goal
–destruct returning_deco as Hr | Hr
4 openfocused goal
deferred goal
+destruct step_callers_returnge fr [ ] m fuel o E Hr as _ m′ Hi
4 opendeferred goal
deferred goal
do 4 eexists
8 opendeferred goal
deferred goal
deferred goal
shelved goal
shelved goal
shelved goal
shelved goal
eapply hs_return ; eassumption
3 opendeferred goal
deferred goal
+do 4 eexists
7 opendeferred goal
deferred goal
shelved goal
shelved goal
shelved goal
eapply hs_stop ; eassumption
2 opendeferred goal
–destruct R.allocs q as base s′ | eqn: Ea
3 openfocused goal
+do 4 eexists
7 opendeferred goal
deferred goal
shelved goal
shelved goal
shelved goal
shelved goal
eapply hs_alloc ; exact E | lia | exact Ea
2 opendeferred goal
+do 4 eexists
6 opendeferred goal
shelved goal
shelved goal
shelved goal
shelved goal
eapply hs_refused ; exact E | lia | exact Ea
–contradiction
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Nor an admissible external call: ERunfr at one is head-reducible, by hs_call_wait, whether or not the contract allows a return.
Explore proof 4 tactics
Initial goal
destruct σ as m s fuel w
intros site & Hs & spec & xs & Hr & Hx & Ha & Hp
do 4 eexists
5 openshelved goal
shelved goal
shelved goal
shelved goal
eapply hs_call_wait ; eassumption
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A frame that proceeds is head-reducible.
Explore proof 1 tactics
Initial goal
intros H | H ; exact run_reducible_ _ H | exact admissible_reducible_ _ H
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A returned outcome waiting on a caller is reducible, under any callers, only where the caller resumes.
Explore proof 10 tactics
Initial goal
intros H
apply ctx_base_reducible in H as κ & e′ & σ′ & efs & Hs
3 openfocused goal
–inversion Hs ; subst
3 opendeferred goal
eauto
2 opendeferred goal
–reflexivity
–intros cf′ pd′ e′ Heq
cbn in Heq
injection Heq as ← _ _
eexists
2 openreflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A bad return is stuck under any callers.
Explore proof 6 tactics
Initial goal
intros H
apply ctx_base_reducible in H as κ & e′ & σ′ & efs & Hs
3 openfocused goal
–inversion Hs
2 opendeferred goal
–reflexivity
–intros cf pd e′ Heq
discriminate Heq
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Where the expression of the configuration c is not stuck, its running frame proceeds.
Explore proof 9 tactics
Initial goal
intros v Hv | Hred
2 openfocused goal
–change to_valconf_exprc = Somev in Hv
2 opendeferred goal
unfold conf_expr in Hv
2 opendeferred goal
rewrite to_val_stack in Hv ; discriminate Hv | reflexivity
deferred goal
–apply ctx_base_reducible in Hred as κ & e′ & σ′ & efs & Hs
3 openfocused goal
+exact run_proceeds_ _ _ _ _ _ Hs
2 opendeferred goal
+reflexivity
+intros cf pd e′ Heq
discriminate Heq
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Adequacy
Adequacy for the run of the frame fr0, with the contracts of registry in the genv ge, from the memory m0, the runtime state s0, the fuel fuel0 and the world w0.
The configuration c with the runtime state s and the world w is Iris-reachable: its expression and state follow the initial ones by Iris steps.
Where Iris adequacy holds, the running frame of every Iris-reachable configuration proceeds.
Explore proof 4 tactics
Initial goal
intros Had Hr
apply conf_reducibleregistry ge c s w
apply adequate_not_stuck_ _ _ _ Had _ _ conf_exprc eq_refl Hr
left
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Proof 43 steps Qed
An Iris-reachable configuration whose frame alone does not fails does not fail: where its return to a caller is stuck, the returned outcome waiting on that caller is Iris-reachable and stuck.
Proof 27 steps Qed
An Iris-reachable configuration at no external site does not fails.
Explore proof 5 tactics
Initial goal
intros Had Hr Hns
apply reach_not_failsφ c s w Had Hr
destruct reach_proceedsφ c s w Had Hr as Hnf | site & Hs & _ ; exact Hnf |
exfalso
exact Hnssite Hs
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
A core ending of an Iris-reachable configuration at no external site is no failure; a returning one is a top-level return, whose value satisfies φ in some Iris-reachable state.
Proof 27 steps Qed
An Iris-reachable configuration at no external site is not stuck.
Explore proof 5 tactics
Initial goal
intros Had Hr Hns E
apply reach_coreφ c s w Had Hr Hns
unfold fails
rewrite E
exact I
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
An external call's return to an Iris-reachable configuration reaches an Iris-reachable one: hs_call_return under the callers.
Explore proof 4 tactics
Initial goal
intros Hr Hs Hreg Hx Hi He
destruct c as fr cs m fuel
eapply rtc_r ; exact Hr |
exact head_erasedregistry ge cs _ _ _ _ hs_call_returnregistry ge fr m s fuel w site spec xs trace values s′ m′ w′ e Hs Hreg Hx Hi He
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
An Iris-reachable configuration's external call never returns words its call site cannot take: that would reach EBad.
Explore proof 9 tactics
Initial goal
intros Had Hr Hs Hreg Hx Hi He
destruct c as fr cs m fuel
assert Hr′ : rtc@erased_stepnanofil_langregistry ge ERunfr0, mkLstatem0 s0 fuel0 w0 stack_exprEBad cs, mkLstatem′ s′ fuel w′
2 openfocused goal
{eapply rtc_r ; exact Hr |
2 opendeferred goal
exact head_erasedregistry ge cs _ _ _ _ hs_call_badregistry ge fr m s fuel w site spec xs trace values s′ m′ w′ Hs Hreg Hx Hi He
deferred goal
destruct adequate_not_stuck_ _ _ _ Had _ _ _ eq_refl Hr′ ltac:left as v Hv | Hred
2 openfocused goal
–change to_valstack_exprEBad cs = Somev in Hv
2 opendeferred goal
rewrite to_val_stack in Hv ; discriminate Hv | reflexivity
deferred goal
–exact bad_stuckregistry ge cs _ Hred
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
No external call of an Iris-reachable configuration is M.rejected: its frame proceeds, and it is at a failing step, so its call is admissible.
Explore proof 12 tactics
Initial goal
intros Had Hr Hs Hrej
destruct reach_proceedsφ c s w Had Hr as Hnf | site′ & Hs′ & Hadm
2 openfocused goal
–apply Hnf
2 opendeferred goal
unfold fails
2 opendeferred goal
cbn [ conf_state ls_mem ls_fuel ]
2 opendeferred goal
rewrite external_site_stuck_ _ _ external_site_framege c c_memc c_fuelc site Hs
2 opendeferred goal
exact I
deferred goal
–assert site′ = site as →
2 openfocused goal
{eapply external_site_uniquege ; | exact Hs′ | exact Hs
2 opendeferred goal
reflexivity
deferred goal
destruct c as fr cs m fuel
exact M.admissible_not_rejectedworld registry ge mkConfigfr cs m fuel w site why Hadm Hrej
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
What adequacy says of a labelled machine state: a running state is Iris-reachable; a stopped one stopped with no failure_ending, and a returning core ending satisfies φ in some state.
Every labelled step from an Iris-reachable running state reaches a labelled_good state: a core step is reach_step; an external return is reach_return; a core ending is reach_end; an exit is no failure, nor a resource ending (invoke_resource_refusal), nor a refusal; and a stuck core step, a rejected call and a bad return cannot happen.
Proof 30 steps Qed
Adequacy for the labelled machine (ExternalMachine.v): where Iris adequacy holds for ERunfr0 from m0, s0, fuel0 and w0, every running state of a labelled run from there is Iris-reachable, and every stopped state stopped with no failure_ending; where it stopped with a returning core ending, a top-level return, its value satisfies φ in some state.
Explore proof 18 tactics
Initial goal
intros Had
assert Hgen : ∀st1 trace st2, M.runregistry ge st1 trace st2 → labelled_goodφ st1 → labelled_goodφ st2
2 openfocused goal
{intros st1 trace st2 H
2 opendeferred goal
induction H as st | st tr mid tail last Hs _ IH ; auto |
2 opendeferred goal
intros Hg
2 opendeferred goal
apply IH
2 opendeferred goal
destruct st as c s w | why ms w
3 openfocused goal
deferred goal
–exact reach_labelledφ c s w tr mid Had Hg Hs
2 opendeferred goal
deferred goal
–exfalso
2 opendeferred goal
eapply M.stopped_no_step
10 opendeferred goal
shelved goal
shelved goal
shelved goal
shelved goal
shelved goal
shelved goal
shelved goal
shelved goal
exact Hs
deferred goal
intros trace st Hrun
pose proof Hgen_ _ _ Hrun rtc_refl_ _ as Hg
split
2 openfocused goal
–intros c s w →
2 opendeferred goal
exact Hg
deferred goal
–intros why ms w →
exact Hg
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
With no contracts no call is admissible: a frame proceeds only where it does not fail.
Explore proof 1 tactics
Source script
Explore proof 15 tactics
Initial goal
intros Had
pose reach := λst : RM.mstate ⇒ iris_reachno_contracts ge fr0 m0 R.start fuel0 tt fstst sndst tt
assert Hgen : ∀st1 st2, RM.mreachablege st1 st2 → reachst1 → reachst2
2 openfocused goal
{intros st1 st2 H
2 opendeferred goal
induction H as c s c′ s′ Hs | st1 | st1 st2 st3 _ IH1 _ IH2 ; auto
2 opendeferred goal
unfold reach
2 opendeferred goal
cbn
2 opendeferred goal
intros Hr
2 opendeferred goal
exact reach_step_ _ _ _ _ _ _ φ c s tt c′ s′ Had Hr Hs
deferred goal
intros c s Hreach
pose proof Hgen_ _ Hreach rtc_refl_ _ as Hr
unfold reach in Hr
cbn [ fst snd ] in Hr |- *
apply reach_not_fails_ _ _ _ _ _ _ φ c s tt Had Hr
exact proceeds_closedge c_framec _ reach_proceeds_ _ _ _ _ _ _ φ c s tt Had Hr
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Adequacy: Iris adequacy proves never_panics. Where the module's initial memory and entry function exist, every admissible input makes the entry's frame, and (where R is ready at its start in that memory) for every fuel and every invariant instance a state interpretation stateI can be allocated that holds of the initial state and gives a NotStuck weakest precondition of the entry's ERun, with no contracts, the module never panics. The later-credit flag hlc is left to the caller.
Proof 21 steps Qed
The labelled machine's safety for the frame fr, with the contracts of registry in the genv ge, from the memory m, the runtime state s, the world w and the fuel fuel: every labelled run from there that stops, stops with no failure_ending, and where it stops with a returning core ending, a top-level return, its value satisfies φ.
Adequacy for the labelled machine: where, for every invariant instance, a state interpretation stateI can be allocated that holds of the initial state (the memory m, the runtime state s, the fuel, the world w) and gives a NotStuck weakest precondition of ERunfr with the postcondition φ, the run is labelled_safe. Where R must be ready in s and m, as for a ghost heap, that is the caller's premise for allocating stateI (heap_labelled_safe).
Explore proof 16 tactics
Initial goal
intros Hw trace why ms w′ Hrun
assert Had : @adequatenanofil_langregistry ge NotStuck ERunfr mkLstatem s fuel w λo _ ⇒ φo
2 openfocused goal
{apply wp_adequacy_genhlc Σ nanofil_langregistry ge NotStuck _ _ φ
2 opendeferred goal
intros Hinv κs
2 opendeferred goal
iMod HwHinv as stateI [Hσ Hwp]
2 opendeferred goal
iModIntro
2 opendeferred goal
iExists λσ _ ⇒ stateIσ, λ_ ⇒ True%I
2 opendeferred goal
cbn
2 opendeferred goal
iFrame Hσ
2 opendeferred goal
iExact Hwp
deferred goal
destruct adequate_labelledregistry ge fr m s fuel w _ Had _ _ Hrun as _ H
destruct Hwhy ms w′ eq_refl as Hf Hφ
split ; exact Hf |
intros o Ho Hr
destruct Hφo Ho Hr as σ Hσ
exact Hσ
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.