Fil-C on Nix

Filnix wiki

the formal campaign

rocq/theories/HelloClose.v

GNU Hello's closeout helpers through the separation logic. Module statics and the four errno bytes are owned pieces. Stream operations are premise triples, including their frame obligations; the null file name excludes the named-file diagnostic.

From iris.proofmode Require Import proofmode
From iris.base_logic.lib Require Import gen_heap
From iris.program_logic Require Import language weakestpre
From Stdlib Require Import ZArith Lia
From Stdlib Require String
From Nanofil Require Import Term Syntax Values Memory Runtime Ops Semantics Run StepRules Symbolic ExternalCalls ExternalMachine Pieces Heap ContractFrame Language Logic StringLogic MemLogic HelloModule HelloLeaf
Open Scope Z_scope
Open Scope list_scope
Arguments Z.add : simpl nomatch
Arguments Z.sub : simpl nomatch
Arguments Z.mul : simpl nomatch

Keep unknown arithmetic folded in computed instruction premises.

The stream-closing helper from the linked IR.

23Definition close_stream_fn: func ≔
Eval vm_compute in hello_fn"close_stream"

The exit callback from the linked IR.

25Definition close_stdout_fn: func ≔
Eval vm_compute in hello_fn"close_stdout"

A close_stream block.

27Definition cs_blocks : String.string : block ≔

A close_stdout block.

29Definition co_blocks : String.string : block ≔

The canonical W loaded from four owned bytes, signed or unsigned.

32Definition close_wxs : listZ : Z ≔
match xs with
a; b; c; d
⇒
extensionSw d × 256 + c × 256 + b × 256 + a mod 2 ^ 32
_
⇒
0

A canonical W value fits its return channel.

39Lemma close_w_range
∀ xs
0 ≤ close_wxs < 2 ^ 32
Explore proof 4 tactics

Initial goal

xs :
listZ
⊢
0 ≤ close_wxs < 2 ^ 32

unfold close_w

xs :
listZ
⊢
0 ≤ match xs with [ ] ⇒ 0 | a ⇒ 0 | a; b ⇒ 0 | a; b; c ⇒ 0 | a; b; c; d ⇒ extensionSw d × 256 + c × 256 + b × 256 + a mod 2 ^ 32 | a :: b :: c :: d :: _ :: _ ⇒ 0 end < 2 ^ 32

destruct xs as | a | b | c | d | u xs ; try cbn ; lia

a, b, c, d :
Z
⊢
0 ≤ extensionSw d × 256 + c × 256 + b × 256 + a mod 2 ^ 32 < 2 ^ 32

apply Z.mod_pos_bound

a, b, c, d :
Z
⊢
0 < 2 ^ 32

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
unfold close_w
destruct xs as | a | b | c | d | u xs ; try cbn ; lia
apply Z.mod_pos_bound
lia

close_stream binds its stream argument.

46Lemma close_stream_entry
Explore proof 1 tactics

Initial goal

p :
⊢
invocationclose_stream_fn WPtrp = fr_fn ≔ close_stream_fn; fr_env ≔ TAtom"v0", WPtrp; fr_locals ≔ [ ]; fr_doomed ≔ None; fr_at ≔ EnterTAtom"start" None

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
reflexivity

The stream helper over any runtime.

51Module HelloCloseOn R : Runtime LG0 : LogicSigR
52Module HL ≔ HelloLeafOn R LG0
53Module ML ≔ HL.ML
54Module SL ≔ ML.SL
55Module LG ≔ ML.LG
56Module L ≔ LG.L
Import L LG SL ML HL
59Section close
60Context `{!invGS_genhlc Σ, !gen_heapGSpiece pval Σ}
61Context world : Type registry : name → optioncontractworld wi : mem → world → gmappiece pval → Prop `{!SafepointStablewi} ge : genv

The instance used by all closeout triples.

65Instance close_irisGS: irisGS_genhlc nanofil_langregistry ge Σ ≔
nanofil_irisGSregistry wi ge

Expressions in the linked program.

68Notation cexpr ≔ language.exprnanofil_langregistry ge

The represented errno cell is fixed in this thread.

71Context eb eo : Z
71Context er : region
71Context cell : world → ptr
71Context rep : mem → world → Prop
71Context Herrno : registryTAtom"__errno_location" = Someerrno_location_contractworld cell rep
71Context Hlinked : hello_linkedge
71Context Hcell : ∀m w h, wim w h → cellw = mkPtreb + eo Objeb
71Context Hrep : ∀m w h, wim w h → repm w ∧ errno_cellm cellw

The errno pointer used in the IR.

78Let ep ≔

Errno lookup exports the represented cell without changing any pieces. Local rule for promotion to a libc logic module.

82Lemma wp_close_errno
∀ f e ls lab d rest j Φ
▷WPERunmkFramef putd WPtrep e ls None Execlab rest j : cexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd P GlobalTAtom"__errno_location" [ ] :: rest j : cexpr {Φ}
Proof 30 steps Qed
iIntros HK
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ errno_location_contractworld cell rep [ ] True%I with [] [HK]
–apply linked_outside ; exact Hlinked | reflexivity
–apply linked_unbound ; exact Hlinked | reflexivity
–reflexivity
–exact Herrno
–reflexivity
–split ; right ; eexists ; reflexivity | reflexivity
–iIntros σ Hσ _
iDestruct Hσ as h [_ %Hσ]
iPureIntro
split ; reflexivity |
apply Hrep with h
exact proj2proj2proj2Hσ
–done
–iNext
iIntros σ tr vs s′ m′ w′ Hi Hσ _
destruct M.E.errno_location_invocation_ _ _ _ _ _ _ _ _ _ _ _ _ _ Hi as _ & _ & _ & _ & _ & → & → & → & He
injection He as →
iDestruct Hσ as h [Hh %Hσ]
pose proof Hcell_ _ _ proj2proj2proj2Hσ as Ec
iModIntro
iExists _
iSplit
+iSplitL Hh ; iExists h ; iFrame ; done |
iExact HK

A four-byte load from owned memory. Local rule for promotion to MemLogic.v; it needs neither a world fact nor eight-byte ownership.

113Lemma wp_close_load_w
∀ f e ls lab d v rest j b reg o xs Φ
value_xge e A v = SomeWPtrmkPtrb + o Objb
0 ≤ b + o < 2 ^ 64
lengthxs = 4%nat
liveb reg −∗ bytesb o xs −∗ ▷liveb reg −∗ bytesb o xs −∗ WPERunmkFramef putd WIntclose_wxs e ls None Execlab rest j : cexpr {Φ} −∗ WPERunmkFramef e ls None Execlab Letd W RawLoadLdNarrowSw 0 v :: rest j : cexpr {Φ}
Proof 36 steps Qed
intros Hv Ha Hlen
iIntros Hl Hx HK
iApply wp_read_ _ _ PLiveb, VLivereg :: byte_psb o xs _ _ [ ] with [Hl Hx] [HK]
–intros m fuel Hag & _
destruct Hag as Hl Hx
cbn [ agree_piece fst snd ] in Hl
destruct xs as | a | c | dd | z | u xs ; try discriminate Hlen
pose proof byte_ps_agree_ _ _ _ _ 0%nat a Hl Hx eq_refl as E0 & H0 & _
pose proof byte_ps_agree_ _ _ _ _ 1%nat c Hl Hx eq_refl as E1 & _
pose proof byte_ps_agree_ _ _ _ _ 2%nat dd Hl Hx eq_refl as E2 & _
pose proof byte_ps_agree_ _ _ _ _ 3%nat z Hl Hx eq_refl as E3 & _ & H3
apply rule_let with classes := A xs := WPtrmkPtrb + o Objb w := WIntclose_wa; c; dd; z ; reflexivity | reflexivity | cbn [ map2_option ] ; rewrite Hv ; reflexivity |
assert Er : raw_addressb + o 0 = b + o by unfold raw_address ; rewrite Z.add_0_r ; apply Z.mod_small ; exact Ha
assert Ea : access_resm b + o Objb 4 Read 1 = Someok
{apply access_obj_ _ reg ; exact proj1Hl | lia | cbn in H3 ; lia | apply Z.mod_1_r
rewrite Er
rewrite Ea
change SomeOpResRValWIntextensionSw load_bytesm b + o 4 mod 2 ^ 32 m = SomeOpResRValWIntclose_wa; c; dd; z m
change SomeOpResRValWIntextensionSw m_bytesm b + o + 3 × 256 + m_bytesm b + o + 2 × 256 + m_bytesm b + o + 1 × 256 + m_bytesm b + o + 0 mod 2 ^ 32 m = SomeOpResRValWIntclose_wa; c; dd; z m
replace b + o + 0 with b + o + 0 by lia
replace b + o + 1 with b + o + 1 by lia
replace b + o + 2 with b + o + 2 by lia
replace b + o + 3 with b + o + 3 by lia
cbn [ Z.of_nat ] in E0 , E1 , E2 , E3
rewrite E0 E1 E2 E3
reflexivity
–rewrite / live / bytes / pts big_sepL_cons big_sepL_nil
iDestruct Hl as [$ _]
iExact Hx
–iNext
iIntros H
iDestruct pts_appPLiveb, VLivereg byte_psb o xs with H as [Hl Hx]
iApply HK with Hl Hx

An invocation frame, promoted locally to an Iris call rule. The pure endpoint premise describes the whole authoritative heap after the call, including updates to pieces the caller handed over. Local bridge for promotion to Logic.v.

159Lemma wp_close_contract
∀ f e ls lab d k g args rest j spec xs ps after : listZ → listpiece × pval good : Z → listZ → Prop Φ
find_fnge g = None
registryg = Somespec
k = W ∨ k = L
map_optionarg_xge e args = Somexs
contract_abispec CResultd k args
∀m w h, wim w h → ∀l v, l, v ∈ ps → h !! l = Somev → contract_prespec xs m w
∀s m w h tr vs s′ m′ w′, agreesm h → live_disjointm → R.readys m → wim w h → ∀l v, l, v ∈ ps → h !! l = Somev → M.E.invokespec CResultd k args xs s m w tr CallReturnvs s′ m′ w′ → ∃n ys, vs = WIntn ∧ 0 ≤ n < 2 ^ if class_eqbk W then 32 else 64 ∧ goodn ys ∧ afterys.*1 = ps.*1 ∧ agreesm′ overwriteafterys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwriteafterys h
ptsps −∗ ▷∀n ys, ⌜goodn ys⌝ −∗ ptsafterys −∗ WPERunmkFramef putd WIntn e ls None Execlab rest j : cexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd k Globalg args :: rest j : cexpr {Φ}
Proof 25 steps Qed
intros Hfn Hg Hfree Hreg Hret Hk Hargs Habi Hpre Hpost
iIntros Hps HK
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ spec xs ptsps with Hps [HK] ; exact Hfn | exact Hg | exact Hfree | exact Hreg | exact Hargs | exact Habi | |
–iIntros σ Hσ Hps
iDestruct Hσ as h [Hh %Hσ]
iDestruct pts_lookup with Hh Hps as %Hl
iPureIntro
apply Hpre_ _ h proj2proj2proj2Hσ Hl
–iNext
iIntros σ tr vs s′ m′ w′ Hi Hσ Hps
iDestruct Hσ as h [Hh %Hσ]
destruct Hσ as Ha & Hd & Hr & Hw
iDestruct pts_lookup with Hh Hps as %Hl
destruct Hpost_ _ _ _ _ _ _ _ _ Ha Hd Hr Hw Hl Hi as n & ys & → & Hn & Hgood & Hkeys & Ha′ & Hd′ & Hr′ & Hw′
iMod pts_update with Hh Hps as [Hh Hps] ; exact Hkeys |
iModIntro
iExists _
iSplit
+iPureIntro
rewrite Hret
destruct Hk as → | → ; cbn [ external_outcome returned_env site_result word_at_class modulus ] ; rewrite Z.mod_small ; reflexivity | exact Hn | reflexivity | exact Hn
+iSplitL Hh ; iExists overwriteafterys h ; iFrame ; iPureIntro ; auto |
iApply HK $! n ys with [%] Hps
exact Hgood

Stream admission and consumption are represented by ghost pieces; fclose replaces their values with closed-state pieces of the same keys, rather than restoring usability of the stream.

202Context stream_ps closed_ps : ptr → listpiece × pval

Ownership of a usable stream's represented pieces.

204Let streamp : iPropΣ ≔

Query specs, including their exact ABI and pure frame obligations. The query preserves the original owned pieces and libc world.

208Context query_spec : name → contractworld
208Context Hquery_reg : ∀g k, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → registryg = Somequery_specg
208Context Hquery_ret : ∀g k, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_returnsquery_specg = RClassk
208Context Hquery_abi : ∀g k d v, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_abiquery_specg CResultd k ArgP v
208Context Hquery_pre : ∀g k p xs m w h, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → wim w h → ∀l v, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prequery_specg WPtrp m w
208Context Hquery_post : ∀g k d v p xs s m w h tr vs s′ m′ w′, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → agreesm h → live_disjointm → R.readys m → wim w h → ∀l v, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → M.E.invokequery_specg CResultd k ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n, vs = WIntn ∧ 0 ≤ n < 2 ^ if class_eqbk W then 32 else 64 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h

fclose's spec consumes usable stream pieces, returning closed pieces and arbitrary four-byte errno contents. Its frame premise includes readiness, separation and libc's world, not just the returned value.

230Context fclose_spec : contractworld
230Context Hfclose_reg : registryTAtom"fclose" = Somefclose_spec
230Context Hfclose_ret : contract_returnsfclose_spec = RClassW
230Context Hfclose_abi : ∀d v, contract_abifclose_spec CResultd W ArgP v
230Context Hfclose_pre : ∀p xs m w h, wim w h → ∀l v, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prefclose_spec WPtrp m w
230Context Hfclose_post : ∀d v p xs s m w h tr vs s′ m′ w′, agreesm h → live_disjointm → R.readys m → wim w h → ∀l v, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → M.E.invokefclose_spec CResultd W ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n ys, vs = WIntn ∧ 0 ≤ n < 2 ^ 32 ∧ lengthys = 4%nat ∧ closed_psp ++ byte_pseb eo ys.*1 = stream_psp ++ byte_pseb eo xs.*1 ∧ agreesm′ overwriteclosed_psp ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwriteclosed_psp ++ byte_pseb eo ys h

Derive the two query call-site triples from their raw contracts.

247Lemma Hquery
∀ g k f e ls lab d v rest j p xs Φ
g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W
arg_xge e ArgP v = SomeWPtrp
lengthxs = 4%nat
streamp −∗ byteseb eo xs −∗ ▷∀n, ⌜0 ≤ n < 2 ^ if class_eqbk W then 32 else 64⌝ −∗ streamp −∗ byteseb eo xs −∗ WPERunmkFramef putd WIntn e ls None Execlab rest j : cexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd k Globalg ArgP v :: rest j : cexpr {Φ}
Proof 31 steps Qed
intros Hwhich f e ls lab d v rest j p xs Φ Hv Hlen
iIntros Hs Hx HK
iApply wp_close_contract_ _ _ _ _ k g _ _ _ query_specg WPtrp stream_psp ++ byte_pseb eo xs λ_ ⇒ stream_psp ++ byte_pseb eo xs λn _ ⇒ 0 ≤ n < 2 ^ if class_eqbk W then 32 else 64 with [Hs Hx] [HK]
–destruct Hwhich as → → | → → ; apply linked_outside ; exact Hlinked | reflexivity | exact Hlinked | reflexivity
–destruct Hwhich as → → | → → ; apply linked_unbound ; exact Hlinked | reflexivity | exact Hlinked | reflexivity
–destruct Hwhich as → → | → → ; reflexivity
–apply Hquery_reg with k
exact Hwhich
–apply Hquery_ret
exact Hwhich
–destruct Hwhich as _ → | _ → ; auto
–cbn [ map_option ]
rewrite Hv
reflexivity
–apply Hquery_abi
exact Hwhich
–intros m w h Hw Hl
exact Hquery_pre_ _ _ _ _ _ _ Hwhich Hw Hl Hlen
–intros s m w h tr vs s′ m′ w′ Ha Hd Hr Hw Hl Hi
destruct Hquery_post_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Hwhich Ha Hd Hr Hw Hl Hi as n & Hvs & Hn & Ha′ & Hd′ & Hr′ & Hw′
exists n, xs
rewrite overwrite_id_ h Hl
repeat split ; try assumption ; try reflexivity ; tauto
–rewrite pts_app
iFrame
–iNext
iIntros n ys Hn H
rewrite pts_app
iDestruct H as [Hs Hx]
iApply HK $! n with [%] Hs Hx
exact Hn

Derive the consuming close call-site triple from its raw contract.

279Lemma Hfclose
∀ f e ls lab d v rest j p xs Φ
arg_xge e ArgP v = SomeWPtrp
lengthxs = 4%nat
streamp −∗ byteseb eo xs −∗ ▷∀n ys, ⌜0 ≤ n < 2 ^ 32 ∧ lengthys = 4%nat⌝ −∗ byteseb eo ys −∗ WPERunmkFramef putd WIntn e ls None Execlab rest j : cexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd W GlobalTAtom"fclose" ArgP v :: rest j : cexpr {Φ}
Proof 28 steps Qed
intros f e ls lab d v rest j p xs Φ Hv Hlen
iIntros Hs Hx HK
iApply wp_close_contract_ _ _ _ _ W TAtom"fclose" _ _ _ fclose_spec WPtrp stream_psp ++ byte_pseb eo xs λys ⇒ closed_psp ++ byte_pseb eo ys λn ys ⇒ 0 ≤ n < 2 ^ 32 ∧ lengthys = 4%nat with [Hs Hx] [HK]
–apply linked_outside ; exact Hlinked | reflexivity
–apply linked_unbound ; exact Hlinked | reflexivity
–reflexivity
–exact Hfclose_reg
–exact Hfclose_ret
–auto
–cbn [ map_option ]
rewrite Hv
reflexivity
–apply Hfclose_abi
–intros m w h Hw Hl
exact Hfclose_pre_ _ _ _ _ Hw Hl Hlen
–intros s m w h tr vs s′ m′ w′ Ha Hd Hr Hw Hl Hi
destruct Hfclose_post_ _ _ _ _ _ _ _ _ _ _ _ _ Ha Hd Hr Hw Hl Hi as n & ys & Hvs & Hn & Hys & Hkeys & Ha′ & Hd′ & Hr′ & Hw′
exists n, ys
cbn [ class_eqb ]
repeat split ; try assumption ; try reflexivity ; tauto
–rewrite pts_app
iFrame
–iNext
iIntros n ys Hn H
rewrite pts_app
iDestruct H as [_ Hx]
iApply HK $! n ys with [%] Hx
exact Hn

Storing zero into owned errno preserves libc's world interpretation.

310Context Kerrno : ∀xs m w h, ∀l v, l, v ∈ PLiveeb, VLiveer :: byte_pseb eo xs → h !! l = Somev → wim w h → wistore_bytesm eb + eo 4 0 w overwritePLiveeb, VLiveer :: byte_pseb eo le_bytes0 4 h

The errno cell is inside the represented address space.

316Context Heo : 0 ≤ eo
316Context Herange : 0 ≤ eb + eo < 2 ^ 64
316Context Heend : eb + eo + 4 ≤ r_ender
316Context He48 : r_ender ≤ 2 ^ 48

Find a stream-close block without unfolding the module in a proof.

320Ltac cs_enter s ≔
iApply wp_enter_ _ _ _ _ _ _ _ cs_blocks ; vm_compute ; reflexivity | word_premise | ; iNext ; cbn [ b_insts b_jump cs_block hblk ]

A pure instruction, with the environment kept abstract.

326Ltac close_let  ≔
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; word_premise | ; iNext ; gen_env

After the error decision, close_stream returns zero or EOF, clearing errno only when an earlier error accompanies a successful fclose.

332Lemma close_stream_L22
∀ e n t xs Φ
lookupTAtom"v14" e = SomeWIntn
lookupTAtom"v37" e = SomeWIntt
0 ≤ n < 2 ^ 32
t = 0 ∨ t = 1
lengthxs = 4%nat
liveeb er −∗ byteseb eo xs −∗ ▷∀r ys, ⌜r = 0 ∨ r = 4294967295 ∧ lengthys = 4%nat⌝ −∗ liveeb er −∗ byteseb eo ys −∗ ΦRetWIntr −∗ WPERunmkFrameclose_stream_fn e [ ] None ExecTAtom"L22" [ ] b_jumpcs_block"L22" : cexpr {Φ}
Proof 47 steps Qed
intros Hn Ht Hrange Ht01 Hlen
iIntros Hl Hx HΦ
destruct Ht01 as → | →
–iApply wp_branch_ _ _ _ _ _ _ _ _ _ 0 ; word_premise |
iNext
cs_enter "L19"
iApply wp_ret ; reflexivity | reflexivity |
iNext
iApply HΦ $! 0 xs with [%] Hl Hx
auto
–iApply wp_branch_ _ _ _ _ _ _ _ _ _ 1 ; word_premise |
iNext
cs_enter "L17"
destruct Z.eq_decn 0 as [ ->| Hnz ]
iApply wp_branch_ _ _ _ _ _ _ _ _ _ 1 ; word_premise |
iNext
cs_enter "L38"
iNext
iApply wp_check with Hl ; reflexivity | word_premise | reflexivity | unfold ep ; addr_premise | unfold ep ; addr_premise | unfold ep ; addr_premise |
iNext
iIntros Hl
iApply wp_raw_store_w with Hl Hx ; word_premise | word_premise | reflexivity | unfold ep ; addr_premise | exact Hlen | apply Kerrno |
iNext
iIntros Hl Hx
iApply wp_goto
iNext
cs_enter "L40"
iApply wp_ret ; reflexivity | reflexivity |
iNext
iApply HΦ $! 4294967295 le_bytes0 4 with [%] Hl Hx
split ; auto | apply length_le_bytes
iApply wp_branch_ _ _ _ _ _ _ _ _ _ 0 ; word_premise |
iNext
cs_enter "L40"
iApply wp_ret ; reflexivity | reflexivity |
iNext
iApply HΦ $! 4294967295 xs with [%] Hl Hx
auto

Hand the merged error flag to the shared return blocks.

364Ltac cs_finish n t Hn Hlen ≔
cs_enter "L22" ; gen_env ; iApply close_stream_L22_ n t with Hl Hx HΦ ; word_premise | word_premise | exact Hn | auto | exact Hlen

close_stream consumes a usable stream and returns zero or EOF. It returns ownership of errno, whose contents may have changed. Sticky error, pending data, fclose failure and EBADF take distinct paths.

372Lemma close_stream_spec
∀ p xs Φ
lengthxs = 4%nat
streamp −∗ liveeb er −∗ byteseb eo xs −∗ ▷∀r ys, ⌜r = 0 ∨ r = 4294967295 ∧ lengthys = 4%nat⌝ −∗ liveeb er −∗ byteseb eo ys −∗ ΦRetWIntr −∗ WPERuninvocationclose_stream_fn WPtrp : cexpr {Φ}
Proof 63 steps Qed
intros Hlen
iIntros Hs Hl Hx HΦ
cs_enter "start"
iApply HqueryTAtom"__fpending" L with Hs Hx ; left ; auto | word_premise | exact Hlen |
iNext
iIntros pending Hpending Hs Hx
cbn [ class_eqb ] in Hpending
iApply HqueryTAtom"ferror" W with Hs Hx ; right ; auto | word_premise | exact Hlen |
iNext
iIntros err Herr Hs Hx
cbn [ class_eqb ] in Herr
iApply Hfclose with Hs Hx ; word_premise | exact Hlen |
iNext
iIntros n ys Hn Hys Hx
destruct Z.eq_decerr 0 as Herr0 | Herr0
–iApply wp_branch_ _ _ _ _ _ _ _ _ _ 0 ; word_premise |
iNext
cs_enter "L21"
destruct Z.eq_decn 0 as Hn0 | Hn0
+iApply wp_branch_ _ _ _ _ _ _ _ _ _ 0 ; word_premise |
iNext
cs_finish n 0 Hn Hys
+iApply wp_branch_ _ _ _ _ _ _ _ _ _ 1 ; word_premise |
iNext
cs_enter "L24"
destruct Z.eq_decpending 0 as Hp0 | Hp0
∗iApply wp_branch_ _ _ _ _ _ _ _ _ _ 0 ; word_premise |
iNext
cs_enter "L27"
iNext
iApply wp_check with Hl ; reflexivity | word_premise | reflexivity | unfold ep ; addr_premise | unfold ep ; addr_premise | unfold ep ; addr_premise |
iNext
iIntros Hl
iApply wp_close_load_w with Hl Hx ; word_premise | exact Herange | exact Hys |
iNext
iIntros Hl Hx
pose proof close_w_rangeys as Hwr
destruct Z.eq_decclose_wys 9 as Hw9 | Hw9 ; close_let ; iApply wp_goto ; iNext
--cs_finish n 0 Hn Hys
--cs_finish n 1 Hn Hys
∗iApply wp_branch_ _ _ _ _ _ _ _ _ _ 1 ; word_premise |
iNext
cs_finish n 1 Hn Hys
–iApply wp_branch_ _ _ _ _ _ _ _ _ _ 1 ; word_premise |
iNext
cs_finish n 1 Hn Hys

Hello's read-only unnamed-file diagnostic strings.

415Let fmt ≔
mkPtr65744 Ro65744

The write-error text.

417Let text ≔
mkPtr65680 Ro65680

The caller hands the diagnostic's represented string pieces to error; they return unchanged while errno may change.

421Context diag_ps : listpiece × pval
421Context error_spec : contractworld
421Context Herror_reg : registryTAtom"error" = Someerror_spec
421Context Herror_ret : contract_returnserror_spec = RVoid
421Context Herror_abi : ∀v fmtv txtv, contract_abierror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv
421Context Herror_pre : ∀n xs m w h, 0 ≤ n < 2 ^ 32 → lengthxs = 4%nat → agreesm h → wim w h → ∀l v, l, v ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev → contract_preerror_spec WInt0; WIntn; WPtrfmt; WPtrtext m w
421Context Herror_post : ∀v fmtv txtv n xs s m w h tr vs s′ m′ w′, lengthxs = 4%nat → agreesm h → live_disjointm → R.readys m → wim w h → ∀l v, l, v ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev → M.E.invokeerror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv WInt0; WIntn; WPtrfmt; WPtrtext s m w tr CallReturnvs s′ m′ w′ → ∃ys, vs = [ ] ∧ lengthys = 4%nat ∧ diag_ps ++ byte_pseb eo ys.*1 = diag_ps ++ byte_pseb eo xs.*1 ∧ agreesm′ overwritediag_ps ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritediag_ps ++ byte_pseb eo ys h

error with zero status returns void; it never substitutes an exit for the following _exit. Resource terminals need no continuation.

442Lemma wp_close_error
∀ f e ls lab v fmtv txtv rest j n xs Φ
arg_xge e ArgW v = SomeWIntn
arg_xge e ArgP fmtv = SomeWPtrfmt
arg_xge e ArgP txtv = SomeWPtrtext
0 ≤ n < 2 ^ 32
lengthxs = 4%nat
ptsdiag_ps −∗ byteseb eo xs −∗ ▷∀ys, ⌜lengthys = 4%nat⌝ −∗ ptsdiag_ps −∗ byteseb eo ys −∗ WPERunmkFramef e ls None Execlab rest j : cexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCVoid GlobalTAtom"error" ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv :: rest j : cexpr {Φ}
Proof 37 steps Qed
intros Hv Hfmt Htext Hn Hlen
iIntros Hd Hx HK
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ error_spec WInt0; WIntn; WPtrfmt; WPtrtext ptsdiag_ps ++ byte_pseb eo xs with [Hd Hx] [HK]
–apply linked_outside ; exact Hlinked | reflexivity
–apply linked_unbound ; exact Hlinked | reflexivity
–reflexivity
–exact Herror_reg
–cbn [ map_option ]
rewrite Hv Hfmt Htext
reflexivity
–apply Herror_abi
–iIntros σ Hσ Hps
iDestruct Hσ as h [Hh %Hσ]
iDestruct pts_lookup with Hh Hps as %Hl
iPureIntro
apply Herror_pre_ _ _ _ _ Hn Hlen proj1Hσ proj2proj2proj2Hσ Hl
–rewrite pts_app
iFrame
–iNext
iIntros σ tr vs s′ m′ w′ Hi Hσ Hps
iDestruct Hσ as h [Hh %Hσ]
destruct Hσ as Ha & Hd & Hr & Hw
iDestruct pts_lookup with Hh Hps as %Hl
destruct Herror_post_ _ _ _ _ _ _ _ _ _ _ _ _ _ Hlen Ha Hd Hr Hw Hl Hi as ys & → & Hys & Hkeys & Ha′ & Hd′ & Hr′ & Hw′
iMod pts_update with Hh Hps as [Hh Hps] ; exact Hkeys |
iModIntro
iExists e
iSplit
+iPureIntro
rewrite Herror_ret
reflexivity
+iSplitL Hh ; iExists overwritediag_ps ++ byte_pseb eo ys h ; iFrame ; iPureIntro ; auto |
rewrite pts_app
iDestruct Hps as [Hd Hx]
iApply HK $! ys with [%] Hd Hx
exact Hys

_exit's raw contract admits a canonical status and has no ordinary return endpoint. Its actual process-exit semantics belong to Ending.

479Context exit_spec : contractworld
479Context Hexit_reg : registryTAtom"_exit" = Someexit_spec
479Context Hexit_ret : contract_returnsexit_spec = RVoid
479Context Hexit_abi : ∀v, contract_abiexit_spec CVoid ArgW v
479Context Hexit_pre : ∀n m w h, 0 ≤ n < 2 ^ 32 → wim w h → contract_preexit_spec WIntn m w
479Context Hexit_post : ∀args n s m w tr vs s′ m′ w′, M.E.invokeexit_spec CVoid args WIntn s m w tr CallReturnvs s′ m′ w′ → False

An admissible _exit call is safe under every postcondition.

488Lemma wp_close_exit
∀ f e ls lab v rest j n Φ
arg_xge e ArgW v = SomeWIntn
0 ≤ n < 2 ^ 32
⊢ WPERunmkFramef e ls None Execlab CallCVoid GlobalTAtom"_exit" ArgW v :: rest j : cexpr {Φ}
Proof 19 steps Qed
intros Hv Hn
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ exit_spec WIntn True%I with [] []
–apply linked_outside ; exact Hlinked | reflexivity
–apply linked_unbound ; exact Hlinked | reflexivity
–reflexivity
–exact Hexit_reg
–cbn [ map_option ]
rewrite Hv
reflexivity
–apply Hexit_abi
–iIntros σ Hσ _
iDestruct Hσ as h [_ %Hσ]
iPureIntro
exact Hexit_pre_ _ _ _ Hn proj2proj2proj2Hσ
–done
–iNext
iIntros σ tr vs s′ m′ w′ Hi _ _
exfalso
exact Hexit_post_ _ _ _ _ _ _ _ _ _ Hi

Load a stream pointer while borrowing its life from the stream's represented pieces, without duplicating that linear life token.

509Lemma wp_close_stream_pointer
∀ f e ls lab d v rest j b reg p Φ
∃pb pr ps, ptr_capp = Objpb ∧ stream_psp = PLivepb, VLivepr :: ps
value_xge e A v = SomeWPtrmkPtrb Objb
0 ≤ b < 2 ^ 64
b mod 8 = 0
0 ≤ ptr_addrp < 2 ^ 64
liveb reg −∗ pcellb 0 p −∗ streamp −∗ ▷liveb reg −∗ pcellb 0 p −∗ streamp −∗ WPERunmkFramef putd WPtrp e ls None Execlab rest j : cexpr {Φ} −∗ WPERunmkFramef e ls None Execlab Letd P RawLoadPointer0 AuxRead; LowerResolve; AddressRead v :: rest j : cexpr {Φ}
Proof 26 steps Qed
intros pb & pr & ps & Hcap & Hps Hv Hb Hb8 Hp
iIntros Hl Hc Hs HK
iAssert livepb pr ∗ ptsps%I with [Hs] as [Hpl Hrest]
{rewrite / stream Hps / live / pts big_sepL_cons big_sepL_singleton
iExact Hs
iApply wp_raw_load_pointer_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ pr with Hl Hc [Hpl] [HK Hrest]
–reflexivity
–cbn [ map2_option ]
rewrite Hv
reflexivity
–reflexivity
–unfold raw_address
cbn [ ptr_addr ]
rewrite Z.add_0_r Z.mod_small ; lia | exact Hb
–rewrite Z.add_0_r
exact Hb8
–exact Hp
–rewrite / live_cap Hcap
iExact Hpl
–iNext
iIntros Hl Hc Hpl
rewrite / live_cap Hcap
iApply HK with Hl Hc [Hpl Hrest]
rewrite / stream Hps / live / pts ! big_sepL_cons big_sepL_nil
iFrame
iDestruct Hpl as [$ _]

The null file-name pointer is eight owned zero bytes and a null aux slot. This is a module invariant, not a fact about libc's world.

538Lemma close_file_name
bytes65584 0 replicate8 0 ∗ auxes65584 0 CNone ⊣⊢ pcell65584 0 mkPtr0 CNone
Explore proof 3 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
eb, eo :
Z
er :
cell :
world → ptr
rep :
mem → world → Prop
Herrno :
registryTAtom"__errno_location" = Someerrno_location_contractworld cell rep
Hlinked :
Hcell :
∀m : mem w : world h : gmappiece pval, wim w h → cellw = ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb
Hrep :
∀m : mem w : world h : gmappiece pval, wim w h → repm w ∧ errno_cellm cellw
ep :=
ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb : ptr
stream_ps, closed_ps :
ptr → listpiece × pval
stream :=
λp : ptr ⇒ ptsstream_psp : ptr → iPropΣ
query_spec :
name → contractworld
Hquery_reg :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → registryg = Somequery_specg
Hquery_ret :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_returnsquery_specg = RClassk
Hquery_abi :
∀g : term k : class d : name v : value, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_abiquery_specg CResultd k ArgP v
Hquery_pre :
∀g : term k : class p : ptr xs : listZ m : mem w : world h : gmappiece pval, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prequery_specg WPtrp m w
Hquery_post :
∀g : term k : class d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokequery_specg CResultd k ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z, vs = WIntn ∧ 0 ≤ n < 2 ^ if class_eqbk W then 32 else 64 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
fclose_spec :
Hfclose_reg :
registryTAtom"fclose" = Somefclose_spec
Hfclose_ret :
Hfclose_abi :
∀d : name v : value, contract_abifclose_spec CResultd W ArgP v
Hfclose_pre :
∀p : ptr xs : listZ m : mem w : world h : gmappiece pval, wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prefclose_spec WPtrp m w
Hfclose_post :
∀d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokefclose_spec CResultd W ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z ys : listZ, vs = WIntn ∧ 0 ≤ n < 2 ^ 32 ∧ lengthys = 4%nat ∧ closed_psp ++ byte_pseb eo ys.*1 = stream_psp ++ byte_pseb eo xs.*1 ∧ agreesm′ overwriteclosed_psp ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwriteclosed_psp ++ byte_pseb eo ys h
Kerrno :
∀xs : listZ m : mem w : world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveeb, VLiveer :: byte_pseb eo xs → h !! l = Somev → wim w h → wistore_bytesm eb + eo 4 0 w overwritePLiveeb, VLiveer :: byte_pseb eo le_bytes0 4 h
Heo :
0 ≤ eo
Herange :
0 ≤ eb + eo < 2 ^ 64
Heend :
eb + eo + 4 ≤ r_ender
He48 :
r_ender ≤ 2 ^ 48
fmt :=
ptr_addr ≔ 65744; ptr_cap ≔ Ro65744 : ptr
text :=
ptr_addr ≔ 65680; ptr_cap ≔ Ro65680 : ptr
diag_ps :
listpiece × pval
error_spec :
Herror_reg :
registryTAtom"error" = Someerror_spec
Herror_ret :
contract_returnserror_spec = RVoid
Herror_abi :
∀v fmtv txtv : value, contract_abierror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv
Herror_pre :
∀n : Z xs : listZ m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → lengthxs = 4%nat → agreesm h → wim w h → ∀l : piece v : pval, l, v ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev → contract_preerror_spec WInt0; WIntn; WPtrfmt; WPtrtext m w
Herror_post :
∀v fmtv txtv : value n : Z xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, lengthxs = 4%nat → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokeerror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv WInt0; WIntn; WPtrfmt; WPtrtext s m w tr CallReturnvs s′ m′ w′ → ∃ys : listZ, vs = [ ] ∧ lengthys = 4%nat ∧ diag_ps ++ byte_pseb eo ys.*1 = diag_ps ++ byte_pseb eo xs.*1 ∧ agreesm′ overwritediag_ps ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritediag_ps ++ byte_pseb eo ys h
exit_spec :
Hexit_reg :
registryTAtom"_exit" = Someexit_spec
Hexit_ret :
Hexit_abi :
∀v : value, contract_abiexit_spec CVoid ArgW v
Hexit_pre :
∀n : Z m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → wim w h → contract_preexit_spec WIntn m w
Hexit_post :
∀args : listarg n : Z s : R.state m : mem w : world tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, M.E.invokeexit_spec CVoid args WIntn s m w tr CallReturnvs s′ m′ w′ → False
⊢
bytes65584 0 replicate8 0 ∗ auxes65584 0 CNone ⊣⊢ pcell65584 0 ptr_addr ≔ 0; ptr_cap ≔ CNone

change ptsHeap.cell65584 0 0 ∗ ptsPAux65584 0, VAuxCNone ⊣⊢ ptsPAux65584 0, VAuxCNone ++ Heap.cell65584 0 0

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
eb, eo :
Z
er :
cell :
world → ptr
rep :
mem → world → Prop
Herrno :
registryTAtom"__errno_location" = Someerrno_location_contractworld cell rep
Hlinked :
Hcell :
∀m : mem w : world h : gmappiece pval, wim w h → cellw = ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb
Hrep :
∀m : mem w : world h : gmappiece pval, wim w h → repm w ∧ errno_cellm cellw
ep :=
ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb : ptr
stream_ps, closed_ps :
ptr → listpiece × pval
stream :=
λp : ptr ⇒ ptsstream_psp : ptr → iPropΣ
query_spec :
name → contractworld
Hquery_reg :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → registryg = Somequery_specg
Hquery_ret :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_returnsquery_specg = RClassk
Hquery_abi :
∀g : term k : class d : name v : value, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_abiquery_specg CResultd k ArgP v
Hquery_pre :
∀g : term k : class p : ptr xs : listZ m : mem w : world h : gmappiece pval, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prequery_specg WPtrp m w
Hquery_post :
∀g : term k : class d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokequery_specg CResultd k ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z, vs = WIntn ∧ 0 ≤ n < 2 ^ if class_eqbk W then 32 else 64 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
fclose_spec :
Hfclose_reg :
registryTAtom"fclose" = Somefclose_spec
Hfclose_ret :
Hfclose_abi :
∀d : name v : value, contract_abifclose_spec CResultd W ArgP v
Hfclose_pre :
∀p : ptr xs : listZ m : mem w : world h : gmappiece pval, wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prefclose_spec WPtrp m w
Hfclose_post :
∀d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokefclose_spec CResultd W ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z ys : listZ, vs = WIntn ∧ 0 ≤ n < 2 ^ 32 ∧ lengthys = 4%nat ∧ closed_psp ++ byte_pseb eo ys.*1 = stream_psp ++ byte_pseb eo xs.*1 ∧ agreesm′ overwriteclosed_psp ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwriteclosed_psp ++ byte_pseb eo ys h
Kerrno :
∀xs : listZ m : mem w : world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveeb, VLiveer :: byte_pseb eo xs → h !! l = Somev → wim w h → wistore_bytesm eb + eo 4 0 w overwritePLiveeb, VLiveer :: byte_pseb eo le_bytes0 4 h
Heo :
0 ≤ eo
Herange :
0 ≤ eb + eo < 2 ^ 64
Heend :
eb + eo + 4 ≤ r_ender
He48 :
r_ender ≤ 2 ^ 48
fmt :=
ptr_addr ≔ 65744; ptr_cap ≔ Ro65744 : ptr
text :=
ptr_addr ≔ 65680; ptr_cap ≔ Ro65680 : ptr
diag_ps :
listpiece × pval
error_spec :
Herror_reg :
registryTAtom"error" = Someerror_spec
Herror_ret :
contract_returnserror_spec = RVoid
Herror_abi :
∀v fmtv txtv : value, contract_abierror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv
Herror_pre :
∀n : Z xs : listZ m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → lengthxs = 4%nat → agreesm h → wim w h → ∀l : piece v : pval, l, v ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev → contract_preerror_spec WInt0; WIntn; WPtrfmt; WPtrtext m w
Herror_post :
∀v fmtv txtv : value n : Z xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, lengthxs = 4%nat → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokeerror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv WInt0; WIntn; WPtrfmt; WPtrtext s m w tr CallReturnvs s′ m′ w′ → ∃ys : listZ, vs = [ ] ∧ lengthys = 4%nat ∧ diag_ps ++ byte_pseb eo ys.*1 = diag_ps ++ byte_pseb eo xs.*1 ∧ agreesm′ overwritediag_ps ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritediag_ps ++ byte_pseb eo ys h
exit_spec :
Hexit_reg :
registryTAtom"_exit" = Someexit_spec
Hexit_ret :
Hexit_abi :
∀v : value, contract_abiexit_spec CVoid ArgW v
Hexit_pre :
∀n : Z m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → wim w h → contract_preexit_spec WIntn m w
Hexit_post :
∀args : listarg n : Z s : R.state m : mem w : world tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, M.E.invokeexit_spec CVoid args WIntn s m w tr CallReturnvs s′ m′ w′ → False
⊢
ptsHeap.cell65584 0 0 ∗ ptsPAux65584 0, VAuxCNone ⊣⊢ ptsPAux65584 0, VAuxCNone ++ Heap.cell65584 0 0

rewrite pts_app

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
eb, eo :
Z
er :
cell :
world → ptr
rep :
mem → world → Prop
Herrno :
registryTAtom"__errno_location" = Someerrno_location_contractworld cell rep
Hlinked :
Hcell :
∀m : mem w : world h : gmappiece pval, wim w h → cellw = ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb
Hrep :
∀m : mem w : world h : gmappiece pval, wim w h → repm w ∧ errno_cellm cellw
ep :=
ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb : ptr
stream_ps, closed_ps :
ptr → listpiece × pval
stream :=
λp : ptr ⇒ ptsstream_psp : ptr → iPropΣ
query_spec :
name → contractworld
Hquery_reg :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → registryg = Somequery_specg
Hquery_ret :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_returnsquery_specg = RClassk
Hquery_abi :
∀g : term k : class d : name v : value, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_abiquery_specg CResultd k ArgP v
Hquery_pre :
∀g : term k : class p : ptr xs : listZ m : mem w : world h : gmappiece pval, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prequery_specg WPtrp m w
Hquery_post :
∀g : term k : class d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokequery_specg CResultd k ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z, vs = WIntn ∧ 0 ≤ n < 2 ^ if class_eqbk W then 32 else 64 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
fclose_spec :
Hfclose_reg :
registryTAtom"fclose" = Somefclose_spec
Hfclose_ret :
Hfclose_abi :
∀d : name v : value, contract_abifclose_spec CResultd W ArgP v
Hfclose_pre :
∀p : ptr xs : listZ m : mem w : world h : gmappiece pval, wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prefclose_spec WPtrp m w
Hfclose_post :
∀d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokefclose_spec CResultd W ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z ys : listZ, vs = WIntn ∧ 0 ≤ n < 2 ^ 32 ∧ lengthys = 4%nat ∧ closed_psp ++ byte_pseb eo ys.*1 = stream_psp ++ byte_pseb eo xs.*1 ∧ agreesm′ overwriteclosed_psp ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwriteclosed_psp ++ byte_pseb eo ys h
Kerrno :
∀xs : listZ m : mem w : world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveeb, VLiveer :: byte_pseb eo xs → h !! l = Somev → wim w h → wistore_bytesm eb + eo 4 0 w overwritePLiveeb, VLiveer :: byte_pseb eo le_bytes0 4 h
Heo :
0 ≤ eo
Herange :
0 ≤ eb + eo < 2 ^ 64
Heend :
eb + eo + 4 ≤ r_ender
He48 :
r_ender ≤ 2 ^ 48
fmt :=
ptr_addr ≔ 65744; ptr_cap ≔ Ro65744 : ptr
text :=
ptr_addr ≔ 65680; ptr_cap ≔ Ro65680 : ptr
diag_ps :
listpiece × pval
error_spec :
Herror_reg :
registryTAtom"error" = Someerror_spec
Herror_ret :
contract_returnserror_spec = RVoid
Herror_abi :
∀v fmtv txtv : value, contract_abierror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv
Herror_pre :
∀n : Z xs : listZ m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → lengthxs = 4%nat → agreesm h → wim w h → ∀l : piece v : pval, l, v ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev → contract_preerror_spec WInt0; WIntn; WPtrfmt; WPtrtext m w
Herror_post :
∀v fmtv txtv : value n : Z xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, lengthxs = 4%nat → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokeerror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv WInt0; WIntn; WPtrfmt; WPtrtext s m w tr CallReturnvs s′ m′ w′ → ∃ys : listZ, vs = [ ] ∧ lengthys = 4%nat ∧ diag_ps ++ byte_pseb eo ys.*1 = diag_ps ++ byte_pseb eo xs.*1 ∧ agreesm′ overwritediag_ps ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritediag_ps ++ byte_pseb eo ys h
exit_spec :
Hexit_reg :
registryTAtom"_exit" = Someexit_spec
Hexit_ret :
Hexit_abi :
∀v : value, contract_abiexit_spec CVoid ArgW v
Hexit_pre :
∀n : Z m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → wim w h → contract_preexit_spec WIntn m w
Hexit_post :
∀args : listarg n : Z s : R.state m : mem w : world tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, M.E.invokeexit_spec CVoid args WIntn s m w tr CallReturnvs s′ m′ w′ → False
⊢
ptsHeap.cell65584 0 0 ∗ ptsPAux65584 0, VAuxCNone ⊣⊢ ptsPAux65584 0, VAuxCNone ∗ ptsHeap.cell65584 0 0

apply bi.sep_comm

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
change ptsHeap.cell65584 0 0 ∗ ptsPAux65584 0, VAuxCNone ⊣⊢ ptsPAux65584 0, VAuxCNone ++ Heap.cell65584 0 0
rewrite pts_app
apply bi.sep_comm

The concrete module cells; libc supplies only stdout and stderr's pointer-cell locations. All these pieces are handed back on return.

548Context ob sb : Z
548Context oreg sreg freg ireg xreg : region
548Context outp errp : ptr
548Context Hout_live : ∃b reg ps, ptr_capoutp = Objb ∧ stream_psoutp = PLiveb, VLivereg :: ps
548Context Herr_live : ∃b reg ps, ptr_caperrp = Objb ∧ stream_pserrp = PLiveb, VLivereg :: ps
548Context Hstdout : lookupTAtom"stdout" ge_globalsge = SomemkPtrob Objob
548Context Hstderr : lookupTAtom"stderr" ge_globalsge = SomemkPtrsb Objsb
548Context Hob : 0 ≤ ob < 2 ^ 64
548Context Hob8 : ob mod 8 = 0
548Context Hoend : ob + 8 ≤ r_endoreg
548Context Hsb : 0 ≤ sb < 2 ^ 64
548Context Hsb8 : sb mod 8 = 0
548Context Hsend : sb + 8 ≤ r_endsreg
548Context Hout : 0 ≤ ptr_addroutp < 2 ^ 64
548Context Herrp : 0 ≤ ptr_addrerrp < 2 ^ 64
548Context Hfend : 65584 + 8 ≤ r_endfreg
548Context Hiend : 65616 + 1 ≤ r_endireg
548Context Hxend : 65776 + 4 ≤ r_endxreg

Closeout's owned module memory and the imported pointer cells.

560Definition close_cellsfs : listZ : iPropΣ ≔
liveob oreg ∗ pcellob 0 outp ∗ livesb sreg ∗ pcellsb 0 errp ∗ live65584 freg ∗ bytes65584 0 replicate8 0 ∗ auxes65584 0 CNone ∗ live65616 ireg ∗ ibyte65616 0 0 ∗ live65776 xreg ∗ bytes65776 0 fs

The module's symbols put closeout's statics and literals there.

566Lemma close_lookups
lookupTAtom"closeout#file_name" ge_globalsge = SomemkPtr65584 Obj65584 ∧ lookupTAtom"closeout#ignore_EPIPE" ge_globalsge = SomemkPtr65616 Obj65616 ∧ lookupTAtom"exit_failure" ge_globalsge = SomemkPtr65776 Obj65776 ∧ lookupTAtom"closeout#str.55" ge_globalsge = Somefmt ∧ lookupTAtom"closeout#str.53" ge_globalsge = Sometext ∧ ∃p, lookupTAtom"closeout#str.52" ge_globalsge = Somep
Explore proof 6 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
eb, eo :
Z
er :
cell :
world → ptr
rep :
mem → world → Prop
Herrno :
registryTAtom"__errno_location" = Someerrno_location_contractworld cell rep
Hlinked :
Hcell :
∀m : mem w : world h : gmappiece pval, wim w h → cellw = ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb
Hrep :
∀m : mem w : world h : gmappiece pval, wim w h → repm w ∧ errno_cellm cellw
ep :=
ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb : ptr
stream_ps, closed_ps :
ptr → listpiece × pval
stream :=
λp : ptr ⇒ ptsstream_psp : ptr → iPropΣ
query_spec :
name → contractworld
Hquery_reg :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → registryg = Somequery_specg
Hquery_ret :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_returnsquery_specg = RClassk
Hquery_abi :
∀g : term k : class d : name v : value, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_abiquery_specg CResultd k ArgP v
Hquery_pre :
∀g : term k : class p : ptr xs : listZ m : mem w : world h : gmappiece pval, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prequery_specg WPtrp m w
Hquery_post :
∀g : term k : class d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokequery_specg CResultd k ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z, vs = WIntn ∧ 0 ≤ n < 2 ^ if class_eqbk W then 32 else 64 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
fclose_spec :
Hfclose_reg :
registryTAtom"fclose" = Somefclose_spec
Hfclose_ret :
Hfclose_abi :
∀d : name v : value, contract_abifclose_spec CResultd W ArgP v
Hfclose_pre :
∀p : ptr xs : listZ m : mem w : world h : gmappiece pval, wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prefclose_spec WPtrp m w
Hfclose_post :
∀d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokefclose_spec CResultd W ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z ys : listZ, vs = WIntn ∧ 0 ≤ n < 2 ^ 32 ∧ lengthys = 4%nat ∧ closed_psp ++ byte_pseb eo ys.*1 = stream_psp ++ byte_pseb eo xs.*1 ∧ agreesm′ overwriteclosed_psp ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwriteclosed_psp ++ byte_pseb eo ys h
Kerrno :
∀xs : listZ m : mem w : world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveeb, VLiveer :: byte_pseb eo xs → h !! l = Somev → wim w h → wistore_bytesm eb + eo 4 0 w overwritePLiveeb, VLiveer :: byte_pseb eo le_bytes0 4 h
Heo :
0 ≤ eo
Herange :
0 ≤ eb + eo < 2 ^ 64
Heend :
eb + eo + 4 ≤ r_ender
He48 :
r_ender ≤ 2 ^ 48
fmt :=
ptr_addr ≔ 65744; ptr_cap ≔ Ro65744 : ptr
text :=
ptr_addr ≔ 65680; ptr_cap ≔ Ro65680 : ptr
diag_ps :
listpiece × pval
error_spec :
Herror_reg :
registryTAtom"error" = Someerror_spec
Herror_ret :
contract_returnserror_spec = RVoid
Herror_abi :
∀v fmtv txtv : value, contract_abierror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv
Herror_pre :
∀n : Z xs : listZ m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → lengthxs = 4%nat → agreesm h → wim w h → ∀l : piece v : pval, l, v ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev → contract_preerror_spec WInt0; WIntn; WPtrfmt; WPtrtext m w
Herror_post :
∀v fmtv txtv : value n : Z xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, lengthxs = 4%nat → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokeerror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv WInt0; WIntn; WPtrfmt; WPtrtext s m w tr CallReturnvs s′ m′ w′ → ∃ys : listZ, vs = [ ] ∧ lengthys = 4%nat ∧ diag_ps ++ byte_pseb eo ys.*1 = diag_ps ++ byte_pseb eo xs.*1 ∧ agreesm′ overwritediag_ps ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritediag_ps ++ byte_pseb eo ys h
exit_spec :
Hexit_reg :
registryTAtom"_exit" = Someexit_spec
Hexit_ret :
Hexit_abi :
∀v : value, contract_abiexit_spec CVoid ArgW v
Hexit_pre :
∀n : Z m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → wim w h → contract_preexit_spec WIntn m w
Hexit_post :
∀args : listarg n : Z s : R.state m : mem w : world tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, M.E.invokeexit_spec CVoid args WIntn s m w tr CallReturnvs s′ m′ w′ → False
ob, sb :
Z
oreg, sreg, freg, ireg, xreg :
outp, errp :
Hout_live :
∃b : Z reg : region ps : listpiece × pval, ptr_capoutp = Objb ∧ stream_psoutp = PLiveb, VLivereg :: ps
Herr_live :
∃b : Z reg : region ps : listpiece × pval, ptr_caperrp = Objb ∧ stream_pserrp = PLiveb, VLivereg :: ps
Hstdout :
lookupTAtom"stdout" ge_globalsge = Someptr_addr ≔ ob; ptr_cap ≔ Objob
Hstderr :
lookupTAtom"stderr" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hob :
0 ≤ ob < 2 ^ 64
Hob8 :
ob mod 8 = 0
Hoend :
ob + 8 ≤ r_endoreg
Hsb :
0 ≤ sb < 2 ^ 64
Hsb8 :
sb mod 8 = 0
Hsend :
sb + 8 ≤ r_endsreg
Hout :
0 ≤ ptr_addroutp < 2 ^ 64
Herrp :
0 ≤ ptr_addrerrp < 2 ^ 64
Hfend :
65584 + 8 ≤ r_endfreg
Hiend :
65616 + 1 ≤ r_endireg
Hxend :
65776 + 4 ≤ r_endxreg
⊢
lookupTAtom"closeout#file_name" ge_globalsge = Someptr_addr ≔ 65584; ptr_cap ≔ Obj65584 ∧ lookupTAtom"closeout#ignore_EPIPE" ge_globalsge = Someptr_addr ≔ 65616; ptr_cap ≔ Obj65616 ∧ lookupTAtom"exit_failure" ge_globalsge = Someptr_addr ≔ 65776; ptr_cap ≔ Obj65776 ∧ lookupTAtom"closeout#str.55" ge_globalsge = Somefmt ∧ lookupTAtom"closeout#str.53" ge_globalsge = Sometext ∧ ∃p : ptr, lookupTAtom"closeout#str.52" ge_globalsge = Somep

destruct Hlinked as _ & Hg & _

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
eb, eo :
Z
er :
cell :
world → ptr
rep :
mem → world → Prop
Herrno :
registryTAtom"__errno_location" = Someerrno_location_contractworld cell rep
Hlinked :
Hcell :
∀m : mem w : world h : gmappiece pval, wim w h → cellw = ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb
Hrep :
∀m : mem w : world h : gmappiece pval, wim w h → repm w ∧ errno_cellm cellw
ep :=
ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb : ptr
stream_ps, closed_ps :
ptr → listpiece × pval
stream :=
λp : ptr ⇒ ptsstream_psp : ptr → iPropΣ
query_spec :
name → contractworld
Hquery_reg :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → registryg = Somequery_specg
Hquery_ret :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_returnsquery_specg = RClassk
Hquery_abi :
∀g : term k : class d : name v : value, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_abiquery_specg CResultd k ArgP v
Hquery_pre :
∀g : term k : class p : ptr xs : listZ m : mem w : world h : gmappiece pval, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prequery_specg WPtrp m w
Hquery_post :
∀g : term k : class d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokequery_specg CResultd k ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z, vs = WIntn ∧ 0 ≤ n < 2 ^ if class_eqbk W then 32 else 64 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
fclose_spec :
Hfclose_reg :
registryTAtom"fclose" = Somefclose_spec
Hfclose_ret :
Hfclose_abi :
∀d : name v : value, contract_abifclose_spec CResultd W ArgP v
Hfclose_pre :
∀p : ptr xs : listZ m : mem w : world h : gmappiece pval, wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prefclose_spec WPtrp m w
Hfclose_post :
∀d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokefclose_spec CResultd W ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z ys : listZ, vs = WIntn ∧ 0 ≤ n < 2 ^ 32 ∧ lengthys = 4%nat ∧ closed_psp ++ byte_pseb eo ys.*1 = stream_psp ++ byte_pseb eo xs.*1 ∧ agreesm′ overwriteclosed_psp ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwriteclosed_psp ++ byte_pseb eo ys h
Kerrno :
∀xs : listZ m : mem w : world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveeb, VLiveer :: byte_pseb eo xs → h !! l = Somev → wim w h → wistore_bytesm eb + eo 4 0 w overwritePLiveeb, VLiveer :: byte_pseb eo le_bytes0 4 h
Heo :
0 ≤ eo
Herange :
0 ≤ eb + eo < 2 ^ 64
Heend :
eb + eo + 4 ≤ r_ender
He48 :
r_ender ≤ 2 ^ 48
fmt :=
ptr_addr ≔ 65744; ptr_cap ≔ Ro65744 : ptr
text :=
ptr_addr ≔ 65680; ptr_cap ≔ Ro65680 : ptr
diag_ps :
listpiece × pval
error_spec :
Herror_reg :
registryTAtom"error" = Someerror_spec
Herror_ret :
contract_returnserror_spec = RVoid
Herror_abi :
∀v fmtv txtv : value, contract_abierror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv
Herror_pre :
∀n : Z xs : listZ m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → lengthxs = 4%nat → agreesm h → wim w h → ∀l : piece v : pval, l, v ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev → contract_preerror_spec WInt0; WIntn; WPtrfmt; WPtrtext m w
Herror_post :
∀v fmtv txtv : value n : Z xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, lengthxs = 4%nat → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokeerror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv WInt0; WIntn; WPtrfmt; WPtrtext s m w tr CallReturnvs s′ m′ w′ → ∃ys : listZ, vs = [ ] ∧ lengthys = 4%nat ∧ diag_ps ++ byte_pseb eo ys.*1 = diag_ps ++ byte_pseb eo xs.*1 ∧ agreesm′ overwritediag_ps ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritediag_ps ++ byte_pseb eo ys h
exit_spec :
Hexit_reg :
registryTAtom"_exit" = Someexit_spec
Hexit_ret :
Hexit_abi :
∀v : value, contract_abiexit_spec CVoid ArgW v
Hexit_pre :
∀n : Z m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → wim w h → contract_preexit_spec WIntn m w
Hexit_post :
∀args : listarg n : Z s : R.state m : mem w : world tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, M.E.invokeexit_spec CVoid args WIntn s m w tr CallReturnvs s′ m′ w′ → False
ob, sb :
Z
oreg, sreg, freg, ireg, xreg :
outp, errp :
Hout_live :
∃b : Z reg : region ps : listpiece × pval, ptr_capoutp = Objb ∧ stream_psoutp = PLiveb, VLivereg :: ps
Herr_live :
∃b : Z reg : region ps : listpiece × pval, ptr_caperrp = Objb ∧ stream_pserrp = PLiveb, VLivereg :: ps
Hstdout :
lookupTAtom"stdout" ge_globalsge = Someptr_addr ≔ ob; ptr_cap ≔ Objob
Hstderr :
lookupTAtom"stderr" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hob :
0 ≤ ob < 2 ^ 64
Hob8 :
ob mod 8 = 0
Hoend :
ob + 8 ≤ r_endoreg
Hsb :
0 ≤ sb < 2 ^ 64
Hsb8 :
sb mod 8 = 0
Hsend :
sb + 8 ≤ r_endsreg
Hout :
0 ≤ ptr_addroutp < 2 ^ 64
Herrp :
0 ≤ ptr_addrerrp < 2 ^ 64
Hfend :
65584 + 8 ≤ r_endfreg
Hiend :
65616 + 1 ≤ r_endireg
Hxend :
65776 + 4 ≤ r_endxreg
Hg :
∀n : name p : ptr, lookupn hello_globals = Somep → lookupn ge_globalsge = Somep
⊢
lookupTAtom"closeout#file_name" ge_globalsge = Someptr_addr ≔ 65584; ptr_cap ≔ Obj65584 ∧ lookupTAtom"closeout#ignore_EPIPE" ge_globalsge = Someptr_addr ≔ 65616; ptr_cap ≔ Obj65616 ∧ lookupTAtom"exit_failure" ge_globalsge = Someptr_addr ≔ 65776; ptr_cap ≔ Obj65776 ∧ lookupTAtom"closeout#str.55" ge_globalsge = Somefmt ∧ lookupTAtom"closeout#str.53" ge_globalsge = Sometext ∧ ∃p : ptr, lookupTAtom"closeout#str.52" ge_globalsge = Somep

repeat split ; try apply Hg ; vm_compute ; reflexivity

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
eb, eo :
Z
er :
cell :
world → ptr
rep :
mem → world → Prop
Herrno :
registryTAtom"__errno_location" = Someerrno_location_contractworld cell rep
Hlinked :
Hcell :
∀m : mem w : world h : gmappiece pval, wim w h → cellw = ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb
Hrep :
∀m : mem w : world h : gmappiece pval, wim w h → repm w ∧ errno_cellm cellw
ep :=
ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb : ptr
stream_ps, closed_ps :
ptr → listpiece × pval
stream :=
λp : ptr ⇒ ptsstream_psp : ptr → iPropΣ
query_spec :
name → contractworld
Hquery_reg :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → registryg = Somequery_specg
Hquery_ret :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_returnsquery_specg = RClassk
Hquery_abi :
∀g : term k : class d : name v : value, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_abiquery_specg CResultd k ArgP v
Hquery_pre :
∀g : term k : class p : ptr xs : listZ m : mem w : world h : gmappiece pval, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prequery_specg WPtrp m w
Hquery_post :
∀g : term k : class d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokequery_specg CResultd k ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z, vs = WIntn ∧ 0 ≤ n < 2 ^ if class_eqbk W then 32 else 64 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
fclose_spec :
Hfclose_reg :
registryTAtom"fclose" = Somefclose_spec
Hfclose_ret :
Hfclose_abi :
∀d : name v : value, contract_abifclose_spec CResultd W ArgP v
Hfclose_pre :
∀p : ptr xs : listZ m : mem w : world h : gmappiece pval, wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prefclose_spec WPtrp m w
Hfclose_post :
∀d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokefclose_spec CResultd W ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z ys : listZ, vs = WIntn ∧ 0 ≤ n < 2 ^ 32 ∧ lengthys = 4%nat ∧ closed_psp ++ byte_pseb eo ys.*1 = stream_psp ++ byte_pseb eo xs.*1 ∧ agreesm′ overwriteclosed_psp ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwriteclosed_psp ++ byte_pseb eo ys h
Kerrno :
∀xs : listZ m : mem w : world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveeb, VLiveer :: byte_pseb eo xs → h !! l = Somev → wim w h → wistore_bytesm eb + eo 4 0 w overwritePLiveeb, VLiveer :: byte_pseb eo le_bytes0 4 h
Heo :
0 ≤ eo
Herange :
0 ≤ eb + eo < 2 ^ 64
Heend :
eb + eo + 4 ≤ r_ender
He48 :
r_ender ≤ 2 ^ 48
fmt :=
ptr_addr ≔ 65744; ptr_cap ≔ Ro65744 : ptr
text :=
ptr_addr ≔ 65680; ptr_cap ≔ Ro65680 : ptr
diag_ps :
listpiece × pval
error_spec :
Herror_reg :
registryTAtom"error" = Someerror_spec
Herror_ret :
contract_returnserror_spec = RVoid
Herror_abi :
∀v fmtv txtv : value, contract_abierror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv
Herror_pre :
∀n : Z xs : listZ m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → lengthxs = 4%nat → agreesm h → wim w h → ∀l : piece v : pval, l, v ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev → contract_preerror_spec WInt0; WIntn; WPtrfmt; WPtrtext m w
Herror_post :
∀v fmtv txtv : value n : Z xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, lengthxs = 4%nat → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokeerror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv WInt0; WIntn; WPtrfmt; WPtrtext s m w tr CallReturnvs s′ m′ w′ → ∃ys : listZ, vs = [ ] ∧ lengthys = 4%nat ∧ diag_ps ++ byte_pseb eo ys.*1 = diag_ps ++ byte_pseb eo xs.*1 ∧ agreesm′ overwritediag_ps ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritediag_ps ++ byte_pseb eo ys h
exit_spec :
Hexit_reg :
registryTAtom"_exit" = Someexit_spec
Hexit_ret :
Hexit_abi :
∀v : value, contract_abiexit_spec CVoid ArgW v
Hexit_pre :
∀n : Z m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → wim w h → contract_preexit_spec WIntn m w
Hexit_post :
∀args : listarg n : Z s : R.state m : mem w : world tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, M.E.invokeexit_spec CVoid args WIntn s m w tr CallReturnvs s′ m′ w′ → False
ob, sb :
Z
oreg, sreg, freg, ireg, xreg :
outp, errp :
Hout_live :
∃b : Z reg : region ps : listpiece × pval, ptr_capoutp = Objb ∧ stream_psoutp = PLiveb, VLivereg :: ps
Herr_live :
∃b : Z reg : region ps : listpiece × pval, ptr_caperrp = Objb ∧ stream_pserrp = PLiveb, VLivereg :: ps
Hstdout :
lookupTAtom"stdout" ge_globalsge = Someptr_addr ≔ ob; ptr_cap ≔ Objob
Hstderr :
lookupTAtom"stderr" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hob :
0 ≤ ob < 2 ^ 64
Hob8 :
ob mod 8 = 0
Hoend :
ob + 8 ≤ r_endoreg
Hsb :
0 ≤ sb < 2 ^ 64
Hsb8 :
sb mod 8 = 0
Hsend :
sb + 8 ≤ r_endsreg
Hout :
0 ≤ ptr_addroutp < 2 ^ 64
Herrp :
0 ≤ ptr_addrerrp < 2 ^ 64
Hfend :
65584 + 8 ≤ r_endfreg
Hiend :
65616 + 1 ≤ r_endireg
Hxend :
65776 + 4 ≤ r_endxreg
Hg :
∀n : name p : ptr, lookupn hello_globals = Somep → lookupn ge_globalsge = Somep
⊢
∃p : ptr, lookupTAtom"closeout#str.52" ge_globalsge = Somep

exists mkPtr65648 Ro65648

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
eb, eo :
Z
er :
cell :
world → ptr
rep :
mem → world → Prop
Herrno :
registryTAtom"__errno_location" = Someerrno_location_contractworld cell rep
Hlinked :
Hcell :
∀m : mem w : world h : gmappiece pval, wim w h → cellw = ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb
Hrep :
∀m : mem w : world h : gmappiece pval, wim w h → repm w ∧ errno_cellm cellw
ep :=
ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb : ptr
stream_ps, closed_ps :
ptr → listpiece × pval
stream :=
λp : ptr ⇒ ptsstream_psp : ptr → iPropΣ
query_spec :
name → contractworld
Hquery_reg :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → registryg = Somequery_specg
Hquery_ret :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_returnsquery_specg = RClassk
Hquery_abi :
∀g : term k : class d : name v : value, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_abiquery_specg CResultd k ArgP v
Hquery_pre :
∀g : term k : class p : ptr xs : listZ m : mem w : world h : gmappiece pval, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prequery_specg WPtrp m w
Hquery_post :
∀g : term k : class d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokequery_specg CResultd k ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z, vs = WIntn ∧ 0 ≤ n < 2 ^ if class_eqbk W then 32 else 64 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
fclose_spec :
Hfclose_reg :
registryTAtom"fclose" = Somefclose_spec
Hfclose_ret :
Hfclose_abi :
∀d : name v : value, contract_abifclose_spec CResultd W ArgP v
Hfclose_pre :
∀p : ptr xs : listZ m : mem w : world h : gmappiece pval, wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prefclose_spec WPtrp m w
Hfclose_post :
∀d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokefclose_spec CResultd W ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z ys : listZ, vs = WIntn ∧ 0 ≤ n < 2 ^ 32 ∧ lengthys = 4%nat ∧ closed_psp ++ byte_pseb eo ys.*1 = stream_psp ++ byte_pseb eo xs.*1 ∧ agreesm′ overwriteclosed_psp ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwriteclosed_psp ++ byte_pseb eo ys h
Kerrno :
∀xs : listZ m : mem w : world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveeb, VLiveer :: byte_pseb eo xs → h !! l = Somev → wim w h → wistore_bytesm eb + eo 4 0 w overwritePLiveeb, VLiveer :: byte_pseb eo le_bytes0 4 h
Heo :
0 ≤ eo
Herange :
0 ≤ eb + eo < 2 ^ 64
Heend :
eb + eo + 4 ≤ r_ender
He48 :
r_ender ≤ 2 ^ 48
fmt :=
ptr_addr ≔ 65744; ptr_cap ≔ Ro65744 : ptr
text :=
ptr_addr ≔ 65680; ptr_cap ≔ Ro65680 : ptr
diag_ps :
listpiece × pval
error_spec :
Herror_reg :
registryTAtom"error" = Someerror_spec
Herror_ret :
contract_returnserror_spec = RVoid
Herror_abi :
∀v fmtv txtv : value, contract_abierror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv
Herror_pre :
∀n : Z xs : listZ m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → lengthxs = 4%nat → agreesm h → wim w h → ∀l : piece v : pval, l, v ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev → contract_preerror_spec WInt0; WIntn; WPtrfmt; WPtrtext m w
Herror_post :
∀v fmtv txtv : value n : Z xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, lengthxs = 4%nat → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokeerror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv WInt0; WIntn; WPtrfmt; WPtrtext s m w tr CallReturnvs s′ m′ w′ → ∃ys : listZ, vs = [ ] ∧ lengthys = 4%nat ∧ diag_ps ++ byte_pseb eo ys.*1 = diag_ps ++ byte_pseb eo xs.*1 ∧ agreesm′ overwritediag_ps ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritediag_ps ++ byte_pseb eo ys h
exit_spec :
Hexit_reg :
registryTAtom"_exit" = Someexit_spec
Hexit_ret :
Hexit_abi :
∀v : value, contract_abiexit_spec CVoid ArgW v
Hexit_pre :
∀n : Z m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → wim w h → contract_preexit_spec WIntn m w
Hexit_post :
∀args : listarg n : Z s : R.state m : mem w : world tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, M.E.invokeexit_spec CVoid args WIntn s m w tr CallReturnvs s′ m′ w′ → False
ob, sb :
Z
oreg, sreg, freg, ireg, xreg :
outp, errp :
Hout_live :
∃b : Z reg : region ps : listpiece × pval, ptr_capoutp = Objb ∧ stream_psoutp = PLiveb, VLivereg :: ps
Herr_live :
∃b : Z reg : region ps : listpiece × pval, ptr_caperrp = Objb ∧ stream_pserrp = PLiveb, VLivereg :: ps
Hstdout :
lookupTAtom"stdout" ge_globalsge = Someptr_addr ≔ ob; ptr_cap ≔ Objob
Hstderr :
lookupTAtom"stderr" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hob :
0 ≤ ob < 2 ^ 64
Hob8 :
ob mod 8 = 0
Hoend :
ob + 8 ≤ r_endoreg
Hsb :
0 ≤ sb < 2 ^ 64
Hsb8 :
sb mod 8 = 0
Hsend :
sb + 8 ≤ r_endsreg
Hout :
0 ≤ ptr_addroutp < 2 ^ 64
Herrp :
0 ≤ ptr_addrerrp < 2 ^ 64
Hfend :
65584 + 8 ≤ r_endfreg
Hiend :
65616 + 1 ≤ r_endireg
Hxend :
65776 + 4 ≤ r_endxreg
Hg :
∀n : name p : ptr, lookupn hello_globals = Somep → lookupn ge_globalsge = Somep
⊢
lookupTAtom"closeout#str.52" ge_globalsge = Someptr_addr ≔ 65648; ptr_cap ≔ Ro65648

apply Hg

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
eb, eo :
Z
er :
cell :
world → ptr
rep :
mem → world → Prop
Herrno :
registryTAtom"__errno_location" = Someerrno_location_contractworld cell rep
Hlinked :
Hcell :
∀m : mem w : world h : gmappiece pval, wim w h → cellw = ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb
Hrep :
∀m : mem w : world h : gmappiece pval, wim w h → repm w ∧ errno_cellm cellw
ep :=
ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb : ptr
stream_ps, closed_ps :
ptr → listpiece × pval
stream :=
λp : ptr ⇒ ptsstream_psp : ptr → iPropΣ
query_spec :
name → contractworld
Hquery_reg :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → registryg = Somequery_specg
Hquery_ret :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_returnsquery_specg = RClassk
Hquery_abi :
∀g : term k : class d : name v : value, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_abiquery_specg CResultd k ArgP v
Hquery_pre :
∀g : term k : class p : ptr xs : listZ m : mem w : world h : gmappiece pval, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prequery_specg WPtrp m w
Hquery_post :
∀g : term k : class d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokequery_specg CResultd k ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z, vs = WIntn ∧ 0 ≤ n < 2 ^ if class_eqbk W then 32 else 64 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
fclose_spec :
Hfclose_reg :
registryTAtom"fclose" = Somefclose_spec
Hfclose_ret :
Hfclose_abi :
∀d : name v : value, contract_abifclose_spec CResultd W ArgP v
Hfclose_pre :
∀p : ptr xs : listZ m : mem w : world h : gmappiece pval, wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prefclose_spec WPtrp m w
Hfclose_post :
∀d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokefclose_spec CResultd W ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z ys : listZ, vs = WIntn ∧ 0 ≤ n < 2 ^ 32 ∧ lengthys = 4%nat ∧ closed_psp ++ byte_pseb eo ys.*1 = stream_psp ++ byte_pseb eo xs.*1 ∧ agreesm′ overwriteclosed_psp ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwriteclosed_psp ++ byte_pseb eo ys h
Kerrno :
∀xs : listZ m : mem w : world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveeb, VLiveer :: byte_pseb eo xs → h !! l = Somev → wim w h → wistore_bytesm eb + eo 4 0 w overwritePLiveeb, VLiveer :: byte_pseb eo le_bytes0 4 h
Heo :
0 ≤ eo
Herange :
0 ≤ eb + eo < 2 ^ 64
Heend :
eb + eo + 4 ≤ r_ender
He48 :
r_ender ≤ 2 ^ 48
fmt :=
ptr_addr ≔ 65744; ptr_cap ≔ Ro65744 : ptr
text :=
ptr_addr ≔ 65680; ptr_cap ≔ Ro65680 : ptr
diag_ps :
listpiece × pval
error_spec :
Herror_reg :
registryTAtom"error" = Someerror_spec
Herror_ret :
contract_returnserror_spec = RVoid
Herror_abi :
∀v fmtv txtv : value, contract_abierror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv
Herror_pre :
∀n : Z xs : listZ m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → lengthxs = 4%nat → agreesm h → wim w h → ∀l : piece v : pval, l, v ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev → contract_preerror_spec WInt0; WIntn; WPtrfmt; WPtrtext m w
Herror_post :
∀v fmtv txtv : value n : Z xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, lengthxs = 4%nat → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokeerror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv WInt0; WIntn; WPtrfmt; WPtrtext s m w tr CallReturnvs s′ m′ w′ → ∃ys : listZ, vs = [ ] ∧ lengthys = 4%nat ∧ diag_ps ++ byte_pseb eo ys.*1 = diag_ps ++ byte_pseb eo xs.*1 ∧ agreesm′ overwritediag_ps ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritediag_ps ++ byte_pseb eo ys h
exit_spec :
Hexit_reg :
registryTAtom"_exit" = Someexit_spec
Hexit_ret :
Hexit_abi :
∀v : value, contract_abiexit_spec CVoid ArgW v
Hexit_pre :
∀n : Z m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → wim w h → contract_preexit_spec WIntn m w
Hexit_post :
∀args : listarg n : Z s : R.state m : mem w : world tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, M.E.invokeexit_spec CVoid args WIntn s m w tr CallReturnvs s′ m′ w′ → False
ob, sb :
Z
oreg, sreg, freg, ireg, xreg :
outp, errp :
Hout_live :
∃b : Z reg : region ps : listpiece × pval, ptr_capoutp = Objb ∧ stream_psoutp = PLiveb, VLivereg :: ps
Herr_live :
∃b : Z reg : region ps : listpiece × pval, ptr_caperrp = Objb ∧ stream_pserrp = PLiveb, VLivereg :: ps
Hstdout :
lookupTAtom"stdout" ge_globalsge = Someptr_addr ≔ ob; ptr_cap ≔ Objob
Hstderr :
lookupTAtom"stderr" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hob :
0 ≤ ob < 2 ^ 64
Hob8 :
ob mod 8 = 0
Hoend :
ob + 8 ≤ r_endoreg
Hsb :
0 ≤ sb < 2 ^ 64
Hsb8 :
sb mod 8 = 0
Hsend :
sb + 8 ≤ r_endsreg
Hout :
0 ≤ ptr_addroutp < 2 ^ 64
Herrp :
0 ≤ ptr_addrerrp < 2 ^ 64
Hfend :
65584 + 8 ≤ r_endfreg
Hiend :
65616 + 1 ≤ r_endireg
Hxend :
65776 + 4 ≤ r_endxreg
Hg :
∀n : name p : ptr, lookupn hello_globals = Somep → lookupn ge_globalsge = Somep
⊢
lookupTAtom"closeout#str.52" hello_globals = Someptr_addr ≔ 65648; ptr_cap ≔ Ro65648

vm_compute

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
eb, eo :
Z
er :
cell :
world → ptr
rep :
mem → world → Prop
Herrno :
registryTAtom"__errno_location" = Someerrno_location_contractworld cell rep
Hlinked :
Hcell :
∀m : mem w : world h : gmappiece pval, wim w h → cellw = ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb
Hrep :
∀m : mem w : world h : gmappiece pval, wim w h → repm w ∧ errno_cellm cellw
ep :=
ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb : ptr
stream_ps, closed_ps :
ptr → listpiece × pval
stream :=
λp : ptr ⇒ ptsstream_psp : ptr → iPropΣ
query_spec :
name → contractworld
Hquery_reg :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → registryg = Somequery_specg
Hquery_ret :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_returnsquery_specg = RClassk
Hquery_abi :
∀g : term k : class d : name v : value, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_abiquery_specg CResultd k ArgP v
Hquery_pre :
∀g : term k : class p : ptr xs : listZ m : mem w : world h : gmappiece pval, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prequery_specg WPtrp m w
Hquery_post :
∀g : term k : class d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokequery_specg CResultd k ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z, vs = WIntn ∧ 0 ≤ n < 2 ^ if class_eqbk W then 32 else 64 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
fclose_spec :
Hfclose_reg :
registryTAtom"fclose" = Somefclose_spec
Hfclose_ret :
Hfclose_abi :
∀d : name v : value, contract_abifclose_spec CResultd W ArgP v
Hfclose_pre :
∀p : ptr xs : listZ m : mem w : world h : gmappiece pval, wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prefclose_spec WPtrp m w
Hfclose_post :
∀d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokefclose_spec CResultd W ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z ys : listZ, vs = WIntn ∧ 0 ≤ n < 2 ^ 32 ∧ lengthys = 4%nat ∧ closed_psp ++ byte_pseb eo ys.*1 = stream_psp ++ byte_pseb eo xs.*1 ∧ agreesm′ overwriteclosed_psp ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwriteclosed_psp ++ byte_pseb eo ys h
Kerrno :
∀xs : listZ m : mem w : world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveeb, VLiveer :: byte_pseb eo xs → h !! l = Somev → wim w h → wistore_bytesm eb + eo 4 0 w overwritePLiveeb, VLiveer :: byte_pseb eo le_bytes0 4 h
Heo :
0 ≤ eo
Herange :
0 ≤ eb + eo < 2 ^ 64
Heend :
eb + eo + 4 ≤ r_ender
He48 :
r_ender ≤ 2 ^ 48
fmt :=
ptr_addr ≔ 65744; ptr_cap ≔ Ro65744 : ptr
text :=
ptr_addr ≔ 65680; ptr_cap ≔ Ro65680 : ptr
diag_ps :
listpiece × pval
error_spec :
Herror_reg :
registryTAtom"error" = Someerror_spec
Herror_ret :
contract_returnserror_spec = RVoid
Herror_abi :
∀v fmtv txtv : value, contract_abierror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv
Herror_pre :
∀n : Z xs : listZ m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → lengthxs = 4%nat → agreesm h → wim w h → ∀l : piece v : pval, l, v ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev → contract_preerror_spec WInt0; WIntn; WPtrfmt; WPtrtext m w
Herror_post :
∀v fmtv txtv : value n : Z xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, lengthxs = 4%nat → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokeerror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv WInt0; WIntn; WPtrfmt; WPtrtext s m w tr CallReturnvs s′ m′ w′ → ∃ys : listZ, vs = [ ] ∧ lengthys = 4%nat ∧ diag_ps ++ byte_pseb eo ys.*1 = diag_ps ++ byte_pseb eo xs.*1 ∧ agreesm′ overwritediag_ps ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritediag_ps ++ byte_pseb eo ys h
exit_spec :
Hexit_reg :
registryTAtom"_exit" = Someexit_spec
Hexit_ret :
Hexit_abi :
∀v : value, contract_abiexit_spec CVoid ArgW v
Hexit_pre :
∀n : Z m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → wim w h → contract_preexit_spec WIntn m w
Hexit_post :
∀args : listarg n : Z s : R.state m : mem w : world tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, M.E.invokeexit_spec CVoid args WIntn s m w tr CallReturnvs s′ m′ w′ → False
ob, sb :
Z
oreg, sreg, freg, ireg, xreg :
outp, errp :
Hout_live :
∃b : Z reg : region ps : listpiece × pval, ptr_capoutp = Objb ∧ stream_psoutp = PLiveb, VLivereg :: ps
Herr_live :
∃b : Z reg : region ps : listpiece × pval, ptr_caperrp = Objb ∧ stream_pserrp = PLiveb, VLivereg :: ps
Hstdout :
lookupTAtom"stdout" ge_globalsge = Someptr_addr ≔ ob; ptr_cap ≔ Objob
Hstderr :
lookupTAtom"stderr" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hob :
0 ≤ ob < 2 ^ 64
Hob8 :
ob mod 8 = 0
Hoend :
ob + 8 ≤ r_endoreg
Hsb :
0 ≤ sb < 2 ^ 64
Hsb8 :
sb mod 8 = 0
Hsend :
sb + 8 ≤ r_endsreg
Hout :
0 ≤ ptr_addroutp < 2 ^ 64
Herrp :
0 ≤ ptr_addrerrp < 2 ^ 64
Hfend :
65584 + 8 ≤ r_endfreg
Hiend :
65616 + 1 ≤ r_endireg
Hxend :
65776 + 4 ≤ r_endxreg
Hg :
∀n : name p : ptr, lookupn hello_globals = Somep → lookupn ge_globalsge = Somep
⊢
Someptr_addr ≔ 65648; ptr_cap ≔ Ro65648 = Someptr_addr ≔ 65648; ptr_cap ≔ Ro65648

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
destruct Hlinked as _ & Hg & _
repeat split ; try apply Hg ; vm_compute ; reflexivity
exists mkPtr65648 Ro65648
apply Hg
vm_compute
reflexivity

Enter one of close_stdout's blocks.

579Ltac co_enter s ≔
iApply wp_enter_ _ _ _ _ _ _ _ co_blocks ; vm_compute ; reflexivity | word_premise | ; iNext ; cbn [ b_insts b_jump co_block hblk ]

The linked module dispatches close_stream to its proved body.

585Lemma close_stream_linked
Explore proof 4 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
eb, eo :
Z
er :
cell :
world → ptr
rep :
mem → world → Prop
Herrno :
registryTAtom"__errno_location" = Someerrno_location_contractworld cell rep
Hlinked :
Hcell :
∀m : mem w : world h : gmappiece pval, wim w h → cellw = ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb
Hrep :
∀m : mem w : world h : gmappiece pval, wim w h → repm w ∧ errno_cellm cellw
ep :=
ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb : ptr
stream_ps, closed_ps :
ptr → listpiece × pval
stream :=
λp : ptr ⇒ ptsstream_psp : ptr → iPropΣ
query_spec :
name → contractworld
Hquery_reg :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → registryg = Somequery_specg
Hquery_ret :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_returnsquery_specg = RClassk
Hquery_abi :
∀g : term k : class d : name v : value, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_abiquery_specg CResultd k ArgP v
Hquery_pre :
∀g : term k : class p : ptr xs : listZ m : mem w : world h : gmappiece pval, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prequery_specg WPtrp m w
Hquery_post :
∀g : term k : class d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokequery_specg CResultd k ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z, vs = WIntn ∧ 0 ≤ n < 2 ^ if class_eqbk W then 32 else 64 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
fclose_spec :
Hfclose_reg :
registryTAtom"fclose" = Somefclose_spec
Hfclose_ret :
Hfclose_abi :
∀d : name v : value, contract_abifclose_spec CResultd W ArgP v
Hfclose_pre :
∀p : ptr xs : listZ m : mem w : world h : gmappiece pval, wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prefclose_spec WPtrp m w
Hfclose_post :
∀d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokefclose_spec CResultd W ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z ys : listZ, vs = WIntn ∧ 0 ≤ n < 2 ^ 32 ∧ lengthys = 4%nat ∧ closed_psp ++ byte_pseb eo ys.*1 = stream_psp ++ byte_pseb eo xs.*1 ∧ agreesm′ overwriteclosed_psp ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwriteclosed_psp ++ byte_pseb eo ys h
Kerrno :
∀xs : listZ m : mem w : world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveeb, VLiveer :: byte_pseb eo xs → h !! l = Somev → wim w h → wistore_bytesm eb + eo 4 0 w overwritePLiveeb, VLiveer :: byte_pseb eo le_bytes0 4 h
Heo :
0 ≤ eo
Herange :
0 ≤ eb + eo < 2 ^ 64
Heend :
eb + eo + 4 ≤ r_ender
He48 :
r_ender ≤ 2 ^ 48
fmt :=
ptr_addr ≔ 65744; ptr_cap ≔ Ro65744 : ptr
text :=
ptr_addr ≔ 65680; ptr_cap ≔ Ro65680 : ptr
diag_ps :
listpiece × pval
error_spec :
Herror_reg :
registryTAtom"error" = Someerror_spec
Herror_ret :
contract_returnserror_spec = RVoid
Herror_abi :
∀v fmtv txtv : value, contract_abierror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv
Herror_pre :
∀n : Z xs : listZ m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → lengthxs = 4%nat → agreesm h → wim w h → ∀l : piece v : pval, l, v ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev → contract_preerror_spec WInt0; WIntn; WPtrfmt; WPtrtext m w
Herror_post :
∀v fmtv txtv : value n : Z xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, lengthxs = 4%nat → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokeerror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv WInt0; WIntn; WPtrfmt; WPtrtext s m w tr CallReturnvs s′ m′ w′ → ∃ys : listZ, vs = [ ] ∧ lengthys = 4%nat ∧ diag_ps ++ byte_pseb eo ys.*1 = diag_ps ++ byte_pseb eo xs.*1 ∧ agreesm′ overwritediag_ps ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritediag_ps ++ byte_pseb eo ys h
exit_spec :
Hexit_reg :
registryTAtom"_exit" = Someexit_spec
Hexit_ret :
Hexit_abi :
∀v : value, contract_abiexit_spec CVoid ArgW v
Hexit_pre :
∀n : Z m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → wim w h → contract_preexit_spec WIntn m w
Hexit_post :
∀args : listarg n : Z s : R.state m : mem w : world tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, M.E.invokeexit_spec CVoid args WIntn s m w tr CallReturnvs s′ m′ w′ → False
ob, sb :
Z
oreg, sreg, freg, ireg, xreg :
outp, errp :
Hout_live :
∃b : Z reg : region ps : listpiece × pval, ptr_capoutp = Objb ∧ stream_psoutp = PLiveb, VLivereg :: ps
Herr_live :
∃b : Z reg : region ps : listpiece × pval, ptr_caperrp = Objb ∧ stream_pserrp = PLiveb, VLivereg :: ps
Hstdout :
lookupTAtom"stdout" ge_globalsge = Someptr_addr ≔ ob; ptr_cap ≔ Objob
Hstderr :
lookupTAtom"stderr" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hob :
0 ≤ ob < 2 ^ 64
Hob8 :
ob mod 8 = 0
Hoend :
ob + 8 ≤ r_endoreg
Hsb :
0 ≤ sb < 2 ^ 64
Hsb8 :
sb mod 8 = 0
Hsend :
sb + 8 ≤ r_endsreg
Hout :
0 ≤ ptr_addroutp < 2 ^ 64
Herrp :
0 ≤ ptr_addrerrp < 2 ^ 64
Hfend :
65584 + 8 ≤ r_endfreg
Hiend :
65616 + 1 ≤ r_endireg
Hxend :
65776 + 4 ≤ r_endxreg
⊢
find_fnge TAtom"close_stream" = SomeDefinedclose_stream_fn

unfold find_fn

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
eb, eo :
Z
er :
cell :
world → ptr
rep :
mem → world → Prop
Herrno :
registryTAtom"__errno_location" = Someerrno_location_contractworld cell rep
Hlinked :
Hcell :
∀m : mem w : world h : gmappiece pval, wim w h → cellw = ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb
Hrep :
∀m : mem w : world h : gmappiece pval, wim w h → repm w ∧ errno_cellm cellw
ep :=
ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb : ptr
stream_ps, closed_ps :
ptr → listpiece × pval
stream :=
λp : ptr ⇒ ptsstream_psp : ptr → iPropΣ
query_spec :
name → contractworld
Hquery_reg :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → registryg = Somequery_specg
Hquery_ret :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_returnsquery_specg = RClassk
Hquery_abi :
∀g : term k : class d : name v : value, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_abiquery_specg CResultd k ArgP v
Hquery_pre :
∀g : term k : class p : ptr xs : listZ m : mem w : world h : gmappiece pval, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prequery_specg WPtrp m w
Hquery_post :
∀g : term k : class d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokequery_specg CResultd k ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z, vs = WIntn ∧ 0 ≤ n < 2 ^ if class_eqbk W then 32 else 64 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
fclose_spec :
Hfclose_reg :
registryTAtom"fclose" = Somefclose_spec
Hfclose_ret :
Hfclose_abi :
∀d : name v : value, contract_abifclose_spec CResultd W ArgP v
Hfclose_pre :
∀p : ptr xs : listZ m : mem w : world h : gmappiece pval, wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prefclose_spec WPtrp m w
Hfclose_post :
∀d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokefclose_spec CResultd W ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z ys : listZ, vs = WIntn ∧ 0 ≤ n < 2 ^ 32 ∧ lengthys = 4%nat ∧ closed_psp ++ byte_pseb eo ys.*1 = stream_psp ++ byte_pseb eo xs.*1 ∧ agreesm′ overwriteclosed_psp ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwriteclosed_psp ++ byte_pseb eo ys h
Kerrno :
∀xs : listZ m : mem w : world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveeb, VLiveer :: byte_pseb eo xs → h !! l = Somev → wim w h → wistore_bytesm eb + eo 4 0 w overwritePLiveeb, VLiveer :: byte_pseb eo le_bytes0 4 h
Heo :
0 ≤ eo
Herange :
0 ≤ eb + eo < 2 ^ 64
Heend :
eb + eo + 4 ≤ r_ender
He48 :
r_ender ≤ 2 ^ 48
fmt :=
ptr_addr ≔ 65744; ptr_cap ≔ Ro65744 : ptr
text :=
ptr_addr ≔ 65680; ptr_cap ≔ Ro65680 : ptr
diag_ps :
listpiece × pval
error_spec :
Herror_reg :
registryTAtom"error" = Someerror_spec
Herror_ret :
contract_returnserror_spec = RVoid
Herror_abi :
∀v fmtv txtv : value, contract_abierror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv
Herror_pre :
∀n : Z xs : listZ m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → lengthxs = 4%nat → agreesm h → wim w h → ∀l : piece v : pval, l, v ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev → contract_preerror_spec WInt0; WIntn; WPtrfmt; WPtrtext m w
Herror_post :
∀v fmtv txtv : value n : Z xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, lengthxs = 4%nat → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokeerror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv WInt0; WIntn; WPtrfmt; WPtrtext s m w tr CallReturnvs s′ m′ w′ → ∃ys : listZ, vs = [ ] ∧ lengthys = 4%nat ∧ diag_ps ++ byte_pseb eo ys.*1 = diag_ps ++ byte_pseb eo xs.*1 ∧ agreesm′ overwritediag_ps ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritediag_ps ++ byte_pseb eo ys h
exit_spec :
Hexit_reg :
registryTAtom"_exit" = Someexit_spec
Hexit_ret :
Hexit_abi :
∀v : value, contract_abiexit_spec CVoid ArgW v
Hexit_pre :
∀n : Z m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → wim w h → contract_preexit_spec WIntn m w
Hexit_post :
∀args : listarg n : Z s : R.state m : mem w : world tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, M.E.invokeexit_spec CVoid args WIntn s m w tr CallReturnvs s′ m′ w′ → False
ob, sb :
Z
oreg, sreg, freg, ireg, xreg :
outp, errp :
Hout_live :
∃b : Z reg : region ps : listpiece × pval, ptr_capoutp = Objb ∧ stream_psoutp = PLiveb, VLivereg :: ps
Herr_live :
∃b : Z reg : region ps : listpiece × pval, ptr_caperrp = Objb ∧ stream_pserrp = PLiveb, VLivereg :: ps
Hstdout :
lookupTAtom"stdout" ge_globalsge = Someptr_addr ≔ ob; ptr_cap ≔ Objob
Hstderr :
lookupTAtom"stderr" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hob :
0 ≤ ob < 2 ^ 64
Hob8 :
ob mod 8 = 0
Hoend :
ob + 8 ≤ r_endoreg
Hsb :
0 ≤ sb < 2 ^ 64
Hsb8 :
sb mod 8 = 0
Hsend :
sb + 8 ≤ r_endsreg
Hout :
0 ≤ ptr_addroutp < 2 ^ 64
Herrp :
0 ≤ ptr_addrerrp < 2 ^ 64
Hfend :
65584 + 8 ≤ r_endfreg
Hiend :
65616 + 1 ≤ r_endireg
Hxend :
65776 + 4 ≤ r_endxreg
⊢
match find_directTAtom"close_stream" ge_modulege with
Somed
⇒
Somed
None
⇒
let* t ≔ find_aliasTAtom"close_stream" ge_modulege in
=

rewrite proj1Hlinked

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
eb, eo :
Z
er :
cell :
world → ptr
rep :
mem → world → Prop
Herrno :
registryTAtom"__errno_location" = Someerrno_location_contractworld cell rep
Hlinked :
Hcell :
∀m : mem w : world h : gmappiece pval, wim w h → cellw = ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb
Hrep :
∀m : mem w : world h : gmappiece pval, wim w h → repm w ∧ errno_cellm cellw
ep :=
ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb : ptr
stream_ps, closed_ps :
ptr → listpiece × pval
stream :=
λp : ptr ⇒ ptsstream_psp : ptr → iPropΣ
query_spec :
name → contractworld
Hquery_reg :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → registryg = Somequery_specg
Hquery_ret :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_returnsquery_specg = RClassk
Hquery_abi :
∀g : term k : class d : name v : value, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_abiquery_specg CResultd k ArgP v
Hquery_pre :
∀g : term k : class p : ptr xs : listZ m : mem w : world h : gmappiece pval, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prequery_specg WPtrp m w
Hquery_post :
∀g : term k : class d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokequery_specg CResultd k ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z, vs = WIntn ∧ 0 ≤ n < 2 ^ if class_eqbk W then 32 else 64 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
fclose_spec :
Hfclose_reg :
registryTAtom"fclose" = Somefclose_spec
Hfclose_ret :
Hfclose_abi :
∀d : name v : value, contract_abifclose_spec CResultd W ArgP v
Hfclose_pre :
∀p : ptr xs : listZ m : mem w : world h : gmappiece pval, wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prefclose_spec WPtrp m w
Hfclose_post :
∀d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokefclose_spec CResultd W ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z ys : listZ, vs = WIntn ∧ 0 ≤ n < 2 ^ 32 ∧ lengthys = 4%nat ∧ closed_psp ++ byte_pseb eo ys.*1 = stream_psp ++ byte_pseb eo xs.*1 ∧ agreesm′ overwriteclosed_psp ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwriteclosed_psp ++ byte_pseb eo ys h
Kerrno :
∀xs : listZ m : mem w : world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveeb, VLiveer :: byte_pseb eo xs → h !! l = Somev → wim w h → wistore_bytesm eb + eo 4 0 w overwritePLiveeb, VLiveer :: byte_pseb eo le_bytes0 4 h
Heo :
0 ≤ eo
Herange :
0 ≤ eb + eo < 2 ^ 64
Heend :
eb + eo + 4 ≤ r_ender
He48 :
r_ender ≤ 2 ^ 48
fmt :=
ptr_addr ≔ 65744; ptr_cap ≔ Ro65744 : ptr
text :=
ptr_addr ≔ 65680; ptr_cap ≔ Ro65680 : ptr
diag_ps :
listpiece × pval
error_spec :
Herror_reg :
registryTAtom"error" = Someerror_spec
Herror_ret :
contract_returnserror_spec = RVoid
Herror_abi :
∀v fmtv txtv : value, contract_abierror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv
Herror_pre :
∀n : Z xs : listZ m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → lengthxs = 4%nat → agreesm h → wim w h → ∀l : piece v : pval, l, v ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev → contract_preerror_spec WInt0; WIntn; WPtrfmt; WPtrtext m w
Herror_post :
∀v fmtv txtv : value n : Z xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, lengthxs = 4%nat → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokeerror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv WInt0; WIntn; WPtrfmt; WPtrtext s m w tr CallReturnvs s′ m′ w′ → ∃ys : listZ, vs = [ ] ∧ lengthys = 4%nat ∧ diag_ps ++ byte_pseb eo ys.*1 = diag_ps ++ byte_pseb eo xs.*1 ∧ agreesm′ overwritediag_ps ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritediag_ps ++ byte_pseb eo ys h
exit_spec :
Hexit_reg :
registryTAtom"_exit" = Someexit_spec
Hexit_ret :
Hexit_abi :
∀v : value, contract_abiexit_spec CVoid ArgW v
Hexit_pre :
∀n : Z m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → wim w h → contract_preexit_spec WIntn m w
Hexit_post :
∀args : listarg n : Z s : R.state m : mem w : world tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, M.E.invokeexit_spec CVoid args WIntn s m w tr CallReturnvs s′ m′ w′ → False
ob, sb :
Z
oreg, sreg, freg, ireg, xreg :
outp, errp :
Hout_live :
∃b : Z reg : region ps : listpiece × pval, ptr_capoutp = Objb ∧ stream_psoutp = PLiveb, VLivereg :: ps
Herr_live :
∃b : Z reg : region ps : listpiece × pval, ptr_caperrp = Objb ∧ stream_pserrp = PLiveb, VLivereg :: ps
Hstdout :
lookupTAtom"stdout" ge_globalsge = Someptr_addr ≔ ob; ptr_cap ≔ Objob
Hstderr :
lookupTAtom"stderr" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hob :
0 ≤ ob < 2 ^ 64
Hob8 :
ob mod 8 = 0
Hoend :
ob + 8 ≤ r_endoreg
Hsb :
0 ≤ sb < 2 ^ 64
Hsb8 :
sb mod 8 = 0
Hsend :
sb + 8 ≤ r_endsreg
Hout :
0 ≤ ptr_addroutp < 2 ^ 64
Herrp :
0 ≤ ptr_addrerrp < 2 ^ 64
Hfend :
65584 + 8 ≤ r_endfreg
Hiend :
65616 + 1 ≤ r_endireg
Hxend :
65776 + 4 ≤ r_endxreg
⊢
match find_directTAtom"close_stream" hello_module with
Somed
⇒
Somed
None
⇒
=

vm_compute

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
eb, eo :
Z
er :
cell :
world → ptr
rep :
mem → world → Prop
Herrno :
registryTAtom"__errno_location" = Someerrno_location_contractworld cell rep
Hlinked :
Hcell :
∀m : mem w : world h : gmappiece pval, wim w h → cellw = ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb
Hrep :
∀m : mem w : world h : gmappiece pval, wim w h → repm w ∧ errno_cellm cellw
ep :=
ptr_addr ≔ eb + eo; ptr_cap ≔ Objeb : ptr
stream_ps, closed_ps :
ptr → listpiece × pval
stream :=
λp : ptr ⇒ ptsstream_psp : ptr → iPropΣ
query_spec :
name → contractworld
Hquery_reg :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → registryg = Somequery_specg
Hquery_ret :
∀g : term k : class, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_returnsquery_specg = RClassk
Hquery_abi :
∀g : term k : class d : name v : value, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → contract_abiquery_specg CResultd k ArgP v
Hquery_pre :
∀g : term k : class p : ptr xs : listZ m : mem w : world h : gmappiece pval, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prequery_specg WPtrp m w
Hquery_post :
∀g : term k : class d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, g = TAtom"__fpending" ∧ k = L ∨ g = TAtom"ferror" ∧ k = W → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokequery_specg CResultd k ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z, vs = WIntn ∧ 0 ≤ n < 2 ^ if class_eqbk W then 32 else 64 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
fclose_spec :
Hfclose_reg :
registryTAtom"fclose" = Somefclose_spec
Hfclose_ret :
Hfclose_abi :
∀d : name v : value, contract_abifclose_spec CResultd W ArgP v
Hfclose_pre :
∀p : ptr xs : listZ m : mem w : world h : gmappiece pval, wim w h → ∀l : piece v : pval, l, v ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev → lengthxs = 4%nat → contract_prefclose_spec WPtrp m w
Hfclose_post :
∀d : name v : value p : ptr xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ stream_psp ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokefclose_spec CResultd W ArgP v WPtrp s m w tr CallReturnvs s′ m′ w′ → ∃n : Z ys : listZ, vs = WIntn ∧ 0 ≤ n < 2 ^ 32 ∧ lengthys = 4%nat ∧ closed_psp ++ byte_pseb eo ys.*1 = stream_psp ++ byte_pseb eo xs.*1 ∧ agreesm′ overwriteclosed_psp ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwriteclosed_psp ++ byte_pseb eo ys h
Kerrno :
∀xs : listZ m : mem w : world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveeb, VLiveer :: byte_pseb eo xs → h !! l = Somev → wim w h → wistore_bytesm eb + eo 4 0 w overwritePLiveeb, VLiveer :: byte_pseb eo le_bytes0 4 h
Heo :
0 ≤ eo
Herange :
0 ≤ eb + eo < 2 ^ 64
Heend :
eb + eo + 4 ≤ r_ender
He48 :
r_ender ≤ 2 ^ 48
fmt :=
ptr_addr ≔ 65744; ptr_cap ≔ Ro65744 : ptr
text :=
ptr_addr ≔ 65680; ptr_cap ≔ Ro65680 : ptr
diag_ps :
listpiece × pval
error_spec :
Herror_reg :
registryTAtom"error" = Someerror_spec
Herror_ret :
contract_returnserror_spec = RVoid
Herror_abi :
∀v fmtv txtv : value, contract_abierror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv
Herror_pre :
∀n : Z xs : listZ m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → lengthxs = 4%nat → agreesm h → wim w h → ∀l : piece v : pval, l, v ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev → contract_preerror_spec WInt0; WIntn; WPtrfmt; WPtrtext m w
Herror_post :
∀v fmtv txtv : value n : Z xs : listZ s : R.state m : mem w : world h : gmappiece pval tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, lengthxs = 4%nat → agreesm h → live_disjointm → R.readys m → wim w h → ∀l : piece v0 : pval, l, v0 ∈ diag_ps ++ byte_pseb eo xs → h !! l = Somev0 → M.E.invokeerror_spec CVoid ArgW Const0; ArgW v; ArgP fmtv; ArgP txtv WInt0; WIntn; WPtrfmt; WPtrtext s m w tr CallReturnvs s′ m′ w′ → ∃ys : listZ, vs = [ ] ∧ lengthys = 4%nat ∧ diag_ps ++ byte_pseb eo ys.*1 = diag_ps ++ byte_pseb eo xs.*1 ∧ agreesm′ overwritediag_ps ++ byte_pseb eo ys h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritediag_ps ++ byte_pseb eo ys h
exit_spec :
Hexit_reg :
registryTAtom"_exit" = Someexit_spec
Hexit_ret :
Hexit_abi :
∀v : value, contract_abiexit_spec CVoid ArgW v
Hexit_pre :
∀n : Z m : mem w : world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → wim w h → contract_preexit_spec WIntn m w
Hexit_post :
∀args : listarg n : Z s : R.state m : mem w : world tr : listevent vs : listword s′ : R.state m′ : mem w′ : world, M.E.invokeexit_spec CVoid args WIntn s m w tr CallReturnvs s′ m′ w′ → False
ob, sb :
Z
oreg, sreg, freg, ireg, xreg :
outp, errp :
Hout_live :
∃b : Z reg : region ps : listpiece × pval, ptr_capoutp = Objb ∧ stream_psoutp = PLiveb, VLivereg :: ps
Herr_live :
∃b : Z reg : region ps : listpiece × pval, ptr_caperrp = Objb ∧ stream_pserrp = PLiveb, VLivereg :: ps
Hstdout :
lookupTAtom"stdout" ge_globalsge = Someptr_addr ≔ ob; ptr_cap ≔ Objob
Hstderr :
lookupTAtom"stderr" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hob :
0 ≤ ob < 2 ^ 64
Hob8 :
ob mod 8 = 0
Hoend :
ob + 8 ≤ r_endoreg
Hsb :
0 ≤ sb < 2 ^ 64
Hsb8 :
sb mod 8 = 0
Hsend :
sb + 8 ≤ r_endsreg
Hout :
0 ≤ ptr_addroutp < 2 ^ 64
Herrp :
0 ≤ ptr_addrerrp < 2 ^ 64
Hfend :
65584 + 8 ≤ r_endfreg
Hiend :
65616 + 1 ≤ r_endireg
Hxend :
65776 + 4 ≤ r_endxreg
⊢
SomeDefinedfn_name ≔ TAtom"close_stream"; fn_linkage ≔ TAtom"export"; fn_ret ≔ RClassW; fn_params ≔ P, TAtom"v0"; fn_blocks ≔ b_label ≔ TAtom"start"; b_phis ≔ [ ]; b_insts ≔ CallCResultTAtom"v4" L GlobalTAtom"__fpending" ArgP TmpTAtom"v0"; LetTAtom"v5" W CmpNe L TmpTAtom"v4"; Const0; CallCResultTAtom"v9" W GlobalTAtom"ferror" ArgP TmpTAtom"v0"; LetTAtom"v10" W CmpNe W TmpTAtom"v9"; Const0; CallCResultTAtom"v14" W GlobalTAtom"fclose" ArgP TmpTAtom"v0"; LetTAtom"v15" W CmpNe W TmpTAtom"v14"; Const0; b_jump ≔ JBranchTmpTAtom"v10" ToTAtom"L22" ToTAtom"L21"; b_label ≔ TAtom"L21"; b_phis ≔ [ ]; b_insts ≔ [ ]; b_jump ≔ JBranchTmpTAtom"v15" ToTAtom"L24" ToTAtom"L22"; b_label ≔ TAtom"L24"; b_phis ≔ [ ]; b_insts ≔ [ ]; b_jump ≔ JBranchTmpTAtom"v5" ToTAtom"L22" ToTAtom"L27"; b_label ≔ TAtom"L27"; b_phis ≔ [ ]; b_insts ≔ CallCResultTAtom"v29" P GlobalTAtom"__errno_location" [ ]; LetTAtom"chk0" A Check0 4 Read 1 TmpTAtom"v29"; LetTAtom"v30" W RawLoadLdNarrowSw 0 TmpTAtom"chk0"; LetTAtom"v31" W CmpNe W TmpTAtom"v30"; Const9; b_jump ≔ JGotoToTAtom"L22"; b_label ≔ TAtom"L22"; b_phis ≔ PhiTAtom"v37" W TAtom"start", Const1; TAtom"L21", Const0; TAtom"L24", Const1; TAtom"L27", TmpTAtom"v31"; b_insts ≔ [ ]; b_jump ≔ JBranchTmpTAtom"v37" ToTAtom"L17" ToTAtom"L19"; b_label ≔ TAtom"L17"; b_phis ≔ [ ]; b_insts ≔ LetTAtom"v42" W CmpEq W TmpTAtom"v14"; Const0; b_jump ≔ JBranchTmpTAtom"v42" ToTAtom"L38" ToTAtom"L40"; b_label ≔ TAtom"L38"; b_phis ≔ [ ]; b_insts ≔ CallCResultTAtom"v43" P GlobalTAtom"__errno_location" [ ]; LetTAtom"chk1" A Check0 4 Write 1 TmpTAtom"v43"; RawStoreWw 0 Const0 TmpTAtom"chk1"; b_jump ≔ JGotoToTAtom"L40"; b_label ≔ TAtom"L40"; b_phis ≔ [ ]; b_insts ≔ [ ]; b_jump ≔ JRetConst4294967295; b_label ≔ TAtom"L19"; b_phis ≔ [ ]; b_insts ≔ [ ]; b_jump ≔ JRetConst0 = SomeDefinedfn_name ≔ TAtom"close_stream"; fn_linkage ≔ TAtom"export"; fn_ret ≔ RClassW; fn_params ≔ P, TAtom"v0"; fn_blocks ≔ b_label ≔ TAtom"start"; b_phis ≔ [ ]; b_insts ≔ CallCResultTAtom"v4" L GlobalTAtom"__fpending" ArgP TmpTAtom"v0"; LetTAtom"v5" W CmpNe L TmpTAtom"v4"; Const0; CallCResultTAtom"v9" W GlobalTAtom"ferror" ArgP TmpTAtom"v0"; LetTAtom"v10" W CmpNe W TmpTAtom"v9"; Const0; CallCResultTAtom"v14" W GlobalTAtom"fclose" ArgP TmpTAtom"v0"; LetTAtom"v15" W CmpNe W TmpTAtom"v14"; Const0; b_jump ≔ JBranchTmpTAtom"v10" ToTAtom"L22" ToTAtom"L21"; b_label ≔ TAtom"L21"; b_phis ≔ [ ]; b_insts ≔ [ ]; b_jump ≔ JBranchTmpTAtom"v15" ToTAtom"L24" ToTAtom"L22"; b_label ≔ TAtom"L24"; b_phis ≔ [ ]; b_insts ≔ [ ]; b_jump ≔ JBranchTmpTAtom"v5" ToTAtom"L22" ToTAtom"L27"; b_label ≔ TAtom"L27"; b_phis ≔ [ ]; b_insts ≔ CallCResultTAtom"v29" P GlobalTAtom"__errno_location" [ ]; LetTAtom"chk0" A Check0 4 Read 1 TmpTAtom"v29"; LetTAtom"v30" W RawLoadLdNarrowSw 0 TmpTAtom"chk0"; LetTAtom"v31" W CmpNe W TmpTAtom"v30"; Const9; b_jump ≔ JGotoToTAtom"L22"; b_label ≔ TAtom"L22"; b_phis ≔ PhiTAtom"v37" W TAtom"start", Const1; TAtom"L21", Const0; TAtom"L24", Const1; TAtom"L27", TmpTAtom"v31"; b_insts ≔ [ ]; b_jump ≔ JBranchTmpTAtom"v37" ToTAtom"L17" ToTAtom"L19"; b_label ≔ TAtom"L17"; b_phis ≔ [ ]; b_insts ≔ LetTAtom"v42" W CmpEq W TmpTAtom"v14"; Const0; b_jump ≔ JBranchTmpTAtom"v42" ToTAtom"L38" ToTAtom"L40"; b_label ≔ TAtom"L38"; b_phis ≔ [ ]; b_insts ≔ CallCResultTAtom"v43" P GlobalTAtom"__errno_location" [ ]; LetTAtom"chk1" A Check0 4 Write 1 TmpTAtom"v43"; RawStoreWw 0 Const0 TmpTAtom"chk1"; b_jump ≔ JGotoToTAtom"L40"; b_label ≔ TAtom"L40"; b_phis ≔ [ ]; b_insts ≔ [ ]; b_jump ≔ JRetConst4294967295; b_label ≔ TAtom"L19"; b_phis ≔ [ ]; b_insts ≔ [ ]; b_jump ≔ JRetConst0

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
unfold find_fn
rewrite proj1Hlinked
vm_compute
reflexivity

A null file name takes the unnamed-file diagnostic, then _exit. quotearg_colon is not called and needs no premise triple.

590Lemma close_stdout_error
∀ e xs fs Φ
lengthxs = 4%nat
lengthfs = 4%nat
live65584 freg −∗ bytes65584 0 replicate8 0 −∗ auxes65584 0 CNone −∗ live65776 xreg −∗ bytes65776 0 fs −∗ liveeb er −∗ byteseb eo xs −∗ ptsdiag_ps −∗ WPERunmkFrameclose_stdout_fn e [ ] None EnterTAtom"L0" SomeTAtom"L8" : cexpr {Φ}
Proof 62 steps Qed
intros Hxs Hfs
iIntros Hfl Hfb Hfa Hxl Hxb Hl Hx Hd
destruct close_lookups as Hfile & Hignore & Hfailure & Hfmt & Htext & p & Hdomain
iAssert pcell65584 0 mkPtr0 CNone with [Hfb Hfa] as Hfc
iFrame
iApply wp_check with Hfl
–reflexivity
–reflexivity
–change 65584 ≤ 65584
lia
–change 65584 + 8 ≤ r_endfreg
exact Hfend
–reflexivity
–iNext
iIntros Hfl
iApply wp_raw_load_pointer_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ freg with Hfl Hfc [] ; reflexivity | word_premise | reflexivity | addr_premise | reflexivity | cbn ; lia | done |
iNext
iIntros Hfl Hfc _
iApply wp_branch_ _ _ _ _ _ _ _ _ _ 0 ; word_premise |
iNext
co_enter "L61"
iNext
iApply wp_check with Hl ; reflexivity | word_premise | reflexivity | unfold ep ; addr_premise | unfold ep ; addr_premise | unfold ep ; addr_premise |
iNext
iIntros Hl
iApply wp_close_load_w with Hl Hx ; word_premise | exact Herange | exact Hxs |
iNext
iIntros Hl Hx
pose proof close_w_rangexs as Hwr
iApply wp_close_error with Hd Hx ; word_premise | unfold fmt ; word_premise | unfold text ; word_premise | apply close_w_range | exact Hxs |
iNext
iIntros ys Hys Hd Hx
iApply wp_goto
iNext
co_enter "L26"
iApply wp_check with Hxl ; reflexivity | word_premise | reflexivity | addr_premise | addr_premise | addr_premise |
iNext
iIntros Hxl
iApply wp_close_load_w with Hxl Hxb ; word_premise | cbn ; lia | exact Hfs |
iNext
iIntros Hxl Hxb
pose proof close_w_rangefs as Hfr

Close stderr after stdout was settled. Its failure exits directly; a successful return preserves all module cells and errno ownership.

634Lemma close_stdout_L91
∀ e xs fs Φ
lengthxs = 4%nat
lengthfs = 4%nat
streamerrp −∗ close_cellsfs −∗ liveeb er −∗ byteseb eo xs −∗ ptsdiag_ps −∗ ▷∀ys, ⌜lengthys = 4%nat⌝ −∗ close_cellsfs −∗ liveeb er −∗ byteseb eo ys −∗ ptsdiag_ps −∗ ΦRetVoid −∗ WPERunmkFrameclose_stdout_fn e [ ] None EnterTAtom"L91" SomeTAtom"L8" : cexpr {Φ}
Proof 49 steps Qed
intros Hxs Hfs
iIntros Hs Hcells Hl Hx Hd HΦ
iDestruct Hcells as (Hol & Hoc & Hsl & Hsc & Hfl & Hfb & Hfa & Hil & Hib & Hxl & Hxb)
destruct close_lookups as _ & _ & Hfailure & _
co_enter "L91"
assert Esb : raw_addresssb 0 = sb by unfold raw_address ; rewrite Z.add_0_r ; apply Z.mod_small ; exact Hsb
iApply wp_check with Hsl ; reflexivity | word_premise | reflexivity | change sb ≤ raw_addresssb 0 ; rewrite Esb ; lia | change raw_addresssb 0 + 8 ≤ r_endsreg ; rewrite Esb ; exact Hsend | change raw_addresssb 0 mod 8 = 0 ; rewrite Esb ; exact Hsb8 |
iNext
iIntros Hsl
iApply wp_close_stream_pointer with Hsl Hsc Hs ; exact Herr_live | word_premise | exact Hsb | exact Hsb8 | exact Herrp |
iNext
iIntros Hsl Hsc Hs
iApply wp_call_bind_ _ _ _ _ _ _ _ _ _ _ _ _ close_stream_fn invocationclose_stream_fn WPtrerrp ; word_premise | exact close_stream_linked | reflexivity |
iNext
iApply close_stream_spec with Hs Hl Hx ; exact Hxs |
iNext
iIntros r ys Hr Hys Hl Hx
iExists _
iSplit ; iPureIntro ; reflexivity |
iNext
destruct Hr as → | →
–iApply wp_branch_ _ _ _ _ _ _ _ _ _ 0 ; word_premise |
iNext
co_enter "L89"
iNext
iApply HΦ $! ys with [%] [Hol Hoc Hsl Hsc Hfl Hfb Hfa Hil Hib Hxl Hxb] Hl Hx Hd ; exact Hys | rewrite / close_cells ; iFrame
–iApply wp_branch_ _ _ _ _ _ _ _ _ _ 1 ; word_premise |
iNext
co_enter "L87"
iApply wp_check with Hxl ; reflexivity | word_premise | reflexivity | addr_premise | addr_premise | addr_premise |
iNext
iIntros Hxl
iApply wp_close_load_w with Hxl Hxb ; word_premise | cbn ; lia | exact Hfs |
iNext
iIntros Hxl Hxb
pose proof close_w_rangefs as Hfr

The exit callback closes stdout then stderr. It returns all module statics and pointer cells on normal return; errors either report the unnamed write failure and exit or, for stderr, exit directly.

679Lemma close_stdout_spec
∀ xs fs Φ
lengthxs = 4%nat
lengthfs = 4%nat
streamoutp −∗ streamerrp −∗ close_cellsfs −∗ liveeb er −∗ byteseb eo xs −∗ ptsdiag_ps −∗ ▷∀ys, ⌜lengthys = 4%nat⌝ −∗ close_cellsfs −∗ liveeb er −∗ byteseb eo ys −∗ ptsdiag_ps −∗ ΦRetVoid −∗ WPERuninvocationclose_stdout_fn [ ] : cexpr {Φ}
Proof 61 steps Qed
intros Hxs Hfs
iIntros Hout Herr Hcells Hl Hx Hd HΦ
iDestruct Hcells as (Hol & Hoc & Hsl & Hsc & Hfl & Hfb & Hfa & Hil & Hib & Hxl & Hxb)
destruct close_lookups as _ & Hignore & _
change invocationclose_stdout_fn [ ] with mkFrameclose_stdout_fn [ ] [ ] None EnterTAtom"start" None
co_enter "start"
assert Eob : raw_addressob 0 = ob by unfold raw_address ; rewrite Z.add_0_r ; apply Z.mod_small ; exact Hob
iApply wp_check with Hol ; reflexivity | word_premise | reflexivity | change ob ≤ raw_addressob 0 ; rewrite Eob ; lia | change raw_addressob 0 + 8 ≤ r_endoreg ; rewrite Eob ; exact Hoend | change raw_addressob 0 mod 8 = 0 ; rewrite Eob ; exact Hob8 |
iNext
iIntros Hol
iApply wp_close_stream_pointer with Hol Hoc Hout ; exact Hout_live | word_premise | exact Hob | exact Hob8 | exact Hout |
iNext
iIntros Hol Hoc Hout
iApply wp_call_bind_ _ _ _ _ _ _ _ _ _ _ _ _ close_stream_fn invocationclose_stream_fn WPtroutp ; word_premise | exact close_stream_linked | reflexivity |
iNext
iApply close_stream_spec with Hout Hl Hx ; exact Hxs |
iNext
iIntros r ys Hr Hys Hl Hx
iExists _
iSplit ; iPureIntro ; reflexivity |
iNext
destruct Hr as → | →
–iApply wp_branch_ _ _ _ _ _ _ _ _ _ 0 ; word_premise |
iNext
iApply wp_branch_ _ _ _ _ _ _ _ _ _ 0 ; word_premise |
iNext
iApply close_stdout_L91 with Herr [Hol Hoc Hsl Hsc Hfl Hfb Hfa Hil Hib Hxl Hxb] Hl Hx Hd HΦ ; exact Hys | exact Hfs | rewrite / close_cells ; iFrame
–iApply wp_branch_ _ _ _ _ _ _ _ _ _ 1 ; word_premise |
iNext
iApply wp_check with Hil ; reflexivity | word_premise | reflexivity | addr_premise | addr_premise | addr_premise |
iNext
iIntros Hil
iApply wp_raw_load_byte with Hil Hib ; reflexivity | word_premise | reflexivity | reflexivity | left ; reflexivity | addr_premise |
iNext
iIntros Hil Hib
iApply wp_branch_ _ _ _ _ _ _ _ _ _ 0 ; word_premise |
iNext
co_enter "L12"
iApply wp_goto
iNext
iApply wp_branch_ _ _ _ _ _ _ _ _ _ 1 ; word_premise |
iNext
iApply close_stdout_error with Hfl Hfb Hfa Hxl Hxb Hl Hx Hd ; exact Hys | exact Hfs

HelloCloseOn over a Logic instance of its own.

732Module HelloClose R : Runtime
733Module LG0 ≔ Logic R
Include HelloCloseOn R LG0