Fil-C on Nix

Filnix wiki

the formal campaign

rocq/theories/Ending.v

Exit requests precede terminal external dispatch. This additive bridge shares Linked's current payload and authoritative shutdown inventory. Native registration, administrative effects and host completion remain explicit trusted obligations; no native coverage or termination follows.

From Stdlib Require Import String ZArith List Bool Lia
From Nanofil Require Import Term Maps Syntax Values Memory Runtime Ops Semantics Machine Identity ExternalCalls Startup Stdio Shutdown ExitMemory ExternalMachine Linked
Import ListNotations
Open Scope Z_scope
Open Scope list_scope

Only these unresolved direct symbols are plain exit requests. An already stopped ExternalExit is never decoded as another request.

15Definition exit_symbolsymbol : name : optionhandoff_kind ≔
name_eqbsymbol TAtom"exit"
→
name_eqbsymbol TAtom"_exit"
→
name_eqbsymbol TAtom"_Exit"
→
else
None

A C int argument has W class and a nonreturning void call site.

21Definition exit_abir : call_result args : listarg : Prop ≔
r = CVoid ∧ ∃value, args = ArgW value

Initial and nested soft requests retain the CURRENT inventory and stdout. Initial application execution uses Tls as its dormant phase. No soft request reopens closed cleanup. Hard exit never flushes.

27Inductive exit_request: handoff_kind → Z → shutdown_state → shutdown_state → Prop ≔
∀ status old pending consumed q
exit_requestSoftExit status mkShutdownTls old pending consumed q mkShutdownTls status pending consumed q
request_initial
∀ status old active pending consumed q
exit_requestSoftExit status mkShutdownInCallbackactive old pending consumed q mkShutdownTls status pending consumed q
request_recursive

Requests preserve all registration instances and output obligations.

41Lemma exit_request_inventory
∀ kind status sh sh′
exit_requestkind status sh sh′
Explore proof 2 tactics

Initial goal

⊢
∀kind : handoff_kind status : Z sh sh′ : shutdown_state, exit_requestkind status sh sh′ → shutdown_pendingsh′ = shutdown_pendingsh ∧ shutdown_consumedsh′ = shutdown_consumedsh ∧ shutdown_stdoutsh′ = shutdown_stdoutsh ∧ shutdown_statussh′ = status

intros kind status sh sh′ H

status :
Z
sh, sh′ :
H :
exit_requestkind status sh sh′

destruct H ; repeat split ; reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros kind status sh sh′ H
destruct H ; repeat split ; reflexivity

Uniqueness survives recursive and hard exit without a new inventory.

49Lemma exit_request_unique
∀ kind status sh sh′
exit_requestkind status sh sh′
Explore proof 2 tactics

Initial goal

⊢
∀kind : handoff_kind status : Z sh sh′ : shutdown_state, exit_requestkind status sh sh′ → shutdown_uniquesh → shutdown_uniquesh′

intros kind status sh sh′ H

status :
Z
sh, sh′ :
H :
exit_requestkind status sh sh′

destruct H ; auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros kind status sh sh′ H
destruct H ; auto

Successful registration is permitted before exit or inside a callback, never after cleanup. Tokens are fresh even for repeated function names.

55Inductive registration_updateentry : registration : shutdown_state → shutdown_state → Prop ≔
∀ status pending consumed q
¬Inregistration_tokenentry consumed ++ mapregistration_token pending
registration_before_exit
registration_updateentry mkShutdownTls status pending consumed q mkShutdownTls status entry :: pending consumed q
∀ status active pending consumed q
¬Inregistration_tokenentry consumed ++ mapregistration_token pending
registration_in_callback
registration_updateentry mkShutdownInCallbackactive status pending consumed q mkShutdownInCallbackactive status entry :: pending consumed q

Registration does not alter the active status, consumed history or stdout.

66Lemma registration_update_unique
∀ entry sh sh′
Explore proof 2 tactics

Initial goal

⊢
∀entry : registration sh sh′ : shutdown_state, registration_updateentry sh sh′ → shutdown_uniquesh → shutdown_uniquesh′

intros entry sh sh′ H Hu

destruct H ; unfold shutdown_unique in * ; simpl in * ; apply shutdown_unique_insert ; assumption

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros entry sh sh′ H Hu
destruct H ; unfold shutdown_unique in * ; simpl in * ; apply shutdown_unique_insert ; assumption

This pin implements atexit with a cxa slot, null argument and null DSO. Physical representation and callback semantic admission are independent.

75Definition atexit_installedm head blocks function entry : Prop ≔
∃token symbol, entry = mkRegistrationtoken CxaExitsymbol WPtrmkPtr0 CNone ∧ ptr_capfunction = Fnsymbol ∧ InCxaSlottoken symbol function mkPtr0 CNone mkPtr0 CNone flat_mapblock_slots blocks ∧ exit_registry_memorym head blocks

Even resource/unfinished prefixes retain the current inventory or add exactly one freshly installed instance. Reserved physical slots do not yet add a logical callback. No completion result is asserted here.

86Definition atexit_progresspayload : Type represented : mem → payload → ptr → listexit_block → Prop xs w : payload × shutdown_state m′ w′ : payload × shutdown_state : Prop ≔
∃head blocks, representedm′ fstw′ head blocks ∧ exit_registry_memorym′ head blocks ∧ exit_registry_pendingblocks = shutdown_pendingsndw′ ∧ sndw′ = sndw ∨ ∃function entry, xs = WPtrfunction ∧ atexit_installedm′ head blocks function entry ∧ registration_updateentry sndw sndw′

The native contract supplies effects, allocation and private registry authority. This overlay supplies the exact public API and couples its successful result to physical installation and the single inventory. Callback admission must be supplied independently at entry.

100Definition atexit_contractpayload : Type ge : genv native : contractpayload × shutdown_state represented : mem → payload → ptr → listexit_block → Prop : contractpayload × shutdown_state ≔
mkContract_ RClassW λr args ⇒ r = CVoid ∨ ∃d, r = CResultd W ∧ ∃value, args = ArgP value ∧ contract_abinative r args λxs m w ⇒ contract_prenative xs m w ∧ shutdown_uniquesndw ∧ atexit_progressrepresented xs w m w ∧ ∃function, xs = WPtrfunction ∧ function_check_resge function = Someok contract_sourcesnative contract_writesnative contract_releasesnative contract_requestsnative λxs m w born trace m′ w′ ⇒ contract_prefixnative xs m w born trace m′ w′ ∧ trace = [ ] ∧ atexit_progressrepresented xs w m′ w′ λxs m w born trace ending m′ w′ ⇒ contract_postnative xs m w born trace ending m′ w′ ∧ ∃function result, xs = WPtrfunction ∧ ending = CallReturnWIntresult ∧ trace = [ ] ∧ result = 0 ∧ ∃head blocks entry, representedm′ fstw′ head blocks ∧ atexit_installedm′ head blocks function entry ∧ exit_registry_pendingblocks = shutdown_pendingsndw′ ∧ registration_updateentry sndw sndw′ ∨ result = 2 ^ 32 − 1 ∧ sndw′ = sndw contract_resourcenative contract_panicsnative

Only administrative actions may be delegated wholesale. Callback pop, execution and return use the separate, memory-backed rules below.

128Definition administrativeaction : shutdown_action : Prop ≔
match action with
_
⇒
False

Requests and callbacks extend the labelled machine, never Machine.v.

135Module Ending R : Runtime L : LinkedSigR
136Module M ≔ L.M
137Module E ≔ M.E
138Module RM ≔ L.RM
139Module Pop ≔ ExitPop R
142Section World
143Variable payload : Type

One payload and one authoritative lifecycle, as in Linked.

145Definition world: Type ≔

Running application/callback code, a suspended exit loop, and completed host termination retain exact machine snapshots. Stopped remains stopped.

149Inductive state: Type ≔
|Executing
|Draining
ms : RM.mstate w : world
|Partial
ms : RM.mstate w : world
|Finished
ms : RM.mstate w : world

Every mode retains its exact machine snapshot, including partial leaves.

156Definition machine_ofst : state : RM.mstate ≔
match st with
Executingactive
⇒
M.machine_of_ active
Drainingms _ | Partialms _ | Finishedms _
⇒
ms

Readiness does not assert contract admission, progress or native coverage.

163Definition state_readyst : state : Prop ≔

Administrative libc effects use the existing capability/effects boundary. Readiness/representation at both endpoints is an explicit obligation, not a native satisfaction theorem. A synthetic CallReturn marks a completed internal cutpoint, not a native return from host handoff. registry_rep identifies the authoritative physical chain in the payload; use this same projection as atexit_contract's represented argument.

171Record boundary: Type ≔ mkBoundary
ending_rep
 : R.state → mem → world → Prop
registry_rep
 : mem → payload → ptr → listexit_block → Prop
registry_owned
 : payload → listZ
action_spec
action_args
 : shutdown_action → listarg
action_values
 : shutdown_action → listword
host_complete
 : R.state → mem → world → Prop

The selected request syntax, evaluated independently of any invocation.

182Definition request_sitege c site kind bits : Prop ≔
external_sitege c site ∧ exit_symbolsite_namesite = Somekind ∧ exit_abisite_resultsite site_argssite ∧ map_optionarg_xge fr_envc_framec site_argssite = SomeWIntbits

Admission is independent of successful execution. Reached-call proofs must establish it again after safepoints; its failure is visible below.

189Definition request_admittedb : boundary ge c s w site kind : Prop ≔
ending_repb s c_memc w ∧ shutdown_uniquesndw ∧ ∃bits sh′, request_sitege c site kind bits ∧ exit_requestkind main_statusbits sndw sh′

A single dispatcher: reserved names (e.g. error) are handled by a further explicit bridge, not ordinary terminal external dispatch. Safepoints at intercepted calls still run and recheck admission later.

197Inductive stepregistry : name → optioncontractworld ge reserved : name → bool b : boundary admitted : registration → R.state → mem → world → Prop : state → listevent → state → Prop ≔
∀ st trace st′
∀c s w site, st = M.Runningc, s w → external_sitege c site → exit_symbolsite_namesite = None ∧ reservedsite_namesite = false
M.stepregistry ge st trace st′
ending_ordinary
stepregistry ge reserved b admitted Executingst trace Executingst′
∀ c s w s′ m′
RM.safepoint_duege c = true
R.safepoints c_memc s′ m′
ending_poll
stepregistry ge reserved b admitted ExecutingM.Runningc, s w [ ] ExecutingM.RunningRM.with_memc m′, s′ w
∀ c s w site kind bits sh′
request_sitege c site kind bits
exit_requestkind main_statusbits sndw sh′
ending_request
stepregistry ge reserved b admitted ExecutingM.Runningc, s w [ ] Drainingc, s fstw, sh′
∀ c s w site kind
external_sitege c site
exit_symbolsite_namesite = Somekind
¬request_admittedb ge c s w site kind
ending_rejected
stepregistry ge reserved b admitted ExecutingM.Runningc, s w [ ] ExecutingM.StoppedContractViolationsite_namesite BadPrecondition c, s w
∀ c s w action trace s′ m′ w′
shutdown_stepsndw action sndw′
E.invokeaction_specb action CVoid action_argsb action action_valuesb action s c_memc w trace CallReturn[ ] s′ m′ w′
trace
=
match action with
_
⇒
[ ]
ending_repb s′ m′ w′
ending_action
stepregistry ge reserved b admitted Drainingc, s w trace DrainingRM.with_memc m′, s′ w′
∀ c s w action born trace s′ m′ w′
E.prefixaction_specb action action_valuesb action s c_memc w born trace s′ m′ w′
∀status, ¬InProcessExitstatus trace
ending_action_prefix
stepregistry ge reserved b admitted Drainingc, s w trace PartialRM.with_memc m′, s′ w′
∀ c s w action trace why s′ m′ w′
E.invokeaction_specb action CVoid action_argsb action action_valuesb action s c_memc w trace CallResourcewhy s′ m′ w′
∀status, ¬InProcessExitstatus trace
ending_action_resource
stepregistry ge reserved b admitted Drainingc, s w trace ExecutingM.StoppedCoreEndTrapwhy RM.with_memc m′, s′ w′
∀ c s data status consumed q head p older slot rest entry fuel callback
registry_repb c_memc data head mkExitBlockp older ++ slot :: rest
exit_registry_memoryc_memc head mkExitBlockp older ++ slot :: rest
exit_slot_pendingslot = entry
shutdown_uniquemkShutdownHandlers status exit_registry_pendingmkExitBlockp older ++ slot :: rest consumed q
L.callback_entrypayload admitted ge slot entry s exit_pop_memoryc_memc p older slot data, mkShutdownInCallbackentry status exit_registry_pendingmkExitBlockp older :: rest consumed ++ registration_tokenentry q fuel callback
fuel = c_fuelc
registry_repb exit_pop_memoryc_memc p older slot data head mkExitBlockp older :: rest
ending_pop
stepregistry ge reserved b admitted Drainingc, s data, mkShutdownHandlers status exit_registry_pendingmkExitBlockp older ++ slot :: rest consumed q [ ] ExecutingM.Runningcallback, s data, mkShutdownInCallbackentry status exit_registry_pendingmkExitBlockp older :: rest consumed ++ registration_tokenentry q
∀ c s data status consumed q head p older slot rest
registry_repb c_memc data head mkExitBlockp older ++ slot :: rest
exit_registry_memoryc_memc head mkExitBlockp older ++ slot :: rest
slot = FreeSlot ∨ slot = ReservedSlot
registry_repb exit_pop_memoryc_memc p older slot data head mkExitBlockp older :: rest
ending_skip
stepregistry ge reserved b admitted Drainingc, s data, mkShutdownHandlers status exit_registry_pendingmkExitBlockp older ++ slot :: rest consumed q [ ] DrainingRM.with_memc exit_pop_memoryc_memc p older slot, s data, mkShutdownHandlers status exit_registry_pendingmkExitBlockp older :: rest consumed q
∀ c s data sh head block rest m′
registry_repb c_memc data head rest
R.freeWPtrblock_ptrblock c_memc = Someok, m′
E.effects[ ] [ ] ptr_addrblock_ptrblock λ_ _ ⇒ False s c_memc [ ] s m′ [ ]
registry_repb m′ data head rest
ending_retire
stepregistry ge reserved b admitted Drainingc, s data, sh [ ] DrainingRM.with_memc m′, s data, sh
∀ entry st ms′ w′
L.callback_returnpayload entry st ms′ w′
ending_return
stepregistry ge reserved b admitted Executingst [ ] Drainingms′ w′
∀ c s data kind status pending consumed q
host_completeb s c_memc data, mkShutdownHandedOffkind status pending consumed q
ending_complete
stepregistry ge reserved b admitted Drainingc, s data, mkShutdownHandedOffkind status pending consumed q ProcessExitprocess_statusstatus Finishedc, s data, mkShutdownHandedOffkind status pending consumed q

Entry uses the actual post-pop memory, not a second chosen snapshot.

314Lemma callback_entry_memory
∀ admitted ge slot entry s m w fuel callback
L.callback_entrypayload admitted ge slot entry s m w fuel callback
c_memcallback = m
Explore proof 2 tactics

Initial goal

payload :
Type
⊢
∀admitted : registration → R.state → mem → L.callback_worldpayload → Prop ge : genv slot : exit_slot entry : registration s : R.state m : mem w : payload × shutdown_state fuel : Z callback : config, L.callback_entrypayload admitted ge slot entry s m w fuel callback → c_memcallback = m

intros admitted ge slot entry s m w fuel callback _ & _ & _ & _ & _ & _ & fr & _ & →

payload :
Type
admitted :
registration → R.state → mem → L.callback_worldpayload → Prop
ge :
slot :
m :
w :
payload × shutdown_state
fuel :
Z
fr :
⊢
c_memc_frame ≔ fr; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel = m

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros admitted ge slot entry s m w fuel callback _ & _ & _ & _ & _ & _ & fr & _ & →
reflexivity

Every new edge preserves readiness and identities by its existing effect path or local teardown. This is structural preservation, not safety.

323Theorem step_preserve
∀ registry ge reserved b admitted st trace st′
ge_freege = R.free
stepregistry ge reserved b admitted st trace st′
Proof 23 steps Qed
intros registry ge reserved b admitted st trace st′ Hfree H
destruct H ; unfold state_ready , machine_of , RM.ready_state ; simpl ; intros Hr
–split ; eapply M.step_ready | eapply M.step_persists ; eauto
–assert Hs : M.stepregistry ge M.Runningc, s w [ ] M.RunningRM.with_memc m', s' w
eapply RM.mstep_safepoint ; eauto
split
+exact M.step_readyworld registry ge _ _ _ Hfree Hs Hr
+exact M.step_persistsworld registry ge _ _ _ Hfree Hs Hr
–split ; auto using persists_refl
–split ; auto using persists_refl
–eapply E.invoke_preserve ; eauto
–eapply E.prefix_preserve ; eauto
–eapply E.invoke_preserve ; eauto
–match goal withHentry : L.callback_entry_ _ _ _ _ _ _ _ _ _ |- _⇒rewrite callback_entry_memory_ _ _ _ _ _ _ _ _ Hentryend
exact proj2Pop.pop_preserves_ _ _ _ _ H3 Hr
–exact proj2Pop.pop_preserves_ _ _ _ _ H3 Hr
–eapply Unlink.unlink_preserves ; eauto
match goal withHregistry : exit_registry_memory_ _ _ |- _⇒exact proj1proj1proj2proj2Hregistryend
–eapply E.effects_preserve ; eauto
–destruct L.callback_return_preserve_ _ _ _ _ H Hr as Hr′ Hp _
auto
–split ; auto using persists_refl

Finite prefixes need not finish a handler or reach host completion.

355Inductive runregistry ge reserved b admitted : state → listevent → state → Prop ≔
∀ st
runregistry ge reserved b admitted st [ ] st
run_refl
∀ st trace mid tail st′
stepregistry ge reserved b admitted st trace mid
runregistry ge reserved b admitted mid tail st′
run_cons
runregistry ge reserved b admitted st trace ++ tail st′

Finite execution retains readiness and every starting identity.

363Theorem run_preserve
∀ registry ge reserved b admitted st trace st′
ge_freege = R.free
runregistry ge reserved b admitted st trace st′
Explore proof 7 tactics

Initial goal

payload :
Type
⊢
∀registry : name → optioncontractworld ge : genv reserved : name → bool b : boundary admitted : registration → R.state → mem → world → Prop st : state trace : listevent st′ : state, ge_freege = R.free → runregistry ge reserved b admitted st trace st′ → state_readyst → state_readyst′ ∧ persistsc_memfstmachine_ofst c_memfstmachine_ofst′

intros registry ge reserved b admitted st trace st′ Hfree H

payload :
Type
registry :
name → optioncontractworld
ge :
reserved :
name → bool
admitted :
registration → R.state → mem → world → Prop
st :
trace :
listevent
st′ :
Hfree :
ge_freege = R.free
H :
runregistry ge reserved b admitted st trace st′

induction H ; intros Hr

2 open

payload :
Type
registry :
name → optioncontractworld
ge :
reserved :
name → bool
admitted :
registration → R.state → mem → world → Prop
Hfree :
ge_freege = R.free
st :
focused goal
payload :
Type
registry :
name → optioncontractworld
ge :
reserved :
name → bool
admitted :
registration → R.state → mem → world → Prop
Hfree :
ge_freege = R.free
st :
trace :
listevent
mid :
tail :
listevent
st′ :
H :
stepregistry ge reserved b admitted st trace mid
H0 :
runregistry ge reserved b admitted mid tail st′
IHrun :

–split ; auto using persists_refl

deferred goal
payload :
Type
registry :
name → optioncontractworld
ge :
reserved :
name → bool
admitted :
registration → R.state → mem → world → Prop
Hfree :
ge_freege = R.free
st :
trace :
listevent
mid :
tail :
listevent
st′ :
H :
stepregistry ge reserved b admitted st trace mid
H0 :
runregistry ge reserved b admitted mid tail st′
IHrun :

–destruct step_preserve_ _ _ _ _ _ _ _ Hfree H Hr as Hr1 Hp1

payload :
Type
registry :
name → optioncontractworld
ge :
reserved :
name → bool
admitted :
registration → R.state → mem → world → Prop
Hfree :
ge_freege = R.free
st :
trace :
listevent
mid :
tail :
listevent
st′ :
H :
stepregistry ge reserved b admitted st trace mid
H0 :
runregistry ge reserved b admitted mid tail st′
IHrun :
Hr1 :

destruct IHrunHr1 as Hr′ Hp2

payload :
Type
registry :
name → optioncontractworld
ge :
reserved :
name → bool
admitted :
registration → R.state → mem → world → Prop
Hfree :
ge_freege = R.free
st :
trace :
listevent
mid :
tail :
listevent
st′ :
H :
stepregistry ge reserved b admitted st trace mid
H0 :
runregistry ge reserved b admitted mid tail st′
IHrun :
Hr1 :
Hr′ :

split ; exact Hr′ |

payload :
Type
registry :
name → optioncontractworld
ge :
reserved :
name → bool
admitted :
registration → R.state → mem → world → Prop
Hfree :
ge_freege = R.free
st :
trace :
listevent
mid :
tail :
listevent
st′ :
H :
stepregistry ge reserved b admitted st trace mid
H0 :
runregistry ge reserved b admitted mid tail st′
IHrun :
Hr1 :
Hr′ :

eapply persists_trans ; eauto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros registry ge reserved b admitted st trace st′ Hfree H
induction H ; intros Hr
–split ; auto using persists_refl
–destruct step_preserve_ _ _ _ _ _ _ _ Hfree H Hr as Hr1 Hp1
destruct IHrunHr1 as Hr′ Hp2
split ; exact Hr′ |
eapply persists_trans ; eauto

A request is silent and never takes the caller's ordinary continuation.

376Lemma request_no_observation
∀ registry ge reserved b admitted c s w site kind bits sh′
request_sitege c site kind bits
exit_requestkind main_statusbits sndw sh′
stepregistry ge reserved b admitted ExecutingM.Runningc, s w [ ] Drainingc, s fstw, sh′
Explore proof 2 tactics

Initial goal

payload :
Type
⊢
∀registry : name → optioncontractworld ge : genv reserved : name → bool b : boundary admitted : registration → R.state → mem → world → Prop c : config s : R.state w : world site : call_site kind : handoff_kind bits : Z sh′ : shutdown_state, request_sitege c site kind bits → ending_repb s c_memc w → shutdown_uniquesndw → exit_requestkind main_statusbits sndw sh′ → stepregistry ge reserved b admitted ExecutingM.Runningc, s w [ ] Drainingc, s fstw, sh′

intros

payload :
Type
registry :
name → optioncontractworld
ge :
reserved :
name → bool
admitted :
registration → R.state → mem → world → Prop
site :
bits :
Z
H :
request_sitege c site kind bits
H0 :
H2 :
exit_requestkind main_statusbits sndw sh′
⊢
stepregistry ge reserved b admitted ExecutingM.Runningc, s w [ ] Drainingc, s fstw, sh′

eapply ending_request ; eauto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros
eapply ending_request ; eauto

Partial cutpoints cannot resume shutdown or inherit a completed action.

384Lemma partial_terminal
∀ registry ge reserved b admitted ms w trace st′
¬stepregistry ge reserved b admitted Partialms w trace st′
Explore proof 2 tactics

Initial goal

payload :
Type
⊢
∀registry : name → optioncontractworld ge : genv reserved : name → bool b : boundary admitted : registration → R.state → mem → world → Prop ms : RM.mstate w : world trace : listevent st′ : state, ¬stepregistry ge reserved b admitted Partialms w trace st′

intros registry ge reserved b admitted ms w trace st′ H

payload :
Type
registry :
name → optioncontractworld
ge :
reserved :
name → bool
admitted :
registration → R.state → mem → world → Prop
trace :
listevent
st′ :
H :
stepregistry ge reserved b admitted Partialms w trace st′
⊢
False

inversion H

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros registry ge reserved b admitted ms w trace st′ H
inversion H

Completed external exits cannot resume a callback or request shutdown.

389Lemma completed_exit_terminal
∀ registry ge reserved b admitted status ms w trace st′
¬stepregistry ge reserved b admitted ExecutingM.StoppedExternalExitstatus ms w trace st′
Explore proof 4 tactics

Initial goal

payload :
Type
⊢
∀registry : name → optioncontractworld ge : genv reserved : name → bool b : boundary admitted : registration → R.state → mem → world → Prop status : Z ms : M.P.I.RM.mstate w : world trace : listevent st′ : state, ¬stepregistry ge reserved b admitted ExecutingM.StoppedExternalExitstatus ms w trace st′

intros registry ge reserved b admitted status ms w trace st′ H

payload :
Type
registry :
name → optioncontractworld
ge :
reserved :
name → bool
admitted :
registration → R.state → mem → world → Prop
status :
Z
trace :
listevent
st′ :
H :
stepregistry ge reserved b admitted ExecutingM.StoppedExternalExitstatus ms w trace st′
⊢
False

inversion H ; subst

2 open

payload :
Type
registry :
name → optioncontractworld
ge :
reserved :
name → bool
admitted :
registration → R.state → mem → world → Prop
status :
Z
trace :
listevent
H :
stepregistry ge reserved b admitted ExecutingM.StoppedExternalExitstatus ms w trace Executingst'0
H1 :
∀c : config s : R.state w0 : world site : call_site, M.StoppedExternalExitstatus ms w = M.Runningc, s w0 → external_sitege c site → exit_symbolsite_namesite = None ∧ reservedsite_namesite = false
H2 :
M.stepregistry ge M.StoppedExternalExitstatus ms w trace st'0
⊢
False
focused goal
payload :
Type
registry :
name → optioncontractworld
ge :
reserved :
name → bool
admitted :
registration → R.state → mem → world → Prop
status :
Z
w′ :
H :
stepregistry ge reserved b admitted ExecutingM.StoppedExternalExitstatus ms w [ ] Drainingms′ w′
H1 :
L.callback_returnpayload entry M.StoppedExternalExitstatus ms w ms′ w′
⊢
False

–eapply M.stopped_no_step ; eauto

deferred goal
payload :
Type
registry :
name → optioncontractworld
ge :
reserved :
name → bool
admitted :
registration → R.state → mem → world → Prop
status :
Z
w′ :
H :
stepregistry ge reserved b admitted ExecutingM.StoppedExternalExitstatus ms w [ ] Drainingms′ w′
H1 :
L.callback_returnpayload entry M.StoppedExternalExitstatus ms w ms′ w′
⊢
False

–match goal withHreturn : L.callback_return_ _ _ _ _ |- _⇒apply L.callback_return_only_void in Hreturn ; discriminateend

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros registry ge reserved b admitted status ms w trace st′ H
inversion H ; subst
–eapply M.stopped_no_step ; eauto
–match goal withHreturn : L.callback_return_ _ _ _ _ |- _⇒apply L.callback_return_only_void in Hreturn ; discriminateend

abort is deliberately not mapped to soft exit. A whole-program safety proof must exclude every reached abort call or provide another boundary.

400Example abort_not_exit: exit_symbolTAtom"abort" = None
Explore proof 1 tactics

Initial goal

payload :
Type
⊢
exit_symbolTAtom"abort" = None

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
reflexivity

Signed status replacement retains partially outstanding output.

407Example request_nested_current: ∀q, exit_requestSoftExit −257 mkShutdownInCallbackexit_second 31 exit_added; exit_first 2%nat q mkShutdownTls −257 exit_added; exit_first 2%nat q
Explore proof 2 tactics
Source script
intros
constructor

Neither cleanup nor an already completed handoff can restart soft exit.

414Example request_closed: ∀status old pending consumed q sh′, ¬exit_requestSoftExit status mkShutdownCleanup old pending consumed q sh′ ∧ ¬exit_requestSoftExit status mkShutdownHandedOffSoftExit old pending consumed q sh′
Explore proof 2 tactics

Initial goal

⊢
∀status old : Z pending : listregistration consumed : listnat q : stream_state sh′ : shutdown_state, ¬exit_requestSoftExit status shutdown_at ≔ Cleanup; shutdown_status ≔ old; shutdown_pending ≔ pending; shutdown_consumed ≔ consumed; shutdown_stdout ≔ q sh′ ∧ ¬exit_requestSoftExit status shutdown_at ≔ HandedOffSoftExit; shutdown_status ≔ old; shutdown_pending ≔ pending; shutdown_consumed ≔ consumed; shutdown_stdout ≔ q sh′

intros

status, old :
Z
pending :
consumed :
listnat
⊢
¬exit_requestSoftExit status shutdown_at ≔ Cleanup; shutdown_status ≔ old; shutdown_pending ≔ pending; shutdown_consumed ≔ consumed; shutdown_stdout ≔ q sh′ ∧ ¬exit_requestSoftExit status shutdown_at ≔ HandedOffSoftExit; shutdown_status ≔ old; shutdown_pending ≔ pending; shutdown_consumed ≔ consumed; shutdown_stdout ≔ q sh′

split ; intro H ; inversion H

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros
split ; intro H ; inversion H