Fil-C on Nix

Filnix wiki

the formal campaign

rocq/theories/HelloVersion.v

GNU Hello's version and help helpers through the program logic. The output contracts are supplied by the caller's stdio world; stdout remains world-owned.

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 Identity Machine Panics
Open Scope Z_scope
Open Scope list_scope
Arguments Z.add : simpl nomatch
Arguments Z.sub : simpl nomatch
Arguments Z.mul : simpl nomatch

Keep symbolic address arithmetic folded while computing IR operands.

Keep symbolic offsets folded while computing IR operands.

Keep symbolic scaled indices folded while computing IR operands.

The compiled proper-name helper returns its argument unchanged.

24Definition proper_name_fn: func ≔
Eval vm_compute in hello_fn"proper_name"

Its empty entry block returns the pointer.

26Definition proper_name_start: block ≔
Eval vm_compute in hblkproper_name_fn "start"

The entry block is present in the compiled function.

28Lemma find_proper_name_start
Explore proof 2 tactics

Initial goal

vm_compute

⊢
Someb_label ≔ TAtom"start"; b_phis ≔ [ ]; b_insts ≔ [ ]; b_jump ≔ JRetTmpTAtom"v0" = Someb_label ≔ TAtom"start"; b_phis ≔ [ ]; b_insts ≔ [ ]; b_jump ≔ JRetTmpTAtom"v0"

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
vm_compute
reflexivity

Its call frame binds the sole pointer argument.

32Lemma proper_name_entry
Explore proof 1 tactics

Initial goal

p :
⊢
invocationproper_name_fn WPtrp = fr_fn ≔ proper_name_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 help footer prints the bug-reporting addresses.

37Definition emit_bug_reporting_address_fn: func ≔
Eval vm_compute in hello_fn"emit_bug_reporting_address"

Its single block loads stdout and makes four output calls.

39Definition emit_bug_reporting_address_start: block ≔
Eval vm_compute in hblkemit_bug_reporting_address_fn "start"

The footer's entry block is present.

42Lemma find_emit_bug_reporting_address_start
Explore proof 2 tactics

Initial goal

vm_compute

⊢
Someb_label ≔ TAtom"start"; b_phis ≔ [ ]; b_insts ≔ LetTAtom"v0" P Copy GlobalTAtom"version-etc#str.45"; LetTAtom"v1" P Copy GlobalTAtom"stdout"; LetTAtom"chk0" A Check0 8 Read 8 TmpTAtom"v1"; LetTAtom"v2" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk0"; CallCResultTAtom"v3" W GlobalTAtom"fputs" ArgP TmpTAtom"v0"; ArgP TmpTAtom"v2"; LetTAtom"v4" P Copy GlobalTAtom"version-etc#str.43"; LetTAtom"v5" P Copy GlobalTAtom"version-etc#str.58"; LetTAtom"v6" P Copy GlobalTAtom"version-etc#str.59"; CallCResultTAtom"v7" W GlobalTAtom"printf" ArgP TmpTAtom"v5"; ArgP TmpTAtom"v6"; LetTAtom"v8" P Copy GlobalTAtom"version-etc#str.43"; LetTAtom"v9" P Copy GlobalTAtom"version-etc#str.60"; LetTAtom"v10" P Copy GlobalTAtom"version-etc#str.61"; LetTAtom"v11" P Copy GlobalTAtom"version-etc#str.62"; CallCResultTAtom"v12" W GlobalTAtom"printf" ArgP TmpTAtom"v9"; ArgP TmpTAtom"v10"; ArgP TmpTAtom"v11"; LetTAtom"v13" P Copy GlobalTAtom"version-etc#str.43"; LetTAtom"v14" P Copy GlobalTAtom"version-etc#str.63"; LetTAtom"v15" P Copy GlobalTAtom"version-etc#str.64"; CallCResultTAtom"v16" W GlobalTAtom"printf" ArgP TmpTAtom"v14"; ArgP TmpTAtom"v15"; b_jump ≔ JRetVoid = Someb_label ≔ TAtom"start"; b_phis ≔ [ ]; b_insts ≔ LetTAtom"v0" P Copy GlobalTAtom"version-etc#str.45"; LetTAtom"v1" P Copy GlobalTAtom"stdout"; LetTAtom"chk0" A Check0 8 Read 8 TmpTAtom"v1"; LetTAtom"v2" P RawLoadPointer0 AuxRead; LowerResolve; AddressRead TmpTAtom"chk0"; CallCResultTAtom"v3" W GlobalTAtom"fputs" ArgP TmpTAtom"v0"; ArgP TmpTAtom"v2"; LetTAtom"v4" P Copy GlobalTAtom"version-etc#str.43"; LetTAtom"v5" P Copy GlobalTAtom"version-etc#str.58"; LetTAtom"v6" P Copy GlobalTAtom"version-etc#str.59"; CallCResultTAtom"v7" W GlobalTAtom"printf" ArgP TmpTAtom"v5"; ArgP TmpTAtom"v6"; LetTAtom"v8" P Copy GlobalTAtom"version-etc#str.43"; LetTAtom"v9" P Copy GlobalTAtom"version-etc#str.60"; LetTAtom"v10" P Copy GlobalTAtom"version-etc#str.61"; LetTAtom"v11" P Copy GlobalTAtom"version-etc#str.62"; CallCResultTAtom"v12" W GlobalTAtom"printf" ArgP TmpTAtom"v9"; ArgP TmpTAtom"v10"; ArgP TmpTAtom"v11"; LetTAtom"v13" P Copy GlobalTAtom"version-etc#str.43"; LetTAtom"v14" P Copy GlobalTAtom"version-etc#str.63"; LetTAtom"v15" P Copy GlobalTAtom"version-etc#str.64"; CallCResultTAtom"v16" W GlobalTAtom"printf" ArgP TmpTAtom"v14"; ArgP TmpTAtom"v15"; b_jump ≔ JRetVoid

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
vm_compute
reflexivity

A version-etc literal's pointer in the linked fixture.

48Definition version_literals : String.string : ptr ≔
Eval vm_compute in match lookupTAtoms hello_globals with Somep ⇒ p | None ⇒ mkPtr0 CNone end

The array-based version helper reached by Hello's single version call.

52Definition version_etc_arn_fn: func ≔
Eval vm_compute in hello_fn"version_etc_arn"

Its entry selects the format with a command name.

54Definition arn_start: block ≔
Eval vm_compute in hblkversion_etc_arn_fn "start"

The command-name version heading.

56Definition arn_L12: block ≔
Eval vm_compute in hblkversion_etc_arn_fn "L12"

The copyright and license lines precede author dispatch.

58Definition arn_L14: block ≔
Eval vm_compute in hblkversion_etc_arn_fn "L14"

The first dispatch compares the count with two.

60Definition arn_L263: block ≔
Eval vm_compute in hblkversion_etc_arn_fn "L263"

The second dispatch tests for two authors.

62Definition arn_L267: block ≔
Eval vm_compute in hblkversion_etc_arn_fn "L267"

The third dispatch tests for three authors.

64Definition arn_L273: block ≔
Eval vm_compute in hblkversion_etc_arn_fn "L273"

The last reachable dispatch tests for four authors.

66Definition arn_L275: block ≔
Eval vm_compute in hblkversion_etc_arn_fn "L275"

The four-author output reads four cells of the array.

68Definition arn_L82: block ≔
Eval vm_compute in hblkversion_etc_arn_fn "L82"

The shared return after author output.

70Definition arn_L47: block ≔
Eval vm_compute in hblkversion_etc_arn_fn "L47"

Every block on the reachable four-author path occurs in the fixture.

73Lemma find_arn_blocks
Forallλlb ⇒ find_blockTAtomlb.1 fn_blocksversion_etc_arn_fn = Somelb.2 "start", arn_start; "L12", arn_L12; "L14", arn_L14; "L263", arn_L263; "L267", arn_L267; "L273", arn_L273; "L275", arn_L275; "L82", arn_L82; "L47", arn_L47
Proof 2 steps Qed
vm_compute
repeat constructor

The array helper's entry for main's three heading literals and four authors. The count is the result the variadic loop must prove.

82Lemma version_etc_arn_entry
∀ stream authors
invocationversion_etc_arn_fn WPtrstream; WPtrversion_literal"hello#str.70"; WPtrversion_literal"hello#str.63"; WPtrversion_literal"hello#str.71"; WPtrauthors; WInt4 = mkFrameversion_etc_arn_fn TAtom"v10", WInt4; TAtom"v8", WPtrauthors; TAtom"v6", WPtrversion_literal"hello#str.71"; TAtom"v4", WPtrversion_literal"hello#str.63"; TAtom"v2", WPtrversion_literal"hello#str.70"; TAtom"v0", WPtrstream [ ] None EnterTAtom"start" None
Explore proof 1 tactics

Initial goal

stream, authors :
⊢
invocationversion_etc_arn_fn WPtrstream; WPtrversion_literal"hello#str.70"; WPtrversion_literal"hello#str.63"; WPtrversion_literal"hello#str.71"; WPtrauthors; WInt4 = fr_fn ≔ version_etc_arn_fn; fr_env ≔ TAtom"v10", WInt4; TAtom"v8", WPtrauthors; TAtom"v6", WPtrversion_literal"hello#str.71"; TAtom"v4", WPtrversion_literal"hello#str.63"; TAtom"v2", WPtrversion_literal"hello#str.70"; TAtom"v0", WPtrstream; 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 six exact output calls on the four-author path; the copyright year is a promoted W argument, not a pointer or a 64-bit integer.

97Definition version_output_argsstream : ptr : listname × listword ≔
TAtom"fprintf", WPtrstream; WPtrversion_literal"version-etc#str.41"; WPtrversion_literal"hello#str.70"; WPtrversion_literal"hello#str.63"; WPtrversion_literal"hello#str.71"; TAtom"fprintf", WPtrstream; WPtrversion_literal"version_etc_copyright"; WPtrversion_literal"version-etc#str.44"; WInt2026; TAtom"fputs", WPtrversion_literal"version-etc#str.45"; WPtrstream; TAtom"fprintf", WPtrstream; WPtrversion_literal"version-etc#str.46"; WPtrversion_literal"version-etc#str.47"; TAtom"fputs", WPtrversion_literal"version-etc#str.45"; WPtrstream; TAtom"fprintf", WPtrstream; WPtrversion_literal"version-etc#str.51"; WPtrversion_literal"hello#str.72"; WPtrversion_literal"hello#str.73"; WPtrversion_literal"hello#str.74"; WPtrversion_literal"hello#str.75"

The promoted classes at these output sites: pointers and int words.

112Definition version_output_classesxs : listword : listclass ≔
λ x  ⇒
match x with
⇒
_
⇒
<$>
xs

The four exact output argument lists in the help footer: the newline, bug address, home-page line, and general-help line.

117Definition emit_output_argsstdout : ptr : listname × listword ≔
TAtom"fputs", WPtrversion_literal"version-etc#str.45"; WPtrstdout; TAtom"printf", WPtrversion_literal"version-etc#str.58"; WPtrversion_literal"version-etc#str.59"; TAtom"printf", WPtrversion_literal"version-etc#str.60"; WPtrversion_literal"version-etc#str.61"; WPtrversion_literal"version-etc#str.62"; TAtom"printf", WPtrversion_literal"version-etc#str.63"; WPtrversion_literal"version-etc#str.64"

For promotion: reading the hidden variadic snapshot is a pure instruction. Its pointer is frame state, not a new heap resource. This equation follows rule_inst and inst_step.

130Lemma rule_va_args
∀ ge f e ls l d off rest j cs m fuel p
Semantics.stepge mkConfigmkFramef e ls None Execl Letd P VaArgs Constoff :: rest j cs m fuel = NextmkConfigmkFramef putd WPtrmkPtrptr_addrp + off mod 2 ^ 64 ptr_capp e ls None Execl rest j cs m fuel
Explore proof 7 tactics

Initial goal

ge :
f :
e :
listname × word
ls :
listname × optionZ
l, d :
off :
Z
rest :
listinst
j :
cs :
listframe × pending
m :
fuel :
Z
p :
⊢
lookupva_snapshot e = SomeWPtrp → stepge c_frame ≔ fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd P VaArgs Constoff :: rest j; c_callers ≔ cs; c_mem ≔ m; c_fuel ≔ fuel = Nextc_frame ≔ fr_fn ≔ f; fr_env ≔ putd WPtrptr_addr ≔ ptr_addrp + off mod 2 ^ 64; ptr_cap ≔ ptr_capp e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j; c_callers ≔ cs; c_mem ≔ m; c_fuel ≔ fuel

intros Hp

ge :
f :
e :
listname × word
ls :
listname × optionZ
l, d :
off :
Z
rest :
listinst
j :
cs :
listframe × pending
m :
fuel :
Z
p :
Hp :
⊢
stepge c_frame ≔ fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd P VaArgs Constoff :: rest j; c_callers ≔ cs; c_mem ≔ m; c_fuel ≔ fuel = Nextc_frame ≔ fr_fn ≔ f; fr_env ≔ putd WPtrptr_addr ≔ ptr_addrp + off mod 2 ^ 64; ptr_cap ≔ ptr_capp e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j; c_callers ≔ cs; c_mem ≔ m; c_fuel ≔ fuel

apply rule_instge f e ls l Letd P VaArgs Constoff rest j cs m fuel IContinueputd WPtrmkPtrptr_addrp + off mod 2 ^ 64 ptr_capp e ls m

2 open

ge :
f :
e :
listname × word
ls :
listname × optionZ
l, d :
off :
Z
rest :
listinst
j :
cs :
listframe × pending
m :
fuel :
Z
p :
Hp :
⊢
inst_stepge fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd P VaArgs Constoff :: rest j m Letd P VaArgs Constoff = SomeIContinueputd WPtrptr_addr ≔ ptr_addrp + off mod 2 ^ 64; ptr_cap ≔ ptr_capp e ls m
focused goal
ge :
f :
e :
listname × word
ls :
listname × optionZ
l, d :
off :
Z
rest :
listinst
j :
cs :
listframe × pending
m :
fuel :
Z
p :
Hp :
⊢
doomed_resultge fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd P VaArgs Constoff :: rest j m Letd P VaArgs Constoff IContinueputd WPtrptr_addr ≔ ptr_addrp + off mod 2 ^ 64; ptr_cap ≔ ptr_capp e ls m = SomeIContinueputd WPtrptr_addr ≔ ptr_addrp + off mod 2 ^ 64; ptr_cap ≔ ptr_capp e ls m, None

–cbn [ inst_step fr_env fr_locals ]

2 open

ge :
f :
e :
listname × word
ls :
listname × optionZ
l, d :
off :
Z
rest :
listinst
j :
cs :
listframe × pending
m :
fuel :
Z
p :
Hp :
⊢
match lookupva_snapshot e with
SomeWPtrp0
⇒
SomeIContinueputd WPtrptr_addr ≔ ptr_addrp0 + off mod 2 ^ 64; ptr_cap ≔ ptr_capp0 e ls m
_
⇒
None
=
SomeIContinueputd WPtrptr_addr ≔ ptr_addrp + off mod 2 ^ 64; ptr_cap ≔ ptr_capp e ls m
deferred goal
ge :
f :
e :
listname × word
ls :
listname × optionZ
l, d :
off :
Z
rest :
listinst
j :
cs :
listframe × pending
m :
fuel :
Z
p :
Hp :
⊢
doomed_resultge fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd P VaArgs Constoff :: rest j m Letd P VaArgs Constoff IContinueputd WPtrptr_addr ≔ ptr_addrp + off mod 2 ^ 64; ptr_cap ≔ ptr_capp e ls m = SomeIContinueputd WPtrptr_addr ≔ ptr_addrp + off mod 2 ^ 64; ptr_cap ≔ ptr_capp e ls m, None

rewrite Hp

2 open

ge :
f :
e :
listname × word
ls :
listname × optionZ
l, d :
off :
Z
rest :
listinst
j :
cs :
listframe × pending
m :
fuel :
Z
p :
Hp :
⊢
SomeIContinueputd WPtrptr_addr ≔ ptr_addrp + off mod 2 ^ 64; ptr_cap ≔ ptr_capp e ls m = SomeIContinueputd WPtrptr_addr ≔ ptr_addrp + off mod 2 ^ 64; ptr_cap ≔ ptr_capp e ls m
deferred goal
ge :
f :
e :
listname × word
ls :
listname × optionZ
l, d :
off :
Z
rest :
listinst
j :
cs :
listframe × pending
m :
fuel :
Z
p :
Hp :
⊢
doomed_resultge fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd P VaArgs Constoff :: rest j m Letd P VaArgs Constoff IContinueputd WPtrptr_addr ≔ ptr_addrp + off mod 2 ^ 64; ptr_cap ≔ ptr_capp e ls m = SomeIContinueputd WPtrptr_addr ≔ ptr_addrp + off mod 2 ^ 64; ptr_cap ≔ ptr_capp e ls m, None

reflexivity

deferred goal
ge :
f :
e :
listname × word
ls :
listname × optionZ
l, d :
off :
Z
rest :
listinst
j :
cs :
listframe × pending
m :
fuel :
Z
p :
Hp :
⊢
doomed_resultge fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd P VaArgs Constoff :: rest j m Letd P VaArgs Constoff IContinueputd WPtrptr_addr ≔ ptr_addrp + off mod 2 ^ 64; ptr_cap ≔ ptr_capp e ls m = SomeIContinueputd WPtrptr_addr ≔ ptr_addrp + off mod 2 ^ 64; ptr_cap ≔ ptr_capp e ls m, None

–apply doomed_result_continue

ge :
f :
e :
listname × word
ls :
listname × optionZ
l, d :
off :
Z
rest :
listinst
j :
cs :
listframe × pending
m :
fuel :
Z
p :
Hp :
⊢
fr_doomedfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd P VaArgs Constoff :: rest j = None

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hp
apply rule_instge f e ls l Letd P VaArgs Constoff rest j cs m fuel IContinueputd WPtrmkPtrptr_addrp + off mod 2 ^ 64 ptr_capp e ls m
rewrite Hp
reflexivity
reflexivity

For promotion: a successful variadic read updates the cursor's memory and binds its result. This is rule_let specialized to va_arg_res; the cursor is not frame-only state.

147Lemma rule_va_arg
∀ ge f e ls l d k args rest j cs m fuel p x m′
map2_optionvalue_xge e P args = SomeWPtrp
va_arg_resk p m = SomeRValx, m′
Semantics.stepge mkConfigmkFramef e ls None Execl Letd k VaArg args :: rest j cs m fuel = NextmkConfigmkFramef putd x e ls None Execl rest j cs m′ fuel
Explore proof 5 tactics

Initial goal

ge :
f :
e :
ls :
listname × optionZ
l, d :
args :
listvalue
rest :
listinst
j :
cs :
listframe × pending
m :
fuel :
Z
p :
x :
m′ :
⊢
map2_optionvalue_xge e P args = SomeWPtrp → va_arg_resk p m = SomeRValx, m′ → stepge c_frame ≔ fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd k VaArg args :: rest j; c_callers ≔ cs; c_mem ≔ m; c_fuel ≔ fuel = Nextc_frame ≔ fr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j; c_callers ≔ cs; c_mem ≔ m′; c_fuel ≔ fuel

intros Hargs Hread

ge :
f :
e :
ls :
listname × optionZ
l, d :
args :
listvalue
rest :
listinst
j :
cs :
listframe × pending
m :
fuel :
Z
p :
x :
m′ :
Hargs :
map2_optionvalue_xge e P args = SomeWPtrp
Hread :
va_arg_resk p m = SomeRValx, m′
⊢
stepge c_frame ≔ fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd k VaArg args :: rest j; c_callers ≔ cs; c_mem ≔ m; c_fuel ≔ fuel = Nextc_frame ≔ fr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j; c_callers ≔ cs; c_mem ≔ m′; c_fuel ≔ fuel

apply rule_let with classes := P xs := WPtrp ; reflexivity | reflexivity | exact Hargs |

ge :
f :
e :
ls :
listname × optionZ
l, d :
args :
listvalue
rest :
listinst
j :
cs :
listframe × pending
m :
fuel :
Z
p :
x :
m′ :
Hargs :
map2_optionvalue_xge e P args = SomeWPtrp
Hread :
va_arg_resk p m = SomeRValx, m′
⊢
op_resVaArg k WPtrp m = SomeOpResRValx m′

cbn [ op_res ]

ge :
f :
e :
ls :
listname × optionZ
l, d :
args :
listvalue
rest :
listinst
j :
cs :
listframe × pending
m :
fuel :
Z
p :
x :
m′ :
Hargs :
map2_optionvalue_xge e P args = SomeWPtrp
Hread :
va_arg_resk p m = SomeRValx, m′
⊢
let* rm ≔ va_arg_resk p m in
SomeOpResrm.1 rm.2
=
SomeOpResRValx m′

rewrite Hread

ge :
f :
e :
ls :
listname × optionZ
l, d :
args :
listvalue
rest :
listinst
j :
cs :
listframe × pending
m :
fuel :
Z
p :
x :
m′ :
Hargs :
map2_optionvalue_xge e P args = SomeWPtrp
Hread :
va_arg_resk p m = SomeRValx, m′
⊢
SomeOpResRValx, m′.1 RValx, m′.2 = SomeOpResRValx m′

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hargs Hread
apply rule_let with classes := P xs := WPtrp ; reflexivity | reflexivity | exact Hargs |
cbn [ op_res ]
rewrite Hread
reflexivity

For promotion: taking the pointer argument at an aligned cursor reads its bytes and capability after advancing the cursor. The hypotheses expose both checked reads and the checked cursor write, including the case where the write overlaps the argument cell.

163Lemma va_arg_pointer
∀ m p a c m′ x
a mod 8 = 0
access_resm a c 8 Read 8 = Someok
store_resWl m ptr_addrp ptr_capp WInta + 8 = Someok, m′
load_bytesm′ a 8 = ptr_addrx
aux_atm′ a = ptr_capx
va_arg_resP p m = SomeRValWPtrx, m′
Explore proof 14 tactics

Initial goal

m :
p :
a :
Z
c :
m′ :
x :
⊢
access_resm ptr_addrp ptr_capp 8 Read 8 = Someok → load_bytesm ptr_addrp 8 = a → aux_atm ptr_addrp = c → a mod 8 = 0 → access_resm a c 8 Read 8 = Someok → store_resWl m ptr_addrp ptr_capp WInta + 8 = Someok, m′ → load_bytesm′ a 8 = ptr_addrx → aux_atm′ a = ptr_capx → va_arg_resP p m = SomeRValWPtrx, m′

intros Hp Ha Hc Hal Hcell Hstore Haddr Hcap

m :
p :
a :
Z
c :
m′ :
x :
Hp :
Ha :
Hc :
Hal :
a mod 8 = 0
Hcell :
access_resm a c 8 Read 8 = Someok
Hstore :
store_resWl m ptr_addrp ptr_capp WInta + 8 = Someok, m′
Haddr :
load_bytesm′ a 8 = ptr_addrx
Hcap :
aux_atm′ a = ptr_capx
⊢
va_arg_resP p m = SomeRValWPtrx, m′

assert Halign : a + 8 − 1 / 8 × 8 = a

2 open

m :
p :
a :
Z
c :
m′ :
x :
Hp :
Ha :
Hc :
Hal :
a mod 8 = 0
Hcell :
access_resm a c 8 Read 8 = Someok
Hstore :
store_resWl m ptr_addrp ptr_capp WInta + 8 = Someok, m′
Haddr :
load_bytesm′ a 8 = ptr_addrx
Hcap :
aux_atm′ a = ptr_capx
⊢
a + 8 − 1 / 8 × 8 = a
focused goal
m :
p :
a :
Z
c :
m′ :
x :
Hp :
Ha :
Hc :
Hal :
a mod 8 = 0
Hcell :
access_resm a c 8 Read 8 = Someok
Hstore :
store_resWl m ptr_addrp ptr_capp WInta + 8 = Someok, m′
Haddr :
load_bytesm′ a 8 = ptr_addrx
Hcap :
aux_atm′ a = ptr_capx
Halign :
a + 8 − 1 / 8 × 8 = a
⊢
va_arg_resP p m = SomeRValWPtrx, m′

{pose proof Z.div_moda 8 ltac:lia as Hdiv

2 open

m :
p :
a :
Z
c :
m′ :
x :
Hp :
Ha :
Hc :
Hal :
a mod 8 = 0
Hcell :
access_resm a c 8 Read 8 = Someok
Hstore :
store_resWl m ptr_addrp ptr_capp WInta + 8 = Someok, m′
Haddr :
load_bytesm′ a 8 = ptr_addrx
Hcap :
aux_atm′ a = ptr_capx
Hdiv :
a = 8 × a / 8 + a mod 8
⊢
a + 8 − 1 / 8 × 8 = a
deferred goal
m :
p :
a :
Z
c :
m′ :
x :
Hp :
Ha :
Hc :
Hal :
a mod 8 = 0
Hcell :
access_resm a c 8 Read 8 = Someok
Hstore :
store_resWl m ptr_addrp ptr_capp WInta + 8 = Someok, m′
Haddr :
load_bytesm′ a 8 = ptr_addrx
Hcap :
aux_atm′ a = ptr_capx
Halign :
a + 8 − 1 / 8 × 8 = a
⊢
va_arg_resP p m = SomeRValWPtrx, m′

rewrite Hal in Hdiv

2 open

m :
p :
a :
Z
c :
m′ :
x :
Hp :
Ha :
Hc :
Hal :
a mod 8 = 0
Hcell :
access_resm a c 8 Read 8 = Someok
Hstore :
store_resWl m ptr_addrp ptr_capp WInta + 8 = Someok, m′
Haddr :
load_bytesm′ a 8 = ptr_addrx
Hcap :
aux_atm′ a = ptr_capx
Hdiv :
a = 8 × a / 8 + 0
⊢
a + 8 − 1 / 8 × 8 = a
deferred goal
m :
p :
a :
Z
c :
m′ :
x :
Hp :
Ha :
Hc :
Hal :
a mod 8 = 0
Hcell :
access_resm a c 8 Read 8 = Someok
Hstore :
store_resWl m ptr_addrp ptr_capp WInta + 8 = Someok, m′
Haddr :
load_bytesm′ a 8 = ptr_addrx
Hcap :
aux_atm′ a = ptr_capx
Halign :
a + 8 − 1 / 8 × 8 = a
⊢
va_arg_resP p m = SomeRValWPtrx, m′

replace a + 8 − 1 with 7 + a / 8 × 8 by lia

2 open

m :
p :
a :
Z
c :
m′ :
x :
Hp :
Ha :
Hc :
Hal :
a mod 8 = 0
Hcell :
access_resm a c 8 Read 8 = Someok
Hstore :
store_resWl m ptr_addrp ptr_capp WInta + 8 = Someok, m′
Haddr :
load_bytesm′ a 8 = ptr_addrx
Hcap :
aux_atm′ a = ptr_capx
Hdiv :
a = 8 × a / 8 + 0
⊢
7 + a / 8 × 8 / 8 × 8 = a
deferred goal
m :
p :
a :
Z
c :
m′ :
x :
Hp :
Ha :
Hc :
Hal :
a mod 8 = 0
Hcell :
access_resm a c 8 Read 8 = Someok
Hstore :
store_resWl m ptr_addrp ptr_capp WInta + 8 = Someok, m′
Haddr :
load_bytesm′ a 8 = ptr_addrx
Hcap :
aux_atm′ a = ptr_capx
Halign :
a + 8 − 1 / 8 × 8 = a
⊢
va_arg_resP p m = SomeRValWPtrx, m′

rewrite Z.div_add ; | lia

2 open

m :
p :
a :
Z
c :
m′ :
x :
Hp :
Ha :
Hc :
Hal :
a mod 8 = 0
Hcell :
access_resm a c 8 Read 8 = Someok
Hstore :
store_resWl m ptr_addrp ptr_capp WInta + 8 = Someok, m′
Haddr :
load_bytesm′ a 8 = ptr_addrx
Hcap :
aux_atm′ a = ptr_capx
Hdiv :
a = 8 × a / 8 + 0
⊢
7 / 8 + a / 8 × 8 = a
deferred goal
m :
p :
a :
Z
c :
m′ :
x :
Hp :
Ha :
Hc :
Hal :
a mod 8 = 0
Hcell :
access_resm a c 8 Read 8 = Someok
Hstore :
store_resWl m ptr_addrp ptr_capp WInta + 8 = Someok, m′
Haddr :
load_bytesm′ a 8 = ptr_addrx
Hcap :
aux_atm′ a = ptr_capx
Halign :
a + 8 − 1 / 8 × 8 = a
⊢
va_arg_resP p m = SomeRValWPtrx, m′

replace 7 / 8 with 0 by reflexivity

2 open

m :
p :
a :
Z
c :
m′ :
x :
Hp :
Ha :
Hc :
Hal :
a mod 8 = 0
Hcell :
access_resm a c 8 Read 8 = Someok
Hstore :
store_resWl m ptr_addrp ptr_capp WInta + 8 = Someok, m′
Haddr :
load_bytesm′ a 8 = ptr_addrx
Hcap :
aux_atm′ a = ptr_capx
Hdiv :
a = 8 × a / 8 + 0
⊢
0 + a / 8 × 8 = a
deferred goal
m :
p :
a :
Z
c :
m′ :
x :
Hp :
Ha :
Hc :
Hal :
a mod 8 = 0
Hcell :
access_resm a c 8 Read 8 = Someok
Hstore :
store_resWl m ptr_addrp ptr_capp WInta + 8 = Someok, m′
Haddr :
load_bytesm′ a 8 = ptr_addrx
Hcap :
aux_atm′ a = ptr_capx
Halign :
a + 8 − 1 / 8 × 8 = a
⊢
va_arg_resP p m = SomeRValWPtrx, m′

lia

deferred goal
m :
p :
a :
Z
c :
m′ :
x :
Hp :
Ha :
Hc :
Hal :
a mod 8 = 0
Hcell :
access_resm a c 8 Read 8 = Someok
Hstore :
store_resWl m ptr_addrp ptr_capp WInta + 8 = Someok, m′
Haddr :
load_bytesm′ a 8 = ptr_addrx
Hcap :
aux_atm′ a = ptr_capx
Halign :
a + 8 − 1 / 8 × 8 = a
⊢
va_arg_resP p m = SomeRValWPtrx, m′

unfold va_arg_res

m :
p :
a :
Z
c :
m′ :
x :
Hp :
Ha :
Hc :
Hal :
a mod 8 = 0
Hcell :
access_resm a c 8 Read 8 = Someok
Hstore :
store_resWl m ptr_addrp ptr_capp WInta + 8 = Someok, m′
Haddr :
load_bytesm′ a 8 = ptr_addrx
Hcap :
aux_atm′ a = ptr_capx
Halign :
a + 8 − 1 / 8 × 8 = a
⊢
match access_resm ptr_addrp ptr_capp 8 Read 8 with
SomeRVal_
⇒
match va_cellP with
Somestep, align
⇒
let* _ ≔ class_widthP in
match access_resm ptr_addrptr_addr ≔ load_bytesm ptr_addrp 8; ptr_cap ≔ aux_atm ptr_addrp + align − 1 / align × align ptr_capptr_addr ≔ load_bytesm ptr_addrp 8; ptr_cap ≔ aux_atm ptr_addrp step Read 8 with
SomeRVal_
⇒
match store_resWl m ptr_addrp ptr_capp WIntptr_addrptr_addr ≔ load_bytesm ptr_addrp 8; ptr_cap ≔ aux_atm ptr_addrp + align − 1 / align × align + step with
SomeRVal_, m1
⇒
SomeRValWPtrptr_addr ≔ load_bytesm1 ptr_addrptr_addr ≔ load_bytesm ptr_addrp 8; ptr_cap ≔ aux_atm ptr_addrp + align − 1 / align × align 8; ptr_cap ≔ aux_atm1 ptr_addrptr_addr ≔ load_bytesm ptr_addrp 8; ptr_cap ≔ aux_atm ptr_addrp + align − 1 / align × align, m1
SomeRTrapwhy, m1
⇒
SomeRTrapwhy, m1
_
⇒
None
SomeRTrapwhy
⇒
SomeRTrapwhy, m
_
⇒
None
None
⇒
None
SomeRTrapwhy
⇒
SomeRTrapwhy, m
_
⇒
None
=
SomeRValWPtrx, m′

rewrite Hp Ha Hc

m :
p :
a :
Z
c :
m′ :
x :
Hp :
Ha :
Hc :
Hal :
a mod 8 = 0
Hcell :
access_resm a c 8 Read 8 = Someok
Hstore :
store_resWl m ptr_addrp ptr_capp WInta + 8 = Someok, m′
Haddr :
load_bytesm′ a 8 = ptr_addrx
Hcap :
aux_atm′ a = ptr_capx
Halign :
a + 8 − 1 / 8 × 8 = a
⊢
match va_cellP with
Somestep, align
⇒
let* _ ≔ class_widthP in
match access_resm ptr_addrptr_addr ≔ a; ptr_cap ≔ c + align − 1 / align × align ptr_capptr_addr ≔ a; ptr_cap ≔ c step Read 8 with
SomeRVal_
⇒
match store_resWl m ptr_addrp ptr_capp WIntptr_addrptr_addr ≔ a; ptr_cap ≔ c + align − 1 / align × align + step with
SomeRVal_, m1
⇒
SomeRValWPtrptr_addr ≔ load_bytesm1 ptr_addrptr_addr ≔ a; ptr_cap ≔ c + align − 1 / align × align 8; ptr_cap ≔ aux_atm1 ptr_addrptr_addr ≔ a; ptr_cap ≔ c + align − 1 / align × align, m1
SomeRTrapwhy, m1
⇒
SomeRTrapwhy, m1
_
⇒
None
SomeRTrapwhy
⇒
SomeRTrapwhy, m
_
⇒
None
None
⇒
None
=
SomeRValWPtrx, m′

cbn [ va_cell class_width width_bytes ptr_addr ptr_cap ]

m :
p :
a :
Z
c :
m′ :
x :
Hp :
Ha :
Hc :
Hal :
a mod 8 = 0
Hcell :
access_resm a c 8 Read 8 = Someok
Hstore :
store_resWl m ptr_addrp ptr_capp WInta + 8 = Someok, m′
Haddr :
load_bytesm′ a 8 = ptr_addrx
Hcap :
aux_atm′ a = ptr_capx
Halign :
a + 8 − 1 / 8 × 8 = a
⊢
match access_resm a + 8 − 1 / 8 × 8 c 8 Read 8 with
SomeRVal_
⇒
match store_resWl m ptr_addrp ptr_capp WInta + 8 − 1 / 8 × 8 + 8 with
SomeRVal_, m1
⇒
SomeRValWPtrptr_addr ≔ load_bytesm1 a + 8 − 1 / 8 × 8 8; ptr_cap ≔ aux_atm1 a + 8 − 1 / 8 × 8, m1
SomeRTrapwhy, m1
⇒
SomeRTrapwhy, m1
_
⇒
None
SomeRTrapwhy
⇒
SomeRTrapwhy, m
_
⇒
None
=
SomeRValWPtrx, m′

rewrite Halign Hcell Hstore Haddr Hcap

m :
p :
a :
Z
c :
m′ :
x :
Hp :
Ha :
Hc :
Hal :
a mod 8 = 0
Hcell :
access_resm a c 8 Read 8 = Someok
Hstore :
store_resWl m ptr_addrp ptr_capp WInta + 8 = Someok, m′
Haddr :
load_bytesm′ a 8 = ptr_addrx
Hcap :
aux_atm′ a = ptr_capx
Halign :
a + 8 − 1 / 8 × 8 = a
⊢
SomeRValWPtrptr_addr ≔ ptr_addrx; ptr_cap ≔ ptr_capx, m′ = SomeRValWPtrx, m′

destruct x

m :
p :
a :
Z
c :
m′ :
ptr_addr :
Z
ptr_cap :
Hal :
a mod 8 = 0
Hcell :
access_resm a c 8 Read 8 = Someok
Hstore :
Haddr :
load_bytesm′ a 8 = Values.ptr_addrptr_addr ≔ ptr_addr; ptr_cap ≔ ptr_cap
Hcap :
aux_atm′ a = Values.ptr_capptr_addr ≔ ptr_addr; ptr_cap ≔ ptr_cap
Halign :
a + 8 − 1 / 8 × 8 = a
⊢
SomeRValWPtrptr_addr ≔ Values.ptr_addrptr_addr ≔ ptr_addr; ptr_cap ≔ ptr_cap; ptr_cap ≔ Values.ptr_capptr_addr ≔ ptr_addr; ptr_cap ≔ ptr_cap, m′ = SomeRValWPtrptr_addr ≔ ptr_addr; ptr_cap ≔ ptr_cap, m′

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hp Ha Hc Hal Hcell Hstore Haddr Hcap
assert Halign : a + 8 − 1 / 8 × 8 = a
{pose proof Z.div_moda 8 ltac:lia as Hdiv
rewrite Hal in Hdiv
replace a + 8 − 1 with 7 + a / 8 × 8 by lia
rewrite Z.div_add ; | lia
replace 7 / 8 with 0 by reflexivity
lia
unfold va_arg_res
rewrite Hp Ha Hc
rewrite Halign Hcell Hstore Haddr Hcap
destruct x
reflexivity

For promotion: snapshot stores at an address depend only on the bytes and capability already at that address, not on other memory.

185Lemma snapshot_values_pointwise
∀ xs a m1 m2 t
m_bytesm1 t = m_bytesm2 t
m_auxm1 t = m_auxm2 t
Explore proof 3 tactics

Initial goal

xs :
listword
a :
Z
m1, m2 :
t :
Z
⊢
m_bytesm1 t = m_bytesm2 t → m_auxm1 t = m_auxm2 t → m_bytessnapshot_valuesxs a m1 t = m_bytessnapshot_valuesxs a m2 t ∧ m_auxsnapshot_valuesxs a m1 t = m_auxsnapshot_valuesxs a m2 t

revert a m1 m2

xs :
listword
t :
Z
⊢
∀a : Z m1 m2 : mem, m_bytesm1 t = m_bytesm2 t → m_auxm1 t = m_auxm2 t → m_bytessnapshot_valuesxs a m1 t = m_bytessnapshot_valuesxs a m2 t ∧ m_auxsnapshot_valuesxs a m1 t = m_auxsnapshot_valuesxs a m2 t

induction xs as | x xs IH ; intros a m1 m2 Hb Ha ; exact conjHb Ha |

x :
xs :
listword
t :
Z
IH :
∀a : Z m1 m2 : mem, m_bytesm1 t = m_bytesm2 t → m_auxm1 t = m_auxm2 t → m_bytessnapshot_valuesxs a m1 t = m_bytessnapshot_valuesxs a m2 t ∧ m_auxsnapshot_valuesxs a m1 t = m_auxsnapshot_valuesxs a m2 t
a :
Z
m1, m2 :
Hb :
m_bytesm1 t = m_bytesm2 t
Ha :
m_auxm1 t = m_auxm2 t
⊢
m_bytessnapshot_valuesx :: xs a m1 t = m_bytessnapshot_valuesx :: xs a m2 t ∧ m_auxsnapshot_valuesx :: xs a m1 t = m_auxsnapshot_valuesx :: xs a m2 t

destruct x ; cbn [ snapshot_values ] ; apply IH ; cbn [ store_bytes store_aux m_bytes m_aux ] ; try rewrite Hb ; try rewrite Ha ; reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
revert a m1 m2
induction xs as | x xs IH ; intros a m1 m2 Hb Ha ; exact conjHb Ha |
destruct x ; cbn [ snapshot_values ] ; apply IH ; cbn [ store_bytes store_aux m_bytes m_aux ] ; try rewrite Hb ; try rewrite Ha ; reflexivity

For promotion: taking the snapshot changes no address outside its eight-byte argument cells, even for words the snapshot skips.

199Lemma snapshot_values_outside
∀ xs a m t
t < a ∨ a + 8 × Z.of_natlengthxs ≤ t
m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
Explore proof 19 tactics

Initial goal

xs :
listword
a :
Z
m :
t :
Z
⊢
t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t

revert a m

xs :
listword
t :
Z
⊢
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t

induction xs as | x xs IH ; intros a m Hout ; split ; reflexivity |

x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × lengthx :: xs ≤ t
⊢
m_bytessnapshot_valuesx :: xs a m t = m_bytesm t ∧ m_auxsnapshot_valuesx :: xs a m t = m_auxm t

cbn [ length ] in Hout

x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × Slengthxs ≤ t
⊢
m_bytessnapshot_valuesx :: xs a m t = m_bytesm t ∧ m_auxsnapshot_valuesx :: xs a m t = m_auxm t

rewrite Nat2Z.inj_succ in Hout

x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × Z.succlengthxs ≤ t
⊢
m_bytessnapshot_valuesx :: xs a m t = m_bytesm t ∧ m_auxsnapshot_valuesx :: xs a m t = m_auxm t

assert Htail : t < a + 8 ∨ a + 8 + 8 × Z.of_natlengthxs ≤ t

2 open

x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × Z.succlengthxs ≤ t
⊢
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
focused goal
x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
⊢
m_bytessnapshot_valuesx :: xs a m t = m_bytesm t ∧ m_auxsnapshot_valuesx :: xs a m t = m_auxm t

{lia

deferred goal
x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
⊢
m_bytessnapshot_valuesx :: xs a m t = m_bytesm t ∧ m_auxsnapshot_valuesx :: xs a m t = m_auxm t

assert Hbyte : a ≤? t && t <? a + 8 = false

2 open

x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
⊢
a ≤? t && t <? a + 8 = false
focused goal
x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
Hbyte :
a ≤? t && t <? a + 8 = false
⊢
m_bytessnapshot_valuesx :: xs a m t = m_bytesm t ∧ m_auxsnapshot_valuesx :: xs a m t = m_auxm t

{apply andb_false_iff

2 open

x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
⊢
a ≤? t = false ∨ t <? a + 8 = false
deferred goal
x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
Hbyte :
a ≤? t && t <? a + 8 = false
⊢
m_bytessnapshot_valuesx :: xs a m t = m_bytesm t ∧ m_auxsnapshot_valuesx :: xs a m t = m_auxm t

destruct Hout as Hout | Hout

3 open

x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
⊢
a ≤? t = false ∨ t <? a + 8 = false
focused goal
x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
⊢
a ≤? t = false ∨ t <? a + 8 = false
deferred goal
x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
Hbyte :
a ≤? t && t <? a + 8 = false
⊢
m_bytessnapshot_valuesx :: xs a m t = m_bytesm t ∧ m_auxsnapshot_valuesx :: xs a m t = m_auxm t

–left

3 open

x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
⊢
a ≤? t = false
deferred goal
x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
⊢
a ≤? t = false ∨ t <? a + 8 = false
deferred goal
x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
Hbyte :
a ≤? t && t <? a + 8 = false
⊢
m_bytessnapshot_valuesx :: xs a m t = m_bytesm t ∧ m_auxsnapshot_valuesx :: xs a m t = m_auxm t

apply Z.leb_gt

3 open

x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
⊢
t < a
deferred goal
x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
⊢
a ≤? t = false ∨ t <? a + 8 = false
deferred goal
x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
Hbyte :
a ≤? t && t <? a + 8 = false
⊢
m_bytessnapshot_valuesx :: xs a m t = m_bytesm t ∧ m_auxsnapshot_valuesx :: xs a m t = m_auxm t

lia

2 open

deferred goal
x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
⊢
a ≤? t = false ∨ t <? a + 8 = false
deferred goal
x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
Hbyte :
a ≤? t && t <? a + 8 = false
⊢
m_bytessnapshot_valuesx :: xs a m t = m_bytesm t ∧ m_auxsnapshot_valuesx :: xs a m t = m_auxm t

–right

2 open

x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
⊢
t <? a + 8 = false
deferred goal
x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
Hbyte :
a ≤? t && t <? a + 8 = false
⊢
m_bytessnapshot_valuesx :: xs a m t = m_bytesm t ∧ m_auxsnapshot_valuesx :: xs a m t = m_auxm t

apply Z.ltb_ge

2 open

x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
⊢
a + 8 ≤ t
deferred goal
x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
Hbyte :
a ≤? t && t <? a + 8 = false
⊢
m_bytessnapshot_valuesx :: xs a m t = m_bytesm t ∧ m_auxsnapshot_valuesx :: xs a m t = m_auxm t

lia

deferred goal
x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
Hbyte :
a ≤? t && t <? a + 8 = false
⊢
m_bytessnapshot_valuesx :: xs a m t = m_bytesm t ∧ m_auxsnapshot_valuesx :: xs a m t = m_auxm t

assert Haux : t =? a = false

2 open

x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
Hbyte :
a ≤? t && t <? a + 8 = false
⊢
t =? a = false
focused goal
x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
Hbyte :
a ≤? t && t <? a + 8 = false
Haux :
t =? a = false
⊢
m_bytessnapshot_valuesx :: xs a m t = m_bytesm t ∧ m_auxsnapshot_valuesx :: xs a m t = m_auxm t

{apply Z.eqb_neq

2 open

x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
Hbyte :
a ≤? t && t <? a + 8 = false
⊢
t ≠ a
deferred goal
x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
Hbyte :
a ≤? t && t <? a + 8 = false
Haux :
t =? a = false
⊢
m_bytessnapshot_valuesx :: xs a m t = m_bytesm t ∧ m_auxsnapshot_valuesx :: xs a m t = m_auxm t

destruct Hout as Hout | Hout ; rewrite ?Nat2Z.inj_succ in Hout ; lia

deferred goal
x :
xs :
listword
t :
Z
IH :
∀a : Z m : mem, t < a ∨ a + 8 × lengthxs ≤ t → m_bytessnapshot_valuesxs a m t = m_bytesm t ∧ m_auxsnapshot_valuesxs a m t = m_auxm t
a :
Z
m :
Hout :
t < a ∨ a + 8 × Z.succlengthxs ≤ t
Htail :
t < a + 8 ∨ a + 8 + 8 × lengthxs ≤ t
Hbyte :
a ≤? t && t <? a + 8 = false
Haux :
t =? a = false
⊢
m_bytessnapshot_valuesx :: xs a m t = m_bytesm t ∧ m_auxsnapshot_valuesx :: xs a m t = m_auxm t

destruct x ; cbn [ snapshot_values ];match goal with|- m_bytessnapshot_valuesxs ?a′ ?m′ t = _ ∧ _⇒destruct IHa′ m′ Htail as Hb Haend;rewrite Hb Ha;cbn [ store_bytes store_aux m_bytes m_aux ];rewrite ?Hbyte ?Haux;split;reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
revert a m
induction xs as | x xs IH ; intros a m Hout ; split ; reflexivity |
cbn [ length ] in Hout
rewrite Nat2Z.inj_succ in Hout
assert Htail : t < a + 8 ∨ a + 8 + 8 × Z.of_natlengthxs ≤ t
{lia
assert Hbyte : a ≤? t && t <? a + 8 = false
{apply andb_false_iff
destruct Hout as Hout | Hout
–left
apply Z.leb_gt
lia
–right
apply Z.ltb_ge
lia
assert Haux : t =? a = false
{apply Z.eqb_neq
destruct Hout as Hout | Hout ; rewrite ?Nat2Z.inj_succ in Hout ; lia
destruct x ; cbn [ snapshot_values ];match goal with|- m_bytessnapshot_valuesxs ?a′ ?m′ t = _ ∧ _⇒destruct IHa′ m′ Htail as Hb Haend;rewrite Hb Ha;cbn [ store_bytes store_aux m_bytes m_aux ];rewrite ?Hbyte ?Haux;split;reflexivity

A pointer argument's bytes survive all the later snapshot stores.

225Lemma snapshot_pointer_byte
∀ xs i p a m j
xs !! i = SomeWPtrp
0 ≤ j < 8
m_bytessnapshot_valuesxs a m a + 8 × Z.of_nati + j = byte_ofptr_addrp j
Explore proof 16 tactics

Initial goal

xs :
listword
i :
nat
p :
a :
Z
m :
j :
Z
⊢
xs !! i = SomeWPtrp → 0 ≤ j < 8 → m_bytessnapshot_valuesxs a m a + 8 × i + j = byte_ofptr_addrp j

revert xs a m

i :
nat
p :
j :
Z
⊢
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → 0 ≤ j < 8 → m_bytessnapshot_valuesxs a m a + 8 × i + j = byte_ofptr_addrp j

induction i as | i IH ; intros | x xs a m Hnth Hj ; try discriminate

2 open

p :
j :
Z
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! 0%nat = SomeWPtrp
Hj :
0 ≤ j < 8
⊢
m_bytessnapshot_valuesx :: xs a m a + 8 × 0%nat + j = byte_ofptr_addrp j
focused goal
i :
nat
p :
j :
Z
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → 0 ≤ j < 8 → m_bytessnapshot_valuesxs a m a + 8 × i + j = byte_ofptr_addrp j
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
Hj :
0 ≤ j < 8
⊢
m_bytessnapshot_valuesx :: xs a m a + 8 × Si + j = byte_ofptr_addrp j

–cbn [ lookup list_lookup ] in Hnth

2 open

p :
j :
Z
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! 0%nat = SomeWPtrp
Hj :
0 ≤ j < 8
⊢
m_bytessnapshot_valuesx :: xs a m a + 8 × 0%nat + j = byte_ofptr_addrp j
deferred goal
i :
nat
p :
j :
Z
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → 0 ≤ j < 8 → m_bytessnapshot_valuesxs a m a + 8 × i + j = byte_ofptr_addrp j
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
Hj :
0 ≤ j < 8
⊢
m_bytessnapshot_valuesx :: xs a m a + 8 × Si + j = byte_ofptr_addrp j

injection Hnth as →

2 open

p :
j :
Z
xs :
listword
a :
Z
m :
Hj :
0 ≤ j < 8
⊢
m_bytessnapshot_valuesWPtrp :: xs a m a + 8 × 0%nat + j = byte_ofptr_addrp j
deferred goal
i :
nat
p :
j :
Z
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → 0 ≤ j < 8 → m_bytessnapshot_valuesxs a m a + 8 × i + j = byte_ofptr_addrp j
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
Hj :
0 ≤ j < 8
⊢
m_bytessnapshot_valuesx :: xs a m a + 8 × Si + j = byte_ofptr_addrp j

cbn [ snapshot_values ]

2 open

p :
j :
Z
xs :
listword
a :
Z
m :
Hj :
0 ≤ j < 8
⊢
m_bytessnapshot_valuesxs a + 8 store_auxstore_bytesm a 8 ptr_addrp a ptr_capp a + 8 × 0%nat + j = byte_ofptr_addrp j
deferred goal
i :
nat
p :
j :
Z
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → 0 ≤ j < 8 → m_bytessnapshot_valuesxs a m a + 8 × i + j = byte_ofptr_addrp j
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
Hj :
0 ≤ j < 8
⊢
m_bytessnapshot_valuesx :: xs a m a + 8 × Si + j = byte_ofptr_addrp j

rewrite Z.mul_0_r Z.add_0_r

2 open

p :
j :
Z
xs :
listword
a :
Z
m :
Hj :
0 ≤ j < 8
deferred goal
i :
nat
p :
j :
Z
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → 0 ≤ j < 8 → m_bytessnapshot_valuesxs a m a + 8 × i + j = byte_ofptr_addrp j
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
Hj :
0 ≤ j < 8
⊢
m_bytessnapshot_valuesx :: xs a m a + 8 × Si + j = byte_ofptr_addrp j

rewrite proj1snapshot_values_outsidexs a + 8 _ a + j ltac:left ; lia

2 open

p :
j :
Z
xs :
listword
a :
Z
m :
Hj :
0 ≤ j < 8
deferred goal
i :
nat
p :
j :
Z
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → 0 ≤ j < 8 → m_bytessnapshot_valuesxs a m a + 8 × i + j = byte_ofptr_addrp j
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
Hj :
0 ≤ j < 8
⊢
m_bytessnapshot_valuesx :: xs a m a + 8 × Si + j = byte_ofptr_addrp j

cbn [ store_aux store_bytes m_bytes ]

2 open

p :
j :
Z
xs :
listword
a :
Z
m :
Hj :
0 ≤ j < 8
⊢
a ≤? a + j && a + j <? a + 8
→
byte_ofptr_addrp a + j − a
else
m_bytesm a + j
=
deferred goal
i :
nat
p :
j :
Z
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → 0 ≤ j < 8 → m_bytessnapshot_valuesxs a m a + 8 × i + j = byte_ofptr_addrp j
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
Hj :
0 ≤ j < 8
⊢
m_bytessnapshot_valuesx :: xs a m a + 8 × Si + j = byte_ofptr_addrp j

rewrite proj2Z.leb_lea a + j ltac:lia

2 open

p :
j :
Z
xs :
listword
a :
Z
m :
Hj :
0 ≤ j < 8
⊢
true && a + j <? a + 8
→
byte_ofptr_addrp a + j − a
else
m_bytesm a + j
=
deferred goal
i :
nat
p :
j :
Z
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → 0 ≤ j < 8 → m_bytessnapshot_valuesxs a m a + 8 × i + j = byte_ofptr_addrp j
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
Hj :
0 ≤ j < 8
⊢
m_bytessnapshot_valuesx :: xs a m a + 8 × Si + j = byte_ofptr_addrp j

rewrite proj2Z.ltb_lta + j a + 8 ltac:lia

2 open

p :
j :
Z
xs :
listword
a :
Z
m :
Hj :
0 ≤ j < 8
⊢
true && true
→
byte_ofptr_addrp a + j − a
else
m_bytesm a + j
=
deferred goal
i :
nat
p :
j :
Z
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → 0 ≤ j < 8 → m_bytessnapshot_valuesxs a m a + 8 × i + j = byte_ofptr_addrp j
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
Hj :
0 ≤ j < 8
⊢
m_bytessnapshot_valuesx :: xs a m a + 8 × Si + j = byte_ofptr_addrp j

cbn [ andb ]

2 open

p :
j :
Z
xs :
listword
a :
Z
m :
Hj :
0 ≤ j < 8
⊢
byte_ofptr_addrp a + j − a = byte_ofptr_addrp j
deferred goal
i :
nat
p :
j :
Z
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → 0 ≤ j < 8 → m_bytessnapshot_valuesxs a m a + 8 × i + j = byte_ofptr_addrp j
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
Hj :
0 ≤ j < 8
⊢
m_bytessnapshot_valuesx :: xs a m a + 8 × Si + j = byte_ofptr_addrp j

replace a + j − a with j by lia

2 open

p :
j :
Z
xs :
listword
a :
Z
m :
Hj :
0 ≤ j < 8
deferred goal
i :
nat
p :
j :
Z
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → 0 ≤ j < 8 → m_bytessnapshot_valuesxs a m a + 8 × i + j = byte_ofptr_addrp j
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
Hj :
0 ≤ j < 8
⊢
m_bytessnapshot_valuesx :: xs a m a + 8 × Si + j = byte_ofptr_addrp j

reflexivity

deferred goal
i :
nat
p :
j :
Z
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → 0 ≤ j < 8 → m_bytessnapshot_valuesxs a m a + 8 × i + j = byte_ofptr_addrp j
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
Hj :
0 ≤ j < 8
⊢
m_bytessnapshot_valuesx :: xs a m a + 8 × Si + j = byte_ofptr_addrp j

–cbn [ lookup list_lookup ] in Hnth

i :
nat
p :
j :
Z
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → 0 ≤ j < 8 → m_bytessnapshot_valuesxs a m a + 8 × i + j = byte_ofptr_addrp j
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
Hj :
0 ≤ j < 8
⊢
m_bytessnapshot_valuesx :: xs a m a + 8 × Si + j = byte_ofptr_addrp j

replace a + 8 × Z.of_natSi + j with a + 8 + 8 × Z.of_nati + j by rewrite Nat2Z.inj_succ ; lia

i :
nat
p :
j :
Z
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → 0 ≤ j < 8 → m_bytessnapshot_valuesxs a m a + 8 × i + j = byte_ofptr_addrp j
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
Hj :
0 ≤ j < 8
⊢
m_bytessnapshot_valuesx :: xs a m a + 8 + 8 × i + j = byte_ofptr_addrp j

destruct x ; cbn [ snapshot_values ] ; apply IH ; assumption

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
revert xs a m
induction i as | i IH ; intros | x xs a m Hnth Hj ; try discriminate
–cbn [ lookup list_lookup ] in Hnth
injection Hnth as →
rewrite Z.mul_0_r Z.add_0_r
rewrite proj1snapshot_values_outsidexs a + 8 _ a + j ltac:left ; lia
rewrite proj2Z.leb_lea a + j ltac:lia
rewrite proj2Z.ltb_lta + j a + 8 ltac:lia
cbn [ andb ]
replace a + j − a with j by lia
reflexivity
–cbn [ lookup list_lookup ] in Hnth
replace a + 8 × Z.of_natSi + j with a + 8 + 8 × Z.of_nati + j by rewrite Nat2Z.inj_succ ; lia
destruct x ; cbn [ snapshot_values ] ; apply IH ; assumption

A pointer argument's capability survives all later snapshot stores.

244Lemma snapshot_pointer_aux
∀ xs i p a m
xs !! i = SomeWPtrp
m_auxsnapshot_valuesxs a m a + 8 × Z.of_nati = ptr_capp
Explore proof 13 tactics

Initial goal

xs :
listword
i :
nat
p :
a :
Z
m :
⊢
xs !! i = SomeWPtrp → m_auxsnapshot_valuesxs a m a + 8 × i = ptr_capp

revert xs a m

i :
nat
p :
⊢
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → m_auxsnapshot_valuesxs a m a + 8 × i = ptr_capp

induction i as | i IH ; intros | x xs a m Hnth ; try discriminate

2 open

p :
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! 0%nat = SomeWPtrp
⊢
m_auxsnapshot_valuesx :: xs a m a + 8 × 0%nat = ptr_capp
focused goal
i :
nat
p :
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → m_auxsnapshot_valuesxs a m a + 8 × i = ptr_capp
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
⊢
m_auxsnapshot_valuesx :: xs a m a + 8 × Si = ptr_capp

–cbn [ lookup list_lookup ] in Hnth

2 open

p :
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! 0%nat = SomeWPtrp
⊢
m_auxsnapshot_valuesx :: xs a m a + 8 × 0%nat = ptr_capp
deferred goal
i :
nat
p :
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → m_auxsnapshot_valuesxs a m a + 8 × i = ptr_capp
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
⊢
m_auxsnapshot_valuesx :: xs a m a + 8 × Si = ptr_capp

injection Hnth as →

2 open

p :
xs :
listword
a :
Z
m :
⊢
m_auxsnapshot_valuesWPtrp :: xs a m a + 8 × 0%nat = ptr_capp
deferred goal
i :
nat
p :
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → m_auxsnapshot_valuesxs a m a + 8 × i = ptr_capp
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
⊢
m_auxsnapshot_valuesx :: xs a m a + 8 × Si = ptr_capp

cbn [ snapshot_values ]

2 open

p :
xs :
listword
a :
Z
m :
⊢
m_auxsnapshot_valuesxs a + 8 store_auxstore_bytesm a 8 ptr_addrp a ptr_capp a + 8 × 0%nat = ptr_capp
deferred goal
i :
nat
p :
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → m_auxsnapshot_valuesxs a m a + 8 × i = ptr_capp
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
⊢
m_auxsnapshot_valuesx :: xs a m a + 8 × Si = ptr_capp

rewrite Z.mul_0_r Z.add_0_r

2 open

p :
xs :
listword
a :
Z
m :
deferred goal
i :
nat
p :
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → m_auxsnapshot_valuesxs a m a + 8 × i = ptr_capp
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
⊢
m_auxsnapshot_valuesx :: xs a m a + 8 × Si = ptr_capp

rewrite proj2snapshot_values_outsidexs a + 8 _ a ltac:left ; lia

2 open

p :
xs :
listword
a :
Z
m :
deferred goal
i :
nat
p :
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → m_auxsnapshot_valuesxs a m a + 8 × i = ptr_capp
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
⊢
m_auxsnapshot_valuesx :: xs a m a + 8 × Si = ptr_capp

cbn [ store_aux m_aux ]

2 open

p :
xs :
listword
a :
Z
m :
⊢
a =? a
→
=
deferred goal
i :
nat
p :
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → m_auxsnapshot_valuesxs a m a + 8 × i = ptr_capp
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
⊢
m_auxsnapshot_valuesx :: xs a m a + 8 × Si = ptr_capp

rewrite Z.eqb_refl

2 open

p :
xs :
listword
a :
Z
m :
deferred goal
i :
nat
p :
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → m_auxsnapshot_valuesxs a m a + 8 × i = ptr_capp
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
⊢
m_auxsnapshot_valuesx :: xs a m a + 8 × Si = ptr_capp

reflexivity

deferred goal
i :
nat
p :
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → m_auxsnapshot_valuesxs a m a + 8 × i = ptr_capp
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
⊢
m_auxsnapshot_valuesx :: xs a m a + 8 × Si = ptr_capp

–cbn [ lookup list_lookup ] in Hnth

i :
nat
p :
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → m_auxsnapshot_valuesxs a m a + 8 × i = ptr_capp
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
⊢
m_auxsnapshot_valuesx :: xs a m a + 8 × Si = ptr_capp

replace a + 8 × Z.of_natSi with a + 8 + 8 × Z.of_nati by rewrite Nat2Z.inj_succ ; lia

i :
nat
p :
IH :
∀xs : listword a : Z m : mem, xs !! i = SomeWPtrp → m_auxsnapshot_valuesxs a m a + 8 × i = ptr_capp
x :
xs :
listword
a :
Z
m :
Hnth :
x :: xs !! Si = SomeWPtrp
⊢
m_auxsnapshot_valuesx :: xs a m a + 8 + 8 × i = ptr_capp

destruct x ; cbn [ snapshot_values ] ; apply IH ; assumption

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
revert xs a m
induction i as | i IH ; intros | x xs a m Hnth ; try discriminate
–cbn [ lookup list_lookup ] in Hnth
injection Hnth as →
rewrite Z.mul_0_r Z.add_0_r
rewrite proj2snapshot_values_outsidexs a + 8 _ a ltac:left ; lia
rewrite Z.eqb_refl
reflexivity
–cbn [ lookup list_lookup ] in Hnth
replace a + 8 × Z.of_natSi with a + 8 + 8 × Z.of_nati by rewrite Nat2Z.inj_succ ; lia
destruct x ; cbn [ snapshot_values ] ; apply IH ; assumption

For promotion: values for a snapshot's pieces can be computed from empty memory. Freshness guarantees the actual allocated cells start with the same zero bytes and empty capability slots.

262Definition snapshot_piecexs base q lv : piece × pval : piece × pval ≔
let m ≔ snapshot_valuesxs base allocatedempty_mem q base in
match lv.1 with
⇒
lv.1, VBytem_bytesm b + o
PAuxb o
⇒
lv.1, VAuxm_auxm b + o
_
⇒
lv

For promotion: a snapshot owns the same keys as the new object, populated with the snapshot's bytes and capabilities.

272Definition snapshot_psxs base q : listpiece × pval ≔
snapshot_piecexs base q <$> obj_psbase q

For promotion: populating a snapshot leaves its ownership keys unchanged, so their distinctness follows from obj_ps_nodup.

277Lemma snapshot_ps_keys
∀ xs base q
snapshot_psxs base q.*1 = obj_psbase q.*1
Explore proof 5 tactics

Initial goal

xs :
listword
base :
Z
⊢
snapshot_psxs base q.*1 = obj_psbase q.*1

unfold snapshot_ps

xs :
listword
base :
Z
⊢
snapshot_piecexs base q <$> obj_psbase q.*1 = obj_psbase q.*1

rewrite - list_fmap_compose

xs :
listword
base :
Z
⊢
fst ∘ snapshot_piecexs base q <$> obj_psbase q = obj_psbase q.*1

apply list_fmap_ext

xs :
listword
base :
Z
⊢
∀i : nat x : piece × pval, obj_psbase q !! i = Somex → fst ∘ snapshot_piecexs base qx = x.1

intros i l v Hi

xs :
listword
base :
Z
i :
nat
v :
Hi :
obj_psbase q !! i = Somel, v
⊢
fst ∘ snapshot_piecexs base ql, v = l, v.1

destruct l ; reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
rewrite - list_fmap_compose
apply list_fmap_ext
intros i l v Hi
destruct l ; reflexivity

The snapshot pieces contain an argument's complete pointer cell.

285Lemma snapshot_ps_pointer
∀ xs i p base q l v
xs !! i = SomeWPtrp
8 × Z.of_natSi ≤ req_extentq
l, v ∈ PAuxbase 8 × Z.of_nati, VAuxptr_capp :: cellbase 8 × Z.of_nati ptr_addrp
l, v ∈ snapshot_psxs base q
Explore proof 46 tactics

Initial goal

xs :
listword
i :
nat
p :
base :
Z
⊢
xs !! i = SomeWPtrp → 8 × Si ≤ req_extentq → ∀l : piece v : pval, l, v ∈ PAuxbase 8 × i, VAuxptr_capp :: cellbase 8 × i ptr_addrp → l, v ∈ snapshot_psxs base q

intros Hnth Hextent l v Hin

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ PAuxbase 8 × i, VAuxptr_capp :: cellbase 8 × i ptr_addrp
⊢
l, v ∈ snapshot_psxs base q

unfold snapshot_ps

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ PAuxbase 8 × i, VAuxptr_capp :: cellbase 8 × i ptr_addrp
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

apply elem_of_cons in Hin as = → → | Hin

2 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
⊢
PAuxbase 8 × i, VAuxptr_capp ∈ snapshot_piecexs base q <$> obj_psbase q
focused goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ cellbase 8 × i ptr_addrp
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

–apply list_elem_of_fmap

2 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
⊢
∃x : piece × pval, PAuxbase 8 × i, VAuxptr_capp = snapshot_piecexs base q x ∧ x ∈ obj_psbase q
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ cellbase 8 × i ptr_addrp
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

exists PAuxbase 8 × Z.of_nati, VAuxCNone

2 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
⊢
PAuxbase 8 × i, VAuxptr_capp = snapshot_piecexs base q PAuxbase 8 × i, VAuxCNone ∧ PAuxbase 8 × i, VAuxCNone ∈ obj_psbase q
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ cellbase 8 × i ptr_addrp
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

split

3 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
⊢
PAuxbase 8 × i, VAuxptr_capp = snapshot_piecexs base q PAuxbase 8 × i, VAuxCNone
focused goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
⊢
PAuxbase 8 × i, VAuxCNone ∈ obj_psbase q
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ cellbase 8 × i ptr_addrp
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

+unfold snapshot_piece

3 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
⊢
PAuxbase 8 × i, VAuxptr_capp
=
match PAuxbase 8 × i, VAuxCNone.1 with
⇒
PAuxbase 8 × i, VAuxCNone.1, VBytem_bytessnapshot_valuesxs base allocatedempty_mem q base b + o
PAuxb o
⇒
PAuxbase 8 × i, VAuxCNone.1, VAuxm_auxsnapshot_valuesxs base allocatedempty_mem q base b + o
_
⇒
PAuxbase 8 × i, VAuxCNone
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
⊢
PAuxbase 8 × i, VAuxCNone ∈ obj_psbase q
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ cellbase 8 × i ptr_addrp
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

cbn [ fst snd ]

3 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
⊢
PAuxbase 8 × i, VAuxptr_capp = PAuxbase 8 × i, VAuxm_auxsnapshot_valuesxs base allocatedempty_mem q base base + 8 × i
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
⊢
PAuxbase 8 × i, VAuxCNone ∈ obj_psbase q
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ cellbase 8 × i ptr_addrp
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

rewrite snapshot_pointer_aux_ _ _ _ _ Hnth

3 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
⊢
PAuxbase 8 × i, VAuxptr_capp = PAuxbase 8 × i, VAuxptr_capp
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
⊢
PAuxbase 8 × i, VAuxCNone ∈ obj_psbase q
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ cellbase 8 × i ptr_addrp
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

reflexivity

2 open

deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
⊢
PAuxbase 8 × i, VAuxCNone ∈ obj_psbase q
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ cellbase 8 × i ptr_addrp
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

+unfold obj_ps

2 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
⊢
PAuxbase 8 × i, VAuxCNone ∈ PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live :: λi0 : Z ⇒ PBytebase i0, VByte0 <$> seqZ0 req_extentq ++ λi0 : Z ⇒ PAuxbase i0, VAuxCNone <$> seqZ0 req_extentq
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ cellbase 8 × i ptr_addrp
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

apply elem_of_cons

2 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
⊢
PAuxbase 8 × i, VAuxCNone = PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live ∨ PAuxbase 8 × i, VAuxCNone ∈ λi0 : Z ⇒ PBytebase i0, VByte0 <$> seqZ0 req_extentq ++ λi0 : Z ⇒ PAuxbase i0, VAuxCNone <$> seqZ0 req_extentq
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ cellbase 8 × i ptr_addrp
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

right

2 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
⊢
PAuxbase 8 × i, VAuxCNone ∈ λi0 : Z ⇒ PBytebase i0, VByte0 <$> seqZ0 req_extentq ++ λi0 : Z ⇒ PAuxbase i0, VAuxCNone <$> seqZ0 req_extentq
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ cellbase 8 × i ptr_addrp
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

apply elem_of_app

2 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
⊢
PAuxbase 8 × i, VAuxCNone ∈ λi0 : Z ⇒ PBytebase i0, VByte0 <$> seqZ0 req_extentq ∨ PAuxbase 8 × i, VAuxCNone ∈ λi0 : Z ⇒ PAuxbase i0, VAuxCNone <$> seqZ0 req_extentq
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ cellbase 8 × i ptr_addrp
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

right

2 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
⊢
PAuxbase 8 × i, VAuxCNone ∈ λi0 : Z ⇒ PAuxbase i0, VAuxCNone <$> seqZ0 req_extentq
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ cellbase 8 × i ptr_addrp
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

apply list_elem_of_fmap

2 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
⊢
∃x : Z, PAuxbase 8 × i, VAuxCNone = PAuxbase x, VAuxCNone ∧ x ∈ seqZ0 req_extentq
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ cellbase 8 × i ptr_addrp
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

exists 8 × Z.of_nati

2 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
⊢
PAuxbase 8 × i, VAuxCNone = PAuxbase 8 × i, VAuxCNone ∧ 8 × i ∈ seqZ0 req_extentq
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ cellbase 8 × i ptr_addrp
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

split ; reflexivity |

2 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
⊢
8 × i ∈ seqZ0 req_extentq
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ cellbase 8 × i ptr_addrp
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

apply elem_of_seqZ

2 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
⊢
0 ≤ 8 × i < 0 + req_extentq
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ cellbase 8 × i ptr_addrp
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

rewrite Nat2Z.inj_succ in Hextent

2 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Z.succi ≤ req_extentq
⊢
0 ≤ 8 × i < 0 + req_extentq
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ cellbase 8 × i ptr_addrp
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

lia

deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ cellbase 8 × i ptr_addrp
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

–unfold cell in Hin

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
v :
Hin :
l, v ∈ mapλi0 : Z ⇒ PBytebase 8 × i + i0, VBytebyte_ofptr_addrp i0 0; 1; 2; 3; 4; 5; 6; 7
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

apply list_elem_of_fmap in Hin as j & = → → & Hj

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
⊢
PBytebase 8 × i + j, VBytebyte_ofptr_addrp j ∈ snapshot_piecexs base q <$> obj_psbase q

assert Hjrange : 0 ≤ j < 8

2 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
⊢
0 ≤ j < 8
focused goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VBytebyte_ofptr_addrp j ∈ snapshot_piecexs base q <$> obj_psbase q

{apply list_elem_of_In in Hj

2 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
Inj 0; 1; 2; 3; 4; 5; 6; 7
⊢
0 ≤ j < 8
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VBytebyte_ofptr_addrp j ∈ snapshot_piecexs base q <$> obj_psbase q

cbn in Hj

2 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
0 = j ∨ 1 = j ∨ 2 = j ∨ 3 = j ∨ 4 = j ∨ 5 = j ∨ 6 = j ∨ 7 = j ∨ False
⊢
0 ≤ j < 8
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VBytebyte_ofptr_addrp j ∈ snapshot_piecexs base q <$> obj_psbase q

repeat destruct Hj as ← | Hj ; try contradiction ; lia

deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VBytebyte_ofptr_addrp j ∈ snapshot_piecexs base q <$> obj_psbase q

apply list_elem_of_fmap

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
∃x : piece × pval, PBytebase 8 × i + j, VBytebyte_ofptr_addrp j = snapshot_piecexs base q x ∧ x ∈ obj_psbase q

exists PBytebase 8 × Z.of_nati + j, VByte0

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VBytebyte_ofptr_addrp j = snapshot_piecexs base q PBytebase 8 × i + j, VByte0 ∧ PBytebase 8 × i + j, VByte0 ∈ obj_psbase q

split

2 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VBytebyte_ofptr_addrp j = snapshot_piecexs base q PBytebase 8 × i + j, VByte0
focused goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VByte0 ∈ obj_psbase q

+unfold snapshot_piece

2 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VBytebyte_ofptr_addrp j
=
match PBytebase 8 × i + j, VByte0.1 with
⇒
PBytebase 8 × i + j, VByte0.1, VBytem_bytessnapshot_valuesxs base allocatedempty_mem q base b + o
PAuxb o
⇒
PBytebase 8 × i + j, VByte0.1, VAuxm_auxsnapshot_valuesxs base allocatedempty_mem q base b + o
_
⇒
PBytebase 8 × i + j, VByte0
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VByte0 ∈ obj_psbase q

cbn [ fst snd ]

2 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VBytebyte_ofptr_addrp j = PBytebase 8 × i + j, VBytem_bytessnapshot_valuesxs base allocatedempty_mem q base base + 8 × i + j
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VByte0 ∈ obj_psbase q

replace base + 8 × Z.of_nati + j with base + 8 × Z.of_nati + j by lia

2 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VBytebyte_ofptr_addrp j = PBytebase 8 × i + j, VBytem_bytessnapshot_valuesxs base allocatedempty_mem q base base + 8 × i + j
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VByte0 ∈ obj_psbase q

rewrite snapshot_pointer_byte_ _ _ _ _ _ Hnth Hjrange

2 open

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VBytebyte_ofptr_addrp j = PBytebase 8 × i + j, VBytebyte_ofptr_addrp j
deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VByte0 ∈ obj_psbase q

reflexivity

deferred goal
xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VByte0 ∈ obj_psbase q

+unfold obj_ps

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VByte0 ∈ PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live :: λi0 : Z ⇒ PBytebase i0, VByte0 <$> seqZ0 req_extentq ++ λi0 : Z ⇒ PAuxbase i0, VAuxCNone <$> seqZ0 req_extentq

apply elem_of_cons

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VByte0 = PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live ∨ PBytebase 8 × i + j, VByte0 ∈ λi0 : Z ⇒ PBytebase i0, VByte0 <$> seqZ0 req_extentq ++ λi0 : Z ⇒ PAuxbase i0, VAuxCNone <$> seqZ0 req_extentq

right

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VByte0 ∈ λi0 : Z ⇒ PBytebase i0, VByte0 <$> seqZ0 req_extentq ++ λi0 : Z ⇒ PAuxbase i0, VAuxCNone <$> seqZ0 req_extentq

apply elem_of_app

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VByte0 ∈ λi0 : Z ⇒ PBytebase i0, VByte0 <$> seqZ0 req_extentq ∨ PBytebase 8 × i + j, VByte0 ∈ λi0 : Z ⇒ PAuxbase i0, VAuxCNone <$> seqZ0 req_extentq

left

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VByte0 ∈ λi0 : Z ⇒ PBytebase i0, VByte0 <$> seqZ0 req_extentq

apply list_elem_of_fmap

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
∃x : Z, PBytebase 8 × i + j, VByte0 = PBytebase x, VByte0 ∧ x ∈ seqZ0 req_extentq

exists 8 × Z.of_nati + j

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
PBytebase 8 × i + j, VByte0 = PBytebase 8 × i + j, VByte0 ∧ 8 × i + j ∈ seqZ0 req_extentq

split ; reflexivity |

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
8 × i + j ∈ seqZ0 req_extentq

apply elem_of_seqZ

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
Hextent :
8 × Si ≤ req_extentq
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
⊢
0 ≤ 8 × i + j < 0 + req_extentq

rewrite Nat2Z.inj_succ in Hextent

xs :
listword
i :
nat
p :
base :
Z
Hnth :
xs !! i = SomeWPtrp
j :
Z
Hj :
j ∈ 0; 1; 2; 3; 4; 5; 6; 7
Hjrange :
0 ≤ j < 8
Hextent :
8 × Z.succi ≤ req_extentq
⊢
0 ≤ 8 × i + j < 0 + req_extentq

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hnth Hextent l v Hin
apply elem_of_cons in Hin as = → → | Hin
–apply list_elem_of_fmap
exists PAuxbase 8 × Z.of_nati, VAuxCNone
split
cbn [ fst snd ]
rewrite snapshot_pointer_aux_ _ _ _ _ Hnth
reflexivity
+unfold obj_ps
apply elem_of_cons
right
apply elem_of_app
right
apply list_elem_of_fmap
exists 8 × Z.of_nati
split ; reflexivity |
apply elem_of_seqZ
rewrite Nat2Z.inj_succ in Hextent
lia
–unfold cell in Hin
apply list_elem_of_fmap in Hin as j & = → → & Hj
assert Hjrange : 0 ≤ j < 8
{apply list_elem_of_In in Hj
cbn in Hj
repeat destruct Hj as ← | Hj ; try contradiction ; lia
apply list_elem_of_fmap
exists PBytebase 8 × Z.of_nati + j, VByte0
split
cbn [ fst snd ]
replace base + 8 × Z.of_nati + j with base + 8 × Z.of_nati + j by lia
rewrite snapshot_pointer_byte_ _ _ _ _ _ Hnth Hjrange
reflexivity
+unfold obj_ps
apply elem_of_cons
right
apply elem_of_app
left
apply list_elem_of_fmap
exists 8 × Z.of_nati + j
split ; reflexivity |
apply elem_of_seqZ
rewrite Nat2Z.inj_succ in Hextent
lia

For promotion: each snapshot piece names its fresh object.

313Lemma snapshot_ps_id
∀ xs base q l v
l, v ∈ snapshot_psxs base q
piece_idl = base
Explore proof 8 tactics

Initial goal

xs :
listword
base :
Z
v :
⊢
l, v ∈ snapshot_psxs base q → piece_idl = base

unfold snapshot_ps

xs :
listword
base :
Z
v :
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q → piece_idl = base

intros Hin

xs :
listword
base :
Z
v :
Hin :
l, v ∈ snapshot_piecexs base q <$> obj_psbase q
⊢
piece_idl = base

apply list_elem_of_fmap in Hin as k u & Hkv & Hin

xs :
listword
base :
Z
v :
u :
Hkv :
l, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ obj_psbase q
⊢
piece_idl = base

assert Hkey : l = k

2 open

xs :
listword
base :
Z
v :
u :
Hkv :
l, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ obj_psbase q
⊢
l = k
focused goal
xs :
listword
base :
Z
v :
u :
Hkv :
l, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ obj_psbase q
Hkey :
l = k
⊢
piece_idl = base

{apply f_equalfst in Hkv

2 open

xs :
listword
base :
Z
v :
u :
Hkv :
l, v.1 = snapshot_piecexs base q k, u.1
Hin :
k, u ∈ obj_psbase q
⊢
l = k
deferred goal
xs :
listword
base :
Z
v :
u :
Hkv :
l, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ obj_psbase q
Hkey :
l = k
⊢
piece_idl = base

destruct k ; exact Hkv

deferred goal
xs :
listword
base :
Z
v :
u :
Hkv :
l, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ obj_psbase q
Hkey :
l = k
⊢
piece_idl = base

subst l

xs :
listword
base :
Z
v :
u :
Hkv :
k, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ obj_psbase q
⊢
piece_idk = base

exact obj_ps_id_ _ _ _ Hin

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hin
apply list_elem_of_fmap in Hin as k u & Hkv & Hin
assert Hkey : l = k
{apply f_equalfst in Hkv
destruct k ; exact Hkv
subst l
exact obj_ps_id_ _ _ _ Hin

For promotion: all snapshot keys are memory pieces, so an old agreeing heap cannot already own a key of the fresh object.

324Lemma snapshot_ps_mem
∀ xs base q l v
l, v ∈ snapshot_psxs base q
Explore proof 8 tactics

Initial goal

xs :
listword
base :
Z
v :
⊢
l, v ∈ snapshot_psxs base q → mem_piecel

unfold snapshot_ps

xs :
listword
base :
Z
v :
⊢
l, v ∈ snapshot_piecexs base q <$> obj_psbase q → mem_piecel

intros Hin

xs :
listword
base :
Z
v :
Hin :
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

apply list_elem_of_fmap in Hin as k u & Hkv & Hin

xs :
listword
base :
Z
v :
u :
Hkv :
l, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ obj_psbase q

assert Hkey : l = k

2 open

xs :
listword
base :
Z
v :
u :
Hkv :
l, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ obj_psbase q
⊢
l = k
focused goal
xs :
listword
base :
Z
v :
u :
Hkv :
l, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ obj_psbase q
Hkey :
l = k

{apply f_equalfst in Hkv

2 open

xs :
listword
base :
Z
v :
u :
Hkv :
l, v.1 = snapshot_piecexs base q k, u.1
Hin :
k, u ∈ obj_psbase q
⊢
l = k
deferred goal
xs :
listword
base :
Z
v :
u :
Hkv :
l, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ obj_psbase q
Hkey :
l = k

destruct k ; exact Hkv

deferred goal
xs :
listword
base :
Z
v :
u :
Hkv :
l, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ obj_psbase q
Hkey :
l = k

subst l

xs :
listword
base :
Z
v :
u :
Hkv :
k, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ obj_psbase q

exact obj_ps_mem_ _ _ _ Hin

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hin
apply list_elem_of_fmap in Hin as k u & Hkv & Hin
assert Hkey : l = k
{apply f_equalfst in Hkv
destruct k ; exact Hkv
subst l
exact obj_ps_mem_ _ _ _ Hin

For promotion: freshness makes the computed snapshot pieces agree with the real allocation after its argument stores.

335Lemma snapshot_ps_agree
∀ m xs base q
Memory.freshm q base
Explore proof 22 tactics

Initial goal

m :
xs :
listword
base :
Z
⊢
freshm q base → all_agreesnapshot_valuesxs base allocatedm q base snapshot_psxs base q

intros _ & _ & _ & _ & _ & Hz

m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone

assert Hsame : ∀i, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i

2 open

m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
⊢
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
focused goal
m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i

{intros i Hi

2 open

m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
i :
Z
Hi :
0 ≤ i < req_extentq
⊢
m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
deferred goal
m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i

destruct Hzbase + i ltac:lia as Hb Ha

2 open

m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
i :
Z
Hi :
0 ≤ i < req_extentq
Hb :
m_bytesm base + i = 0
Ha :
m_auxm base + i = CNone
⊢
m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
deferred goal
m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i

apply snapshot_values_pointwise ; exact Hb | exact Ha

deferred goal
m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i

apply all_agree_intro

m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
⊢
∀l : piece v : pval, l, v ∈ snapshot_psxs base q → agree_piecesnapshot_valuesxs base allocatedm q base l v

intros l v Hin

m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
v :
Hin :
l, v ∈ snapshot_psxs base q

unfold snapshot_ps in Hin

m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
v :
Hin :
l, v ∈ snapshot_piecexs base q <$> obj_psbase q

apply list_elem_of_fmap in Hin as k u & Hlv & Hin

m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
v :
u :
Hlv :
l, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ obj_psbase q

change agree_piecesnapshot_valuesxs base allocatedm q base l, v.1 l, v.2

m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
v :
u :
Hlv :
l, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ obj_psbase q
⊢
agree_piecesnapshot_valuesxs base allocatedm q base l, v.1 l, v.2

rewrite Hlv

m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
v :
u :
Hlv :
l, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ obj_psbase q
⊢
agree_piecesnapshot_valuesxs base allocatedm q base snapshot_piecexs base q k, u.1 snapshot_piecexs base q k, u.2

unfold obj_ps in Hin

m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
v :
u :
Hlv :
l, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ 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
⊢
agree_piecesnapshot_valuesxs base allocatedm q base snapshot_piecexs base q k, u.1 snapshot_piecexs base q k, u.2

apply elem_of_cons in Hin as = → → | Hin

2 open

m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
v :
Hlv :
l, v = snapshot_piecexs base q PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live
⊢
agree_piecesnapshot_valuesxs base allocatedm q base snapshot_piecexs base q PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live.1 snapshot_piecexs base q PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live.2
focused goal
m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
v :
u :
Hlv :
l, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ λi : Z ⇒ PBytebase i, VByte0 <$> seqZ0 req_extentq ++ λi : Z ⇒ PAuxbase i, VAuxCNone <$> seqZ0 req_extentq
⊢
agree_piecesnapshot_valuesxs base allocatedm q base snapshot_piecexs base q k, u.1 snapshot_piecexs base q k, u.2

–unfold snapshot_piece

2 open

m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
v :
Hlv :
l, v = snapshot_piecexs base q PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live
⊢
agree_piecesnapshot_valuesxs base allocatedm q base match PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live.1 with PByteb o ⇒ PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live.1, VBytem_bytessnapshot_valuesxs base allocatedempty_mem q base b + o | PAuxb o ⇒ PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live.1, VAuxm_auxsnapshot_valuesxs base allocatedempty_mem q base b + o | _ ⇒ PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live end.1 match PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live.1 with PByteb o ⇒ PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live.1, VBytem_bytessnapshot_valuesxs base allocatedempty_mem q base b + o | PAuxb o ⇒ PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live.1, VAuxm_auxsnapshot_valuesxs base allocatedempty_mem q base b + o | _ ⇒ PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live end.2
deferred goal
m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
v :
u :
Hlv :
l, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ λi : Z ⇒ PBytebase i, VByte0 <$> seqZ0 req_extentq ++ λi : Z ⇒ PAuxbase i, VAuxCNone <$> seqZ0 req_extentq
⊢
agree_piecesnapshot_valuesxs base allocatedm q base snapshot_piecexs base q k, u.1 snapshot_piecexs base q k, u.2

cbn [ fst snd agree_piece ]

2 open

m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
v :
Hlv :
l, v = snapshot_piecexs base q PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live
⊢
live_atsnapshot_valuesxs base allocatedm q base base r_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live
deferred goal
m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
v :
u :
Hlv :
l, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ λi : Z ⇒ PBytebase i, VByte0 <$> seqZ0 req_extentq ++ λi : Z ⇒ PAuxbase i, VAuxCNone <$> seqZ0 req_extentq
⊢
agree_piecesnapshot_valuesxs base allocatedm q base snapshot_piecexs base q k, u.1 snapshot_piecexs base q k, u.2

unfold live_at

2 open

m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
v :
Hlv :
l, v = snapshot_piecexs base q PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live
⊢
object_regionbase m_regionssnapshot_valuesxs base allocatedm q base = Somer_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live ∧ r_lifer_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live = Live
deferred goal
m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
v :
u :
Hlv :
l, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ λi : Z ⇒ PBytebase i, VByte0 <$> seqZ0 req_extentq ++ λi : Z ⇒ PAuxbase i, VAuxCNone <$> seqZ0 req_extentq
⊢
agree_piecesnapshot_valuesxs base allocatedm q base snapshot_piecexs base q k, u.1 snapshot_piecexs base q k, u.2

rewrite snapshot_values_regions object_region_allocated Z.eqb_refl

2 open

m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
v :
Hlv :
l, v = snapshot_piecexs base q PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live
⊢
Somer_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live = Somer_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live ∧ r_lifer_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live = Live
deferred goal
m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
v :
u :
Hlv :
l, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ λi : Z ⇒ PBytebase i, VByte0 <$> seqZ0 req_extentq ++ λi : Z ⇒ PAuxbase i, VAuxCNone <$> seqZ0 req_extentq
⊢
agree_piecesnapshot_valuesxs base allocatedm q base snapshot_piecexs base q k, u.1 snapshot_piecexs base q k, u.2

split ; reflexivity

deferred goal
m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
v :
u :
Hlv :
l, v = snapshot_piecexs base q k, u
Hin :
k, u ∈ λi : Z ⇒ PBytebase i, VByte0 <$> seqZ0 req_extentq ++ λi : Z ⇒ PAuxbase i, VAuxCNone <$> seqZ0 req_extentq
⊢
agree_piecesnapshot_valuesxs base allocatedm q base snapshot_piecexs base q k, u.1 snapshot_piecexs base q k, u.2

–apply elem_of_app in Hin as Hin | Hin ; apply list_elem_of_fmap in Hin as i & = → → & Hi ; apply elem_of_seqZ in Hi ; unfold snapshot_piece ; cbn [ fst snd agree_piece ] ; unfold registered , in_live ; rewrite snapshot_values_regions object_region_allocated Z.eqb_refl ; split ; discriminate | ; intros reg = ← _ ; cbn [ r_end ] ; split ; lia | ; split ; lia |

2 open

m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
v :
i :
Z
Hlv :
l, v = snapshot_piecexs base q PBytebase i, VByte0
Hi :
0 ≤ i < 0 + req_extentq
⊢
m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i
focused goal
m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
v :
i :
Z
Hlv :
l, v = snapshot_piecexs base q PAuxbase i, VAuxCNone
Hi :
0 ≤ i < 0 + req_extentq
⊢
aux_holdssnapshot_valuesxs base allocatedm q base base + i m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i

+exact proj1Hsamei ltac:lia

deferred goal
m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
v :
i :
Z
Hlv :
l, v = snapshot_piecexs base q PAuxbase i, VAuxCNone
Hi :
0 ≤ i < 0 + req_extentq
⊢
aux_holdssnapshot_valuesxs base allocatedm q base base + i m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i

+left

m :
xs :
listword
base :
Z
Hz :
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
Hsame :
∀i : Z, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
v :
i :
Z
Hlv :
l, v = snapshot_piecexs base q PAuxbase i, VAuxCNone
Hi :
0 ≤ i < 0 + req_extentq
⊢
m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i

exact proj2Hsamei ltac:lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros _ & _ & _ & _ & _ & Hz
assert Hsame : ∀i, 0 ≤ i < req_extentq → m_bytessnapshot_valuesxs base allocatedm q base base + i = m_bytessnapshot_valuesxs base allocatedempty_mem q base base + i ∧ m_auxsnapshot_valuesxs base allocatedm q base base + i = m_auxsnapshot_valuesxs base allocatedempty_mem q base base + i
{intros i Hi
destruct Hzbase + i ltac:lia as Hb Ha
apply snapshot_values_pointwise ; exact Hb | exact Ha
intros l v Hin
unfold snapshot_ps in Hin
apply list_elem_of_fmap in Hin as k u & Hlv & Hin
change agree_piecesnapshot_valuesxs base allocatedm q base l, v.1 l, v.2
rewrite Hlv
unfold obj_ps in Hin
apply elem_of_cons in Hin as = → → | Hin
–unfold snapshot_piece
cbn [ fst snd agree_piece ]
unfold live_at
split ; reflexivity
–apply elem_of_app in Hin as Hin | Hin ; apply list_elem_of_fmap in Hin as i & = → → & Hi ; apply elem_of_seqZ in Hi ; unfold snapshot_piece ; cbn [ fst snd agree_piece ] ; unfold registered , in_live ; rewrite snapshot_values_regions object_region_allocated Z.eqb_refl ; split ; discriminate | ; intros reg = ← _ ; cbn [ r_end ] ; split ; lia | ; split ; lia |
+exact proj1Hsamei ltac:lia
+left
exact proj2Hsamei ltac:lia

For promotion: snapshot stores frame every piece outside the fresh object's keys. The proof uses frame_within and the exact store range, not a promise about the caller's memory.

367Lemma snapshot_frame
∀ m xs base q
8 × Z.of_natlengthxs ≤ req_extentq
frame_okobj_psbase q.*1 allocatedm q base snapshot_valuesxs base allocatedm q base
Explore proof 37 tactics

Initial goal

m :
xs :
listword
base :
Z
⊢
live_disjointallocatedm q base → 8 × lengthxs ≤ req_extentq → frame_okobj_psbase q.*1 allocatedm q base snapshot_valuesxs base allocatedm q base

intros Hd Hsize

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
frame_okobj_psbase q.*1 allocatedm q base snapshot_valuesxs base allocatedm q base

apply frame_within_ _ _ base mkRegionbase base + req_extentq req_kindq Live ; apply snapshot_values_regions | exact Hd | | |

3 open

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
live_atallocatedm q base base r_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live
focused goal
m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
∀a : Z, base ≤ a < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PBytebase a − base ∉ obj_psbase q.*1 → m_bytessnapshot_valuesxs base allocatedm q base a = m_bytesallocatedm q base a
focused goal
m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
∀a : Z, base ≤ a < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase a − base ∉ obj_psbase q.*1 → m_auxsnapshot_valuesxs base allocatedm q base a = m_auxallocatedm q base a

–split ; rewrite object_region_allocated Z.eqb_refl ; reflexivity | reflexivity

2 open

deferred goal
m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
∀a : Z, base ≤ a < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PBytebase a − base ∉ obj_psbase q.*1 → m_bytessnapshot_valuesxs base allocatedm q base a = m_bytesallocatedm q base a
deferred goal
m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
∀a : Z, base ≤ a < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase a − base ∉ obj_psbase q.*1 → m_auxsnapshot_valuesxs base allocatedm q base a = m_auxallocatedm q base a

–intros t Hnot

2 open

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PBytebase t − base ∉ obj_psbase q.*1
⊢
m_bytessnapshot_valuesxs base allocatedm q base t = m_bytesallocatedm q base t
deferred goal
m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
∀a : Z, base ≤ a < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase a − base ∉ obj_psbase q.*1 → m_auxsnapshot_valuesxs base allocatedm q base a = m_auxallocatedm q base a

destruct Z_le_gt_decbase t as Hlo | Hlo ; destruct Z_lt_ge_dect base + req_extentq as Hhi | Hhi ; try apply proj1snapshot_values_outsidexs base _ t ltac:lia

2 open

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PBytebase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
m_bytessnapshot_valuesxs base allocatedm q base t = m_bytesallocatedm q base t
deferred goal
m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
∀a : Z, base ≤ a < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase a − base ∉ obj_psbase q.*1 → m_auxsnapshot_valuesxs base allocatedm q base a = m_auxallocatedm q base a

exfalso

2 open

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PBytebase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
False
deferred goal
m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
∀a : Z, base ≤ a < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase a − base ∉ obj_psbase q.*1 → m_auxsnapshot_valuesxs base allocatedm q base a = m_auxallocatedm q base a

apply Hnotltac:cbn ; lia

2 open

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PBytebase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
PBytebase t − base ∈ obj_psbase q.*1
deferred goal
m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
∀a : Z, base ≤ a < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase a − base ∉ obj_psbase q.*1 → m_auxsnapshot_valuesxs base allocatedm q base a = m_auxallocatedm q base a

apply list_elem_of_fmap

2 open

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PBytebase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
∃x : piece × pval, PBytebase t − base = x.1 ∧ x ∈ obj_psbase q
deferred goal
m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
∀a : Z, base ≤ a < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase a − base ∉ obj_psbase q.*1 → m_auxsnapshot_valuesxs base allocatedm q base a = m_auxallocatedm q base a

exists PBytebase t − base, VByte0

2 open

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PBytebase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
PBytebase t − base = PBytebase t − base, VByte0.1 ∧ PBytebase t − base, VByte0 ∈ obj_psbase q
deferred goal
m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
∀a : Z, base ≤ a < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase a − base ∉ obj_psbase q.*1 → m_auxsnapshot_valuesxs base allocatedm q base a = m_auxallocatedm q base a

split ; reflexivity |

2 open

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PBytebase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
PBytebase t − base, VByte0 ∈ obj_psbase q
deferred goal
m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
∀a : Z, base ≤ a < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase a − base ∉ obj_psbase q.*1 → m_auxsnapshot_valuesxs base allocatedm q base a = m_auxallocatedm q base a

unfold obj_ps

2 open

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PBytebase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
PBytebase t − base, VByte0 ∈ 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
deferred goal
m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
∀a : Z, base ≤ a < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase a − base ∉ obj_psbase q.*1 → m_auxsnapshot_valuesxs base allocatedm q base a = m_auxallocatedm q base a

apply elem_of_cons

2 open

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PBytebase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
PBytebase t − base, VByte0 = PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live ∨ PBytebase t − base, VByte0 ∈ λi : Z ⇒ PBytebase i, VByte0 <$> seqZ0 req_extentq ++ λi : Z ⇒ PAuxbase i, VAuxCNone <$> seqZ0 req_extentq
deferred goal
m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
∀a : Z, base ≤ a < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase a − base ∉ obj_psbase q.*1 → m_auxsnapshot_valuesxs base allocatedm q base a = m_auxallocatedm q base a

right

2 open

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PBytebase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
PBytebase t − base, VByte0 ∈ λi : Z ⇒ PBytebase i, VByte0 <$> seqZ0 req_extentq ++ λi : Z ⇒ PAuxbase i, VAuxCNone <$> seqZ0 req_extentq
deferred goal
m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
∀a : Z, base ≤ a < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase a − base ∉ obj_psbase q.*1 → m_auxsnapshot_valuesxs base allocatedm q base a = m_auxallocatedm q base a

apply elem_of_app

2 open

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PBytebase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
PBytebase t − base, VByte0 ∈ λi : Z ⇒ PBytebase i, VByte0 <$> seqZ0 req_extentq ∨ PBytebase t − base, VByte0 ∈ λi : Z ⇒ PAuxbase i, VAuxCNone <$> seqZ0 req_extentq
deferred goal
m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
∀a : Z, base ≤ a < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase a − base ∉ obj_psbase q.*1 → m_auxsnapshot_valuesxs base allocatedm q base a = m_auxallocatedm q base a

left

2 open

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PBytebase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
PBytebase t − base, VByte0 ∈ λi : Z ⇒ PBytebase i, VByte0 <$> seqZ0 req_extentq
deferred goal
m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
∀a : Z, base ≤ a < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase a − base ∉ obj_psbase q.*1 → m_auxsnapshot_valuesxs base allocatedm q base a = m_auxallocatedm q base a

apply list_elem_of_fmap

2 open

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PBytebase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
∃x : Z, PBytebase t − base, VByte0 = PBytebase x, VByte0 ∧ x ∈ seqZ0 req_extentq
deferred goal
m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
∀a : Z, base ≤ a < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase a − base ∉ obj_psbase q.*1 → m_auxsnapshot_valuesxs base allocatedm q base a = m_auxallocatedm q base a

exists t − base

2 open

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PBytebase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
PBytebase t − base, VByte0 = PBytebase t − base, VByte0 ∧ t − base ∈ seqZ0 req_extentq
deferred goal
m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
∀a : Z, base ≤ a < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase a − base ∉ obj_psbase q.*1 → m_auxsnapshot_valuesxs base allocatedm q base a = m_auxallocatedm q base a

split ; reflexivity |

2 open

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PBytebase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
t − base ∈ seqZ0 req_extentq
deferred goal
m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
∀a : Z, base ≤ a < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase a − base ∉ obj_psbase q.*1 → m_auxsnapshot_valuesxs base allocatedm q base a = m_auxallocatedm q base a

apply elem_of_seqZ

2 open

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PBytebase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
0 ≤ t − base < 0 + req_extentq
deferred goal
m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
∀a : Z, base ≤ a < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase a − base ∉ obj_psbase q.*1 → m_auxsnapshot_valuesxs base allocatedm q base a = m_auxallocatedm q base a

lia

deferred goal
m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
⊢
∀a : Z, base ≤ a < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase a − base ∉ obj_psbase q.*1 → m_auxsnapshot_valuesxs base allocatedm q base a = m_auxallocatedm q base a

–intros t Hnot

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase t − base ∉ obj_psbase q.*1
⊢
m_auxsnapshot_valuesxs base allocatedm q base t = m_auxallocatedm q base t

destruct Z_le_gt_decbase t as Hlo | Hlo ; destruct Z_lt_ge_dect base + req_extentq as Hhi | Hhi ; try apply proj2snapshot_values_outsidexs base _ t ltac:lia

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
m_auxsnapshot_valuesxs base allocatedm q base t = m_auxallocatedm q base t

exfalso

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
False

apply Hnotltac:cbn ; lia

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
PAuxbase t − base ∈ obj_psbase q.*1

apply list_elem_of_fmap

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
∃x : piece × pval, PAuxbase t − base = x.1 ∧ x ∈ obj_psbase q

exists PAuxbase t − base, VAuxCNone

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
PAuxbase t − base = PAuxbase t − base, VAuxCNone.1 ∧ PAuxbase t − base, VAuxCNone ∈ obj_psbase q

split ; reflexivity |

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
PAuxbase t − base, VAuxCNone ∈ obj_psbase q

unfold obj_ps

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
PAuxbase t − base, VAuxCNone ∈ 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

apply elem_of_cons

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
PAuxbase t − base, VAuxCNone = PLivebase, VLiver_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live ∨ PAuxbase t − base, VAuxCNone ∈ λi : Z ⇒ PBytebase i, VByte0 <$> seqZ0 req_extentq ++ λi : Z ⇒ PAuxbase i, VAuxCNone <$> seqZ0 req_extentq

right

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
PAuxbase t − base, VAuxCNone ∈ λi : Z ⇒ PBytebase i, VByte0 <$> seqZ0 req_extentq ++ λi : Z ⇒ PAuxbase i, VAuxCNone <$> seqZ0 req_extentq

apply elem_of_app

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
PAuxbase t − base, VAuxCNone ∈ λi : Z ⇒ PBytebase i, VByte0 <$> seqZ0 req_extentq ∨ PAuxbase t − base, VAuxCNone ∈ λi : Z ⇒ PAuxbase i, VAuxCNone <$> seqZ0 req_extentq

right

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
PAuxbase t − base, VAuxCNone ∈ λi : Z ⇒ PAuxbase i, VAuxCNone <$> seqZ0 req_extentq

apply list_elem_of_fmap

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
∃x : Z, PAuxbase t − base, VAuxCNone = PAuxbase x, VAuxCNone ∧ x ∈ seqZ0 req_extentq

exists t − base

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
PAuxbase t − base, VAuxCNone = PAuxbase t − base, VAuxCNone ∧ t − base ∈ seqZ0 req_extentq

split ; reflexivity |

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
t − base ∈ seqZ0 req_extentq

apply elem_of_seqZ

m :
xs :
listword
base :
Z
Hsize :
8 × lengthxs ≤ req_extentq
t :
Z
Hnot :
base ≤ t < r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live → PAuxbase t − base ∉ obj_psbase q.*1
Hlo :
base ≤ t
Hhi :
t < base + req_extentq
⊢
0 ≤ t − base < 0 + req_extentq

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hd Hsize
apply frame_within_ _ _ base mkRegionbase base + req_extentq req_kindq Live ; apply snapshot_values_regions | exact Hd | | |
–split ; rewrite object_region_allocated Z.eqb_refl ; reflexivity | reflexivity
–intros t Hnot
destruct Z_le_gt_decbase t as Hlo | Hlo ; destruct Z_lt_ge_dect base + req_extentq as Hhi | Hhi ; try apply proj1snapshot_values_outsidexs base _ t ltac:lia
exfalso
apply Hnotltac:cbn ; lia
apply list_elem_of_fmap
exists PBytebase t − base, VByte0
split ; reflexivity |
unfold obj_ps
apply elem_of_cons
right
apply elem_of_app
left
apply list_elem_of_fmap
exists t − base
split ; reflexivity |
apply elem_of_seqZ
lia
–intros t Hnot
destruct Z_le_gt_decbase t as Hlo | Hlo ; destruct Z_lt_ge_dect base + req_extentq as Hhi | Hhi ; try apply proj2snapshot_values_outsidexs base _ t ltac:lia
exfalso
apply Hnotltac:cbn ; lia
apply list_elem_of_fmap
exists PAuxbase t − base, VAuxCNone
split ; reflexivity |
unfold obj_ps
apply elem_of_cons
right
apply elem_of_app
right
apply list_elem_of_fmap
exists t − base
split ; reflexivity |
apply elem_of_seqZ
lia

For promotion: the nonempty snapshot equation of Semantics.step. The read-only pointer goes in the frame; the argument cells are allocated and populated in memory by that same step.

395Lemma rule_snapshot
∀ ge f e ls l cs m fuel xs
xs ≠ [ ]
forallbsnapshot_word xs = true
let q ≔ heap_req16 8 × Z.of_natlengthxs in
Semantics.stepge mkConfigmkFramef e ls None Snapshotxs l cs m fuel = Freshq λbase ⇒ mkConfigmkFramef putva_snapshot WPtrmkPtrbase Robase e ls None Enterl None cs snapshot_valuesxs base allocatedm q base fuel
Explore proof 5 tactics

Initial goal

ge :
f :
e :
ls :
listname × optionZ
l :
cs :
listframe × pending
m :
fuel :
Z
xs :
listword
⊢
xs ≠ [ ]
→
forallbsnapshot_word xs = true
→
let q ≔ heap_req16 8 × lengthxs in
stepge c_frame ≔ fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Snapshotxs l; c_callers ≔ cs; c_mem ≔ m; c_fuel ≔ fuel = Freshq λbase : Z ⇒ c_frame ≔ fr_fn ≔ f; fr_env ≔ putva_snapshot WPtrptr_addr ≔ base; ptr_cap ≔ Robase e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Enterl None; c_callers ≔ cs; c_mem ≔ snapshot_valuesxs base allocatedm q base; c_fuel ≔ fuel

intros Hne Hwords q

ge :
f :
e :
ls :
listname × optionZ
l :
cs :
listframe × pending
m :
fuel :
Z
xs :
listword
Hne :
xs ≠ [ ]
Hwords :
forallbsnapshot_word xs = true
q :=
heap_req16 8 × lengthxs : alloc_req
⊢
stepge c_frame ≔ fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Snapshotxs l; c_callers ≔ cs; c_mem ≔ m; c_fuel ≔ fuel = Freshq λbase : Z ⇒ c_frame ≔ fr_fn ≔ f; fr_env ≔ putva_snapshot WPtrptr_addr ≔ base; ptr_cap ≔ Robase e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Enterl None; c_callers ≔ cs; c_mem ≔ snapshot_valuesxs base allocatedm q base; c_fuel ≔ fuel

destruct xs ; contradiction |

ge :
f :
e :
ls :
listname × optionZ
l :
cs :
listframe × pending
m :
fuel :
Z
w :
xs :
listword
Hne :
w :: xs ≠ [ ]
Hwords :
forallbsnapshot_word w :: xs = true
q :=
heap_req16 8 × lengthw :: xs : alloc_req
⊢
stepge c_frame ≔ fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Snapshotw :: xs l; c_callers ≔ cs; c_mem ≔ m; c_fuel ≔ fuel = Freshq λbase : Z ⇒ c_frame ≔ fr_fn ≔ f; fr_env ≔ putva_snapshot WPtrptr_addr ≔ base; ptr_cap ≔ Robase e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Enterl None; c_callers ≔ cs; c_mem ≔ snapshot_valuesw :: xs base allocatedm q base; c_fuel ≔ fuel

cbn [ Semantics.step c_frame c_mem c_callers c_fuel fr_at fr_fn fr_env fr_locals fr_doomed ]

ge :
f :
e :
ls :
listname × optionZ
l :
cs :
listframe × pending
m :
fuel :
Z
w :
xs :
listword
Hne :
w :: xs ≠ [ ]
Hwords :
forallbsnapshot_word w :: xs = true
q :=
heap_req16 8 × lengthw :: xs : alloc_req
⊢
negbforallbsnapshot_word w :: xs
→
Stuck"snapshot"
else
Freshheap_req16 8 × lengthw :: xs λbase : Z ⇒ c_frame ≔ fr_fn ≔ f; fr_env ≔ putva_snapshot WPtrptr_addr ≔ base; ptr_cap ≔ Robase e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Enterl None; c_callers ≔ cs; c_mem ≔ snapshot_valuesw :: xs base allocatedm heap_req16 8 × lengthw :: xs base; c_fuel ≔ fuel
=
Freshq λbase : Z ⇒ c_frame ≔ fr_fn ≔ f; fr_env ≔ putva_snapshot WPtrptr_addr ≔ base; ptr_cap ≔ Robase e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Enterl None; c_callers ≔ cs; c_mem ≔ snapshot_valuesw :: xs base allocatedm q base; c_fuel ≔ fuel

rewrite Hwords

ge :
f :
e :
ls :
listname × optionZ
l :
cs :
listframe × pending
m :
fuel :
Z
w :
xs :
listword
Hne :
w :: xs ≠ [ ]
Hwords :
forallbsnapshot_word w :: xs = true
q :=
heap_req16 8 × lengthw :: xs : alloc_req
⊢
negbtrue
→
Stuck"snapshot"
else
Freshheap_req16 8 × lengthw :: xs λbase : Z ⇒ c_frame ≔ fr_fn ≔ f; fr_env ≔ putva_snapshot WPtrptr_addr ≔ base; ptr_cap ≔ Robase e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Enterl None; c_callers ≔ cs; c_mem ≔ snapshot_valuesw :: xs base allocatedm heap_req16 8 × lengthw :: xs base; c_fuel ≔ fuel
=
Freshq λbase : Z ⇒ c_frame ≔ fr_fn ≔ f; fr_env ≔ putva_snapshot WPtrptr_addr ≔ base; ptr_cap ≔ Robase e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Enterl None; c_callers ≔ cs; c_mem ≔ snapshot_valuesw :: xs base allocatedm q base; c_fuel ≔ fuel

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hne Hwords q
destruct xs ; contradiction |
rewrite Hwords
reflexivity

For promotion: the collector cannot rewrite a stored read-only capability while its object is live. This is the read-only case of aux_holds_live, derived directly from freed_in.

411Lemma aux_holds_ro
∀ m a b reg
live_atm b reg
m_auxm a = Rob
Explore proof 6 tactics

Initial goal

m :
a, b :
Z
reg :
⊢
aux_holdsm a Rob → live_atm b reg → m_auxm a = Rob

intros Heq | b′ & reg′ & Hcap & Hreg & Hfreed & _ Hlive Hlife ; exact Heq |

m :
a, b :
Z
reg :
b′ :
Z
reg′ :
Hcap :
Rob = Objb′ ∨ Rob = Rob′
Hreg :
object_regionb′ m_regionsm = Somereg′
Hfreed :
r_lifereg′ = Freed
Hlive :
Hlife :
r_lifereg = Live
⊢
m_auxm a = Rob

destruct Hcap as Hcap | Hcap ; discriminate |

m :
a, b :
Z
reg :
b′ :
Z
reg′ :
Hcap :
Rob = Rob′
Hreg :
object_regionb′ m_regionsm = Somereg′
Hfreed :
r_lifereg′ = Freed
Hlive :
Hlife :
r_lifereg = Live
⊢
m_auxm a = Rob

injection Hcap as ←

m :
a, b :
Z
reg, reg′ :
Hreg :
object_regionb m_regionsm = Somereg′
Hfreed :
r_lifereg′ = Freed
Hlive :
Hlife :
r_lifereg = Live
⊢
m_auxm a = Rob

rewrite Hlive in Hreg

m :
a, b :
Z
reg, reg′ :
Hfreed :
r_lifereg′ = Freed
Hlive :
Hlife :
r_lifereg = Live
Hreg :
Somereg = Somereg′
⊢
m_auxm a = Rob

injection Hreg as ←

m :
a, b :
Z
reg :
Hfreed :
Hlive :
Hlife :
r_lifereg = Live
⊢
m_auxm a = Rob

congruence

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Heq | b′ & reg′ & Hcap & Hreg & Hfreed & _ Hlive Hlife ; exact Heq |
destruct Hcap as Hcap | Hcap ; discriminate |
injection Hcap as ←
rewrite Hlive in Hreg
injection Hreg as ←
congruence

Writing concatenated piece lists is their two overwrites in order.

421Lemma overwrite_app
∀ ps qs h
overwriteps ++ qs h = overwriteps overwriteqs h
Explore proof 1 tactics

Initial goal

ps, qs :
listpiece × pval
h :
⊢
overwriteps ++ qs h = overwriteps overwriteqs h

induction ps as | l v ps IH ; cbn ; reflexivity | rewrite IH ; reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
induction ps as | l v ps IH ; cbn ; reflexivity | rewrite IH ; reflexivity

Rewriting already-owned values leaves the authoritative map unchanged.

425Lemma overwrite_owned
∀ ps h
∀l v, l, v ∈ ps → h !! l = Somev
overwriteps h = h
Explore proof 13 tactics

Initial goal

ps :
listpiece × pval
h :
⊢
∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → overwriteps h = h

induction ps as | l v ps IH ; intros Hown ; reflexivity |

v :
ps :
listpiece × pval
h :
IH :
∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → overwriteps h = h
Hown :
∀l0 : piece v0 : pval, l0, v0 ∈ l, v :: ps → h !! l0 = Somev0
⊢
overwritel, v :: ps h = h

cbn

v :
ps :
listpiece × pval
h :
IH :
∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → overwriteps h = h
Hown :
∀l0 : piece v0 : pval, l0, v0 ∈ l, v :: ps → h !! l0 = Somev0
⊢
<[l ≔ v]>overwriteps h = h

rewrite IH

2 open

v :
ps :
listpiece × pval
h :
IH :
∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → overwriteps h = h
Hown :
∀l0 : piece v0 : pval, l0, v0 ∈ l, v :: ps → h !! l0 = Somev0
⊢
<[l ≔ v]>h = h
focused goal
v :
ps :
listpiece × pval
h :
IH :
∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → overwriteps h = h
Hown :
∀l0 : piece v0 : pval, l0, v0 ∈ l, v :: ps → h !! l0 = Somev0
⊢
∀l0 : piece v0 : pval, l0, v0 ∈ ps → h !! l0 = Somev0

–apply insert_id

2 open

v :
ps :
listpiece × pval
h :
IH :
∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → overwriteps h = h
Hown :
∀l0 : piece v0 : pval, l0, v0 ∈ l, v :: ps → h !! l0 = Somev0
⊢
h !! l = Somev
deferred goal
v :
ps :
listpiece × pval
h :
IH :
∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → overwriteps h = h
Hown :
∀l0 : piece v0 : pval, l0, v0 ∈ l, v :: ps → h !! l0 = Somev0
⊢
∀l0 : piece v0 : pval, l0, v0 ∈ ps → h !! l0 = Somev0

apply Hown

2 open

v :
ps :
listpiece × pval
h :
IH :
∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → overwriteps h = h
Hown :
∀l0 : piece v0 : pval, l0, v0 ∈ l, v :: ps → h !! l0 = Somev0
⊢
l, v ∈ l, v :: ps
deferred goal
v :
ps :
listpiece × pval
h :
IH :
∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → overwriteps h = h
Hown :
∀l0 : piece v0 : pval, l0, v0 ∈ l, v :: ps → h !! l0 = Somev0
⊢
∀l0 : piece v0 : pval, l0, v0 ∈ ps → h !! l0 = Somev0

apply elem_of_cons

2 open

v :
ps :
listpiece × pval
h :
IH :
∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → overwriteps h = h
Hown :
∀l0 : piece v0 : pval, l0, v0 ∈ l, v :: ps → h !! l0 = Somev0
⊢
l, v = l, v ∨ l, v ∈ ps
deferred goal
v :
ps :
listpiece × pval
h :
IH :
∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → overwriteps h = h
Hown :
∀l0 : piece v0 : pval, l0, v0 ∈ l, v :: ps → h !! l0 = Somev0
⊢
∀l0 : piece v0 : pval, l0, v0 ∈ ps → h !! l0 = Somev0

left

2 open

v :
ps :
listpiece × pval
h :
IH :
∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → overwriteps h = h
Hown :
∀l0 : piece v0 : pval, l0, v0 ∈ l, v :: ps → h !! l0 = Somev0
⊢
l, v = l, v
deferred goal
v :
ps :
listpiece × pval
h :
IH :
∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → overwriteps h = h
Hown :
∀l0 : piece v0 : pval, l0, v0 ∈ l, v :: ps → h !! l0 = Somev0
⊢
∀l0 : piece v0 : pval, l0, v0 ∈ ps → h !! l0 = Somev0

reflexivity

deferred goal
v :
ps :
listpiece × pval
h :
IH :
∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → overwriteps h = h
Hown :
∀l0 : piece v0 : pval, l0, v0 ∈ l, v :: ps → h !! l0 = Somev0
⊢
∀l0 : piece v0 : pval, l0, v0 ∈ ps → h !! l0 = Somev0

–intros k u Hin

v :
ps :
listpiece × pval
h :
IH :
∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → overwriteps h = h
Hown :
∀l0 : piece v0 : pval, l0, v0 ∈ l, v :: ps → h !! l0 = Somev0
u :
Hin :
k, u ∈ ps
⊢
h !! k = Someu

apply Hown

v :
ps :
listpiece × pval
h :
IH :
∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → overwriteps h = h
Hown :
∀l0 : piece v0 : pval, l0, v0 ∈ l, v :: ps → h !! l0 = Somev0
u :
Hin :
k, u ∈ ps
⊢
k, u ∈ l, v :: ps

apply elem_of_cons

v :
ps :
listpiece × pval
h :
IH :
∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → overwriteps h = h
Hown :
∀l0 : piece v0 : pval, l0, v0 ∈ l, v :: ps → h !! l0 = Somev0
u :
Hin :
k, u ∈ ps
⊢
k, u = l, v ∨ k, u ∈ ps

right

v :
ps :
listpiece × pval
h :
IH :
∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → overwriteps h = h
Hown :
∀l0 : piece v0 : pval, l0, v0 ∈ l, v :: ps → h !! l0 = Somev0
u :
Hin :
k, u ∈ ps
⊢
k, u ∈ ps

exact Hin

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
induction ps as | l v ps IH ; intros Hown ; reflexivity |
cbn
rewrite IH
–apply insert_id
apply Hown
apply elem_of_cons
left
reflexivity
–intros k u Hin
apply Hown
apply elem_of_cons
right
exact Hin

The mutable va_list cell: its life, pointer capability, and cursor bytes. Advancing the cursor keeps the capability unchanged.

436Definition va_cursor_psb reg cursor : ptr : listpiece × pval ≔
PLiveb, VLivereg; PAuxb 0, VAuxptr_capcursor ++ cellb 0 ptr_addrcursor

The helpers over any runtime and caller-supplied world.

440Module HelloVersionOn R : Runtime LG0 : LogicSigR
441Module HL ≔ HelloLeafOn R LG0
442Module ML ≔ HL.ML
443Module SL ≔ ML.SL
444Module LG ≔ ML.LG
445Module L ≔ LG.L
Import L LG SL ML HL
448Section version
449Context `{!invGS_genhlc Σ, !gen_heapGSpiece pval Σ}
450Context world : Type registry : name → optioncontractworld wi : mem → world → gmappiece pval → Prop `{!SafepointStablewi} ge : genv

The Iris instance uses exactly the caller's registry and world.

454Instance version_irisGS: irisGS_genhlc nanofil_langregistry ge Σ ≔
nanofil_irisGSregistry wi ge

Expressions in that language.

457Notation hexpr ≔ language.exprnanofil_langregistry ge

Full ownership cannot contain two pieces with the same key. This supplies the disjointness needed when a cursor read also owns its snapshot and literal frames.

462Lemma pts_keys_nodup
∀ ps
ptsps −∗ ⌜NoDupps.*1⌝
Explore proof 14 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 :
ps :
listpiece × pval
⊢
ptsps −∗ ⌜NoDupps.*1⌝

induction ps as | l v ps IH ; iIntros _ ; iPureIntro ; constructor |

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 :
v :
ps :
listpiece × pval
IH :
ptsps −∗ ⌜NoDupps.*1⌝
⊢
ptsl, v :: ps −∗ ⌜NoDupl, v :: ps.*1⌝

rewrite / pts big_sepL_cons

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 :
v :
ps :
listpiece × pval
IH :
ptsps −∗ ⌜NoDupps.*1⌝
⊢
pointstol, v.1 DfracOwn1 l, v.2 ∗ ∗y∈pspointstoy.1 DfracOwn1 y.2 −∗ ⌜NoDupl, v :: ps.*1⌝

iIntros [Hl Hps]

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 :
v :
ps :
listpiece × pval
IH :
ptsps −∗ ⌜NoDupps.*1⌝
Hl :
pointstol, v.1 DfracOwn1 l, v.2
Hps :
∗y∈pspointstoy.1 DfracOwn1 y.2
∗
⌜NoDupl, v :: ps.*1⌝

iDestruct IH with Hps as %Hnd

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 :
v :
ps :
listpiece × pval
IH :
ptsps −∗ ⌜NoDupps.*1⌝
Hnd :
NoDupps.*1
Hl :
pointstol, v.1 DfracOwn1 l, v.2
Hps :
∗y∈pspointstoy.1 DfracOwn1 y.2
∗
⌜NoDupl, v :: ps.*1⌝

destruct decidel ∈ ps.*1 as Hin | Hnot

2 open

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 :
v :
ps :
listpiece × pval
IH :
ptsps −∗ ⌜NoDupps.*1⌝
Hnd :
NoDupps.*1
Hin :
l ∈ ps.*1
Hl :
pointstol, v.1 DfracOwn1 l, v.2
Hps :
∗y∈pspointstoy.1 DfracOwn1 y.2
∗
⌜NoDupl, v :: ps.*1⌝
focused 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 :
v :
ps :
listpiece × pval
IH :
ptsps −∗ ⌜NoDupps.*1⌝
Hnd :
NoDupps.*1
Hnot :
l ∉ ps.*1
Hl :
pointstol, v.1 DfracOwn1 l, v.2
Hps :
∗y∈pspointstoy.1 DfracOwn1 y.2
∗
⌜NoDupl, v :: ps.*1⌝

–apply list_elem_of_fmap in Hin as k u & Hkey & Hin

2 open

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 :
v :
ps :
listpiece × pval
IH :
ptsps −∗ ⌜NoDupps.*1⌝
Hnd :
NoDupps.*1
u :
Hkey :
l = k, u.1
Hin :
k, u ∈ ps
Hl :
pointstol, v.1 DfracOwn1 l, v.2
Hps :
∗y∈pspointstoy.1 DfracOwn1 y.2
∗
⌜NoDupl, v :: ps.*1⌝
deferred 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 :
v :
ps :
listpiece × pval
IH :
ptsps −∗ ⌜NoDupps.*1⌝
Hnd :
NoDupps.*1
Hnot :
l ∉ ps.*1
Hl :
pointstol, v.1 DfracOwn1 l, v.2
Hps :
∗y∈pspointstoy.1 DfracOwn1 y.2
∗
⌜NoDupl, v :: ps.*1⌝

cbn in Hkey

2 open

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 :
v :
ps :
listpiece × pval
IH :
ptsps −∗ ⌜NoDupps.*1⌝
Hnd :
NoDupps.*1
u :
Hkey :
l = k
Hin :
k, u ∈ ps
Hl :
pointstol, v.1 DfracOwn1 l, v.2
Hps :
∗y∈pspointstoy.1 DfracOwn1 y.2
∗
⌜NoDupl, v :: ps.*1⌝
deferred 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 :
v :
ps :
listpiece × pval
IH :
ptsps −∗ ⌜NoDupps.*1⌝
Hnd :
NoDupps.*1
Hnot :
l ∉ ps.*1
Hl :
pointstol, v.1 DfracOwn1 l, v.2
Hps :
∗y∈pspointstoy.1 DfracOwn1 y.2
∗
⌜NoDupl, v :: ps.*1⌝

subst k

2 open

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 :
v :
ps :
listpiece × pval
IH :
ptsps −∗ ⌜NoDupps.*1⌝
Hnd :
NoDupps.*1
u :
Hin :
l, u ∈ ps
Hl :
pointstol, v.1 DfracOwn1 l, v.2
Hps :
∗y∈pspointstoy.1 DfracOwn1 y.2
∗
⌜NoDupl, v :: ps.*1⌝
deferred 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 :
v :
ps :
listpiece × pval
IH :
ptsps −∗ ⌜NoDupps.*1⌝
Hnd :
NoDupps.*1
Hnot :
l ∉ ps.*1
Hl :
pointstol, v.1 DfracOwn1 l, v.2
Hps :
∗y∈pspointstoy.1 DfracOwn1 y.2
∗
⌜NoDupl, v :: ps.*1⌝

iDestruct big_sepL_elem_of_ _ _ Hin with Hps as Hk

2 open

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 :
v :
ps :
listpiece × pval
IH :
ptsps −∗ ⌜NoDupps.*1⌝
Hnd :
NoDupps.*1
u :
Hin :
l, u ∈ ps
Hl :
pointstol, v.1 DfracOwn1 l, v.2
Hk :
pointstol, u.1 DfracOwn1 l, u.2
∗
⌜NoDupl, v :: ps.*1⌝
deferred 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 :
v :
ps :
listpiece × pval
IH :
ptsps −∗ ⌜NoDupps.*1⌝
Hnd :
NoDupps.*1
Hnot :
l ∉ ps.*1
Hl :
pointstol, v.1 DfracOwn1 l, v.2
Hps :
∗y∈pspointstoy.1 DfracOwn1 y.2
∗
⌜NoDupl, v :: ps.*1⌝

iDestruct pointsto_ne with Hl Hk as %Hne

2 open

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 :
v :
ps :
listpiece × pval
IH :
ptsps −∗ ⌜NoDupps.*1⌝
Hnd :
NoDupps.*1
u :
Hin :
l, u ∈ ps
Hne :
l, v.1 ≠ l, u.1
Hl :
pointstol, v.1 DfracOwn1 l, v.2
Hk :
pointstol, u.1 DfracOwn1 l, u.2
∗
⌜NoDupl, v :: ps.*1⌝
deferred 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 :
v :
ps :
listpiece × pval
IH :
ptsps −∗ ⌜NoDupps.*1⌝
Hnd :
NoDupps.*1
Hnot :
l ∉ ps.*1
Hl :
pointstol, v.1 DfracOwn1 l, v.2
Hps :
∗y∈pspointstoy.1 DfracOwn1 y.2
∗
⌜NoDupl, v :: ps.*1⌝

contradiction

deferred 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 :
v :
ps :
listpiece × pval
IH :
ptsps −∗ ⌜NoDupps.*1⌝
Hnd :
NoDupps.*1
Hnot :
l ∉ ps.*1
Hl :
pointstol, v.1 DfracOwn1 l, v.2
Hps :
∗y∈pspointstoy.1 DfracOwn1 y.2
∗
⌜NoDupl, v :: ps.*1⌝

–iPureIntro

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 :
v :
ps :
listpiece × pval
IH :
ptsps −∗ ⌜NoDupps.*1⌝
Hnd :
NoDupps.*1
Hnot :
l ∉ ps.*1
⊢
NoDupl, v :: ps.*1

apply NoDup_cons

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 :
v :
ps :
listpiece × pval
IH :
ptsps −∗ ⌜NoDupps.*1⌝
Hnd :
NoDupps.*1
Hnot :
l ∉ ps.*1
⊢
l, v.1
∉
fix go l0 : listpiece × pval : listpiece ≔
match l0 with
[ ]
⇒
[ ]
x :: l1
⇒
x.1 :: gol1
ps
∧
NoDup
fix go l0 : listpiece × pval : listpiece ≔
match l0 with
[ ]
⇒
[ ]
x :: l1
⇒
x.1 :: gol1
ps

auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
induction ps as | l v ps IH ; iIntros _ ; iPureIntro ; constructor |
rewrite / pts big_sepL_cons
iIntros [Hl Hps]
iDestruct IH with Hps as %Hnd
destruct decidel ∈ ps.*1 as Hin | Hnot
–apply list_elem_of_fmap in Hin as k u & Hkey & Hin
cbn in Hkey
subst k
iDestruct big_sepL_elem_of_ _ _ Hin with Hps as Hk
iDestruct pointsto_ne with Hl Hk as %Hne
contradiction
–iPureIntro
apply NoDup_cons
auto

For promotion: allocating a nonempty variadic snapshot yields its populated pieces, with the read-only pointer installed in the frame. This lifts rule_snapshot through wp_lift_run; only preservation of the caller's world interpretation remains a premise.

478Lemma wp_snapshot
∀ f e ls l xs Φ
xs ≠ [ ]
forallbsnapshot_word xs = true
let q ≔ heap_req16 8 × Z.of_natlengthxs in
∀m wd h base, Memory.freshm q base → wim wd h → wisnapshot_valuesxs base allocatedm q base wd overwritesnapshot_psxs base q h → ▷∀base, ⌜0 < base ∧ base mod req_alignq = 0 ∧ base + req_extentq ≤ 2 ^ 48⌝ −∗ ptssnapshot_psxs base q −∗ WPERunmkFramef putva_snapshot WPtrmkPtrbase Robase e ls None Enterl None : hexpr {Φ} −∗ WPERunmkFramef e ls None Snapshotxs l : hexpr {Φ}
Proof 66 steps Qed
intros Hne Hwords q Hwi
assert Hex : 0 ≤ req_extentq
{pose proof heap_req_extent16 8 × Z.of_natlengthxs
unfold q
lia
assert Hal : 0 < req_alignq by cbn ; lia
pose proof λm fuel ⇒ rule_snapshotge f e ls l [ ] m fuel xs Hne Hwords as Hst
iIntros HK
iApply wp_lift_run with HK
–iIntros σ _ _
iPureIntro
left
unfold fails
rewrite Hst
fold q
lia
–iIntros m s fuel w Hσ HK
iNext
iIntros e2 σ2 Hm
destruct moves_coreregistry ge _ _ _ _ Hm ltac:intros ? ; cbn [ ls_mem ls_fuel ] ; rewrite Hst ; discriminate as c′ & E′ & _ | q′ & kk & base & s′ & E′ & _ & Ha & → & → | o & m′ & E′ & _ ; cbn [ ls_mem ls_fuel ls_rt ] in E' ; rewrite Hst in E' ; try discriminate E'
injection E' as ← ←
fold q in Ha |- *
iDestruct Hσ as h [Hh %Hσ]
destruct Hσ as Hag & Hd & Hr & Hw
cbn [ ls_mem ls_rt ls_world ] in Hag , Hd , Hr , Hw
destruct R.fresh_allocation_ _ _ _ _ Hr Hal Hex Ha as Hf Hr_alloc
pose proof Hf as Hpos & Hmod & _ & Hn & _
assert Hd_alloc : live_disjointallocatedm q base
{exact live_disjoint_allocated_ _ _ Hd Hf Hex
assert Hr′ : R.readys' snapshot_valuesxs base allocatedm q base
{apply R.ready_kept_ _ _ Hr_alloc
exact snapshot_alloc_keptxs m base
pose proof snapshot_framem xs base q Hd_alloc heap_req_extent16 8 × Z.of_natlengthxs as Hframe
iMod pts_alloch snapshot_psxs base q with Hh as [Hh Hps]
{intros k v Hin
destruct h !! k as u | eqn: E ; | reflexivity
exfalso
pose proof agree_piece_registered_ _ _ snapshot_ps_mem_ _ _ _ _ Hin Hagk u E as Hreg
rewrite snapshot_ps_id_ _ _ _ _ Hin in Hreg
exact HregHn
iModIntro
iSplitL Hh
+iExists _
iFrame Hh
iPureIntro
split ; | split ; | split
∗intros k v Hk
destruct lookup_overwrite_ _ _ _ Hk as Hin | Hnot Hold
--exact all_agree_elem_ _ _ _ snapshot_ps_agree_ _ _ _ Hf Hin
--rewrite snapshot_ps_keys in Hnot
apply Hframek v Hnot
exact agree_piece_allocated_ _ _ _ _ Hn Hagk v Hold
∗apply live_disjoint_regionsallocatedm q base ; apply snapshot_values_regions | exact Hd_alloc
∗exact Hr'
∗exact Hwim w h base Hf Hw
+iApply HK with [%] Hps
split ; exact Hpos |
split ; exact Hmod |
destruct R.address_space_ _ Hr' base mkRegionbase base + req_extentq req_kindq Live as _ Hend
reflexivity
exact Hend

For promotion: the Iris rule for VaArgs, lifted directly from rule_va_args through wp_pure_next.

539Lemma wp_va_args
∀ f e ls l d off rest j p Φ
▷WPERunmkFramef putd WPtrmkPtrptr_addrp + off mod 2 ^ 64 ptr_capp e ls None Execl rest j : hexpr {Φ} −∗ WPERunmkFramef e ls None Execl Letd P VaArgs Constoff :: rest j : hexpr {Φ}
Explore proof 5 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 :
f :
e :
listname × word
ls :
listname × optionZ
l, d :
off :
Z
rest :
listinst
j :
p :
Φ :
valnanofil_langregistry ge → iPropIΣ
⊢
lookupva_snapshot e = SomeWPtrp → ▷WPERunfr_fn ≔ f; fr_env ≔ putd WPtrptr_addr ≔ ptr_addrp + off mod 2 ^ 64; ptr_cap ≔ ptr_capp e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j : hexpr {v. Φv} −∗ WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd P VaArgs Constoff :: rest j : hexpr {v. Φv}

intros Hp

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 :
f :
e :
listname × word
ls :
listname × optionZ
l, d :
off :
Z
rest :
listinst
j :
p :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hp :
⊢
▷WPERunfr_fn ≔ f; fr_env ≔ putd WPtrptr_addr ≔ ptr_addrp + off mod 2 ^ 64; ptr_cap ≔ ptr_capp e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j : hexpr {v. Φv} −∗ WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd P VaArgs Constoff :: rest j : hexpr {v. Φv}

apply wp_pure_nextregistry wi ge _ _ [ ]

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 :
f :
e :
listname × word
ls :
listname × optionZ
l, d :
off :
Z
rest :
listinst
j :
p :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hp :
⊢
∀m : mem fuel : Z, stepge c_frame ≔ fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd P VaArgs Constoff :: rest j; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel = Nextc_frame ≔ fr_fn ≔ f; fr_env ≔ putd WPtrptr_addr ≔ ptr_addrp + off mod 2 ^ 64; ptr_cap ≔ ptr_capp e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel

intros m fuel

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 :
f :
e :
listname × word
ls :
listname × optionZ
l, d :
off :
Z
rest :
listinst
j :
p :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hp :
m :
fuel :
Z
⊢
stepge c_frame ≔ fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd P VaArgs Constoff :: rest j; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel = Nextc_frame ≔ fr_fn ≔ f; fr_env ≔ putd WPtrptr_addr ≔ ptr_addrp + off mod 2 ^ 64; ptr_cap ≔ ptr_capp e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel

apply rule_va_args

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 :
f :
e :
listname × word
ls :
listname × optionZ
l, d :
off :
Z
rest :
listinst
j :
p :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hp :
m :
fuel :
Z
⊢

exact Hp

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hp
apply wp_pure_nextregistry wi ge _ _ [ ]
intros m fuel
exact Hp

For promotion: a variadic argument read is a heap write, not a pure read of the frame. Owned pieces justify va_arg_res and retain exactly their keys after the cursor update. This lifts rule_va_arg through wp_write, including its world-frame premise.

555Lemma wp_va_arg
∀ f e ls l d k args rest j p x ps ps′ upd Φ
map2_optionvalue_xge e P args = SomeWPtrp
ps′.*1 = ps.*1
∀m, owned_factsps m → va_arg_resk p m = SomeRValx, updm ∧ m_regionsupdm = m_regionsm ∧ keptm updm ∧ all_agreeupdm ps′ ∧ frame_okps′.*1 m updm
∀m w h, ∀l v, l, v ∈ ps → h !! l = Somev → wim w h → wiupdm w overwriteps′ h
ptsps −∗ ▷ptsps′ −∗ WPERunmkFramef putd x e ls None Execl rest j : hexpr {Φ} −∗ WPERunmkFramef e ls None Execl Letd k VaArg args :: rest j : hexpr {Φ}
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 :
f :
e :
ls :
listname × optionZ
l, d :
args :
listvalue
rest :
listinst
j :
p :
x :
ps, ps′ :
listpiece × pval
upd :
mem → mem
Φ :
valnanofil_langregistry ge → iPropIΣ
⊢
map2_optionvalue_xge e P args = SomeWPtrp → ps′.*1 = ps.*1 → ∀m : mem, owned_factsps m → va_arg_resk p m = SomeRValx, updm ∧ m_regionsupdm = m_regionsm ∧ keptm updm ∧ all_agreeupdm ps′ ∧ frame_okps′.*1 m updm → ∀m : mem w : world h : gmappiece pval, ∀l0 : piece v : pval, l0, v ∈ ps → h !! l0 = Somev → wim w h → wiupdm w overwriteps′ h → ptsps −∗ ▷ptsps′ −∗ WPERunfr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j : hexpr {v. Φv} −∗ WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd k VaArg args :: rest j : hexpr {v. Φv}

intros Hargs Hkeys Hread Hwi

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 :
f :
e :
ls :
listname × optionZ
l, d :
args :
listvalue
rest :
listinst
j :
p :
x :
ps, ps′ :
listpiece × pval
upd :
mem → mem
Φ :
valnanofil_langregistry ge → iPropIΣ
Hargs :
map2_optionvalue_xge e P args = SomeWPtrp
Hkeys :
ps′.*1 = ps.*1
Hread :
∀m : mem, owned_factsps m → va_arg_resk p m = SomeRValx, updm ∧ m_regionsupdm = m_regionsm ∧ keptm updm ∧ all_agreeupdm ps′ ∧ frame_okps′.*1 m updm
Hwi :
∀m : mem w : world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → wim w h → wiupdm w overwriteps′ h
⊢
ptsps −∗ ▷ptsps′ −∗ WPERunfr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j : hexpr {v. Φv} −∗ WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd k VaArg args :: rest j : hexpr {v. Φv}

iIntros Hps HK

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 :
f :
e :
ls :
listname × optionZ
l, d :
args :
listvalue
rest :
listinst
j :
p :
x :
ps, ps′ :
listpiece × pval
upd :
mem → mem
Φ :
valnanofil_langregistry ge → iPropIΣ
Hargs :
map2_optionvalue_xge e P args = SomeWPtrp
Hkeys :
ps′.*1 = ps.*1
Hread :
∀m : mem, owned_factsps m → va_arg_resk p m = SomeRValx, updm ∧ m_regionsupdm = m_regionsm ∧ keptm updm ∧ all_agreeupdm ps′ ∧ frame_okps′.*1 m updm
Hwi :
∀m : mem w : world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → wim w h → wiupdm w overwriteps′ h
Hps :
ptsps
HK :
▷ptsps′ −∗ WPERunfr_fn ≔ f; fr_env ≔ putd x 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 Letd k VaArg args :: rest j {v. Φv}

iApply wp_writeregistry wi ge ps ps′ _ _ [ ] upd with Hps HK ; exact Hkeys | | exact Hwi

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 :
f :
e :
ls :
listname × optionZ
l, d :
args :
listvalue
rest :
listinst
j :
p :
x :
ps, ps′ :
listpiece × pval
upd :
mem → mem
Φ :
valnanofil_langregistry ge → iPropIΣ
Hargs :
map2_optionvalue_xge e P args = SomeWPtrp
Hkeys :
ps′.*1 = ps.*1
Hread :
∀m : mem, owned_factsps m → va_arg_resk p m = SomeRValx, updm ∧ m_regionsupdm = m_regionsm ∧ keptm updm ∧ all_agreeupdm ps′ ∧ frame_okps′.*1 m updm
Hwi :
∀m : mem w : world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → wim w h → wiupdm w overwriteps′ h
⊢
∀m : mem fuel : Z, owned_factsps m → stepge c_frame ≔ fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd k VaArg args :: rest j; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel = Nextc_frame ≔ fr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j; c_callers ≔ [ ]; c_mem ≔ updm; c_fuel ≔ fuel ∧ m_regionsupdm = m_regionsm ∧ keptm updm ∧ all_agreeupdm ps′ ∧ frame_okps′.*1 m updm

intros m fuel Hfacts

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 :
f :
e :
ls :
listname × optionZ
l, d :
args :
listvalue
rest :
listinst
j :
p :
x :
ps, ps′ :
listpiece × pval
upd :
mem → mem
Φ :
valnanofil_langregistry ge → iPropIΣ
Hargs :
map2_optionvalue_xge e P args = SomeWPtrp
Hkeys :
ps′.*1 = ps.*1
Hread :
∀m : mem, owned_factsps m → va_arg_resk p m = SomeRValx, updm ∧ m_regionsupdm = m_regionsm ∧ keptm updm ∧ all_agreeupdm ps′ ∧ frame_okps′.*1 m updm
Hwi :
∀m : mem w : world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → wim w h → wiupdm w overwriteps′ h
m :
fuel :
Z
Hfacts :
⊢
stepge c_frame ≔ fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd k VaArg args :: rest j; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel = Nextc_frame ≔ fr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j; c_callers ≔ [ ]; c_mem ≔ updm; c_fuel ≔ fuel ∧ m_regionsupdm = m_regionsm ∧ keptm updm ∧ all_agreeupdm ps′ ∧ frame_okps′.*1 m updm

destruct Hreadm Hfacts as Hres & Hrest

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 :
f :
e :
ls :
listname × optionZ
l, d :
args :
listvalue
rest :
listinst
j :
p :
x :
ps, ps′ :
listpiece × pval
upd :
mem → mem
Φ :
valnanofil_langregistry ge → iPropIΣ
Hargs :
map2_optionvalue_xge e P args = SomeWPtrp
Hkeys :
ps′.*1 = ps.*1
Hread :
∀m : mem, owned_factsps m → va_arg_resk p m = SomeRValx, updm ∧ m_regionsupdm = m_regionsm ∧ keptm updm ∧ all_agreeupdm ps′ ∧ frame_okps′.*1 m updm
Hwi :
∀m : mem w : world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ ps → h !! l = Somev → wim w h → wiupdm w overwriteps′ h
m :
fuel :
Z
Hfacts :
Hres :
va_arg_resk p m = SomeRValx, updm
Hrest :
m_regionsupdm = m_regionsm ∧ keptm updm ∧ all_agreeupdm ps′ ∧ frame_okps′.*1 m updm
⊢
stepge c_frame ≔ fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd k VaArg args :: rest j; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel = Nextc_frame ≔ fr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j; c_callers ≔ [ ]; c_mem ≔ updm; c_fuel ≔ fuel ∧ m_regionsupdm = m_regionsm ∧ keptm updm ∧ all_agreeupdm ps′ ∧ frame_okps′.*1 m updm

split ; exact rule_va_arg_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Hargs Hres | exact Hrest

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hargs Hkeys Hread Hwi
iIntros Hps HK
iApply wp_writeregistry wi ge ps ps′ _ _ [ ] upd with Hps HK ; exact Hkeys | | exact Hwi
intros m fuel Hfacts
destruct Hreadm Hfacts as Hres & Hrest
split ; exact rule_va_arg_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Hargs Hres | exact Hrest

For promotion: a pointer va_arg reads its snapshot cell and advances only the mutable cursor. The source and literal pieces are framed, including when the argument is the terminating null pointer.

578Lemma wp_va_arg_pointer
∀ f e ls l d args rest j cb cr sb sr off x ps Φ
cb mod 8 = 0
0 < sb
0 ≤ off
sb + off + 8 ≤ r_endsr
r_endsr ≤ 2 ^ 48
sb + off mod 8 = 0
0 ≤ ptr_addrx < 2 ^ 64
ptr_capx = CNone ∨ ∃xb xr, ptr_capx = Objxb ∨ ptr_capx = Roxb ∧ PLivexb, VLivexr ∈ ps
∀m w h, ∀k v, k, v ∈ va_cursor_pscb cr mkPtrsb + off Rosb → h !! k = Somev → wim w h → wistore_bytesm cb 8 sb + off + 8 w overwriteva_cursor_pscb cr mkPtrsb + off + 8 Rosb h
ptsva_cursor_pscb cr mkPtrsb + off Rosb −∗ livesb sr −∗ pcellsb off x −∗ ptsps −∗ ▷ptsva_cursor_pscb cr mkPtrsb + off + 8 Rosb −∗ livesb sr −∗ pcellsb off x −∗ ptsps −∗ WPERunmkFramef putd WPtrx e ls None Execl rest j : hexpr {Φ} −∗ WPERunmkFramef e ls None Execl Letd P VaArg args :: rest j : hexpr {Φ}
Proof 152 steps Qed
intros Hargs Hcb Hsb Hoff Hsend Hsmax Hal Hrange Htarget Hwi
set before := va_cursor_pscb cr mkPtrsb + off Rosb
set after := va_cursor_pscb cr mkPtrsb + off + 8 Rosb
set reads := PLivesb, VLivesr; PAuxsb off, VAuxptr_capx ++ cellsb off ptr_addrx ++ ps
iIntros Hcursor Hsl Hsc Hps HK
iAssert ptsbefore ++ reads with [Hcursor Hsl Hsc Hps] as Hpieces
{rewrite pts_app
iFrame Hcursor
replace reads with PLivesb, VLivesr ++ PAuxsb off, VAuxptr_capx :: cellsb off ptr_addrx ++ ps by reflexivity
rewrite ! pts_app
iFrame Hsl Hsc Hps
iDestruct pts_keys_nodup with Hpieces as %Hnd
rewrite fmap_app in Hnd
apply NoDup_app in Hnd as _ & Hseparate & _
iApply wp_va_argf e ls l d P args rest j mkPtrcb Objcb WPtrx before ++ reads after ++ reads λm ⇒ store_bytesm cb 8 sb + off + 8 with Hpieces [HK]
–exact Hargs
–rewrite ! fmap_app
unfold before , after , va_cursor_ps , cell
reflexivity
–intros m Hagree & Hd & _
apply all_agree_app in Hagree as Hcur Hreads
unfold before , va_cursor_ps in Hcur
cbn [ all_agree fst snd ] in Hcur
destruct Hcur as Hclive & Hcaux & Hcbytes
unfold reads in Hreads
cbn [ all_agree fst snd ] in Hreads
destruct Hreads as Hslive & Hsaux & Hrest
change all_agreem cellsb off ptr_addrx ++ ps in Hrest
destruct proj1all_agree_appm cellsb off ptr_addrx ps Hrest as Hsbytes Hps
destruct cell_bounds_ _ _ _ _ Hclive Hcbytes as Hc0 Hcend
destruct cell_store_okm cb cr 0 cb sb + off + 8 Hd Hclive Hc0 ltac:lia ltac:lia as Hnew Hframe
assert Hframe_reads : all_agreestore_bytesm cb 8 sb + off + 8 reads
intros k v Hin
apply Hframe
–intros Hkey
apply Hseparatek
+unfold before , va_cursor_ps
rewrite fmap_app
apply elem_of_app
right
exact Hkey
+exact list_elem_of_fmap_2fst _ _ Hin
–apply all_agree_elem_ reads k v ; | exact Hin
unfold reads
cbn [ all_agree fst snd ]
split ; exact Hslive |
split ; exact Hsaux |
apply proj2all_agree_appm cellsb off ptr_addrx ps
auto
assert Hslive′ : live_atstore_bytesm cb 8 sb + off + 8 sb sr
{exact Hslive
assert Hsaux′ : agree_piecestore_bytesm cb 8 sb + off + 8 PAuxsb off VAuxptr_capx
{apply all_agree_elem_ reads _ _ Hframe_reads
unfold reads
cbn
right
left
assert Hsbytes′ : all_agreestore_bytesm cb 8 sb + off + 8 cellsb off ptr_addrx
intros k v Hin
apply all_agree_elem_ reads k v Hframe_reads
unfold reads
apply elem_of_app
right
apply elem_of_app
left
exact Hin
assert Hcursor : load_bytesm cb 8 = sb + off
{replace cb with cb + 0 at 1 by lia
rewrite cell_loadm cb cr 0 sb + off cb + 0 Hclive Hcbytes eq_refl
apply Z.mod_small
lia
assert Hcursor_cap : aux_atm cb = Rosb
{unfold aux_at
replace cb with cb + 0 at 1 by lia
apply aux_holds_rom cb + 0 sb sr ; | exact Hslive
exact aux_piece_holds_ _ _ _ _ Hclive Hcaux
assert Hresult_cap : aux_atstore_bytesm cb 8 sb + off + 8 sb + off = ptr_capx
{unfold aux_at
pose proof aux_piece_holds_ _ _ _ _ Hslive' Hsaux' as Haux
destruct Htarget as Hnull | xb & xr & Hobj | Hro & Hmember
–apply aux_holds_live ; exact Haux | auto
–apply aux_holds_live ; exact Haux |
right
exists xb, xr
split ; exact Hobj |
exact all_agree_elem_ _ _ _ Hps Hmember
–rewrite Hro in Haux |- *
apply aux_holds_ro_ _ _ xr Haux
exact all_agree_elem_ _ _ _ Hps Hmember
split
+apply va_arg_pointerm mkPtrcb Objcb sb + off Rosb store_bytesm cb 8 sb + off + 8 x
∗cbn [ ptr_addr ptr_cap ]
apply access_obj_ _ cr ; exact proj1Hclive | lia | lia | exact Hcb
∗exact Hcursor
∗exact Hcursor_cap
∗exact Hal
∗apply access_ro_read_ _ sr ; exact proj1Hslive | lia | exact Hsend | exact Hal
apply access_obj_ _ cr ; exact proj1Hclive | lia | lia | apply Z.mod_1_r
∗rewrite cell_load_ sb sr off ptr_addrx sb + off Hslive' Hsbytes' eq_refl
apply Z.mod_small
exact Hrange
∗exact Hresult_cap
+split ; reflexivity |
split
exact in_object_live_ _ _ cb Hclive ltac:lia ltac:lia
∗split
split ; | exact Hframe_reads
unfold after , va_cursor_ps
cbn [ all_agree fst snd ]
split ; exact Hclive |
split ; exact Hcaux | exact Hnew
--eapply frame_ok_mono ; | exact Hframe
intros k Hin
rewrite fmap_app
apply elem_of_app
left
unfold after , va_cursor_ps
rewrite fmap_app
apply elem_of_app
right
exact Hin
–intros m w h Hown Hw
rewrite overwrite_ownedreads h
+apply Hwi ; | exact Hw
intros k v Hin
apply Hown
apply elem_of_app
left
exact Hin
+intros k v Hin
apply Hown
apply elem_of_app
right
exact Hin
–iNext
iIntros Hpieces
iEval rewritepts_app in Hpieces
iDestruct Hpieces as [Hcursor Hreads]
iEval rewrite / reads ; rewrite pts_app in Hreads
iDestruct Hreads as [Hhead Htail]
iEval rewritepts_app in Htail
iDestruct Htail as [Hsc Hps]
iEval ( rewrite / pts ! big_sepL_cons ) in Hhead
iDestruct Hhead as (Hsl & Hsa & _)
iApply HK with Hcursor [Hsl] [Hsa Hsc] Hps ; rewrite / live / pcell / pts ; iFrame ; done

For promotion: a pointer load can return a read-only literal. Its life comes from the caller's existing pieces rather than a new token. This lifts rule_let and op_raw_load_pointer through wp_read_with, and preserves those pieces.

702Lemma wp_raw_load_literal
∀ f e ls l d off args rest j classes p b reg o x xb xr ps Φ
map2_optionvalue_xge e classes args = SomeWPtrp
raw_addressptr_addrp off = b + o
b + o mod 8 = 0
0 ≤ ptr_addrx < 2 ^ 64
ptr_capx = Roxb
PLivexb, VLivexr ∈ ps
liveb reg −∗ pcellb o x −∗ ptsps −∗ ▷liveb reg −∗ pcellb o x −∗ ptsps −∗ WPERunmkFramef putd WPtrx e ls None Execl rest j : hexpr {Φ} −∗ WPERunmkFramef e ls None Execl Letd P RawLoadPointeroff AuxRead; LowerResolve; AddressRead args :: rest j : hexpr {Φ}
Proof 28 steps Qed
intros Hc Hx Hp Ha Hal Hrange Hcap Hmember
iIntros Hl Hc Hps HK
iApply wp_read_withregistry wi ge liveb reg ∗ pcellb o x ∗ ptsps λm ⇒ live_atm b reg ∧ agree_piecem PAuxb o VAuxptr_capx ∧ all_agreem cellb o ptr_addrx ∧ live_atm xb xr _ _ [ ] with [$Hl $Hc $Hps] [HK]
–iIntros σ Hσ (Hl & Hc & Hps)
iDestruct pts_facts with Hσ Hl as %Hlv _ & _
iDestruct pts_facts with Hσ Hc as %Hax Hcl & _
iDestruct pts_facts with Hσ Hps as %Hps & _
pose proof all_agree_elem_ _ _ _ Hps Hmember as Htarget
iPureIntro
auto
–intros m fuel Hlv & Hax & Hcl & Htarget
destruct cell_bounds_ _ _ _ _ Hlv Hcl as Ho He
apply rule_let with classes := classes xs := WPtrp ; reflexivity | exact Hc | exact Hx |
+rewrite Hp Ha
apply access_obj_ _ reg ; exact proj1Hlv | lia | lia | exact Hal
+rewrite pointer_load_plain Ha cell_loadm b reg o ptr_addrx b + o Hlv Hcl eq_refl
rewrite Z.mod_small ; | exact Hrange
unfold aux_at
pose proof aux_piece_holds_ _ _ _ _ Hlv Hax as Haux
rewrite Hcap in Haux
rewrite aux_holds_ro_ _ _ _ Haux Htarget
rewrite <- Hcap
destruct x
reflexivity
–iNext
iIntros (Hl & Hc & Hps)
iApply HK with Hl Hc Hps

For promotion: a memory-reading operation justified by the world interpretation, without claiming ownership of a world-owned cell. It is rule_let lifted through wp_read_with.

740Lemma wp_world_let
∀ f e ls l d k o args rest j classes xs x Φ
general_opo = true
op_arg_classeso k = Someclasses
map2_optionvalue_xge e classes args = Somexs
∀m w h, wim w h → op_reso k xs m = SomeOpResRValx m
▷WPERunmkFramef putd x e ls None Execl rest j : hexpr {Φ} −∗ WPERunmkFramef e ls None Execl Letd k o args :: rest j : hexpr {Φ}
Explore proof 13 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
⊢
general_opo = true → op_arg_classeso k = Someclasses → map2_optionvalue_xge e classes args = Somexs → ∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m → ▷WPERunfr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j : hexpr {v. Φv} −∗ WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd k o args :: rest j : hexpr {v. Φv}

intros Hg Hc Hargs Hop

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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
⊢
▷WPERunfr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j : hexpr {v. Φv} −∗ WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd k o args :: rest j : hexpr {v. Φv}

iIntros HK

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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
HK :
▷WPERunfr_fn ≔ f; fr_env ≔ putd x 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 Letd k o args :: rest j {v. Φv}

iApply wp_read_with_ _ _ emp λm ⇒ op_reso k xs m = SomeOpResRValx m _ _ [ ] with [] [HK]

5 open

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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
⊢
∀σ : HelloVersionOn.LG.L.lstateworld, heap_interpwi σ −∗ emp −∗ ⌜op_reso k xs HelloVersionOn.LG.L.ls_memσ = SomeOpResRValx HelloVersionOn.LG.L.ls_memσ⌝
focused 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
⊢
∀m : mem fuel : Z, op_reso k xs m = SomeOpResRValx m → stepge c_frame ≔ fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd k o args :: rest j; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel = Nextc_frame ≔ ?fr′; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel
focused 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
∗
focused 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
HK :
▷WPERunfr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j {v. Φv}
∗
shelved 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m

–iIntros σ (%h & _ & %Hf) _

5 open

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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
h :
Hf :
agreesHelloVersionOn.LG.L.ls_memσ h ∧ live_disjointHelloVersionOn.LG.L.ls_memσ ∧ R.readyHelloVersionOn.LG.L.ls_rtσ HelloVersionOn.LG.L.ls_memσ ∧ wiHelloVersionOn.LG.L.ls_memσ HelloVersionOn.LG.L.ls_worldσ h
∗
⌜op_reso k xs HelloVersionOn.LG.L.ls_memσ = SomeOpResRValx HelloVersionOn.LG.L.ls_memσ⌝
deferred 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
⊢
∀m : mem fuel : Z, op_reso k xs m = SomeOpResRValx m → stepge c_frame ≔ fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd k o args :: rest j; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel = Nextc_frame ≔ ?fr′; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel
deferred 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
∗
deferred 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
HK :
▷WPERunfr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j {v. Φv}
∗
shelved 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m

destruct Hf as _ & _ & _ & Hw

5 open

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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
h :
Hw :
wiHelloVersionOn.LG.L.ls_memσ HelloVersionOn.LG.L.ls_worldσ h
∗
⌜op_reso k xs HelloVersionOn.LG.L.ls_memσ = SomeOpResRValx HelloVersionOn.LG.L.ls_memσ⌝
deferred 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
⊢
∀m : mem fuel : Z, op_reso k xs m = SomeOpResRValx m → stepge c_frame ≔ fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd k o args :: rest j; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel = Nextc_frame ≔ ?fr′; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel
deferred 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
∗
deferred 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
HK :
▷WPERunfr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j {v. Φv}
∗
shelved 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m

iPureIntro

5 open

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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
h :
Hw :
wiHelloVersionOn.LG.L.ls_memσ HelloVersionOn.LG.L.ls_worldσ h
⊢
op_reso k xs HelloVersionOn.LG.L.ls_memσ = SomeOpResRValx HelloVersionOn.LG.L.ls_memσ
deferred 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
⊢
∀m : mem fuel : Z, op_reso k xs m = SomeOpResRValx m → stepge c_frame ≔ fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd k o args :: rest j; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel = Nextc_frame ≔ ?fr′; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel
deferred 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
∗
deferred 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
HK :
▷WPERunfr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j {v. Φv}
∗
shelved 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m

exact Hop_ _ _ Hw

4 open

deferred 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
⊢
∀m : mem fuel : Z, op_reso k xs m = SomeOpResRValx m → stepge c_frame ≔ fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd k o args :: rest j; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel = Nextc_frame ≔ ?fr′; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel
deferred 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
∗
deferred 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
HK :
▷WPERunfr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j {v. Φv}
∗
shelved 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m

–intros m fuel Hm

4 open

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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
m :
fuel :
Z
Hm :
op_reso k xs m = SomeOpResRValx m
⊢
stepge c_frame ≔ fr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl Letd k o args :: rest j; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel = Nextc_frame ≔ ?fr′; c_callers ≔ [ ]; c_mem ≔ m; c_fuel ≔ fuel
deferred 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
∗
deferred 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
HK :
▷WPERunfr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j {v. Φv}
∗
shelved 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m

exact rule_let_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Hg Hc Hargs Hm

2 open

deferred 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
∗
deferred 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
HK :
▷WPERunfr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j {v. Φv}
∗
▷emp −∗ WPHelloVersionOn.LG.L.stack_exprHelloVersionOn.LG.L.ERunfr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j [ ] {v. Φv}

–done

deferred 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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
HK :
▷WPERunfr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j {v. Φv}
∗
▷emp −∗ WPHelloVersionOn.LG.L.stack_exprHelloVersionOn.LG.L.ERunfr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j [ ] {v. Φv}

–iNext

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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
HK :
WPERunfr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j {v. Φv}
∗
emp −∗ WPHelloVersionOn.LG.L.stack_exprHelloVersionOn.LG.L.ERunfr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j [ ] {v. Φv}

iIntros _

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 :
f :
e :
ls :
listname × optionZ
l, d :
o :
args :
listvalue
rest :
listinst
j :
classes :
listclass
xs :
listword
x :
Φ :
valnanofil_langregistry ge → iPropIΣ
Hg :
general_opo = true
Hc :
op_arg_classeso k = Someclasses
Hargs :
map2_optionvalue_xge e classes args = Somexs
Hop :
∀m : mem w : world h : gmappiece pval, wim w h → op_reso k xs m = SomeOpResRValx m
HK :
WPERunfr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j {v. Φv}
∗
WPHelloVersionOn.LG.L.stack_exprHelloVersionOn.LG.L.ERunfr_fn ≔ f; fr_env ≔ putd x e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execl rest j [ ] {v. Φv}

iExact HK

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hg Hc Hargs Hop
iIntros HK
iApply wp_read_with_ _ _ emp λm ⇒ op_reso k xs m = SomeOpResRValx m _ _ [ ] with [] [HK]
–iIntros σ (%h & _ & %Hf) _
destruct Hf as _ & _ & _ & Hw
iPureIntro
exact Hop_ _ _ Hw
–intros m fuel Hm
exact rule_let_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Hg Hc Hargs Hm
–done
–iNext
iIntros _
iExact HK

The compiled proper-name helper preserves every framed resource: it never dereferences the pointer or calls an external function.

759Lemma proper_name_spec
∀ p Φ
▷ΦRetWPtrp −∗ WPERuninvocationproper_name_fn WPtrp : hexpr {Φ}
Explore proof 8 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 :
p :
Φ :
outcome → iPropIΣ
⊢
▷ΦRetWPtrp −∗ WPERuninvocationproper_name_fn WPtrp : hexpr {v. Φv}

iIntros HΦ

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 :
p :
Φ :
outcome → iPropIΣ
HΦ :
▷ΦRetWPtrp
∗

rewrite proper_name_entry

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 :
p :
Φ :
outcome → iPropIΣ
HΦ :
▷ΦRetWPtrp
∗
WPERunfr_fn ≔ proper_name_fn; fr_env ≔ TAtom"v0", WPtrp; fr_locals ≔ [ ]; fr_doomed ≔ None; fr_at ≔ EnterTAtom"start" None {v. Φv}

iApply wp_enter ; exact find_proper_name_start | 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 :
p :
Φ :
outcome → iPropIΣ
HΦ :
▷ΦRetWPtrp
∗

iNext

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 :
p :
Φ :
outcome → iPropIΣ
HΦ :
∗

cbn [ b_insts b_jump proper_name_start ]

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 :
p :
Φ :
outcome → iPropIΣ
HΦ :
∗
WPHelloVersionOn.LG.L.ERunfr_fn ≔ proper_name_fn; fr_env ≔ TAtom"v0", WPtrp; fr_locals ≔ [ ]; fr_doomed ≔ None; fr_at ≔ ExecTAtom"start" [ ] JRetTmpTAtom"v0" {v. Φv}

iApply wp_ret ; reflexivity | 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 :
p :
Φ :
outcome → iPropIΣ
HΦ :
∗
▷ΦRetWPtrp

iNext

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 :
p :
Φ :
outcome → iPropIΣ
HΦ :
∗

iExact HΦ

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
iIntros HΦ
iApply wp_enter ; exact find_proper_name_start | reflexivity |
iNext
iApply wp_ret ; reflexivity | reflexivity |
iNext
iExact HΦ
769Section emit

The footer links the fixture's literals, but libc supplies stdout.

771Context Hlinked : hello_linkedge
771Context stdout_cell stdout : ptr
771Context Hstdout_global : lookupTAtom"stdout" ge_globalsge = Somestdout_cell

The stdio world owns the stdout cell and guarantees its read, not an Iris piece owned by the program.

The program-owned pieces containing the footer's format and string literals. The stdio precondition reads them through pts_lookup; the world does not have to own them.

784Context literal_ps : listpiece × pval

Output specs supplied by the stdio package. The preconditions are required for these four exact calls, including the NUL-terminated format and string arguments; output failure cannot waive them.

789Context output_spec : name → contractworld
789Context Houtput_reg : ∀g xs, Ing, xs emit_output_argsstdout → registryg = Someoutput_specg
789Context Houtput_ret : ∀g xs, Ing, xs emit_output_argsstdout → contract_returnsoutput_specg = RClassW
789Context Houtput_abi : ∀g xs d args, Ing, xs emit_output_argsstdout → mapλa ⇒ match a with Argk _ ⇒ k end args = replicatelengthxs P → contract_abioutput_specg CResultd W args
789Context Houtput_pre : ∀g xs m w h, Ing, xs emit_output_argsstdout → ∀l v, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preoutput_specg xs m w
789Context Houtput_frame : ∀g xs r args s m w h trace values s′ m′ w′, Ing, xs emit_output_argsstdout → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeoutput_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n, values = WIntn ∧ 0 ≤ n < 2 ^ 32

The footer's pure symbol copies find the same literal in ge.

807Lemma emit_literal_lookup
∀ s
Ins "version-etc#str.43"; "version-etc#str.45"; "version-etc#str.58"; "version-etc#str.59"; "version-etc#str.60"; "version-etc#str.61"; "version-etc#str.62"; "version-etc#str.63"; "version-etc#str.64"
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 :
Hlinked :
stdout_cell, stdout :
Hstdout_global :
lookupTAtom"stdout" ge_globalsge = Somestdout_cell
wi_stdout :
∀m : mem w : world h : gmappiece pval, wim w h → access_resm raw_addressptr_addrstdout_cell 0 ptr_capstdout_cell 8 Read 8 = Someok ∧ pointer_load_effectsm raw_addressptr_addrstdout_cell 0 AuxRead; LowerResolve; AddressRead = Somestdout
literal_ps :
listpiece × pval
output_spec :
name → contractworld
Houtput_reg :
∀g : name xs : listword, Ing, xs emit_output_argsstdout → registryg = Someoutput_specg
Houtput_ret :
∀g : name xs : listword, Ing, xs emit_output_argsstdout → contract_returnsoutput_specg = RClassW
Houtput_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs emit_output_argsstdout
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
replicatelengthxs P
→
contract_abioutput_specg CResultd W args
Houtput_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs emit_output_argsstdout → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preoutput_specg xs m w
Houtput_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs emit_output_argsstdout → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeoutput_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
⊢
Ins "version-etc#str.43"; "version-etc#str.45"; "version-etc#str.58"; "version-etc#str.59"; "version-etc#str.60"; "version-etc#str.61"; "version-etc#str.62"; "version-etc#str.63"; "version-etc#str.64" → lookupTAtoms ge_globalsge = Someversion_literals

intros Hin

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 :
Hlinked :
stdout_cell, stdout :
Hstdout_global :
lookupTAtom"stdout" ge_globalsge = Somestdout_cell
wi_stdout :
∀m : mem w : world h : gmappiece pval, wim w h → access_resm raw_addressptr_addrstdout_cell 0 ptr_capstdout_cell 8 Read 8 = Someok ∧ pointer_load_effectsm raw_addressptr_addrstdout_cell 0 AuxRead; LowerResolve; AddressRead = Somestdout
literal_ps :
listpiece × pval
output_spec :
name → contractworld
Houtput_reg :
∀g : name xs : listword, Ing, xs emit_output_argsstdout → registryg = Someoutput_specg
Houtput_ret :
∀g : name xs : listword, Ing, xs emit_output_argsstdout → contract_returnsoutput_specg = RClassW
Houtput_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs emit_output_argsstdout
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
replicatelengthxs P
→
contract_abioutput_specg CResultd W args
Houtput_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs emit_output_argsstdout → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preoutput_specg xs m w
Houtput_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs emit_output_argsstdout → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeoutput_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Hin :
Ins "version-etc#str.43"; "version-etc#str.45"; "version-etc#str.58"; "version-etc#str.59"; "version-etc#str.60"; "version-etc#str.61"; "version-etc#str.62"; "version-etc#str.63"; "version-etc#str.64"

apply proj1proj2Hlinked

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 :
Hlinked :
stdout_cell, stdout :
Hstdout_global :
lookupTAtom"stdout" ge_globalsge = Somestdout_cell
wi_stdout :
∀m : mem w : world h : gmappiece pval, wim w h → access_resm raw_addressptr_addrstdout_cell 0 ptr_capstdout_cell 8 Read 8 = Someok ∧ pointer_load_effectsm raw_addressptr_addrstdout_cell 0 AuxRead; LowerResolve; AddressRead = Somestdout
literal_ps :
listpiece × pval
output_spec :
name → contractworld
Houtput_reg :
∀g : name xs : listword, Ing, xs emit_output_argsstdout → registryg = Someoutput_specg
Houtput_ret :
∀g : name xs : listword, Ing, xs emit_output_argsstdout → contract_returnsoutput_specg = RClassW
Houtput_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs emit_output_argsstdout
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
replicatelengthxs P
→
contract_abioutput_specg CResultd W args
Houtput_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs emit_output_argsstdout → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preoutput_specg xs m w
Houtput_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs emit_output_argsstdout → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeoutput_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Hin :
Ins "version-etc#str.43"; "version-etc#str.45"; "version-etc#str.58"; "version-etc#str.59"; "version-etc#str.60"; "version-etc#str.61"; "version-etc#str.62"; "version-etc#str.63"; "version-etc#str.64"

repeat destruct Hin as ← | Hin ; try contradiction ; vm_compute ; reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hin
apply proj1proj2Hlinked
repeat destruct Hin as ← | Hin ; try contradiction ; vm_compute ; reflexivity

The output call is safe and returns an arbitrary canonical int, retaining the caller's heap and stdio interpretation on errors too.

819Lemma wp_emit_output
∀ f e ls lab d g args rest j xs Φ
map_optionarg_xge e args = Somexs
map
λ a  ⇒
match a with
Argk _
⇒
k
args
=
replicatelengthxs P
ptsliteral_ps −∗ ▷∀n, ptsliteral_ps −∗ WPERunmkFramef putd WIntn e ls None Execlab rest j : hexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd W Globalg args :: rest j : hexpr {Φ}
Proof 32 steps Qed
intros Hin Hargs Hclasses
iIntros Hps HK
assert Hg : g = TAtom"fputs" ∨ g = TAtom"printf"
repeat destruct Hin as H | Hin ; try contradiction ; inversion H ; auto
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ output_specg xs ptsliteral_ps with Hps [HK]
–destruct Hg as → | → ; apply hello_outside ; try exact proj1Hlinked ; reflexivity
–destruct Hg as → | → ; apply proj2proj2Hlinked ; reflexivity
–destruct Hg as → | → ; reflexivity
–exact Houtput_reg_ _ Hin
–exact Hargs
–exact Houtput_abi_ _ _ _ Hin Hclasses
–iIntros σ (%h & Hh & %Hf) Hps
destruct Hf as Ha & _ & _ & Hw
iDestruct pts_lookup with Hh Hps as %Hps
iPureIntro
exact Houtput_pre_ _ _ _ _ Hin Hps Ha Hw
–iNext
iIntros σ trace values s′ m′ w′ Hinv (%h & Hh & %Hf) Hps
destruct Hf as Ha & Hd & Hr & Hw
destruct Houtput_frame_ _ _ _ _ _ _ _ _ _ _ _ _ Hin Ha Hd Hr Hw Hinv as Ha′ & Hd′ & Hr′ & Hw′ & n & → & Hn
iModIntro
iExists putd WIntn e
iSplit
+iPureIntro
cbn [ site_result ]
rewrite Houtput_ret_ _ Hin
cbn
rewrite Z.mod_small ; reflexivity | exact Hn
+iSplitL Hh ; iExists h ; iFrame ; iPureIntro ; auto |
iApply HK with Hps

The complete help footer, including failed and partial output: every stdio result is ignored and every framed resource survives.

855Lemma emit_bug_reporting_address_spec
∀ Φ
ptsliteral_ps −∗ ▷ptsliteral_ps −∗ ΦRetVoid −∗ WPERuninvocationemit_bug_reporting_address_fn [ ] : hexpr {Φ}
Proof 62 steps Qed
pose proof emit_literal_lookup"version-etc#str.43" ltac:simpl ; tauto as H43
pose proof emit_literal_lookup"version-etc#str.45" ltac:simpl ; tauto as H45
pose proof emit_literal_lookup"version-etc#str.58" ltac:simpl ; tauto as H58
pose proof emit_literal_lookup"version-etc#str.59" ltac:simpl ; tauto as H59
pose proof emit_literal_lookup"version-etc#str.60" ltac:simpl ; tauto as H60
pose proof emit_literal_lookup"version-etc#str.61" ltac:simpl ; tauto as H61
pose proof emit_literal_lookup"version-etc#str.62" ltac:simpl ; tauto as H62
pose proof emit_literal_lookup"version-etc#str.63" ltac:simpl ; tauto as H63
pose proof emit_literal_lookup"version-etc#str.64" ltac:simpl ; tauto as H64
iIntros Hps HΦ
iApply wp_enter ; exact find_emit_bug_reporting_address_start | reflexivity |
iNext
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; reflexivity |
iNext
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; reflexivity |
iNext
iApply wp_world_let ; reflexivity | reflexivity | word_premise | |
{intros m w h Hw
apply op_check
exact proj1wi_stdout_ _ _ Hw
iNext
iApply wp_world_let ; reflexivity | reflexivity | word_premise | |
{intros m w h Hw
apply op_raw_load_pointer ; apply wi_stdout_ _ _ Hw
iNext
iApply wp_emit_output with Hps ; unfold emit_output_args ; left ; reflexivity | word_premise | reflexivity |
iNext
iIntros n0 Hps
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; reflexivity |
iNext
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; reflexivity |
iNext
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; reflexivity |
iNext
iApply wp_emit_output with Hps ; unfold emit_output_args ; right ; left ; reflexivity | word_premise | reflexivity |
iNext
iIntros n1 Hps
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; reflexivity |
iNext
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; reflexivity |
iNext
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; reflexivity |
iNext
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; reflexivity |
iNext
iApply wp_emit_output with Hps ; unfold emit_output_args ; right ; right ; left ; reflexivity | word_premise | reflexivity |
iNext
iIntros n2 Hps
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; reflexivity |
iNext
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; reflexivity |
iNext
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; reflexivity |
iNext
iApply wp_emit_output with Hps ; unfold emit_output_args ; right ; right ; right ; left ; reflexivity | word_premise | reflexivity |
iNext
iIntros n3 Hps
iNext
iApply HΦ with Hps
906Section arn

The reachable version path uses the linked heading, author, and format literals; the stream itself belongs to the stdio world.

909Context Hlinked : hello_linkedge
909Context stream : ptr
909Context literal_ps : listpiece × pval

The existing literal resources include each author's live object; this prevents the collector from rewriting its read-only capability.

913Context author_reg : String.string → region
913Context Hauthor_live : ∀s, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps

The four initialized array cells that the counting loop passes on.

918Definition version_author_cellsb : Z : iPropΣ ≔
pcellb 0 version_literal"hello#str.72" ∗ pcellb 8 version_literal"hello#str.73" ∗ pcellb 16 version_literal"hello#str.74" ∗ pcellb 24 version_literal"hello#str.75"

The pure literal copies in the reachable array helper are linked.

925Lemma arn_literal_lookup
∀ s
Ins "version-etc#str.41"; "version_etc_copyright"; "version-etc#str.43"; "version-etc#str.44"; "version-etc#str.45"; "version-etc#str.46"; "version-etc#str.47"; "version-etc#str.51"
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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
⊢
Ins "version-etc#str.41"; "version_etc_copyright"; "version-etc#str.43"; "version-etc#str.44"; "version-etc#str.45"; "version-etc#str.46"; "version-etc#str.47"; "version-etc#str.51" → lookupTAtoms ge_globalsge = Someversion_literals

intros Hin

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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
Hin :
Ins "version-etc#str.41"; "version_etc_copyright"; "version-etc#str.43"; "version-etc#str.44"; "version-etc#str.45"; "version-etc#str.46"; "version-etc#str.47"; "version-etc#str.51"

apply proj1proj2Hlinked

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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
Hin :
Ins "version-etc#str.41"; "version_etc_copyright"; "version-etc#str.43"; "version-etc#str.44"; "version-etc#str.45"; "version-etc#str.46"; "version-etc#str.47"; "version-etc#str.51"

repeat destruct Hin as ← | Hin ; try contradiction ; vm_compute ; reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hin
apply proj1proj2Hlinked
repeat destruct Hin as ← | Hin ; try contradiction ; vm_compute ; reflexivity

Advance one memory-independent IR let on the fixed version path.

936Ltac version_let  ≔
iApply wp_let ; reflexivity | reflexivity | word_premise | intros m ; word_premise | ; iNext ; gen_env

These are the stdio contracts for the six exact version calls. The mixed pointer/int classes are checked before any output result; partial output and negative results retain the caller's resources.

943Context version_spec : name → contractworld
943Context Hversion_reg : ∀g xs, Ing, xs version_output_argsstream → registryg = Someversion_specg
943Context Hversion_ret : ∀g xs, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
943Context Hversion_abi : ∀g xs d args, Ing, xs version_output_argsstream → mapλa ⇒ match a with Argk _ ⇒ k end args = version_output_classesxs → contract_abiversion_specg CResultd W args
943Context Hversion_pre : ∀g xs m w h, Ing, xs version_output_argsstream → ∀l v, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
943Context Hversion_frame : ∀g xs r args s m w h trace values s′ m′ w′, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n, values = WIntn ∧ 0 ≤ n < 2 ^ 32

The reachable version calls preserve their literals and ignore every canonical int result, including negative and partial output.

962Lemma wp_version_output
∀ f e ls lab d g args rest j xs Φ
map_optionarg_xge e args = Somexs
map
λ a  ⇒
match a with
Argk _
⇒
k
args
=
ptsliteral_ps −∗ ▷∀n, ptsliteral_ps −∗ WPERunmkFramef putd WIntn e ls None Execlab rest j : hexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd W Globalg args :: rest j : hexpr {Φ}
Proof 32 steps Qed
intros Hin Hargs Hclasses
iIntros Hps HK
assert Hg : g = TAtom"fputs" ∨ g = TAtom"fprintf"
repeat destruct Hin as H | Hin ; try contradiction ; inversion H ; auto
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ version_specg xs ptsliteral_ps with Hps [HK]
–destruct Hg as → | → ; apply hello_outside ; try exact proj1Hlinked ; reflexivity
–destruct Hg as → | → ; apply proj2proj2Hlinked ; reflexivity
–destruct Hg as → | → ; reflexivity
–exact Hversion_reg_ _ Hin
–exact Hargs
–exact Hversion_abi_ _ _ _ Hin Hclasses
–iIntros σ (%h & Hh & %Hf) Hps
destruct Hf as Ha & _ & _ & Hw
iDestruct pts_lookup with Hh Hps as %Hps
iPureIntro
exact Hversion_pre_ _ _ _ _ Hin Hps Ha Hw
–iNext
iIntros σ trace values s′ m′ w′ Hinv (%h & Hh & %Hf) Hps
destruct Hf as Ha & Hd & Hr & Hw
destruct Hversion_frame_ _ _ _ _ _ _ _ _ _ _ _ _ Hin Ha Hd Hr Hw Hinv as Ha′ & Hd′ & Hr′ & Hw′ & n & → & Hn
iModIntro
iExists putd WIntn e
iSplit
+iPureIntro
cbn [ site_result ]
rewrite Hversion_ret_ _ Hin
cbn
rewrite Z.mod_small ; reflexivity | exact Hn
+iSplitL Hh ; iExists h ; iFrame ; iPureIntro ; auto |
iApply HK with Hps

The reachable array helper prints the heading and four authors, preserving the array and literal resources for every stdio result. Its fixed count is discharged by version_etc_va, not assumed by main.

999Lemma version_etc_arn_spec
∀ b Φ
0 < b
b mod 16 = 0
b + 80 ≤ 2 ^ 48
ptsliteral_ps −∗ liveb mkRegionb b + 80 Heap Live −∗ version_author_cellsb −∗ ▷ptsliteral_ps −∗ liveb mkRegionb b + 80 Heap Live −∗ version_author_cellsb −∗ ΦRetVoid −∗ WPERuninvocationversion_etc_arn_fn WPtrstream; WPtrversion_literal"hello#str.70"; WPtrversion_literal"hello#str.63"; WPtrversion_literal"hello#str.71"; WPtrmkPtrb Objb; WInt4 : hexpr {Φ}
Proof 161 steps Qed
intros Hb Hmod Hend
assert Hmod8 : b mod 8 = 0
{apply Z.mod_divide ; lia |
apply Z.divide_trans8 16 b
–exists 2
reflexivity
–apply Z.mod_divide ; lia | exact Hmod
pose proof arn_literal_lookup"version-etc#str.41" ltac:simpl ; tauto as H41
pose proof arn_literal_lookup"version_etc_copyright" ltac:simpl ; tauto as Hcopyright
pose proof arn_literal_lookup"version-etc#str.43" ltac:simpl ; tauto as H43
pose proof arn_literal_lookup"version-etc#str.44" ltac:simpl ; tauto as H44
pose proof arn_literal_lookup"version-etc#str.45" ltac:simpl ; tauto as H45
pose proof arn_literal_lookup"version-etc#str.46" ltac:simpl ; tauto as H46
pose proof arn_literal_lookup"version-etc#str.47" ltac:simpl ; tauto as H47
pose proof arn_literal_lookup"version-etc#str.51" ltac:simpl ; tauto as H51
iIntros Hps Hl (H0 & H1 & H2 & H3) HΦ
set e := TAtom"v10", WInt4; TAtom"v8", WPtrmkPtrb Objb; TAtom"v6", WPtrversion_literal"hello#str.71"; TAtom"v4", WPtrversion_literal"hello#str.63"; TAtom"v2", WPtrversion_literal"hello#str.70"; TAtom"v0", WPtrstream
assert Hv0 : lookupTAtom"v0" e = SomeWPtrstream by reflexivity
assert Hv2 : lookupTAtom"v2" e = SomeWPtrversion_literal"hello#str.70" by reflexivity
assert Hv4 : lookupTAtom"v4" e = SomeWPtrversion_literal"hello#str.63" by reflexivity
assert Hv6 : lookupTAtom"v6" e = SomeWPtrversion_literal"hello#str.71" by reflexivity
assert Hv8 : lookupTAtom"v8" e = SomeWPtrmkPtrb Objb by reflexivity
assert Hv10 : lookupTAtom"v10" e = SomeWInt4 by reflexivity
clearbody e
iApply wp_enter ; vm_compute ; reflexivity | reflexivity |
iNext
iNext
iApply wp_enter ; vm_compute ; reflexivity | reflexivity |
iNext
iApply wp_version_output with Hps ; unfold version_output_args ; left ; reflexivity | word_premise | reflexivity |
iNext
iIntros n0 Hps
iApply wp_goto
iNext
iApply wp_enter ; vm_compute ; reflexivity | reflexivity |
iNext
iApply wp_version_output with Hps ; unfold version_output_args ; right ; left ; reflexivity | word_premise | reflexivity |
iNext
iIntros n1 Hps
iApply wp_version_output with Hps ; unfold version_output_args ; right ; right ; left ; reflexivity | word_premise | reflexivity |
iNext
iIntros n2 Hps
iApply wp_version_output with Hps ; unfold version_output_args ; right ; right ; right ; left ; reflexivity | word_premise | reflexivity |
iNext
iIntros n3 Hps
iApply wp_version_output with Hps ; unfold version_output_args ; right ; right ; right ; right ; left ; reflexivity | word_premise | reflexivity |
iNext
iIntros n4 Hps
iNext
iApply wp_enter ; vm_compute ; reflexivity | reflexivity |
iNext
iNext
iApply wp_enter ; vm_compute ; reflexivity | reflexivity |
iNext
iNext
iApply wp_enter ; vm_compute ; reflexivity | reflexivity |
iNext
iNext
iApply wp_enter ; vm_compute ; reflexivity | reflexivity |
iNext
iNext
iApply wp_enter ; vm_compute ; reflexivity | reflexivity |
iNext
iApply wp_check with Hl ; reflexivity | word_premise | reflexivity | addr_premise | cbn [ r_end ] ; addr_premise | addr_premise |
iNext
iIntros Hl
iApply wp_raw_load_literal with Hl H0 Hps ; reflexivity | word_premise | reflexivity | addr_premise | addr_premise | vm_compute ; split ; congruence | vm_compute ; reflexivity | apply Hauthor_live"hello#str.72" ; simpl ; tauto |
iNext
iIntros Hl H0 Hps
iApply wp_flight_ _ _ _ _ _ _ _ _ _ _ _ _ _ b + 8 ; word_premise | cbn ; f_equal ; f_equal ; addr_premise | word_premise |
iNext
iApply wp_half_check with Hl ; reflexivity | word_premise | reflexivity | reflexivity | addr_premise | cbn [ r_end ] ; addr_premise | lia | cbn ; lia | addr_premise |
iNext
iIntros Hl
iApply wp_raw_load_literal with Hl H1 Hps ; reflexivity | word_premise | reflexivity | addr_premise | addr_premise | vm_compute ; split ; congruence | vm_compute ; reflexivity | apply Hauthor_live"hello#str.73" ; simpl ; tauto |
iNext
iIntros Hl H1 Hps
iApply wp_flight_ _ _ _ _ _ _ _ _ _ _ _ _ _ b + 16 ; word_premise | cbn ; f_equal ; f_equal ; addr_premise | word_premise |
iNext
iApply wp_half_check with Hl ; reflexivity | word_premise | reflexivity | reflexivity | addr_premise | cbn [ r_end ] ; addr_premise | lia | cbn ; lia | addr_premise |
iNext
iIntros Hl
iApply wp_raw_load_literal with Hl H2 Hps ; reflexivity | word_premise | reflexivity | addr_premise | addr_premise | vm_compute ; split ; congruence | vm_compute ; reflexivity | apply Hauthor_live"hello#str.74" ; simpl ; tauto |
iNext
iIntros Hl H2 Hps
iApply wp_flight_ _ _ _ _ _ _ _ _ _ _ _ _ _ b + 24 ; word_premise | cbn ; f_equal ; f_equal ; addr_premise | word_premise |
iNext
iApply wp_half_check with Hl ; reflexivity | word_premise | reflexivity | reflexivity | addr_premise | cbn [ r_end ] ; addr_premise | lia | cbn ; lia | addr_premise |
iNext
iIntros Hl
iApply wp_raw_load_literal with Hl H3 Hps ; reflexivity | word_premise | reflexivity | addr_premise | addr_premise | vm_compute ; split ; congruence | vm_compute ; reflexivity | apply Hauthor_live"hello#str.75" ; simpl ; tauto |
iNext
iIntros Hl H3 Hps
iApply wp_version_output with Hps ; unfold version_output_args ; right ; right ; right ; right ; right ; left ; reflexivity | word_premise | reflexivity |
iNext
iIntros n5 Hps
iApply wp_goto
iNext
iApply wp_enter ; vm_compute ; reflexivity | reflexivity |
iNext
iNext
iApply HΦ with Hps Hl [H0 H1 H2 H3]
iFrame

The variadic counting helper in the linked program.

1119Definition version_etc_va_fn: func ≔
Eval vm_compute in hello_fn"version_etc_va"

The allocation block of the counting helper.

1121Definition va_start: block ≔
Eval vm_compute in hblkversion_etc_va_fn "start"

The loop header binds the current author count.

1123Definition va_L12: block ≔
Eval vm_compute in hblkversion_etc_va_fn "L12"

The loop body consumes and stores one variadic pointer.

1125Definition va_L18: block ≔
Eval vm_compute in hblkversion_etc_va_fn "L18"

The null test selects another iteration or the array helper.

1127Definition va_L19: block ≔
Eval vm_compute in hblkversion_etc_va_fn "L19"

The back edge increments the count of non-null authors.

1129Definition va_L14: block ≔
Eval vm_compute in hblkversion_etc_va_fn "L14"

The exit block passes the derived count to the array helper.

1131Definition va_L15: block ≔
Eval vm_compute in hblkversion_etc_va_fn "L15"

Zero pointer bytes coincide with the eight-byte string block.

1134Lemma version_zero_cell
∀ b o
bytesb o replicate8 0 −∗ auxesb o replicate8 CNone −∗ pcellb o null
Proof 17 steps Qed
assert Hbyte : ∀i, byte_of0 i = 0
{intros i
unfold byte_of
destruct Z.eq_dec2 ^ 8 × i 0 as → | Hne
–reflexivity
–rewrite Z.div_0_l ; reflexivity | exact Hne
assert Hcell : cellb o 0 = byte_psb o replicate8 0
{unfold cell , byte_ps , seqZ
cbn
rewrite ! Hbyte Nat2Z.id
cbn
repeat f_equal ; try lia
rewrite / pcell / pts big_sepL_cons Hcell
iIntros Hx Ha
iEval rewrite / auxes ; rewrite aux_ps_cons / pts big_sepL_cons in Ha
iDestruct Ha as [Ha _]
iFrame Ha Hx

Split off one zero pointer cell without expanding the rest of its allocation into individually searched heap pieces.

1151Lemma version_zero_cell_prefix
∀ b o n
bytesb o replicate8 + n 0 −∗ auxesb o replicate8 + n CNone −∗ pcellb o null ∗ bytesb o + 8 replicaten 0 ∗ auxesb o + 8 replicaten CNone
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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
b, o :
Z
n :
nat
⊢
bytesb o replicate8 + n 0 −∗ auxesb o replicate8 + n CNone −∗ pcellb o null ∗ bytesb o + 8 replicaten 0 ∗ auxesb o + 8 replicaten CNone

rewrite ! replicate_add bytes_app auxes_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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
b, o :
Z
n :
nat
⊢
bytesb o replicate8 0 ∗ bytesb o + lengthreplicate8 0 replicaten 0 −∗ auxesb o replicate8 CNone ∗ auxesb o + lengthreplicate8 CNone replicaten CNone −∗ pcellb o null ∗ bytesb o + 8 replicaten 0 ∗ auxesb o + 8 replicaten CNone

iIntros [Hx Hrest] [Ha Htail]

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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
b, o :
Z
n :
nat
Hx :
bytesb o replicate8 0
Hrest :
bytesb o + lengthreplicate8 0 replicaten 0
Ha :
auxesb o replicate8 CNone
Htail :
auxesb o + lengthreplicate8 CNone replicaten CNone
∗
pcellb o null ∗ bytesb o + 8 replicaten 0 ∗ auxesb o + 8 replicaten CNone

iFrame Hrest Htail

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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
b, o :
Z
n :
nat
Hx :
bytesb o replicate8 0
Ha :
auxesb o replicate8 CNone
∗

iApply version_zero_cell with Hx Ha

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
rewrite ! replicate_add bytes_app auxes_app
iIntros [Hx Hrest] [Ha Htail]
iFrame Hrest Htail
iApply version_zero_cell with Hx Ha

Five zero cells suffice for the four authors and their terminator; the rest of the allocated array is unused.

1162Lemma version_array_zero
∀ b
objb heap_req8 80 −∗ liveb mkRegionb b + 80 Heap Live ∗ pcellb 0 null ∗ pcellb 8 null ∗ pcellb 16 null ∗ pcellb 24 null ∗ pcellb 32 null
Explore proof 9 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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
b :
Z
⊢
objb heap_req8 80 −∗ liveb r_base ≔ b; r_end ≔ b + 80; r_kind ≔ Heap; r_life ≔ Live ∗ pcellb 0 null ∗ pcellb 8 null ∗ pcellb 16 null ∗ pcellb 24 null ∗ pcellb 32 null

iIntros Hobj

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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
b :
Z
Hobj :
∗
liveb r_base ≔ b; r_end ≔ b + 80; r_kind ≔ Heap; r_life ≔ Live ∗ pcellb 0 null ∗ pcellb 8 null ∗ pcellb 16 null ∗ pcellb 24 null ∗ pcellb 32 null

iDestruct obj_zero_block with Hobj as (Hl & Hx & Ha) ; compute ; discriminate |

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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
b :
Z
Hl :
HelloVersionOn.ML.LG.liveb r_base ≔ b; r_end ≔ b + req_extentheap_req8 80; r_kind ≔ req_kindheap_req8 80; r_life ≔ Live
Hx :
bytesb 0 replicateZ.to_natreq_extentheap_req8 80 0
Ha :
auxesb 0 replicateZ.to_natreq_extentheap_req8 80 CNone
∗
liveb r_base ≔ b; r_end ≔ b + 80; r_kind ≔ Heap; r_life ≔ Live ∗ pcellb 0 null ∗ pcellb 8 null ∗ pcellb 16 null ∗ pcellb 24 null ∗ pcellb 32 null

iSplitL Hl ; iExact Hl |

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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
b :
Z
Hx :
bytesb 0 replicateZ.to_natreq_extentheap_req8 80 0
Ha :
auxesb 0 replicateZ.to_natreq_extentheap_req8 80 CNone
∗
pcellb 0 null ∗ pcellb 8 null ∗ pcellb 16 null ∗ pcellb 24 null ∗ pcellb 32 null

iDestruct version_zero_cell_prefixb 0 72 with Hx Ha as (H0 & Hx & Ha)

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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
b :
Z
H0 :
Hx :
bytesb 0 + 8 replicate72 0
Ha :
auxesb 0 + 8 replicate72 CNone
∗
pcellb 0 null ∗ pcellb 8 null ∗ pcellb 16 null ∗ pcellb 24 null ∗ pcellb 32 null

iDestruct version_zero_cell_prefixb 8 64 with Hx Ha as (H1 & Hx & Ha)

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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
b :
Z
H0 :
H1 :
Hx :
bytesb 8 + 8 replicate64 0
Ha :
auxesb 8 + 8 replicate64 CNone
∗
pcellb 0 null ∗ pcellb 8 null ∗ pcellb 16 null ∗ pcellb 24 null ∗ pcellb 32 null

iDestruct version_zero_cell_prefixb 16 56 with Hx Ha as (H2 & Hx & Ha)

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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
b :
Z
H0 :
H1 :
H2 :
Hx :
bytesb 16 + 8 replicate56 0
Ha :
auxesb 16 + 8 replicate56 CNone
∗
pcellb 0 null ∗ pcellb 8 null ∗ pcellb 16 null ∗ pcellb 24 null ∗ pcellb 32 null

iDestruct version_zero_cell_prefixb 24 48 with Hx Ha as (H3 & Hx & Ha)

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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
b :
Z
H0 :
H1 :
H2 :
H3 :
Hx :
bytesb 24 + 8 replicate48 0
Ha :
auxesb 24 + 8 replicate48 CNone
∗
pcellb 0 null ∗ pcellb 8 null ∗ pcellb 16 null ∗ pcellb 24 null ∗ pcellb 32 null

iDestruct version_zero_cell_prefixb 32 40 with Hx Ha as (H4 & _ & _)

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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
b :
Z
H0 :
H1 :
H2 :
H3 :
H4 :
∗
pcellb 0 null ∗ pcellb 8 null ∗ pcellb 16 null ∗ pcellb 24 null ∗ pcellb 32 null

iFrame H0 H1 H2 H3 H4

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
iIntros Hobj
iDestruct obj_zero_block with Hobj as (Hl & Hx & Ha) ; compute ; discriminate |
iSplitL Hl ; iExact Hl |
iDestruct version_zero_cell_prefixb 0 72 with Hx Ha as (H0 & Hx & Ha)
iDestruct version_zero_cell_prefixb 8 64 with Hx Ha as (H1 & Hx & Ha)
iDestruct version_zero_cell_prefixb 16 56 with Hx Ha as (H2 & Hx & Ha)
iDestruct version_zero_cell_prefixb 24 48 with Hx Ha as (H3 & Hx & Ha)
iDestruct version_zero_cell_prefixb 32 40 with Hx Ha as (H4 & _ & _)
iFrame H0 H1 H2 H3 H4

The entry binds the heading literals and the caller's va_list.

1178Lemma version_etc_va_entry
∀ cb
invocationversion_etc_va_fn WPtrstream; WPtrversion_literal"hello#str.70"; WPtrversion_literal"hello#str.63"; WPtrversion_literal"hello#str.71"; WPtrmkPtrcb Objcb = mkFrameversion_etc_va_fn TAtom"v8", WPtrmkPtrcb Objcb; TAtom"v6", WPtrversion_literal"hello#str.71"; TAtom"v4", WPtrversion_literal"hello#str.63"; TAtom"v2", WPtrversion_literal"hello#str.70"; TAtom"v0", WPtrstream [ ] None EnterTAtom"start" None
Explore proof 1 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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
cb :
Z
⊢
invocationversion_etc_va_fn WPtrstream; WPtrversion_literal"hello#str.70"; WPtrversion_literal"hello#str.63"; WPtrversion_literal"hello#str.71"; WPtrptr_addr ≔ cb; ptr_cap ≔ Objcb = fr_fn ≔ version_etc_va_fn; fr_env ≔ TAtom"v8", WPtrptr_addr ≔ cb; ptr_cap ≔ Objcb; TAtom"v6", WPtrversion_literal"hello#str.71"; TAtom"v4", WPtrversion_literal"hello#str.63"; TAtom"v2", WPtrversion_literal"hello#str.70"; TAtom"v0", WPtrstream; fr_locals ≔ [ ]; fr_doomed ≔ None; fr_at ≔ EnterTAtom"start" None

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
reflexivity

Program-local allocations preserve the caller's opaque world.

1192Context Kversion_alloc : ∀size m wd h base, Insize 24; 80 → freshm heap_req8 size base → wim wd h → wiallocatedm heap_req8 size base wd overwriteobj_psbase heap_req8 size h

Storing a pointer in an owned program cell preserves that world; no ownership of the output stream is introduced.

1199Context Kversion_store : ∀b reg o x xp m wd h, ∀k v, k, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! k = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h

Advancing an owned va_list cursor preserves the caller's world.

1208Context Kversion_cursor : ∀cb cr sb off m wd h, ∀k v, k, v ∈ va_cursor_pscb cr mkPtrsb + off Rosb → h !! k = Somev → wim wd h → wistore_bytesm cb 8 sb + off + 8 wd overwriteva_cursor_pscb cr mkPtrsb + off + 8 Rosb h

The heading, cursor and array registers survive every loop round.

1215Definition version_va_savede cb b : Prop ≔
lookupTAtom"v0" e = SomeWPtrstream ∧ lookupTAtom"v2" e = SomeWPtrversion_literal"hello#str.70" ∧ lookupTAtom"v4" e = SomeWPtrversion_literal"hello#str.63" ∧ lookupTAtom"v6" e = SomeWPtrversion_literal"hello#str.71" ∧ lookupTAtom"v8" e = SomeWPtrmkPtrcb Objcb ∧ lookupTAtom"v11" e = SomeWPtrmkPtrb Objb

The common loop body begins after the scalar index and flight.

1224Definition va_read_body: listinst ≔
Eval vm_compute in skipn2 b_instsva_L18

Check the non-null body once, with an abstract incoming and outgoing environment, rather than expanding its proof at every author.

1228Lemma version_va_round_step
∀ e i cb cr sb sr off b o x Φ
lookupTAtom"pr.1" e = SomeWInti
lookupTAtom"v22" e = SomeWPtrmkPtrb + o Objb
0 ≤ i < 4
cb mod 8 = 0
0 < sb
0 ≤ off
sb + off + 8 ≤ r_endsr
r_endsr ≤ 2 ^ 48
sb + off mod 8 = 0
0 < b
0 ≤ o
o + 8 ≤ 80
b + 80 ≤ 2 ^ 48
b + o mod 8 = 0
0 < ptr_addrx < 2 ^ 64
ptr_capx = CNone ∨ ∃xb xr, ptr_capx = Objxb ∨ ptr_capx = Roxb ∧ PLivexb, VLivexr ∈ literal_ps
ptsliteral_ps −∗ ptsva_cursor_pscb cr mkPtrsb + off Rosb −∗ livesb sr −∗ pcellsb off x −∗ liveb mkRegionb b + 80 Heap Live −∗ pcellb o null −∗ ▷∀e′, ⌜version_va_savede′ cb b ∧ lookupTAtom"v31" e′ = SomeWInti + 1⌝ −∗ ptsliteral_ps −∗ ptsva_cursor_pscb cr mkPtrsb + off + 8 Rosb −∗ livesb sr −∗ pcellsb off x −∗ liveb mkRegionb b + 80 Heap Live −∗ pcellb o x −∗ WPERunmkFrameversion_etc_va_fn e′ [ ] None ExecTAtom"L14" [ ] JGotoPollTAtom"L12" : hexpr {Φ} −∗ WPERunmkFrameversion_etc_va_fn e [ ] None ExecTAtom"L18" va_read_body JGotoToTAtom"L19" : hexpr {Φ}
Proof 41 steps Qed
intros Hsaved Hcount Hflight Hi Hcb Hsb Hoff Hsend Hsmax Hsal Hb Ho Hoend Hbend Hbal Hx Htarget
destruct Hsaved as Hv0 & Hv2 & Hv4 & Hv6 & Hv8 & Hv11
assert Hxmod : ptr_addrx mod 2 ^ 64 = ptr_addrx by apply Z.mod_small ; lia
assert Hxne : ptr_addrx =? 0 = false by apply Z.eqb_neq ; lia
iIntros Hps Hcursor Hsl Hsource Hl Hdest HK
cbn [ va_read_body ]
iApply wp_va_arg_pointer with Hcursor Hsl Hsource Hps ; word_premise | exact Hcb | exact Hsb | exact Hoff | exact Hsend | exact Hsmax | exact Hsal | lia | exact Htarget | apply Kversion_cursor |
iNext
iIntros Hcursor Hsl Hsource Hps
iApply wp_check with Hl ; reflexivity | word_premise | reflexivity | addr_premise | cbn [ r_end ] ; addr_premise | addr_premise |
iNext
iIntros Hl
iApply wp_raw_store_pointer with Hl Hdest ; word_premise | word_premise | reflexivity | addr_premise | addr_premise | apply Kversion_store |
iNext
iIntros Hl Hdest
rewrite ?Hxmod
rewrite ?Hxmod ?Hxne
iApply wp_goto
iNext
iApply wp_enter ; vm_compute ; reflexivity | word_premise |
iNext
iNext
iApply wp_enter ; vm_compute ; reflexivity | reflexivity |
iNext
iApply HK with [%] Hps Hcursor Hsl Hsource Hl Hdest
split ; unfold version_va_saved ; repeat split ; word_premise | word_premise

Select the concrete index, then reuse the opaque non-null body.

1278Ltac version_va_round addr src dst text ≔
iRename src into Hsource ; iRename dst into Hdest ; iApply wp_goto ; iNext ; iApply wp_enter ; vm_compute ; reflexivity | word_premise | ; iNext ; gen_env ; cbn [ b_insts b_jump va_L12 ] ; version_let ; gen_env ; iApply wp_branch ; word_premise | ; iNext ; cbn [ Z.eqb edge_label ] ; iApply wp_enter ; vm_compute ; reflexivity | reflexivity | ; iNext ; cbn [ b_insts b_jump va_L18 ] ; version_let ; gen_env ; iApply wp_flight_ _ _ _ _ _ _ _ _ _ _ _ _ _ addr ; word_premise | cbn ; f_equal ; f_equal ; addr_premise | word_premise | ; iNext ; gen_env ; iApply version_va_round_step with Hps Hcursor Hsl Hsource Hl Hdest ; unfold version_va_saved ; repeat split ; word_premise | word_premise | repeat progress cbn - [ load_bytes store_bytes ] ; use_facts_goal ; repeat f_equal ; try lia | vm_compute ; split ; congruence | assumption | assumption | lia | lia | assumption | addr_premise | assumption | lia | lia | assumption | addr_premise | vm_compute ; split ; congruence | right ; exists ptr_addrversion_literaltext, author_regtext ; split ; right ; vm_compute ; reflexivity | apply Hauthor_live ; simpl ; tauto | ; iNext ; iIntros e′ Hsaved Hps Hcursor Hsl Hsource Hl Hdest;match goal withH : version_va_saved_ _ _ ∧ _ |- _⇒destruct H as ? & ? & ? & ? & ? & ? & ?end;iRename Hsource into src;iRename Hdest into dst

The counting loop reads four literal authors and the actual null terminator, then calls the array helper with the derived count four. It returns the caller's literals, snapshot cells, and advanced cursor.

1306Lemma version_etc_va_spec
∀ cb cr sb sr Φ
cb mod 8 = 0
0 < sb
sb mod 16 = 0
sb + 72 ≤ r_endsr
r_endsr ≤ 2 ^ 48
ptsliteral_ps −∗ ptsva_cursor_pscb cr mkPtrsb + 32 Rosb −∗ livesb sr −∗ pcellsb 32 version_literal"hello#str.72" −∗ pcellsb 40 version_literal"hello#str.73" −∗ pcellsb 48 version_literal"hello#str.74" −∗ pcellsb 56 version_literal"hello#str.75" −∗ pcellsb 64 null −∗ ▷ptsliteral_ps −∗ ptsva_cursor_pscb cr mkPtrsb + 72 Rosb −∗ livesb sr −∗ pcellsb 32 version_literal"hello#str.72" −∗ pcellsb 40 version_literal"hello#str.73" −∗ pcellsb 48 version_literal"hello#str.74" −∗ pcellsb 56 version_literal"hello#str.75" −∗ pcellsb 64 null −∗ ΦRetVoid −∗ WPERuninvocationversion_etc_va_fn WPtrstream; WPtrversion_literal"hello#str.70"; WPtrversion_literal"hello#str.63"; WPtrversion_literal"hello#str.71"; WPtrmkPtrcb Objcb : hexpr {Φ}
Proof 97 steps Qed
intros Hcb Hsb Hsmod Hsend Hsmax
assert Hs8 : sb mod 8 = 0
{apply Z.mod_divide ; lia |
apply Z.divide_trans8 16 sb
–exists 2
reflexivity
–apply Z.mod_divide ; lia | exact Hsmod
iIntros Hps Hcursor Hsl Hs0 Hs1 Hs2 Hs3 Hs4 HK
iApply wp_enter ; vm_compute ; reflexivity | reflexivity |
iNext
iApply wp_alloc_ _ _ _ _ _ _ _ _ _ _ _ _ 80 ; reflexivity | lia | unfold max_allocation_size ; lia | intros m wd h base Hf Hw ; apply Kversion_alloc ; simpl ; tauto | exact Hf | exact Hw |
iNext
iIntros b Hb Hbmod Hbend Hobj
change b mod 16 = 0 in Hbmod
change b + 80 ≤ 2 ^ 48 in Hbend
assert Hb8 : b mod 8 = 0
{apply Z.mod_divide ; lia |
apply Z.divide_trans8 16 b
–exists 2
reflexivity
–apply Z.mod_divide ; lia | exact Hbmod
iDestruct version_array_zero with Hobj as (Hl & H0 & H1 & H2 & H3 & H4)
assert H40 : sb + 32 + 8 = sb + 40 by lia
assert H48 : sb + 40 + 8 = sb + 48 by lia
assert H56 : sb + 48 + 8 = sb + 56 by lia
assert H64 : sb + 56 + 8 = sb + 64 by lia
version_va_round b "Hs0" "H0" "hello#str.72"
iEval rewriteH40 in Hcursor
version_va_round b + 8 "Hs1" "H1" "hello#str.73"
iEval rewriteH48 in Hcursor
version_va_round b + 16 "Hs2" "H2" "hello#str.74"
iEval rewriteH56 in Hcursor
version_va_round b + 24 "Hs3" "H3" "hello#str.75"
iEval rewriteH64 in Hcursor
iApply wp_goto
iNext
iApply wp_enter ; vm_compute ; reflexivity | word_premise |
iNext
iNext
iApply wp_enter ; vm_compute ; reflexivity | reflexivity |
iNext
iApply wp_flight_ _ _ _ _ _ _ _ _ _ _ _ _ _ b + 32 ; word_premise | cbn ; f_equal ; f_equal ; addr_premise | word_premise |
iNext
iApply wp_va_arg_pointer with Hcursor Hsl Hs4 Hps ; word_premise | exact Hcb | exact Hsb | lia | lia | exact Hsmax | addr_premise | vm_compute ; split ; congruence | left ; reflexivity | apply Kversion_cursor |
iNext
iIntros Hcursor Hsl Hs4 Hps
iApply wp_check with Hl ; reflexivity | word_premise | reflexivity | addr_premise | cbn [ r_end ] ; addr_premise | addr_premise |
iNext
iIntros Hl
iApply wp_raw_store_pointer with Hl H4 ; word_premise | word_premise | reflexivity | addr_premise | addr_premise | apply Kversion_store |
iNext
iIntros Hl H4
iApply wp_goto
iNext
iApply wp_enter ; vm_compute ; reflexivity | word_premise |
iNext
iNext
iApply wp_enter ; vm_compute ; reflexivity | reflexivity |
iNext
iApply wp_call_bind_ _ _ _ _ _ _ _ _ _ _ _ _ version_etc_arn_fn invocationversion_etc_arn_fn WPtrstream; WPtrversion_literal"hello#str.70"; WPtrversion_literal"hello#str.63"; WPtrversion_literal"hello#str.71"; WPtrmkPtrb Objb; WInt4 ; word_premise | unfold find_fn ; rewrite proj1Hlinked ; vm_compute ; reflexivity | reflexivity |
iNext
iApply version_etc_arn_spec with Hps Hl [H0 H1 H2 H3] ; exact Hb | exact Hbmod | exact Hbend | rewrite / version_author_cells ; iFrame |
iNext
iIntros Hps Hl Ha
iExists _
iSplit ; iPureIntro ; reflexivity |
iNext
iNext
assert H72 : sb + 64 + 8 = sb + 72 by lia
iEval rewriteH72 in Hcursor
iApply HK with Hps Hcursor Hsl Hs0 Hs1 Hs2 Hs3 Hs4

The only version invocation in main: four literal author pointers, followed by the pointer-class interpretation of const zero.

1400Definition version_main_args: listword ≔
WPtrstream; WPtrversion_literal"hello#str.70"; WPtrversion_literal"hello#str.63"; WPtrversion_literal"hello#str.71"; WPtrversion_literal"hello#str.72"; WPtrversion_literal"hello#str.73"; WPtrversion_literal"hello#str.74"; WPtrversion_literal"hello#str.75"; WPtrnull

The five pointer cells selected from main's actual snapshot.

1407Definition version_snapshot_cellssb : listpiece × pval ≔
PLivesb, VLivemkRegionsb sb + 80 Heap Live ++ PAuxsb 32, VAuxptr_capversion_literal"hello#str.72" :: cellsb 32 ptr_addrversion_literal"hello#str.72" ++ PAuxsb 40, VAuxptr_capversion_literal"hello#str.73" :: cellsb 40 ptr_addrversion_literal"hello#str.73" ++ PAuxsb 48, VAuxptr_capversion_literal"hello#str.74" :: cellsb 48 ptr_addrversion_literal"hello#str.74" ++ PAuxsb 56, VAuxptr_capversion_literal"hello#str.75" :: cellsb 56 ptr_addrversion_literal"hello#str.75" ++ PAuxsb 64, VAuxCNone :: cellsb 64 0

The selected cells have distinct life, byte, and capability keys.

1420Lemma version_snapshot_cells_nodup
∀ sb
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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Kversion_alloc :
∀size : Z m : mem wd : world h : gmappiece pval base : Z, Insize 24; 80 → freshm heap_req8 size base → wim wd h → wiallocatedm heap_req8 size base wd overwriteobj_psbase heap_req8 size h
Kversion_store :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! k = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
Kversion_cursor :
∀cb : Z cr : region sb off : Z m : mem wd : world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ va_cursor_pscb cr ptr_addr ≔ sb + off; ptr_cap ≔ Rosb → h !! k = Somev → wim wd h → wistore_bytesm cb 8 sb + off + 8 wd overwriteva_cursor_pscb cr ptr_addr ≔ sb + off + 8; ptr_cap ≔ Rosb h
sb :
Z

unfold version_snapshot_cells , cell

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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Kversion_alloc :
∀size : Z m : mem wd : world h : gmappiece pval base : Z, Insize 24; 80 → freshm heap_req8 size base → wim wd h → wiallocatedm heap_req8 size base wd overwriteobj_psbase heap_req8 size h
Kversion_store :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! k = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
Kversion_cursor :
∀cb : Z cr : region sb off : Z m : mem wd : world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ va_cursor_pscb cr ptr_addr ≔ sb + off; ptr_cap ≔ Rosb → h !! k = Somev → wim wd h → wistore_bytesm cb 8 sb + off + 8 wd overwriteva_cursor_pscb cr ptr_addr ≔ sb + off + 8; ptr_cap ≔ Rosb h
sb :
Z
⊢
NoDupPLivesb, VLiver_base ≔ sb; r_end ≔ sb + 80; r_kind ≔ Heap; r_life ≔ Live ++ PAuxsb 32, VAuxptr_capversion_literal"hello#str.72" :: mapλi : Z ⇒ PBytesb 32 + i, VBytebyte_ofptr_addrversion_literal"hello#str.72" i 0; 1; 2; 3; 4; 5; 6; 7 ++ PAuxsb 40, VAuxptr_capversion_literal"hello#str.73" :: mapλi : Z ⇒ PBytesb 40 + i, VBytebyte_ofptr_addrversion_literal"hello#str.73" i 0; 1; 2; 3; 4; 5; 6; 7 ++ PAuxsb 48, VAuxptr_capversion_literal"hello#str.74" :: mapλi : Z ⇒ PBytesb 48 + i, VBytebyte_ofptr_addrversion_literal"hello#str.74" i 0; 1; 2; 3; 4; 5; 6; 7 ++ PAuxsb 56, VAuxptr_capversion_literal"hello#str.75" :: mapλi : Z ⇒ PBytesb 56 + i, VBytebyte_ofptr_addrversion_literal"hello#str.75" i 0; 1; 2; 3; 4; 5; 6; 7 ++ PAuxsb 64, VAuxCNone :: mapλi : Z ⇒ PBytesb 64 + i, VBytebyte_of0 i 0; 1; 2; 3; 4; 5; 6; 7.*1

cbn

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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Kversion_alloc :
∀size : Z m : mem wd : world h : gmappiece pval base : Z, Insize 24; 80 → freshm heap_req8 size base → wim wd h → wiallocatedm heap_req8 size base wd overwriteobj_psbase heap_req8 size h
Kversion_store :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! k = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
Kversion_cursor :
∀cb : Z cr : region sb off : Z m : mem wd : world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ va_cursor_pscb cr ptr_addr ≔ sb + off; ptr_cap ≔ Rosb → h !! k = Somev → wim wd h → wistore_bytesm cb 8 sb + off + 8 wd overwriteva_cursor_pscb cr ptr_addr ≔ sb + off + 8; ptr_cap ≔ Rosb h
sb :
Z
⊢
NoDupPLivesb; PAuxsb 32; PBytesb 32; PBytesb Z.pos32 + 1; PBytesb Z.pos32 + 2; PBytesb Z.pos32 + 3; PBytesb Z.pos32 + 4; PBytesb Z.pos32 + 5; PBytesb Z.pos32 + 6; PBytesb Z.pos32 + 7; PAuxsb 40; PBytesb 40; PBytesb Z.pos40 + 1; PBytesb Z.pos40 + 2; PBytesb Z.pos40 + 3; PBytesb Z.pos40 + 4; PBytesb Z.pos40 + 5; PBytesb Z.pos40 + 6; PBytesb Z.pos40 + 7; PAuxsb 48; PBytesb 48; PBytesb Z.pos48 + 1; PBytesb Z.pos48 + 2; PBytesb Z.pos48 + 3; PBytesb Z.pos48 + 4; PBytesb Z.pos48 + 5; PBytesb Z.pos48 + 6; PBytesb Z.pos48 + 7; PAuxsb 56; PBytesb 56; PBytesb Z.pos56 + 1; PBytesb Z.pos56 + 2; PBytesb Z.pos56 + 3; PBytesb Z.pos56 + 4; PBytesb Z.pos56 + 5; PBytesb Z.pos56 + 6; PBytesb Z.pos56 + 7; PAuxsb 64; PBytesb 64; PBytesb Z.pos64 + 1; PBytesb Z.pos64 + 2; PBytesb Z.pos64 + 3; PBytesb Z.pos64 + 4; PBytesb Z.pos64 + 5; PBytesb Z.pos64 + 6; PBytesb Z.pos64 + 7

repeat constructor ; intros Hin ; repeat apply elem_of_cons in Hin ; destruct Hin as Hin | Hin ; inversion Hin

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
cbn
repeat constructor ; intros Hin ; repeat apply elem_of_cons in Hin ; destruct Hin as Hin | Hin ; inversion Hin

The selected cells are populated by argument indices four through eight of the actual snapshot, not supplied as new initial memory.

1429Lemma version_snapshot_cells_member
Proof 15 steps Qed
destruct lv as l v
rewrite ! elem_of_app
intros Hlive | H0 | H1 | H2 | H3 | H4
–apply elem_of_cons in Hlive as Hlive | Hfalse ; | inversion Hfalse
injection Hlive as → →
apply list_elem_of_fmap
exists PLivesb, VLivemkRegionsb sb + 80 Heap Live
split ; reflexivity | left ; reflexivity
–apply snapshot_ps_pointerversion_main_args 4 version_literal"hello#str.72" ; reflexivity | vm_compute ; congruence | exact H0
–apply snapshot_ps_pointerversion_main_args 5 version_literal"hello#str.73" ; reflexivity | vm_compute ; congruence | exact H1
–apply snapshot_ps_pointerversion_main_args 6 version_literal"hello#str.74" ; reflexivity | vm_compute ; congruence | exact H2
–apply snapshot_ps_pointerversion_main_args 7 version_literal"hello#str.75" ; reflexivity | vm_compute ; congruence | exact H3
–apply snapshot_ps_pointerversion_main_args 8 null ; reflexivity | vm_compute ; congruence | exact H4

Extracting only the used cells discards unused snapshot padding.

1453Lemma version_snapshot_authors
∀ sb
ptssnapshot_psversion_main_args sb heap_req16 72 −∗ livesb mkRegionsb sb + 80 Heap Live ∗ pcellsb 32 version_literal"hello#str.72" ∗ pcellsb 40 version_literal"hello#str.73" ∗ pcellsb 48 version_literal"hello#str.74" ∗ pcellsb 56 version_literal"hello#str.75" ∗ pcellsb 64 null
Proof 9 steps Qed
iIntros Hps
iAssert ptsversion_snapshot_cellssb with [Hps] as Hps
{iApply big_sepL_submseteq with Hps
apply NoDup_submseteq
–apply NoDup_fmap_1fst
iExact Hps

The public variadic wrapper in the linked program.

1470Definition version_etc_fn: func ≔
Eval vm_compute in hello_fn"version_etc"

Its single block constructs a va_list and calls the counting helper.

1472Definition version_start: block ≔
Eval vm_compute in hblkversion_etc_fn "start"

The variadic entry retains every actual argument for Snapshot.

1475Lemma version_etc_entry
Explore proof 1 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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Kversion_alloc :
∀size : Z m : mem wd : world h : gmappiece pval base : Z, Insize 24; 80 → freshm heap_req8 size base → wim wd h → wiallocatedm heap_req8 size base wd overwriteobj_psbase heap_req8 size h
Kversion_store :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! k = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
Kversion_cursor :
∀cb : Z cr : region sb off : Z m : mem wd : world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ va_cursor_pscb cr ptr_addr ≔ sb + off; ptr_cap ≔ Rosb → h !! k = Somev → wim wd h → wistore_bytesm cb 8 sb + off + 8 wd overwriteva_cursor_pscb cr ptr_addr ≔ sb + off + 8; ptr_cap ≔ Rosb h
⊢
invocationversion_etc_fn version_main_args = fr_fn ≔ version_etc_fn; fr_env ≔ TAtom"v6", WPtrversion_literal"hello#str.71"; TAtom"v4", WPtrversion_literal"hello#str.63"; TAtom"v2", WPtrversion_literal"hello#str.70"; TAtom"v0", WPtrstream; fr_locals ≔ [ ]; fr_doomed ≔ None; fr_at ≔ Snapshotversion_main_args TAtom"start"

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
reflexivity

The local va_list begins with one zero pointer cell.

1484Lemma version_cursor_zero
∀ cb
objcb heap_req8 24 −∗ livecb mkRegioncb cb + 32 Heap Live ∗ pcellcb 0 null
Explore proof 5 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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Kversion_alloc :
∀size : Z m : mem wd : world h : gmappiece pval base : Z, Insize 24; 80 → freshm heap_req8 size base → wim wd h → wiallocatedm heap_req8 size base wd overwriteobj_psbase heap_req8 size h
Kversion_store :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! k = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
Kversion_cursor :
∀cb : Z cr : region sb off : Z m : mem wd : world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ va_cursor_pscb cr ptr_addr ≔ sb + off; ptr_cap ≔ Rosb → h !! k = Somev → wim wd h → wistore_bytesm cb 8 sb + off + 8 wd overwriteva_cursor_pscb cr ptr_addr ≔ sb + off + 8; ptr_cap ≔ Rosb h
cb :
Z
⊢
objcb heap_req8 24 −∗ livecb r_base ≔ cb; r_end ≔ cb + 32; r_kind ≔ Heap; r_life ≔ Live ∗ pcellcb 0 null

iIntros Hobj

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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Kversion_alloc :
∀size : Z m : mem wd : world h : gmappiece pval base : Z, Insize 24; 80 → freshm heap_req8 size base → wim wd h → wiallocatedm heap_req8 size base wd overwriteobj_psbase heap_req8 size h
Kversion_store :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! k = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
Kversion_cursor :
∀cb : Z cr : region sb off : Z m : mem wd : world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ va_cursor_pscb cr ptr_addr ≔ sb + off; ptr_cap ≔ Rosb → h !! k = Somev → wim wd h → wistore_bytesm cb 8 sb + off + 8 wd overwriteva_cursor_pscb cr ptr_addr ≔ sb + off + 8; ptr_cap ≔ Rosb h
cb :
Z
Hobj :
∗
livecb r_base ≔ cb; r_end ≔ cb + 32; r_kind ≔ Heap; r_life ≔ Live ∗ pcellcb 0 null

iDestruct obj_zero_block with Hobj as (Hl & Hx & Ha) ; compute ; discriminate |

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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Kversion_alloc :
∀size : Z m : mem wd : world h : gmappiece pval base : Z, Insize 24; 80 → freshm heap_req8 size base → wim wd h → wiallocatedm heap_req8 size base wd overwriteobj_psbase heap_req8 size h
Kversion_store :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! k = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
Kversion_cursor :
∀cb : Z cr : region sb off : Z m : mem wd : world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ va_cursor_pscb cr ptr_addr ≔ sb + off; ptr_cap ≔ Rosb → h !! k = Somev → wim wd h → wistore_bytesm cb 8 sb + off + 8 wd overwriteva_cursor_pscb cr ptr_addr ≔ sb + off + 8; ptr_cap ≔ Rosb h
cb :
Z
Hl :
HelloVersionOn.ML.LG.livecb r_base ≔ cb; r_end ≔ cb + req_extentheap_req8 24; r_kind ≔ req_kindheap_req8 24; r_life ≔ Live
Hx :
bytescb 0 replicateZ.to_natreq_extentheap_req8 24 0
Ha :
auxescb 0 replicateZ.to_natreq_extentheap_req8 24 CNone
∗
livecb r_base ≔ cb; r_end ≔ cb + 32; r_kind ≔ Heap; r_life ≔ Live ∗ pcellcb 0 null

iSplitL Hl ; iExact Hl |

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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Kversion_alloc :
∀size : Z m : mem wd : world h : gmappiece pval base : Z, Insize 24; 80 → freshm heap_req8 size base → wim wd h → wiallocatedm heap_req8 size base wd overwriteobj_psbase heap_req8 size h
Kversion_store :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! k = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
Kversion_cursor :
∀cb : Z cr : region sb off : Z m : mem wd : world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ va_cursor_pscb cr ptr_addr ≔ sb + off; ptr_cap ≔ Rosb → h !! k = Somev → wim wd h → wistore_bytesm cb 8 sb + off + 8 wd overwriteva_cursor_pscb cr ptr_addr ≔ sb + off + 8; ptr_cap ≔ Rosb h
cb :
Z
Hx :
bytescb 0 replicateZ.to_natreq_extentheap_req8 24 0
Ha :
auxescb 0 replicateZ.to_natreq_extentheap_req8 24 CNone
∗

iDestruct version_zero_cell_prefixcb 0 24 with Hx Ha as (Hc & _ & _)

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 :
Hlinked :
stream :
literal_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ literal_ps
version_spec :
name → contractworld
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ literal_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Kversion_alloc :
∀size : Z m : mem wd : world h : gmappiece pval base : Z, Insize 24; 80 → freshm heap_req8 size base → wim wd h → wiallocatedm heap_req8 size base wd overwriteobj_psbase heap_req8 size h
Kversion_store :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! k = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
Kversion_cursor :
∀cb : Z cr : region sb off : Z m : mem wd : world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ va_cursor_pscb cr ptr_addr ≔ sb + off; ptr_cap ≔ Rosb → h !! k = Somev → wim wd h → wistore_bytesm cb 8 sb + off + 8 wd overwriteva_cursor_pscb cr ptr_addr ≔ sb + off + 8; ptr_cap ≔ Rosb h
cb :
Z
Hc :
∗

iExact Hc

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
iIntros Hobj
iDestruct obj_zero_block with Hobj as (Hl & Hx & Ha) ; compute ; discriminate |
iSplitL Hl ; iExact Hl |
iDestruct version_zero_cell_prefixcb 0 24 with Hx Ha as (Hc & _ & _)
iExact Hc

Snapshot population preserves the same opaque world under the already proved fresh-object and exact-store frame facts.

1496Context Kversion_snapshot : ∀m wd h sb, freshm heap_req16 72 sb → wim wd h → wisnapshot_valuesversion_main_args sb allocatedm heap_req16 72 sb wd overwritesnapshot_psversion_main_args sb heap_req16 72 h

Main can apply this triple directly after the four proper_name identities. The snapshot and the counting loop derive the count; neither the count nor the array contents are caller premises.

1504Lemma version_etc_spec
∀ Φ
Proof 48 steps Qed
iIntros Hps HK
iApply wp_snapshot ; discriminate | reflexivity | exact Kversion_snapshot |
iNext
iIntros sb Hsb Hsmod Hsend Hsnapshot
change sb mod 16 = 0 in Hsmod
change sb + 80 ≤ 2 ^ 48 in Hsend
iDestruct version_snapshot_authors with Hsnapshot as (Hsl & Hs0 & Hs1 & Hs2 & Hs3 & Hs4)
iApply wp_enter ; vm_compute ; reflexivity | reflexivity |
iNext
iApply wp_alloc_ _ _ _ _ _ _ _ _ _ _ _ _ 24 ; reflexivity | lia | unfold max_allocation_size ; lia | intros m wd h base Hf Hw ; apply Kversion_alloc ; simpl ; tauto | exact Hf | exact Hw |
iNext
iIntros cb Hcb Hcmod Hcend Hobj
change cb mod 16 = 0 in Hcmod
change cb + 32 ≤ 2 ^ 48 in Hcend
assert Hc8 : cb mod 8 = 0
{apply Z.mod_divide ; lia |
apply Z.divide_trans8 16 cb
–exists 2
reflexivity
–apply Z.mod_divide ; lia | exact Hcmod
iDestruct version_cursor_zero with Hobj as [Hcl Hc]
iApply wp_va_args ; reflexivity |
iNext
iApply wp_check with Hcl ; reflexivity | word_premise | reflexivity | addr_premise | cbn [ r_end ] ; addr_premise | addr_premise |
iNext
iIntros Hcl
iApply wp_raw_store_pointer with Hcl Hc ; word_premise | word_premise | reflexivity | addr_premise | addr_premise | apply Kversion_store |
iNext
iIntros Hcl Hc
assert Hwrap : sb + 32 mod 2 ^ 64 = sb + 32 by apply Z.mod_small ; lia
iEval cbn [ ptr_addr ] ; rewrite Hwrap in Hc
iAssert ptsva_cursor_pscb mkRegioncb cb + 32 Heap Live mkPtrsb + 32 Rosb with [Hcl Hc] as Hcursor
{replace va_cursor_pscb mkRegioncb cb + 32 Heap Live mkPtrsb + 32 Rosb with PLivecb, VLivemkRegioncb cb + 32 Heap Live ++ PAuxcb 0, VAuxRosb :: cellcb 0 sb + 32 by reflexivity
rewrite pts_app
iFrame Hcl Hc
iApply wp_call_bind_ _ _ _ _ _ _ _ _ _ _ _ _ version_etc_va_fn invocationversion_etc_va_fn WPtrstream; WPtrversion_literal"hello#str.70"; WPtrversion_literal"hello#str.63"; WPtrversion_literal"hello#str.71"; WPtrmkPtrcb Objcb ; word_premise | unfold find_fn ; rewrite proj1Hlinked ; vm_compute ; reflexivity | reflexivity |
iNext
iApply version_etc_va_spec with Hps Hcursor Hsl Hs0 Hs1 Hs2 Hs3 Hs4 ; exact Hc8 | exact Hsb | exact Hsmod | cbn [ r_end ] ; lia | cbn [ r_end ] ; lia |
iNext
iIntros Hps Hcursor Hsl Hs0 Hs1 Hs2 Hs3 Hs4
iExists _
iSplit ; iPureIntro ; reflexivity |
iNext
iNext
iApply HK with Hps

HelloVersionOn over a Logic instance of its own.

1562Module HelloVersion R : Runtime
1563Module LG0 ≔ Logic R
Include HelloVersionOn R LG0