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 HelloConvDefs HelloName HelloProgName Startup Getopt GetoptLogic HelloVersion
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

A slot's bytes are a pointer cell's.

333Lemma slot_cell
∀ b o x
byte_psb o slot_bytesx = cellb o x
Explore proof 4 tactics

Initial goal

b, o, x :
Z
⊢
byte_psb o slot_bytesx = cellb o x

unfold byte_ps , slot_bytes , cell , seqZ

b, o, x :
Z
⊢
zip_withλi x0 : Z ⇒ PByteb i, VBytex0 λi : nat ⇒ i + o <$> seq0 Z.to_natlengthmapbyte_ofx 0; 1; 2; 3; 4; 5; 6; 7 mapbyte_ofx 0; 1; 2; 3; 4; 5; 6; 7 = mapλi : Z ⇒ PByteb o + i, VBytebyte_ofx i 0; 1; 2; 3; 4; 5; 6; 7

simpl

b, o, x :
Z
⊢
PByteb 0%nat + o, VBytebyte_ofx 0; PByteb 1%nat + o, VBytebyte_ofx 1; PByteb 2%nat + o, VBytebyte_ofx 2; PByteb 3%nat + o, VBytebyte_ofx 3; PByteb 4%nat + o, VBytebyte_ofx 4; PByteb 5%nat + o, VBytebyte_ofx 5; PByteb 6%nat + o, VBytebyte_ofx 6; PByteb 7%nat + o, VBytebyte_ofx 7 = PByteb o + 0, VBytebyte_ofx 0; PByteb o + 1, VBytebyte_ofx 1; PByteb o + 2, VBytebyte_ofx 2; PByteb o + 3, VBytebyte_ofx 3; PByteb o + 4, VBytebyte_ofx 4; PByteb o + 5, VBytebyte_ofx 5; PByteb o + 6, VBytebyte_ofx 6; PByteb o + 7, VBytebyte_ofx 7

rewrite ! Z.add_comm_ o Z.add_0_r

b, o, x :
Z
⊢
PByteb o, VBytebyte_ofx 0; PByteb o + 1%nat, VBytebyte_ofx 1; PByteb o + 2%nat, VBytebyte_ofx 2; PByteb o + 3%nat, VBytebyte_ofx 3; PByteb o + 4%nat, VBytebyte_ofx 4; PByteb o + 5%nat, VBytebyte_ofx 5; PByteb o + 6%nat, VBytebyte_ofx 6; PByteb o + 7%nat, VBytebyte_ofx 7 = PByteb o, VBytebyte_ofx 0; PByteb o + 1, VBytebyte_ofx 1; PByteb o + 2, VBytebyte_ofx 2; PByteb o + 3, VBytebyte_ofx 3; PByteb o + 4, VBytebyte_ofx 4; PByteb o + 5, VBytebyte_ofx 5; PByteb o + 6, VBytebyte_ofx 6; PByteb o + 7, VBytebyte_ofx 7

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
unfold byte_ps , slot_bytes , cell , seqZ
simpl
rewrite ! Z.add_comm_ o Z.add_0_r
reflexivity

Slot k of argv holding a permitted order ps: an argument, before the sentinel, or the sentinel itself, null.

340Lemma slot_kinds
∀ sargs ps k q
ps ++ null !! k = Someq
k = lengthps ∧ q = null ∨ k < lengthps%nat ∧ ∃s, Ins sargs ∧ q = arg_ptrs
Explore proof 13 tactics

Initial goal

sargs :
ps :
listptr
k :
nat
q :
⊢
getopt_ordermaparg_ptr sargs ps → ps ++ null !! k = Someq → k = lengthps ∧ q = null ∨ k < lengthps%nat ∧ ∃s : argument, Ins sargs ∧ q = arg_ptrs

intros Ho Hq

sargs :
ps :
listptr
k :
nat
q :
Ho :
Hq :
ps ++ null !! k = Someq
⊢
k = lengthps ∧ q = null ∨ k < lengthps%nat ∧ ∃s : argument, Ins sargs ∧ q = arg_ptrs

apply lookup_app_Some in Hq as Hq | Hle Hq

2 open

sargs :
ps :
listptr
k :
nat
q :
Ho :
Hq :
ps !! k = Someq
⊢
k = lengthps ∧ q = null ∨ k < lengthps%nat ∧ ∃s : argument, Ins sargs ∧ q = arg_ptrs
focused goal
sargs :
ps :
listptr
k :
nat
q :
Ho :
Hle :
lengthps ≤ k%nat
Hq :
null !! k − lengthps%nat = Someq
⊢
k = lengthps ∧ q = null ∨ k < lengthps%nat ∧ ∃s : argument, Ins sargs ∧ q = arg_ptrs

–right

2 open

sargs :
ps :
listptr
k :
nat
q :
Ho :
Hq :
ps !! k = Someq
⊢
k < lengthps%nat ∧ ∃s : argument, Ins sargs ∧ q = arg_ptrs
deferred goal
sargs :
ps :
listptr
k :
nat
q :
Ho :
Hle :
lengthps ≤ k%nat
Hq :
null !! k − lengthps%nat = Someq
⊢
k = lengthps ∧ q = null ∨ k < lengthps%nat ∧ ∃s : argument, Ins sargs ∧ q = arg_ptrs

split ; exact lookup_lt_Some_ _ _ Hq |

2 open

sargs :
ps :
listptr
k :
nat
q :
Ho :
Hq :
ps !! k = Someq
⊢
∃s : argument, Ins sargs ∧ q = arg_ptrs
deferred goal
sargs :
ps :
listptr
k :
nat
q :
Ho :
Hle :
lengthps ≤ k%nat
Hq :
null !! k − lengthps%nat = Someq
⊢
k = lengthps ∧ q = null ∨ k < lengthps%nat ∧ ∃s : argument, Ins sargs ∧ q = arg_ptrs

apply order_insargs ps q Ho

2 open

sargs :
ps :
listptr
k :
nat
q :
Ho :
Hq :
ps !! k = Someq
⊢
Inq ps
deferred goal
sargs :
ps :
listptr
k :
nat
q :
Ho :
Hle :
lengthps ≤ k%nat
Hq :
null !! k − lengthps%nat = Someq
⊢
k = lengthps ∧ q = null ∨ k < lengthps%nat ∧ ∃s : argument, Ins sargs ∧ q = arg_ptrs

apply list_elem_of_In

2 open

sargs :
ps :
listptr
k :
nat
q :
Ho :
Hq :
ps !! k = Someq
⊢
q ∈ ps
deferred goal
sargs :
ps :
listptr
k :
nat
q :
Ho :
Hle :
lengthps ≤ k%nat
Hq :
null !! k − lengthps%nat = Someq
⊢
k = lengthps ∧ q = null ∨ k < lengthps%nat ∧ ∃s : argument, Ins sargs ∧ q = arg_ptrs

exact list_elem_of_lookup_2_ _ _ Hq

deferred goal
sargs :
ps :
listptr
k :
nat
q :
Ho :
Hle :
lengthps ≤ k%nat
Hq :
null !! k − lengthps%nat = Someq
⊢
k = lengthps ∧ q = null ∨ k < lengthps%nat ∧ ∃s : argument, Ins sargs ∧ q = arg_ptrs

–left

sargs :
ps :
listptr
k :
nat
q :
Ho :
Hle :
lengthps ≤ k%nat
Hq :
null !! k − lengthps%nat = Someq
⊢
k = lengthps ∧ q = null

revert Hq

sargs :
ps :
listptr
k :
nat
q :
Ho :
Hle :
lengthps ≤ k%nat
⊢
null !! k − lengthps%nat = Someq → k = lengthps ∧ q = null

destruct k − lengthps%nat as | j eqn: E ; intros Hq ; | destruct j ; discriminate Hq

sargs :
ps :
listptr
k :
nat
q :
Ho :
Hle :
lengthps ≤ k%nat
E :
k − lengthps%nat = 0%nat
Hq :
null !! 0%nat = Someq
⊢
k = lengthps ∧ q = null

cbn in Hq

sargs :
ps :
listptr
k :
nat
q :
Ho :
Hle :
lengthps ≤ k%nat
E :
k − lengthps%nat = 0%nat
Hq :
Somenull = Someq
⊢
k = lengthps ∧ q = null

assert q = null as → by congruence

sargs :
ps :
listptr
k :
nat
Ho :
Hle :
lengthps ≤ k%nat
E :
k − lengthps%nat = 0%nat
Hq :
Somenull = Somenull
⊢
k = lengthps ∧ null = null

split ; lia | reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Ho Hq
apply lookup_app_Some in Hq as Hq | Hle Hq
–right
split ; exact lookup_lt_Some_ _ _ Hq |
apply order_insargs ps q Ho
apply list_elem_of_In
exact list_elem_of_lookup_2_ _ _ Hq
–left
revert Hq
destruct k − lengthps%nat as | j eqn: E ; intros Hq ; | destruct j ; discriminate Hq
cbn in Hq
assert q = null as → by congruence
split ; lia | reflexivity

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

Main's output calls, in order: the help text's usage line with the program's name, its six lines of options and the hint that a translation's bugs go elsewhere, then, on stderr, the hint to try --help.

356Definition main_output_argsstream errstream pname : ptr : listname × listword ≔
TAtom"fprintf", WPtrstream; WPtrversion_literal"hello#str.54"; WPtrpname; TAtom"fputs", WPtrversion_literal"hello#str.55"; WPtrstream; TAtom"fputs", WPtrversion_literal"hello#str.56"; WPtrstream; TAtom"fputs", WPtrversion_literal"hello#str.57"; WPtrstream; TAtom"fputs", WPtrversion_literal"hello#str.58"; WPtrstream; TAtom"fputs", WPtrversion_literal"hello#str.59"; WPtrstream; TAtom"fputs", WPtrversion_literal"hello#str.60"; WPtrstream; TAtom"fprintf", WPtrstream; WPtrversion_literal"hello#str.62"; WPtrversion_literal"hello#str.63"; TAtom"fprintf", WPtrerrstream; WPtrversion_literal"hello#str.79"; WPtrpname

The program's name as set_program_name leaves it: a suffix of the first argument's string.

370Definition name_oksargs : listargument pname : ptr : Prop ≔
∃s0 srest i : nat, sargs = s0 :: srest ∧ i ≤ lengtharg_texts0%nat ∧ pname = mkPtrptr_addrarg_ptrs0 + Z.of_nati ptr_caparg_ptrs0
374Module HelloMain R : Runtime
375Module LG0 ≔ Logic R
376Module HP ≔ HelloProgNameOn R LG0
377Module GL ≔ GetoptLogicOn R LG0
378Module HV ≔ HelloVersionOn R LG0
379Module HLo ≔ HelloLocaleOn R LG0
380Module HL ≔ HLo.HL
381Module LL ≔ HL.LL
382Module ML ≔ HL.ML
383Module SL ≔ ML.SL
384Module LG ≔ LG0
385Module L ≔ LG.L
386Module GR ≔ GetoptRefinementOn R L.M
Import L LG SL ML LL HL
389Section main
390Context `{!invGS_genhlc Σ, !gen_heapGSpiece pval Σ}
391Context registry : name → optioncontractlibc_world wi : mem → libc_world → gmappiece pval → Prop `{!SafepointStablewi} ge : genv

The Iris instance of the registry and wi.

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

The expressions of the language.

399Notation mexpr ≔ language.exprnanofil_langregistry ge

The genv links Hello.

402Context Hlinked : hello_linkedge

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

405Context 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.

410Context Hmemset : registryTAtom"memset" = Somememset_contractlibc_world
410Context 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.

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

433Context rep : mem → libc_world → Prop
433Context requests : listword → mem → libc_world → Z → Z → Prop
433Context Hsetlocale : registryTAtom"setlocale" = Somelibc_setlocale_contractrep requests
433Context 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
433Context 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
433Context 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.

451Lemma 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.

490Context 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.

500Context atexit_spec : contractlibc_world
500Context Hatexit : registryTAtom"atexit" = Someatexit_spec
500Context Hatexit_ret : contract_returnsatexit_spec = RClassW
500Context Hatexit_abi : contract_abiatexit_spec CResultTAtom"v15" W ArgP TmpTAtom"v14"
500Context Hatexit_pre : ∀m w h, wim w h → contract_preatexit_spec WPtrclose_stdout_ptr m w
500Context 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.

513Lemma zero_pcell
∀ b
bytesb 0 replicate8 0 ∗ auxesb 0 CNone ⊣⊢ pcellb 0 mkPtr0 CNone
Proof 8 steps Qed
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.

523Ltac 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.

529Lemma 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.

543Definition 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 "".

547Definition 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.

555Definition 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.

561Lemma 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 bytes_take_drop_ _ _ 8 ; | rewrite length_replicate ; vm_compute ; lia in Hy6
iEval rewrite auxes_take_drop_ _ _ 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.

640Lemma 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 bytes_take_drop_ _ _ 8 ; | rewrite length_replicate ; lia in Hy4
iEval rewrite auxes_take_drop_ _ _ 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.

703Lemma 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_refined_contract for this run's input, fixed for the run: the safety contract libc_getopt_contract, whose admission, writes and prefixes it keeps, with a transition added to its ordinary returns. 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.

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

The number of argv's bytes and aux slots.

759Notation argv_len ≔ 8 × lengthsargs + 1%nat

getopt_long has libc's refined contract for this run's input, over the native parser's initialized and running representations, its allocation requests and the transition an ordinary return makes.

764Context initialized running : mem → libc_world → Prop
764Context grequests : listword → mem → libc_world → Z → Z → Prop
764Context transition : listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → Prop

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.

776Context optarg_cell optind_cell : ptr

wi keeps Hello's option literals in memory.

782Context 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.

799Context 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 from a memory that agrees with the ghost heap, with its live objects apart and the runtime ready, keeps wi, with argv's block holding what the memory then holds and the token naming the new optarg and optind.

808Context 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 → agreesm h → live_disjointm → R.readys m → 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.

816Lemma 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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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.

824Lemma 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.

867Lemma 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.

915Lemma 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 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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
m :
trace :
listevent
values :
listword
s′ :
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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
m :
trace :
listevent
values :
listword
s′ :
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′

apply GR.refined_invoke_base 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
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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
m :
trace :
listevent
values :
listword
s′ :
m′ :
H :
GR.E.invokegetopt_contracthello_inputav sargs libc_getopt_view libc_getopt_repinitialized libc_getopt_inflightrunning libc_getopt_stable grequests 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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
m :
trace :
listevent
values :
listword
s′ :
m′ :
H :
GR.E.invokegetopt_contracthello_inputav sargs libc_getopt_view libc_getopt_repinitialized libc_getopt_inflightrunning libc_getopt_stable grequests r args xs s m w trace CallReturnvalues s′ m′ w′
born :
listZ
Hp :
GR.E.prefixgetopt_contracthello_inputav sargs libc_getopt_view libc_getopt_repinitialized libc_getopt_inflightrunning libc_getopt_stable grequests xs s m w born trace s′ m′ w′
Hpost :
H0 :
∀why : reason, CallReturnvalues ≠ CallResourcewhy
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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
m :
trace :
listevent
values :
listword
s′ :
m′ :
H :
GR.E.invokegetopt_contracthello_inputav sargs libc_getopt_view libc_getopt_repinitialized libc_getopt_inflightrunning libc_getopt_stable grequests r args xs s m w trace CallReturnvalues s′ m′ w′
born :
listZ
Hp :
GR.E.prefixgetopt_contracthello_inputav sargs libc_getopt_view libc_getopt_repinitialized libc_getopt_inflightrunning libc_getopt_stable grequests xs s m w born trace s′ m′ w′
Hpost :
H0 :
∀why : reason, CallReturnvalues ≠ CallResourcewhy
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

What a return of getopt_long with values from the token a, i shows of the transition: a call from a memory and world where wi holds with the token's pieces made that transition.

927Definition getopt_stepa : ptr i : Z values : listword : Prop ≔
∃xs m w h born trace m′ w′, wim w h ∧ ∀l v, l, v ∈ getopt_psa i → h !! l = Somev ∧ transitionxs m w born trace values m′ w′

A return of getopt_long, from a memory and world where wi holds with the token's pieces, makes the transition: refined_return.

934Lemma getopt_stepped
∀ r args xs s m w h trace values s′ m′ w′ a i
M.E.invokegetopt_spec r args xs s m w trace CallReturnvalues s′ m′ w′
wim w h
∀l v, l, v ∈ getopt_psa i → h !! l = Somev
getopt_stepa i values
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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
m :
h :
trace :
listevent
values :
listword
s′ :
m′ :
a :
i :
Z
⊢
M.E.invokegetopt_spec r args xs s m w trace CallReturnvalues s′ m′ w′ → wim w h → ∀l : piece v : pval, l, v ∈ getopt_psa i → h !! l = Somev → getopt_stepa i values

intros Hi Hw Kt

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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
m :
h :
trace :
listevent
values :
listword
s′ :
m′ :
a :
i :
Z
Hi :
M.E.invokegetopt_spec r args xs s m w trace CallReturnvalues s′ m′ w′
Hw :
wim w h
Kt :
∀l : piece v : pval, l, v ∈ getopt_psa i → h !! l = Somev
⊢
getopt_stepa i values

destruct GR.refined_return_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Hi as born & Ht

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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
m :
h :
trace :
listevent
values :
listword
s′ :
m′ :
a :
i :
Z
Hi :
M.E.invokegetopt_spec r args xs s m w trace CallReturnvalues s′ m′ w′
Hw :
wim w h
Kt :
∀l : piece v : pval, l, v ∈ getopt_psa i → h !! l = Somev
born :
listZ
Ht :
transitionxs m w born trace values m′ w′
⊢
getopt_stepa i values

exists xs, m, w, h, born, trace, m′, w′

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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
m :
h :
trace :
listevent
values :
listword
s′ :
m′ :
a :
i :
Z
Hi :
M.E.invokegetopt_spec r args xs s m w trace CallReturnvalues s′ m′ w′
Hw :
wim w h
Kt :
∀l : piece v : pval, l, v ∈ getopt_psa i → h !! l = Somev
born :
listZ
Ht :
transitionxs m w born trace values m′ w′
⊢
wim w h ∧ ∀l : piece v : pval, l, v ∈ getopt_psa i → h !! l = Somev ∧ transitionxs m w born trace values m′ w′

auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hi Hw Kt
destruct GR.refined_return_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Hi as born & Ht
exists xs, m, w, h, born, trace, m′, w′
auto

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.

948Lemma 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
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, and the code is a getopt_step from the token.

1004Lemma 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 ∧ getopt_stepa i WIntcode mod 2 ^ 32⌝ −∗ 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 80 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
iDestruct pts_lookup with Hh Ht as %Kt
destruct getopt_returned_ _ _ _ _ _ _ _ _ _ _ Hinv as born & _ & Hin′ & _ & _ & code & Hend & Hres
injection Hend as →
pose proof getopt_stepped_ _ _ _ _ _ _ _ _ _ _ _ a i Hinv Hw Kt as Hstep
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 Ha Hd Hr 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 |
split ; exact Hg | exact Hstep

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.

1087Context Hoptarg_g : lookupTAtom"optarg" ge_globalsge = Someoptarg_cell
1087Context 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.

1092Definition 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.

1098Definition 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.

1104Definition 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.

1112Definition 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.

1119Definition 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.

1127Lemma 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.

1251Lemma 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 first entry: main_start, with argv's first slot and string out of argv's block and the arguments, then put back. The continuation is given the loop's pieces and facts, and everything the start block leaves outside the loop.

1272Lemma main_to_L8
∀ 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⌝ −∗ ⌜loop_factse b4 b6 maparg_ptr sargs cs0 ix greeting_ptr⌝ −∗ loop_resb4 maparg_ptr sargs cs0 a ix greeting_ptr −∗ 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 −∗ WPERunmkFramemain_fn e [ ] None EnterTAtom"iw_1.L8" SomeTAtom"start" : mexpr {Φ} −∗ WPERuninvocationmain_fn WIntZ.of_natlengthsargs; WPtrmkPtrav Objav : mexpr {Φ}
Proof 47 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 HK $! e b4 b6 i k q new c′ with [%] [%] [Hb Hs Ht Hl4 Hp4] Hlit Hcells Hlent Hcod Hs80 Hy4 Hc4 Hl6 Hy6 Hy6′ Hc6 Hc6′
–auto 10
–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

Main from its entry to the option loop's exits: main_to_L8, then main_loop from start. The continuation is given everything the start block leaves outside the loop, and builds the exits.

1336Lemma 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 9 steps Qed
intros Hhd Hcs Hix
iIntros Hb Hs Ht Hlit Hcells Hks Hcod Hs80 HK
iApply main_to_L8 with Hb Hs Ht Hlit Hcells Hks Hcod Hs80 ; exact Hhd | exact Hcs | exact Hix |
iNext
iIntros e b4 b6 i k q new c′ Hst Hf Hres Hlit Hcells Hlent Hcod Hs80 Hy4 Hc4 Hl6 Hy6 Hy6′ Hc6 Hc6′
iApply main_loopb4 b6 Φ $! "start"%string e 0 maparg_ptr sargs cs0 a ix greeting_ptr with [%] Hres [-]
–split ; left ; split ; reflexivity | exact Hf
–iApply HK $! e b4 b6 i k q new c′ with [%] Hlit Hcells Hlent Hcod Hs80 Hy4 Hc4 Hl6 Hy6 Hy6′ Hc6 Hc6′
exact Hst

The operand check

After the options, main checks that no operand is left: unless pr.2 is set, it compares optind with argc (iw_1.L59), and if an operand remains or pr.2 is set, it loads argvoptind (iw_1.L55). A nonnull one is an extra operand (iw_1.L79); a null one, with pr.2 set, leads to the hint to try --help (iw_1.L113). Otherwise main goes on to greet (iw_1.join). optind is the token's, at most argc, so the load is of one of argv's argc + 1 slots.

libc's optind cell is the global optind.

1385Context Hoptind_g : lookupTAtom"optind" ge_globalsge = Someoptind_cell

A pointer cell is its bytes and its first aux slot.

1388Lemma pcell_split
∀ b o q
pcellb o q ⊣⊢ bytesb o slot_bytesptr_addrq ∗ auxesb o ptr_capq
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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
Hoptarg_g :
lookupTAtom"optarg" ge_globalsge = Someoptarg_cell
Hcells :
0 ≤ ptr_addroptarg_cell < 2 ^ 64 ∧ 0 ≤ ptr_addroptind_cell < 2 ^ 64
Hoptind_g :
lookupTAtom"optind" ge_globalsge = Someoptind_cell
b, o :
Z
q :
⊢
pcellb o q ⊣⊢ bytesb o slot_bytesptr_addrq ∗ auxesb o ptr_capq

rewrite / pcell / bytes / auxes slot_cell

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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
Hoptarg_g :
lookupTAtom"optarg" ge_globalsge = Someoptarg_cell
Hcells :
0 ≤ ptr_addroptarg_cell < 2 ^ 64 ∧ 0 ≤ ptr_addroptind_cell < 2 ^ 64
Hoptind_g :
lookupTAtom"optind" ge_globalsge = Someoptind_cell
b, o :
Z
q :
⊢
ptsPAuxb o, VAuxptr_capq :: cellb o ptr_addrq ⊣⊢ ptscellb o ptr_addrq ∗ ptsaux_psb o ptr_capq

change PAuxb o, VAuxptr_capq :: cellb o ptr_addrq with PAuxb o, VAuxptr_capq ++ cellb o ptr_addrq

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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
Hoptarg_g :
lookupTAtom"optarg" ge_globalsge = Someoptarg_cell
Hcells :
0 ≤ ptr_addroptarg_cell < 2 ^ 64 ∧ 0 ≤ ptr_addroptind_cell < 2 ^ 64
Hoptind_g :
lookupTAtom"optind" ge_globalsge = Someoptind_cell
b, o :
Z
q :
⊢
ptsPAuxb o, VAuxptr_capq ++ cellb o ptr_addrq ⊣⊢ ptscellb o ptr_addrq ∗ ptsaux_psb o ptr_capq

rewrite 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
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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
Hoptarg_g :
lookupTAtom"optarg" ge_globalsge = Someoptarg_cell
Hcells :
0 ≤ ptr_addroptarg_cell < 2 ^ 64 ∧ 0 ≤ ptr_addroptind_cell < 2 ^ 64
Hoptind_g :
lookupTAtom"optind" ge_globalsge = Someoptind_cell
b, o :
Z
q :
⊢

change aux_psb o ptr_capq with [ PAuxb o, VAuxptr_capq ]

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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
Hoptarg_g :
lookupTAtom"optarg" ge_globalsge = Someoptarg_cell
Hcells :
0 ≤ ptr_addroptarg_cell < 2 ^ 64 ∧ 0 ≤ ptr_addroptind_cell < 2 ^ 64
Hoptind_g :
lookupTAtom"optind" ge_globalsge = Someoptind_cell
b, o :
Z
q :
⊢

iSplit ; iIntros [A B] ; iFrame

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
rewrite / pcell / bytes / auxes slot_cell
change PAuxb o, VAuxptr_capq :: cellb o ptr_addrq with PAuxb o, VAuxptr_capq ++ cellb o ptr_addrq
rewrite pts_app
change aux_psb o ptr_capq with [ PAuxb o, VAuxptr_capq ]
iSplit ; iIntros [A B] ; iFrame

argv's block holding ps: its life, the slots before slot k, slot k's pointer cell, and the slots after it.

1399Lemma argv_block_slot
∀ b reg ps cs k q
ps ++ null !! k = Someq
ptsblock_psb reg 0 argv_bytesps cs ⊣⊢ liveb reg ∗ bytesb 0 slots_bytestakek ps ++ null ∗ auxesb 0 take8 × k cs ∗ pcellb 8 × Z.of_natk q ∗ bytesb 8 × Z.of_natk + 8 slots_bytesdropSk ps ++ null ∗ auxesb 8 × Z.of_natk + 1 dropS8 × k cs
Proof 33 steps Qed
intros Lc Hc Hq
pose proof lookup_lt_Some_ _ _ Hq as Hk
pose proof Hck q Hq as Hcq
assert Ex : argv_bytesps = slots_bytestakek ps ++ null ++ slot_bytesptr_addrq ++ slots_bytesdropSk ps ++ null
{unfold argv_bytes
transitivity slots_bytestakek ps ++ null ++ q :: dropSk ps ++ null
–rewrite take_drop_middle_ _ _ Hq
reflexivity
–unfold slots_bytes
rewrite flat_map_app
reflexivity
assert Ec : take8 × k cs ++ ptr_capq :: dropS8 × k cs = cs by exact take_drop_middle_ _ _ Hcq
assert Lt : lengthslots_bytestakek ps ++ null = 8 × k%nat
{rewrite length_slots_bytes length_take
lia
assert Lt′ : lengthtake8 × k cs = 8 × k%nat
{rewrite length_take Lc
lia
assert A : auxesb 0 cs ⊣⊢ auxesb 0 take8 × k cs ∗ auxesb 8 × Z.of_natk ptr_capq ∗ auxesb 8 × Z.of_natk + 1 dropS8 × k cs
{transitivity auxesb 0 take8 × k cs ++ ptr_capq :: dropS8 × k cs ; rewrite Ec ; reflexivity |
rewrite auxes_app Lt'
change ptr_capq :: dropS8 × k cs with ptr_capq ++ dropS8 × k cs
rewrite auxes_app
cbn [ length ]
replace 0 + Z.of_nat8 × k with 8 × Z.of_natk by lia
change Z.of_nat1 with 1
reflexivity
rewrite block_pts Ex ! bytes_app Lt
change lengthslot_bytesptr_addrq with 8%nat
replace 0 + Z.of_nat8 × k with 8 × Z.of_natk by lia
change Z.of_nat8 with 8
rewrite A pcell_split
iSplit ; iIntros (Hl & (Hy0 & Hy1 & Hy2) & (Hx0 & Hx1 & Hx2)) | iIntros (Hl & Hy0 & Hx0 & (Hy1 & Hx1) & Hy2 & Hx2) ; iFrame

An exit of the operand check: entering the block lab from the block from, with the loop's facts and pieces and pr.2 bound to lose, where P lose i holds of pr.2 and optind.

1435Definition operand_exitb4 b6 : Z lab from : String.string P : Z → Z → Prop Φ : 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 ∧ Plose i⌝ −∗ loop_resb4 ps cs a i g −∗ WPERunmkFramemain_fn e [ ] None EnterTAtomlab SomeTAtomfrom : mexpr {Φ}

iw_1.L55: argvoptind, at most argc, is loaded; a nonnull one goes to iw_1.L79 with optind below argc, a null one to iw_1.L113, which only pr.2 set reaches, as without it optind is below argc.

1445Lemma operand_L55
∀ b4 b6 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 ∧ lose = 0 → i < Z.of_natlengthsargs⌝ −∗ loop_resb4 ps cs a i g −∗ operand_exitb4 b6 "iw_1.L79"%string "iw_1.L55"%string λ_ i ⇒ i < Z.of_natlengthsargs Φ ∧ operand_exitb4 b6 "iw_1.L113"%string "iw_1.L55"%string λlose i ⇒ lose = 1 ∧ i = Z.of_natlengthsargs Φ −∗ WPERunmkFramemain_fn e [ ] None EnterTAtom"iw_1.L55" SomeTAtom"iw_1.L60" : mexpr {Φ}
Proof 101 steps Qed
iIntros Hf & Hpr & Hlose & Hlt (Hb & Hs & Ht & Hl4 & Hp4) HK
pose proof Hf as H0 & H2 & H4 & H6 & H11 & Hc1 & Hfr & Ho & Hc & Hi & Hg
pose proof Hav as Hav0 & Hav8 & Haend & Har48
pose proof Hargc as Hargc′
pose proof order_lengthps Ho as Lp
destruct lookup_lt_is_Some_2ps ++ null Z.to_nati as q Hq
{rewrite length_app Lp
cbn [ length ]
lia
pose proof slot_kindssargs ps Z.to_nati q Ho Hq as Hkind
assert Hqf : 0 ≤ ptr_addrq < 2 ^ 64 ∧ ∀xb, ptr_capq = Objxb ∨ ptr_capq = Roxb → ∃xr, PLivexb, VLivexr ∈ flat_maparg_ps sargs
{destruct Hkind as _ → | _ s & Hs & →
–split ; cbn ; lia |
intros xb E | E ; discriminate E
–pose proof proj1List.Forall_forall_ _ Hargs s Hs as Hcap & Hb0 & Hbp & Hend & H48 & _
split ; lia |
intros xb Hxb
exists arg_regions
assert xb = arg_bases as →
{destruct Hcap as E1 | E1 ; rewrite E1 in Hxb ; destruct Hxb as E2 | E2 ; congruence
apply list_elem_of_In , in_flat_map
exists s
split ; exact Hs |
unfold arg_ps , string_ps
left
reflexivity
destruct Hqf as Hqr Hlife
mn_enter "iw_1.L55"

optind, sign-extended, times 8, past argv.

iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite Hoptind_g ; reflexivity | intros ?m ; word_premise |
iNext
iNext
iNext
iIntros Ht
iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
iNext

argvoptind.

iEval rewriteargv_block_slotav ar ps cs Z.to_nati q Hc Hq in Hb
iDestruct Hb as (Hal & Hy0 & Hx0 & Hq & Hy1 & Hx1)
iApply wp_check_read with Hal ; reflexivity | word_premise | left ; reflexivity | addr_premise | addr_premise | addr_premise |
iNext
iIntros Hal
iApply wp_raw_load_pointer_in with Hal Hq Hs ; reflexivity | word_premise | left ; reflexivity | addr_premise | addr_premise | exact Hqr | exact Hlife |
iNext
iIntros Hal Hq Hs
iAssert ptsblock_psav ar 0 argv_bytesps cs with [Hal Hy0 Hx0 Hq Hy1 Hx1] as Hb
{rewrite argv_block_slotav ar ps cs Z.to_nati q Hc Hq
iFrame
destruct Hkind as Ek → | Ek s & Hs & →

Null: optind is argc, which only pr.2 set lets through.

–assert Ei : i = Z.of_natlengthsargs by lia
assert Hl1 : lose = 1
{destruct Hlose as El | El ; | exact El
specialize HltEl
lia
iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
iApply wp_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 | split ; exact Hl1 | exact Ei
split ; repeat split ; assumption |
split ; assumption |
split ; exact Hfr |
auto

An argument: an extra operand.

–pose proof proj1List.Forall_forall_ _ Hargs s Hs as _ & Hb0 & Hbp & _
assert Ei : i < Z.of_natlengthsargs by lia
iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
iApply wp_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 Ei
split ; repeat split ; assumption |
split ; assumption |
split ; exact Hfr |
auto

The operand check, from iw_1.L10, entered at the end of options, to its three exits.

1521Lemma main_operands
∀ b4 b6 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 −∗ operand_exitb4 b6 "iw_1.L79"%string "iw_1.L55"%string λ_ i ⇒ i < Z.of_natlengthsargs Φ ∧ operand_exitb4 b6 "iw_1.L113"%string "iw_1.L55"%string λlose i ⇒ lose = 1 ∧ i = Z.of_natlengthsargs Φ ∧ operand_exitb4 b6 "iw_1.join"%string "iw_1.L60"%string λlose i ⇒ lose = 0 ∧ i = Z.of_natlengthsargs Φ −∗ WPERunmkFramemain_fn e [ ] None EnterTAtom"iw_1.L10" SomeTAtom"iw_1.L8" : mexpr {Φ}
Proof 69 steps Qed
iIntros Hf & Hpr & Hlose Hr HK
pose proof Hf as H0 & H2 & H4 & H6 & H11 & Hc1 & Hfr & Ho & Hc & Hi & Hg
pose proof Hargc as Hargc′
mn_enter "iw_1.L10"
iApply wp_branch_ _ _ _ _ _ _ _ _ _ lose ; word_premise |
iNext
destruct Hlose as El | El ; subst lose ; cbn [ Z.eqb edge_label ]

pr.2 clear: is optind below argc?

–mn_enter "iw_1.L59"
unfold loop_res
iDestruct Hr as (Hb & Hs & Ht & Hl4 & Hp4)
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite Hoptind_g ; reflexivity | intros ?m ; word_premise |
iNext
iNext
iNext
iIntros Ht
destruct Z.lt_ge_casesi Z.of_natlengthsargs as Hlt | Hge
+iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
iApply wp_goto
iNext
cbn [ edge_label ]
mn_enter "iw_1.L60"
iApply wp_branch_ _ _ _ _ _ _ _ _ _ 1 ; word_premise |
iNext
cbn [ Z.eqb edge_label ]
iApply operand_L55b4 b6 _ ps cs a i g 0 with [%] [$Hb $Hs $Ht $Hl4 $Hp4] [HK]
∗split ; | split ; assumption | split ; left ; reflexivity | intros _ ; exact Hlt
split ; repeat split ; assumption |
split ; assumption |
split ; exact Hfr |
auto
∗iSplit ; iDestruct HK as [H _] | iDestruct HK as [_ [H _]] ; iExact H
+iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
iApply wp_goto
iNext
cbn [ edge_label ]
mn_enter "iw_1.L60"
iApply wp_branch_ _ _ _ _ _ _ _ _ _ 0 ; word_premise |
iNext
cbn [ Z.eqb edge_label ]
iDestruct HK as [_ [_ HK]]
iApply HK $! _ ps cs a i g 0 with [%] [$Hb $Hs $Ht $Hl4 $Hp4]
split ; | split ; assumption | split ; reflexivity | lia
split ; repeat split ; assumption |
split ; assumption |
split ; exact Hfr |
auto

pr.2 set: straight to argvoptind.

–mn_enter "iw_1.L60"
iApply wp_branch_ _ _ _ _ _ _ _ _ _ 1 ; word_premise |
iNext
cbn [ Z.eqb edge_label ]
iApply operand_L55b4 b6 _ ps cs a i g 1 with [%] Hr [HK]
+split ; | split ; assumption | split ; right ; reflexivity | intros E ; discriminate E
split ; repeat split ; assumption |
split ; assumption |
split ; exact Hfr |
auto
+iSplit ; iDestruct HK as [H _] | iDestruct HK as [_ [H _]] ; iExact H

The operand check is the loop's end-of-options exit.

1572Lemma operands_exit
∀ b4 b6 Φ
operand_exitb4 b6 "iw_1.L79"%string "iw_1.L55"%string λ_ i ⇒ i < Z.of_natlengthsargs Φ ∧ operand_exitb4 b6 "iw_1.L113"%string "iw_1.L55"%string λlose i ⇒ lose = 1 ∧ i = Z.of_natlengthsargs Φ ∧ operand_exitb4 b6 "iw_1.join"%string "iw_1.L60"%string λlose i ⇒ lose = 0 ∧ i = Z.of_natlengthsargs Φ −∗ loop_exitb4 b6 "iw_1.L10"%string "iw_1.L8"%string Φ
Proof 5 steps Qed
iIntros HK
rewrite / loop_exit
iIntros e ps cs a i g lose Hf Hr
iApply main_operands with [%] Hr HK
exact Hf

exit has a contract that admits any canonical status and never returns to main. The handlers it runs, close_stdout among them, are the ending's, not main's: in this language the call stalls.

1587Context exit_spec : contractlibc_world
1587Context Hexit : registryTAtom"exit" = Someexit_spec
1587Context Hexit_abi : ∀v, contract_abiexit_spec CVoid ArgW v
1587Context Hexit_pre : ∀n m w h, 0 ≤ n < 2 ^ 32 → wim w h → contract_preexit_spec WIntn m w
1587Context Hexit_post : ∀args n s m w tr vs s′ m′ w′, M.E.invokeexit_spec CVoid args WIntn s m w tr CallReturnvs s′ m′ w′ → False

exit(n), for a canonical n, is safe under every postcondition.

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

libc's stdout: the world keeps its cell readable and holding the stream, as HelloVersion's footer assumes.

1616Context stdout_cell stream : ptr
1616Context Hstdout_g : lookupTAtom"stdout" ge_globalsge = Somestdout_cell

version_etc's premises, as HelloVersion's version_etc_spec takes them: the literal pieces main owns, the authors' lives among them, the six output contracts and the frame of its allocations, stores and snapshot.

1627Context version_ps : listpiece × pval
1627Context author_reg : String.string → region
1627Context Hauthor_live : ∀s, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ version_ps
1627Context version_spec : name → contractlibc_world
1627Context Hversion_reg : ∀g xs, Ing, xs version_output_argsstream → registryg = Someversion_specg
1627Context Hversion_ret : ∀g xs, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
1627Context Hversion_abi : ∀g xs d args, Ing, xs version_output_argsstream → mapλa ⇒ match a with Argk _ ⇒ k end args = version_output_classesxs → contract_abiversion_specg CResultd W args
1627Context Hversion_pre : ∀g xs m w h, Ing, xs version_output_argsstream → ∀l v, l, v ∈ version_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
1627Context Hversion_frame : ∀g xs r args s m w h trace values s′ m′ w′, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n, values = WIntn ∧ 0 ≤ n < 2 ^ 32
1627Context Kversion_alloc : ∀size m wd h base, Insize 24; 80 → freshm heap_req8 size base → wim wd h → wiallocatedm heap_req8 size base wd overwriteobj_psbase heap_req8 size h
1627Context Kversion_store : ∀b reg o x xp m wd h, ∀k v, k, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! k = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
1627Context Kversion_cursor : ∀cb cr sb off m wd h, ∀k v, k, v ∈ va_cursor_pscb cr mkPtrsb + off Rosb → h !! k = Somev → wim wd h → wistore_bytesm cb 8 sb + off + 8 wd overwriteva_cursor_pscb cr mkPtrsb + off + 8 Rosb h
1627Context Kversion_snapshot : ∀m wd h sb, freshm heap_req16 72 sb → wim wd h → wisnapshot_valuesHV.version_main_argsstream sb allocatedm heap_req16 72 sb wd overwritesnapshot_psHV.version_main_argsstream sb heap_req16 72 h

The version block's literals are linked where HelloVersion reads them.

1668Lemma main_version_lookup
∀ s
Ins "hello#str.70"; "hello#str.63"; "hello#str.71"; "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75"
Explore proof 3 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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
Hoptarg_g :
lookupTAtom"optarg" ge_globalsge = Someoptarg_cell
Hcells :
0 ≤ ptr_addroptarg_cell < 2 ^ 64 ∧ 0 ≤ ptr_addroptind_cell < 2 ^ 64
Hoptind_g :
lookupTAtom"optind" ge_globalsge = Someoptind_cell
Hexit :
registryTAtom"exit" = Someexit_spec
Hexit_abi :
∀v : value, contract_abiexit_spec CVoid ArgW v
Hexit_pre :
∀n : Z m : mem w : libc_world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → wim w h → contract_preexit_spec WIntn m w
Hexit_post :
∀args : listarg n : Z s : R.state m : mem w : libc_world tr : listevent vs : listword s′ : R.state m′ : mem w′ : libc_world, M.E.invokeexit_spec CVoid args WIntn s m w tr CallReturnvs s′ m′ w′ → False
stdout_cell, stream :
Hstdout_g :
lookupTAtom"stdout" ge_globalsge = Somestdout_cell
wi_stdout :
∀m : mem w : libc_world h : gmappiece pval, wim w h → access_resm raw_addressptr_addrstdout_cell 0 ptr_capstdout_cell 8 Read 8 = Someok ∧ pointer_load_effectsm raw_addressptr_addrstdout_cell 0 AuxRead; LowerResolve; AddressRead = Somestream
version_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ version_ps
version_spec :
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : libc_world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ version_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Kversion_alloc :
∀size : Z m : mem wd : libc_world h : gmappiece pval base : Z, Insize 24; 80 → freshm heap_req8 size base → wim wd h → wiallocatedm heap_req8 size base wd overwriteobj_psbase heap_req8 size h
Kversion_store :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! k = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
Kversion_cursor :
∀cb : Z cr : region sb off : Z m : mem wd : libc_world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ va_cursor_pscb cr ptr_addr ≔ sb + off; ptr_cap ≔ Rosb → h !! k = Somev → wim wd h → wistore_bytesm cb 8 sb + off + 8 wd overwriteva_cursor_pscb cr ptr_addr ≔ sb + off + 8; ptr_cap ≔ Rosb h
Kversion_snapshot :
∀m : mem wd : libc_world h : gmappiece pval sb : Z, freshm heap_req16 72 sb → wim wd h → wisnapshot_valuesHV.version_main_argsstream sb allocatedm heap_req16 72 sb wd overwritesnapshot_psHV.version_main_argsstream sb heap_req16 72 h
⊢
Ins "hello#str.70"; "hello#str.63"; "hello#str.71"; "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → lookupTAtoms ge_globalsge = Someversion_literals

intros Hin

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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
Hoptarg_g :
lookupTAtom"optarg" ge_globalsge = Someoptarg_cell
Hcells :
0 ≤ ptr_addroptarg_cell < 2 ^ 64 ∧ 0 ≤ ptr_addroptind_cell < 2 ^ 64
Hoptind_g :
lookupTAtom"optind" ge_globalsge = Someoptind_cell
Hexit :
registryTAtom"exit" = Someexit_spec
Hexit_abi :
∀v : value, contract_abiexit_spec CVoid ArgW v
Hexit_pre :
∀n : Z m : mem w : libc_world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → wim w h → contract_preexit_spec WIntn m w
Hexit_post :
∀args : listarg n : Z s : R.state m : mem w : libc_world tr : listevent vs : listword s′ : R.state m′ : mem w′ : libc_world, M.E.invokeexit_spec CVoid args WIntn s m w tr CallReturnvs s′ m′ w′ → False
stdout_cell, stream :
Hstdout_g :
lookupTAtom"stdout" ge_globalsge = Somestdout_cell
wi_stdout :
∀m : mem w : libc_world h : gmappiece pval, wim w h → access_resm raw_addressptr_addrstdout_cell 0 ptr_capstdout_cell 8 Read 8 = Someok ∧ pointer_load_effectsm raw_addressptr_addrstdout_cell 0 AuxRead; LowerResolve; AddressRead = Somestream
version_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ version_ps
version_spec :
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : libc_world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ version_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Kversion_alloc :
∀size : Z m : mem wd : libc_world h : gmappiece pval base : Z, Insize 24; 80 → freshm heap_req8 size base → wim wd h → wiallocatedm heap_req8 size base wd overwriteobj_psbase heap_req8 size h
Kversion_store :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! k = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
Kversion_cursor :
∀cb : Z cr : region sb off : Z m : mem wd : libc_world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ va_cursor_pscb cr ptr_addr ≔ sb + off; ptr_cap ≔ Rosb → h !! k = Somev → wim wd h → wistore_bytesm cb 8 sb + off + 8 wd overwriteva_cursor_pscb cr ptr_addr ≔ sb + off + 8; ptr_cap ≔ Rosb h
Kversion_snapshot :
∀m : mem wd : libc_world h : gmappiece pval sb : Z, freshm heap_req16 72 sb → wim wd h → wisnapshot_valuesHV.version_main_argsstream sb allocatedm heap_req16 72 sb wd overwritesnapshot_psHV.version_main_argsstream sb heap_req16 72 h
Hin :
Ins "hello#str.70"; "hello#str.63"; "hello#str.71"; "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75"

apply proj1proj2Hlinked

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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
Hoptarg_g :
lookupTAtom"optarg" ge_globalsge = Someoptarg_cell
Hcells :
0 ≤ ptr_addroptarg_cell < 2 ^ 64 ∧ 0 ≤ ptr_addroptind_cell < 2 ^ 64
Hoptind_g :
lookupTAtom"optind" ge_globalsge = Someoptind_cell
Hexit :
registryTAtom"exit" = Someexit_spec
Hexit_abi :
∀v : value, contract_abiexit_spec CVoid ArgW v
Hexit_pre :
∀n : Z m : mem w : libc_world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → wim w h → contract_preexit_spec WIntn m w
Hexit_post :
∀args : listarg n : Z s : R.state m : mem w : libc_world tr : listevent vs : listword s′ : R.state m′ : mem w′ : libc_world, M.E.invokeexit_spec CVoid args WIntn s m w tr CallReturnvs s′ m′ w′ → False
stdout_cell, stream :
Hstdout_g :
lookupTAtom"stdout" ge_globalsge = Somestdout_cell
wi_stdout :
∀m : mem w : libc_world h : gmappiece pval, wim w h → access_resm raw_addressptr_addrstdout_cell 0 ptr_capstdout_cell 8 Read 8 = Someok ∧ pointer_load_effectsm raw_addressptr_addrstdout_cell 0 AuxRead; LowerResolve; AddressRead = Somestream
version_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ version_ps
version_spec :
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : libc_world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ version_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Kversion_alloc :
∀size : Z m : mem wd : libc_world h : gmappiece pval base : Z, Insize 24; 80 → freshm heap_req8 size base → wim wd h → wiallocatedm heap_req8 size base wd overwriteobj_psbase heap_req8 size h
Kversion_store :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! k = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
Kversion_cursor :
∀cb : Z cr : region sb off : Z m : mem wd : libc_world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ va_cursor_pscb cr ptr_addr ≔ sb + off; ptr_cap ≔ Rosb → h !! k = Somev → wim wd h → wistore_bytesm cb 8 sb + off + 8 wd overwriteva_cursor_pscb cr ptr_addr ≔ sb + off + 8; ptr_cap ≔ Rosb h
Kversion_snapshot :
∀m : mem wd : libc_world h : gmappiece pval sb : Z, freshm heap_req16 72 sb → wim wd h → wisnapshot_valuesHV.version_main_argsstream sb allocatedm heap_req16 72 sb wd overwritesnapshot_psHV.version_main_argsstream sb heap_req16 72 h
Hin :
Ins "hello#str.70"; "hello#str.63"; "hello#str.71"; "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75"

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

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

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

proper_name(p), from main: the helper is the identity, so d is bound to p and nothing main owns changes.

1679Lemma wp_main_proper_name
∀ e ls lab d v rest j p Φ
arg_xge e ArgP v = SomeWPtrp
▷WPERunmkFramemain_fn putd WPtrp e ls None Execlab rest j : mexpr {Φ} −∗ WPERunmkFramemain_fn e ls None Execlab CallCResultd P GlobalTAtom"proper_name" ArgP v :: rest j : mexpr {Φ}
Proof 13 steps Qed
intros Hv
iIntros HK
iApply wp_call_bind_ _ _ _ _ _ _ _ _ _ _ _ _ proper_name_fn invocationproper_name_fn WPtrp
1: cbn [ map_option ] ; rewrite Hv ; reflexivity
1: unfold find_fn ; rewrite proj1Hlinked ; vm_compute ; reflexivity
1: reflexivity
iNext
iApply HV.proper_name_specregistry wi ge
iNext
iExists _
iSplit ; iPureIntro ; reflexivity |
iNext
iExact HK

--version, iw_1.L21: main loads stdout, names the four authors, calls version_etc and exits with 0. Only the version literals are needed; the loop's pieces are left behind, since exit does not return.

1698Lemma main_version
∀ b4 b6 Φ
ptsversion_ps −∗ loop_exitb4 b6 "iw_1.L21"%string "iw_1.L19"%string Φ
Proof 70 steps Qed
pose proof main_version_lookup"hello#str.70" ltac:simpl ; tauto as H70
pose proof main_version_lookup"hello#str.63" ltac:simpl ; tauto as H63
pose proof main_version_lookup"hello#str.71" ltac:simpl ; tauto as H71
pose proof main_version_lookup"hello#str.72" ltac:simpl ; tauto as H72
pose proof main_version_lookup"hello#str.73" ltac:simpl ; tauto as H73
pose proof main_version_lookup"hello#str.74" ltac:simpl ; tauto as H74
pose proof main_version_lookup"hello#str.75" ltac:simpl ; tauto as H75
iIntros Hps
rewrite / loop_exit
iIntros e ps cs a i g lose _ _
mn_enter "iw_1.L21"

stdout's stream.

iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite Hstdout_g ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_world_let_withregistry wi ge [ ] ; reflexivity | reflexivity | word_premise | | rewrite / pts /= ; done |
{intros m w h Hw _
apply op_check
exact proj1wi_stdout_ _ _ Hw
iNext
iIntros _
iApply wp_world_let_withregistry wi ge [ ] ; reflexivity | reflexivity | word_premise | | rewrite / pts /= ; done |
{intros m w h Hw _
apply op_raw_load_pointer ; apply wi_stdout_ _ _ Hw
iNext
iIntros _

The heading's literals and the four authors.

iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite H70 ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite H63 ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite H71 ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite H72 ; reflexivity | intros ?m ; word_premise |
iNext
iNext
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite H73 ; reflexivity | intros ?m ; word_premise |
iNext
iNext
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite H74 ; reflexivity | intros ?m ; word_premise |
iNext
iNext
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite H75 ; reflexivity | intros ?m ; word_premise |
iNext
iNext

version_etc, then exit(0).

iApply wp_call_bind_ _ _ _ _ _ _ _ _ _ _ _ _ HV.version_etc_fn invocationHV.version_etc_fn HV.version_main_argsstream ; word_premise | unfold find_fn ; rewrite proj1Hlinked ; vm_compute ; reflexivity | reflexivity |
iNext
iNext
iIntros _
iExists _
iSplit ; iPureIntro ; reflexivity |
iNext
iApply wp_main_exit_ _ _ _ _ _ _ 0 ; reflexivity | lia

--version from main's entry

Where getopt_long's first call can only return 129, main goes from its entry straight to --version: the loop's first round enters iw_1.L8, calls getopt_long, and with 129 branches by iw_1.L19 to iw_1.L21. No other exit of the loop is reached, so the greeting, --help and the diagnostics need none of their premises.

The option loop's first round, where every getopt_step from the token a, i returns 129: from its entry by any edge to the version exit.

1761Lemma loop_version
∀ b4 b6 from e lose ps cs a i g Φ
loop_entryfrom e lose
loop_factse b4 b6 ps cs i g
∀c, 0 ≤ c < 2 ^ 32 → getopt_stepa i WIntc → c = 129
loop_resb4 ps cs a i g −∗ loop_exitb4 b6 "iw_1.L21"%string "iw_1.L19"%string Φ −∗ WPERunmkFramemain_fn e [ ] None EnterTAtom"iw_1.L8" SomeTAtomfrom : mexpr {Φ}
Proof 48 steps Qed
intros Hent Hf Hlaw
iIntros (Hb & Hs & Ht & Hl4 & Hp4) HK
destruct Hf as H0 & H2 & H4 & H6 & H11 & Hc1 & Hfr & Ho & Hc & Hi & Hg
assert Hlose : lose = 0 ∨ lose = 1
{destruct Hent as _ → | _ → | _ _ Hl ; auto
destruct getopt_globals as G69 & G64 & _
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) returns 129.

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 & _ & Hstep Hb Hs Ht
pose proof Z.mod_pos_boundcode 2 ^ 32 ltac:lia as Hcr
pose proof Hlaw_ Hcr Hstep as E129
rewrite E129
iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
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
iApply wp_branch_ _ _ _ _ _ _ _ _ _ 1 ; word_premise |
iNext
cbn [ Z.eqb edge_label ]
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

Main from its entry to its exit by --version, where every getopt_step from the first token returns 129: main_to_L8, loop_version and main_version. Main owns what the start block and the version block need, and nothing for the other paths.

1802Lemma main_to_version
∀ s0 srest r3 r4 x0 x1 y0 old c0 r80 cs0 a ix Φ
sargs = s0 :: srest
0 ≤ ix ≤ Z.of_natlengthsargs
∀c, 0 ≤ c < 2 ^ 32 → getopt_stepa ix WIntc → c = 129
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 [ ] −∗ ptsversion_ps −∗ WPERuninvocationmain_fn WIntZ.of_natlengthsargs; WPtrmkPtrav Objav : mexpr {Φ}
Proof 11 steps Qed
intros Hhd Hcs Hix Hlaw
iIntros Hb Hs Ht Hlit Hcells Hks Hcod Hs80 Hv
iApply main_to_L8 with Hb Hs Ht Hlit Hcells Hks Hcod Hs80 ; exact Hhd | exact Hcs | exact Hix |
iNext
iIntros e b4 b6 i k q new c′ _ Hf Hres _ _ _ _ _ _ _ _ _ _ _ _
iApply loop_versionb4 b6 "start"%string e 0 with Hres [Hv]
–left
split ; reflexivity
–exact Hf
–exact Hlaw
–iApply main_version with Hv

setlocale's query of LC_MESSAGES, whose name is lent, is admitted, returns that name and changes nothing: LocaleLogic's locale_wi_pre and locale_wi_query, for libc's world.

1825Context Hquery_pre : ∀m w h p t, wim w h → h !! PName5 = SomeVNamep t → contract_prelibc_setlocale_contractrep requests WInt5; WPtrnull m w
1825Context Hquery : ∀r args s m w h p t trace ending s′ m′ w′, wim w h → h !! PName5 = SomeVNamep t → M.E.invokelibc_setlocale_contractrep requests r args WInt5; WPtrnull s m w trace ending s′ m′ w′ → s′ = s ∧ m′ = m ∧ w′ = w ∧ ending = CallReturnWPtrp

libc's stderr: the world keeps its cell readable and holding the stream, as for stdout.

1834Context stderr_cell errstream : ptr
1834Context Hstderr_g : lookupTAtom"stderr" ge_globalsge = Somestderr_cell

The output contracts of main's own calls and of the footer, as HelloVersion states the footer's: each is admitted with the literals' pieces (and, for a line naming the program, the arguments' strings, one of which holds its name), returns a canonical int and keeps the world interpretation, whether its output succeeded or not.

1847Context help_ps : listpiece × pval
1847Context output_spec : name → contractlibc_world
1847Context Hhelp_reg : ∀pname g xs, Ing, xs main_output_argsstream errstream pname → registryg = Someoutput_specg
1847Context Hhelp_ret : ∀pname g xs, Ing, xs main_output_argsstream errstream pname → contract_returnsoutput_specg = RClassW
1847Context Hhelp_abi : ∀pname g xs d args, Ing, xs main_output_argsstream errstream pname → mapλa ⇒ match a with Argk _ ⇒ k end args = replicatelengthxs P → contract_abioutput_specg CResultd W args
1847Context Hhelp_pre : ∀pname g xs m w h, name_oksargs pname → Ing, xs main_output_argsstream errstream pname → ∀l v, l, v ∈ help_ps ++ flat_maparg_ps sargs → h !! l = Somev → agreesm h → wim w h → contract_preoutput_specg xs m w
1847Context Hhelp_frame : ∀pname g xs r args s m w h trace values s′ m′ w′, Ing, xs main_output_argsstream errstream pname → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeoutput_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n, values = WIntn ∧ 0 ≤ n < 2 ^ 32
1847Context Houtput_reg : ∀g xs, Ing, xs emit_output_argsstream → registryg = Someoutput_specg
1847Context Houtput_ret : ∀g xs, Ing, xs emit_output_argsstream → contract_returnsoutput_specg = RClassW
1847Context Houtput_abi : ∀g xs d args, Ing, xs emit_output_argsstream → mapλa ⇒ match a with Argk _ ⇒ k end args = replicatelengthxs P → contract_abioutput_specg CResultd W args
1847Context Houtput_pre : ∀g xs m w h, Ing, xs emit_output_argsstream → ∀l v, l, v ∈ help_ps → h !! l = Somev → agreesm h → wim w h → contract_preoutput_specg xs m w
1847Context Houtput_frame : ∀g xs r args s m w h trace values s′ m′ w′, Ing, xs emit_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeoutput_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n, values = WIntn ∧ 0 ≤ n < 2 ^ 32

The help block's literals and program_name's cell are linked where main reads them.

1882Lemma main_help_lookup
∀ s
Ins "hello#str.54"; "hello#str.55"; "hello#str.56"; "hello#str.57"; "hello#str.58"; "hello#str.59"; "hello#str.60"; "hello#str.61"; "hello#str.62"; "hello#str.63"; "hello#str.79"
Explore proof 3 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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
Hoptarg_g :
lookupTAtom"optarg" ge_globalsge = Someoptarg_cell
Hcells :
0 ≤ ptr_addroptarg_cell < 2 ^ 64 ∧ 0 ≤ ptr_addroptind_cell < 2 ^ 64
Hoptind_g :
lookupTAtom"optind" ge_globalsge = Someoptind_cell
Hexit :
registryTAtom"exit" = Someexit_spec
Hexit_abi :
∀v : value, contract_abiexit_spec CVoid ArgW v
Hexit_pre :
∀n : Z m : mem w : libc_world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → wim w h → contract_preexit_spec WIntn m w
Hexit_post :
∀args : listarg n : Z s : R.state m : mem w : libc_world tr : listevent vs : listword s′ : R.state m′ : mem w′ : libc_world, M.E.invokeexit_spec CVoid args WIntn s m w tr CallReturnvs s′ m′ w′ → False
stdout_cell, stream :
Hstdout_g :
lookupTAtom"stdout" ge_globalsge = Somestdout_cell
wi_stdout :
∀m : mem w : libc_world h : gmappiece pval, wim w h → access_resm raw_addressptr_addrstdout_cell 0 ptr_capstdout_cell 8 Read 8 = Someok ∧ pointer_load_effectsm raw_addressptr_addrstdout_cell 0 AuxRead; LowerResolve; AddressRead = Somestream
version_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ version_ps
version_spec :
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : libc_world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ version_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Kversion_alloc :
∀size : Z m : mem wd : libc_world h : gmappiece pval base : Z, Insize 24; 80 → freshm heap_req8 size base → wim wd h → wiallocatedm heap_req8 size base wd overwriteobj_psbase heap_req8 size h
Kversion_store :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! k = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
Kversion_cursor :
∀cb : Z cr : region sb off : Z m : mem wd : libc_world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ va_cursor_pscb cr ptr_addr ≔ sb + off; ptr_cap ≔ Rosb → h !! k = Somev → wim wd h → wistore_bytesm cb 8 sb + off + 8 wd overwriteva_cursor_pscb cr ptr_addr ≔ sb + off + 8; ptr_cap ≔ Rosb h
Kversion_snapshot :
∀m : mem wd : libc_world h : gmappiece pval sb : Z, freshm heap_req16 72 sb → wim wd h → wisnapshot_valuesHV.version_main_argsstream sb allocatedm heap_req16 72 sb wd overwritesnapshot_psHV.version_main_argsstream sb heap_req16 72 h
Hquery_pre :
∀m : mem w : libc_world h : gmappiece pval p : ptr t : listZ, wim w h → h !! PName5 = SomeVNamep t → contract_prelibc_setlocale_contractrep requests WInt5; WPtrnull m w
Hquery :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval p : ptr t : listZ trace : listevent ending : call_end s′ : R.state m′ : mem w′ : libc_world, wim w h → h !! PName5 = SomeVNamep t → M.E.invokelibc_setlocale_contractrep requests r args WInt5; WPtrnull s m w trace ending s′ m′ w′ → s′ = s ∧ m′ = m ∧ w′ = w ∧ ending = CallReturnWPtrp
stderr_cell, errstream :
Hstderr_g :
lookupTAtom"stderr" ge_globalsge = Somestderr_cell
wi_stderr :
∀m : mem w : libc_world h : gmappiece pval, wim w h → access_resm raw_addressptr_addrstderr_cell 0 ptr_capstderr_cell 8 Read 8 = Someok ∧ pointer_load_effectsm raw_addressptr_addrstderr_cell 0 AuxRead; LowerResolve; AddressRead = Someerrstream
help_ps :
listpiece × pval
output_spec :
Hhelp_reg :
∀pname : ptr g : name xs : listword, Ing, xs main_output_argsstream errstream pname → registryg = Someoutput_specg
Hhelp_ret :
∀pname : ptr g : name xs : listword, Ing, xs main_output_argsstream errstream pname → contract_returnsoutput_specg = RClassW
Hhelp_abi :
∀ pname : ptr g : name xs : listword d : name args : listarg  ,
Ing, xs main_output_argsstream errstream pname
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
replicatelengthxs P
→
contract_abioutput_specg CResultd W args
Hhelp_pre :
∀pname : ptr g : name xs : listword m : mem w : libc_world h : gmappiece pval, name_oksargs pname → Ing, xs main_output_argsstream errstream pname → ∀l : piece v : pval, l, v ∈ help_ps ++ flat_maparg_ps sargs → h !! l = Somev → agreesm h → wim w h → contract_preoutput_specg xs m w
Hhelp_frame :
∀pname : ptr g : name xs : listword 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, Ing, xs main_output_argsstream errstream pname → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeoutput_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Houtput_reg :
∀g : name xs : listword, Ing, xs emit_output_argsstream → registryg = Someoutput_specg
Houtput_ret :
∀g : name xs : listword, Ing, xs emit_output_argsstream → contract_returnsoutput_specg = RClassW
Houtput_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs emit_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
replicatelengthxs P
→
contract_abioutput_specg CResultd W args
Houtput_pre :
∀g : name xs : listword m : mem w : libc_world h : gmappiece pval, Ing, xs emit_output_argsstream → ∀l : piece v : pval, l, v ∈ help_ps → h !! l = Somev → agreesm h → wim w h → contract_preoutput_specg xs m w
Houtput_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, Ing, xs emit_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeoutput_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
⊢
Ins "hello#str.54"; "hello#str.55"; "hello#str.56"; "hello#str.57"; "hello#str.58"; "hello#str.59"; "hello#str.60"; "hello#str.61"; "hello#str.62"; "hello#str.63"; "hello#str.79" → lookupTAtoms ge_globalsge = Someversion_literals

intros Hin

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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
Hoptarg_g :
lookupTAtom"optarg" ge_globalsge = Someoptarg_cell
Hcells :
0 ≤ ptr_addroptarg_cell < 2 ^ 64 ∧ 0 ≤ ptr_addroptind_cell < 2 ^ 64
Hoptind_g :
lookupTAtom"optind" ge_globalsge = Someoptind_cell
Hexit :
registryTAtom"exit" = Someexit_spec
Hexit_abi :
∀v : value, contract_abiexit_spec CVoid ArgW v
Hexit_pre :
∀n : Z m : mem w : libc_world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → wim w h → contract_preexit_spec WIntn m w
Hexit_post :
∀args : listarg n : Z s : R.state m : mem w : libc_world tr : listevent vs : listword s′ : R.state m′ : mem w′ : libc_world, M.E.invokeexit_spec CVoid args WIntn s m w tr CallReturnvs s′ m′ w′ → False
stdout_cell, stream :
Hstdout_g :
lookupTAtom"stdout" ge_globalsge = Somestdout_cell
wi_stdout :
∀m : mem w : libc_world h : gmappiece pval, wim w h → access_resm raw_addressptr_addrstdout_cell 0 ptr_capstdout_cell 8 Read 8 = Someok ∧ pointer_load_effectsm raw_addressptr_addrstdout_cell 0 AuxRead; LowerResolve; AddressRead = Somestream
version_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ version_ps
version_spec :
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : libc_world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ version_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Kversion_alloc :
∀size : Z m : mem wd : libc_world h : gmappiece pval base : Z, Insize 24; 80 → freshm heap_req8 size base → wim wd h → wiallocatedm heap_req8 size base wd overwriteobj_psbase heap_req8 size h
Kversion_store :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! k = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
Kversion_cursor :
∀cb : Z cr : region sb off : Z m : mem wd : libc_world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ va_cursor_pscb cr ptr_addr ≔ sb + off; ptr_cap ≔ Rosb → h !! k = Somev → wim wd h → wistore_bytesm cb 8 sb + off + 8 wd overwriteva_cursor_pscb cr ptr_addr ≔ sb + off + 8; ptr_cap ≔ Rosb h
Kversion_snapshot :
∀m : mem wd : libc_world h : gmappiece pval sb : Z, freshm heap_req16 72 sb → wim wd h → wisnapshot_valuesHV.version_main_argsstream sb allocatedm heap_req16 72 sb wd overwritesnapshot_psHV.version_main_argsstream sb heap_req16 72 h
Hquery_pre :
∀m : mem w : libc_world h : gmappiece pval p : ptr t : listZ, wim w h → h !! PName5 = SomeVNamep t → contract_prelibc_setlocale_contractrep requests WInt5; WPtrnull m w
Hquery :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval p : ptr t : listZ trace : listevent ending : call_end s′ : R.state m′ : mem w′ : libc_world, wim w h → h !! PName5 = SomeVNamep t → M.E.invokelibc_setlocale_contractrep requests r args WInt5; WPtrnull s m w trace ending s′ m′ w′ → s′ = s ∧ m′ = m ∧ w′ = w ∧ ending = CallReturnWPtrp
stderr_cell, errstream :
Hstderr_g :
lookupTAtom"stderr" ge_globalsge = Somestderr_cell
wi_stderr :
∀m : mem w : libc_world h : gmappiece pval, wim w h → access_resm raw_addressptr_addrstderr_cell 0 ptr_capstderr_cell 8 Read 8 = Someok ∧ pointer_load_effectsm raw_addressptr_addrstderr_cell 0 AuxRead; LowerResolve; AddressRead = Someerrstream
help_ps :
listpiece × pval
output_spec :
Hhelp_reg :
∀pname : ptr g : name xs : listword, Ing, xs main_output_argsstream errstream pname → registryg = Someoutput_specg
Hhelp_ret :
∀pname : ptr g : name xs : listword, Ing, xs main_output_argsstream errstream pname → contract_returnsoutput_specg = RClassW
Hhelp_abi :
∀ pname : ptr g : name xs : listword d : name args : listarg  ,
Ing, xs main_output_argsstream errstream pname
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
replicatelengthxs P
→
contract_abioutput_specg CResultd W args
Hhelp_pre :
∀pname : ptr g : name xs : listword m : mem w : libc_world h : gmappiece pval, name_oksargs pname → Ing, xs main_output_argsstream errstream pname → ∀l : piece v : pval, l, v ∈ help_ps ++ flat_maparg_ps sargs → h !! l = Somev → agreesm h → wim w h → contract_preoutput_specg xs m w
Hhelp_frame :
∀pname : ptr g : name xs : listword 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, Ing, xs main_output_argsstream errstream pname → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeoutput_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Houtput_reg :
∀g : name xs : listword, Ing, xs emit_output_argsstream → registryg = Someoutput_specg
Houtput_ret :
∀g : name xs : listword, Ing, xs emit_output_argsstream → contract_returnsoutput_specg = RClassW
Houtput_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs emit_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
replicatelengthxs P
→
contract_abioutput_specg CResultd W args
Houtput_pre :
∀g : name xs : listword m : mem w : libc_world h : gmappiece pval, Ing, xs emit_output_argsstream → ∀l : piece v : pval, l, v ∈ help_ps → h !! l = Somev → agreesm h → wim w h → contract_preoutput_specg xs m w
Houtput_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, Ing, xs emit_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeoutput_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Hin :
Ins "hello#str.54"; "hello#str.55"; "hello#str.56"; "hello#str.57"; "hello#str.58"; "hello#str.59"; "hello#str.60"; "hello#str.61"; "hello#str.62"; "hello#str.63"; "hello#str.79"

apply proj1proj2Hlinked

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
transition :
listword → mem → libc_world → listZ → listevent → listword → mem → libc_world → 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 → agreesm h → live_disjointm → R.readys m → 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
Hoptarg_g :
lookupTAtom"optarg" ge_globalsge = Someoptarg_cell
Hcells :
0 ≤ ptr_addroptarg_cell < 2 ^ 64 ∧ 0 ≤ ptr_addroptind_cell < 2 ^ 64
Hoptind_g :
lookupTAtom"optind" ge_globalsge = Someoptind_cell
Hexit :
registryTAtom"exit" = Someexit_spec
Hexit_abi :
∀v : value, contract_abiexit_spec CVoid ArgW v
Hexit_pre :
∀n : Z m : mem w : libc_world h : gmappiece pval, 0 ≤ n < 2 ^ 32 → wim w h → contract_preexit_spec WIntn m w
Hexit_post :
∀args : listarg n : Z s : R.state m : mem w : libc_world tr : listevent vs : listword s′ : R.state m′ : mem w′ : libc_world, M.E.invokeexit_spec CVoid args WIntn s m w tr CallReturnvs s′ m′ w′ → False
stdout_cell, stream :
Hstdout_g :
lookupTAtom"stdout" ge_globalsge = Somestdout_cell
wi_stdout :
∀m : mem w : libc_world h : gmappiece pval, wim w h → access_resm raw_addressptr_addrstdout_cell 0 ptr_capstdout_cell 8 Read 8 = Someok ∧ pointer_load_effectsm raw_addressptr_addrstdout_cell 0 AuxRead; LowerResolve; AddressRead = Somestream
version_ps :
listpiece × pval
author_reg :
Hauthor_live :
∀s : String.string, Ins "hello#str.72"; "hello#str.73"; "hello#str.74"; "hello#str.75" → PLiveptr_addrversion_literals, VLiveauthor_regs ∈ version_ps
version_spec :
Hversion_reg :
∀g : name xs : listword, Ing, xs version_output_argsstream → registryg = Someversion_specg
Hversion_ret :
∀g : name xs : listword, Ing, xs version_output_argsstream → contract_returnsversion_specg = RClassW
Hversion_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs version_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
→
contract_abiversion_specg CResultd W args
Hversion_pre :
∀g : name xs : listword m : mem w : libc_world h : gmappiece pval, Ing, xs version_output_argsstream → ∀l : piece v : pval, l, v ∈ version_ps → h !! l = Somev → agreesm h → wim w h → contract_preversion_specg xs m w
Hversion_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, Ing, xs version_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeversion_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Kversion_alloc :
∀size : Z m : mem wd : libc_world h : gmappiece pval base : Z, Insize 24; 80 → freshm heap_req8 size base → wim wd h → wiallocatedm heap_req8 size base wd overwriteobj_psbase heap_req8 size h
Kversion_store :
∀b : Z reg : region o : Z x xp : ptr m : mem wd : libc_world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ PLiveb, VLivereg ++ PAuxb o, VAuxptr_capx :: cellb o ptr_addrx → h !! k = Somev → wim wd h → wistore_bytesstore_auxm b + o ptr_capxp b + o 8 ptr_addrxp wd overwritePLiveb, VLivereg ++ PAuxb o, VAuxptr_capxp :: cellb o ptr_addrxp h
Kversion_cursor :
∀cb : Z cr : region sb off : Z m : mem wd : libc_world h : gmappiece pval, ∀k : piece v : pval, k, v ∈ va_cursor_pscb cr ptr_addr ≔ sb + off; ptr_cap ≔ Rosb → h !! k = Somev → wim wd h → wistore_bytesm cb 8 sb + off + 8 wd overwriteva_cursor_pscb cr ptr_addr ≔ sb + off + 8; ptr_cap ≔ Rosb h
Kversion_snapshot :
∀m : mem wd : libc_world h : gmappiece pval sb : Z, freshm heap_req16 72 sb → wim wd h → wisnapshot_valuesHV.version_main_argsstream sb allocatedm heap_req16 72 sb wd overwritesnapshot_psHV.version_main_argsstream sb heap_req16 72 h
Hquery_pre :
∀m : mem w : libc_world h : gmappiece pval p : ptr t : listZ, wim w h → h !! PName5 = SomeVNamep t → contract_prelibc_setlocale_contractrep requests WInt5; WPtrnull m w
Hquery :
∀r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval p : ptr t : listZ trace : listevent ending : call_end s′ : R.state m′ : mem w′ : libc_world, wim w h → h !! PName5 = SomeVNamep t → M.E.invokelibc_setlocale_contractrep requests r args WInt5; WPtrnull s m w trace ending s′ m′ w′ → s′ = s ∧ m′ = m ∧ w′ = w ∧ ending = CallReturnWPtrp
stderr_cell, errstream :
Hstderr_g :
lookupTAtom"stderr" ge_globalsge = Somestderr_cell
wi_stderr :
∀m : mem w : libc_world h : gmappiece pval, wim w h → access_resm raw_addressptr_addrstderr_cell 0 ptr_capstderr_cell 8 Read 8 = Someok ∧ pointer_load_effectsm raw_addressptr_addrstderr_cell 0 AuxRead; LowerResolve; AddressRead = Someerrstream
help_ps :
listpiece × pval
output_spec :
Hhelp_reg :
∀pname : ptr g : name xs : listword, Ing, xs main_output_argsstream errstream pname → registryg = Someoutput_specg
Hhelp_ret :
∀pname : ptr g : name xs : listword, Ing, xs main_output_argsstream errstream pname → contract_returnsoutput_specg = RClassW
Hhelp_abi :
∀ pname : ptr g : name xs : listword d : name args : listarg  ,
Ing, xs main_output_argsstream errstream pname
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
replicatelengthxs P
→
contract_abioutput_specg CResultd W args
Hhelp_pre :
∀pname : ptr g : name xs : listword m : mem w : libc_world h : gmappiece pval, name_oksargs pname → Ing, xs main_output_argsstream errstream pname → ∀l : piece v : pval, l, v ∈ help_ps ++ flat_maparg_ps sargs → h !! l = Somev → agreesm h → wim w h → contract_preoutput_specg xs m w
Hhelp_frame :
∀pname : ptr g : name xs : listword 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, Ing, xs main_output_argsstream errstream pname → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeoutput_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Houtput_reg :
∀g : name xs : listword, Ing, xs emit_output_argsstream → registryg = Someoutput_specg
Houtput_ret :
∀g : name xs : listword, Ing, xs emit_output_argsstream → contract_returnsoutput_specg = RClassW
Houtput_abi :
∀ g : name xs : listword d : name args : listarg  ,
Ing, xs emit_output_argsstream
→
map
λ a : arg  ⇒
match a with
Argk _
⇒
k
args
=
replicatelengthxs P
→
contract_abioutput_specg CResultd W args
Houtput_pre :
∀g : name xs : listword m : mem w : libc_world h : gmappiece pval, Ing, xs emit_output_argsstream → ∀l : piece v : pval, l, v ∈ help_ps → h !! l = Somev → agreesm h → wim w h → contract_preoutput_specg xs m w
Houtput_frame :
∀g : name xs : listword r : call_result args : listarg s : R.state m : mem w : libc_world h : gmappiece pval trace : listevent values : listword s′ : R.state m′ : mem w′ : libc_world, Ing, xs emit_output_argsstream → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokeoutput_specg r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h ∧ ∃n : Z, values = WIntn ∧ 0 ≤ n < 2 ^ 32
Hin :
Ins "hello#str.54"; "hello#str.55"; "hello#str.56"; "hello#str.57"; "hello#str.58"; "hello#str.59"; "hello#str.60"; "hello#str.61"; "hello#str.62"; "hello#str.63"; "hello#str.79"

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

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

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

One of main's output calls: it is safe, binds d to some int and keeps the literals and the arguments' strings.

1894Lemma wp_main_output
∀ f e ls lab d g args rest j pname xs Φ
map_optionarg_xge e args = Somexs
map
λ a  ⇒
match a with
Argk _
⇒
k
args
=
replicatelengthxs P
ptshelp_ps −∗ ptsflat_maparg_ps sargs −∗ ▷∀n, ptshelp_ps −∗ ptsflat_maparg_ps sargs −∗ WPERunmkFramef putd WIntn e ls None Execlab rest j : mexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd W Globalg args :: rest j : mexpr {Φ}
Proof 35 steps Qed
intros Hname Hin Hargs′ Hclasses
iIntros Hps Has HK
assert Hg : g = TAtom"fputs" ∨ g = TAtom"fprintf"
{unfold main_output_args in Hin
repeat destruct Hin as H | Hin ; try contradiction ; inversion H ; auto
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ output_specg xs ptshelp_ps ∗ ptsflat_maparg_ps sargs with [$Hps $Has] [HK]
–destruct Hg as → | → ; apply linked_outside ; first exact Hlinked | reflexivity
–destruct Hg as → | → ; apply linked_unbound ; first exact Hlinked | reflexivity
–destruct Hg as → | → ; reflexivity
–exact Hhelp_reg_ _ _ Hin
–exact Hargs′
–exact Hhelp_abi_ _ _ _ _ Hin Hclasses
–iIntros σ (%h & Hh & %Hf) [Hps Has]
destruct Hf as Ha & _ & _ & Hw
iDestruct pts_lookup with Hh Hps as %Hps
iDestruct pts_lookup with Hh Has as %Has
iPureIntro
apply Hhelp_pre_ _ _ _ _ h Hname Hin ; | exact Ha | exact Hw
intros l v Hl
apply elem_of_app in Hl as Hl | Hl ; exact Hps_ _ Hl | exact Has_ _ Hl
–iNext
iIntros σ trace values s′ m′ w′ Hinv (%h & Hh & %Hf) [Hps Has]
destruct Hf as Ha & Hd & Hr & Hw
destruct Hhelp_frame_ _ _ _ _ _ _ _ _ _ _ _ _ _ Hin Ha Hd Hr Hw Hinv as Ha′ & Hd′ & Hr′ & Hw′ & n & → & Hn
iModIntro
iExists putd WIntn e
iSplit
+iPureIntro
cbn [ site_result ]
rewrite Hhelp_ret_ _ _ Hin
cbn
rewrite Z.mod_small ; reflexivity | exact Hn
+iSplitL Hh ; iExists h ; iFrame ; iPureIntro ; auto |
iApply HK with Hps Has

The program's name is a pointer whose capability's life, if any, is among the arguments' pieces: wp_raw_load_pointer_in can load it out of its cell.

1932Lemma name_life
∀ x0
0 ≤ ptr_addrx0 < 2 ^ 64 ∧ ∀xb, ptr_capx0 = Objxb ∨ ptr_capx0 = Roxb → ∃xr, PLivexb, VLivexr ∈ flat_maparg_ps sargs
Proof 16 steps Qed
intros s0 & srest & i & Hs0 & Hi & Ex0
assert Hin0 : Ins0 sargs by rewrite Hs0 ; left ; reflexivity
pose proof proj1List.Forall_forall_ _ Hargs s0 Hin0 as Hcap & Hb0 & Hbp & Hend & H48 & _
split ; rewrite Ex0 ; cbn [ ptr_addr ] ; lia |
intros xb Hxb
exists arg_regions0
rewrite Ex0 in Hxb
cbn [ ptr_cap ] in Hxb
assert xb = arg_bases0 as →
{destruct Hcap as E1 | E1 ; rewrite E1 in Hxb ; destruct Hxb as E2 | E2 ; congruence
apply list_elem_of_In , in_flat_map
exists s0
split ; exact Hin0 |
unfold arg_ps , string_ps
left
reflexivity

iw_1.iw_1.L32, the help text's end: main loads stderr, compares it with stdout and exits with 0 or 1.

1949Lemma help_L32
∀ e from Φ
lookupTAtom"iw_1.v41" e = SomeWPtrstream
⊢ WPERunmkFramemain_fn e [ ] None EnterTAtom"iw_1.iw_1.L32" SomeTAtomfrom : mexpr {Φ}
Proof 42 steps Qed
intros H41
mn_enter "iw_1.iw_1.L32"
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite Hstderr_g ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_world_let_withregistry wi ge [ ] ; reflexivity | reflexivity | word_premise | | rewrite / pts /= ; done |
{intros m w h Hw _
apply op_check
exact proj1wi_stderr_ _ _ Hw
iNext
iIntros _
iApply wp_world_let_withregistry wi ge [ ] ; reflexivity | reflexivity | word_premise | | rewrite / pts /= ; done |
{intros m w h Hw _
apply op_raw_load_pointer ; apply wi_stderr_ _ _ Hw
iNext
iIntros _
iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
destruct ptr_addrstream mod 2 ^ 64 =? ptr_addrerrstream mod 2 ^ 64

Help went to stderr: exit(1).

–iApply wp_branch_ _ _ _ _ _ _ _ _ _ 1 ; word_premise |
iNext
cbn [ Z.eqb edge_label ]
mn_enter "iw_1.iw_1.L50"
iApply wp_main_exit_ _ _ _ _ _ _ 1 ; word_premise | lia

To stdout: exit(0).

–iApply wp_branch_ _ _ _ _ _ _ _ _ _ 0 ; word_premise |
iNext
cbn [ Z.eqb edge_label ]
mn_enter "iw_1.iw_1.L49"
iApply wp_goto
iNext
cbn [ edge_label ]
mn_enter "iw_1.iw_1.L50"
iApply wp_main_exit_ _ _ _ _ _ _ 0 ; word_premise | lia

Pick the output call's entry in a list of calls.

1980Ltac pick_output  ≔
repeat first left ; reflexivity | right

--help, iw_1.L39: main loads stdout, queries LC_MESSAGES' name, prints the usage line with the program's name and the option lines, calls the footer, and, unless the locale's name starts with "en_", a line on where to report translation bugs; then iw_1.iw_1.L32 exits. The pieces it needs are the help literals, the "en_" string, the program's name cells and LC_MESSAGES' lent name.

1988Lemma main_help
∀ b4 b6 x0 x1 y0 p t b61 r61 Φ
LL.lent5 p t −∗ ptshelp_ps −∗ stringversion_literal"hello#str.61" b61 r61 101; 110; 95 −∗ HP.HN.name_cellspn nreg sreg nb sb x0 x1 y0 −∗ loop_exitb4 b6 "iw_1.L39"%string "iw_1.L50"%string Φ
Proof 171 steps Qed
intros Hname
pose proof main_help_lookup"hello#str.54" ltac:simpl ; tauto as H54
pose proof main_help_lookup"hello#str.55" ltac:simpl ; tauto as H55
pose proof main_help_lookup"hello#str.56" ltac:simpl ; tauto as H56
pose proof main_help_lookup"hello#str.57" ltac:simpl ; tauto as H57
pose proof main_help_lookup"hello#str.58" ltac:simpl ; tauto as H58
pose proof main_help_lookup"hello#str.59" ltac:simpl ; tauto as H59
pose proof main_help_lookup"hello#str.60" ltac:simpl ; tauto as H60
pose proof main_help_lookup"hello#str.61" ltac:simpl ; tauto as H61
pose proof main_help_lookup"hello#str.62" ltac:simpl ; tauto as H62
pose proof main_help_lookup"hello#str.63" ltac:simpl ; tauto as H63
assert Hpn : lookupTAtom"program_name" ge_globalsge = SomemkPtrprogram_name_b Objprogram_name_b
{apply proj1proj2Hlinked
vm_compute
reflexivity
destruct name_lifex0 Hname as Hxr Hxlife
pose proof Hpn_end as Hpn_end′
iIntros #Hk Hps H61 (Hpl & Hpc & Hnl & Hnc & Hsl & Hsc)
rewrite / loop_exit
iIntros e ps cs a ix g lose _ (Hb & Has & Ht & Hl4 & Hp4)
iPoseProof Hk as [%Hpk _]
destruct Hpk as Hp0 & Hpt & _
mn_enter "iw_1.L39"

stdout's stream.

iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite Hstdout_g ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_world_let_withregistry wi ge [ ] ; reflexivity | reflexivity | word_premise | | rewrite / pts /= ; done |
{intros m w h Hw _
apply op_check
exact proj1wi_stdout_ _ _ Hw
iNext
iIntros _
iApply wp_world_let_withregistry wi ge [ ] ; reflexivity | reflexivity | word_premise | | rewrite / pts /= ; done |
{intros m w h Hw _
apply op_raw_load_pointer ; apply wi_stdout_ _ _ Hw
iNext
iIntros _

setlocale(LC_MESSAGES, NULL).

iApply LL.wp_lent_queryregistry wi ge _ _ _ _ _ TAtom"setlocale" _ _ _ libc_setlocale_contractrep requests WInt5; WPtrnull 5 p t with Hk ; exact Hsetlocale | reflexivity | apply linked_outside ; first exact Hlinked | reflexivity | apply linked_unbound ; first exact Hlinked | reflexivity | reflexivity | word_premise | split ; right ; eexists ; reflexivity | do 2 eexists ; reflexivity | intros m w h Hw Hl ; exact Hquery_pre_ _ _ _ _ Hw Hl | intros s m w h trace ending s′ m′ w′ Hw Hl Hq ; exact Hquery_ _ _ _ _ _ _ _ _ _ _ _ _ Hw Hl Hq |
iNext

The usage line.

iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite H54 ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite Hpn ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_check_read with Hpl ; reflexivity | word_premise | left ; reflexivity | unfold raw_address ; cbn [ ptr_addr ] ; unfold program_name_b ; rewrite Z.add_0_r Z.mod_small ; lia | unfold raw_address ; cbn [ ptr_addr ] ; rewrite Z.add_0_r Z.mod_small ; lia | unfold program_name_b ; lia | unfold raw_address ; cbn [ ptr_addr ] ; unfold program_name_b ; reflexivity |
iNext
iIntros Hpl
iApply wp_raw_load_pointer_in with Hpl Hpc Has ; reflexivity | word_premise | left ; reflexivity | unfold raw_address ; cbn [ ptr_addr ] ; unfold program_name_b ; reflexivity | unfold program_name_b ; reflexivity | exact Hxr | exact Hxlife |
iNext
iIntros Hpl Hpc Has
iApply wp_main_output with Hps Has ; exact Hname | | word_premise | reflexivity | ; unfold main_output_args ; pick_output |
iNext
iIntros n0 Hps Has

The option lines.

iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite H55 ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_main_output with Hps Has ; exact Hname | | word_premise | reflexivity | ; unfold main_output_args ; pick_output |
iNext
iIntros ?n Hps Has
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite H56 ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_main_output with Hps Has ; exact Hname | | word_premise | reflexivity | ; unfold main_output_args ; pick_output |
iNext
iIntros ?n Hps Has
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite H57 ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_main_output with Hps Has ; exact Hname | | word_premise | reflexivity | ; unfold main_output_args ; pick_output |
iNext
iIntros ?n Hps Has
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite H58 ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_main_output with Hps Has ; exact Hname | | word_premise | reflexivity | ; unfold main_output_args ; pick_output |
iNext
iIntros ?n Hps Has
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite H56 ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_main_output with Hps Has ; exact Hname | | word_premise | reflexivity | ; unfold main_output_args ; pick_output |
iNext
iIntros ?n Hps Has
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite H59 ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_main_output with Hps Has ; exact Hname | | word_premise | reflexivity | ; unfold main_output_args ; pick_output |
iNext
iIntros ?n Hps Has
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite H60 ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_main_output with Hps Has ; exact Hname | | word_premise | reflexivity | ; unfold main_output_args ; pick_output |
iNext
iIntros ?n Hps Has

The footer.

iApply wp_call_bind_ _ _ _ _ _ _ _ _ _ _ _ _ emit_bug_reporting_address_fn invocationemit_bug_reporting_address_fn [ ] ; reflexivity | unfold find_fn ; rewrite proj1Hlinked ; vm_compute ; reflexivity | reflexivity |
iNext
iNext
iIntros Hps
iExists _
iSplit ; iPureIntro ; reflexivity |
iNext

The locale's name is never null: it is lent.

iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
assert Ep : ptr_addrp =? 0 = false by apply Z.eqb_neq ; lia
match goal withH : lookupTAtom"iw_1.iw_1.v35" _ = _ |- _⇒rewrite Ep in H ; cbn [ negb ] in Hend
iApply wp_branch_ _ _ _ _ _ _ _ _ _ 1 ; word_premise |
iNext
cbn [ Z.eqb edge_label ]

strncmp(name, "en_", 3).

mn_enter "iw_1.iw_1.L36"
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite H61 ; reflexivity | intros ?m ; word_premise |
iNext
iApply LL.wp_strncmp_lentregistry wi ge Hlent _ _ _ _ _ _ _ _ _ _ 5 p t _ _ _ _ 3 with Hk H61 ; exact Hstrncmp | apply linked_outside ; first exact Hlinked | reflexivity | apply linked_unbound ; first exact Hlinked | reflexivity | word_premise | word_premise | word_premise | lia |
iNext
iIntros bits H61
iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
iApply wp_goto
iNext
cbn [ edge_label ]
mn_enter "iw_1.iw_1.L37"
match goal withH : lookupTAtom"iw_1.iw_1.v43" _ = SomeWIntif ?c then _ else _ mod _ |- _⇒destruct cend

Not English: where to report translation bugs.

–iApply wp_branch_ _ _ _ _ _ _ _ _ _ 1 ; word_premise |
iNext
cbn [ Z.eqb edge_label ]
mn_enter "iw_1.iw_1.L30"
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite H62 ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite H63 ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_main_output with Hps Has ; exact Hname | | word_premise | reflexivity | ; unfold main_output_args ; pick_output |
iNext
iIntros ?n Hps Has
iApply wp_goto
iNext
cbn [ edge_label ]
iApply help_L32
assumption
–iApply wp_branch_ _ _ _ _ _ _ _ _ _ 0 ; word_premise |
iNext
cbn [ Z.eqb edge_label ]
iApply help_L32
assumption

iw_1.L113, after a bad option or an extra operand: main prints to stderr that --help says more, naming the program, and exits with 1.

2133Lemma main_hint
∀ e from x0 x1 y0 Φ
ptshelp_ps −∗ ptsflat_maparg_ps sargs −∗ HP.HN.name_cellspn nreg sreg nb sb x0 x1 y0 −∗ WPERunmkFramemain_fn e [ ] None EnterTAtom"iw_1.L113" SomeTAtomfrom : mexpr {Φ}
Proof 45 steps Qed
intros Hname
pose proof main_help_lookup"hello#str.79" ltac:simpl ; tauto as H79
assert Hpn : lookupTAtom"program_name" ge_globalsge = SomemkPtrprogram_name_b Objprogram_name_b
{apply proj1proj2Hlinked
vm_compute
reflexivity
destruct name_lifex0 Hname as Hxr Hxlife
pose proof Hpn_end as Hpn_end′
iIntros Hps Has (Hpl & Hpc & Hnl & Hnc & Hsl & Hsc)
mn_enter "iw_1.L113"

stderr's stream.

iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite Hstderr_g ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_world_let_withregistry wi ge [ ] ; reflexivity | reflexivity | word_premise | | rewrite / pts /= ; done |
{intros m w h Hw _
apply op_check
exact proj1wi_stderr_ _ _ Hw
iNext
iIntros _
iApply wp_world_let_withregistry wi ge [ ] ; reflexivity | reflexivity | word_premise | | rewrite / pts /= ; done |
{intros m w h Hw _
apply op_raw_load_pointer ; apply wi_stderr_ _ _ Hw
iNext
iIntros _

The hint, naming the program.

iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite H79 ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite Hpn ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_check_read with Hpl ; reflexivity | word_premise | left ; reflexivity | unfold raw_address ; cbn [ ptr_addr ] ; unfold program_name_b ; rewrite Z.add_0_r Z.mod_small ; lia | unfold raw_address ; cbn [ ptr_addr ] ; rewrite Z.add_0_r Z.mod_small ; lia | unfold program_name_b ; lia | unfold raw_address ; cbn [ ptr_addr ] ; unfold program_name_b ; reflexivity |
iNext
iIntros Hpl
iApply wp_raw_load_pointer_in with Hpl Hpc Has ; reflexivity | word_premise | left ; reflexivity | unfold raw_address ; cbn [ ptr_addr ] ; unfold program_name_b ; reflexivity | unfold program_name_b ; reflexivity | exact Hxr | exact Hxlife |
iNext
iIntros Hpl Hpc Has
iApply wp_main_output with Hps Has ; exact Hname | | word_premise | reflexivity | ; unfold main_output_args ; pick_output |
iNext
iIntros ?n Hps Has
iApply wp_main_exit_ _ _ _ _ _ _ 1 ; word_premise | lia

The operand check's exit to the hint: the loop's pieces supply the arguments' strings, and the caller the literals and name cells.

2180Lemma hint_exit
∀ b4 b6 from P x0 x1 y0 Φ
ptshelp_ps −∗ HP.HN.name_cellspn nreg sreg nb sb x0 x1 y0 −∗ operand_exitb4 b6 "iw_1.L113"%string from P Φ
Proof 6 steps Qed
intros Hname
iIntros Hps Hcells
rewrite / operand_exit
iIntros e ps cs a i g lose _ (_ & Has & _)
iApply main_hint with Hps Has Hcells
exact Hname

error(0, 0, fmt, text, arg), the diagnostic for an extra operand, has a contract that returns: admitted with the literals' and the arguments' pieces for an argument's string, it keeps the world interpretation and every piece main owns.

2194Context diag_spec : contractlibc_world
2194Context Hdiag_reg : registryTAtom"error" = Somediag_spec
2194Context Hdiag_ret : contract_returnsdiag_spec = RVoid
2194Context Hdiag_abi : ∀args, mapλa ⇒ match a with Argk _ ⇒ k end args = W; W; P; P; P → contract_abidiag_spec CVoid args
2194Context Hdiag_pre : ∀q m w h, Inq maparg_ptr sargs → ∀l v, l, v ∈ help_ps ++ flat_maparg_ps sargs → h !! l = Somev → agreesm h → wim w h → contract_prediag_spec WInt0; WInt0; WPtrversion_literal"hello#str.77"; WPtrversion_literal"hello#str.78"; WPtrq m w
2194Context Hdiag_post : ∀q args s m w h tr vs s′ m′ w′, Inq maparg_ptr sargs → agreesm h → live_disjointm → R.readys m → wim w h → M.E.invokediag_spec CVoid args WInt0; WInt0; WPtrversion_literal"hello#str.77"; WPtrversion_literal"hello#str.78"; WPtrq s m w tr CallReturnvs s′ m′ w′ → vs = [ ] ∧ agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ wim′ w′ h

The literals of the extra-operand diagnostic are linked.

2212Lemma main_extra_lookup
∀ s
Ins "hello#str.77"; "hello#str.78"
Proof 3 steps Qed
intros Hin
apply proj1proj2Hlinked
repeat destruct Hin as ← | Hin ; try contradiction ; vm_compute ; reflexivity

iw_1.L79, an extra operand: main loads argvoptind again, which is an argument as optind is below argc, reports it with error(0, ...), and goes on to the hint.

2222Lemma main_extra
∀ b4 b6 x0 x1 y0 Φ
ptshelp_ps −∗ HP.HN.name_cellspn nreg sreg nb sb x0 x1 y0 −∗ operand_exitb4 b6 "iw_1.L79"%string "iw_1.L55"%string λ_ i ⇒ i < Z.of_natlengthsargs Φ
Proof 92 steps Qed
intros Hname
pose proof main_extra_lookup"hello#str.77" ltac:simpl ; tauto as H77
pose proof main_extra_lookup"hello#str.78" ltac:simpl ; tauto as H78
iIntros Hps Hcells
rewrite / operand_exit
iIntros e ps cs a i g lose Hf & Hpr & Hlt (Hb & Hs & Ht & Hl4 & Hp4)
pose proof Hf as H0 & H2 & H4 & H6 & H11 & Hc1 & Hfr & Ho & Hc & Hi & Hg
pose proof Hav as Hav0 & Hav8 & Haend & Har48
pose proof Hargc as Hargc′
pose proof order_lengthps Ho as Lp
destruct lookup_lt_is_Some_2ps ++ null Z.to_nati as q Hq
{rewrite length_app Lp
cbn [ length ]
lia
pose proof slot_kindssargs ps Z.to_nati q Ho Hq as Hkind
destruct Hkind as Ek _ | _ s & Hs & → ; lia |
pose proof proj1List.Forall_forall_ _ Hargs s Hs as Hcap & Hb0 & Hbp & Hend & H48 & _
assert Hqr : 0 ≤ ptr_addrarg_ptrs < 2 ^ 64 by lia
assert Hlife : ∀xb, ptr_caparg_ptrs = Objxb ∨ ptr_caparg_ptrs = Roxb → ∃xr, PLivexb, VLivexr ∈ flat_maparg_ps sargs
{intros xb Hxb
exists arg_regions
assert xb = arg_bases as →
{destruct Hcap as E1 | E1 ; rewrite E1 in Hxb ; destruct Hxb as E2 | E2 ; congruence
apply list_elem_of_In , in_flat_map
exists s
split ; exact Hs |
unfold arg_ps , string_ps
left
reflexivity
assert Hqin : Inarg_ptrs maparg_ptr sargs by apply in_map ; exact Hs
mn_enter "iw_1.L79"
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite H77 ; reflexivity | intros ?m ; word_premise |
iNext
iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite H78 ; reflexivity | intros ?m ; word_premise |
iNext

argvoptind again.

iApply wp_let ; reflexivity | reflexivity | cbn ; rewrite Hoptind_g ; reflexivity | intros ?m ; word_premise |
iNext
iNext
iNext
iIntros Ht
iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
iApply wp_let ; reflexivity | reflexivity | word_premise | intros ?m ; word_premise |
iNext
iNext
iEval rewriteargv_block_slotav ar ps cs Z.to_nati arg_ptrs Hc Hq in Hb
iDestruct Hb as (Hal & Hy0 & Hx0 & Hq & Hy1 & Hx1)
iApply wp_check_read with Hal ; reflexivity | word_premise | left ; reflexivity | addr_premise | addr_premise | addr_premise |
iNext
iIntros Hal
iApply wp_raw_load_pointer_in with Hal Hq Hs ; reflexivity | word_premise | left ; reflexivity | addr_premise | addr_premise | exact Hqr | exact Hlife |
iNext
iIntros Hal Hq Hs

error(0, 0, "extra operand %s", ..., argvoptind).

iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ diag_spec WInt0; WInt0; WPtrversion_literal"hello#str.77"; WPtrversion_literal"hello#str.78"; WPtrarg_ptrs ptshelp_ps ∗ ptsflat_maparg_ps sargs with [$Hps $Hs] [Hcells] ; apply linked_outside ; first exact Hlinked | reflexivity | apply linked_unbound ; first exact Hlinked | reflexivity | reflexivity | exact Hdiag_reg | word_premise | apply Hdiag_abi ; reflexivity | |
–iIntros σ (%h & Hh & %Hσ) [Hps Has]
destruct Hσ as Ha & _ & _ & Hw
iDestruct pts_lookup with Hh Hps as %Hps
iDestruct pts_lookup with Hh Has as %Has
iPureIntro
apply Hdiag_pre_ _ _ h Hqin ; | exact Ha | exact Hw
intros l v Hl
apply elem_of_app in Hl as Hl | Hl ; exact Hps_ _ Hl | exact Has_ _ Hl
–iNext
iIntros σ tr vs s′ m′ w′ Hinv (%h & Hh & %Hσ) [Hps Has]
destruct Hσ as Ha & Hd & Hr & Hw
destruct Hdiag_post_ _ _ _ _ _ _ _ _ _ _ Hqin Ha Hd Hr Hw Hinv as → & Ha′ & Hd′ & Hr′ & Hw′
iModIntro
iExists _
iSplit
+iPureIntro
rewrite Hdiag_ret
reflexivity
+iSplitL Hh ; iExists h ; iFrame ; iPureIntro ; auto |
iApply wp_goto
iNext
cbn [ edge_label ]
iApply main_hint with Hps Has Hcells
exact Hname

The loop's exits but the greeting: --version, --help, and, at the end of options, an extra operand or the hint. Each branch has every resource, as only one runs.

2298Lemma loop_exits
∀ b4 b6 x0 x1 y0 p t b61 r61 Φ
ptsversion_ps −∗ ptshelp_ps −∗ LL.lent5 p t −∗ stringversion_literal"hello#str.61" b61 r61 101; 110; 95 −∗ HP.HN.name_cellspn nreg sreg nb sb x0 x1 y0 −∗ operand_exitb4 b6 "iw_1.join"%string "iw_1.L60"%string λlose i ⇒ lose = 0 ∧ i = Z.of_natlengthsargs Φ −∗ 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 Φ
Proof 7 steps Qed
intros Hname
iIntros Hv Hh #Hk H61 Hc Hj
iSplit ; iApply main_version with Hv |
iSplit ; iApply main_help with Hk Hh H61 Hc ; exact Hname |
iSplit ; iApply main_extra with Hh Hc ; exact Hname |
iSplit ; iApply hint_exit with Hh Hc ; exact Hname | iExact Hj

Main from its entry to the greeting: the start block, the option loop and every exit of it but the greeting are proved, and only iw_1.join, entered with pr.2 clear and optind at argc, is left to the continuation. The version and help paths use up the literals and the program's name cells; the greeting needs neither.

2322Lemma main_to_join
∀ s0 srest r3 r4 x0 x1 y0 old c0 r80 cs0 a ix b61 r61 Φ
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 [ ] −∗ ptsversion_ps −∗ ptshelp_ps −∗ stringversion_literal"hello#str.61" b61 r61 101; 110; 95 −∗ ▷∀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 −∗ ∗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 −∗ operand_exitb4 b6 "iw_1.join"%string "iw_1.L60"%string λlose i ⇒ lose = 0 ∧ i = Z.of_natlengthsargs Φ −∗ WPERuninvocationmain_fn WIntZ.of_natlengthsargs; WPtrmkPtrav Objav : mexpr {Φ}
Proof 11 steps Qed
intros Hhd Hcs Hix
iIntros Hb Hs Ht Hlit Hcells Hks Hcod Hs80 Hv Hh H61 HK
iApply main_to_loop with Hb Hs Ht Hlit Hcells Hks Hcod Hs80 ; exact Hhd | exact Hcs | exact Hix |
iNext
iIntros e b4 b6 i k q new c′ Hf Hlit Hcells #Hl Hcod Hs80 Hy4 Hc4 Hl6 Hy6 Hy6′ Hc6 Hc6′
pose proof Hf as _ & _ & _ & _ & Hi & _
iDestruct big_sepL_elem_of_ _ 5 with Hl as Hk5 ; apply list_elem_of_In ; unfold locale_categories ; cbn ; repeat first left ; reflexivity | right |
iApply loop_exits with Hv Hh Hk5 H61 Hcells [-]
{exists s0, srest, i
auto
iApply HK $! e b4 b6 i k q new c′ Hf with Hlit Hl Hcod Hs80 Hy4 Hc4 Hl6 Hy6 Hy6′ Hc6 Hc6′