Fil-C on Nix

Filnix wiki

the formal campaign

rocq/theories/Startup.v

The Fil-C launcher's entry contract, before libc calls main (milestone 3a).

The pinned filc_start_program.c copies argv and environ into fresh capability-bearing objects. Pointer arrays include a null sentinel; strings include an in-object first NUL. Lengths and contents are not restricted to the native probes. The launcher asserts argc >= 1.

These are concrete predicates on model memory, not new runtime axioms or a proof of the native launcher. Establishing the full entry image from startup allocations, including libc/TLS and finalizer roots, remains a separate obligation. Resource refusal before entry must not be confused with a malformed entry or deleted execution.

From Stdlib Require Import String ZArith List Bool Lia
From Nanofil Require Import Term Syntax Values Memory Runtime Ops Semantics Run Machine Identity ExternalCalls ExternalMachine
Import ListNotations
Open Scope Z_scope

The eight-byte cell at address a of memory m holds pointer p: its bytes read as p's address and its aux entry is p's capability. A slot carries address bits AND the corresponding capability. Bounding the address below 2^64 prevents an integer outside the word range from standing for the same stored bytes.

26Definition pointer_slotm : mem a : Z p : ptr : Prop ≔
0 ≤ ptr_addrp < 2 ^ 64 ∧ load_bytesm a 8 = ptr_addrp ∧ m_auxm a = ptr_capp

The same address/aux store used by store_res constructs an actual decoded slot. No access or capability authority is inferred here; local_store_pointer supplies the separate footprint obligation.

33Lemma pointer_slot_written
∀ m a p
0 ≤ ptr_addrp < 2 ^ 64
Explore proof 10 tactics

Initial goal

⊢
∀m : mem a : Z p : ptr, 0 ≤ ptr_addrp < 2 ^ 64 → pointer_slotstore_auxstore_bytesm a 8 ptr_addrp a ptr_capp a p

intros m a p Hp

m :
a :
Z
p :
Hp :
0 ≤ ptr_addrp < 2 ^ 64

split ; exact Hp |

m :
a :
Z
p :
Hp :
0 ≤ ptr_addrp < 2 ^ 64

split

2 open

m :
a :
Z
p :
Hp :
0 ≤ ptr_addrp < 2 ^ 64
focused goal
m :
a :
Z
p :
Hp :
0 ≤ ptr_addrp < 2 ^ 64

–change load_bytesstore_bytesm a 8 ptr_addrp a 8 = ptr_addrp

2 open

m :
a :
Z
p :
Hp :
0 ≤ ptr_addrp < 2 ^ 64
deferred goal
m :
a :
Z
p :
Hp :
0 ≤ ptr_addrp < 2 ^ 64

rewrite stored_bytes_value by lia

2 open

m :
a :
Z
p :
Hp :
0 ≤ ptr_addrp < 2 ^ 64
⊢
ptr_addrp mod 256 ^ 8 = ptr_addrp
deferred goal
m :
a :
Z
p :
Hp :
0 ≤ ptr_addrp < 2 ^ 64

apply Z.mod_small

2 open

m :
a :
Z
p :
Hp :
0 ≤ ptr_addrp < 2 ^ 64
⊢
0 ≤ ptr_addrp < 256 ^ 8
deferred goal
m :
a :
Z
p :
Hp :
0 ≤ ptr_addrp < 2 ^ 64

exact Hp

deferred goal
m :
a :
Z
p :
Hp :
0 ≤ ptr_addrp < 2 ^ 64

–simpl

m :
a :
Z
p :
Hp :
0 ≤ ptr_addrp < 2 ^ 64
⊢
a =? a
→
else
=

rewrite Z.eqb_refl

m :
a :
Z
p :
Hp :
0 ≤ ptr_addrp < 2 ^ 64

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m a p Hp
split ; exact Hp |
split
–change load_bytesstore_bytesm a 8 ptr_addrp a 8 = ptr_addrp
rewrite stored_bytes_value by lia
apply Z.mod_small
exact Hp
–simpl
rewrite Z.eqb_refl
reflexivity

A byte store of size bytes at address a keeps a pointer_slot at b that it does not overlap.

45Lemma pointer_slot_bytes_disjoint
∀ m a size x b p
0 ≤ size
b + 8 ≤ a ∨ a + size ≤ b
Explore proof 12 tactics

Initial goal

⊢
∀m : mem a size x b : Z p : ptr, 0 ≤ size → b + 8 ≤ a ∨ a + size ≤ b → pointer_slotm b p → pointer_slotstore_bytesm a size x b p

intros m a size x b p Hsize Hdis Hp Hbytes Haux

m :
a, size, x, b :
Z
p :
Hsize :
0 ≤ size
Hdis :
b + 8 ≤ a ∨ a + size ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm b = ptr_capp
⊢

split ; exact Hp |

m :
a, size, x, b :
Z
p :
Hsize :
0 ≤ size
Hdis :
b + 8 ≤ a ∨ a + size ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm b = ptr_capp
⊢
load_bytesstore_bytesm a size x b 8 = ptr_addrp ∧ m_auxstore_bytesm a size x b = ptr_capp

split ; | exact Haux

m :
a, size, x, b :
Z
p :
Hsize :
0 ≤ size
Hdis :
b + 8 ≤ a ∨ a + size ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm b = ptr_capp
⊢

rewrite <- Hbytes

m :
a, size, x, b :
Z
p :
Hsize :
0 ≤ size
Hdis :
b + 8 ≤ a ∨ a + size ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm b = ptr_capp
⊢
load_bytesstore_bytesm a size x b 8 = load_bytesm b 8

apply load_bytes_agree ; lia |

m :
a, size, x, b :
Z
p :
Hsize :
0 ≤ size
Hdis :
b + 8 ≤ a ∨ a + size ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm b = ptr_capp
⊢
∀i : Z, 0 ≤ i < 8 → m_bytesstore_bytesm a size x b + i = m_bytesm b + i

intros i Hi

m :
a, size, x, b :
Z
p :
Hsize :
0 ≤ size
Hdis :
b + 8 ≤ a ∨ a + size ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm b = ptr_capp
i :
Z
Hi :
0 ≤ i < 8
⊢
m_bytesstore_bytesm a size x b + i = m_bytesm b + i

simpl

m :
a, size, x, b :
Z
p :
Hsize :
0 ≤ size
Hdis :
b + 8 ≤ a ∨ a + size ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm b = ptr_capp
i :
Z
Hi :
0 ≤ i < 8
⊢
a ≤? b + i && b + i <? a + size
→
byte_ofx b + i − a
else
m_bytesm b + i
=
m_bytesm b + i

destruct a ≤? b + i && b + i <? a + size eqn: E ; | reflexivity

m :
a, size, x, b :
Z
p :
Hsize :
0 ≤ size
Hdis :
b + 8 ≤ a ∨ a + size ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm b = ptr_capp
i :
Z
Hi :
0 ≤ i < 8
E :
a ≤? b + i && b + i <? a + size = true
⊢
byte_ofx b + i − a = m_bytesm b + i

apply andb_true_iff in E as E1 E2

m :
a, size, x, b :
Z
p :
Hsize :
0 ≤ size
Hdis :
b + 8 ≤ a ∨ a + size ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm b = ptr_capp
i :
Z
Hi :
0 ≤ i < 8
E1 :
a ≤? b + i = true
E2 :
b + i <? a + size = true
⊢
byte_ofx b + i − a = m_bytesm b + i

apply Z.leb_le in E1

m :
a, size, x, b :
Z
p :
Hsize :
0 ≤ size
Hdis :
b + 8 ≤ a ∨ a + size ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm b = ptr_capp
i :
Z
Hi :
0 ≤ i < 8
E1 :
a ≤ b + i
E2 :
b + i <? a + size = true
⊢
byte_ofx b + i − a = m_bytesm b + i

apply Z.ltb_lt in E2

m :
a, size, x, b :
Z
p :
Hsize :
0 ≤ size
Hdis :
b + 8 ≤ a ∨ a + size ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm b = ptr_capp
i :
Z
Hi :
0 ≤ i < 8
E1 :
a ≤ b + i
E2 :
b + i < a + size
⊢
byte_ofx b + i − a = m_bytesm b + i

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m a size x b p Hsize Hdis Hp Hbytes Haux
split ; exact Hp |
split ; | exact Haux
rewrite <- Hbytes
apply load_bytes_agree ; lia |
intros i Hi
simpl
destruct a ≤? b + i && b + i <? a + size eqn: E ; | reflexivity
apply andb_true_iff in E as E1 E2
apply Z.leb_le in E1
apply Z.ltb_lt in E2
lia

A pointer store at address a keeps a pointer_slot at b eight or more bytes away.

57Lemma pointer_slot_pointer_disjoint
∀ m a p b q
b + 8 ≤ a ∨ a + 8 ≤ b
Explore proof 8 tactics

Initial goal

⊢
∀m : mem a : Z p : ptr b : Z q : ptr, b + 8 ≤ a ∨ a + 8 ≤ b → pointer_slotm b q → pointer_slotstore_auxstore_bytesm a 8 ptr_addrp a ptr_capp b q

intros m a p b q Hdis Hslot

m :
a :
Z
p :
b :
Z
q :
Hdis :
b + 8 ≤ a ∨ a + 8 ≤ b
Hslot :

destruct pointer_slot_bytes_disjointm a 8 ptr_addrp b q ltac:lia Hdis Hslot as Hq Hbytes Haux

m :
a :
Z
p :
b :
Z
q :
Hdis :
b + 8 ≤ a ∨ a + 8 ≤ b
Hslot :
Hq :
0 ≤ ptr_addrq < 2 ^ 64

split ; exact Hq |

m :
a :
Z
p :
b :
Z
q :
Hdis :
b + 8 ≤ a ∨ a + 8 ≤ b
Hslot :
Hq :
0 ≤ ptr_addrq < 2 ^ 64

split ; exact Hbytes |

m :
a :
Z
p :
b :
Z
q :
Hdis :
b + 8 ≤ a ∨ a + 8 ≤ b
Hslot :
Hq :
0 ≤ ptr_addrq < 2 ^ 64

simpl

m :
a :
Z
p :
b :
Z
q :
Hdis :
b + 8 ≤ a ∨ a + 8 ≤ b
Hslot :
Hq :
0 ≤ ptr_addrq < 2 ^ 64
⊢
b =? a
→
else
=

assert b =? a = false as E by apply Z.eqb_neq ; lia

m :
a :
Z
p :
b :
Z
q :
Hdis :
b + 8 ≤ a ∨ a + 8 ≤ b
Hslot :
Hq :
0 ≤ ptr_addrq < 2 ^ 64
E :
b =? a = false
⊢
b =? a
→
else
=

rewrite E

m :
a :
Z
p :
b :
Z
q :
Hdis :
b + 8 ≤ a ∨ a + 8 ≤ b
Hslot :
Hq :
0 ≤ ptr_addrq < 2 ^ 64
E :
b =? a = false
⊢
m_auxm b = ptr_capq

exact Haux

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m a p b q Hdis Hslot
destruct pointer_slot_bytes_disjointm a 8 ptr_addrp b q ltac:lia Hdis Hslot as Hq Hbytes Haux
split ; exact Hq |
split ; exact Hbytes |
simpl
assert b =? a = false as E by apply Z.eqb_neq ; lia
rewrite E
exact Haux

From address a on, memory m holds one pointer_slot per text, each pointing at a c_string with that text, then a null slot.

70Fixpoint string_slotsm : mem a : Z texts : listlistZ : Prop ≔
match texts with
text :: rest
⇒
∃p, pointer_slotm a p ∧ c_stringm p text ∧ string_slotsm a + 8 rest

Pointer table points at a null-terminated array of C strings with the given texts, as argv and envp are. Check the entire pointer array, including its sentinel, with the array's capability and pointer alignment. A raw address whose aux metadata was lost does not satisfy the string slots.

82Definition string_vectorm : mem table : ptr texts : listlistZ : Prop ≔
access_resm ptr_addrtable ptr_captable 8 × Z.of_natlengthtexts + 1 Read 8 = Someok ∧ string_slotsm ptr_addrtable texts

Memory m is the launcher's entry image for main's arguments argc, argv and envp, with argument strings args and environment strings environment: argc is a positive int counting args, and argv and envp are string_vectors of them.

91Definition startup_atm : mem argc : Z argv envp : ptr args environment : listlistZ : Prop ≔
1 ≤ argc < 2 ^ 31 ∧ argc = Z.of_natlengthargs ∧ string_vectorm argv args ∧ string_vectorm envp environment

A libc-exposed pointer cell has its own writable object authority and decoded value. Authority to its pointee is not authority to change the cell, nor does this predicate establish FILE validity.

99Definition exposed_pointer_cellm : mem cell value : ptr : Prop ≔
writable_spanm mkSpancell 8 ∧ access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok ∧ access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok ∧ pointer_slotm ptr_addrcell value

Distinct symbolic roles, not an assertion that their storage is disjoint. The program-name aliases may name the same native cells.

107Record libc_global_cells: Type ≔ mkLibcGlobalCells
stdout_cell
 : ptr
stderr_cell
 : ptr
invocation_name_cell
 : ptr
short_name_cell
 : ptr

Symbol resolution reaches the cells themselves, not the FILE or character buffer stored in them. Module linking supplies this map.

116Definition libc_globals_boundge : genv g : libc_global_cells : Prop ≔
lookupTAtom"stdout" ge_globalsge = Somestdout_cellg ∧ lookupTAtom"stderr" ge_globalsge = Somestderr_cellg ∧ lookupTAtom"program_invocation_name" ge_globalsge = Someinvocation_name_cellg ∧ lookupTAtom"program_invocation_short_name" ge_globalsge = Someshort_name_cellg

Concrete exposed cells at a successful entry. Program names have independently readable NUL-terminated contents; they are not silently identified with the launcher's copied argv0. Program code may subsequently replace their pointer values. Stream object validity, libc/TLS state and separation remain separate premises.

127Definition libc_globals_atm : mem g : libc_global_cells out err full short : ptr : Prop ≔
exposed_pointer_cellm stdout_cellg out ∧ exposed_pointer_cellm stderr_cellg err ∧ exposed_pointer_cellm invocation_name_cellg full ∧ exposed_pointer_cellm short_name_cellg short ∧ ∃bytes, c_stringm full bytes ∧ ∃bytes, c_stringm short bytes

The ordinary non-atomic pointer-load protocol recovers exactly the stored address AND capability, not an external/null surrogate.

137Lemma exposed_pointer_load
∀ m cell value
Explore proof 5 tactics

Initial goal

⊢
∀m : mem cell value : ptr, exposed_pointer_cellm cell value → pointer_load_effectsm ptr_addrcell AuxRead; LowerResolve; AddressRead = Somevalue

intros m cell a c _ & _ & _ & _ & Hbytes & Haux

m :
cell :
a :
Z
c :
Hbytes :
load_bytesm ptr_addrcell 8 = ptr_addrptr_addr ≔ a; ptr_cap ≔ c
Haux :
m_auxm ptr_addrcell = ptr_capptr_addr ≔ a; ptr_cap ≔ c

unfold pointer_load_effects , pointer_load_effect , aux_at

m :
cell :
a :
Z
c :
Hbytes :
load_bytesm ptr_addrcell 8 = ptr_addrptr_addr ≔ a; ptr_cap ≔ c
Haux :
m_auxm ptr_addrcell = ptr_capptr_addr ≔ a; ptr_cap ≔ c
⊢
let* st ≔
fold_left
λ st : optioncap × ptr e : effect  ⇒
match st with
Somec0, p
⇒
match e with
⇒
Somec0, ptr_addr ≔ ptr_addrp; ptr_cap ≔ c0
⇒
Somec0, ptr_addr ≔ load_bytesm ptr_addrcell 8; ptr_cap ≔ ptr_capp
_
⇒
None
None
⇒
None
SomeCNone, ptr_addr ≔ 0; ptr_cap ≔ CNone
in
Somesndst
=
Someptr_addr ≔ a; ptr_cap ≔ c

simpl

m :
cell :
a :
Z
c :
Hbytes :
load_bytesm ptr_addrcell 8 = ptr_addrptr_addr ≔ a; ptr_cap ≔ c
Haux :
m_auxm ptr_addrcell = ptr_capptr_addr ≔ a; ptr_cap ≔ c
⊢
Someptr_addr ≔ load_bytesm ptr_addrcell 8; ptr_cap ≔ m_auxm ptr_addrcell = Someptr_addr ≔ a; ptr_cap ≔ c

rewrite Hbytes , Haux

m :
cell :
a :
Z
c :
Hbytes :
load_bytesm ptr_addrcell 8 = ptr_addrptr_addr ≔ a; ptr_cap ≔ c
Haux :
m_auxm ptr_addrcell = ptr_capptr_addr ≔ a; ptr_cap ≔ c
⊢
Someptr_addr ≔ ptr_addrptr_addr ≔ a; ptr_cap ≔ c; ptr_cap ≔ ptr_capptr_addr ≔ a; ptr_cap ≔ c = Someptr_addr ≔ a; ptr_cap ≔ c

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m cell a c _ & _ & _ & _ & Hbytes & Haux
simpl
rewrite Hbytes , Haux
reflexivity

The three words the launcher passes to main: argc, argv, envp.

147Definition main_argumentsargc : Z argv envp : ptr : listword ≔
WIntargc; WPtrargv; WPtrenvp

Hello's two-parameter main binds the first two launcher words and ignores the extra environment word. This gives its actual fresh frame, without restricting the strings or resetting runtime state.

153Lemma main_argv_frame
∀ f b blocks argc_name argv_name argc argv envp
fn_paramsf = W, argc_name; P, argv_name
fn_blocksf = b :: blocks
variadic_funcf = false
call_framef main_argumentsargc argv envp = SomemkFramef putargv_name WPtrargv putargc_name WIntargc [ ] mapλxs ⇒ fstxs, None local_objectsf None Enterb_labelb None
Explore proof 4 tactics

Initial goal

⊢
∀f : func b : block blocks : listblock argc_name argv_name : name argc : Z argv envp : ptr, fn_paramsf = W, argc_name; P, argv_name → fn_blocksf = b :: blocks → variadic_funcf = false → call_framef main_argumentsargc argv envp = Somefr_fn ≔ f; fr_env ≔ putargv_name WPtrargv putargc_name WIntargc [ ]; fr_locals ≔ mapλxs : name × Z ⇒ fstxs, None local_objectsf; fr_doomed ≔ None; fr_at ≔ Enterb_labelb None

intros f b blocks an vn argc argv envp Hp Hb Hv

f :
blocks :
listblock
an, vn :
argc :
Z
argv, envp :
Hp :
fn_paramsf = W, an; P, vn
Hb :
fn_blocksf = b :: blocks
Hv :
variadic_funcf = false
⊢
call_framef main_argumentsargc argv envp = Somefr_fn ≔ f; fr_env ≔ putvn WPtrargv putan WIntargc [ ]; fr_locals ≔ mapλxs : name × Z ⇒ fstxs, None local_objectsf; fr_doomed ≔ None; fr_at ≔ Enterb_labelb None

unfold call_frame

f :
blocks :
listblock
an, vn :
argc :
Z
argv, envp :
Hp :
fn_paramsf = W, an; P, vn
Hb :
fn_blocksf = b :: blocks
Hv :
variadic_funcf = false
⊢
Datatypes.lengthmain_argumentsargc argv envp <? Datatypes.lengthfn_paramsf%nat
→
None
else
match fn_blocksf with
[ ]
⇒
None
b0 :: _
⇒
Somefr_fn ≔ f; fr_env ≔ fold_leftλe : listname × word px : class × name × word ⇒ putsndfstpx sndpx e combinefn_paramsf firstnDatatypes.lengthfn_paramsf main_argumentsargc argv envp [ ]; fr_locals ≔ mapλxs : name × Z ⇒ fstxs, None local_objectsf; fr_doomed ≔ None; fr_at ≔ if variadic_funcf then Snapshotmain_argumentsargc argv envp b_labelb0 else Enterb_labelb0 None
=
Somefr_fn ≔ f; fr_env ≔ putvn WPtrargv putan WIntargc [ ]; fr_locals ≔ mapλxs : name × Z ⇒ fstxs, None local_objectsf; fr_doomed ≔ None; fr_at ≔ Enterb_labelb None

rewrite Hp , Hb , Hv

f :
blocks :
listblock
an, vn :
argc :
Z
argv, envp :
Hp :
fn_paramsf = W, an; P, vn
Hb :
fn_blocksf = b :: blocks
Hv :
variadic_funcf = false
⊢
Datatypes.lengthmain_argumentsargc argv envp <? Datatypes.lengthW, an; P, vn%nat
→
None
else
Somefr_fn ≔ f; fr_env ≔ fold_leftλe : listname × word px : class × name × word ⇒ putsndfstpx sndpx e combineW, an; P, vn firstnDatatypes.lengthW, an; P, vn main_argumentsargc argv envp [ ]; fr_locals ≔ mapλxs : name × Z ⇒ fstxs, None local_objectsf; fr_doomed ≔ None; fr_at ≔ Enterb_labelb None
=
Somefr_fn ≔ f; fr_env ≔ putvn WPtrargv putan WIntargc [ ]; fr_locals ≔ mapλxs : name × Z ⇒ fstxs, None local_objectsf; fr_doomed ≔ None; fr_at ≔ Enterb_labelb None

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros f b blocks an vn argc argv envp Hp Hb Hv
unfold call_frame
rewrite Hp , Hb , Hv
reflexivity

The byte size of the launcher's argv copy, 8 * (argc + 1). The native expression argc + 1 is evaluated as int BEFORE the checked size multiplication. Readable entry and successful copying are distinct: INT_MAX is an ABI value but overflows that expression.

167Definition argv_copy_sizeargc : Z : Z ≔
8 × argc + 1

For argc from 1 below INT_MAX (2^31 - 1), argc + 1 does not overflow int and the copy size is a positive legal allocation size (max_allocation_size).

172Lemma argv_copy_bounds
∀ argc
1 ≤ argc < 2 ^ 31 − 1
0 < argc + 1 < 2 ^ 31 ∧ 0 < argv_copy_sizeargc ≤ max_allocation_size
Explore proof 3 tactics

Initial goal

⊢
∀argc : Z, 1 ≤ argc < 2 ^ 31 − 1 → 0 < argc + 1 < 2 ^ 31 ∧ 0 < argv_copy_sizeargc ≤ max_allocation_size

intros argc H

argc :
Z
H :
1 ≤ argc < 2 ^ 31 − 1
⊢
0 < argc + 1 < 2 ^ 31 ∧ 0 < argv_copy_sizeargc ≤ max_allocation_size

unfold argv_copy_size , max_allocation_size

argc :
Z
H :
1 ≤ argc < 2 ^ 31 − 1
⊢
0 < argc + 1 < 2 ^ 31 ∧ 0 < 8 × argc + 1 ≤ 2 ^ 48 − 1

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros argc H
lia

If string_slots holds from a, the slot of the i-th text, at a + 8 * i, points at a C string with that text.

179Lemma string_slots_nth
∀ m texts a i text
string_slotsm a texts
nth_errortexts i = Sometext
∃p, pointer_slotm a + 8 × Z.of_nati p ∧ c_stringm p text
Explore proof 13 tactics

Initial goal

⊢
∀m : mem texts : listlistZ a : Z i : nat text : listZ, string_slotsm a texts → nth_errortexts i = Sometext → ∃p : ptr, pointer_slotm a + 8 × Z.of_nati p ∧ c_stringm p text

intros m texts

m :
texts :
listlistZ
⊢
∀a : Z i : nat text : listZ, string_slotsm a texts → nth_errortexts i = Sometext → ∃p : ptr, pointer_slotm a + 8 × Z.of_nati p ∧ c_stringm p text

induction texts as | head rest IH ; intros a i text Hslots Hi

2 open

m :
a :
Z
i :
nat
text :
listZ
Hslots :
Hi :
nth_error[ ] i = Sometext
⊢
∃p : ptr, pointer_slotm a + 8 × Z.of_nati p ∧ c_stringm p text
focused goal
m :
head :
listZ
rest :
listlistZ
IH :
∀a : Z i : nat text : listZ, string_slotsm a rest → nth_errorrest i = Sometext → ∃p : ptr, pointer_slotm a + 8 × Z.of_nati p ∧ c_stringm p text
a :
Z
i :
nat
text :
listZ
Hslots :
string_slotsm a head :: rest
Hi :
nth_errorhead :: rest i = Sometext
⊢
∃p : ptr, pointer_slotm a + 8 × Z.of_nati p ∧ c_stringm p text

–destruct i ; discriminate Hi

deferred goal
m :
head :
listZ
rest :
listlistZ
IH :
∀a : Z i : nat text : listZ, string_slotsm a rest → nth_errorrest i = Sometext → ∃p : ptr, pointer_slotm a + 8 × Z.of_nati p ∧ c_stringm p text
a :
Z
i :
nat
text :
listZ
Hslots :
string_slotsm a head :: rest
Hi :
nth_errorhead :: rest i = Sometext
⊢
∃p : ptr, pointer_slotm a + 8 × Z.of_nati p ∧ c_stringm p text

–destruct Hslots as p & Hp & Hs & Hrest

m :
head :
listZ
rest :
listlistZ
IH :
∀a : Z i : nat text : listZ, string_slotsm a rest → nth_errorrest i = Sometext → ∃p : ptr, pointer_slotm a + 8 × Z.of_nati p ∧ c_stringm p text
a :
Z
i :
nat
text :
listZ
p :
Hp :
Hs :
c_stringm p head
Hrest :
string_slotsm a + 8 rest
Hi :
nth_errorhead :: rest i = Sometext
⊢
∃p0 : ptr, pointer_slotm a + 8 × Z.of_nati p0 ∧ c_stringm p0 text

destruct i as | i

2 open

m :
head :
listZ
rest :
listlistZ
IH :
∀a : Z i : nat text : listZ, string_slotsm a rest → nth_errorrest i = Sometext → ∃p : ptr, pointer_slotm a + 8 × Z.of_nati p ∧ c_stringm p text
a :
Z
text :
listZ
p :
Hp :
Hs :
c_stringm p head
Hrest :
string_slotsm a + 8 rest
Hi :
nth_errorhead :: rest 0 = Sometext
⊢
∃p0 : ptr, pointer_slotm a + 8 × Z.of_nat0 p0 ∧ c_stringm p0 text
focused goal
m :
head :
listZ
rest :
listlistZ
IH :
∀a : Z i : nat text : listZ, string_slotsm a rest → nth_errorrest i = Sometext → ∃p : ptr, pointer_slotm a + 8 × Z.of_nati p ∧ c_stringm p text
a :
Z
i :
nat
text :
listZ
p :
Hp :
Hs :
c_stringm p head
Hrest :
string_slotsm a + 8 rest
Hi :
nth_errorhead :: rest Si = Sometext
⊢
∃p0 : ptr, pointer_slotm a + 8 × Z.of_natSi p0 ∧ c_stringm p0 text

+injection Hi as ←

2 open

m :
head :
listZ
rest :
listlistZ
IH :
∀a : Z i : nat text : listZ, string_slotsm a rest → nth_errorrest i = Sometext → ∃p : ptr, pointer_slotm a + 8 × Z.of_nati p ∧ c_stringm p text
a :
Z
p :
Hp :
Hs :
c_stringm p head
Hrest :
string_slotsm a + 8 rest
⊢
∃p0 : ptr, pointer_slotm a + 8 × Z.of_nat0 p0 ∧ c_stringm p0 head
deferred goal
m :
head :
listZ
rest :
listlistZ
IH :
∀a : Z i : nat text : listZ, string_slotsm a rest → nth_errorrest i = Sometext → ∃p : ptr, pointer_slotm a + 8 × Z.of_nati p ∧ c_stringm p text
a :
Z
i :
nat
text :
listZ
p :
Hp :
Hs :
c_stringm p head
Hrest :
string_slotsm a + 8 rest
Hi :
nth_errorhead :: rest Si = Sometext
⊢
∃p0 : ptr, pointer_slotm a + 8 × Z.of_natSi p0 ∧ c_stringm p0 text

replace a + 8 × Z.of_nat0 with a by lia

2 open

m :
head :
listZ
rest :
listlistZ
IH :
∀a : Z i : nat text : listZ, string_slotsm a rest → nth_errorrest i = Sometext → ∃p : ptr, pointer_slotm a + 8 × Z.of_nati p ∧ c_stringm p text
a :
Z
p :
Hp :
Hs :
c_stringm p head
Hrest :
string_slotsm a + 8 rest
⊢
∃p0 : ptr, pointer_slotm a p0 ∧ c_stringm p0 head
deferred goal
m :
head :
listZ
rest :
listlistZ
IH :
∀a : Z i : nat text : listZ, string_slotsm a rest → nth_errorrest i = Sometext → ∃p : ptr, pointer_slotm a + 8 × Z.of_nati p ∧ c_stringm p text
a :
Z
i :
nat
text :
listZ
p :
Hp :
Hs :
c_stringm p head
Hrest :
string_slotsm a + 8 rest
Hi :
nth_errorhead :: rest Si = Sometext
⊢
∃p0 : ptr, pointer_slotm a + 8 × Z.of_natSi p0 ∧ c_stringm p0 text

eauto

deferred goal
m :
head :
listZ
rest :
listlistZ
IH :
∀a : Z i : nat text : listZ, string_slotsm a rest → nth_errorrest i = Sometext → ∃p : ptr, pointer_slotm a + 8 × Z.of_nati p ∧ c_stringm p text
a :
Z
i :
nat
text :
listZ
p :
Hp :
Hs :
c_stringm p head
Hrest :
string_slotsm a + 8 rest
Hi :
nth_errorhead :: rest Si = Sometext
⊢
∃p0 : ptr, pointer_slotm a + 8 × Z.of_natSi p0 ∧ c_stringm p0 text

+simpl in Hi

m :
head :
listZ
rest :
listlistZ
IH :
∀a : Z i : nat text : listZ, string_slotsm a rest → nth_errorrest i = Sometext → ∃p : ptr, pointer_slotm a + 8 × Z.of_nati p ∧ c_stringm p text
a :
Z
i :
nat
text :
listZ
p :
Hp :
Hs :
c_stringm p head
Hrest :
string_slotsm a + 8 rest
Hi :
nth_errorrest i = Sometext
⊢
∃p0 : ptr, pointer_slotm a + 8 × Z.of_natSi p0 ∧ c_stringm p0 text

destruct IH_ _ _ Hrest Hi as q & Hq & Htext

m :
head :
listZ
rest :
listlistZ
IH :
∀a : Z i : nat text : listZ, string_slotsm a rest → nth_errorrest i = Sometext → ∃p : ptr, pointer_slotm a + 8 × Z.of_nati p ∧ c_stringm p text
a :
Z
i :
nat
text :
listZ
p :
Hp :
Hs :
c_stringm p head
Hrest :
string_slotsm a + 8 rest
Hi :
nth_errorrest i = Sometext
q :
Hq :
pointer_slotm a + 8 + 8 × Z.of_nati q
Htext :
c_stringm q text
⊢
∃p0 : ptr, pointer_slotm a + 8 × Z.of_natSi p0 ∧ c_stringm p0 text

exists q

m :
head :
listZ
rest :
listlistZ
IH :
∀a : Z i : nat text : listZ, string_slotsm a rest → nth_errorrest i = Sometext → ∃p : ptr, pointer_slotm a + 8 × Z.of_nati p ∧ c_stringm p text
a :
Z
i :
nat
text :
listZ
p :
Hp :
Hs :
c_stringm p head
Hrest :
string_slotsm a + 8 rest
Hi :
nth_errorrest i = Sometext
q :
Hq :
pointer_slotm a + 8 + 8 × Z.of_nati q
Htext :
c_stringm q text
⊢
pointer_slotm a + 8 × Z.of_natSi q ∧ c_stringm q text

replace a + 8 × Z.of_natSi with a + 8 + 8 × Z.of_nati by lia

m :
head :
listZ
rest :
listlistZ
IH :
∀a : Z i : nat text : listZ, string_slotsm a rest → nth_errorrest i = Sometext → ∃p : ptr, pointer_slotm a + 8 × Z.of_nati p ∧ c_stringm p text
a :
Z
i :
nat
text :
listZ
p :
Hp :
Hs :
c_stringm p head
Hrest :
string_slotsm a + 8 rest
Hi :
nth_errorrest i = Sometext
q :
Hq :
pointer_slotm a + 8 + 8 × Z.of_nati q
Htext :
c_stringm q text
⊢
pointer_slotm a + 8 + 8 × Z.of_nati q ∧ c_stringm q text

auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m texts
induction texts as | head rest IH ; intros a i text Hslots Hi
–destruct i ; discriminate Hi
–destruct Hslots as p & Hp & Hs & Hrest
destruct i as | i
+injection Hi as ←
replace a + 8 × Z.of_nat0 with a by lia
eauto
+simpl in Hi
destruct IH_ _ _ Hrest Hi as q & Hq & Htext
exists q
replace a + 8 × Z.of_natSi with a + 8 + 8 × Z.of_nati by lia
auto

If string_slots holds from a, the slot after the last text is null.

193Lemma string_slots_sentinel
∀ m texts a
string_slotsm a texts
pointer_slotm a + 8 × Z.of_natlengthtexts mkPtr0 CNone
Explore proof 10 tactics

Initial goal

⊢
∀m : mem texts : listlistZ a : Z, string_slotsm a texts → pointer_slotm a + 8 × Z.of_natDatatypes.lengthtexts ptr_addr ≔ 0; ptr_cap ≔ CNone

intros m texts

m :
texts :
listlistZ
⊢
∀a : Z, string_slotsm a texts → pointer_slotm a + 8 × Z.of_natDatatypes.lengthtexts ptr_addr ≔ 0; ptr_cap ≔ CNone

induction texts as | text rest IH ; intros a H

2 open

m :
a :
Z
H :
⊢
pointer_slotm a + 8 × Z.of_natDatatypes.length[ ] ptr_addr ≔ 0; ptr_cap ≔ CNone
focused goal
m :
text :
listZ
rest :
listlistZ
IH :
∀a : Z, string_slotsm a rest → pointer_slotm a + 8 × Z.of_natDatatypes.lengthrest ptr_addr ≔ 0; ptr_cap ≔ CNone
a :
Z
H :
string_slotsm a text :: rest
⊢
pointer_slotm a + 8 × Z.of_natDatatypes.lengthtext :: rest ptr_addr ≔ 0; ptr_cap ≔ CNone

–replace a + 8 × Z.of_natlength[ ] with a by simpl ; lia

2 open

m :
a :
Z
H :
⊢
deferred goal
m :
text :
listZ
rest :
listlistZ
IH :
∀a : Z, string_slotsm a rest → pointer_slotm a + 8 × Z.of_natDatatypes.lengthrest ptr_addr ≔ 0; ptr_cap ≔ CNone
a :
Z
H :
string_slotsm a text :: rest
⊢
pointer_slotm a + 8 × Z.of_natDatatypes.lengthtext :: rest ptr_addr ≔ 0; ptr_cap ≔ CNone

exact H

deferred goal
m :
text :
listZ
rest :
listlistZ
IH :
∀a : Z, string_slotsm a rest → pointer_slotm a + 8 × Z.of_natDatatypes.lengthrest ptr_addr ≔ 0; ptr_cap ≔ CNone
a :
Z
H :
string_slotsm a text :: rest
⊢
pointer_slotm a + 8 × Z.of_natDatatypes.lengthtext :: rest ptr_addr ≔ 0; ptr_cap ≔ CNone

–destruct H as p & _ & _ & H

m :
text :
listZ
rest :
listlistZ
IH :
∀a : Z, string_slotsm a rest → pointer_slotm a + 8 × Z.of_natDatatypes.lengthrest ptr_addr ≔ 0; ptr_cap ≔ CNone
a :
Z
p :
H :
string_slotsm a + 8 rest
⊢
pointer_slotm a + 8 × Z.of_natDatatypes.lengthtext :: rest ptr_addr ≔ 0; ptr_cap ≔ CNone

specialize IH_ H

m :
text :
listZ
rest :
listlistZ
a :
Z
IH :
pointer_slotm a + 8 + 8 × Z.of_natDatatypes.lengthrest ptr_addr ≔ 0; ptr_cap ≔ CNone
p :
H :
string_slotsm a + 8 rest
⊢
pointer_slotm a + 8 × Z.of_natDatatypes.lengthtext :: rest ptr_addr ≔ 0; ptr_cap ≔ CNone

change pointer_slotm a + 8 × Z.of_natSlengthrest mkPtr0 CNone

m :
text :
listZ
rest :
listlistZ
a :
Z
IH :
pointer_slotm a + 8 + 8 × Z.of_natDatatypes.lengthrest ptr_addr ≔ 0; ptr_cap ≔ CNone
p :
H :
string_slotsm a + 8 rest
⊢
pointer_slotm a + 8 × Z.of_natSDatatypes.lengthrest ptr_addr ≔ 0; ptr_cap ≔ CNone

rewrite Nat2Z.inj_succ

m :
text :
listZ
rest :
listlistZ
a :
Z
IH :
pointer_slotm a + 8 + 8 × Z.of_natDatatypes.lengthrest ptr_addr ≔ 0; ptr_cap ≔ CNone
p :
H :
string_slotsm a + 8 rest
⊢
pointer_slotm a + 8 × Z.succZ.of_natDatatypes.lengthrest ptr_addr ≔ 0; ptr_cap ≔ CNone

replace a + 8 × Z.succZ.of_natlengthrest with a + 8 + 8 × Z.of_natlengthrest by lia

m :
text :
listZ
rest :
listlistZ
a :
Z
IH :
pointer_slotm a + 8 + 8 × Z.of_natDatatypes.lengthrest ptr_addr ≔ 0; ptr_cap ≔ CNone
p :
H :
string_slotsm a + 8 rest
⊢
pointer_slotm a + 8 + 8 × Z.of_natDatatypes.lengthrest ptr_addr ≔ 0; ptr_cap ≔ CNone

exact IH

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m texts
induction texts as | text rest IH ; intros a H
–replace a + 8 × Z.of_natlength[ ] with a by simpl ; lia
exact H
–destruct H as p & _ & _ & H
specialize IH_ H
change pointer_slotm a + 8 × Z.of_natSlengthrest mkPtr0 CNone
rewrite Nat2Z.inj_succ
replace a + 8 × Z.succZ.of_natlengthrest with a + 8 + 8 × Z.of_natlengthrest by lia
exact IH

In an entry image (startup_at), argv's i-th slot points at a C string with the i-th argument, for any finite arguments.

208Theorem startup_argument
∀ m argc argv envp args environment i text
startup_atm argc argv envp args environment
nth_errorargs i = Sometext
∃p, pointer_slotm ptr_addrargv + 8 × Z.of_nati p ∧ c_stringm p text
Explore proof 2 tactics

Initial goal

⊢
∀m : mem argc : Z argv envp : ptr args environment : listlistZ i : nat text : listZ, startup_atm argc argv envp args environment → nth_errorargs i = Sometext → ∃p : ptr, pointer_slotm ptr_addrargv + 8 × Z.of_nati p ∧ c_stringm p text

intros m argc argv envp args environment i text _ & _ & _ H & _ Hi

m :
argc :
Z
argv, envp :
args, environment :
listlistZ
i :
nat
text :
listZ
H :
Hi :
nth_errorargs i = Sometext
⊢
∃p : ptr, pointer_slotm ptr_addrargv + 8 × Z.of_nati p ∧ c_stringm p text

exact string_slots_nth_ _ _ _ _ H Hi

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m argc argv envp args environment i text _ & _ & _ H & _ Hi
exact string_slots_nth_ _ _ _ _ H Hi

Likewise, envp's i-th slot points at the i-th environment string.

217Theorem startup_environment
∀ m argc argv envp args environment i text
startup_atm argc argv envp args environment
nth_errorenvironment i = Sometext
∃p, pointer_slotm ptr_addrenvp + 8 × Z.of_nati p ∧ c_stringm p text
Explore proof 2 tactics

Initial goal

⊢
∀m : mem argc : Z argv envp : ptr args environment : listlistZ i : nat text : listZ, startup_atm argc argv envp args environment → nth_errorenvironment i = Sometext → ∃p : ptr, pointer_slotm ptr_addrenvp + 8 × Z.of_nati p ∧ c_stringm p text

intros m argc argv envp args environment i text _ & _ & _ & _ H Hi

m :
argc :
Z
argv, envp :
args, environment :
listlistZ
i :
nat
text :
listZ
H :
string_slotsm ptr_addrenvp environment
Hi :
nth_errorenvironment i = Sometext
⊢
∃p : ptr, pointer_slotm ptr_addrenvp + 8 × Z.of_nati p ∧ c_stringm p text

exact string_slots_nth_ _ _ _ _ H Hi

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m argc argv envp args environment i text _ & _ & _ & _ H Hi
exact string_slots_nth_ _ _ _ _ H Hi

In an entry image, argv's slot argc and envp's slot after the last environment string are null.

227Theorem startup_sentinels
∀ m argc argv envp args environment
startup_atm argc argv envp args environment
pointer_slotm ptr_addrargv + 8 × argc mkPtr0 CNone ∧ pointer_slotm ptr_addrenvp + 8 × Z.of_natlengthenvironment mkPtr0 CNone
Explore proof 2 tactics

Initial goal

⊢
∀m : mem argc : Z argv envp : ptr args environment : listlistZ, startup_atm argc argv envp args environment → pointer_slotm ptr_addrargv + 8 × argc ptr_addr ≔ 0; ptr_cap ≔ CNone ∧ pointer_slotm ptr_addrenvp + 8 × Z.of_natDatatypes.lengthenvironment ptr_addr ≔ 0; ptr_cap ≔ CNone

intros m argc argv envp args environment _ & → & _ Ha & _ He

m :
argv, envp :
args, environment :
listlistZ
Ha :
He :
string_slotsm ptr_addrenvp environment
⊢
pointer_slotm ptr_addrargv + 8 × Z.of_natDatatypes.lengthargs ptr_addr ≔ 0; ptr_cap ≔ CNone ∧ pointer_slotm ptr_addrenvp + 8 × Z.of_natDatatypes.lengthenvironment ptr_addr ≔ 0; ptr_cap ≔ CNone

split ; apply string_slots_sentinel ; assumption

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m argc argv envp args environment _ & → & _ Ha & _ He
split ; apply string_slots_sentinel ; assumption

For a function f with no parameters, a first block b and no variadic arguments, call_frame with the launcher's three words gives the same fresh frame as with none: C's main(void) ignores the launcher's extra arguments. Do not replace a general entry by a launcher with an empty argv.

241Lemma main_void_entry
∀ f b blocks argc argv envp
fn_paramsf = [ ]
fn_blocksf = b :: blocks
variadic_funcf = false
call_framef main_argumentsargc argv envp = SomemkFramef [ ] mapλxs ⇒ fstxs, None local_objectsf None Enterb_labelb None
Explore proof 4 tactics

Initial goal

⊢
∀f : func b : block blocks : listblock argc : Z argv envp : ptr, fn_paramsf = [ ] → fn_blocksf = b :: blocks → variadic_funcf = false → call_framef main_argumentsargc argv envp = Somefr_fn ≔ f; fr_env ≔ [ ]; fr_locals ≔ mapλxs : name × Z ⇒ fstxs, None local_objectsf; fr_doomed ≔ None; fr_at ≔ Enterb_labelb None

intros f b blocks argc argv envp Hp Hb Hv

f :
blocks :
listblock
argc :
Z
argv, envp :
Hp :
fn_paramsf = [ ]
Hb :
fn_blocksf = b :: blocks
Hv :
variadic_funcf = false
⊢
call_framef main_argumentsargc argv envp = Somefr_fn ≔ f; fr_env ≔ [ ]; fr_locals ≔ mapλxs : name × Z ⇒ fstxs, None local_objectsf; fr_doomed ≔ None; fr_at ≔ Enterb_labelb None

unfold call_frame

f :
blocks :
listblock
argc :
Z
argv, envp :
Hp :
fn_paramsf = [ ]
Hb :
fn_blocksf = b :: blocks
Hv :
variadic_funcf = false
⊢
Datatypes.lengthmain_argumentsargc argv envp <? Datatypes.lengthfn_paramsf%nat
→
None
else
match fn_blocksf with
[ ]
⇒
None
b0 :: _
⇒
Somefr_fn ≔ f; fr_env ≔ fold_leftλe : listname × word px : class × name × word ⇒ putsndfstpx sndpx e combinefn_paramsf firstnDatatypes.lengthfn_paramsf main_argumentsargc argv envp [ ]; fr_locals ≔ mapλxs : name × Z ⇒ fstxs, None local_objectsf; fr_doomed ≔ None; fr_at ≔ if variadic_funcf then Snapshotmain_argumentsargc argv envp b_labelb0 else Enterb_labelb0 None
=
Somefr_fn ≔ f; fr_env ≔ [ ]; fr_locals ≔ mapλxs : name × Z ⇒ fstxs, None local_objectsf; fr_doomed ≔ None; fr_at ≔ Enterb_labelb None

rewrite Hp , Hb , Hv

f :
blocks :
listblock
argc :
Z
argv, envp :
Hp :
fn_paramsf = [ ]
Hb :
fn_blocksf = b :: blocks
Hv :
variadic_funcf = false
⊢
Datatypes.lengthmain_argumentsargc argv envp <? Datatypes.length[ ]%nat
→
None
else
Somefr_fn ≔ f; fr_env ≔ fold_leftλe : listname × word px : class × name × word ⇒ putsndfstpx sndpx e combine[ ] firstnDatatypes.length[ ] main_argumentsargc argv envp [ ]; fr_locals ≔ mapλxs : name × Z ⇒ fstxs, None local_objectsf; fr_doomed ≔ None; fr_at ≔ Enterb_labelb None
=
Somefr_fn ≔ f; fr_env ≔ [ ]; fr_locals ≔ mapλxs : name × Z ⇒ fstxs, None local_objectsf; fr_doomed ≔ None; fr_at ≔ Enterb_labelb None

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros f b blocks argc argv envp Hp Hb Hv
unfold call_frame
rewrite Hp , Hb , Hv
reflexivity

The exit status the process reports for main's or exit's status: its low byte, not a second acceptance or flush event. This conversion will be used only AFTER shutdown.

254Definition process_statusstatus : Z : Z ≔
status mod 256

A process status is a byte.

257Lemma process_status_range
∀ status
0 ≤ process_statusstatus < 256
Explore proof 4 tactics

Initial goal

⊢
∀status : Z, 0 ≤ process_statusstatus < 256

intros status

status :
Z
⊢
0 ≤ process_statusstatus < 256

unfold process_status

status :
Z
⊢
0 ≤ status mod 256 < 256

apply Z.mod_pos_bound

status :
Z
⊢
0 < 256

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros status
apply Z.mod_pos_bound
lia

Constructing the launcher's copied strings

The source bytes here describe native argv/environ strings, before they enter the capability model. This is the memcpy suboperation, including the NUL. It never creates a pointer capability by copying raw bytes; only the actual allocator answer creates that identity.

Copy bytes to address a, then write one NUL; copy no capability.

267Fixpoint copy_c_bytesm : mem a : Z bytes : listZ : mem ≔
match bytes with
[ ]
⇒
b :: rest
⇒
copy_c_bytesstore_bytesm a 1 b a + 1 rest

Copying the bytes and NUL leaves every object's region unchanged.

274Lemma copy_c_bytes_regions
∀ bytes m a
Explore proof 1 tactics

Initial goal

⊢
∀bytes : listZ m : mem a : Z, m_regionscopy_c_bytesm a bytes = m_regionsm

induction bytes ; intros ; simpl ; reflexivity | rewrite IHbytes ; reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
induction bytes ; intros ; simpl ; reflexivity | rewrite IHbytes ; reflexivity

Byte copying changes no stored capabilities, even inside the copy.

279Lemma copy_c_bytes_aux
∀ bytes m a
Explore proof 1 tactics

Initial goal

⊢
∀bytes : listZ m : mem a : Z, m_auxcopy_c_bytesm a bytes = m_auxm

induction bytes ; intros ; simpl ; reflexivity | rewrite IHbytes ; reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
induction bytes ; intros ; simpl ; reflexivity | rewrite IHbytes ; reflexivity

Bytes before the copy or at and beyond its end keep their old values.

284Lemma copy_c_bytes_outside
∀ bytes m a b
b < a ∨ a + Z.of_natlengthbytes + 1 ≤ b
m_bytescopy_c_bytesm a bytes b = m_bytesm b
Explore proof 18 tactics

Initial goal

⊢
∀bytes : listZ m : mem a b : Z, b < a ∨ a + Z.of_natDatatypes.lengthbytes + 1 ≤ b → m_bytescopy_c_bytesm a bytes b = m_bytesm b

induction bytes as | head rest IH ; intros m a b Hout

2 open

m :
a, b :
Z
Hout :
b < a ∨ a + Z.of_natDatatypes.length[ ] + 1 ≤ b
⊢
focused goal
head :
Z
rest :
listZ
IH :
∀m : mem a b : Z, b < a ∨ a + Z.of_natDatatypes.lengthrest + 1 ≤ b → m_bytescopy_c_bytesm a rest b = m_bytesm b
m :
a, b :
Z
Hout :
b < a ∨ a + Z.of_natDatatypes.lengthhead :: rest + 1 ≤ b
⊢
m_bytescopy_c_bytesm a head :: rest b = m_bytesm b

–simpl

2 open

m :
a, b :
Z
Hout :
b < a ∨ a + Z.of_natDatatypes.length[ ] + 1 ≤ b
⊢
a ≤? b && b <? a + 1
→
byte_of0 b − a
else
=
deferred goal
head :
Z
rest :
listZ
IH :
∀m : mem a b : Z, b < a ∨ a + Z.of_natDatatypes.lengthrest + 1 ≤ b → m_bytescopy_c_bytesm a rest b = m_bytesm b
m :
a, b :
Z
Hout :
b < a ∨ a + Z.of_natDatatypes.lengthhead :: rest + 1 ≤ b
⊢
m_bytescopy_c_bytesm a head :: rest b = m_bytesm b

destruct a ≤? b && b <? a + 1 eqn: E ; | reflexivity

2 open

m :
a, b :
Z
Hout :
b < a ∨ a + Z.of_natDatatypes.length[ ] + 1 ≤ b
E :
a ≤? b && b <? a + 1 = true
⊢
byte_of0 b − a = m_bytesm b
deferred goal
head :
Z
rest :
listZ
IH :
∀m : mem a b : Z, b < a ∨ a + Z.of_natDatatypes.lengthrest + 1 ≤ b → m_bytescopy_c_bytesm a rest b = m_bytesm b
m :
a, b :
Z
Hout :
b < a ∨ a + Z.of_natDatatypes.lengthhead :: rest + 1 ≤ b
⊢
m_bytescopy_c_bytesm a head :: rest b = m_bytesm b

apply andb_true_iff in E as E1 E2

2 open

m :
a, b :
Z
Hout :
b < a ∨ a + Z.of_natDatatypes.length[ ] + 1 ≤ b
E1 :
a ≤? b = true
E2 :
b <? a + 1 = true
⊢
byte_of0 b − a = m_bytesm b
deferred goal
head :
Z
rest :
listZ
IH :
∀m : mem a b : Z, b < a ∨ a + Z.of_natDatatypes.lengthrest + 1 ≤ b → m_bytescopy_c_bytesm a rest b = m_bytesm b
m :
a, b :
Z
Hout :
b < a ∨ a + Z.of_natDatatypes.lengthhead :: rest + 1 ≤ b
⊢
m_bytescopy_c_bytesm a head :: rest b = m_bytesm b

apply Z.leb_le in E1

2 open

m :
a, b :
Z
Hout :
b < a ∨ a + Z.of_natDatatypes.length[ ] + 1 ≤ b
E1 :
a ≤ b
E2 :
b <? a + 1 = true
⊢
byte_of0 b − a = m_bytesm b
deferred goal
head :
Z
rest :
listZ
IH :
∀m : mem a b : Z, b < a ∨ a + Z.of_natDatatypes.lengthrest + 1 ≤ b → m_bytescopy_c_bytesm a rest b = m_bytesm b
m :
a, b :
Z
Hout :
b < a ∨ a + Z.of_natDatatypes.lengthhead :: rest + 1 ≤ b
⊢
m_bytescopy_c_bytesm a head :: rest b = m_bytesm b

apply Z.ltb_lt in E2

2 open

m :
a, b :
Z
Hout :
b < a ∨ a + Z.of_natDatatypes.length[ ] + 1 ≤ b
E1 :
a ≤ b
E2 :
b < a + 1
⊢
byte_of0 b − a = m_bytesm b
deferred goal
head :
Z
rest :
listZ
IH :
∀m : mem a b : Z, b < a ∨ a + Z.of_natDatatypes.lengthrest + 1 ≤ b → m_bytescopy_c_bytesm a rest b = m_bytesm b
m :
a, b :
Z
Hout :
b < a ∨ a + Z.of_natDatatypes.lengthhead :: rest + 1 ≤ b
⊢
m_bytescopy_c_bytesm a head :: rest b = m_bytesm b

simpl in Hout

2 open

m :
a, b :
Z
Hout :
b < a ∨ a + 0 + 1 ≤ b
E1 :
a ≤ b
E2 :
b < a + 1
⊢
byte_of0 b − a = m_bytesm b
deferred goal
head :
Z
rest :
listZ
IH :
∀m : mem a b : Z, b < a ∨ a + Z.of_natDatatypes.lengthrest + 1 ≤ b → m_bytescopy_c_bytesm a rest b = m_bytesm b
m :
a, b :
Z
Hout :
b < a ∨ a + Z.of_natDatatypes.lengthhead :: rest + 1 ≤ b
⊢
m_bytescopy_c_bytesm a head :: rest b = m_bytesm b

lia

deferred goal
head :
Z
rest :
listZ
IH :
∀m : mem a b : Z, b < a ∨ a + Z.of_natDatatypes.lengthrest + 1 ≤ b → m_bytescopy_c_bytesm a rest b = m_bytesm b
m :
a, b :
Z
Hout :
b < a ∨ a + Z.of_natDatatypes.lengthhead :: rest + 1 ≤ b
⊢
m_bytescopy_c_bytesm a head :: rest b = m_bytesm b

–change m_bytescopy_c_bytesstore_bytesm a 1 head a + 1 rest b = m_bytesm b

head :
Z
rest :
listZ
IH :
∀m : mem a b : Z, b < a ∨ a + Z.of_natDatatypes.lengthrest + 1 ≤ b → m_bytescopy_c_bytesm a rest b = m_bytesm b
m :
a, b :
Z
Hout :
b < a ∨ a + Z.of_natDatatypes.lengthhead :: rest + 1 ≤ b
⊢
m_bytescopy_c_bytesstore_bytesm a 1 head a + 1 rest b = m_bytesm b

change b < a ∨ a + Z.of_natSlengthrest + 1 ≤ b in Hout

head :
Z
rest :
listZ
IH :
∀m : mem a b : Z, b < a ∨ a + Z.of_natDatatypes.lengthrest + 1 ≤ b → m_bytescopy_c_bytesm a rest b = m_bytesm b
m :
a, b :
Z
Hout :
b < a ∨ a + Z.of_natSDatatypes.lengthrest + 1 ≤ b
⊢
m_bytescopy_c_bytesstore_bytesm a 1 head a + 1 rest b = m_bytesm b

rewrite Nat2Z.inj_succ in Hout

head :
Z
rest :
listZ
IH :
∀m : mem a b : Z, b < a ∨ a + Z.of_natDatatypes.lengthrest + 1 ≤ b → m_bytescopy_c_bytesm a rest b = m_bytesm b
m :
a, b :
Z
Hout :
b < a ∨ a + Z.succZ.of_natDatatypes.lengthrest + 1 ≤ b
⊢
m_bytescopy_c_bytesstore_bytesm a 1 head a + 1 rest b = m_bytesm b

rewrite IH by lia

head :
Z
rest :
listZ
IH :
∀m : mem a b : Z, b < a ∨ a + Z.of_natDatatypes.lengthrest + 1 ≤ b → m_bytescopy_c_bytesm a rest b = m_bytesm b
m :
a, b :
Z
Hout :
b < a ∨ a + Z.succZ.of_natDatatypes.lengthrest + 1 ≤ b
⊢
m_bytesstore_bytesm a 1 head b = m_bytesm b

simpl

head :
Z
rest :
listZ
IH :
∀m : mem a b : Z, b < a ∨ a + Z.of_natDatatypes.lengthrest + 1 ≤ b → m_bytescopy_c_bytesm a rest b = m_bytesm b
m :
a, b :
Z
Hout :
b < a ∨ a + Z.succZ.of_natDatatypes.lengthrest + 1 ≤ b
⊢
a ≤? b && b <? a + 1
→
byte_ofhead b − a
else
=

destruct a ≤? b && b <? a + 1 eqn: E ; | reflexivity

head :
Z
rest :
listZ
IH :
∀m : mem a b : Z, b < a ∨ a + Z.of_natDatatypes.lengthrest + 1 ≤ b → m_bytescopy_c_bytesm a rest b = m_bytesm b
m :
a, b :
Z
Hout :
b < a ∨ a + Z.succZ.of_natDatatypes.lengthrest + 1 ≤ b
E :
a ≤? b && b <? a + 1 = true
⊢
byte_ofhead b − a = m_bytesm b

apply andb_true_iff in E as E1 E2

head :
Z
rest :
listZ
IH :
∀m : mem a b : Z, b < a ∨ a + Z.of_natDatatypes.lengthrest + 1 ≤ b → m_bytescopy_c_bytesm a rest b = m_bytesm b
m :
a, b :
Z
Hout :
b < a ∨ a + Z.succZ.of_natDatatypes.lengthrest + 1 ≤ b
E1 :
a ≤? b = true
E2 :
b <? a + 1 = true
⊢
byte_ofhead b − a = m_bytesm b

apply Z.leb_le in E1

head :
Z
rest :
listZ
IH :
∀m : mem a b : Z, b < a ∨ a + Z.of_natDatatypes.lengthrest + 1 ≤ b → m_bytescopy_c_bytesm a rest b = m_bytesm b
m :
a, b :
Z
Hout :
b < a ∨ a + Z.succZ.of_natDatatypes.lengthrest + 1 ≤ b
E1 :
a ≤ b
E2 :
b <? a + 1 = true
⊢
byte_ofhead b − a = m_bytesm b

apply Z.ltb_lt in E2

head :
Z
rest :
listZ
IH :
∀m : mem a b : Z, b < a ∨ a + Z.of_natDatatypes.lengthrest + 1 ≤ b → m_bytescopy_c_bytesm a rest b = m_bytesm b
m :
a, b :
Z
Hout :
b < a ∨ a + Z.succZ.of_natDatatypes.lengthrest + 1 ≤ b
E1 :
a ≤ b
E2 :
b < a + 1
⊢
byte_ofhead b − a = m_bytesm b

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
induction bytes as | head rest IH ; intros m a b Hout
–simpl
destruct a ≤? b && b <? a + 1 eqn: E ; | reflexivity
apply andb_true_iff in E as E1 E2
apply Z.leb_le in E1
apply Z.ltb_lt in E2
simpl in Hout
lia
–change m_bytescopy_c_bytesstore_bytesm a 1 head a + 1 rest b = m_bytesm b
change b < a ∨ a + Z.of_natSlengthrest + 1 ≤ b in Hout
rewrite Nat2Z.inj_succ in Hout
rewrite IH by lia
simpl
destruct a ≤? b && b <? a + 1 eqn: E ; | reflexivity
apply andb_true_iff in E as E1 E2
apply Z.leb_le in E1
apply Z.ltb_lt in E2
lia

Nonzero byte values are copied exactly, with the first NUL just after them.

300Theorem copied_string_bytes
∀ bytes m a
Forallλb ⇒ 0 < b < 256 bytes
string_atcopy_c_bytesm a bytes a bytes
Explore proof 22 tactics

Initial goal

⊢
∀bytes : listZ m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 bytes → string_atcopy_c_bytesm a bytes a bytes

induction bytes as | b rest IH ; intros m a Hbytes

2 open

m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 [ ]
⊢
focused goal
b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
⊢
string_atcopy_c_bytesm a b :: rest a b :: rest

–simpl

2 open

m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 [ ]
⊢
a ≤? a && a <? a + 1
→
byte_of0 a − a
else
=
0
deferred goal
b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
⊢
string_atcopy_c_bytesm a b :: rest a b :: rest

rewrite Z.leb_refl

2 open

m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 [ ]
⊢
true && a <? a + 1
→
byte_of0 a − a
else
=
0
deferred goal
b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
⊢
string_atcopy_c_bytesm a b :: rest a b :: rest

assert a <? a + 1 = true as E by apply Z.ltb_lt ; lia

2 open

m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 [ ]
E :
a <? a + 1 = true
⊢
true && a <? a + 1
→
byte_of0 a − a
else
=
0
deferred goal
b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
⊢
string_atcopy_c_bytesm a b :: rest a b :: rest

rewrite E

2 open

m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 [ ]
E :
a <? a + 1 = true
⊢
true && true
→
byte_of0 a − a
else
=
0
deferred goal
b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
⊢
string_atcopy_c_bytesm a b :: rest a b :: rest

replace a − a with 0 by lia

2 open

m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 [ ]
E :
a <? a + 1 = true
⊢
true && true
→
else
=
0
deferred goal
b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
⊢
string_atcopy_c_bytesm a b :: rest a b :: rest

reflexivity

deferred goal
b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
⊢
string_atcopy_c_bytesm a b :: rest a b :: rest

–inversion Hbytes as | head tail Hb Hrest ; subst

b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
⊢
string_atcopy_c_bytesm a b :: rest a b :: rest

simpl

b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
⊢
0 < b < 256 ∧ m_bytescopy_c_bytesstore_bytesm a 1 b a + 1 rest a = b ∧ string_atcopy_c_bytesstore_bytesm a 1 b a + 1 rest a + 1 rest

split ; exact Hb |

b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
⊢
m_bytescopy_c_bytesstore_bytesm a 1 b a + 1 rest a = b ∧ string_atcopy_c_bytesstore_bytesm a 1 b a + 1 rest a + 1 rest

split

2 open

b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
⊢
m_bytescopy_c_bytesstore_bytesm a 1 b a + 1 rest a = b
focused goal
b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
⊢
string_atcopy_c_bytesstore_bytesm a 1 b a + 1 rest a + 1 rest

+rewrite copy_c_bytes_outside by lia

2 open

b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
⊢
m_bytesstore_bytesm a 1 b a = b
deferred goal
b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
⊢
string_atcopy_c_bytesstore_bytesm a 1 b a + 1 rest a + 1 rest

pose proof stored_bytem a 1 b 0 ltac:lia as Hstored

2 open

b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
Hstored :
m_bytesstore_bytesm a 1 b a + 0 = byte_ofb 0
⊢
m_bytesstore_bytesm a 1 b a = b
deferred goal
b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
⊢
string_atcopy_c_bytesstore_bytesm a 1 b a + 1 rest a + 1 rest

replace a + 0 with a in Hstored by lia

2 open

b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
Hstored :
⊢
m_bytesstore_bytesm a 1 b a = b
deferred goal
b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
⊢
string_atcopy_c_bytesstore_bytesm a 1 b a + 1 rest a + 1 rest

rewrite Hstored

2 open

b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
Hstored :
⊢
byte_ofb 0 = b
deferred goal
b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
⊢
string_atcopy_c_bytesstore_bytesm a 1 b a + 1 rest a + 1 rest

unfold byte_of

2 open

b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
Hstored :
⊢
b / 2 ^ 8 × 0 mod 256 = b
deferred goal
b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
⊢
string_atcopy_c_bytesstore_bytesm a 1 b a + 1 rest a + 1 rest

change b / 1 mod 256 = b

2 open

b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
Hstored :
⊢
b / 1 mod 256 = b
deferred goal
b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
⊢
string_atcopy_c_bytesstore_bytesm a 1 b a + 1 rest a + 1 rest

rewrite Z.div_1_r

2 open

b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
Hstored :
⊢
b mod 256 = b
deferred goal
b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
⊢
string_atcopy_c_bytesstore_bytesm a 1 b a + 1 rest a + 1 rest

apply Z.mod_small

2 open

b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
Hstored :
⊢
0 ≤ b < 256
deferred goal
b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
⊢
string_atcopy_c_bytesstore_bytesm a 1 b a + 1 rest a + 1 rest

lia

deferred goal
b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
⊢
string_atcopy_c_bytesstore_bytesm a 1 b a + 1 rest a + 1 rest

+apply IH

b :
Z
rest :
listZ
IH :
∀m : mem a : Z, Forallλb : Z ⇒ 0 < b < 256 rest → string_atcopy_c_bytesm a rest a rest
m :
a :
Z
Hbytes :
Forallλb : Z ⇒ 0 < b < 256 b :: rest
Hb :
0 < b < 256
Hrest :
Forallλb : Z ⇒ 0 < b < 256 rest
⊢
Forallλb0 : Z ⇒ 0 < b0 < 256 rest

exact Hrest

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
induction bytes as | b rest IH ; intros m a Hbytes
–simpl
rewrite Z.leb_refl
assert a <? a + 1 = true as E by apply Z.ltb_lt ; lia
rewrite E
replace a − a with 0 by lia
reflexivity
–inversion Hbytes as | head tail Hb Hrest ; subst
simpl
split ; exact Hb |
split
+rewrite copy_c_bytes_outside by lia
pose proof stored_bytem a 1 b 0 ltac:lia as Hstored
replace a + 0 with a in Hstored by lia
rewrite Hstored
unfold byte_of
change b / 1 mod 256 = b
rewrite Z.div_1_r
apply Z.mod_small
lia
+apply IH
exact Hrest

A copied fresh string cannot modify any old object, not just an enumerated set of startup roots. This frame will retain earlier strings while subsequent launcher allocations/copies take place.

319Theorem copied_string_old_object
∀ m q base bytes a
freshm q base
Z.of_natlengthbytes + 1 ≤ req_extentq
m_bytescopy_c_bytesallocatedm q base base bytes a = m_bytesm a ∧ m_auxcopy_c_bytesallocatedm q base base bytes a = m_auxm a
Explore proof 7 tactics

Initial goal

⊢
∀m : mem q : alloc_req base : Z bytes : listZ a : Z, freshm q base → Z.of_natDatatypes.lengthbytes + 1 ≤ req_extentq → in_objectm a → m_bytescopy_c_bytesallocatedm q base base bytes a = m_bytesm a ∧ m_auxcopy_c_bytesallocatedm q base base bytes a = m_auxm a

intros m q base bytes a _ & _ & _ & _ & Hdis & _ Hsize old & reg & Hreg & Hrange

m :
base :
Z
bytes :
listZ
a :
Z
Hdis :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → ¬base < r_endreg ∧ b < base + req_extentq
Hsize :
Z.of_natDatatypes.lengthbytes + 1 ≤ req_extentq
old :
Z
reg :
Hreg :
object_regionold m_regionsm = Somereg
Hrange :
old ≤ a < r_endreg
⊢
m_bytescopy_c_bytesallocatedm q base base bytes a = m_bytesm a ∧ m_auxcopy_c_bytesallocatedm q base base bytes a = m_auxm a

specialize Hdisold reg Hreg

m :
base :
Z
bytes :
listZ
a, old :
Z
reg :
Hdis :
¬base < r_endreg ∧ old < base + req_extentq
Hsize :
Z.of_natDatatypes.lengthbytes + 1 ≤ req_extentq
Hreg :
object_regionold m_regionsm = Somereg
Hrange :
old ≤ a < r_endreg
⊢
m_bytescopy_c_bytesallocatedm q base base bytes a = m_bytesm a ∧ m_auxcopy_c_bytesallocatedm q base base bytes a = m_auxm a

split

2 open

m :
base :
Z
bytes :
listZ
a, old :
Z
reg :
Hdis :
¬base < r_endreg ∧ old < base + req_extentq
Hsize :
Z.of_natDatatypes.lengthbytes + 1 ≤ req_extentq
Hreg :
object_regionold m_regionsm = Somereg
Hrange :
old ≤ a < r_endreg
⊢
m_bytescopy_c_bytesallocatedm q base base bytes a = m_bytesm a
focused goal
m :
base :
Z
bytes :
listZ
a, old :
Z
reg :
Hdis :
¬base < r_endreg ∧ old < base + req_extentq
Hsize :
Z.of_natDatatypes.lengthbytes + 1 ≤ req_extentq
Hreg :
object_regionold m_regionsm = Somereg
Hrange :
old ≤ a < r_endreg
⊢
m_auxcopy_c_bytesallocatedm q base base bytes a = m_auxm a

–rewrite copy_c_bytes_outside by lia

2 open

m :
base :
Z
bytes :
listZ
a, old :
Z
reg :
Hdis :
¬base < r_endreg ∧ old < base + req_extentq
Hsize :
Z.of_natDatatypes.lengthbytes + 1 ≤ req_extentq
Hreg :
object_regionold m_regionsm = Somereg
Hrange :
old ≤ a < r_endreg
⊢
m_bytesallocatedm q base a = m_bytesm a
deferred goal
m :
base :
Z
bytes :
listZ
a, old :
Z
reg :
Hdis :
¬base < r_endreg ∧ old < base + req_extentq
Hsize :
Z.of_natDatatypes.lengthbytes + 1 ≤ req_extentq
Hreg :
object_regionold m_regionsm = Somereg
Hrange :
old ≤ a < r_endreg
⊢
m_auxcopy_c_bytesallocatedm q base base bytes a = m_auxm a

reflexivity

deferred goal
m :
base :
Z
bytes :
listZ
a, old :
Z
reg :
Hdis :
¬base < r_endreg ∧ old < base + req_extentq
Hsize :
Z.of_natDatatypes.lengthbytes + 1 ≤ req_extentq
Hreg :
object_regionold m_regionsm = Somereg
Hrange :
old ≤ a < r_endreg
⊢
m_auxcopy_c_bytesallocatedm q base base bytes a = m_auxm a

–rewrite copy_c_bytes_aux

m :
base :
Z
bytes :
listZ
a, old :
Z
reg :
Hdis :
¬base < r_endreg ∧ old < base + req_extentq
Hsize :
Z.of_natDatatypes.lengthbytes + 1 ≤ req_extentq
Hreg :
object_regionold m_regionsm = Somereg
Hrange :
old ≤ a < r_endreg
⊢
m_auxallocatedm q base a = m_auxm a

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m q base bytes a _ & _ & _ & _ & Hdis & _ Hsize old & reg & Hreg & Hrange
specialize Hdisold reg Hreg
split
–rewrite copy_c_bytes_outside by lia
reflexivity
–rewrite copy_c_bytes_aux
reflexivity

Startup keeps all old regions exactly and all old-object bytes and capabilities outside the pointer slots it is filling. New objects need not be unchanged; their contents are constructed separately.

333Definition startup_framem m′ : mem lo hi : Z : Prop ≔
∀b reg, object_regionb m_regionsm = Somereg → object_regionb m_regionsm′ = Somereg ∧ ∀a, in_objectm a → a < lo ∨ hi ≤ a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a

Allocating and copying a fresh string frames every old object.

340Lemma copied_string_frame
∀ m q base bytes lo hi
freshm q base
Z.of_natlengthbytes + 1 ≤ req_extentq
startup_framem copy_c_bytesallocatedm q base base bytes lo hi
Explore proof 8 tactics

Initial goal

⊢
∀m : mem q : alloc_req base : Z bytes : listZ lo hi : Z, freshm q base → Z.of_natDatatypes.lengthbytes + 1 ≤ req_extentq → startup_framem copy_c_bytesallocatedm q base base bytes lo hi

intros m q base bytes lo hi Hfresh Hsize

m :
base :
Z
bytes :
listZ
lo, hi :
Z
Hfresh :
freshm q base
Hsize :
Z.of_natDatatypes.lengthbytes + 1 ≤ req_extentq
⊢
startup_framem copy_c_bytesallocatedm q base base bytes lo hi

split

2 open

m :
base :
Z
bytes :
listZ
lo, hi :
Z
Hfresh :
freshm q base
Hsize :
Z.of_natDatatypes.lengthbytes + 1 ≤ req_extentq
⊢
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionscopy_c_bytesallocatedm q base base bytes = Somereg
focused goal
m :
base :
Z
bytes :
listZ
lo, hi :
Z
Hfresh :
freshm q base
Hsize :
Z.of_natDatatypes.lengthbytes + 1 ≤ req_extentq
⊢
∀a : Z, in_objectm a → a < lo ∨ hi ≤ a → m_bytescopy_c_bytesallocatedm q base base bytes a = m_bytesm a ∧ m_auxcopy_c_bytesallocatedm q base base bytes a = m_auxm a

–intros b reg H

2 open

m :
base :
Z
bytes :
listZ
lo, hi :
Z
Hfresh :
freshm q base
Hsize :
Z.of_natDatatypes.lengthbytes + 1 ≤ req_extentq
b :
Z
reg :
H :
⊢
object_regionb m_regionscopy_c_bytesallocatedm q base base bytes = Somereg
deferred goal
m :
base :
Z
bytes :
listZ
lo, hi :
Z
Hfresh :
freshm q base
Hsize :
Z.of_natDatatypes.lengthbytes + 1 ≤ req_extentq
⊢
∀a : Z, in_objectm a → a < lo ∨ hi ≤ a → m_bytescopy_c_bytesallocatedm q base base bytes a = m_bytesm a ∧ m_auxcopy_c_bytesallocatedm q base base bytes a = m_auxm a

rewrite copy_c_bytes_regions

2 open

m :
base :
Z
bytes :
listZ
lo, hi :
Z
Hfresh :
freshm q base
Hsize :
Z.of_natDatatypes.lengthbytes + 1 ≤ req_extentq
b :
Z
reg :
H :
⊢
object_regionb m_regionsallocatedm q base = Somereg
deferred goal
m :
base :
Z
bytes :
listZ
lo, hi :
Z
Hfresh :
freshm q base
Hsize :
Z.of_natDatatypes.lengthbytes + 1 ≤ req_extentq
⊢
∀a : Z, in_objectm a → a < lo ∨ hi ≤ a → m_bytescopy_c_bytesallocatedm q base base bytes a = m_bytesm a ∧ m_auxcopy_c_bytesallocatedm q base base bytes a = m_auxm a

eapply allocated_old_region ; | exact H

2 open

m :
base :
Z
bytes :
listZ
lo, hi :
Z
Hfresh :
freshm q base
Hsize :
Z.of_natDatatypes.lengthbytes + 1 ≤ req_extentq
b :
Z
reg :
H :
⊢
deferred goal
m :
base :
Z
bytes :
listZ
lo, hi :
Z
Hfresh :
freshm q base
Hsize :
Z.of_natDatatypes.lengthbytes + 1 ≤ req_extentq
⊢
∀a : Z, in_objectm a → a < lo ∨ hi ≤ a → m_bytescopy_c_bytesallocatedm q base base bytes a = m_bytesm a ∧ m_auxcopy_c_bytesallocatedm q base base bytes a = m_auxm a

exact proj1proj2proj2proj2Hfresh

deferred goal
m :
base :
Z
bytes :
listZ
lo, hi :
Z
Hfresh :
freshm q base
Hsize :
Z.of_natDatatypes.lengthbytes + 1 ≤ req_extentq
⊢
∀a : Z, in_objectm a → a < lo ∨ hi ≤ a → m_bytescopy_c_bytesallocatedm q base base bytes a = m_bytesm a ∧ m_auxcopy_c_bytesallocatedm q base base bytes a = m_auxm a

–intros a Hin _

m :
base :
Z
bytes :
listZ
lo, hi :
Z
Hfresh :
freshm q base
Hsize :
Z.of_natDatatypes.lengthbytes + 1 ≤ req_extentq
a :
Z
Hin :
⊢
m_bytescopy_c_bytesallocatedm q base base bytes a = m_bytesm a ∧ m_auxcopy_c_bytesallocatedm q base base bytes a = m_auxm a

eapply copied_string_old_object ; eauto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m q base bytes lo hi Hfresh Hsize
split
–intros b reg H
eapply allocated_old_region ; | exact H
exact proj1proj2proj2proj2Hfresh
–intros a Hin _

A startup frame transports old access checks without ending lifetimes.

351Lemma startup_frame_access
∀ m m′ lo hi a c size rights align
startup_framem m′ lo hi
access_resm a c size rights align = Someok
access_resm′ a c size rights align = Someok
Explore proof 4 tactics

Initial goal

⊢
∀m m′ : mem lo hi a : Z c : cap size : Z rights : rights align : Z, startup_framem m′ lo hi → access_resm a c size rights align = Someok → access_resm′ a c size rights align = Someok

intros m m′ lo hi a c size rights align Hr _ Ha

m, m′ :
lo, hi, a :
Z
c :
size :
Z
rights :
rights
align :
Z
Hr :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm′ = Somereg
Ha :
access_resm a c size rights align = Someok
⊢
access_resm′ a c size rights align = Someok

unfold access_res , cap_access_res in Ha

m, m′ :
lo, hi, a :
Z
c :
size :
Z
rights :
rights
align :
Z
Hr :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm′ = Somereg
Ha :
match c with
Objbase
⇒
let* reg ≔ object_regionbase m_regionsm in
Some
base ≤? a && a + size ≤? r_endreg
→
Robase
⇒
let* reg ≔ object_regionbase m_regionsm in
Some
base ≤? a && a + size ≤? r_endreg
→
readonly_access_resrights a align
⇒
None
=
Someok
⊢
access_resm′ a c size rights align = Someok

destruct c as | b | b | f | f ; try discriminate

2 open

m, m′ :
lo, hi, a, b, size :
Z
rights :
rights
align :
Z
Hr :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm′ = Somereg
Ha :
let* reg ≔ object_regionb m_regionsm in
Some
b ≤? a && a + size ≤? r_endreg
→
=
Someok
⊢
access_resm′ a Objb size rights align = Someok
focused goal
m, m′ :
lo, hi, a, b, size :
Z
rights :
rights
align :
Z
Hr :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm′ = Somereg
Ha :
let* reg ≔ object_regionb m_regionsm in
Some
b ≤? a && a + size ≤? r_endreg
→
readonly_access_resrights a align
=
Someok
⊢
access_resm′ a Rob size rights align = Someok

all: destruct object_regionb m_regionsm as reg | eqn: E ; try discriminate ; unfold access_res , cap_access_res ; rewrite Hr_ _ E ; exact Ha

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m m′ lo hi a c size rights align Hr _ Ha
unfold access_res , cap_access_res in Ha
destruct c as | b | b | f | f ; try discriminate
all: destruct object_regionb m_regionsm as reg | eqn: E ; try discriminate ; unfold access_res , cap_access_res ; rewrite Hr_ _ E ; exact Ha

Framing an old object leaves it an object for later allocations.

362Lemma startup_frame_in
∀ m m′ lo hi a
startup_framem m′ lo hi
in_objectm′ a
Explore proof 3 tactics

Initial goal

⊢
∀m m′ : mem lo hi a : Z, startup_framem m′ lo hi → in_objectm a → in_objectm′ a

intros m m′ lo hi a Hr _ b & reg & E & H

m, m′ :
lo, hi, a :
Z
Hr :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm′ = Somereg
b :
Z
reg :
E :
H :
b ≤ a < r_endreg
⊢
in_objectm′ a

exists b, reg

m, m′ :
lo, hi, a :
Z
Hr :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm′ = Somereg
b :
Z
reg :
E :
H :
b ≤ a < r_endreg
⊢
object_regionb m_regionsm′ = Somereg ∧ b ≤ a < r_endreg

auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m m′ lo hi a Hr _ b & reg & E & H
exists b, reg
auto

Consecutive construction steps may write in adjoining slot ranges.

367Lemma startup_frame_join
∀ m m1 m2 lo mid hi
lo ≤ mid ≤ hi
startup_framem m1 lo mid
startup_framem1 m2 mid hi
startup_framem m2 lo hi
Explore proof 12 tactics

Initial goal

⊢
∀m m1 m2 : mem lo mid hi : Z, lo ≤ mid ≤ hi → startup_framem m1 lo mid → startup_framem1 m2 mid hi → startup_framem m2 lo hi

intros m m1 m2 lo mid hi Hbounds Hr1 Hb1 Hr2 Hb2

m, m1, m2 :
lo, mid, hi :
Z
Hbounds :
lo ≤ mid ≤ hi
Hr1 :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm1 = Somereg
Hb1 :
∀a : Z, in_objectm a → a < lo ∨ mid ≤ a → m_bytesm1 a = m_bytesm a ∧ m_auxm1 a = m_auxm a
Hr2 :
∀b : Z reg : region, object_regionb m_regionsm1 = Somereg → object_regionb m_regionsm2 = Somereg
Hb2 :
∀a : Z, in_objectm1 a → a < mid ∨ hi ≤ a → m_bytesm2 a = m_bytesm1 a ∧ m_auxm2 a = m_auxm1 a
⊢
startup_framem m2 lo hi

split

2 open

m, m1, m2 :
lo, mid, hi :
Z
Hbounds :
lo ≤ mid ≤ hi
Hr1 :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm1 = Somereg
Hb1 :
∀a : Z, in_objectm a → a < lo ∨ mid ≤ a → m_bytesm1 a = m_bytesm a ∧ m_auxm1 a = m_auxm a
Hr2 :
∀b : Z reg : region, object_regionb m_regionsm1 = Somereg → object_regionb m_regionsm2 = Somereg
Hb2 :
∀a : Z, in_objectm1 a → a < mid ∨ hi ≤ a → m_bytesm2 a = m_bytesm1 a ∧ m_auxm2 a = m_auxm1 a
⊢
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm2 = Somereg
focused goal
m, m1, m2 :
lo, mid, hi :
Z
Hbounds :
lo ≤ mid ≤ hi
Hr1 :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm1 = Somereg
Hb1 :
∀a : Z, in_objectm a → a < lo ∨ mid ≤ a → m_bytesm1 a = m_bytesm a ∧ m_auxm1 a = m_auxm a
Hr2 :
∀b : Z reg : region, object_regionb m_regionsm1 = Somereg → object_regionb m_regionsm2 = Somereg
Hb2 :
∀a : Z, in_objectm1 a → a < mid ∨ hi ≤ a → m_bytesm2 a = m_bytesm1 a ∧ m_auxm2 a = m_auxm1 a
⊢
∀a : Z, in_objectm a → a < lo ∨ hi ≤ a → m_bytesm2 a = m_bytesm a ∧ m_auxm2 a = m_auxm a

–intros b reg H

2 open

m, m1, m2 :
lo, mid, hi :
Z
Hbounds :
lo ≤ mid ≤ hi
Hr1 :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm1 = Somereg
Hb1 :
∀a : Z, in_objectm a → a < lo ∨ mid ≤ a → m_bytesm1 a = m_bytesm a ∧ m_auxm1 a = m_auxm a
Hr2 :
∀b : Z reg : region, object_regionb m_regionsm1 = Somereg → object_regionb m_regionsm2 = Somereg
Hb2 :
∀a : Z, in_objectm1 a → a < mid ∨ hi ≤ a → m_bytesm2 a = m_bytesm1 a ∧ m_auxm2 a = m_auxm1 a
b :
Z
reg :
H :
⊢
object_regionb m_regionsm2 = Somereg
deferred goal
m, m1, m2 :
lo, mid, hi :
Z
Hbounds :
lo ≤ mid ≤ hi
Hr1 :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm1 = Somereg
Hb1 :
∀a : Z, in_objectm a → a < lo ∨ mid ≤ a → m_bytesm1 a = m_bytesm a ∧ m_auxm1 a = m_auxm a
Hr2 :
∀b : Z reg : region, object_regionb m_regionsm1 = Somereg → object_regionb m_regionsm2 = Somereg
Hb2 :
∀a : Z, in_objectm1 a → a < mid ∨ hi ≤ a → m_bytesm2 a = m_bytesm1 a ∧ m_auxm2 a = m_auxm1 a
⊢
∀a : Z, in_objectm a → a < lo ∨ hi ≤ a → m_bytesm2 a = m_bytesm a ∧ m_auxm2 a = m_auxm a

auto

deferred goal
m, m1, m2 :
lo, mid, hi :
Z
Hbounds :
lo ≤ mid ≤ hi
Hr1 :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm1 = Somereg
Hb1 :
∀a : Z, in_objectm a → a < lo ∨ mid ≤ a → m_bytesm1 a = m_bytesm a ∧ m_auxm1 a = m_auxm a
Hr2 :
∀b : Z reg : region, object_regionb m_regionsm1 = Somereg → object_regionb m_regionsm2 = Somereg
Hb2 :
∀a : Z, in_objectm1 a → a < mid ∨ hi ≤ a → m_bytesm2 a = m_bytesm1 a ∧ m_auxm2 a = m_auxm1 a
⊢
∀a : Z, in_objectm a → a < lo ∨ hi ≤ a → m_bytesm2 a = m_bytesm a ∧ m_auxm2 a = m_auxm a

–intros a Hin Hout

m, m1, m2 :
lo, mid, hi :
Z
Hbounds :
lo ≤ mid ≤ hi
Hr1 :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm1 = Somereg
Hb1 :
∀a : Z, in_objectm a → a < lo ∨ mid ≤ a → m_bytesm1 a = m_bytesm a ∧ m_auxm1 a = m_auxm a
Hr2 :
∀b : Z reg : region, object_regionb m_regionsm1 = Somereg → object_regionb m_regionsm2 = Somereg
Hb2 :
∀a : Z, in_objectm1 a → a < mid ∨ hi ≤ a → m_bytesm2 a = m_bytesm1 a ∧ m_auxm2 a = m_auxm1 a
a :
Z
Hin :
Hout :
a < lo ∨ hi ≤ a
⊢
m_bytesm2 a = m_bytesm a ∧ m_auxm2 a = m_auxm a

assert Hin1 : in_objectm1 a

2 open

m, m1, m2 :
lo, mid, hi :
Z
Hbounds :
lo ≤ mid ≤ hi
Hr1 :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm1 = Somereg
Hb1 :
∀a : Z, in_objectm a → a < lo ∨ mid ≤ a → m_bytesm1 a = m_bytesm a ∧ m_auxm1 a = m_auxm a
Hr2 :
∀b : Z reg : region, object_regionb m_regionsm1 = Somereg → object_regionb m_regionsm2 = Somereg
Hb2 :
∀a : Z, in_objectm1 a → a < mid ∨ hi ≤ a → m_bytesm2 a = m_bytesm1 a ∧ m_auxm2 a = m_auxm1 a
a :
Z
Hin :
Hout :
a < lo ∨ hi ≤ a
⊢
focused goal
m, m1, m2 :
lo, mid, hi :
Z
Hbounds :
lo ≤ mid ≤ hi
Hr1 :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm1 = Somereg
Hb1 :
∀a : Z, in_objectm a → a < lo ∨ mid ≤ a → m_bytesm1 a = m_bytesm a ∧ m_auxm1 a = m_auxm a
Hr2 :
∀b : Z reg : region, object_regionb m_regionsm1 = Somereg → object_regionb m_regionsm2 = Somereg
Hb2 :
∀a : Z, in_objectm1 a → a < mid ∨ hi ≤ a → m_bytesm2 a = m_bytesm1 a ∧ m_auxm2 a = m_auxm1 a
a :
Z
Hin :
Hout :
a < lo ∨ hi ≤ a
Hin1 :
⊢
m_bytesm2 a = m_bytesm a ∧ m_auxm2 a = m_auxm a

{destruct Hin as b & reg & E & H

2 open

m, m1, m2 :
lo, mid, hi :
Z
Hbounds :
lo ≤ mid ≤ hi
Hr1 :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm1 = Somereg
Hb1 :
∀a : Z, in_objectm a → a < lo ∨ mid ≤ a → m_bytesm1 a = m_bytesm a ∧ m_auxm1 a = m_auxm a
Hr2 :
∀b : Z reg : region, object_regionb m_regionsm1 = Somereg → object_regionb m_regionsm2 = Somereg
Hb2 :
∀a : Z, in_objectm1 a → a < mid ∨ hi ≤ a → m_bytesm2 a = m_bytesm1 a ∧ m_auxm2 a = m_auxm1 a
a, b :
Z
reg :
E :
H :
b ≤ a < r_endreg
Hout :
a < lo ∨ hi ≤ a
⊢
deferred goal
m, m1, m2 :
lo, mid, hi :
Z
Hbounds :
lo ≤ mid ≤ hi
Hr1 :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm1 = Somereg
Hb1 :
∀a : Z, in_objectm a → a < lo ∨ mid ≤ a → m_bytesm1 a = m_bytesm a ∧ m_auxm1 a = m_auxm a
Hr2 :
∀b : Z reg : region, object_regionb m_regionsm1 = Somereg → object_regionb m_regionsm2 = Somereg
Hb2 :
∀a : Z, in_objectm1 a → a < mid ∨ hi ≤ a → m_bytesm2 a = m_bytesm1 a ∧ m_auxm2 a = m_auxm1 a
a :
Z
Hin :
Hout :
a < lo ∨ hi ≤ a
Hin1 :
⊢
m_bytesm2 a = m_bytesm a ∧ m_auxm2 a = m_auxm a

exists b, reg

2 open

m, m1, m2 :
lo, mid, hi :
Z
Hbounds :
lo ≤ mid ≤ hi
Hr1 :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm1 = Somereg
Hb1 :
∀a : Z, in_objectm a → a < lo ∨ mid ≤ a → m_bytesm1 a = m_bytesm a ∧ m_auxm1 a = m_auxm a
Hr2 :
∀b : Z reg : region, object_regionb m_regionsm1 = Somereg → object_regionb m_regionsm2 = Somereg
Hb2 :
∀a : Z, in_objectm1 a → a < mid ∨ hi ≤ a → m_bytesm2 a = m_bytesm1 a ∧ m_auxm2 a = m_auxm1 a
a, b :
Z
reg :
E :
H :
b ≤ a < r_endreg
Hout :
a < lo ∨ hi ≤ a
⊢
object_regionb m_regionsm1 = Somereg ∧ b ≤ a < r_endreg
deferred goal
m, m1, m2 :
lo, mid, hi :
Z
Hbounds :
lo ≤ mid ≤ hi
Hr1 :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm1 = Somereg
Hb1 :
∀a : Z, in_objectm a → a < lo ∨ mid ≤ a → m_bytesm1 a = m_bytesm a ∧ m_auxm1 a = m_auxm a
Hr2 :
∀b : Z reg : region, object_regionb m_regionsm1 = Somereg → object_regionb m_regionsm2 = Somereg
Hb2 :
∀a : Z, in_objectm1 a → a < mid ∨ hi ≤ a → m_bytesm2 a = m_bytesm1 a ∧ m_auxm2 a = m_auxm1 a
a :
Z
Hin :
Hout :
a < lo ∨ hi ≤ a
Hin1 :
⊢
m_bytesm2 a = m_bytesm a ∧ m_auxm2 a = m_auxm a

auto

deferred goal
m, m1, m2 :
lo, mid, hi :
Z
Hbounds :
lo ≤ mid ≤ hi
Hr1 :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm1 = Somereg
Hb1 :
∀a : Z, in_objectm a → a < lo ∨ mid ≤ a → m_bytesm1 a = m_bytesm a ∧ m_auxm1 a = m_auxm a
Hr2 :
∀b : Z reg : region, object_regionb m_regionsm1 = Somereg → object_regionb m_regionsm2 = Somereg
Hb2 :
∀a : Z, in_objectm1 a → a < mid ∨ hi ≤ a → m_bytesm2 a = m_bytesm1 a ∧ m_auxm2 a = m_auxm1 a
a :
Z
Hin :
Hout :
a < lo ∨ hi ≤ a
Hin1 :
⊢
m_bytesm2 a = m_bytesm a ∧ m_auxm2 a = m_auxm a

destruct Hb2a Hin1 ltac:lia as Hbytes Haux

m, m1, m2 :
lo, mid, hi :
Z
Hbounds :
lo ≤ mid ≤ hi
Hr1 :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm1 = Somereg
Hb1 :
∀a : Z, in_objectm a → a < lo ∨ mid ≤ a → m_bytesm1 a = m_bytesm a ∧ m_auxm1 a = m_auxm a
Hr2 :
∀b : Z reg : region, object_regionb m_regionsm1 = Somereg → object_regionb m_regionsm2 = Somereg
Hb2 :
∀a : Z, in_objectm1 a → a < mid ∨ hi ≤ a → m_bytesm2 a = m_bytesm1 a ∧ m_auxm2 a = m_auxm1 a
a :
Z
Hin :
Hout :
a < lo ∨ hi ≤ a
Hin1 :
Hbytes :
m_bytesm2 a = m_bytesm1 a
Haux :
m_auxm2 a = m_auxm1 a
⊢
m_bytesm2 a = m_bytesm a ∧ m_auxm2 a = m_auxm a

rewrite Hbytes , Haux

m, m1, m2 :
lo, mid, hi :
Z
Hbounds :
lo ≤ mid ≤ hi
Hr1 :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → object_regionb m_regionsm1 = Somereg
Hb1 :
∀a : Z, in_objectm a → a < lo ∨ mid ≤ a → m_bytesm1 a = m_bytesm a ∧ m_auxm1 a = m_auxm a
Hr2 :
∀b : Z reg : region, object_regionb m_regionsm1 = Somereg → object_regionb m_regionsm2 = Somereg
Hb2 :
∀a : Z, in_objectm1 a → a < mid ∨ hi ≤ a → m_bytesm2 a = m_bytesm1 a ∧ m_auxm2 a = m_auxm1 a
a :
Z
Hin :
Hout :
a < lo ∨ hi ≤ a
Hin1 :
Hbytes :
m_bytesm2 a = m_bytesm1 a
Haux :
m_auxm2 a = m_auxm1 a
⊢
m_bytesm1 a = m_bytesm a ∧ m_auxm1 a = m_auxm a

apply Hb1 ; auto ; lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m m1 m2 lo mid hi Hbounds Hr1 Hb1 Hr2 Hb2
split
–intros b reg H
auto
–intros a Hin Hout
assert Hin1 : in_objectm1 a
{destruct Hin as b & reg & E & H
exists b, reg
auto
destruct Hb2a Hin1 ltac:lia as Hbytes Haux
rewrite Hbytes , Haux
apply Hb1 ; auto ; lia

A store writes the address bytes and the capability of a pointer.

381Definition startup_storem : mem a : Z p : ptr : mem ≔

A pointer store frames every old byte and capability outside its slot.

385Lemma startup_store_frame
∀ m a p
Explore proof 15 tactics

Initial goal

⊢
∀m : mem a : Z p : ptr, startup_framem startup_storem a p a a + 8

intros m a p

m :
a :
Z
p :
⊢

split ; intros ; assumption |

m :
a :
Z
p :
⊢
∀a0 : Z, in_objectm a0 → a0 < a ∨ a + 8 ≤ a0 → m_bytesstartup_storem a p a0 = m_bytesm a0 ∧ m_auxstartup_storem a p a0 = m_auxm a0

intros b Hin Hout

m :
a :
Z
p :
b :
Z
Hin :
Hout :
b < a ∨ a + 8 ≤ b
⊢
m_bytesstartup_storem a p b = m_bytesm b ∧ m_auxstartup_storem a p b = m_auxm b

unfold startup_store

m :
a :
Z
p :
b :
Z
Hin :
Hout :
b < a ∨ a + 8 ≤ b

simpl

m :
a :
Z
p :
b :
Z
Hin :
Hout :
b < a ∨ a + 8 ≤ b
⊢
a ≤? b && b <? a + 8
→
byte_ofptr_addrp b − a
else
=
∧
b =? a
→
else
=

assert a ≤? b && b <? a + 8 = false as E

2 open

m :
a :
Z
p :
b :
Z
Hin :
Hout :
b < a ∨ a + 8 ≤ b
⊢
a ≤? b && b <? a + 8 = false
focused goal
m :
a :
Z
p :
b :
Z
Hin :
Hout :
b < a ∨ a + 8 ≤ b
E :
a ≤? b && b <? a + 8 = false
⊢
a ≤? b && b <? a + 8
→
byte_ofptr_addrp b − a
else
=
∧
b =? a
→
else
=

{apply Bool.not_true_is_false

2 open

m :
a :
Z
p :
b :
Z
Hin :
Hout :
b < a ∨ a + 8 ≤ b
⊢
a ≤? b && b <? a + 8 ≠ true
deferred goal
m :
a :
Z
p :
b :
Z
Hin :
Hout :
b < a ∨ a + 8 ≤ b
E :
a ≤? b && b <? a + 8 = false
⊢
a ≤? b && b <? a + 8
→
byte_ofptr_addrp b − a
else
=
∧
b =? a
→
else
=

intros H

2 open

m :
a :
Z
p :
b :
Z
Hin :
Hout :
b < a ∨ a + 8 ≤ b
H :
a ≤? b && b <? a + 8 = true
⊢
False
deferred goal
m :
a :
Z
p :
b :
Z
Hin :
Hout :
b < a ∨ a + 8 ≤ b
E :
a ≤? b && b <? a + 8 = false
⊢
a ≤? b && b <? a + 8
→
byte_ofptr_addrp b − a
else
=
∧
b =? a
→
else
=

apply andb_true_iff in H as H1 H2

2 open

m :
a :
Z
p :
b :
Z
Hin :
Hout :
b < a ∨ a + 8 ≤ b
H1 :
a ≤? b = true
H2 :
b <? a + 8 = true
⊢
False
deferred goal
m :
a :
Z
p :
b :
Z
Hin :
Hout :
b < a ∨ a + 8 ≤ b
E :
a ≤? b && b <? a + 8 = false
⊢
a ≤? b && b <? a + 8
→
byte_ofptr_addrp b − a
else
=
∧
b =? a
→
else
=

apply Z.leb_le in H1

2 open

m :
a :
Z
p :
b :
Z
Hin :
Hout :
b < a ∨ a + 8 ≤ b
H1 :
a ≤ b
H2 :
b <? a + 8 = true
⊢
False
deferred goal
m :
a :
Z
p :
b :
Z
Hin :
Hout :
b < a ∨ a + 8 ≤ b
E :
a ≤? b && b <? a + 8 = false
⊢
a ≤? b && b <? a + 8
→
byte_ofptr_addrp b − a
else
=
∧
b =? a
→
else
=

apply Z.ltb_lt in H2

2 open

m :
a :
Z
p :
b :
Z
Hin :
Hout :
b < a ∨ a + 8 ≤ b
H1 :
a ≤ b
H2 :
b < a + 8
⊢
False
deferred goal
m :
a :
Z
p :
b :
Z
Hin :
Hout :
b < a ∨ a + 8 ≤ b
E :
a ≤? b && b <? a + 8 = false
⊢
a ≤? b && b <? a + 8
→
byte_ofptr_addrp b − a
else
=
∧
b =? a
→
else
=

lia

deferred goal
m :
a :
Z
p :
b :
Z
Hin :
Hout :
b < a ∨ a + 8 ≤ b
E :
a ≤? b && b <? a + 8 = false
⊢
a ≤? b && b <? a + 8
→
byte_ofptr_addrp b − a
else
=
∧
b =? a
→
else
=

assert b =? a = false as E′ by apply Z.eqb_neq ; lia

m :
a :
Z
p :
b :
Z
Hin :
Hout :
b < a ∨ a + 8 ≤ b
E :
a ≤? b && b <? a + 8 = false
E′ :
b =? a = false
⊢
a ≤? b && b <? a + 8
→
byte_ofptr_addrp b − a
else
=
∧
b =? a
→
else
=

rewrite E , E′

m :
a :
Z
p :
b :
Z
Hin :
Hout :
b < a ∨ a + 8 ≤ b
E :
a ≤? b && b <? a + 8 = false
E′ :
b =? a = false
⊢
m_bytesm b = m_bytesm b ∧ m_auxm b = m_auxm b

auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m a p
split ; intros ; assumption |
intros b Hin Hout
simpl
assert a ≤? b && b <? a + 8 = false as E
{apply Bool.not_true_is_false
intros H
apply andb_true_iff in H as H1 H2
apply Z.leb_le in H1
apply Z.ltb_lt in H2
lia
assert b =? a = false as E′ by apply Z.eqb_neq ; lia
rewrite E , E′
auto

An old checked pointer slot survives a frame disjoint from its eight bytes.

397Lemma startup_frame_slot
∀ m m′ lo hi a p
startup_framem m′ lo hi
∀b, a ≤ b < a + 8 → in_objectm b
∀b, a ≤ b < a + 8 → b < lo ∨ hi ≤ b
pointer_slotm′ a p
Explore proof 9 tactics

Initial goal

⊢
∀m m′ : mem lo hi a : Z p : ptr, startup_framem m′ lo hi → ∀b : Z, a ≤ b < a + 8 → in_objectm b → ∀b : Z, a ≤ b < a + 8 → b < lo ∨ hi ≤ b → pointer_slotm a p → pointer_slotm′ a p

intros m m′ lo hi a p _ Hb Ha Hdis Hp Hbytes Haux

m, m′ :
lo, hi, a :
Z
p :
Hb :
∀a : Z, in_objectm a → a < lo ∨ hi ≤ a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Ha :
∀b : Z, a ≤ b < a + 8 → in_objectm b
Hdis :
∀b : Z, a ≤ b < a + 8 → b < lo ∨ hi ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm a = ptr_capp
⊢
pointer_slotm′ a p

split ; exact Hp |

m, m′ :
lo, hi, a :
Z
p :
Hb :
∀a : Z, in_objectm a → a < lo ∨ hi ≤ a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Ha :
∀b : Z, a ≤ b < a + 8 → in_objectm b
Hdis :
∀b : Z, a ≤ b < a + 8 → b < lo ∨ hi ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm a = ptr_capp
⊢
load_bytesm′ a 8 = ptr_addrp ∧ m_auxm′ a = ptr_capp

split

2 open

m, m′ :
lo, hi, a :
Z
p :
Hb :
∀a : Z, in_objectm a → a < lo ∨ hi ≤ a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Ha :
∀b : Z, a ≤ b < a + 8 → in_objectm b
Hdis :
∀b : Z, a ≤ b < a + 8 → b < lo ∨ hi ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm a = ptr_capp
⊢
load_bytesm′ a 8 = ptr_addrp
focused goal
m, m′ :
lo, hi, a :
Z
p :
Hb :
∀a : Z, in_objectm a → a < lo ∨ hi ≤ a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Ha :
∀b : Z, a ≤ b < a + 8 → in_objectm b
Hdis :
∀b : Z, a ≤ b < a + 8 → b < lo ∨ hi ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm a = ptr_capp
⊢
m_auxm′ a = ptr_capp

–rewrite <- Hbytes

2 open

m, m′ :
lo, hi, a :
Z
p :
Hb :
∀a : Z, in_objectm a → a < lo ∨ hi ≤ a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Ha :
∀b : Z, a ≤ b < a + 8 → in_objectm b
Hdis :
∀b : Z, a ≤ b < a + 8 → b < lo ∨ hi ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm a = ptr_capp
⊢
load_bytesm′ a 8 = load_bytesm a 8
deferred goal
m, m′ :
lo, hi, a :
Z
p :
Hb :
∀a : Z, in_objectm a → a < lo ∨ hi ≤ a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Ha :
∀b : Z, a ≤ b < a + 8 → in_objectm b
Hdis :
∀b : Z, a ≤ b < a + 8 → b < lo ∨ hi ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm a = ptr_capp
⊢
m_auxm′ a = ptr_capp

apply load_bytes_agree ; lia |

2 open

m, m′ :
lo, hi, a :
Z
p :
Hb :
∀a : Z, in_objectm a → a < lo ∨ hi ≤ a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Ha :
∀b : Z, a ≤ b < a + 8 → in_objectm b
Hdis :
∀b : Z, a ≤ b < a + 8 → b < lo ∨ hi ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm a = ptr_capp
⊢
∀i : Z, 0 ≤ i < 8 → m_bytesm′ a + i = m_bytesm a + i
deferred goal
m, m′ :
lo, hi, a :
Z
p :
Hb :
∀a : Z, in_objectm a → a < lo ∨ hi ≤ a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Ha :
∀b : Z, a ≤ b < a + 8 → in_objectm b
Hdis :
∀b : Z, a ≤ b < a + 8 → b < lo ∨ hi ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm a = ptr_capp
⊢
m_auxm′ a = ptr_capp

intros i Hi

2 open

m, m′ :
lo, hi, a :
Z
p :
Hb :
∀a : Z, in_objectm a → a < lo ∨ hi ≤ a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Ha :
∀b : Z, a ≤ b < a + 8 → in_objectm b
Hdis :
∀b : Z, a ≤ b < a + 8 → b < lo ∨ hi ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm a = ptr_capp
i :
Z
Hi :
0 ≤ i < 8
⊢
m_bytesm′ a + i = m_bytesm a + i
deferred goal
m, m′ :
lo, hi, a :
Z
p :
Hb :
∀a : Z, in_objectm a → a < lo ∨ hi ≤ a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Ha :
∀b : Z, a ≤ b < a + 8 → in_objectm b
Hdis :
∀b : Z, a ≤ b < a + 8 → b < lo ∨ hi ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm a = ptr_capp
⊢
m_auxm′ a = ptr_capp

apply proj1Hba + i Haa + i ltac:lia Hdisa + i ltac:lia

deferred goal
m, m′ :
lo, hi, a :
Z
p :
Hb :
∀a : Z, in_objectm a → a < lo ∨ hi ≤ a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Ha :
∀b : Z, a ≤ b < a + 8 → in_objectm b
Hdis :
∀b : Z, a ≤ b < a + 8 → b < lo ∨ hi ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm a = ptr_capp
⊢
m_auxm′ a = ptr_capp

–rewrite proj2Hba Haa ltac:lia Hdisa ltac:lia

m, m′ :
lo, hi, a :
Z
p :
Hb :
∀a : Z, in_objectm a → a < lo ∨ hi ≤ a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Ha :
∀b : Z, a ≤ b < a + 8 → in_objectm b
Hdis :
∀b : Z, a ≤ b < a + 8 → b < lo ∨ hi ≤ b
Hp :
0 ≤ ptr_addrp < 2 ^ 64
Hbytes :
Haux :
m_auxm a = ptr_capp
⊢
m_auxm a = ptr_capp

exact Haux

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m m′ lo hi a p _ Hb Ha Hdis Hp Hbytes Haux
split ; exact Hp |
split
–rewrite <- Hbytes
apply load_bytes_agree ; lia |
intros i Hi
apply proj1Hba + i Haa + i ltac:lia Hdisa + i ltac:lia
–rewrite proj2Hba Haa ltac:lia Hdisa ltac:lia
exact Haux

C-string contents depend only on their payload bytes and final NUL.

410Lemma string_at_agree
∀ bytes m m′ a
∀b, a ≤ b < a + Z.of_natlengthbytes + 1 → m_bytesm′ b = m_bytesm b
string_atm a bytes
string_atm′ a bytes
Explore proof 15 tactics

Initial goal

⊢
∀bytes : listZ m m′ : mem a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthbytes + 1 → m_bytesm′ b = m_bytesm b → string_atm a bytes → string_atm′ a bytes

induction bytes as | b rest IH ; intros m m′ a Hb Hs

2 open

m, m′ :
a :
Z
Hb :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.length[ ] + 1 → m_bytesm′ b = m_bytesm b
Hs :
string_atm a [ ]
⊢
string_atm′ a [ ]
focused goal
b :
Z
rest :
listZ
IH :
∀m m′ : mem a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → m_bytesm′ b = m_bytesm b → string_atm a rest → string_atm′ a rest
m, m′ :
a :
Z
Hb :
∀b0 : Z, a ≤ b0 < a + Z.of_natDatatypes.lengthb :: rest + 1 → m_bytesm′ b0 = m_bytesm b0
Hs :
string_atm a b :: rest
⊢
string_atm′ a b :: rest

–simpl in *

2 open

m, m′ :
a :
Z
Hb :
∀b : Z, a ≤ b < a + 0 + 1 → m_bytesm′ b = m_bytesm b
Hs :
m_bytesm a = 0
⊢
m_bytesm′ a = 0
deferred goal
b :
Z
rest :
listZ
IH :
∀m m′ : mem a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → m_bytesm′ b = m_bytesm b → string_atm a rest → string_atm′ a rest
m, m′ :
a :
Z
Hb :
∀b0 : Z, a ≤ b0 < a + Z.of_natDatatypes.lengthb :: rest + 1 → m_bytesm′ b0 = m_bytesm b0
Hs :
string_atm a b :: rest
⊢
string_atm′ a b :: rest

rewrite Hb by lia

2 open

m, m′ :
a :
Z
Hb :
∀b : Z, a ≤ b < a + 0 + 1 → m_bytesm′ b = m_bytesm b
Hs :
m_bytesm a = 0
⊢
m_bytesm a = 0
deferred goal
b :
Z
rest :
listZ
IH :
∀m m′ : mem a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → m_bytesm′ b = m_bytesm b → string_atm a rest → string_atm′ a rest
m, m′ :
a :
Z
Hb :
∀b0 : Z, a ≤ b0 < a + Z.of_natDatatypes.lengthb :: rest + 1 → m_bytesm′ b0 = m_bytesm b0
Hs :
string_atm a b :: rest
⊢
string_atm′ a b :: rest

exact Hs

deferred goal
b :
Z
rest :
listZ
IH :
∀m m′ : mem a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → m_bytesm′ b = m_bytesm b → string_atm a rest → string_atm′ a rest
m, m′ :
a :
Z
Hb :
∀b0 : Z, a ≤ b0 < a + Z.of_natDatatypes.lengthb :: rest + 1 → m_bytesm′ b0 = m_bytesm b0
Hs :
string_atm a b :: rest
⊢
string_atm′ a b :: rest

–destruct Hs as Hbyte Hhead Hrest

b :
Z
rest :
listZ
IH :
∀m m′ : mem a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → m_bytesm′ b = m_bytesm b → string_atm a rest → string_atm′ a rest
m, m′ :
a :
Z
Hb :
∀b0 : Z, a ≤ b0 < a + Z.of_natDatatypes.lengthb :: rest + 1 → m_bytesm′ b0 = m_bytesm b0
Hbyte :
0 < b < 256
Hhead :
m_bytesm a = b
Hrest :
string_atm a + 1 rest
⊢
string_atm′ a b :: rest

simpl

b :
Z
rest :
listZ
IH :
∀m m′ : mem a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → m_bytesm′ b = m_bytesm b → string_atm a rest → string_atm′ a rest
m, m′ :
a :
Z
Hb :
∀b0 : Z, a ≤ b0 < a + Z.of_natDatatypes.lengthb :: rest + 1 → m_bytesm′ b0 = m_bytesm b0
Hbyte :
0 < b < 256
Hhead :
m_bytesm a = b
Hrest :
string_atm a + 1 rest
⊢
0 < b < 256 ∧ m_bytesm′ a = b ∧ string_atm′ a + 1 rest

split ; exact Hbyte |

b :
Z
rest :
listZ
IH :
∀m m′ : mem a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → m_bytesm′ b = m_bytesm b → string_atm a rest → string_atm′ a rest
m, m′ :
a :
Z
Hb :
∀b0 : Z, a ≤ b0 < a + Z.of_natDatatypes.lengthb :: rest + 1 → m_bytesm′ b0 = m_bytesm b0
Hbyte :
0 < b < 256
Hhead :
m_bytesm a = b
Hrest :
string_atm a + 1 rest
⊢
m_bytesm′ a = b ∧ string_atm′ a + 1 rest

split

2 open

b :
Z
rest :
listZ
IH :
∀m m′ : mem a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → m_bytesm′ b = m_bytesm b → string_atm a rest → string_atm′ a rest
m, m′ :
a :
Z
Hb :
∀b0 : Z, a ≤ b0 < a + Z.of_natDatatypes.lengthb :: rest + 1 → m_bytesm′ b0 = m_bytesm b0
Hbyte :
0 < b < 256
Hhead :
m_bytesm a = b
Hrest :
string_atm a + 1 rest
⊢
m_bytesm′ a = b
focused goal
b :
Z
rest :
listZ
IH :
∀m m′ : mem a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → m_bytesm′ b = m_bytesm b → string_atm a rest → string_atm′ a rest
m, m′ :
a :
Z
Hb :
∀b0 : Z, a ≤ b0 < a + Z.of_natDatatypes.lengthb :: rest + 1 → m_bytesm′ b0 = m_bytesm b0
Hbyte :
0 < b < 256
Hhead :
m_bytesm a = b
Hrest :
string_atm a + 1 rest
⊢
string_atm′ a + 1 rest

+rewrite Hb ; exact Hhead | simpl ; lia

deferred goal
b :
Z
rest :
listZ
IH :
∀m m′ : mem a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → m_bytesm′ b = m_bytesm b → string_atm a rest → string_atm′ a rest
m, m′ :
a :
Z
Hb :
∀b0 : Z, a ≤ b0 < a + Z.of_natDatatypes.lengthb :: rest + 1 → m_bytesm′ b0 = m_bytesm b0
Hbyte :
0 < b < 256
Hhead :
m_bytesm a = b
Hrest :
string_atm a + 1 rest
⊢
string_atm′ a + 1 rest

+apply IHm m′ ; | exact Hrest

b :
Z
rest :
listZ
IH :
∀m m′ : mem a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → m_bytesm′ b = m_bytesm b → string_atm a rest → string_atm′ a rest
m, m′ :
a :
Z
Hb :
∀b0 : Z, a ≤ b0 < a + Z.of_natDatatypes.lengthb :: rest + 1 → m_bytesm′ b0 = m_bytesm b0
Hbyte :
0 < b < 256
Hhead :
m_bytesm a = b
Hrest :
string_atm a + 1 rest
⊢
∀b0 : Z, a + 1 ≤ b0 < a + 1 + Z.of_natDatatypes.lengthrest + 1 → m_bytesm′ b0 = m_bytesm b0

intros x Hx

b :
Z
rest :
listZ
IH :
∀m m′ : mem a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → m_bytesm′ b = m_bytesm b → string_atm a rest → string_atm′ a rest
m, m′ :
a :
Z
Hb :
∀b0 : Z, a ≤ b0 < a + Z.of_natDatatypes.lengthb :: rest + 1 → m_bytesm′ b0 = m_bytesm b0
Hbyte :
0 < b < 256
Hhead :
m_bytesm a = b
Hrest :
string_atm a + 1 rest
x :
Z
Hx :
a + 1 ≤ x < a + 1 + Z.of_natDatatypes.lengthrest + 1
⊢
m_bytesm′ x = m_bytesm x

apply Hb

b :
Z
rest :
listZ
IH :
∀m m′ : mem a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → m_bytesm′ b = m_bytesm b → string_atm a rest → string_atm′ a rest
m, m′ :
a :
Z
Hb :
∀b0 : Z, a ≤ b0 < a + Z.of_natDatatypes.lengthb :: rest + 1 → m_bytesm′ b0 = m_bytesm b0
Hbyte :
0 < b < 256
Hhead :
m_bytesm a = b
Hrest :
string_atm a + 1 rest
x :
Z
Hx :
a + 1 ≤ x < a + 1 + Z.of_natDatatypes.lengthrest + 1
⊢
a ≤ x < a + Z.of_natDatatypes.lengthb :: rest + 1

change a ≤ x < a + Z.of_natSlengthrest + 1

b :
Z
rest :
listZ
IH :
∀m m′ : mem a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → m_bytesm′ b = m_bytesm b → string_atm a rest → string_atm′ a rest
m, m′ :
a :
Z
Hb :
∀b0 : Z, a ≤ b0 < a + Z.of_natDatatypes.lengthb :: rest + 1 → m_bytesm′ b0 = m_bytesm b0
Hbyte :
0 < b < 256
Hhead :
m_bytesm a = b
Hrest :
string_atm a + 1 rest
x :
Z
Hx :
a + 1 ≤ x < a + 1 + Z.of_natDatatypes.lengthrest + 1
⊢
a ≤ x < a + Z.of_natSDatatypes.lengthrest + 1

rewrite Nat2Z.inj_succ

b :
Z
rest :
listZ
IH :
∀m m′ : mem a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → m_bytesm′ b = m_bytesm b → string_atm a rest → string_atm′ a rest
m, m′ :
a :
Z
Hb :
∀b0 : Z, a ≤ b0 < a + Z.of_natDatatypes.lengthb :: rest + 1 → m_bytesm′ b0 = m_bytesm b0
Hbyte :
0 < b < 256
Hhead :
m_bytesm a = b
Hrest :
string_atm a + 1 rest
x :
Z
Hx :
a + 1 ≤ x < a + 1 + Z.of_natDatatypes.lengthrest + 1
⊢
a ≤ x < a + Z.succZ.of_natDatatypes.lengthrest + 1

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
induction bytes as | b rest IH ; intros m m′ a Hb Hs
–simpl in *
rewrite Hb by lia
exact Hs
–destruct Hs as Hbyte Hhead Hrest
simpl
split ; exact Hbyte |
split
+rewrite Hb ; exact Hhead | simpl ; lia
+apply IHm m′ ; | exact Hrest
intros x Hx
apply Hb
change a ≤ x < a + Z.of_natSlengthrest + 1
rewrite Nat2Z.inj_succ
lia

A frame disjoint from an old string preserves its complete checked NUL.

424Lemma startup_frame_string
∀ m m′ lo hi p bytes
startup_framem m′ lo hi
c_stringm p bytes
∀a, ptr_addrp ≤ a < ptr_addrp + Z.of_natlengthbytes + 1 → a < lo ∨ hi ≤ a
c_stringm′ p bytes
Explore proof 6 tactics

Initial goal

⊢
∀m m′ : mem lo hi : Z p : ptr bytes : listZ, startup_framem m′ lo hi → c_stringm p bytes → ∀a : Z, ptr_addrp ≤ a < ptr_addrp + Z.of_natDatatypes.lengthbytes + 1 → a < lo ∨ hi ≤ a → c_stringm′ p bytes

intros m m′ lo hi p bytes Hf Ha Hs Hdis

m, m′ :
lo, hi :
Z
p :
bytes :
listZ
Hf :
startup_framem m′ lo hi
Ha :
access_resm ptr_addrp ptr_capp Z.of_natDatatypes.lengthbytes + 1 Read 1 = Someok
Hs :
Hdis :
∀a : Z, ptr_addrp ≤ a < ptr_addrp + Z.of_natDatatypes.lengthbytes + 1 → a < lo ∨ hi ≤ a
⊢
c_stringm′ p bytes

split

2 open

m, m′ :
lo, hi :
Z
p :
bytes :
listZ
Hf :
startup_framem m′ lo hi
Ha :
access_resm ptr_addrp ptr_capp Z.of_natDatatypes.lengthbytes + 1 Read 1 = Someok
Hs :
Hdis :
∀a : Z, ptr_addrp ≤ a < ptr_addrp + Z.of_natDatatypes.lengthbytes + 1 → a < lo ∨ hi ≤ a
⊢
access_resm′ ptr_addrp ptr_capp Z.of_natDatatypes.lengthbytes + 1 Read 1 = Someok
focused goal
m, m′ :
lo, hi :
Z
p :
bytes :
listZ
Hf :
startup_framem m′ lo hi
Ha :
access_resm ptr_addrp ptr_capp Z.of_natDatatypes.lengthbytes + 1 Read 1 = Someok
Hs :
Hdis :
∀a : Z, ptr_addrp ≤ a < ptr_addrp + Z.of_natDatatypes.lengthbytes + 1 → a < lo ∨ hi ≤ a
⊢
string_atm′ ptr_addrp bytes

–eapply startup_frame_access ; eauto

deferred goal
m, m′ :
lo, hi :
Z
p :
bytes :
listZ
Hf :
startup_framem m′ lo hi
Ha :
access_resm ptr_addrp ptr_capp Z.of_natDatatypes.lengthbytes + 1 Read 1 = Someok
Hs :
Hdis :
∀a : Z, ptr_addrp ≤ a < ptr_addrp + Z.of_natDatatypes.lengthbytes + 1 → a < lo ∨ hi ≤ a
⊢
string_atm′ ptr_addrp bytes

–eapply string_at_agree ; | exact Hs

m, m′ :
lo, hi :
Z
p :
bytes :
listZ
Hf :
startup_framem m′ lo hi
Ha :
access_resm ptr_addrp ptr_capp Z.of_natDatatypes.lengthbytes + 1 Read 1 = Someok
Hs :
Hdis :
∀a : Z, ptr_addrp ≤ a < ptr_addrp + Z.of_natDatatypes.lengthbytes + 1 → a < lo ∨ hi ≤ a
⊢
∀b : Z, ptr_addrp ≤ b < ptr_addrp + Z.of_natDatatypes.lengthbytes + 1 → m_bytesm′ b = m_bytesm b

intros a Hrange

m, m′ :
lo, hi :
Z
p :
bytes :
listZ
Hf :
startup_framem m′ lo hi
Ha :
access_resm ptr_addrp ptr_capp Z.of_natDatatypes.lengthbytes + 1 Read 1 = Someok
Hs :
Hdis :
∀a : Z, ptr_addrp ≤ a < ptr_addrp + Z.of_natDatatypes.lengthbytes + 1 → a < lo ∨ hi ≤ a
a :
Z
Hrange :
ptr_addrp ≤ a < ptr_addrp + Z.of_natDatatypes.lengthbytes + 1
⊢
m_bytesm′ a = m_bytesm a

apply proj1proj2Hf a ltac:eapply access_in ; exact Ha | lia Hdisa Hrange

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m m′ lo hi p bytes Hf Ha Hs Hdis
split
–eapply startup_frame_access ; eauto
–eapply string_at_agree ; | exact Hs
intros a Hrange
apply proj1proj2Hf a ltac:eapply access_in ; exact Ha | lia Hdisa Hrange

A construction that frames every old object retains old vectors too.

436Lemma startup_frame_slots
∀ texts m m′ a
startup_framem m′ 0 0
∀b, a ≤ b < a + 8 × Z.of_natlengthtexts + 1 → in_objectm b
string_slotsm a texts
string_slotsm′ a texts
Explore proof 24 tactics

Initial goal

⊢
∀texts : listlistZ m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtexts + 1 → in_objectm b → string_slotsm a texts → string_slotsm′ a texts

induction texts as | text rest IH ; intros m m′ a Hf Hin Hslots

2 open

m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.length[ ] + 1 → in_objectm b
Hslots :
⊢
string_slotsm′ a [ ]
focused goal
text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
Hslots :
string_slotsm a text :: rest
⊢
string_slotsm′ a text :: rest

–eapply startup_frame_slot ; exact Hf | | intros ; lia | exact Hslots

2 open

m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.length[ ] + 1 → in_objectm b
Hslots :
⊢
∀b : Z, a ≤ b < a + 8 → in_objectm b
deferred goal
text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
Hslots :
string_slotsm a text :: rest
⊢
string_slotsm′ a text :: rest

intros b Hb

2 open

m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.length[ ] + 1 → in_objectm b
Hslots :
b :
Z
Hb :
a ≤ b < a + 8
⊢
deferred goal
text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
Hslots :
string_slotsm a text :: rest
⊢
string_slotsm′ a text :: rest

apply Hin

2 open

m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.length[ ] + 1 → in_objectm b
Hslots :
b :
Z
Hb :
a ≤ b < a + 8
⊢
a ≤ b < a + 8 × Z.of_natDatatypes.length[ ] + 1
deferred goal
text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
Hslots :
string_slotsm a text :: rest
⊢
string_slotsm′ a text :: rest

simpl

2 open

m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.length[ ] + 1 → in_objectm b
Hslots :
b :
Z
Hb :
a ≤ b < a + 8
⊢
a ≤ b < a + 8
deferred goal
text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
Hslots :
string_slotsm a text :: rest
⊢
string_slotsm′ a text :: rest

lia

deferred goal
text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
Hslots :
string_slotsm a text :: rest
⊢
string_slotsm′ a text :: rest

–destruct Hslots as p & Hp & Hs & Hr

text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
⊢
string_slotsm′ a text :: rest

exists p

text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
⊢
pointer_slotm′ a p ∧ c_stringm′ p text ∧ string_slotsm′ a + 8 rest

split

2 open

text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
⊢
pointer_slotm′ a p
focused goal
text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
⊢
c_stringm′ p text ∧ string_slotsm′ a + 8 rest

+eapply startup_frame_slot ; exact Hf | | intros ; lia | exact Hp

2 open

text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
⊢
∀b : Z, a ≤ b < a + 8 → in_objectm b
deferred goal
text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
⊢
c_stringm′ p text ∧ string_slotsm′ a + 8 rest

intros b Hb

2 open

text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
b :
Z
Hb :
a ≤ b < a + 8
⊢
deferred goal
text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
⊢
c_stringm′ p text ∧ string_slotsm′ a + 8 rest

apply Hin

2 open

text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
b :
Z
Hb :
a ≤ b < a + 8
⊢
a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1
deferred goal
text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
⊢
c_stringm′ p text ∧ string_slotsm′ a + 8 rest

change a ≤ b < a + 8 × Z.of_natSlengthrest + 1

2 open

text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
b :
Z
Hb :
a ≤ b < a + 8
⊢
a ≤ b < a + 8 × Z.of_natSDatatypes.lengthrest + 1
deferred goal
text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
⊢
c_stringm′ p text ∧ string_slotsm′ a + 8 rest

rewrite Nat2Z.inj_succ

2 open

text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
b :
Z
Hb :
a ≤ b < a + 8
⊢
a ≤ b < a + 8 × Z.succZ.of_natDatatypes.lengthrest + 1
deferred goal
text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
⊢
c_stringm′ p text ∧ string_slotsm′ a + 8 rest

lia

deferred goal
text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
⊢
c_stringm′ p text ∧ string_slotsm′ a + 8 rest

+split

2 open

text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
⊢
c_stringm′ p text
focused goal
text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
⊢
string_slotsm′ a + 8 rest

∗eapply startup_frame_string ; exact Hf | exact Hs |

2 open

text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
⊢
∀a0 : Z, ptr_addrp ≤ a0 < ptr_addrp + Z.of_natDatatypes.lengthtext + 1 → a0 < 0 ∨ 0 ≤ a0
deferred goal
text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
⊢
string_slotsm′ a + 8 rest

intros ; lia

deferred goal
text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
⊢
string_slotsm′ a + 8 rest

∗apply IHm m′ ; exact Hf | | exact Hr

text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
⊢
∀b : Z, a + 8 ≤ b < a + 8 + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b

intros b Hb

text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
b :
Z
Hb :
a + 8 ≤ b < a + 8 + 8 × Z.of_natDatatypes.lengthrest + 1
⊢

apply Hin

text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
b :
Z
Hb :
a + 8 ≤ b < a + 8 + 8 × Z.of_natDatatypes.lengthrest + 1
⊢
a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1

change a ≤ b < a + 8 × Z.of_natSlengthrest + 1

text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
b :
Z
Hb :
a + 8 ≤ b < a + 8 + 8 × Z.of_natDatatypes.lengthrest + 1
⊢
a ≤ b < a + 8 × Z.of_natSDatatypes.lengthrest + 1

rewrite Nat2Z.inj_succ

text :
listZ
rest :
listlistZ
IH :
∀m m′ : mem a : Z, startup_framem m′ 0 0 → ∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthrest + 1 → in_objectm b → string_slotsm a rest → string_slotsm′ a rest
m, m′ :
a :
Z
Hf :
startup_framem m′ 0 0
Hin :
∀b : Z, a ≤ b < a + 8 × Z.of_natDatatypes.lengthtext :: rest + 1 → in_objectm b
p :
Hp :
Hs :
c_stringm p text
Hr :
string_slotsm a + 8 rest
b :
Z
Hb :
a + 8 ≤ b < a + 8 + 8 × Z.of_natDatatypes.lengthrest + 1
⊢
a ≤ b < a + 8 × Z.succZ.of_natDatatypes.lengthrest + 1

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
induction texts as | text rest IH ; intros m m′ a Hf Hin Hslots
–eapply startup_frame_slot ; exact Hf | | intros ; lia | exact Hslots
intros b Hb
apply Hin
simpl
lia
–destruct Hslots as p & Hp & Hs & Hr
exists p
split
+eapply startup_frame_slot ; exact Hf | | intros ; lia | exact Hp
intros b Hb
apply Hin
change a ≤ b < a + 8 × Z.of_natSlengthrest + 1
rewrite Nat2Z.inj_succ
lia
+split
∗eapply startup_frame_string ; exact Hf | exact Hs |
intros ; lia
∗apply IHm m′ ; exact Hf | | exact Hr
intros b Hb
apply Hin
change a ≤ b < a + 8 × Z.of_natSlengthrest + 1
rewrite Nat2Z.inj_succ
lia

The readable pointer array and every pointed-to string survive later copies.

456Lemma startup_frame_vector
∀ m m′ table texts
startup_framem m′ 0 0
string_vectorm table texts
string_vectorm′ table texts
Explore proof 6 tactics

Initial goal

⊢
∀m m′ : mem table : ptr texts : listlistZ, startup_framem m′ 0 0 → string_vectorm table texts → string_vectorm′ table texts

intros m m′ table texts Hf Ha Hslots

m, m′ :
table :
texts :
listlistZ
Hf :
startup_framem m′ 0 0
Ha :
access_resm ptr_addrtable ptr_captable 8 × Z.of_natDatatypes.lengthtexts + 1 Read 8 = Someok
Hslots :
⊢
string_vectorm′ table texts

split

2 open

m, m′ :
table :
texts :
listlistZ
Hf :
startup_framem m′ 0 0
Ha :
access_resm ptr_addrtable ptr_captable 8 × Z.of_natDatatypes.lengthtexts + 1 Read 8 = Someok
Hslots :
⊢
access_resm′ ptr_addrtable ptr_captable 8 × Z.of_natDatatypes.lengthtexts + 1 Read 8 = Someok
focused goal
m, m′ :
table :
texts :
listlistZ
Hf :
startup_framem m′ 0 0
Ha :
access_resm ptr_addrtable ptr_captable 8 × Z.of_natDatatypes.lengthtexts + 1 Read 8 = Someok
Hslots :
⊢
string_slotsm′ ptr_addrtable texts

–eapply startup_frame_access ; eauto

deferred goal
m, m′ :
table :
texts :
listlistZ
Hf :
startup_framem m′ 0 0
Ha :
access_resm ptr_addrtable ptr_captable 8 × Z.of_natDatatypes.lengthtexts + 1 Read 8 = Someok
Hslots :
⊢
string_slotsm′ ptr_addrtable texts

–eapply startup_frame_slots ; exact Hf | | exact Hslots

m, m′ :
table :
texts :
listlistZ
Hf :
startup_framem m′ 0 0
Ha :
access_resm ptr_addrtable ptr_captable 8 × Z.of_natDatatypes.lengthtexts + 1 Read 8 = Someok
Hslots :
⊢
∀b : Z, ptr_addrtable ≤ b < ptr_addrtable + 8 × Z.of_natDatatypes.lengthtexts + 1 → in_objectm b

intros b Hb

m, m′ :
table :
texts :
listlistZ
Hf :
startup_framem m′ 0 0
Ha :
access_resm ptr_addrtable ptr_captable 8 × Z.of_natDatatypes.lengthtexts + 1 Read 8 = Someok
Hslots :
b :
Z
Hb :
ptr_addrtable ≤ b < ptr_addrtable + 8 × Z.of_natDatatypes.lengthtexts + 1
⊢

eapply access_in ; exact Ha | exact Hb

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m m′ table texts Hf Ha Hslots
split
–eapply startup_frame_access ; eauto
–eapply startup_frame_slots ; exact Hf | | exact Hslots
intros b Hb
eapply access_in ; exact Ha | exact Hb

Launcher allocation/copying preserves each exposed old pointer cell, including its write authority, address bytes and capability.

467Lemma startup_frame_exposed_cell
∀ m m′ cell value
startup_framem m′ 0 0
exposed_pointer_cellm′ cell value
Explore proof 16 tactics

Initial goal

⊢
∀m m′ : mem cell value : ptr, startup_framem m′ 0 0 → exposed_pointer_cellm cell value → exposed_pointer_cellm′ cell value

intros m m′ cell value Hframe Hw & Hr & Hwr & Hslot

m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hw :
writable_spanm span_ptr ≔ cell; span_size ≔ 8
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
exposed_pointer_cellm′ cell value

split

2 open

m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hw :
writable_spanm span_ptr ≔ cell; span_size ≔ 8
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
writable_spanm′ span_ptr ≔ cell; span_size ≔ 8
focused goal
m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hw :
writable_spanm span_ptr ≔ cell; span_size ≔ 8
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
access_resm′ ptr_addrcell ptr_capcell 8 Read 8 = Someok ∧ access_resm′ ptr_addrcell ptr_capcell 8 Write 8 = Someok ∧ pointer_slotm′ ptr_addrcell value

–destruct Hw as Hn & b & reg & Hcap & Hreg & Hlive & Ha

2 open

m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hn :
0 ≤ span_sizespan_ptr ≔ cell; span_size ≔ 8
b :
Z
reg :
Hcap :
ptr_capspan_ptrspan_ptr ≔ cell; span_size ≔ 8 = Objb
Hreg :
Hlive :
r_lifereg = Live
Ha :
access_resm ptr_addrspan_ptrspan_ptr ≔ cell; span_size ≔ 8 Objb span_sizespan_ptr ≔ cell; span_size ≔ 8 Write 1 = Someok
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
writable_spanm′ span_ptr ≔ cell; span_size ≔ 8
deferred goal
m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hw :
writable_spanm span_ptr ≔ cell; span_size ≔ 8
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
access_resm′ ptr_addrcell ptr_capcell 8 Read 8 = Someok ∧ access_resm′ ptr_addrcell ptr_capcell 8 Write 8 = Someok ∧ pointer_slotm′ ptr_addrcell value

split ; exact Hn |

2 open

m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hn :
0 ≤ span_sizespan_ptr ≔ cell; span_size ≔ 8
b :
Z
reg :
Hcap :
ptr_capspan_ptrspan_ptr ≔ cell; span_size ≔ 8 = Objb
Hreg :
Hlive :
r_lifereg = Live
Ha :
access_resm ptr_addrspan_ptrspan_ptr ≔ cell; span_size ≔ 8 Objb span_sizespan_ptr ≔ cell; span_size ≔ 8 Write 1 = Someok
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
∃base : Z reg0 : region, ptr_capspan_ptrspan_ptr ≔ cell; span_size ≔ 8 = Objbase ∧ object_regionbase m_regionsm′ = Somereg0 ∧ r_lifereg0 = Live ∧ access_resm′ ptr_addrspan_ptrspan_ptr ≔ cell; span_size ≔ 8 Objbase span_sizespan_ptr ≔ cell; span_size ≔ 8 Write 1 = Someok
deferred goal
m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hw :
writable_spanm span_ptr ≔ cell; span_size ≔ 8
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
access_resm′ ptr_addrcell ptr_capcell 8 Read 8 = Someok ∧ access_resm′ ptr_addrcell ptr_capcell 8 Write 8 = Someok ∧ pointer_slotm′ ptr_addrcell value

exists b, reg

2 open

m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hn :
0 ≤ span_sizespan_ptr ≔ cell; span_size ≔ 8
b :
Z
reg :
Hcap :
ptr_capspan_ptrspan_ptr ≔ cell; span_size ≔ 8 = Objb
Hreg :
Hlive :
r_lifereg = Live
Ha :
access_resm ptr_addrspan_ptrspan_ptr ≔ cell; span_size ≔ 8 Objb span_sizespan_ptr ≔ cell; span_size ≔ 8 Write 1 = Someok
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
ptr_capspan_ptrspan_ptr ≔ cell; span_size ≔ 8 = Objb ∧ object_regionb m_regionsm′ = Somereg ∧ r_lifereg = Live ∧ access_resm′ ptr_addrspan_ptrspan_ptr ≔ cell; span_size ≔ 8 Objb span_sizespan_ptr ≔ cell; span_size ≔ 8 Write 1 = Someok
deferred goal
m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hw :
writable_spanm span_ptr ≔ cell; span_size ≔ 8
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
access_resm′ ptr_addrcell ptr_capcell 8 Read 8 = Someok ∧ access_resm′ ptr_addrcell ptr_capcell 8 Write 8 = Someok ∧ pointer_slotm′ ptr_addrcell value

split ; exact Hcap |

2 open

m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hn :
0 ≤ span_sizespan_ptr ≔ cell; span_size ≔ 8
b :
Z
reg :
Hcap :
ptr_capspan_ptrspan_ptr ≔ cell; span_size ≔ 8 = Objb
Hreg :
Hlive :
r_lifereg = Live
Ha :
access_resm ptr_addrspan_ptrspan_ptr ≔ cell; span_size ≔ 8 Objb span_sizespan_ptr ≔ cell; span_size ≔ 8 Write 1 = Someok
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
object_regionb m_regionsm′ = Somereg ∧ r_lifereg = Live ∧ access_resm′ ptr_addrspan_ptrspan_ptr ≔ cell; span_size ≔ 8 Objb span_sizespan_ptr ≔ cell; span_size ≔ 8 Write 1 = Someok
deferred goal
m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hw :
writable_spanm span_ptr ≔ cell; span_size ≔ 8
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
access_resm′ ptr_addrcell ptr_capcell 8 Read 8 = Someok ∧ access_resm′ ptr_addrcell ptr_capcell 8 Write 8 = Someok ∧ pointer_slotm′ ptr_addrcell value

split

3 open

m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hn :
0 ≤ span_sizespan_ptr ≔ cell; span_size ≔ 8
b :
Z
reg :
Hcap :
ptr_capspan_ptrspan_ptr ≔ cell; span_size ≔ 8 = Objb
Hreg :
Hlive :
r_lifereg = Live
Ha :
access_resm ptr_addrspan_ptrspan_ptr ≔ cell; span_size ≔ 8 Objb span_sizespan_ptr ≔ cell; span_size ≔ 8 Write 1 = Someok
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
object_regionb m_regionsm′ = Somereg
focused goal
m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hn :
0 ≤ span_sizespan_ptr ≔ cell; span_size ≔ 8
b :
Z
reg :
Hcap :
ptr_capspan_ptrspan_ptr ≔ cell; span_size ≔ 8 = Objb
Hreg :
Hlive :
r_lifereg = Live
Ha :
access_resm ptr_addrspan_ptrspan_ptr ≔ cell; span_size ≔ 8 Objb span_sizespan_ptr ≔ cell; span_size ≔ 8 Write 1 = Someok
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
r_lifereg = Live ∧ access_resm′ ptr_addrspan_ptrspan_ptr ≔ cell; span_size ≔ 8 Objb span_sizespan_ptr ≔ cell; span_size ≔ 8 Write 1 = Someok
deferred goal
m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hw :
writable_spanm span_ptr ≔ cell; span_size ≔ 8
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
access_resm′ ptr_addrcell ptr_capcell 8 Read 8 = Someok ∧ access_resm′ ptr_addrcell ptr_capcell 8 Write 8 = Someok ∧ pointer_slotm′ ptr_addrcell value

+apply proj1Hframe

3 open

m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hn :
0 ≤ span_sizespan_ptr ≔ cell; span_size ≔ 8
b :
Z
reg :
Hcap :
ptr_capspan_ptrspan_ptr ≔ cell; span_size ≔ 8 = Objb
Hreg :
Hlive :
r_lifereg = Live
Ha :
access_resm ptr_addrspan_ptrspan_ptr ≔ cell; span_size ≔ 8 Objb span_sizespan_ptr ≔ cell; span_size ≔ 8 Write 1 = Someok
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
deferred goal
m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hn :
0 ≤ span_sizespan_ptr ≔ cell; span_size ≔ 8
b :
Z
reg :
Hcap :
ptr_capspan_ptrspan_ptr ≔ cell; span_size ≔ 8 = Objb
Hreg :
Hlive :
r_lifereg = Live
Ha :
access_resm ptr_addrspan_ptrspan_ptr ≔ cell; span_size ≔ 8 Objb span_sizespan_ptr ≔ cell; span_size ≔ 8 Write 1 = Someok
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
r_lifereg = Live ∧ access_resm′ ptr_addrspan_ptrspan_ptr ≔ cell; span_size ≔ 8 Objb span_sizespan_ptr ≔ cell; span_size ≔ 8 Write 1 = Someok
deferred goal
m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hw :
writable_spanm span_ptr ≔ cell; span_size ≔ 8
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
access_resm′ ptr_addrcell ptr_capcell 8 Read 8 = Someok ∧ access_resm′ ptr_addrcell ptr_capcell 8 Write 8 = Someok ∧ pointer_slotm′ ptr_addrcell value

exact Hreg

2 open

deferred goal
m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hn :
0 ≤ span_sizespan_ptr ≔ cell; span_size ≔ 8
b :
Z
reg :
Hcap :
ptr_capspan_ptrspan_ptr ≔ cell; span_size ≔ 8 = Objb
Hreg :
Hlive :
r_lifereg = Live
Ha :
access_resm ptr_addrspan_ptrspan_ptr ≔ cell; span_size ≔ 8 Objb span_sizespan_ptr ≔ cell; span_size ≔ 8 Write 1 = Someok
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
r_lifereg = Live ∧ access_resm′ ptr_addrspan_ptrspan_ptr ≔ cell; span_size ≔ 8 Objb span_sizespan_ptr ≔ cell; span_size ≔ 8 Write 1 = Someok
deferred goal
m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hw :
writable_spanm span_ptr ≔ cell; span_size ≔ 8
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
access_resm′ ptr_addrcell ptr_capcell 8 Read 8 = Someok ∧ access_resm′ ptr_addrcell ptr_capcell 8 Write 8 = Someok ∧ pointer_slotm′ ptr_addrcell value

+split ; exact Hlive |

2 open

m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hn :
0 ≤ span_sizespan_ptr ≔ cell; span_size ≔ 8
b :
Z
reg :
Hcap :
ptr_capspan_ptrspan_ptr ≔ cell; span_size ≔ 8 = Objb
Hreg :
Hlive :
r_lifereg = Live
Ha :
access_resm ptr_addrspan_ptrspan_ptr ≔ cell; span_size ≔ 8 Objb span_sizespan_ptr ≔ cell; span_size ≔ 8 Write 1 = Someok
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
access_resm′ ptr_addrspan_ptrspan_ptr ≔ cell; span_size ≔ 8 Objb span_sizespan_ptr ≔ cell; span_size ≔ 8 Write 1 = Someok
deferred goal
m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hw :
writable_spanm span_ptr ≔ cell; span_size ≔ 8
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
access_resm′ ptr_addrcell ptr_capcell 8 Read 8 = Someok ∧ access_resm′ ptr_addrcell ptr_capcell 8 Write 8 = Someok ∧ pointer_slotm′ ptr_addrcell value

eapply startup_frame_access ; eauto

deferred goal
m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hw :
writable_spanm span_ptr ≔ cell; span_size ≔ 8
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
access_resm′ ptr_addrcell ptr_capcell 8 Read 8 = Someok ∧ access_resm′ ptr_addrcell ptr_capcell 8 Write 8 = Someok ∧ pointer_slotm′ ptr_addrcell value

–split ; eapply startup_frame_access ; eauto |

m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hw :
writable_spanm span_ptr ≔ cell; span_size ≔ 8
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
access_resm′ ptr_addrcell ptr_capcell 8 Write 8 = Someok ∧ pointer_slotm′ ptr_addrcell value

split ; eapply startup_frame_access ; eauto |

m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hw :
writable_spanm span_ptr ≔ cell; span_size ≔ 8
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
pointer_slotm′ ptr_addrcell value

eapply startup_frame_slot ; exact Hframe | | intros ; lia | exact Hslot

m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hw :
writable_spanm span_ptr ≔ cell; span_size ≔ 8
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
⊢
∀b : Z, ptr_addrcell ≤ b < ptr_addrcell + 8 → in_objectm b

intros a Ha

m, m′ :
cell, value :
Hframe :
startup_framem m′ 0 0
Hw :
writable_spanm span_ptr ≔ cell; span_size ≔ 8
Hr :
access_resm ptr_addrcell ptr_capcell 8 Read 8 = Someok
Hwr :
access_resm ptr_addrcell ptr_capcell 8 Write 8 = Someok
Hslot :
a :
Z
Ha :
ptr_addrcell ≤ a < ptr_addrcell + 8
⊢

eapply access_in ; exact Hr | exact Ha

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m m′ cell value Hframe Hw & Hr & Hwr & Hslot
split
–destruct Hw as Hn & b & reg & Hcap & Hreg & Hlive & Ha
split ; exact Hn |
exists b, reg
split ; exact Hcap |
split
+apply proj1Hframe
exact Hreg
+split ; exact Hlive |
eapply startup_frame_access ; eauto
–split ; eapply startup_frame_access ; eauto |
split ; eapply startup_frame_access ; eauto |
eapply startup_frame_slot ; exact Hframe | | intros ; lia | exact Hslot
intros a Ha
eapply access_in ; exact Hr | exact Ha

Exposed libc cells and their readable name payloads survive the two successful launcher-copy loops. This preserves module data; it does not construct or assume native FILE/TLS validity.

486Theorem startup_frame_libc_globals
∀ m m′ g out err full short
startup_framem m′ 0 0
libc_globals_atm g out err full short
libc_globals_atm′ g out err full short
Explore proof 14 tactics

Initial goal

⊢
∀m m′ : mem g : libc_global_cells out err full short : ptr, startup_framem m′ 0 0 → libc_globals_atm g out err full short → libc_globals_atm′ g out err full short

intros m m′ g out err full short Hf Ho & He & Hn & Hs & Hfull & Hshort

m, m′ :
out, err, full, short :
Hf :
startup_framem m′ 0 0
Hfull :
∃bytes : listZ, c_stringm full bytes
Hshort :
∃bytes : listZ, c_stringm short bytes
⊢
libc_globals_atm′ g out err full short

split ; eapply startup_frame_exposed_cell ; eauto |

m, m′ :
out, err, full, short :
Hf :
startup_framem m′ 0 0
Hfull :
∃bytes : listZ, c_stringm full bytes
Hshort :
∃bytes : listZ, c_stringm short bytes
⊢
exposed_pointer_cellm′ stderr_cellg err ∧ exposed_pointer_cellm′ invocation_name_cellg full ∧ exposed_pointer_cellm′ short_name_cellg short ∧ ∃bytes : listZ, c_stringm′ full bytes ∧ ∃bytes : listZ, c_stringm′ short bytes

split ; eapply startup_frame_exposed_cell ; eauto |

m, m′ :
out, err, full, short :
Hf :
startup_framem m′ 0 0
Hfull :
∃bytes : listZ, c_stringm full bytes
Hshort :
∃bytes : listZ, c_stringm short bytes
⊢
exposed_pointer_cellm′ invocation_name_cellg full ∧ exposed_pointer_cellm′ short_name_cellg short ∧ ∃bytes : listZ, c_stringm′ full bytes ∧ ∃bytes : listZ, c_stringm′ short bytes

split ; eapply startup_frame_exposed_cell ; eauto |

m, m′ :
out, err, full, short :
Hf :
startup_framem m′ 0 0
Hfull :
∃bytes : listZ, c_stringm full bytes
Hshort :
∃bytes : listZ, c_stringm short bytes
⊢
exposed_pointer_cellm′ short_name_cellg short ∧ ∃bytes : listZ, c_stringm′ full bytes ∧ ∃bytes : listZ, c_stringm′ short bytes

split ; eapply startup_frame_exposed_cell ; eauto |

m, m′ :
out, err, full, short :
Hf :
startup_framem m′ 0 0
Hfull :
∃bytes : listZ, c_stringm full bytes
Hshort :
∃bytes : listZ, c_stringm short bytes
⊢
∃bytes : listZ, c_stringm′ full bytes ∧ ∃bytes : listZ, c_stringm′ short bytes

split

2 open

m, m′ :
out, err, full, short :
Hf :
startup_framem m′ 0 0
Hfull :
∃bytes : listZ, c_stringm full bytes
Hshort :
∃bytes : listZ, c_stringm short bytes
⊢
∃bytes : listZ, c_stringm′ full bytes
focused goal
m, m′ :
out, err, full, short :
Hf :
startup_framem m′ 0 0
Hfull :
∃bytes : listZ, c_stringm full bytes
Hshort :
∃bytes : listZ, c_stringm short bytes
⊢
∃bytes : listZ, c_stringm′ short bytes

–destruct Hfull as bytes H

2 open

m, m′ :
out, err, full, short :
Hf :
startup_framem m′ 0 0
bytes :
listZ
H :
c_stringm full bytes
Hshort :
∃bytes : listZ, c_stringm short bytes
⊢
∃bytes0 : listZ, c_stringm′ full bytes0
deferred goal
m, m′ :
out, err, full, short :
Hf :
startup_framem m′ 0 0
Hfull :
∃bytes : listZ, c_stringm full bytes
Hshort :
∃bytes : listZ, c_stringm short bytes
⊢
∃bytes : listZ, c_stringm′ short bytes

exists bytes

2 open

m, m′ :
out, err, full, short :
Hf :
startup_framem m′ 0 0
bytes :
listZ
H :
c_stringm full bytes
Hshort :
∃bytes : listZ, c_stringm short bytes
⊢
c_stringm′ full bytes
deferred goal
m, m′ :
out, err, full, short :
Hf :
startup_framem m′ 0 0
Hfull :
∃bytes : listZ, c_stringm full bytes
Hshort :
∃bytes : listZ, c_stringm short bytes
⊢
∃bytes : listZ, c_stringm′ short bytes

eapply startup_frame_string ; eauto

2 open

m, m′ :
out, err, full, short :
Hf :
startup_framem m′ 0 0
bytes :
listZ
H :
c_stringm full bytes
Hshort :
∃bytes : listZ, c_stringm short bytes
⊢
∀a : Z, ptr_addrfull ≤ a < ptr_addrfull + Z.of_natDatatypes.lengthbytes + 1 → a < 0 ∨ 0 ≤ a
deferred goal
m, m′ :
out, err, full, short :
Hf :
startup_framem m′ 0 0
Hfull :
∃bytes : listZ, c_stringm full bytes
Hshort :
∃bytes : listZ, c_stringm short bytes
⊢
∃bytes : listZ, c_stringm′ short bytes

intros ; lia

deferred goal
m, m′ :
out, err, full, short :
Hf :
startup_framem m′ 0 0
Hfull :
∃bytes : listZ, c_stringm full bytes
Hshort :
∃bytes : listZ, c_stringm short bytes
⊢
∃bytes : listZ, c_stringm′ short bytes

–destruct Hshort as bytes H

m, m′ :
out, err, full, short :
Hf :
startup_framem m′ 0 0
Hfull :
∃bytes : listZ, c_stringm full bytes
bytes :
listZ
H :
c_stringm short bytes
⊢
∃bytes0 : listZ, c_stringm′ short bytes0

exists bytes

m, m′ :
out, err, full, short :
Hf :
startup_framem m′ 0 0
Hfull :
∃bytes : listZ, c_stringm full bytes
bytes :
listZ
H :
c_stringm short bytes
⊢
c_stringm′ short bytes

eapply startup_frame_string ; eauto

m, m′ :
out, err, full, short :
Hf :
startup_framem m′ 0 0
Hfull :
∃bytes : listZ, c_stringm full bytes
bytes :
listZ
H :
c_stringm short bytes
⊢
∀a : Z, ptr_addrshort ≤ a < ptr_addrshort + Z.of_natDatatypes.lengthbytes + 1 → a < 0 ∨ 0 ≤ a

intros ; lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m m′ g out err full short Hf Ho & He & Hn & Hs & Hfull & Hshort
split ; eapply startup_frame_exposed_cell ; eauto |
split ; eapply startup_frame_exposed_cell ; eauto |
split ; eapply startup_frame_exposed_cell ; eauto |
split ; eapply startup_frame_exposed_cell ; eauto |
split
–destruct Hfull as bytes H
exists bytes
eapply startup_frame_string ; eauto
intros ; lia
–destruct Hshort as bytes H
exists bytes
eapply startup_frame_string ; eauto
intros ; lia

Sixteen-byte rounding provides at least the original positive request.

500Lemma startup_extent
∀ size
0 < size
size ≤ req_extentheap_req16 size
Explore proof 6 tactics

Initial goal

⊢
∀size : Z, 0 < size → size ≤ req_extentheap_req16 size

intros size Hsize

size :
Z
Hsize :
0 < size
⊢
size ≤ req_extentheap_req16 size

unfold heap_req

size :
Z
Hsize :
0 < size
⊢
size ≤ req_extentreq_align ≔ Z.max16 16; req_extent ≔ size + 15 / 16 × 16; req_kind ≔ Heap

simpl

size :
Z
Hsize :
0 < size
⊢
size ≤ size + 15 / 16 × 16

pose proof Z.mod_pos_boundsize + 15 16 ltac:lia

size :
Z
Hsize :
0 < size
H :
0 ≤ size + 15 mod 16 < 16
⊢
size ≤ size + 15 / 16 × 16

pose proof Z.div_modsize + 15 16 ltac:lia

size :
Z
Hsize :
0 < size
H :
0 ≤ size + 15 mod 16 < 16
H0 :
size + 15 = 16 × size + 15 / 16 + size + 15 mod 16
⊢
size ≤ size + 15 / 16 × 16

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros size Hsize
unfold heap_req
simpl
pose proof Z.mod_pos_boundsize + 15 16 ltac:lia
pose proof Z.div_modsize + 15 16 ltac:lia
lia

The table's actual object, bounds and alignment justify each slot access.

508Lemma startup_table_access
∀ m table end_ a size rights align
object_regiontable m_regionsm = SomemkRegiontable end_ Heap Live
table ≤ a
a + size ≤ end_
a mod align = 0
access_resm a Objtable size rights align = Someok
Explore proof 11 tactics

Initial goal

⊢
∀m : mem table end_ a size : Z rights : rights align : Z, object_regiontable m_regionsm = Somer_base ≔ table; r_end ≔ end_; r_kind ≔ Heap; r_life ≔ Live → table ≤ a → a + size ≤ end_ → a mod align = 0 → access_resm a Objtable size rights align = Someok

intros m table end_ a size rights align Hr Hlo Hhi Ha

m :
table, end_, a, size :
Z
rights :
rights
align :
Z
Hr :
object_regiontable m_regionsm = Somer_base ≔ table; r_end ≔ end_; r_kind ≔ Heap; r_life ≔ Live
Hlo :
table ≤ a
Hhi :
a + size ≤ end_
Ha :
a mod align = 0
⊢
access_resm a Objtable size rights align = Someok

unfold access_res , cap_access_res

m :
table, end_, a, size :
Z
rights :
rights
align :
Z
Hr :
object_regiontable m_regionsm = Somer_base ≔ table; r_end ≔ end_; r_kind ≔ Heap; r_life ≔ Live
Hlo :
table ≤ a
Hhi :
a + size ≤ end_
Ha :
a mod align = 0
⊢
let* reg ≔ object_regiontable m_regionsm in
Some
table ≤? a && a + size ≤? r_endreg
→
=
Someok

rewrite Hr

m :
table, end_, a, size :
Z
rights :
rights
align :
Z
Hr :
object_regiontable m_regionsm = Somer_base ≔ table; r_end ≔ end_; r_kind ≔ Heap; r_life ≔ Live
Hlo :
table ≤ a
Hhi :
a + size ≤ end_
Ha :
a mod align = 0
⊢
Some
table ≤? a && a + size ≤? r_endr_base ≔ table; r_end ≔ end_; r_kind ≔ Heap; r_life ≔ Live
→
=
Someok

simpl

m :
table, end_, a, size :
Z
rights :
rights
align :
Z
Hr :
object_regiontable m_regionsm = Somer_base ≔ table; r_end ≔ end_; r_kind ≔ Heap; r_life ≔ Live
Hlo :
table ≤ a
Hhi :
a + size ≤ end_
Ha :
a mod align = 0
⊢
Some
table ≤? a && a + size ≤? end_
→
=
Someok

assert table ≤? a && a + size ≤? end_ = true as E

2 open

m :
table, end_, a, size :
Z
rights :
rights
align :
Z
Hr :
object_regiontable m_regionsm = Somer_base ≔ table; r_end ≔ end_; r_kind ≔ Heap; r_life ≔ Live
Hlo :
table ≤ a
Hhi :
a + size ≤ end_
Ha :
a mod align = 0
⊢
table ≤? a && a + size ≤? end_ = true
focused goal
m :
table, end_, a, size :
Z
rights :
rights
align :
Z
Hr :
object_regiontable m_regionsm = Somer_base ≔ table; r_end ≔ end_; r_kind ≔ Heap; r_life ≔ Live
Hlo :
table ≤ a
Hhi :
a + size ≤ end_
Ha :
a mod align = 0
E :
table ≤? a && a + size ≤? end_ = true
⊢
Some
table ≤? a && a + size ≤? end_
→
=
Someok

{apply andb_true_iff

2 open

m :
table, end_, a, size :
Z
rights :
rights
align :
Z
Hr :
object_regiontable m_regionsm = Somer_base ≔ table; r_end ≔ end_; r_kind ≔ Heap; r_life ≔ Live
Hlo :
table ≤ a
Hhi :
a + size ≤ end_
Ha :
a mod align = 0
⊢
table ≤? a = true ∧ a + size ≤? end_ = true
deferred goal
m :
table, end_, a, size :
Z
rights :
rights
align :
Z
Hr :
object_regiontable m_regionsm = Somer_base ≔ table; r_end ≔ end_; r_kind ≔ Heap; r_life ≔ Live
Hlo :
table ≤ a
Hhi :
a + size ≤ end_
Ha :
a mod align = 0
E :
table ≤? a && a + size ≤? end_ = true
⊢
Some
table ≤? a && a + size ≤? end_
→
=
Someok

split ; apply Z.leb_le ; lia

deferred goal
m :
table, end_, a, size :
Z
rights :
rights
align :
Z
Hr :
object_regiontable m_regionsm = Somer_base ≔ table; r_end ≔ end_; r_kind ≔ Heap; r_life ≔ Live
Hlo :
table ≤ a
Hhi :
a + size ≤ end_
Ha :
a mod align = 0
E :
table ≤? a && a + size ≤? end_ = true
⊢
Some
table ≤? a && a + size ≤? end_
→
=
Someok

rewrite E

m :
table, end_, a, size :
Z
rights :
rights
align :
Z
Hr :
object_regiontable m_regionsm = Somer_base ≔ table; r_end ≔ end_; r_kind ≔ Heap; r_life ≔ Live
Hlo :
table ≤ a
Hhi :
a + size ≤ end_
Ha :
a mod align = 0
E :
table ≤? a && a + size ≤? end_ = true
⊢
Somealigned_resa align = Someok

unfold aligned_res

m :
table, end_, a, size :
Z
rights :
rights
align :
Z
Hr :
object_regiontable m_regionsm = Somer_base ≔ table; r_end ≔ end_; r_kind ≔ Heap; r_life ≔ Live
Hlo :
table ≤ a
Hhi :
a + size ≤ end_
Ha :
a mod align = 0
E :
table ≤? a && a + size ≤? end_ = true
⊢
Some
a mod align =? 0
→
=
Someok

rewrite Ha

m :
table, end_, a, size :
Z
rights :
rights
align :
Z
Hr :
object_regiontable m_regionsm = Somer_base ≔ table; r_end ≔ end_; r_kind ≔ Heap; r_life ≔ Live
Hlo :
table ≤ a
Hhi :
a + size ≤ end_
Ha :
a mod align = 0
E :
table ≤? a && a + size ≤? end_ = true
⊢
Some
0 =? 0
→
=
Someok

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros m table end_ a size rights align Hr Hlo Hhi Ha
rewrite Hr
simpl
assert table ≤? a && a + size ≤? end_ = true as E
{apply andb_true_iff
split ; apply Z.leb_le ; lia
rewrite E
rewrite Ha
reflexivity

Startup copying over the caller's exact machine instance.

521Module StartupOn R : Runtime M : ExternalMachineSigR

The external-call effects of this machine.

523Module E ≔ M.E

Copying through supplied write authority is a finite path of local effects.

526Lemma copy_c_bytes_effects
∀ bytes sources roots releases requests s m born a
∀b, a ≤ b < a + Z.of_natlengthbytes + 1 → write_authorityroots born m b
E.effectssources roots releases requests s m born s copy_c_bytesm a bytes born
Explore proof 21 tactics

Initial goal

⊢
∀bytes : listZ sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthbytes + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a bytes born

induction bytes as | head rest IH ; intros sources roots releases requests s m born a Hw

2 open

sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.length[ ] + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s m born s copy_c_bytesm a [ ] born
focused goal
head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s m born s copy_c_bytesm a head :: rest born

–eapply E.effects_local with m1 := store_bytesm a 1 0

3 open

sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.length[ ] + 1 → write_authorityroots born m b
⊢
local_effectsources roots releases born m store_bytesm a 1 0
focused goal
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.length[ ] + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s store_bytesm a 1 0 born s copy_c_bytesm a [ ] born
deferred goal
head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s m born s copy_c_bytesm a head :: rest born

+apply local_store_bytes

3 open

sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.length[ ] + 1 → write_authorityroots born m b
⊢
∀b : Z, a ≤ b < a + 1 → write_authorityroots born m b
deferred goal
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.length[ ] + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s store_bytesm a 1 0 born s copy_c_bytesm a [ ] born
deferred goal
head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s m born s copy_c_bytesm a head :: rest born

intros b Hb

3 open

sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.length[ ] + 1 → write_authorityroots born m b
b :
Z
Hb :
a ≤ b < a + 1
⊢
write_authorityroots born m b
deferred goal
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.length[ ] + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s store_bytesm a 1 0 born s copy_c_bytesm a [ ] born
deferred goal
head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s m born s copy_c_bytesm a head :: rest born

apply Hw

3 open

sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.length[ ] + 1 → write_authorityroots born m b
b :
Z
Hb :
a ≤ b < a + 1
⊢
a ≤ b < a + Z.of_natDatatypes.length[ ] + 1
deferred goal
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.length[ ] + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s store_bytesm a 1 0 born s copy_c_bytesm a [ ] born
deferred goal
head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s m born s copy_c_bytesm a head :: rest born

simpl

3 open

sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.length[ ] + 1 → write_authorityroots born m b
b :
Z
Hb :
a ≤ b < a + 1
⊢
a ≤ b < a + 0 + 1
deferred goal
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.length[ ] + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s store_bytesm a 1 0 born s copy_c_bytesm a [ ] born
deferred goal
head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s m born s copy_c_bytesm a head :: rest born

lia

2 open

deferred goal
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.length[ ] + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s store_bytesm a 1 0 born s copy_c_bytesm a [ ] born
deferred goal
head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s m born s copy_c_bytesm a head :: rest born

+constructor

deferred goal
head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s m born s copy_c_bytesm a head :: rest born

–eapply E.effects_local with m1 := store_bytesm a 1 head

2 open

head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
⊢
local_effectsources roots releases born m store_bytesm a 1 head
focused goal
head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s store_bytesm a 1 head born s copy_c_bytesm a head :: rest born

+apply local_store_bytes

2 open

head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
⊢
∀b : Z, a ≤ b < a + 1 → write_authorityroots born m b
deferred goal
head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s store_bytesm a 1 head born s copy_c_bytesm a head :: rest born

intros b Hb

2 open

head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
b :
Z
Hb :
a ≤ b < a + 1
⊢
write_authorityroots born m b
deferred goal
head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s store_bytesm a 1 head born s copy_c_bytesm a head :: rest born

apply Hw

2 open

head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
b :
Z
Hb :
a ≤ b < a + 1
⊢
a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1
deferred goal
head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s store_bytesm a 1 head born s copy_c_bytesm a head :: rest born

change a ≤ b < a + Z.of_natSlengthrest + 1

2 open

head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
b :
Z
Hb :
a ≤ b < a + 1
⊢
a ≤ b < a + Z.of_natSDatatypes.lengthrest + 1
deferred goal
head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s store_bytesm a 1 head born s copy_c_bytesm a head :: rest born

rewrite Nat2Z.inj_succ

2 open

head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
b :
Z
Hb :
a ≤ b < a + 1
⊢
a ≤ b < a + Z.succZ.of_natDatatypes.lengthrest + 1
deferred goal
head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s store_bytesm a 1 head born s copy_c_bytesm a head :: rest born

lia

deferred goal
head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
⊢
E.effectssources roots releases requests s store_bytesm a 1 head born s copy_c_bytesm a head :: rest born

+apply IH

head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
⊢
∀b : Z, a + 1 ≤ b < a + 1 + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born store_bytesm a 1 head b

intros b Hb

head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
b :
Z
Hb :
a + 1 ≤ b < a + 1 + Z.of_natDatatypes.lengthrest + 1
⊢
write_authorityroots born store_bytesm a 1 head b

apply Hw

head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
b :
Z
Hb :
a + 1 ≤ b < a + 1 + Z.of_natDatatypes.lengthrest + 1
⊢
a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1

change a ≤ b < a + Z.of_natSlengthrest + 1

head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
b :
Z
Hb :
a + 1 ≤ b < a + 1 + Z.of_natDatatypes.lengthrest + 1
⊢
a ≤ b < a + Z.of_natSDatatypes.lengthrest + 1

rewrite Nat2Z.inj_succ

head :
Z
rest :
listZ
IH :
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ a : Z, ∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthrest + 1 → write_authorityroots born m b → E.effectssources roots releases requests s m born s copy_c_bytesm a rest born
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
a :
Z
Hw :
∀b : Z, a ≤ b < a + Z.of_natDatatypes.lengthhead :: rest + 1 → write_authorityroots born m b
b :
Z
Hb :
a + 1 ≤ b < a + 1 + Z.of_natDatatypes.lengthrest + 1
⊢
a ≤ b < a + Z.succZ.of_natDatatypes.lengthrest + 1

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
induction bytes as | head rest IH ; intros sources roots releases requests s m born a Hw
–eapply E.effects_local with m1 := store_bytesm a 1 0
intros b Hb
apply Hw
simpl
lia
+constructor
–eapply E.effects_local with m1 := store_bytesm a 1 head
intros b Hb
apply Hw
change a ≤ b < a + Z.of_natSlengthrest + 1
rewrite Nat2Z.inj_succ
lia
+apply IH
intros b Hb
apply Hw
change a ≤ b < a + Z.of_natSlengthrest + 1
rewrite Nat2Z.inj_succ
lia

Success remains conditional on the runtime's real answer, for the original strlen + 1 request. No small fixed bound or NULL-success case is introduced. The result includes the entire checked NUL.

544Theorem copy_string
∀ bytes sources roots releases requests s m born base s′
R.readys m
Forallλb ⇒ 0 < b < 256 bytes
Z.of_natlengthbytes + 1 ≤ max_allocation_size
requests16 Z.of_natlengthbytes + 1
R.allocs heap_req16 Z.of_natlengthbytes + 1 = Somebase, s′
let q ≔ heap_req16 Z.of_natlengthbytes + 1 in
let m′ ≔ copy_c_bytesallocatedm q base base bytes in
E.effectssources roots releases requests s m born s′ m′ base :: born ∧ R.readys′ m′ ∧ persistsm m′ ∧ c_stringm′ mkPtrbase Objbase bytes ∧ writable_spanm′ mkSpanmkPtrbase Objbase Z.of_natlengthbytes + 1 ∧ 0 ≤ base < 2 ^ 64 ∧ ∀a, in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Proof 63 steps Qed
intros bytes sources roots releases requests s m born base s′ Hr Hbytes Hmax Hrequest Ha
set size := Z.of_natlengthbytes + 1
set q := heap_req16 size
assert Hsize : 0 < size by unfold size ; lia
assert Hfit : size ≤ req_extentq
{unfold q , heap_req
simpl
pose proof Z.mod_pos_boundsize + 15 16 ltac:lia
pose proof Z.div_modsize + 15 16 ltac:lia
lia
destruct R.fresh_allocations m q base s' Hr ltac:simpl ; lia ltac:lia Ha as Hfresh Hr1
assert Hreg : object_regionbase m_regionsallocatedm q base = SomemkRegionbase base + req_extentq Heap Live
{simpl
rewrite Z.eqb_refl
reflexivity
assert He : E.effectssources roots releases requests s m born s' copy_c_bytesallocatedm q base base bytes base :: born
{eapply E.effects_alloc with align := 16 size := size
–exact Hrequest
–split ; lia | exact Hmax
–exact Ha
intros a Hrange
right
exists base, mkRegionbase base + req_extentq Heap Live
split ; simpl ; auto |
split ; exact Hreg |
split ; reflexivity |
split ; reflexivity |
change base ≤ a < base + req_extentq
unfold size in Hfit
lia
destruct E.effects_preserve_ _ _ _ _ _ _ _ _ _ He Hr as Hr′ Hpersist
assert Haccess : access_rescopy_c_bytesallocatedm q base base bytes base Objbase size Write 1 = Someok
{unfold access_res
rewrite Hreg
change Someif base ≤? base && base + size ≤? base + req_extentq then aligned_resbase 1 else RTrapOutOfBounds = Someok
assert base ≤? base && base + size ≤? base + req_extentq = true as E
{apply andb_true_iff
split ; apply Z.leb_le ; lia
rewrite E
rewrite Z.mod_1_r
reflexivity
split ; exact He |
split ; exact Hr' |
split ; exact Hpersist |
split
–split ; exact Haccess |
exact Hbytes
–split
+split ; simpl ; lia |
exists base, mkRegionbase base + req_extentq Heap Live
split ; reflexivity |
split ; rewrite copy_c_bytes_regions ; exact Hreg |
split ; reflexivity | exact Haccess
+split
∗destruct Hfresh as Hbase & _ & Hend & _
lia
∗intros a Hin

Append two actual effect paths, retaining the same contract authority.

600Lemma effects_trans
∀ sources roots releases requests s m born s1 m1 born1 s2 m2 born2
E.effectssources roots releases requests s m born s1 m1 born1
E.effectssources roots releases requests s1 m1 born1 s2 m2 born2
E.effectssources roots releases requests s m born s2 m2 born2
Explore proof 2 tactics

Initial goal

⊢
∀sources roots : listspan releases : listZ requests : Z → Z → Prop s : R.state m : mem born : listZ s1 : R.state m1 : mem born1 : listZ s2 : R.state m2 : mem born2 : listZ, E.effectssources roots releases requests s m born s1 m1 born1 → E.effectssources roots releases requests s1 m1 born1 s2 m2 born2 → E.effectssources roots releases requests s m born s2 m2 born2

intros sources roots releases requests s m born s1 m1 born1 s2 m2 born2 H

sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
s :
R.state
m :
born :
listZ
s1 :
R.state
m1 :
born1 :
listZ
s2 :
R.state
m2 :
born2 :
listZ
H :
E.effectssources roots releases requests s m born s1 m1 born1
⊢
E.effectssources roots releases requests s1 m1 born1 s2 m2 born2 → E.effectssources roots releases requests s m born s2 m2 born2

induction H ; intros Htail ; eauto using E.effects_local , E.effects_alloc

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros sources roots releases requests s m born s1 m1 born1 s2 m2 born2 H
induction H ; intros Htail ; eauto using E.effects_local , E.effects_alloc

Preconditions on copied pre-NUL payloads and their original allocation sizes.

610Definition payloads_allowedrequests : Z → Z → Prop texts : listlistZ : Prop ≔
Forallλtext ⇒ Forallλb ⇒ 0 < b < 256 text ∧ Z.of_natlengthtext + 1 ≤ max_allocation_size ∧ requests16 Z.of_natlengthtext + 1 texts

Fill a preallocated pointer table in forward order. None says only that this successful construction did not complete, not why native startup ended. Each allocation uses the preceding runtime state.

618Fixpoint copy_slotstexts : listlistZ s : R.state m : mem born : listZ cursor : Z : optionR.state × mem × listZ ≔
match texts with
[ ]
⇒
Somes, m, born
text :: rest
⇒
match R.allocs heap_req16 Z.of_natlengthtext + 1 with
None
⇒
None
Somebase, s1
⇒
let m1 ≔ copy_c_bytesallocatedm heap_req16 Z.of_natlengthtext + 1 base base text in
copy_slotsrest s1 startup_storem1 cursor mkPtrbase Objbase base :: born cursor + 8

Allocate the pointer table first, even when there are no strings. Fresh zero bytes and capabilities supply its sentinel, not a synthetic final store. Allocation failures remain unclassified.

636Definition copy_vectortexts : listlistZ s : R.state m : mem born : listZ : optionptr × R.state × mem × listZ ≔
let size ≔ 8 × Z.of_natlengthtexts + 1 in
match R.allocs heap_req16 size with
None
⇒
None
Sometable, s1
⇒
match copy_slotstexts s1 allocatedm heap_req16 size table table :: born table with
None
⇒
None
Somes2, m2, born2
⇒
SomemkPtrtable Objtable, s2, m2, born2

The forward loop retains earlier strings and the sentinel while writing only its remaining slots in the already-born table.

650Theorem copy_slots_correct
∀ texts s m born cursor s′ m′ born′ sources roots releases requests table end_
copy_slotstexts s m born cursor = Somes′, m′, born′
R.readys m
payloads_allowedrequests texts
Intable born
object_regiontable m_regionsm = SomemkRegiontable end_ Heap Live
table ≤ cursor
cursor + 8 × Z.of_natlengthtexts + 1 ≤ end_
cursor mod 8 = 0
pointer_slotm cursor + 8 × Z.of_natlengthtexts mkPtr0 CNone
E.effectssources roots releases requests s m born s′ m′ born′ ∧ R.readys′ m′ ∧ persistsm m′ ∧ startup_framem m′ cursor cursor + 8 × Z.of_natlengthtexts ∧ string_slotsm′ cursor texts
Proof 97 steps Qed
induction texts as | text rest IH ; intros s m born cursor s′ m′ born′ sources roots releases requests table end_ Hcopy Hr Hallowed Hborn Htable Hlo Hhi Halign Hsent
–simpl in Hcopy
injection Hcopy as ← ← ←
split ; constructor |
split ; exact Hr |
split ; apply persists_refl |
split
+split ; auto | auto
+replace cursor + 8 × Z.of_natlength[ ] with cursor in Hsent by simpl ; lia
exact Hsent
–cbn [ copy_slots ] in Hcopy
destruct R.allocs heap_req16 Z.of_natlengthtext + 1 as base s1 | eqn: Ha ; | discriminate Hcopy
inversion Hallowed as | head tail Hbytes Hmax Hrequest Hrest ; subst head tail
set q := heap_req16 Z.of_natlengthtext + 1
set m1 := copy_c_bytesallocatedm q base base text
set m2 := startup_storem1 cursor mkPtrbase Objbase
assert Hfit : Z.of_natlengthtext + 1 ≤ req_extentq by apply startup_extent ; lia
destruct R.fresh_allocations m q base s1 Hr ltac:simpl ; lia ltac:lia Ha as Hfresh Hready1
assert Hframe1 : startup_framem m1 cursor cursor by apply copied_string_frame ; auto
assert Htable1 : object_regiontable m_regionsm1 = SomemkRegiontable end_ Heap Live by apply proj1Hframe1 ; exact Htable
destruct copy_stringtext sources roots releases requests s m born base s1 Hr Hbytes Hmax Hrequest Ha as He1 & Hr1 & Hp1 & Hstring & Hwrite & Hbase & Hold
fold q m1 in He1 , Hr1 , Hp1 , Hstring , Hwrite , Hold
assert Hstore : local_effectsources roots releases base :: born m1 m2
–intros a Hrange
right
exists table, mkRegiontable end_ Heap Live
split ; simpl ; auto |
split ; exact Htable1 |
change cursor + 8 × Z.of_natSlengthrest + 1 ≤ end_ in Hhi
rewrite Nat2Z.inj_succ in Hhi
repeat split ; simpl ; try reflexivity ; lia
–right
right
right
exists base
simpl
auto
assert Hr2 : R.readys1 m2 by eapply R.ready_kept ; exact Hr1 | apply local_effect_kept in Hstore ; exact Hstore
assert Hframe2 : startup_framem m2 cursor cursor + 8
{eapply startup_frame_join with mid := cursor ; lia | exact Hframe1 | apply startup_store_frame
assert Htable2 : object_regiontable m_regionsm2 = SomemkRegiontable end_ Heap Live by apply proj1Hframe2 ; exact Htable
assert Hsent2 : pointer_slotm2 cursor + 8 + 8 × Z.of_natlengthrest mkPtr0 CNone
{replace cursor + 8 + 8 × Z.of_natlengthrest with cursor + 8 × Z.of_natSlengthrest by rewrite Nat2Z.inj_succ ; lia
eapply startup_frame_slot ; exact Hframe2 | | | exact Hsent
–intros a Hrange
exists table, mkRegiontable end_ Heap Live
split ; exact Htable |
simpl
change cursor + 8 × Z.of_natSlengthrest + 1 ≤ end_ in Hhi
lia
–intros a Hrange
rewrite Nat2Z.inj_succ in Hrange
lia
destruct IHs1 m2 base :: born cursor + 8 s' m' born' sources roots releases requests table end_ Hcopy Hr2 Hrest ltac:simpl ; auto Htable2 ltac:lia ltac:change cursor + 8 × Z.of_natSlengthrest + 1 ≤ end_ in Hhi ; rewrite Nat2Z.inj_succ in Hhi ; lia ltac:rewrite Z.add_mod by lia ; rewrite Halign ; reflexivity Hsent2 as He2 & Hr′ & Hp2 & Hframe3 & Hslots
split
+eapply effects_trans ; exact He1 |
eapply E.effects_local ; exact Hstore | exact He2
+split ; exact Hr' |
split
∗eapply persists_trans ; exact Hp1 |
eapply persists_trans ; apply kept_ids_persists ; apply local_effect_kept in Hstore ; exact Hstore | exact proj1Hstore | exact Hp2
∗split
--replace cursor + 8 × Z.of_natlengthtext :: rest with cursor + 8 + 8 × Z.of_natlengthrest by simpl length ; rewrite Nat2Z.inj_succ ; lia
eapply startup_frame_join with mid := cursor + 8 ; lia | exact Hframe2 | exact Hframe3
--exists mkPtrbase Objbase
split
++eapply startup_frame_slot ; exact Hframe3 | | intros ; lia |
**intros a Hrange
exists table, mkRegiontable end_ Heap Live
split ; exact Htable2 |
simpl
change cursor + 8 × Z.of_natSlengthrest + 1 ≤ end_ in Hhi
rewrite Nat2Z.inj_succ in Hhi
lia
exact Hbase
++split ; | exact Hslots
assert Hdis : ∀a, base ≤ a < base + Z.of_natlengthtext + 1 → a < cursor ∨ end_ ≤ a
{intros a Hrange
destruct Hfresh as _ & _ & _ & _ & Hseparate & _
specialize Hseparate_ _ Htable
change ¬base < end_ ∧ table < base + req_extentq in Hseparate
lia
assert Hstring2 : c_stringm2 mkPtrbase Objbase text
{eapply startup_frame_string ; apply startup_store_frame | exact Hstring |
intros a Hrange
simpl in Hrange
specialize Hdisa Hrange
lia
eapply startup_frame_string ; exact Hframe3 | exact Hstring2 |
intros a Hrange
simpl in Hrange
specialize Hdisa Hrange
change cursor + 8 × Z.of_natSlengthrest + 1 ≤ end_ in Hhi
rewrite Nat2Z.inj_succ in Hhi
lia

A successful table-first construction gives a checked writable vector and frames every object that existed before its table.

739Theorem copy_vector_correct
∀ texts s m born table s′ m′ born′ sources roots releases requests
copy_vectortexts s m born = Sometable, s′, m′, born′
R.readys m
payloads_allowedrequests texts
8 × Z.of_natlengthtexts + 1 ≤ max_allocation_size
requests16 8 × Z.of_natlengthtexts + 1
E.effectssources roots releases requests s m born s′ m′ born′ ∧ R.readys′ m′ ∧ persistsm m′ ∧ startup_framem m′ 0 0 ∧ string_vectorm′ table texts ∧ writable_spanm′ mkSpantable 8 × Z.of_natlengthtexts + 1
Proof 66 steps Qed
intros texts s m born table s′ m′ born′ sources roots releases requests Hcopy Hr Hallowed Hmax Hrequest
unfold copy_vector in Hcopy
destruct R.allocs heap_req16 8 × Z.of_natlengthtexts + 1 as base s1 | eqn: Ha ; | discriminate Hcopy
set size := 8 × Z.of_natlengthtexts + 1 in *
set q := heap_req16 size in *
destruct copy_slotstexts s1 allocatedm q base base :: born base as s2 m2 born2 | eqn: Hslots ; | discriminate Hcopy
injection Hcopy as ← ← ← ←
assert Hsize : 0 < size by unfold size ; lia
assert Hfit : size ≤ req_extentq by apply startup_extent ; exact Hsize
destruct R.fresh_allocations m q base s1 Hr ltac:simpl ; lia ltac:lia Ha as Hfresh Hr1
assert Htable : object_regionbase m_regionsallocatedm q base = SomemkRegionbase base + req_extentq Heap Live by simpl ; rewrite Z.eqb_refl ; reflexivity
assert Halign : base mod 8 = 0
{destruct Hfresh as _ & Halign & _
change base mod 16 = 0 in Halign
apply Z.mod_divide ; lia |
apply Z.mod_divide in Halign ; | lia
destruct Halign as k Hk
exists 2 × k
lia
assert Hsent : pointer_slotallocatedm q base base + 8 × Z.of_natlengthtexts mkPtr0 CNone
{destruct Hfresh as _ & _ & _ & _ & _ & Hzero
split ; simpl ; lia |
split
–transitivity load_bytesmkMemλ_ ⇒ 0 [ ] λ_ ⇒ CNone base + 8 × Z.of_natlengthtexts 8 ; | reflexivity
apply load_bytes_agree ; lia |
intros i Hi
simpl
apply proj1Hzerobase + 8 × Z.of_natlengthtexts + i ltac:unfold size in Hfit ; lia
–simpl
apply proj2Hzerobase + 8 × Z.of_natlengthtexts ltac:unfold size in Hfit ; lia
destruct copy_slots_correcttexts s1 allocatedm q base base :: born base s2 m2 born2 sources roots releases requests base base + req_extentq Hslots Hr1 Hallowed ltac:simpl ; auto Htable ltac:lia ltac:unfold size in Hfit ; lia Halign Hsent as He & Hr2 & Hp & Hframe & Hvector
assert Heall : E.effectssources roots releases requests s m born s2 m2 born2
{eapply E.effects_alloc ; exact Hrequest | split ; lia | exact Ha | exact He
destruct E.effects_preserve_ _ _ _ _ _ _ _ _ _ Heall Hr as Hr′ Hpall
split ; exact Heall |
split ; exact Hr' |
split ; exact Hpall |
split
–split
+intros b reg Hold
apply proj1Hframe
eapply allocated_old_region ; | exact Hold
exact proj1proj2proj2proj2Hfresh
+intros a Hin _
apply proj2Hframe a
∗destruct Hin as b & reg & E & Hrange
exists b, reg
split ; | exact Hrange
eapply allocated_old_region ; | exact E
exact proj1proj2proj2proj2Hfresh
∗destruct Hin as b & reg & E & Hrange
destruct Hfresh as _ & _ & _ & _ & Hdis & _
specialize Hdis_ _ E
unfold size in Hfit
lia
–assert Htable′ : object_regionbase m_regionsm2 = SomemkRegionbase base + req_extentq Heap Live by apply proj1Hframe ; exact Htable
split
+split ; | exact Hvector
apply startup_table_accessm2 base base + req_extentq base size Read 8 Htable' ltac:lia ltac:lia Halign
+split ; simpl ; unfold size ; lia |
exists base, mkRegionbase base + req_extentq Heap Live
split ; reflexivity |
split ; exact Htable' |
split ; reflexivity |
apply startup_table_accessm2 base base + req_extentq base size Write 1 Htable' ltac:lia ltac:lia Z.mod_1_rbase

The environment's count, increment and checked multiplication fit size_t whenever its original table request is legal. Unlike argv, this count is not restricted to signed int.

806Lemma environment_copy_bounds
∀ n
8 × Z.of_natn + 1 ≤ max_allocation_size
0 ≤ Z.of_natn < 2 ^ 64 − 1 ∧ 0 < 8 × Z.of_natn + 1 < 2 ^ 64
Explore proof 3 tactics

Initial goal

⊢
∀n : nat, 8 × Z.of_natn + 1 ≤ max_allocation_size → 0 ≤ Z.of_natn < 2 ^ 64 − 1 ∧ 0 < 8 × Z.of_natn + 1 < 2 ^ 64

intros n H

n :
nat
H :
8 × Z.of_natn + 1 ≤ max_allocation_size
⊢
0 ≤ Z.of_natn < 2 ^ 64 − 1 ∧ 0 < 8 × Z.of_natn + 1 < 2 ^ 64

unfold max_allocation_size in H

n :
nat
H :
8 × Z.of_natn + 1 ≤ 2 ^ 48 − 1
⊢
0 ≤ Z.of_natn < 2 ^ 64 − 1 ∧ 0 < 8 × Z.of_natn + 1 < 2 ^ 64

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros n H
lia

Compose the argv and environment memory constructions. This is not the complete native launcher trace: obtaining/tracking main between the two loops, auxv and libc initialization still need coverage.

814Theorem copied_startup
∀ args environment s m born argv s1 m1 born1 envp s2 m2 born2 sources roots releases requests
copy_vectorargs s m born = Someargv, s1, m1, born1
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
R.readys m
1 ≤ Z.of_natlengthargs < 2 ^ 31 − 1
payloads_allowedrequests args
payloads_allowedrequests environment
8 × Z.of_natlengthenvironment + 1 ≤ max_allocation_size
requests16 8 × Z.of_natlengthargs + 1
requests16 8 × Z.of_natlengthenvironment + 1
E.effectssources roots releases requests s m born s2 m2 born2 ∧ R.readys2 m2 ∧ persistsm m2 ∧ startup_framem m2 0 0 ∧ startup_atm2 Z.of_natlengthargs argv envp args environment
Explore proof 15 tactics

Initial goal

⊢
∀args environment : listlistZ s : R.state m : mem born : listZ argv : ptr s1 : R.state m1 : mem born1 : listZ envp : ptr s2 : R.state m2 : mem born2 : listZ sources roots : listspan releases : listZ requests : Z → Z → Prop, copy_vectorargs s m born = Someargv, s1, m1, born1 → copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2 → R.readys m → 1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1 → payloads_allowedrequests args → payloads_allowedrequests environment → 8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size → requests16 8 × Z.of_natDatatypes.lengthargs + 1 → requests16 8 × Z.of_natDatatypes.lengthenvironment + 1 → E.effectssources roots releases requests s m born s2 m2 born2 ∧ R.readys2 m2 ∧ persistsm m2 ∧ startup_framem m2 0 0 ∧ startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment

intros args environment s m born argv s1 m1 born1 envp s2 m2 born2 sources roots releases requests Ha He Hr Hargc Hargs Henv Hmax Hrequesta Hrequeste

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hrequesta :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hrequeste :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
⊢
E.effectssources roots releases requests s m born s2 m2 born2 ∧ R.readys2 m2 ∧ persistsm m2 ∧ startup_framem m2 0 0 ∧ startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment

pose proof proj2argv_copy_bounds_ Hargc as Hargmax

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hrequesta :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hrequeste :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hargmax :
0 < argv_copy_sizeZ.of_natDatatypes.lengthargs ≤ max_allocation_size
⊢
E.effectssources roots releases requests s m born s2 m2 born2 ∧ R.readys2 m2 ∧ persistsm m2 ∧ startup_framem m2 0 0 ∧ startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment

unfold argv_copy_size in Hargmax

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hrequesta :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hrequeste :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hargmax :
0 < 8 × Z.of_natDatatypes.lengthargs + 1 ≤ max_allocation_size
⊢
E.effectssources roots releases requests s m born s2 m2 born2 ∧ R.readys2 m2 ∧ persistsm m2 ∧ startup_framem m2 0 0 ∧ startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment

destruct copy_vector_correctargs s m born argv s1 m1 born1 sources roots releases requests Ha Hr Hargs ltac:lia Hrequesta as Hea & Hr1 & Hp1 & Hf1 & Hva & Hwa

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hrequesta :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hrequeste :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hargmax :
0 < 8 × Z.of_natDatatypes.lengthargs + 1 ≤ max_allocation_size
Hea :
E.effectssources roots releases requests s m born s1 m1 born1
Hr1 :
R.readys1 m1
Hp1 :
Hf1 :
Hva :
string_vectorm1 argv args
Hwa :
writable_spanm1 span_ptr ≔ argv; span_size ≔ 8 × Z.of_natDatatypes.lengthargs + 1
⊢
E.effectssources roots releases requests s m born s2 m2 born2 ∧ R.readys2 m2 ∧ persistsm m2 ∧ startup_framem m2 0 0 ∧ startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment

destruct copy_vector_correctenvironment s1 m1 born1 envp s2 m2 born2 sources roots releases requests He Hr1 Henv Hmax Hrequeste as Hee & Hr2 & Hp2 & Hf2 & Hve & Hwe

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hrequesta :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hrequeste :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hargmax :
0 < 8 × Z.of_natDatatypes.lengthargs + 1 ≤ max_allocation_size
Hea :
E.effectssources roots releases requests s m born s1 m1 born1
Hr1 :
R.readys1 m1
Hp1 :
Hf1 :
Hva :
string_vectorm1 argv args
Hwa :
writable_spanm1 span_ptr ≔ argv; span_size ≔ 8 × Z.of_natDatatypes.lengthargs + 1
Hee :
E.effectssources roots releases requests s1 m1 born1 s2 m2 born2
Hr2 :
R.readys2 m2
Hp2 :
Hf2 :
startup_framem1 m2 0 0
Hve :
string_vectorm2 envp environment
Hwe :
writable_spanm2 span_ptr ≔ envp; span_size ≔ 8 × Z.of_natDatatypes.lengthenvironment + 1
⊢
E.effectssources roots releases requests s m born s2 m2 born2 ∧ R.readys2 m2 ∧ persistsm m2 ∧ startup_framem m2 0 0 ∧ startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment

split ; eapply effects_trans ; eauto |

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hrequesta :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hrequeste :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hargmax :
0 < 8 × Z.of_natDatatypes.lengthargs + 1 ≤ max_allocation_size
Hea :
E.effectssources roots releases requests s m born s1 m1 born1
Hr1 :
R.readys1 m1
Hp1 :
Hf1 :
Hva :
string_vectorm1 argv args
Hwa :
writable_spanm1 span_ptr ≔ argv; span_size ≔ 8 × Z.of_natDatatypes.lengthargs + 1
Hee :
E.effectssources roots releases requests s1 m1 born1 s2 m2 born2
Hr2 :
R.readys2 m2
Hp2 :
Hf2 :
startup_framem1 m2 0 0
Hve :
string_vectorm2 envp environment
Hwe :
writable_spanm2 span_ptr ≔ envp; span_size ≔ 8 × Z.of_natDatatypes.lengthenvironment + 1
⊢
R.readys2 m2 ∧ persistsm m2 ∧ startup_framem m2 0 0 ∧ startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment

split ; exact Hr2 |

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hrequesta :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hrequeste :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hargmax :
0 < 8 × Z.of_natDatatypes.lengthargs + 1 ≤ max_allocation_size
Hea :
E.effectssources roots releases requests s m born s1 m1 born1
Hr1 :
R.readys1 m1
Hp1 :
Hf1 :
Hva :
string_vectorm1 argv args
Hwa :
writable_spanm1 span_ptr ≔ argv; span_size ≔ 8 × Z.of_natDatatypes.lengthargs + 1
Hee :
E.effectssources roots releases requests s1 m1 born1 s2 m2 born2
Hr2 :
R.readys2 m2
Hp2 :
Hf2 :
startup_framem1 m2 0 0
Hve :
string_vectorm2 envp environment
Hwe :
writable_spanm2 span_ptr ≔ envp; span_size ≔ 8 × Z.of_natDatatypes.lengthenvironment + 1
⊢
persistsm m2 ∧ startup_framem m2 0 0 ∧ startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment

split

2 open

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hrequesta :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hrequeste :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hargmax :
0 < 8 × Z.of_natDatatypes.lengthargs + 1 ≤ max_allocation_size
Hea :
E.effectssources roots releases requests s m born s1 m1 born1
Hr1 :
R.readys1 m1
Hp1 :
Hf1 :
Hva :
string_vectorm1 argv args
Hwa :
writable_spanm1 span_ptr ≔ argv; span_size ≔ 8 × Z.of_natDatatypes.lengthargs + 1
Hee :
E.effectssources roots releases requests s1 m1 born1 s2 m2 born2
Hr2 :
R.readys2 m2
Hp2 :
Hf2 :
startup_framem1 m2 0 0
Hve :
string_vectorm2 envp environment
Hwe :
writable_spanm2 span_ptr ≔ envp; span_size ≔ 8 × Z.of_natDatatypes.lengthenvironment + 1
⊢
focused goal
args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hrequesta :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hrequeste :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hargmax :
0 < 8 × Z.of_natDatatypes.lengthargs + 1 ≤ max_allocation_size
Hea :
E.effectssources roots releases requests s m born s1 m1 born1
Hr1 :
R.readys1 m1
Hp1 :
Hf1 :
Hva :
string_vectorm1 argv args
Hwa :
writable_spanm1 span_ptr ≔ argv; span_size ≔ 8 × Z.of_natDatatypes.lengthargs + 1
Hee :
E.effectssources roots releases requests s1 m1 born1 s2 m2 born2
Hr2 :
R.readys2 m2
Hp2 :
Hf2 :
startup_framem1 m2 0 0
Hve :
string_vectorm2 envp environment
Hwe :
writable_spanm2 span_ptr ≔ envp; span_size ≔ 8 × Z.of_natDatatypes.lengthenvironment + 1
⊢
startup_framem m2 0 0 ∧ startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment

–eapply persists_trans ; eauto

deferred goal
args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hrequesta :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hrequeste :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hargmax :
0 < 8 × Z.of_natDatatypes.lengthargs + 1 ≤ max_allocation_size
Hea :
E.effectssources roots releases requests s m born s1 m1 born1
Hr1 :
R.readys1 m1
Hp1 :
Hf1 :
Hva :
string_vectorm1 argv args
Hwa :
writable_spanm1 span_ptr ≔ argv; span_size ≔ 8 × Z.of_natDatatypes.lengthargs + 1
Hee :
E.effectssources roots releases requests s1 m1 born1 s2 m2 born2
Hr2 :
R.readys2 m2
Hp2 :
Hf2 :
startup_framem1 m2 0 0
Hve :
string_vectorm2 envp environment
Hwe :
writable_spanm2 span_ptr ≔ envp; span_size ≔ 8 × Z.of_natDatatypes.lengthenvironment + 1
⊢
startup_framem m2 0 0 ∧ startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment

–split

2 open

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hrequesta :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hrequeste :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hargmax :
0 < 8 × Z.of_natDatatypes.lengthargs + 1 ≤ max_allocation_size
Hea :
E.effectssources roots releases requests s m born s1 m1 born1
Hr1 :
R.readys1 m1
Hp1 :
Hf1 :
Hva :
string_vectorm1 argv args
Hwa :
writable_spanm1 span_ptr ≔ argv; span_size ≔ 8 × Z.of_natDatatypes.lengthargs + 1
Hee :
E.effectssources roots releases requests s1 m1 born1 s2 m2 born2
Hr2 :
R.readys2 m2
Hp2 :
Hf2 :
startup_framem1 m2 0 0
Hve :
string_vectorm2 envp environment
Hwe :
writable_spanm2 span_ptr ≔ envp; span_size ≔ 8 × Z.of_natDatatypes.lengthenvironment + 1
⊢
focused goal
args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hrequesta :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hrequeste :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hargmax :
0 < 8 × Z.of_natDatatypes.lengthargs + 1 ≤ max_allocation_size
Hea :
E.effectssources roots releases requests s m born s1 m1 born1
Hr1 :
R.readys1 m1
Hp1 :
Hf1 :
Hva :
string_vectorm1 argv args
Hwa :
writable_spanm1 span_ptr ≔ argv; span_size ≔ 8 × Z.of_natDatatypes.lengthargs + 1
Hee :
E.effectssources roots releases requests s1 m1 born1 s2 m2 born2
Hr2 :
R.readys2 m2
Hp2 :
Hf2 :
startup_framem1 m2 0 0
Hve :
string_vectorm2 envp environment
Hwe :
writable_spanm2 span_ptr ≔ envp; span_size ≔ 8 × Z.of_natDatatypes.lengthenvironment + 1
⊢
startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment

+eapply startup_frame_join with mid := 0 ; lia | exact Hf1 | exact Hf2

deferred goal
args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hrequesta :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hrequeste :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hargmax :
0 < 8 × Z.of_natDatatypes.lengthargs + 1 ≤ max_allocation_size
Hea :
E.effectssources roots releases requests s m born s1 m1 born1
Hr1 :
R.readys1 m1
Hp1 :
Hf1 :
Hva :
string_vectorm1 argv args
Hwa :
writable_spanm1 span_ptr ≔ argv; span_size ≔ 8 × Z.of_natDatatypes.lengthargs + 1
Hee :
E.effectssources roots releases requests s1 m1 born1 s2 m2 born2
Hr2 :
R.readys2 m2
Hp2 :
Hf2 :
startup_framem1 m2 0 0
Hve :
string_vectorm2 envp environment
Hwe :
writable_spanm2 span_ptr ≔ envp; span_size ≔ 8 × Z.of_natDatatypes.lengthenvironment + 1
⊢
startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment

+split ; lia |

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hrequesta :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hrequeste :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hargmax :
0 < 8 × Z.of_natDatatypes.lengthargs + 1 ≤ max_allocation_size
Hea :
E.effectssources roots releases requests s m born s1 m1 born1
Hr1 :
R.readys1 m1
Hp1 :
Hf1 :
Hva :
string_vectorm1 argv args
Hwa :
writable_spanm1 span_ptr ≔ argv; span_size ≔ 8 × Z.of_natDatatypes.lengthargs + 1
Hee :
E.effectssources roots releases requests s1 m1 born1 s2 m2 born2
Hr2 :
R.readys2 m2
Hp2 :
Hf2 :
startup_framem1 m2 0 0
Hve :
string_vectorm2 envp environment
Hwe :
writable_spanm2 span_ptr ≔ envp; span_size ≔ 8 × Z.of_natDatatypes.lengthenvironment + 1
⊢
Z.of_natDatatypes.lengthargs = Z.of_natDatatypes.lengthargs ∧ string_vectorm2 argv args ∧ string_vectorm2 envp environment

split ; reflexivity |

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hrequesta :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hrequeste :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hargmax :
0 < 8 × Z.of_natDatatypes.lengthargs + 1 ≤ max_allocation_size
Hea :
E.effectssources roots releases requests s m born s1 m1 born1
Hr1 :
R.readys1 m1
Hp1 :
Hf1 :
Hva :
string_vectorm1 argv args
Hwa :
writable_spanm1 span_ptr ≔ argv; span_size ≔ 8 × Z.of_natDatatypes.lengthargs + 1
Hee :
E.effectssources roots releases requests s1 m1 born1 s2 m2 born2
Hr2 :
R.readys2 m2
Hp2 :
Hf2 :
startup_framem1 m2 0 0
Hve :
string_vectorm2 envp environment
Hwe :
writable_spanm2 span_ptr ≔ envp; span_size ≔ 8 × Z.of_natDatatypes.lengthenvironment + 1
⊢
string_vectorm2 argv args ∧ string_vectorm2 envp environment

split ; | exact Hve

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hrequesta :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hrequeste :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hargmax :
0 < 8 × Z.of_natDatatypes.lengthargs + 1 ≤ max_allocation_size
Hea :
E.effectssources roots releases requests s m born s1 m1 born1
Hr1 :
R.readys1 m1
Hp1 :
Hf1 :
Hva :
string_vectorm1 argv args
Hwa :
writable_spanm1 span_ptr ≔ argv; span_size ≔ 8 × Z.of_natDatatypes.lengthargs + 1
Hee :
E.effectssources roots releases requests s1 m1 born1 s2 m2 born2
Hr2 :
R.readys2 m2
Hp2 :
Hf2 :
startup_framem1 m2 0 0
Hve :
string_vectorm2 envp environment
Hwe :
writable_spanm2 span_ptr ≔ envp; span_size ≔ 8 × Z.of_natDatatypes.lengthenvironment + 1
⊢
string_vectorm2 argv args

eapply startup_frame_vector ; eauto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros args environment s m born argv s1 m1 born1 envp s2 m2 born2 sources roots releases requests Ha He Hr Hargc Hargs Henv Hmax Hrequesta Hrequeste
pose proof proj2argv_copy_bounds_ Hargc as Hargmax
unfold argv_copy_size in Hargmax
destruct copy_vector_correctargs s m born argv s1 m1 born1 sources roots releases requests Ha Hr Hargs ltac:lia Hrequesta as Hea & Hr1 & Hp1 & Hf1 & Hva & Hwa
destruct copy_vector_correctenvironment s1 m1 born1 envp s2 m2 born2 sources roots releases requests He Hr1 Henv Hmax Hrequeste as Hee & Hr2 & Hp2 & Hf2 & Hve & Hwe
split ; eapply effects_trans ; eauto |
split ; exact Hr2 |
split
–eapply persists_trans ; eauto
–split
+eapply startup_frame_join with mid := 0 ; lia | exact Hf1 | exact Hf2
+split ; lia |
split ; reflexivity |
split ; | exact Hve
eapply startup_frame_vector ; eauto

A ready entry frame for a linked two-parameter main after the successful launcher copies. Existing global cells and name strings survive; the linked symbol map and exact runtime state are retained. FILE/TLS validity and the program's logical precondition are still separate trusted entry obligations, not consequences of copying.

848Theorem copied_startup_main
∀ args environment s m born argv s1 m1 born1 envp s2 m2 born2 sources roots releases requests ge g out err full short f b blocks an vn fuel
copy_vectorargs s m born = Someargv, s1, m1, born1
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
R.readys m
1 ≤ Z.of_natlengthargs < 2 ^ 31 − 1
payloads_allowedrequests args
payloads_allowedrequests environment
8 × Z.of_natlengthenvironment + 1 ≤ max_allocation_size
requests16 8 × Z.of_natlengthargs + 1
requests16 8 × Z.of_natlengthenvironment + 1
libc_globals_atm g out err full short
find_fnge TAtom"main" = SomeDefinedf
fn_paramsf = W, an; P, vn
fn_blocksf = b :: blocks
variadic_funcf = false
∃fr, call_framef main_argumentsZ.of_natlengthargs argv envp = Somefr ∧ find_fnge TAtom"main" = SomeDefinedf ∧ E.effectssources roots releases requests s m born s2 m2 born2 ∧ R.readys2 c_memmkConfigfr [ ] m2 fuel ∧ persistsm m2 ∧ startup_framem m2 0 0 ∧ startup_atm2 Z.of_natlengthargs argv envp args environment ∧ libc_globals_boundge g ∧ libc_globals_atm2 g out err full short
Explore proof 12 tactics

Initial goal

⊢
forall (args environment : list (list Z)) (s : R.state) (m : mem) (born : list Z) (argv : ptr) (s1 : R.state) (m1 : mem) (born1 : list Z) (envp : ptr) (s2 : R.state) (m2 : mem) (born2 : list Z) (sources roots : list span) (releases : list Z) (requests : Z -> Z -> Prop) (ge : genv) (g : libc_global_cells) (out err full short : ptr) (f : func) (b : block) (blocks : list block) (an vn : name) (fuel : Z), copy_vector args s m born = Some (argv, s1, m1, born1) -> copy_vector environment s1 m1 born1 = Some (envp, s2, m2, born2) -> R.ready s m -> 1 <= Z.of_nat (Datatypes.length args) < 2 ^ 31 - 1 -> payloads_allowed requests args -> payloads_allowed requests environment -> 8 * (Z.of_nat (Datatypes.length environment) + 1) <= max_allocation_size -> requests 16 (8 * (Z.of_nat (Datatypes.length args) + 1)) -> requests 16 (8 * (Z.of_nat (Datatypes.length environment) + 1)) -> libc_globals_bound ge g -> libc_globals_at m g out err full short -> find_fn ge (TAtom "main") = Some (Defined f) -> fn_params f = [(W, an); (P, vn)] -> fn_blocks f = b :: blocks -> variadic_func f = false -> exists fr : frame, call_frame f (main_arguments ... ... ...) = Some fr /\ find_fn ... ... = Some ... /\ E.effects ... ... ... ... ... ... ... ... ... ... /\ ... /\ ...

intros args environment s m born argv s1 m1 born1 envp s2 m2 born2 sources roots releases requests ge g out err full short f b blocks an vn fuel Ha He Hr Hargc Hargs Henv Hmax Hra Hre Hbound Hglobals Hfind Hp Hb Hv

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
ge :
out, err, full, short :
f :
blocks :
listblock
an, vn :
fuel :
Z
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hra :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hre :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hbound :
Hglobals :
libc_globals_atm g out err full short
Hfind :
find_fnge TAtom"main" = SomeDefinedf
Hp :
fn_paramsf = W, an; P, vn
Hb :
fn_blocksf = b :: blocks
Hv :
variadic_funcf = false
⊢
∃fr : frame, call_framef main_argumentsZ.of_natDatatypes.lengthargs argv envp = Somefr ∧ find_fnge TAtom"main" = SomeDefinedf ∧ E.effectssources roots releases requests s m born s2 m2 born2 ∧ R.readys2 c_memc_frame ≔ fr; c_callers ≔ [ ]; c_mem ≔ m2; c_fuel ≔ fuel ∧ persistsm m2 ∧ startup_framem m2 0 0 ∧ startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment ∧ libc_globals_boundge g ∧ libc_globals_atm2 g out err full short

destruct copied_startupargs environment s m born argv s1 m1 born1 envp s2 m2 born2 sources roots releases requests Ha He Hr Hargc Hargs Henv Hmax Hra Hre as Heffects & Hr2 & Hpersists & Hframe & Hstartup

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
ge :
out, err, full, short :
f :
blocks :
listblock
an, vn :
fuel :
Z
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hra :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hre :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hbound :
Hglobals :
libc_globals_atm g out err full short
Hfind :
find_fnge TAtom"main" = SomeDefinedf
Hp :
fn_paramsf = W, an; P, vn
Hb :
fn_blocksf = b :: blocks
Hv :
variadic_funcf = false
Heffects :
E.effectssources roots releases requests s m born s2 m2 born2
Hr2 :
R.readys2 m2
Hpersists :
Hframe :
Hstartup :
startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment
⊢
∃fr : frame, call_framef main_argumentsZ.of_natDatatypes.lengthargs argv envp = Somefr ∧ find_fnge TAtom"main" = SomeDefinedf ∧ E.effectssources roots releases requests s m born s2 m2 born2 ∧ R.readys2 c_memc_frame ≔ fr; c_callers ≔ [ ]; c_mem ≔ m2; c_fuel ≔ fuel ∧ persistsm m2 ∧ startup_framem m2 0 0 ∧ startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment ∧ libc_globals_boundge g ∧ libc_globals_atm2 g out err full short

eexists

2 open

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
ge :
out, err, full, short :
f :
blocks :
listblock
an, vn :
fuel :
Z
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hra :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hre :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hbound :
Hglobals :
libc_globals_atm g out err full short
Hfind :
find_fnge TAtom"main" = SomeDefinedf
Hp :
fn_paramsf = W, an; P, vn
Hb :
fn_blocksf = b :: blocks
Hv :
variadic_funcf = false
Heffects :
E.effectssources roots releases requests s m born s2 m2 born2
Hr2 :
R.readys2 m2
Hpersists :
Hframe :
Hstartup :
startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment
⊢
call_framef main_argumentsZ.of_natDatatypes.lengthargs argv envp = Some?fr ∧ find_fnge TAtom"main" = SomeDefinedf ∧ E.effectssources roots releases requests s m born s2 m2 born2 ∧ R.readys2 c_memc_frame ≔ ?fr; c_callers ≔ [ ]; c_mem ≔ m2; c_fuel ≔ fuel ∧ persistsm m2 ∧ startup_framem m2 0 0 ∧ startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment ∧ libc_globals_boundge g ∧ libc_globals_atm2 g out err full short
shelved goal
args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
ge :
out, err, full, short :
f :
blocks :
listblock
an, vn :
fuel :
Z
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hra :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hre :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hbound :
Hglobals :
libc_globals_atm g out err full short
Hfind :
find_fnge TAtom"main" = SomeDefinedf
Hp :
fn_paramsf = W, an; P, vn
Hb :
fn_blocksf = b :: blocks
Hv :
variadic_funcf = false
Heffects :
E.effectssources roots releases requests s m born s2 m2 born2
Hr2 :
R.readys2 m2
Hpersists :
Hframe :
Hstartup :
startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment

split ; eapply main_argv_frame ; eauto |

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
ge :
out, err, full, short :
f :
blocks :
listblock
an, vn :
fuel :
Z
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hra :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hre :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hbound :
Hglobals :
libc_globals_atm g out err full short
Hfind :
find_fnge TAtom"main" = SomeDefinedf
Hp :
fn_paramsf = W, an; P, vn
Hb :
fn_blocksf = b :: blocks
Hv :
variadic_funcf = false
Heffects :
E.effectssources roots releases requests s m born s2 m2 born2
Hr2 :
R.readys2 m2
Hpersists :
Hframe :
Hstartup :
startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment
⊢
find_fnge TAtom"main" = SomeDefinedf ∧ E.effectssources roots releases requests s m born s2 m2 born2 ∧ R.readys2 c_memc_frame ≔ fr_fn ≔ f; fr_env ≔ putvn WPtrargv putan WIntZ.of_natDatatypes.lengthargs [ ]; fr_locals ≔ mapλxs : name × Z ⇒ fstxs, None local_objectsf; fr_doomed ≔ None; fr_at ≔ Enterb_labelb None; c_callers ≔ [ ]; c_mem ≔ m2; c_fuel ≔ fuel ∧ persistsm m2 ∧ startup_framem m2 0 0 ∧ startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment ∧ libc_globals_boundge g ∧ libc_globals_atm2 g out err full short

split ; exact Hfind |

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
ge :
out, err, full, short :
f :
blocks :
listblock
an, vn :
fuel :
Z
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hra :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hre :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hbound :
Hglobals :
libc_globals_atm g out err full short
Hfind :
find_fnge TAtom"main" = SomeDefinedf
Hp :
fn_paramsf = W, an; P, vn
Hb :
fn_blocksf = b :: blocks
Hv :
variadic_funcf = false
Heffects :
E.effectssources roots releases requests s m born s2 m2 born2
Hr2 :
R.readys2 m2
Hpersists :
Hframe :
Hstartup :
startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment
⊢
E.effectssources roots releases requests s m born s2 m2 born2 ∧ R.readys2 c_memc_frame ≔ fr_fn ≔ f; fr_env ≔ putvn WPtrargv putan WIntZ.of_natDatatypes.lengthargs [ ]; fr_locals ≔ mapλxs : name × Z ⇒ fstxs, None local_objectsf; fr_doomed ≔ None; fr_at ≔ Enterb_labelb None; c_callers ≔ [ ]; c_mem ≔ m2; c_fuel ≔ fuel ∧ persistsm m2 ∧ startup_framem m2 0 0 ∧ startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment ∧ libc_globals_boundge g ∧ libc_globals_atm2 g out err full short

split ; exact Heffects |

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
ge :
out, err, full, short :
f :
blocks :
listblock
an, vn :
fuel :
Z
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hra :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hre :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hbound :
Hglobals :
libc_globals_atm g out err full short
Hfind :
find_fnge TAtom"main" = SomeDefinedf
Hp :
fn_paramsf = W, an; P, vn
Hb :
fn_blocksf = b :: blocks
Hv :
variadic_funcf = false
Heffects :
E.effectssources roots releases requests s m born s2 m2 born2
Hr2 :
R.readys2 m2
Hpersists :
Hframe :
Hstartup :
startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment
⊢
R.readys2 c_memc_frame ≔ fr_fn ≔ f; fr_env ≔ putvn WPtrargv putan WIntZ.of_natDatatypes.lengthargs [ ]; fr_locals ≔ mapλxs : name × Z ⇒ fstxs, None local_objectsf; fr_doomed ≔ None; fr_at ≔ Enterb_labelb None; c_callers ≔ [ ]; c_mem ≔ m2; c_fuel ≔ fuel ∧ persistsm m2 ∧ startup_framem m2 0 0 ∧ startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment ∧ libc_globals_boundge g ∧ libc_globals_atm2 g out err full short

split ; exact Hr2 |

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
ge :
out, err, full, short :
f :
blocks :
listblock
an, vn :
fuel :
Z
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hra :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hre :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hbound :
Hglobals :
libc_globals_atm g out err full short
Hfind :
find_fnge TAtom"main" = SomeDefinedf
Hp :
fn_paramsf = W, an; P, vn
Hb :
fn_blocksf = b :: blocks
Hv :
variadic_funcf = false
Heffects :
E.effectssources roots releases requests s m born s2 m2 born2
Hr2 :
R.readys2 m2
Hpersists :
Hframe :
Hstartup :
startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment
⊢
persistsm m2 ∧ startup_framem m2 0 0 ∧ startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment ∧ libc_globals_boundge g ∧ libc_globals_atm2 g out err full short

split ; exact Hpersists |

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
ge :
out, err, full, short :
f :
blocks :
listblock
an, vn :
fuel :
Z
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hra :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hre :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hbound :
Hglobals :
libc_globals_atm g out err full short
Hfind :
find_fnge TAtom"main" = SomeDefinedf
Hp :
fn_paramsf = W, an; P, vn
Hb :
fn_blocksf = b :: blocks
Hv :
variadic_funcf = false
Heffects :
E.effectssources roots releases requests s m born s2 m2 born2
Hr2 :
R.readys2 m2
Hpersists :
Hframe :
Hstartup :
startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment
⊢
startup_framem m2 0 0 ∧ startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment ∧ libc_globals_boundge g ∧ libc_globals_atm2 g out err full short

split ; exact Hframe |

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
ge :
out, err, full, short :
f :
blocks :
listblock
an, vn :
fuel :
Z
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hra :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hre :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hbound :
Hglobals :
libc_globals_atm g out err full short
Hfind :
find_fnge TAtom"main" = SomeDefinedf
Hp :
fn_paramsf = W, an; P, vn
Hb :
fn_blocksf = b :: blocks
Hv :
variadic_funcf = false
Heffects :
E.effectssources roots releases requests s m born s2 m2 born2
Hr2 :
R.readys2 m2
Hpersists :
Hframe :
Hstartup :
startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment
⊢
startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment ∧ libc_globals_boundge g ∧ libc_globals_atm2 g out err full short

split ; exact Hstartup |

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
ge :
out, err, full, short :
f :
blocks :
listblock
an, vn :
fuel :
Z
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hra :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hre :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hbound :
Hglobals :
libc_globals_atm g out err full short
Hfind :
find_fnge TAtom"main" = SomeDefinedf
Hp :
fn_paramsf = W, an; P, vn
Hb :
fn_blocksf = b :: blocks
Hv :
variadic_funcf = false
Heffects :
E.effectssources roots releases requests s m born s2 m2 born2
Hr2 :
R.readys2 m2
Hpersists :
Hframe :
Hstartup :
startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment
⊢
libc_globals_boundge g ∧ libc_globals_atm2 g out err full short

split ; exact Hbound |

args, environment :
listlistZ
s :
R.state
m :
born :
listZ
argv :
s1 :
R.state
m1 :
born1 :
listZ
envp :
s2 :
R.state
m2 :
born2 :
listZ
sources, roots :
listspan
releases :
listZ
requests :
Z → Z → Prop
ge :
out, err, full, short :
f :
blocks :
listblock
an, vn :
fuel :
Z
Ha :
copy_vectorargs s m born = Someargv, s1, m1, born1
He :
copy_vectorenvironment s1 m1 born1 = Someenvp, s2, m2, born2
Hr :
R.readys m
Hargc :
1 ≤ Z.of_natDatatypes.lengthargs < 2 ^ 31 − 1
Hargs :
payloads_allowedrequests args
Henv :
payloads_allowedrequests environment
Hmax :
8 × Z.of_natDatatypes.lengthenvironment + 1 ≤ max_allocation_size
Hra :
requests16 8 × Z.of_natDatatypes.lengthargs + 1
Hre :
requests16 8 × Z.of_natDatatypes.lengthenvironment + 1
Hbound :
Hglobals :
libc_globals_atm g out err full short
Hfind :
find_fnge TAtom"main" = SomeDefinedf
Hp :
fn_paramsf = W, an; P, vn
Hb :
fn_blocksf = b :: blocks
Hv :
variadic_funcf = false
Heffects :
E.effectssources roots releases requests s m born s2 m2 born2
Hr2 :
R.readys2 m2
Hpersists :
Hframe :
Hstartup :
startup_atm2 Z.of_natDatatypes.lengthargs argv envp args environment
⊢
libc_globals_atm2 g out err full short

eapply startup_frame_libc_globals ; eauto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros args environment s m born argv s1 m1 born1 envp s2 m2 born2 sources roots releases requests ge g out err full short f b blocks an vn fuel Ha He Hr Hargc Hargs Henv Hmax Hra Hre Hbound Hglobals Hfind Hp Hb Hv
destruct copied_startupargs environment s m born argv s1 m1 born1 envp s2 m2 born2 sources roots releases requests Ha He Hr Hargc Hargs Henv Hmax Hra Hre as Heffects & Hr2 & Hpersists & Hframe & Hstartup
eexists
split ; eapply main_argv_frame ; eauto |
split ; exact Hfind |
split ; exact Heffects |
split ; exact Hr2 |
split ; exact Hpersists |
split ; exact Hframe |
split ; exact Hstartup |
split ; exact Hbound |

Standalone wrapper for existing entry clients.

884Module Startup R : Runtime
885Module M ≔ ExternalMachine R
Include StartupOn R M

Entry regressions

Two arguments of unequal lengths, including the empty string, and an empty environment distinguish argc, slot spacing and sentinels. The fixture reuses the independent hello string, not its fake ABI.

argv: a three-slot array at 4096.

896Definition entry_argv: ptr ≔
mkPtr4096 Obj4096

envp: a one-slot array at 4200, the sentinel alone.

898Definition entry_envp: ptr ≔
mkPtr4200 Obj4200

hello_mem plus the two arrays: argv's slots point at hello (with its read-only capability) and at an empty string in the object at 3072, then null; envp's only slot is null.

902Definition entry_mem: mem ≔
λ a  ⇒
4096 ≤? a && a <? 4104
→
byte_of1024 a − 4096
4104 ≤? a && a <? 4112
→
byte_of3072 a − 4104
λ a  ⇒
a =? 4096
→
Ro1024
a =? 4104
→
Obj3072
else

entry_mem is an entry image with argc 2, arguments hello and the empty string, and no environment.

912Example entry_two_arguments: startup_atentry_mem 2 entry_argv entry_envp hello_bytes; [ ] [ ]
Explore proof 12 tactics

Initial goal

split ; lia |

⊢
2 = Z.of_natDatatypes.lengthhello_bytes; [ ] ∧ string_vectorentry_mem entry_argv hello_bytes; [ ] ∧ string_vectorentry_mem entry_envp [ ]

split ; reflexivity |

split

2 open

focused goal

–split ; reflexivity |

2 open

deferred goal

exists hello_ptr

2 open

deferred goal

split ; vm_compute ; repeat split ; congruence |

2 open

deferred goal

split ; vm_compute ; repeat split ; congruence |

2 open

deferred goal

exists mkPtr3072 Obj3072

2 open

deferred goal

vm_compute

2 open

⊢
Datatypes.Lt = Datatypes.Gt → False ∧ Datatypes.Lt = Datatypes.Lt ∧ 3072 = 3072 ∧ Obj3072 = Obj3072 ∧ Someok = Someok ∧ 0 = 0 ∧ Datatypes.Eq = Datatypes.Gt → False ∧ Datatypes.Lt = Datatypes.Lt ∧ 0 = 0 ∧ CNone = CNone
deferred goal

repeat split ; congruence

deferred goal

–vm_compute

⊢
Someok = Someok ∧ Datatypes.Eq = Datatypes.Gt → False ∧ Datatypes.Lt = Datatypes.Lt ∧ 0 = 0 ∧ CNone = CNone

repeat split ; congruence

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
split ; lia |
split ; reflexivity |
split
–split ; reflexivity |
exists hello_ptr
split ; vm_compute ; repeat split ; congruence |
split ; vm_compute ; repeat split ; congruence |
exists mkPtr3072 Obj3072
vm_compute
repeat split ; congruence
–vm_compute
repeat split ; congruence

argc must count the arguments.

922Example entry_bad_count: ¬startup_atentry_mem 1 entry_argv entry_envp hello_bytes; [ ] [ ]
Explore proof 2 tactics

Initial goal

intros _ & H & _

H :
1 = Z.of_natDatatypes.lengthhello_bytes; [ ]
⊢
False

discriminate H

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros _ & H & _
discriminate H

A nonzero address in argv's sentinel slot is not a string_vector.

926Example entry_nonnull_sentinel: ¬string_vectorstore_bytesentry_mem 4112 8 1024 entry_argv hello_bytes; [ ]
Explore proof 3 tactics

Initial goal

intros _ H

pose proof string_slots_sentinel_ _ _ H as _ & Hbits & _

Hbits :
load_bytesstore_bytesentry_mem 4112 8 1024 ptr_addrentry_argv + 8 × Z.of_natDatatypes.lengthhello_bytes; [ ] 8 = ptr_addrptr_addr ≔ 0; ptr_cap ≔ CNone
⊢
False

discriminate Hbits

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros _ H
pose proof string_slots_sentinel_ _ _ H as _ & Hbits & _
discriminate Hbits

Nor is a slot whose aux lost its capability, though its address bytes are right.

935Example entry_missing_capability: ¬string_vectorstore_auxentry_mem 4096 CNone entry_argv hello_bytes; [ ]
Explore proof 5 tactics

Initial goal

intros _ p & _ & Hbits & Hcap & Hread _ & _

change 1024 = ptr_addrp in Hbits

p :
Hbits :
1024 = ptr_addrp
Hread :
access_resstore_auxentry_mem 4096 CNone ptr_addrp ptr_capp Z.of_natDatatypes.lengthhello_bytes + 1 Read 1 = Someok
⊢
False

change CNone = ptr_capp in Hcap

p :
Hbits :
1024 = ptr_addrp
Hcap :
Hread :
access_resstore_auxentry_mem 4096 CNone ptr_addrp ptr_capp Z.of_natDatatypes.lengthhello_bytes + 1 Read 1 = Someok
⊢
False

rewrite <- Hbits , <- Hcap in Hread

p :
Hbits :
1024 = ptr_addrp
Hcap :
Hread :
access_resstore_auxentry_mem 4096 CNone 1024 CNone Z.of_natDatatypes.lengthhello_bytes + 1 Read 1 = Someok
⊢
False

discriminate Hread

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros _ p & _ & Hbits & Hcap & Hread _ & _
change 1024 = ptr_addrp in Hbits
change CNone = ptr_capp in Hcap
rewrite <- Hbits , <- Hcap in Hread
discriminate Hread

Nor an argv object too small to hold the sentinel slot.

Explore proof 2 tactics

Initial goal

intros H _

H :
access_resm_bytes ≔ m_bytesentry_mem; m_regions ≔ r_base ≔ 4096; r_end ≔ 4112; r_kind ≔ Heap; r_life ≔ Live :: m_regionshello_mem; m_aux ≔ m_auxentry_mem ptr_addrentry_argv ptr_capentry_argv 8 × Z.of_natDatatypes.lengthhello_bytes; [ ] + 1 Read 8 = Someok
⊢
False

discriminate H

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros H _
discriminate H

Nor a slot whose address bytes point one byte into the string.

951Example entry_wrong_address: ¬string_vectorstore_bytesentry_mem 4096 8 1025 entry_argv hello_bytes; [ ]
Explore proof 5 tactics

Initial goal

intros _ p & _ & Hbits & _ & _ Hstring & _

change 1025 = ptr_addrp in Hbits

p :
Hbits :
1025 = ptr_addrp
⊢
False

rewrite <- Hbits in Hstring

p :
Hbits :
1025 = ptr_addrp
Hstring :
⊢
False

destruct Hstring as _ & Hbyte & _

p :
Hbits :
1025 = ptr_addrp
Hbyte :
m_bytesstore_bytesentry_mem 4096 8 1025 1025 = 104
⊢
False

discriminate Hbyte

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros _ p & _ & Hbits & _ & _ Hstring & _
change 1025 = ptr_addrp in Hbits
rewrite <- Hbits in Hstring
destruct Hstring as _ & Hbyte & _
discriminate Hbyte

Nor a string whose NUL was overwritten.

960Example entry_missing_nul: ¬string_vectorstore_bytesentry_mem 1029 1 65 entry_argv hello_bytes; [ ]
Explore proof 5 tactics

Initial goal

intros _ p & _ & Hbits & _ & _ Hstring & _

change 1024 = ptr_addrp in Hbits

p :
Hbits :
1024 = ptr_addrp
⊢
False

rewrite <- Hbits in Hstring

p :
Hbits :
1024 = ptr_addrp
⊢
False

destruct Hstring as _ & _ & _ & _ & _ & _ & _ & _ & _ & _ & Hnul

p :
Hbits :
1024 = ptr_addrp
Hnul :
string_atstore_bytesentry_mem 1029 1 65 1024 + 1 + 1 + 1 + 1 + 1 [ ]
⊢
False

discriminate Hnul

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros _ p & _ & Hbits & _ & _ Hstring & _
change 1024 = ptr_addrp in Hbits
rewrite <- Hbits in Hstring
destruct Hstring as _ & _ & _ & _ & _ & _ & _ & _ & _ & _ & Hnul
discriminate Hnul

The largest argc whose copy size is computable, INT_MAX - 1, gives 17179869176 bytes; at INT_MAX, argc + 1 overflows int.

971Example argv_copy_boundary: argv_copy_size2 ^ 31 − 2 = 17179869176 ∧ ¬0 < 2 ^ 31 − 1 + 1 < 2 ^ 31
Explore proof 1 tactics

Initial goal

⊢
argv_copy_size2 ^ 31 − 2 = 17179869176 ∧ ¬0 < 2 ^ 31 − 1 + 1 < 2 ^ 31

split ; reflexivity | lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
split ; reflexivity | lia

Status 513 reports 1, and -1 reports 255.

977Example exit_status_low_byte: process_status513 = 1 ∧ process_status−1 = 255
Explore proof 1 tactics

Initial goal

⊢
process_status513 = 1 ∧ process_status−1 = 255

split ; reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
split ; reflexivity

Construction, not a preassumed final entry image. All old argument table bytes/capabilities stay; high bytes are not interpreted as text, and the NUL must fit the new object's checked bounds.

983Definition copied_entry_string: mem ≔
copy_c_bytesallocatedentry_mem heap_req16 4 16384 16384 1; 128; 255

An empty string needs one byte for its NUL, within a rounded 16-byte object.

987Example copy_empty_string: c_stringcopy_c_bytesallocatedentry_mem heap_req16 1 16384 16384 [ ] mkPtr16384 Obj16384 [ ] ∧ req_extentheap_req16 1 = 16
Explore proof 1 tactics

Initial goal

⊢
c_stringcopy_c_bytesallocatedentry_mem heap_req16 1 16384 16384 [ ] ptr_addr ≔ 16384; ptr_cap ≔ Obj16384 [ ] ∧ req_extentheap_req16 1 = 16

repeat split ; reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
repeat split ; reflexivity

High bytes survive exactly, along with the old pointer slot and environment.

993Example copy_high_bytes_and_old_slot: c_stringcopied_entry_string mkPtr16384 Obj16384 1; 128; 255 ∧ m_bytescopied_entry_string 16387 = 0 ∧ pointer_slotcopied_entry_string 4096 hello_ptr ∧ string_vectorcopied_entry_string entry_envp [ ]
Explore proof 2 tactics

Initial goal

vm_compute

⊢
Someok = Someok ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 1 = 1 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 128 = 128 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 255 = 255 ∧ 0 = 0 ∧ 0 = 0 ∧ Datatypes.Lt = Datatypes.Gt → False ∧ Datatypes.Lt = Datatypes.Lt ∧ 1024 = 1024 ∧ Ro1024 = Ro1024 ∧ Someok = Someok ∧ Datatypes.Eq = Datatypes.Gt → False ∧ Datatypes.Lt = Datatypes.Lt ∧ 0 = 0 ∧ CNone = CNone

repeat constructor ; discriminate

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
vm_compute
repeat constructor ; discriminate

Sixteen payload bytes need a seventeenth NUL byte and a 32-byte extent.

1001Example copy_crosses_rounding_boundary: c_stringcopy_c_bytesallocatedentry_mem heap_req16 17 16384 16384 repeat255 16 mkPtr16384 Obj16384 repeat255 16 ∧ req_extentheap_req16 17 = 32
Explore proof 2 tactics

Initial goal

⊢
c_stringcopy_c_bytesallocatedentry_mem heap_req16 17 16384 16384 repeat255 16 ptr_addr ≔ 16384; ptr_cap ≔ Obj16384 repeat255 16 ∧ req_extentheap_req16 17 = 32

vm_compute

⊢
Someok = Someok ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 255 = 255 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 255 = 255 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 255 = 255 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 255 = 255 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 255 = 255 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 255 = 255 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 255 = 255 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 255 = 255 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 255 = 255 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 255 = 255 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 255 = 255 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 255 = 255 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 255 = 255 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 255 = 255 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 255 = 255 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 255 = 255 ∧ 0 = 0 ∧ 32 = 32

repeat constructor ; discriminate

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
vm_compute
repeat constructor ; discriminate

Correct payload bytes are insufficient when the NUL lies outside the object.

1007Example copied_nul_needs_bounds: ¬c_stringmkMemm_bytescopied_entry_string mkRegion16384 16387 Heap Live m_auxcopied_entry_string mkPtr16384 Obj16384 1; 128; 255
Explore proof 2 tactics

Initial goal

⊢
¬c_stringm_bytes ≔ m_bytescopied_entry_string; m_regions ≔ r_base ≔ 16384; r_end ≔ 16387; r_kind ≔ Heap; r_life ≔ Live; m_aux ≔ m_auxcopied_entry_string ptr_addr ≔ 16384; ptr_cap ≔ Obj16384 1; 128; 255

intros H _

H :
access_resm_bytes ≔ m_bytescopied_entry_string; m_regions ≔ r_base ≔ 16384; r_end ≔ 16387; r_kind ≔ Heap; r_life ≔ Live; m_aux ≔ m_auxcopied_entry_string ptr_addrptr_addr ≔ 16384; ptr_cap ≔ Obj16384 ptr_capptr_addr ≔ 16384; ptr_cap ≔ Obj16384 Z.of_natDatatypes.length1; 128; 255 + 1 Read 1 = Someok
⊢
False

discriminate H

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros H _
discriminate H

A pre-NUL payload contains neither a zero nor a value outside the byte range.

1014Example pre_nul_representation: ¬Forallλb ⇒ 0 < b < 256 65; 0; 66 ∧ ¬Forallλb ⇒ 0 < b < 256 65; 256
Explore proof 1 tactics

Initial goal

⊢
¬Forallλb : Z ⇒ 0 < b < 256 65; 0; 66 ∧ ¬Forallλb : Z ⇒ 0 < b < 256 65; 256

split ; intros H ; inversion H as | head rest Hb Hrest ; subst ; inversion Hrest as | head tail Hbad Htail ; subst ; lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
split ; intros H ; inversion H as | head rest Hb Hrest ; subst ; inversion Hrest as | head tail Hbad Htail ; subst ; lia

Executable construction examples use the ordinary interpreter runtime.

1023Module StartupExamples ≔ Startup InterpRuntime

Table first, then three strings in forward order, with distinct sizes and contents. Old pointer bytes and read-only authority stay.

1027Example constructed_argv_order: match StartupExamples.copy_vector65; 66; [ ]; 1; 128; 255 16384 entry_mem [ ] with Someargv, next, m, born ⇒ argv = mkPtr16384 Obj16384 ∧ next = 16528 ∧ born = 16496; 16464; 16432; 16384 ∧ pointer_slotm 16384 mkPtr16432 Obj16432 ∧ pointer_slotm 16392 mkPtr16464 Obj16464 ∧ pointer_slotm 16400 mkPtr16496 Obj16496 ∧ pointer_slotm 16408 mkPtr0 CNone ∧ c_stringm mkPtr16432 Obj16432 65; 66 ∧ c_stringm mkPtr16464 Obj16464 [ ] ∧ c_stringm mkPtr16496 Obj16496 1; 128; 255 ∧ pointer_slotm 4096 hello_ptr ∧ m_bytesm 1024 = 104 | None ⇒ False end
Explore proof 2 tactics

Initial goal

⊢
match StartupExamples.copy_vector65; 66; [ ]; 1; 128; 255 16384 entry_mem [ ] with
Someargv, next, m, born
⇒
argv = ptr_addr ≔ 16384; ptr_cap ≔ Obj16384 ∧ next = 16528 ∧ born = 16496; 16464; 16432; 16384 ∧ pointer_slotm 16384 ptr_addr ≔ 16432; ptr_cap ≔ Obj16432 ∧ pointer_slotm 16392 ptr_addr ≔ 16464; ptr_cap ≔ Obj16464 ∧ pointer_slotm 16400 ptr_addr ≔ 16496; ptr_cap ≔ Obj16496 ∧ pointer_slotm 16408 ptr_addr ≔ 0; ptr_cap ≔ CNone ∧ c_stringm ptr_addr ≔ 16432; ptr_cap ≔ Obj16432 65; 66 ∧ c_stringm ptr_addr ≔ 16464; ptr_cap ≔ Obj16464 [ ] ∧ c_stringm ptr_addr ≔ 16496; ptr_cap ≔ Obj16496 1; 128; 255 ∧ pointer_slotm 4096 hello_ptr ∧ m_bytesm 1024 = 104
None
⇒
False

vm_compute

⊢
ptr_addr ≔ 16384; ptr_cap ≔ Obj16384 = ptr_addr ≔ 16384; ptr_cap ≔ Obj16384 ∧ 16528 = 16528 ∧ 16496; 16464; 16432; 16384 = 16496; 16464; 16432; 16384 ∧ Datatypes.Lt = Datatypes.Gt → False ∧ Datatypes.Lt = Datatypes.Lt ∧ 16432 = 16432 ∧ Obj16432 = Obj16432 ∧ Datatypes.Lt = Datatypes.Gt → False ∧ Datatypes.Lt = Datatypes.Lt ∧ 16464 = 16464 ∧ Obj16464 = Obj16464 ∧ Datatypes.Lt = Datatypes.Gt → False ∧ Datatypes.Lt = Datatypes.Lt ∧ 16496 = 16496 ∧ Obj16496 = Obj16496 ∧ Datatypes.Eq = Datatypes.Gt → False ∧ Datatypes.Lt = Datatypes.Lt ∧ 0 = 0 ∧ CNone = CNone ∧ Someok = Someok ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 65 = 65 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 66 = 66 ∧ 0 = 0 ∧ Someok = Someok ∧ 0 = 0 ∧ Someok = Someok ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 1 = 1 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 128 = 128 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 255 = 255 ∧ 0 = 0 ∧ Datatypes.Lt = Datatypes.Gt → False ∧ Datatypes.Lt = Datatypes.Lt ∧ 1024 = 1024 ∧ Ro1024 = Ro1024 ∧ 104 = 104

repeat constructor ; discriminate

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
vm_compute
repeat constructor ; discriminate

The environment copy preserves the earlier argv and its strings; an empty environment still allocates a checked sentinel table.

1046Example constructed_entry_empty_environment: match StartupExamples.copy_vector65; 66; [ ]; 1; 128; 255 16384 entry_mem [ ] with Someargv, s, m, born ⇒ match StartupExamples.copy_vector[ ] s m born with Someenvp, next, m′, born′ ⇒ envp = mkPtr16528 Obj16528 ∧ next = 16560 ∧ born′ = 16528; 16496; 16464; 16432; 16384 ∧ pointer_slotm′ 16384 mkPtr16432 Obj16432 ∧ pointer_slotm′ 16408 mkPtr0 CNone ∧ pointer_slotm′ 16528 mkPtr0 CNone ∧ c_stringm′ mkPtr16496 Obj16496 1; 128; 255 ∧ access_resm′ ptr_addrenvp ptr_capenvp 8 Write 1 = Someok ∧ pointer_slotm′ 4096 hello_ptr | None ⇒ False end | None ⇒ False end
Explore proof 2 tactics

Initial goal

⊢
match StartupExamples.copy_vector65; 66; [ ]; 1; 128; 255 16384 entry_mem [ ] with
Some_, s, m, born
⇒
match StartupExamples.copy_vector[ ] s m born with
Someenvp, next, m′, born′
⇒
envp = ptr_addr ≔ 16528; ptr_cap ≔ Obj16528 ∧ next = 16560 ∧ born′ = 16528; 16496; 16464; 16432; 16384 ∧ pointer_slotm′ 16384 ptr_addr ≔ 16432; ptr_cap ≔ Obj16432 ∧ pointer_slotm′ 16408 ptr_addr ≔ 0; ptr_cap ≔ CNone ∧ pointer_slotm′ 16528 ptr_addr ≔ 0; ptr_cap ≔ CNone ∧ c_stringm′ ptr_addr ≔ 16496; ptr_cap ≔ Obj16496 1; 128; 255 ∧ access_resm′ ptr_addrenvp ptr_capenvp 8 Write 1 = Someok ∧ pointer_slotm′ 4096 hello_ptr
None
⇒
False
None
⇒
False

vm_compute

⊢
ptr_addr ≔ 16528; ptr_cap ≔ Obj16528 = ptr_addr ≔ 16528; ptr_cap ≔ Obj16528 ∧ 16560 = 16560 ∧ 16528; 16496; 16464; 16432; 16384 = 16528; 16496; 16464; 16432; 16384 ∧ Datatypes.Lt = Datatypes.Gt → False ∧ Datatypes.Lt = Datatypes.Lt ∧ 16432 = 16432 ∧ Obj16432 = Obj16432 ∧ Datatypes.Eq = Datatypes.Gt → False ∧ Datatypes.Lt = Datatypes.Lt ∧ 0 = 0 ∧ CNone = CNone ∧ Datatypes.Eq = Datatypes.Gt → False ∧ Datatypes.Lt = Datatypes.Lt ∧ 0 = 0 ∧ CNone = CNone ∧ Someok = Someok ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 1 = 1 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 128 = 128 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 255 = 255 ∧ 0 = 0 ∧ Someok = Someok ∧ Datatypes.Lt = Datatypes.Gt → False ∧ Datatypes.Lt = Datatypes.Lt ∧ 1024 = 1024 ∧ Ro1024 = Ro1024

repeat constructor ; discriminate

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
vm_compute
repeat constructor ; discriminate

A populated environment uses its own forward copy loop and sentinel, retaining the earlier argv even through two further string allocations.

1066Example constructed_entry_environment_bytes: match StartupExamples.copy_vector65; 66; [ ]; 1; 128; 255 16384 entry_mem [ ] with Someargv, s, m, born ⇒ match StartupExamples.copy_vector78; 70; 61; 65; 88; 61; 255 s m born with Someenvp, next, m′, born′ ⇒ envp = mkPtr16528 Obj16528 ∧ next = 16640 ∧ born′ = 16608; 16576; 16528; 16496; 16464; 16432; 16384 ∧ pointer_slotm′ 16384 mkPtr16432 Obj16432 ∧ pointer_slotm′ 16408 mkPtr0 CNone ∧ c_stringm′ mkPtr16432 Obj16432 65; 66 ∧ c_stringm′ mkPtr16464 Obj16464 [ ] ∧ c_stringm′ mkPtr16496 Obj16496 1; 128; 255 ∧ pointer_slotm′ 16528 mkPtr16576 Obj16576 ∧ pointer_slotm′ 16536 mkPtr16608 Obj16608 ∧ pointer_slotm′ 16544 mkPtr0 CNone ∧ c_stringm′ mkPtr16576 Obj16576 78; 70; 61; 65 ∧ c_stringm′ mkPtr16608 Obj16608 88; 61; 255 ∧ pointer_slotm′ 4096 hello_ptr | None ⇒ False end | None ⇒ False end
Explore proof 2 tactics

Initial goal

⊢
match StartupExamples.copy_vector65; 66; [ ]; 1; 128; 255 16384 entry_mem [ ] with
Some_, s, m, born
⇒
match StartupExamples.copy_vector78; 70; 61; 65; 88; 61; 255 s m born with
Someenvp, next, m′, born′
⇒
envp = ptr_addr ≔ 16528; ptr_cap ≔ Obj16528 ∧ next = 16640 ∧ born′ = 16608; 16576; 16528; 16496; 16464; 16432; 16384 ∧ pointer_slotm′ 16384 ptr_addr ≔ 16432; ptr_cap ≔ Obj16432 ∧ pointer_slotm′ 16408 ptr_addr ≔ 0; ptr_cap ≔ CNone ∧ c_stringm′ ptr_addr ≔ 16432; ptr_cap ≔ Obj16432 65; 66 ∧ c_stringm′ ptr_addr ≔ 16464; ptr_cap ≔ Obj16464 [ ] ∧ c_stringm′ ptr_addr ≔ 16496; ptr_cap ≔ Obj16496 1; 128; 255 ∧ pointer_slotm′ 16528 ptr_addr ≔ 16576; ptr_cap ≔ Obj16576 ∧ pointer_slotm′ 16536 ptr_addr ≔ 16608; ptr_cap ≔ Obj16608 ∧ pointer_slotm′ 16544 ptr_addr ≔ 0; ptr_cap ≔ CNone ∧ c_stringm′ ptr_addr ≔ 16576; ptr_cap ≔ Obj16576 78; 70; 61; 65 ∧ c_stringm′ ptr_addr ≔ 16608; ptr_cap ≔ Obj16608 88; 61; 255 ∧ pointer_slotm′ 4096 hello_ptr
None
⇒
False
None
⇒
False

vm_compute

⊢
ptr_addr ≔ 16528; ptr_cap ≔ Obj16528 = ptr_addr ≔ 16528; ptr_cap ≔ Obj16528 ∧ 16640 = 16640 ∧ 16608; 16576; 16528; 16496; 16464; 16432; 16384 = 16608; 16576; 16528; 16496; 16464; 16432; 16384 ∧ Datatypes.Lt = Datatypes.Gt → False ∧ Datatypes.Lt = Datatypes.Lt ∧ 16432 = 16432 ∧ Obj16432 = Obj16432 ∧ Datatypes.Eq = Datatypes.Gt → False ∧ Datatypes.Lt = Datatypes.Lt ∧ 0 = 0 ∧ CNone = CNone ∧ Someok = Someok ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 65 = 65 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 66 = 66 ∧ 0 = 0 ∧ Someok = Someok ∧ 0 = 0 ∧ Someok = Someok ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 1 = 1 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 128 = 128 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 255 = 255 ∧ 0 = 0 ∧ Datatypes.Lt = Datatypes.Gt → False ∧ Datatypes.Lt = Datatypes.Lt ∧ 16576 = 16576 ∧ Obj16576 = Obj16576 ∧ Datatypes.Lt = Datatypes.Gt → False ∧ Datatypes.Lt = Datatypes.Lt ∧ 16608 = 16608 ∧ Obj16608 = Obj16608 ∧ Datatypes.Eq = Datatypes.Gt → False ∧ Datatypes.Lt = Datatypes.Lt ∧ 0 = 0 ∧ CNone = CNone ∧ Someok = Someok ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 78 = 78 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 70 = 70 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 61 = 61 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 65 = 65 ∧ 0 = 0 ∧ Someok = Someok ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 88 = 88 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 61 = 61 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 255 = 255 ∧ 0 = 0 ∧ Datatypes.Lt = Datatypes.Gt → False ∧ Datatypes.Lt = Datatypes.Lt ∧ 1024 = 1024 ∧ Ro1024 = Ro1024

repeat constructor ; discriminate

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
vm_compute
repeat constructor ; discriminate

A resource-refusing allocator does not produce a successful empty table.

1090Example constructed_table_refusal: StartupExamples.copy_vector[ ] 2 ^ 48 − 1 entry_mem [ ] = None
Explore proof 1 tactics

Initial goal

⊢
StartupExamples.copy_vector[ ] 2 ^ 48 − 1 entry_mem [ ] = None

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
reflexivity

Environment counts above INT_MAX are not rejected by argv's int rule.

1095Example environment_count_not_int: ∀n, Z.of_natn = 2 ^ 31 → 2 ^ 31 − 1 < Z.of_natn ∧ 8 × Z.of_natn + 1 ≤ max_allocation_size
Explore proof 4 tactics

Initial goal

⊢
∀n : nat, Z.of_natn = 2 ^ 31 → 2 ^ 31 − 1 < Z.of_natn ∧ 8 × Z.of_natn + 1 ≤ max_allocation_size

intros n H

n :
nat
H :
Z.of_natn = 2 ^ 31
⊢
2 ^ 31 − 1 < Z.of_natn ∧ 8 × Z.of_natn + 1 ≤ max_allocation_size

rewrite H

n :
nat
H :
Z.of_natn = 2 ^ 31
⊢
2 ^ 31 − 1 < 2 ^ 31 ∧ 8 × 2 ^ 31 + 1 ≤ max_allocation_size

unfold max_allocation_size

n :
nat
H :
Z.of_natn = 2 ^ 31
⊢
2 ^ 31 − 1 < 2 ^ 31 ∧ 8 × 2 ^ 31 + 1 ≤ 2 ^ 48 − 1

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros n H
rewrite H
lia

An independent initialized module, not a preassumed cell predicate. Opaque stream storage is only raw data here, deliberately not FILE validity. Both names share a read-only object; short is interior.

1103Definition exposed_module: module ≔
IDataTAtom"out_storage" LLocal 16 Zero224; IDataTAtom"err_storage" LLocal 16 Zero224; IDataTAtom"name_storage" LRoTAtom"local" 1 Str120; 47; 104; 0; IDataTAtom"stdout" LExport 8 SymTAtom"out_storage" 0; IDataTAtom"stderr" LExport 8 SymTAtom"err_storage" 0; IDataTAtom"program_invocation_name" LExport 8 SymTAtom"name_storage" 0; IDataTAtom"program_invocation_short_name" LExport 8 SymTAtom"name_storage" 2

The actual initialized symbol map and memory of exposed_module.

1113Definition exposed_image: listname × ptr × mem ≔
Someimage
⇒
image
None
⇒

The initializer really succeeds at the hand-computed cell addresses.

1117Example exposed_initial_symbols: option_mapfst initial_memoryexposed_module = SomeTAtom"program_invocation_short_name", mkPtr66144 Obj66144; TAtom"program_invocation_name", mkPtr66112 Obj66112; TAtom"stderr", mkPtr66080 Obj66080; TAtom"stdout", mkPtr66048 Obj66048; TAtom"name_storage", mkPtr66016 Ro66016; TAtom"err_storage", mkPtr65776 Obj65776; TAtom"out_storage", mkPtr65536 Obj65536
Explore proof 2 tactics

Initial goal

⊢
option_mapfst initial_memoryexposed_module = SomeTAtom"program_invocation_short_name", ptr_addr ≔ 66144; ptr_cap ≔ Obj66144; TAtom"program_invocation_name", ptr_addr ≔ 66112; ptr_cap ≔ Obj66112; TAtom"stderr", ptr_addr ≔ 66080; ptr_cap ≔ Obj66080; TAtom"stdout", ptr_addr ≔ 66048; ptr_cap ≔ Obj66048; TAtom"name_storage", ptr_addr ≔ 66016; ptr_cap ≔ Ro66016; TAtom"err_storage", ptr_addr ≔ 65776; ptr_cap ≔ Obj65776; TAtom"out_storage", ptr_addr ≔ 65536; ptr_cap ≔ Obj65536

vm_compute

⊢
SomeTAtom"program_invocation_short_name", ptr_addr ≔ 66144; ptr_cap ≔ Obj66144; TAtom"program_invocation_name", ptr_addr ≔ 66112; ptr_cap ≔ Obj66112; TAtom"stderr", ptr_addr ≔ 66080; ptr_cap ≔ Obj66080; TAtom"stdout", ptr_addr ≔ 66048; ptr_cap ≔ Obj66048; TAtom"name_storage", ptr_addr ≔ 66016; ptr_cap ≔ Ro66016; TAtom"err_storage", ptr_addr ≔ 65776; ptr_cap ≔ Obj65776; TAtom"out_storage", ptr_addr ≔ 65536; ptr_cap ≔ Obj65536 = SomeTAtom"program_invocation_short_name", ptr_addr ≔ 66144; ptr_cap ≔ Obj66144; TAtom"program_invocation_name", ptr_addr ≔ 66112; ptr_cap ≔ Obj66112; TAtom"stderr", ptr_addr ≔ 66080; ptr_cap ≔ Obj66080; TAtom"stdout", ptr_addr ≔ 66048; ptr_cap ≔ Obj66048; TAtom"name_storage", ptr_addr ≔ 66016; ptr_cap ≔ Ro66016; TAtom"err_storage", ptr_addr ≔ 65776; ptr_cap ≔ Obj65776; TAtom"out_storage", ptr_addr ≔ 65536; ptr_cap ≔ Obj65536

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
vm_compute
reflexivity

Exact cell identities, independent of the values stored in them.

1129Definition exposed_cells: libc_global_cells ≔
mkLibcGlobalCellsmkPtr66048 Obj66048 mkPtr66080 Obj66080 mkPtr66112 Obj66112 mkPtr66144 Obj66144

Symbol lookup reaches cells while the initialized contents point elsewhere, with the name's exact read-only capability.

Explore proof 17 tactics

Initial goal

⊢
libc_globals_boundge_module ≔ exposed_module; ge_globals ≔ fstexposed_image; ge_free ≔ free_res exposed_cells ∧ libc_globals_atsndexposed_image exposed_cells ptr_addr ≔ 65536; ptr_cap ≔ Obj65536 ptr_addr ≔ 65776; ptr_cap ≔ Obj65776 ptr_addr ≔ 66016; ptr_cap ≔ Ro66016 ptr_addr ≔ 66018; ptr_cap ≔ Ro66016

split ; vm_compute ; repeat split ; reflexivity |

⊢
libc_globals_atsndexposed_image exposed_cells ptr_addr ≔ 65536; ptr_cap ≔ Obj65536 ptr_addr ≔ 65776; ptr_cap ≔ Obj65776 ptr_addr ≔ 66016; ptr_cap ≔ Ro66016 ptr_addr ≔ 66018; ptr_cap ≔ Ro66016

unfold libc_globals_at

repeat split;lazymatch goal with|- ∃_, _⇒idtac_⇒vm_compute ; congruenceend

6 open

focused goal
focused goal
focused goal
focused goal
⊢
∃bytes : listZ, c_stringsndexposed_image ptr_addr ≔ 66016; ptr_cap ≔ Ro66016 bytes
focused goal
⊢
∃bytes : listZ, c_stringsndexposed_image ptr_addr ≔ 66018; ptr_cap ≔ Ro66016 bytes

–exists 66048, mkRegion66048 66056 GlobalData Live

6 open

deferred goal
deferred goal
deferred goal
deferred goal
⊢
∃bytes : listZ, c_stringsndexposed_image ptr_addr ≔ 66016; ptr_cap ≔ Ro66016 bytes
deferred goal
⊢
∃bytes : listZ, c_stringsndexposed_image ptr_addr ≔ 66018; ptr_cap ≔ Ro66016 bytes

repeat split ; reflexivity

5 open

deferred goal
deferred goal
deferred goal
deferred goal
⊢
∃bytes : listZ, c_stringsndexposed_image ptr_addr ≔ 66016; ptr_cap ≔ Ro66016 bytes
deferred goal
⊢
∃bytes : listZ, c_stringsndexposed_image ptr_addr ≔ 66018; ptr_cap ≔ Ro66016 bytes

–exists 66080, mkRegion66080 66088 GlobalData Live

5 open

deferred goal
deferred goal
deferred goal
⊢
∃bytes : listZ, c_stringsndexposed_image ptr_addr ≔ 66016; ptr_cap ≔ Ro66016 bytes
deferred goal
⊢
∃bytes : listZ, c_stringsndexposed_image ptr_addr ≔ 66018; ptr_cap ≔ Ro66016 bytes

repeat split ; reflexivity

4 open

deferred goal
deferred goal
deferred goal
⊢
∃bytes : listZ, c_stringsndexposed_image ptr_addr ≔ 66016; ptr_cap ≔ Ro66016 bytes
deferred goal
⊢
∃bytes : listZ, c_stringsndexposed_image ptr_addr ≔ 66018; ptr_cap ≔ Ro66016 bytes

–exists 66112, mkRegion66112 66120 GlobalData Live

4 open

deferred goal
deferred goal
⊢
∃bytes : listZ, c_stringsndexposed_image ptr_addr ≔ 66016; ptr_cap ≔ Ro66016 bytes
deferred goal
⊢
∃bytes : listZ, c_stringsndexposed_image ptr_addr ≔ 66018; ptr_cap ≔ Ro66016 bytes

repeat split ; reflexivity

3 open

deferred goal
deferred goal
⊢
∃bytes : listZ, c_stringsndexposed_image ptr_addr ≔ 66016; ptr_cap ≔ Ro66016 bytes
deferred goal
⊢
∃bytes : listZ, c_stringsndexposed_image ptr_addr ≔ 66018; ptr_cap ≔ Ro66016 bytes

–exists 66144, mkRegion66144 66152 GlobalData Live

3 open

deferred goal
⊢
∃bytes : listZ, c_stringsndexposed_image ptr_addr ≔ 66016; ptr_cap ≔ Ro66016 bytes
deferred goal
⊢
∃bytes : listZ, c_stringsndexposed_image ptr_addr ≔ 66018; ptr_cap ≔ Ro66016 bytes

repeat split ; reflexivity

2 open

deferred goal
⊢
∃bytes : listZ, c_stringsndexposed_image ptr_addr ≔ 66016; ptr_cap ≔ Ro66016 bytes
deferred goal
⊢
∃bytes : listZ, c_stringsndexposed_image ptr_addr ≔ 66018; ptr_cap ≔ Ro66016 bytes

–exists 120; 47; 104

2 open

⊢
c_stringsndexposed_image ptr_addr ≔ 66016; ptr_cap ≔ Ro66016 120; 47; 104
deferred goal
⊢
∃bytes : listZ, c_stringsndexposed_image ptr_addr ≔ 66018; ptr_cap ≔ Ro66016 bytes

vm_compute

2 open

⊢
Someok = Someok ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 120 = 120 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 47 = 47 ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 104 = 104 ∧ 0 = 0
deferred goal
⊢
∃bytes : listZ, c_stringsndexposed_image ptr_addr ≔ 66018; ptr_cap ≔ Ro66016 bytes

repeat split ; reflexivity

deferred goal
⊢
∃bytes : listZ, c_stringsndexposed_image ptr_addr ≔ 66018; ptr_cap ≔ Ro66016 bytes

–exists 104

⊢
c_stringsndexposed_image ptr_addr ≔ 66018; ptr_cap ≔ Ro66016 104

vm_compute

⊢
Someok = Someok ∧ Datatypes.Lt = Datatypes.Lt ∧ Datatypes.Lt = Datatypes.Lt ∧ 104 = 104 ∧ 0 = 0

repeat split ; reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
split ; vm_compute ; repeat split ; reflexivity |
repeat split;lazymatch goal with|- ∃_, _⇒idtac_⇒vm_compute ; congruenceend
–exists 66048, mkRegion66048 66056 GlobalData Live
repeat split ; reflexivity
–exists 66080, mkRegion66080 66088 GlobalData Live
repeat split ; reflexivity
–exists 66112, mkRegion66112 66120 GlobalData Live
repeat split ; reflexivity
–exists 66144, mkRegion66144 66152 GlobalData Live
repeat split ; reflexivity
–exists 120; 47; 104
vm_compute
repeat split ; reflexivity
–exists 104
vm_compute
repeat split ; reflexivity

Ordinary pointer loads recover different stored addresses and the exact mutable/read-only authority, not the cells' own capabilities.

1154Example exposed_initial_loads: pointer_load_effectssndexposed_image 66048 AuxRead; LowerResolve; AddressRead = SomemkPtr65536 Obj65536 ∧ pointer_load_effectssndexposed_image 66144 AuxRead; LowerResolve; AddressRead = SomemkPtr66018 Ro66016
Explore proof 2 tactics

Initial goal

vm_compute

⊢
Someptr_addr ≔ 65536; ptr_cap ≔ Obj65536 = Someptr_addr ≔ 65536; ptr_cap ≔ Obj65536 ∧ Someptr_addr ≔ 66018; ptr_cap ≔ Ro66016 = Someptr_addr ≔ 66018; ptr_cap ≔ Ro66016

split ; reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
vm_compute
split ; reflexivity

A basename can be the empty suffix in the same name object.

1162Example exposed_empty_suffix: exposed_pointer_cellstore_auxstore_bytessndexposed_image 66144 8 66019 66144 Ro66016 short_name_cellexposed_cells mkPtr66019 Ro66016 ∧ c_stringsndexposed_image mkPtr66019 Ro66016 [ ]
Explore proof 4 tactics

Initial goal

⊢
exposed_pointer_cellstore_auxstore_bytessndexposed_image 66144 8 66019 66144 Ro66016 short_name_cellexposed_cells ptr_addr ≔ 66019; ptr_cap ≔ Ro66016 ∧ c_stringsndexposed_image ptr_addr ≔ 66019; ptr_cap ≔ Ro66016 [ ]

split ; | vm_compute ; repeat split ; reflexivity

repeat split;lazymatch goal with|- ∃_, _⇒idtac_⇒vm_compute ; congruenceend

exists 66144, mkRegion66144 66152 GlobalData Live

⊢

repeat split ; reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
split ; | vm_compute ; repeat split ; reflexivity
repeat split;lazymatch goal with|- ∃_, _⇒idtac_⇒vm_compute ; congruenceend
exists 66144, mkRegion66144 66152 GlobalData Live
repeat split ; reflexivity

Right address bits do not compensate for missing stored authority.

Explore proof 2 tactics

Initial goal

intros _ & _ & _ & _ & _ & Haux

discriminate Haux

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros _ & _ & _ & _ & _ & Haux
discriminate Haux

Correct aux does not compensate for wrong stored address bits.

1180Example exposed_wrong_bits: ¬exposed_pointer_cellstore_bytessndexposed_image 66048 8 65537 stdout_cellexposed_cells mkPtr65536 Obj65536
Explore proof 2 tactics

Initial goal

intros _ & _ & _ & _ & Hbits & _

⊢
False

discriminate Hbits

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros _ & _ & _ & _ & Hbits & _
discriminate Hbits

Pointee authority is not authority for accessing the pointer cell.

1186Example exposed_wrong_cell_identity: ¬exposed_pointer_cellsndexposed_image mkPtr66048 Obj65536 mkPtr65536 Obj65536
Explore proof 2 tactics

Initial goal

⊢
¬exposed_pointer_cellsndexposed_image ptr_addr ≔ 66048; ptr_cap ≔ Obj65536 ptr_addr ≔ 65536; ptr_cap ≔ Obj65536

intros _ & Hr & _

Hr :
access_ressndexposed_image ptr_addrptr_addr ≔ 66048; ptr_cap ≔ Obj65536 ptr_capptr_addr ≔ 66048; ptr_cap ≔ Obj65536 8 Read 8 = Someok
⊢
False

discriminate Hr

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros _ & Hr & _
discriminate Hr

The full aligned word must fit the cell's object.

Explore proof 2 tactics

Initial goal

intros _ & Hr & _

discriminate Hr

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros _ & Hr & _
discriminate Hr

Sufficient raw extent does not waive pointer-load alignment.

1199Example exposed_unaligned_cell: ¬exposed_pointer_cellmkMemm_bytessndexposed_image mkRegion66048 66064 GlobalData Live m_auxsndexposed_image mkPtr66049 Obj66048 mkPtr65536 Obj65536
Explore proof 2 tactics

Initial goal

⊢
¬exposed_pointer_cellm_bytes ≔ m_bytessndexposed_image; m_regions ≔ r_base ≔ 66048; r_end ≔ 66064; r_kind ≔ GlobalData; r_life ≔ Live; m_aux ≔ m_auxsndexposed_image ptr_addr ≔ 66049; ptr_cap ≔ Obj66048 ptr_addr ≔ 65536; ptr_cap ≔ Obj65536

intros _ & Hr & _

Hr :
access_resm_bytes ≔ m_bytessndexposed_image; m_regions ≔ r_base ≔ 66048; r_end ≔ 66064; r_kind ≔ GlobalData; r_life ≔ Live; m_aux ≔ m_auxsndexposed_image ptr_addrptr_addr ≔ 66049; ptr_cap ≔ Obj66048 ptr_capptr_addr ≔ 66049; ptr_cap ≔ Obj66048 8 Read 8 = Someok
⊢
False

discriminate Hr

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros _ & Hr & _
discriminate Hr