Fil-C on Nix

Filnix wiki

the formal campaign

rocq/theories/StringLogic.v

C strings in the program logic of Logic.v, and the triples of the libc string calls derived from Campaign 4's contracts.

string p b reg bytes owns a C string: the life of the object b that p's capability names, read-write or read-only, and its bytes from p's offset through the terminating NUL (byte_ps). Owning it in an interpreted state gives the contracts' readings of a string, terminated_length and c_string (string_facts). One byte of it can be lent out to a load (string_byte).

The triples are each contract's precondition read from owned pieces, and its postcondition handed back as owned pieces and bound results:

  • wp_strlen and wp_strchr, from strlen_contract and strchr_contract: pure calls, which change no memory and no world (pure_return), so the state interpretation holds again with the same ghost heap, over any registry and world;
  • wp_puts, from puts_contract: a call that writes its world's roots and may allocate, under the world interpretation stdio_wi: puts's rep and readiness, and the world's writable roots apart from the program's live objects. After a return, the frame for external calls (Logic.v's prefix_agrees) keeps the program's pieces and puts's prefix the world (puts_return_frame).

Each triple is stated at any call site, so a program uses it as a rule.

From iris.proofmode Require Import proofmode
From iris.base_logic.lib Require Import gen_heap
From iris.program_logic Require Import language weakestpre
From Stdlib Require Import ZArith Lia
From Stdlib Require String
From Nanofil Require Import Term Syntax Values Memory Runtime Ops Semantics Run Machine Panics StepRules ExternalCalls ExternalMachine Pieces Heap ContractFrame Language Logic
Open Scope Z_scope
Open Scope list_scope

Byte pieces

The pieces of the bytes xs from offset o of the object b.

41Definition byte_psb o : Z xs : listZ : listpiece × pval ≔
zip_withλi x ⇒ PByteb i, VBytex seqZo Z.of_natlengthxs xs

The first byte's piece, then the rest's.

45Lemma byte_ps_cons
∀ b o x xs
byte_psb o x :: xs = PByteb o, VBytex :: byte_psb o + 1 xs
Explore proof 5 tactics

Initial goal

b, o, x :
Z
xs :
listZ
⊢
byte_psb o x :: xs = PByteb o, VBytex :: byte_psb o + 1 xs

unfold byte_ps

b, o, x :
Z
xs :
listZ
⊢
zip_withλi x0 : Z ⇒ PByteb i, VBytex0 seqZo lengthx :: xs x :: xs = PByteb o, VBytex :: zip_withλi x0 : Z ⇒ PByteb i, VBytex0 seqZo + 1 lengthxs xs

cbn [ length ]

b, o, x :
Z
xs :
listZ
⊢
zip_withλi x0 : Z ⇒ PByteb i, VBytex0 seqZo Slengthxs x :: xs = PByteb o, VBytex :: zip_withλi x0 : Z ⇒ PByteb i, VBytex0 seqZo + 1 lengthxs xs

rewrite Nat2Z.inj_succ seqZ_cons ; | lia

b, o, x :
Z
xs :
listZ
⊢
zip_withλi x0 : Z ⇒ PByteb i, VBytex0 o :: seqZZ.succo Z.predZ.succlengthxs x :: xs = PByteb o, VBytex :: zip_withλi x0 : Z ⇒ PByteb i, VBytex0 seqZo + 1 lengthxs xs

rewrite Z.pred_succ

b, o, x :
Z
xs :
listZ
⊢
zip_withλi x0 : Z ⇒ PByteb i, VBytex0 o :: seqZZ.succo lengthxs x :: xs = PByteb o, VBytex :: zip_withλi x0 : Z ⇒ PByteb i, VBytex0 seqZo + 1 lengthxs xs

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
unfold byte_ps
cbn [ length ]
rewrite Nat2Z.inj_succ seqZ_cons ; | lia
rewrite Z.pred_succ
reflexivity

The i-th piece is the i-th byte's.

52Lemma byte_ps_lookup
∀ b o xs i x
xs !! i = Somex
byte_psb o xs !! i = SomePByteb o + Z.of_nati, VBytex
Explore proof 10 tactics

Initial goal

b, o :
Z
xs :
listZ
i :
nat
x :
Z
⊢
xs !! i = Somex → byte_psb o xs !! i = SomePByteb o + i, VBytex

revert o i

b :
Z
xs :
listZ
x :
Z
⊢
∀o : Z i : nat, xs !! i = Somex → byte_psb o xs !! i = SomePByteb o + i, VBytex

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

b, y :
Z
xs :
listZ
x :
Z
IH :
∀o : Z i : nat, xs !! i = Somex → byte_psb o xs !! i = SomePByteb o + i, VBytex
o :
Z
i :
nat
H :
y :: xs !! i = Somex
⊢
byte_psb o y :: xs !! i = SomePByteb o + i, VBytex

rewrite byte_ps_cons

b, y :
Z
xs :
listZ
x :
Z
IH :
∀o : Z i : nat, xs !! i = Somex → byte_psb o xs !! i = SomePByteb o + i, VBytex
o :
Z
i :
nat
H :
y :: xs !! i = Somex
⊢
PByteb o, VBytey :: byte_psb o + 1 xs !! i = SomePByteb o + i, VBytex

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

2 open

b, y :
Z
xs :
listZ
x :
Z
IH :
∀o : Z i : nat, xs !! i = Somex → byte_psb o xs !! i = SomePByteb o + i, VBytex
o :
Z
H :
Somey = Somex
⊢
SomePByteb o, VBytey = SomePByteb o + 0%nat, VBytex
focused goal
b, y :
Z
xs :
listZ
x :
Z
IH :
∀o : Z i : nat, xs !! i = Somex → byte_psb o xs !! i = SomePByteb o + i, VBytex
o :
Z
i :
nat
H :
xs !! i = Somex
⊢
byte_psb o + 1 xs !! i = SomePByteb o + Si, VBytex

–injection H as →

2 open

b :
Z
xs :
listZ
x :
Z
IH :
∀o : Z i : nat, xs !! i = Somex → byte_psb o xs !! i = SomePByteb o + i, VBytex
o :
Z
⊢
SomePByteb o, VBytex = SomePByteb o + 0%nat, VBytex
deferred goal
b, y :
Z
xs :
listZ
x :
Z
IH :
∀o : Z i : nat, xs !! i = Somex → byte_psb o xs !! i = SomePByteb o + i, VBytex
o :
Z
i :
nat
H :
xs !! i = Somex
⊢
byte_psb o + 1 xs !! i = SomePByteb o + Si, VBytex

rewrite Z.add_0_r

2 open

b :
Z
xs :
listZ
x :
Z
IH :
∀o : Z i : nat, xs !! i = Somex → byte_psb o xs !! i = SomePByteb o + i, VBytex
o :
Z
⊢
SomePByteb o, VBytex = SomePByteb o, VBytex
deferred goal
b, y :
Z
xs :
listZ
x :
Z
IH :
∀o : Z i : nat, xs !! i = Somex → byte_psb o xs !! i = SomePByteb o + i, VBytex
o :
Z
i :
nat
H :
xs !! i = Somex
⊢
byte_psb o + 1 xs !! i = SomePByteb o + Si, VBytex

reflexivity

deferred goal
b, y :
Z
xs :
listZ
x :
Z
IH :
∀o : Z i : nat, xs !! i = Somex → byte_psb o xs !! i = SomePByteb o + i, VBytex
o :
Z
i :
nat
H :
xs !! i = Somex
⊢
byte_psb o + 1 xs !! i = SomePByteb o + Si, VBytex

–rewrite IHo + 1 i H

b, y :
Z
xs :
listZ
x :
Z
IH :
∀o : Z i : nat, xs !! i = Somex → byte_psb o xs !! i = SomePByteb o + i, VBytex
o :
Z
i :
nat
H :
xs !! i = Somex
⊢
SomePByteb o + 1 + i, VBytex = SomePByteb o + Si, VBytex

do 3 f_equal

b, y :
Z
xs :
listZ
x :
Z
IH :
∀o : Z i : nat, xs !! i = Somex → byte_psb o xs !! i = SomePByteb o + i, VBytex
o :
Z
i :
nat
H :
xs !! i = Somex
⊢
o + 1 + i = o + Si

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
revert o i
induction xs as | y xs IH ; intros o i H ; discriminate |
rewrite byte_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

Where the pieces of xs from offset o of the live object b agree, each byte is in the object and holds its value.

63Lemma byte_ps_agree
∀ m b reg o xs i x
live_atm b reg
xs !! i = Somex
m_bytesm b + o + Z.of_nati = x ∧ 0 ≤ o + Z.of_nati ∧ b + o + Z.of_nati < r_endreg
Explore proof 4 tactics

Initial goal

m :
b :
Z
reg :
o :
Z
xs :
listZ
i :
nat
x :
Z
⊢
live_atm b reg → all_agreem byte_psb o xs → xs !! i = Somex → m_bytesm b + o + i = x ∧ 0 ≤ o + i ∧ b + o + i < r_endreg

intros E Lv Ha Hx

m :
b :
Z
reg :
o :
Z
xs :
listZ
i :
nat
x :
Z
E :
Lv :
r_lifereg = Live
Ha :
Hx :
xs !! i = Somex
⊢
m_bytesm b + o + i = x ∧ 0 ≤ o + i ∧ b + o + i < r_endreg

pose proof all_agree_elem_ _ _ _ Ha list_elem_of_lookup_2_ _ _ byte_ps_lookupb o xs i x Hx as _ Hin

m :
b :
Z
reg :
o :
Z
xs :
listZ
i :
nat
x :
Z
E :
Lv :
r_lifereg = Live
Ha :
Hx :
xs !! i = Somex
Hin :
in_livem b o + i m_bytesm b + o + i = x
⊢
m_bytesm b + o + i = x ∧ 0 ≤ o + i ∧ b + o + i < r_endreg

destruct Hinreg E Lv as Ho & He & Hv

m :
b :
Z
reg :
o :
Z
xs :
listZ
i :
nat
x :
Z
E :
Lv :
r_lifereg = Live
Ha :
Hx :
xs !! i = Somex
Hin :
in_livem b o + i m_bytesm b + o + i = x
Ho :
0 ≤ o + i
He :
b + o + i < r_endreg
Hv :
m_bytesm b + o + i = x
⊢
m_bytesm b + o + i = x ∧ 0 ≤ o + i ∧ b + o + i < r_endreg

auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros E Lv Ha Hx
pose proof all_agree_elem_ _ _ _ Ha list_elem_of_lookup_2_ _ _ byte_ps_lookupb o xs i x Hx as _ Hin
destruct Hinreg E Lv as Ho & He & Hv
auto

The bytes, nonzero, followed by a NUL, as the memory holds them from a, are a string_at a.

75Lemma string_at_of
∀ m a bytes
Forallλx ⇒ 0 < x < 256 bytes
∀i x, bytes ++ 0 !! i = Somex → m_bytesm a + Z.of_nati = x
string_atm a bytes
Explore proof 16 tactics

Initial goal

m :
a :
Z
bytes :
listZ
⊢
Forallλx : Z ⇒ 0 < x < 256 bytes → ∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm a + i = x → string_atm a bytes

revert a

m :
bytes :
listZ
⊢
∀a : Z, Forallλx : Z ⇒ 0 < x < 256 bytes → ∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm a + i = x → string_atm a bytes

induction bytes as | y bytes IH ; intros a Hf Hb

2 open

m :
a :
Z
Hf :
Forallλx : Z ⇒ 0 < x < 256 [ ]
Hb :
∀i : nat x : Z, [ ] ++ 0 !! i = Somex → m_bytesm a + i = x
⊢
string_atm a [ ]
focused goal
m :
y :
Z
bytes :
listZ
IH :
∀a : Z, Forallλx : Z ⇒ 0 < x < 256 bytes → ∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm a + i = x → string_atm a bytes
a :
Z
Hf :
Forallλx : Z ⇒ 0 < x < 256 y :: bytes
Hb :
∀i : nat x : Z, y :: bytes ++ 0 !! i = Somex → m_bytesm a + i = x
⊢
string_atm a y :: bytes

–cbn

2 open

m :
a :
Z
Hf :
Forallλx : Z ⇒ 0 < x < 256 [ ]
Hb :
∀i : nat x : Z, [ ] ++ 0 !! i = Somex → m_bytesm a + i = x
⊢
m_bytesm a = 0
deferred goal
m :
y :
Z
bytes :
listZ
IH :
∀a : Z, Forallλx : Z ⇒ 0 < x < 256 bytes → ∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm a + i = x → string_atm a bytes
a :
Z
Hf :
Forallλx : Z ⇒ 0 < x < 256 y :: bytes
Hb :
∀i : nat x : Z, y :: bytes ++ 0 !! i = Somex → m_bytesm a + i = x
⊢
string_atm a y :: bytes

rewrite <- Z.add_0_ra

2 open

m :
a :
Z
Hf :
Forallλx : Z ⇒ 0 < x < 256 [ ]
Hb :
∀i : nat x : Z, [ ] ++ 0 !! i = Somex → m_bytesm a + i = x
⊢
m_bytesm a + 0 = 0
deferred goal
m :
y :
Z
bytes :
listZ
IH :
∀a : Z, Forallλx : Z ⇒ 0 < x < 256 bytes → ∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm a + i = x → string_atm a bytes
a :
Z
Hf :
Forallλx : Z ⇒ 0 < x < 256 y :: bytes
Hb :
∀i : nat x : Z, y :: bytes ++ 0 !! i = Somex → m_bytesm a + i = x
⊢
string_atm a y :: bytes

exact Hb0%nat 0 eq_refl

deferred goal
m :
y :
Z
bytes :
listZ
IH :
∀a : Z, Forallλx : Z ⇒ 0 < x < 256 bytes → ∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm a + i = x → string_atm a bytes
a :
Z
Hf :
Forallλx : Z ⇒ 0 < x < 256 y :: bytes
Hb :
∀i : nat x : Z, y :: bytes ++ 0 !! i = Somex → m_bytesm a + i = x
⊢
string_atm a y :: bytes

–apply Forall_cons_1 in Hf as Hy Hf

m :
y :
Z
bytes :
listZ
IH :
∀a : Z, Forallλx : Z ⇒ 0 < x < 256 bytes → ∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm a + i = x → string_atm a bytes
a :
Z
Hy :
0 < y < 256
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hb :
∀i : nat x : Z, y :: bytes ++ 0 !! i = Somex → m_bytesm a + i = x
⊢
string_atm a y :: bytes

cbn

m :
y :
Z
bytes :
listZ
IH :
∀a : Z, Forallλx : Z ⇒ 0 < x < 256 bytes → ∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm a + i = x → string_atm a bytes
a :
Z
Hy :
0 < y < 256
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hb :
∀i : nat x : Z, y :: bytes ++ 0 !! i = Somex → m_bytesm a + i = x
⊢
0 < y < 256 ∧ m_bytesm a = y ∧ string_atm a + 1 bytes

split ; exact Hy |

m :
y :
Z
bytes :
listZ
IH :
∀a : Z, Forallλx : Z ⇒ 0 < x < 256 bytes → ∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm a + i = x → string_atm a bytes
a :
Z
Hy :
0 < y < 256
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hb :
∀i : nat x : Z, y :: bytes ++ 0 !! i = Somex → m_bytesm a + i = x
⊢
m_bytesm a = y ∧ string_atm a + 1 bytes

split

2 open

m :
y :
Z
bytes :
listZ
IH :
∀a : Z, Forallλx : Z ⇒ 0 < x < 256 bytes → ∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm a + i = x → string_atm a bytes
a :
Z
Hy :
0 < y < 256
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hb :
∀i : nat x : Z, y :: bytes ++ 0 !! i = Somex → m_bytesm a + i = x
⊢
m_bytesm a = y
focused goal
m :
y :
Z
bytes :
listZ
IH :
∀a : Z, Forallλx : Z ⇒ 0 < x < 256 bytes → ∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm a + i = x → string_atm a bytes
a :
Z
Hy :
0 < y < 256
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hb :
∀i : nat x : Z, y :: bytes ++ 0 !! i = Somex → m_bytesm a + i = x
⊢
string_atm a + 1 bytes

+rewrite <- Z.add_0_ra

2 open

m :
y :
Z
bytes :
listZ
IH :
∀a : Z, Forallλx : Z ⇒ 0 < x < 256 bytes → ∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm a + i = x → string_atm a bytes
a :
Z
Hy :
0 < y < 256
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hb :
∀i : nat x : Z, y :: bytes ++ 0 !! i = Somex → m_bytesm a + i = x
⊢
m_bytesm a + 0 = y
deferred goal
m :
y :
Z
bytes :
listZ
IH :
∀a : Z, Forallλx : Z ⇒ 0 < x < 256 bytes → ∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm a + i = x → string_atm a bytes
a :
Z
Hy :
0 < y < 256
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hb :
∀i : nat x : Z, y :: bytes ++ 0 !! i = Somex → m_bytesm a + i = x
⊢
string_atm a + 1 bytes

exact Hb0%nat y eq_refl

deferred goal
m :
y :
Z
bytes :
listZ
IH :
∀a : Z, Forallλx : Z ⇒ 0 < x < 256 bytes → ∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm a + i = x → string_atm a bytes
a :
Z
Hy :
0 < y < 256
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hb :
∀i : nat x : Z, y :: bytes ++ 0 !! i = Somex → m_bytesm a + i = x
⊢
string_atm a + 1 bytes

+apply IH ; exact Hf |

m :
y :
Z
bytes :
listZ
IH :
∀a : Z, Forallλx : Z ⇒ 0 < x < 256 bytes → ∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm a + i = x → string_atm a bytes
a :
Z
Hy :
0 < y < 256
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hb :
∀i : nat x : Z, y :: bytes ++ 0 !! i = Somex → m_bytesm a + i = x
⊢
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm a + 1 + i = x

intros i x Hx

m :
y :
Z
bytes :
listZ
IH :
∀a : Z, Forallλx : Z ⇒ 0 < x < 256 bytes → ∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm a + i = x → string_atm a bytes
a :
Z
Hy :
0 < y < 256
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hb :
∀i : nat x : Z, y :: bytes ++ 0 !! i = Somex → m_bytesm a + i = x
i :
nat
x :
Z
Hx :
bytes ++ 0 !! i = Somex
⊢
m_bytesm a + 1 + i = x

replace a + 1 + Z.of_nati with a + Z.of_natSi by lia

m :
y :
Z
bytes :
listZ
IH :
∀a : Z, Forallλx : Z ⇒ 0 < x < 256 bytes → ∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm a + i = x → string_atm a bytes
a :
Z
Hy :
0 < y < 256
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hb :
∀i : nat x : Z, y :: bytes ++ 0 !! i = Somex → m_bytesm a + i = x
i :
nat
x :
Z
Hx :
bytes ++ 0 !! i = Somex
⊢
m_bytesm a + Si = x

apply Hb

m :
y :
Z
bytes :
listZ
IH :
∀a : Z, Forallλx : Z ⇒ 0 < x < 256 bytes → ∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm a + i = x → string_atm a bytes
a :
Z
Hy :
0 < y < 256
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hb :
∀i : nat x : Z, y :: bytes ++ 0 !! i = Somex → m_bytesm a + i = x
i :
nat
x :
Z
Hx :
bytes ++ 0 !! i = Somex
⊢
y :: bytes ++ 0 !! Si = Somex

exact Hx

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
revert a
induction bytes as | y bytes IH ; intros a Hf Hb
–cbn
rewrite <- Z.add_0_ra
exact Hb0%nat 0 eq_refl
–apply Forall_cons_1 in Hf as Hy Hf
cbn
split ; exact Hy |
split
+rewrite <- Z.add_0_ra
exact Hb0%nat y eq_refl
+apply IH ; exact Hf |
intros i x Hx
replace a + 1 + Z.of_nati with a + Z.of_natSi by lia
apply Hb
exact Hx

The pieces of xs ++ ys are xs's, then ys's after them.

89Lemma byte_ps_app
∀ b o xs ys
byte_psb o xs ++ ys = byte_psb o xs ++ byte_psb o + Z.of_natlengthxs ys
Explore proof 7 tactics

Initial goal

b, o :
Z
xs, ys :
listZ
⊢
byte_psb o xs ++ ys = byte_psb o xs ++ byte_psb o + lengthxs ys

revert o

b :
Z
xs, ys :
listZ
⊢
∀o : Z, byte_psb o xs ++ ys = byte_psb o xs ++ byte_psb o + lengthxs ys

induction xs as | x xs IH ; intros o ; cbn ; rewrite Z.add_0_r ; reflexivity |

b, x :
Z
xs, ys :
listZ
IH :
∀o : Z, byte_psb o xs ++ ys = byte_psb o xs ++ byte_psb o + lengthxs ys
o :
Z
⊢
byte_psb o x :: xs ++ ys = byte_psb o x :: xs ++ byte_psb o + lengthx :: xs ys

cbn [ app ]

b, x :
Z
xs, ys :
listZ
IH :
∀o : Z, byte_psb o xs ++ ys = byte_psb o xs ++ byte_psb o + lengthxs ys
o :
Z
⊢
byte_psb o x :: xs ++ ys = byte_psb o x :: xs ++ byte_psb o + lengthx :: xs ys

rewrite ! byte_ps_cons IH

b, x :
Z
xs, ys :
listZ
IH :
∀o : Z, byte_psb o xs ++ ys = byte_psb o xs ++ byte_psb o + lengthxs ys
o :
Z
⊢
PByteb o, VBytex :: byte_psb o + 1 xs ++ byte_psb o + 1 + lengthxs ys = PByteb o, VBytex :: byte_psb o + 1 xs ++ byte_psb o + lengthx :: xs ys

cbn [ app length ]

b, x :
Z
xs, ys :
listZ
IH :
∀o : Z, byte_psb o xs ++ ys = byte_psb o xs ++ byte_psb o + lengthxs ys
o :
Z
⊢
PByteb o, VBytex :: byte_psb o + 1 xs ++ byte_psb o + 1 + lengthxs ys = PByteb o, VBytex :: byte_psb o + 1 xs ++ byte_psb o + Slengthxs ys

replace o + Z.of_natSlengthxs with o + 1 + Z.of_natlengthxs by lia

b, x :
Z
xs, ys :
listZ
IH :
∀o : Z, byte_psb o xs ++ ys = byte_psb o xs ++ byte_psb o + lengthxs ys
o :
Z
⊢
PByteb o, VBytex :: byte_psb o + 1 xs ++ byte_psb o + 1 + lengthxs ys = PByteb o, VBytex :: byte_psb o + 1 xs ++ byte_psb o + 1 + lengthxs ys

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
revert o
induction xs as | x xs IH ; intros o ; cbn ; rewrite Z.add_0_r ; reflexivity |
cbn [ app ]
rewrite ! byte_ps_cons IH
cbn [ app length ]
replace o + Z.of_natSlengthxs with o + 1 + Z.of_natlengthxs by lia
reflexivity

The pieces of xs are byte pieces at the offsets from o.

98Lemma byte_ps_keys
∀ b o xs
byte_psb o xs.*1 = PByteb <$> seqZo Z.of_natlengthxs
Explore proof 9 tactics

Initial goal

b, o :
Z
xs :
listZ
⊢
byte_psb o xs.*1 = PByteb <$> seqZo lengthxs

revert o

b :
Z
xs :
listZ
⊢
∀o : Z, byte_psb o xs.*1 = PByteb <$> seqZo lengthxs

induction xs as | x xs IH ; intros o ; reflexivity |

b, x :
Z
xs :
listZ
IH :
∀o : Z, byte_psb o xs.*1 = PByteb <$> seqZo lengthxs
o :
Z
⊢
byte_psb o x :: xs.*1 = PByteb <$> seqZo lengthx :: xs

rewrite byte_ps_cons

b, x :
Z
xs :
listZ
IH :
∀o : Z, byte_psb o xs.*1 = PByteb <$> seqZo lengthxs
o :
Z
⊢
PByteb o, VBytex :: byte_psb o + 1 xs.*1 = PByteb <$> seqZo lengthx :: xs

cbn [ fmap list_fmap fst ]

b, x :
Z
xs :
listZ
IH :
∀o : Z, byte_psb o xs.*1 = PByteb <$> seqZo lengthxs
o :
Z
⊢
PByteb o :: byte_psb o + 1 xs.*1 = PByteb <$> seqZo lengthx :: xs

rewrite IH

b, x :
Z
xs :
listZ
IH :
∀o : Z, byte_psb o xs.*1 = PByteb <$> seqZo lengthxs
o :
Z
⊢
PByteb o :: PByteb <$> seqZo + 1 lengthxs = PByteb <$> seqZo lengthx :: xs

cbn [ length ]

b, x :
Z
xs :
listZ
IH :
∀o : Z, byte_psb o xs.*1 = PByteb <$> seqZo lengthxs
o :
Z
⊢
PByteb o :: PByteb <$> seqZo + 1 lengthxs = PByteb <$> seqZo Slengthxs

rewrite Nat2Z.inj_succ seqZ_conso ; | lia

b, x :
Z
xs :
listZ
IH :
∀o : Z, byte_psb o xs.*1 = PByteb <$> seqZo lengthxs
o :
Z
⊢
PByteb o :: PByteb <$> seqZo + 1 lengthxs = PByteb <$> o :: seqZZ.succo Z.predZ.succlengthxs

rewrite Z.pred_succ

b, x :
Z
xs :
listZ
IH :
∀o : Z, byte_psb o xs.*1 = PByteb <$> seqZo lengthxs
o :
Z
⊢
PByteb o :: PByteb <$> seqZo + 1 lengthxs = PByteb <$> o :: seqZZ.succo lengthxs

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
revert o
induction xs as | x xs IH ; intros o ; reflexivity |
rewrite byte_ps_cons
cbn [ fmap list_fmap fst ]
rewrite IH
cbn [ length ]
rewrite Nat2Z.inj_succ seqZ_conso ; | lia
rewrite Z.pred_succ
reflexivity

Strings

The shape of a C string at p with contents bytes in the object b with the region reg: p's capability names b, read-write or read-only, at a positive base; the bytes and their NUL lie in the region, which ends within the address space; every byte is nonzero.

112Definition string_okp : ptr b : Z reg : region bytes : listZ : Prop ≔
ptr_capp = Objb ∨ ptr_capp = Rob ∧ 0 < b ∧ b ≤ ptr_addrp ∧ ptr_addrp + Z.of_natlengthbytes + 1 ≤ r_endreg ∧ r_endreg ≤ 2 ^ 48 ∧ Forallλx ⇒ 0 < x < 256 bytes

The pieces of the string: its object's life and its bytes from p's offset, NUL included.

119Definition string_psp : ptr b : Z reg : region bytes : listZ : listpiece × pval ≔
PLiveb, VLivereg :: byte_psb ptr_addrp − b bytes ++ 0

Where the string's pieces agree, the memory holds its bytes and NUL from p.

124Lemma string_bytes
∀ m p b reg bytes i x
string_okp b reg bytes
all_agreem string_psp b reg bytes
bytes ++ 0 !! i = Somex
m_bytesm ptr_addrp + Z.of_nati = x
Explore proof 5 tactics

Initial goal

m :
p :
b :
Z
reg :
bytes :
listZ
⊢
string_okp b reg bytes → all_agreem string_psp b reg bytes → ∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x

intros _ Hl Ha i x Hx

m :
p :
b :
Z
reg :
bytes :
listZ
Hl :
Ha :
all_agreem byte_psb ptr_addrp − b bytes ++ 0
i :
nat
x :
Z
Hx :
bytes ++ 0 !! i = Somex
⊢
m_bytesm ptr_addrp + i = x

cbn [ fst snd agree_piece ] in Hl

m :
p :
b :
Z
reg :
bytes :
listZ
Hl :
live_atm b reg
Ha :
all_agreem byte_psb ptr_addrp − b bytes ++ 0
i :
nat
x :
Z
Hx :
bytes ++ 0 !! i = Somex
⊢
m_bytesm ptr_addrp + i = x

destruct byte_ps_agree_ _ _ _ _ _ _ Hl Ha Hx as Hv _

m :
p :
b :
Z
reg :
bytes :
listZ
Hl :
live_atm b reg
Ha :
all_agreem byte_psb ptr_addrp − b bytes ++ 0
i :
nat
x :
Z
Hx :
bytes ++ 0 !! i = Somex
Hv :
m_bytesm b + ptr_addrp − b + i = x
⊢
m_bytesm ptr_addrp + i = x

replace ptr_addrp + Z.of_nati with b + ptr_addrp − b + Z.of_nati by lia

m :
p :
b :
Z
reg :
bytes :
listZ
Hl :
live_atm b reg
Ha :
all_agreem byte_psb ptr_addrp − b bytes ++ 0
i :
nat
x :
Z
Hx :
bytes ++ 0 !! i = Somex
Hv :
m_bytesm b + ptr_addrp − b + i = x
⊢
m_bytesm b + ptr_addrp − b + i = x

exact Hv

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros _ Hl Ha i x Hx
cbn [ fst snd agree_piece ] in Hl
destruct byte_ps_agree_ _ _ _ _ _ _ Hl Ha Hx as Hv _
replace ptr_addrp + Z.of_nati with b + ptr_addrp − b + Z.of_nati by lia
exact Hv

Where the string's pieces agree, p points at a terminated_length string of its length: Campaign 4's reading of a string.

135Lemma string_terminated
∀ m p b reg bytes
string_okp b reg bytes
all_agreem string_psp b reg bytes
terminated_lengthm p Z.of_natlengthbytes
Explore proof 22 tactics

Initial goal

m :
p :
b :
Z
reg :
bytes :
listZ
⊢
string_okp b reg bytes → all_agreem string_psp b reg bytes → terminated_lengthm p lengthbytes

intros Hok Ha

m :
p :
b :
Z
reg :
bytes :
listZ
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
⊢
terminated_lengthm p lengthbytes

pose proof string_bytesm p b reg bytes Hok Ha as Hb

m :
p :
b :
Z
reg :
bytes :
listZ
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
terminated_lengthm p lengthbytes

destruct Hok as Hc & H0 & H1 & H2 & H3 & Hf

m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Ha :
all_agreem string_psp b reg bytes
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
terminated_lengthm p lengthbytes

destruct Ha as E Lv _

m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
terminated_lengthm p lengthbytes

assert Hn : Z.of_natlengthbytes < 2 ^ 64 − 1 by lia

m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
⊢
terminated_lengthm p lengthbytes

split ; | exact Hn

m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
⊢
bounded_lengthm p 2 ^ 64 − 1 lengthbytes

split ; lia |

m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
⊢
0 ≤ lengthbytes ≤ 2 ^ 64 − 1
∧
∃base : Z reg0 : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg0 ∧ r_lifereg0 = Live
∧
lengthbytes
+
lengthbytes <? 2 ^ 64 − 1
→
1
else
0
1
=
Someok
∧
∀i : Z, 0 ≤ i < lengthbytes → 0 < m_bytesm ptr_addrp + i < 256 ∧ lengthbytes < 2 ^ 64 − 1 → m_bytesm ptr_addrp + lengthbytes = 0

split ; lia |

m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
⊢
∃base : Z reg0 : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg0 ∧ r_lifereg0 = Live
∧
lengthbytes
+
lengthbytes <? 2 ^ 64 − 1
→
1
else
0
1
=
Someok
∧
∀i : Z, 0 ≤ i < lengthbytes → 0 < m_bytesm ptr_addrp + i < 256 ∧ lengthbytes < 2 ^ 64 − 1 → m_bytesm ptr_addrp + lengthbytes = 0

split ; exists b, reg ; auto |

m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
⊢
lengthbytes
+
lengthbytes <? 2 ^ 64 − 1
→
1
else
0
1
=
Someok
∧
∀i : Z, 0 ≤ i < lengthbytes → 0 < m_bytesm ptr_addrp + i < 256 ∧ lengthbytes < 2 ^ 64 − 1 → m_bytesm ptr_addrp + lengthbytes = 0

replace Z.of_natlengthbytes <? 2 ^ 64 − 1 with true by symmetry ; apply Z.ltb_lt ; exact Hn

m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
⊢
access_resm ptr_addrp ptr_capp lengthbytes + 1 Read 1 = Someok ∧ ∀i : Z, 0 ≤ i < lengthbytes → 0 < m_bytesm ptr_addrp + i < 256 ∧ lengthbytes < 2 ^ 64 − 1 → m_bytesm ptr_addrp + lengthbytes = 0

split ; apply access_read_ b reg ; exact Hc | exact E | lia | lia | apply Z.mod_1_r |

m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
⊢
∀i : Z, 0 ≤ i < lengthbytes → 0 < m_bytesm ptr_addrp + i < 256 ∧ lengthbytes < 2 ^ 64 − 1 → m_bytesm ptr_addrp + lengthbytes = 0

split

2 open

m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
⊢
∀i : Z, 0 ≤ i < lengthbytes → 0 < m_bytesm ptr_addrp + i < 256
focused goal
m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
⊢
lengthbytes < 2 ^ 64 − 1 → m_bytesm ptr_addrp + lengthbytes = 0

–intros i Hi

2 open

m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
i :
Z
Hi :
0 ≤ i < lengthbytes
⊢
0 < m_bytesm ptr_addrp + i < 256
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
⊢
lengthbytes < 2 ^ 64 − 1 → m_bytesm ptr_addrp + lengthbytes = 0

destruct lookup_lt_is_Some_2bytes Z.to_nati ltac:lia as x Hx

2 open

m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
i :
Z
Hi :
0 ≤ i < lengthbytes
x :
Z
Hx :
bytes !! Z.to_nati = Somex
⊢
0 < m_bytesm ptr_addrp + i < 256
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
⊢
lengthbytes < 2 ^ 64 − 1 → m_bytesm ptr_addrp + lengthbytes = 0

rewrite <- Z2Nat.idi by lia

2 open

m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
i :
Z
Hi :
0 ≤ i < lengthbytes
x :
Z
Hx :
bytes !! Z.to_nati = Somex
⊢
0 < m_bytesm ptr_addrp + Z.to_nati < 256
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
⊢
lengthbytes < 2 ^ 64 − 1 → m_bytesm ptr_addrp + lengthbytes = 0

rewrite HbZ.to_nati x ; | by apply lookup_app_l_Some

2 open

m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
i :
Z
Hi :
0 ≤ i < lengthbytes
x :
Z
Hx :
bytes !! Z.to_nati = Somex
⊢
0 < x < 256
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
⊢
lengthbytes < 2 ^ 64 − 1 → m_bytesm ptr_addrp + lengthbytes = 0

exact Forall_lookup_1_ _ _ _ Hf Hx

deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
⊢
lengthbytes < 2 ^ 64 − 1 → m_bytesm ptr_addrp + lengthbytes = 0

–intros _

m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
⊢
m_bytesm ptr_addrp + lengthbytes = 0

apply Hblengthbytes 0

m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
⊢
bytes ++ 0 !! lengthbytes = Some0

rewrite lookup_app_r ; | lia

m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
⊢
0 !! lengthbytes − lengthbytes%nat = Some0

rewrite Nat.sub_diag

m :
p :
b :
Z
reg :
bytes :
listZ
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hn :
lengthbytes < 2 ^ 64 − 1
⊢
0 !! 0%nat = Some0

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hok Ha
pose proof string_bytesm p b reg bytes Hok Ha as Hb
destruct Hok as Hc & H0 & H1 & H2 & H3 & Hf
destruct Ha as E Lv _
assert Hn : Z.of_natlengthbytes < 2 ^ 64 − 1 by lia
split ; | exact Hn
split ; lia |
split ; lia |
split ; exists b, reg ; auto |
replace Z.of_natlengthbytes <? 2 ^ 64 − 1 with true by symmetry ; apply Z.ltb_lt ; exact Hn
split ; apply access_read_ b reg ; exact Hc | exact E | lia | lia | apply Z.mod_1_r |
split
–intros i Hi
destruct lookup_lt_is_Some_2bytes Z.to_nati ltac:lia as x Hx
rewrite <- Z2Nat.idi by lia
rewrite HbZ.to_nati x ; | by apply lookup_app_l_Some
exact Forall_lookup_1_ _ _ _ Hf Hx
–intros _
apply Hblengthbytes 0
rewrite lookup_app_r ; | lia
rewrite Nat.sub_diag
reflexivity

Where the string's pieces agree, p points at a c_string with contents bytes: puts's reading of a string.

154Lemma string_c_string
∀ m p b reg bytes
string_okp b reg bytes
all_agreem string_psp b reg bytes
c_stringm p bytes
Explore proof 7 tactics

Initial goal

m :
p :
b :
Z
reg :
bytes :
listZ
⊢
string_okp b reg bytes → all_agreem string_psp b reg bytes → c_stringm p bytes

intros Hok Ha

m :
p :
b :
Z
reg :
bytes :
listZ
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
⊢
c_stringm p bytes

pose proof string_bytesm p b reg bytes Hok Ha as Hb

m :
p :
b :
Z
reg :
bytes :
listZ
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
c_stringm p bytes

pose proof Hok as Hc & _ & H1 & H2 & _ & Hf

m :
p :
b :
Z
reg :
bytes :
listZ
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
⊢
c_stringm p bytes

destruct Ha as E _ _

m :
p :
b :
Z
reg :
bytes :
listZ
Hok :
string_okp b reg bytes
E :
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
⊢
c_stringm p bytes

split

2 open

m :
p :
b :
Z
reg :
bytes :
listZ
Hok :
string_okp b reg bytes
E :
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
⊢
access_resm ptr_addrp ptr_capp lengthbytes + 1 Read 1 = Someok
focused goal
m :
p :
b :
Z
reg :
bytes :
listZ
Hok :
string_okp b reg bytes
E :
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
⊢

–apply access_read_ b reg ; exact Hc | exact E | lia | lia | apply Z.mod_1_r

deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
Hok :
string_okp b reg bytes
E :
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
⊢

–apply string_at_of ; exact Hf | exact Hb

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hok Ha
pose proof string_bytesm p b reg bytes Hok Ha as Hb
pose proof Hok as Hc & _ & H1 & H2 & _ & Hf
destruct Ha as E _ _
split
–apply access_read_ b reg ; exact Hc | exact E | lia | lia | apply Z.mod_1_r
–apply string_at_of ; exact Hf | exact Hb

No piece of a string is listed twice.

164Lemma string_ps_nodup
∀ p b reg bytes
NoDupstring_psp b reg bytes.*1
Explore proof 8 tactics

Initial goal

p :
b :
Z
reg :
bytes :
listZ
⊢
NoDupstring_psp b reg bytes.*1

unfold string_ps

p :
b :
Z
reg :
bytes :
listZ
⊢
NoDupPLiveb, VLivereg :: byte_psb ptr_addrp − b bytes ++ 0.*1

cbn [ fmap list_fmap fst ]

p :
b :
Z
reg :
bytes :
listZ
⊢
NoDupPLiveb :: byte_psb ptr_addrp − b bytes ++ 0.*1

rewrite byte_ps_keys

p :
b :
Z
reg :
bytes :
listZ
⊢
NoDupPLiveb :: PByteb <$> seqZptr_addrp − b lengthbytes ++ 0

apply NoDup_cons_2

2 open

p :
b :
Z
reg :
bytes :
listZ
⊢
PLiveb ∉ PByteb <$> seqZptr_addrp − b lengthbytes ++ 0
focused goal
p :
b :
Z
reg :
bytes :
listZ
⊢
NoDupPByteb <$> seqZptr_addrp − b lengthbytes ++ 0

–rewrite list_elem_of_fmap

2 open

p :
b :
Z
reg :
bytes :
listZ
⊢
¬∃x : Z, PLiveb = PByteb x ∧ x ∈ seqZptr_addrp − b lengthbytes ++ 0
deferred goal
p :
b :
Z
reg :
bytes :
listZ
⊢
NoDupPByteb <$> seqZptr_addrp − b lengthbytes ++ 0

intros o & E & _

2 open

p :
b :
Z
reg :
bytes :
listZ
o :
Z
E :
PLiveb = PByteb o
⊢
False
deferred goal
p :
b :
Z
reg :
bytes :
listZ
⊢
NoDupPByteb <$> seqZptr_addrp − b lengthbytes ++ 0

discriminate E

deferred goal
p :
b :
Z
reg :
bytes :
listZ
⊢
NoDupPByteb <$> seqZptr_addrp − b lengthbytes ++ 0

–apply NoDup_fmap_2 ; intros x y E ; injection E as → ; reflexivity | apply NoDup_seqZ

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
unfold string_ps
cbn [ fmap list_fmap fst ]
rewrite byte_ps_keys
apply NoDup_cons_2
–rewrite list_elem_of_fmap
intros o & E & _
discriminate E
–apply NoDup_fmap_2 ; intros x y E ; injection E as → ; reflexivity | apply NoDup_seqZ

Every piece of a string is of its object.

172Lemma string_ps_id
∀ p b reg bytes l v
l, v ∈ string_psp b reg bytes
piece_idl = b
Explore proof 8 tactics

Initial goal

p :
b :
Z
reg :
bytes :
listZ
v :
⊢
l, v ∈ string_psp b reg bytes → piece_idl = b

unfold string_ps

p :
b :
Z
reg :
bytes :
listZ
v :
⊢
l, v ∈ PLiveb, VLivereg :: byte_psb ptr_addrp − b bytes ++ 0 → piece_idl = b

rewrite elem_of_cons

p :
b :
Z
reg :
bytes :
listZ
v :
⊢
l, v = PLiveb, VLivereg ∨ l, v ∈ byte_psb ptr_addrp − b bytes ++ 0 → piece_idl = b

intros H | H ; injection H as → _ ; reflexivity |

p :
b :
Z
reg :
bytes :
listZ
v :
H :
l, v ∈ byte_psb ptr_addrp − b bytes ++ 0
⊢
piece_idl = b

apply list_elem_of_fmap_2fst in H

p :
b :
Z
reg :
bytes :
listZ
v :
H :
l, v.1 ∈ byte_psb ptr_addrp − b bytes ++ 0.*1
⊢
piece_idl = b

cbn [ fst ] in H

p :
b :
Z
reg :
bytes :
listZ
v :
H :
l ∈ byte_psb ptr_addrp − b bytes ++ 0.*1
⊢
piece_idl = b

rewrite byte_ps_keys in H

p :
b :
Z
reg :
bytes :
listZ
v :
H :
l ∈ PByteb <$> seqZptr_addrp − b lengthbytes ++ 0
⊢
piece_idl = b

apply list_elem_of_fmap in H as o & → & _

p :
b :
Z
reg :
bytes :
listZ
v :
o :
Z
⊢

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
unfold string_ps
rewrite elem_of_cons
intros H | H ; injection H as → _ ; reflexivity |
apply list_elem_of_fmap_2fst in H
cbn [ fst ] in H
rewrite byte_ps_keys in H
apply list_elem_of_fmap in H as o & → & _
reflexivity

Every piece of a string is a piece of memory.

180Lemma string_ps_mem
∀ p b reg bytes l v
l, v ∈ string_psp b reg bytes
Explore proof 8 tactics

Initial goal

p :
b :
Z
reg :
bytes :
listZ
v :
⊢
l, v ∈ string_psp b reg bytes → mem_piecel

unfold string_ps

p :
b :
Z
reg :
bytes :
listZ
v :
⊢
l, v ∈ PLiveb, VLivereg :: byte_psb ptr_addrp − b bytes ++ 0 → mem_piecel

rewrite elem_of_cons

p :
b :
Z
reg :
bytes :
listZ
v :
⊢
l, v = PLiveb, VLivereg ∨ l, v ∈ byte_psb ptr_addrp − b bytes ++ 0 → mem_piecel

intros H | H ; injection H as → _ ; exact I |

p :
b :
Z
reg :
bytes :
listZ
v :
H :
l, v ∈ byte_psb ptr_addrp − b bytes ++ 0

apply list_elem_of_fmap_2fst in H

p :
b :
Z
reg :
bytes :
listZ
v :
H :
l, v.1 ∈ byte_psb ptr_addrp − b bytes ++ 0.*1

cbn [ fst ] in H

p :
b :
Z
reg :
bytes :
listZ
v :
H :
l ∈ byte_psb ptr_addrp − b bytes ++ 0.*1

rewrite byte_ps_keys in H

p :
b :
Z
reg :
bytes :
listZ
v :
H :
l ∈ PByteb <$> seqZptr_addrp − b lengthbytes ++ 0

apply list_elem_of_fmap in H as o & → & _

p :
b :
Z
reg :
bytes :
listZ
v :
o :
Z

exact I

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
unfold string_ps
rewrite elem_of_cons
intros H | H ; injection H as → _ ; exact I |
apply list_elem_of_fmap_2fst in H
cbn [ fst ] in H
rewrite byte_ps_keys in H
apply list_elem_of_fmap in H as o & → & _
exact I

The suffix of the string p from its i-th byte, at q: the pieces of the string are its life, the bytes before q, and the pieces of the suffix's bytes, which are the string at q's.

190Lemma string_ps_suffix
∀ p b reg bytes i
i ≤ lengthbytes%nat
let q ≔ mkPtrptr_addrp + Z.of_nati ptr_capp in
string_psp b reg bytes = PLiveb, VLivereg :: byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrq − b dropi bytes ++ 0 ∧ string_psq b reg dropi bytes = PLiveb, VLivereg :: byte_psb ptr_addrq − b dropi bytes ++ 0
Explore proof 9 tactics

Initial goal

p :
b :
Z
reg :
bytes :
listZ
i :
nat
⊢
i ≤ lengthbytes%nat
→
let q ≔ ptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp in
string_psp b reg bytes = PLiveb, VLivereg :: byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrq − b dropi bytes ++ 0 ∧ string_psq b reg dropi bytes = PLiveb, VLivereg :: byte_psb ptr_addrq − b dropi bytes ++ 0

intros Hi q

p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
q :=
ptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp : ptr
⊢
string_psp b reg bytes = PLiveb, VLivereg :: byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrq − b dropi bytes ++ 0 ∧ string_psq b reg dropi bytes = PLiveb, VLivereg :: byte_psb ptr_addrq − b dropi bytes ++ 0

split ; | reflexivity

p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
q :=
ptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp : ptr
⊢
string_psp b reg bytes = PLiveb, VLivereg :: byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrq − b dropi bytes ++ 0

unfold string_ps

p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
q :=
ptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp : ptr
⊢
PLiveb, VLivereg :: byte_psb ptr_addrp − b bytes ++ 0 = PLiveb, VLivereg :: byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrq − b dropi bytes ++ 0

f_equal

p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
q :=
ptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp : ptr
⊢
byte_psb ptr_addrp − b bytes ++ 0 = byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrq − b dropi bytes ++ 0

rewrite <- take_dropi bytes at 1

p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
q :=
ptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp : ptr
⊢
byte_psb ptr_addrp − b takei bytes ++ dropi bytes ++ 0 = byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrq − b dropi bytes ++ 0

rewrite <- app_assoc , byte_ps_app , length_take

p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
q :=
ptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp : ptr
⊢
byte_ps b (ptr_addr p - b) (take i bytes) ++ byte_ps b (ptr_addr p - b + (i `min` length bytes)%nat) (drop i bytes ++ [0]) = byte_ps b (ptr_addr p - b) (take i bytes) ++ byte_ps b (ptr_addr q - b) (drop i bytes ++ [0])

cbn [ ptr_addr q ]

p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
q :=
ptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp : ptr
⊢
byte_ps b (ptr_addr p - b) (take i bytes) ++ byte_ps b (ptr_addr p - b + (i `min` length bytes)%nat) (drop i bytes ++ [0]) = byte_ps b (ptr_addr p - b) (take i bytes) ++ byte_ps b (ptr_addr p + i - b) (drop i bytes ++ [0])

replace ptr_addrp − b + Z.of_natNat.mini lengthbytes with ptr_addrp + Z.of_nati − b by lia

p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
q :=
ptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp : ptr
⊢
byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrp + i − b dropi bytes ++ 0 = byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrp + i − b dropi bytes ++ 0

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hi q
split ; | reflexivity
unfold string_ps
f_equal
rewrite <- take_dropi bytes at 1
rewrite <- app_assoc , byte_ps_app , length_take
cbn [ ptr_addr q ]
replace ptr_addrp − b + Z.of_natNat.mini lengthbytes with ptr_addrp + Z.of_nati − b by lia
reflexivity

The suffix of a string from a byte before its NUL is a string.

205Lemma string_ok_suffix
∀ p b reg bytes i
i ≤ lengthbytes%nat
string_okp b reg bytes
string_okmkPtrptr_addrp + Z.of_nati ptr_capp b reg dropi bytes
Explore proof 11 tactics

Initial goal

p :
b :
Z
reg :
bytes :
listZ
i :
nat
⊢
i ≤ lengthbytes%nat → string_okp b reg bytes → string_okptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes

intros Hi Hc & H0 & H1 & H2 & H3 & Hf

p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
⊢
string_okptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes

unfold string_ok

p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
⊢
ptr_capptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp = Objb ∨ ptr_capptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp = Rob ∧ 0 < b ∧ b ≤ ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp ∧ ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp + lengthdropi bytes + 1 ≤ r_endreg ∧ r_endreg ≤ 2 ^ 48 ∧ Forallλx : Z ⇒ 0 < x < 256 dropi bytes

cbn [ ptr_addr ptr_cap ]

p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
⊢
ptr_capp = Objb ∨ ptr_capp = Rob ∧ 0 < b ∧ b ≤ ptr_addrp + i ∧ ptr_addrp + i + lengthdropi bytes + 1 ≤ r_endreg ∧ r_endreg ≤ 2 ^ 48 ∧ Forallλx : Z ⇒ 0 < x < 256 dropi bytes

rewrite length_drop

p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
⊢
ptr_capp = Objb ∨ ptr_capp = Rob ∧ 0 < b ∧ b ≤ ptr_addrp + i ∧ ptr_addrp + i + lengthbytes − i%nat + 1 ≤ r_endreg ∧ r_endreg ≤ 2 ^ 48 ∧ Forallλx : Z ⇒ 0 < x < 256 dropi bytes

split ; exact Hc |

p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
⊢
0 < b ∧ b ≤ ptr_addrp + i ∧ ptr_addrp + i + lengthbytes − i%nat + 1 ≤ r_endreg ∧ r_endreg ≤ 2 ^ 48 ∧ Forallλx : Z ⇒ 0 < x < 256 dropi bytes

split ; exact H0 |

p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
⊢
b ≤ ptr_addrp + i ∧ ptr_addrp + i + lengthbytes − i%nat + 1 ≤ r_endreg ∧ r_endreg ≤ 2 ^ 48 ∧ Forallλx : Z ⇒ 0 < x < 256 dropi bytes

split ; lia |

p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
⊢
ptr_addrp + i + lengthbytes − i%nat + 1 ≤ r_endreg ∧ r_endreg ≤ 2 ^ 48 ∧ Forallλx : Z ⇒ 0 < x < 256 dropi bytes

split ; lia |

p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
⊢
r_endreg ≤ 2 ^ 48 ∧ Forallλx : Z ⇒ 0 < x < 256 dropi bytes

split ; exact H3 |

p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
⊢
Forallλx : Z ⇒ 0 < x < 256 dropi bytes

apply Forall_drop

p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
⊢
Forallλx : Z ⇒ 0 < x < 256 bytes

exact Hf

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hi Hc & H0 & H1 & H2 & H3 & Hf
unfold string_ok
rewrite length_drop
split ; exact Hc |
split ; exact H0 |
split ; lia |
split ; lia |
split ; exact H3 |
apply Forall_drop
exact Hf

The stdio world

The world interpretation of a program that calls puts: puts's representation rep and stdio_ready of the world w in m, and the world's writable roots apart from the live objects owning pieces of the ghost heap h.

220Definition stdio_wirep : mem → stdio_world → Prop m : mem w : stdio_world h : gmappiece pval : Prop ≔
repm w ∧ stdio_readym w ∧ roots_apartstdio_rootsw h m

C strings and the string calls over any runtime R.

225Module StringLogicOn R : Runtime LG0 : LogicSigR
226Module LG ≔ LG0
227Module L ≔ LG.L
Import L LG

A safepoint keeps stdio_wi where it keeps rep and readiness: the roots stay apart since no region changes (collector_live).

232Lemma stdio_wi_safepoint
∀ rep : mem → stdio_world → Prop
∀s m s′ m′ w, R.safepoints m s′ m′ → repm w → stdio_readym w → repm′ w ∧ stdio_readym′ w
Explore proof 14 tactics

Initial goal

rep :
mem → stdio_world → Prop
⊢
∀s : R.state m : mem s′ : R.state m′ : mem w : stdio_world, R.safepoints m s′ m′ → repm w → stdio_readym w → repm′ w ∧ stdio_readym′ w → SafepointStablestdio_wirep

intros Hst

rep :
mem → stdio_world → Prop
Hst :
∀s : R.state m : mem s′ : R.state m′ : mem w : stdio_world, R.safepoints m s′ m′ → repm w → stdio_readym w → repm′ w ∧ stdio_readym′ w

split

rep :
mem → stdio_world → Prop
Hst :
∀s : R.state m : mem s′ : R.state m′ : mem w : stdio_world, R.safepoints m s′ m′ → repm w → stdio_readym w → repm′ w ∧ stdio_readym′ w
⊢
∀s : R.state m : mem s′ : R.state m′ : mem w : stdio_world h : gmappiece pval, R.safepoints m s′ m′ → stdio_wirep m w h → stdio_wirep m′ w h

intros s m s′ m′ w h Hsp Hr & Hw & Ha

rep :
mem → stdio_world → Prop
Hst :
∀s : R.state m : mem s′ : R.state m′ : mem w : stdio_world, R.safepoints m s′ m′ → repm w → stdio_readym w → repm′ w ∧ stdio_readym′ w
s :
R.state
m :
s′ :
R.state
m′ :
h :
Hsp :
R.safepoints m s′ m′
Hr :
repm w
⊢
stdio_wirep m′ w h

destruct Hst_ _ _ _ _ Hsp Hr Hw as Hr′ Hw′

rep :
mem → stdio_world → Prop
Hst :
∀s : R.state m : mem s′ : R.state m′ : mem w : stdio_world, R.safepoints m s′ m′ → repm w → stdio_readym w → repm′ w ∧ stdio_readym′ w
s :
R.state
m :
s′ :
R.state
m′ :
h :
Hsp :
R.safepoints m s′ m′
Hr :
repm w
Hr′ :
repm′ w
Hw′ :
⊢
stdio_wirep m′ w h

split ; exact Hr′ |

rep :
mem → stdio_world → Prop
Hst :
∀s : R.state m : mem s′ : R.state m′ : mem w : stdio_world, R.safepoints m s′ m′ → repm w → stdio_readym w → repm′ w ∧ stdio_readym′ w
s :
R.state
m :
s′ :
R.state
m′ :
h :
Hsp :
R.safepoints m s′ m′
Hr :
repm w
Hr′ :
repm′ w
Hw′ :
⊢

split ; exact Hw′ |

rep :
mem → stdio_world → Prop
Hst :
∀s : R.state m : mem s′ : R.state m′ : mem w : stdio_world, R.safepoints m s′ m′ → repm w → stdio_readym w → repm′ w ∧ stdio_readym′ w
s :
R.state
m :
s′ :
R.state
m′ :
h :
Hsp :
R.safepoints m s′ m′
Hr :
repm w
Hr′ :
repm′ w
Hw′ :

intros sp a Hin Hs l & v & reg & Hl & Hm & E Hlive & Hb

rep :
mem → stdio_world → Prop
Hst :
∀s : R.state m : mem s′ : R.state m′ : mem w : stdio_world, R.safepoints m s′ m′ → repm w → stdio_readym w → repm′ w ∧ stdio_readym′ w
s :
R.state
m :
s′ :
R.state
m′ :
h :
Hsp :
R.safepoints m s′ m′
Hr :
repm w
Hr′ :
repm′ w
Hw′ :
sp :
a :
Z
Hin :
v :
reg :
Hl :
h !! l = Somev
E :
Hlive :
r_lifereg = Live
Hb :
piece_idl ≤ a < r_endreg
⊢
False

apply Hasp a Hin Hs

rep :
mem → stdio_world → Prop
Hst :
∀s : R.state m : mem s′ : R.state m′ : mem w : stdio_world, R.safepoints m s′ m′ → repm w → stdio_readym w → repm′ w ∧ stdio_readym′ w
s :
R.state
m :
s′ :
R.state
m′ :
h :
Hsp :
R.safepoints m s′ m′
Hr :
repm w
Hr′ :
repm′ w
Hw′ :
sp :
a :
Z
Hin :
v :
reg :
Hl :
h !! l = Somev
E :
Hlive :
r_lifereg = Live
Hb :
piece_idl ≤ a < r_endreg
⊢

rewrite R.collector_live_ _ _ _ Hsp in E

rep :
mem → stdio_world → Prop
Hst :
∀s : R.state m : mem s′ : R.state m′ : mem w : stdio_world, R.safepoints m s′ m′ → repm w → stdio_readym w → repm′ w ∧ stdio_readym′ w
s :
R.state
m :
s′ :
R.state
m′ :
h :
Hsp :
R.safepoints m s′ m′
Hr :
repm w
Hr′ :
repm′ w
Hw′ :
sp :
a :
Z
Hin :
v :
reg :
Hl :
h !! l = Somev
Hlive :
r_lifereg = Live
Hb :
piece_idl ≤ a < r_endreg
⊢

exists l, v, reg

rep :
mem → stdio_world → Prop
Hst :
∀s : R.state m : mem s′ : R.state m′ : mem w : stdio_world, R.safepoints m s′ m′ → repm w → stdio_readym w → repm′ w ∧ stdio_readym′ w
s :
R.state
m :
s′ :
R.state
m′ :
h :
Hsp :
R.safepoints m s′ m′
Hr :
repm w
Hr′ :
repm′ w
Hw′ :
sp :
a :
Z
Hin :
v :
reg :
Hl :
h !! l = Somev
Hlive :
r_lifereg = Live
Hb :
piece_idl ≤ a < r_endreg
⊢
h !! l = Somev ∧ mem_piecel ∧ live_atm piece_idl reg ∧ piece_idl ≤ a < r_endreg

split ; exact Hl |

rep :
mem → stdio_world → Prop
Hst :
∀s : R.state m : mem s′ : R.state m′ : mem w : stdio_world, R.safepoints m s′ m′ → repm w → stdio_readym w → repm′ w ∧ stdio_readym′ w
s :
R.state
m :
s′ :
R.state
m′ :
h :
Hsp :
R.safepoints m s′ m′
Hr :
repm w
Hr′ :
repm′ w
Hw′ :
sp :
a :
Z
Hin :
v :
reg :
Hl :
h !! l = Somev
Hlive :
r_lifereg = Live
Hb :
piece_idl ≤ a < r_endreg
⊢
mem_piecel ∧ live_atm piece_idl reg ∧ piece_idl ≤ a < r_endreg

split ; exact Hm |

rep :
mem → stdio_world → Prop
Hst :
∀s : R.state m : mem s′ : R.state m′ : mem w : stdio_world, R.safepoints m s′ m′ → repm w → stdio_readym w → repm′ w ∧ stdio_readym′ w
s :
R.state
m :
s′ :
R.state
m′ :
h :
Hsp :
R.safepoints m s′ m′
Hr :
repm w
Hr′ :
repm′ w
Hw′ :
sp :
a :
Z
Hin :
v :
reg :
Hl :
h !! l = Somev
Hlive :
r_lifereg = Live
Hb :
piece_idl ≤ a < r_endreg
⊢
live_atm piece_idl reg ∧ piece_idl ≤ a < r_endreg

split ; | exact Hb

rep :
mem → stdio_world → Prop
Hst :
∀s : R.state m : mem s′ : R.state m′ : mem w : stdio_world, R.safepoints m s′ m′ → repm w → stdio_readym w → repm′ w ∧ stdio_readym′ w
s :
R.state
m :
s′ :
R.state
m′ :
h :
Hsp :
R.safepoints m s′ m′
Hr :
repm w
Hr′ :
repm′ w
Hw′ :
sp :
a :
Z
Hin :
v :
reg :
Hl :
h !! l = Somev
Hlive :
r_lifereg = Live
Hb :
piece_idl ≤ a < r_endreg
⊢

split ; exact E | exact Hlive

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hst
split
intros s m s′ m′ w h Hsp Hr & Hw & Ha
destruct Hst_ _ _ _ _ Hsp Hr Hw as Hr′ Hw′
split ; exact Hr′ |
split ; exact Hw′ |
intros sp a Hin Hs l & v & reg & Hl & Hm & E Hlive & Hb
apply Hasp a Hin Hs
rewrite R.collector_live_ _ _ _ Hsp in E
exists l, v, reg
split ; exact Hl |
split ; exact Hm |
split ; | exact Hb
split ; exact E | exact Hlive

A puts call returns one int.

247Lemma puts_returns_int
∀ rep requests r args xs s m w trace values s′ m′ w′
M.E.invokeputs_contractrep requests r args xs s m w trace CallReturnvalues s′ m′ w′
∃n, values = WIntn
Explore proof 7 tactics

Initial goal

rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
args :
listarg
xs :
listword
s :
R.state
m :
trace :
listevent
values :
listword
s′ :
R.state
m′ :
⊢
M.E.invokeputs_contractrep requests r args xs s m w trace CallReturnvalues s′ m′ w′ → ∃n : Z, values = WIntn

intros Hi

rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
args :
listarg
xs :
listword
s :
R.state
m :
trace :
listevent
values :
listword
s′ :
R.state
m′ :
Hi :
M.E.invokeputs_contractrep requests r args xs s m w trace CallReturnvalues s′ m′ w′
⊢
∃n : Z, values = WIntn

remember CallReturnvalues as en eqn: Een

rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
args :
listarg
xs :
listword
s :
R.state
m :
trace :
listevent
values :
listword
s′ :
R.state
m′ :
Een :
en = CallReturnvalues
Hi :
M.E.invokeputs_contractrep requests r args xs s m w trace en s′ m′ w′
⊢
∃n : Z, values = WIntn

destruct Hi as ? ? ? ? ? ? _ _ _ Hp | ? ? ? ? ? ? _ _ _ _ _ ; | discriminate Een

rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
args :
listarg
xs :
listword
s :
R.state
m :
values :
listword
ending :
Een :
ending = CallReturnvalues
trace :
listevent
s′ :
R.state
m′ :
born :
listZ
Hp :
contract_postputs_contractrep requests xs m w born trace ending m′ w′
H :
∀why : reason, ending ≠ CallResourcewhy
H0 :
∀values : listword, ending = CallReturnvalues → return_shapecontract_returnsputs_contractrep requests values ∧ Forallword_authoritycontract_sourcesputs_contractrep requests xs m w born m′ values
H1 :
∀status : Z, ending = CallExitstatus → ∃before : listevent, trace = before ++ ProcessExitstatus
⊢
∃n : Z, values = WIntn

destruct Hp as p & bytes & acc & tail & n & _ & _ & _ & _ & _ & Hend & _

rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
args :
listarg
xs :
listword
s :
R.state
m :
values :
listword
ending :
Een :
ending = CallReturnvalues
trace :
listevent
s′ :
R.state
m′ :
born :
listZ
p :
bytes, acc, tail :
listZ
n :
Z
Hend :
ending = CallReturnWIntn
H :
∀why : reason, ending ≠ CallResourcewhy
H0 :
∀values : listword, ending = CallReturnvalues → return_shapecontract_returnsputs_contractrep requests values ∧ Forallword_authoritycontract_sourcesputs_contractrep requests xs m w born m′ values
H1 :
∀status : Z, ending = CallExitstatus → ∃before : listevent, trace = before ++ ProcessExitstatus
⊢
∃n0 : Z, values = WIntn0

subst

rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
args :
listarg
xs :
listword
s :
R.state
m :
values :
listword
trace :
listevent
s′ :
R.state
m′ :
born :
listZ
p :
bytes, acc, tail :
listZ
n :
Z
H1 :
∀status : Z, CallReturnvalues = CallExitstatus → ∃before : listevent, trace = before ++ ProcessExitstatus
H0 :
∀values0 : listword, CallReturnvalues = CallReturnvalues0 → return_shapecontract_returnsputs_contractrep requests values0 ∧ Forallword_authoritycontract_sourcesputs_contractrep requests xs m w born m′ values0
H :
∀why : reason, CallReturnvalues ≠ CallResourcewhy
Hend :
⊢
∃n0 : Z, values = WIntn0

injection Hend as →

rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
args :
listarg
xs :
listword
s :
R.state
m :
trace :
listevent
s′ :
R.state
m′ :
born :
listZ
p :
bytes, acc, tail :
listZ
n :
Z
H :
∀why : reason, CallReturnWIntn ≠ CallResourcewhy
H0 :
∀values : listword, CallReturnWIntn = CallReturnvalues → return_shapecontract_returnsputs_contractrep requests values ∧ Forallword_authoritycontract_sourcesputs_contractrep requests xs m w born m′ values
H1 :
∀status : Z, CallReturnWIntn = CallExitstatus → ∃before : listevent, trace = before ++ ProcessExitstatus
⊢
∃n0 : Z, WIntn = WIntn0

eauto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hi
remember CallReturnvalues as en eqn: Een
destruct Hi as ? ? ? ? ? ? _ _ _ Hp | ? ? ? ? ? ? _ _ _ _ _ ; | discriminate Een
destruct Hp as p & bytes & acc & tail & n & _ & _ & _ & _ & _ & Hend & _
subst
injection Hend as →
eauto

After a puts call that returns, from a state interpreted with the ghost heap h, the state is interpreted with h again: puts's prefix keeps the runtime ready, the frame keeps h agreeing and live objects apart, and the prefix gives rep and readiness of the new world, whose roots it delegated from the old roots and its born objects, so they stay apart from h.

263Lemma puts_return_frame
∀ rep requests r args xs s m w trace values s′ m′ w′ h
M.E.invokeputs_contractrep requests r args xs s m w trace CallReturnvalues s′ m′ w′
R.readys m
stdio_wirep m w h
agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ stdio_wirep m′ w′ h
Explore proof 12 tactics

Initial goal

rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
args :
listarg
xs :
listword
s :
R.state
m :
trace :
listevent
values :
listword
s′ :
R.state
m′ :
h :
⊢
M.E.invokeputs_contractrep requests r args xs s m w trace CallReturnvalues s′ m′ w′ → agreesm h → live_disjointm → R.readys m → stdio_wirep m w h → agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ stdio_wirep m′ w′ h

intros Hi Ha Hd Hr Hrep & Hw & Hapart

rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
args :
listarg
xs :
listword
s :
R.state
m :
trace :
listevent
values :
listword
s′ :
R.state
m′ :
h :
Hi :
M.E.invokeputs_contractrep requests r args xs s m w trace CallReturnvalues s′ m′ w′
Ha :
Hr :
R.readys m
Hrep :
repm w
⊢
agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ stdio_wirep m′ w′ h

destruct M.E.invoke_prefix_ _ _ _ _ _ _ _ _ _ _ _ _ Hi as born & Hp

rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
args :
listarg
xs :
listword
s :
R.state
m :
trace :
listevent
values :
listword
s′ :
R.state
m′ :
h :
Hi :
M.E.invokeputs_contractrep requests r args xs s m w trace CallReturnvalues s′ m′ w′
Ha :
Hr :
R.readys m
Hrep :
repm w
born :
listZ
Hp :
M.E.prefixputs_contractrep requests xs s m w born trace s′ m′ w′
⊢
agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ stdio_wirep m′ w′ h

destruct M.E.prefix_preserve_ _ _ _ _ _ _ _ _ _ _ Hp Hr as Hr′ _

rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
args :
listarg
xs :
listword
s :
R.state
m :
trace :
listevent
values :
listword
s′ :
R.state
m′ :
h :
Hi :
M.E.invokeputs_contractrep requests r args xs s m w trace CallReturnvalues s′ m′ w′
Ha :
Hr :
R.readys m
Hrep :
repm w
born :
listZ
Hp :
M.E.prefixputs_contractrep requests xs s m w born trace s′ m′ w′
Hr′ :
R.readys′ m′
⊢
agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ stdio_wirep m′ w′ h

destruct prefix_agrees_ _ _ _ _ _ _ _ _ _ _ h Hp Hr Hd Ha Hapart ltac:intros ? ? ? as Ha′ & Hd′ & Hb & Hapart′

rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
args :
listarg
xs :
listword
s :
R.state
m :
trace :
listevent
values :
listword
s′ :
R.state
m′ :
h :
Hi :
M.E.invokeputs_contractrep requests r args xs s m w trace CallReturnvalues s′ m′ w′
Ha :
Hr :
R.readys m
Hrep :
repm w
born :
listZ
Hp :
M.E.prefixputs_contractrep requests xs s m w born trace s′ m′ w′
Hr′ :
R.readys′ m′
Ha′ :
agreesm′ h
Hd′ :
Hb :
ids_apartborn h
Hapart′ :
roots_apartcontract_writesputs_contractrep requests xs m w h m′
⊢
agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ stdio_wirep m′ w′ h

destruct Hp as _ Hrep′ & Hw′ & Hdel & _

rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
args :
listarg
xs :
listword
s :
R.state
m :
trace :
listevent
values :
listword
s′ :
R.state
m′ :
h :
Hi :
M.E.invokeputs_contractrep requests r args xs s m w trace CallReturnvalues s′ m′ w′
Ha :
Hr :
R.readys m
Hrep :
repm w
born :
listZ
Hrep′ :
repm′ w′
Hw′ :
stdio_readym′ w′
Hdel :
Hr′ :
R.readys′ m′
Ha′ :
agreesm′ h
Hd′ :
Hb :
ids_apartborn h
Hapart′ :
roots_apartcontract_writesputs_contractrep requests xs m w h m′
⊢
agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ stdio_wirep m′ w′ h

change roots_apartstdio_rootsw h m′ in Hapart′

rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
args :
listarg
xs :
listword
s :
R.state
m :
trace :
listevent
values :
listword
s′ :
R.state
m′ :
h :
Hi :
M.E.invokeputs_contractrep requests r args xs s m w trace CallReturnvalues s′ m′ w′
Ha :
Hr :
R.readys m
Hrep :
repm w
born :
listZ
Hrep′ :
repm′ w′
Hw′ :
stdio_readym′ w′
Hdel :
Hr′ :
R.readys′ m′
Ha′ :
agreesm′ h
Hd′ :
Hb :
ids_apartborn h
Hapart′ :
⊢
agreesm′ h ∧ live_disjointm′ ∧ R.readys′ m′ ∧ stdio_wirep m′ w′ h

split ; exact Ha′ |

rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
args :
listarg
xs :
listword
s :
R.state
m :
trace :
listevent
values :
listword
s′ :
R.state
m′ :
h :
Hi :
M.E.invokeputs_contractrep requests r args xs s m w trace CallReturnvalues s′ m′ w′
Ha :
Hr :
R.readys m
Hrep :
repm w
born :
listZ
Hrep′ :
repm′ w′
Hw′ :
stdio_readym′ w′
Hdel :
Hr′ :
R.readys′ m′
Ha′ :
agreesm′ h
Hd′ :
Hb :
ids_apartborn h
Hapart′ :
⊢
live_disjointm′ ∧ R.readys′ m′ ∧ stdio_wirep m′ w′ h

split ; exact Hd′ |

rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
args :
listarg
xs :
listword
s :
R.state
m :
trace :
listevent
values :
listword
s′ :
R.state
m′ :
h :
Hi :
M.E.invokeputs_contractrep requests r args xs s m w trace CallReturnvalues s′ m′ w′
Ha :
Hr :
R.readys m
Hrep :
repm w
born :
listZ
Hrep′ :
repm′ w′
Hw′ :
stdio_readym′ w′
Hdel :
Hr′ :
R.readys′ m′
Ha′ :
agreesm′ h
Hd′ :
Hb :
ids_apartborn h
Hapart′ :
⊢
R.readys′ m′ ∧ stdio_wirep m′ w′ h

split ; exact Hr′ |

rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
args :
listarg
xs :
listword
s :
R.state
m :
trace :
listevent
values :
listword
s′ :
R.state
m′ :
h :
Hi :
M.E.invokeputs_contractrep requests r args xs s m w trace CallReturnvalues s′ m′ w′
Ha :
Hr :
R.readys m
Hrep :
repm w
born :
listZ
Hrep′ :
repm′ w′
Hw′ :
stdio_readym′ w′
Hdel :
Hr′ :
R.readys′ m′
Ha′ :
agreesm′ h
Hd′ :
Hb :
ids_apartborn h
Hapart′ :
⊢
stdio_wirep m′ w′ h

split ; exact Hrep′ |

rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
args :
listarg
xs :
listword
s :
R.state
m :
trace :
listevent
values :
listword
s′ :
R.state
m′ :
h :
Hi :
M.E.invokeputs_contractrep requests r args xs s m w trace CallReturnvalues s′ m′ w′
Ha :
Hr :
R.readys m
Hrep :
repm w
born :
listZ
Hrep′ :
repm′ w′
Hw′ :
stdio_readym′ w′
Hdel :
Hr′ :
R.readys′ m′
Ha′ :
agreesm′ h
Hd′ :
Hb :
ids_apartborn h
Hapart′ :
⊢
stdio_readym′ w′ ∧ roots_apartstdio_rootsw′ h m′

split ; exact Hw′ |

rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
args :
listarg
xs :
listword
s :
R.state
m :
trace :
listevent
values :
listword
s′ :
R.state
m′ :
h :
Hi :
M.E.invokeputs_contractrep requests r args xs s m w trace CallReturnvalues s′ m′ w′
Ha :
Hr :
R.readys m
Hrep :
repm w
born :
listZ
Hrep′ :
repm′ w′
Hw′ :
stdio_readym′ w′
Hdel :
Hr′ :
R.readys′ m′
Ha′ :
agreesm′ h
Hd′ :
Hb :
ids_apartborn h
Hapart′ :

exact delegates_apart_ _ _ _ h Hdel Hapart′ Hb Hd′

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hi Ha Hd Hr Hrep & Hw & Hapart
destruct M.E.invoke_prefix_ _ _ _ _ _ _ _ _ _ _ _ _ Hi as born & Hp
destruct M.E.prefix_preserve_ _ _ _ _ _ _ _ _ _ _ Hp Hr as Hr′ _
destruct prefix_agrees_ _ _ _ _ _ _ _ _ _ _ h Hp Hr Hd Ha Hapart ltac:intros ? ? ? as Ha′ & Hd′ & Hb & Hapart′
destruct Hp as _ Hrep′ & Hw′ & Hdel & _
change roots_apartstdio_rootsw h m′ in Hapart′
split ; exact Ha′ |
split ; exact Hd′ |
split ; exact Hr′ |
split ; exact Hrep′ |
split ; exact Hw′ |
exact delegates_apart_ _ _ _ h Hdel Hapart′ Hb Hd′
279Section strings
280Context `{!invGS_genhlc Σ, !gen_heapGSpiece pval Σ}

string p b reg bytes: owning the C string at p with contents bytes, in the object b with the region reg: its life and its bytes through the NUL, of the shape string_ok.

285Definition stringp : ptr b : Z reg : region bytes : listZ : iPropΣ ≔
⌜string_okp b reg bytes⌝ ∗ ptsstring_psp b reg bytes

Owning a string in an interpreted state, p points there at a terminated_length string of its length and at a c_string.

290Lemma string_facts
∀ world : Type wi : mem → world → gmappiece pval → Prop σ p b reg bytes
heap_interpwi σ −∗ stringp b reg bytes −∗ ⌜terminated_lengthls_memσ p Z.of_natlengthbytes ∧ c_stringls_memσ p bytes⌝
Explore proof 4 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
wi :
mem → world → gmappiece pval → Prop
σ :
p :
b :
Z
reg :
bytes :
listZ
⊢
heap_interpwi σ −∗ stringp b reg bytes −∗ ⌜terminated_lengthls_memσ p lengthbytes ∧ c_stringls_memσ p bytes⌝

iIntros Hσ [%Hok Hs]

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
wi :
mem → world → gmappiece pval → Prop
σ :
p :
b :
Z
reg :
bytes :
listZ
Hok :
string_okp b reg bytes
Hσ :
heap_interpwi σ
Hs :
ptsstring_psp b reg bytes
∗
⌜terminated_lengthls_memσ p lengthbytes ∧ c_stringls_memσ p bytes⌝

iDestruct pts_facts with Hσ Hs as %Ha & _

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
wi :
mem → world → gmappiece pval → Prop
σ :
p :
b :
Z
reg :
bytes :
listZ
Hok :
string_okp b reg bytes
Ha :
all_agreeL.ls_memσ string_psp b reg bytes
Hσ :
heap_interpwi σ
Hs :
ptsstring_psp b reg bytes
∗
⌜terminated_lengthls_memσ p lengthbytes ∧ c_stringls_memσ p bytes⌝

iPureIntro

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
wi :
mem → world → gmappiece pval → Prop
σ :
p :
b :
Z
reg :
bytes :
listZ
Hok :
string_okp b reg bytes
Ha :
all_agreeL.ls_memσ string_psp b reg bytes
⊢
terminated_lengthls_memσ p lengthbytes ∧ c_stringls_memσ p bytes

split ; exact string_terminated_ _ _ _ _ Hok Ha | exact string_c_string_ _ _ _ _ Hok Ha

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
iIntros Hσ [%Hok Hs]
iDestruct pts_facts with Hσ Hs as %Ha & _
iPureIntro
split ; exact string_terminated_ _ _ _ _ Hok Ha | exact string_c_string_ _ _ _ _ Hok Ha

The string lends its object's life and its i-th byte, x, the NUL for i its length, and takes them back.

300Lemma string_byte
∀ p b reg bytes i x
bytes ++ 0 !! i = Somex
stringp b reg bytes −∗ ⌜string_okp b reg bytes⌝ ∗ liveb reg ∗ ibyteb ptr_addrp − b + Z.of_nati x ∗ liveb reg −∗ ibyteb ptr_addrp − b + Z.of_nati x −∗ stringp b reg bytes
Explore proof 11 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
x :
Z
⊢
bytes ++ 0 !! i = Somex → stringp b reg bytes −∗ ⌜string_okp b reg bytes⌝ ∗ liveb reg ∗ ibyteb ptr_addrp − b + i x ∗ liveb reg −∗ ibyteb ptr_addrp − b + i x −∗ stringp b reg bytes

intros Hx

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
x :
Z
Hx :
bytes ++ 0 !! i = Somex
⊢
stringp b reg bytes −∗ ⌜string_okp b reg bytes⌝ ∗ liveb reg ∗ ibyteb ptr_addrp − b + i x ∗ liveb reg −∗ ibyteb ptr_addrp − b + i x −∗ stringp b reg bytes

iIntros [%Hok [Hl Hs]]

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
x :
Z
Hx :
bytes ++ 0 !! i = Somex
Hok :
string_okp b reg bytes
Hl :
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2
Hs :
∗y∈byte_psb ptr_addrp − b bytes ++ 0pointstoy.1 DfracOwn1 y.2
∗
⌜string_okp b reg bytes⌝ ∗ liveb reg ∗ ibyteb ptr_addrp − b + i x ∗ liveb reg −∗ ibyteb ptr_addrp − b + i x −∗ stringp b reg bytes

rewrite / live / ibyte / pts /=

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
x :
Z
Hx :
bytes ++ 0 !! i = Somex
Hok :
string_okp b reg bytes
Hl :
pointstoPLiveb DfracOwn1 VLivereg
Hs :
∗y∈byte_psb ptr_addrp − b bytes ++ 0pointstoy.1 DfracOwn1 y.2
∗
⌜string_okp b reg bytes⌝ ∗ pointstoPLiveb DfracOwn1 VLivereg ∗ emp ∗ pointstoPByteb ptr_addrp − b + i DfracOwn1 VBytex ∗ emp ∗ pointstoPLiveb DfracOwn1 VLivereg ∗ emp −∗ pointstoPByteb ptr_addrp − b + i DfracOwn1 VBytex ∗ emp −∗ stringp b reg bytes

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

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
x :
Z
Hx :
bytes ++ 0 !! i = Somex
Hok :
string_okp b reg bytes
Hl :
pointstoPLiveb DfracOwn1 VLivereg
Hb :
pointstoPByteb ptr_addrp − b + i, VBytex.1 DfracOwn1 PByteb ptr_addrp − b + i, VBytex.2
Hk :
pointstoPByteb ptr_addrp − b + i, VBytex.1 DfracOwn1 PByteb ptr_addrp − b + i, VBytex.2 −∗ ∗y∈byte_psb ptr_addrp − b bytes ++ 0pointstoy.1 DfracOwn1 y.2
∗
⌜string_okp b reg bytes⌝ ∗ pointstoPLiveb DfracOwn1 VLivereg ∗ emp ∗ pointstoPByteb ptr_addrp − b + i DfracOwn1 VBytex ∗ emp ∗ pointstoPLiveb DfracOwn1 VLivereg ∗ emp −∗ pointstoPByteb ptr_addrp − b + i DfracOwn1 VBytex ∗ emp −∗ stringp b reg bytes

iSplit ; done |

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
x :
Z
Hx :
bytes ++ 0 !! i = Somex
Hok :
string_okp b reg bytes
Hl :
pointstoPLiveb DfracOwn1 VLivereg
Hb :
pointstoPByteb ptr_addrp − b + i, VBytex.1 DfracOwn1 PByteb ptr_addrp − b + i, VBytex.2
Hk :
pointstoPByteb ptr_addrp − b + i, VBytex.1 DfracOwn1 PByteb ptr_addrp − b + i, VBytex.2 −∗ ∗y∈byte_psb ptr_addrp − b bytes ++ 0pointstoy.1 DfracOwn1 y.2
∗
pointstoPLiveb DfracOwn1 VLivereg ∗ emp ∗ pointstoPByteb ptr_addrp − b + i DfracOwn1 VBytex ∗ emp ∗ pointstoPLiveb DfracOwn1 VLivereg ∗ emp −∗ pointstoPByteb ptr_addrp − b + i DfracOwn1 VBytex ∗ emp −∗ stringp b reg bytes

iSplitL Hl ; iFrame |

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
x :
Z
Hx :
bytes ++ 0 !! i = Somex
Hok :
string_okp b reg bytes
Hb :
pointstoPByteb ptr_addrp − b + i, VBytex.1 DfracOwn1 PByteb ptr_addrp − b + i, VBytex.2
Hk :
pointstoPByteb ptr_addrp − b + i, VBytex.1 DfracOwn1 PByteb ptr_addrp − b + i, VBytex.2 −∗ ∗y∈byte_psb ptr_addrp − b bytes ++ 0pointstoy.1 DfracOwn1 y.2
∗
pointstoPByteb ptr_addrp − b + i DfracOwn1 VBytex ∗ emp ∗ pointstoPLiveb DfracOwn1 VLivereg ∗ emp −∗ pointstoPByteb ptr_addrp − b + i DfracOwn1 VBytex ∗ emp −∗ stringp b reg bytes

iSplitL Hb ; iFrame |

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
x :
Z
Hx :
bytes ++ 0 !! i = Somex
Hok :
string_okp b reg bytes
Hk :
pointstoPByteb ptr_addrp − b + i, VBytex.1 DfracOwn1 PByteb ptr_addrp − b + i, VBytex.2 −∗ ∗y∈byte_psb ptr_addrp − b bytes ++ 0pointstoy.1 DfracOwn1 y.2
∗
pointstoPLiveb DfracOwn1 VLivereg ∗ emp −∗ pointstoPByteb ptr_addrp − b + i DfracOwn1 VBytex ∗ emp −∗ stringp b reg bytes

iIntros [Hl _] [Hb _]

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
x :
Z
Hx :
bytes ++ 0 !! i = Somex
Hok :
string_okp b reg bytes
Hk :
pointstoPByteb ptr_addrp − b + i, VBytex.1 DfracOwn1 PByteb ptr_addrp − b + i, VBytex.2 −∗ ∗y∈byte_psb ptr_addrp − b bytes ++ 0pointstoy.1 DfracOwn1 y.2
Hl :
pointstoPLiveb DfracOwn1 VLivereg
Hb :
pointstoPByteb ptr_addrp − b + i DfracOwn1 VBytex
∗
stringp b reg bytes

iSplit ; done |

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
x :
Z
Hx :
bytes ++ 0 !! i = Somex
Hok :
string_okp b reg bytes
Hk :
pointstoPByteb ptr_addrp − b + i, VBytex.1 DfracOwn1 PByteb ptr_addrp − b + i, VBytex.2 −∗ ∗y∈byte_psb ptr_addrp − b bytes ++ 0pointstoy.1 DfracOwn1 y.2
Hl :
pointstoPLiveb DfracOwn1 VLivereg
Hb :
pointstoPByteb ptr_addrp − b + i DfracOwn1 VBytex
∗
ptsstring_psp b reg bytes

iFrame Hl

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
x :
Z
Hx :
bytes ++ 0 !! i = Somex
Hok :
string_okp b reg bytes
Hk :
pointstoPByteb ptr_addrp − b + i, VBytex.1 DfracOwn1 PByteb ptr_addrp − b + i, VBytex.2 −∗ ∗y∈byte_psb ptr_addrp − b bytes ++ 0pointstoy.1 DfracOwn1 y.2
Hb :
pointstoPByteb ptr_addrp − b + i DfracOwn1 VBytex
∗
∗y∈byte_psb ptr_addrp − b bytes ++ 0pointstoy.1 DfracOwn1 y.2

iApply Hk with Hb

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hx
iIntros [%Hok [Hl Hs]]
rewrite / live / ibyte / pts /=
iDestruct big_sepL_lookup_acc with Hs as [Hb Hk] ; exact byte_ps_lookup_ _ _ _ _ Hx |
iSplit ; done |
iSplitL Hl ; iFrame |
iSplitL Hb ; iFrame |
iIntros [Hl _] [Hb _]
iSplit ; done |
iFrame Hl
iApply Hk with Hb

A string lends the suffix from its i-th byte, before its NUL or at it, as the string at q, and takes it back.

314Lemma string_suffix
∀ p b reg bytes i
i ≤ lengthbytes%nat
stringp b reg bytes −∗ stringmkPtrptr_addrp + Z.of_nati ptr_capp b reg dropi bytes ∗ stringmkPtrptr_addrp + Z.of_nati ptr_capp b reg dropi bytes −∗ stringp b reg bytes
Explore proof 14 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
⊢
i ≤ lengthbytes%nat → stringp b reg bytes −∗ stringptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes ∗ stringptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes −∗ stringp b reg bytes

intros Hi

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
⊢
stringp b reg bytes −∗ stringptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes ∗ stringptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes −∗ stringp b reg bytes

destruct string_ps_suffixp b reg bytes i Hi as Ep Eq

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Ep :
string_psp b reg bytes = PLiveb, VLivereg :: byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Eq :
string_psptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes = PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
⊢
stringp b reg bytes −∗ stringptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes ∗ stringptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes −∗ stringp b reg bytes

iIntros [%Hok Hs]

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Ep :
string_psp b reg bytes = PLiveb, VLivereg :: byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Eq :
string_psptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes = PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Hok :
string_okp b reg bytes
Hs :
ptsstring_psp b reg bytes
∗
stringptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes ∗ stringptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes −∗ stringp b reg bytes

rewrite / string Ep Eq / pts big_sepL_cons big_sepL_app

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Ep :
string_psp b reg bytes = PLiveb, VLivereg :: byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Eq :
string_psptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes = PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Hok :
string_okp b reg bytes
Hs :
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈byte_psb ptr_addrp − b takei bytespointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstoy.1 DfracOwn1 y.2
∗
⌜string_okptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes⌝ ∗ ∗lv∈PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstolv.1 DfracOwn1 lv.2 ∗ ⌜string_okptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes⌝ ∗ ∗lv∈PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstolv.1 DfracOwn1 lv.2 −∗ ⌜string_okp b reg bytes⌝ ∗ pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈byte_psb ptr_addrp − b takei bytespointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstoy.1 DfracOwn1 y.2

iDestruct Hs as (Hl & Hpre & Hsuf)

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Ep :
string_psp b reg bytes = PLiveb, VLivereg :: byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Eq :
string_psptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes = PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Hok :
string_okp b reg bytes
Hl :
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2
Hpre :
∗y∈byte_psb ptr_addrp − b takei bytespointstoy.1 DfracOwn1 y.2
Hsuf :
∗y∈byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstoy.1 DfracOwn1 y.2
∗
⌜string_okptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes⌝ ∗ ∗lv∈PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstolv.1 DfracOwn1 lv.2 ∗ ⌜string_okptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes⌝ ∗ ∗lv∈PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstolv.1 DfracOwn1 lv.2 −∗ ⌜string_okp b reg bytes⌝ ∗ pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈byte_psb ptr_addrp − b takei bytespointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstoy.1 DfracOwn1 y.2

iSplitL Hl Hsuf

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Ep :
string_psp b reg bytes = PLiveb, VLivereg :: byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Eq :
string_psptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes = PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Hok :
string_okp b reg bytes
Hl :
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2
Hsuf :
∗y∈byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstoy.1 DfracOwn1 y.2
∗
⌜string_okptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes⌝ ∗ ∗lv∈PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstolv.1 DfracOwn1 lv.2
focused goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Ep :
string_psp b reg bytes = PLiveb, VLivereg :: byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Eq :
string_psptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes = PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Hok :
string_okp b reg bytes
Hpre :
∗y∈byte_psb ptr_addrp − b takei bytespointstoy.1 DfracOwn1 y.2
∗
⌜string_okptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes⌝ ∗ ∗lv∈PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstolv.1 DfracOwn1 lv.2 −∗ ⌜string_okp b reg bytes⌝ ∗ pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈byte_psb ptr_addrp − b takei bytespointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstoy.1 DfracOwn1 y.2

–iSplit ; iPureIntro ; exact string_ok_suffix_ _ _ _ _ Hi Hok |

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Ep :
string_psp b reg bytes = PLiveb, VLivereg :: byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Eq :
string_psptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes = PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Hok :
string_okp b reg bytes
Hl :
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2
Hsuf :
∗y∈byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstoy.1 DfracOwn1 y.2
∗
∗lv∈PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstolv.1 DfracOwn1 lv.2
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Ep :
string_psp b reg bytes = PLiveb, VLivereg :: byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Eq :
string_psptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes = PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Hok :
string_okp b reg bytes
Hpre :
∗y∈byte_psb ptr_addrp − b takei bytespointstoy.1 DfracOwn1 y.2
∗
⌜string_okptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes⌝ ∗ ∗lv∈PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstolv.1 DfracOwn1 lv.2 −∗ ⌜string_okp b reg bytes⌝ ∗ pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈byte_psb ptr_addrp − b takei bytespointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstoy.1 DfracOwn1 y.2

rewrite big_sepL_cons

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Ep :
string_psp b reg bytes = PLiveb, VLivereg :: byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Eq :
string_psptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes = PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Hok :
string_okp b reg bytes
Hl :
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2
Hsuf :
∗y∈byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstoy.1 DfracOwn1 y.2
∗
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstoy.1 DfracOwn1 y.2
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Ep :
string_psp b reg bytes = PLiveb, VLivereg :: byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Eq :
string_psptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes = PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Hok :
string_okp b reg bytes
Hpre :
∗y∈byte_psb ptr_addrp − b takei bytespointstoy.1 DfracOwn1 y.2
∗
⌜string_okptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes⌝ ∗ ∗lv∈PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstolv.1 DfracOwn1 lv.2 −∗ ⌜string_okp b reg bytes⌝ ∗ pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈byte_psb ptr_addrp − b takei bytespointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstoy.1 DfracOwn1 y.2

iFrame

deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Ep :
string_psp b reg bytes = PLiveb, VLivereg :: byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Eq :
string_psptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes = PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Hok :
string_okp b reg bytes
Hpre :
∗y∈byte_psb ptr_addrp − b takei bytespointstoy.1 DfracOwn1 y.2
∗
⌜string_okptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes⌝ ∗ ∗lv∈PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstolv.1 DfracOwn1 lv.2 −∗ ⌜string_okp b reg bytes⌝ ∗ pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈byte_psb ptr_addrp − b takei bytespointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstoy.1 DfracOwn1 y.2

–iIntros [_ Hq]

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Ep :
string_psp b reg bytes = PLiveb, VLivereg :: byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Eq :
string_psptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes = PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Hok :
string_okp b reg bytes
Hpre :
∗y∈byte_psb ptr_addrp − b takei bytespointstoy.1 DfracOwn1 y.2
Hq :
∗lv∈PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstolv.1 DfracOwn1 lv.2
∗
⌜string_okp b reg bytes⌝ ∗ pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈byte_psb ptr_addrp − b takei bytespointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstoy.1 DfracOwn1 y.2

rewrite big_sepL_cons

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Ep :
string_psp b reg bytes = PLiveb, VLivereg :: byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Eq :
string_psptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes = PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Hok :
string_okp b reg bytes
Hpre :
∗y∈byte_psb ptr_addrp − b takei bytespointstoy.1 DfracOwn1 y.2
Hq :
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstoy.1 DfracOwn1 y.2
∗
⌜string_okp b reg bytes⌝ ∗ pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈byte_psb ptr_addrp − b takei bytespointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstoy.1 DfracOwn1 y.2

iDestruct Hq as [Hl Hsuf]

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Ep :
string_psp b reg bytes = PLiveb, VLivereg :: byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Eq :
string_psptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes = PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Hok :
string_okp b reg bytes
Hpre :
∗y∈byte_psb ptr_addrp − b takei bytespointstoy.1 DfracOwn1 y.2
Hl :
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2
Hsuf :
∗y∈byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstoy.1 DfracOwn1 y.2
∗
⌜string_okp b reg bytes⌝ ∗ pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈byte_psb ptr_addrp − b takei bytespointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstoy.1 DfracOwn1 y.2

iSplit ; done |

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
bytes :
listZ
i :
nat
Hi :
i ≤ lengthbytes%nat
Ep :
string_psp b reg bytes = PLiveb, VLivereg :: byte_psb ptr_addrp − b takei bytes ++ byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Eq :
string_psptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp b reg dropi bytes = PLiveb, VLivereg :: byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0
Hok :
string_okp b reg bytes
Hpre :
∗y∈byte_psb ptr_addrp − b takei bytespointstoy.1 DfracOwn1 y.2
Hl :
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2
Hsuf :
∗y∈byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstoy.1 DfracOwn1 y.2
∗
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈byte_psb ptr_addrp − b takei bytespointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrptr_addr ≔ ptr_addrp + i; ptr_cap ≔ ptr_capp − b dropi bytes ++ 0pointstoy.1 DfracOwn1 y.2

iFrame

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hi
destruct string_ps_suffixp b reg bytes i Hi as Ep Eq
iIntros [%Hok Hs]
rewrite / string Ep Eq / pts big_sepL_cons big_sepL_app
iDestruct Hs as (Hl & Hpre & Hsuf)
iSplitL Hl Hsuf
–iSplit ; iPureIntro ; exact string_ok_suffix_ _ _ _ _ Hi Hok |
rewrite big_sepL_cons
iFrame
–iIntros [_ Hq]
rewrite big_sepL_cons
iDestruct Hq as [Hl Hsuf]
iSplit ; done |
iFrame

Where the string's pieces agree, p points at a bounded_length string for any bound n: its length, or n if that is shorter. Campaign 4's reading of a string for strncmp.

330Lemma string_bounded
∀ m p b reg bytes n
string_okp b reg bytes
all_agreem string_psp b reg bytes
0 ≤ n < 2 ^ 64
bounded_lengthm p n Z.minZ.of_natlengthbytes n
Explore proof 22 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
⊢
string_ok p b reg bytes → all_agree m (string_ps p b reg bytes) → 0 <= n < 2 ^ 64 → bounded_length m p n (length bytes `min` n)

intros Hok Ha Hn

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
Hn :
0 ≤ n < 2 ^ 64
⊢
bounded_length m p n (length bytes `min` n)

pose proof string_bytesm p b reg bytes Hok Ha as Hb

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
bounded_length m p n (length bytes `min` n)

destruct Hok as Hc & H0 & H1 & H2 & H3 & Hf

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Ha :
all_agreem string_psp b reg bytes
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
bounded_length m p n (length bytes `min` n)

destruct Ha as E Lv _

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
bounded_length m p n (length bytes `min` n)

split ; exact Hn |

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
0 <= length bytes `min` n <= n ∧ (∃ (base : Z) (reg0 : region), (ptr_cap p = Obj base ∨ ptr_cap p = Ro base) ∧ object_region base (m_regions m) = Some reg0 ∧ r_life reg0 = Live) ∧ access_res m (ptr_addr p) (ptr_cap p) (length bytes `min` n + (if length bytes `min` n <? n then 1 else 0)) Read 1 = Some ok ∧ (∀ i : Z, 0 <= i < length bytes `min` n → 0 < m_bytes m (ptr_addr p + i) < 256) ∧ (length bytes `min` n < n → m_bytes m (ptr_addr p + length bytes `min` n) = 0)

split ; lia |

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
(∃ (base : Z) (reg0 : region), (ptr_cap p = Obj base ∨ ptr_cap p = Ro base) ∧ object_region base (m_regions m) = Some reg0 ∧ r_life reg0 = Live) ∧ access_res m (ptr_addr p) (ptr_cap p) (length bytes `min` n + (if length bytes `min` n <? n then 1 else 0)) Read 1 = Some ok ∧ (∀ i : Z, 0 <= i < length bytes `min` n → 0 < m_bytes m (ptr_addr p + i) < 256) ∧ (length bytes `min` n < n → m_bytes m (ptr_addr p + length bytes `min` n) = 0)

split ; exists b, reg ; auto |

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
access_res m (ptr_addr p) (ptr_cap p) (length bytes `min` n + (if length bytes `min` n <? n then 1 else 0)) Read 1 = Some ok ∧ (∀ i : Z, 0 <= i < length bytes `min` n → 0 < m_bytes m (ptr_addr p + i) < 256) ∧ (length bytes `min` n < n → m_bytes m (ptr_addr p + length bytes `min` n) = 0)

split

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
access_res m (ptr_addr p) (ptr_cap p) (length bytes `min` n + (if length bytes `min` n <? n then 1 else 0)) Read 1 = Some ok
focused goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
(∀ i : Z, 0 <= i < length bytes `min` n → 0 < m_bytes m (ptr_addr p + i) < 256) ∧ (length bytes `min` n < n → m_bytes m (ptr_addr p + length bytes `min` n) = 0)

–apply access_read_ b reg ; exact Hc | exact E | lia | | apply Z.mod_1_r

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
ptr_addr p + (length bytes `min` n + (if length bytes `min` n <? n then 1 else 0)) <= r_end reg
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
(∀ i : Z, 0 <= i < length bytes `min` n → 0 < m_bytes m (ptr_addr p + i) < 256) ∧ (length bytes `min` n < n → m_bytes m (ptr_addr p + length bytes `min` n) = 0)

destruct Z.min_ n <? n ; lia

deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
(∀ i : Z, 0 <= i < length bytes `min` n → 0 < m_bytes m (ptr_addr p + i) < 256) ∧ (length bytes `min` n < n → m_bytes m (ptr_addr p + length bytes `min` n) = 0)

–split

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
∀ i : Z, 0 <= i < length bytes `min` n → 0 < m_bytes m (ptr_addr p + i) < 256
focused goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
length bytes `min` n < n → m_bytes m (ptr_addr p + length bytes `min` n) = 0

+intros i Hi

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
i :
Z
Hi : 0 <= i < length bytes `min` n
⊢
0 < m_bytesm ptr_addrp + i < 256
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
length bytes `min` n < n → m_bytes m (ptr_addr p + length bytes `min` n) = 0

destruct lookup_lt_is_Some_2bytes Z.to_nati ltac:lia as x Hx

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
i :
Z
Hi : 0 <= i < length bytes `min` n
x :
Z
Hx :
bytes !! Z.to_nati = Somex
⊢
0 < m_bytesm ptr_addrp + i < 256
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
length bytes `min` n < n → m_bytes m (ptr_addr p + length bytes `min` n) = 0

rewrite <- Z2Nat.idi by lia

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
i :
Z
Hi : 0 <= i < length bytes `min` n
x :
Z
Hx :
bytes !! Z.to_nati = Somex
⊢
0 < m_bytesm ptr_addrp + Z.to_nati < 256
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
length bytes `min` n < n → m_bytes m (ptr_addr p + length bytes `min` n) = 0

rewrite HbZ.to_nati x ; | by apply lookup_app_l_Some

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
i :
Z
Hi : 0 <= i < length bytes `min` n
x :
Z
Hx :
bytes !! Z.to_nati = Somex
⊢
0 < x < 256
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
length bytes `min` n < n → m_bytes m (ptr_addr p + length bytes `min` n) = 0

exact Forall_lookup_1_ _ _ _ Hf Hx

deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
length bytes `min` n < n → m_bytes m (ptr_addr p + length bytes `min` n) = 0

+intros Hk

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hk : length bytes `min` n < n
⊢
m_bytes m (ptr_addr p + length bytes `min` n) = 0

assert Z.minZ.of_natlengthbytes n = Z.of_natlengthbytes as → by lia

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hk : length bytes `min` n < n
⊢
m_bytesm ptr_addrp + lengthbytes = 0

apply Hblengthbytes 0

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hk : length bytes `min` n < n
⊢
bytes ++ 0 !! lengthbytes = Some0

rewrite lookup_app_r ; | lia

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hk : length bytes `min` n < n
⊢
0 !! lengthbytes − lengthbytes%nat = Some0

rewrite Nat.sub_diag

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
m :
p :
b :
Z
reg :
bytes :
listZ
n :
Z
Hc :
ptr_capp = Objb ∨ ptr_capp = Rob
H0 :
0 < b
H1 :
b ≤ ptr_addrp
H2 :
ptr_addrp + lengthbytes + 1 ≤ r_endreg
H3 :
r_endreg ≤ 2 ^ 48
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
E :
Lv :
r_lifereg = Live
Hn :
0 ≤ n < 2 ^ 64
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hk : length bytes `min` n < n
⊢
0 !! 0%nat = Some0

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hok Ha Hn
pose proof string_bytesm p b reg bytes Hok Ha as Hb
destruct Hok as Hc & H0 & H1 & H2 & H3 & Hf
destruct Ha as E Lv _
split ; exact Hn |
split ; lia |
split ; exists b, reg ; auto |
split
–apply access_read_ b reg ; exact Hc | exact E | lia | | apply Z.mod_1_r
destruct Z.min_ n <? n ; lia
–split
+intros i Hi
destruct lookup_lt_is_Some_2bytes Z.to_nati ltac:lia as x Hx
rewrite <- Z2Nat.idi by lia
rewrite HbZ.to_nati x ; | by apply lookup_app_l_Some
exact Forall_lookup_1_ _ _ _ Hf Hx
+intros Hk
assert Z.minZ.of_natlengthbytes n = Z.of_natlengthbytes as → by lia
apply Hblengthbytes 0
rewrite lookup_app_r ; | lia
rewrite Nat.sub_diag
reflexivity

The calls

349Section calls
350Context world : Type registry : name → optioncontractworld wi : mem → world → gmappiece pval → Prop `{!SafepointStablewi} ge : genv

The Iris instance of the registry and wi.

354Instance string_irisGS: irisGS_genhlc nanofil_langregistry ge Σ ≔
nanofil_irisGSregistry wi ge

The expressions of the language.

358Notation sexpr ≔ language.exprnanofil_langregistry ge

A call that changes no memory and no world, from a ready runtime, keeps the state interpretation, with the same ghost heap, whatever the runtime state after it.

363Lemma pure_return
∀ spec : contractworld r args xs σ : lstateworld trace ending s′
M.E.invokespec r args xs ls_rtσ ls_memσ ls_worldσ trace ending s′ ls_memσ ls_worldσ
heap_interpwi σ −∗ heap_interpwi mkLstatels_memσ s′ ls_fuelσ ls_worldσ
Explore proof 10 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
spec :
args :
listarg
xs :
listword
σ :
lstateworld
trace :
listevent
ending :
s′ :
R.state
⊢
M.E.invokespec r args xs ls_rtσ ls_memσ ls_worldσ trace ending s′ ls_memσ ls_worldσ → heap_interpwi σ −∗ heap_interpwi ls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ

intros Hi

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
spec :
args :
listarg
xs :
listword
σ :
lstateworld
trace :
listevent
ending :
s′ :
R.state
Hi :
M.E.invokespec r args xs ls_rtσ ls_memσ ls_worldσ trace ending s′ ls_memσ ls_worldσ
⊢
heap_interpwi σ −∗ heap_interpwi ls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ

iIntros (%h & Hh & %Hf)

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
spec :
args :
listarg
xs :
listword
σ :
lstateworld
trace :
listevent
ending :
s′ :
R.state
Hi :
M.E.invokespec r args xs ls_rtσ ls_memσ ls_worldσ trace ending s′ ls_memσ ls_worldσ
h :
Hf :
agreesL.ls_memσ h ∧ live_disjointL.ls_memσ ∧ R.readyL.ls_rtσ L.ls_memσ ∧ wiL.ls_memσ L.ls_worldσ h
Hh :
gen_heap_interph
∗
heap_interpwi ls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ

destruct Hf as Ha & Hd & Hr & Hw

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
spec :
args :
listarg
xs :
listword
σ :
lstateworld
trace :
listevent
ending :
s′ :
R.state
Hi :
M.E.invokespec r args xs ls_rtσ ls_memσ ls_worldσ trace ending s′ ls_memσ ls_worldσ
h :
Ha :
agreesL.ls_memσ h
Hd :
live_disjointL.ls_memσ
Hr :
R.readyL.ls_rtσ L.ls_memσ
Hw :
wiL.ls_memσ L.ls_worldσ h
Hh :
gen_heap_interph
∗
heap_interpwi ls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ

destruct M.E.invoke_prefix_ _ _ _ _ _ _ _ _ _ _ _ _ Hi as born & Hp

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
spec :
args :
listarg
xs :
listword
σ :
lstateworld
trace :
listevent
ending :
s′ :
R.state
Hi :
M.E.invokespec r args xs ls_rtσ ls_memσ ls_worldσ trace ending s′ ls_memσ ls_worldσ
h :
Ha :
agreesL.ls_memσ h
Hd :
live_disjointL.ls_memσ
Hr :
R.readyL.ls_rtσ L.ls_memσ
Hw :
wiL.ls_memσ L.ls_worldσ h
born :
listZ
Hp :
M.E.prefixspec xs ls_rtσ ls_memσ ls_worldσ born trace s′ ls_memσ ls_worldσ
Hh :
gen_heap_interph
∗
heap_interpwi ls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ

destruct M.E.prefix_preserve_ _ _ _ _ _ _ _ _ _ _ Hp Hr as Hr′ _

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
spec :
args :
listarg
xs :
listword
σ :
lstateworld
trace :
listevent
ending :
s′ :
R.state
Hi :
M.E.invokespec r args xs ls_rtσ ls_memσ ls_worldσ trace ending s′ ls_memσ ls_worldσ
h :
Ha :
agreesL.ls_memσ h
Hd :
live_disjointL.ls_memσ
Hr :
R.readyL.ls_rtσ L.ls_memσ
Hw :
wiL.ls_memσ L.ls_worldσ h
born :
listZ
Hp :
M.E.prefixspec xs ls_rtσ ls_memσ ls_worldσ born trace s′ ls_memσ ls_worldσ
Hr′ :
R.readys′ ls_memσ
Hh :
gen_heap_interph
∗
heap_interpwi ls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ

iExists h

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
spec :
args :
listarg
xs :
listword
σ :
lstateworld
trace :
listevent
ending :
s′ :
R.state
Hi :
M.E.invokespec r args xs ls_rtσ ls_memσ ls_worldσ trace ending s′ ls_memσ ls_worldσ
h :
Ha :
agreesL.ls_memσ h
Hd :
live_disjointL.ls_memσ
Hr :
R.readyL.ls_rtσ L.ls_memσ
Hw :
wiL.ls_memσ L.ls_worldσ h
born :
listZ
Hp :
M.E.prefixspec xs ls_rtσ ls_memσ ls_worldσ born trace s′ ls_memσ ls_worldσ
Hr′ :
R.readys′ ls_memσ
Hh :
gen_heap_interph
∗
gen_heap_interph ∗ ⌜agreesL.ls_memls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ h ∧ live_disjointL.ls_memls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ ∧ R.readyL.ls_rtls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ L.ls_memls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ ∧ wiL.ls_memls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ L.ls_worldls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ h⌝

iFrame Hh

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
spec :
args :
listarg
xs :
listword
σ :
lstateworld
trace :
listevent
ending :
s′ :
R.state
Hi :
M.E.invokespec r args xs ls_rtσ ls_memσ ls_worldσ trace ending s′ ls_memσ ls_worldσ
h :
Ha :
agreesL.ls_memσ h
Hd :
live_disjointL.ls_memσ
Hr :
R.readyL.ls_rtσ L.ls_memσ
Hw :
wiL.ls_memσ L.ls_worldσ h
born :
listZ
Hp :
M.E.prefixspec xs ls_rtσ ls_memσ ls_worldσ born trace s′ ls_memσ ls_worldσ
Hr′ :
R.readys′ ls_memσ
∗
⌜agreesL.ls_memls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ h ∧ live_disjointL.ls_memls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ ∧ R.readyL.ls_rtls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ L.ls_memls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ ∧ wiL.ls_memls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ L.ls_worldls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ h⌝

iPureIntro

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
spec :
args :
listarg
xs :
listword
σ :
lstateworld
trace :
listevent
ending :
s′ :
R.state
Hi :
M.E.invokespec r args xs ls_rtσ ls_memσ ls_worldσ trace ending s′ ls_memσ ls_worldσ
h :
Ha :
agreesL.ls_memσ h
Hd :
live_disjointL.ls_memσ
Hr :
R.readyL.ls_rtσ L.ls_memσ
Hw :
wiL.ls_memσ L.ls_worldσ h
born :
listZ
Hp :
M.E.prefixspec xs ls_rtσ ls_memσ ls_worldσ born trace s′ ls_memσ ls_worldσ
Hr′ :
R.readys′ ls_memσ
⊢
agreesL.ls_memls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ h ∧ live_disjointL.ls_memls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ ∧ R.readyL.ls_rtls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ L.ls_memls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ ∧ wiL.ls_memls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ L.ls_worldls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ h

cbn

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
spec :
args :
listarg
xs :
listword
σ :
lstateworld
trace :
listevent
ending :
s′ :
R.state
Hi :
M.E.invokespec r args xs ls_rtσ ls_memσ ls_worldσ trace ending s′ ls_memσ ls_worldσ
h :
Ha :
agreesL.ls_memσ h
Hd :
live_disjointL.ls_memσ
Hr :
R.readyL.ls_rtσ L.ls_memσ
Hw :
wiL.ls_memσ L.ls_worldσ h
born :
listZ
Hp :
M.E.prefixspec xs ls_rtσ ls_memσ ls_worldσ born trace s′ ls_memσ ls_worldσ
Hr′ :
R.readys′ ls_memσ
⊢
agreesls_memσ h ∧ live_disjointls_memσ ∧ R.readys′ ls_memσ ∧ wils_memσ ls_worldσ h

auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hi
iIntros (%h & Hh & %Hf)
destruct Hf as Ha & Hd & Hr & Hw
destruct M.E.invoke_prefix_ _ _ _ _ _ _ _ _ _ _ _ _ Hi as born & Hp
destruct M.E.prefix_preserve_ _ _ _ _ _ _ _ _ _ _ Hp Hr as Hr′ _
iExists h
iFrame Hh
iPureIntro
cbn
auto

strlen's triple, from strlen_contract: owning the string at p, which v reads as, the call binds d to its length.

375Lemma wp_strlen
∀ f e ls lab d v rest j p b reg bytes Φ
registryTAtom"strlen" = Somestrlen_contractworld
find_fnge TAtom"strlen" = None
lookupTAtom"strlen" ge_globalsge = None
arg_xge e ArgP v = SomeWPtrp
stringp b reg bytes −∗ ▷stringp b reg bytes −∗ WPERunmkFramef putd WIntZ.of_natlengthbytes e ls None Execlab rest j : sexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd L GlobalTAtom"strlen" ArgP v :: rest j : sexpr {Φ}
Proof 28 steps Qed
intros Hreg Hfn Hdata Hv
iIntros Hs HK
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ strlen_contractworld WPtrp stringp b reg bytes with Hs [HK] ; done | done | done | done | cbn [ map_option ] ; rewrite Hv ; done | | |
–split ; right ; eexists ; reflexivity | eexists ; reflexivity
–iIntros σ Hσ Hs
iDestruct string_facts with Hσ Hs as %Ht _
iPureIntro
exists p, Z.of_natlengthbytes
auto
–iNext
iIntros σ trace values s′ m′ w′ Hinv Hσ Hs
iDestruct string_facts with Hσ Hs as %Ht _
destruct M.E.strlen_invocation_ _ _ _ _ _ _ _ _ _ _ _ Hinv as _ & → & → & p′ & k & Hx & Hk & He
injection Hx as ←
injection He as →
rewrite terminated_length_unique_ _ _ _ Hk Ht
iDestruct pure_return with Hσ as Hσ ; exact Hinv |
destruct σ as m s fuel w
iModIntro
iExists _
iSplit
+iPureIntro
cbn
rewrite Z.mod_small ; reflexivity |
destruct Ht as _ ?
lia
+iFrame Hσ
iApply HK with Hs

What strchr finds in the string p with contents bytes for the int c, whose low byte is not the NUL: the first byte equal to it, at offset i, with p's capability, or null if there is none.

407Definition strchr_foundp : ptr bytes : listZ c : Z q : ptr : Prop ≔
∃i x, bytes !! i = Somex ∧ x = c mod 256 ∧ ∀i′ x′, i′ < i%nat → bytes !! i′ = Somex′ → x′ ≠ c mod 256 ∧ q = mkPtrptr_addrp + Z.of_nati ptr_capp ∨ ∀i′ x′, bytes !! i′ = Somex′ → x′ ≠ c mod 256 ∧ q = mkPtr0 CNone

strchr's triple, from strchr_contract: owning the string at p, which v reads as, the call binds d to what it finds of the int c, which w reads as.

416Lemma wp_strchr
∀ f e ls lab d v w rest j p b reg bytes c Φ
registryTAtom"strchr" = Somestrchr_contractworld
find_fnge TAtom"strchr" = None
lookupTAtom"strchr" ge_globalsge = None
arg_xge e ArgP v = SomeWPtrp
arg_xge e ArgW w = SomeWIntc
0 ≤ c < 2 ^ 32
c mod 256 ≠ 0
stringp b reg bytes −∗ ▷∀q, ⌜strchr_foundp bytes c q⌝ −∗ stringp b reg bytes −∗ WPERunmkFramef putd WPtrq e ls None Execlab rest j : sexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd P GlobalTAtom"strchr" ArgP v; ArgW w :: rest j : sexpr {Φ}
Proof 61 steps Qed
intros Hreg Hfn Hdata Hv Hw Hc Hnz
iIntros Hs HK
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ strchr_contractworld WPtrp; WIntc stringp b reg bytes with Hs [HK] ; done | done | done | done | cbn [ map_option ] ; rewrite Hv Hw ; done | | |
–split ; right ; eexists ; reflexivity | do 2 eexists ; reflexivity
–iIntros σ Hσ Hs
iDestruct string_facts with Hσ Hs as %Ht _
iPureIntro
exists p, c, Z.of_natlengthbytes
auto
–iNext
iIntros σ trace values s′ m′ w′ Hinv Hσ Hs
iDestruct Hs as [%Hok Hs]
iDestruct pts_facts with Hσ Hs as %Ha & _
pose proof string_terminated_ _ _ _ _ Hok Ha as Ht
pose proof string_bytes_ _ _ _ _ Hok Ha as Hb
destruct M.E.strchr_invocation_ _ _ _ _ _ _ _ _ _ _ _ Hinv as _ & → & → & p′ & c′ & q & Hx & _ & k & Hk & Hq & He
injection Hx as ← ←
injection He as →
rewrite terminated_length_unique_ _ _ _ Hk Ht in Hq
iDestruct pure_return with Hσ as Hσ ; exact Hinv |
destruct σ as m s fuel w0
iModIntro
iExists _
iSplit ; iPureIntro ; reflexivity |
iFrame Hσ
iApply HK with [%] [Hs] ; | by iSplit
cbn [ ls_mem ] in Hb
destruct Hq as i & Hi & Hv′ & Hbefore & → | Hnone & →
+assert Hil : Z.to_nati < lengthbytes%nat
{destruct decideZ.to_nati = lengthbytes as Heq | Hne ; | lia
exfalso
apply Hnz
rewrite <- Hv'
rewrite <- Z2Nat.idi by lia
rewrite Heq
apply Hblengthbytes 0
rewrite lookup_app_r ; | lia
rewrite Nat.sub_diag
reflexivity
destruct lookup_lt_is_Some_2bytes Z.to_nati Hil as x Hx
left
exists Z.to_nati, x
split ; exact Hx |
split
∗rewrite <- Hv'
rewrite <- Z2Nat.idi at 1 by lia
symmetry
apply Hb
by apply lookup_app_l_Some
∗split ; | rewrite Z2Nat.id ; reflexivity | lia
intros i′ x′ Hlt Hx′
specialize HbeforeZ.of_nati' ltac:lia
rewrite Hbi' x' in Hbefore ; exact Hbefore |
by apply lookup_app_l_Some
+right
split ; | reflexivity
intros i′ x′ Hx′
assert Hl : i' < lengthbytes%nat by apply lookup_lt_Some in Hx' ; exact Hx'
specialize HnoneZ.of_nati' ltac:lia
rewrite Hbi' x' in Hnone ; exact Hnone |
by apply lookup_app_l_Some

strcmp's triple, from strcmp_contract: owning the strings at p and q, which v and w read as, the call binds d to an int. Which int does not matter to a caller that only branches on it.

467Lemma wp_strcmp
∀ f e ls lab d v w rest j p b reg xs q b′ reg′ ys Φ
registryTAtom"strcmp" = Somestrcmp_contractworld
find_fnge TAtom"strcmp" = None
lookupTAtom"strcmp" ge_globalsge = None
arg_xge e ArgP v = SomeWPtrp
arg_xge e ArgP w = SomeWPtrq
stringp b reg xs −∗ stringq b′ reg′ ys −∗ ▷∀bits, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunmkFramef putd WIntbits e ls None Execlab rest j : sexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd W GlobalTAtom"strcmp" ArgP v; ArgP w :: rest j : sexpr {Φ}
Explore proof 21 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
⊢
registryTAtom"strcmp" = Somestrcmp_contractworld → find_fnge TAtom"strcmp" = None → lookupTAtom"strcmp" ge_globalsge = None → arg_xge e ArgP v = SomeWPtrp → arg_xge e ArgP w = SomeWPtrq → stringp b reg xs −∗ stringq b′ reg′ ys −∗ ▷∀bits : Z, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntbits e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j : sexpr {v. Φv} −∗ WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab CallCResultd W GlobalTAtom"strcmp" ArgP v; ArgP w :: rest j : sexpr {v. Φv}

intros Hreg Hfn Hdata Hv Hw

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
⊢
stringp b reg xs −∗ stringq b′ reg′ ys −∗ ▷∀bits : Z, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntbits e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j : sexpr {v. Φv} −∗ WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab CallCResultd W GlobalTAtom"strcmp" ArgP v; ArgP w :: rest j : sexpr {v. Φv}

iIntros Hs Ht HK

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
Hs :
stringp b reg xs
Ht :
stringq b′ reg′ ys
HK :
▷∀bits : Z, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntbits e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab CallCResultd W GlobalTAtom"strcmp" ArgP v; ArgP w :: rest j {v. Φv}

iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ strcmp_contractworld WPtrp; WPtrq stringp b reg xs ∗ stringq b′ reg′ ys with [$Hs $Ht] [HK] ; done | done | done | done | cbn [ map_option ] ; rewrite Hv Hw ; done | | |

3 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
focused goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
⊢
∀σ : L.lstateworld, heap_interpwi σ −∗ stringp b reg xs ∗ stringq b′ reg′ ys −∗ ⌜contract_prestrcmp_contractworld WPtrp; WPtrq L.ls_memσ L.ls_worldσ⌝
focused goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
HK :
▷∀bits : Z, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntbits e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
▷∀σ : L.lstateworld trace : listevent values : listword s′ : R.state m′ : mem w′ : world, ⌜L.M.E.invokestrcmp_contractworld CResultd W ArgP v; ArgP w WPtrp; WPtrq L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′⌝ −∗ heap_interpwi σ −∗ stringp b reg xs ∗ stringq b′ reg′ ys ⇛ ∃e′ : env, ⌜external_envstrcmp_contractworld site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"strcmp"; site_args ≔ ArgP v; ArgP w; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpwi ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

–split ; right ; eexists ; reflexivity | do 2 eexists ; reflexivity

2 open

deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
⊢
∀σ : L.lstateworld, heap_interpwi σ −∗ stringp b reg xs ∗ stringq b′ reg′ ys −∗ ⌜contract_prestrcmp_contractworld WPtrp; WPtrq L.ls_memσ L.ls_worldσ⌝
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
HK :
▷∀bits : Z, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntbits e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
▷∀σ : L.lstateworld trace : listevent values : listword s′ : R.state m′ : mem w′ : world, ⌜L.M.E.invokestrcmp_contractworld CResultd W ArgP v; ArgP w WPtrp; WPtrq L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′⌝ −∗ heap_interpwi σ −∗ stringp b reg xs ∗ stringq b′ reg′ ys ⇛ ∃e′ : env, ⌜external_envstrcmp_contractworld site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"strcmp"; site_args ≔ ArgP v; ArgP w; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpwi ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

–iIntros σ Hσ [Hs Ht]

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
σ :
Hσ :
heap_interpwi σ
Hs :
stringp b reg xs
Ht :
stringq b′ reg′ ys
∗
⌜contract_prestrcmp_contractworld WPtrp; WPtrq L.ls_memσ L.ls_worldσ⌝
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
HK :
▷∀bits : Z, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntbits e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
▷∀σ : L.lstateworld trace : listevent values : listword s′ : R.state m′ : mem w′ : world, ⌜L.M.E.invokestrcmp_contractworld CResultd W ArgP v; ArgP w WPtrp; WPtrq L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′⌝ −∗ heap_interpwi σ −∗ stringp b reg xs ∗ stringq b′ reg′ ys ⇛ ∃e′ : env, ⌜external_envstrcmp_contractworld site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"strcmp"; site_args ≔ ArgP v; ArgP w; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpwi ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

iDestruct string_facts with Hσ Hs as %Hp _

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
σ :
Hp :
Hσ :
heap_interpwi σ
Hs :
stringp b reg xs
Ht :
stringq b′ reg′ ys
∗
⌜contract_prestrcmp_contractworld WPtrp; WPtrq L.ls_memσ L.ls_worldσ⌝
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
HK :
▷∀bits : Z, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntbits e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
▷∀σ : L.lstateworld trace : listevent values : listword s′ : R.state m′ : mem w′ : world, ⌜L.M.E.invokestrcmp_contractworld CResultd W ArgP v; ArgP w WPtrp; WPtrq L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′⌝ −∗ heap_interpwi σ −∗ stringp b reg xs ∗ stringq b′ reg′ ys ⇛ ∃e′ : env, ⌜external_envstrcmp_contractworld site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"strcmp"; site_args ≔ ArgP v; ArgP w; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpwi ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

iDestruct string_facts with Hσ Ht as %Hq _

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
σ :
Hp :
Hq :
Hσ :
heap_interpwi σ
Hs :
stringp b reg xs
Ht :
stringq b′ reg′ ys
∗
⌜contract_prestrcmp_contractworld WPtrp; WPtrq L.ls_memσ L.ls_worldσ⌝
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
HK :
▷∀bits : Z, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntbits e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
▷∀σ : L.lstateworld trace : listevent values : listword s′ : R.state m′ : mem w′ : world, ⌜L.M.E.invokestrcmp_contractworld CResultd W ArgP v; ArgP w WPtrp; WPtrq L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′⌝ −∗ heap_interpwi σ −∗ stringp b reg xs ∗ stringq b′ reg′ ys ⇛ ∃e′ : env, ⌜external_envstrcmp_contractworld site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"strcmp"; site_args ≔ ArgP v; ArgP w; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpwi ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

iPureIntro

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
σ :
Hp :
Hq :
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
HK :
▷∀bits : Z, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntbits e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
▷∀σ : L.lstateworld trace : listevent values : listword s′ : R.state m′ : mem w′ : world, ⌜L.M.E.invokestrcmp_contractworld CResultd W ArgP v; ArgP w WPtrp; WPtrq L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′⌝ −∗ heap_interpwi σ −∗ stringp b reg xs ∗ stringq b′ reg′ ys ⇛ ∃e′ : env, ⌜external_envstrcmp_contractworld site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"strcmp"; site_args ≔ ArgP v; ArgP w; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpwi ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

exists p, q, Z.of_natlengthxs, Z.of_natlengthys

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
σ :
Hp :
Hq :
⊢
WPtrp; WPtrq = WPtrp; WPtrq ∧ terminated_lengthL.ls_memσ p lengthxs ∧ terminated_lengthL.ls_memσ q lengthys
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
HK :
▷∀bits : Z, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntbits e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
▷∀σ : L.lstateworld trace : listevent values : listword s′ : R.state m′ : mem w′ : world, ⌜L.M.E.invokestrcmp_contractworld CResultd W ArgP v; ArgP w WPtrp; WPtrq L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′⌝ −∗ heap_interpwi σ −∗ stringp b reg xs ∗ stringq b′ reg′ ys ⇛ ∃e′ : env, ⌜external_envstrcmp_contractworld site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"strcmp"; site_args ≔ ArgP v; ArgP w; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpwi ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

auto

deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
HK :
▷∀bits : Z, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntbits e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
▷∀σ : L.lstateworld trace : listevent values : listword s′ : R.state m′ : mem w′ : world, ⌜L.M.E.invokestrcmp_contractworld CResultd W ArgP v; ArgP w WPtrp; WPtrq L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′⌝ −∗ heap_interpwi σ −∗ stringp b reg xs ∗ stringq b′ reg′ ys ⇛ ∃e′ : env, ⌜external_envstrcmp_contractworld site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"strcmp"; site_args ≔ ArgP v; ArgP w; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpwi ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

–iNext

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
HK :
∀bits : Z, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntbits e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
∀σ : L.lstateworld trace : listevent values : listword s′ : R.state m′ : mem w′ : world, ⌜L.M.E.invokestrcmp_contractworld CResultd W ArgP v; ArgP w WPtrp; WPtrq L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′⌝ −∗ heap_interpwi σ −∗ stringp b reg xs ∗ stringq b′ reg′ ys ⇛ ∃e′ : env, ⌜external_envstrcmp_contractworld site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"strcmp"; site_args ≔ ArgP v; ArgP w; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpwi ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

iIntros σ trace values s′ m′ w′ Hinv Hσ [Hs Ht]

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
σ :
trace :
listevent
values :
listword
s′ :
R.state
m′ :
w′ :
world
Hinv :
L.M.E.invokestrcmp_contractworld CResultd W ArgP v; ArgP w WPtrp; WPtrq L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′
HK :
∀bits : Z, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntbits e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
Hσ :
heap_interpwi σ
Hs :
stringp b reg xs
Ht :
stringq b′ reg′ ys
∗
|⇛ ∃e′ : env, ⌜external_envstrcmp_contractworld site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"strcmp"; site_args ≔ ArgP v; ArgP w; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpwi ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

destruct M.E.strcmp_invocation_ _ _ _ _ _ _ _ _ _ _ _ Hinv as _ & → & → & p′ & q′ & bits & Hx & _ & He

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
σ :
trace :
listevent
values :
listword
s′ :
R.state
Hinv :
L.M.E.invokestrcmp_contractworld CResultd W ArgP v; ArgP w WPtrp; WPtrq L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ L.ls_memσ L.ls_worldσ
p′, q′ :
bits :
Z
Hx :
WPtrp; WPtrq = WPtrp′; WPtrq′
He :
HK :
∀bits0 : Z, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntbits0 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
Hσ :
heap_interpwi σ
Hs :
stringp b reg xs
Ht :
stringq b′ reg′ ys
∗
|⇛ ∃e′ : env, ⌜external_envstrcmp_contractworld site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"strcmp"; site_args ≔ ArgP v; ArgP w; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpwi ls_mem ≔ L.ls_memσ; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ L.ls_worldσ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

injection He as →

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
σ :
trace :
listevent
s′ :
R.state
bits :
Z
Hinv :
L.M.E.invokestrcmp_contractworld CResultd W ArgP v; ArgP w WPtrp; WPtrq L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnWIntbits s′ L.ls_memσ L.ls_worldσ
p′, q′ :
Hx :
WPtrp; WPtrq = WPtrp′; WPtrq′
HK :
∀bits0 : Z, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntbits0 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
Hσ :
heap_interpwi σ
Hs :
stringp b reg xs
Ht :
stringq b′ reg′ ys
∗
|⇛ ∃e′ : env, ⌜external_envstrcmp_contractworld site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"strcmp"; site_args ≔ ArgP v; ArgP w; site_rest ≔ rest; site_jump ≔ j WIntbits e = Somee′⌝ ∗ heap_interpwi ls_mem ≔ L.ls_memσ; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ L.ls_worldσ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

iDestruct pure_return with Hσ as Hσ ; exact Hinv |

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
σ :
trace :
listevent
s′ :
R.state
bits :
Z
Hinv :
L.M.E.invokestrcmp_contractworld CResultd W ArgP v; ArgP w WPtrp; WPtrq L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnWIntbits s′ L.ls_memσ L.ls_worldσ
p′, q′ :
Hx :
WPtrp; WPtrq = WPtrp′; WPtrq′
HK :
∀bits0 : Z, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntbits0 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
Hs :
stringp b reg xs
Ht :
stringq b′ reg′ ys
Hσ :
heap_interpwi ls_mem ≔ ls_memσ; ls_rt ≔ s′; ls_fuel ≔ ls_fuelσ; ls_world ≔ ls_worldσ
∗
|⇛ ∃e′ : env, ⌜external_envstrcmp_contractworld site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"strcmp"; site_args ≔ ArgP v; ArgP w; site_rest ≔ rest; site_jump ≔ j WIntbits e = Somee′⌝ ∗ heap_interpwi ls_mem ≔ L.ls_memσ; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ L.ls_worldσ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

destruct σ as m s fuel w0

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
m :
s :
R.state
fuel :
Z
w0 :
world
trace :
listevent
s′ :
R.state
bits :
Z
Hinv :
L.M.E.invokestrcmp_contractworld CResultd W ArgP v; ArgP w WPtrp; WPtrq L.ls_rtls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 L.ls_memls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 L.ls_worldls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 trace CallReturnWIntbits s′ L.ls_memls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 L.ls_worldls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0
p′, q′ :
Hx :
WPtrp; WPtrq = WPtrp′; WPtrq′
HK :
∀bits0 : Z, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntbits0 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
Hs :
stringp b reg xs
Ht :
stringq b′ reg′ ys
Hσ :
heap_interpwi ls_mem ≔ ls_memls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0; ls_rt ≔ s′; ls_fuel ≔ ls_fuells_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0; ls_world ≔ ls_worldls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0
∗
|⇛ ∃e′ : env, ⌜external_envstrcmp_contractworld site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"strcmp"; site_args ≔ ArgP v; ArgP w; site_rest ≔ rest; site_jump ≔ j WIntbits e = Somee′⌝ ∗ heap_interpwi ls_mem ≔ L.ls_memls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuells_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0; ls_world ≔ L.ls_worldls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

iModIntro

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
m :
s :
R.state
fuel :
Z
w0 :
world
trace :
listevent
s′ :
R.state
bits :
Z
Hinv :
L.M.E.invokestrcmp_contractworld CResultd W ArgP v; ArgP w WPtrp; WPtrq L.ls_rtls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 L.ls_memls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 L.ls_worldls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 trace CallReturnWIntbits s′ L.ls_memls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 L.ls_worldls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0
p′, q′ :
Hx :
WPtrp; WPtrq = WPtrp′; WPtrq′
HK :
∀bits0 : Z, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntbits0 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
Hs :
stringp b reg xs
Ht :
stringq b′ reg′ ys
Hσ :
heap_interpwi ls_mem ≔ ls_memls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0; ls_rt ≔ s′; ls_fuel ≔ ls_fuells_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0; ls_world ≔ ls_worldls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0
∗
∃e′ : env, ⌜external_envstrcmp_contractworld site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"strcmp"; site_args ≔ ArgP v; ArgP w; site_rest ≔ rest; site_jump ≔ j WIntbits e = Somee′⌝ ∗ heap_interpwi ls_mem ≔ L.ls_memls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuells_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0; ls_world ≔ L.ls_worldls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

iExists _

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
m :
s :
R.state
fuel :
Z
w0 :
world
trace :
listevent
s′ :
R.state
bits :
Z
Hinv :
L.M.E.invokestrcmp_contractworld CResultd W ArgP v; ArgP w WPtrp; WPtrq L.ls_rtls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 L.ls_memls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 L.ls_worldls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 trace CallReturnWIntbits s′ L.ls_memls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 L.ls_worldls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0
p′, q′ :
Hx :
WPtrp; WPtrq = WPtrp′; WPtrq′
HK :
∀bits0 : Z, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntbits0 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
Hs :
stringp b reg xs
Ht :
stringq b′ reg′ ys
Hσ :
heap_interpwi ls_mem ≔ ls_memls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0; ls_rt ≔ s′; ls_fuel ≔ ls_fuells_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0; ls_world ≔ ls_worldls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0
∗
⌜external_envstrcmp_contractworld site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"strcmp"; site_args ≔ ArgP v; ArgP w; site_rest ≔ rest; site_jump ≔ j WIntbits e = Some?e⌝ ∗ heap_interpwi ls_mem ≔ L.ls_memls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuells_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0; ls_world ≔ L.ls_worldls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ ?e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
shelved goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
m :
s :
R.state
fuel :
Z
w0 :
world
trace :
listevent
s′ :
R.state
bits :
Z
Hinv :
L.M.E.invokestrcmp_contractworld CResultd W ArgP v; ArgP w WPtrp; WPtrq L.ls_rtls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 L.ls_memls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 L.ls_worldls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 trace CallReturnWIntbits s′ L.ls_memls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 L.ls_worldls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0
p′, q′ :
Hx :
WPtrp; WPtrq = WPtrp′; WPtrq′
⊢

iSplit ; iPureIntro ; reflexivity |

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
m :
s :
R.state
fuel :
Z
w0 :
world
trace :
listevent
s′ :
R.state
bits :
Z
Hinv :
L.M.E.invokestrcmp_contractworld CResultd W ArgP v; ArgP w WPtrp; WPtrq L.ls_rtls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 L.ls_memls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 L.ls_worldls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 trace CallReturnWIntbits s′ L.ls_memls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 L.ls_worldls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0
p′, q′ :
Hx :
WPtrp; WPtrq = WPtrp′; WPtrq′
HK :
∀bits0 : Z, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntbits0 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
Hs :
stringp b reg xs
Ht :
stringq b′ reg′ ys
Hσ :
heap_interpwi ls_mem ≔ ls_memls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0; ls_rt ≔ s′; ls_fuel ≔ ls_fuells_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0; ls_world ≔ ls_worldls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0
∗
heap_interpwi ls_mem ≔ L.ls_memls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuells_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0; ls_world ≔ L.ls_worldls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ putd WIntbits mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

iFrame Hσ

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
v, w :
rest :
listinst
j :
p :
b :
Z
reg :
xs :
listZ
q :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcmp" = Somestrcmp_contractworld
Hfn :
find_fnge TAtom"strcmp" = None
Hdata :
lookupTAtom"strcmp" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hw :
arg_xge e ArgP w = SomeWPtrq
m :
s :
R.state
fuel :
Z
w0 :
world
trace :
listevent
s′ :
R.state
bits :
Z
Hinv :
L.M.E.invokestrcmp_contractworld CResultd W ArgP v; ArgP w WPtrp; WPtrq L.ls_rtls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 L.ls_memls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 L.ls_worldls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 trace CallReturnWIntbits s′ L.ls_memls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0 L.ls_worldls_mem ≔ m; ls_rt ≔ s; ls_fuel ≔ fuel; ls_world ≔ w0
p′, q′ :
Hx :
WPtrp; WPtrq = WPtrp′; WPtrq′
HK :
∀bits0 : Z, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntbits0 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
Hs :
stringp b reg xs
Ht :
stringq b′ reg′ ys
∗
WPL.ERunfr_fn ≔ f; fr_env ≔ putd WIntbits mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

iApply HK with Hs Ht

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hreg Hfn Hdata Hv Hw
iIntros Hs Ht HK
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ strcmp_contractworld WPtrp; WPtrq stringp b reg xs ∗ stringq b′ reg′ ys with [$Hs $Ht] [HK] ; done | done | done | done | cbn [ map_option ] ; rewrite Hv Hw ; done | | |
–split ; right ; eexists ; reflexivity | do 2 eexists ; reflexivity
–iIntros σ Hσ [Hs Ht]
iDestruct string_facts with Hσ Hs as %Hp _
iDestruct string_facts with Hσ Ht as %Hq _
iPureIntro
exists p, q, Z.of_natlengthxs, Z.of_natlengthys
auto
–iNext
iIntros σ trace values s′ m′ w′ Hinv Hσ [Hs Ht]
destruct M.E.strcmp_invocation_ _ _ _ _ _ _ _ _ _ _ _ Hinv as _ & → & → & p′ & q′ & bits & Hx & _ & He
injection He as →
iDestruct pure_return with Hσ as Hσ ; exact Hinv |
destruct σ as m s fuel w0
iModIntro
iExists _
iSplit ; iPureIntro ; reflexivity |
iFrame Hσ
iApply HK with Hs Ht

strncmp's triple, from strncmp_contract: owning the strings at p and q, which v and w read as, compared up to n bytes, which u reads as, the call binds d to an int.

496Lemma wp_strncmp
∀ f e ls lab d v w u rest j p b reg xs q b′ reg′ ys n Φ
registryTAtom"strncmp" = Somestrncmp_contractworld
find_fnge TAtom"strncmp" = None
lookupTAtom"strncmp" ge_globalsge = None
arg_xge e ArgP v = SomeWPtrp
arg_xge e ArgP w = SomeWPtrq
arg_xge e ArgL u = SomeWIntn
0 ≤ n < 2 ^ 64
stringp b reg xs −∗ stringq b′ reg′ ys −∗ ▷∀bits, stringp b reg xs −∗ stringq b′ reg′ ys −∗ WPERunmkFramef putd WIntbits e ls None Execlab rest j : sexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd W GlobalTAtom"strncmp" ArgP v; ArgP w; ArgL u :: rest j : sexpr {Φ}
Proof 22 steps Qed
intros Hreg Hfn Hdata Hv Hw Hu Hn
iIntros Hs Ht HK
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ strncmp_contractworld WPtrp; WPtrq; WIntn stringp b reg xs ∗ stringq b' reg' ys with [$Hs $Ht] [HK] ; done | done | done | done | cbn [ map_option ] ; rewrite Hv Hw Hu ; done | | |
–split ; right ; eexists ; reflexivity | do 3 eexists ; reflexivity
–iIntros σ Hσ [[%Hok Hs] [%Hok′ Ht]]
iDestruct pts_facts with Hσ Hs as %Ha & _
iDestruct pts_facts with Hσ Ht as %Ha′ & _
iPureIntro
do 5 eexists
split ; reflexivity |
split ; exact string_bounded_ _ _ _ _ _ Hok Ha Hn | exact string_bounded_ _ _ _ _ _ Hok' Ha' Hn
–iNext
iIntros σ trace values s′ m′ w′ Hinv Hσ [Hs Ht]
destruct M.E.strncmp_invocation_ _ _ _ _ _ _ _ _ _ _ _ Hinv as _ & → & → & p′ & q′ & n′ & bits & Hx & _ & He
injection He as →
iDestruct pure_return with Hσ as Hσ ; exact Hinv |
destruct σ as m s fuel w0
iModIntro
iExists _
iSplit ; iPureIntro ; reflexivity |
iFrame Hσ
iApply HK with Hs Ht

strrchr's triple, from strrchr_contract: owning the string at p, which v reads as, the call binds d to null or to a pointer into the string before its NUL, with p's capability, for an int c, which w reads as, whose low byte is not the NUL.

528Lemma wp_strrchr
∀ f e ls lab d v w rest j p b reg bytes c Φ
registryTAtom"strrchr" = Somestrrchr_contractworld
find_fnge TAtom"strrchr" = None
lookupTAtom"strrchr" ge_globalsge = None
arg_xge e ArgP v = SomeWPtrp
arg_xge e ArgW w = SomeWIntc
0 ≤ c < 2 ^ 32
c mod 256 ≠ 0
stringp b reg bytes −∗ ▷∀q, ⌜q = mkPtr0 CNone ∨ ∃i, i < lengthbytes%nat ∧ q = mkPtrptr_addrp + Z.of_nati ptr_capp⌝ −∗ stringp b reg bytes −∗ WPERunmkFramef putd WPtrq e ls None Execlab rest j : sexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd P GlobalTAtom"strrchr" ArgP v; ArgW w :: rest j : sexpr {Φ}
Proof 40 steps Qed
intros Hreg Hfn Hdata Hv Hw Hc Hnz
iIntros Hs HK
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ strrchr_contractworld WPtrp; WIntc stringp b reg bytes with Hs [HK] ; done | done | done | done | cbn [ map_option ] ; rewrite Hv Hw ; done | | |
–split ; right ; eexists ; reflexivity | do 2 eexists ; reflexivity
–iIntros σ Hσ Hs
iDestruct string_facts with Hσ Hs as %Ht _
iPureIntro
exists p, c, Z.of_natlengthbytes
auto
–iNext
iIntros σ trace values s′ m′ w′ Hinv Hσ Hs
iDestruct Hs as [%Hok Hs]
iDestruct pts_facts with Hσ Hs as %Ha & _
pose proof string_terminated_ _ _ _ _ Hok Ha as Ht
pose proof string_bytes_ _ _ _ _ Hok Ha as Hb
destruct M.E.strrchr_invocation_ _ _ _ _ _ _ _ _ _ _ _ Hinv as _ & → & → & p′ & c′ & q & Hx & _ & k & Hk & Hq & He
injection Hx as ← ←
injection He as →
rewrite terminated_length_unique_ _ _ _ Hk Ht in Hq
iDestruct pure_return with Hσ as Hσ ; exact Hinv |
destruct σ as m s fuel w0
iModIntro
iExists _
iSplit ; iPureIntro ; reflexivity |
iFrame Hσ
iApply HK with [%] [Hs] ; | by iSplit
cbn [ ls_mem ] in Hb
destruct Hq as i & Hi & Hv′ & _ & → | _ & → ; right | left ; reflexivity
exists Z.to_nati
split ; | rewrite Z2Nat.id ; reflexivity | lia
destruct decideZ.to_nati = lengthbytes as Heq | Hne ; | lia
exfalso
apply Hnz
rewrite <- Hv'
rewrite <- Z2Nat.idi by lia
rewrite Heq
apply Hblengthbytes 0
rewrite lookup_app_r ; | lia
rewrite Nat.sub_diag
reflexivity

puts

571Section puts
572Context rep : mem → stdio_world → Prop requests : listword → mem → stdio_world → Z → Z → Prop registry : name → optioncontractstdio_world `{!SafepointStablestdio_wirep} ge : genv

The Iris instance of the registry and stdio_wi.

576Instance puts_irisGS: irisGS_genhlc nanofil_langregistry ge Σ ≔
nanofil_irisGSregistry stdio_wirep ge

The expressions of the language.

580Notation pexpr ≔ language.exprnanofil_langregistry ge

puts's triple, from puts_contract: owning the string at p, which v reads as, the call binds d to the int it returns, n modulo 2^32, and the string is still owned: puts writes only its world's roots, which stdio_wi keeps apart from it.

586Lemma wp_puts
∀ f e ls lab d v rest j p b reg bytes Φ
registryTAtom"puts" = Someputs_contractrep requests
find_fnge TAtom"puts" = None
arg_xge e ArgP v = SomeWPtrp
stringp b reg bytes −∗ ▷∀n, stringp b reg bytes −∗ WPERunmkFramef putd WIntn mod 2 ^ 32 e ls None Execlab rest j : pexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd W GlobalTAtom"puts" ArgP v :: rest j : pexpr {Φ}
Explore proof 23 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
⊢
registryTAtom"puts" = Someputs_contractrep requests → find_fnge TAtom"puts" = None → lookupTAtom"puts" ge_globalsge = None → arg_xge e ArgP v = SomeWPtrp → stringp b reg bytes −∗ ▷∀n : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j : pexpr {v. Φv} −∗ WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab CallCResultd W GlobalTAtom"puts" ArgP v :: rest j : pexpr {v. Φv}

intros Hreg Hfn Hdata Hv

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
⊢
stringp b reg bytes −∗ ▷∀n : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j : pexpr {v. Φv} −∗ WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab CallCResultd W GlobalTAtom"puts" ArgP v :: rest j : pexpr {v. Φv}

iIntros Hs HK

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hs :
stringp b reg bytes
HK :
▷∀n : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab CallCResultd W GlobalTAtom"puts" ArgP v :: rest j {v. Φv}

iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ puts_contractrep requests WPtrp stringp b reg bytes with Hs [HK] ; done | done | done | done | cbn [ map_option ] ; rewrite Hv ; done | | |

3 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
focused goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
⊢
∀σ : L.lstatestdio_world, heap_interpstdio_wirep σ −∗ stringp b reg bytes −∗ ⌜contract_preputs_contractrep requests WPtrp L.ls_memσ L.ls_worldσ⌝
focused goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
HK :
▷∀n : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
▷∀σ : L.lstatestdio_world trace : listevent values : listword s′ : R.state m′ : mem w′ : stdio_world, ⌜L.M.E.invokeputs_contractrep requests CResultd W ArgP v WPtrp L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′⌝ −∗ heap_interpstdio_wirep σ −∗ stringp b reg bytes ⇛ ∃e′ : env, ⌜external_envputs_contractrep requests site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"puts"; site_args ≔ ArgP v; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpstdio_wirep ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

–split ; right ; eexists ; reflexivity | eexists ; reflexivity

2 open

deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
⊢
∀σ : L.lstatestdio_world, heap_interpstdio_wirep σ −∗ stringp b reg bytes −∗ ⌜contract_preputs_contractrep requests WPtrp L.ls_memσ L.ls_worldσ⌝
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
HK :
▷∀n : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
▷∀σ : L.lstatestdio_world trace : listevent values : listword s′ : R.state m′ : mem w′ : stdio_world, ⌜L.M.E.invokeputs_contractrep requests CResultd W ArgP v WPtrp L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′⌝ −∗ heap_interpstdio_wirep σ −∗ stringp b reg bytes ⇛ ∃e′ : env, ⌜external_envputs_contractrep requests site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"puts"; site_args ≔ ArgP v; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpstdio_wirep ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

–iIntros σ Hσ Hs

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hσ :
heap_interpstdio_wirep σ
Hs :
stringp b reg bytes
∗
⌜contract_preputs_contractrep requests WPtrp L.ls_memσ L.ls_worldσ⌝
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
HK :
▷∀n : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
▷∀σ : L.lstatestdio_world trace : listevent values : listword s′ : R.state m′ : mem w′ : stdio_world, ⌜L.M.E.invokeputs_contractrep requests CResultd W ArgP v WPtrp L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′⌝ −∗ heap_interpstdio_wirep σ −∗ stringp b reg bytes ⇛ ∃e′ : env, ⌜external_envputs_contractrep requests site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"puts"; site_args ≔ ArgP v; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpstdio_wirep ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

iDestruct string_facts with Hσ Hs as %_ Hc

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hc :
c_stringls_memσ p bytes
Hσ :
heap_interpstdio_wirep σ
Hs :
stringp b reg bytes
∗
⌜contract_preputs_contractrep requests WPtrp L.ls_memσ L.ls_worldσ⌝
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
HK :
▷∀n : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
▷∀σ : L.lstatestdio_world trace : listevent values : listword s′ : R.state m′ : mem w′ : stdio_world, ⌜L.M.E.invokeputs_contractrep requests CResultd W ArgP v WPtrp L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′⌝ −∗ heap_interpstdio_wirep σ −∗ stringp b reg bytes ⇛ ∃e′ : env, ⌜external_envputs_contractrep requests site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"puts"; site_args ≔ ArgP v; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpstdio_wirep ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

iDestruct Hσ as h [_ %Hf]

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hc :
c_stringls_memσ p bytes
h :
Hf :
agreesL.ls_memσ h ∧ live_disjointL.ls_memσ ∧ R.readyL.ls_rtσ L.ls_memσ ∧ stdio_wirep L.ls_memσ L.ls_worldσ h
Hs :
stringp b reg bytes
∗
⌜contract_preputs_contractrep requests WPtrp L.ls_memσ L.ls_worldσ⌝
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
HK :
▷∀n : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
▷∀σ : L.lstatestdio_world trace : listevent values : listword s′ : R.state m′ : mem w′ : stdio_world, ⌜L.M.E.invokeputs_contractrep requests CResultd W ArgP v WPtrp L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′⌝ −∗ heap_interpstdio_wirep σ −∗ stringp b reg bytes ⇛ ∃e′ : env, ⌜external_envputs_contractrep requests site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"puts"; site_args ≔ ArgP v; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpstdio_wirep ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

destruct Hf as _ & _ & _ & Hrep & Hw & _

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hc :
c_stringls_memσ p bytes
h :
Hrep :
repL.ls_memσ L.ls_worldσ
Hw :
Hs :
stringp b reg bytes
∗
⌜contract_preputs_contractrep requests WPtrp L.ls_memσ L.ls_worldσ⌝
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
HK :
▷∀n : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
▷∀σ : L.lstatestdio_world trace : listevent values : listword s′ : R.state m′ : mem w′ : stdio_world, ⌜L.M.E.invokeputs_contractrep requests CResultd W ArgP v WPtrp L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′⌝ −∗ heap_interpstdio_wirep σ −∗ stringp b reg bytes ⇛ ∃e′ : env, ⌜external_envputs_contractrep requests site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"puts"; site_args ≔ ArgP v; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpstdio_wirep ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

iPureIntro

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hc :
c_stringls_memσ p bytes
h :
Hrep :
repL.ls_memσ L.ls_worldσ
Hw :
⊢
contract_preputs_contractrep requests WPtrp L.ls_memσ L.ls_worldσ
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
HK :
▷∀n : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
▷∀σ : L.lstatestdio_world trace : listevent values : listword s′ : R.state m′ : mem w′ : stdio_world, ⌜L.M.E.invokeputs_contractrep requests CResultd W ArgP v WPtrp L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′⌝ −∗ heap_interpstdio_wirep σ −∗ stringp b reg bytes ⇛ ∃e′ : env, ⌜external_envputs_contractrep requests site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"puts"; site_args ≔ ArgP v; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpstdio_wirep ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

split ; exact Hrep |

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hc :
c_stringls_memσ p bytes
h :
Hrep :
repL.ls_memσ L.ls_worldσ
Hw :
⊢
stdio_readyL.ls_memσ L.ls_worldσ ∧ ∃p0 : ptr bytes0 : listZ, WPtrp = WPtrp0 ∧ c_stringL.ls_memσ p0 bytes0
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
HK :
▷∀n : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
▷∀σ : L.lstatestdio_world trace : listevent values : listword s′ : R.state m′ : mem w′ : stdio_world, ⌜L.M.E.invokeputs_contractrep requests CResultd W ArgP v WPtrp L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′⌝ −∗ heap_interpstdio_wirep σ −∗ stringp b reg bytes ⇛ ∃e′ : env, ⌜external_envputs_contractrep requests site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"puts"; site_args ≔ ArgP v; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpstdio_wirep ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

split ; exact Hw |

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hc :
c_stringls_memσ p bytes
h :
Hrep :
repL.ls_memσ L.ls_worldσ
Hw :
⊢
∃p0 : ptr bytes0 : listZ, WPtrp = WPtrp0 ∧ c_stringL.ls_memσ p0 bytes0
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
HK :
▷∀n : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
▷∀σ : L.lstatestdio_world trace : listevent values : listword s′ : R.state m′ : mem w′ : stdio_world, ⌜L.M.E.invokeputs_contractrep requests CResultd W ArgP v WPtrp L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′⌝ −∗ heap_interpstdio_wirep σ −∗ stringp b reg bytes ⇛ ∃e′ : env, ⌜external_envputs_contractrep requests site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"puts"; site_args ≔ ArgP v; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpstdio_wirep ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

exists p, bytes

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
Hc :
c_stringls_memσ p bytes
h :
Hrep :
repL.ls_memσ L.ls_worldσ
Hw :
⊢
WPtrp = WPtrp ∧ c_stringL.ls_memσ p bytes
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
HK :
▷∀n : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
▷∀σ : L.lstatestdio_world trace : listevent values : listword s′ : R.state m′ : mem w′ : stdio_world, ⌜L.M.E.invokeputs_contractrep requests CResultd W ArgP v WPtrp L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′⌝ −∗ heap_interpstdio_wirep σ −∗ stringp b reg bytes ⇛ ∃e′ : env, ⌜external_envputs_contractrep requests site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"puts"; site_args ≔ ArgP v; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpstdio_wirep ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

auto

deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
HK :
▷∀n : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
▷∀σ : L.lstatestdio_world trace : listevent values : listword s′ : R.state m′ : mem w′ : stdio_world, ⌜L.M.E.invokeputs_contractrep requests CResultd W ArgP v WPtrp L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′⌝ −∗ heap_interpstdio_wirep σ −∗ stringp b reg bytes ⇛ ∃e′ : env, ⌜external_envputs_contractrep requests site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"puts"; site_args ≔ ArgP v; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpstdio_wirep ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

–iNext

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
HK :
∀n : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
∗
∀σ : L.lstatestdio_world trace : listevent values : listword s′ : R.state m′ : mem w′ : stdio_world, ⌜L.M.E.invokeputs_contractrep requests CResultd W ArgP v WPtrp L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′⌝ −∗ heap_interpstdio_wirep σ −∗ stringp b reg bytes ⇛ ∃e′ : env, ⌜external_envputs_contractrep requests site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"puts"; site_args ≔ ArgP v; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpstdio_wirep ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

iIntros σ trace values s′ m′ w′ Hinv (%h & Hh & %Hf) Hs

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
trace :
listevent
values :
listword
s′ :
R.state
m′ :
Hinv :
L.M.E.invokeputs_contractrep requests CResultd W ArgP v WPtrp L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′
h :
Hf :
agreesL.ls_memσ h ∧ live_disjointL.ls_memσ ∧ R.readyL.ls_rtσ L.ls_memσ ∧ stdio_wirep L.ls_memσ L.ls_worldσ h
HK :
∀n : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
Hh :
gen_heap_interph
Hs :
stringp b reg bytes
∗
|⇛ ∃e′ : env, ⌜external_envputs_contractrep requests site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"puts"; site_args ≔ ArgP v; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpstdio_wirep ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

destruct Hf as Ha & Hd & Hr & Hwi

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
trace :
listevent
values :
listword
s′ :
R.state
m′ :
Hinv :
L.M.E.invokeputs_contractrep requests CResultd W ArgP v WPtrp L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′
h :
Ha :
agreesL.ls_memσ h
Hd :
live_disjointL.ls_memσ
Hr :
R.readyL.ls_rtσ L.ls_memσ
Hwi :
stdio_wirep L.ls_memσ L.ls_worldσ h
HK :
∀n : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
Hh :
gen_heap_interph
Hs :
stringp b reg bytes
∗
|⇛ ∃e′ : env, ⌜external_envputs_contractrep requests site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"puts"; site_args ≔ ArgP v; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpstdio_wirep ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

destruct puts_return_frame_ _ _ _ _ _ _ _ _ _ _ _ _ h Hinv Ha Hd Hr Hwi as Ha′ & Hd′ & Hr′ & Hwi′

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
trace :
listevent
values :
listword
s′ :
R.state
m′ :
Hinv :
L.M.E.invokeputs_contractrep requests CResultd W ArgP v WPtrp L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnvalues s′ m′ w′
h :
Ha :
agreesL.ls_memσ h
Hd :
live_disjointL.ls_memσ
Hr :
R.readyL.ls_rtσ L.ls_memσ
Hwi :
stdio_wirep L.ls_memσ L.ls_worldσ h
Ha′ :
agreesm′ h
Hd′ :
Hr′ :
R.readys′ m′
Hwi′ :
stdio_wirep m′ w′ h
HK :
∀n : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
Hh :
gen_heap_interph
Hs :
stringp b reg bytes
∗
|⇛ ∃e′ : env, ⌜external_envputs_contractrep requests site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"puts"; site_args ≔ ArgP v; site_rest ≔ rest; site_jump ≔ j values e = Somee′⌝ ∗ heap_interpstdio_wirep ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

destruct puts_returns_int_ _ _ _ _ _ _ _ _ _ _ _ _ Hinv as n & →

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
trace :
listevent
s′ :
R.state
m′ :
n :
Z
Hinv :
L.M.E.invokeputs_contractrep requests CResultd W ArgP v WPtrp L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnWIntn s′ m′ w′
h :
Ha :
agreesL.ls_memσ h
Hd :
live_disjointL.ls_memσ
Hr :
R.readyL.ls_rtσ L.ls_memσ
Hwi :
stdio_wirep L.ls_memσ L.ls_worldσ h
Ha′ :
agreesm′ h
Hd′ :
Hr′ :
R.readys′ m′
Hwi′ :
stdio_wirep m′ w′ h
HK :
∀n0 : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn0 mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
Hh :
gen_heap_interph
Hs :
stringp b reg bytes
∗
|⇛ ∃e′ : env, ⌜external_envputs_contractrep requests site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"puts"; site_args ≔ ArgP v; site_rest ≔ rest; site_jump ≔ j WIntn e = Somee′⌝ ∗ heap_interpstdio_wirep ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

iModIntro

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
trace :
listevent
s′ :
R.state
m′ :
n :
Z
Hinv :
L.M.E.invokeputs_contractrep requests CResultd W ArgP v WPtrp L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnWIntn s′ m′ w′
h :
Ha :
agreesL.ls_memσ h
Hd :
live_disjointL.ls_memσ
Hr :
R.readyL.ls_rtσ L.ls_memσ
Hwi :
stdio_wirep L.ls_memσ L.ls_worldσ h
Ha′ :
agreesm′ h
Hd′ :
Hr′ :
R.readys′ m′
Hwi′ :
stdio_wirep m′ w′ h
HK :
∀n0 : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn0 mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
Hh :
gen_heap_interph
Hs :
stringp b reg bytes
∗
∃e′ : env, ⌜external_envputs_contractrep requests site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"puts"; site_args ≔ ArgP v; site_rest ≔ rest; site_jump ≔ j WIntn e = Somee′⌝ ∗ heap_interpstdio_wirep ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ e′; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

iExists _

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
trace :
listevent
s′ :
R.state
m′ :
n :
Z
Hinv :
L.M.E.invokeputs_contractrep requests CResultd W ArgP v WPtrp L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnWIntn s′ m′ w′
h :
Ha :
agreesL.ls_memσ h
Hd :
live_disjointL.ls_memσ
Hr :
R.readyL.ls_rtσ L.ls_memσ
Hwi :
stdio_wirep L.ls_memσ L.ls_worldσ h
Ha′ :
agreesm′ h
Hd′ :
Hr′ :
R.readys′ m′
Hwi′ :
stdio_wirep m′ w′ h
HK :
∀n0 : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn0 mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
Hh :
gen_heap_interph
Hs :
stringp b reg bytes
∗
⌜external_envputs_contractrep requests site_label ≔ lab; site_result ≔ CResultd W; site_name ≔ TAtom"puts"; site_args ≔ ArgP v; site_rest ≔ rest; site_jump ≔ j WIntn e = Some?e⌝ ∗ heap_interpstdio_wirep ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ ?e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
shelved goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
trace :
listevent
s′ :
R.state
m′ :
n :
Z
Hinv :
L.M.E.invokeputs_contractrep requests CResultd W ArgP v WPtrp L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnWIntn s′ m′ w′
h :
Ha :
agreesL.ls_memσ h
Hd :
live_disjointL.ls_memσ
Hr :
R.readyL.ls_rtσ L.ls_memσ
Hwi :
stdio_wirep L.ls_memσ L.ls_worldσ h
Ha′ :
agreesm′ h
Hd′ :
Hr′ :
R.readys′ m′
Hwi′ :
stdio_wirep m′ w′ h
⊢

iSplit ; iPureIntro ; reflexivity |

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
trace :
listevent
s′ :
R.state
m′ :
n :
Z
Hinv :
L.M.E.invokeputs_contractrep requests CResultd W ArgP v WPtrp L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnWIntn s′ m′ w′
h :
Ha :
agreesL.ls_memσ h
Hd :
live_disjointL.ls_memσ
Hr :
R.readyL.ls_rtσ L.ls_memσ
Hwi :
stdio_wirep L.ls_memσ L.ls_worldσ h
Ha′ :
agreesm′ h
Hd′ :
Hr′ :
R.readys′ m′
Hwi′ :
stdio_wirep m′ w′ h
HK :
∀n0 : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn0 mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
Hh :
gen_heap_interph
Hs :
stringp b reg bytes
∗
heap_interpstdio_wirep ls_mem ≔ m′; ls_rt ≔ s′; ls_fuel ≔ L.ls_fuelσ; ls_world ≔ w′ ∗ WPL.ERunfr_fn ≔ f; fr_env ≔ putd WIntn mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

iSplitL Hh ; iExists h ; iFrame Hh ; iPureIntro ; auto |

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
rep :
mem → stdio_world → Prop
requests :
listword → mem → stdio_world → Z → Z → Prop
registry :
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
rest :
listinst
j :
p :
b :
Z
reg :
bytes :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"puts" = Someputs_contractrep requests
Hfn :
find_fnge TAtom"puts" = None
Hdata :
lookupTAtom"puts" ge_globalsge = None
Hv :
arg_xge e ArgP v = SomeWPtrp
trace :
listevent
s′ :
R.state
m′ :
n :
Z
Hinv :
L.M.E.invokeputs_contractrep requests CResultd W ArgP v WPtrp L.ls_rtσ L.ls_memσ L.ls_worldσ trace CallReturnWIntn s′ m′ w′
h :
Ha :
agreesL.ls_memσ h
Hd :
live_disjointL.ls_memσ
Hr :
R.readyL.ls_rtσ L.ls_memσ
Hwi :
stdio_wirep L.ls_memσ L.ls_worldσ h
Ha′ :
agreesm′ h
Hd′ :
Hr′ :
R.readys′ m′
Hwi′ :
stdio_wirep m′ w′ h
HK :
∀n0 : Z, stringp b reg bytes −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WIntn0 mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}
Hs :
stringp b reg bytes
∗
WPL.ERunfr_fn ≔ f; fr_env ≔ putd WIntn mod 2 ^ 32 e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j {v. Φv}

iApply HK with Hs

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hreg Hfn Hdata Hv
iIntros Hs HK
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ puts_contractrep requests WPtrp stringp b reg bytes with Hs [HK] ; done | done | done | done | cbn [ map_option ] ; rewrite Hv ; done | | |
–split ; right ; eexists ; reflexivity | eexists ; reflexivity
–iIntros σ Hσ Hs
iDestruct string_facts with Hσ Hs as %_ Hc
iDestruct Hσ as h [_ %Hf]
destruct Hf as _ & _ & _ & Hrep & Hw & _
iPureIntro
split ; exact Hrep |
split ; exact Hw |
exists p, bytes
auto
–iNext
iIntros σ trace values s′ m′ w′ Hinv (%h & Hh & %Hf) Hs
destruct Hf as Ha & Hd & Hr & Hwi
destruct puts_return_frame_ _ _ _ _ _ _ _ _ _ _ _ _ h Hinv Ha Hd Hr Hwi as Ha′ & Hd′ & Hr′ & Hwi′
destruct puts_returns_int_ _ _ _ _ _ _ _ _ _ _ _ _ Hinv as n & →
iModIntro
iExists _
iSplit ; iPureIntro ; reflexivity |
iSplitL Hh ; iExists h ; iFrame Hh ; iPureIntro ; auto |
iApply HK with Hs

StringLogicOn over a Logic instance of its own.

620Module StringLogic R : Runtime
621Module LG0 ≔ Logic R
Include StringLogicOn R LG0