Fil-C on Nix

Filnix wiki

the formal campaign

rocq/theories/SlotLogic.v

rocq/programs/slot.c through the program logic of Logic.v: a callee that owns memory across calls, in the shape of gnulib's quotearg.

fill keeps one heap buffer in its static slot, with its size in slot_size. When a request does not fit it frees the buffer and mallocs a bigger one; then it memsets the request, terminates it, and returns the buffer. The caller may read the buffer until its next call of fill, which reuses it or frees it.

That ownership is the module invariant slot_inv: the two static objects, the pointer and size they hold, and the buffer's object with all its bytes and aux slots (buffer): null and size 0 before the first call. fill's triple (fill_spec) takes the invariant and lends the filled bytes to the caller (lent), with a wand that, given them back, gives the invariant back. The caller cannot keep the bytes across the next call: the next call needs the invariant, which needs them.

The grow path uses wp_free on the old buffer, whose life token then ends, and wp_malloc, whose fresh object becomes the new buffer (obj_block); both paths then go through the fill in fill_L6, with wp_memset and a byte store. use calls fill three times, through wp_call_bind and fill_spec, and reads the buffer after each call (use_spec).

slot_logic_safe is the labelled machine's safety from any memory whose static objects hold null and 0, over any runtime, whose free succeeds on null and the buffer (R.free_succeeds), and interp_slot_logic_safe instantiates it from the module's initial memory under the interpreter's runtime.

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 Machine Panics StepRules Symbolic ExternalCalls ExternalMachine Transport Pieces Heap ContractFrame Language Logic StringLogic MemLogic SlotCode HiLogic
Open Scope Z_scope
Open Scope list_scope
Arguments Z.add : simpl nomatch
Arguments Z.sub : simpl nomatch
Arguments Z.mul : simpl nomatch

Integer arithmetic on an unknown stays folded when a premise is computed (Symbolic.v).

The module

The checked module nanofil makes of slot.c (slot_term).

52Definition slot_module: module ≔
Somemd
⇒
md
None
⇒
[ ]

The fixture decodes to slot_module.

56Lemma slot_decodes
Explore proof 2 tactics

Initial goal

vm_compute

⊢
SomeIFuncfn_name ≔ TAtom"fill"; fn_linkage ≔ TAtom"export"; fn_ret ≔ RClassP; fn_params ≔ W, TAtom"v0"; L, TAtom"v2"; fn_blocks ≔ b_label ≔ TAtom"start"; b_phis ≔ [ ]; b_insts ≔ LetTAtom"v7" P Copy GlobalTAtom"slot_size"; LetTAtom"chk0" A Check0 8 Read 1 TmpTAtom"v7"; LetTAtom"v8" L RawLoadLdL 0 TmpTAtom"chk0"; LetTAtom"v10" W CmpUle L TmpTAtom"v8"; TmpTAtom"v2"; b_jump ≔ JBranchTmpTAtom"v10" ToTAtom"L4" ToTAtom"L6"; b_label ≔ TAtom"L4"; b_phis ≔ [ ]; b_insts ≔ LetTAtom"v11" P Copy GlobalTAtom"slot"; LetTAtom"chk1" A Check0 8 Read 8 TmpTAtom"v11"; LetTAtom"v12" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk1"; CallCVoid GlobalTAtom"free" ArgP TmpTAtom"v12"; LetTAtom"v13" P Copy GlobalTAtom"slot"; LetTAtom"v15" L Add TmpTAtom"v2"; Const1; CallCResultTAtom"v16" P GlobalTAtom"malloc" ArgL TmpTAtom"v15"; LetTAtom"chk2" A Check0 8 Write 8 TmpTAtom"v13"; RawStorePointer0 TmpTAtom"v16" TmpTAtom"chk2" AuxEnsure; LowerBarrier; RootedReload; LowerWrite; AddressWrite; LetTAtom"v17" P Copy GlobalTAtom"slot_size"; LetTAtom"chk3" A Check0 8 Write 1 TmpTAtom"v17"; RawStoreWl 0 TmpTAtom"v15" TmpTAtom"chk3"; b_jump ≔ JGotoToTAtom"L6"; b_label ≔ TAtom"L6"; b_phis ≔ [ ]; b_insts ≔ LetTAtom"v20" P Copy GlobalTAtom"slot"; LetTAtom"chk4" A Check0 8 Read 8 TmpTAtom"v20"; LetTAtom"v21" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk4"; CallCResultTAtom"v24" P GlobalTAtom"memset" ArgP TmpTAtom"v21"; ArgW TmpTAtom"v0"; ArgL TmpTAtom"v2"; LetTAtom"v25" P Copy GlobalTAtom"slot"; LetTAtom"chk5" A Check0 8 Read 8 TmpTAtom"v25"; LetTAtom"v26" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk5"; FlightTAtom"v28" Add FAddressTmpTAtom"v26"; FValueTmpTAtom"v2" LowerOfTmpTAtom"v26"; LetTAtom"chk6" A Check0 1 Write 1 TmpTAtom"v28"; RawStoreWb 0 Const0 TmpTAtom"chk6"; LetTAtom"v29" P Copy GlobalTAtom"slot"; LetTAtom"chk7" A Check0 8 Read 8 TmpTAtom"v29"; LetTAtom"v30" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk7"; b_jump ≔ JRetTmpTAtom"v30"; IFuncfn_name ≔ TAtom"use"; fn_linkage ≔ TAtom"export"; fn_ret ≔ RClassW; fn_params ≔ [ ]; fn_blocks ≔ b_label ≔ TAtom"start"; b_phis ≔ [ ]; b_insts ≔ CallCResultTAtom"v1" P GlobalTAtom"fill" ArgW Const97; ArgL Const8; FlightTAtom"v4" Add FAddressTmpTAtom"v1"; FValueConst7 LowerOfTmpTAtom"v1"; LetTAtom"chk0" A Check0 1 Read 1 TmpTAtom"v4"; LetTAtom"v5" W RawLoadLdNarrowSb 0 TmpTAtom"chk0"; CallCResultTAtom"v7" P GlobalTAtom"fill" ArgW Const98; ArgL Const3; LetTAtom"chk1" A Check0 1 Read 1 TmpTAtom"v7"; LetTAtom"v11" W RawLoadLdNarrowSb 0 TmpTAtom"chk1"; CallCResultTAtom"v13" P GlobalTAtom"fill" ArgW Const99; ArgL Const16; LetTAtom"v16" W Add TmpTAtom"v5"; TmpTAtom"v11"; FlightTAtom"v18" Add FAddressTmpTAtom"v13"; FValueConst15 LowerOfTmpTAtom"v13"; LetTAtom"chk2" A Check0 1 Read 1 TmpTAtom"v18"; LetTAtom"v19" W RawLoadLdNarrowSb 0 TmpTAtom"chk2"; LetTAtom"v20" W Add TmpTAtom"v16"; TmpTAtom"v19"; b_jump ≔ JRetTmpTAtom"v20"; IDataTAtom"slot" LLocal 8 Zero8; IDataTAtom"slot_size" LLocal 8 Zero8 = SomeIFuncfn_name ≔ TAtom"fill"; fn_linkage ≔ TAtom"export"; fn_ret ≔ RClassP; fn_params ≔ W, TAtom"v0"; L, TAtom"v2"; fn_blocks ≔ b_label ≔ TAtom"start"; b_phis ≔ [ ]; b_insts ≔ LetTAtom"v7" P Copy GlobalTAtom"slot_size"; LetTAtom"chk0" A Check0 8 Read 1 TmpTAtom"v7"; LetTAtom"v8" L RawLoadLdL 0 TmpTAtom"chk0"; LetTAtom"v10" W CmpUle L TmpTAtom"v8"; TmpTAtom"v2"; b_jump ≔ JBranchTmpTAtom"v10" ToTAtom"L4" ToTAtom"L6"; b_label ≔ TAtom"L4"; b_phis ≔ [ ]; b_insts ≔ LetTAtom"v11" P Copy GlobalTAtom"slot"; LetTAtom"chk1" A Check0 8 Read 8 TmpTAtom"v11"; LetTAtom"v12" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk1"; CallCVoid GlobalTAtom"free" ArgP TmpTAtom"v12"; LetTAtom"v13" P Copy GlobalTAtom"slot"; LetTAtom"v15" L Add TmpTAtom"v2"; Const1; CallCResultTAtom"v16" P GlobalTAtom"malloc" ArgL TmpTAtom"v15"; LetTAtom"chk2" A Check0 8 Write 8 TmpTAtom"v13"; RawStorePointer0 TmpTAtom"v16" TmpTAtom"chk2" AuxEnsure; LowerBarrier; RootedReload; LowerWrite; AddressWrite; LetTAtom"v17" P Copy GlobalTAtom"slot_size"; LetTAtom"chk3" A Check0 8 Write 1 TmpTAtom"v17"; RawStoreWl 0 TmpTAtom"v15" TmpTAtom"chk3"; b_jump ≔ JGotoToTAtom"L6"; b_label ≔ TAtom"L6"; b_phis ≔ [ ]; b_insts ≔ LetTAtom"v20" P Copy GlobalTAtom"slot"; LetTAtom"chk4" A Check0 8 Read 8 TmpTAtom"v20"; LetTAtom"v21" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk4"; CallCResultTAtom"v24" P GlobalTAtom"memset" ArgP TmpTAtom"v21"; ArgW TmpTAtom"v0"; ArgL TmpTAtom"v2"; LetTAtom"v25" P Copy GlobalTAtom"slot"; LetTAtom"chk5" A Check0 8 Read 8 TmpTAtom"v25"; LetTAtom"v26" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk5"; FlightTAtom"v28" Add FAddressTmpTAtom"v26"; FValueTmpTAtom"v2" LowerOfTmpTAtom"v26"; LetTAtom"chk6" A Check0 1 Write 1 TmpTAtom"v28"; RawStoreWb 0 Const0 TmpTAtom"chk6"; LetTAtom"v29" P Copy GlobalTAtom"slot"; LetTAtom"chk7" A Check0 8 Read 8 TmpTAtom"v29"; LetTAtom"v30" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk7"; b_jump ≔ JRetTmpTAtom"v30"; IFuncfn_name ≔ TAtom"use"; fn_linkage ≔ TAtom"export"; fn_ret ≔ RClassW; fn_params ≔ [ ]; fn_blocks ≔ b_label ≔ TAtom"start"; b_phis ≔ [ ]; b_insts ≔ CallCResultTAtom"v1" P GlobalTAtom"fill" ArgW Const97; ArgL Const8; FlightTAtom"v4" Add FAddressTmpTAtom"v1"; FValueConst7 LowerOfTmpTAtom"v1"; LetTAtom"chk0" A Check0 1 Read 1 TmpTAtom"v4"; LetTAtom"v5" W RawLoadLdNarrowSb 0 TmpTAtom"chk0"; CallCResultTAtom"v7" P GlobalTAtom"fill" ArgW Const98; ArgL Const3; LetTAtom"chk1" A Check0 1 Read 1 TmpTAtom"v7"; LetTAtom"v11" W RawLoadLdNarrowSb 0 TmpTAtom"chk1"; CallCResultTAtom"v13" P GlobalTAtom"fill" ArgW Const99; ArgL Const16; LetTAtom"v16" W Add TmpTAtom"v5"; TmpTAtom"v11"; FlightTAtom"v18" Add FAddressTmpTAtom"v13"; FValueConst15 LowerOfTmpTAtom"v13"; LetTAtom"chk2" A Check0 1 Read 1 TmpTAtom"v18"; LetTAtom"v19" W RawLoadLdNarrowSb 0 TmpTAtom"chk2"; LetTAtom"v20" W Add TmpTAtom"v16"; TmpTAtom"v19"; b_jump ≔ JRetTmpTAtom"v20"; IDataTAtom"slot" LLocal 8 Zero8; IDataTAtom"slot_size" LLocal 8 Zero8

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
vm_compute
reflexivity

The module's i-th function, or an empty one.

60Definition slot_nthi : nat : func ≔
match nth_errorslot_module i with
SomeIFuncf
⇒
f
_
⇒
mkFuncTAtom"none" TAtom"export" RVoid [ ] [ ]

fill: grow the buffer if need be, fill it, lend it.

67Definition fill_fn: func ≔
Eval vm_compute in slot_nth0

use: three calls of fill, each read after it.

69Definition use_fn: func ≔
Eval vm_compute in slot_nth1

The identity of the static slot, which holds the buffer.

72Definition slot_b: Z ≔
65568

The identity of the static slot_size, which holds its size.

74Definition size_b: Z ≔
65600

slot's region.

76Definition slot_reg: region ≔

slot_size's region.

78Definition size_reg: region ≔

The module's symbols.

81Definition slot_globals: listname × ptr ≔
TAtom"slot_size", mkPtrsize_b Objsize_b; TAtom"slot", mkPtrslot_b Objslot_b; TAtom"use", mkPtr65552 FnTAtom"use"; TAtom"fill", mkPtr65536 FnTAtom"fill"

Laying out the module gives slot_globals.

86Lemma slot_layout
Explore proof 2 tactics

Initial goal

⊢

vm_compute

⊢
SomeTAtom"slot_size", ptr_addr ≔ 65600; ptr_cap ≔ Obj65600; TAtom"slot", ptr_addr ≔ 65568; ptr_cap ≔ Obj65568; TAtom"use", ptr_addr ≔ 65552; ptr_cap ≔ FnTAtom"use"; TAtom"fill", ptr_addr ≔ 65536; ptr_cap ≔ FnTAtom"fill" = SomeTAtom"slot_size", ptr_addr ≔ 65600; ptr_cap ≔ Obj65600; TAtom"slot", ptr_addr ≔ 65568; ptr_cap ≔ Obj65568; TAtom"use", ptr_addr ≔ 65552; ptr_cap ≔ FnTAtom"use"; TAtom"fill", ptr_addr ≔ 65536; ptr_cap ≔ FnTAtom"fill"

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
vm_compute
reflexivity

Block l of f, or an empty one.

90Definition sblkf : func l : String.string : block ≔
Someb
⇒
b
None
⇒

fill's entry: does the request fit?

97Definition f_start: block ≔
Eval vm_compute in sblkfill_fn "start"

The grow path: free the old buffer, malloc a new one.

99Definition f_L4: block ≔
Eval vm_compute in sblkfill_fn "L4"

The fill: memset, the terminator, return the buffer.

101Definition f_L6: block ≔
Eval vm_compute in sblkfill_fn "L6"

use's one block.

103Definition u_start: block ≔
Eval vm_compute in sblkuse_fn "start"

fill has its entry.

106Lemma find_f_start
Explore proof 2 tactics

Initial goal

vm_compute

⊢
Someb_label ≔ TAtom"start"; b_phis ≔ [ ]; b_insts ≔ LetTAtom"v7" P Copy GlobalTAtom"slot_size"; LetTAtom"chk0" A Check0 8 Read 1 TmpTAtom"v7"; LetTAtom"v8" L RawLoadLdL 0 TmpTAtom"chk0"; LetTAtom"v10" W CmpUle L TmpTAtom"v8"; TmpTAtom"v2"; b_jump ≔ JBranchTmpTAtom"v10" ToTAtom"L4" ToTAtom"L6" = Someb_label ≔ TAtom"start"; b_phis ≔ [ ]; b_insts ≔ LetTAtom"v7" P Copy GlobalTAtom"slot_size"; LetTAtom"chk0" A Check0 8 Read 1 TmpTAtom"v7"; LetTAtom"v8" L RawLoadLdL 0 TmpTAtom"chk0"; LetTAtom"v10" W CmpUle L TmpTAtom"v8"; TmpTAtom"v2"; b_jump ≔ JBranchTmpTAtom"v10" ToTAtom"L4" ToTAtom"L6"

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
vm_compute
reflexivity

fill has its grow path.

109Lemma find_f_L4
Explore proof 2 tactics

Initial goal

vm_compute

⊢

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
vm_compute
reflexivity

fill has its fill.

112Lemma find_f_L6
Explore proof 2 tactics

Initial goal

vm_compute

⊢
Someb_label ≔ TAtom"L6"; b_phis ≔ [ ]; b_insts ≔ LetTAtom"v20" P Copy GlobalTAtom"slot"; LetTAtom"chk4" A Check0 8 Read 8 TmpTAtom"v20"; LetTAtom"v21" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk4"; CallCResultTAtom"v24" P GlobalTAtom"memset" ArgP TmpTAtom"v21"; ArgW TmpTAtom"v0"; ArgL TmpTAtom"v2"; LetTAtom"v25" P Copy GlobalTAtom"slot"; LetTAtom"chk5" A Check0 8 Read 8 TmpTAtom"v25"; LetTAtom"v26" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk5"; FlightTAtom"v28" Add FAddressTmpTAtom"v26"; FValueTmpTAtom"v2" LowerOfTmpTAtom"v26"; LetTAtom"chk6" A Check0 1 Write 1 TmpTAtom"v28"; RawStoreWb 0 Const0 TmpTAtom"chk6"; LetTAtom"v29" P Copy GlobalTAtom"slot"; LetTAtom"chk7" A Check0 8 Read 8 TmpTAtom"v29"; LetTAtom"v30" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk7"; b_jump ≔ JRetTmpTAtom"v30" = Someb_label ≔ TAtom"L6"; b_phis ≔ [ ]; b_insts ≔ LetTAtom"v20" P Copy GlobalTAtom"slot"; LetTAtom"chk4" A Check0 8 Read 8 TmpTAtom"v20"; LetTAtom"v21" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk4"; CallCResultTAtom"v24" P GlobalTAtom"memset" ArgP TmpTAtom"v21"; ArgW TmpTAtom"v0"; ArgL TmpTAtom"v2"; LetTAtom"v25" P Copy GlobalTAtom"slot"; LetTAtom"chk5" A Check0 8 Read 8 TmpTAtom"v25"; LetTAtom"v26" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk5"; FlightTAtom"v28" Add FAddressTmpTAtom"v26"; FValueTmpTAtom"v2" LowerOfTmpTAtom"v26"; LetTAtom"chk6" A Check0 1 Write 1 TmpTAtom"v28"; RawStoreWb 0 Const0 TmpTAtom"chk6"; LetTAtom"v29" P Copy GlobalTAtom"slot"; LetTAtom"chk7" A Check0 8 Read 8 TmpTAtom"v29"; LetTAtom"v30" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk7"; b_jump ≔ JRetTmpTAtom"v30"

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
vm_compute
reflexivity

use has its block.

115Lemma find_u_start
Explore proof 2 tactics

Initial goal

vm_compute

⊢
Someb_label ≔ TAtom"start"; b_phis ≔ [ ]; b_insts ≔ CallCResultTAtom"v1" P GlobalTAtom"fill" ArgW Const97; ArgL Const8; FlightTAtom"v4" Add FAddressTmpTAtom"v1"; FValueConst7 LowerOfTmpTAtom"v1"; LetTAtom"chk0" A Check0 1 Read 1 TmpTAtom"v4"; LetTAtom"v5" W RawLoadLdNarrowSb 0 TmpTAtom"chk0"; CallCResultTAtom"v7" P GlobalTAtom"fill" ArgW Const98; ArgL Const3; LetTAtom"chk1" A Check0 1 Read 1 TmpTAtom"v7"; LetTAtom"v11" W RawLoadLdNarrowSb 0 TmpTAtom"chk1"; CallCResultTAtom"v13" P GlobalTAtom"fill" ArgW Const99; ArgL Const16; LetTAtom"v16" W Add TmpTAtom"v5"; TmpTAtom"v11"; FlightTAtom"v18" Add FAddressTmpTAtom"v13"; FValueConst15 LowerOfTmpTAtom"v13"; LetTAtom"chk2" A Check0 1 Read 1 TmpTAtom"v18"; LetTAtom"v19" W RawLoadLdNarrowSb 0 TmpTAtom"chk2"; LetTAtom"v20" W Add TmpTAtom"v16"; TmpTAtom"v19"; b_jump ≔ JRetTmpTAtom"v20" = Someb_label ≔ TAtom"start"; b_phis ≔ [ ]; b_insts ≔ CallCResultTAtom"v1" P GlobalTAtom"fill" ArgW Const97; ArgL Const8; FlightTAtom"v4" Add FAddressTmpTAtom"v1"; FValueConst7 LowerOfTmpTAtom"v1"; LetTAtom"chk0" A Check0 1 Read 1 TmpTAtom"v4"; LetTAtom"v5" W RawLoadLdNarrowSb 0 TmpTAtom"chk0"; CallCResultTAtom"v7" P GlobalTAtom"fill" ArgW Const98; ArgL Const3; LetTAtom"chk1" A Check0 1 Read 1 TmpTAtom"v7"; LetTAtom"v11" W RawLoadLdNarrowSb 0 TmpTAtom"chk1"; CallCResultTAtom"v13" P GlobalTAtom"fill" ArgW Const99; ArgL Const16; LetTAtom"v16" W Add TmpTAtom"v5"; TmpTAtom"v11"; FlightTAtom"v18" Add FAddressTmpTAtom"v13"; FValueConst15 LowerOfTmpTAtom"v13"; LetTAtom"chk2" A Check0 1 Read 1 TmpTAtom"v18"; LetTAtom"v19" W RawLoadLdNarrowSb 0 TmpTAtom"chk2"; LetTAtom"v20" W Add TmpTAtom"v16"; TmpTAtom"v19"; b_jump ≔ JRetTmpTAtom"v20"

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
vm_compute
reflexivity

fill called with the int c and the size n.

119Definition fill_entryc n : Z : frame ≔
mkFramefill_fn putTAtom"v2" WIntn putTAtom"v0" WIntc [ ] [ ] None EnterTAtom"start" None

A call of fill starts it at fill_entry.

124Lemma fill_call_frame
Explore proof 1 tactics

Initial goal

c, n :
Z

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
reflexivity

use called.

128Definition use_entry: frame ≔
mkFrameuse_fn [ ] [ ] None EnterTAtom"start" None

slot.c's contracts: malloc's and memset's, over no world.

131Definition slot_registrysymbol : name : optioncontractunit ≔
name_eqbsymbol TAtom"malloc"
→
name_eqbsymbol TAtom"memset"
→
else
None

A fresh object's pieces, all zero bytes and empty slots, are a block from offset 0 of its whole extent.

138Lemma obj_block
∀ base q
0 ≤ req_extentq
obj_psbase q = block_psbase mkRegionbase base + req_extentq req_kindq Live 0 replicateZ.to_natreq_extentq 0 replicateZ.to_natreq_extentq CNone
Explore proof 6 tactics

Initial goal

base :
Z
⊢
0 ≤ req_extentq → obj_psbase q = block_psbase r_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live 0 replicateZ.to_natreq_extentq 0 replicateZ.to_natreq_extentq CNone

intros Hq

base :
Z
Hq :
0 ≤ req_extentq
⊢
obj_psbase q = block_psbase r_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live 0 replicateZ.to_natreq_extentq 0 replicateZ.to_natreq_extentq CNone

unfold obj_ps , block_ps , byte_ps , aux_ps

base :
Z
Hq :
0 ≤ req_extentq
⊢
PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live :: λi : Z ⇒ PBytebase i, VByte0 <$> seqZ0 req_extentq ++ λi : Z ⇒ PAuxbase i, VAuxCNone <$> seqZ0 req_extentq = PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live :: zip_withλi x : Z ⇒ PBytebase i, VBytex seqZ0 lengthreplicateZ.to_natreq_extentq 0 replicateZ.to_natreq_extentq 0 ++ zip_withλi : Z c : cap ⇒ PAuxbase i, VAuxc seqZ0 lengthreplicateZ.to_natreq_extentq CNone replicateZ.to_natreq_extentq CNone

rewrite ! length_replicate Z2Nat.id ; | exact Hq

base :
Z
Hq :
0 ≤ req_extentq
⊢
PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live :: λi : Z ⇒ PBytebase i, VByte0 <$> seqZ0 req_extentq ++ λi : Z ⇒ PAuxbase i, VAuxCNone <$> seqZ0 req_extentq = PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live :: zip_withλi x : Z ⇒ PBytebase i, VBytex seqZ0 req_extentq replicateZ.to_natreq_extentq 0 ++ zip_withλi : Z c : cap ⇒ PAuxbase i, VAuxc seqZ0 req_extentq replicateZ.to_natreq_extentq CNone

rewrite zip_with_replicate_r_eq_ Z.to_natreq_extentq ; | apply length_seqZ

base :
Z
Hq :
0 ≤ req_extentq
⊢
PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live :: λi : Z ⇒ PBytebase i, VByte0 <$> seqZ0 req_extentq ++ λi : Z ⇒ PAuxbase i, VAuxCNone <$> seqZ0 req_extentq = PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live :: flipλi x : Z ⇒ PBytebase i, VBytex 0 <$> seqZ0 req_extentq ++ zip_withλi : Z c : cap ⇒ PAuxbase i, VAuxc seqZ0 req_extentq replicateZ.to_natreq_extentq CNone

rewrite zip_with_replicate_r_eq_ Z.to_natreq_extentq ; | apply length_seqZ

base :
Z
Hq :
0 ≤ req_extentq
⊢
PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live :: λi : Z ⇒ PBytebase i, VByte0 <$> seqZ0 req_extentq ++ λi : Z ⇒ PAuxbase i, VAuxCNone <$> seqZ0 req_extentq = PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live :: flipλi x : Z ⇒ PBytebase i, VBytex 0 <$> seqZ0 req_extentq ++ flipλi : Z c : cap ⇒ PAuxbase i, VAuxc CNone <$> seqZ0 req_extentq

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hq
rewrite ! length_replicate Z2Nat.id ; | exact Hq
rewrite zip_with_replicate_r_eq_ Z.to_natreq_extentq ; | apply length_seqZ
rewrite zip_with_replicate_r_eq_ Z.to_natreq_extentq ; | apply length_seqZ
reflexivity

Prove an address premise: drop the wraps of raw_address and of a flight's sum where arithmetic shows them the identity, then arithmetic.

152Ltac addr_premise  ≔

Prove a premise about a static object's address: by computation.

155Ltac static_premise  ≔
unfold slot_b , size_b , slot_reg , size_reg ; vm_compute ; first reflexivity | congruence

Prove a premise that names words: by computation, with the environment's facts.

159Ltac word_premise  ≔
first reflexivity | compute_premise

The pieces a run of use starts owning: the static objects, slot holding null and slot_size holding 0.

163Definition slot_ps0: listpiece × pval ≔

No piece of slot_ps0 is listed twice.

168Lemma slot_ps0_nodup
NoDupslot_ps0.*1
Explore proof 4 tactics

Initial goal

⊢
NoDupslot_ps0.*1

cbv [ slot_ps0 cell fmap list_fmap fst map app slot_b size_b ]

⊢
NoDupPLive65568; PLive65600; PAux65568 0; PByte65568 0 + 0; PByte65568 0 + 1; PByte65568 0 + 2; PByte65568 0 + 3; PByte65568 0 + 4; PByte65568 0 + 5; PByte65568 0 + 6; PByte65568 0 + 7; PByte65600 0 + 0; PByte65600 0 + 1; PByte65600 0 + 2; PByte65600 0 + 3; PByte65600 0 + 4; PByte65600 0 + 5; PByte65600 0 + 6; PByte65600 0 + 7

cbn [ Z.add ]

⊢
NoDupPLive65568; PLive65600; PAux65568 0; PByte65568 0; PByte65568 1; PByte65568 2; PByte65568 3; PByte65568 4; PByte65568 5; PByte65568 6; PByte65568 7; PByte65600 0; PByte65600 1; PByte65600 2; PByte65600 3; PByte65600 4; PByte65600 5; PByte65600 6; PByte65600 7

repeat apply NoDup_cons_2 ; intros Hin ; repeat apply elem_of_cons in Hin as Hin | Hin ; discriminate Hin | ; apply elem_of_nil in Hin ; exact Hin |

⊢
NoDup[ ]

apply NoDup_nil_2

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
cbv [ slot_ps0 cell fmap list_fmap fst map app slot_b size_b ]
cbn [ Z.add ]
repeat apply NoDup_cons_2 ; intros Hin ; repeat apply elem_of_cons in Hin as Hin | Hin ; discriminate Hin | ; apply elem_of_nil in Hin ; exact Hin |
apply NoDup_nil_2

slot.c over any runtime R.

178Module SlotLogic R : Runtime
179Module ML ≔ MemLogic R
180Module SL ≔ ML.SL
181Module LG ≔ ML.LG
182Module L ≔ LG.L
Import L LG SL ML

The linked genv: the module, its symbols, R's free.

186Definition slot_ge: genv ≔

fill is a function of the module.

189Lemma find_fill
Explore proof 2 tactics

Initial goal

vm_compute

⊢
SomeDefinedfn_name ≔ TAtom"fill"; fn_linkage ≔ TAtom"export"; fn_ret ≔ RClassP; fn_params ≔ W, TAtom"v0"; L, TAtom"v2"; fn_blocks ≔ b_label ≔ TAtom"start"; b_phis ≔ [ ]; b_insts ≔ LetTAtom"v7" P Copy GlobalTAtom"slot_size"; LetTAtom"chk0" A Check0 8 Read 1 TmpTAtom"v7"; LetTAtom"v8" L RawLoadLdL 0 TmpTAtom"chk0"; LetTAtom"v10" W CmpUle L TmpTAtom"v8"; TmpTAtom"v2"; b_jump ≔ JBranchTmpTAtom"v10" ToTAtom"L4" ToTAtom"L6"; b_label ≔ TAtom"L4"; b_phis ≔ [ ]; b_insts ≔ LetTAtom"v11" P Copy GlobalTAtom"slot"; LetTAtom"chk1" A Check0 8 Read 8 TmpTAtom"v11"; LetTAtom"v12" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk1"; CallCVoid GlobalTAtom"free" ArgP TmpTAtom"v12"; LetTAtom"v13" P Copy GlobalTAtom"slot"; LetTAtom"v15" L Add TmpTAtom"v2"; Const1; CallCResultTAtom"v16" P GlobalTAtom"malloc" ArgL TmpTAtom"v15"; LetTAtom"chk2" A Check0 8 Write 8 TmpTAtom"v13"; RawStorePointer0 TmpTAtom"v16" TmpTAtom"chk2" AuxEnsure; LowerBarrier; RootedReload; LowerWrite; AddressWrite; LetTAtom"v17" P Copy GlobalTAtom"slot_size"; LetTAtom"chk3" A Check0 8 Write 1 TmpTAtom"v17"; RawStoreWl 0 TmpTAtom"v15" TmpTAtom"chk3"; b_jump ≔ JGotoToTAtom"L6"; b_label ≔ TAtom"L6"; b_phis ≔ [ ]; b_insts ≔ LetTAtom"v20" P Copy GlobalTAtom"slot"; LetTAtom"chk4" A Check0 8 Read 8 TmpTAtom"v20"; LetTAtom"v21" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk4"; CallCResultTAtom"v24" P GlobalTAtom"memset" ArgP TmpTAtom"v21"; ArgW TmpTAtom"v0"; ArgL TmpTAtom"v2"; LetTAtom"v25" P Copy GlobalTAtom"slot"; LetTAtom"chk5" A Check0 8 Read 8 TmpTAtom"v25"; LetTAtom"v26" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk5"; FlightTAtom"v28" Add FAddressTmpTAtom"v26"; FValueTmpTAtom"v2" LowerOfTmpTAtom"v26"; LetTAtom"chk6" A Check0 1 Write 1 TmpTAtom"v28"; RawStoreWb 0 Const0 TmpTAtom"chk6"; LetTAtom"v29" P Copy GlobalTAtom"slot"; LetTAtom"chk7" A Check0 8 Read 8 TmpTAtom"v29"; LetTAtom"v30" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk7"; b_jump ≔ JRetTmpTAtom"v30" = SomeDefinedfn_name ≔ TAtom"fill"; fn_linkage ≔ TAtom"export"; fn_ret ≔ RClassP; fn_params ≔ W, TAtom"v0"; L, TAtom"v2"; fn_blocks ≔ b_label ≔ TAtom"start"; b_phis ≔ [ ]; b_insts ≔ LetTAtom"v7" P Copy GlobalTAtom"slot_size"; LetTAtom"chk0" A Check0 8 Read 1 TmpTAtom"v7"; LetTAtom"v8" L RawLoadLdL 0 TmpTAtom"chk0"; LetTAtom"v10" W CmpUle L TmpTAtom"v8"; TmpTAtom"v2"; b_jump ≔ JBranchTmpTAtom"v10" ToTAtom"L4" ToTAtom"L6"; b_label ≔ TAtom"L4"; b_phis ≔ [ ]; b_insts ≔ LetTAtom"v11" P Copy GlobalTAtom"slot"; LetTAtom"chk1" A Check0 8 Read 8 TmpTAtom"v11"; LetTAtom"v12" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk1"; CallCVoid GlobalTAtom"free" ArgP TmpTAtom"v12"; LetTAtom"v13" P Copy GlobalTAtom"slot"; LetTAtom"v15" L Add TmpTAtom"v2"; Const1; CallCResultTAtom"v16" P GlobalTAtom"malloc" ArgL TmpTAtom"v15"; LetTAtom"chk2" A Check0 8 Write 8 TmpTAtom"v13"; RawStorePointer0 TmpTAtom"v16" TmpTAtom"chk2" AuxEnsure; LowerBarrier; RootedReload; LowerWrite; AddressWrite; LetTAtom"v17" P Copy GlobalTAtom"slot_size"; LetTAtom"chk3" A Check0 8 Write 1 TmpTAtom"v17"; RawStoreWl 0 TmpTAtom"v15" TmpTAtom"chk3"; b_jump ≔ JGotoToTAtom"L6"; b_label ≔ TAtom"L6"; b_phis ≔ [ ]; b_insts ≔ LetTAtom"v20" P Copy GlobalTAtom"slot"; LetTAtom"chk4" A Check0 8 Read 8 TmpTAtom"v20"; LetTAtom"v21" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk4"; CallCResultTAtom"v24" P GlobalTAtom"memset" ArgP TmpTAtom"v21"; ArgW TmpTAtom"v0"; ArgL TmpTAtom"v2"; LetTAtom"v25" P Copy GlobalTAtom"slot"; LetTAtom"chk5" A Check0 8 Read 8 TmpTAtom"v25"; LetTAtom"v26" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk5"; FlightTAtom"v28" Add FAddressTmpTAtom"v26"; FValueTmpTAtom"v2" LowerOfTmpTAtom"v26"; LetTAtom"chk6" A Check0 1 Write 1 TmpTAtom"v28"; RawStoreWb 0 Const0 TmpTAtom"chk6"; LetTAtom"v29" P Copy GlobalTAtom"slot"; LetTAtom"chk7" A Check0 8 Read 8 TmpTAtom"v29"; LetTAtom"v30" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk7"; b_jump ≔ JRetTmpTAtom"v30"

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
vm_compute
reflexivity
192Section proof
194Section wp
195Context `{!invGS_genhlc Σ, !gen_heapGSpiece pval Σ}

The Iris instance of slot.c: malloc's and memset's contracts, no world.

199Instance slot_irisGS: irisGS_genhlc nanofil_langslot_registry slot_ge Σ ≔

The expressions of slot.c's language.

203Notation sexpr ≔ language.exprnanofil_langslot_registry slot_ge

The module invariant

What slot holding p and slot_size holding sz own: nothing for null and size 0; else the heap object p's capability names, at a multiple of 16, live, with every byte and aux slot of its first length xs bytes, at least sz of them.

211Definition bufferp : ptr sz : Z : iPropΣ ≔
⌜p = null ∧ sz = 0⌝ ∨ ∃b reg xs cs, ⌜p = mkPtrb Objb ∧ 0 < b ∧ b mod 16 = 0 ∧ r_kindreg = Heap ∧ 0 < sz ≤ Z.of_natlengthxs ∧ lengthcs = lengthxs ∧ b + Z.of_natlengthxs ≤ r_endreg ∧ r_endreg ≤ 2 ^ 48⌝ ∗ liveb reg ∗ bytesb 0 xs ∗ auxesb 0 cs

The module invariant: both static objects, the pointer and size they hold, and the buffer they describe.

220Definition slot_inv: iPropΣ ≔
liveslot_b slot_reg ∗ livesize_b size_reg ∗ ∃p sz, ⌜0 ≤ sz < 2 ^ 48⌝ ∗ pcellslot_b 0 p ∗ icellsize_b 0 sz ∗ bufferp sz

What fill lends its caller: the life of the buffer b and its first n bytes, all c's low byte, with the byte after them inside its bounds; and, for those given back, the module invariant.

227Definition lentb : Z reg : region n c : Z : iPropΣ ≔
⌜0 < b ∧ b + n < r_endreg ∧ r_endreg ≤ 2 ^ 48⌝ ∗ liveb reg ∗ bytesb 0 replicateZ.to_natn c mod 256 ∗ liveb reg −∗ bytesb 0 replicateZ.to_natn c mod 256 −∗ slot_inv

Bytes

The bytes ys, then x, then zs, are ys's, x's, then zs's.

234Lemma bytes_split
∀ b o ys x zs
bytesb o ys ++ x :: zs ⊣⊢ bytesb o ys ∗ ibyteb o + Z.of_natlengthys x ∗ bytesb o + Z.of_natlengthys + 1 zs
Explore proof 3 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b, o :
Z
ys :
listZ
x :
Z
zs :
listZ
⊢
bytesb o ys ++ x :: zs ⊣⊢ bytesb o ys ∗ ibyteb o + lengthys x ∗ bytesb o + lengthys + 1 zs

rewrite / bytes / ibyte / pts byte_ps_app byte_ps_cons big_sepL_app big_sepL_cons big_sepL_singleton

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b, o :
Z
ys :
listZ
x :
Z
zs :
listZ
⊢
∗y∈byte_psb o yspointstoy.1 DfracOwn1 y.2 ∗ pointstoPByteb o + lengthys, VBytex.1 DfracOwn1 PByteb o + lengthys, VBytex.2 ∗ ∗y∈byte_psb o + lengthys + 1 zspointstoy.1 DfracOwn1 y.2 ⊣⊢ ∗lv∈byte_psb o yspointstolv.1 DfracOwn1 lv.2 ∗ pointstoPByteb o + lengthys, VBytex.1 DfracOwn1 PByteb o + lengthys, VBytex.2 ∗ ∗lv∈byte_psb o + lengthys + 1 zspointstolv.1 DfracOwn1 lv.2

replace o + Z.of_natlengthys + 1 with o + Z.of_natlengthys + 1 by lia

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b, o :
Z
ys :
listZ
x :
Z
zs :
listZ
⊢
∗y∈byte_psb o yspointstoy.1 DfracOwn1 y.2 ∗ pointstoPByteb o + lengthys, VBytex.1 DfracOwn1 PByteb o + lengthys, VBytex.2 ∗ ∗y∈byte_psb o + lengthys + 1 zspointstoy.1 DfracOwn1 y.2 ⊣⊢ ∗lv∈byte_psb o yspointstolv.1 DfracOwn1 lv.2 ∗ pointstoPByteb o + lengthys, VBytex.1 DfracOwn1 PByteb o + lengthys, VBytex.2 ∗ ∗lv∈byte_psb o + lengthys + 1 zspointstolv.1 DfracOwn1 lv.2

done

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
rewrite / bytes / ibyte / pts byte_ps_app byte_ps_cons big_sepL_app big_sepL_cons big_sepL_singleton
replace o + Z.of_natlengthys + 1 with o + Z.of_natlengthys + 1 by lia
done

The slots cs1 then cs2 are cs1's, then cs2's.

243Lemma auxes_app
∀ b o cs1 cs2
auxesb o cs1 ++ cs2 ⊣⊢ auxesb o cs1 ∗ auxesb o + Z.of_natlengthcs1 cs2
Explore proof 12 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b, o :
Z
cs1, cs2 :
listcap
⊢
auxesb o cs1 ++ cs2 ⊣⊢ auxesb o cs1 ∗ auxesb o + lengthcs1 cs2

rewrite / auxes / pts - big_sepL_app

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b, o :
Z
cs1, cs2 :
listcap
⊢
∗lv∈aux_psb o cs1 ++ cs2pointstolv.1 DfracOwn1 lv.2 ⊣⊢ ∗y∈aux_psb o cs1 ++ aux_psb o + lengthcs1 cs2pointstoy.1 DfracOwn1 y.2

f_equiv

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b, o :
Z
cs1, cs2 :
listcap
⊢
aux_ps b o (cs1 ++ cs2) ≡ₚ aux_ps b o cs1 ++ aux_ps b (o + length cs1) cs2

revert o

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
cs1, cs2 :
listcap
⊢
∀ o : Z, aux_ps b o (cs1 ++ cs2) ≡ₚ aux_ps b o cs1 ++ aux_ps b (o + length cs1) cs2

induction cs1 as | c cs1 IH ; intros o

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
cs2 :
listcap
o :
Z
⊢
aux_ps b o ([] ++ cs2) ≡ₚ aux_ps b o [] ++ aux_ps b (o + length []) cs2
focused goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
c :
cs1, cs2 :
listcap
IH : ∀ o : Z, aux_ps b o (cs1 ++ cs2) ≡ₚ aux_ps b o cs1 ++ aux_ps b (o + length cs1) cs2
o :
Z
⊢
aux_ps b o ((c :: cs1) ++ cs2) ≡ₚ aux_ps b o (c :: cs1) ++ aux_ps b (o + length (c :: cs1)) cs2

–cbn

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
cs2 :
listcap
o :
Z
⊢
aux_ps b o cs2 ≡ₚ aux_ps b o [] ++ aux_ps b (o + 0%nat) cs2
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
c :
cs1, cs2 :
listcap
IH : ∀ o : Z, aux_ps b o (cs1 ++ cs2) ≡ₚ aux_ps b o cs1 ++ aux_ps b (o + length cs1) cs2
o :
Z
⊢
aux_ps b o ((c :: cs1) ++ cs2) ≡ₚ aux_ps b o (c :: cs1) ++ aux_ps b (o + length (c :: cs1)) cs2

rewrite Z.add_0_r

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
cs2 :
listcap
o :
Z
⊢
aux_ps b o cs2 ≡ₚ aux_ps b o [] ++ aux_ps b o cs2
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
c :
cs1, cs2 :
listcap
IH : ∀ o : Z, aux_ps b o (cs1 ++ cs2) ≡ₚ aux_ps b o cs1 ++ aux_ps b (o + length cs1) cs2
o :
Z
⊢
aux_ps b o ((c :: cs1) ++ cs2) ≡ₚ aux_ps b o (c :: cs1) ++ aux_ps b (o + length (c :: cs1)) cs2

reflexivity

deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
c :
cs1, cs2 :
listcap
IH : ∀ o : Z, aux_ps b o (cs1 ++ cs2) ≡ₚ aux_ps b o cs1 ++ aux_ps b (o + length cs1) cs2
o :
Z
⊢
aux_ps b o ((c :: cs1) ++ cs2) ≡ₚ aux_ps b o (c :: cs1) ++ aux_ps b (o + length (c :: cs1)) cs2

–cbn [ app ]

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
c :
cs1, cs2 :
listcap
IH : ∀ o : Z, aux_ps b o (cs1 ++ cs2) ≡ₚ aux_ps b o cs1 ++ aux_ps b (o + length cs1) cs2
o :
Z
⊢
aux_ps b o (c :: cs1 ++ cs2) ≡ₚ aux_ps b o (c :: cs1) ++ aux_ps b (o + length (c :: cs1)) cs2

rewrite ! aux_ps_cons IH

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
c :
cs1, cs2 :
listcap
IH : ∀ o : Z, aux_ps b o (cs1 ++ cs2) ≡ₚ aux_ps b o cs1 ++ aux_ps b (o + length cs1) cs2
o :
Z
⊢
(PAux b o, VAux c) :: aux_ps b (o + 1) cs1 ++ aux_ps b (o + 1 + length cs1) cs2 ≡ₚ ((PAux b o, VAux c) :: aux_ps b (o + 1) cs1) ++ aux_ps b (o + length (c :: cs1)) cs2

cbn [ app length ]

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
c :
cs1, cs2 :
listcap
IH : ∀ o : Z, aux_ps b o (cs1 ++ cs2) ≡ₚ aux_ps b o cs1 ++ aux_ps b (o + length cs1) cs2
o :
Z
⊢
(PAux b o, VAux c) :: aux_ps b (o + 1) cs1 ++ aux_ps b (o + 1 + length cs1) cs2 ≡ₚ (PAux b o, VAux c) :: aux_ps b (o + 1) cs1 ++ aux_ps b (o + S (length cs1)) cs2

replace o + Z.of_natSlengthcs1 with o + 1 + Z.of_natlengthcs1 by lia

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
c :
cs1, cs2 :
listcap
IH : ∀ o : Z, aux_ps b o (cs1 ++ cs2) ≡ₚ aux_ps b o cs1 ++ aux_ps b (o + length cs1) cs2
o :
Z
⊢
(PAux b o, VAux c) :: aux_ps b (o + 1) cs1 ++ aux_ps b (o + 1 + length cs1) cs2 ≡ₚ (PAux b o, VAux c) :: aux_ps b (o + 1) cs1 ++ aux_ps b (o + 1 + length cs1) cs2

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
rewrite / auxes / pts - big_sepL_app
f_equiv
revert o
induction cs1 as | c cs1 IH ; intros o
–cbn
rewrite Z.add_0_r
reflexivity
–cbn [ app ]
rewrite ! aux_ps_cons IH
cbn [ app length ]
replace o + Z.of_natSlengthcs1 with o + 1 + Z.of_natlengthcs1 by lia
reflexivity

The bytes xs lend their i-th, x, and take it back.

252Lemma bytes_byte
∀ b o xs i x
xs !! i = Somex
bytesb o xs −∗ ibyteb o + Z.of_nati x ∗ ibyteb o + Z.of_nati x −∗ bytesb o xs
Explore proof 7 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b, o :
Z
xs :
listZ
i :
nat
x :
Z
⊢
xs !! i = Somex → bytesb o xs −∗ ibyteb o + i x ∗ ibyteb o + i x −∗ bytesb o xs

intros Hx

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b, o :
Z
xs :
listZ
i :
nat
x :
Z
Hx :
xs !! i = Somex
⊢
bytesb o xs −∗ ibyteb o + i x ∗ ibyteb o + i x −∗ bytesb o xs

rewrite / bytes / ibyte / pts big_sepL_singleton

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b, o :
Z
xs :
listZ
i :
nat
x :
Z
Hx :
xs !! i = Somex
⊢
∗lv∈byte_psb o xspointstolv.1 DfracOwn1 lv.2 −∗ pointstoPByteb o + i, VBytex.1 DfracOwn1 PByteb o + i, VBytex.2 ∗ pointstoPByteb o + i, VBytex.1 DfracOwn1 PByteb o + i, VBytex.2 −∗ ∗lv∈byte_psb o xspointstolv.1 DfracOwn1 lv.2

iIntros Hs

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b, o :
Z
xs :
listZ
i :
nat
x :
Z
Hx :
xs !! i = Somex
Hs :
∗lv∈byte_psb o xspointstolv.1 DfracOwn1 lv.2
∗
pointstoPByteb o + i, VBytex.1 DfracOwn1 PByteb o + i, VBytex.2 ∗ pointstoPByteb o + i, VBytex.1 DfracOwn1 PByteb o + i, VBytex.2 −∗ ∗lv∈byte_psb o xspointstolv.1 DfracOwn1 lv.2

iDestruct big_sepL_lookup_acc with Hs as [Hb Hk] ; exact byte_ps_lookup_ _ _ _ _ Hx |

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b, o :
Z
xs :
listZ
i :
nat
x :
Z
Hx :
xs !! i = Somex
Hb :
pointstoPByteb o + i, VBytex.1 DfracOwn1 PByteb o + i, VBytex.2
Hk :
pointstoPByteb o + i, VBytex.1 DfracOwn1 PByteb o + i, VBytex.2 −∗ ∗y∈byte_psb o xspointstoy.1 DfracOwn1 y.2
∗
pointstoPByteb o + i, VBytex.1 DfracOwn1 PByteb o + i, VBytex.2 ∗ pointstoPByteb o + i, VBytex.1 DfracOwn1 PByteb o + i, VBytex.2 −∗ ∗lv∈byte_psb o xspointstolv.1 DfracOwn1 lv.2

iSplitL Hb ; iExact Hb |

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b, o :
Z
xs :
listZ
i :
nat
x :
Z
Hx :
xs !! i = Somex
Hk :
pointstoPByteb o + i, VBytex.1 DfracOwn1 PByteb o + i, VBytex.2 −∗ ∗y∈byte_psb o xspointstoy.1 DfracOwn1 y.2
∗
pointstoPByteb o + i, VBytex.1 DfracOwn1 PByteb o + i, VBytex.2 −∗ ∗lv∈byte_psb o xspointstolv.1 DfracOwn1 lv.2

iIntros Hb

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b, o :
Z
xs :
listZ
i :
nat
x :
Z
Hx :
xs !! i = Somex
Hk :
pointstoPByteb o + i, VBytex.1 DfracOwn1 PByteb o + i, VBytex.2 −∗ ∗y∈byte_psb o xspointstoy.1 DfracOwn1 y.2
Hb :
pointstoPByteb o + i, VBytex.1 DfracOwn1 PByteb o + i, VBytex.2
∗
∗lv∈byte_psb o xspointstolv.1 DfracOwn1 lv.2

iApply Hk with Hb

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hx
rewrite / bytes / ibyte / pts big_sepL_singleton
iIntros Hs
iDestruct big_sepL_lookup_acc with Hs as [Hb Hk] ; exact byte_ps_lookup_ _ _ _ _ Hx |
iSplitL Hb ; iExact Hb |
iIntros Hb
iApply Hk with Hb

The buffer

The buffer lends the life of the object its pointer's capability names, if any (live_cap), and takes it back; its pointer's address is in range.

266Lemma buffer_cap
∀ p sz
bufferp sz −∗ ∃reg′, ⌜0 ≤ ptr_addrp < 2 ^ 64⌝ ∗ live_capptr_capp reg′ ∗ live_capptr_capp reg′ −∗ bufferp sz
Explore proof 17 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
sz :
Z
⊢
bufferp sz −∗ ∃reg′ : region, ⌜0 ≤ ptr_addrp < 2 ^ 64⌝ ∗ live_capptr_capp reg′ ∗ live_capptr_capp reg′ −∗ bufferp sz

iIntros [[%Hp %Hz] | (%b & %reg & %xs & %cs & %Hf & Hl & Hx & Hcs)]

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
sz :
Z
Hp :
p = null
Hz :
sz = 0
∗
∃reg′ : region, ⌜0 ≤ ptr_addrp < 2 ^ 64⌝ ∗ live_capptr_capp reg′ ∗ live_capptr_capp reg′ −∗ bufferp sz
focused goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
sz, b :
Z
reg :
xs :
listZ
cs :
listcap
Hf :
p = ptr_addr ≔ b; ptr_cap ≔ Objb ∧ 0 < b ∧ b mod 16 = 0 ∧ r_kindreg = Heap ∧ 0 < sz ≤ lengthxs ∧ lengthcs = lengthxs ∧ b + lengthxs ≤ r_endreg ≤ 2 ^ 48
Hl :
liveb reg
Hx :
bytesb 0 xs
Hcs :
auxesb 0 cs
∗
∃reg′ : region, ⌜0 ≤ ptr_addrp < 2 ^ 64⌝ ∗ live_capptr_capp reg′ ∗ live_capptr_capp reg′ −∗ bufferp sz

–iExists slot_reg

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
sz :
Z
Hp :
p = null
Hz :
sz = 0
∗
⌜0 ≤ ptr_addrp < 2 ^ 64⌝ ∗ live_capptr_capp slot_reg ∗ live_capptr_capp slot_reg −∗ bufferp sz
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
sz, b :
Z
reg :
xs :
listZ
cs :
listcap
Hf :
p = ptr_addr ≔ b; ptr_cap ≔ Objb ∧ 0 < b ∧ b mod 16 = 0 ∧ r_kindreg = Heap ∧ 0 < sz ≤ lengthxs ∧ lengthcs = lengthxs ∧ b + lengthxs ≤ r_endreg ≤ 2 ^ 48
Hl :
liveb reg
Hx :
bytesb 0 xs
Hcs :
auxesb 0 cs
∗
∃reg′ : region, ⌜0 ≤ ptr_addrp < 2 ^ 64⌝ ∗ live_capptr_capp reg′ ∗ live_capptr_capp reg′ −∗ bufferp sz

subst p

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
sz :
Z
Hz :
sz = 0
∗
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
sz, b :
Z
reg :
xs :
listZ
cs :
listcap
Hf :
p = ptr_addr ≔ b; ptr_cap ≔ Objb ∧ 0 < b ∧ b mod 16 = 0 ∧ r_kindreg = Heap ∧ 0 < sz ≤ lengthxs ∧ lengthcs = lengthxs ∧ b + lengthxs ≤ r_endreg ≤ 2 ^ 48
Hl :
liveb reg
Hx :
bytesb 0 xs
Hcs :
auxesb 0 cs
∗
∃reg′ : region, ⌜0 ≤ ptr_addrp < 2 ^ 64⌝ ∗ live_capptr_capp reg′ ∗ live_capptr_capp reg′ −∗ bufferp sz

iSplit ; iPureIntro ; cbn ; lia |

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
sz :
Z
Hz :
sz = 0
∗
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
sz, b :
Z
reg :
xs :
listZ
cs :
listcap
Hf :
p = ptr_addr ≔ b; ptr_cap ≔ Objb ∧ 0 < b ∧ b mod 16 = 0 ∧ r_kindreg = Heap ∧ 0 < sz ≤ lengthxs ∧ lengthcs = lengthxs ∧ b + lengthxs ≤ r_endreg ≤ 2 ^ 48
Hl :
liveb reg
Hx :
bytesb 0 xs
Hcs :
auxesb 0 cs
∗
∃reg′ : region, ⌜0 ≤ ptr_addrp < 2 ^ 64⌝ ∗ live_capptr_capp reg′ ∗ live_capptr_capp reg′ −∗ bufferp sz

iSplit ; done |

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
sz :
Z
Hz :
sz = 0
∗
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
sz, b :
Z
reg :
xs :
listZ
cs :
listcap
Hf :
p = ptr_addr ≔ b; ptr_cap ≔ Objb ∧ 0 < b ∧ b mod 16 = 0 ∧ r_kindreg = Heap ∧ 0 < sz ≤ lengthxs ∧ lengthcs = lengthxs ∧ b + lengthxs ≤ r_endreg ≤ 2 ^ 48
Hl :
liveb reg
Hx :
bytesb 0 xs
Hcs :
auxesb 0 cs
∗
∃reg′ : region, ⌜0 ≤ ptr_addrp < 2 ^ 64⌝ ∗ live_capptr_capp reg′ ∗ live_capptr_capp reg′ −∗ bufferp sz

iIntros _

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
sz :
Z
Hz :
sz = 0
∗
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
sz, b :
Z
reg :
xs :
listZ
cs :
listcap
Hf :
p = ptr_addr ≔ b; ptr_cap ≔ Objb ∧ 0 < b ∧ b mod 16 = 0 ∧ r_kindreg = Heap ∧ 0 < sz ≤ lengthxs ∧ lengthcs = lengthxs ∧ b + lengthxs ≤ r_endreg ≤ 2 ^ 48
Hl :
liveb reg
Hx :
bytesb 0 xs
Hcs :
auxesb 0 cs
∗
∃reg′ : region, ⌜0 ≤ ptr_addrp < 2 ^ 64⌝ ∗ live_capptr_capp reg′ ∗ live_capptr_capp reg′ −∗ bufferp sz

iLeft

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
sz :
Z
Hz :
sz = 0
∗
⌜null = null ∧ sz = 0⌝
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
sz, b :
Z
reg :
xs :
listZ
cs :
listcap
Hf :
p = ptr_addr ≔ b; ptr_cap ≔ Objb ∧ 0 < b ∧ b mod 16 = 0 ∧ r_kindreg = Heap ∧ 0 < sz ≤ lengthxs ∧ lengthcs = lengthxs ∧ b + lengthxs ≤ r_endreg ≤ 2 ^ 48
Hl :
liveb reg
Hx :
bytesb 0 xs
Hcs :
auxesb 0 cs
∗
∃reg′ : region, ⌜0 ≤ ptr_addrp < 2 ^ 64⌝ ∗ live_capptr_capp reg′ ∗ live_capptr_capp reg′ −∗ bufferp sz

done

deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
sz, b :
Z
reg :
xs :
listZ
cs :
listcap
Hf :
p = ptr_addr ≔ b; ptr_cap ≔ Objb ∧ 0 < b ∧ b mod 16 = 0 ∧ r_kindreg = Heap ∧ 0 < sz ≤ lengthxs ∧ lengthcs = lengthxs ∧ b + lengthxs ≤ r_endreg ≤ 2 ^ 48
Hl :
liveb reg
Hx :
bytesb 0 xs
Hcs :
auxesb 0 cs
∗
∃reg′ : region, ⌜0 ≤ ptr_addrp < 2 ^ 64⌝ ∗ live_capptr_capp reg′ ∗ live_capptr_capp reg′ −∗ bufferp sz

–pose proof Hf as Hpe & Hb & _ & _ & _ & _ & Hend & Hend48

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
sz, b :
Z
reg :
xs :
listZ
cs :
listcap
Hf :
p = ptr_addr ≔ b; ptr_cap ≔ Objb ∧ 0 < b ∧ b mod 16 = 0 ∧ r_kindreg = Heap ∧ 0 < sz ≤ lengthxs ∧ lengthcs = lengthxs ∧ b + lengthxs ≤ r_endreg ≤ 2 ^ 48
Hpe :
p = ptr_addr ≔ b; ptr_cap ≔ Objb
Hb :
0 < b
Hend :
b + lengthxs ≤ r_endreg
Hend48 :
r_endreg ≤ 2 ^ 48
Hl :
liveb reg
Hx :
bytesb 0 xs
Hcs :
auxesb 0 cs
∗
∃reg′ : region, ⌜0 ≤ ptr_addrp < 2 ^ 64⌝ ∗ live_capptr_capp reg′ ∗ live_capptr_capp reg′ −∗ bufferp sz

subst p

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
sz, b :
Z
reg :
xs :
listZ
cs :
listcap
Hf :
ptr_addr ≔ b; ptr_cap ≔ Objb = ptr_addr ≔ b; ptr_cap ≔ Objb ∧ 0 < b ∧ b mod 16 = 0 ∧ r_kindreg = Heap ∧ 0 < sz ≤ lengthxs ∧ lengthcs = lengthxs ∧ b + lengthxs ≤ r_endreg ≤ 2 ^ 48
Hb :
0 < b
Hend :
b + lengthxs ≤ r_endreg
Hend48 :
r_endreg ≤ 2 ^ 48
Hl :
liveb reg
Hx :
bytesb 0 xs
Hcs :
auxesb 0 cs
∗
∃reg′ : region, ⌜0 ≤ ptr_addrptr_addr ≔ b; ptr_cap ≔ Objb < 2 ^ 64⌝ ∗ live_capptr_capptr_addr ≔ b; ptr_cap ≔ Objb reg′ ∗ live_capptr_capptr_addr ≔ b; ptr_cap ≔ Objb reg′ −∗ bufferptr_addr ≔ b; ptr_cap ≔ Objb sz

iExists reg

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
sz, b :
Z
reg :
xs :
listZ
cs :
listcap
Hf :
ptr_addr ≔ b; ptr_cap ≔ Objb = ptr_addr ≔ b; ptr_cap ≔ Objb ∧ 0 < b ∧ b mod 16 = 0 ∧ r_kindreg = Heap ∧ 0 < sz ≤ lengthxs ∧ lengthcs = lengthxs ∧ b + lengthxs ≤ r_endreg ≤ 2 ^ 48
Hb :
0 < b
Hend :
b + lengthxs ≤ r_endreg
Hend48 :
r_endreg ≤ 2 ^ 48
Hl :
liveb reg
Hx :
bytesb 0 xs
Hcs :
auxesb 0 cs
∗
⌜0 ≤ ptr_addrptr_addr ≔ b; ptr_cap ≔ Objb < 2 ^ 64⌝ ∗ live_capptr_capptr_addr ≔ b; ptr_cap ≔ Objb reg ∗ live_capptr_capptr_addr ≔ b; ptr_cap ≔ Objb reg −∗ bufferptr_addr ≔ b; ptr_cap ≔ Objb sz

iSplit ; iPureIntro ; cbn ; lia |

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
sz, b :
Z
reg :
xs :
listZ
cs :
listcap
Hf :
ptr_addr ≔ b; ptr_cap ≔ Objb = ptr_addr ≔ b; ptr_cap ≔ Objb ∧ 0 < b ∧ b mod 16 = 0 ∧ r_kindreg = Heap ∧ 0 < sz ≤ lengthxs ∧ lengthcs = lengthxs ∧ b + lengthxs ≤ r_endreg ≤ 2 ^ 48
Hb :
0 < b
Hend :
b + lengthxs ≤ r_endreg
Hend48 :
r_endreg ≤ 2 ^ 48
Hl :
liveb reg
Hx :
bytesb 0 xs
Hcs :
auxesb 0 cs
∗
live_capptr_capptr_addr ≔ b; ptr_cap ≔ Objb reg ∗ live_capptr_capptr_addr ≔ b; ptr_cap ≔ Objb reg −∗ bufferptr_addr ≔ b; ptr_cap ≔ Objb sz

iFrame Hl

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
sz, b :
Z
reg :
xs :
listZ
cs :
listcap
Hf :
ptr_addr ≔ b; ptr_cap ≔ Objb = ptr_addr ≔ b; ptr_cap ≔ Objb ∧ 0 < b ∧ b mod 16 = 0 ∧ r_kindreg = Heap ∧ 0 < sz ≤ lengthxs ∧ lengthcs = lengthxs ∧ b + lengthxs ≤ r_endreg ≤ 2 ^ 48
Hb :
0 < b
Hend :
b + lengthxs ≤ r_endreg
Hend48 :
r_endreg ≤ 2 ^ 48
Hx :
bytesb 0 xs
Hcs :
auxesb 0 cs
∗
live_capptr_capptr_addr ≔ b; ptr_cap ≔ Objb reg −∗ bufferptr_addr ≔ b; ptr_cap ≔ Objb sz

iIntros Hl

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
sz, b :
Z
reg :
xs :
listZ
cs :
listcap
Hf :
ptr_addr ≔ b; ptr_cap ≔ Objb = ptr_addr ≔ b; ptr_cap ≔ Objb ∧ 0 < b ∧ b mod 16 = 0 ∧ r_kindreg = Heap ∧ 0 < sz ≤ lengthxs ∧ lengthcs = lengthxs ∧ b + lengthxs ≤ r_endreg ≤ 2 ^ 48
Hb :
0 < b
Hend :
b + lengthxs ≤ r_endreg
Hend48 :
r_endreg ≤ 2 ^ 48
Hx :
bytesb 0 xs
Hcs :
auxesb 0 cs
Hl :
∗
bufferptr_addr ≔ b; ptr_cap ≔ Objb sz

iRight

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
sz, b :
Z
reg :
xs :
listZ
cs :
listcap
Hf :
ptr_addr ≔ b; ptr_cap ≔ Objb = ptr_addr ≔ b; ptr_cap ≔ Objb ∧ 0 < b ∧ b mod 16 = 0 ∧ r_kindreg = Heap ∧ 0 < sz ≤ lengthxs ∧ lengthcs = lengthxs ∧ b + lengthxs ≤ r_endreg ≤ 2 ^ 48
Hb :
0 < b
Hend :
b + lengthxs ≤ r_endreg
Hend48 :
r_endreg ≤ 2 ^ 48
Hx :
bytesb 0 xs
Hcs :
auxesb 0 cs
Hl :
∗
∃b0 : Z reg0 : region xs0 : listZ cs0 : listcap, ⌜ptr_addr ≔ b; ptr_cap ≔ Objb = ptr_addr ≔ b0; ptr_cap ≔ Objb0 ∧ 0 < b0 ∧ b0 mod 16 = 0 ∧ r_kindreg0 = Heap ∧ 0 < sz ≤ lengthxs0 ∧ lengthcs0 = lengthxs0 ∧ b0 + lengthxs0 ≤ r_endreg0 ≤ 2 ^ 48⌝ ∗ liveb0 reg0 ∗ bytesb0 0 xs0 ∗ auxesb0 0 cs0

iExists b, reg, xs, cs

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
sz, b :
Z
reg :
xs :
listZ
cs :
listcap
Hf :
ptr_addr ≔ b; ptr_cap ≔ Objb = ptr_addr ≔ b; ptr_cap ≔ Objb ∧ 0 < b ∧ b mod 16 = 0 ∧ r_kindreg = Heap ∧ 0 < sz ≤ lengthxs ∧ lengthcs = lengthxs ∧ b + lengthxs ≤ r_endreg ≤ 2 ^ 48
Hb :
0 < b
Hend :
b + lengthxs ≤ r_endreg
Hend48 :
r_endreg ≤ 2 ^ 48
Hx :
bytesb 0 xs
Hcs :
auxesb 0 cs
Hl :
∗
⌜ptr_addr ≔ b; ptr_cap ≔ Objb = ptr_addr ≔ b; ptr_cap ≔ Objb ∧ 0 < b ∧ b mod 16 = 0 ∧ r_kindreg = Heap ∧ 0 < sz ≤ lengthxs ∧ lengthcs = lengthxs ∧ b + lengthxs ≤ r_endreg ≤ 2 ^ 48⌝ ∗ liveb reg ∗ bytesb 0 xs ∗ auxesb 0 cs

by iFrame

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
iIntros [[%Hp %Hz] | (%b & %reg & %xs & %cs & %Hf & Hl & Hx & Hcs)]
–iExists slot_reg
subst p
iSplit ; iPureIntro ; cbn ; lia |
iSplit ; done |
iIntros _
iLeft
done
–pose proof Hf as Hpe & Hb & _ & _ & _ & _ & Hend & Hend48
subst p
iExists reg
iSplit ; iPureIntro ; cbn ; lia |
iFrame Hl
iIntros Hl
iRight
iExists b, reg, xs, cs
by iFrame

A call of free on the buffer's pointer, which v reads as, frees it if it is not null, and gives up the whole buffer.

278Lemma wp_free_buffer
∀ f e ls l v rest j p sz Φ
arg_xslot_ge e ArgP v = SomeWPtrp
bufferp sz −∗ ▷WPERunmkFramef e ls None Execl rest j : sexpr {Φ} −∗ WPERunmkFramef e ls None Execl CallCVoid Globalfree_name ArgP v :: rest j : sexpr {Φ}
Explore proof 6 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
f :
e :
ls :
listname × optionZ
l :
rest :
listinst
j :
p :
sz :
Z
Φ :
valnanofil_langslot_registry slot_ge → iPropIΣ
⊢
arg_xslot_ge e ArgP v = SomeWPtrp → bufferp sz −∗ ▷WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j : sexpr {v. Φv} −∗ WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl CallCVoid Globalfree_name ArgP v :: rest j : sexpr {v. Φv}

intros Hv

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
f :
e :
ls :
listname × optionZ
l :
rest :
listinst
j :
p :
sz :
Z
Φ :
valnanofil_langslot_registry slot_ge → iPropIΣ
Hv :
arg_xslot_ge e ArgP v = SomeWPtrp
⊢
bufferp sz −∗ ▷WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j : sexpr {v. Φv} −∗ WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl CallCVoid Globalfree_name ArgP v :: rest j : sexpr {v. Φv}

iIntros [[%Hp _] | (%b & %reg & %xs & %cs & %Hf & Hl & _ & _)] HK

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
f :
e :
ls :
listname × optionZ
l :
rest :
listinst
j :
p :
sz :
Z
Φ :
valnanofil_langslot_registry slot_ge → iPropIΣ
Hv :
arg_xslot_ge e ArgP v = SomeWPtrp
Hp :
p = null
HK :
▷WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j {v. Φv}
∗
WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl CallCVoid Globalfree_name ArgP v :: rest j {v. Φv}
focused goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
f :
e :
ls :
listname × optionZ
l :
rest :
listinst
j :
p :
sz :
Z
Φ :
valnanofil_langslot_registry slot_ge → iPropIΣ
Hv :
arg_xslot_ge e ArgP v = SomeWPtrp
b :
Z
reg :
xs :
listZ
cs :
listcap
Hf :
p = ptr_addr ≔ b; ptr_cap ≔ Objb ∧ 0 < b ∧ b mod 16 = 0 ∧ r_kindreg = Heap ∧ 0 < sz ≤ lengthxs ∧ lengthcs = lengthxs ∧ b + lengthxs ≤ r_endreg ≤ 2 ^ 48
Hl :
liveb reg
HK :
▷WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j {v. Φv}
∗
WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl CallCVoid Globalfree_name ArgP v :: rest j {v. Φv}

–subst p

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
f :
e :
ls :
listname × optionZ
l :
rest :
listinst
j :
sz :
Z
Φ :
valnanofil_langslot_registry slot_ge → iPropIΣ
Hv :
HK :
▷WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j {v. Φv}
∗
WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl CallCVoid Globalfree_name ArgP v :: rest j {v. Φv}
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
f :
e :
ls :
listname × optionZ
l :
rest :
listinst
j :
p :
sz :
Z
Φ :
valnanofil_langslot_registry slot_ge → iPropIΣ
Hv :
arg_xslot_ge e ArgP v = SomeWPtrp
b :
Z
reg :
xs :
listZ
cs :
listcap
Hf :
p = ptr_addr ≔ b; ptr_cap ≔ Objb ∧ 0 < b ∧ b mod 16 = 0 ∧ r_kindreg = Heap ∧ 0 < sz ≤ lengthxs ∧ lengthcs = lengthxs ∧ b + lengthxs ≤ r_endreg ≤ 2 ^ 48
Hl :
liveb reg
HK :
▷WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j {v. Φv}
∗
WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl CallCVoid Globalfree_name ArgP v :: rest j {v. Φv}

iApply wp_free_null with HK ; exact R.free_succeeds | reflexivity | reflexivity | exact Hv

deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
f :
e :
ls :
listname × optionZ
l :
rest :
listinst
j :
p :
sz :
Z
Φ :
valnanofil_langslot_registry slot_ge → iPropIΣ
Hv :
arg_xslot_ge e ArgP v = SomeWPtrp
b :
Z
reg :
xs :
listZ
cs :
listcap
Hf :
p = ptr_addr ≔ b; ptr_cap ≔ Objb ∧ 0 < b ∧ b mod 16 = 0 ∧ r_kindreg = Heap ∧ 0 < sz ≤ lengthxs ∧ lengthcs = lengthxs ∧ b + lengthxs ≤ r_endreg ≤ 2 ^ 48
Hl :
liveb reg
HK :
▷WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j {v. Φv}
∗
WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl CallCVoid Globalfree_name ArgP v :: rest j {v. Φv}

–destruct Hf as → & Hb & _ & Hk & _

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
f :
e :
ls :
listname × optionZ
l :
rest :
listinst
j :
sz :
Z
Φ :
valnanofil_langslot_registry slot_ge → iPropIΣ
b :
Z
Hv :
arg_xslot_ge e ArgP v = SomeWPtrptr_addr ≔ b; ptr_cap ≔ Objb
reg :
xs :
listZ
cs :
listcap
Hb :
0 < b
Hk :
r_kindreg = Heap
Hl :
liveb reg
HK :
▷WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j {v. Φv}
∗
WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl CallCVoid Globalfree_name ArgP v :: rest j {v. Φv}

iApply wp_free with Hl HK ; exact R.free_succeeds | reflexivity | reflexivity | exact Hv | exact Hk | lia | intros ; exact I

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hv
iIntros [[%Hp _] | (%b & %reg & %xs & %cs & %Hf & Hl & _ & _)] HK
–subst p
iApply wp_free_null with HK ; exact R.free_succeeds | reflexivity | reflexivity | exact Hv
–destruct Hf as → & Hb & _ & Hk & _
iApply wp_free with Hl HK ; exact R.free_succeeds | reflexivity | reflexivity | exact Hv | exact Hk | lia | intros ; exact I

fill

The fill, from L6's instructions: owning the static objects holding the buffer b and its size sz, more than n, and the buffer's bytes xs and slots cs: memset its first n bytes, terminate them, and return the buffer, lending the bytes.

297Lemma fill_L6
∀ e c n b reg xs cs sz Φ
lookupTAtom"v0" e = SomeWIntc
lookupTAtom"v2" e = SomeWIntn
0 ≤ c < 2 ^ 32
0 ≤ n < sz
sz < 2 ^ 48
0 < b
b mod 16 = 0
r_kindreg = Heap
sz ≤ Z.of_natlengthxs
lengthcs = lengthxs
b + Z.of_natlengthxs ≤ r_endreg
r_endreg ≤ 2 ^ 48
liveslot_b slot_reg −∗ livesize_b size_reg −∗ pcellslot_b 0 mkPtrb Objb −∗ icellsize_b 0 sz −∗ liveb reg −∗ bytesb 0 xs −∗ auxesb 0 cs −∗ ▷∀b reg, lentb reg n c −∗ ΦRetWPtrmkPtrb Objb −∗ WPERunmkFramefill_fn e [ ] None ExecTAtom"L6" b_instsf_L6 b_jumpf_L6 : sexpr {Φ}
Proof 87 steps Qed
intros Hc Hn Hc32 Hnsz Hsz Hb0 Hb16 Hk Hxs Hcs Hend Hend48
iIntros Hls Hlz Hp Hz Hl Hx Hcs HΦ

Split the buffer at n: the n bytes memset fills, the terminator, the rest.

assert Hnx : Z.to_natn < lengthxs%nat by lia
destruct lookup_lt_is_Some_2xs _ Hnx as x Hx
rewrite <- take_drop_middlexs Z.to_natn x Hx
rewrite <- take_dropZ.to_natn cs
iDestruct bytes_split with Hx as (Hx & Hx0 & Hxr)
iDestruct auxes_app with Hcs as [Hcs Hcr]
assert Ht : lengthtakeZ.to_natn xs = Z.to_natn by rewrite length_take ; lia
assert Htc : lengthtakeZ.to_natn cs = lengthtakeZ.to_natn xs by rewrite ! length_take ; lia
rewrite Ht
assert Hb8 : b mod 8 = 0
{pose proof Z.div_modb 16 ltac:lia
pose proof Z.div_modb 8 ltac:lia
pose proof Z.mod_pos_boundb 8 ltac:lia
lia
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; word_premise |
iNext
iApply wp_check with Hls ; reflexivity | word_premise | reflexivity | static_premise | static_premise | static_premise |
iNext
iIntros Hls
iApply wp_raw_load_pointer_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ reg with Hls Hp Hl ; reflexivity | word_premise | reflexivity | static_premise | static_premise | cbn ; lia |
iNext
iIntros Hls Hp Hl
iApply wp_memset_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 0 with Hl Hx Hcs ; reflexivity | reflexivity | reflexivity | rewrite Z.add_0_r ; word_premise | word_premise | rewrite Ht Z2Nat.id ; word_premise | lia | exact Hc32 | exact Hb8 | reflexivity | lia | rewrite Ht ; lia | exact Htc | intros ; exact I |
iNext
iIntros Hl Hx Hcs
rewrite Z.add_0_r
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; word_premise |
iNext
iApply wp_check with Hls ; reflexivity | word_premise | reflexivity | static_premise | static_premise | static_premise |
iNext
iIntros Hls
iApply wp_raw_load_pointer_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ reg with Hls Hp Hl ; reflexivity | word_premise | reflexivity | static_premise | static_premise | cbn ; lia |
iNext
iIntros Hls Hp Hl
iApply wp_flight_ _ _ _ _ _ _ _ _ _ _ _ _ _ b + n ; word_premise | cbn ; f_equal ; f_equal ; addr_premise | word_premise |
iNext
iApply wp_check with Hl ; reflexivity | word_premise | reflexivity | addr_premise | addr_premise | apply Z.mod_1_r |
iNext
iIntros Hl
iApply wp_raw_store_byte with Hl Hx0 ; word_premise | word_premise | reflexivity | addr_premise | intros ; exact I |
iNext
iIntros Hl Hx0
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; word_premise |
iNext
iApply wp_check with Hls ; reflexivity | word_premise | reflexivity | static_premise | static_premise | static_premise |
iNext
iIntros Hls
iApply wp_raw_load_pointer_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ reg with Hls Hp Hl ; reflexivity | word_premise | reflexivity | static_premise | static_premise | cbn ; lia |
iNext
iIntros Hls Hp Hl
iApply wp_ret ; reflexivity | word_premise |
iNext
rewrite Ht
iApply HΦ $! b reg
iSplit ; iPureIntro ; lia |
iFrame Hl Hx
iIntros Hl Hx
iFrame Hls Hlz
iExists _, sz
iFrame Hp Hz
iSplit ; iPureIntro ; lia |
iRight
iExists b, reg, replicateZ.to_natn c mod 256 ++ 0 mod 256 :: dropSZ.to_natn xs, clear_slots0 takeZ.to_natn cs ++ dropZ.to_natn cs
rewrite bytes_split auxes_app length_replicate length_clear_slots Htc Ht
iFrame Hl Hx Hx0 Hxr Hcs Hcr
iPureIntro
rewrite ! length_app
cbn [ length ]
rewrite ! length_replicate length_clear_slots ! length_drop ! length_take
split ; reflexivity |
repeat split ; first assumption | lia

fill's triple: with the module invariant, called with an int c and a size n below 2^47, it returns the buffer, lending its first n bytes, each c's low byte (lent). From the entry: load the size, and if it is at most n, free the old buffer (wp_free_buffer), malloc n + 1 bytes (wp_malloc) and store the new buffer and its size; then fill_L6.

371Lemma fill_spec
∀ c n Φ
0 ≤ c < 2 ^ 32
0 ≤ n < 2 ^ 47
slot_inv −∗ ▷∀b reg, lentb reg n c −∗ ΦRetWPtrmkPtrb Objb −∗ WPERunfill_entryc n : sexpr {Φ}
Proof 93 steps Qed
intros Hc Hn
iIntros (Hls & Hlz & %p & %sz & %Hsz & Hp & Hz & Hbuf) HΦ
unfold fill_entry
remember putTAtom"v2" WIntn putTAtom"v0" WIntc [ ] as e eqn: Ee
assert Hv0 : lookupTAtom"v0" e = SomeWIntc by subst e ; reflexivity
assert Hv2 : lookupTAtom"v2" e = SomeWIntn by subst e ; reflexivity
clear Ee
iApply wp_enter ; exact find_f_start | reflexivity |
iNext
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; word_premise |
iNext
iApply wp_check with Hlz ; reflexivity | word_premise | reflexivity | static_premise | static_premise | static_premise |
iNext
iIntros Hlz
iApply wp_raw_load with Hlz Hz ; reflexivity | word_premise | reflexivity | static_premise |
iNext
iIntros Hlz Hz
destruct Z.le_gt_casessz n as Hle | Hgt

Too small: free the buffer, malloc n + 1 bytes, and store them.

–iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; word_premise |
iNext
iApply wp_branch_ _ _ _ _ _ _ _ _ _ 1 ; word_premise |
iNext
iApply wp_enter ; exact find_f_L4 | reflexivity |
iNext
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; word_premise |
iNext
iApply wp_check with Hls ; reflexivity | word_premise | reflexivity | static_premise | static_premise | static_premise |
iNext
iIntros Hls
iDestruct buffer_cap with Hbuf as reg′ (%Hpa & Hcap & Hbuf)
iApply wp_raw_load_pointer with Hls Hp Hcap ; reflexivity | word_premise | reflexivity | static_premise | static_premise | exact Hpa |
iNext
iIntros Hls Hp Hcap
iDestruct Hbuf with Hcap as Hbuf
iApply wp_free_buffer with Hbuf ; word_premise |
iNext
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; word_premise |
iNext
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; word_premise |
iNext
iApply wp_malloc ; reflexivity | reflexivity | reflexivity | word_premise | lia | intros ; exact I |
iNext
iIntros base Hpos & Hmod & Hend & Hmax Hobj
iApply wp_check with Hls ; reflexivity | word_premise | reflexivity | static_premise | static_premise | static_premise |
iNext
iIntros Hls
iApply wp_raw_store_pointer with Hls Hp ; word_premise | word_premise | reflexivity | static_premise | static_premise | intros ; exact I |
iNext
iIntros Hls Hp
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; word_premise |
iNext
iApply wp_check with Hlz ; reflexivity | word_premise | reflexivity | static_premise | static_premise | static_premise |
iNext
iIntros Hlz
iApply wp_raw_store with Hlz Hz ; word_premise | word_premise | reflexivity | static_premise | intros ; exact I |
iNext
iIntros Hlz Hz
iApply wp_goto
iNext
iApply wp_enter ; exact find_f_L6 | reflexivity |
iNext
pose proof malloc_extentn + 1 ltac:lia as Hext
rewrite / obj obj_block ; | lia
rewrite block_pts
iDestruct Hobj as (Hl & Hx & Hcs)
iApply fill_L6 with Hls Hlz Hp Hz Hl Hx Hcs HΦ ; assumption | assumption | exact Hc | lia | lia | exact Hpos | exact Hmod | reflexivity | rewrite length_replicate Z2Nat.id ; lia | rewrite ! length_replicate ; reflexivity | cbn [ r_end ] ; rewrite length_replicate Z2Nat.id ; lia | cbn [ r_end ] ; lia

Big enough: the buffer is not null; fill it.

–iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; word_premise |
iNext
iApply wp_branch_ _ _ _ _ _ _ _ _ _ 0 ; word_premise |
iNext
iApply wp_enter ; exact find_f_L6 | reflexivity |
iNext
iDestruct Hbuf as [[_ %Hz0] | (%b & %reg & %xs & %cs & %Hf & Hl & Hx & Hcs)] ; lia |
destruct Hf as → & Hb & Hb16 & Hk & Hszx & Hcx & Hend & Hend48
iApply fill_L6 with Hls Hlz Hp Hz Hl Hx Hcs HΦ ; assumption | assumption | exact Hc | lia | lia | exact Hb | exact Hb16 | exact Hk | lia | exact Hcx | exact Hend | exact Hend48

use is safe and returns an int: it calls fill three times through fill_spec, each time reading a byte of the bytes lent (bytes_byte) and handing them back for the next call.

440Lemma use_spec
slot_inv −∗ WPERunuse_entry : sexpr {o. ⌜∃k, o = RetWIntk⌝}
Proof 69 steps Qed
iIntros Hinv
iApply wp_enter ; exact find_u_start | reflexivity |
iNext

fill('a', 8), then a7.

iApply wp_call_bind ; reflexivity | exact find_fill | reflexivity |
iNext
iApply fill_spec97 8 with Hinv ; lia | lia |
iNext
iIntros b reg (%Hb & Hl & Hx & Hback)
iExists _
iSplit ; iPureIntro ; reflexivity |
iNext
iApply wp_flight_ _ _ _ _ _ _ _ _ _ _ _ _ _ b + 7 ; word_premise | cbn ; f_equal ; f_equal ; addr_premise | word_premise |
iNext
iApply wp_check with Hl ; reflexivity | word_premise | reflexivity | addr_premise | addr_premise | apply Z.mod_1_r |
iNext
iIntros Hl
iDestruct bytes_byte_ _ _ 7 with Hx as [Hb Hx] ; reflexivity |
iApply wp_raw_load_byte with Hl Hb ; reflexivity | word_premise | reflexivity | reflexivity | left ; reflexivity | addr_premise |
iNext
iIntros Hl Hb
iDestruct Hx with Hb as Hx
iDestruct Hback with Hl Hx as Hinv

fill('b', 3), then b0.

iApply wp_call_bind ; reflexivity | exact find_fill | reflexivity |
iNext
iApply fill_spec98 3 with Hinv ; lia | lia |
iNext
iIntros b2 reg2 (%Hb2 & Hl & Hx & Hback)
iExists _
iSplit ; iPureIntro ; reflexivity |
iNext
iApply wp_check with Hl ; reflexivity | word_premise | reflexivity | addr_premise | addr_premise | apply Z.mod_1_r |
iNext
iIntros Hl
iDestruct bytes_byte_ _ _ 0 with Hx as [Hb Hx] ; reflexivity |
iApply wp_raw_load_byte with Hl Hb ; reflexivity | word_premise | reflexivity | reflexivity | left ; reflexivity | addr_premise |
iNext
iIntros Hl Hb
iDestruct Hx with Hb as Hx
iDestruct Hback with Hl Hx as Hinv

fill('c', 16), then c15, and the sum.

iApply wp_call_bind ; reflexivity | exact find_fill | reflexivity |
iNext
iApply fill_spec99 16 with Hinv ; lia | lia |
iNext
iIntros b3 reg3 (%Hb3 & Hl & Hx & _)
iExists _
iSplit ; iPureIntro ; reflexivity |
iNext
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; word_premise |
iNext
iApply wp_flight_ _ _ _ _ _ _ _ _ _ _ _ _ _ b3 + 15 ; word_premise | cbn ; f_equal ; f_equal ; addr_premise | word_premise |
iNext
iApply wp_check with Hl ; reflexivity | word_premise | reflexivity | addr_premise | addr_premise | apply Z.mod_1_r |
iNext
iIntros Hl
iDestruct bytes_byte_ _ _ 15 with Hx as [Hb _] ; reflexivity |
iApply wp_raw_load_byte with Hl Hb ; reflexivity | word_premise | reflexivity | reflexivity | left ; reflexivity | addr_premise |
iNext
iIntros _ _
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; word_premise |
iNext
iApply wp_ret ; reflexivity | word_premise |
iNext
iPureIntro
eexists
reflexivity

use is safe: from a ready runtime, live objects apart, and a memory whose static objects hold null and 0, with any fuel, no labelled run stops with a failure_ending, and a run that returns returns an int. By heap_labelled_safe from use_spec, the ghost heap starting with slot_ps0.

481Theorem slot_logic_safe
∀ Σ HinvP : invGpreSΣ HheapP : gen_heapGpreSpiece pval Σ m s fuel
labelled_safeslot_registry slot_ge use_entry m s tt fuel λo ⇒ ∃k, o = RetWIntk
Explore proof 21 tactics

Initial goal

Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
⊢
R.readys m → live_disjointm → all_agreem slot_ps0 → labelled_safeslot_registry slot_ge use_entry m s () fuel λo : outcome ⇒ ∃k : Z, o = RetWIntk

intros Hr Hd Ha

Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
⊢
labelled_safeslot_registry slot_ge use_entry m s () fuel λo : outcome ⇒ ∃k : Z, o = RetWIntk

apply heap_labelled_safeΣ slot_registry no_world slot_ge use_entry m s tt list_to_mapslot_ps0

5 open

Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
⊢
R.readys m
focused goal
Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
focused goal
Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
⊢
agreesm list_to_mapslot_ps0
focused goal
Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
⊢
no_worldm () list_to_mapslot_ps0
focused goal
Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
⊢
∀ HinvG : invGS_genHasNoLc Σ HheapG : gen_heapGSpiece pval Σ  ,
∗l↦v∈list_to_mapslot_ps0pointstol DfracOwn1 v
⊢
let H ≔ nanofil_irisGSslot_registry no_world slot_ge in
WPSlotLogic.LG.L.ERunuse_entry {o. ⌜∃k : Z, o = RetWIntk⌝}

–exact Hr

4 open

deferred goal
Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
deferred goal
Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
⊢
agreesm list_to_mapslot_ps0
deferred goal
Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
⊢
no_worldm () list_to_mapslot_ps0
deferred goal
Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
⊢
∀ HinvG : invGS_genHasNoLc Σ HheapG : gen_heapGSpiece pval Σ  ,
∗l↦v∈list_to_mapslot_ps0pointstol DfracOwn1 v
⊢
let H ≔ nanofil_irisGSslot_registry no_world slot_ge in
WPSlotLogic.LG.L.ERunuse_entry {o. ⌜∃k : Z, o = RetWIntk⌝}

–exact Hd

3 open

deferred goal
Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
⊢
agreesm list_to_mapslot_ps0
deferred goal
Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
⊢
no_worldm () list_to_mapslot_ps0
deferred goal
Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
⊢
∀ HinvG : invGS_genHasNoLc Σ HheapG : gen_heapGSpiece pval Σ  ,
∗l↦v∈list_to_mapslot_ps0pointstol DfracOwn1 v
⊢
let H ≔ nanofil_irisGSslot_registry no_world slot_ge in
WPSlotLogic.LG.L.ERunuse_entry {o. ⌜∃k : Z, o = RetWIntk⌝}

–intros l v Hl

3 open

Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
v :
Hl :
list_to_mapslot_ps0 !! l = Somev
⊢
deferred goal
Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
⊢
no_worldm () list_to_mapslot_ps0
deferred goal
Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
⊢
∀ HinvG : invGS_genHasNoLc Σ HheapG : gen_heapGSpiece pval Σ  ,
∗l↦v∈list_to_mapslot_ps0pointstol DfracOwn1 v
⊢
let H ≔ nanofil_irisGSslot_registry no_world slot_ge in
WPSlotLogic.LG.L.ERunuse_entry {o. ⌜∃k : Z, o = RetWIntk⌝}

exact all_agree_elem_ _ _ _ Ha elem_of_list_to_map_2_ _ _ Hl

2 open

deferred goal
Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
⊢
no_worldm () list_to_mapslot_ps0
deferred goal
Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
⊢
∀ HinvG : invGS_genHasNoLc Σ HheapG : gen_heapGSpiece pval Σ  ,
∗l↦v∈list_to_mapslot_ps0pointstol DfracOwn1 v
⊢
let H ≔ nanofil_irisGSslot_registry no_world slot_ge in
WPSlotLogic.LG.L.ERunuse_entry {o. ⌜∃k : Z, o = RetWIntk⌝}

–exact I

deferred goal
Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
⊢
∀ HinvG : invGS_genHasNoLc Σ HheapG : gen_heapGSpiece pval Σ  ,
∗l↦v∈list_to_mapslot_ps0pointstol DfracOwn1 v
⊢
let H ≔ nanofil_irisGSslot_registry no_world slot_ge in
WPSlotLogic.LG.L.ERunuse_entry {o. ⌜∃k : Z, o = RetWIntk⌝}

–intros HinvG HheapG

Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
HinvG :
invGS_genHasNoLc Σ
HheapG :
gen_heapGSpiece pval Σ
⊢
∗l↦v∈list_to_mapslot_ps0pointstol DfracOwn1 v
⊢
let H ≔ nanofil_irisGSslot_registry no_world slot_ge in
WPSlotLogic.LG.L.ERunuse_entry {o. ⌜∃k : Z, o = RetWIntk⌝}

rewrite big_sepM_list_to_map ; | exact slot_ps0_nodup

Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
HinvG :
invGS_genHasNoLc Σ
HheapG :
gen_heapGSpiece pval Σ
⊢
∗xk∈slot_ps0pointstoxk.1 DfracOwn1 xk.2
⊢
let H ≔ nanofil_irisGSslot_registry no_world slot_ge in
WPSlotLogic.LG.L.ERunuse_entry {o. ⌜∃k : Z, o = RetWIntk⌝}

iIntros Hps

Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
HinvG :
invGS_genHasNoLc Σ
HheapG :
gen_heapGSpiece pval Σ
Hps :
∗xk∈slot_ps0pointstoxk.1 DfracOwn1 xk.2
∗
WPSlotLogic.LG.L.ERunuse_entry {o. ⌜∃k : Z, o = RetWIntk⌝}

iApply use_spec

Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
HinvG :
invGS_genHasNoLc Σ
HheapG :
gen_heapGSpiece pval Σ
Hps :
∗xk∈slot_ps0pointstoxk.1 DfracOwn1 xk.2
∗

rewrite / slot_ps0 / pts big_sepL_cons big_sepL_cons big_sepL_app

Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
HinvG :
invGS_genHasNoLc Σ
HheapG :
gen_heapGSpiece pval Σ
Hps :
pointstoPLiveslot_b, VLiveslot_reg.1 DfracOwn1 PLiveslot_b, VLiveslot_reg.2 ∗ pointstoPLivesize_b, VLivesize_reg.1 DfracOwn1 PLivesize_b, VLivesize_reg.2 ∗ ∗y∈PAuxslot_b 0, VAuxCNone :: cellslot_b 0 0pointstoy.1 DfracOwn1 y.2 ∗ ∗y∈cellsize_b 0 0pointstoy.1 DfracOwn1 y.2
∗

iDestruct Hps as (Hls & Hlz & Hp & Hz)

Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
HinvG :
invGS_genHasNoLc Σ
HheapG :
gen_heapGSpiece pval Σ
Hls :
Hlz :
Hp :
∗y∈PAuxslot_b 0, VAuxCNone :: cellslot_b 0 0pointstoy.1 DfracOwn1 y.2
Hz :
∗y∈cellsize_b 0 0pointstoy.1 DfracOwn1 y.2
∗

rewrite / slot_inv / live / pts ! big_sepL_singleton

Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
HinvG :
invGS_genHasNoLc Σ
HheapG :
gen_heapGSpiece pval Σ
Hls :
Hlz :
Hp :
∗y∈PAuxslot_b 0, VAuxCNone :: cellslot_b 0 0pointstoy.1 DfracOwn1 y.2
Hz :
∗y∈cellsize_b 0 0pointstoy.1 DfracOwn1 y.2
∗
pointstoPLiveslot_b, VLiveslot_reg.1 DfracOwn1 PLiveslot_b, VLiveslot_reg.2 ∗ pointstoPLivesize_b, VLivesize_reg.1 DfracOwn1 PLivesize_b, VLivesize_reg.2 ∗ ∃p : ptr sz : Z, ⌜0 ≤ sz < 2 ^ 48⌝ ∗ pcellslot_b 0 p ∗ icellsize_b 0 sz ∗ bufferp sz

iFrame Hls Hlz

Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
HinvG :
invGS_genHasNoLc Σ
HheapG :
gen_heapGSpiece pval Σ
Hp :
∗y∈PAuxslot_b 0, VAuxCNone :: cellslot_b 0 0pointstoy.1 DfracOwn1 y.2
Hz :
∗y∈cellsize_b 0 0pointstoy.1 DfracOwn1 y.2
∗
∃p : ptr sz : Z, ⌜0 ≤ sz < 2 ^ 48⌝ ∗ pcellslot_b 0 p ∗ icellsize_b 0 sz ∗ bufferp sz

iExists null, 0

Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
HinvG :
invGS_genHasNoLc Σ
HheapG :
gen_heapGSpiece pval Σ
Hp :
∗y∈PAuxslot_b 0, VAuxCNone :: cellslot_b 0 0pointstoy.1 DfracOwn1 y.2
Hz :
∗y∈cellsize_b 0 0pointstoy.1 DfracOwn1 y.2
∗
⌜0 ≤ 0 < 2 ^ 48⌝ ∗ pcellslot_b 0 null ∗ icellsize_b 0 0 ∗ buffernull 0

iSplit ; iPureIntro ; lia |

Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
HinvG :
invGS_genHasNoLc Σ
HheapG :
gen_heapGSpiece pval Σ
Hp :
∗y∈PAuxslot_b 0, VAuxCNone :: cellslot_b 0 0pointstoy.1 DfracOwn1 y.2
Hz :
∗y∈cellsize_b 0 0pointstoy.1 DfracOwn1 y.2
∗

iSplitL Hp ; iExact Hp |

Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
HinvG :
invGS_genHasNoLc Σ
HheapG :
gen_heapGSpiece pval Σ
Hz :
∗y∈cellsize_b 0 0pointstoy.1 DfracOwn1 y.2
∗

iSplitL Hz ; iExact Hz |

Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
HinvG :
invGS_genHasNoLc Σ
HheapG :
gen_heapGSpiece pval Σ
∗

iLeft

Σ :
gFunctors
HinvP :
invGpreSΣ
HheapP :
gen_heapGpreSpiece pval Σ
m :
s :
R.state
fuel :
Z
Hr :
R.readys m
HinvG :
invGS_genHasNoLc Σ
HheapG :
gen_heapGSpiece pval Σ
∗
⌜null = null ∧ 0 = 0⌝

done

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hr Hd Ha
–exact Hr
–exact Hd
–intros l v Hl
exact all_agree_elem_ _ _ _ Ha elem_of_list_to_map_2_ _ _ Hl
–exact I
–intros HinvG HheapG
rewrite big_sepM_list_to_map ; | exact slot_ps0_nodup
iIntros Hps
iApply use_spec
rewrite / slot_ps0 / pts big_sepL_cons big_sepL_cons big_sepL_app
iDestruct Hps as (Hls & Hlz & Hp & Hz)
rewrite / slot_inv / live / pts ! big_sepL_singleton
iFrame Hls Hlz
iExists null, 0
iSplit ; iPureIntro ; lia |
iSplitL Hp ; iExact Hp |
iSplitL Hz ; iExact Hz |
iLeft
done

The interpreter's runtime

slot.c over the interpreter's runtime.

504Module InterpSlotLogic ≔ SlotLogic InterpRuntime

The module's initial memory: the two static objects, every byte 0 and every aux slot empty.

508Definition slot_memory: mem ≔
mkMemλ_ ⇒ 0 size_reg; slot_reg λ_ ⇒ CNone

Laying out the module gives slot_memory.

Explore proof 2 tactics

Initial goal

vm_compute

⊢
SomeTAtom"slot_size", ptr_addr ≔ 65600; ptr_cap ≔ Obj65600; TAtom"slot", ptr_addr ≔ 65568; ptr_cap ≔ Obj65568; TAtom"use", ptr_addr ≔ 65552; ptr_cap ≔ FnTAtom"use"; TAtom"fill", ptr_addr ≔ 65536; ptr_cap ≔ FnTAtom"fill", m_bytes ≔ λ_ : Z ⇒ 0; m_regions ≔ r_base ≔ 65600; r_end ≔ 65608; r_kind ≔ GlobalData; r_life ≔ Live; r_base ≔ 65568; r_end ≔ 65576; r_kind ≔ GlobalData; r_life ≔ Live; m_aux ≔ λ_ : Z ⇒ CNone = SomeTAtom"slot_size", ptr_addr ≔ 65600; ptr_cap ≔ Obj65600; TAtom"slot", ptr_addr ≔ 65568; ptr_cap ≔ Obj65568; TAtom"use", ptr_addr ≔ 65552; ptr_cap ≔ FnTAtom"use"; TAtom"fill", ptr_addr ≔ 65536; ptr_cap ≔ FnTAtom"fill", m_bytes ≔ λ_ : Z ⇒ 0; m_regions ≔ r_base ≔ 65600; r_end ≔ 65608; r_kind ≔ GlobalData; r_life ≔ Live; r_base ≔ 65568; r_end ≔ 65576; r_kind ≔ GlobalData; r_life ≔ Live; m_aux ≔ λ_ : Z ⇒ CNone

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
vm_compute
reflexivity

The interpreter is ready in slot_memory at its start: both objects lie below it.

Explore proof 6 tactics

Initial goal

split ; vm_compute ; split ; congruence |

⊢
∀b : Z reg : region, object_regionb m_regionsslot_memory = Somereg → 0 ≤ b < InterpRuntime.start ∧ r_endreg ≤ InterpRuntime.start ∧ r_lifereg = Freed → r_endreg = b ∧ ∀a : Z, InterpRuntime.start ≤ a → m_bytesslot_memory a = 0 ∧ m_auxslot_memory a = CNone

split ; | intros a _ ; split ; reflexivity

⊢
∀b : Z reg : region, object_regionb m_regionsslot_memory = Somereg → 0 ≤ b < InterpRuntime.start ∧ r_endreg ≤ InterpRuntime.start ∧ r_lifereg = Freed → r_endreg = b

intros b reg E

⊢
0 ≤ b < InterpRuntime.start ∧ r_endreg ≤ InterpRuntime.start ∧ r_lifereg = Freed → r_endreg = b

change object_regionb size_reg; slot_reg = Somereg in E

b :
Z
reg :
⊢
0 ≤ b < InterpRuntime.start ∧ r_endreg ≤ InterpRuntime.start ∧ r_lifereg = Freed → r_endreg = b

cbn - [ Z.eqb ] in E

b :
Z
reg :
E :
65600 =? b
→
65568 =? b
→
else
None
=
Somereg
⊢
0 ≤ b < InterpRuntime.start ∧ r_endreg ≤ InterpRuntime.start ∧ r_lifereg = Freed → r_endreg = b

destruct 65600 =? b eqn: E1 ; | destruct 65568 =? b eqn: E2 ; | discriminate E ; apply Z.eqb_eq in E1 || apply Z.eqb_eq in E2 ; subst b ; injection E as ← ; split ; vm_compute ; split ; congruence | ; split ; vm_compute ; congruence | discriminate

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
split ; vm_compute ; split ; congruence |
split ; | intros a _ ; split ; reflexivity
intros b reg E
change object_regionb size_reg; slot_reg = Somereg in E
cbn - [ Z.eqb ] in E
destruct 65600 =? b eqn: E1 ; | destruct 65568 =? b eqn: E2 ; | discriminate E ; apply Z.eqb_eq in E1 || apply Z.eqb_eq in E2 ; subst b ; injection E as ← ; split ; vm_compute ; split ; congruence | ; split ; vm_compute ; congruence | discriminate

The two static objects are apart.

527Lemma slot_memory_disjoint
Explore proof 5 tactics

Initial goal

intros b1 r1 b2 r2 E1 _ E2 _ Hne

b1 :
Z
r1 :
b2 :
Z
r2 :
Hne :
b1 ≠ b2
⊢
r_endr1 ≤ b2 ∨ r_endr2 ≤ b1

change object_regionb1 size_reg; slot_reg = Somer1 in E1

b1 :
Z
r1 :
b2 :
Z
r2 :
Hne :
b1 ≠ b2
⊢
r_endr1 ≤ b2 ∨ r_endr2 ≤ b1

change object_regionb2 size_reg; slot_reg = Somer2 in E2

b1 :
Z
r1 :
b2 :
Z
r2 :
Hne :
b1 ≠ b2
⊢
r_endr1 ≤ b2 ∨ r_endr2 ≤ b1

cbn - [ Z.eqb ] in E1 , E2

b1 :
Z
r1 :
b2 :
Z
r2 :
E1 :
65600 =? b1
→
65568 =? b1
→
else
None
=
Somer1
E2 :
65600 =? b2
→
65568 =? b2
→
else
None
=
Somer2
Hne :
b1 ≠ b2
⊢
r_endr1 ≤ b2 ∨ r_endr2 ≤ b1

destruct 65600 =? b1 eqn: F1 ; | destruct 65568 =? b1 eqn: G1 ; | discriminate E1 ; destruct 65600 =? b2 eqn: F2 ; | destruct 65568 =? b2 eqn: G2 ; | discriminate E2;repeat match goal withH : _ =? _ = true |- _⇒apply Z.eqb_eq in Hend;injection E1 as ←;injection E2 as ←;cbn;lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros b1 r1 b2 r2 E1 _ E2 _ Hne
change object_regionb1 size_reg; slot_reg = Somer1 in E1
change object_regionb2 size_reg; slot_reg = Somer2 in E2
cbn - [ Z.eqb ] in E1 , E2
destruct 65600 =? b1 eqn: F1 ; | destruct 65568 =? b1 eqn: G1 ; | discriminate E1 ; destruct 65600 =? b2 eqn: F2 ; | destruct 65568 =? b2 eqn: G2 ; | discriminate E2;repeat match goal withH : _ =? _ = true |- _⇒apply Z.eqb_eq in Hend;injection E1 as ←;injection E2 as ←;cbn;lia

slot_ps0 agrees with slot_memory: its objects are live, every byte is 0 and every aux slot empty.

541Lemma slot_memory_agrees
Explore proof 3 tactics

Initial goal

cbv [ slot_ps0 cell map app slot_b size_b ]

⊢
all_agreeslot_memory PLive65568, VLiveslot_reg; PLive65600, VLivesize_reg; PAux65568 0, VAuxCNone; PByte65568 0 + 0, VBytebyte_of0 0; PByte65568 0 + 1, VBytebyte_of0 1; PByte65568 0 + 2, VBytebyte_of0 2; PByte65568 0 + 3, VBytebyte_of0 3; PByte65568 0 + 4, VBytebyte_of0 4; PByte65568 0 + 5, VBytebyte_of0 5; PByte65568 0 + 6, VBytebyte_of0 6; PByte65568 0 + 7, VBytebyte_of0 7; PByte65600 0 + 0, VBytebyte_of0 0; PByte65600 0 + 1, VBytebyte_of0 1; PByte65600 0 + 2, VBytebyte_of0 2; PByte65600 0 + 3, VBytebyte_of0 3; PByte65600 0 + 4, VBytebyte_of0 4; PByte65600 0 + 5, VBytebyte_of0 5; PByte65600 0 + 6, VBytebyte_of0 6; PByte65600 0 + 7, VBytebyte_of0 7

cbn [ all_agree agree_piece fst snd ]

⊢
live_atslot_memory 65568 slot_reg ∧ live_atslot_memory 65600 size_reg ∧ registeredslot_memory 65568 ∧ in_liveslot_memory 65568 0 aux_holdsslot_memory 65568 + 0 CNone ∧ registeredslot_memory 65568 ∧ in_liveslot_memory 65568 0 + 0 m_bytesslot_memory 65568 + 0 + 0 = byte_of0 0 ∧ registeredslot_memory 65568 ∧ in_liveslot_memory 65568 0 + 1 m_bytesslot_memory 65568 + 0 + 1 = byte_of0 1 ∧ registeredslot_memory 65568 ∧ in_liveslot_memory 65568 0 + 2 m_bytesslot_memory 65568 + 0 + 2 = byte_of0 2 ∧ registeredslot_memory 65568 ∧ in_liveslot_memory 65568 0 + 3 m_bytesslot_memory 65568 + 0 + 3 = byte_of0 3 ∧ registeredslot_memory 65568 ∧ in_liveslot_memory 65568 0 + 4 m_bytesslot_memory 65568 + 0 + 4 = byte_of0 4 ∧ registeredslot_memory 65568 ∧ in_liveslot_memory 65568 0 + 5 m_bytesslot_memory 65568 + 0 + 5 = byte_of0 5 ∧ registeredslot_memory 65568 ∧ in_liveslot_memory 65568 0 + 6 m_bytesslot_memory 65568 + 0 + 6 = byte_of0 6 ∧ registeredslot_memory 65568 ∧ in_liveslot_memory 65568 0 + 7 m_bytesslot_memory 65568 + 0 + 7 = byte_of0 7 ∧ registeredslot_memory 65600 ∧ in_liveslot_memory 65600 0 + 0 m_bytesslot_memory 65600 + 0 + 0 = byte_of0 0 ∧ registeredslot_memory 65600 ∧ in_liveslot_memory 65600 0 + 1 m_bytesslot_memory 65600 + 0 + 1 = byte_of0 1 ∧ registeredslot_memory 65600 ∧ in_liveslot_memory 65600 0 + 2 m_bytesslot_memory 65600 + 0 + 2 = byte_of0 2 ∧ registeredslot_memory 65600 ∧ in_liveslot_memory 65600 0 + 3 m_bytesslot_memory 65600 + 0 + 3 = byte_of0 3 ∧ registeredslot_memory 65600 ∧ in_liveslot_memory 65600 0 + 4 m_bytesslot_memory 65600 + 0 + 4 = byte_of0 4 ∧ registeredslot_memory 65600 ∧ in_liveslot_memory 65600 0 + 5 m_bytesslot_memory 65600 + 0 + 5 = byte_of0 5 ∧ registeredslot_memory 65600 ∧ in_liveslot_memory 65600 0 + 6 m_bytesslot_memory 65600 + 0 + 6 = byte_of0 6 ∧ registeredslot_memory 65600 ∧ in_liveslot_memory 65600 0 + 7 m_bytesslot_memory 65600 + 0 + 7 = byte_of0 7 ∧ True

repeat match goal with|- _ ∧ _⇒split|- True⇒exact I|- live_at_ _ _⇒split ; reflexivity|- registered_ _⇒unfold registered ; vm_compute ; discriminate|- in_live_ _ _ _⇒let reg ≔ fresh "reg" in let E ≔ fresh "E" in intros reg E _ ; vm_compute in E ; injection E as ← ; cbn [ r_end ] ; split ; lia | ; split ; lia | ; first left ; reflexivity | reflexivityend

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
cbv [ slot_ps0 cell map app slot_b size_b ]
cbn [ all_agree agree_piece fst snd ]
repeat match goal with|- _ ∧ _⇒split|- True⇒exact I|- live_at_ _ _⇒split ; reflexivity|- registered_ _⇒unfold registered ; vm_compute ; discriminate|- in_live_ _ _ _⇒let reg ≔ fresh "reg" in let E ≔ fresh "E" in intros reg E _ ; vm_compute in E ; injection E as ← ; cbn [ r_end ] ; split ; lia | ; split ; lia | ; first left ; reflexivity | reflexivityend

use is safe under the interpreter's runtime, from the module's initial memory (slot_initial).

Explore proof 5 tactics

Initial goal

intros fuel

apply InterpSlotLogic.slot_logic_safehiΣ

3 open

focused goal
focused goal

–exact slot_memory_ready

2 open

deferred goal
deferred goal

–exact slot_memory_disjoint

deferred goal

–exact slot_memory_agrees

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script