Fil-C on Nix

Filnix wiki

the formal campaign

rocq/theories/HelloMain.v

GNU Hello's main through the program logic

Main's proof calls the triples of every Hello layer, so it applies each layer's functor to one Logic instance: two applications of Logic have distinct expressions, and their triples could not be combined. The world is libc's, and its interpretation wi stays abstract: each premise below is what one call needs of it, so a concrete interpretation discharges them once.

From iris.proofmode Require Import proofmode
From iris.base_logic.lib Require Import gen_heap
From iris.program_logic Require Import language weakestpre
From Stdlib Require Import ZArith Lia Permutation
From Stdlib Require String
From Nanofil Require Import Term Syntax Values Memory Runtime Ops Semantics Run StepRules Symbolic ExternalCalls ExternalMachine Pieces Heap ContractFrame Language Logic StringLogic MemLogic LentLogic Locale LocaleLogic Libc HelloModule HelloLeaf HelloLocale HelloConv HelloName HelloProgName Startup Getopt GetoptLogic
Open Scope Z_scope
Open Scope list_scope

Main's function, read from the linked module.

23Definition main_fn: func ≔
Eval vm_compute in hello_fn"main"

A block of main.

26Definition main_blocks : String.string : block ≔

A 16-aligned base is 8-aligned.

29Lemma mod16_mod8
∀ b
b mod 16 = 0
b mod 8 = 0
Explore proof 6 tactics

Initial goal

b :
Z
⊢
b mod 16 = 0 → b mod 8 = 0

intros H

b :
Z
H :
b mod 16 = 0
⊢
b mod 8 = 0

apply Z.mod_divide in H ; | lia

b :
Z
H :
16 | b
⊢
b mod 8 = 0

destruct H as k →

k :
Z
⊢
k × 16 mod 8 = 0

replace k × 16 with 2 × k × 8 by lia

k :
Z
⊢
2 × k × 8 mod 8 = 0

apply Z.mod_mul

k :
Z
⊢
8 ≠ 0

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros H
apply Z.mod_divide in H ; | lia
destruct H as k →
replace k × 16 with 2 × k × 8 by lia
apply Z.mod_mul
lia

The literals main copies: "" for setlocale, the default greeting, read-only, and close_stdout's function pointer.

37Definition empty_ptr: ptr ≔
mkPtr69968 Ro69968

"Hello, world!".

39Definition greeting_ptr: ptr ≔
mkPtr70000 Ro70000

Its bytes.

41Definition greeting_bytes: listZ ≔
72; 101; 108; 108; 111; 44; 32; 119; 111; 114; 108; 100; 33

close_stdout, as a function pointer.

43Definition close_stdout_ptr: ptr ≔
mkPtr65568 FnTAtom"close_stdout"

Hello's symbols put them there.

46Lemma main_globals
lookupTAtom"hello#str.80" hello_globals = Someempty_ptr ∧ lookupTAtom"hello#str.81" hello_globals = Somegreeting_ptr ∧ lookupTAtom"close_stdout" hello_globals = Someclose_stdout_ptr
Explore proof 2 tactics

Initial goal

⊢
lookupTAtom"hello#str.80" hello_globals = Someempty_ptr ∧ lookupTAtom"hello#str.81" hello_globals = Somegreeting_ptr ∧ lookupTAtom"close_stdout" hello_globals = Someclose_stdout_ptr

vm_compute

⊢
Someptr_addr ≔ 69968; ptr_cap ≔ Ro69968 = Someptr_addr ≔ 69968; ptr_cap ≔ Ro69968 ∧ Someptr_addr ≔ 70000; ptr_cap ≔ Ro70000 = Someptr_addr ≔ 70000; ptr_cap ≔ Ro70000 ∧ Someptr_addr ≔ 65568; ptr_cap ≔ FnTAtom"close_stdout" = Someptr_addr ≔ 65568; ptr_cap ≔ FnTAtom"close_stdout"

auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
vm_compute
auto

Main's entry binds argc and argv.

53Lemma main_entry
∀ argc argv
invocationmain_fn WIntargc; WPtrargv = mkFramemain_fn TAtom"v2", WPtrargv; TAtom"v0", WIntargc [ ] None EnterTAtom"start" None
Explore proof 1 tactics

Initial goal

argc :
Z
argv :
⊢
invocationmain_fn WIntargc; WPtrargv = fr_fn ≔ main_fn; fr_env ≔ TAtom"v2", WPtrargv; TAtom"v0", WIntargc; fr_locals ≔ [ ]; fr_doomed ≔ None; fr_at ≔ EnterTAtom"start" None

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
reflexivity

getopt_long's literals

Main parses its options with getopt_long(argc, argv, "g:t", longopts, NULL). The option string and the table are Hello's read-only literals; every option's flag is null, so getopt_long returns its value.

"g:t".

66Definition optstring_ptr: ptr ≔
mkPtr69584 Ro69584

The long options table.

68Definition longopts_ptr: ptr ≔
mkPtr68672 Ro68672

The traditional greeting, "hello, world".

70Definition traditional_ptr: ptr ≔
mkPtr69808 Ro69808

Hello's long options: greeting, taking an argument, as 'g'; traditional as 't'; help and version as 128 and 129.

74Definition hello_options: listlong_option ≔
mkLongOptionmkPtr69456 Ro69456 103; 114; 101; 101; 116; 105; 110; 103 1 null 103; mkLongOptionmkPtr69488 Ro69488 116; 114; 97; 100; 105; 116; 105; 111; 110; 97; 108 0 null 116; mkLongOptionmkPtr69520 Ro69520 104; 101; 108; 112 0 null 128; mkLongOptionmkPtr69552 Ro69552 118; 101; 114; 115; 105; 111; 110 0 null 129

Hello's symbols put them there.

81Lemma getopt_globals
lookupTAtom"hello#str.69" hello_globals = Someoptstring_ptr ∧ lookupTAtom"hello#parse_options.longopts.64" hello_globals = Somelongopts_ptr ∧ lookupTAtom"hello#str.76" hello_globals = Sometraditional_ptr ∧ mapλo ⇒ Someoption_nameo hello_options = mapλs ⇒ lookupTAtoms hello_globals "hello#str.65"; "hello#str.66"; "hello#str.67"; "hello#str.68"%string
Explore proof 2 tactics

Initial goal

⊢
lookupTAtom"hello#str.69" hello_globals = Someoptstring_ptr ∧ lookupTAtom"hello#parse_options.longopts.64" hello_globals = Somelongopts_ptr ∧ lookupTAtom"hello#str.76" hello_globals = Sometraditional_ptr ∧ mapλo : long_option ⇒ Someoption_nameo hello_options = mapλs : string ⇒ lookupTAtoms hello_globals "hello#str.65"; "hello#str.66"; "hello#str.67"; "hello#str.68"

vm_compute

⊢
Someptr_addr ≔ 69584; ptr_cap ≔ Ro69584 = Someptr_addr ≔ 69584; ptr_cap ≔ Ro69584 ∧ Someptr_addr ≔ 68672; ptr_cap ≔ Ro68672 = Someptr_addr ≔ 68672; ptr_cap ≔ Ro68672 ∧ Someptr_addr ≔ 69808; ptr_cap ≔ Ro69808 = Someptr_addr ≔ 69808; ptr_cap ≔ Ro69808 ∧ Someptr_addr ≔ 69456; ptr_cap ≔ Ro69456; Someptr_addr ≔ 69488; ptr_cap ≔ Ro69488; Someptr_addr ≔ 69520; ptr_cap ≔ Ro69520; Someptr_addr ≔ 69552; ptr_cap ≔ Ro69552 = Someptr_addr ≔ 69456; ptr_cap ≔ Ro69456; Someptr_addr ≔ 69488; ptr_cap ≔ Ro69488; Someptr_addr ≔ 69520; ptr_cap ≔ Ro69520; Someptr_addr ≔ 69552; ptr_cap ≔ Ro69552

auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
vm_compute
auto

One of main's arguments: the C string at arg_ptr, in the object arg_base with the region arg_region, with contents arg_text.

91Record argument: Type ≔ mkArgument
arg_ptr
 : ptr
arg_base
 : Z
arg_region
 : region
arg_text
 : listZ

Its pieces: the string's.

99Definition arg_pss : argument : listpiece × pval ≔

getopt_long's input for one run of main, whose argv is at av and whose arguments are sargs: the same at every call, as the registry is fixed for the run.

105Definition hello_inputav : Z sargs : listargument : getopt_input ≔
mkGetoptInputZ.of_natlengthsargs mkPtrav Objav mapλs ⇒ arg_ptrs, arg_texts sargs optstring_ptr 103; 58; 116 longopts_ptr hello_options null

Argv's order is that of the arguments.

111Lemma hello_input_order
∀ av sargs
mapfst getopt_argumentshello_inputav sargs = maparg_ptr sargs
Explore proof 3 tactics

Initial goal

av :
Z
sargs :
⊢
mapfst getopt_argumentshello_inputav sargs = maparg_ptr sargs

cbn

av :
Z
sargs :
⊢
mapfst mapλs : argument ⇒ arg_ptrs, arg_texts sargs = maparg_ptr sargs

rewrite map_map

av :
Z
sargs :
⊢
mapλx : argument ⇒ arg_ptrx, arg_textx.1 sargs = maparg_ptr sargs

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
cbn
rewrite map_map
reflexivity

The literals getopt_long reads are in memory: the option string, the table's bounds and its records.

116Definition hello_table_atm : mem : Prop ≔

What main learns from getopt_long's code: a C int, and 'g' ('g' or --greeting) comes with a nonnull borrow of an argument, as both take one.

125Lemma hello_code
∀ av sargs m′ g code
getopt_resulthello_inputav sargs m′ g code
getopt_intcode ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
Explore proof 21 tactics

Initial goal

av :
Z
sargs :
m′ :
code :
Z
⊢
getopt_resulthello_inputav sargs m′ g code → getopt_intcode ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0

unfold getopt_int

av :
Z
sargs :
m′ :
code :
Z
⊢
getopt_resulthello_inputav sargs m′ g code → −2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0

intros → & _ | → | → & _ | byte & mode & Hb & _ & _ & → & Hmode & Harg | rest & Hs & _ | i & o & Hi & Hflag & _ & Harg

6 open

av :
Z
sargs :
m′ :
⊢
−2 ^ 31 ≤ −1 < 2 ^ 31 ∧ −1 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
focused goal
av :
Z
sargs :
m′ :
⊢
−2 ^ 31 ≤ 63 < 2 ^ 31 ∧ 63 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
focused goal
av :
Z
sargs :
m′ :
⊢
−2 ^ 31 ≤ 58 < 2 ^ 31 ∧ 58 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
focused goal
av :
Z
sargs :
m′ :
byte, mode :
Z
Hb :
0 < byte < 256
⊢
−2 ^ 31 ≤ if byte <? 128 then byte else byte − 256 < 2 ^ 31
∧
byte <? 128
→
byte
else
byte − 256
=
103
→
focused goal
av :
Z
sargs :
m′ :
code :
Z
rest :
listZ
Hs :
getopt_short_optionshello_inputav sargs = 45 :: rest
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
focused goal
av :
Z
sargs :
m′ :
code :
Z
i :
nat
Hi :
nth_errorgetopt_optionshello_inputav sargs i = Someo
Hflag :
else
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0

–split ; lia | intros E ; discriminate E

5 open

deferred goal
av :
Z
sargs :
m′ :
⊢
−2 ^ 31 ≤ 63 < 2 ^ 31 ∧ 63 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
⊢
−2 ^ 31 ≤ 58 < 2 ^ 31 ∧ 58 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
byte, mode :
Z
Hb :
0 < byte < 256
⊢
−2 ^ 31 ≤ if byte <? 128 then byte else byte − 256 < 2 ^ 31
∧
byte <? 128
→
byte
else
byte − 256
=
103
→
deferred goal
av :
Z
sargs :
m′ :
code :
Z
rest :
listZ
Hs :
getopt_short_optionshello_inputav sargs = 45 :: rest
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
i :
nat
Hi :
nth_errorgetopt_optionshello_inputav sargs i = Someo
Hflag :
else
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0

–split ; lia | intros E ; discriminate E

4 open

deferred goal
av :
Z
sargs :
m′ :
⊢
−2 ^ 31 ≤ 58 < 2 ^ 31 ∧ 58 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
byte, mode :
Z
Hb :
0 < byte < 256
⊢
−2 ^ 31 ≤ if byte <? 128 then byte else byte − 256 < 2 ^ 31
∧
byte <? 128
→
byte
else
byte − 256
=
103
→
deferred goal
av :
Z
sargs :
m′ :
code :
Z
rest :
listZ
Hs :
getopt_short_optionshello_inputav sargs = 45 :: rest
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
i :
nat
Hi :
nth_errorgetopt_optionshello_inputav sargs i = Someo
Hflag :
else
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0

–split ; lia | intros E ; discriminate E

3 open

deferred goal
av :
Z
sargs :
m′ :
byte, mode :
Z
Hb :
0 < byte < 256
⊢
−2 ^ 31 ≤ if byte <? 128 then byte else byte − 256 < 2 ^ 31
∧
byte <? 128
→
byte
else
byte − 256
=
103
→
deferred goal
av :
Z
sargs :
m′ :
code :
Z
rest :
listZ
Hs :
getopt_short_optionshello_inputav sargs = 45 :: rest
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
i :
nat
Hi :
nth_errorgetopt_optionshello_inputav sargs i = Someo
Hflag :
else
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0

–destruct Z.ltb_specbyte 128 as Hlt | Hge

4 open

av :
Z
sargs :
m′ :
byte, mode :
Z
Hb :
0 < byte < 256
Hlt :
byte < 128
⊢
−2 ^ 31 ≤ byte < 2 ^ 31 ∧ byte = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
focused goal
av :
Z
sargs :
m′ :
byte, mode :
Z
Hb :
0 < byte < 256
Hge :
128 ≤ byte
⊢
−2 ^ 31 ≤ byte − 256 < 2 ^ 31 ∧ byte − 256 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
rest :
listZ
Hs :
getopt_short_optionshello_inputav sargs = 45 :: rest
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
i :
nat
Hi :
nth_errorgetopt_optionshello_inputav sargs i = Someo
Hflag :
else
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0

+split ; lia |

4 open

av :
Z
sargs :
m′ :
byte, mode :
Z
Hb :
0 < byte < 256
Hlt :
byte < 128
⊢
byte = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
byte, mode :
Z
Hb :
0 < byte < 256
Hge :
128 ≤ byte
⊢
−2 ^ 31 ≤ byte − 256 < 2 ^ 31 ∧ byte − 256 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
rest :
listZ
Hs :
getopt_short_optionshello_inputav sargs = 45 :: rest
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
i :
nat
Hi :
nth_errorgetopt_optionshello_inputav sargs i = Someo
Hflag :
else
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0

intros →

4 open

av :
Z
sargs :
m′ :
mode :
Z
Hb :
0 < 103 < 256
Hlt :
103 < 128
deferred goal
av :
Z
sargs :
m′ :
byte, mode :
Z
Hb :
0 < byte < 256
Hge :
128 ≤ byte
⊢
−2 ^ 31 ≤ byte − 256 < 2 ^ 31 ∧ byte − 256 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
rest :
listZ
Hs :
getopt_short_optionshello_inputav sargs = 45 :: rest
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
i :
nat
Hi :
nth_errorgetopt_optionshello_inputav sargs i = Someo
Hflag :
else
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0

cbn in Hmode

4 open

av :
Z
sargs :
m′ :
mode :
Z
Hmode :
Some1 = Somemode
Hb :
0 < 103 < 256
Hlt :
103 < 128
deferred goal
av :
Z
sargs :
m′ :
byte, mode :
Z
Hb :
0 < byte < 256
Hge :
128 ≤ byte
⊢
−2 ^ 31 ≤ byte − 256 < 2 ^ 31 ∧ byte − 256 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
rest :
listZ
Hs :
getopt_short_optionshello_inputav sargs = 45 :: rest
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
i :
nat
Hi :
nth_errorgetopt_optionshello_inputav sargs i = Someo
Hflag :
else
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0

assert mode = 1 as → by congruence

4 open

av :
Z
sargs :
m′ :
Hmode :
Some1 = Some1
Hb :
0 < 103 < 256
Hlt :
103 < 128
deferred goal
av :
Z
sargs :
m′ :
byte, mode :
Z
Hb :
0 < byte < 256
Hge :
128 ≤ byte
⊢
−2 ^ 31 ≤ byte − 256 < 2 ^ 31 ∧ byte − 256 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
rest :
listZ
Hs :
getopt_short_optionshello_inputav sargs = 45 :: rest
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
i :
nat
Hi :
nth_errorgetopt_optionshello_inputav sargs i = Someo
Hflag :
else
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0

exact getopt_required_argument_ _ Harg

3 open

deferred goal
av :
Z
sargs :
m′ :
byte, mode :
Z
Hb :
0 < byte < 256
Hge :
128 ≤ byte
⊢
−2 ^ 31 ≤ byte − 256 < 2 ^ 31 ∧ byte − 256 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
rest :
listZ
Hs :
getopt_short_optionshello_inputav sargs = 45 :: rest
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
i :
nat
Hi :
nth_errorgetopt_optionshello_inputav sargs i = Someo
Hflag :
else
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0

+split ; lia | lia

2 open

deferred goal
av :
Z
sargs :
m′ :
code :
Z
rest :
listZ
Hs :
getopt_short_optionshello_inputav sargs = 45 :: rest
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
i :
nat
Hi :
nth_errorgetopt_optionshello_inputav sargs i = Someo
Hflag :
else
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0

–cbn in Hs

2 open

av :
Z
sargs :
m′ :
code :
Z
rest :
listZ
Hs :
103; 58; 116 = 45 :: rest
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
i :
nat
Hi :
nth_errorgetopt_optionshello_inputav sargs i = Someo
Hflag :
else
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0

discriminate Hs

deferred goal
av :
Z
sargs :
m′ :
code :
Z
i :
nat
Hi :
nth_errorgetopt_optionshello_inputav sargs i = Someo
Hflag :
else
⊢
−2 ^ 31 ≤ code < 2 ^ 31 ∧ code = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0

–destruct i as | | | | i ; | | | | destruct i ; discriminate Hi ; unfold hello_options in Hi ; cbn in Hi ; injection Hi as ← ; cbn in Hflag ; rewrite Hflag

4 open

av :
Z
sargs :
m′ :
code :
Z
Harg :
getopt_argument_athello_inputav sargs getopt_optargg option_argumentoption_name ≔ ptr_addr ≔ 69456; ptr_cap ≔ Ro69456; option_text ≔ 103; 114; 101; 101; 116; 105; 110; 103; option_argument ≔ 1; option_flag ≔ null; option_value ≔ 103
Hflag :
code = 103
⊢
−2 ^ 31 ≤ 103 < 2 ^ 31 ∧ 103 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
focused goal
av :
Z
sargs :
m′ :
code :
Z
Harg :
getopt_argument_athello_inputav sargs getopt_optargg option_argumentoption_name ≔ ptr_addr ≔ 69488; ptr_cap ≔ Ro69488; option_text ≔ 116; 114; 97; 100; 105; 116; 105; 111; 110; 97; 108; option_argument ≔ 0; option_flag ≔ null; option_value ≔ 116
Hflag :
code = 116
⊢
−2 ^ 31 ≤ 116 < 2 ^ 31 ∧ 116 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
focused goal
av :
Z
sargs :
m′ :
code :
Z
Harg :
getopt_argument_athello_inputav sargs getopt_optargg option_argumentoption_name ≔ ptr_addr ≔ 69520; ptr_cap ≔ Ro69520; option_text ≔ 104; 101; 108; 112; option_argument ≔ 0; option_flag ≔ null; option_value ≔ 128
Hflag :
code = 128
⊢
−2 ^ 31 ≤ 128 < 2 ^ 31 ∧ 128 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
focused goal
av :
Z
sargs :
m′ :
code :
Z
Harg :
getopt_argument_athello_inputav sargs getopt_optargg option_argumentoption_name ≔ ptr_addr ≔ 69552; ptr_cap ≔ Ro69552; option_text ≔ 118; 101; 114; 115; 105; 111; 110; option_argument ≔ 0; option_flag ≔ null; option_value ≔ 129
Hflag :
code = 129
⊢
−2 ^ 31 ≤ 129 < 2 ^ 31 ∧ 129 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0

+split ; lia |

4 open

av :
Z
sargs :
m′ :
code :
Z
Harg :
getopt_argument_athello_inputav sargs getopt_optargg option_argumentoption_name ≔ ptr_addr ≔ 69456; ptr_cap ≔ Ro69456; option_text ≔ 103; 114; 101; 101; 116; 105; 110; 103; option_argument ≔ 1; option_flag ≔ null; option_value ≔ 103
Hflag :
code = 103
⊢
103 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
Harg :
getopt_argument_athello_inputav sargs getopt_optargg option_argumentoption_name ≔ ptr_addr ≔ 69488; ptr_cap ≔ Ro69488; option_text ≔ 116; 114; 97; 100; 105; 116; 105; 111; 110; 97; 108; option_argument ≔ 0; option_flag ≔ null; option_value ≔ 116
Hflag :
code = 116
⊢
−2 ^ 31 ≤ 116 < 2 ^ 31 ∧ 116 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
Harg :
getopt_argument_athello_inputav sargs getopt_optargg option_argumentoption_name ≔ ptr_addr ≔ 69520; ptr_cap ≔ Ro69520; option_text ≔ 104; 101; 108; 112; option_argument ≔ 0; option_flag ≔ null; option_value ≔ 128
Hflag :
code = 128
⊢
−2 ^ 31 ≤ 128 < 2 ^ 31 ∧ 128 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
Harg :
getopt_argument_athello_inputav sargs getopt_optargg option_argumentoption_name ≔ ptr_addr ≔ 69552; ptr_cap ≔ Ro69552; option_text ≔ 118; 101; 114; 115; 105; 111; 110; option_argument ≔ 0; option_flag ≔ null; option_value ≔ 129
Hflag :
code = 129
⊢
−2 ^ 31 ≤ 129 < 2 ^ 31 ∧ 129 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0

intros _

4 open

av :
Z
sargs :
m′ :
code :
Z
Harg :
getopt_argument_athello_inputav sargs getopt_optargg option_argumentoption_name ≔ ptr_addr ≔ 69456; ptr_cap ≔ Ro69456; option_text ≔ 103; 114; 101; 101; 116; 105; 110; 103; option_argument ≔ 1; option_flag ≔ null; option_value ≔ 103
Hflag :
code = 103
deferred goal
av :
Z
sargs :
m′ :
code :
Z
Harg :
getopt_argument_athello_inputav sargs getopt_optargg option_argumentoption_name ≔ ptr_addr ≔ 69488; ptr_cap ≔ Ro69488; option_text ≔ 116; 114; 97; 100; 105; 116; 105; 111; 110; 97; 108; option_argument ≔ 0; option_flag ≔ null; option_value ≔ 116
Hflag :
code = 116
⊢
−2 ^ 31 ≤ 116 < 2 ^ 31 ∧ 116 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
Harg :
getopt_argument_athello_inputav sargs getopt_optargg option_argumentoption_name ≔ ptr_addr ≔ 69520; ptr_cap ≔ Ro69520; option_text ≔ 104; 101; 108; 112; option_argument ≔ 0; option_flag ≔ null; option_value ≔ 128
Hflag :
code = 128
⊢
−2 ^ 31 ≤ 128 < 2 ^ 31 ∧ 128 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
Harg :
getopt_argument_athello_inputav sargs getopt_optargg option_argumentoption_name ≔ ptr_addr ≔ 69552; ptr_cap ≔ Ro69552; option_text ≔ 118; 101; 114; 115; 105; 111; 110; option_argument ≔ 0; option_flag ≔ null; option_value ≔ 129
Hflag :
code = 129
⊢
−2 ^ 31 ≤ 129 < 2 ^ 31 ∧ 129 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0

exact getopt_required_argument_ _ Harg

3 open

deferred goal
av :
Z
sargs :
m′ :
code :
Z
Harg :
getopt_argument_athello_inputav sargs getopt_optargg option_argumentoption_name ≔ ptr_addr ≔ 69488; ptr_cap ≔ Ro69488; option_text ≔ 116; 114; 97; 100; 105; 116; 105; 111; 110; 97; 108; option_argument ≔ 0; option_flag ≔ null; option_value ≔ 116
Hflag :
code = 116
⊢
−2 ^ 31 ≤ 116 < 2 ^ 31 ∧ 116 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
Harg :
getopt_argument_athello_inputav sargs getopt_optargg option_argumentoption_name ≔ ptr_addr ≔ 69520; ptr_cap ≔ Ro69520; option_text ≔ 104; 101; 108; 112; option_argument ≔ 0; option_flag ≔ null; option_value ≔ 128
Hflag :
code = 128
⊢
−2 ^ 31 ≤ 128 < 2 ^ 31 ∧ 128 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
Harg :
getopt_argument_athello_inputav sargs getopt_optargg option_argumentoption_name ≔ ptr_addr ≔ 69552; ptr_cap ≔ Ro69552; option_text ≔ 118; 101; 114; 115; 105; 111; 110; option_argument ≔ 0; option_flag ≔ null; option_value ≔ 129
Hflag :
code = 129
⊢
−2 ^ 31 ≤ 129 < 2 ^ 31 ∧ 129 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0

+split ; lia | intros E ; discriminate E

2 open

deferred goal
av :
Z
sargs :
m′ :
code :
Z
Harg :
getopt_argument_athello_inputav sargs getopt_optargg option_argumentoption_name ≔ ptr_addr ≔ 69520; ptr_cap ≔ Ro69520; option_text ≔ 104; 101; 108; 112; option_argument ≔ 0; option_flag ≔ null; option_value ≔ 128
Hflag :
code = 128
⊢
−2 ^ 31 ≤ 128 < 2 ^ 31 ∧ 128 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0
deferred goal
av :
Z
sargs :
m′ :
code :
Z
Harg :
getopt_argument_athello_inputav sargs getopt_optargg option_argumentoption_name ≔ ptr_addr ≔ 69552; ptr_cap ≔ Ro69552; option_text ≔ 118; 101; 114; 115; 105; 111; 110; option_argument ≔ 0; option_flag ≔ null; option_value ≔ 129
Hflag :
code = 129
⊢
−2 ^ 31 ≤ 129 < 2 ^ 31 ∧ 129 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0

+split ; lia | intros E ; discriminate E

deferred goal
av :
Z
sargs :
m′ :
code :
Z
Harg :
getopt_argument_athello_inputav sargs getopt_optargg option_argumentoption_name ≔ ptr_addr ≔ 69552; ptr_cap ≔ Ro69552; option_text ≔ 118; 101; 114; 115; 105; 111; 110; option_argument ≔ 0; option_flag ≔ null; option_value ≔ 129
Hflag :
code = 129
⊢
−2 ^ 31 ≤ 129 < 2 ^ 31 ∧ 129 = 103 → getopt_borrowhello_inputav sargs getopt_optargg ∧ ptr_addrgetopt_optargg ≠ 0

+split ; lia | intros E ; discriminate E

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
unfold getopt_int
intros → & _ | → | → & _ | byte & mode & Hb & _ & _ & → & Hmode & Harg | rest & Hs & _ | i & o & Hi & Hflag & _ & Harg
–split ; lia | intros E ; discriminate E
–split ; lia | intros E ; discriminate E
–split ; lia | intros E ; discriminate E
–destruct Z.ltb_specbyte 128 as Hlt | Hge
+split ; lia |
intros →
cbn in Hmode
assert mode = 1 as → by congruence
+split ; lia | lia
–cbn in Hs
discriminate Hs
–destruct i as | | | | i ; | | | | destruct i ; discriminate Hi ; unfold hello_options in Hi ; cbn in Hi ; injection Hi as ← ; cbn in Hflag ; rewrite Hflag
+split ; lia |
intros _
+split ; lia | intros E ; discriminate E
+split ; lia | intros E ; discriminate E
+split ; lia | intros E ; discriminate E

argv as one block

Main hands argv to getopt_long whole, as HelloConv.v hands mbrtowc its cells: its life, the bytes of its argc + 1 pointer slots and every aux slot of them (block_ps). The bytes are those of the pointers ps argv holds, then null (argv_bytes); the aux slot at the start of each holds its capability (argv_caps). getopt_long may permute the arguments, and Campaign 4's getopt_slots says each slot's bytes are a byte each, so the block it hands back is of the same form.

The eight bytes of the address x, least significant first.

161Definition slot_bytesx : Z : listZ ≔
mapbyte_ofx 0; 1; 2; 3; 4; 5; 6; 7

The bytes of the slots holding the pointers L.

164Definition slots_bytesL : listptr : listZ ≔
flat_mapλq ⇒ slot_bytesptr_addrq L

argv's bytes, holding ps and the null sentinel.

167Definition argv_bytesps : listptr : listZ ≔

The aux slots cs of argv holding ps: as many as its bytes, the first of each pointer's eight holding its capability.

171Definition argv_capscs : listcap ps : listptr : Prop ≔
lengthcs = 8 × lengthps ++ null%nat ∧ ∀k q, ps ++ null !! k = Someq → cs !! 8 × k%nat = Someptr_capq

The memory m holds the pointer q at a: a word address, its eight bytes, and its capability in the aux slot.

177Definition slot_atm : mem a : Z q : ptr : Prop ≔
0 ≤ ptr_addrq < 2 ^ 64 ∧ ∀i, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i ∧ m_auxm a = ptr_capq

Eight bytes per pointer.

182Lemma length_slots_bytes
∀ L
lengthslots_bytesL = 8 × lengthL%nat
Explore proof 5 tactics

Initial goal

L :
listptr
⊢
lengthslots_bytesL = 8 × lengthL%nat

induction L as | q L IH ; reflexivity |

q :
L :
listptr
IH :
lengthslots_bytesL = 8 × lengthL%nat
⊢
lengthslots_bytesq :: L = 8 × lengthq :: L%nat

cbn [ slots_bytes flat_map ]

q :
L :
listptr
IH :
lengthslots_bytesL = 8 × lengthL%nat
⊢
lengthslot_bytesptr_addrq ++ flat_mapλq0 : ptr ⇒ slot_bytesptr_addrq0 L = 8 × lengthq :: L%nat

rewrite length_app IH

q :
L :
listptr
IH :
lengthslots_bytesL = 8 × lengthL%nat
⊢
lengthslot_bytesptr_addrq + 8 × lengthL%nat = 8 × lengthq :: L%nat

cbn

q :
L :
listptr
IH :
lengthslots_bytesL = 8 × lengthL%nat
⊢
SSSSSSSSlengthL + lengthL + lengthL + lengthL + lengthL + lengthL + lengthL + lengthL + 0 = SlengthL + SlengthL + SlengthL + SlengthL + SlengthL + SlengthL + SlengthL + SlengthL + 0

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
induction L as | q L IH ; reflexivity |
cbn [ slots_bytes flat_map ]
rewrite length_app IH
cbn
lia

The j-th byte of the k-th slot.

186Lemma slots_bytes_lookup
∀ L k q j
L !! k = Someq
j < 8%nat
slots_bytesL !! 8 × k + j%nat = Somebyte_ofptr_addrq Z.of_natj
Explore proof 13 tactics

Initial goal

L :
listptr
k :
nat
q :
j :
nat
⊢
L !! k = Someq → j < 8%nat → slots_bytesL !! 8 × k + j%nat = Somebyte_ofptr_addrq j

revert k

L :
listptr
q :
j :
nat
⊢
∀k : nat, L !! k = Someq → j < 8%nat → slots_bytesL !! 8 × k + j%nat = Somebyte_ofptr_addrq j

induction L as | x L IH ; intros k Hk Hj ; discriminate Hk |

x :
L :
listptr
q :
j :
nat
IH :
∀k : nat, L !! k = Someq → j < 8%nat → slots_bytesL !! 8 × k + j%nat = Somebyte_ofptr_addrq j
k :
nat
Hk :
x :: L !! k = Someq
Hj :
j < 8%nat
⊢
slots_bytesx :: L !! 8 × k + j%nat = Somebyte_ofptr_addrq j

cbn [ slots_bytes flat_map ]

x :
L :
listptr
q :
j :
nat
IH :
∀k : nat, L !! k = Someq → j < 8%nat → slots_bytesL !! 8 × k + j%nat = Somebyte_ofptr_addrq j
k :
nat
Hk :
x :: L !! k = Someq
Hj :
j < 8%nat
⊢
slot_bytesptr_addrx ++ flat_mapλq0 : ptr ⇒ slot_bytesptr_addrq0 L !! 8 × k + j%nat = Somebyte_ofptr_addrq j

destruct k as | k

2 open

x :
L :
listptr
q :
j :
nat
IH :
∀k : nat, L !! k = Someq → j < 8%nat → slots_bytesL !! 8 × k + j%nat = Somebyte_ofptr_addrq j
Hk :
x :: L !! 0%nat = Someq
Hj :
j < 8%nat
⊢
slot_bytesptr_addrx ++ flat_mapλq0 : ptr ⇒ slot_bytesptr_addrq0 L !! 8 × 0 + j%nat = Somebyte_ofptr_addrq j
focused goal
x :
L :
listptr
q :
j :
nat
IH :
∀k : nat, L !! k = Someq → j < 8%nat → slots_bytesL !! 8 × k + j%nat = Somebyte_ofptr_addrq j
k :
nat
Hk :
x :: L !! Sk = Someq
Hj :
j < 8%nat
⊢
slot_bytesptr_addrx ++ flat_mapλq0 : ptr ⇒ slot_bytesptr_addrq0 L !! 8 × Sk + j%nat = Somebyte_ofptr_addrq j

–cbn in Hk

2 open

x :
L :
listptr
q :
j :
nat
IH :
∀k : nat, L !! k = Someq → j < 8%nat → slots_bytesL !! 8 × k + j%nat = Somebyte_ofptr_addrq j
Hk :
Somex = Someq
Hj :
j < 8%nat
⊢
slot_bytesptr_addrx ++ flat_mapλq0 : ptr ⇒ slot_bytesptr_addrq0 L !! 8 × 0 + j%nat = Somebyte_ofptr_addrq j
deferred goal
x :
L :
listptr
q :
j :
nat
IH :
∀k : nat, L !! k = Someq → j < 8%nat → slots_bytesL !! 8 × k + j%nat = Somebyte_ofptr_addrq j
k :
nat
Hk :
x :: L !! Sk = Someq
Hj :
j < 8%nat
⊢
slot_bytesptr_addrx ++ flat_mapλq0 : ptr ⇒ slot_bytesptr_addrq0 L !! 8 × Sk + j%nat = Somebyte_ofptr_addrq j

injection Hk as →

2 open

L :
listptr
q :
j :
nat
IH :
∀k : nat, L !! k = Someq → j < 8%nat → slots_bytesL !! 8 × k + j%nat = Somebyte_ofptr_addrq j
Hj :
j < 8%nat
⊢
slot_bytesptr_addrq ++ flat_mapλq0 : ptr ⇒ slot_bytesptr_addrq0 L !! 8 × 0 + j%nat = Somebyte_ofptr_addrq j
deferred goal
x :
L :
listptr
q :
j :
nat
IH :
∀k : nat, L !! k = Someq → j < 8%nat → slots_bytesL !! 8 × k + j%nat = Somebyte_ofptr_addrq j
k :
nat
Hk :
x :: L !! Sk = Someq
Hj :
j < 8%nat
⊢
slot_bytesptr_addrx ++ flat_mapλq0 : ptr ⇒ slot_bytesptr_addrq0 L !! 8 × Sk + j%nat = Somebyte_ofptr_addrq j

rewrite lookup_app_l ; | cbn ; lia

2 open

L :
listptr
q :
j :
nat
IH :
∀k : nat, L !! k = Someq → j < 8%nat → slots_bytesL !! 8 × k + j%nat = Somebyte_ofptr_addrq j
Hj :
j < 8%nat
⊢
slot_bytesptr_addrq !! 8 × 0 + j%nat = Somebyte_ofptr_addrq j
deferred goal
x :
L :
listptr
q :
j :
nat
IH :
∀k : nat, L !! k = Someq → j < 8%nat → slots_bytesL !! 8 × k + j%nat = Somebyte_ofptr_addrq j
k :
nat
Hk :
x :: L !! Sk = Someq
Hj :
j < 8%nat
⊢
slot_bytesptr_addrx ++ flat_mapλq0 : ptr ⇒ slot_bytesptr_addrq0 L !! 8 × Sk + j%nat = Somebyte_ofptr_addrq j

do 8 destruct j as | j ; reflexivity |

2 open

L :
listptr
q :
j :
nat
IH :
∀k : nat, L !! k = Someq → SSSSSSSSj < 8%nat → slots_bytesL !! 8 × k + SSSSSSSSj%nat = Somebyte_ofptr_addrq SSSSSSSSj
Hj :
SSSSSSSSj < 8%nat
⊢
slot_bytesptr_addrq !! 8 × 0 + SSSSSSSSj%nat = Somebyte_ofptr_addrq SSSSSSSSj
deferred goal
x :
L :
listptr
q :
j :
nat
IH :
∀k : nat, L !! k = Someq → j < 8%nat → slots_bytesL !! 8 × k + j%nat = Somebyte_ofptr_addrq j
k :
nat
Hk :
x :: L !! Sk = Someq
Hj :
j < 8%nat
⊢
slot_bytesptr_addrx ++ flat_mapλq0 : ptr ⇒ slot_bytesptr_addrq0 L !! 8 × Sk + j%nat = Somebyte_ofptr_addrq j

lia

deferred goal
x :
L :
listptr
q :
j :
nat
IH :
∀k : nat, L !! k = Someq → j < 8%nat → slots_bytesL !! 8 × k + j%nat = Somebyte_ofptr_addrq j
k :
nat
Hk :
x :: L !! Sk = Someq
Hj :
j < 8%nat
⊢
slot_bytesptr_addrx ++ flat_mapλq0 : ptr ⇒ slot_bytesptr_addrq0 L !! 8 × Sk + j%nat = Somebyte_ofptr_addrq j

–rewrite lookup_app_r ; | cbn ; lia

x :
L :
listptr
q :
j :
nat
IH :
∀k : nat, L !! k = Someq → j < 8%nat → slots_bytesL !! 8 × k + j%nat = Somebyte_ofptr_addrq j
k :
nat
Hk :
x :: L !! Sk = Someq
Hj :
j < 8%nat
⊢
flat_mapλq0 : ptr ⇒ slot_bytesptr_addrq0 L !! 8 × Sk + j − lengthslot_bytesptr_addrx%nat = Somebyte_ofptr_addrq j

change lengthslot_bytesptr_addrx with 8%nat

x :
L :
listptr
q :
j :
nat
IH :
∀k : nat, L !! k = Someq → j < 8%nat → slots_bytesL !! 8 × k + j%nat = Somebyte_ofptr_addrq j
k :
nat
Hk :
x :: L !! Sk = Someq
Hj :
j < 8%nat
⊢
flat_mapλq0 : ptr ⇒ slot_bytesptr_addrq0 L !! 8 × Sk + j − 8%nat = Somebyte_ofptr_addrq j

replace 8 × Sk + j − 8%nat with 8 × k + j%nat by lia

x :
L :
listptr
q :
j :
nat
IH :
∀k : nat, L !! k = Someq → j < 8%nat → slots_bytesL !! 8 × k + j%nat = Somebyte_ofptr_addrq j
k :
nat
Hk :
x :: L !! Sk = Someq
Hj :
j < 8%nat
⊢
flat_mapλq0 : ptr ⇒ slot_bytesptr_addrq0 L !! 8 × k + j%nat = Somebyte_ofptr_addrq j

exact IHk Hk Hj

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
revert k
induction L as | x L IH ; intros k Hk Hj ; discriminate Hk |
cbn [ slots_bytes flat_map ]
destruct k as | k
–cbn in Hk
injection Hk as →
rewrite lookup_app_l ; | cbn ; lia
do 8 destruct j as | j ; reflexivity |
lia
–rewrite lookup_app_r ; | cbn ; lia
change lengthslot_bytesptr_addrx with 8%nat
replace 8 × Sk + j − 8%nat with 8 × k + j%nat by lia
exact IHk Hk Hj

Eight canonical bytes are determined by their little-endian value.

198Lemma load_bytes_canonical
∀ m m′ a i
∀i, 0 ≤ i < 8 → 0 ≤ m_bytesm a + i < 256
∀i, 0 ≤ i < 8 → 0 ≤ m_bytesm′ a + i < 256
load_bytesm a 8 = load_bytesm′ a 8
0 ≤ i < 8
m_bytesm a + i = m_bytesm′ a + i
Explore proof 17 tactics

Initial goal

m, m′ :
a :
Z
⊢
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm a + i < 256 → ∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm′ a + i < 256 → load_bytesm a 8 = load_bytesm′ a 8 → ∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = m_bytesm′ a + i

intros H H′ E i Hi

m, m′ :
a :
Z
H :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm a + i < 256
H′ :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm′ a + i < 256
E :
load_bytesm a 8 = load_bytesm′ a 8
i :
Z
Hi :
0 ≤ i < 8
⊢
m_bytesm a + i = m_bytesm′ a + i

unfold load_bytes in E

m, m′ :
a :
Z
H :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm a + i < 256
H′ :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm′ a + i < 256
E :
fix go n : nat acc : Z {struct n} : Z ≔
match n with
0%nat
⇒
acc
Sn′
⇒
gon′ acc × 256 + m_bytesm a + n′
Z.to_nat8 0
=
fix go n : nat acc : Z {struct n} : Z ≔
match n with
0%nat
⇒
acc
Sn′
⇒
gon′ acc × 256 + m_bytesm′ a + n′
Z.to_nat8 0
i :
Z
Hi :
0 ≤ i < 8
⊢
m_bytesm a + i = m_bytesm′ a + i

change Z.to_nat8 with 8%nat in E

m, m′ :
a :
Z
H :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm a + i < 256
H′ :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm′ a + i < 256
E :
fix go n : nat acc : Z {struct n} : Z ≔
match n with
0%nat
⇒
acc
Sn′
⇒
gon′ acc × 256 + m_bytesm a + n′
8%nat 0
=
fix go n : nat acc : Z {struct n} : Z ≔
match n with
0%nat
⇒
acc
Sn′
⇒
gon′ acc × 256 + m_bytesm′ a + n′
8%nat 0
i :
Z
Hi :
0 ≤ i < 8
⊢
m_bytesm a + i = m_bytesm′ a + i

simpl in E

m, m′ :
a :
Z
H :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm a + i < 256
H′ :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm′ a + i < 256
E :
0 × 256 + m_bytesm a + 7%nat × 256 + m_bytesm a + 6%nat × 256 + m_bytesm a + 5%nat × 256 + m_bytesm a + 4%nat × 256 + m_bytesm a + 3%nat × 256 + m_bytesm a + 2%nat × 256 + m_bytesm a + 1%nat × 256 + m_bytesm a + 0%nat = 0 × 256 + m_bytesm′ a + 7%nat × 256 + m_bytesm′ a + 6%nat × 256 + m_bytesm′ a + 5%nat × 256 + m_bytesm′ a + 4%nat × 256 + m_bytesm′ a + 3%nat × 256 + m_bytesm′ a + 2%nat × 256 + m_bytesm′ a + 1%nat × 256 + m_bytesm′ a + 0%nat
i :
Z
Hi :
0 ≤ i < 8
⊢
m_bytesm a + i = m_bytesm′ a + i

pose proof H0 ltac:lia as H0 ; pose proof H1 ltac:lia as H1 ; pose proof H2 ltac:lia as H2 ; pose proof H3 ltac:lia as H3 ; pose proof H4 ltac:lia as H4 ; pose proof H5 ltac:lia as H5 ; pose proof H6 ltac:lia as H6 ; pose proof H7 ltac:lia as H7

m, m′ :
a :
Z
H :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm a + i < 256
H′ :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm′ a + i < 256
E :
0 × 256 + m_bytesm a + 7%nat × 256 + m_bytesm a + 6%nat × 256 + m_bytesm a + 5%nat × 256 + m_bytesm a + 4%nat × 256 + m_bytesm a + 3%nat × 256 + m_bytesm a + 2%nat × 256 + m_bytesm a + 1%nat × 256 + m_bytesm a + 0%nat = 0 × 256 + m_bytesm′ a + 7%nat × 256 + m_bytesm′ a + 6%nat × 256 + m_bytesm′ a + 5%nat × 256 + m_bytesm′ a + 4%nat × 256 + m_bytesm′ a + 3%nat × 256 + m_bytesm′ a + 2%nat × 256 + m_bytesm′ a + 1%nat × 256 + m_bytesm′ a + 0%nat
i :
Z
Hi :
0 ≤ i < 8
H0 :
0 ≤ m_bytesm a + 0 < 256
H1 :
0 ≤ m_bytesm a + 1 < 256
H2 :
0 ≤ m_bytesm a + 2 < 256
H3 :
0 ≤ m_bytesm a + 3 < 256
H4 :
0 ≤ m_bytesm a + 4 < 256
H5 :
0 ≤ m_bytesm a + 5 < 256
H6 :
0 ≤ m_bytesm a + 6 < 256
H7 :
0 ≤ m_bytesm a + 7 < 256
⊢
m_bytesm a + i = m_bytesm′ a + i

pose proof H′0 ltac:lia as H0′ ; pose proof H′1 ltac:lia as H1′ ; pose proof H′2 ltac:lia as H2′ ; pose proof H′3 ltac:lia as H3′ ; pose proof H′4 ltac:lia as H4′ ; pose proof H′5 ltac:lia as H5′ ; pose proof H′6 ltac:lia as H6′ ; pose proof H′7 ltac:lia as H7′

m, m′ :
a :
Z
H :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm a + i < 256
H′ :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm′ a + i < 256
E :
0 × 256 + m_bytesm a + 7%nat × 256 + m_bytesm a + 6%nat × 256 + m_bytesm a + 5%nat × 256 + m_bytesm a + 4%nat × 256 + m_bytesm a + 3%nat × 256 + m_bytesm a + 2%nat × 256 + m_bytesm a + 1%nat × 256 + m_bytesm a + 0%nat = 0 × 256 + m_bytesm′ a + 7%nat × 256 + m_bytesm′ a + 6%nat × 256 + m_bytesm′ a + 5%nat × 256 + m_bytesm′ a + 4%nat × 256 + m_bytesm′ a + 3%nat × 256 + m_bytesm′ a + 2%nat × 256 + m_bytesm′ a + 1%nat × 256 + m_bytesm′ a + 0%nat
i :
Z
Hi :
0 ≤ i < 8
H0 :
0 ≤ m_bytesm a + 0 < 256
H1 :
0 ≤ m_bytesm a + 1 < 256
H2 :
0 ≤ m_bytesm a + 2 < 256
H3 :
0 ≤ m_bytesm a + 3 < 256
H4 :
0 ≤ m_bytesm a + 4 < 256
H5 :
0 ≤ m_bytesm a + 5 < 256
H6 :
0 ≤ m_bytesm a + 6 < 256
H7 :
0 ≤ m_bytesm a + 7 < 256
H0′ :
0 ≤ m_bytesm′ a + 0 < 256
H1′ :
0 ≤ m_bytesm′ a + 1 < 256
H2′ :
0 ≤ m_bytesm′ a + 2 < 256
H3′ :
0 ≤ m_bytesm′ a + 3 < 256
H4′ :
0 ≤ m_bytesm′ a + 4 < 256
H5′ :
0 ≤ m_bytesm′ a + 5 < 256
H6′ :
0 ≤ m_bytesm′ a + 6 < 256
H7′ :
0 ≤ m_bytesm′ a + 7 < 256
⊢
m_bytesm a + i = m_bytesm′ a + i

change Z.of_nat0 with 0 in E ; change Z.of_nat1 with 1 in E ; change Z.of_nat2 with 2 in E ; change Z.of_nat3 with 3 in E ; change Z.of_nat4 with 4 in E ; change Z.of_nat5 with 5 in E ; change Z.of_nat6 with 6 in E ; change Z.of_nat7 with 7 in E

m, m′ :
a :
Z
H :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm a + i < 256
H′ :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm′ a + i < 256
E :
0 × 256 + m_bytesm a + 7 × 256 + m_bytesm a + 6 × 256 + m_bytesm a + 5 × 256 + m_bytesm a + 4 × 256 + m_bytesm a + 3 × 256 + m_bytesm a + 2 × 256 + m_bytesm a + 1 × 256 + m_bytesm a + 0 = 0 × 256 + m_bytesm′ a + 7 × 256 + m_bytesm′ a + 6 × 256 + m_bytesm′ a + 5 × 256 + m_bytesm′ a + 4 × 256 + m_bytesm′ a + 3 × 256 + m_bytesm′ a + 2 × 256 + m_bytesm′ a + 1 × 256 + m_bytesm′ a + 0
i :
Z
Hi :
0 ≤ i < 8
H0 :
0 ≤ m_bytesm a + 0 < 256
H1 :
0 ≤ m_bytesm a + 1 < 256
H2 :
0 ≤ m_bytesm a + 2 < 256
H3 :
0 ≤ m_bytesm a + 3 < 256
H4 :
0 ≤ m_bytesm a + 4 < 256
H5 :
0 ≤ m_bytesm a + 5 < 256
H6 :
0 ≤ m_bytesm a + 6 < 256
H7 :
0 ≤ m_bytesm a + 7 < 256
H0′ :
0 ≤ m_bytesm′ a + 0 < 256
H1′ :
0 ≤ m_bytesm′ a + 1 < 256
H2′ :
0 ≤ m_bytesm′ a + 2 < 256
H3′ :
0 ≤ m_bytesm′ a + 3 < 256
H4′ :
0 ≤ m_bytesm′ a + 4 < 256
H5′ :
0 ≤ m_bytesm′ a + 5 < 256
H6′ :
0 ≤ m_bytesm′ a + 6 < 256
H7′ :
0 ≤ m_bytesm′ a + 7 < 256
⊢
m_bytesm a + i = m_bytesm′ a + i

assert m_bytesm a + 7 = m_bytesm′ a + 7 by lia

m, m′ :
a :
Z
H :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm a + i < 256
H′ :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm′ a + i < 256
E :
0 × 256 + m_bytesm a + 7 × 256 + m_bytesm a + 6 × 256 + m_bytesm a + 5 × 256 + m_bytesm a + 4 × 256 + m_bytesm a + 3 × 256 + m_bytesm a + 2 × 256 + m_bytesm a + 1 × 256 + m_bytesm a + 0 = 0 × 256 + m_bytesm′ a + 7 × 256 + m_bytesm′ a + 6 × 256 + m_bytesm′ a + 5 × 256 + m_bytesm′ a + 4 × 256 + m_bytesm′ a + 3 × 256 + m_bytesm′ a + 2 × 256 + m_bytesm′ a + 1 × 256 + m_bytesm′ a + 0
i :
Z
Hi :
0 ≤ i < 8
H0 :
0 ≤ m_bytesm a + 0 < 256
H1 :
0 ≤ m_bytesm a + 1 < 256
H2 :
0 ≤ m_bytesm a + 2 < 256
H3 :
0 ≤ m_bytesm a + 3 < 256
H4 :
0 ≤ m_bytesm a + 4 < 256
H5 :
0 ≤ m_bytesm a + 5 < 256
H6 :
0 ≤ m_bytesm a + 6 < 256
H7 :
0 ≤ m_bytesm a + 7 < 256
H0′ :
0 ≤ m_bytesm′ a + 0 < 256
H1′ :
0 ≤ m_bytesm′ a + 1 < 256
H2′ :
0 ≤ m_bytesm′ a + 2 < 256
H3′ :
0 ≤ m_bytesm′ a + 3 < 256
H4′ :
0 ≤ m_bytesm′ a + 4 < 256
H5′ :
0 ≤ m_bytesm′ a + 5 < 256
H6′ :
0 ≤ m_bytesm′ a + 6 < 256
H7′ :
0 ≤ m_bytesm′ a + 7 < 256
H8 :
m_bytesm a + 7 = m_bytesm′ a + 7
⊢
m_bytesm a + i = m_bytesm′ a + i

assert m_bytesm a + 6 = m_bytesm′ a + 6 by lia

m, m′ :
a :
Z
H :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm a + i < 256
H′ :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm′ a + i < 256
E :
0 × 256 + m_bytesm a + 7 × 256 + m_bytesm a + 6 × 256 + m_bytesm a + 5 × 256 + m_bytesm a + 4 × 256 + m_bytesm a + 3 × 256 + m_bytesm a + 2 × 256 + m_bytesm a + 1 × 256 + m_bytesm a + 0 = 0 × 256 + m_bytesm′ a + 7 × 256 + m_bytesm′ a + 6 × 256 + m_bytesm′ a + 5 × 256 + m_bytesm′ a + 4 × 256 + m_bytesm′ a + 3 × 256 + m_bytesm′ a + 2 × 256 + m_bytesm′ a + 1 × 256 + m_bytesm′ a + 0
i :
Z
Hi :
0 ≤ i < 8
H0 :
0 ≤ m_bytesm a + 0 < 256
H1 :
0 ≤ m_bytesm a + 1 < 256
H2 :
0 ≤ m_bytesm a + 2 < 256
H3 :
0 ≤ m_bytesm a + 3 < 256
H4 :
0 ≤ m_bytesm a + 4 < 256
H5 :
0 ≤ m_bytesm a + 5 < 256
H6 :
0 ≤ m_bytesm a + 6 < 256
H7 :
0 ≤ m_bytesm a + 7 < 256
H0′ :
0 ≤ m_bytesm′ a + 0 < 256
H1′ :
0 ≤ m_bytesm′ a + 1 < 256
H2′ :
0 ≤ m_bytesm′ a + 2 < 256
H3′ :
0 ≤ m_bytesm′ a + 3 < 256
H4′ :
0 ≤ m_bytesm′ a + 4 < 256
H5′ :
0 ≤ m_bytesm′ a + 5 < 256
H6′ :
0 ≤ m_bytesm′ a + 6 < 256
H7′ :
0 ≤ m_bytesm′ a + 7 < 256
H8 :
m_bytesm a + 7 = m_bytesm′ a + 7
H9 :
m_bytesm a + 6 = m_bytesm′ a + 6
⊢
m_bytesm a + i = m_bytesm′ a + i

assert m_bytesm a + 5 = m_bytesm′ a + 5 by lia

m, m′ :
a :
Z
H :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm a + i < 256
H′ :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm′ a + i < 256
E :
0 × 256 + m_bytesm a + 7 × 256 + m_bytesm a + 6 × 256 + m_bytesm a + 5 × 256 + m_bytesm a + 4 × 256 + m_bytesm a + 3 × 256 + m_bytesm a + 2 × 256 + m_bytesm a + 1 × 256 + m_bytesm a + 0 = 0 × 256 + m_bytesm′ a + 7 × 256 + m_bytesm′ a + 6 × 256 + m_bytesm′ a + 5 × 256 + m_bytesm′ a + 4 × 256 + m_bytesm′ a + 3 × 256 + m_bytesm′ a + 2 × 256 + m_bytesm′ a + 1 × 256 + m_bytesm′ a + 0
i :
Z
Hi :
0 ≤ i < 8
H0 :
0 ≤ m_bytesm a + 0 < 256
H1 :
0 ≤ m_bytesm a + 1 < 256
H2 :
0 ≤ m_bytesm a + 2 < 256
H3 :
0 ≤ m_bytesm a + 3 < 256
H4 :
0 ≤ m_bytesm a + 4 < 256
H5 :
0 ≤ m_bytesm a + 5 < 256
H6 :
0 ≤ m_bytesm a + 6 < 256
H7 :
0 ≤ m_bytesm a + 7 < 256
H0′ :
0 ≤ m_bytesm′ a + 0 < 256
H1′ :
0 ≤ m_bytesm′ a + 1 < 256
H2′ :
0 ≤ m_bytesm′ a + 2 < 256
H3′ :
0 ≤ m_bytesm′ a + 3 < 256
H4′ :
0 ≤ m_bytesm′ a + 4 < 256
H5′ :
0 ≤ m_bytesm′ a + 5 < 256
H6′ :
0 ≤ m_bytesm′ a + 6 < 256
H7′ :
0 ≤ m_bytesm′ a + 7 < 256
H8 :
m_bytesm a + 7 = m_bytesm′ a + 7
H9 :
m_bytesm a + 6 = m_bytesm′ a + 6
H10 :
m_bytesm a + 5 = m_bytesm′ a + 5
⊢
m_bytesm a + i = m_bytesm′ a + i

assert m_bytesm a + 4 = m_bytesm′ a + 4 by lia

m, m′ :
a :
Z
H :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm a + i < 256
H′ :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm′ a + i < 256
E :
0 × 256 + m_bytesm a + 7 × 256 + m_bytesm a + 6 × 256 + m_bytesm a + 5 × 256 + m_bytesm a + 4 × 256 + m_bytesm a + 3 × 256 + m_bytesm a + 2 × 256 + m_bytesm a + 1 × 256 + m_bytesm a + 0 = 0 × 256 + m_bytesm′ a + 7 × 256 + m_bytesm′ a + 6 × 256 + m_bytesm′ a + 5 × 256 + m_bytesm′ a + 4 × 256 + m_bytesm′ a + 3 × 256 + m_bytesm′ a + 2 × 256 + m_bytesm′ a + 1 × 256 + m_bytesm′ a + 0
i :
Z
Hi :
0 ≤ i < 8
H0 :
0 ≤ m_bytesm a + 0 < 256
H1 :
0 ≤ m_bytesm a + 1 < 256
H2 :
0 ≤ m_bytesm a + 2 < 256
H3 :
0 ≤ m_bytesm a + 3 < 256
H4 :
0 ≤ m_bytesm a + 4 < 256
H5 :
0 ≤ m_bytesm a + 5 < 256
H6 :
0 ≤ m_bytesm a + 6 < 256
H7 :
0 ≤ m_bytesm a + 7 < 256
H0′ :
0 ≤ m_bytesm′ a + 0 < 256
H1′ :
0 ≤ m_bytesm′ a + 1 < 256
H2′ :
0 ≤ m_bytesm′ a + 2 < 256
H3′ :
0 ≤ m_bytesm′ a + 3 < 256
H4′ :
0 ≤ m_bytesm′ a + 4 < 256
H5′ :
0 ≤ m_bytesm′ a + 5 < 256
H6′ :
0 ≤ m_bytesm′ a + 6 < 256
H7′ :
0 ≤ m_bytesm′ a + 7 < 256
H8 :
m_bytesm a + 7 = m_bytesm′ a + 7
H9 :
m_bytesm a + 6 = m_bytesm′ a + 6
H10 :
m_bytesm a + 5 = m_bytesm′ a + 5
H11 :
m_bytesm a + 4 = m_bytesm′ a + 4
⊢
m_bytesm a + i = m_bytesm′ a + i

assert m_bytesm a + 3 = m_bytesm′ a + 3 by lia

m, m′ :
a :
Z
H :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm a + i < 256
H′ :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm′ a + i < 256
E :
0 × 256 + m_bytesm a + 7 × 256 + m_bytesm a + 6 × 256 + m_bytesm a + 5 × 256 + m_bytesm a + 4 × 256 + m_bytesm a + 3 × 256 + m_bytesm a + 2 × 256 + m_bytesm a + 1 × 256 + m_bytesm a + 0 = 0 × 256 + m_bytesm′ a + 7 × 256 + m_bytesm′ a + 6 × 256 + m_bytesm′ a + 5 × 256 + m_bytesm′ a + 4 × 256 + m_bytesm′ a + 3 × 256 + m_bytesm′ a + 2 × 256 + m_bytesm′ a + 1 × 256 + m_bytesm′ a + 0
i :
Z
Hi :
0 ≤ i < 8
H0 :
0 ≤ m_bytesm a + 0 < 256
H1 :
0 ≤ m_bytesm a + 1 < 256
H2 :
0 ≤ m_bytesm a + 2 < 256
H3 :
0 ≤ m_bytesm a + 3 < 256
H4 :
0 ≤ m_bytesm a + 4 < 256
H5 :
0 ≤ m_bytesm a + 5 < 256
H6 :
0 ≤ m_bytesm a + 6 < 256
H7 :
0 ≤ m_bytesm a + 7 < 256
H0′ :
0 ≤ m_bytesm′ a + 0 < 256
H1′ :
0 ≤ m_bytesm′ a + 1 < 256
H2′ :
0 ≤ m_bytesm′ a + 2 < 256
H3′ :
0 ≤ m_bytesm′ a + 3 < 256
H4′ :
0 ≤ m_bytesm′ a + 4 < 256
H5′ :
0 ≤ m_bytesm′ a + 5 < 256
H6′ :
0 ≤ m_bytesm′ a + 6 < 256
H7′ :
0 ≤ m_bytesm′ a + 7 < 256
H8 :
m_bytesm a + 7 = m_bytesm′ a + 7
H9 :
m_bytesm a + 6 = m_bytesm′ a + 6
H10 :
m_bytesm a + 5 = m_bytesm′ a + 5
H11 :
m_bytesm a + 4 = m_bytesm′ a + 4
H12 :
m_bytesm a + 3 = m_bytesm′ a + 3
⊢
m_bytesm a + i = m_bytesm′ a + i

assert m_bytesm a + 2 = m_bytesm′ a + 2 by lia

m, m′ :
a :
Z
H :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm a + i < 256
H′ :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm′ a + i < 256
E :
0 × 256 + m_bytesm a + 7 × 256 + m_bytesm a + 6 × 256 + m_bytesm a + 5 × 256 + m_bytesm a + 4 × 256 + m_bytesm a + 3 × 256 + m_bytesm a + 2 × 256 + m_bytesm a + 1 × 256 + m_bytesm a + 0 = 0 × 256 + m_bytesm′ a + 7 × 256 + m_bytesm′ a + 6 × 256 + m_bytesm′ a + 5 × 256 + m_bytesm′ a + 4 × 256 + m_bytesm′ a + 3 × 256 + m_bytesm′ a + 2 × 256 + m_bytesm′ a + 1 × 256 + m_bytesm′ a + 0
i :
Z
Hi :
0 ≤ i < 8
H0 :
0 ≤ m_bytesm a + 0 < 256
H1 :
0 ≤ m_bytesm a + 1 < 256
H2 :
0 ≤ m_bytesm a + 2 < 256
H3 :
0 ≤ m_bytesm a + 3 < 256
H4 :
0 ≤ m_bytesm a + 4 < 256
H5 :
0 ≤ m_bytesm a + 5 < 256
H6 :
0 ≤ m_bytesm a + 6 < 256
H7 :
0 ≤ m_bytesm a + 7 < 256
H0′ :
0 ≤ m_bytesm′ a + 0 < 256
H1′ :
0 ≤ m_bytesm′ a + 1 < 256
H2′ :
0 ≤ m_bytesm′ a + 2 < 256
H3′ :
0 ≤ m_bytesm′ a + 3 < 256
H4′ :
0 ≤ m_bytesm′ a + 4 < 256
H5′ :
0 ≤ m_bytesm′ a + 5 < 256
H6′ :
0 ≤ m_bytesm′ a + 6 < 256
H7′ :
0 ≤ m_bytesm′ a + 7 < 256
H8 :
m_bytesm a + 7 = m_bytesm′ a + 7
H9 :
m_bytesm a + 6 = m_bytesm′ a + 6
H10 :
m_bytesm a + 5 = m_bytesm′ a + 5
H11 :
m_bytesm a + 4 = m_bytesm′ a + 4
H12 :
m_bytesm a + 3 = m_bytesm′ a + 3
H13 :
m_bytesm a + 2 = m_bytesm′ a + 2
⊢
m_bytesm a + i = m_bytesm′ a + i

assert m_bytesm a + 1 = m_bytesm′ a + 1 by lia

m, m′ :
a :
Z
H :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm a + i < 256
H′ :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm′ a + i < 256
E :
0 × 256 + m_bytesm a + 7 × 256 + m_bytesm a + 6 × 256 + m_bytesm a + 5 × 256 + m_bytesm a + 4 × 256 + m_bytesm a + 3 × 256 + m_bytesm a + 2 × 256 + m_bytesm a + 1 × 256 + m_bytesm a + 0 = 0 × 256 + m_bytesm′ a + 7 × 256 + m_bytesm′ a + 6 × 256 + m_bytesm′ a + 5 × 256 + m_bytesm′ a + 4 × 256 + m_bytesm′ a + 3 × 256 + m_bytesm′ a + 2 × 256 + m_bytesm′ a + 1 × 256 + m_bytesm′ a + 0
i :
Z
Hi :
0 ≤ i < 8
H0 :
0 ≤ m_bytesm a + 0 < 256
H1 :
0 ≤ m_bytesm a + 1 < 256
H2 :
0 ≤ m_bytesm a + 2 < 256
H3 :
0 ≤ m_bytesm a + 3 < 256
H4 :
0 ≤ m_bytesm a + 4 < 256
H5 :
0 ≤ m_bytesm a + 5 < 256
H6 :
0 ≤ m_bytesm a + 6 < 256
H7 :
0 ≤ m_bytesm a + 7 < 256
H0′ :
0 ≤ m_bytesm′ a + 0 < 256
H1′ :
0 ≤ m_bytesm′ a + 1 < 256
H2′ :
0 ≤ m_bytesm′ a + 2 < 256
H3′ :
0 ≤ m_bytesm′ a + 3 < 256
H4′ :
0 ≤ m_bytesm′ a + 4 < 256
H5′ :
0 ≤ m_bytesm′ a + 5 < 256
H6′ :
0 ≤ m_bytesm′ a + 6 < 256
H7′ :
0 ≤ m_bytesm′ a + 7 < 256
H8 :
m_bytesm a + 7 = m_bytesm′ a + 7
H9 :
m_bytesm a + 6 = m_bytesm′ a + 6
H10 :
m_bytesm a + 5 = m_bytesm′ a + 5
H11 :
m_bytesm a + 4 = m_bytesm′ a + 4
H12 :
m_bytesm a + 3 = m_bytesm′ a + 3
H13 :
m_bytesm a + 2 = m_bytesm′ a + 2
H14 :
m_bytesm a + 1 = m_bytesm′ a + 1
⊢
m_bytesm a + i = m_bytesm′ a + i

assert m_bytesm a + 0 = m_bytesm′ a + 0 by lia

m, m′ :
a :
Z
H :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm a + i < 256
H′ :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm′ a + i < 256
E :
0 × 256 + m_bytesm a + 7 × 256 + m_bytesm a + 6 × 256 + m_bytesm a + 5 × 256 + m_bytesm a + 4 × 256 + m_bytesm a + 3 × 256 + m_bytesm a + 2 × 256 + m_bytesm a + 1 × 256 + m_bytesm a + 0 = 0 × 256 + m_bytesm′ a + 7 × 256 + m_bytesm′ a + 6 × 256 + m_bytesm′ a + 5 × 256 + m_bytesm′ a + 4 × 256 + m_bytesm′ a + 3 × 256 + m_bytesm′ a + 2 × 256 + m_bytesm′ a + 1 × 256 + m_bytesm′ a + 0
i :
Z
Hi :
0 ≤ i < 8
H0 :
0 ≤ m_bytesm a + 0 < 256
H1 :
0 ≤ m_bytesm a + 1 < 256
H2 :
0 ≤ m_bytesm a + 2 < 256
H3 :
0 ≤ m_bytesm a + 3 < 256
H4 :
0 ≤ m_bytesm a + 4 < 256
H5 :
0 ≤ m_bytesm a + 5 < 256
H6 :
0 ≤ m_bytesm a + 6 < 256
H7 :
0 ≤ m_bytesm a + 7 < 256
H0′ :
0 ≤ m_bytesm′ a + 0 < 256
H1′ :
0 ≤ m_bytesm′ a + 1 < 256
H2′ :
0 ≤ m_bytesm′ a + 2 < 256
H3′ :
0 ≤ m_bytesm′ a + 3 < 256
H4′ :
0 ≤ m_bytesm′ a + 4 < 256
H5′ :
0 ≤ m_bytesm′ a + 5 < 256
H6′ :
0 ≤ m_bytesm′ a + 6 < 256
H7′ :
0 ≤ m_bytesm′ a + 7 < 256
H8 :
m_bytesm a + 7 = m_bytesm′ a + 7
H9 :
m_bytesm a + 6 = m_bytesm′ a + 6
H10 :
m_bytesm a + 5 = m_bytesm′ a + 5
H11 :
m_bytesm a + 4 = m_bytesm′ a + 4
H12 :
m_bytesm a + 3 = m_bytesm′ a + 3
H13 :
m_bytesm a + 2 = m_bytesm′ a + 2
H14 :
m_bytesm a + 1 = m_bytesm′ a + 1
H15 :
m_bytesm a + 0 = m_bytesm′ a + 0
⊢
m_bytesm a + i = m_bytesm′ a + i

assert i = 0 ∨ i = 1 ∨ i = 2 ∨ i = 3 ∨ i = 4 ∨ i = 5 ∨ i = 6 ∨ i = 7 as Hc by lia

m, m′ :
a :
Z
H :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm a + i < 256
H′ :
∀i : Z, 0 ≤ i < 8 → 0 ≤ m_bytesm′ a + i < 256
E :
0 × 256 + m_bytesm a + 7 × 256 + m_bytesm a + 6 × 256 + m_bytesm a + 5 × 256 + m_bytesm a + 4 × 256 + m_bytesm a + 3 × 256 + m_bytesm a + 2 × 256 + m_bytesm a + 1 × 256 + m_bytesm a + 0 = 0 × 256 + m_bytesm′ a + 7 × 256 + m_bytesm′ a + 6 × 256 + m_bytesm′ a + 5 × 256 + m_bytesm′ a + 4 × 256 + m_bytesm′ a + 3 × 256 + m_bytesm′ a + 2 × 256 + m_bytesm′ a + 1 × 256 + m_bytesm′ a + 0
i :
Z
Hi :
0 ≤ i < 8
H0 :
0 ≤ m_bytesm a + 0 < 256
H1 :
0 ≤ m_bytesm a + 1 < 256
H2 :
0 ≤ m_bytesm a + 2 < 256
H3 :
0 ≤ m_bytesm a + 3 < 256
H4 :
0 ≤ m_bytesm a + 4 < 256
H5 :
0 ≤ m_bytesm a + 5 < 256
H6 :
0 ≤ m_bytesm a + 6 < 256
H7 :
0 ≤ m_bytesm a + 7 < 256
H0′ :
0 ≤ m_bytesm′ a + 0 < 256
H1′ :
0 ≤ m_bytesm′ a + 1 < 256
H2′ :
0 ≤ m_bytesm′ a + 2 < 256
H3′ :
0 ≤ m_bytesm′ a + 3 < 256
H4′ :
0 ≤ m_bytesm′ a + 4 < 256
H5′ :
0 ≤ m_bytesm′ a + 5 < 256
H6′ :
0 ≤ m_bytesm′ a + 6 < 256
H7′ :
0 ≤ m_bytesm′ a + 7 < 256
H8 :
m_bytesm a + 7 = m_bytesm′ a + 7
H9 :
m_bytesm a + 6 = m_bytesm′ a + 6
H10 :
m_bytesm a + 5 = m_bytesm′ a + 5
H11 :
m_bytesm a + 4 = m_bytesm′ a + 4
H12 :
m_bytesm a + 3 = m_bytesm′ a + 3
H13 :
m_bytesm a + 2 = m_bytesm′ a + 2
H14 :
m_bytesm a + 1 = m_bytesm′ a + 1
H15 :
m_bytesm a + 0 = m_bytesm′ a + 0
Hc :
i = 0 ∨ i = 1 ∨ i = 2 ∨ i = 3 ∨ i = 4 ∨ i = 5 ∨ i = 6 ∨ i = 7
⊢
m_bytesm a + i = m_bytesm′ a + i

destruct Hc as [ ->| [ ->| [ ->| [ ->| [ ->| [ ->| [ ->| -> ] ] ] ] ] ] ] ; assumption

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros H H′ E i Hi
unfold load_bytes in E
change Z.to_nat8 with 8%nat in E
simpl in E
pose proof H0 ltac:lia as H0 ; pose proof H1 ltac:lia as H1 ; pose proof H2 ltac:lia as H2 ; pose proof H3 ltac:lia as H3 ; pose proof H4 ltac:lia as H4 ; pose proof H5 ltac:lia as H5 ; pose proof H6 ltac:lia as H6 ; pose proof H7 ltac:lia as H7
pose proof H′0 ltac:lia as H0′ ; pose proof H′1 ltac:lia as H1′ ; pose proof H′2 ltac:lia as H2′ ; pose proof H′3 ltac:lia as H3′ ; pose proof H′4 ltac:lia as H4′ ; pose proof H′5 ltac:lia as H5′ ; pose proof H′6 ltac:lia as H6′ ; pose proof H′7 ltac:lia as H7′
change Z.of_nat0 with 0 in E ; change Z.of_nat1 with 1 in E ; change Z.of_nat2 with 2 in E ; change Z.of_nat3 with 3 in E ; change Z.of_nat4 with 4 in E ; change Z.of_nat5 with 5 in E ; change Z.of_nat6 with 6 in E ; change Z.of_nat7 with 7 in E
assert m_bytesm a + 7 = m_bytesm′ a + 7 by lia
assert m_bytesm a + 6 = m_bytesm′ a + 6 by lia
assert m_bytesm a + 5 = m_bytesm′ a + 5 by lia
assert m_bytesm a + 4 = m_bytesm′ a + 4 by lia
assert m_bytesm a + 3 = m_bytesm′ a + 3 by lia
assert m_bytesm a + 2 = m_bytesm′ a + 2 by lia
assert m_bytesm a + 1 = m_bytesm′ a + 1 by lia
assert m_bytesm a + 0 = m_bytesm′ a + 0 by lia
assert i = 0 ∨ i = 1 ∨ i = 2 ∨ i = 3 ∨ i = 4 ∨ i = 5 ∨ i = 6 ∨ i = 7 as Hc by lia
destruct Hc as [ ->| [ ->| [ ->| [ ->| [ ->| [ ->| [ ->| -> ] ] ] ] ] ] ] ; assumption

A slot is Campaign 4's: a pointer_slot of canonical bytes.

222Lemma slot_pointer
∀ m a q
slot_atm a q
pointer_slotm a q ∧ ∀k, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
Explore proof 14 tactics

Initial goal

m :
a :
Z
q :
⊢
slot_atm a q → pointer_slotm a q ∧ ∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256

intros Hr & Hb & Hc

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hb :
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i
Hc :
m_auxm a = ptr_capq
⊢
pointer_slotm a q ∧ ∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256

split ; split ; exact Hr | split ; | exact Hc |

2 open

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hb :
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i
Hc :
m_auxm a = ptr_capq
⊢
focused goal
m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hb :
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i
Hc :
m_auxm a = ptr_capq
⊢
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256

–rewrite <- Z.mod_smallptr_addrq 2 ^ 64 ; | exact Hr

2 open

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hb :
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i
Hc :
m_auxm a = ptr_capq
⊢
load_bytesm a 8 = ptr_addrq mod 2 ^ 64
deferred goal
m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hb :
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i
Hc :
m_auxm a = ptr_capq
⊢
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256

change 2 ^ 64 with 256 ^ 8

2 open

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hb :
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i
Hc :
m_auxm a = ptr_capq
⊢
load_bytesm a 8 = ptr_addrq mod 256 ^ 8
deferred goal
m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hb :
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i
Hc :
m_auxm a = ptr_capq
⊢
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256

rewrite <- stored_bytes_valuem a 8 ptr_addrq ; | lia

2 open

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hb :
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i
Hc :
m_auxm a = ptr_capq
deferred goal
m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hb :
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i
Hc :
m_auxm a = ptr_capq
⊢
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256

apply load_bytes_agree ; lia |

2 open

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hb :
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i
Hc :
m_auxm a = ptr_capq
⊢
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = m_bytesstore_bytesm a 8 ptr_addrq a + i
deferred goal
m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hb :
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i
Hc :
m_auxm a = ptr_capq
⊢
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256

intros i Hi

2 open

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hb :
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i
Hc :
m_auxm a = ptr_capq
i :
Z
Hi :
0 ≤ i < 8
⊢
m_bytesm a + i = m_bytesstore_bytesm a 8 ptr_addrq a + i
deferred goal
m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hb :
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i
Hc :
m_auxm a = ptr_capq
⊢
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256

rewrite stored_byte ; | exact Hi

2 open

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hb :
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i
Hc :
m_auxm a = ptr_capq
i :
Z
Hi :
0 ≤ i < 8
⊢
m_bytesm a + i = byte_ofptr_addrq i
deferred goal
m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hb :
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i
Hc :
m_auxm a = ptr_capq
⊢
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256

exact Hbi Hi

deferred goal
m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hb :
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i
Hc :
m_auxm a = ptr_capq
⊢
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256

–intros k Hk

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hb :
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i
Hc :
m_auxm a = ptr_capq
k :
Z
Hk :
0 ≤ k < 8
⊢
0 ≤ m_bytesm a + k < 256

rewrite Hbk Hk

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hb :
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i
Hc :
m_auxm a = ptr_capq
k :
Z
Hk :
0 ≤ k < 8
⊢
0 ≤ byte_ofptr_addrq k < 256

unfold byte_of

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hb :
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i
Hc :
m_auxm a = ptr_capq
k :
Z
Hk :
0 ≤ k < 8
⊢
0 ≤ ptr_addrq / 2 ^ 8 × k mod 256 < 256

apply Z.mod_pos_bound

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hb :
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i
Hc :
m_auxm a = ptr_capq
k :
Z
Hk :
0 ≤ k < 8
⊢
0 < 256

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hr & Hb & Hc
split ; split ; exact Hr | split ; | exact Hc |
–rewrite <- Z.mod_smallptr_addrq 2 ^ 64 ; | exact Hr
change 2 ^ 64 with 256 ^ 8
rewrite <- stored_bytes_valuem a 8 ptr_addrq ; | lia
apply load_bytes_agree ; lia |
intros i Hi
rewrite stored_byte ; | exact Hi
exact Hbi Hi
–intros k Hk
rewrite Hbk Hk
unfold byte_of
apply Z.mod_pos_bound
lia

And back.

233Lemma pointer_slot_at
∀ m a q
∀k, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
slot_atm a q
Explore proof 17 tactics

Initial goal

m :
a :
Z
q :
⊢
pointer_slotm a q → ∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256 → slot_atm a q

intros Hr & Hl & Hc Hb

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hl :
Hc :
m_auxm a = ptr_capq
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
⊢
slot_atm a q

split ; exact Hr |

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hl :
Hc :
m_auxm a = ptr_capq
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
⊢
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i ∧ m_auxm a = ptr_capq

split ; | exact Hc

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hl :
Hc :
m_auxm a = ptr_capq
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
⊢
∀i : Z, 0 ≤ i < 8 → m_bytesm a + i = byte_ofptr_addrq i

intros i Hi

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hl :
Hc :
m_auxm a = ptr_capq
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
i :
Z
Hi :
0 ≤ i < 8
⊢
m_bytesm a + i = byte_ofptr_addrq i

rewrite <- stored_bytem a 8 ptr_addrq i Hi

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hl :
Hc :
m_auxm a = ptr_capq
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
i :
Z
Hi :
0 ≤ i < 8
⊢
m_bytesm a + i = m_bytesstore_bytesm a 8 ptr_addrq a + i

apply load_bytes_canonicalm store_bytesm a 8 ptr_addrq a ; exact Hb | | | exact Hi

2 open

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hl :
Hc :
m_auxm a = ptr_capq
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
i :
Z
Hi :
0 ≤ i < 8
⊢
∀i0 : Z, 0 ≤ i0 < 8 → 0 ≤ m_bytesstore_bytesm a 8 ptr_addrq a + i0 < 256
focused goal
m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hl :
Hc :
m_auxm a = ptr_capq
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
i :
Z
Hi :
0 ≤ i < 8

–intros k Hk

2 open

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hl :
Hc :
m_auxm a = ptr_capq
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
i :
Z
Hi :
0 ≤ i < 8
k :
Z
Hk :
0 ≤ k < 8
⊢
0 ≤ m_bytesstore_bytesm a 8 ptr_addrq a + k < 256
deferred goal
m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hl :
Hc :
m_auxm a = ptr_capq
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
i :
Z
Hi :
0 ≤ i < 8

rewrite stored_byte ; | exact Hk

2 open

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hl :
Hc :
m_auxm a = ptr_capq
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
i :
Z
Hi :
0 ≤ i < 8
k :
Z
Hk :
0 ≤ k < 8
⊢
0 ≤ byte_ofptr_addrq k < 256
deferred goal
m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hl :
Hc :
m_auxm a = ptr_capq
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
i :
Z
Hi :
0 ≤ i < 8

unfold byte_of

2 open

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hl :
Hc :
m_auxm a = ptr_capq
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
i :
Z
Hi :
0 ≤ i < 8
k :
Z
Hk :
0 ≤ k < 8
⊢
0 ≤ ptr_addrq / 2 ^ 8 × k mod 256 < 256
deferred goal
m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hl :
Hc :
m_auxm a = ptr_capq
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
i :
Z
Hi :
0 ≤ i < 8

apply Z.mod_pos_bound

2 open

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hl :
Hc :
m_auxm a = ptr_capq
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
i :
Z
Hi :
0 ≤ i < 8
k :
Z
Hk :
0 ≤ k < 8
⊢
0 < 256
deferred goal
m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hl :
Hc :
m_auxm a = ptr_capq
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
i :
Z
Hi :
0 ≤ i < 8

lia

deferred goal
m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hl :
Hc :
m_auxm a = ptr_capq
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
i :
Z
Hi :
0 ≤ i < 8

–rewrite Hl

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hl :
Hc :
m_auxm a = ptr_capq
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
i :
Z
Hi :
0 ≤ i < 8

rewrite stored_bytes_value ; | lia

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hl :
Hc :
m_auxm a = ptr_capq
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
i :
Z
Hi :
0 ≤ i < 8
⊢
ptr_addrq = ptr_addrq mod 256 ^ 8

change 256 ^ 8 with 2 ^ 64

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hl :
Hc :
m_auxm a = ptr_capq
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
i :
Z
Hi :
0 ≤ i < 8
⊢
ptr_addrq = ptr_addrq mod 2 ^ 64

symmetry

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hl :
Hc :
m_auxm a = ptr_capq
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
i :
Z
Hi :
0 ≤ i < 8
⊢
ptr_addrq mod 2 ^ 64 = ptr_addrq

apply Z.mod_small

m :
a :
Z
q :
Hr :
0 ≤ ptr_addrq < 2 ^ 64
Hl :
Hc :
m_auxm a = ptr_capq
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
i :
Z
Hi :
0 ≤ i < 8
⊢
0 ≤ ptr_addrq < 2 ^ 64

exact Hr

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hr & Hl & Hc Hb
split ; exact Hr |
split ; | exact Hc
intros i Hi
rewrite <- stored_bytem a 8 ptr_addrq i Hi
apply load_bytes_canonicalm store_bytesm a 8 ptr_addrq a ; exact Hb | | | exact Hi
–intros k Hk
rewrite stored_byte ; | exact Hk
unfold byte_of
apply Z.mod_pos_bound
lia
–rewrite Hl
rewrite stored_bytes_value ; | lia
change 256 ^ 8 with 2 ^ 64
symmetry
apply Z.mod_small
exact Hr

getopt_slots is a slot at each eighth byte, for each pointer and the sentinel.

246Lemma slots_of_at
∀ m a ps
∀k q, ps ++ null !! k = Someq → slot_atm a + 8 × Z.of_natk q
Explore proof 17 tactics

Initial goal

m :
a :
Z
ps :
listptr
⊢
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q → getopt_slotsm a ps

revert a

m :
ps :
listptr
⊢
∀a : Z, ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q → getopt_slotsm a ps

induction ps as | p ps IH ; intros a H

2 open

m :
a :
Z
H :
∀k : nat q : ptr, [ ] ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
focused goal
m :
p :
ps :
listptr
IH :
∀a : Z, ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q → getopt_slotsm a ps
a :
Z
H :
∀k : nat q : ptr, p :: ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
getopt_slotsm a p :: ps

–cbn [ getopt_slots ]

2 open

m :
a :
Z
H :
∀k : nat q : ptr, [ ] ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
pointer_slotm a ptr_addr ≔ 0; ptr_cap ≔ CNone ∧ ∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
deferred goal
m :
p :
ps :
listptr
IH :
∀a : Z, ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q → getopt_slotsm a ps
a :
Z
H :
∀k : nat q : ptr, p :: ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
getopt_slotsm a p :: ps

apply slot_pointer

2 open

m :
a :
Z
H :
∀k : nat q : ptr, [ ] ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
slot_atm a ptr_addr ≔ 0; ptr_cap ≔ CNone
deferred goal
m :
p :
ps :
listptr
IH :
∀a : Z, ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q → getopt_slotsm a ps
a :
Z
H :
∀k : nat q : ptr, p :: ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
getopt_slotsm a p :: ps

pose proof H0%nat null eq_refl as H0

2 open

m :
a :
Z
H :
∀k : nat q : ptr, [ ] ++ null !! k = Someq → slot_atm a + 8 × k q
H0 :
slot_atm a + 8 × 0%nat null
⊢
slot_atm a ptr_addr ≔ 0; ptr_cap ≔ CNone
deferred goal
m :
p :
ps :
listptr
IH :
∀a : Z, ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q → getopt_slotsm a ps
a :
Z
H :
∀k : nat q : ptr, p :: ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
getopt_slotsm a p :: ps

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

2 open

m :
a :
Z
H :
∀k : nat q : ptr, [ ] ++ null !! k = Someq → slot_atm a + 8 × k q
H0 :
⊢
slot_atm a ptr_addr ≔ 0; ptr_cap ≔ CNone
deferred goal
m :
p :
ps :
listptr
IH :
∀a : Z, ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q → getopt_slotsm a ps
a :
Z
H :
∀k : nat q : ptr, p :: ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
getopt_slotsm a p :: ps

exact H0

deferred goal
m :
p :
ps :
listptr
IH :
∀a : Z, ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q → getopt_slotsm a ps
a :
Z
H :
∀k : nat q : ptr, p :: ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
getopt_slotsm a p :: ps

–cbn [ getopt_slots ]

m :
p :
ps :
listptr
IH :
∀a : Z, ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q → getopt_slotsm a ps
a :
Z
H :
∀k : nat q : ptr, p :: ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
pointer_slotm a p ∧ ∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256 ∧ getopt_slotsm a + 8 ps

pose proof H0%nat p eq_refl as H0

m :
p :
ps :
listptr
IH :
∀a : Z, ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q → getopt_slotsm a ps
a :
Z
H :
∀k : nat q : ptr, p :: ps ++ null !! k = Someq → slot_atm a + 8 × k q
H0 :
slot_atm a + 8 × 0%nat p
⊢
pointer_slotm a p ∧ ∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256 ∧ getopt_slotsm a + 8 ps

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

m :
p :
ps :
listptr
IH :
∀a : Z, ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q → getopt_slotsm a ps
a :
Z
H :
∀k : nat q : ptr, p :: ps ++ null !! k = Someq → slot_atm a + 8 × k q
H0 :
slot_atm a p
⊢
pointer_slotm a p ∧ ∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256 ∧ getopt_slotsm a + 8 ps

destruct slot_pointer_ _ _ H0 as Hp Hb

m :
p :
ps :
listptr
IH :
∀a : Z, ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q → getopt_slotsm a ps
a :
Z
H :
∀k : nat q : ptr, p :: ps ++ null !! k = Someq → slot_atm a + 8 × k q
H0 :
slot_atm a p
Hp :
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
⊢
pointer_slotm a p ∧ ∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256 ∧ getopt_slotsm a + 8 ps

split ; exact Hp |

m :
p :
ps :
listptr
IH :
∀a : Z, ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q → getopt_slotsm a ps
a :
Z
H :
∀k : nat q : ptr, p :: ps ++ null !! k = Someq → slot_atm a + 8 × k q
H0 :
slot_atm a p
Hp :
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
⊢
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256 ∧ getopt_slotsm a + 8 ps

split ; exact Hb |

m :
p :
ps :
listptr
IH :
∀a : Z, ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q → getopt_slotsm a ps
a :
Z
H :
∀k : nat q : ptr, p :: ps ++ null !! k = Someq → slot_atm a + 8 × k q
H0 :
slot_atm a p
Hp :
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
⊢
getopt_slotsm a + 8 ps

apply IH

m :
p :
ps :
listptr
IH :
∀a : Z, ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q → getopt_slotsm a ps
a :
Z
H :
∀k : nat q : ptr, p :: ps ++ null !! k = Someq → slot_atm a + 8 × k q
H0 :
slot_atm a p
Hp :
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
⊢
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 + 8 × k q

intros k q Hk

m :
p :
ps :
listptr
IH :
∀a : Z, ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q → getopt_slotsm a ps
a :
Z
H :
∀k : nat q : ptr, p :: ps ++ null !! k = Someq → slot_atm a + 8 × k q
H0 :
slot_atm a p
Hp :
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
k :
nat
q :
Hk :
ps ++ null !! k = Someq
⊢
slot_atm a + 8 + 8 × k q

replace a + 8 + 8 × Z.of_natk with a + 8 × Z.of_natSk by lia

m :
p :
ps :
listptr
IH :
∀a : Z, ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q → getopt_slotsm a ps
a :
Z
H :
∀k : nat q : ptr, p :: ps ++ null !! k = Someq → slot_atm a + 8 × k q
H0 :
slot_atm a p
Hp :
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
k :
nat
q :
Hk :
ps ++ null !! k = Someq
⊢
slot_atm a + 8 × Sk q

exact HSk q Hk

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
revert a
induction ps as | p ps IH ; intros a H
–cbn [ getopt_slots ]
pose proof H0%nat null eq_refl as H0
replace a + 8 × Z.of_nat0 with a in H0 by lia
exact H0
–cbn [ getopt_slots ]
pose proof H0%nat p eq_refl as H0
replace a + 8 × Z.of_nat0 with a in H0 by lia
destruct slot_pointer_ _ _ H0 as Hp Hb
split ; exact Hp |
split ; exact Hb |
apply IH
intros k q Hk
replace a + 8 + 8 × Z.of_natk with a + 8 × Z.of_natSk by lia
exact HSk q Hk

And back.

260Lemma at_of_slots
∀ m a ps k q
ps ++ null !! k = Someq
slot_atm a + 8 × Z.of_natk q
Explore proof 14 tactics

Initial goal

m :
a :
Z
ps :
listptr
⊢
getopt_slotsm a ps → ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q

revert a

m :
ps :
listptr
⊢
∀a : Z, getopt_slotsm a ps → ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q

induction ps as | p ps IH ; intros a Hs k q Hk

2 open

m :
a :
Z
Hs :
k :
nat
q :
Hk :
[ ] ++ null !! k = Someq
⊢
slot_atm a + 8 × k q
focused goal
m :
p :
ps :
listptr
IH :
∀a : Z, getopt_slotsm a ps → ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
a :
Z
Hs :
getopt_slotsm a p :: ps
k :
nat
q :
Hk :
p :: ps ++ null !! k = Someq
⊢
slot_atm a + 8 × k q

–destruct k as | k ; | destruct k ; discriminate Hk

2 open

m :
a :
Z
Hs :
q :
Hk :
[ ] ++ null !! 0%nat = Someq
⊢
slot_atm a + 8 × 0%nat q
deferred goal
m :
p :
ps :
listptr
IH :
∀a : Z, getopt_slotsm a ps → ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
a :
Z
Hs :
getopt_slotsm a p :: ps
k :
nat
q :
Hk :
p :: ps ++ null !! k = Someq
⊢
slot_atm a + 8 × k q

injection Hk as ←

2 open

m :
a :
Z
Hs :
⊢
slot_atm a + 8 × 0%nat null
deferred goal
m :
p :
ps :
listptr
IH :
∀a : Z, getopt_slotsm a ps → ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
a :
Z
Hs :
getopt_slotsm a p :: ps
k :
nat
q :
Hk :
p :: ps ++ null !! k = Someq
⊢
slot_atm a + 8 × k q

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

2 open

m :
a :
Z
Hs :
deferred goal
m :
p :
ps :
listptr
IH :
∀a : Z, getopt_slotsm a ps → ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
a :
Z
Hs :
getopt_slotsm a p :: ps
k :
nat
q :
Hk :
p :: ps ++ null !! k = Someq
⊢
slot_atm a + 8 × k q

destruct Hs as Hp Hb

2 open

m :
a :
Z
Hp :
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
deferred goal
m :
p :
ps :
listptr
IH :
∀a : Z, getopt_slotsm a ps → ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
a :
Z
Hs :
getopt_slotsm a p :: ps
k :
nat
q :
Hk :
p :: ps ++ null !! k = Someq
⊢
slot_atm a + 8 × k q

exact pointer_slot_at_ _ _ Hp Hb

deferred goal
m :
p :
ps :
listptr
IH :
∀a : Z, getopt_slotsm a ps → ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
a :
Z
Hs :
getopt_slotsm a p :: ps
k :
nat
q :
Hk :
p :: ps ++ null !! k = Someq
⊢
slot_atm a + 8 × k q

–destruct Hs as Hp & Hb & Hr

m :
p :
ps :
listptr
IH :
∀a : Z, getopt_slotsm a ps → ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
a :
Z
Hp :
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
Hr :
getopt_slotsm a + 8 ps
k :
nat
q :
Hk :
p :: ps ++ null !! k = Someq
⊢
slot_atm a + 8 × k q

destruct k as | k

2 open

m :
p :
ps :
listptr
IH :
∀a : Z, getopt_slotsm a ps → ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
a :
Z
Hp :
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
Hr :
getopt_slotsm a + 8 ps
q :
Hk :
p :: ps ++ null !! 0%nat = Someq
⊢
slot_atm a + 8 × 0%nat q
focused goal
m :
p :
ps :
listptr
IH :
∀a : Z, getopt_slotsm a ps → ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
a :
Z
Hp :
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
Hr :
getopt_slotsm a + 8 ps
k :
nat
q :
Hk :
p :: ps ++ null !! Sk = Someq
⊢
slot_atm a + 8 × Sk q

+injection Hk as ←

2 open

m :
p :
ps :
listptr
IH :
∀a : Z, getopt_slotsm a ps → ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
a :
Z
Hp :
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
Hr :
getopt_slotsm a + 8 ps
⊢
slot_atm a + 8 × 0%nat p
deferred goal
m :
p :
ps :
listptr
IH :
∀a : Z, getopt_slotsm a ps → ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
a :
Z
Hp :
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
Hr :
getopt_slotsm a + 8 ps
k :
nat
q :
Hk :
p :: ps ++ null !! Sk = Someq
⊢
slot_atm a + 8 × Sk q

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

2 open

m :
p :
ps :
listptr
IH :
∀a : Z, getopt_slotsm a ps → ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
a :
Z
Hp :
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
Hr :
getopt_slotsm a + 8 ps
⊢
slot_atm a p
deferred goal
m :
p :
ps :
listptr
IH :
∀a : Z, getopt_slotsm a ps → ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
a :
Z
Hp :
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
Hr :
getopt_slotsm a + 8 ps
k :
nat
q :
Hk :
p :: ps ++ null !! Sk = Someq
⊢
slot_atm a + 8 × Sk q

exact pointer_slot_at_ _ _ Hp Hb

deferred goal
m :
p :
ps :
listptr
IH :
∀a : Z, getopt_slotsm a ps → ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
a :
Z
Hp :
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
Hr :
getopt_slotsm a + 8 ps
k :
nat
q :
Hk :
p :: ps ++ null !! Sk = Someq
⊢
slot_atm a + 8 × Sk q

+replace a + 8 × Z.of_natSk with a + 8 + 8 × Z.of_natk by lia

m :
p :
ps :
listptr
IH :
∀a : Z, getopt_slotsm a ps → ∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
a :
Z
Hp :
Hb :
∀k : Z, 0 ≤ k < 8 → 0 ≤ m_bytesm a + k < 256
Hr :
getopt_slotsm a + 8 ps
k :
nat
q :
Hk :
p :: ps ++ null !! Sk = Someq
⊢
slot_atm a + 8 + 8 × k q

exact IH_ Hr k q Hk

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
revert a
induction ps as | p ps IH ; intros a Hs k q Hk
–destruct k as | k ; | destruct k ; discriminate Hk
injection Hk as ←
replace a + 8 × Z.of_nat0 with a by lia
destruct Hs as Hp Hb
exact pointer_slot_at_ _ _ Hp Hb
–destruct Hs as Hp & Hb & Hr
destruct k as | k
+injection Hk as ←
replace a + 8 × Z.of_nat0 with a by lia
exact pointer_slot_at_ _ _ Hp Hb
+replace a + 8 × Z.of_natSk with a + 8 + 8 × Z.of_natk by lia
exact IH_ Hr k q Hk

Memory whose slots hold ps holds argv's bytes and slots for ps.

272Lemma argv_of_slots
∀ m a ps
mem_bytesm a 8 × lengthps ++ null = argv_bytesps ∧ argv_capsmem_auxesm a 8 × lengthps ++ null ps
Explore proof 36 tactics

Initial goal

m :
a :
Z
ps :
listptr
⊢
getopt_slotsm a ps → mem_bytesm a 8 × lengthps ++ null = argv_bytesps ∧ argv_capsmem_auxesm a 8 × lengthps ++ null ps

intros Hs

m :
a :
Z
ps :
listptr
Hs :
⊢
mem_bytesm a 8 × lengthps ++ null = argv_bytesps ∧ argv_capsmem_auxesm a 8 × lengthps ++ null ps

pose proof at_of_slotsm a ps Hs as H

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
mem_bytesm a 8 × lengthps ++ null = argv_bytesps ∧ argv_capsmem_auxesm a 8 × lengthps ++ null ps

split

2 open

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
mem_bytesm a 8 × lengthps ++ null = argv_bytesps
focused goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

–apply list_eq

2 open

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
∀i : nat, mem_bytesm a 8 × lengthps ++ null !! i = argv_bytesps !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

intros i

2 open

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
⊢
mem_bytesm a 8 × lengthps ++ null !! i = argv_bytesps !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

unfold mem_bytes , argv_bytes

2 open

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
⊢
λi0 : nat ⇒ m_bytesm a + i0 <$> seq0 8 × lengthps ++ null !! i = slots_bytesps ++ null !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

rewrite list_lookup_fmap

2 open

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
⊢
λi0 : nat ⇒ m_bytesm a + i0 <$> seq0 8 × lengthps ++ null !! i = slots_bytesps ++ null !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

destruct decidei < 8 × lengthps ++ null%nat as Hi | Hi

3 open

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
i < 8 × lengthps ++ null%nat
⊢
λi0 : nat ⇒ m_bytesm a + i0 <$> seq0 8 × lengthps ++ null !! i = slots_bytesps ++ null !! i
focused goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
¬i < 8 × lengthps ++ null%nat
⊢
λi0 : nat ⇒ m_bytesm a + i0 <$> seq0 8 × lengthps ++ null !! i = slots_bytesps ++ null !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

+rewrite lookup_seq_lt ; | exact Hi

3 open

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
i < 8 × lengthps ++ null%nat
⊢
λi0 : nat ⇒ m_bytesm a + i0 <$> Some0 + i%nat = slots_bytesps ++ null !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
¬i < 8 × lengthps ++ null%nat
⊢
λi0 : nat ⇒ m_bytesm a + i0 <$> seq0 8 × lengthps ++ null !! i = slots_bytesps ++ null !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

cbn [ fmap option_fmap option_map ]

3 open

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
i < 8 × lengthps ++ null%nat
⊢
Somem_bytesm a + 0 + i%nat = slots_bytesps ++ null !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
¬i < 8 × lengthps ++ null%nat
⊢
λi0 : nat ⇒ m_bytesm a + i0 <$> seq0 8 × lengthps ++ null !! i = slots_bytesps ++ null !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

pose proof Nat.div_mod_eqi 8 as Ei

3 open

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
i < 8 × lengthps ++ null%nat
Ei :
i = 8 × i / 8 + i mod 8%nat
⊢
Somem_bytesm a + 0 + i%nat = slots_bytesps ++ null !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
¬i < 8 × lengthps ++ null%nat
⊢
λi0 : nat ⇒ m_bytesm a + i0 <$> seq0 8 × lengthps ++ null !! i = slots_bytesps ++ null !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

pose proof Nat.mod_upper_boundi 8 ltac:lia as Ej

3 open

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
i < 8 × lengthps ++ null%nat
Ei :
i = 8 × i / 8 + i mod 8%nat
Ej :
i mod 8 < 8%nat
⊢
Somem_bytesm a + 0 + i%nat = slots_bytesps ++ null !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
¬i < 8 × lengthps ++ null%nat
⊢
λi0 : nat ⇒ m_bytesm a + i0 <$> seq0 8 × lengthps ++ null !! i = slots_bytesps ++ null !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

destruct lookup_lt_is_Some_2ps ++ null i / 8 as q Hq ; lia |

3 open

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
i < 8 × lengthps ++ null%nat
Ei :
i = 8 × i / 8 + i mod 8%nat
Ej :
i mod 8 < 8%nat
q :
Hq :
ps ++ null !! i / 8%nat = Someq
⊢
Somem_bytesm a + 0 + i%nat = slots_bytesps ++ null !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
¬i < 8 × lengthps ++ null%nat
⊢
λi0 : nat ⇒ m_bytesm a + i0 <$> seq0 8 × lengthps ++ null !! i = slots_bytesps ++ null !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

rewrite Ei slots_bytes_lookup_ _ _ _ Hq Ej

3 open

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
i < 8 × lengthps ++ null%nat
Ei :
i = 8 × i / 8 + i mod 8%nat
Ej :
i mod 8 < 8%nat
q :
Hq :
ps ++ null !! i / 8%nat = Someq
⊢
Somem_bytesm a + 0 + 8 × i / 8 + i mod 8%nat = Somebyte_ofptr_addrq i mod 8%nat
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
¬i < 8 × lengthps ++ null%nat
⊢
λi0 : nat ⇒ m_bytesm a + i0 <$> seq0 8 × lengthps ++ null !! i = slots_bytesps ++ null !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

destruct H_ _ Hq as _ & Hb & _

3 open

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
i < 8 × lengthps ++ null%nat
Ei :
i = 8 × i / 8 + i mod 8%nat
Ej :
i mod 8 < 8%nat
q :
Hq :
ps ++ null !! i / 8%nat = Someq
Hb :
∀i0 : Z, 0 ≤ i0 < 8 → m_bytesm a + 8 × i / 8%nat + i0 = byte_ofptr_addrq i0
⊢
Somem_bytesm a + 0 + 8 × i / 8 + i mod 8%nat = Somebyte_ofptr_addrq i mod 8%nat
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
¬i < 8 × lengthps ++ null%nat
⊢
λi0 : nat ⇒ m_bytesm a + i0 <$> seq0 8 × lengthps ++ null !! i = slots_bytesps ++ null !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

f_equal

3 open

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
i < 8 × lengthps ++ null%nat
Ei :
i = 8 × i / 8 + i mod 8%nat
Ej :
i mod 8 < 8%nat
q :
Hq :
ps ++ null !! i / 8%nat = Someq
Hb :
∀i0 : Z, 0 ≤ i0 < 8 → m_bytesm a + 8 × i / 8%nat + i0 = byte_ofptr_addrq i0
⊢
m_bytesm a + 0 + 8 × i / 8 + i mod 8%nat = byte_ofptr_addrq i mod 8%nat
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
¬i < 8 × lengthps ++ null%nat
⊢
λi0 : nat ⇒ m_bytesm a + i0 <$> seq0 8 × lengthps ++ null !! i = slots_bytesps ++ null !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

rewrite <- Hb ; | lia

3 open

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
i < 8 × lengthps ++ null%nat
Ei :
i = 8 × i / 8 + i mod 8%nat
Ej :
i mod 8 < 8%nat
q :
Hq :
ps ++ null !! i / 8%nat = Someq
Hb :
∀i0 : Z, 0 ≤ i0 < 8 → m_bytesm a + 8 × i / 8%nat + i0 = byte_ofptr_addrq i0
⊢
m_bytesm a + 0 + 8 × i / 8 + i mod 8%nat = m_bytesm a + 8 × i / 8%nat + i mod 8%nat
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
¬i < 8 × lengthps ++ null%nat
⊢
λi0 : nat ⇒ m_bytesm a + i0 <$> seq0 8 × lengthps ++ null !! i = slots_bytesps ++ null !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

f_equal

3 open

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
i < 8 × lengthps ++ null%nat
Ei :
i = 8 × i / 8 + i mod 8%nat
Ej :
i mod 8 < 8%nat
q :
Hq :
ps ++ null !! i / 8%nat = Someq
Hb :
∀i0 : Z, 0 ≤ i0 < 8 → m_bytesm a + 8 × i / 8%nat + i0 = byte_ofptr_addrq i0
⊢
a + 0 + 8 × i / 8 + i mod 8%nat = a + 8 × i / 8%nat + i mod 8%nat
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
¬i < 8 × lengthps ++ null%nat
⊢
λi0 : nat ⇒ m_bytesm a + i0 <$> seq0 8 × lengthps ++ null !! i = slots_bytesps ++ null !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

lia

2 open

deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
¬i < 8 × lengthps ++ null%nat
⊢
λi0 : nat ⇒ m_bytesm a + i0 <$> seq0 8 × lengthps ++ null !! i = slots_bytesps ++ null !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

+rewrite lookup_seq_ge ; | lia

2 open

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
¬i < 8 × lengthps ++ null%nat
⊢
λi0 : nat ⇒ m_bytesm a + i0 <$> None = slots_bytesps ++ null !! i
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

symmetry

2 open

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
¬i < 8 × lengthps ++ null%nat
⊢
slots_bytesps ++ null !! i = λi0 : nat ⇒ m_bytesm a + i0 <$> None
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

apply lookup_ge_None_2

2 open

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
¬i < 8 × lengthps ++ null%nat
⊢
lengthslots_bytesps ++ null ≤ i%nat
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

rewrite length_slots_bytes

2 open

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
i :
nat
Hi :
¬i < 8 × lengthps ++ null%nat
⊢
8 × lengthps ++ null ≤ i%nat
deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

lia

deferred goal
m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
argv_capsmem_auxesm a 8 × lengthps ++ null ps

–split ; apply length_mem_auxes |

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
⊢
∀k : nat q : ptr, ps ++ null !! k = Someq → mem_auxesm a 8 × lengthps ++ null !! 8 × k%nat = Someptr_capq

intros k q Hk

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
k :
nat
q :
Hk :
ps ++ null !! k = Someq
⊢
mem_auxesm a 8 × lengthps ++ null !! 8 × k%nat = Someptr_capq

pose proof lookup_lt_Some_ _ _ Hk as Hlt

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
k :
nat
q :
Hk :
ps ++ null !! k = Someq
Hlt :
k < lengthps ++ null%nat
⊢
mem_auxesm a 8 × lengthps ++ null !! 8 × k%nat = Someptr_capq

unfold mem_auxes

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
k :
nat
q :
Hk :
ps ++ null !! k = Someq
Hlt :
k < lengthps ++ null%nat
⊢
λi : nat ⇒ m_auxm a + i <$> seq0 8 × lengthps ++ null !! 8 × k%nat = Someptr_capq

rewrite list_lookup_fmap

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
k :
nat
q :
Hk :
ps ++ null !! k = Someq
Hlt :
k < lengthps ++ null%nat
⊢
λi : nat ⇒ m_auxm a + i <$> seq0 8 × lengthps ++ null !! 8 × k%nat = Someptr_capq

rewrite lookup_seq_lt ; | lia

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
k :
nat
q :
Hk :
ps ++ null !! k = Someq
Hlt :
k < lengthps ++ null%nat
⊢
λi : nat ⇒ m_auxm a + i <$> Some0 + 8 × k%nat = Someptr_capq

cbn

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
k :
nat
q :
Hk :
ps ++ null !! k = Someq
Hlt :
k < lengthps ++ null%nat
⊢
Somem_auxm a + k + k + k + k + k + k + k + k + 0%nat = Someptr_capq

destruct H_ _ Hk as _ & _ & Hc

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
k :
nat
q :
Hk :
ps ++ null !! k = Someq
Hlt :
k < lengthps ++ null%nat
Hc :
m_auxm a + 8 × k = ptr_capq
⊢
Somem_auxm a + k + k + k + k + k + k + k + k + 0%nat = Someptr_capq

rewrite <- Hc

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
k :
nat
q :
Hk :
ps ++ null !! k = Someq
Hlt :
k < lengthps ++ null%nat
Hc :
m_auxm a + 8 × k = ptr_capq
⊢
Somem_auxm a + k + k + k + k + k + k + k + k + 0%nat = Somem_auxm a + 8 × k

f_equal

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
k :
nat
q :
Hk :
ps ++ null !! k = Someq
Hlt :
k < lengthps ++ null%nat
Hc :
m_auxm a + 8 × k = ptr_capq
⊢
m_auxm a + k + k + k + k + k + k + k + k + 0%nat = m_auxm a + 8 × k

f_equal

m :
a :
Z
ps :
listptr
Hs :
H :
∀k : nat q : ptr, ps ++ null !! k = Someq → slot_atm a + 8 × k q
k :
nat
q :
Hk :
ps ++ null !! k = Someq
Hlt :
k < lengthps ++ null%nat
Hc :
m_auxm a + 8 × k = ptr_capq
⊢
a + k + k + k + k + k + k + k + k + 0%nat = a + 8 × k

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hs
pose proof at_of_slotsm a ps Hs as H
split
–apply list_eq
intros i
rewrite list_lookup_fmap
destruct decidei < 8 × lengthps ++ null%nat as Hi | Hi
+rewrite lookup_seq_lt ; | exact Hi
cbn [ fmap option_fmap option_map ]
pose proof Nat.div_mod_eqi 8 as Ei
pose proof Nat.mod_upper_boundi 8 ltac:lia as Ej
destruct lookup_lt_is_Some_2ps ++ null i / 8 as q Hq ; lia |
rewrite Ei slots_bytes_lookup_ _ _ _ Hq Ej
destruct H_ _ Hq as _ & Hb & _
f_equal
rewrite <- Hb ; | lia
f_equal
lia
+rewrite lookup_seq_ge ; | lia
symmetry
apply lookup_ge_None_2
lia
–split ; apply length_mem_auxes |
intros k q Hk
pose proof lookup_lt_Some_ _ _ Hk as Hlt
unfold mem_auxes
rewrite list_lookup_fmap
rewrite lookup_seq_lt ; | lia
cbn
destruct H_ _ Hk as _ & _ & Hc
rewrite <- Hc
f_equal
f_equal
lia

The i-th aux piece is the i-th slot's.

292Lemma aux_ps_lookup
∀ b o cs i c
cs !! i = Somec
aux_psb o cs !! i = SomePAuxb o + Z.of_nati, VAuxc
Explore proof 10 tactics

Initial goal

b, o :
Z
cs :
listcap
i :
nat
c :
⊢
cs !! i = Somec → aux_psb o cs !! i = SomePAuxb o + i, VAuxc

revert o i

b :
Z
cs :
listcap
c :
⊢
∀o : Z i : nat, cs !! i = Somec → aux_psb o cs !! i = SomePAuxb o + i, VAuxc

induction cs as | y cs IH ; intros o i H ; discriminate |

b :
Z
y :
cs :
listcap
c :
IH :
∀o : Z i : nat, cs !! i = Somec → aux_psb o cs !! i = SomePAuxb o + i, VAuxc
o :
Z
i :
nat
H :
y :: cs !! i = Somec
⊢
aux_psb o y :: cs !! i = SomePAuxb o + i, VAuxc

rewrite aux_ps_cons

b :
Z
y :
cs :
listcap
c :
IH :
∀o : Z i : nat, cs !! i = Somec → aux_psb o cs !! i = SomePAuxb o + i, VAuxc
o :
Z
i :
nat
H :
y :: cs !! i = Somec
⊢
PAuxb o, VAuxy :: aux_psb o + 1 cs !! i = SomePAuxb o + i, VAuxc

destruct i as | i ; cbn in H |- *

2 open

b :
Z
y :
cs :
listcap
c :
IH :
∀o : Z i : nat, cs !! i = Somec → aux_psb o cs !! i = SomePAuxb o + i, VAuxc
o :
Z
H :
Somey = Somec
⊢
SomePAuxb o, VAuxy = SomePAuxb o + 0%nat, VAuxc
focused goal
b :
Z
y :
cs :
listcap
c :
IH :
∀o : Z i : nat, cs !! i = Somec → aux_psb o cs !! i = SomePAuxb o + i, VAuxc
o :
Z
i :
nat
H :
cs !! i = Somec
⊢
aux_psb o + 1 cs !! i = SomePAuxb o + Si, VAuxc

–injection H as →

2 open

b :
Z
cs :
listcap
c :
IH :
∀o : Z i : nat, cs !! i = Somec → aux_psb o cs !! i = SomePAuxb o + i, VAuxc
o :
Z
⊢
SomePAuxb o, VAuxc = SomePAuxb o + 0%nat, VAuxc
deferred goal
b :
Z
y :
cs :
listcap
c :
IH :
∀o : Z i : nat, cs !! i = Somec → aux_psb o cs !! i = SomePAuxb o + i, VAuxc
o :
Z
i :
nat
H :
cs !! i = Somec
⊢
aux_psb o + 1 cs !! i = SomePAuxb o + Si, VAuxc

rewrite Z.add_0_r

2 open

b :
Z
cs :
listcap
c :
IH :
∀o : Z i : nat, cs !! i = Somec → aux_psb o cs !! i = SomePAuxb o + i, VAuxc
o :
Z
⊢
SomePAuxb o, VAuxc = SomePAuxb o, VAuxc
deferred goal
b :
Z
y :
cs :
listcap
c :
IH :
∀o : Z i : nat, cs !! i = Somec → aux_psb o cs !! i = SomePAuxb o + i, VAuxc
o :
Z
i :
nat
H :
cs !! i = Somec
⊢
aux_psb o + 1 cs !! i = SomePAuxb o + Si, VAuxc

reflexivity

deferred goal
b :
Z
y :
cs :
listcap
c :
IH :
∀o : Z i : nat, cs !! i = Somec → aux_psb o cs !! i = SomePAuxb o + i, VAuxc
o :
Z
i :
nat
H :
cs !! i = Somec
⊢
aux_psb o + 1 cs !! i = SomePAuxb o + Si, VAuxc

–rewrite IHo + 1 i H

b :
Z
y :
cs :
listcap
c :
IH :
∀o : Z i : nat, cs !! i = Somec → aux_psb o cs !! i = SomePAuxb o + i, VAuxc
o :
Z
i :
nat
H :
cs !! i = Somec
⊢
SomePAuxb o + 1 + i, VAuxc = SomePAuxb o + Si, VAuxc

do 3 f_equal

b :
Z
y :
cs :
listcap
c :
IH :
∀o : Z i : nat, cs !! i = Somec → aux_psb o cs !! i = SomePAuxb o + i, VAuxc
o :
Z
i :
nat
H :
cs !! i = Somec
⊢
o + 1 + i = o + Si

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
revert o i
induction cs as | y cs IH ; intros o i H ; discriminate |
rewrite aux_ps_cons
destruct i as | i ; cbn in H |- *
–injection H as →
rewrite Z.add_0_r
reflexivity
–rewrite IHo + 1 i H
do 3 f_equal
lia

A pointer of a permitted order of argv is one of the arguments'.

302Lemma order_in
∀ sargs ps q
Inq ps
∃s, Ins sargs ∧ q = arg_ptrs
Explore proof 4 tactics

Initial goal

sargs :
ps :
listptr
q :
⊢
getopt_ordermaparg_ptr sargs ps → Inq ps → ∃s : argument, Ins sargs ∧ q = arg_ptrs

intros H Hq

sargs :
ps :
listptr
q :
H :
Hq :
Inq ps
⊢
∃s : argument, Ins sargs ∧ q = arg_ptrs

apply Permutation_in_ Permutation_symgetopt_order_inventory_ _ H in Hq

sargs :
ps :
listptr
q :
H :
Hq :
Inq maparg_ptr sargs
⊢
∃s : argument, Ins sargs ∧ q = arg_ptrs

apply in_map_iff in Hq as s & ← & Hs

sargs :
ps :
listptr
H :
Hs :
Ins sargs
⊢
∃s0 : argument, Ins0 sargs ∧ arg_ptrs = arg_ptrs0

eauto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros H Hq
apply Permutation_in_ Permutation_symgetopt_order_inventory_ _ H in Hq
apply in_map_iff in Hq as s & ← & Hs
eauto

A C int cut to 32 bits: itself if nonnegative, else 2^32 more.

310Lemma int32_mod
∀ x
x mod 2 ^ 32
=
x <? 0
→
x + 2 ^ 32
else
x
Explore proof 7 tactics

Initial goal

x :
Z
⊢
→
x mod 2 ^ 32
=
x <? 0
→
x + 2 ^ 32
else
x

unfold getopt_int

x :
Z
⊢
−2 ^ 31 ≤ x < 2 ^ 31
→
x mod 2 ^ 32
=
x <? 0
→
x + 2 ^ 32
else
x

intros Hx

x :
Z
Hx :
−2 ^ 31 ≤ x < 2 ^ 31
⊢
x mod 2 ^ 32
=
x <? 0
→
x + 2 ^ 32
else
x

destruct Z.ltb_specx 0

2 open

x :
Z
Hx :
−2 ^ 31 ≤ x < 2 ^ 31
H :
x < 0
⊢
x mod 2 ^ 32 = x + 2 ^ 32
focused goal
x :
Z
Hx :
−2 ^ 31 ≤ x < 2 ^ 31
H :
0 ≤ x
⊢
x mod 2 ^ 32 = x

–symmetry

2 open

x :
Z
Hx :
−2 ^ 31 ≤ x < 2 ^ 31
H :
x < 0
⊢
x + 2 ^ 32 = x mod 2 ^ 32
deferred goal
x :
Z
Hx :
−2 ^ 31 ≤ x < 2 ^ 31
H :
0 ≤ x
⊢
x mod 2 ^ 32 = x

apply Z.mod_uniquex 2 ^ 32 −1 ; left ; lia | lia

deferred goal
x :
Z
Hx :
−2 ^ 31 ≤ x < 2 ^ 31
H :
0 ≤ x
⊢
x mod 2 ^ 32 = x

–apply Z.mod_small

x :
Z
Hx :
−2 ^ 31 ≤ x < 2 ^ 31
H :
0 ≤ x
⊢
0 ≤ x < 2 ^ 32

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
unfold getopt_int
intros Hx
destruct Z.ltb_specx 0
–symmetry
apply Z.mod_uniquex 2 ^ 32 −1 ; left ; lia | lia
–apply Z.mod_small
lia

A C int's 32 bits are those of a nonnegative C int k just if it is k.

319Lemma int32_eq
∀ x k
0 ≤ k < 2 ^ 31
x mod 2 ^ 32 = k ↔ x = k
Explore proof 4 tactics

Initial goal

x, k :
Z
⊢
getopt_intx → 0 ≤ k < 2 ^ 31 → x mod 2 ^ 32 = k ↔ x = k

intros Hx Hk

x, k :
Z
Hk :
0 ≤ k < 2 ^ 31
⊢
x mod 2 ^ 32 = k ↔ x = k

rewrite int32_modx Hx

x, k :
Z
Hk :
0 ≤ k < 2 ^ 31
⊢
x <? 0
→
x + 2 ^ 32
else
x
=
k
↔
x = k

unfold getopt_int in Hx

x, k :
Z
Hx :
−2 ^ 31 ≤ x < 2 ^ 31
Hk :
0 ≤ k < 2 ^ 31
⊢
x <? 0
→
x + 2 ^ 32
else
x
=
k
↔
x = k

destruct Z.ltb_specx 0 ; split ; lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hx Hk
rewrite int32_modx Hx
unfold getopt_int in Hx
destruct Z.ltb_specx 0 ; split ; lia

A C int's 32 bits are all ones just if it is -1, getopt's end.

326Lemma int32_end
∀ x
x mod 2 ^ 32 = 4294967295 ↔ x = −1
Explore proof 4 tactics

Initial goal

x :
Z
⊢
getopt_intx → x mod 2 ^ 32 = 4294967295 ↔ x = −1

intros Hx

x :
Z
⊢
x mod 2 ^ 32 = 4294967295 ↔ x = −1

rewrite int32_modx Hx

x :
Z
⊢
x <? 0
→
x + 2 ^ 32
else
x
=
4294967295
↔
x = −1

unfold getopt_int in Hx

x :
Z
Hx :
−2 ^ 31 ≤ x < 2 ^ 31
⊢
x <? 0
→
x + 2 ^ 32
else
x
=
4294967295
↔
x = −1

destruct Z.ltb_specx 0 ; split ; lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hx
rewrite int32_modx Hx
unfold getopt_int in Hx
destruct Z.ltb_specx 0 ; split ; lia

Main's proof over one Logic instance shared by every layer.

333Module HelloMain R : Runtime
334Module LG0 ≔ Logic R
335Module HC ≔ HelloConvOn R LG0
336Module HP ≔ HelloProgNameOn R LG0
337Module GL ≔ GetoptLogicOn R LG0
338Module HLo ≔ HC.HLo
339Module HL ≔ HC.HL
340Module LL ≔ HC.LL
341Module ML ≔ HC.ML
342Module SL ≔ HC.SL
343Module LG ≔ LG0
344Module L ≔ LG.L
Import L LG SL ML LL HL
347Section main
348Context `{!invGS_genhlc Σ, !gen_heapGSpiece pval Σ}
349Context registry : name → optioncontractlibc_world wi : mem → libc_world → gmappiece pval → Prop `{!SafepointStablewi} ge : genv

The Iris instance of the registry and wi.

353Instance main_irisGS: irisGS_genhlc nanofil_langregistry ge Σ ≔
nanofil_irisGSregistry wi ge

The expressions of the language.

357Notation mexpr ≔ language.exprnanofil_langregistry ge

The genv links Hello.

360Context Hlinked : hello_linkedge

An allocation of a fresh object, with its pieces added, keeps wi.

363Context Kalloc : ∀q m wd h base, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h

memset has its contract, and zeroing eight bytes of a block the program owns keeps wi.

368Context Hmemset : registryTAtom"memset" = Somememset_contractlibc_world
368Context Kmemset : ∀b reg o xs cs m m′ wd h, memset_resultm mkPtrb + o Objb 0 8 m′ → ∀l v, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h

set_program_name's contracts, and the layout and store premises of its three cells, as HelloName states them.

375Context Hstrrchr : registryTAtom"strrchr" = Somestrrchr_contractlibc_world
375Context Hmemcmp : registryTAtom"memcmp" = Somememcmp_contractlibc_world
375Context Hstrncmp : registryTAtom"strncmp" = Somestrncmp_contractlibc_world
378Context pn nreg sreg : region
378Context nb sb : Z
378Context Hnb : lookupTAtom"program_invocation_name" ge_globalsge = SomemkPtrnb Objnb
378Context Hsb : lookupTAtom"program_invocation_short_name" ge_globalsge = SomemkPtrsb Objsb
378Context Hpn_end : program_name_b + 8 ≤ r_endpn
378Context Hnb_cell : 0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ∧ r_endnreg ≤ 2 ^ 48
378Context Hsb_cell : 0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ∧ r_endsreg ≤ 2 ^ 48
378Context Knb : HP.HN.store_keepswi nb nreg
378Context Ksb : HP.HN.store_keepswi sb sreg

setlocale has libc's contract. The world interpretation keeps every lent name where lent_at says, admits setlocale's precondition for a category and a string the program owns, and survives its return, which lends every category's new name and sets the codec piece.

391Context rep : mem → libc_world → Prop
391Context requests : listword → mem → libc_world → Z → Z → Prop
391Context Hsetlocale : registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
391Context Hlent : ∀m w h k p t, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
391Context Hset_pre : ∀m w h c p b reg bytes, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
391Context Kset : ∀r args c p s m w h trace values s′ m′ w′, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q new : Z → ptr × listZ c′, values = WPtrq ∧ q = mkPtr0 CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new

setlocale(c, p) over libc's world, from wp_lend: owning every category's name, the codec piece and the string at p, the call lends every category's new name for good, gives the codec piece a new codec and binds d to null or c's new name.

409Lemma wp_main_setlocale
∀ f e ls lab d vc vp rest j c p b reg bytes old c0 Φ
arg_xge e ArgW vc = SomeWIntc
arg_xge e ArgP vp = SomeWPtrp
∗k∈locale_categoriesLL.namedk oldk.1 oldk.2 −∗ ptscodec_psc0 −∗ stringp b reg bytes −∗ ▷∀q new : Z → ptr × listZ c′, ⌜q = mkPtr0 CNone ∨ q = newc.1⌝ −∗ stringp b reg bytes −∗ ptscodec_psc′ −∗ ∗k∈locale_categoriesLL.lentk newk.1 newk.2 −∗ WPERunmkFramef putd WPtrq e ls None Execlab rest j : mexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd P GlobalTAtom"setlocale" ArgW vc; ArgP vp :: rest j : mexpr {Φ}
Proof 33 steps Qed
intros Hc Hp Hcat
iIntros Hks Hcodec Hs HK
pose proof Hlinked as _ & _ & Hext
iApply LL.wp_lendregistry wi ge Hlent f e ls lab d TAtom"setlocale" ArgW vc; ArgP vp rest j libc_setlocale_contractrep requests WIntc; WPtrp locale_categories old codec_psc0 λq new gs′ ⇒ q = mkPtr0 CNone ∨ q = newc.1 ∧ ∃c′, gs′ = codec_psc′ with Hks Hcodec Hs [HK] ; exact Hsetlocale | reflexivity | apply linked_outside ; first exact Hlinked | reflexivity | apply linked_unbound ; first exact Hlinked | reflexivity | reflexivity | cbn [ map_option ] ; rewrite Hc Hp ; reflexivity | | | | |
–split ; right ; eexists ; reflexivity | do 2 eexists ; reflexivity
–apply List.Forall_forall
intros k Hk
cbn
rewrite list_elem_of_singleton
intros E
injection E as →
cbn in Hk
intuition lia
–iIntros σ Hσ Hs
iDestruct Hs as [%Hok Hps]
iDestruct pts_facts with Hσ Hps as %Hag & _
iDestruct Hσ as h [_ %Hf]
destruct Hf as _ & _ & _ & Hw
iPureIntro
exact Hset_pre_ _ _ _ _ _ _ _ Hw Hcat Hok Hag
–intros s m w h trace values s′ m′ w′ Hw Ha Hd Hr Hi
destruct Kset_ _ _ _ _ _ _ _ _ _ _ _ _ Hw Ha Hd Hr Hi as q & new & c′ & Hv & Hq & Ha′ & Hd′ & Hr′ & Hw′
exists q, new, codec_psc'
split ; exact Hv |
split ; split ; exact Hq | eauto |
split ; reflexivity |
split ; cbn ; repeat constructor |
auto
–iNext
iIntros q new gs′ Hq c′ → Hs Hcodec Hl
iApply HK with [%] Hs Hcodec Hl
exact Hq

A pointer store into a cell the program owns keeps wi.

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

atexit has a contract returning an int, which admits the call main makes, registering close_stdout, and whose return keeps the program's pieces and wi: the registration is libc's state.

458Context atexit_spec : contractlibc_world
458Context Hatexit : registryTAtom"atexit" = Someatexit_spec
458Context Hatexit_ret : contract_returnsatexit_spec = RClassW
458Context Hatexit_abi : contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
458Context Hatexit_pre : ∀m w h, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
458Context Katexit : ∀r args s m w h trace values s′ m′ w′, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h

Eight zero bytes and an empty slot at offset 0 are a null pointer cell.

471Lemma zero_pcell
∀ b
bytesb 0 replicate8 0 ∗ auxesb 0 CNone ⊣⊢ pcellb 0 mkPtr0 CNone
Explore proof 8 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
b :
Z
⊢
bytesb 0 replicate8 0 ∗ auxesb 0 CNone ⊣⊢ pcellb 0 ptr_addr ≔ 0; ptr_cap ≔ CNone

rewrite / bytes / auxes / pcell - pts_app

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
b :
Z
⊢
ptsbyte_psb 0 replicate8 0 ++ aux_psb 0 CNone ⊣⊢ ptsPAuxb 0, VAuxptr_capptr_addr ≔ 0; ptr_cap ≔ CNone :: cellb 0 ptr_addrptr_addr ≔ 0; ptr_cap ≔ CNone

assert E : byte_psb 0 replicate8 0 ++ aux_psb 0 CNone = cellb 0 0 ++ PAuxb 0, VAuxCNone

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
b :
Z
⊢
byte_psb 0 replicate8 0 ++ aux_psb 0 CNone = cellb 0 0 ++ PAuxb 0, VAuxCNone
focused goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
b :
Z
E :
byte_psb 0 replicate8 0 ++ aux_psb 0 CNone = cellb 0 0 ++ PAuxb 0, VAuxCNone
⊢
ptsbyte_psb 0 replicate8 0 ++ aux_psb 0 CNone ⊣⊢ ptsPAuxb 0, VAuxptr_capptr_addr ≔ 0; ptr_cap ≔ CNone :: cellb 0 ptr_addrptr_addr ≔ 0; ptr_cap ≔ CNone

{vm_compute

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
b :
Z
⊢
PByteb 0, VByte0; PByteb 1, VByte0; PByteb 2, VByte0; PByteb 3, VByte0; PByteb 4, VByte0; PByteb 5, VByte0; PByteb 6, VByte0; PByteb 7, VByte0; PAuxb 0, VAuxCNone = PByteb 0, VByte0; PByteb 1, VByte0; PByteb 2, VByte0; PByteb 3, VByte0; PByteb 4, VByte0; PByteb 5, VByte0; PByteb 6, VByte0; PByteb 7, VByte0; PAuxb 0, VAuxCNone
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
b :
Z
E :
byte_psb 0 replicate8 0 ++ aux_psb 0 CNone = cellb 0 0 ++ PAuxb 0, VAuxCNone
⊢
ptsbyte_psb 0 replicate8 0 ++ aux_psb 0 CNone ⊣⊢ ptsPAuxb 0, VAuxptr_capptr_addr ≔ 0; ptr_cap ≔ CNone :: cellb 0 ptr_addrptr_addr ≔ 0; ptr_cap ≔ CNone

reflexivity

deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
b :
Z
E :
byte_psb 0 replicate8 0 ++ aux_psb 0 CNone = cellb 0 0 ++ PAuxb 0, VAuxCNone
⊢
ptsbyte_psb 0 replicate8 0 ++ aux_psb 0 CNone ⊣⊢ ptsPAuxb 0, VAuxptr_capptr_addr ≔ 0; ptr_cap ≔ CNone :: cellb 0 ptr_addrptr_addr ≔ 0; ptr_cap ≔ CNone

rewrite E pts_app

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
b :
Z
E :
byte_psb 0 replicate8 0 ++ aux_psb 0 CNone = cellb 0 0 ++ PAuxb 0, VAuxCNone
⊢
ptscellb 0 0 ∗ ptsPAuxb 0, VAuxCNone ⊣⊢ ptsPAuxb 0, VAuxptr_capptr_addr ≔ 0; ptr_cap ≔ CNone :: cellb 0 ptr_addrptr_addr ≔ 0; ptr_cap ≔ CNone

cbn [ ptr_addr ptr_cap ]

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
b :
Z
E :
byte_psb 0 replicate8 0 ++ aux_psb 0 CNone = cellb 0 0 ++ PAuxb 0, VAuxCNone
⊢
ptscellb 0 0 ∗ ptsPAuxb 0, VAuxCNone ⊣⊢ ptsPAuxb 0, VAuxCNone :: cellb 0 0

rewrite / pts ! big_sepL_cons big_sepL_nil

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
b :
Z
E :
byte_psb 0 replicate8 0 ++ aux_psb 0 CNone = cellb 0 0 ++ PAuxb 0, VAuxCNone
⊢
pointstoPByteb 0 + 0, VBytebyte_of0 0.1 DfracOwn1 PByteb 0 + 0, VBytebyte_of0 0.2 ∗ pointstoPByteb 0 + 1, VBytebyte_of0 1.1 DfracOwn1 PByteb 0 + 1, VBytebyte_of0 1.2 ∗ pointstoPByteb 0 + 2, VBytebyte_of0 2.1 DfracOwn1 PByteb 0 + 2, VBytebyte_of0 2.2 ∗ pointstoPByteb 0 + 3, VBytebyte_of0 3.1 DfracOwn1 PByteb 0 + 3, VBytebyte_of0 3.2 ∗ pointstoPByteb 0 + 4, VBytebyte_of0 4.1 DfracOwn1 PByteb 0 + 4, VBytebyte_of0 4.2 ∗ pointstoPByteb 0 + 5, VBytebyte_of0 5.1 DfracOwn1 PByteb 0 + 5, VBytebyte_of0 5.2 ∗ pointstoPByteb 0 + 6, VBytebyte_of0 6.1 DfracOwn1 PByteb 0 + 6, VBytebyte_of0 6.2 ∗ pointstoPByteb 0 + 7, VBytebyte_of0 7.1 DfracOwn1 PByteb 0 + 7, VBytebyte_of0 7.2 ∗ emp ∗ pointstoPAuxb 0, VAuxCNone.1 DfracOwn1 PAuxb 0, VAuxCNone.2 ∗ emp ⊣⊢ pointstoPAuxb 0, VAuxCNone.1 DfracOwn1 PAuxb 0, VAuxCNone.2 ∗ pointstoPByteb 0 + 0, VBytebyte_of0 0.1 DfracOwn1 PByteb 0 + 0, VBytebyte_of0 0.2 ∗ pointstoPByteb 0 + 1, VBytebyte_of0 1.1 DfracOwn1 PByteb 0 + 1, VBytebyte_of0 1.2 ∗ pointstoPByteb 0 + 2, VBytebyte_of0 2.1 DfracOwn1 PByteb 0 + 2, VBytebyte_of0 2.2 ∗ pointstoPByteb 0 + 3, VBytebyte_of0 3.1 DfracOwn1 PByteb 0 + 3, VBytebyte_of0 3.2 ∗ pointstoPByteb 0 + 4, VBytebyte_of0 4.1 DfracOwn1 PByteb 0 + 4, VBytebyte_of0 4.2 ∗ pointstoPByteb 0 + 5, VBytebyte_of0 5.1 DfracOwn1 PByteb 0 + 5, VBytebyte_of0 5.2 ∗ pointstoPByteb 0 + 6, VBytebyte_of0 6.1 DfracOwn1 PByteb 0 + 6, VBytebyte_of0 6.2 ∗ pointstoPByteb 0 + 7, VBytebyte_of0 7.1 DfracOwn1 PByteb 0 + 7, VBytebyte_of0 7.2 ∗ emp

iSplit ; iIntros [H [A _]] ; iFrame | iIntros [A H] ; iFrame

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
rewrite / bytes / auxes / pcell - pts_app
assert E : byte_psb 0 replicate8 0 ++ aux_psb 0 CNone = cellb 0 0 ++ PAuxb 0, VAuxCNone
{vm_compute
reflexivity
rewrite E pts_app
rewrite / pts ! big_sepL_cons big_sepL_nil
iSplit ; iIntros [H [A _]] ; iFrame | iIntros [A H] ; iFrame

Enter a block of main.

481Ltac mn_enter s ≔
iApply wp_enter_ _ _ _ _ _ _ _ main_blocks ; vm_compute ; reflexivity | word_premise | ; iNext ; cbn [ b_insts b_jump main_block hblk ]

mbszero at the start of an object: mbszero_spec at offset 0.

487Lemma mbszero_at
∀ b reg xs cs Φ
lengthxs = 8%nat
lengthcs = 8%nat
b mod 8 = 0
b + 8 ≤ r_endreg
liveb reg −∗ bytesb 0 xs −∗ auxesb 0 cs −∗ ▷liveb reg −∗ bytesb 0 replicate8 0 −∗ auxesb 0 clear_slots0 cs −∗ ΦRetVoid −∗ WPERuninvocationmbszero_fn WPtrmkPtrb Objb : mexpr {Φ}
Explore proof 8 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
b :
Z
reg :
xs :
listZ
cs :
listcap
Φ :
outcome → iPropIΣ
⊢
lengthxs = 8%nat → lengthcs = 8%nat → b mod 8 = 0 → b + 8 ≤ r_endreg → liveb reg −∗ bytesb 0 xs −∗ auxesb 0 cs −∗ ▷liveb reg −∗ bytesb 0 replicate8 0 −∗ auxesb 0 clear_slots0 cs −∗ ΦRetVoid −∗ WPERuninvocationmbszero_fn WPtrptr_addr ≔ b; ptr_cap ≔ Objb : mexpr {v. Φv}

intros Lx Lc Hb8 Hend

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
b :
Z
reg :
xs :
listZ
cs :
listcap
Φ :
outcome → iPropIΣ
Lx :
lengthxs = 8%nat
Lc :
lengthcs = 8%nat
Hb8 :
b mod 8 = 0
Hend :
b + 8 ≤ r_endreg
⊢
liveb reg −∗ bytesb 0 xs −∗ auxesb 0 cs −∗ ▷liveb reg −∗ bytesb 0 replicate8 0 −∗ auxesb 0 clear_slots0 cs −∗ ΦRetVoid −∗ WPERuninvocationmbszero_fn WPtrptr_addr ≔ b; ptr_cap ≔ Objb : mexpr {v. Φv}

pose proof mbszero_specregistry wi ge Hlinked b reg 0 xs cs Φ as H

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
b :
Z
reg :
xs :
listZ
cs :
listcap
Φ :
outcome → iPropIΣ
Lx :
lengthxs = 8%nat
Lc :
lengthcs = 8%nat
Hb8 :
b mod 8 = 0
Hend :
b + 8 ≤ r_endreg
H :
registryTAtom"memset" = Somememset_contractlibc_world → lengthxs = 8%nat → lengthcs = 8%nat → b mod 8 = 0 → 0 mod 8 = 0 → 0 ≤ 0 → b + 0 + 8 ≤ r_endreg → ∀m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + 0; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg 0 xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg 0 replicate8 0 clear_slots0 cs h → LG.liveb reg −∗ ML.bytesb 0 xs −∗ ML.auxesb 0 cs −∗ ▷LG.liveb reg −∗ ML.bytesb 0 replicate8 0 −∗ ML.auxesb 0 clear_slots0 cs −∗ ΦRetVoid −∗ WPL.ERuninvocationmbszero_fn WPtrptr_addr ≔ b + 0; ptr_cap ≔ Objb : mexpr {v. Φv}
⊢
liveb reg −∗ bytesb 0 xs −∗ auxesb 0 cs −∗ ▷liveb reg −∗ bytesb 0 replicate8 0 −∗ auxesb 0 clear_slots0 cs −∗ ΦRetVoid −∗ WPERuninvocationmbszero_fn WPtrptr_addr ≔ b; ptr_cap ≔ Objb : mexpr {v. Φv}

rewrite ! Z.add_0_r in H

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
b :
Z
reg :
xs :
listZ
cs :
listcap
Φ :
outcome → iPropIΣ
Lx :
lengthxs = 8%nat
Lc :
lengthcs = 8%nat
Hb8 :
b mod 8 = 0
Hend :
b + 8 ≤ r_endreg
H :
registryTAtom"memset" = Somememset_contractlibc_world → lengthxs = 8%nat → lengthcs = 8%nat → b mod 8 = 0 → 0 mod 8 = 0 → 0 ≤ 0 → b + 8 ≤ r_endreg → ∀m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg 0 xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg 0 replicate8 0 clear_slots0 cs h → LG.liveb reg −∗ ML.bytesb 0 xs −∗ ML.auxesb 0 cs −∗ ▷LG.liveb reg −∗ ML.bytesb 0 replicate8 0 −∗ ML.auxesb 0 clear_slots0 cs −∗ ΦRetVoid −∗ WPL.ERuninvocationmbszero_fn WPtrptr_addr ≔ b; ptr_cap ≔ Objb {v. Φv}
⊢
liveb reg −∗ bytesb 0 xs −∗ auxesb 0 cs −∗ ▷liveb reg −∗ bytesb 0 replicate8 0 −∗ auxesb 0 clear_slots0 cs −∗ ΦRetVoid −∗ WPERuninvocationmbszero_fn WPtrptr_addr ≔ b; ptr_cap ≔ Objb : mexpr {v. Φv}

iApply H ; exact Hmemset | exact Lx | exact Lc | exact Hb8 | reflexivity | lia | exact Hend |

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
b :
Z
reg :
xs :
listZ
cs :
listcap
Φ :
outcome → iPropIΣ
Lx :
lengthxs = 8%nat
Lc :
lengthcs = 8%nat
Hb8 :
b mod 8 = 0
Hend :
b + 8 ≤ r_endreg
H :
registryTAtom"memset" = Somememset_contractlibc_world → lengthxs = 8%nat → lengthcs = 8%nat → b mod 8 = 0 → 0 mod 8 = 0 → 0 ≤ 0 → b + 8 ≤ r_endreg → ∀m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg 0 xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg 0 replicate8 0 clear_slots0 cs h → LG.liveb reg −∗ ML.bytesb 0 xs −∗ ML.auxesb 0 cs −∗ ▷LG.liveb reg −∗ ML.bytesb 0 replicate8 0 −∗ ML.auxesb 0 clear_slots0 cs −∗ ΦRetVoid −∗ WPL.ERuninvocationmbszero_fn WPtrptr_addr ≔ b; ptr_cap ≔ Objb {v. Φv}
⊢
∀m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg 0 xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg 0 replicate8 0 clear_slots0 cs h

intros m m′ wd h Hr Hin Hw

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
b :
Z
reg :
xs :
listZ
cs :
listcap
Φ :
outcome → iPropIΣ
Lx :
lengthxs = 8%nat
Lc :
lengthcs = 8%nat
Hb8 :
b mod 8 = 0
Hend :
b + 8 ≤ r_endreg
H :
registryTAtom"memset" = Somememset_contractlibc_world → lengthxs = 8%nat → lengthcs = 8%nat → b mod 8 = 0 → 0 mod 8 = 0 → 0 ≤ 0 → b + 8 ≤ r_endreg → ∀m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg 0 xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg 0 replicate8 0 clear_slots0 cs h → LG.liveb reg −∗ ML.bytesb 0 xs −∗ ML.auxesb 0 cs −∗ ▷LG.liveb reg −∗ ML.bytesb 0 replicate8 0 −∗ ML.auxesb 0 clear_slots0 cs −∗ ΦRetVoid −∗ WPL.ERuninvocationmbszero_fn WPtrptr_addr ≔ b; ptr_cap ≔ Objb {v. Φv}
m, m′ :
h :
Hr :
memset_resultm ptr_addr ≔ b; ptr_cap ≔ Objb 0 8 m′
Hin :
∀l : piece v : pval, l, v ∈ block_psb reg 0 xs cs → h !! l = Somev
Hw :
wim wd h
⊢
wim′ wd overwriteblock_psb reg 0 replicate8 0 clear_slots0 cs h

pose proof Kmemsetb reg 0 xs cs m m′ wd h as K

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
b :
Z
reg :
xs :
listZ
cs :
listcap
Φ :
outcome → iPropIΣ
Lx :
lengthxs = 8%nat
Lc :
lengthcs = 8%nat
Hb8 :
b mod 8 = 0
Hend :
b + 8 ≤ r_endreg
H :
registryTAtom"memset" = Somememset_contractlibc_world → lengthxs = 8%nat → lengthcs = 8%nat → b mod 8 = 0 → 0 mod 8 = 0 → 0 ≤ 0 → b + 8 ≤ r_endreg → ∀m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg 0 xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg 0 replicate8 0 clear_slots0 cs h → LG.liveb reg −∗ ML.bytesb 0 xs −∗ ML.auxesb 0 cs −∗ ▷LG.liveb reg −∗ ML.bytesb 0 replicate8 0 −∗ ML.auxesb 0 clear_slots0 cs −∗ ΦRetVoid −∗ WPL.ERuninvocationmbszero_fn WPtrptr_addr ≔ b; ptr_cap ≔ Objb {v. Φv}
m, m′ :
h :
Hr :
memset_resultm ptr_addr ≔ b; ptr_cap ≔ Objb 0 8 m′
Hin :
∀l : piece v : pval, l, v ∈ block_psb reg 0 xs cs → h !! l = Somev
Hw :
wim wd h
K :
memset_resultm ptr_addr ≔ b + 0; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg 0 xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg 0 replicate8 0 clear_slots0 cs h
⊢
wim′ wd overwriteblock_psb reg 0 replicate8 0 clear_slots0 cs h

rewrite ! Z.add_0_r in K

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
b :
Z
reg :
xs :
listZ
cs :
listcap
Φ :
outcome → iPropIΣ
Lx :
lengthxs = 8%nat
Lc :
lengthcs = 8%nat
Hb8 :
b mod 8 = 0
Hend :
b + 8 ≤ r_endreg
H :
registryTAtom"memset" = Somememset_contractlibc_world → lengthxs = 8%nat → lengthcs = 8%nat → b mod 8 = 0 → 0 mod 8 = 0 → 0 ≤ 0 → b + 8 ≤ r_endreg → ∀m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg 0 xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg 0 replicate8 0 clear_slots0 cs h → LG.liveb reg −∗ ML.bytesb 0 xs −∗ ML.auxesb 0 cs −∗ ▷LG.liveb reg −∗ ML.bytesb 0 replicate8 0 −∗ ML.auxesb 0 clear_slots0 cs −∗ ΦRetVoid −∗ WPL.ERuninvocationmbszero_fn WPtrptr_addr ≔ b; ptr_cap ≔ Objb {v. Φv}
m, m′ :
h :
Hr :
memset_resultm ptr_addr ≔ b; ptr_cap ≔ Objb 0 8 m′
Hin :
∀l : piece v : pval, l, v ∈ block_psb reg 0 xs cs → h !! l = Somev
Hw :
wim wd h
K :
memset_resultm ptr_addr ≔ b; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg 0 xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg 0 replicate8 0 clear_slots0 cs h
⊢
wim′ wd overwriteblock_psb reg 0 replicate8 0 clear_slots0 cs h

exact KHr Hin Hw

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Lx Lc Hb8 Hend
pose proof mbszero_specregistry wi ge Hlinked b reg 0 xs cs Φ as H
rewrite ! Z.add_0_r in H
iApply H ; exact Hmemset | exact Lx | exact Lc | exact Hb8 | reflexivity | lia | exact Hend |
intros m m′ wd h Hr Hin Hw
pose proof Kmemsetb reg 0 xs cs m m′ wd h as K
rewrite ! Z.add_0_r in K
exact KHr Hin Hw

The instructions of main's start block from setlocale's call on.

501Definition start_rest: listinst ≔
Eval vm_compute in drop7 b_instsmain_block"start"

The temporaries main has bound before setlocale: argc, argv, the greeting's cell b4, the state b6, and the literal "".

505Definition start_varse : env argc : Z av b4 b6 : Z : Prop ≔
lookupTAtom"v0" e = SomeWIntargc ∧ lookupTAtom"v2" e = SomeWPtrmkPtrav Objav ∧ lookupTAtom"v4" e = SomeWPtrmkPtrb4 Objb4 ∧ lookupTAtom"v6" e = SomeWPtrmkPtrb6 Objb6 ∧ lookupTAtom"v11" e = SomeWPtrempty_ptr

A fresh heap object of main: positive, 16-aligned, in the address space.

513Definition fresh_okb : Z : Prop ≔
0 < b ∧ b mod 16 = 0 ∧ b + 16 ≤ 2 ^ 48

Main's start block up to setlocale: two fresh objects, b4 for the greeting's cell and b6 for the conversion state, which mbszero zeroes; argv0 loaded and handed to set_program_name, which leaves the name cells at a suffix of it; the literal "" copied.

519Lemma main_to_setlocale
∀ argc av ar a0 b0 r0 ys0 r3 r4 x0 x1 y0 Φ
0 < av
av mod 8 = 0
av + 8 ≤ r_endar
r_endar ≤ 2 ^ 48
liveav ar −∗ pcellav 0 a0 −∗ stringa0 b0 r0 ys0 −∗ HP.HN.literalsr3 r4 −∗ HP.HN.name_cellspn nreg sreg nb sb x0 x1 y0 −∗ ▷∀e b4 b6 i k : nat, ⌜start_varse argc av b4 b6 ∧ fresh_okb4 ∧ fresh_okb6 ∧ i ≤ lengthys0%nat ∧ k ≤ lengthys0%nat⌝ −∗ liveav ar −∗ pcellav 0 a0 −∗ stringa0 b0 r0 ys0 −∗ HP.HN.literalsr3 r4 −∗ HP.HN.name_cellspn nreg sreg nb sb mkPtrptr_addra0 + Z.of_nati ptr_capa0 mkPtrptr_addra0 + Z.of_nati ptr_capa0 mkPtrptr_addra0 + Z.of_natk ptr_capa0 −∗ liveb4 mkRegionb4 b4 + 16 Heap Live −∗ bytesb4 0 replicate16 0 −∗ auxesb4 0 replicate16 CNone −∗ liveb6 mkRegionb6 b6 + 16 Heap Live −∗ bytesb6 0 replicate8 0 −∗ bytesb6 8 replicate8 0 −∗ auxesb6 0 clear_slots0 replicate8 CNone −∗ auxesb6 8 replicate8 CNone −∗ WPERunmkFramemain_fn e [ ] None ExecTAtom"start" start_rest b_jumpmain_block"start" : mexpr {Φ} −∗ WPERuninvocationmain_fn WIntargc; WPtrmkPtrav Objav : mexpr {Φ}
Proof 66 steps Qed
intros Hav Hav8 Haend Har48
iIntros Hal Ha0 Hs0 Hlit Hcells HK
pose proof Hlinked as Hm & _ & Hext
rewrite main_entry
mn_enter "start"
iApply wp_alloc_ _ _ _ _ _ _ _ _ _ _ _ _ 8 ; reflexivity | lia | unfold max_allocation_size ; lia | intros m wd h base Hf Hw ; exact Kalloc_ _ _ _ _ Hf Hw |
iNext
iIntros b4 Hb4 Hb4
iApply wp_alloc_ _ _ _ _ _ _ _ _ _ _ _ _ 8 ; reflexivity | lia | unfold max_allocation_size ; lia | intros m wd h base Hf Hw ; exact Kalloc_ _ _ _ _ Hf Hw |
iNext
iIntros b6 Hb6 Hb6

The state is zeroed.

iEval rewrite obj_zero_blockb6 _ ; | compute ; congruence in Hb6
iDestruct Hb6 as (Hl6 & Hy6 & Hc6)
cbn [ req_extent heap_req Z.to_nat Pos.to_nat ] in *
iEval rewrite HC.bytes_split_ _ _ 8 ; | rewrite length_replicate ; vm_compute ; lia in Hy6
iEval rewrite HC.auxes_split_ _ _ 8 ; | rewrite length_replicate ; vm_compute ; lia in Hc6
iDestruct Hy6 as [Hy6 Hy6′]
iDestruct Hc6 as [Hc6 Hc6′]
iApply wp_call_bind_ _ _ _ _ _ _ _ _ _ _ _ _ mbszero_fn invocationmbszero_fn WPtrmkPtrb6 Objb6 ; word_premise | unfold find_fn ; rewrite Hm ; vm_compute ; reflexivity | reflexivity |
iNext
iApply mbszero_at with Hl6 Hy6 Hc6 ; rewrite length_take length_replicate ; vm_compute ; lia | rewrite length_take length_replicate ; vm_compute ; lia | destruct Hb6 as _ & H16 & _ ; apply mod16_mod8 ; exact H16 | change b6 + 8 ≤ b6 + 16 ; lia |
iNext
iIntros Hl6 Hy6 Hc6
iExists _
iSplit ; iPureIntro ; reflexivity |
iNext

argv0, the program's name.

iApply wp_check_read with Hal ; reflexivity | word_premise | left ; reflexivity | addr_premise | addr_premise | addr_premise |
iNext
iIntros Hal
iDestruct Hs0 as [%Hok0 Hps0]
pose proof Hok0 as Hc0 & Hb0 & Hbp0 & Hsend0 & H480 & Hbs0
iApply wp_raw_load_pointer_in with Hal Ha0 Hps0 ; reflexivity | word_premise | left ; reflexivity | addr_premise | addr_premise | lia | intros xb Hxb ; exists r0 ; destruct Hc0 as Hc0 | Hc0 ; rewrite Hc0 in Hxb ; destruct Hxb as Hxb | Hxb ; try discriminate Hxb ; injection Hxb as ← ; apply elem_of_cons ; left ; reflexivity |
iNext
iIntros Hal Ha0 Hps0
iAssert stringa0 b0 r0 ys0 with [$Hps0] as Hs0 ; done |
iApply wp_call_bind_ _ _ _ _ _ _ _ _ _ _ _ _ set_program_name_fn invocationset_program_name_fn WPtra0 ; word_premise | unfold find_fn ; rewrite Hm ; vm_compute ; reflexivity | reflexivity |
iNext
iNext
iIntros i k Hi Hk Hsuf Hback Hlit Hcells
iExists _
iSplit ; iPureIntro ; reflexivity |
iNext
iDestruct Hback with Hsuf as Hs0

setlocale(LC_ALL, "").

destruct main_globals as G80 & G81 & Gcs
destruct Hlinked as _ & Hg & _
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite Hg_ _ G80 ; reflexivity | intros ?m ; word_premise |
iNext
iEval rewrite obj_zero_blockb4 _ ; | compute ; congruence in Hb4
iDestruct Hb4 as (Hl4 & Hy4 & Hc4)
destruct Hb4 as Hb40 & Hb416 & Hb448
destruct Hb6 as Hb60 & Hb616 & Hb648
iApply HK $! _ b4 b6 i k with [%] Hal Ha0 Hs0 Hlit Hcells Hl4 Hy4 Hc4 Hl6 Hy6 Hy6′ Hc6 Hc6′
split ; repeat split ; assumption |
split ; split ; exact Hb40 | split ; exact Hb416 | exact Hb448 |
split ; split ; exact Hb60 | split ; exact Hb616 | exact Hb648 |
auto

The rest of main's start block, from setlocale's call: setlocale lends every category's new name and sets the codec; the default greeting is stored in b4's cell; atexit registers close_stdout; and the option loop is entered.

598Lemma main_start_rest
∀ e argc av b4 b6 old c0 r80 Φ
start_varse argc av b4 b6
∗k∈locale_categoriesLL.namedk oldk.1 oldk.2 −∗ ptscodec_psc0 −∗ stringempty_ptr 69968 r80 [ ] −∗ liveb4 mkRegionb4 b4 + 16 Heap Live −∗ bytesb4 0 replicate16 0 −∗ auxesb4 0 replicate16 CNone −∗ ▷∀e′ q new : Z → ptr × listZ c′, ⌜start_varse′ argc av b4 b6 ∧ lookupTAtom"chk1" e′ = SomeWPtrmkPtrb4 Objb4 ∧ q = mkPtr0 CNone ∨ q = new6.1⌝ −∗ ∗k∈locale_categoriesLL.lentk newk.1 newk.2 −∗ ptscodec_psc′ −∗ stringempty_ptr 69968 r80 [ ] −∗ liveb4 mkRegionb4 b4 + 16 Heap Live −∗ pcellb4 0 greeting_ptr −∗ bytesb4 8 replicate8 0 −∗ auxesb4 1 replicate15 CNone −∗ WPERunmkFramemain_fn e′ [ ] None EnterTAtom"iw_1.L8" SomeTAtom"start" : mexpr {Φ} −∗ WPERunmkFramemain_fn e [ ] None ExecTAtom"start" start_rest b_jumpmain_block"start" : mexpr {Φ}
Proof 55 steps Qed
intros H0 & H2 & H4 & H6 & H11 Hb40 & Hb416 & Hb448
iIntros Hks Hcod Hs80 Hl4 Hy4 Hc4 HK
destruct main_globals as G80 & G81 & Gcs
pose proof Hlinked as Hm & Hg & _
rewrite / start_rest

setlocale(LC_ALL, "").

iApply wp_main_setlocale with Hks Hcod Hs80 ; word_premise | word_premise | cbn ; tauto |
iNext
iIntros q new c′ Hq Hs80 Hcod Hlent

The default greeting, stored in b4's cell.

iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite Hg_ _ G81 ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_check with Hl4 ; reflexivity | word_premise | reflexivity | addr_premise | cbn [ ptr_addr r_end ] ; unfold raw_address ; drop_wraps_goal ; lia | cbn [ ptr_addr ] ; unfold raw_address ; drop_wraps_goal ; rewrite Z.add_0_r ; apply mod16_mod8 ; exact Hb416 |
iNext
iIntros Hl4
iEval rewrite HC.bytes_split_ _ _ 8 ; | rewrite length_replicate ; lia in Hy4
iEval rewrite HC.auxes_split_ _ _ 1 ; | rewrite length_replicate ; lia in Hc4
iDestruct Hy4 as [Hy4 Hy4′]
iDestruct Hc4 as [Hc4 Hc4′]
iAssert pcellb4 0 mkPtr0 CNone with [Hy4 Hc4] as Hp4 ; iApply zero_pcell ; iFrame |
iApply wp_raw_store_pointer with Hl4 Hp4 ; word_premise | word_premise | reflexivity | addr_premise | rewrite Z.add_0_r ; apply mod16_mod8 ; exact Hb416 | intros m wd h Hin Hw ; exact Kpstore_ _ _ _ _ _ _ _ Hin Hw |
iNext
iIntros Hl4 Hp4

atexit(close_stdout).

iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite Hg_ _ Gcs ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ atexit_spec WPtrclose_stdout_ptr emp%I with [//] [-] ; apply linked_outside ; first exact Hlinked | reflexivity | apply linked_unbound ; first exact Hlinked | reflexivity | reflexivity | exact Hatexit | cbn [ map_option ] ; word_premise | exact Hatexit_abi | |
–iIntros σ Hσ _
iDestruct Hσ as h [_ %Hf]
destruct Hf as _ & _ & _ & Hw
iPureIntro
exact Hatexit_pre_ _ _ Hw
–iNext
iIntros σ trace values s′ m′ w′ Hi Hσ _
iDestruct Hσ as h [Hh %Hf]
destruct Hf as Ha & Hd & Hr & Hw
destruct Katexit_ _ _ _ _ _ _ _ _ _ _ Hw Ha Hd Hr Hi as x & → & Hx & Ha′ & Hd′ & Hr′ & Hw′
iModIntro
iExists _
iSplit
+iPureIntro
rewrite Hatexit_ret
cbn
reflexivity
+iSplitL Hh ; iExists h ; iFrame ; iPureIntro ; auto |
iApply wp_goto
iNext
cbn [ edge_label ]
iApply HK $! _ q new c' with [%] Hlent Hcod Hs80 Hl4 Hp4 Hy4′ Hc4′
split ; repeat split ; assumption |
split ; assumption | exact Hq

Main's start block, from its entry to the option loop: the two segments above.

661Lemma main_start
∀ argc av ar a0 b0 r0 ys0 r3 r4 x0 x1 y0 old c0 r80 Φ
0 < av
av mod 8 = 0
av + 8 ≤ r_endar
r_endar ≤ 2 ^ 48
liveav ar −∗ pcellav 0 a0 −∗ stringa0 b0 r0 ys0 −∗ HP.HN.literalsr3 r4 −∗ HP.HN.name_cellspn nreg sreg nb sb x0 x1 y0 −∗ ∗k∈locale_categoriesLL.namedk oldk.1 oldk.2 −∗ ptscodec_psc0 −∗ stringempty_ptr 69968 r80 [ ] −∗ ▷∀e b4 b6 i k : nat q new : Z → ptr × listZ c′, ⌜start_varse argc av b4 b6 ∧ lookupTAtom"chk1" e = SomeWPtrmkPtrb4 Objb4 ∧ fresh_okb4 ∧ fresh_okb6 ∧ i ≤ lengthys0%nat ∧ k ≤ lengthys0%nat ∧ q = mkPtr0 CNone ∨ q = new6.1⌝ −∗ liveav ar −∗ pcellav 0 a0 −∗ stringa0 b0 r0 ys0 −∗ HP.HN.literalsr3 r4 −∗ HP.HN.name_cellspn nreg sreg nb sb mkPtrptr_addra0 + Z.of_nati ptr_capa0 mkPtrptr_addra0 + Z.of_nati ptr_capa0 mkPtrptr_addra0 + Z.of_natk ptr_capa0 −∗ ∗k∈locale_categoriesLL.lentk newk.1 newk.2 −∗ ptscodec_psc′ −∗ stringempty_ptr 69968 r80 [ ] −∗ liveb4 mkRegionb4 b4 + 16 Heap Live −∗ pcellb4 0 greeting_ptr −∗ bytesb4 8 replicate8 0 −∗ auxesb4 1 replicate15 CNone −∗ liveb6 mkRegionb6 b6 + 16 Heap Live −∗ bytesb6 0 replicate8 0 −∗ bytesb6 8 replicate8 0 −∗ auxesb6 0 clear_slots0 replicate8 CNone −∗ auxesb6 8 replicate8 CNone −∗ WPERunmkFramemain_fn e [ ] None EnterTAtom"iw_1.L8" SomeTAtom"start" : mexpr {Φ} −∗ WPERuninvocationmain_fn WIntargc; WPtrmkPtrav Objav : mexpr {Φ}
Proof 10 steps Qed
intros Hav Hav8 Haend Har48
iIntros Hal Ha0 Hs0 Hlit Hcells Hks Hcod Hs80 HK
iApply main_to_setlocale with Hal Ha0 Hs0 Hlit Hcells ; exact Hav | exact Hav8 | exact Haend | exact Har48 |
iNext
iIntros e b4 b6 i k Hv & Hf4 & Hf6 & Hi & Hk Hal Ha0 Hs0 Hlit Hcells Hl4 Hy4 Hc4 Hl6 Hy6 Hy6′ Hc6 Hc6′
iApply main_start_rest with Hks Hcod Hs80 Hl4 Hy4 Hc4 ; exact Hv | exact Hf4 |
iNext
iIntros e′ q new c′ Hv′ & Hc1 & Hq Hlent Hcod Hs80 Hl4 Hp4 Hy4 Hc4
iApply HK $! e' b4 b6 i k q new c' with [%] Hal Ha0 Hs0 Hlit Hcells Hlent Hcod Hs80 Hl4 Hp4 Hy4 Hc4 Hl6 Hy6 Hy6′ Hc6 Hc6′
auto 10

getopt_long's call

The run's argv is at av, in an object of the region ar, and holds the arguments sargs; the launcher copies each into an object of its own. getopt_long's registry entry is Campaign 4's libc_getopt_contract for this run's input, fixed for the run. Main owns argv as one block, the arguments' strings and the getopt token; the call hands argv back permuted, the strings unchanged and the token naming the new optarg and optind.

argv: aligned, its argc + 1 slots in its region, argc a positive C int, each argument a C string.

709Context av : Z
709Context ar : region
709Context sargs : listargument
709Context Hav : 0 < av ∧ av mod 8 = 0 ∧ av + 8 × Z.of_natlengthsargs + 1 ≤ r_endar ∧ r_endar ≤ 2 ^ 48
709Context Hargc : 1 ≤ Z.of_natlengthsargs < 2 ^ 31
709Context Hargs : Forallλs ⇒ string_okarg_ptrs arg_bases arg_regions arg_texts sargs

The number of argv's bytes and aux slots.

715Notation argv_len ≔ 8 × lengthsargs + 1%nat

getopt_long has libc's contract for this run's input, over the native parser's initialized and running representations and its allocation requests.

720Context initialized running : mem → libc_world → Prop
720Context grequests : listword → mem → libc_world → Z → Z → Prop
720Context Hgetopt : registryTAtom"getopt_long" = Somelibc_getopt_contracthello_inputav sargs initialized running grequests

The contract.

wi ties libc's optarg and optind cells to the parser's state and the getopt token, as GetoptLogic.v's reads need.

730Context optarg_cell optind_cell : ptr

wi keeps Hello's option literals in memory.

736Context Htable : ∀m w h, wim w h → hello_table_atm

wi admits getopt_long's libc side where main owns argv and the arguments: the parser's representation, its private roots and reads, and their separation from the call's inputs and outputs.

getopt_long's private roots and libc's cells are apart from the program's objects, and it releases none of them.

753Context Hgetopt_apart : ∀m w h, wim w h → ∀s a, Ins getopt_rootslibc_getopt_vieww ++ getopt_cellslibc_getopt_vieww → span_containss a → ¬owned_liveh m a ∧ ids_apartgetopt_ownedlibc_getopt_vieww h

A return of getopt_long keeps wi, with argv's block holding what the memory then holds and the token naming the new optarg and optind.

761Context Kgetopt : ∀r args xs s m w h trace values s′ m′ w′ bs cs, M.E.invokegetopt_spec r args xs s m w trace CallReturnvalues s′ m′ w′ → ∀l v, l, v ∈ block_psav ar 0 bs cs → h !! l = Somev → wim w h → wim′ w′ overwriteblock_psav ar 0 mem_bytesm′ av argv_len mem_auxesm′ av argv_len ++ getopt_psgetopt_optarglibc_getopt_vieww′ getopt_optindlibc_getopt_vieww′ h

A permitted order of argv has argc pointers.

768Lemma order_length
∀ ps
lengthps = lengthsargs
Explore proof 5 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
av :
Z
ar :
sargs :
Hav :
0 < av ∧ av mod 8 = 0 ∧ av + 8 × lengthsargs + 1 ≤ r_endar ≤ 2 ^ 48
Hargc :
1 ≤ lengthsargs < 2 ^ 31
Hargs :
initialized, running :
mem → libc_world → Prop
grequests :
listword → mem → libc_world → Z → Z → Prop
Hgetopt :
registryTAtom"getopt_long" = Somegetopt_spec
optarg_cell, optind_cell :
Hgetopt_wi :
Htable :
∀m : mem w : libc_world h : gmappiece pval, wim w h → hello_table_atm
Hgetopt_env :
∀m : mem w : libc_world h : gmappiece pval xs : listZ cs : listcap, wim w h → agreesm h → live_disjointm → ∀l : piece v : pval, l, v ∈ block_psav ar 0 xs cs ++ flat_maparg_ps sargs → h !! l = Somev → getopt_input_atm hello_inputav sargs → libc_getopt_repinitialized m w ∧ Forallwritable_spanm getopt_rootslibc_getopt_vieww ∧ Forallλs : span ⇒ readable_bytesm span_ptrs span_sizes getopt_readslibc_getopt_vieww ∧ getopt_separatedhello_inputav sargs libc_getopt_vieww ∧ getopt_disjointgetopt_public_writeshello_inputav sargs libc_getopt_vieww ∧ getopt_private_ownedm hello_inputav sargs libc_getopt_vieww
Hgetopt_apart :
∀m : mem w : libc_world h : gmappiece pval, wim w h → ∀s : span a : Z, Ins getopt_rootslibc_getopt_vieww ++ getopt_cellslibc_getopt_vieww → span_containss a → ¬owned_liveh m a ∧ ids_apartgetopt_ownedlibc_getopt_vieww h
Kgetopt :
∀r : call_result args : listarg xs : listword s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world bs : listZ cs : listcap, M.E.invokegetopt_spec r args xs s m w trace CallReturnvalues s′ m′ w′ → ∀l : piece v : pval, l, v ∈ block_psav ar 0 bs cs → h !! l = Somev → wim w h → wim′ w′ overwriteblock_psav ar 0 mem_bytesm′ av argv_len mem_auxesm′ av argv_len ++ getopt_psgetopt_optarglibc_getopt_vieww′ getopt_optindlibc_getopt_vieww′ h
ps :
listptr
⊢
getopt_ordermaparg_ptr sargs ps → lengthps = lengthsargs

intros H

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
av :
Z
ar :
sargs :
Hav :
0 < av ∧ av mod 8 = 0 ∧ av + 8 × lengthsargs + 1 ≤ r_endar ≤ 2 ^ 48
Hargc :
1 ≤ lengthsargs < 2 ^ 31
Hargs :
initialized, running :
mem → libc_world → Prop
grequests :
listword → mem → libc_world → Z → Z → Prop
Hgetopt :
registryTAtom"getopt_long" = Somegetopt_spec
optarg_cell, optind_cell :
Hgetopt_wi :
Htable :
∀m : mem w : libc_world h : gmappiece pval, wim w h → hello_table_atm
Hgetopt_env :
∀m : mem w : libc_world h : gmappiece pval xs : listZ cs : listcap, wim w h → agreesm h → live_disjointm → ∀l : piece v : pval, l, v ∈ block_psav ar 0 xs cs ++ flat_maparg_ps sargs → h !! l = Somev → getopt_input_atm hello_inputav sargs → libc_getopt_repinitialized m w ∧ Forallwritable_spanm getopt_rootslibc_getopt_vieww ∧ Forallλs : span ⇒ readable_bytesm span_ptrs span_sizes getopt_readslibc_getopt_vieww ∧ getopt_separatedhello_inputav sargs libc_getopt_vieww ∧ getopt_disjointgetopt_public_writeshello_inputav sargs libc_getopt_vieww ∧ getopt_private_ownedm hello_inputav sargs libc_getopt_vieww
Hgetopt_apart :
∀m : mem w : libc_world h : gmappiece pval, wim w h → ∀s : span a : Z, Ins getopt_rootslibc_getopt_vieww ++ getopt_cellslibc_getopt_vieww → span_containss a → ¬owned_liveh m a ∧ ids_apartgetopt_ownedlibc_getopt_vieww h
Kgetopt :
∀r : call_result args : listarg xs : listword s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world bs : listZ cs : listcap, M.E.invokegetopt_spec r args xs s m w trace CallReturnvalues s′ m′ w′ → ∀l : piece v : pval, l, v ∈ block_psav ar 0 bs cs → h !! l = Somev → wim w h → wim′ w′ overwriteblock_psav ar 0 mem_bytesm′ av argv_len mem_auxesm′ av argv_len ++ getopt_psgetopt_optarglibc_getopt_vieww′ getopt_optindlibc_getopt_vieww′ h
ps :
listptr
H :
⊢
lengthps = lengthsargs

rewrite <- length_maparg_ptr sargs

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
av :
Z
ar :
sargs :
Hav :
0 < av ∧ av mod 8 = 0 ∧ av + 8 × lengthsargs + 1 ≤ r_endar ≤ 2 ^ 48
Hargc :
1 ≤ lengthsargs < 2 ^ 31
Hargs :
initialized, running :
mem → libc_world → Prop
grequests :
listword → mem → libc_world → Z → Z → Prop
Hgetopt :
registryTAtom"getopt_long" = Somegetopt_spec
optarg_cell, optind_cell :
Hgetopt_wi :
Htable :
∀m : mem w : libc_world h : gmappiece pval, wim w h → hello_table_atm
Hgetopt_env :
∀m : mem w : libc_world h : gmappiece pval xs : listZ cs : listcap, wim w h → agreesm h → live_disjointm → ∀l : piece v : pval, l, v ∈ block_psav ar 0 xs cs ++ flat_maparg_ps sargs → h !! l = Somev → getopt_input_atm hello_inputav sargs → libc_getopt_repinitialized m w ∧ Forallwritable_spanm getopt_rootslibc_getopt_vieww ∧ Forallλs : span ⇒ readable_bytesm span_ptrs span_sizes getopt_readslibc_getopt_vieww ∧ getopt_separatedhello_inputav sargs libc_getopt_vieww ∧ getopt_disjointgetopt_public_writeshello_inputav sargs libc_getopt_vieww ∧ getopt_private_ownedm hello_inputav sargs libc_getopt_vieww
Hgetopt_apart :
∀m : mem w : libc_world h : gmappiece pval, wim w h → ∀s : span a : Z, Ins getopt_rootslibc_getopt_vieww ++ getopt_cellslibc_getopt_vieww → span_containss a → ¬owned_liveh m a ∧ ids_apartgetopt_ownedlibc_getopt_vieww h
Kgetopt :
∀r : call_result args : listarg xs : listword s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world bs : listZ cs : listcap, M.E.invokegetopt_spec r args xs s m w trace CallReturnvalues s′ m′ w′ → ∀l : piece v : pval, l, v ∈ block_psav ar 0 bs cs → h !! l = Somev → wim w h → wim′ w′ overwriteblock_psav ar 0 mem_bytesm′ av argv_len mem_auxesm′ av argv_len ++ getopt_psgetopt_optarglibc_getopt_vieww′ getopt_optindlibc_getopt_vieww′ h
ps :
listptr
H :
⊢
lengthps = lengthmaparg_ptr sargs

symmetry

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
av :
Z
ar :
sargs :
Hav :
0 < av ∧ av mod 8 = 0 ∧ av + 8 × lengthsargs + 1 ≤ r_endar ≤ 2 ^ 48
Hargc :
1 ≤ lengthsargs < 2 ^ 31
Hargs :
initialized, running :
mem → libc_world → Prop
grequests :
listword → mem → libc_world → Z → Z → Prop
Hgetopt :
registryTAtom"getopt_long" = Somegetopt_spec
optarg_cell, optind_cell :
Hgetopt_wi :
Htable :
∀m : mem w : libc_world h : gmappiece pval, wim w h → hello_table_atm
Hgetopt_env :
∀m : mem w : libc_world h : gmappiece pval xs : listZ cs : listcap, wim w h → agreesm h → live_disjointm → ∀l : piece v : pval, l, v ∈ block_psav ar 0 xs cs ++ flat_maparg_ps sargs → h !! l = Somev → getopt_input_atm hello_inputav sargs → libc_getopt_repinitialized m w ∧ Forallwritable_spanm getopt_rootslibc_getopt_vieww ∧ Forallλs : span ⇒ readable_bytesm span_ptrs span_sizes getopt_readslibc_getopt_vieww ∧ getopt_separatedhello_inputav sargs libc_getopt_vieww ∧ getopt_disjointgetopt_public_writeshello_inputav sargs libc_getopt_vieww ∧ getopt_private_ownedm hello_inputav sargs libc_getopt_vieww
Hgetopt_apart :
∀m : mem w : libc_world h : gmappiece pval, wim w h → ∀s : span a : Z, Ins getopt_rootslibc_getopt_vieww ++ getopt_cellslibc_getopt_vieww → span_containss a → ¬owned_liveh m a ∧ ids_apartgetopt_ownedlibc_getopt_vieww h
Kgetopt :
∀r : call_result args : listarg xs : listword s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world bs : listZ cs : listcap, M.E.invokegetopt_spec r args xs s m w trace CallReturnvalues s′ m′ w′ → ∀l : piece v : pval, l, v ∈ block_psav ar 0 bs cs → h !! l = Somev → wim w h → wim′ w′ overwriteblock_psav ar 0 mem_bytesm′ av argv_len mem_auxesm′ av argv_len ++ getopt_psgetopt_optarglibc_getopt_vieww′ getopt_optindlibc_getopt_vieww′ h
ps :
listptr
H :
⊢
lengthmaparg_ptr sargs = lengthps

apply Permutation_length

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
av :
Z
ar :
sargs :
Hav :
0 < av ∧ av mod 8 = 0 ∧ av + 8 × lengthsargs + 1 ≤ r_endar ≤ 2 ^ 48
Hargc :
1 ≤ lengthsargs < 2 ^ 31
Hargs :
initialized, running :
mem → libc_world → Prop
grequests :
listword → mem → libc_world → Z → Z → Prop
Hgetopt :
registryTAtom"getopt_long" = Somegetopt_spec
optarg_cell, optind_cell :
Hgetopt_wi :
Htable :
∀m : mem w : libc_world h : gmappiece pval, wim w h → hello_table_atm
Hgetopt_env :
∀m : mem w : libc_world h : gmappiece pval xs : listZ cs : listcap, wim w h → agreesm h → live_disjointm → ∀l : piece v : pval, l, v ∈ block_psav ar 0 xs cs ++ flat_maparg_ps sargs → h !! l = Somev → getopt_input_atm hello_inputav sargs → libc_getopt_repinitialized m w ∧ Forallwritable_spanm getopt_rootslibc_getopt_vieww ∧ Forallλs : span ⇒ readable_bytesm span_ptrs span_sizes getopt_readslibc_getopt_vieww ∧ getopt_separatedhello_inputav sargs libc_getopt_vieww ∧ getopt_disjointgetopt_public_writeshello_inputav sargs libc_getopt_vieww ∧ getopt_private_ownedm hello_inputav sargs libc_getopt_vieww
Hgetopt_apart :
∀m : mem w : libc_world h : gmappiece pval, wim w h → ∀s : span a : Z, Ins getopt_rootslibc_getopt_vieww ++ getopt_cellslibc_getopt_vieww → span_containss a → ¬owned_liveh m a ∧ ids_apartgetopt_ownedlibc_getopt_vieww h
Kgetopt :
∀r : call_result args : listarg xs : listword s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world bs : listZ cs : listcap, M.E.invokegetopt_spec r args xs s m w trace CallReturnvalues s′ m′ w′ → ∀l : piece v : pval, l, v ∈ block_psav ar 0 bs cs → h !! l = Somev → wim w h → wim′ w′ overwriteblock_psav ar 0 mem_bytesm′ av argv_len mem_auxesm′ av argv_len ++ getopt_psgetopt_optarglibc_getopt_vieww′ getopt_optindlibc_getopt_vieww′ h
ps :
listptr
H :
⊢
map arg_ptr sargs ≡ₚ ps

exact getopt_order_inventory_ _ H

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros H
rewrite <- length_maparg_ptr sargs
symmetry
apply Permutation_length

Owning argv's block holding ps, and the arguments, the memory's slots hold ps: getopt_slots.

776Lemma argv_slots
∀ m h ps cs
∀l v, l, v ∈ block_psav ar 0 argv_bytesps cs → h !! l = Somev
∀l v, l, v ∈ flat_maparg_ps sargs → h !! l = Somev
Proof 58 steps Qed
intros Ha Ho Lc Hc Kb Ks
assert Hlv : live_atm av ar
{apply HaPLiveav VLivear , Kb
apply elem_of_cons
left
reflexivity
intros k q Hk
assert Hq : 0 ≤ ptr_addrq < 2 ^ 64 ∧ ¬freed_inm_regionsm ptr_capq
{pose proof list_elem_of_lookup_2_ _ _ Hk as Hq′
apply list_elem_of_In , in_app_or in Hq' as Hq′ | ← |
–destruct order_in_ _ _ Ho Hq' as s & Hs & →
pose proof proj1List.Forall_forall_ _ Hargs s Hs as Hcap & Hb0 & Hbp & Hend & H48 & _
assert Hlive : live_atm arg_bases arg_regions
apply list_elem_of_In , in_flat_map
exists s
split ; exact Hs |
unfold arg_ps , string_ps
left
reflexivity
split ; lia |
intros b′ & reg′ & Hc′ & E′ & L′
destruct Hlive as E1 L1
destruct Hcap as Hc0 | Hc0 ; rewrite Hc0 in Hc' ; destruct Hc' as E0 | E0 ; try discriminate E0 ; injection E0 as ← ; rewrite E1 in E' ; injection E' as ← ; congruence
–split ; cbn ; lia |
intros b′ & reg′ & Hc′ & _
destruct Hc' as E0 | E0 ; discriminate E0
destruct Hq as Hr Hf
split ; exact Hr |
split
–intros i Hi
assert Hin : PByteav 0 + Z.of_nat8 × k + Z.to_nati, VBytebyte_ofptr_addrq i ∈ block_psav ar 0 argv_bytesps cs
{apply elem_of_cons
right
apply elem_of_app
left
apply list_elem_of_lookup_2_ 8 × k + Z.to_nati%nat
unfold argv_bytes
rewrite slots_bytes_lookup_ _ _ _ Hk ; | lia
rewrite Z2Nat.id ; reflexivity | lia
destruct Ha_ _ Kb_ _ Hin as _ Hil
destruct Hilar proj1Hlv proj2Hlv as _ & _ & Hx
rewrite <- Hx
f_equal
lia
–assert Hin : PAuxav 0 + Z.of_nat8 × k, VAuxptr_capq ∈ block_psav ar 0 argv_bytesps cs
{apply elem_of_cons
right
apply elem_of_app
right
apply list_elem_of_lookup_2_ 8 × k%nat
exact Hck q Hk
pose proof aux_piece_holds_ _ _ _ _ Hlv Ha_ _ Kb_ _ Hin as Hh
replace av + 8 × Z.of_natk with av + 0 + Z.of_nat8 × k by lia
exact aux_holds_kept_ _ _ Hh Hf

The arguments are admitted (getopt_pre) where main owns argv's block, holding a permitted order ps, the arguments' strings and the token, whose optind i is at most argc.

819Lemma getopt_admitted
∀ m w h ps cs a i
wim w h
0 ≤ i ≤ Z.of_natlengthsargs
∀l v, l, v ∈ block_psav ar 0 argv_bytesps cs → h !! l = Somev
∀l v, l, v ∈ flat_maparg_ps sargs → h !! l = Somev
∀l v, l, v ∈ getopt_psa i → h !! l = Somev
Proof 64 steps Qed
intros Hw Ha Hd Ho Hc Hi Kb Ks Kt
assert Hlv : live_atm av ar
{apply HaPLiveav VLivear , Kb
apply elem_of_cons
left
reflexivity
pose proof Hav as Hav0 & Hav8 & Haend & Har48
{destruct Htablem w h Hw as T1 & T2 & T3
split ; lia |
split ; rewrite length_map ; reflexivity |
split
{split ; | split ; | split
–unfold writable_span
split ; lia |
exists av, ar
split ; reflexivity |
split ; exact proj1Hlv |
split ; exact proj2Hlv |
apply access_obj_ _ ar ; exact proj1Hlv | lia | lia | apply Z.mod_1_r
–cbn [ ptr_addr ptr_cap ]
apply access_obj_ _ ar ; exact proj1Hlv | lia | lia | exact Hav8
–cbn [ ptr_addr ptr_cap ]
apply access_obj_ _ ar ; exact proj1Hlv | lia | lia | exact Hav8
–exists ps
split ; rewrite map_map ; exact Ho |
exact argv_slotsm h ps cs Ha Ho Hc Kb Ks
split
{apply List.Forall_forall
intros q t Hq
apply in_map_iff in Hq as s & E & Hs
injection E as ← ←
cbn [ fst snd ]
apply string_c_string_ _ arg_bases arg_regions ; exact proj1List.Forall_forall_ _ Hargs s Hs |
intros l v Hl
apply Ha , Ks
apply list_elem_of_In , in_flat_map
exists s
split ; exact Hs | apply list_elem_of_In ; exact Hl
split ; exact T1 |
split ; exact T2 |
split ; exact T3 |
split ; left ; reflexivity |
vm_compute
reflexivity
assert Kall : ∀l v, l, v ∈ block_psav ar 0 argv_bytesps cs ++ flat_maparg_ps sargs → h !! l = Somev
{intros l v Hl
apply elem_of_app in Hl as Hl | Hl ; exact Kb_ _ Hl | exact Ks_ _ Hl
destruct Hgetopt_envm w h _ _ Hw Ha Hd Kall Hin as Hrep & Hroots & Hreads & Hsep & Hdisj & Hpriv
destruct Hgetopt_wim w h Hw as Hst & _ & _ & Hcur
destruct Hcura i Kt_ _ ltac:left as _ Hi′
split ; reflexivity |
split ; exact Hin |
split ; exact Hrep |
split ; exact Hst |
split ; rewrite Hi' ; unfold hello_input ; cbn [ getopt_argc ] ; lia |
split ; exact Hroots |
split ; exact Hreads |
split ; exact Hsep |
split ; exact Hdisj | exact Hpriv

A return of getopt_long satisfies its postcondition.

867Lemma getopt_returned
∀ r args xs s m w trace values s′ m′ w′
M.E.invokegetopt_spec r args xs s m w trace CallReturnvalues s′ m′ w′
Explore proof 4 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
av :
Z
ar :
sargs :
Hav :
0 < av ∧ av mod 8 = 0 ∧ av + 8 × lengthsargs + 1 ≤ r_endar ≤ 2 ^ 48
Hargc :
1 ≤ lengthsargs < 2 ^ 31
Hargs :
initialized, running :
mem → libc_world → Prop
grequests :
listword → mem → libc_world → Z → Z → Prop
Hgetopt :
registryTAtom"getopt_long" = Somegetopt_spec
optarg_cell, optind_cell :
Hgetopt_wi :
Htable :
∀m : mem w : libc_world h : gmappiece pval, wim w h → hello_table_atm
Hgetopt_env :
∀m : mem w : libc_world h : gmappiece pval xs : listZ cs : listcap, wim w h → agreesm h → live_disjointm → ∀l : piece v : pval, l, v ∈ block_psav ar 0 xs cs ++ flat_maparg_ps sargs → h !! l = Somev → getopt_input_atm hello_inputav sargs → libc_getopt_repinitialized m w ∧ Forallwritable_spanm getopt_rootslibc_getopt_vieww ∧ Forallλs : span ⇒ readable_bytesm span_ptrs span_sizes getopt_readslibc_getopt_vieww ∧ getopt_separatedhello_inputav sargs libc_getopt_vieww ∧ getopt_disjointgetopt_public_writeshello_inputav sargs libc_getopt_vieww ∧ getopt_private_ownedm hello_inputav sargs libc_getopt_vieww
Hgetopt_apart :
∀m : mem w : libc_world h : gmappiece pval, wim w h → ∀s : span a : Z, Ins getopt_rootslibc_getopt_vieww ++ getopt_cellslibc_getopt_vieww → span_containss a → ¬owned_liveh m a ∧ ids_apartgetopt_ownedlibc_getopt_vieww h
Kgetopt :
∀r : call_result args : listarg xs : listword s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world bs : listZ cs : listcap, M.E.invokegetopt_spec r args xs s m w trace CallReturnvalues s′ m′ w′ → ∀l : piece v : pval, l, v ∈ block_psav ar 0 bs cs → h !! l = Somev → wim w h → wim′ w′ overwriteblock_psav ar 0 mem_bytesm′ av argv_len mem_auxesm′ av argv_len ++ getopt_psgetopt_optarglibc_getopt_vieww′ getopt_optindlibc_getopt_vieww′ h
args :
listarg
xs :
listword
s :
R.state
m :
trace :
listevent
values :
listword
s′ :
R.state
m′ :
⊢
M.E.invokegetopt_spec r args xs s m w trace CallReturnvalues s′ m′ w′ → ∃born : listZ, getopt_posthello_inputav sargs libc_getopt_view libc_getopt_repinitialized xs m w born trace CallReturnvalues m′ w′

intros H

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
av :
Z
ar :
sargs :
Hav :
0 < av ∧ av mod 8 = 0 ∧ av + 8 × lengthsargs + 1 ≤ r_endar ≤ 2 ^ 48
Hargc :
1 ≤ lengthsargs < 2 ^ 31
Hargs :
initialized, running :
mem → libc_world → Prop
grequests :
listword → mem → libc_world → Z → Z → Prop
Hgetopt :
registryTAtom"getopt_long" = Somegetopt_spec
optarg_cell, optind_cell :
Hgetopt_wi :
Htable :
∀m : mem w : libc_world h : gmappiece pval, wim w h → hello_table_atm
Hgetopt_env :
∀m : mem w : libc_world h : gmappiece pval xs : listZ cs : listcap, wim w h → agreesm h → live_disjointm → ∀l : piece v : pval, l, v ∈ block_psav ar 0 xs cs ++ flat_maparg_ps sargs → h !! l = Somev → getopt_input_atm hello_inputav sargs → libc_getopt_repinitialized m w ∧ Forallwritable_spanm getopt_rootslibc_getopt_vieww ∧ Forallλs : span ⇒ readable_bytesm span_ptrs span_sizes getopt_readslibc_getopt_vieww ∧ getopt_separatedhello_inputav sargs libc_getopt_vieww ∧ getopt_disjointgetopt_public_writeshello_inputav sargs libc_getopt_vieww ∧ getopt_private_ownedm hello_inputav sargs libc_getopt_vieww
Hgetopt_apart :
∀m : mem w : libc_world h : gmappiece pval, wim w h → ∀s : span a : Z, Ins getopt_rootslibc_getopt_vieww ++ getopt_cellslibc_getopt_vieww → span_containss a → ¬owned_liveh m a ∧ ids_apartgetopt_ownedlibc_getopt_vieww h
Kgetopt :
∀r : call_result args : listarg xs : listword s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world bs : listZ cs : listcap, M.E.invokegetopt_spec r args xs s m w trace CallReturnvalues s′ m′ w′ → ∀l : piece v : pval, l, v ∈ block_psav ar 0 bs cs → h !! l = Somev → wim w h → wim′ w′ overwriteblock_psav ar 0 mem_bytesm′ av argv_len mem_auxesm′ av argv_len ++ getopt_psgetopt_optarglibc_getopt_vieww′ getopt_optindlibc_getopt_vieww′ h
args :
listarg
xs :
listword
s :
R.state
m :
trace :
listevent
values :
listword
s′ :
R.state
m′ :
H :
M.E.invokegetopt_spec r args xs s m w trace CallReturnvalues s′ m′ w′
⊢
∃born : listZ, getopt_posthello_inputav sargs libc_getopt_view libc_getopt_repinitialized xs m w born trace CallReturnvalues m′ w′

inversion H as trace′ ending s0 m0 w0 born Habi Hpre Hp Hpost | ; subst

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
av :
Z
ar :
sargs :
Hav :
0 < av ∧ av mod 8 = 0 ∧ av + 8 × lengthsargs + 1 ≤ r_endar ≤ 2 ^ 48
Hargc :
1 ≤ lengthsargs < 2 ^ 31
Hargs :
initialized, running :
mem → libc_world → Prop
grequests :
listword → mem → libc_world → Z → Z → Prop
Hgetopt :
registryTAtom"getopt_long" = Somegetopt_spec
optarg_cell, optind_cell :
Hgetopt_wi :
Htable :
∀m : mem w : libc_world h : gmappiece pval, wim w h → hello_table_atm
Hgetopt_env :
∀m : mem w : libc_world h : gmappiece pval xs : listZ cs : listcap, wim w h → agreesm h → live_disjointm → ∀l : piece v : pval, l, v ∈ block_psav ar 0 xs cs ++ flat_maparg_ps sargs → h !! l = Somev → getopt_input_atm hello_inputav sargs → libc_getopt_repinitialized m w ∧ Forallwritable_spanm getopt_rootslibc_getopt_vieww ∧ Forallλs : span ⇒ readable_bytesm span_ptrs span_sizes getopt_readslibc_getopt_vieww ∧ getopt_separatedhello_inputav sargs libc_getopt_vieww ∧ getopt_disjointgetopt_public_writeshello_inputav sargs libc_getopt_vieww ∧ getopt_private_ownedm hello_inputav sargs libc_getopt_vieww
Hgetopt_apart :
∀m : mem w : libc_world h : gmappiece pval, wim w h → ∀s : span a : Z, Ins getopt_rootslibc_getopt_vieww ++ getopt_cellslibc_getopt_vieww → span_containss a → ¬owned_liveh m a ∧ ids_apartgetopt_ownedlibc_getopt_vieww h
Kgetopt :
∀r : call_result args : listarg xs : listword s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world bs : listZ cs : listcap, M.E.invokegetopt_spec r args xs s m w trace CallReturnvalues s′ m′ w′ → ∀l : piece v : pval, l, v ∈ block_psav ar 0 bs cs → h !! l = Somev → wim w h → wim′ w′ overwriteblock_psav ar 0 mem_bytesm′ av argv_len mem_auxesm′ av argv_len ++ getopt_psgetopt_optarglibc_getopt_vieww′ getopt_optindlibc_getopt_vieww′ h
args :
listarg
xs :
listword
s :
R.state
m :
trace :
listevent
values :
listword
s′ :
R.state
m′ :
H :
M.E.invokegetopt_spec r args xs s m w trace CallReturnvalues s′ m′ w′
born :
listZ
Habi :
contract_abigetopt_spec r args
Hpre :
contract_pregetopt_spec xs m w
Hp :
M.E.prefixgetopt_spec xs s m w born trace s′ m′ w′
Hpost :
contract_postgetopt_spec xs m w born trace CallReturnvalues m′ w′
H0 :
∀why : reason, CallReturnvalues ≠ CallResourcewhy
H1 :
∀values0 : listword, CallReturnvalues = CallReturnvalues0 → return_shapecontract_returnsgetopt_spec values0 ∧ Forallword_authoritycontract_sourcesgetopt_spec xs m w born m′ values0
H2 :
∀status : Z, CallReturnvalues = CallExitstatus → ∃before : listevent, trace = before ++ ProcessExitstatus
⊢
∃born0 : listZ, getopt_posthello_inputav sargs libc_getopt_view libc_getopt_repinitialized xs m w born0 trace CallReturnvalues m′ w′

exists born

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
registry :
wi :
mem → libc_world → gmappiece pval → Prop
SafepointStable0 :
ge :
Hlinked :
Kalloc :
∀q : alloc_req m : mem wd : libc_world h : gmappiece pval base : Z, freshm q base → wim wd h → wiallocatedm q base wd overwriteobj_psbase q h
Hmemset :
registryTAtom"memset" = Somememset_contractlibc_world
Kmemset :
∀b : Z reg : region o : Z xs : listZ cs : listcap m m′ : mem wd : libc_world h : gmappiece pval, memset_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb 0 8 m′ → ∀l : piece v : pval, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicate8 0 clear_slotso cs h
Hstrrchr :
registryTAtom"strrchr" = Somestrrchr_contractlibc_world
Hmemcmp :
registryTAtom"memcmp" = Somememcmp_contractlibc_world
Hstrncmp :
registryTAtom"strncmp" = Somestrncmp_contractlibc_world
pn, nreg, sreg :
nb, sb :
Z
Hnb :
lookupTAtom"program_invocation_name" ge_globalsge = Someptr_addr ≔ nb; ptr_cap ≔ Objnb
Hsb :
lookupTAtom"program_invocation_short_name" ge_globalsge = Someptr_addr ≔ sb; ptr_cap ≔ Objsb
Hpn_end :
program_name_b + 8 ≤ r_endpn
Hnb_cell :
0 ≤ nb ∧ nb mod 8 = 0 ∧ nb + 8 ≤ r_endnreg ≤ 2 ^ 48
Hsb_cell :
0 ≤ sb ∧ sb mod 8 = 0 ∧ sb + 8 ≤ r_endsreg ≤ 2 ^ 48
Knb :
Ksb :
rep :
mem → libc_world → Prop
requests :
listword → mem → libc_world → Z → Z → Prop
Hsetlocale :
registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
Hlent :
∀m : mem w : libc_world h : gmappiece pval k : Z p : ptr t : listZ, wim w h → live_disjointm → objects_fitm_regionsm → freed_emptym_regionsm → h !! PNamek = SomeVNamep t → lent_atm h p t
Hset_pre :
∀m : mem w : libc_world h : gmappiece pval c : Z p : ptr b : Z reg : region bytes : listZ, wim w h → Inc locale_categories → string_okp b reg bytes → all_agreem string_psp b reg bytes → libc_setlocale_prerep WIntc; WPtrp m w
Kset :
∀r : call_result args : listarg c : Z p : ptr s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokelibc_setlocale_contractrep requests r args WIntc; WPtrp s m w trace CallReturnvalues s′ m′ w′ → ∃q : ptr new : Z → ptr × listZ c′ : term, values = WPtrq ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone ∨ q = newc.1 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ overwritecodec_psc′ renameh locale_categories new
Kpstore :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀l : piece v : pval, l, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! l = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
atexit_spec :
Hatexit :
registryTAtom"atexit" = Someatexit_spec
Hatexit_ret :
Hatexit_abi :
contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
Hatexit_pre :
∀m : mem w : libc_world h : gmappiece pval, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
Katexit :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, wim w h → agreesm h → live_disjointm → R.readys m → M.E.invokeatexit_spec r args WPtrclose_stdout_ptr s m w trace CallReturnvalues s′ m′ w′ → ∃x : Z, values = WIntx ∧ 0 ≤ x < 2 ^ 32 ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h
av :
Z
ar :
sargs :
Hav :
0 < av ∧ av mod 8 = 0 ∧ av + 8 × lengthsargs + 1 ≤ r_endar ≤ 2 ^ 48
Hargc :
1 ≤ lengthsargs < 2 ^ 31
Hargs :
initialized, running :
mem → libc_world → Prop
grequests :
listword → mem → libc_world → Z → Z → Prop
Hgetopt :
registryTAtom"getopt_long" = Somegetopt_spec
optarg_cell, optind_cell :
Hgetopt_wi :
Htable :
∀m : mem w : libc_world h : gmappiece pval, wim w h → hello_table_atm
Hgetopt_env :
∀m : mem w : libc_world h : gmappiece pval xs : listZ cs : listcap, wim w h → agreesm h → live_disjointm → ∀l : piece v : pval, l, v ∈ block_psav ar 0 xs cs ++ flat_maparg_ps sargs → h !! l = Somev → getopt_input_atm hello_inputav sargs → libc_getopt_repinitialized m w ∧ Forallwritable_spanm getopt_rootslibc_getopt_vieww ∧ Forallλs : span ⇒ readable_bytesm span_ptrs span_sizes getopt_readslibc_getopt_vieww ∧ getopt_separatedhello_inputav sargs libc_getopt_vieww ∧ getopt_disjointgetopt_public_writeshello_inputav sargs libc_getopt_vieww ∧ getopt_private_ownedm hello_inputav sargs libc_getopt_vieww
Hgetopt_apart :
∀m : mem w : libc_world h : gmappiece pval, wim w h → ∀s : span a : Z, Ins getopt_rootslibc_getopt_vieww ++ getopt_cellslibc_getopt_vieww → span_containss a → ¬owned_liveh m a ∧ ids_apartgetopt_ownedlibc_getopt_vieww h
Kgetopt :
∀r : call_result args : listarg xs : listword s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world bs : listZ cs : listcap, M.E.invokegetopt_spec r args xs s m w trace CallReturnvalues s′ m′ w′ → ∀l : piece v : pval, l, v ∈ block_psav ar 0 bs cs → h !! l = Somev → wim w h → wim′ w′ overwriteblock_psav ar 0 mem_bytesm′ av argv_len mem_auxesm′ av argv_len ++ getopt_psgetopt_optarglibc_getopt_vieww′ getopt_optindlibc_getopt_vieww′ h
args :
listarg
xs :
listword
s :
R.state
m :
trace :
listevent
values :
listword
s′ :
R.state
m′ :
H :
M.E.invokegetopt_spec r args xs s m w trace CallReturnvalues s′ m′ w′
born :
listZ
Habi :
contract_abigetopt_spec r args
Hpre :
contract_pregetopt_spec xs m w
Hp :
M.E.prefixgetopt_spec xs s m w born trace s′ m′ w′
Hpost :
contract_postgetopt_spec xs m w born trace CallReturnvalues m′ w′
H0 :
∀why : reason, CallReturnvalues ≠ CallResourcewhy
H1 :
∀values0 : listword, CallReturnvalues = CallReturnvalues0 → return_shapecontract_returnsgetopt_spec values0 ∧ Forallword_authoritycontract_sourcesgetopt_spec xs m w born m′ values0
H2 :
∀status : Z, CallReturnvalues = CallExitstatus → ∃before : listevent, trace = before ++ ProcessExitstatus
⊢
getopt_posthello_inputav sargs libc_getopt_view libc_getopt_repinitialized xs m w born trace CallReturnvalues m′ w′

exact Hpost

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros H
inversion H as trace′ ending s0 m0 w0 born Habi Hpre Hp Hpost | ; subst
exists born
exact Hpost

A return of the call keeps every piece but argv's bytes and slots agreeing (prefix_agrees_out): its roots and libc's cells are apart from the program's objects, and argv is the one block of the program's it writes. So with argv's block holding what the memory then holds, and any token, the ghost heap agrees; the live objects stay apart and the runtime ready.

881Lemma getopt_frame_ok
∀ r args s m w h trace values s′ m′ w′ ps cs a′ i′
M.E.invokegetopt_spec r args getopt_wordshello_inputav sargs s m w trace CallReturnvalues s′ m′ w′
wim w h
R.readys m
lengthargv_bytesps = argv_len
lengthcs = argv_len
∀l v, l, v ∈ block_psav ar 0 argv_bytesps cs → h !! l = Somev
agreesm′ overwriteblock_psav ar 0 mem_bytesm′ av argv_len mem_auxesm′ av argv_len ++ getopt_psa′ i′ h ∧ live_disjointm′ ∧ R.readys′ m′
Proof 52 steps Qed
intros Hi Hw Ha Hd Hr Lx Lc Kb
pose proof Hav as Hav0 & Hav8 & Haend & Har48
assert Hlv : live_atm av ar
{apply HaPLiveav VLivear , Kb
apply elem_of_cons
left
reflexivity
destruct Hgetopt_apartm w h Hw as Hroots Hrel
destruct M.E.invoke_prefix_ _ _ _ _ _ _ _ _ _ _ _ _ Hi as born & Hp
destruct M.E.prefix_preserve_ _ _ _ _ _ _ _ _ _ _ Hp Hr as Hr′ _
set ks := byte_psav 0 argv_bytesps ++ aux_psav 0 cs.*1
set outs := λx ⇒ span_containsmkSpanmkPtrav Objav 8 × Z.of_natlengthsargs + 1 x
{rewrite <- app_assoc
reflexivity
destruct prefix_agrees_out_ _ _ _ _ _ _ _ _ _ _ h ks outs Hp Hr Hd as Ha′ & _ & Hd′ & _
–intros l v Hl _
exact Hal v Hl
–intros l v Hl Hm
exact agree_piece_registered_ _ _ Hm Hal v Hl
–rewrite Hwr
intros sp x Hin Hsp Hol
apply in_app_or in Hin as Hin | Hin
+exfalso
exact Hrootssp x Hin Hsp Hol
+destruct Hin as [ <-| [ ] ]
exact Hsp
–intros l v Hl Hk
destruct l as b | b o | b o | k ; try exact I ; intros reg Hlv′ Ho′ He′ Hout ; apply Hk ; unfold outs , span_contains in Hout ; cbn [ span_ptr span_size ptr_addr ] in Hout ; apply block_keym av ar 0 argv_bytesps cs _ b o reg Hd Hlv ; lia | rewrite Lx ; lia | rewrite Lc Lx ; reflexivity | auto | exact Hlv' | exact Ho' | exact He' | rewrite Lx ; lia
–exact Hrel
–assert Hlv′ : live_atm' av ar
{apply Ha'PLiveav VLivear ; apply Kb ; apply elem_of_cons ; left ; reflexivity |
exact live_not_key_ _ _ _ _
split ; | split ; exact Hd' | exact Hr'
intros l v Hl
apply lookup_overwrite in Hl as Hin | Hnk Hh
+apply elem_of_app in Hin as Hin | Hin
∗pose proof block_afterm' av ar 0 argv_len l v Hlv' as H
rewrite ! Z.add_0_r in H
apply H ; lia | lia | exact Hin
∗apply list_elem_of_singleton in Hin
injection Hin as → →
exact I
+apply Ha'l v Hh
intros Hk
apply Hnk
rewrite fmap_app
apply elem_of_app
left
pose proof block_keys_afterm' av ar 0 argv_bytesps cs argv_len l Lx Lc Hk as H
rewrite Z.add_0_r in H
exact H

getopt_long(argc, argv, "g:t", longopts, NULL)'s triple, from libc_getopt_contract: owning argv's block, holding a permitted order ps of the arguments, their strings, and the token, whose optind is at most argc, the call binds d to its code, a C int, and hands back argv holding another permitted order, the strings, and the token naming the new optarg and optind, in range; a 'g' comes with a nonnull borrow of an argument.

936Lemma wp_main_getopt
∀ f e ls lab d va vv vs vl vi rest j ps cs a i Φ
0 ≤ i ≤ Z.of_natlengthsargs
ptsblock_psav ar 0 argv_bytesps cs −∗ ptsflat_maparg_ps sargs −∗ ptsgetopt_psa i −∗ ▷∀code ps′ cs′ a′ i′, ⌜getopt_ordermaparg_ptr sargs ps′ ∧ argv_capscs′ ps′ ∧ 0 ≤ i′ ≤ Z.of_natlengthsargs ∧ getopt_intcode ∧ code = 103 → getopt_borrowhello_inputav sargs a′ ∧ ptr_addra′ ≠ 0⌝ −∗ ptsblock_psav ar 0 argv_bytesps′ cs′ −∗ ptsflat_maparg_ps sargs −∗ ptsgetopt_psa′ i′ −∗ WPERunmkFramef putd WIntcode mod 2 ^ 32 e ls None Execlab rest j : mexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd W GlobalTAtom"getopt_long" ArgW va; ArgP vv; ArgP vs; ArgP vl; ArgP vi :: rest j : mexpr {Φ}
Proof 77 steps Qed
intros Hx Ho Hc Hi
iIntros Hb Hs Ht HK
assert Lp : lengthps = lengthsargs by exact order_lengthps Ho
assert Lx : lengthargv_bytesps = argv_len
{unfold argv_bytes
rewrite length_slots_bytes length_app Lp
cbn [ length ]
lia
assert Lc : lengthcs = argv_len
{destruct Hc as Lc _
rewrite Lc length_app Lp
cbn [ length ]
lia
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ getopt_spec getopt_wordshello_inputav sargs ptsblock_psav ar 0 argv_bytesps cs ∗ ptsflat_maparg_ps sargs ∗ ptsgetopt_psa i with [$Hb $Hs $Ht] [HK] ; apply linked_outside ; first exact Hlinked | reflexivity | apply linked_unbound ; first exact Hlinked | reflexivity | reflexivity | exact Hgetopt | exact Hx | | |
–split ; right ; eexists ; reflexivity | do 5 eexists ; reflexivity
–iIntros σ Hσ (Hb & Hs & Ht)
iDestruct Hσ as h [Hh %Hf]
destruct Hf as Ha & Hd & Hr & Hw
iDestruct pts_lookup with Hh Hb as %Kb
iDestruct pts_lookup with Hh Hs as %Ks
iDestruct pts_lookup with Hh Ht as %Kt
iPureIntro
exact getopt_admitted_ _ _ _ _ _ _ Hw Ha Hd Ho Hc Hi Kb Ks Kt
–iNext
iIntros σ trace values s′ m′ w′ Hinv (%h & Hh & %Hf) (Hb & Hs & Ht)
destruct Hf as Ha & Hd & Hr & Hw
iDestruct pts_lookup with Hh Hb as %Kb
destruct getopt_returned_ _ _ _ _ _ _ _ _ _ _ Hinv as born & _ & Hin′ & _ & _ & code & Hend & Hres
injection Hend as →
change getopt_argchello_inputav sargs with Z.of_natlengthsargs in Hres
assert E : Z.of_natlengthsargs =? 0 = false by apply Z.eqb_neq ; lia
rewrite E in Hres
destruct Hres as _ & _ & Hrange & Hresult
destruct hello_code_ _ _ _ _ Hresult as Hint Hg
destruct Hin' as _ & _ & _ & _ & _ & ps′ & Ho′ & Hsl′ & _
rewrite hello_input_order in Ho'
assert Lp′ : lengthps' = lengthsargs by exact order_lengthps' Ho'
destruct argv_of_slotsm' av ps' Hsl' as Eb Ec
assert EL : 8 × lengthps' ++ null%nat = argv_len by rewrite length_app Lp' ; reflexivity
rewrite EL in Eb , Ec
destruct getopt_frame_ok_ _ _ _ _ _ _ _ _ _ _ ps cs a' i' Hinv Hw Ha Hd Hr Lx Lc Kb as Ha′ & Hd′ & Hr′
pose proof Kgetopt_ _ _ _ _ _ _ _ _ _ _ _ _ _ Hinv Kb Hw as Hw′
rewrite Eb in Ha' , Hw'
iMod pts_update_ block_psav ar 0 argv_bytesps cs ++ getopt_psa i block_psav ar 0 argv_bytesps' mem_auxesm' av argv_len ++ getopt_psa' i' with Hh [Hb Ht] as [Hh Hn]
{rewrite ! fmap_app
rewrite block_ps_keysav ar 0 argv_bytesps cs ; reflexivity | |
–rewrite <- Eb , length_mem_bytes
symmetry
exact Lx
–rewrite length_mem_auxes
symmetry
exact Lc
{rewrite pts_app
iFrame
iModIntro
iExists putd WIntcode mod 2 ^ 32 e
iSplit
{iPureIntro
cbn
rewrite Z.mod_mod ; reflexivity | lia
iSplitL Hh
+iExists _
iFrame Hh
iPureIntro
auto
+rewrite pts_app
iDestruct Hn as [Hb Ht]
iApply HK $! code ps' mem_auxesm' av argv_len a' i' with [%] Hb Hs Ht
split ; exact Ho' |
split ; exact Ec |
split ; exact Hrange |
split ; exact Hint | exact Hg

The option loop

Main calls getopt_long until it returns -1, at block iw_1.L8. A 'g' stores optarg in the greeting's cell b4 (iw_1.L35), a 't' the traditional greeting (iw_1.L42); any other code but --help and --version sets pr.2, the "lose" flag (iw_1.L52). Each goes back round. getopt_long promises no bound on its calls, so the loop is proved by Löb induction: each round enters a block, which takes a step. Its exits are the version and help blocks, iw_1.L21 and iw_1.L39, and the end of options, iw_1.L10, which the proof leaves to continuations.

libc's optarg cell is the global optarg, and both cells are at word addresses.

1016Context Hoptarg_g : lookupTAtom"optarg" ge_globalsge = Someoptarg_cell
1016Context Hcells : 0 ≤ ptr_addroptarg_cell < 2 ^ 64 ∧ 0 ≤ ptr_addroptind_cell < 2 ^ 64

The greetings b4's cell may hold in the loop: the default, the traditional one, or a nonnull borrow of an argument.

1021Definition greeting_okg : ptr : Prop ≔

What main owns in the loop: argv's block holding ps, the arguments' strings, the getopt token, and the greeting's cell b4 holding g.

1027Definition loop_resb4 : Z ps : listptr cs : listcap a : ptr i : Z g : ptr : iPropΣ ≔
ptsblock_psav ar 0 argv_bytesps cs ∗ ptsflat_maparg_ps sargs ∗ ptsgetopt_psa i ∗ liveb4 mkRegionb4 b4 + 16 Heap Live ∗ pcellb4 0 g

What main knows in the loop: its temporaries, argv's order, the token's optind in range and the greeting.

1033Definition loop_factse : env b4 b6 : Z ps : listptr cs : listcap i : Z g : ptr : Prop ≔
start_varse Z.of_natlengthsargs av b4 b6 ∧ lookupTAtom"chk1" e = SomeWPtrmkPtrb4 Objb4 ∧ fresh_okb4 ∧ getopt_ordermaparg_ptr sargs ps ∧ argv_capscs ps ∧ 0 ≤ i ≤ Z.of_natlengthsargs ∧ greeting_okg

The loop's entry by the edge from: from start with pr.2 0, from iw_1.L52 with 1, and from iw_1.L35 or iw_1.L42 with what pr.2 was.

1041Definition loop_entryfrom : String.string e : env lose : Z : Prop ≔
from = "start"%string ∧ lose = 0 ∨ from = "iw_1.L52"%string ∧ lose = 1 ∨ from = "iw_1.L35"%string ∨ from = "iw_1.L42"%string ∧ lookupTAtom"iw_1.pr.2" e = SomeWIntlose ∧ lose = 0 ∨ lose = 1

An exit of the loop: entering the block lab from the block from, with the loop's facts and pieces and pr.2 bound to 0 or 1.

1048Definition loop_exitb4 b6 : Z lab from : String.string Φ : language.valnanofil_langregistry ge → iPropΣ : iPropΣ ≔
∀e ps cs a i g lose, ⌜loop_factse b4 b6 ps cs i g ∧ lookupTAtom"iw_1.pr.2" e = SomeWIntlose ∧ lose = 0 ∨ lose = 1⌝ −∗ loop_resb4 ps cs a i g −∗ WPERunmkFramemain_fn e [ ] None EnterTAtomlab SomeTAtomfrom : mexpr {Φ}

The option loop, from its entry by any edge to one of its exits.

1056Lemma main_loop
∀ b4 b6 Φ
⊢ ∀from e lose ps cs a i g, ⌜loop_entryfrom e lose ∧ loop_factse b4 b6 ps cs i g⌝ −∗ loop_resb4 ps cs a i g −∗ loop_exitb4 b6 "iw_1.L21"%string "iw_1.L19"%string Φ ∧ loop_exitb4 b6 "iw_1.L39"%string "iw_1.L50"%string Φ ∧ loop_exitb4 b6 "iw_1.L10"%string "iw_1.L8"%string Φ −∗ WPERunmkFramemain_fn e [ ] None EnterTAtom"iw_1.L8" SomeTAtomfrom : mexpr {Φ}
Proof 168 steps Qed
iLöb as IH
iIntros from e lose ps cs a i g Hent Hf (Hb & Hs & Ht & Hl4 & Hp4) HK
destruct Hf as H0 & H2 & H4 & H6 & H11 & Hc1 & Hfr & Ho & Hc & Hi & Hg
pose proof Hfr as Hb40 & Hb416 & Hb448
assert Hlose : lose = 0 ∨ lose = 1
{destruct Hent as _ → | _ → | _ _ Hl ; auto
destruct getopt_globals as G69 & G64 & G76 & _
pose proof Hlinked as Hm & Hglob & _
pose proof Hargc as Hargc′

Enter iw_1.L8: pr.2 is lose.

iApply wp_enter_ _ _ _ _ _ _ _ main_block"iw_1.L8" putTAtom"iw_1.pr.2" WIntlose e
{vm_compute
reflexivity
{destruct Hent as → → | → → | → | → Hpr _ ; word_premise
iNext

getopt_long(argc, argv, "g:t", longopts, NULL).

iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite Hglob_ _ G69 ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite Hglob_ _ G64 ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_main_getopt with Hb Hs Ht ; word_premise | exact Ho | exact Hc | exact Hi |
iNext
iIntros code ps′ cs′ a′ i′ Ho′ & Hc′ & Hi′ & Hint & Hgc Hb Hs Ht
pose proof int32_endcode Hint as Hcend
pose proof λk ⇒ int32_eqcode k Hint as Hceq
pose proof Z.mod_pos_boundcode 2 ^ 32 ltac:lia as Hcr
set c := code mod 2 ^ 32 in *
clearbody c
iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
destruct Z.eq_decc 4294967295 as → | Hn1

-1: the end of options.

{iApply wp_branch_ _ _ _ _ _ _ _ _ _ 0 ; word_premise |
iNext
cbn [ Z.eqb edge_label ]
iDestruct HK as [_ [_ HK]]
iApply HK $! _ ps' cs' a' i' g lose with [%] [$Hb $Hs $Ht $Hl4 $Hp4]
split ; | split ; assumption | exact Hlose
split ; repeat split ; assumption |
split ; assumption |
split ; exact Hfr |
auto
iApply wp_branch_ _ _ _ _ _ _ _ _ _ 1 ; word_premise |
iNext
cbn [ Z.eqb edge_label ]
mn_enter "iw_1.L19"
iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
destruct Z.eq_decc 129 as → | H129

--version.

{iApply wp_branch_ _ _ _ _ _ _ _ _ _ 1 ; word_premise |
iNext
cbn [ Z.eqb edge_label ]
iDestruct HK as [HK _]
iApply HK $! _ ps' cs' a' i' g lose with [%] [$Hb $Hs $Ht $Hl4 $Hp4]
split ; | split ; assumption | exact Hlose
split ; repeat split ; assumption |
split ; assumption |
split ; exact Hfr |
auto
iApply wp_branch_ _ _ _ _ _ _ _ _ _ 0 ; word_premise |
iNext
cbn [ Z.eqb edge_label ]
mn_enter "iw_1.L48"
iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
destruct Z.eq_decc 103 as → | H103

'g': the greeting is optarg.

{pose proof proj1Hceq103 ltac:lia eq_refl as →
destruct Hgceq_refl as Hborrow Hnz
iApply wp_branch_ _ _ _ _ _ _ _ _ _ 1 ; word_premise |
iNext
cbn [ Z.eqb edge_label ]
mn_enter "iw_1.L35"
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite Hoptarg_g ; reflexivity | intros ?m ; word_premise |
iNext
iNext
iNext
iIntros Ht
iApply wp_renew with Hl4 ; reflexivity | word_premise | reflexivity | reflexivity | addr_premise | cbn [ ptr_addr r_end ] ; unfold raw_address ; drop_wraps_goal ; lia | cbn [ ptr_addr ] ; unfold raw_address ; drop_wraps_goal ; rewrite Z.add_0_r ; apply mod16_mod8 ; exact Hb416 |
iNext
iIntros Hl4
iApply wp_raw_store_pointer with Hl4 Hp4 ; word_premise | word_premise | reflexivity | addr_premise | rewrite Z.add_0_r ; apply mod16_mod8 ; exact Hb416 | intros m wd h Hin Hw ; exact Kpstore_ _ _ _ _ _ _ _ Hin Hw |
iNext
iIntros Hl4 Hp4
iApply wp_goto
iNext
cbn [ edge_label ]
iApply IH $! "iw_1.L35"%string _ lose ps' cs' a' i' a' with [%] [$Hb $Hs $Ht $Hl4 $Hp4] HK
split ; right ; right ; split ; left ; reflexivity | split ; assumption | exact Hlose |
split ; repeat split ; assumption |
split ; assumption |
split ; exact Hfr |
split ; exact Ho' |
split ; exact Hc' |
split ; exact Hi' |
right ; right ; split ; assumption
iApply wp_branch_ _ _ _ _ _ _ _ _ _ 0 ; word_premise |
iNext
cbn [ Z.eqb edge_label ]
mn_enter "iw_1.L50"
iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
destruct Z.eq_decc 128 as → | H128

--help.

{iApply wp_branch_ _ _ _ _ _ _ _ _ _ 1 ; word_premise |
iNext
cbn [ Z.eqb edge_label ]
iDestruct HK as [_ [HK _]]
iApply HK $! _ ps' cs' a' i' g lose with [%] [$Hb $Hs $Ht $Hl4 $Hp4]
split ; | split ; assumption | exact Hlose
split ; repeat split ; assumption |
split ; assumption |
split ; exact Hfr |
auto
iApply wp_branch_ _ _ _ _ _ _ _ _ _ 0 ; word_premise |
iNext
cbn [ Z.eqb edge_label ]
mn_enter "iw_1.L52"
iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
destruct Z.eq_decc 116 as → | H116

't': the traditional greeting.

{iApply wp_branch_ _ _ _ _ _ _ _ _ _ 1 ; word_premise |
iNext
cbn [ Z.eqb edge_label ]
mn_enter "iw_1.L42"
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite Hglob_ _ G76 ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_renew with Hl4 ; reflexivity | word_premise | reflexivity | reflexivity | addr_premise | cbn [ ptr_addr r_end ] ; unfold raw_address ; drop_wraps_goal ; lia | cbn [ ptr_addr ] ; unfold raw_address ; drop_wraps_goal ; rewrite Z.add_0_r ; apply mod16_mod8 ; exact Hb416 |
iNext
iIntros Hl4
iApply wp_raw_store_pointer with Hl4 Hp4 ; word_premise | word_premise | reflexivity | addr_premise | rewrite Z.add_0_r ; apply mod16_mod8 ; exact Hb416 | intros m wd h Hin Hw ; exact Kpstore_ _ _ _ _ _ _ _ Hin Hw |
iNext
iIntros Hl4 Hp4
iApply wp_goto
iNext
cbn [ edge_label ]
iApply IH $! "iw_1.L42"%string _ lose ps' cs' a' i' traditional_ptr with [%] [$Hb $Hs $Ht $Hl4 $Hp4] HK
split ; right ; right ; split ; right ; reflexivity | split ; assumption | exact Hlose |
split ; repeat split ; assumption |
split ; assumption |
split ; exact Hfr |
split ; exact Ho' |
split ; exact Hc' |
split ; exact Hi' |
right ; left ; reflexivity

Any other code: an unknown option; pr.2 is 1.

iApply wp_branch_ _ _ _ _ _ _ _ _ _ 0 ; word_premise |
iNext
cbn [ Z.eqb edge_label ]
iApply IH $! "iw_1.L52"%string _ 1 ps' cs' a' i' g with [%] [$Hb $Hs $Ht $Hl4 $Hp4] HK
split ; right ; left ; split ; reflexivity |
split ; repeat split ; assumption |
split ; assumption |
split ; exact Hfr |
auto

argv's block, holding q first: its life, q's cell, and the rest's bytes and slots.

1180Lemma argv_block_split
∀ b reg q rest cs
ptsblock_psb reg 0 argv_bytesq :: rest ptr_capq :: cs ⊣⊢ liveb reg ∗ pcellb 0 q ∗ bytesb 8 argv_bytesrest ∗ auxesb 1 cs
Proof 12 steps Qed
cbn [ app flat_map ]
change lengthslot_bytesptr_addrq with 8%nat
change 0 + Z.of_nat8 with 8
change 0 + 1 with 1
assert E : byte_psb 0 slot_bytesptr_addrq = cellb 0 ptr_addrq by reflexivity
rewrite E pts_app
change PAuxb 0, VAuxptr_capq :: aux_psb 1 cs with PAuxb 0, VAuxptr_capq ++ aux_psb 1 cs
change PAuxb 0, VAuxptr_capq :: cellb 0 ptr_addrq with PAuxb 0, VAuxptr_capq ++ cellb 0 ptr_addrq
rewrite ! pts_app
iSplit ; iIntros (Hl & [Hc Hy] & [Ha Hx]) | iIntros (Hl & [Ha Hc] & Hy & Hx) ; iFrame

Main from its entry to the option loop's exits: main_start, with argv's first slot and string out of argv's block and the arguments, then main_loop from start. The continuation is given everything the start block leaves outside the loop, and builds the exits.

1200Lemma main_to_loop
∀ s0 srest r3 r4 x0 x1 y0 old c0 r80 cs0 a ix Φ
sargs = s0 :: srest
0 ≤ ix ≤ Z.of_natlengthsargs
ptsblock_psav ar 0 argv_bytesmaparg_ptr sargs cs0 −∗ ptsflat_maparg_ps sargs −∗ ptsgetopt_psa ix −∗ HP.HN.literalsr3 r4 −∗ HP.HN.name_cellspn nreg sreg nb sb x0 x1 y0 −∗ ∗k∈locale_categoriesLL.namedk oldk.1 oldk.2 −∗ ptscodec_psc0 −∗ stringempty_ptr 69968 r80 [ ] −∗ ▷∀e b4 b6 i k : nat q new : Z → ptr × listZ c′, ⌜start_varse Z.of_natlengthsargs av b4 b6 ∧ lookupTAtom"chk1" e = SomeWPtrmkPtrb4 Objb4 ∧ fresh_okb4 ∧ fresh_okb6 ∧ i ≤ lengtharg_texts0%nat ∧ k ≤ lengtharg_texts0%nat ∧ q = mkPtr0 CNone ∨ q = new6.1⌝ −∗ HP.HN.literalsr3 r4 −∗ HP.HN.name_cellspn nreg sreg nb sb mkPtrptr_addrarg_ptrs0 + Z.of_nati ptr_caparg_ptrs0 mkPtrptr_addrarg_ptrs0 + Z.of_nati ptr_caparg_ptrs0 mkPtrptr_addrarg_ptrs0 + Z.of_natk ptr_caparg_ptrs0 −∗ ∗k∈locale_categoriesLL.lentk newk.1 newk.2 −∗ ptscodec_psc′ −∗ stringempty_ptr 69968 r80 [ ] −∗ bytesb4 8 replicate8 0 −∗ auxesb4 1 replicate15 CNone −∗ liveb6 mkRegionb6 b6 + 16 Heap Live −∗ bytesb6 0 replicate8 0 −∗ bytesb6 8 replicate8 0 −∗ auxesb6 0 clear_slots0 replicate8 CNone −∗ auxesb6 8 replicate8 CNone −∗ loop_exitb4 b6 "iw_1.L21"%string "iw_1.L19"%string Φ ∧ loop_exitb4 b6 "iw_1.L39"%string "iw_1.L50"%string Φ ∧ loop_exitb4 b6 "iw_1.L10"%string "iw_1.L8"%string Φ −∗ WPERuninvocationmain_fn WIntZ.of_natlengthsargs; WPtrmkPtrav Objav : mexpr {Φ}
Proof 49 steps Qed
intros Hhd Lc Hc Hix
iIntros Hb Hs Ht Hlit Hcells Hks Hcod Hs80 HK
pose proof Hav as Hav0 & Hav8 & Haend & Har48
{apply proj1List.Forall_forall_ _ Hargs
rewrite Hhd
left
reflexivity
assert Ec0 : ∃csr, cs0 = ptr_caparg_ptrs0 :: csr
{pose proof Hc0%nat arg_ptrs0 as H
rewrite Hhd in H
specialize Heq_refl
destruct cs0 as | c csr ; discriminate H |
cbn in H
injection H as →
eauto
destruct Ec0 as csr & →
assert Eps : maparg_ptr sargs = arg_ptrs0 :: maparg_ptr srest by rewrite Hhd ; reflexivity
assert Efl : flat_maparg_ps sargs = arg_pss0 ++ flat_maparg_ps srest by rewrite Hhd ; reflexivity
iEval rewriteEps argv_block_split in Hb
iDestruct Hb as (Hal & Ha0 & Hy & Hx)
iEval rewriteEfl pts_app in Hs
iDestruct Hs as [Hs0 Hsr]
iAssert stringarg_ptrs0 arg_bases0 arg_regions0 arg_texts0 with [Hs0] as Hstr
{iSplit ; iPureIntro ; exact Hok0 | iExact Hs0
iApply main_start with Hal Ha0 Hstr Hlit Hcells Hks Hcod Hs80 ; lia | exact Hav8 | lia | exact Har48 |
iNext
iIntros e b4 b6 i k q new c′ Hv & Hc1 & Hf4 & Hf6 & Hi & Hk & Hq Hal Ha0 Hstr Hlit Hcells Hlent Hcod Hs80 Hl4 Hp4 Hy4 Hc4 Hl6 Hy6 Hy6′ Hc6 Hc6′
iDestruct Hstr as [_ Hs0]
iAssert ptsblock_psav ar 0 argv_bytesmaparg_ptr sargs ptr_caparg_ptrs0 :: csr with [Hal Ha0 Hy Hx] as Hb
{rewrite Eps argv_block_split
iFrame
iAssert ptsflat_maparg_ps sargs with [Hs0 Hsr] as Hs
{rewrite Efl pts_app
iFrame
iApply main_loopb4 b6 Φ $! "start"%string e 0 maparg_ptr sargs ptr_caparg_ptrs0 :: csr a ix greeting_ptr with [%] [Hb Hs Ht Hl4 Hp4] [-]
–split ; left ; split ; reflexivity |
split ; exact Hv |
split ; exact Hc1 |
split ; exact Hf4 |
split ; rewrite Eps ; split ; reflexivity | apply Permutation_refl |
split ; split ; exact Lc | exact Hc |
split ; exact Hix |
left
reflexivity
–rewrite / loop_res
iFrame
–iApply HK $! e b4 b6 i k q new c' with [%] Hlit Hcells Hlent Hcod Hs80 Hy4 Hc4 Hl6 Hy6 Hy6′ Hc6 Hc6′
auto 10