Fil-C on Nix

Filnix wiki

the formal campaign

rocq/theories/MemLogic.v

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

A block is owned piece by piece: bytes b o xs, the bytes xs from offset o of the object b, and auxes b o cs, the capabilities cs in its aux slots from the same offset. A write by libc into a block needs both: memset clears every pointer slot it touches, a copy moves pointer slots, and a pointer slot is an aux piece.

Each triple is a contract read as a rule, stated at any call site:

The contracts' exact destination frame (memset_frame, shared by the copies) keeps every piece outside the written block (block_frame, through Heap.v's frame_within); for strdup, whose writes lie in its fresh object, frame_other keeps every other object's pieces. The blocks' offsets are 8-aligned so that the slots a write touches start inside them; the contracts also allow unaligned starts, whose first touched slot begins before them.

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 StringLogic
Open Scope Z_scope
Open Scope list_scope

Aux pieces

The pieces of the aux slots holding cs from offset o of the object b.

58Definition aux_psb o : Z cs : listcap : listpiece × pval ≔
zip_withλi c ⇒ PAuxb i, VAuxc seqZo Z.of_natlengthcs cs

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

62Lemma aux_ps_cons
∀ b o c cs
aux_psb o c :: cs = PAuxb o, VAuxc :: aux_psb o + 1 cs
Explore proof 5 tactics

Initial goal

b, o :
Z
c :
cs :
listcap
⊢
aux_psb o c :: cs = PAuxb o, VAuxc :: aux_psb o + 1 cs

unfold aux_ps

b, o :
Z
c :
cs :
listcap
⊢
zip_withλi : Z c0 : cap ⇒ PAuxb i, VAuxc0 seqZo lengthc :: cs c :: cs = PAuxb o, VAuxc :: zip_withλi : Z c0 : cap ⇒ PAuxb i, VAuxc0 seqZo + 1 lengthcs cs

cbn [ length ]

b, o :
Z
c :
cs :
listcap
⊢
zip_withλi : Z c0 : cap ⇒ PAuxb i, VAuxc0 seqZo Slengthcs c :: cs = PAuxb o, VAuxc :: zip_withλi : Z c0 : cap ⇒ PAuxb i, VAuxc0 seqZo + 1 lengthcs cs

rewrite Nat2Z.inj_succ seqZ_cons ; | lia

b, o :
Z
c :
cs :
listcap
⊢
zip_withλi : Z c0 : cap ⇒ PAuxb i, VAuxc0 o :: seqZZ.succo Z.predZ.succlengthcs c :: cs = PAuxb o, VAuxc :: zip_withλi : Z c0 : cap ⇒ PAuxb i, VAuxc0 seqZo + 1 lengthcs cs

rewrite Z.pred_succ

b, o :
Z
c :
cs :
listcap
⊢
zip_withλi : Z c0 : cap ⇒ PAuxb i, VAuxc0 o :: seqZZ.succo lengthcs c :: cs = PAuxb o, VAuxc :: zip_withλi : Z c0 : cap ⇒ PAuxb i, VAuxc0 seqZo + 1 lengthcs cs

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

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

The pieces of cs ++ ds from o are cs's, then ds's after them.

69Lemma aux_ps_app
∀ b o cs ds
aux_psb o cs ++ ds = aux_psb o cs ++ aux_psb o + Z.of_natlengthcs ds
Explore proof 7 tactics

Initial goal

b, o :
Z
cs, ds :
listcap
⊢
aux_psb o cs ++ ds = aux_psb o cs ++ aux_psb o + lengthcs ds

revert o

b :
Z
cs, ds :
listcap
⊢
∀o : Z, aux_psb o cs ++ ds = aux_psb o cs ++ aux_psb o + lengthcs ds

induction cs as | c cs IH ; intros o ; cbn ; rewrite Z.add_0_r ; reflexivity |

b :
Z
c :
cs, ds :
listcap
IH :
∀o : Z, aux_psb o cs ++ ds = aux_psb o cs ++ aux_psb o + lengthcs ds
o :
Z
⊢
aux_psb o c :: cs ++ ds = aux_psb o c :: cs ++ aux_psb o + lengthc :: cs ds

cbn [ app ]

b :
Z
c :
cs, ds :
listcap
IH :
∀o : Z, aux_psb o cs ++ ds = aux_psb o cs ++ aux_psb o + lengthcs ds
o :
Z
⊢
aux_psb o c :: cs ++ ds = aux_psb o c :: cs ++ aux_psb o + lengthc :: cs ds

rewrite ! aux_ps_cons IH

b :
Z
c :
cs, ds :
listcap
IH :
∀o : Z, aux_psb o cs ++ ds = aux_psb o cs ++ aux_psb o + lengthcs ds
o :
Z
⊢
PAuxb o, VAuxc :: aux_psb o + 1 cs ++ aux_psb o + 1 + lengthcs ds = PAuxb o, VAuxc :: aux_psb o + 1 cs ++ aux_psb o + lengthc :: cs ds

cbn [ app length ]

b :
Z
c :
cs, ds :
listcap
IH :
∀o : Z, aux_psb o cs ++ ds = aux_psb o cs ++ aux_psb o + lengthcs ds
o :
Z
⊢
PAuxb o, VAuxc :: aux_psb o + 1 cs ++ aux_psb o + 1 + lengthcs ds = PAuxb o, VAuxc :: aux_psb o + 1 cs ++ aux_psb o + Slengthcs ds

replace o + Z.of_natSlengthcs with o + 1 + Z.of_natlengthcs by lia

b :
Z
c :
cs, ds :
listcap
IH :
∀o : Z, aux_psb o cs ++ ds = aux_psb o cs ++ aux_psb o + lengthcs ds
o :
Z
⊢
PAuxb o, VAuxc :: aux_psb o + 1 cs ++ aux_psb o + 1 + lengthcs ds = PAuxb o, VAuxc :: aux_psb o + 1 cs ++ aux_psb o + 1 + lengthcs ds

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
revert o
induction cs as | c cs IH ; intros o ; cbn ; rewrite Z.add_0_r ; reflexivity |
cbn [ app ]
rewrite ! aux_ps_cons IH
cbn [ app length ]
replace o + Z.of_natSlengthcs with o + 1 + Z.of_natlengthcs by lia
reflexivity

The pieces of n slots holding c, from o.

78Lemma aux_ps_replicate
∀ b o n c
aux_psb o replicaten c = λi ⇒ PAuxb i, VAuxc <$> seqZo Z.of_natn
Explore proof 5 tactics

Initial goal

b, o :
Z
n :
nat
c :
⊢
aux_psb o replicaten c = λi : Z ⇒ PAuxb i, VAuxc <$> seqZo n

revert o

b :
Z
n :
nat
c :
⊢
∀o : Z, aux_psb o replicaten c = λi : Z ⇒ PAuxb i, VAuxc <$> seqZo n

induction n as | n IH ; intros o ; reflexivity |

b :
Z
n :
nat
c :
IH :
∀o : Z, aux_psb o replicaten c = λi : Z ⇒ PAuxb i, VAuxc <$> seqZo n
o :
Z
⊢
aux_psb o replicateSn c = λi : Z ⇒ PAuxb i, VAuxc <$> seqZo Sn

rewrite replicate_S aux_ps_cons IH Nat2Z.inj_succ seqZ_conso ; | lia

b :
Z
n :
nat
c :
IH :
∀o : Z, aux_psb o replicaten c = λi : Z ⇒ PAuxb i, VAuxc <$> seqZo n
o :
Z
⊢
PAuxb o, VAuxc :: λi : Z ⇒ PAuxb i, VAuxc <$> seqZo + 1 n = λi : Z ⇒ PAuxb i, VAuxc <$> o :: seqZZ.succo Z.predZ.succn

rewrite Z.pred_succ

b :
Z
n :
nat
c :
IH :
∀o : Z, aux_psb o replicaten c = λi : Z ⇒ PAuxb i, VAuxc <$> seqZo n
o :
Z
⊢
PAuxb o, VAuxc :: λi : Z ⇒ PAuxb i, VAuxc <$> seqZo + 1 n = λi : Z ⇒ PAuxb i, VAuxc <$> o :: seqZZ.succo n

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
revert o
induction n as | n IH ; intros o ; reflexivity |
rewrite replicate_S aux_ps_cons IH Nat2Z.inj_succ seqZ_conso ; | lia
rewrite Z.pred_succ
reflexivity

The pieces of n bytes holding x, from o.

87Lemma byte_ps_replicate
∀ b o n x
byte_psb o replicaten x = λi ⇒ PByteb i, VBytex <$> seqZo Z.of_natn
Explore proof 5 tactics

Initial goal

b, o :
Z
n :
nat
x :
Z
⊢
byte_psb o replicaten x = λi : Z ⇒ PByteb i, VBytex <$> seqZo n

revert o

b :
Z
n :
nat
x :
Z
⊢
∀o : Z, byte_psb o replicaten x = λi : Z ⇒ PByteb i, VBytex <$> seqZo n

induction n as | n IH ; intros o ; reflexivity |

b :
Z
n :
nat
x :
Z
IH :
∀o : Z, byte_psb o replicaten x = λi : Z ⇒ PByteb i, VBytex <$> seqZo n
o :
Z
⊢
byte_psb o replicateSn x = λi : Z ⇒ PByteb i, VBytex <$> seqZo Sn

rewrite replicate_S byte_ps_cons IH Nat2Z.inj_succ seqZ_conso ; | lia

b :
Z
n :
nat
x :
Z
IH :
∀o : Z, byte_psb o replicaten x = λi : Z ⇒ PByteb i, VBytex <$> seqZo n
o :
Z
⊢
PByteb o, VBytex :: λi : Z ⇒ PByteb i, VBytex <$> seqZo + 1 n = λi : Z ⇒ PByteb i, VBytex <$> o :: seqZZ.succo Z.predZ.succn

rewrite Z.pred_succ

b :
Z
n :
nat
x :
Z
IH :
∀o : Z, byte_psb o replicaten x = λi : Z ⇒ PByteb i, VBytex <$> seqZo n
o :
Z
⊢
PByteb o, VBytex :: λi : Z ⇒ PByteb i, VBytex <$> seqZo + 1 n = λi : Z ⇒ PByteb i, VBytex <$> o :: seqZZ.succo n

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
revert o
induction n as | n IH ; intros o ; reflexivity |
rewrite replicate_S byte_ps_cons IH Nat2Z.inj_succ seqZ_conso ; | lia
rewrite Z.pred_succ
reflexivity

The pieces of cs are aux pieces at the offsets from o.

96Lemma aux_ps_keys
∀ b o cs
aux_psb o cs.*1 = PAuxb <$> seqZo Z.of_natlengthcs
Explore proof 9 tactics

Initial goal

b, o :
Z
cs :
listcap
⊢
aux_psb o cs.*1 = PAuxb <$> seqZo lengthcs

revert o

b :
Z
cs :
listcap
⊢
∀o : Z, aux_psb o cs.*1 = PAuxb <$> seqZo lengthcs

induction cs as | c cs IH ; intros o ; reflexivity |

b :
Z
c :
cs :
listcap
IH :
∀o : Z, aux_psb o cs.*1 = PAuxb <$> seqZo lengthcs
o :
Z
⊢
aux_psb o c :: cs.*1 = PAuxb <$> seqZo lengthc :: cs

rewrite aux_ps_cons

b :
Z
c :
cs :
listcap
IH :
∀o : Z, aux_psb o cs.*1 = PAuxb <$> seqZo lengthcs
o :
Z
⊢
PAuxb o, VAuxc :: aux_psb o + 1 cs.*1 = PAuxb <$> seqZo lengthc :: cs

cbn [ fmap list_fmap fst ]

b :
Z
c :
cs :
listcap
IH :
∀o : Z, aux_psb o cs.*1 = PAuxb <$> seqZo lengthcs
o :
Z
⊢
PAuxb o :: aux_psb o + 1 cs.*1 = PAuxb <$> seqZo lengthc :: cs

rewrite IH

b :
Z
c :
cs :
listcap
IH :
∀o : Z, aux_psb o cs.*1 = PAuxb <$> seqZo lengthcs
o :
Z
⊢
PAuxb o :: PAuxb <$> seqZo + 1 lengthcs = PAuxb <$> seqZo lengthc :: cs

cbn [ length ]

b :
Z
c :
cs :
listcap
IH :
∀o : Z, aux_psb o cs.*1 = PAuxb <$> seqZo lengthcs
o :
Z
⊢
PAuxb o :: PAuxb <$> seqZo + 1 lengthcs = PAuxb <$> seqZo Slengthcs

rewrite Nat2Z.inj_succ seqZ_conso ; | lia

b :
Z
c :
cs :
listcap
IH :
∀o : Z, aux_psb o cs.*1 = PAuxb <$> seqZo lengthcs
o :
Z
⊢
PAuxb o :: PAuxb <$> seqZo + 1 lengthcs = PAuxb <$> o :: seqZZ.succo Z.predZ.succlengthcs

rewrite Z.pred_succ

b :
Z
c :
cs :
listcap
IH :
∀o : Z, aux_psb o cs.*1 = PAuxb <$> seqZo lengthcs
o :
Z
⊢
PAuxb o :: PAuxb <$> seqZo + 1 lengthcs = PAuxb <$> o :: seqZZ.succo lengthcs

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

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

A byte piece of xs is the i-th byte's, at offset o + i.

104Lemma byte_ps_elem
∀ b o xs l v
l, v ∈ byte_psb o xs
∃i x, xs !! i = Somex ∧ l = PByteb o + Z.of_nati ∧ v = VBytex
Explore proof 7 tactics

Initial goal

b, o :
Z
xs :
listZ
v :
⊢
l, v ∈ byte_psb o xs → ∃i : nat x : Z, xs !! i = Somex ∧ l = PByteb o + i ∧ v = VBytex

intros H

b, o :
Z
xs :
listZ
v :
H :
l, v ∈ byte_psb o xs
⊢
∃i : nat x : Z, xs !! i = Somex ∧ l = PByteb o + i ∧ v = VBytex

apply list_elem_of_lookup in H as k Hk

b, o :
Z
xs :
listZ
v :
k :
nat
Hk :
byte_psb o xs !! k = Somel, v
⊢
∃i : nat x : Z, xs !! i = Somex ∧ l = PByteb o + i ∧ v = VBytex

unfold byte_ps in Hk

b, o :
Z
xs :
listZ
v :
k :
nat
Hk :
zip_withλi x : Z ⇒ PByteb i, VBytex seqZo lengthxs xs !! k = Somel, v
⊢
∃i : nat x : Z, xs !! i = Somex ∧ l = PByteb o + i ∧ v = VBytex

apply lookup_zip_with_Some in Hk as i & x & E & Hi & Hx

b, o :
Z
xs :
listZ
v :
k :
nat
i, x :
Z
E :
l, v = PByteb i, VBytex
Hi :
seqZo lengthxs !! k = Somei
Hx :
xs !! k = Somex
⊢
∃i0 : nat x0 : Z, xs !! i0 = Somex0 ∧ l = PByteb o + i0 ∧ v = VBytex0

apply lookup_seqZ in Hi as → _

b, o :
Z
xs :
listZ
v :
k :
nat
x :
Z
E :
l, v = PByteb o + k, VBytex
Hx :
xs !! k = Somex
⊢
∃i : nat x0 : Z, xs !! i = Somex0 ∧ l = PByteb o + i ∧ v = VBytex0

injection E as → →

b, o :
Z
xs :
listZ
k :
nat
x :
Z
Hx :
xs !! k = Somex
⊢
∃i : nat x0 : Z, xs !! i = Somex0 ∧ PByteb o + k = PByteb o + i ∧ VBytex = VBytex0

eauto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros H
apply list_elem_of_lookup in H as k Hk
unfold byte_ps in Hk
apply lookup_zip_with_Some in Hk as i & x & E & Hi & Hx
apply lookup_seqZ in Hi as → _
injection E as → →
eauto

An aux piece of cs is the i-th slot's, at offset o + i.

113Lemma aux_ps_elem
∀ b o cs l v
l, v ∈ aux_psb o cs
∃i c, cs !! i = Somec ∧ l = PAuxb o + Z.of_nati ∧ v = VAuxc
Explore proof 7 tactics

Initial goal

b, o :
Z
cs :
listcap
v :
⊢
l, v ∈ aux_psb o cs → ∃i : nat c : cap, cs !! i = Somec ∧ l = PAuxb o + i ∧ v = VAuxc

intros H

b, o :
Z
cs :
listcap
v :
H :
l, v ∈ aux_psb o cs
⊢
∃i : nat c : cap, cs !! i = Somec ∧ l = PAuxb o + i ∧ v = VAuxc

apply list_elem_of_lookup in H as k Hk

b, o :
Z
cs :
listcap
v :
k :
nat
Hk :
aux_psb o cs !! k = Somel, v
⊢
∃i : nat c : cap, cs !! i = Somec ∧ l = PAuxb o + i ∧ v = VAuxc

unfold aux_ps in Hk

b, o :
Z
cs :
listcap
v :
k :
nat
Hk :
zip_withλi : Z c : cap ⇒ PAuxb i, VAuxc seqZo lengthcs cs !! k = Somel, v
⊢
∃i : nat c : cap, cs !! i = Somec ∧ l = PAuxb o + i ∧ v = VAuxc

apply lookup_zip_with_Some in Hk as i & c & E & Hi & Hc

b, o :
Z
cs :
listcap
v :
k :
nat
i :
Z
c :
E :
l, v = PAuxb i, VAuxc
Hi :
seqZo lengthcs !! k = Somei
Hc :
cs !! k = Somec
⊢
∃i0 : nat c0 : cap, cs !! i0 = Somec0 ∧ l = PAuxb o + i0 ∧ v = VAuxc0

apply lookup_seqZ in Hi as → _

b, o :
Z
cs :
listcap
v :
k :
nat
c :
E :
l, v = PAuxb o + k, VAuxc
Hc :
cs !! k = Somec
⊢
∃i : nat c0 : cap, cs !! i = Somec0 ∧ l = PAuxb o + i ∧ v = VAuxc0

injection E as → →

b, o :
Z
cs :
listcap
k :
nat
c :
Hc :
cs !! k = Somec
⊢
∃i : nat c0 : cap, cs !! i = Somec0 ∧ PAuxb o + k = PAuxb o + i ∧ VAuxc = VAuxc0

eauto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros H
apply list_elem_of_lookup in H as k Hk
unfold aux_ps in Hk
apply lookup_zip_with_Some in Hk as i & c & E & Hi & Hc
apply lookup_seqZ in Hi as → _
injection E as → →
eauto

The i-th slot's piece is among the keys of cs's pieces.

122Lemma aux_ps_key
∀ b o cs i
0 ≤ i < Z.of_natlengthcs
PAuxb o + i ∈ aux_psb o cs.*1
Explore proof 5 tactics

Initial goal

b, o :
Z
cs :
listcap
i :
Z
⊢
0 ≤ i < lengthcs → PAuxb o + i ∈ aux_psb o cs.*1

intros Hi

b, o :
Z
cs :
listcap
i :
Z
Hi :
0 ≤ i < lengthcs
⊢
PAuxb o + i ∈ aux_psb o cs.*1

rewrite aux_ps_keys

b, o :
Z
cs :
listcap
i :
Z
Hi :
0 ≤ i < lengthcs
⊢
PAuxb o + i ∈ PAuxb <$> seqZo lengthcs

apply list_elem_of_fmap_2

b, o :
Z
cs :
listcap
i :
Z
Hi :
0 ≤ i < lengthcs
⊢
o + i ∈ seqZo lengthcs

apply elem_of_seqZ

b, o :
Z
cs :
listcap
i :
Z
Hi :
0 ≤ i < lengthcs
⊢
o ≤ o + i < o + lengthcs

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hi
rewrite aux_ps_keys
apply list_elem_of_fmap_2
apply elem_of_seqZ
lia

The i-th byte's piece is among the keys of xs's pieces.

128Lemma byte_ps_key
∀ b o xs i
0 ≤ i < Z.of_natlengthxs
PByteb o + i ∈ byte_psb o xs.*1
Explore proof 5 tactics

Initial goal

b, o :
Z
xs :
listZ
i :
Z
⊢
0 ≤ i < lengthxs → PByteb o + i ∈ byte_psb o xs.*1

intros Hi

b, o :
Z
xs :
listZ
i :
Z
Hi :
0 ≤ i < lengthxs
⊢
PByteb o + i ∈ byte_psb o xs.*1

rewrite byte_ps_keys

b, o :
Z
xs :
listZ
i :
Z
Hi :
0 ≤ i < lengthxs
⊢
PByteb o + i ∈ PByteb <$> seqZo lengthxs

apply list_elem_of_fmap_2

b, o :
Z
xs :
listZ
i :
Z
Hi :
0 ≤ i < lengthxs
⊢
o + i ∈ seqZo lengthxs

apply elem_of_seqZ

b, o :
Z
xs :
listZ
i :
Z
Hi :
0 ≤ i < lengthxs
⊢
o ≤ o + i < o + lengthxs

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hi
rewrite byte_ps_keys
apply list_elem_of_fmap_2
apply elem_of_seqZ
lia

Integer stores

The n little-endian bytes of the integer y.

136Definition le_bytesy : Z n : nat : listZ ≔
λi ⇒ byte_ofy Z.of_nati <$> seq0 n

As many bytes as asked for.

139Lemma length_le_bytes
∀ y n
lengthle_bytesy n = n
Explore proof 3 tactics

Initial goal

y :
Z
n :
nat
⊢
lengthle_bytesy n = n

unfold le_bytes

y :
Z
n :
nat
⊢
lengthλi : nat ⇒ byte_ofy i <$> seq0 n = n

rewrite length_fmap length_seq

y :
Z
n :
nat
⊢
n = n

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
unfold le_bytes
rewrite length_fmap length_seq
reflexivity

A store of the integer y over the bytes xs from offset o of the live object b: afterwards they are y's little-endian bytes, and every piece outside them keeps its agreement.

145Lemma store_after
∀ m b reg o xs y
all_agreestore_bytesm b + o Z.of_natlengthxs y byte_psb o le_bytesy lengthxs ∧ frame_okbyte_psb o xs.*1 m store_bytesm b + o Z.of_natlengthxs y
Explore proof 37 tactics

Initial goal

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
⊢
live_disjointm → live_atm b reg → all_agreem byte_psb o xs → all_agreestore_bytesm b + o lengthxs y byte_psb o le_bytesy lengthxs ∧ frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

intros Hd Hl Hx

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
⊢
all_agreestore_bytesm b + o lengthxs y byte_psb o le_bytesy lengthxs ∧ frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

assert Hbyte : ∀i, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + Z.of_nati ∧ b + o + Z.of_nati < r_endreg

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
⊢
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
focused goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
all_agreestore_bytesm b + o lengthxs y byte_psb o le_bytesy lengthxs ∧ frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

{intros i Hi

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
i :
nat
Hi :
i < lengthxs%nat
⊢
registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
all_agreestore_bytesm b + o lengthxs y byte_psb o le_bytesy lengthxs ∧ frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

destruct lookup_lt_is_Some_2xs i Hi as x Hxi

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
i :
nat
Hi :
i < lengthxs%nat
x :
Z
Hxi :
xs !! i = Somex
⊢
registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
all_agreestore_bytesm b + o lengthxs y byte_psb o le_bytesy lengthxs ∧ frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

destruct byte_ps_agree_ _ _ _ _ _ _ Hl Hx Hxi as _ & H1 & H2

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
i :
nat
Hi :
i < lengthxs%nat
x :
Z
Hxi :
xs !! i = Somex
H1 :
0 ≤ o + i
H2 :
b + o + i < r_endreg
⊢
registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
all_agreestore_bytesm b + o lengthxs y byte_psb o le_bytesy lengthxs ∧ frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

split ; destruct Hl as E _ ; unfold registered ; congruence | lia

deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
all_agreestore_bytesm b + o lengthxs y byte_psb o le_bytesy lengthxs ∧ frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

split

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
all_agreestore_bytesm b + o lengthxs y byte_psb o le_bytesy lengthxs
focused goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

–apply all_agree_intro

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
∀l : piece v : pval, l, v ∈ byte_psb o le_bytesy lengthxs → agree_piecestore_bytesm b + o lengthxs y l v
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

intros l v Hin

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
v :
Hin :
l, v ∈ byte_psb o le_bytesy lengthxs
⊢
agree_piecestore_bytesm b + o lengthxs y l v
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

apply byte_ps_elem in Hin as i & x & Hxi & → & →

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
i :
nat
x :
Z
Hxi :
le_bytesy lengthxs !! i = Somex
⊢
agree_piecestore_bytesm b + o lengthxs y PByteb o + i VBytex
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

unfold le_bytes in Hxi

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
i :
nat
x :
Z
Hxi :
λi : nat ⇒ byte_ofy i <$> seq0 lengthxs !! i = Somex
⊢
agree_piecestore_bytesm b + o lengthxs y PByteb o + i VBytex
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

apply list_lookup_fmap_Some in Hxi as k & → & Hk

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
i, k :
nat
Hk :
seq0 lengthxs !! i = Somek
⊢
agree_piecestore_bytesm b + o lengthxs y PByteb o + i VBytebyte_ofy k
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

apply lookup_seq in Hk as → Hi

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
i :
nat
Hi :
i < lengthxs%nat
⊢
agree_piecestore_bytesm b + o lengthxs y PByteb o + i VBytebyte_ofy 0 + i%nat
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

cbn [ Nat.add ]

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
i :
nat
Hi :
i < lengthxs%nat
⊢
agree_piecestore_bytesm b + o lengthxs y PByteb o + i VBytebyte_ofy i
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

destruct Hbytei Hi as Hreg & H1 & H2

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
i :
nat
Hi :
i < lengthxs%nat
Hreg :
H1 :
0 ≤ o + i
H2 :
b + o + i < r_endreg
⊢
agree_piecestore_bytesm b + o lengthxs y PByteb o + i VBytebyte_ofy i
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

cbn [ agree_piece ]

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
i :
nat
Hi :
i < lengthxs%nat
Hreg :
H1 :
0 ≤ o + i
H2 :
b + o + i < r_endreg
⊢
registeredstore_bytesm b + o lengthxs y b ∧ in_livestore_bytesm b + o lengthxs y b o + i m_bytesstore_bytesm b + o lengthxs y b + o + i = byte_ofy i
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

split ; exact Hreg |

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
i :
nat
Hi :
i < lengthxs%nat
Hreg :
H1 :
0 ≤ o + i
H2 :
b + o + i < r_endreg
⊢
in_livestore_bytesm b + o lengthxs y b o + i m_bytesstore_bytesm b + o lengthxs y b + o + i = byte_ofy i
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

intros reg′ E L

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
i :
nat
Hi :
i < lengthxs%nat
Hreg :
H1 :
0 ≤ o + i
H2 :
b + o + i < r_endreg
reg′ :
E :
object_regionb m_regionsstore_bytesm b + o lengthxs y = Somereg′
L :
r_lifereg′ = Live
⊢
0 ≤ o + i ∧ b + o + i < r_endreg′ ∧ m_bytesstore_bytesm b + o lengthxs y b + o + i = byte_ofy i
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

destruct Hl as E0 _

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
E0 :
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
i :
nat
Hi :
i < lengthxs%nat
Hreg :
H1 :
0 ≤ o + i
H2 :
b + o + i < r_endreg
reg′ :
E :
object_regionb m_regionsstore_bytesm b + o lengthxs y = Somereg′
L :
r_lifereg′ = Live
⊢
0 ≤ o + i ∧ b + o + i < r_endreg′ ∧ m_bytesstore_bytesm b + o lengthxs y b + o + i = byte_ofy i
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

rewrite regions_store_bytes E0 in E

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
E0 :
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
i :
nat
Hi :
i < lengthxs%nat
Hreg :
H1 :
0 ≤ o + i
H2 :
b + o + i < r_endreg
reg′ :
L :
r_lifereg′ = Live
E :
Somereg = Somereg′
⊢
0 ≤ o + i ∧ b + o + i < r_endreg′ ∧ m_bytesstore_bytesm b + o lengthxs y b + o + i = byte_ofy i
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

injection E as ←

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
E0 :
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
i :
nat
Hi :
i < lengthxs%nat
Hreg :
H1 :
0 ≤ o + i
H2 :
b + o + i < r_endreg
L :
r_lifereg = Live
⊢
0 ≤ o + i ∧ b + o + i < r_endreg ∧ m_bytesstore_bytesm b + o lengthxs y b + o + i = byte_ofy i
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

split ; exact H1 |

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
E0 :
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
i :
nat
Hi :
i < lengthxs%nat
Hreg :
H1 :
0 ≤ o + i
H2 :
b + o + i < r_endreg
L :
r_lifereg = Live
⊢
b + o + i < r_endreg ∧ m_bytesstore_bytesm b + o lengthxs y b + o + i = byte_ofy i
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

split ; exact H2 |

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
E0 :
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
i :
nat
Hi :
i < lengthxs%nat
Hreg :
H1 :
0 ≤ o + i
H2 :
b + o + i < r_endreg
L :
r_lifereg = Live
⊢
m_bytesstore_bytesm b + o lengthxs y b + o + i = byte_ofy i
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

replace b + o + Z.of_nati with b + o + Z.of_nati by lia

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
E0 :
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
i :
nat
Hi :
i < lengthxs%nat
Hreg :
H1 :
0 ≤ o + i
H2 :
b + o + i < r_endreg
L :
r_lifereg = Live
⊢
m_bytesstore_bytesm b + o lengthxs y b + o + i = byte_ofy i
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

apply stored_byte

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
E0 :
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
i :
nat
Hi :
i < lengthxs%nat
Hreg :
H1 :
0 ≤ o + i
H2 :
b + o + i < r_endreg
L :
r_lifereg = Live
⊢
0 ≤ i < lengthxs
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

lia

deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
frame_okbyte_psb o xs.*1 m store_bytesm b + o lengthxs y

–apply frame_within_ _ _ b reg ; reflexivity | exact Hd | exact Hl | |

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
∀a : Z, b ≤ a < r_endreg → PByteb a − b ∉ byte_psb o xs.*1 → m_bytesstore_bytesm b + o lengthxs y a = m_bytesm a
focused goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
∀a : Z, b ≤ a < r_endreg → PAuxb a − b ∉ byte_psb o xs.*1 → m_auxstore_bytesm b + o lengthxs y a = m_auxm a

+intros a H

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
a :
Z
H :
b ≤ a < r_endreg → PByteb a − b ∉ byte_psb o xs.*1
⊢
m_bytesstore_bytesm b + o lengthxs y a = m_bytesm a
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
∀a : Z, b ≤ a < r_endreg → PAuxb a − b ∉ byte_psb o xs.*1 → m_auxstore_bytesm b + o lengthxs y a = m_auxm a

apply store_bytes_other

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
a :
Z
H :
b ≤ a < r_endreg → PByteb a − b ∉ byte_psb o xs.*1
⊢
¬b + o ≤ a < b + o + lengthxs
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
∀a : Z, b ≤ a < r_endreg → PAuxb a − b ∉ byte_psb o xs.*1 → m_auxstore_bytesm b + o lengthxs y a = m_auxm a

intros Ha

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
a :
Z
H :
b ≤ a < r_endreg → PByteb a − b ∉ byte_psb o xs.*1
Ha :
b + o ≤ a < b + o + lengthxs
⊢
False
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
∀a : Z, b ≤ a < r_endreg → PAuxb a − b ∉ byte_psb o xs.*1 → m_auxstore_bytesm b + o lengthxs y a = m_auxm a

destruct HbyteZ.to_nata − b − o ltac:lia as _ & H1 & H2

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
a :
Z
H :
b ≤ a < r_endreg → PByteb a − b ∉ byte_psb o xs.*1
Ha :
b + o ≤ a < b + o + lengthxs
H1 :
0 ≤ o + Z.to_nata − b − o
H2 :
b + o + Z.to_nata − b − o < r_endreg
⊢
False
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
∀a : Z, b ≤ a < r_endreg → PAuxb a − b ∉ byte_psb o xs.*1 → m_auxstore_bytesm b + o lengthxs y a = m_auxm a

apply H ; lia |

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
a :
Z
H :
b ≤ a < r_endreg → PByteb a − b ∉ byte_psb o xs.*1
Ha :
b + o ≤ a < b + o + lengthxs
H1 :
0 ≤ o + Z.to_nata − b − o
H2 :
b + o + Z.to_nata − b − o < r_endreg
⊢
PByteb a − b ∈ byte_psb o xs.*1
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
∀a : Z, b ≤ a < r_endreg → PAuxb a − b ∉ byte_psb o xs.*1 → m_auxstore_bytesm b + o lengthxs y a = m_auxm a

replace a − b with o + a − b − o by lia

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
a :
Z
H :
b ≤ a < r_endreg → PByteb a − b ∉ byte_psb o xs.*1
Ha :
b + o ≤ a < b + o + lengthxs
H1 :
0 ≤ o + Z.to_nata − b − o
H2 :
b + o + Z.to_nata − b − o < r_endreg
⊢
PByteb o + a − b − o ∈ byte_psb o xs.*1
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
∀a : Z, b ≤ a < r_endreg → PAuxb a − b ∉ byte_psb o xs.*1 → m_auxstore_bytesm b + o lengthxs y a = m_auxm a

apply byte_ps_key

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
a :
Z
H :
b ≤ a < r_endreg → PByteb a − b ∉ byte_psb o xs.*1
Ha :
b + o ≤ a < b + o + lengthxs
H1 :
0 ≤ o + Z.to_nata − b − o
H2 :
b + o + Z.to_nata − b − o < r_endreg
⊢
0 ≤ a − b − o < lengthxs
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
∀a : Z, b ≤ a < r_endreg → PAuxb a − b ∉ byte_psb o xs.*1 → m_auxstore_bytesm b + o lengthxs y a = m_auxm a

lia

deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
⊢
∀a : Z, b ≤ a < r_endreg → PAuxb a − b ∉ byte_psb o xs.*1 → m_auxstore_bytesm b + o lengthxs y a = m_auxm a

+intros a _

m :
b :
Z
reg :
o :
Z
xs :
listZ
y :
Z
Hl :
live_atm b reg
Hx :
Hbyte :
∀i : nat, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + i ∧ b + o + i < r_endreg
a :
Z
⊢
m_auxstore_bytesm b + o lengthxs y a = m_auxm a

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hd Hl Hx
assert Hbyte : ∀i, i < lengthxs%nat → registeredm b ∧ 0 ≤ o + Z.of_nati ∧ b + o + Z.of_nati < r_endreg
{intros i Hi
destruct lookup_lt_is_Some_2xs i Hi as x Hxi
destruct byte_ps_agree_ _ _ _ _ _ _ Hl Hx Hxi as _ & H1 & H2
split ; destruct Hl as E _ ; unfold registered ; congruence | lia
split
intros l v Hin
apply byte_ps_elem in Hin as i & x & Hxi & → & →
unfold le_bytes in Hxi
apply list_lookup_fmap_Some in Hxi as k & → & Hk
apply lookup_seq in Hk as → Hi
cbn [ Nat.add ]
destruct Hbytei Hi as Hreg & H1 & H2
cbn [ agree_piece ]
split ; exact Hreg |
intros reg′ E L
destruct Hl as E0 _
rewrite regions_store_bytes E0 in E
injection E as ←
split ; exact H1 |
split ; exact H2 |
replace b + o + Z.of_nati with b + o + Z.of_nati by lia
lia
–apply frame_within_ _ _ b reg ; reflexivity | exact Hd | exact Hl | |
+intros a H
intros Ha
destruct HbyteZ.to_nata − b − o ltac:lia as _ & H1 & H2
apply H ; lia |
replace a − b with o + a − b − o by lia
lia
+intros a _
reflexivity

Blocks

The pieces of a block: the life of the object b with the region reg, the bytes xs and the aux slots cs from offset o.

174Definition block_psb : Z reg : region o : Z xs : listZ cs : listcap : listpiece × pval ≔
PLiveb, VLivereg :: byte_psb o xs ++ aux_psb o cs

Blocks of the same lengths have the same keys.

178Lemma block_ps_keys
∀ b reg o xs cs ys ds
lengthys = lengthxs
lengthds = lengthcs
block_psb reg o ys ds.*1 = block_psb reg o xs cs.*1
Explore proof 6 tactics

Initial goal

b :
Z
reg :
o :
Z
xs :
listZ
cs :
listcap
ys :
listZ
ds :
listcap
⊢
lengthys = lengthxs → lengthds = lengthcs → block_psb reg o ys ds.*1 = block_psb reg o xs cs.*1

intros Hy Hd

b :
Z
reg :
o :
Z
xs :
listZ
cs :
listcap
ys :
listZ
ds :
listcap
Hy :
lengthys = lengthxs
Hd :
lengthds = lengthcs
⊢
block_psb reg o ys ds.*1 = block_psb reg o xs cs.*1

unfold block_ps

b :
Z
reg :
o :
Z
xs :
listZ
cs :
listcap
ys :
listZ
ds :
listcap
Hy :
lengthys = lengthxs
Hd :
lengthds = lengthcs
⊢
PLiveb, VLivereg :: byte_psb o ys ++ aux_psb o ds.*1 = PLiveb, VLivereg :: byte_psb o xs ++ aux_psb o cs.*1

cbn [ fmap list_fmap fst ]

b :
Z
reg :
o :
Z
xs :
listZ
cs :
listcap
ys :
listZ
ds :
listcap
Hy :
lengthys = lengthxs
Hd :
lengthds = lengthcs
⊢
PLiveb :: byte_psb o ys ++ aux_psb o ds.*1 = PLiveb :: byte_psb o xs ++ aux_psb o cs.*1

rewrite ! fmap_app

b :
Z
reg :
o :
Z
xs :
listZ
cs :
listcap
ys :
listZ
ds :
listcap
Hy :
lengthys = lengthxs
Hd :
lengthds = lengthcs
⊢
PLiveb :: byte_psb o ys.*1 ++ aux_psb o ds.*1 = PLiveb :: byte_psb o xs.*1 ++ aux_psb o cs.*1

rewrite ! byte_ps_keys ! aux_ps_keys Hy Hd

b :
Z
reg :
o :
Z
xs :
listZ
cs :
listcap
ys :
listZ
ds :
listcap
Hy :
lengthys = lengthxs
Hd :
lengthds = lengthcs
⊢
PLiveb :: PByteb <$> seqZo lengthxs ++ PAuxb <$> seqZo lengthcs = PLiveb :: PByteb <$> seqZo lengthxs ++ PAuxb <$> seqZo lengthcs

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hy Hd
unfold block_ps
cbn [ fmap list_fmap fst ]
rewrite ! fmap_app
rewrite ! byte_ps_keys ! aux_ps_keys Hy Hd
reflexivity

The slots cs from offset o once memset has touched each: those that start at a multiple of 8 are empty, the rest are as they were. For an object at a multiple of 8, these are the slots the contract clears.

190Definition clear_slotso : Z cs : listcap : listcap ≔
zip_with
λ i c  ⇒
i mod 8 =? 0
→
else
c
seqZo Z.of_natlengthcs
cs

Clearing keeps the number of slots.

194Lemma length_clear_slots
∀ o cs
lengthclear_slotso cs = lengthcs
Explore proof 3 tactics

Initial goal

o :
Z
cs :
listcap
⊢
lengthclear_slotso cs = lengthcs

unfold clear_slots

o :
Z
cs :
listcap
⊢
length
zip_with
λ i : Z c : cap  ⇒
i mod 8 =? 0
→
else
c
seqZo lengthcs
cs
=
lengthcs

rewrite length_zip_with length_seqZ Nat2Z.id

o :
Z
cs :
listcap
⊢
(length cs `min` length cs)%nat = length cs

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
rewrite length_zip_with length_seqZ Nat2Z.id
lia

The i-th cleared slot.

198Lemma lookup_clear_slots
∀ o cs i c
clear_slotso cs !! i = Somec
∃ c0  ,
cs !! i = Somec0
∧
c
=
o + Z.of_nati mod 8 =? 0
→
else
c0
Explore proof 5 tactics

Initial goal

o :
Z
cs :
listcap
i :
nat
c :
⊢
clear_slotso cs !! i = Somec
→
∃ c0 : cap  ,
cs !! i = Somec0
∧
c
=
o + i mod 8 =? 0
→
else
c0

unfold clear_slots

o :
Z
cs :
listcap
i :
nat
c :
⊢
zip_with
λ i0 : Z c0 : cap  ⇒
i0 mod 8 =? 0
→
else
c0
seqZo lengthcs
cs
!!
i
=
Somec
→
∃ c0 : cap  ,
cs !! i = Somec0
∧
c
=
o + i mod 8 =? 0
→
else
c0

intros H

o :
Z
cs :
listcap
i :
nat
c :
H :
zip_with
λ i : Z c : cap  ⇒
i mod 8 =? 0
→
else
c
seqZo lengthcs
cs
!!
i
=
Somec
⊢
∃ c0 : cap  ,
cs !! i = Somec0
∧
c
=
o + i mod 8 =? 0
→
else
c0

apply lookup_zip_with_Some in H as k & c0 & → & Hk & Hc

o :
Z
cs :
listcap
i :
nat
k :
Z
c0 :
Hk :
seqZo lengthcs !! i = Somek
Hc :
cs !! i = Somec0
⊢
∃ c1 : cap  ,
cs !! i = Somec1
∧
k mod 8 =? 0
→
else
c0
=
o + i mod 8 =? 0
→
else
c1

apply lookup_seqZ in Hk as → _

o :
Z
cs :
listcap
i :
nat
c0 :
Hc :
cs !! i = Somec0
⊢
∃ c1 : cap  ,
cs !! i = Somec1
∧
o + i mod 8 =? 0
→
else
c0
=
o + i mod 8 =? 0
→
else
c1

eauto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros H
apply lookup_zip_with_Some in H as k & c0 & → & Hk & Hc
apply lookup_seqZ in Hk as → _
eauto

memset's exact frame (memset_frame) on the n bytes xs of the block at offset o of the live object b, at a multiple of 8, with its slots cs, keeps the agreement of every piece outside the block. memset and the copies share it.

210Lemma block_frame
∀ m m′ b reg o xs cs
live_atm b reg
b mod 8 = 0
o mod 8 = 0
lengthcs = lengthxs
all_agreem byte_psb o xs ++ aux_psb o cs
memset_framem mkPtrb + o Objb Z.of_natlengthxs m′
frame_okbyte_psb o xs ++ aux_psb o cs.*1 m m′
Proof 46 steps Qed
intros Hd Hl Hb8 Ho8 Hlen Ha Hr & Hbytes & Haux
apply all_agree_app in Ha as Hx Hc
assert Hbyte : ∀i, i < lengthxs%nat → 0 ≤ o + Z.of_nati ∧ b + o + Z.of_nati < r_endreg
{intros i Hi
destruct lookup_lt_is_Some_2xs i Hi as x Hxi
destruct byte_ps_agree_ _ _ _ _ _ _ Hl Hx Hxi as _ & H1 & H2
lia
assert Hmod : ∀i, b + o + i mod 8 = o + i mod 8
{intros i
rewrite Z.add_mod ; | lia
rewrite Hb8 Z.add_0_l Z.mod_mod ; reflexivity | lia
apply frame_within_ _ _ b reg ; exact Hr | exact Hd | exact Hl | |
–intros a H
apply Hbytes
intros Hs
unfold span_contains in Hs
cbn in Hs
destruct HbyteZ.to_nata − b − o ltac:lia as H1 H2
apply H ; lia |
rewrite fmap_app
apply elem_of_app
left
replace a − b with o + a − b − o by lia
lia
–intros a H
apply Haux
destruct memset_touched_ _ _ eqn: Ht ; | reflexivity
exfalso
apply memset_touched_spec in Ht as Hn & Ha8 & Hhi & Hlo
cbn [ ptr_addr ] in Hhi , Hlo
assert Hab : b + o ≤ a
{pose proof Z.div_moda 8 ltac:lia
pose proof Z.div_modb + o 8 ltac:lia
pose proof Hmod0 as Hm0
rewrite Z.add_0_r in Hm0
rewrite Ho8 in Hm0
lia
destruct HbyteZ.to_nata − b − o ltac:lia as H1 H2
apply H ; lia |
rewrite fmap_app
apply elem_of_app
right
replace a − b with o + a − b − o by lia
lia

A memset of the n bytes xs of the block at offset o of the live object b, at a multiple of 8, with its slots cs: afterwards its bytes are c's low byte and its slots clear_slots, and every piece outside it keeps its agreement (frame_ok).

241Lemma fill_after
∀ m m′ b reg o xs cs c
live_atm b reg
b mod 8 = 0
o mod 8 = 0
lengthcs = lengthxs
all_agreem byte_psb o xs ++ aux_psb o cs
memset_resultm mkPtrb + o Objb c Z.of_natlengthxs m′
all_agreem′ byte_psb o replicatelengthxs c mod 256 ++ aux_psb o clear_slotso cs ∧ frame_okbyte_psb o xs ++ aux_psb o cs.*1 m m′
Proof 76 steps Qed
intros Hd Hl Hb8 Ho8 Hlen Ha Hr & Hbytes & Haux & Hfill & Hclear
apply all_agree_app in Ha as Hx Hc
set n := Z.of_natlengthxs
assert Hregs : ∀b′, registeredm b′ → registeredm' b′ by unfold registered ; rewrite Hr ; auto

The i-th byte and slot lie in b's bounds.

assert Hbyte : ∀i, i < lengthxs%nat → 0 ≤ o + Z.of_nati ∧ b + o + Z.of_nati < r_endreg
{intros i Hi
destruct lookup_lt_is_Some_2xs i Hi as x Hxi
destruct byte_ps_agree_ _ _ _ _ _ _ Hl Hx Hxi as _ & H1 & H2
lia
assert Hslot : ∀i c0, cs !! i = Somec0 → registeredm b ∧ 0 ≤ o + Z.of_nati ∧ b + o + Z.of_nati < r_endreg ∧ aux_holdsm b + o + Z.of_nati c0
{intros i c0 Hci
destruct Hl as E L
assert Hin : aux_psb o cs !! i = SomePAuxb o + Z.of_nati, VAuxc0
{unfold aux_ps
apply lookup_zip_with_Some
exists o + Z.of_nati, c0
split ; reflexivity |
split ; | exact Hci
apply lookup_seqZ
split ; reflexivity |
apply lookup_lt_Some in Hci
lia
destruct all_agree_elem_ _ _ _ Hc list_elem_of_lookup_2_ _ _ Hin as Hreg Hin′
destruct Hin'reg E L as Ho & He & Hh
auto
assert Hmod : ∀i, b + o + i mod 8 = o + i mod 8
{intros i
rewrite Z.add_mod ; | lia
rewrite Hb8 Z.add_0_l Z.mod_mod ; reflexivity | lia
split
–apply all_agree_app
split ; apply all_agree_intro ; intros l v Hin
+apply byte_ps_elem in Hin as i & x & Hxi & → & →
apply lookup_replicate in Hxi as → Hi
destruct lookup_lt_is_Some_2xs i Hi as x0 Hx0
pose proof all_agree_elem_ _ _ _ Hx list_elem_of_lookup_2_ _ _ byte_ps_lookupb o xs i x0 Hx0 as Hreg _
cbn [ agree_piece ]
split ; exact Hregs_ Hreg |
intros reg′ E L
destruct Hl as E0 _
rewrite Hr E0 in E
injection E as ←
destruct Hbytei Hi as H1 H2
split ; exact H1 |
split ; exact H2 |
apply Hfill
cbn
lia
+apply aux_ps_elem in Hin as i & c′ & Hci & → & →
destruct lookup_clear_slotso cs i c' Hci as c0 & Hc0 & →
destruct Hsloti c0 Hc0 as Hreg & H1 & H2 & Hh
cbn [ agree_piece ]
split ; exact Hregs_ Hreg |
intros reg′ E L
destruct Hl as E0 _
rewrite Hr E0 in E
injection E as ←
split ; exact H1 |
split ; exact H2 |
assert Hi : i < lengthxs%nat by rewrite <- Hlen ; exact lookup_lt_Some_ _ _ Hc0
destruct Z.eqb_speco + Z.of_nati mod 8 0 as Hz | Hz
∗left
apply Hclear
cbn [ ptr_addr ]
rewrite Hmod
lia
∗unfold aux_holds in *
rewrite Hr
rewrite Haux ; exact Hh |
destruct memset_touched_ _ _ eqn: Ht ; | reflexivity
apply memset_touched_spec in Ht as _ & Ht & _
rewrite Hmod in Ht
contradiction
–apply block_frame_ _ _ reg ; exact Hd | exact Hl | exact Hb8 | exact Ho8 | exact Hlen | apply all_agree_app ; split ; assumption | split ; exact Hr | ; split ; assumption

The slots cs of a destination block after a copy of n bytes from a source block whose slots are ds, both blocks at multiples of 8, so in phase: a slot at a multiple of 8 takes the source's if all 8 of its bytes were copied, and empties if only some were; the others are as they were.

298Definition copy_slotsn : Z ds cs : listcap : listcap ≔
zip_with
λ i dc  ⇒
i mod 8 =? 0
→
i + 8 ≤? n
→
fstdc
else
else
snddc
seqZ0 Z.of_natlengthcs
zipds cs

Copying keeps the number of slots.

303Lemma length_copy_slots
∀ n ds cs
lengthds = lengthcs
lengthcopy_slotsn ds cs = lengthcs
Explore proof 4 tactics

Initial goal

n :
Z
ds, cs :
listcap
⊢
lengthds = lengthcs → lengthcopy_slotsn ds cs = lengthcs

intros H

n :
Z
ds, cs :
listcap
H :
lengthds = lengthcs
⊢
lengthcopy_slotsn ds cs = lengthcs

unfold copy_slots

n :
Z
ds, cs :
listcap
H :
lengthds = lengthcs
⊢
length
zip_with
λ i : Z dc : cap × cap  ⇒
i mod 8 =? 0
→
i + 8 ≤? n
→
dc.1
else
else
dc.2
seqZ0 lengthcs
zipds cs
=
lengthcs

rewrite length_zip_with length_seqZ Nat2Z.id length_zip

n :
Z
ds, cs :
listcap
H :
lengthds = lengthcs
⊢
(length cs `min` (length ds `min` length cs))%nat = length cs

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros H
unfold copy_slots
rewrite length_zip_with length_seqZ Nat2Z.id length_zip
lia

The i-th copied slot.

309Lemma lookup_copy_slots
∀ n ds cs i c
copy_slotsn ds cs !! i = Somec
∃ d0 c0  ,
ds !! i = Somed0
∧
cs !! i = Somec0
∧
c
=
Z.of_nati mod 8 =? 0
→
Z.of_nati + 8 ≤? n
→
d0
else
else
c0
Explore proof 8 tactics

Initial goal

n :
Z
ds, cs :
listcap
i :
nat
c :
⊢
copy_slotsn ds cs !! i = Somec
→
∃ d0 c0 : cap  ,
ds !! i = Somed0
∧
cs !! i = Somec0
∧
c
=
i mod 8 =? 0
→
i + 8 ≤? n
→
d0
else
else
c0

unfold copy_slots

n :
Z
ds, cs :
listcap
i :
nat
c :
⊢
zip_with
λ i0 : Z dc : cap × cap  ⇒
i0 mod 8 =? 0
→
i0 + 8 ≤? n
→
dc.1
else
else
dc.2
seqZ0 lengthcs
zipds cs
!!
i
=
Somec
→
∃ d0 c0 : cap  ,
ds !! i = Somed0
∧
cs !! i = Somec0
∧
c
=
i mod 8 =? 0
→
i + 8 ≤? n
→
d0
else
else
c0

intros H

n :
Z
ds, cs :
listcap
i :
nat
c :
H :
zip_with
λ i : Z dc : cap × cap  ⇒
i mod 8 =? 0
→
i + 8 ≤? n
→
dc.1
else
else
dc.2
seqZ0 lengthcs
zipds cs
!!
i
=
Somec
⊢
∃ d0 c0 : cap  ,
ds !! i = Somed0
∧
cs !! i = Somec0
∧
c
=
i mod 8 =? 0
→
i + 8 ≤? n
→
d0
else
else
c0

apply lookup_zip_with_Some in H as k & d0 c0 & → & Hk & Hdc

n :
Z
ds, cs :
listcap
i :
nat
k :
Z
d0, c0 :
Hk :
seqZ0 lengthcs !! i = Somek
Hdc :
zipds cs !! i = Somed0, c0
⊢
∃ d1 c1 : cap  ,
ds !! i = Somed1
∧
cs !! i = Somec1
∧
k mod 8 =? 0
→
k + 8 ≤? n
→
d0, c0.1
else
else
d0, c0.2
=
i mod 8 =? 0
→
i + 8 ≤? n
→
d1
else
else
c1

apply lookup_seqZ in Hk as → _

n :
Z
ds, cs :
listcap
i :
nat
d0, c0 :
Hdc :
zipds cs !! i = Somed0, c0
⊢
∃ d1 c1 : cap  ,
ds !! i = Somed1
∧
cs !! i = Somec1
∧
0 + i mod 8 =? 0
→
0 + i + 8 ≤? n
→
d0, c0.1
else
else
d0, c0.2
=
i mod 8 =? 0
→
i + 8 ≤? n
→
d1
else
else
c1

apply lookup_zip_with_Some in Hdc as x & y & E & Hd & Hc

n :
Z
ds, cs :
listcap
i :
nat
d0, c0, x, y :
E :
d0, c0 = x, y
Hd :
ds !! i = Somex
Hc :
cs !! i = Somey
⊢
∃ d1 c1 : cap  ,
ds !! i = Somed1
∧
cs !! i = Somec1
∧
0 + i mod 8 =? 0
→
0 + i + 8 ≤? n
→
d0, c0.1
else
else
d0, c0.2
=
i mod 8 =? 0
→
i + 8 ≤? n
→
d1
else
else
c1

injection E as → →

n :
Z
ds, cs :
listcap
i :
nat
x, y :
Hd :
ds !! i = Somex
Hc :
cs !! i = Somey
⊢
∃ d0 c0 : cap  ,
ds !! i = Somed0
∧
cs !! i = Somec0
∧
0 + i mod 8 =? 0
→
0 + i + 8 ≤? n
→
x, y.1
else
else
x, y.2
=
i mod 8 =? 0
→
i + 8 ≤? n
→
d0
else
else
c0

exists x, y

n :
Z
ds, cs :
listcap
i :
nat
x, y :
Hd :
ds !! i = Somex
Hc :
cs !! i = Somey
⊢
ds !! i = Somex
∧
cs !! i = Somey
∧
0 + i mod 8 =? 0
→
0 + i + 8 ≤? n
→
x, y.1
else
else
x, y.2
=
i mod 8 =? 0
→
i + 8 ≤? n
→
x
else
else
y

auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
unfold copy_slots
intros H
apply lookup_zip_with_Some in H as k & d0 c0 & → & Hk & Hdc
apply lookup_seqZ in Hk as → _
apply lookup_zip_with_Some in Hdc as x & y & E & Hd & Hc
injection E as → →
exists x, y
auto

What a copy writes into the slot at offset i of a destination block at b + o, from a source block at b' + o', all at multiples of 8, for i a multiple of 8: the source's slot if the copy covers all 8 bytes, else nothing (copy_slot).

323Lemma copy_slot_at
∀ m b o b′ o′ c′ n i
b mod 8 = 0
o mod 8 = 0
b′ mod 8 = 0
o′ mod 8 = 0
0 ≤ i
i mod 8 = 0
copy_slotm mkPtrb + o Objb mkPtrb′ + o′ c′ n b + o + i
=
i + 8 ≤? n
→
m_auxm b′ + o′ + i
else
Explore proof 16 tactics

Initial goal

m :
b, o, b′, o′ :
Z
c′ :
n, i :
Z
⊢
b mod 8 = 0
→
o mod 8 = 0
→
b′ mod 8 = 0
→
o′ mod 8 = 0
→
0 ≤ i
→
i mod 8 = 0
→
copy_slotm ptr_addr ≔ b + o; ptr_cap ≔ Objb ptr_addr ≔ b′ + o′; ptr_cap ≔ c′ n b + o + i
=
i + 8 ≤? n
→
m_auxm b′ + o′ + i
else

intros Hb Ho Hb′ Ho′ Hi Hi8

m :
b, o, b′, o′ :
Z
c′ :
n, i :
Z
Hb :
b mod 8 = 0
Ho :
o mod 8 = 0
Hb′ :
b′ mod 8 = 0
Ho′ :
o′ mod 8 = 0
Hi :
0 ≤ i
Hi8 :
i mod 8 = 0
⊢
copy_slotm ptr_addr ≔ b + o; ptr_cap ≔ Objb ptr_addr ≔ b′ + o′; ptr_cap ≔ c′ n b + o + i
=
i + 8 ≤? n
→
m_auxm b′ + o′ + i
else

unfold copy_slot , copy_full_slot

m :
b, o, b′, o′ :
Z
c′ :
n, i :
Z
Hb :
b mod 8 = 0
Ho :
o mod 8 = 0
Hb′ :
b′ mod 8 = 0
Ho′ :
o′ mod 8 = 0
Hi :
0 ≤ i
Hi8 :
i mod 8 = 0
⊢
ptr_addrptr_addr ≔ b + o; ptr_cap ≔ Objb ≤? b + o + i && b + o + i + 8 ≤? ptr_addrptr_addr ≔ b + o; ptr_cap ≔ Objb + n && ptr_addrptr_addr ≔ b′ + o′; ptr_cap ≔ c′ + b + o + i − ptr_addrptr_addr ≔ b + o; ptr_cap ≔ Objb mod 8 =? 0
→
m_auxm ptr_addrptr_addr ≔ b′ + o′; ptr_cap ≔ c′ + b + o + i − ptr_addrptr_addr ≔ b + o; ptr_cap ≔ Objb
else
=
i + 8 ≤? n
→
m_auxm b′ + o′ + i
else

cbn [ ptr_addr ]

m :
b, o, b′, o′ :
Z
c′ :
n, i :
Z
Hb :
b mod 8 = 0
Ho :
o mod 8 = 0
Hb′ :
b′ mod 8 = 0
Ho′ :
o′ mod 8 = 0
Hi :
0 ≤ i
Hi8 :
i mod 8 = 0
⊢
b + o ≤? b + o + i && b + o + i + 8 ≤? b + o + n && b′ + o′ + b + o + i − b + o mod 8 =? 0
→
m_auxm b′ + o′ + b + o + i − b + o
else
=
i + 8 ≤? n
→
m_auxm b′ + o′ + i
else

replace b + o ≤? b + o + i with true by symmetry ; apply Z.leb_le ; lia

m :
b, o, b′, o′ :
Z
c′ :
n, i :
Z
Hb :
b mod 8 = 0
Ho :
o mod 8 = 0
Hb′ :
b′ mod 8 = 0
Ho′ :
o′ mod 8 = 0
Hi :
0 ≤ i
Hi8 :
i mod 8 = 0
⊢
true && b + o + i + 8 ≤? b + o + n && b′ + o′ + b + o + i − b + o mod 8 =? 0
→
m_auxm b′ + o′ + b + o + i − b + o
else
=
i + 8 ≤? n
→
m_auxm b′ + o′ + i
else

replace b + o + i + 8 ≤? b + o + n with i + 8 ≤? n by destruct Z.leb_speci + 8 n , Z.leb_specb + o + i + 8 b + o + n ; lia

m :
b, o, b′, o′ :
Z
c′ :
n, i :
Z
Hb :
b mod 8 = 0
Ho :
o mod 8 = 0
Hb′ :
b′ mod 8 = 0
Ho′ :
o′ mod 8 = 0
Hi :
0 ≤ i
Hi8 :
i mod 8 = 0
⊢
true && i + 8 ≤? n && b′ + o′ + b + o + i − b + o mod 8 =? 0
→
m_auxm b′ + o′ + b + o + i − b + o
else
=
i + 8 ≤? n
→
m_auxm b′ + o′ + i
else

replace b′ + o′ + b + o + i − b + o with b′ + o′ + i by lia

m :
b, o, b′, o′ :
Z
c′ :
n, i :
Z
Hb :
b mod 8 = 0
Ho :
o mod 8 = 0
Hb′ :
b′ mod 8 = 0
Ho′ :
o′ mod 8 = 0
Hi :
0 ≤ i
Hi8 :
i mod 8 = 0
⊢
true && i + 8 ≤? n && b′ + o′ + i mod 8 =? 0
→
m_auxm b′ + o′ + i
else
=
i + 8 ≤? n
→
m_auxm b′ + o′ + i
else

replace b′ + o′ + i mod 8 =? 0 with true

2 open

m :
b, o, b′, o′ :
Z
c′ :
n, i :
Z
Hb :
b mod 8 = 0
Ho :
o mod 8 = 0
Hb′ :
b′ mod 8 = 0
Ho′ :
o′ mod 8 = 0
Hi :
0 ≤ i
Hi8 :
i mod 8 = 0
⊢
true && i + 8 ≤? n && true
→
m_auxm b′ + o′ + i
else
=
i + 8 ≤? n
→
m_auxm b′ + o′ + i
else
focused goal
m :
b, o, b′, o′ :
Z
c′ :
n, i :
Z
Hb :
b mod 8 = 0
Ho :
o mod 8 = 0
Hb′ :
b′ mod 8 = 0
Ho′ :
o′ mod 8 = 0
Hi :
0 ≤ i
Hi8 :
i mod 8 = 0
⊢
true = b′ + o′ + i mod 8 =? 0

–destruct i + 8 ≤? n ; reflexivity

deferred goal
m :
b, o, b′, o′ :
Z
c′ :
n, i :
Z
Hb :
b mod 8 = 0
Ho :
o mod 8 = 0
Hb′ :
b′ mod 8 = 0
Ho′ :
o′ mod 8 = 0
Hi :
0 ≤ i
Hi8 :
i mod 8 = 0
⊢
true = b′ + o′ + i mod 8 =? 0

–symmetry

m :
b, o, b′, o′ :
Z
c′ :
n, i :
Z
Hb :
b mod 8 = 0
Ho :
o mod 8 = 0
Hb′ :
b′ mod 8 = 0
Ho′ :
o′ mod 8 = 0
Hi :
0 ≤ i
Hi8 :
i mod 8 = 0
⊢
b′ + o′ + i mod 8 =? 0 = true

apply Z.eqb_eq

m :
b, o, b′, o′ :
Z
c′ :
n, i :
Z
Hb :
b mod 8 = 0
Ho :
o mod 8 = 0
Hb′ :
b′ mod 8 = 0
Ho′ :
o′ mod 8 = 0
Hi :
0 ≤ i
Hi8 :
i mod 8 = 0
⊢
b′ + o′ + i mod 8 = 0

pose proof Z.div_modb′ 8 ltac:lia

m :
b, o, b′, o′ :
Z
c′ :
n, i :
Z
Hb :
b mod 8 = 0
Ho :
o mod 8 = 0
Hb′ :
b′ mod 8 = 0
Ho′ :
o′ mod 8 = 0
Hi :
0 ≤ i
Hi8 :
i mod 8 = 0
H :
b′ = 8 × b′ / 8 + b′ mod 8
⊢
b′ + o′ + i mod 8 = 0

pose proof Z.div_modo′ 8 ltac:lia

m :
b, o, b′, o′ :
Z
c′ :
n, i :
Z
Hb :
b mod 8 = 0
Ho :
o mod 8 = 0
Hb′ :
b′ mod 8 = 0
Ho′ :
o′ mod 8 = 0
Hi :
0 ≤ i
Hi8 :
i mod 8 = 0
H :
b′ = 8 × b′ / 8 + b′ mod 8
H0 :
o′ = 8 × o′ / 8 + o′ mod 8
⊢
b′ + o′ + i mod 8 = 0

pose proof Z.div_modi 8 ltac:lia

m :
b, o, b′, o′ :
Z
c′ :
n, i :
Z
Hb :
b mod 8 = 0
Ho :
o mod 8 = 0
Hb′ :
b′ mod 8 = 0
Ho′ :
o′ mod 8 = 0
Hi :
0 ≤ i
Hi8 :
i mod 8 = 0
H :
b′ = 8 × b′ / 8 + b′ mod 8
H0 :
o′ = 8 × o′ / 8 + o′ mod 8
H1 :
i = 8 × i / 8 + i mod 8
⊢
b′ + o′ + i mod 8 = 0

pose proof Z.div_modb′ + o′ + i 8 ltac:lia

m :
b, o, b′, o′ :
Z
c′ :
n, i :
Z
Hb :
b mod 8 = 0
Ho :
o mod 8 = 0
Hb′ :
b′ mod 8 = 0
Ho′ :
o′ mod 8 = 0
Hi :
0 ≤ i
Hi8 :
i mod 8 = 0
H :
b′ = 8 × b′ / 8 + b′ mod 8
H0 :
o′ = 8 × o′ / 8 + o′ mod 8
H1 :
i = 8 × i / 8 + i mod 8
H2 :
b′ + o′ + i = 8 × b′ + o′ + i / 8 + b′ + o′ + i mod 8
⊢
b′ + o′ + i mod 8 = 0

pose proof Z.mod_pos_boundb′ + o′ + i 8 ltac:lia

m :
b, o, b′, o′ :
Z
c′ :
n, i :
Z
Hb :
b mod 8 = 0
Ho :
o mod 8 = 0
Hb′ :
b′ mod 8 = 0
Ho′ :
o′ mod 8 = 0
Hi :
0 ≤ i
Hi8 :
i mod 8 = 0
H :
b′ = 8 × b′ / 8 + b′ mod 8
H0 :
o′ = 8 × o′ / 8 + o′ mod 8
H1 :
i = 8 × i / 8 + i mod 8
H2 :
b′ + o′ + i = 8 × b′ + o′ + i / 8 + b′ + o′ + i mod 8
H3 :
0 ≤ b′ + o′ + i mod 8 < 8
⊢
b′ + o′ + i mod 8 = 0

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hb Ho Hb′ Ho′ Hi Hi8
cbn [ ptr_addr ]
replace b + o ≤? b + o + i with true by symmetry ; apply Z.leb_le ; lia
replace b + o + i + 8 ≤? b + o + n with i + 8 ≤? n by destruct Z.leb_speci + 8 n , Z.leb_specb + o + i + 8 b + o + n ; lia
replace b′ + o′ + b + o + i − b + o with b′ + o′ + i by lia
replace b′ + o′ + i mod 8 =? 0 with true
–destruct i + 8 ≤? n ; reflexivity
–symmetry
apply Z.eqb_eq
pose proof Z.div_modb′ 8 ltac:lia
pose proof Z.div_modo′ 8 ltac:lia
pose proof Z.div_modi 8 ltac:lia
pose proof Z.div_modb′ + o′ + i 8 ltac:lia
pose proof Z.mod_pos_boundb′ + o′ + i 8 ltac:lia
lia

A copy of the n bytes ys of a source block at offset o' of the live object b' into the block at offset o of the live object b, both at multiples of 8: afterwards the destination's bytes are ys and its slots copy_slots, and every piece outside it keeps its agreement (block_frame).

345Lemma copy_after
∀ m m′ b reg o xs cs b′ reg′ o′ ys ds c′
live_atm b reg
live_atm b′ reg′
b mod 8 = 0
o mod 8 = 0
b′ mod 8 = 0
o′ mod 8 = 0
lengthys = lengthxs
lengthcs = lengthxs
lengthds = lengthxs
all_agreem byte_psb o xs ++ aux_psb o cs
all_agreem byte_psb′ o′ ys ++ aux_psb′ o′ ds
copy_resultm mkPtrb + o Objb mkPtrb′ + o′ c′ Z.of_natlengthxs m′
all_agreem′ byte_psb o ys ++ aux_psb o copy_slotsZ.of_natlengthxs ds cs ∧ frame_okbyte_psb o xs ++ aux_psb o cs.*1 m m′
Proof 81 steps Qed
intros Hd Hl Hl′ Hb8 Ho8 Hb8′ Ho8′ Hly Hlc Hld Hdst Hsrc Hres
pose proof Hres as Hfr & Hcb & Hcs
pose proof Hfr as Hr & _ & Haux
split ; | exact block_frame_ _ _ _ _ _ _ Hd Hl Hb8 Ho8 Hlc Hdst Hfr
pose proof Hdst as Hdst′
apply all_agree_app in Hdst' as Hx Hc
apply all_agree_app in Hsrc as Hy Hds
destruct Hl as E0 L0
assert Hreg : registeredm' b by unfold registered ; rewrite Hr E0 ; discriminate

The i-th byte and slot of the destination lie in b's bounds.

assert Hbyte : ∀i, i < lengthxs%nat → 0 ≤ o + Z.of_nati ∧ b + o + Z.of_nati < r_endreg
{intros i Hi
destruct lookup_lt_is_Some_2xs i Hi as x Hxi
destruct byte_ps_agree_ _ _ _ _ _ _ conjE0 L0 Hx Hxi as _ & H1 & H2
lia
assert Hslot : ∀b0 o0 cs0 i c0, all_agreem aux_psb0 o0 cs0 → cs0 !! i = Somec0 → ∀reg0, live_atm b0 reg0 → aux_holdsm b0 + o0 + Z.of_nati c0
{intros b0 o0 cs0 i c0 Ha Hci reg0 E L
assert Hin : aux_psb0 o0 cs0 !! i = SomePAuxb0 o0 + Z.of_nati, VAuxc0
{unfold aux_ps
apply lookup_zip_with_Some
exists o0 + Z.of_nati, c0
split ; reflexivity |
split ; | exact Hci
apply lookup_seqZ
split ; reflexivity |
apply lookup_lt_Some in Hci
lia
destruct all_agree_elem_ _ _ _ Ha list_elem_of_lookup_2_ _ _ Hin as _ Hin′
destruct Hin'reg0 E L as _ & _ & Hh
exact Hh
assert Hmod : ∀i, b + o + i mod 8 = i mod 8
{intros i
rewrite Z.add_mod ; | lia
rewrite Hb8 Z.add_0_l Z.mod_mod ; | lia
rewrite Z.add_mod ; | lia
rewrite Ho8 Z.add_0_l Z.mod_mod ; reflexivity | lia
split ; apply all_agree_intro ; intros l v Hin
–apply byte_ps_elem in Hin as i & y & Hyi & → & →
assert Hi : i < lengthxs%nat by rewrite <- Hly ; exact lookup_lt_Some_ _ _ Hyi
destruct Hbytei Hi as H1 H2
cbn [ agree_piece ]
split ; exact Hreg |
intros reg0 E L
rewrite Hr E0 in E
injection E as ←
split ; exact H1 |
split ; exact H2 |
rewrite Hcb ; | unfold span_contains ; cbn ; lia
cbn [ ptr_addr ]
replace b' + o' + b + o + Z.of_nati − b + o with b' + o' + Z.of_nati by lia
destruct byte_ps_agree_ _ _ _ _ _ _ Hl' Hy Hyi as Hv & _ & _
exact Hv
–apply aux_ps_elem in Hin as i & c & Hci & → & →
destruct lookup_copy_slots_ _ _ _ _ Hci as d0 & c0 & Hd0 & Hc0 & →
assert Hi : i < lengthxs%nat by rewrite <- Hlc ; exact lookup_lt_Some_ _ _ Hc0
destruct Hbytei Hi as H1 H2
cbn [ agree_piece ]
split ; exact Hreg |
intros reg0 E L
rewrite Hr E0 in E
injection E as ←
split ; exact H1 |
split ; exact H2 |
unfold aux_holds
rewrite Hr
destruct Z.eqb_specZ.of_nati mod 8 0 as Hz | Hz
+assert Ht : memset_touchedmkPtrb + o Objb Z.of_natlengthxs b + o + Z.of_nati = true
cbn [ ptr_addr ]
rewrite Hmod
lia
rewrite Hcs_ Ht copy_slot_at_ _ _ _ _ _ _ Z.of_nati Hb8 Ho8 Hb8' Ho8' ltac:lia Hz
destruct Z.of_nati + 8 ≤? Z.of_natlengthxs
∗exact Hslot_ _ _ _ _ Hds Hd0 _ Hl'
∗left
reflexivity
+rewrite Haux ; exact Hslot_ _ _ _ _ Hc Hc0 _ conjE0 L0 |
destruct memset_touched_ _ _ eqn: Ht ; | reflexivity
apply memset_touched_spec in Ht as _ & Ht & _
rewrite Hmod in Ht
contradiction

A change that keeps every region, and every byte and aux slot outside the live object b, keeps the agreement of every piece of another object: frame_within with every piece of b as keys.

403Lemma frame_other
∀ m m′ b reg l v
live_atm b reg
∀a, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
mem_piecel → piece_idl ≠ b
agree_piecem′ l v
Explore proof 23 tactics

Initial goal

m, m′ :
b :
Z
reg :
v :
⊢
m_regionsm′ = m_regionsm → live_disjointm → live_atm b reg → ∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a → mem_piecel → piece_idl ≠ b → agree_piecem l v → agree_piecem′ l v

intros Hr Hd Hl Hout Hid

m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
⊢
agree_piecem l v → agree_piecem′ l v

set ks := PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b

m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
agree_piecem l v → agree_piecem′ l v

apply frame_withinks m m′ b reg Hr Hd Hl

3 open

m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
∀a : Z, b ≤ a < r_endreg → PByteb a − b ∉ ks → m_bytesm′ a = m_bytesm a
focused goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
∀a : Z, b ≤ a < r_endreg → PAuxb a − b ∉ ks → m_auxm′ a = m_auxm a
focused goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
l ∉ ks

–intros a H

3 open

m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
a :
Z
H :
b ≤ a < r_endreg → PByteb a − b ∉ ks
⊢
m_bytesm′ a = m_bytesm a
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
∀a : Z, b ≤ a < r_endreg → PAuxb a − b ∉ ks → m_auxm′ a = m_auxm a
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
l ∉ ks

apply Hout

3 open

m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
a :
Z
H :
b ≤ a < r_endreg → PByteb a − b ∉ ks
⊢
¬b ≤ a < r_endreg
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
∀a : Z, b ≤ a < r_endreg → PAuxb a − b ∉ ks → m_auxm′ a = m_auxm a
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
l ∉ ks

intros Ha

3 open

m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
a :
Z
H :
b ≤ a < r_endreg → PByteb a − b ∉ ks
Ha :
b ≤ a < r_endreg
⊢
False
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
∀a : Z, b ≤ a < r_endreg → PAuxb a − b ∉ ks → m_auxm′ a = m_auxm a
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
l ∉ ks

apply HHa

3 open

m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
a :
Z
H :
b ≤ a < r_endreg → PByteb a − b ∉ ks
Ha :
b ≤ a < r_endreg
⊢
PByteb a − b ∈ ks
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
∀a : Z, b ≤ a < r_endreg → PAuxb a − b ∉ ks → m_auxm′ a = m_auxm a
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
l ∉ ks

apply elem_of_app

3 open

m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
a :
Z
H :
b ≤ a < r_endreg → PByteb a − b ∉ ks
Ha :
b ≤ a < r_endreg
⊢
PByteb a − b ∈ PByteb <$> seqZ0 r_endreg − b ∨ PByteb a − b ∈ PAuxb <$> seqZ0 r_endreg − b
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
∀a : Z, b ≤ a < r_endreg → PAuxb a − b ∉ ks → m_auxm′ a = m_auxm a
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
l ∉ ks

left

3 open

m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
a :
Z
H :
b ≤ a < r_endreg → PByteb a − b ∉ ks
Ha :
b ≤ a < r_endreg
⊢
PByteb a − b ∈ PByteb <$> seqZ0 r_endreg − b
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
∀a : Z, b ≤ a < r_endreg → PAuxb a − b ∉ ks → m_auxm′ a = m_auxm a
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
l ∉ ks

apply list_elem_of_fmap_2

3 open

m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
a :
Z
H :
b ≤ a < r_endreg → PByteb a − b ∉ ks
Ha :
b ≤ a < r_endreg
⊢
a − b ∈ seqZ0 r_endreg − b
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
∀a : Z, b ≤ a < r_endreg → PAuxb a − b ∉ ks → m_auxm′ a = m_auxm a
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
l ∉ ks

apply elem_of_seqZ

3 open

m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
a :
Z
H :
b ≤ a < r_endreg → PByteb a − b ∉ ks
Ha :
b ≤ a < r_endreg
⊢
0 ≤ a − b < 0 + r_endreg − b
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
∀a : Z, b ≤ a < r_endreg → PAuxb a − b ∉ ks → m_auxm′ a = m_auxm a
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
l ∉ ks

lia

2 open

deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
∀a : Z, b ≤ a < r_endreg → PAuxb a − b ∉ ks → m_auxm′ a = m_auxm a
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
l ∉ ks

–intros a H

2 open

m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
a :
Z
H :
b ≤ a < r_endreg → PAuxb a − b ∉ ks
⊢
m_auxm′ a = m_auxm a
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
l ∉ ks

apply Hout

2 open

m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
a :
Z
H :
b ≤ a < r_endreg → PAuxb a − b ∉ ks
⊢
¬b ≤ a < r_endreg
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
l ∉ ks

intros Ha

2 open

m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
a :
Z
H :
b ≤ a < r_endreg → PAuxb a − b ∉ ks
Ha :
b ≤ a < r_endreg
⊢
False
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
l ∉ ks

apply HHa

2 open

m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
a :
Z
H :
b ≤ a < r_endreg → PAuxb a − b ∉ ks
Ha :
b ≤ a < r_endreg
⊢
PAuxb a − b ∈ ks
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
l ∉ ks

apply elem_of_app

2 open

m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
a :
Z
H :
b ≤ a < r_endreg → PAuxb a − b ∉ ks
Ha :
b ≤ a < r_endreg
⊢
PAuxb a − b ∈ PByteb <$> seqZ0 r_endreg − b ∨ PAuxb a − b ∈ PAuxb <$> seqZ0 r_endreg − b
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
l ∉ ks

right

2 open

m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
a :
Z
H :
b ≤ a < r_endreg → PAuxb a − b ∉ ks
Ha :
b ≤ a < r_endreg
⊢
PAuxb a − b ∈ PAuxb <$> seqZ0 r_endreg − b
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
l ∉ ks

apply list_elem_of_fmap_2

2 open

m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
a :
Z
H :
b ≤ a < r_endreg → PAuxb a − b ∉ ks
Ha :
b ≤ a < r_endreg
⊢
a − b ∈ seqZ0 r_endreg − b
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
l ∉ ks

apply elem_of_seqZ

2 open

m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
a :
Z
H :
b ≤ a < r_endreg → PAuxb a − b ∉ ks
Ha :
b ≤ a < r_endreg
⊢
0 ≤ a − b < 0 + r_endreg − b
deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
l ∉ ks

lia

deferred goal
m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
⊢
l ∉ ks

–intros Hk

m, m′ :
b :
Z
reg :
v :
Hr :
Hl :
live_atm b reg
Hout :
∀a : Z, ¬b ≤ a < r_endreg → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
Hid :
mem_piecel → piece_idl ≠ b
ks :=
PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b : listpiece
Hk :
l ∈ ks
⊢
False

apply elem_of_app in Hk as Hk | Hk ; apply list_elem_of_fmap in Hk as o & → & _ ; exact HidI eq_refl

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hr Hd Hl Hout Hid
set ks := PByteb <$> seqZ0 r_endreg − b ++ PAuxb <$> seqZ0 r_endreg − b
apply frame_withinks m m′ b reg Hr Hd Hl
–intros a H
apply Hout
intros Ha
apply HHa
apply elem_of_app
left
apply list_elem_of_fmap_2
apply elem_of_seqZ
lia
–intros a H
apply Hout
intros Ha
apply HHa
apply elem_of_app
right
apply list_elem_of_fmap_2
apply elem_of_seqZ
lia
–intros Hk
apply elem_of_app in Hk as Hk | Hk ; apply list_elem_of_fmap in Hk as o & → & _ ; exact HidI eq_refl

A copy of the string ys at src, with its NUL, over the bytes xs from offset o of the live object b: afterwards those bytes are ys and the NUL, and every piece outside them keeps its agreement (frame_ok). A scalar copy keeps every aux slot.

423Lemma copy_string_after
∀ m m′ b reg o xs src b′ reg′ ys
live_atm b reg
lengthxs = Slengthys
string_oksrc b′ reg′ ys
all_agreem string_pssrc b′ reg′ ys
string_copy_resultm mkPtrb + o Objb src Z.of_natlengthys + 1 m′
all_agreem′ byte_psb o ys ++ 0 ∧ frame_okbyte_psb o xs.*1 m m′
Proof 41 steps Qed
intros Hd Hl Hx Hlen Hok Hs Hr & Haux & Hbytes & Hcopy
assert Hbyte : ∀i, i < lengthxs%nat → 0 ≤ o + Z.of_nati ∧ b + o + Z.of_nati < r_endreg
{intros i Hi
destruct lookup_lt_is_Some_2xs i Hi as x Hxi
destruct byte_ps_agree_ _ _ _ _ _ _ Hl Hx Hxi as _ & H1 & H2
lia
split
intros l v Hin
apply byte_ps_elem in Hin as i & x & Hxi & → & →
assert Hi : i < lengthxs%nat
{apply lookup_lt_Some in Hxi
rewrite length_app in Hxi
cbn in Hxi
lia
destruct lookup_lt_is_Some_2xs i Hi as x0 Hx0
pose proof all_agree_elem_ _ _ _ Hx list_elem_of_lookup_2_ _ _ byte_ps_lookupb o xs i x0 Hx0 as Hreg _
cbn [ agree_piece ]
split ; unfold registered in * ; rewrite Hr ; exact Hreg |
intros reg0 E L
destruct Hl as E0 _
rewrite Hr E0 in E
injection E as ←
destruct Hbytei Hi as H1 H2
split ; exact H1 |
split ; exact H2 |
rewrite Hcopy ; | unfold span_contains ; cbn ; lia
cbn [ ptr_addr ]
replace ptr_addrsrc + b + o + Z.of_nati − b + o with ptr_addrsrc + Z.of_nati by lia
exact string_bytes_ _ _ _ _ Hok Hs i x Hxi
–apply frame_within_ _ _ b reg ; exact Hr | exact Hd | exact Hl | | intros a _ ; apply Haux
intros a H
apply Hbytes
intros Hsp
unfold span_contains in Hsp
cbn in Hsp
destruct HbyteZ.to_nata − b − o ltac:lia as H1 H2
apply H ; lia |
replace a − b with o + a − b − o by lia
lia

A block of the bytes xs from offset o of the live object b, in its bounds and each a byte, is readable_bytes through b's read-write or read-only capability c, and holds xs.

456Lemma block_readable
∀ m b reg o xs c
live_atm b reg
c = Objb ∨ c = Rob
0 ≤ o
b + o + Z.of_natlengthxs ≤ r_endreg
Forallλx ⇒ 0 ≤ x < 256 xs
readable_bytesm mkPtrb + o c Z.of_natlengthxs ∧ ∀i x, xs !! i = Somex → m_bytesm b + o + Z.of_nati = x
Explore proof 18 tactics

Initial goal

m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
⊢
live_atm b reg → all_agreem byte_psb o xs → objects_fitm_regionsm → c = Objb ∨ c = Rob → 0 ≤ o → b + o + lengthxs ≤ r_endreg → Forallλx : Z ⇒ 0 ≤ x < 256 xs → readable_bytesm ptr_addr ≔ b + o; ptr_cap ≔ c lengthxs ∧ ∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x

intros Hl Hx Hfit Hc Ho Hend Hy

m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
⊢
readable_bytesm ptr_addr ≔ b + o; ptr_cap ≔ c lengthxs ∧ ∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x

destruct Hfitb reg proj1Hl as Hb0 Hfit′

m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
Hb0 :
0 ≤ b
Hfit′ :
r_endreg ≤ 2 ^ 48
⊢
readable_bytesm ptr_addr ≔ b + o; ptr_cap ≔ c lengthxs ∧ ∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x

assert Hv : ∀i x, xs !! i = Somex → m_bytesm b + o + Z.of_nati = x

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
Hb0 :
0 ≤ b
Hfit′ :
r_endreg ≤ 2 ^ 48
⊢
∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x
focused goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
Hb0 :
0 ≤ b
Hfit′ :
r_endreg ≤ 2 ^ 48
Hv :
∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x
⊢
readable_bytesm ptr_addr ≔ b + o; ptr_cap ≔ c lengthxs ∧ ∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x

{intros i x Hi

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
Hb0 :
0 ≤ b
Hfit′ :
r_endreg ≤ 2 ^ 48
i :
nat
x :
Z
Hi :
xs !! i = Somex
⊢
m_bytesm b + o + i = x
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
Hb0 :
0 ≤ b
Hfit′ :
r_endreg ≤ 2 ^ 48
Hv :
∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x
⊢
readable_bytesm ptr_addr ≔ b + o; ptr_cap ≔ c lengthxs ∧ ∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x

destruct byte_ps_agree_ _ _ _ _ _ _ Hl Hx Hi as Hv & _ & _

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
Hb0 :
0 ≤ b
Hfit′ :
r_endreg ≤ 2 ^ 48
i :
nat
x :
Z
Hi :
xs !! i = Somex
Hv :
m_bytesm b + o + i = x
⊢
m_bytesm b + o + i = x
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
Hb0 :
0 ≤ b
Hfit′ :
r_endreg ≤ 2 ^ 48
Hv :
∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x
⊢
readable_bytesm ptr_addr ≔ b + o; ptr_cap ≔ c lengthxs ∧ ∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x

replace b + o + Z.of_nati with b + o + Z.of_nati by lia

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
Hb0 :
0 ≤ b
Hfit′ :
r_endreg ≤ 2 ^ 48
i :
nat
x :
Z
Hi :
xs !! i = Somex
Hv :
m_bytesm b + o + i = x
⊢
m_bytesm b + o + i = x
deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
Hb0 :
0 ≤ b
Hfit′ :
r_endreg ≤ 2 ^ 48
Hv :
∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x
⊢
readable_bytesm ptr_addr ≔ b + o; ptr_cap ≔ c lengthxs ∧ ∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x

exact Hv

deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
Hb0 :
0 ≤ b
Hfit′ :
r_endreg ≤ 2 ^ 48
Hv :
∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x
⊢
readable_bytesm ptr_addr ≔ b + o; ptr_cap ≔ c lengthxs ∧ ∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x

split ; | exact Hv

m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
Hb0 :
0 ≤ b
Hfit′ :
r_endreg ≤ 2 ^ 48
Hv :
∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x
⊢
readable_bytesm ptr_addr ≔ b + o; ptr_cap ≔ c lengthxs

split ; lia |

m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
Hb0 :
0 ≤ b
Hfit′ :
r_endreg ≤ 2 ^ 48
Hv :
∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x
⊢
∃base : Z reg0 : region, ptr_capptr_addr ≔ b + o; ptr_cap ≔ c = Objbase ∨ ptr_capptr_addr ≔ b + o; ptr_cap ≔ c = Robase ∧ object_regionbase m_regionsm = Somereg0 ∧ r_lifereg0 = Live ∧ access_resm ptr_addrptr_addr ≔ b + o; ptr_cap ≔ c ptr_capptr_addr ≔ b + o; ptr_cap ≔ c lengthxs Read 1 = Someok ∧ ∀i : Z, 0 ≤ i < lengthxs → 0 ≤ m_bytesm ptr_addrptr_addr ≔ b + o; ptr_cap ≔ c + i < 256

split ; exists b, reg ; split ; exact Hc | exact Hl |

m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
Hb0 :
0 ≤ b
Hfit′ :
r_endreg ≤ 2 ^ 48
Hv :
∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x
⊢
access_resm ptr_addrptr_addr ≔ b + o; ptr_cap ≔ c ptr_capptr_addr ≔ b + o; ptr_cap ≔ c lengthxs Read 1 = Someok ∧ ∀i : Z, 0 ≤ i < lengthxs → 0 ≤ m_bytesm ptr_addrptr_addr ≔ b + o; ptr_cap ≔ c + i < 256

split

2 open

m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
Hb0 :
0 ≤ b
Hfit′ :
r_endreg ≤ 2 ^ 48
Hv :
∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x
⊢
access_resm ptr_addrptr_addr ≔ b + o; ptr_cap ≔ c ptr_capptr_addr ≔ b + o; ptr_cap ≔ c lengthxs Read 1 = Someok
focused goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
Hb0 :
0 ≤ b
Hfit′ :
r_endreg ≤ 2 ^ 48
Hv :
∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x
⊢
∀i : Z, 0 ≤ i < lengthxs → 0 ≤ m_bytesm ptr_addrptr_addr ≔ b + o; ptr_cap ≔ c + i < 256

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

deferred goal
m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
Hb0 :
0 ≤ b
Hfit′ :
r_endreg ≤ 2 ^ 48
Hv :
∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x
⊢
∀i : Z, 0 ≤ i < lengthxs → 0 ≤ m_bytesm ptr_addrptr_addr ≔ b + o; ptr_cap ≔ c + i < 256

–intros i Hi

m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
Hb0 :
0 ≤ b
Hfit′ :
r_endreg ≤ 2 ^ 48
Hv :
∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x
i :
Z
Hi :
0 ≤ i < lengthxs
⊢
0 ≤ m_bytesm ptr_addrptr_addr ≔ b + o; ptr_cap ≔ c + i < 256

cbn [ ptr_addr ]

m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
Hb0 :
0 ≤ b
Hfit′ :
r_endreg ≤ 2 ^ 48
Hv :
∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x
i :
Z
Hi :
0 ≤ i < lengthxs
⊢
0 ≤ m_bytesm b + o + i < 256

destruct lookup_lt_is_Some_2xs Z.to_nati ltac:lia as x Hxi

m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
Hb0 :
0 ≤ b
Hfit′ :
r_endreg ≤ 2 ^ 48
Hv :
∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x
i :
Z
Hi :
0 ≤ i < lengthxs
x :
Z
Hxi :
xs !! Z.to_nati = Somex
⊢
0 ≤ m_bytesm b + o + i < 256

rewrite <- Z2Nat.idi by lia

m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
Hb0 :
0 ≤ b
Hfit′ :
r_endreg ≤ 2 ^ 48
Hv :
∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x
i :
Z
Hi :
0 ≤ i < lengthxs
x :
Z
Hxi :
xs !! Z.to_nati = Somex
⊢
0 ≤ m_bytesm b + o + Z.to_nati < 256

rewrite Hv_ _ Hxi

m :
b :
Z
reg :
o :
Z
xs :
listZ
c :
Hl :
live_atm b reg
Hx :
Hc :
c = Objb ∨ c = Rob
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hy :
Forallλx : Z ⇒ 0 ≤ x < 256 xs
Hb0 :
0 ≤ b
Hfit′ :
r_endreg ≤ 2 ^ 48
Hv :
∀i : nat x : Z, xs !! i = Somex → m_bytesm b + o + i = x
i :
Z
Hi :
0 ≤ i < lengthxs
x :
Z
Hxi :
xs !! Z.to_nati = Somex
⊢
0 ≤ x < 256

exact Forall_lookup_1_ _ _ _ Hy Hxi

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hl Hx Hfit Hc Ho Hend Hy
destruct Hfitb reg proj1Hl as Hb0 Hfit′
assert Hv : ∀i x, xs !! i = Somex → m_bytesm b + o + Z.of_nati = x
{intros i x Hi
destruct byte_ps_agree_ _ _ _ _ _ _ Hl Hx Hi as Hv & _ & _
replace b + o + Z.of_nati with b + o + Z.of_nati by lia
exact Hv
split ; | exact Hv
split ; lia |
split ; exists b, reg ; split ; exact Hc | exact Hl |
split
–apply access_read_ b reg ; exact Hc | exact proj1Hl | cbn ; lia | cbn ; lia | apply Z.mod_1_r
–intros i Hi
cbn [ ptr_addr ]
destruct lookup_lt_is_Some_2xs Z.to_nati ltac:lia as x Hxi
rewrite <- Z2Nat.idi by lia
rewrite Hv_ _ Hxi
exact Forall_lookup_1_ _ _ _ Hy Hxi

Searching a string for its NUL

A search for the NUL reads a bounded_length string through its NUL when that lies before the bound, and the whole bound otherwise. So memchr_input holds for an int c whose low byte is the NUL, with nothing asked of the bytes after the NUL.

479Lemma memchr_input_bounded
∀ m p c n k
0 ≤ c < 2 ^ 32
c mod 256 = 0
Explore proof 22 tactics

Initial goal

m :
p :
c, n, k :
Z
⊢
0 ≤ c < 2 ^ 32 → c mod 256 = 0 → bounded_lengthm p n k → memchr_inputm p c n

intros Hc H0 Hn & Hk & Hlife & Ha & Hpos & Hnul

m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢

split ; exact Hc |

m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
0 ≤ n < 2 ^ 64
∧
∃ k0 : Z  ,
0 ≤ k0 ≤ n
∧
k0
+
k0 <? n
→
1
else
0
∧
∀i : Z, 0 ≤ i < k0 → m_bytesm ptr_addrp + i ≠ c mod 256 ∧ k0 < n → m_bytesm ptr_addrp + k0 = c mod 256

split ; exact Hn |

m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
∃ k0 : Z  ,
0 ≤ k0 ≤ n
∧
k0
+
k0 <? n
→
1
else
0
∧
∀i : Z, 0 ≤ i < k0 → m_bytesm ptr_addrp + i ≠ c mod 256 ∧ k0 < n → m_bytesm ptr_addrp + k0 = c mod 256

exists k

m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
0 ≤ k ≤ n
∧
k
+
k <? n
→
1
else
0
∧
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ c mod 256 ∧ k < n → m_bytesm ptr_addrp + k = c mod 256

split ; exact Hk |

m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
k
+
k <? n
→
1
else
0
∧
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ c mod 256 ∧ k < n → m_bytesm ptr_addrp + k = c mod 256

rewrite H0

m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
k
+
k <? n
→
1
else
0
∧
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ k < n → m_bytesm ptr_addrp + k = 0

split

2 open

m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
k
+
k <? n
→
1
else
0
focused goal
m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ k < n → m_bytesm ptr_addrp + k = 0

–split ; destruct k <? n eqn: E ; apply Z.ltb_lt in E | apply Z.ltb_ge in E ; lia |

2 open

m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
∧
k
+
k <? n
→
1
else
0
1
=
Someok
∧
∀i : Z, 0 ≤ i < k + if k <? n then 1 else 0 → 0 ≤ m_bytesm ptr_addrp + i < 256
deferred goal
m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ k < n → m_bytesm ptr_addrp + k = 0

split ; exact Hlife |

2 open

m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
k
+
k <? n
→
1
else
0
1
=
Someok
∧
∀i : Z, 0 ≤ i < k + if k <? n then 1 else 0 → 0 ≤ m_bytesm ptr_addrp + i < 256
deferred goal
m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ k < n → m_bytesm ptr_addrp + k = 0

split ; exact Ha |

2 open

m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
∀i : Z, 0 ≤ i < k + if k <? n then 1 else 0 → 0 ≤ m_bytesm ptr_addrp + i < 256
deferred goal
m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ k < n → m_bytesm ptr_addrp + k = 0

destruct k <? n eqn: E ; intros i Hi

3 open

m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
E :
k <? n = true
Ha :
access_resm ptr_addrp ptr_capp k + 1 Read 1 = Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
i :
Z
Hi :
0 ≤ i < k + 1
⊢
0 ≤ m_bytesm ptr_addrp + i < 256
focused goal
m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
E :
k <? n = false
Ha :
access_resm ptr_addrp ptr_capp k + 0 Read 1 = Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
i :
Z
Hi :
0 ≤ i < k + 0
⊢
0 ≤ m_bytesm ptr_addrp + i < 256
deferred goal
m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ k < n → m_bytesm ptr_addrp + k = 0

+apply Z.ltb_lt in E

3 open

m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
E :
k < n
Ha :
access_resm ptr_addrp ptr_capp k + 1 Read 1 = Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
i :
Z
Hi :
0 ≤ i < k + 1
⊢
0 ≤ m_bytesm ptr_addrp + i < 256
deferred goal
m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
E :
k <? n = false
Ha :
access_resm ptr_addrp ptr_capp k + 0 Read 1 = Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
i :
Z
Hi :
0 ≤ i < k + 0
⊢
0 ≤ m_bytesm ptr_addrp + i < 256
deferred goal
m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ k < n → m_bytesm ptr_addrp + k = 0

destruct Z.lt_ge_casesi k as Hik | Hik ; specialize Hposi ltac:lia ; lia |

3 open

m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
E :
k < n
Ha :
access_resm ptr_addrp ptr_capp k + 1 Read 1 = Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
i :
Z
Hi :
0 ≤ i < k + 1
Hik :
k ≤ i
⊢
0 ≤ m_bytesm ptr_addrp + i < 256
deferred goal
m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
E :
k <? n = false
Ha :
access_resm ptr_addrp ptr_capp k + 0 Read 1 = Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
i :
Z
Hi :
0 ≤ i < k + 0
⊢
0 ≤ m_bytesm ptr_addrp + i < 256
deferred goal
m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ k < n → m_bytesm ptr_addrp + k = 0

replace i with k by lia

3 open

m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
E :
k < n
Ha :
access_resm ptr_addrp ptr_capp k + 1 Read 1 = Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
i :
Z
Hi :
0 ≤ i < k + 1
Hik :
k ≤ i
⊢
0 ≤ m_bytesm ptr_addrp + k < 256
deferred goal
m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
E :
k <? n = false
Ha :
access_resm ptr_addrp ptr_capp k + 0 Read 1 = Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
i :
Z
Hi :
0 ≤ i < k + 0
⊢
0 ≤ m_bytesm ptr_addrp + i < 256
deferred goal
m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ k < n → m_bytesm ptr_addrp + k = 0

rewrite HnulE

3 open

m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
E :
k < n
Ha :
access_resm ptr_addrp ptr_capp k + 1 Read 1 = Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
i :
Z
Hi :
0 ≤ i < k + 1
Hik :
k ≤ i
⊢
0 ≤ 0 < 256
deferred goal
m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
E :
k <? n = false
Ha :
access_resm ptr_addrp ptr_capp k + 0 Read 1 = Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
i :
Z
Hi :
0 ≤ i < k + 0
⊢
0 ≤ m_bytesm ptr_addrp + i < 256
deferred goal
m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ k < n → m_bytesm ptr_addrp + k = 0

lia

2 open

deferred goal
m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
E :
k <? n = false
Ha :
access_resm ptr_addrp ptr_capp k + 0 Read 1 = Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
i :
Z
Hi :
0 ≤ i < k + 0
⊢
0 ≤ m_bytesm ptr_addrp + i < 256
deferred goal
m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ k < n → m_bytesm ptr_addrp + k = 0

+specialize Hposi ltac:lia

2 open

m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
E :
k <? n = false
Ha :
access_resm ptr_addrp ptr_capp k + 0 Read 1 = Someok
i :
Z
Hpos :
0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
Hi :
0 ≤ i < k + 0
⊢
0 ≤ m_bytesm ptr_addrp + i < 256
deferred goal
m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ k < n → m_bytesm ptr_addrp + k = 0

lia

deferred goal
m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ k < n → m_bytesm ptr_addrp + k = 0

–split ; | exact Hnul

m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
⊢
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0

intros i Hi

m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
Hpos :
∀i : Z, 0 ≤ i < k → 0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
i :
Z
Hi :
0 ≤ i < k
⊢
m_bytesm ptr_addrp + i ≠ 0

specialize Hposi Hi

m :
p :
c, n, k :
Z
Hc :
0 ≤ c < 2 ^ 32
H0 :
c mod 256 = 0
Hn :
0 ≤ n < 2 ^ 64
Hk :
0 ≤ k ≤ n
Hlife :
∃base : Z reg : region, ptr_capp = Objbase ∨ ptr_capp = Robase ∧ object_regionbase m_regionsm = Somereg ∧ r_lifereg = Live
Ha :
k
+
k <? n
→
1
else
0
1
=
Someok
i :
Z
Hpos :
0 < m_bytesm ptr_addrp + i < 256
Hnul :
k < n → m_bytesm ptr_addrp + k = 0
Hi :
0 ≤ i < k
⊢
m_bytesm ptr_addrp + i ≠ 0

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hc H0 Hn & Hk & Hlife & Ha & Hpos & Hnul
split ; exact Hc |
split ; exact Hn |
exists k
split ; exact Hk |
rewrite H0
split
–split ; destruct k <? n eqn: E ; apply Z.ltb_lt in E | apply Z.ltb_ge in E ; lia |
split ; exact Hlife |
split ; exact Ha |
destruct k <? n eqn: E ; intros i Hi
+apply Z.ltb_lt in E
destruct Z.lt_ge_casesi k as Hik | Hik ; specialize Hposi ltac:lia ; lia |
replace i with k by lia
rewrite HnulE
lia
+specialize Hposi ltac:lia
lia
–split ; | exact Hnul
intros i Hi
specialize Hposi Hi
lia

What a search for the NUL bounded by n finds in the string at p with contents bytes: its NUL, with p's capability, when the string is shorter than n, and null otherwise.

496Definition nul_foundp : ptr bytes : listZ n : Z : ptr ≔
Z.of_natlengthbytes <? n
→
mkPtrptr_addrp + Z.of_natlengthbytes ptr_capp

Where the string's pieces agree, memchr's memchr_result for an int whose low byte is the NUL is nul_found: no byte before the NUL matches, and the NUL does.

503Lemma memchr_result_string
∀ m p b reg bytes c n q
string_okp b reg bytes
all_agreem string_psp b reg bytes
c mod 256 = 0
memchr_resultm p c n q
q = nul_foundp bytes n
Explore proof 34 tactics

Initial goal

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
⊢
string_okp b reg bytes → all_agreem string_psp b reg bytes → c mod 256 = 0 → memchr_resultm p c n q → q = nul_foundp bytes n

intros Hok Ha H0 Hq

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hq :
memchr_resultm p c n q
⊢
q = nul_foundp bytes n

pose proof string_bytesm p b reg bytes Hok Ha as Hb

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hq :
memchr_resultm p c n q
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
⊢
q = nul_foundp bytes n

pose proof Hok as _ & _ & _ & _ & _ & Hf

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hq :
memchr_resultm p c n q
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
⊢
q = nul_foundp bytes n

unfold memchr_result in Hq

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = c mod 256 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ c mod 256 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ c mod 256 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
⊢
q = nul_foundp bytes n

rewrite H0 in Hq

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
⊢
q = nul_foundp bytes n

unfold nul_found

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
⊢
q
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

assert Hnz : ∀i, 0 ≤ i < Z.of_natlengthbytes → m_bytesm ptr_addrp + i ≠ 0

2 open

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
⊢
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
focused goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
⊢
q
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

{intros i Hi

2 open

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
i :
Z
Hi :
0 ≤ i < lengthbytes
⊢
m_bytesm ptr_addrp + i ≠ 0
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
⊢
q
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

destruct lookup_lt_is_Some_2bytes Z.to_nati ltac:lia as x Hx

2 open

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
i :
Z
Hi :
0 ≤ i < lengthbytes
x :
Z
Hx :
bytes !! Z.to_nati = Somex
⊢
m_bytesm ptr_addrp + i ≠ 0
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
⊢
q
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

rewrite <- Z2Nat.idi by lia

2 open

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
i :
Z
Hi :
0 ≤ i < lengthbytes
x :
Z
Hx :
bytes !! Z.to_nati = Somex
⊢
m_bytesm ptr_addrp + Z.to_nati ≠ 0
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
⊢
q
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

rewrite HbZ.to_nati x ; | by apply lookup_app_l_Some

2 open

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
i :
Z
Hi :
0 ≤ i < lengthbytes
x :
Z
Hx :
bytes !! Z.to_nati = Somex
⊢
x ≠ 0
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
⊢
q
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

pose proof Forall_lookup_1_ _ _ _ Hf Hx as Hx0

2 open

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
i :
Z
Hi :
0 ≤ i < lengthbytes
x :
Z
Hx :
bytes !! Z.to_nati = Somex
Hx0 :
λx : Z ⇒ 0 < x < 256x
⊢
x ≠ 0
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
⊢
q
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

cbv beta in Hx0

2 open

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
i :
Z
Hi :
0 ≤ i < lengthbytes
x :
Z
Hx :
bytes !! Z.to_nati = Somex
Hx0 :
0 < x < 256
⊢
x ≠ 0
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
⊢
q
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

lia

deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
⊢
q
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

assert Hz : m_bytesm ptr_addrp + Z.of_natlengthbytes = 0

2 open

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
⊢
m_bytesm ptr_addrp + lengthbytes = 0
focused goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
⊢
q
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

{apply Hblengthbytes 0

2 open

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
⊢
bytes ++ 0 !! lengthbytes = Some0
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
⊢
q
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

rewrite lookup_app_r ; | lia

2 open

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
⊢
0 !! lengthbytes − lengthbytes%nat = Some0
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
⊢
q
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

rewrite Nat.sub_diag

2 open

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
⊢
0 !! 0%nat = Some0
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
⊢
q
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

reflexivity

deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
q :
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hq :
∃k : Z, 0 ≤ k < n ∧ m_bytesm ptr_addrp + k = 0 ∧ ∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp ∨ ∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0 ∧ q = ptr_addr ≔ 0; ptr_cap ≔ CNone
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
⊢
q
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

destruct Hq as k & Hk & Hvk & Hbefore & → | Hmiss & →

2 open

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
k :
Z
Hk :
0 ≤ k < n
Hvk :
m_bytesm ptr_addrp + k = 0
Hbefore :
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
⊢
ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone
focused goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hmiss :
∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
⊢
ptr_addr ≔ 0; ptr_cap ≔ CNone
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

–assert Hkl : k = Z.of_natlengthbytes

3 open

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
k :
Z
Hk :
0 ≤ k < n
Hvk :
m_bytesm ptr_addrp + k = 0
Hbefore :
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
⊢
k = lengthbytes
focused goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
k :
Z
Hk :
0 ≤ k < n
Hvk :
m_bytesm ptr_addrp + k = 0
Hbefore :
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
Hkl :
k = lengthbytes
⊢
ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hmiss :
∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
⊢
ptr_addr ≔ 0; ptr_cap ≔ CNone
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

{destruct Z.lt_trichotomyk Z.of_natlengthbytes as Hl | Hl | Hl

5 open

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
k :
Z
Hk :
0 ≤ k < n
Hvk :
m_bytesm ptr_addrp + k = 0
Hbefore :
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
Hl :
k < lengthbytes
⊢
k = lengthbytes
focused goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
k :
Z
Hk :
0 ≤ k < n
Hvk :
m_bytesm ptr_addrp + k = 0
Hbefore :
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
Hl :
k = lengthbytes
⊢
k = lengthbytes
focused goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
k :
Z
Hk :
0 ≤ k < n
Hvk :
m_bytesm ptr_addrp + k = 0
Hbefore :
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
Hl :
lengthbytes < k
⊢
k = lengthbytes
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
k :
Z
Hk :
0 ≤ k < n
Hvk :
m_bytesm ptr_addrp + k = 0
Hbefore :
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
Hkl :
k = lengthbytes
⊢
ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hmiss :
∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
⊢
ptr_addr ≔ 0; ptr_cap ≔ CNone
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

–exfalso

5 open

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
k :
Z
Hk :
0 ≤ k < n
Hvk :
m_bytesm ptr_addrp + k = 0
Hbefore :
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
Hl :
k < lengthbytes
⊢
False
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
k :
Z
Hk :
0 ≤ k < n
Hvk :
m_bytesm ptr_addrp + k = 0
Hbefore :
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
Hl :
k = lengthbytes
⊢
k = lengthbytes
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
k :
Z
Hk :
0 ≤ k < n
Hvk :
m_bytesm ptr_addrp + k = 0
Hbefore :
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
Hl :
lengthbytes < k
⊢
k = lengthbytes
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
k :
Z
Hk :
0 ≤ k < n
Hvk :
m_bytesm ptr_addrp + k = 0
Hbefore :
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
Hkl :
k = lengthbytes
⊢
ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hmiss :
∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
⊢
ptr_addr ≔ 0; ptr_cap ≔ CNone
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

apply Hnzk ; lia | exact Hvk

4 open

deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
k :
Z
Hk :
0 ≤ k < n
Hvk :
m_bytesm ptr_addrp + k = 0
Hbefore :
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
Hl :
k = lengthbytes
⊢
k = lengthbytes
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
k :
Z
Hk :
0 ≤ k < n
Hvk :
m_bytesm ptr_addrp + k = 0
Hbefore :
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
Hl :
lengthbytes < k
⊢
k = lengthbytes
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
k :
Z
Hk :
0 ≤ k < n
Hvk :
m_bytesm ptr_addrp + k = 0
Hbefore :
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
Hkl :
k = lengthbytes
⊢
ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hmiss :
∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
⊢
ptr_addr ≔ 0; ptr_cap ≔ CNone
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

–exact Hl

3 open

deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
k :
Z
Hk :
0 ≤ k < n
Hvk :
m_bytesm ptr_addrp + k = 0
Hbefore :
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
Hl :
lengthbytes < k
⊢
k = lengthbytes
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
k :
Z
Hk :
0 ≤ k < n
Hvk :
m_bytesm ptr_addrp + k = 0
Hbefore :
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
Hkl :
k = lengthbytes
⊢
ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hmiss :
∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
⊢
ptr_addr ≔ 0; ptr_cap ≔ CNone
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

–exfalso

3 open

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
k :
Z
Hk :
0 ≤ k < n
Hvk :
m_bytesm ptr_addrp + k = 0
Hbefore :
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
Hl :
lengthbytes < k
⊢
False
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
k :
Z
Hk :
0 ≤ k < n
Hvk :
m_bytesm ptr_addrp + k = 0
Hbefore :
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
Hkl :
k = lengthbytes
⊢
ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hmiss :
∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
⊢
ptr_addr ≔ 0; ptr_cap ≔ CNone
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

apply HbeforeZ.of_natlengthbytes ; lia | exact Hz

2 open

deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
k :
Z
Hk :
0 ≤ k < n
Hvk :
m_bytesm ptr_addrp + k = 0
Hbefore :
∀i : Z, 0 ≤ i < k → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
Hkl :
k = lengthbytes
⊢
ptr_addr ≔ ptr_addrp + k; ptr_cap ≔ ptr_capp
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hmiss :
∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
⊢
ptr_addr ≔ 0; ptr_cap ≔ CNone
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

subst k

2 open

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hbefore :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hvk :
m_bytesm ptr_addrp + lengthbytes = 0
Hk :
0 ≤ lengthbytes < n
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
⊢
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hmiss :
∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
⊢
ptr_addr ≔ 0; ptr_cap ≔ CNone
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

rewrite proj2Z.ltb_lt_ _ proj2Hk

2 open

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hbefore :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hvk :
m_bytesm ptr_addrp + lengthbytes = 0
Hk :
0 ≤ lengthbytes < n
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
⊢
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp = ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hmiss :
∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
⊢
ptr_addr ≔ 0; ptr_cap ≔ CNone
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

reflexivity

deferred goal
m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hmiss :
∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
⊢
ptr_addr ≔ 0; ptr_cap ≔ CNone
=
lengthbytes <? n
→
ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp
else
ptr_addr ≔ 0; ptr_cap ≔ CNone

–destruct Z.of_natlengthbytes <? n eqn: E ; | reflexivity

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hmiss :
∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
E :
lengthbytes <? n = true
⊢
ptr_addr ≔ 0; ptr_cap ≔ CNone = ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp

apply Z.ltb_lt in E

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hmiss :
∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
E :
lengthbytes < n
⊢
ptr_addr ≔ 0; ptr_cap ≔ CNone = ptr_addr ≔ ptr_addrp + lengthbytes; ptr_cap ≔ ptr_capp

exfalso

m :
p :
b :
Z
reg :
bytes :
listZ
c, n :
Z
Hok :
string_okp b reg bytes
Ha :
all_agreem string_psp b reg bytes
H0 :
c mod 256 = 0
Hb :
∀i : nat x : Z, bytes ++ 0 !! i = Somex → m_bytesm ptr_addrp + i = x
Hf :
Forallλx : Z ⇒ 0 < x < 256 bytes
Hmiss :
∀i : Z, 0 ≤ i < n → m_bytesm ptr_addrp + i ≠ 0
Hnz :
∀i : Z, 0 ≤ i < lengthbytes → m_bytesm ptr_addrp + i ≠ 0
Hz :
m_bytesm ptr_addrp + lengthbytes = 0
E :
lengthbytes < n
⊢
False

apply HmissZ.of_natlengthbytes ; lia | exact Hz

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hok Ha H0 Hq
pose proof string_bytesm p b reg bytes Hok Ha as Hb
pose proof Hok as _ & _ & _ & _ & _ & Hf
unfold memchr_result in Hq
rewrite H0 in Hq
unfold nul_found
assert Hnz : ∀i, 0 ≤ i < Z.of_natlengthbytes → m_bytesm ptr_addrp + i ≠ 0
{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
pose proof Forall_lookup_1_ _ _ _ Hf Hx as Hx0
cbv beta in Hx0
lia
assert Hz : m_bytesm ptr_addrp + Z.of_natlengthbytes = 0
{apply Hblengthbytes 0
rewrite lookup_app_r ; | lia
rewrite Nat.sub_diag
reflexivity
destruct Hq as k & Hk & Hvk & Hbefore & → | Hmiss & →
–assert Hkl : k = Z.of_natlengthbytes
{destruct Z.lt_trichotomyk Z.of_natlengthbytes as Hl | Hl | Hl
–exfalso
apply Hnzk ; lia | exact Hvk
–exact Hl
–exfalso
apply HbeforeZ.of_natlengthbytes ; lia | exact Hz
subst k
rewrite proj2Z.ltb_lt_ _ proj2Hk
reflexivity
–destruct Z.of_natlengthbytes <? n eqn: E ; | reflexivity
apply Z.ltb_lt in E
exfalso
apply HmissZ.of_natlengthbytes ; lia | exact Hz

The memory and aux triples over any runtime R.

527Module MemLogicOn R : Runtime LG0 : LogicSigR
528Module SL ≔ StringLogicOn R LG0
529Module LG ≔ SL.LG
530Module L ≔ LG.L
Import L LG SL
533Section mem
534Context `{!invGS_genhlc Σ, !gen_heapGSpiece pval Σ}

bytes b o xs: owning the bytes xs from offset o of the object b.

537Definition bytesb o : Z xs : listZ : iPropΣ ≔

auxes b o cs: owning the aux slots holding cs from offset o of the object b.

541Definition auxesb o : Z cs : listcap : iPropΣ ≔
ptsaux_psb o cs

A block's pieces are its life, bytes and slots.

544Lemma block_pts
∀ b reg o xs cs
ptsblock_psb reg o xs cs ⊣⊢ liveb reg ∗ bytesb o xs ∗ auxesb o cs
Explore proof 2 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
reg :
o :
Z
xs :
listZ
cs :
listcap
⊢
ptsblock_psb reg o xs cs ⊣⊢ liveb reg ∗ bytesb o xs ∗ auxesb o cs

rewrite / block_ps / live / bytes / auxes / pts big_sepL_cons big_sepL_app big_sepL_singleton

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
reg :
o :
Z
xs :
listZ
cs :
listcap
⊢
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈byte_psb o xspointstoy.1 DfracOwn1 y.2 ∗ ∗y∈aux_psb o cspointstoy.1 DfracOwn1 y.2 ⊣⊢ pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗lv∈byte_psb o xspointstolv.1 DfracOwn1 lv.2 ∗ ∗lv∈aux_psb o cspointstolv.1 DfracOwn1 lv.2

done

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
rewrite / block_ps / live / bytes / auxes / pts big_sepL_cons big_sepL_app big_sepL_singleton
done

Owning the bytes xs ++ ys from offset o is owning xs there and ys after them.

549Lemma bytes_app
∀ b o xs ys
bytesb o xs ++ ys ⊣⊢ bytesb o xs ∗ bytesb o + Z.of_natlengthxs ys
Explore proof 2 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b, o :
Z
xs, ys :
listZ
⊢
bytesb o xs ++ ys ⊣⊢ bytesb o xs ∗ bytesb o + lengthxs ys

rewrite / bytes byte_ps_app

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b, o :
Z
xs, ys :
listZ
⊢
ptsbyte_psb o xs ++ byte_psb o + lengthxs ys ⊣⊢ ptsbyte_psb o xs ∗ ptsbyte_psb o + lengthxs ys

apply pts_app

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
rewrite / bytes byte_ps_app
apply pts_app

Owning the slots cs ++ ds from offset o is owning cs there and ds after them.

554Lemma auxes_app
∀ b o cs ds
auxesb o cs ++ ds ⊣⊢ auxesb o cs ∗ auxesb o + Z.of_natlengthcs ds
Explore proof 2 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b, o :
Z
cs, ds :
listcap
⊢
auxesb o cs ++ ds ⊣⊢ auxesb o cs ∗ auxesb o + lengthcs ds

rewrite / auxes aux_ps_app

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b, o :
Z
cs, ds :
listcap
⊢
ptsaux_psb o cs ++ aux_psb o + lengthcs ds ⊣⊢ ptsaux_psb o cs ∗ ptsaux_psb o + lengthcs ds

apply pts_app

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
rewrite / auxes aux_ps_app
apply pts_app

A fresh object's pieces are its life, a zero byte at each offset of its extent and an empty slot at each: a block from offset 0.

559Lemma obj_zero_block
∀ b q
0 ≤ req_extentq
objb q ⊣⊢ liveb mkRegionb b + req_extentq req_kindq Live ∗ bytesb 0 replicateZ.to_natreq_extentq 0 ∗ auxesb 0 replicateZ.to_natreq_extentq CNone
Explore proof 4 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
⊢
0 ≤ req_extentq → objb q ⊣⊢ liveb r_base ≔ b; r_end ≔ b + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live ∗ bytesb 0 replicateZ.to_natreq_extentq 0 ∗ auxesb 0 replicateZ.to_natreq_extentq CNone

intros H

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
H :
0 ≤ req_extentq
⊢
objb q ⊣⊢ liveb r_base ≔ b; r_end ≔ b + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live ∗ bytesb 0 replicateZ.to_natreq_extentq 0 ∗ auxesb 0 replicateZ.to_natreq_extentq CNone

rewrite / obj / obj_ps / live / bytes / auxes byte_ps_replicate aux_ps_replicate Z2Nat.id ; | exact H

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
H :
0 ≤ req_extentq
⊢
ptsPLiveb, VLiver_base ≔ b; r_end ≔ b + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live :: λi : Z ⇒ PByteb i, VByte0 <$> seqZ0 req_extentq ++ λi : Z ⇒ PAuxb i, VAuxCNone <$> seqZ0 req_extentq ⊣⊢ ptsPLiveb, VLiver_base ≔ b; r_end ≔ b + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live ∗ ptsλi : Z ⇒ PByteb i, VByte0 <$> seqZ0 req_extentq ∗ ptsλi : Z ⇒ PAuxb i, VAuxCNone <$> seqZ0 req_extentq

rewrite / pts big_sepL_cons big_sepL_app big_sepL_singleton

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
H :
0 ≤ req_extentq
⊢
pointstoPLiveb, VLiver_base ≔ b; r_end ≔ b + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live.1 DfracOwn1 PLiveb, VLiver_base ≔ b; r_end ≔ b + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live.2 ∗ ∗y∈λi : Z ⇒ PByteb i, VByte0 <$> seqZ0 req_extentqpointstoy.1 DfracOwn1 y.2 ∗ ∗y∈λi : Z ⇒ PAuxb i, VAuxCNone <$> seqZ0 req_extentqpointstoy.1 DfracOwn1 y.2 ⊣⊢ pointstoPLiveb, VLiver_base ≔ b; r_end ≔ b + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live.1 DfracOwn1 PLiveb, VLiver_base ≔ b; r_end ≔ b + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live.2 ∗ ∗lv∈λi : Z ⇒ PByteb i, VByte0 <$> seqZ0 req_extentqpointstolv.1 DfracOwn1 lv.2 ∗ ∗lv∈λi : Z ⇒ PAuxb i, VAuxCNone <$> seqZ0 req_extentqpointstolv.1 DfracOwn1 lv.2

done

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros H
rewrite / obj / obj_ps / live / bytes / auxes byte_ps_replicate aux_ps_replicate Z2Nat.id ; | exact H
rewrite / pts big_sepL_cons big_sepL_app big_sepL_singleton
done

The life of an object and a string's are of different objects: each is owned once.

570Lemma live_string_ne
∀ b reg p b′ reg′ ys
liveb reg −∗ stringp b′ reg′ ys −∗ ⌜b ≠ b′⌝
Explore proof 7 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
reg :
p :
b′ :
Z
reg′ :
ys :
listZ
⊢
liveb reg −∗ stringp b′ reg′ ys −∗ ⌜b ≠ b′⌝

rewrite / live / string / string_ps / pts ! big_sepL_cons

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
reg :
p :
b′ :
Z
reg′ :
ys :
listZ
⊢
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈[ ]pointstoy.1 DfracOwn1 y.2 −∗ ⌜string_okp b′ reg′ ys⌝ ∗ pointstoPLiveb′, VLivereg′.1 DfracOwn1 PLiveb′, VLivereg′.2 ∗ ∗y∈byte_psb′ ptr_addrp − b′ ys ++ 0pointstoy.1 DfracOwn1 y.2 −∗ ⌜b ≠ b′⌝

iIntros [Hl _] [_ [Hs _]]

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
reg :
p :
b′ :
Z
reg′ :
ys :
listZ
Hl :
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2
Hs :
pointstoPLiveb′, VLivereg′.1 DfracOwn1 PLiveb′, VLivereg′.2
∗
⌜b ≠ b′⌝

iDestruct pointsto_ne with Hl Hs as %Hne

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
reg :
p :
b′ :
Z
reg′ :
ys :
listZ
Hne :
PLiveb, VLivereg.1 ≠ PLiveb′, VLivereg′.1
Hl :
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2
Hs :
pointstoPLiveb′, VLivereg′.1 DfracOwn1 PLiveb′, VLivereg′.2
∗
⌜b ≠ b′⌝

iPureIntro

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
reg :
p :
b′ :
Z
reg′ :
ys :
listZ
Hne :
PLiveb, VLivereg.1 ≠ PLiveb′, VLivereg′.1
⊢
b ≠ b′

intros ←

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
reg :
p :
reg′ :
ys :
listZ
Hne :
PLiveb, VLivereg.1 ≠ PLiveb, VLivereg′.1
⊢
False

apply Hne

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
reg :
p :
reg′ :
ys :
listZ
Hne :
PLiveb, VLivereg.1 ≠ PLiveb, VLivereg′.1
⊢
PLiveb, VLivereg.1 = PLiveb, VLivereg′.1

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
rewrite / live / string / string_ps / pts ! big_sepL_cons
iIntros [Hl _] [_ [Hs _]]
iDestruct pointsto_ne with Hl Hs as %Hne
iPureIntro
intros ←
apply Hne
reflexivity

An object's life and its bytes from offset o, a string and its NUL, are that string.

578Lemma block_string
∀ b reg o ys
string_okmkPtrb + o Objb b reg ys
liveb reg −∗ bytesb o ys ++ 0 −∗ stringmkPtrb + o Objb b reg ys
Explore proof 7 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
reg :
o :
Z
ys :
listZ
⊢
string_okptr_addr ≔ b + o; ptr_cap ≔ Objb b reg ys → liveb reg −∗ bytesb o ys ++ 0 −∗ stringptr_addr ≔ b + o; ptr_cap ≔ Objb b reg ys

intros Hok

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
reg :
o :
Z
ys :
listZ
Hok :
string_okptr_addr ≔ b + o; ptr_cap ≔ Objb b reg ys
⊢
liveb reg −∗ bytesb o ys ++ 0 −∗ stringptr_addr ≔ b + o; ptr_cap ≔ Objb b reg ys

rewrite / string / string_ps / live / bytes / pts ! big_sepL_cons big_sepL_nil

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
reg :
o :
Z
ys :
listZ
Hok :
string_okptr_addr ≔ b + o; ptr_cap ≔ Objb b reg ys
⊢
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ emp −∗ ∗lv∈byte_psb o ys ++ 0pointstolv.1 DfracOwn1 lv.2 −∗ ⌜string_okptr_addr ≔ b + o; ptr_cap ≔ Objb b reg ys⌝ ∗ pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈byte_psb ptr_addrptr_addr ≔ b + o; ptr_cap ≔ Objb − b ys ++ 0pointstoy.1 DfracOwn1 y.2

cbn [ ptr_addr ]

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
reg :
o :
Z
ys :
listZ
Hok :
string_okptr_addr ≔ b + o; ptr_cap ≔ Objb b reg ys
⊢
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ emp −∗ ∗lv∈byte_psb o ys ++ 0pointstolv.1 DfracOwn1 lv.2 −∗ ⌜string_okptr_addr ≔ b + o; ptr_cap ≔ Objb b reg ys⌝ ∗ pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈byte_psb b + o − b ys ++ 0pointstoy.1 DfracOwn1 y.2

replace b + o − b with o by lia

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
reg :
o :
Z
ys :
listZ
Hok :
string_okptr_addr ≔ b + o; ptr_cap ≔ Objb b reg ys
⊢
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ emp −∗ ∗lv∈byte_psb o ys ++ 0pointstolv.1 DfracOwn1 lv.2 −∗ ⌜string_okptr_addr ≔ b + o; ptr_cap ≔ Objb b reg ys⌝ ∗ pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈byte_psb o ys ++ 0pointstoy.1 DfracOwn1 y.2

iIntros [Hl _] Hx

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
reg :
o :
Z
ys :
listZ
Hok :
string_okptr_addr ≔ b + o; ptr_cap ≔ Objb b reg ys
Hl :
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2
Hx :
∗lv∈byte_psb o ys ++ 0pointstolv.1 DfracOwn1 lv.2
∗
⌜string_okptr_addr ≔ b + o; ptr_cap ≔ Objb b reg ys⌝ ∗ pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈byte_psb o ys ++ 0pointstoy.1 DfracOwn1 y.2

iSplit ; iPureIntro ; exact Hok |

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
b :
Z
reg :
o :
Z
ys :
listZ
Hok :
string_okptr_addr ≔ b + o; ptr_cap ≔ Objb b reg ys
Hl :
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2
Hx :
∗lv∈byte_psb o ys ++ 0pointstolv.1 DfracOwn1 lv.2
∗
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈byte_psb o ys ++ 0pointstoy.1 DfracOwn1 y.2

iFrame

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hok
rewrite / string / string_ps / live / bytes / pts ! big_sepL_cons big_sepL_nil
cbn [ ptr_addr ]
replace b + o − b with o by lia
iIntros [Hl _] Hx
iSplit ; iPureIntro ; exact Hok |
iFrame

A string lends n of its bytes from its k-th on, before its NUL, as a block, with its object's life, and takes them back.

588Lemma string_window
∀ p b reg ys k n
k + n ≤ lengthys%nat
stringp b reg ys −∗ ⌜string_okp b reg ys⌝ ∗ liveb reg ∗ bytesb ptr_addrp − b + Z.of_natk taken dropk ys ∗ liveb reg −∗ bytesb ptr_addrp − b + Z.of_natk taken dropk ys −∗ stringp b reg ys
Explore proof 22 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
⊢
k + n ≤ lengthys%nat → stringp b reg ys −∗ ⌜string_okp b reg ys⌝ ∗ liveb reg ∗ bytesb ptr_addrp − b + k taken dropk ys ∗ liveb reg −∗ bytesb ptr_addrp − b + k taken dropk ys −∗ stringp b reg ys

intros Hk

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
⊢
stringp b reg ys −∗ ⌜string_okp b reg ys⌝ ∗ liveb reg ∗ bytesb ptr_addrp − b + k taken dropk ys ∗ liveb reg −∗ bytesb ptr_addrp − b + k taken dropk ys −∗ stringp b reg ys

iIntros [%Hok Hs]

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
Hs :
ptsstring_psp b reg ys
∗
⌜string_okp b reg ys⌝ ∗ liveb reg ∗ bytesb ptr_addrp − b + k taken dropk ys ∗ liveb reg −∗ bytesb ptr_addrp − b + k taken dropk ys −∗ stringp b reg ys

assert E : ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
⊢
ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
focused goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
E :
ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
Hs :
ptsstring_psp b reg ys
∗
⌜string_okp b reg ys⌝ ∗ liveb reg ∗ bytesb ptr_addrp − b + k taken dropk ys ∗ liveb reg −∗ bytesb ptr_addrp − b + k taken dropk ys −∗ stringp b reg ys

{rewrite app_assoc app_assoc

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
⊢
ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
E :
ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
Hs :
ptsstring_psp b reg ys
∗
⌜string_okp b reg ys⌝ ∗ liveb reg ∗ bytesb ptr_addrp − b + k taken dropk ys ∗ liveb reg −∗ bytesb ptr_addrp − b + k taken dropk ys −∗ stringp b reg ys

f_equal

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
⊢
ys = takek ys ++ taken dropk ys ++ dropk + n ys
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
E :
ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
Hs :
ptsstring_psp b reg ys
∗
⌜string_okp b reg ys⌝ ∗ liveb reg ∗ bytesb ptr_addrp − b + k taken dropk ys ∗ liveb reg −∗ bytesb ptr_addrp − b + k taken dropk ys −∗ stringp b reg ys

rewrite - { 1 } take_dropk ys

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
⊢
takek ys ++ dropk ys = takek ys ++ taken dropk ys ++ dropk + n ys
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
E :
ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
Hs :
ptsstring_psp b reg ys
∗
⌜string_okp b reg ys⌝ ∗ liveb reg ∗ bytesb ptr_addrp − b + k taken dropk ys ∗ liveb reg −∗ bytesb ptr_addrp − b + k taken dropk ys −∗ stringp b reg ys

rewrite - app_assoc

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
⊢
takek ys ++ dropk ys = takek ys ++ taken dropk ys ++ dropk + n ys
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
E :
ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
Hs :
ptsstring_psp b reg ys
∗
⌜string_okp b reg ys⌝ ∗ liveb reg ∗ bytesb ptr_addrp − b + k taken dropk ys ∗ liveb reg −∗ bytesb ptr_addrp − b + k taken dropk ys −∗ stringp b reg ys

f_equal

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
⊢
dropk ys = taken dropk ys ++ dropk + n ys
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
E :
ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
Hs :
ptsstring_psp b reg ys
∗
⌜string_okp b reg ys⌝ ∗ liveb reg ∗ bytesb ptr_addrp − b + k taken dropk ys ∗ liveb reg −∗ bytesb ptr_addrp − b + k taken dropk ys −∗ stringp b reg ys

rewrite - { 1 } take_dropn dropk ys drop_drop

2 open

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
⊢
taken dropk ys ++ dropk + n ys = taken dropk ys ++ dropk + n ys
deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
E :
ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
Hs :
ptsstring_psp b reg ys
∗
⌜string_okp b reg ys⌝ ∗ liveb reg ∗ bytesb ptr_addrp − b + k taken dropk ys ∗ liveb reg −∗ bytesb ptr_addrp − b + k taken dropk ys −∗ stringp b reg ys

reflexivity

deferred goal
hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
E :
ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
Hs :
ptsstring_psp b reg ys
∗
⌜string_okp b reg ys⌝ ∗ liveb reg ∗ bytesb ptr_addrp − b + k taken dropk ys ∗ liveb reg −∗ bytesb ptr_addrp − b + k taken dropk ys −∗ stringp b reg ys

assert Lk : lengthtakek ys = k by rewrite length_take ; lia

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
E :
ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
Lk :
lengthtakek ys = k
Hs :
ptsstring_psp b reg ys
∗
⌜string_okp b reg ys⌝ ∗ liveb reg ∗ bytesb ptr_addrp − b + k taken dropk ys ∗ liveb reg −∗ bytesb ptr_addrp − b + k taken dropk ys −∗ stringp b reg ys

rewrite / string_ps E ! byte_ps_app Lk

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
E :
ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
Lk :
lengthtakek ys = k
Hs :
ptsPLiveb, VLivereg :: byte_psb ptr_addrp − b takek ys ++ byte_psb ptr_addrp − b + k taken dropk ys ++ byte_psb ptr_addrp − b + k + lengthtaken dropk ys dropk + n ys ++ byte_psb ptr_addrp − b + k + lengthtaken dropk ys + lengthdropk + n ys 0
∗
⌜string_okp b reg ys⌝ ∗ liveb reg ∗ bytesb ptr_addrp − b + k taken dropk ys ∗ liveb reg −∗ bytesb ptr_addrp − b + k taken dropk ys −∗ stringp b reg ys

rewrite / live / bytes / pts big_sepL_cons ! big_sepL_app big_sepL_singleton

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
E :
ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
Lk :
lengthtakek ys = k
Hs :
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈byte_psb ptr_addrp − b takek yspointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrp − b + k taken dropk yspointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrp − b + k + lengthtaken dropk ys dropk + n yspointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrp − b + k + lengthtaken dropk ys + lengthdropk + n ys 0pointstoy.1 DfracOwn1 y.2
∗
⌜string_okp b reg ys⌝ ∗ pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗lv∈byte_psb ptr_addrp − b + k taken dropk yspointstolv.1 DfracOwn1 lv.2 ∗ pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 −∗ ∗lv∈byte_psb ptr_addrp − b + k taken dropk yspointstolv.1 DfracOwn1 lv.2 −∗ stringp b reg ys

iDestruct Hs as (Hl & Hpre & Hw & Hpost)

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
E :
ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
Lk :
lengthtakek ys = k
Hl :
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2
Hpre :
∗y∈byte_psb ptr_addrp − b takek yspointstoy.1 DfracOwn1 y.2
Hw :
∗y∈byte_psb ptr_addrp − b + k taken dropk yspointstoy.1 DfracOwn1 y.2
Hpost :
∗y∈byte_psb ptr_addrp − b + k + lengthtaken dropk ys dropk + n yspointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrp − b + k + lengthtaken dropk ys + lengthdropk + n ys 0pointstoy.1 DfracOwn1 y.2
∗
⌜string_okp b reg ys⌝ ∗ pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗lv∈byte_psb ptr_addrp − b + k taken dropk yspointstolv.1 DfracOwn1 lv.2 ∗ pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 −∗ ∗lv∈byte_psb ptr_addrp − b + k taken dropk yspointstolv.1 DfracOwn1 lv.2 −∗ stringp b reg ys

iSplit ; done |

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
E :
ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
Lk :
lengthtakek ys = k
Hl :
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2
Hpre :
∗y∈byte_psb ptr_addrp − b takek yspointstoy.1 DfracOwn1 y.2
Hw :
∗y∈byte_psb ptr_addrp − b + k taken dropk yspointstoy.1 DfracOwn1 y.2
Hpost :
∗y∈byte_psb ptr_addrp − b + k + lengthtaken dropk ys dropk + n yspointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrp − b + k + lengthtaken dropk ys + lengthdropk + n ys 0pointstoy.1 DfracOwn1 y.2
∗
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗lv∈byte_psb ptr_addrp − b + k taken dropk yspointstolv.1 DfracOwn1 lv.2 ∗ pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 −∗ ∗lv∈byte_psb ptr_addrp − b + k taken dropk yspointstolv.1 DfracOwn1 lv.2 −∗ stringp b reg ys

iFrame Hl Hw

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
E :
ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
Lk :
lengthtakek ys = k
Hpre :
∗y∈byte_psb ptr_addrp − b takek yspointstoy.1 DfracOwn1 y.2
Hpost :
∗y∈byte_psb ptr_addrp − b + k + lengthtaken dropk ys dropk + n yspointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrp − b + k + lengthtaken dropk ys + lengthdropk + n ys 0pointstoy.1 DfracOwn1 y.2
∗
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 −∗ ∗lv∈byte_psb ptr_addrp − b + k taken dropk yspointstolv.1 DfracOwn1 lv.2 −∗ stringp b reg ys

iIntros Hl Hw

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
E :
ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
Lk :
lengthtakek ys = k
Hpre :
∗y∈byte_psb ptr_addrp − b takek yspointstoy.1 DfracOwn1 y.2
Hpost :
∗y∈byte_psb ptr_addrp − b + k + lengthtaken dropk ys dropk + n yspointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrp − b + k + lengthtaken dropk ys + lengthdropk + n ys 0pointstoy.1 DfracOwn1 y.2
Hl :
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2
Hw :
∗lv∈byte_psb ptr_addrp − b + k taken dropk yspointstolv.1 DfracOwn1 lv.2
∗
stringp b reg ys

rewrite / string

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
E :
ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
Lk :
lengthtakek ys = k
Hpre :
∗y∈byte_psb ptr_addrp − b takek yspointstoy.1 DfracOwn1 y.2
Hpost :
∗y∈byte_psb ptr_addrp − b + k + lengthtaken dropk ys dropk + n yspointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrp − b + k + lengthtaken dropk ys + lengthdropk + n ys 0pointstoy.1 DfracOwn1 y.2
Hl :
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2
Hw :
∗lv∈byte_psb ptr_addrp − b + k taken dropk yspointstolv.1 DfracOwn1 lv.2
∗
⌜string_okp b reg ys⌝ ∗ ptsstring_psp b reg ys

iSplit ; done |

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
E :
ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
Lk :
lengthtakek ys = k
Hpre :
∗y∈byte_psb ptr_addrp − b takek yspointstoy.1 DfracOwn1 y.2
Hpost :
∗y∈byte_psb ptr_addrp − b + k + lengthtaken dropk ys dropk + n yspointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrp − b + k + lengthtaken dropk ys + lengthdropk + n ys 0pointstoy.1 DfracOwn1 y.2
Hl :
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2
Hw :
∗lv∈byte_psb ptr_addrp − b + k taken dropk yspointstolv.1 DfracOwn1 lv.2
∗
ptsstring_psp b reg ys

rewrite / string_ps E ! byte_ps_app Lk

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
E :
ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
Lk :
lengthtakek ys = k
Hpre :
∗y∈byte_psb ptr_addrp − b takek yspointstoy.1 DfracOwn1 y.2
Hpost :
∗y∈byte_psb ptr_addrp − b + k + lengthtaken dropk ys dropk + n yspointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrp − b + k + lengthtaken dropk ys + lengthdropk + n ys 0pointstoy.1 DfracOwn1 y.2
Hl :
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2
Hw :
∗lv∈byte_psb ptr_addrp − b + k taken dropk yspointstolv.1 DfracOwn1 lv.2
∗
ptsPLiveb, VLivereg :: byte_psb ptr_addrp − b takek ys ++ byte_psb ptr_addrp − b + k taken dropk ys ++ byte_psb ptr_addrp − b + k + lengthtaken dropk ys dropk + n ys ++ byte_psb ptr_addrp − b + k + lengthtaken dropk ys + lengthdropk + n ys 0

rewrite / pts big_sepL_cons ! big_sepL_app

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
p :
b :
Z
reg :
ys :
listZ
k, n :
nat
Hk :
k + n ≤ lengthys%nat
Hok :
string_okp b reg ys
E :
ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
Lk :
lengthtakek ys = k
Hpre :
∗y∈byte_psb ptr_addrp − b takek yspointstoy.1 DfracOwn1 y.2
Hpost :
∗y∈byte_psb ptr_addrp − b + k + lengthtaken dropk ys dropk + n yspointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrp − b + k + lengthtaken dropk ys + lengthdropk + n ys 0pointstoy.1 DfracOwn1 y.2
Hl :
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2
Hw :
∗lv∈byte_psb ptr_addrp − b + k taken dropk yspointstolv.1 DfracOwn1 lv.2
∗
pointstoPLiveb, VLivereg.1 DfracOwn1 PLiveb, VLivereg.2 ∗ ∗y∈byte_psb ptr_addrp − b takek yspointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrp − b + k taken dropk yspointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrp − b + k + lengthtaken dropk ys dropk + n yspointstoy.1 DfracOwn1 y.2 ∗ ∗y∈byte_psb ptr_addrp − b + k + lengthtaken dropk ys + lengthdropk + n ys 0pointstoy.1 DfracOwn1 y.2

iFrame

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hk
iIntros [%Hok Hs]
assert E : ys ++ 0 = takek ys ++ taken dropk ys ++ dropk + n ys ++ 0
{rewrite app_assoc app_assoc
f_equal
rewrite - { 1 } take_dropk ys
rewrite - app_assoc
f_equal
rewrite - { 1 } take_dropn dropk ys drop_drop
reflexivity
assert Lk : lengthtakek ys = k by rewrite length_take ; lia
rewrite / string_ps E ! byte_ps_app Lk
rewrite / live / bytes / pts big_sepL_cons ! big_sepL_app big_sepL_singleton
iDestruct Hs as (Hl & Hpre & Hw & Hpost)
iSplit ; done |
iFrame Hl Hw
iIntros Hl Hw
rewrite / string
iSplit ; done |
rewrite / string_ps E ! byte_ps_app Lk
rewrite / pts big_sepL_cons ! big_sepL_app
iFrame
606Section calls
607Context world : Type registry : name → optioncontractworld wi : mem → world → gmappiece pval → Prop `{!SafepointStablewi} ge : genv

The Iris instance of the registry and wi.

611Instance mem_irisGS: irisGS_genhlc nanofil_langregistry ge Σ ≔
nanofil_irisGSregistry wi ge

The expressions of the language.

615Notation mexpr ≔ language.exprnanofil_langregistry ge

A raw store of the 32-bit int y, which v reads as, through the proven pointer p, which a reads as and which addresses offset o of the live object b at offset off, over the four bytes xs there, where the store keeps the world interpretation: they are now y's four little-endian bytes.

622Lemma wp_raw_store_w
∀ f e ls l off v a rest j p b reg o xs y Φ
value_xge e W v = SomeWInty
value_xge e A a = SomeWPtrp
raw_addressptr_addrp off = b + o
lengthxs = 4%nat
∀m wd h, ∀l v, l, v ∈ PLiveb, VLivereg :: byte_psb o xs → h !! l = Somev → wim wd h → wistore_bytesm b + o 4 y wd overwritePLiveb, VLivereg :: byte_psb o le_bytesy 4 h
liveb reg −∗ bytesb o xs −∗ ▷liveb reg −∗ bytesb o le_bytesy 4 −∗ WPERunmkFramef e ls None Execl rest j : mexpr {Φ} −∗ WPERunmkFramef e ls None Execl RawStoreWw off v a :: rest j : mexpr {Φ}
Proof 44 steps Qed
intros Hv Ha Hp Hoff Hlen Hwi
iIntros Hl Hx HK
iApply wp_write_ _ _ PLiveb, VLivereg :: byte_psb o xs PLiveb, VLivereg :: byte_psb o le_bytesy 4 _ _ [ ] λm ⇒ store_bytesm b + o 4 y with [Hl Hx] [HK] ; cbn [ fmap list_fmap fst ] ; rewrite ! byte_ps_keys length_le_bytes Hlen ; reflexivity | | exact Hwi | rewrite / live / bytes / pts ! big_sepL_cons big_sepL_nil ; iFrame ; iDestruct Hl as [$ _] |
–intros m fuel Hf & Hd & _
cbn [ all_agree agree_piece fst snd ] in Hf
destruct Hf as Hlv Hx
destruct store_afterm b reg o xs y Hd Hlv Hx as Hag Hfr
rewrite Hlen in Hag Hfr
cbn in Hag , Hfr
assert Hb : ∀i, i < 4%nat → 0 ≤ o + Z.of_nati ∧ b + o + Z.of_nati < r_endreg
{intros i Hi
rewrite <- Hlen in Hi
destruct lookup_lt_is_Some_2xs i Hi as x Hxi
destruct byte_ps_agree_ _ _ _ _ _ _ Hlv Hx Hxi as _ & H1 & H2
lia
destruct Hb0%nat ltac:lia as H0 _
destruct Hb3%nat ltac:lia as _ H3
cbn in H0 , H3
split ; | split ; reflexivity | split ; | split
+apply rule_raw_store with vk := W x := WInty p := p ; reflexivity | exact Hv | exact Ha |
rewrite Hoff
rewrite Hp
rewrite access_obj_ _ reg ; reflexivity | exact proj1Hlv | lia | lia | apply Z.mod_1_r
intros a′ Ha′
exists b, reg
split ; exact proj1Hlv | lia
+cbn [ all_agree agree_piece fst snd ]
split ; exact Hlv | exact Hag
+intros l′ v′ Hn Ha′
apply Hfr ; | exact Ha'
intros Hin
apply Hn
cbn [ fmap list_fmap fst ]
apply elem_of_cons
right
rewrite byte_ps_keys Hlen in Hin
exact Hin
–iNext
iIntros H
iDestruct pts_appPLiveb, VLivereg byte_psb o le_bytesy 4 with H as [Hl Hx]
iApply HK with Hl Hx

memset's triple, from memset_contract: owning the life of the object b, at a multiple of 8, with the region reg, and the block of the bytes xs and the slots cs from the 8-aligned offset o, inside its bounds, where vp reads as the block's pointer, vc as the int c and vn as its length, and where the fill keeps the world interpretation: the call fills the bytes with c's low byte, clears the slots it touches, and binds d to the block's pointer.

664Lemma wp_memset
∀ f e ls lab d vp vc vn rest j b reg o xs cs c Φ
registryTAtom"memset" = Somememset_contractworld
find_fnge TAtom"memset" = None
lookupTAtom"memset" ge_globalsge = None
arg_xge e ArgP vp = SomeWPtrmkPtrb + o Objb
arg_xge e ArgW vc = SomeWIntc
arg_xge e ArgL vn = SomeWIntZ.of_natlengthxs
0 ≤ c < 2 ^ 32
b mod 8 = 0
o mod 8 = 0
0 ≤ o
b + o + Z.of_natlengthxs ≤ r_endreg
lengthcs = lengthxs
∀m m′ wd h, memset_resultm mkPtrb + o Objb c Z.of_natlengthxs m′ → ∀l v, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o replicatelengthxs c mod 256 clear_slotso cs h
liveb reg −∗ bytesb o xs −∗ auxesb o cs −∗ ▷liveb reg −∗ bytesb o replicatelengthxs c mod 256 −∗ auxesb o clear_slotso cs −∗ WPERunmkFramef putd WPtrmkPtrb + o Objb e ls None Execlab rest j : mexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd P GlobalTAtom"memset" ArgP vp; ArgW vc; ArgL vn :: rest j : mexpr {Φ}
Proof 75 steps Qed
intros Hreg Hfn Hdata Hp Hc Hn Hc32 Hb8 Ho8 Ho Hend Hlen Hwi
iIntros Hl Hx Hcs HK
iDestruct block_ptsb reg o xs cs with [$Hl $Hx $Hcs] as Hps
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ memset_contractworld WPtrmkPtrb + o Objb; WIntc; WIntZ.of_natlengthxs ptsblock_psb reg o xs cs with Hps [HK] ; done | done | done | done | cbn [ map_option ] ; rewrite Hp Hc Hn ; done | | |
–split ; right ; eexists ; reflexivity | do 3 eexists ; reflexivity
–iIntros σ Hσ Hps
iDestruct pts_facts with Hσ Hps as %Ha & _ & Hfit
iPureIntro
destruct Ha as E L _
cbn [ fst snd ] in E , L
destruct Hfitb reg E as Hb0 Hfit′
eexists _, c, _
split ; reflexivity |
split ; exact Hc32 |
split ; lia |
split
split ; lia |
exists b, reg
split ; reflexivity |
split ; exact E |
split ; exact L |
apply access_obj_ _ reg ; exact E | lia | lia | apply Z.mod_1_r
+right
exists b
auto
–iNext
iIntros σ trace values s′ m′ w′ Hinv (%h & Hh & %Hf) Hps
destruct Hf as Ha & Hd & Hr & Hw
destruct M.E.memset_invocation_ _ _ _ _ _ _ _ _ _ _ _ Hinv as _ & → & p′ & c′ & n′ & Hx & _ & Hres & He
injection Hx as ← ← ←
injection He as →
iDestruct pts_lookup with Hh Hps as %Hlk
assert Hold : all_agreels_memσ block_psb reg o xs cs
intros l v Hin
exact Hal v Hlkl v Hin
destruct Hold as Hlv Hold
cbn [ agree_piece fst snd ] in Hlv
destruct fill_afterls_memσ m' b reg o xs cs c Hd Hlv Hb8 Ho8 Hlen Hold Hres as Hnew Hfr
destruct M.E.invoke_prefix_ _ _ _ _ _ _ _ _ _ _ _ _ Hinv as born & Hpre
destruct M.E.prefix_preserve_ _ _ _ _ _ _ _ _ _ _ Hpre Hr as Hr′ _
pose proof Hres as Hregs & _ & _
iMod pts_update_ _ block_psb reg o replicatelengthxs c mod 256 clear_slotso cs with Hh Hps as [Hh Hps]
{apply block_ps_keys ; apply length_replicate | apply length_clear_slots
iModIntro
iExists _
iSplit ; iPureIntro ; reflexivity |
iSplitL Hh
+iExists _
iFrame Hh
iPureIntro
split ; | split ; | split
∗intros l v Hl′
destruct lookup_overwrite_ _ _ _ Hl' as Hin | Hnk Hh
--apply elem_of_cons in Hin as Hin | Hin
++injection Hin as → →
cbn [ agree_piece ]
exact live_at_regions_ _ _ _ Hregs Hlv
++exact all_agree_elem_ _ _ _ Hnew Hin
--apply Hfr ; | exact Hal v Hh
intros Hk
apply Hnk
rewrite block_ps_keysb reg o xs cs ; | apply length_replicate | apply length_clear_slots
cbn [ fmap list_fmap fst block_ps ]
right
exact Hk
∗exact live_disjoint_regions_ _ Hregs Hd
∗exact Hr'
∗exact Hwi_ _ _ _ Hres Hlk Hw
+rewrite block_pts
iDestruct Hps as (Hl & Hx & Hcs)
iApply HK with Hl Hx Hcs

malloc's triple, from malloc_contract: for a size n that v reads as, where an allocation keeps the world interpretation, the call binds d to the base pointer of a fresh heap object of n bytes, rounded up to 16, whose pieces it owns (obj). The selected malloc never returns null: a refusal is a resource ending, which is not a return, so the triple has no null case.

734Lemma wp_malloc
∀ f e ls lab d v rest j n Φ
registryTAtom"malloc" = Somemalloc_contractworld
find_fnge TAtom"malloc" = None
lookupTAtom"malloc" ge_globalsge = None
arg_xge e ArgL v = SomeWIntn
0 ≤ n < 2 ^ 64
∀m wd h base, freshm heap_req16 n base → wim wd h → wiallocatedm heap_req16 n base wd overwriteobj_psbase heap_req16 n h
▷∀base, ⌜0 < base ∧ base mod 16 = 0 ∧ base + req_extentheap_req16 n ≤ 2 ^ 48 ∧ n ≤ max_allocation_size⌝ −∗ objbase heap_req16 n −∗ WPERunmkFramef putd WPtrmkPtrbase Objbase e ls None Execlab rest j : mexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd P GlobalTAtom"malloc" ArgL v :: rest j : mexpr {Φ}
Proof 52 steps Qed
intros Hreg Hfn Hdata Hv Hn Hwi
iIntros HK
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ malloc_contractworld WIntn True%I with [//] [HK] ; done | done | done | done | cbn [ map_option ] ; rewrite Hv ; done | | |
–split ; right ; eexists ; reflexivity | eexists ; reflexivity
–iIntros σ _ _
iPureIntro
exists n
auto
–iNext
iIntros σ trace values s′ m′ w′ Hinv (%h & Hh & %Hf) _
destruct Hf as Ha & Hd & Hr & Hw
destruct M.E.invoke_prefix_ _ _ _ _ _ _ _ _ _ _ _ _ Hinv as born & Hp
destruct M.E.prefix_preserve_ _ _ _ _ _ _ _ _ _ _ Hp Hr as Hr′ _
destruct M.E.malloc_invocation_ _ _ _ _ _ _ _ _ _ _ _ Hinv as _ & → & n′ & Hx & _ & base & Hres & He | why & born′ & He & _ ; | discriminate He
injection Hx as ←
injection He as →
destruct Hres as Hmax & Hfr & →
assert Hex : 0 ≤ req_extentheap_req16 n
{cbn
apply Z.mul_nonneg_nonneg ; apply Z.div_pos | ; lia
pose proof Hfr as Hpos & Hmod & _ & Hnone & _
iMod pts_alloch obj_psbase heap_req16 n with Hh as [Hh Hps]
{intros l′ v′ Hin
destruct h !! l' as v0 | eqn: E ; | reflexivity
exfalso
pose proof agree_piece_registered_ _ _ obj_ps_mem_ _ _ _ Hin Hal' v0 E as Hreg′
rewrite obj_ps_id_ _ _ _ Hin in Hreg'
exact Hreg'Hnone
iModIntro
iExists _
iSplit ; iPureIntro ; reflexivity |
iSplitL Hh
+iExists _
iFrame Hh
iPureIntro
split ; | split ; | split
∗intros l′ v′ Hl
destruct lookup_overwrite_ _ _ _ Hl as Hin | _ Hh
--exact obj_ps_agree_ _ _ _ _ Hfr Hex Hin
--exact agree_piece_allocated_ _ _ _ _ Hnone Hal' v' Hh
∗exact live_disjoint_allocated_ _ _ Hd Hfr Hex
∗exact Hr'
∗exact Hwi_ _ _ _ Hfr Hw
+iApply HK with [%] Hps
split ; exact Hpos |
split ; exact Hmod |
split ; | exact proj2Hmax
destruct R.address_space_ _ Hr' base mkRegionbase base + req_extentheap_req16 n req_kindheap_req16 n Live as _ Hend ; rewrite object_region_allocated Z.eqb_refl ; reflexivity |
cbn [ r_end ] in Hend
exact Hend

memcpy's triple, from memcpy_contract: owning the destination block (the bytes xs and slots cs from offset o of the live object b) and the source block (the bytes ys and slots ds from offset o' of the live object b', another object, through the capability c', read-write or read-only), of the same length, all at multiples of 8, where vd, vs and vn read as their pointers and length, and where the copy keeps the world interpretation: the destination's bytes become ys, its slots copy_slots, and d is bound to the destination pointer. The source is handed back unchanged.

794Lemma wp_memcpy
∀ f e ls lab d vd vs vn rest j b reg o xs cs b′ reg′ o′ c′ ys ds Φ
registryTAtom"memcpy" = Somememcpy_contractworld
find_fnge TAtom"memcpy" = None
lookupTAtom"memcpy" ge_globalsge = None
arg_xge e ArgP vd = SomeWPtrmkPtrb + o Objb
arg_xge e ArgP vs = SomeWPtrmkPtrb′ + o′ c′
c′ = Objb′ ∨ c′ = Rob′
arg_xge e ArgL vn = SomeWIntZ.of_natlengthxs
b ≠ b′
b mod 8 = 0
o mod 8 = 0
b′ mod 8 = 0
o′ mod 8 = 0
0 ≤ o
0 ≤ o′
b + o + Z.of_natlengthxs ≤ r_endreg
b′ + o′ + Z.of_natlengthxs ≤ r_endreg′
lengthys = lengthxs
lengthcs = lengthxs
lengthds = lengthxs
Forallλy ⇒ 0 ≤ y < 256 ys
∀m m′ wd h, copy_resultm mkPtrb + o Objb mkPtrb′ + o′ c′ Z.of_natlengthxs m′ → ∀l v, l, v ∈ block_psb reg o xs cs → h !! l = Somev → wim wd h → wim′ wd overwriteblock_psb reg o ys copy_slotsZ.of_natlengthxs ds cs h
liveb reg −∗ bytesb o xs −∗ auxesb o cs −∗ liveb′ reg′ −∗ bytesb′ o′ ys −∗ auxesb′ o′ ds −∗ ▷liveb reg −∗ bytesb o ys −∗ auxesb o copy_slotsZ.of_natlengthxs ds cs −∗ liveb′ reg′ −∗ bytesb′ o′ ys −∗ auxesb′ o′ ds −∗ WPERunmkFramef putd WPtrmkPtrb + o Objb e ls None Execlab rest j : mexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd P GlobalTAtom"memcpy" ArgP vd; ArgP vs; ArgL vn :: rest j : mexpr {Φ}
Proof 108 steps Qed
intros Hreg Hfn Hdata Hpd Hps Hc′ Hn Hne Hb8 Ho8 Hb8′ Ho8′ Ho Ho′ Hend Hend′ Hly Hlc Hld Hy Hwi
iIntros Hl Hx Hcs Hl′ Hy Hds HK
iDestruct block_ptsb reg o xs cs with [$Hl $Hx $Hcs] as Hdst
iDestruct block_ptsb' reg' o' ys ds with [$Hl′ $Hy $Hds] as Hsrc
iCombine Hdst Hsrc as Hps
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ memcpy_contractworld WPtrmkPtrb + o Objb; WPtrmkPtrb' + o' c'; WIntZ.of_natlengthxs ptsblock_psb reg o xs cs ∗ ptsblock_psb' reg' o' ys ds with Hps [HK] ; done | done | done | done | cbn [ map_option ] ; rewrite Hpd Hps Hn ; done | | |
–split ; right ; eexists ; reflexivity | exists vd, vs, vn ; reflexivity
–iIntros σ Hσ [Hdst Hsrc]
iDestruct pts_facts with Hσ Hdst as %Ha & Hd & Hfit
iDestruct pts_facts with Hσ Hsrc as %Ha′ & _ & _
iPureIntro
destruct Ha as E L _
destruct Ha' as E′ L′ Hsrc
cbn [ fst snd ] in E , L , E' , L'
apply all_agree_app in Hsrc as Hys _
destruct Hfitb reg E as Hb0 Hfit′
destruct Hfitb' reg' E' as Hb0′ Hfit′′
eexists _, _, _
split ; reflexivity |
split ; | split ; | split
+split ; lia |
split ; lia |
split
∗unfold writable_span
split ; lia |
exists b, reg
split ; reflexivity |
split ; exact E |
split ; exact L |
apply access_obj_ _ reg ; exact E | lia | lia | apply Z.mod_1_r
∗right
exists b
auto
+split ; lia |
split ; exists b', reg' ; auto |
split
∗apply access_read_ b' reg' ; exact Hc' | exact E' | cbn ; lia | cbn ; lia | apply Z.mod_1_r
∗intros i Hi
cbn [ ptr_addr ]
destruct lookup_lt_is_Some_2ys Z.to_nati ltac:lia as y Hyi
destruct byte_ps_agree_ _ _ _ _ _ _ conjE' L' Hys Hyi as Hv & _ & _
replace b' + o' + i with b' + o' + Z.of_natZ.to_nati by lia
rewrite Hv
exact Forall_lookup_1_ _ _ _ Hy Hyi
+right
exists b'
auto
+right
right
cbn [ ptr_addr ]
destruct Hdb reg b' reg' conjE L conjE' L' Hne ; left | right ; lia
–iNext
iIntros σ trace values s′ m′ w′ Hinv (%h & Hh & %Hf) [Hdst Hsrc]
destruct Hf as Ha & Hd & Hr & Hw
destruct M.E.copy_invocation_ _ _ _ _ _ _ _ _ _ _ _ _ _ Hinv as _ & → & d′ & s0 & n′ & Hx & _ & Hres & He
injection Hx as ← ← ←
injection He as →
iDestruct pts_lookup with Hh Hdst as %Hlk
iDestruct pts_lookup with Hh Hsrc as %Hlk′
assert Hold : all_agreels_memσ block_psb reg o xs cs
intros l v Hin
exact Hal v Hlkl v Hin
assert Hold′ : all_agreels_memσ block_psb' reg' o' ys ds
intros l v Hin
exact Hal v Hlk'l v Hin
destruct Hold as Hlv Hold
destruct Hold' as Hlv′ Hold′
cbn [ agree_piece fst snd ] in Hlv , Hlv'
destruct copy_afterls_memσ m' b reg o xs cs b' reg' o' ys ds c' Hd Hlv Hlv' Hb8 Ho8 Hb8' Ho8' Hly Hlc Hld Hold Hold' Hres as Hnew Hfr
destruct M.E.invoke_prefix_ _ _ _ _ _ _ _ _ _ _ _ _ Hinv as born & Hpre
destruct M.E.prefix_preserve_ _ _ _ _ _ _ _ _ _ _ Hpre Hr as Hr′ _
pose proof Hres as Hregs & _ & _
assert Hk : block_psb reg o ys copy_slotsZ.of_natlengthxs ds cs.*1 = block_psb reg o xs cs.*1
{apply block_ps_keys ; exact Hly | rewrite length_copy_slots ; lia
iMod pts_update_ _ block_psb reg o ys copy_slotsZ.of_natlengthxs ds cs with Hh Hdst as [Hh Hdst] ; exact Hk |
iModIntro
iExists _
iSplit ; iPureIntro ; reflexivity |
iSplitL Hh
+iExists _
iFrame Hh
iPureIntro
split ; | split ; | split
∗intros l v Hl′
destruct lookup_overwrite_ _ _ _ Hl' as Hin | Hnk Hh
--apply elem_of_cons in Hin as Hin | Hin
++injection Hin as → →
cbn [ agree_piece ]
exact live_at_regions_ _ _ _ Hregs Hlv
++exact all_agree_elem_ _ _ _ Hnew Hin
--apply Hfr ; | exact Hal v Hh
intros Hk′
apply Hnk
rewrite Hk
cbn [ fmap list_fmap fst block_ps ]
right
exact Hk'
∗exact live_disjoint_regions_ _ Hregs Hd
∗exact Hr'
∗exact Hwi_ _ _ _ Hres Hlk Hw
+rewrite ! block_pts
iDestruct Hdst as (Hl & Hx & Hcs)
iDestruct Hsrc as (Hl′ & Hy & Hds)
iApply HK with Hl Hx Hcs Hl′ Hy Hds

strdup's triple, from strdup_contract: owning the string at p, which v reads as, in an object at a multiple of 8, the call binds d to the base pointer of a fresh heap object holding a copy of the string, which it owns as a string (its life and the copied bytes; the fresh object's other bytes and its aux slots stay unowned), and hands the original back. A refusal is a resource ending.

889Lemma wp_strdup
∀ f e ls lab d v rest j p b reg bytes Φ
registryTAtom"strdup" = Somestrdup_contractworld
find_fnge TAtom"strdup" = None
lookupTAtom"strdup" ge_globalsge = None
arg_xge e ArgP v = SomeWPtrp
b mod 8 = 0
∀m m′ wd h base k, strdup_resultm p k base m′ → wim wd h → wim′ wd overwritestring_psmkPtrbase Objbase base mkRegionbase base + req_extentheap_req16 k Heap Live bytes h
stringp b reg bytes −∗ ▷∀base reg′, stringp b reg bytes −∗ stringmkPtrbase Objbase base reg′ bytes −∗ WPERunmkFramef putd WPtrmkPtrbase Objbase e ls None Execlab rest j : mexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd P GlobalTAtom"strdup" ArgP v :: rest j : mexpr {Φ}
Proof 131 steps Qed
intros Hreg Hfn Hdata Hv Hb8 Hwi
iIntros Hs HK
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ strdup_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 _
iDestruct Hs as [%Hok _]
iPureIntro
destruct Hok as Hc & _
exists p, Z.of_natlengthbytes
split ; reflexivity |
split ; exact Ht |
exists b
auto
–iNext
iIntros σ trace values s′ m′ w′ Hinv (%h & Hh & %Hf) [%Hok Hs]
destruct Hf as Ha & Hd & Hr & Hw
iDestruct pts_lookup with Hh Hs as %Hlk
assert Hold : all_agreels_memσ string_psp b reg bytes
intros l v′ Hin
exact Hal v' Hlkl v' Hin
pose proof string_terminated_ _ _ _ _ Hok Hold as Ht
pose proof string_bytes_ _ _ _ _ Hok Hold as Hbs
destruct M.E.invoke_prefix_ _ _ _ _ _ _ _ _ _ _ _ _ Hinv as born & Hp
destruct M.E.prefix_preserve_ _ _ _ _ _ _ _ _ _ _ Hp Hr as Hr′ _
destruct M.E.strdup_invocation_ _ _ _ _ _ _ _ _ _ _ _ Hinv as _ & → & p′ & k & Hx & Hk & _ & base & Hres & He | why & born′ & He & _ ; | discriminate He
injection Hx as ←
injection He as →
rewrite <- terminated_length_unique_ _ _ _ Ht Hk in Hres
set n := Z.of_natlengthbytes in *
pose proof malloc_extentn + 1 ltac:unfold n ; lia as Hext
assert Hn0 : 0 ≤ n by unfold n ; lia
set q := heap_req16 n + 1 in *
set reg′ := mkRegionbase base + req_extentq Heap Live
destruct Hres as Hmax & Hfr & _ Hcopy
pose proof Hfr as Hpos & Hmod & _ & Hnone & _
pose proof Hcopy as Hregs & Hbytes & Haux & Hcb & _
set m1 := allocatedls_memσ q base in *
assert Hl1 : live_atm1 base reg'
{split ; | reflexivity
unfold m1
rewrite object_region_allocated Z.eqb_refl
reflexivity
assert Hd1 : live_disjointm1
{apply live_disjoint_allocated ; exact Hd | exact Hfr | lia
assert Hout : ∀a, ¬base ≤ a < r_endreg' → m_bytesm' a = m_bytesm1 a ∧ m_auxm' a = m_auxm1 a
{intros a Ha′
cbn [ r_end reg' ] in Ha'
split
–apply Hbytes
cbn
lia
–apply Haux
destruct memset_touched_ _ a eqn: Ht' ; | reflexivity
exfalso
apply memset_touched_spec in Ht' as _ & Ha8 & Hhi & Hlo
cbn [ ptr_addr ] in Hhi , Hlo
assert Hb16 : base mod 8 = 0 by exact fresh_heap_aligned8_ _ _ Hfr
pose proof Z.div_moda 8 ltac:lia
pose proof Z.div_modbase 8 ltac:lia
lia
iMod pts_alloch string_psmkPtrbase Objbase base reg' bytes with Hh as [Hh Hnew]
{intros l′ v′ Hin
destruct h !! l' as v0 | eqn: E ; | reflexivity
exfalso
pose proof agree_piece_registered_ _ _ string_ps_mem_ _ _ _ _ _ Hin Hal' v0 E as Hreg′
rewrite string_ps_id_ _ _ _ _ _ Hin in Hreg'
exact Hreg'Hnone
iModIntro
iExists _
iSplit ; iPureIntro ; reflexivity |
iSplitL Hh
+iExists _
iFrame Hh
iPureIntro
split ; | split ; | split
∗intros l′ v′ Hl
destruct lookup_overwrite_ _ _ _ Hl as Hin | _ Hh
--apply elem_of_cons in Hin as Hin | Hin
++injection Hin as → →
cbn [ agree_piece ]
unfold live_at
rewrite Hregs
exact Hl1
++cbn [ ptr_addr ] in Hin
rewrite Z.sub_diag in Hin
apply byte_ps_elem in Hin as i & x & Hxi & → & →
cbn [ agree_piece ]
assert Hi : i ≤ lengthbytes%nat
{apply lookup_lt_Some in Hxi
rewrite length_app in Hxi
cbn in Hxi
lia
split ; unfold registered ; rewrite Hregs ; destruct Hl1 as E _ ; rewrite E ; discriminate |
intros reg0 E L
rewrite Hregs in E
destruct Hl1 as E1 _
rewrite E1 in E
injection E as ←
cbn [ r_end reg' ]
split ; lia |
split ; lia |
rewrite Hcb ; | unfold span_contains ; cbn ; lia
cbn [ ptr_addr ]
replace base + 0 + Z.of_nati − base with Z.of_nati by lia
exact Hbsi x Hxi
--apply frame_otherm1 m' base reg' ; exact Hregs | exact Hd1 | exact Hl1 | exact Hout | |
++intros Hm Hid
pose proof agree_piece_registered_ _ _ Hm Hal' v' Hh as Hreg′
rewrite Hid in Hreg'
exact Hreg'Hnone
++exact agree_piece_allocated_ _ _ _ _ Hnone Hal' v' Hh
∗exact live_disjoint_regions_ _ Hregs Hd1
∗exact Hr'
∗exact Hwi_ _ _ _ _ _ conjconjHmax conjHfr eq_refl Hcopy Hw
+iApply HK with [Hs] [Hnew]
∗iSplit ; iPureIntro ; exact Hok | iExact Hs
∗iSplit ; | iExact Hnew
iPureIntro
unfold string_ok
cbn [ ptr_cap ptr_addr r_end reg' ]
destruct Hok as _ & _ & _ & _ & _ & Hf
destruct R.address_space_ _ Hr' base reg' as _ Hend ; rewrite Hregs ; exact proj1Hl1 |
cbn [ r_end reg' ] in Hend
split ; left ; reflexivity |
repeat split ; try lia
exact Hf

The scalar string copies' triple, from string_copy_contract: owning the life of the object b, above 0, and its bytes xs from offset o, one more than the string's, and the string ys at src, where vd reads as the bytes' pointer and vs as src, and where the copy keeps the world interpretation: the bytes become the string and its NUL, a string the call hands over, and d is bound to the destination pointer, or for stpcpy (copy_return) to its NUL. The source is handed back. The two objects differ, since each life is owned once (live_string_ne), so the bytes do not overlap; no aux slot needs owning, since a scalar copy keeps them all.

991Lemma wp_string_copy
∀ end_return g f e ls lab d vd vs rest j b reg o xs src b′ reg′ ys Φ
registryg = Somestring_copy_contractend_return world
find_fnge g = None
arg_xge e ArgP vd = SomeWPtrmkPtrb + o Objb
arg_xge e ArgP vs = SomeWPtrsrc
0 < b
0 ≤ o
b + o + Z.of_natlengthxs ≤ r_endreg
lengthxs = Slengthys
∀m m′ wd h, string_copy_resultm mkPtrb + o Objb src Z.of_natlengthys + 1 m′ → ∀l v, l, v ∈ byte_psb o xs → h !! l = Somev → wim wd h → wim′ wd overwritebyte_psb o ys ++ 0 h
liveb reg −∗ bytesb o xs −∗ stringsrc b′ reg′ ys −∗ ▷stringmkPtrb + o Objb b reg ys −∗ stringsrc b′ reg′ ys −∗ WPERunmkFramef putd WPtrcopy_returnend_return mkPtrb + o Objb Z.of_natlengthys e ls None Execlab rest j : mexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd P Globalg ArgP vd; ArgP vs :: rest j : mexpr {Φ}
Proof 93 steps Qed
intros Hreg Hfn Hdata Hfree Hpd Hps Hb0 Ho Hend Hlen Hwi
iIntros Hl Hx Hs HK
iDestruct live_string_ne with Hl Hs as %Hne
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ string_copy_contractend_return world WPtrmkPtrb + o Objb; WPtrsrc liveb reg ∗ bytesb o xs ∗ stringsrc b' reg' ys with [$Hl $Hx $Hs] [HK] ; done | done | done | done | cbn [ map_option ] ; rewrite Hpd Hps ; done | | |
–split ; right ; eexists ; reflexivity | exists vd, vs ; reflexivity
–iIntros σ Hσ (Hl & _ & [%Hok Hs])
iDestruct pts_facts with Hσ Hl as %Hal & Hd & _
iDestruct pts_facts with Hσ Hs as %Has & _ & _
iPureIntro
pose proof string_terminated_ _ _ _ _ Hok Has as Ht
destruct Hal as E L _
destruct Has as E′ L′ _
cbn [ fst snd ] in E , L , E' , L'
exists mkPtrb + o Objb, src, Z.of_natlengthys
split ; reflexivity |
split ; exact Ht |
split
split ; lia |
exists b, reg
split ; reflexivity |
split ; exact E |
split ; exact L |
apply access_obj_ _ reg ; exact E | lia | lia | apply Z.mod_1_r
+cbn [ ptr_addr ]
destruct Hok as _ & _ & Hs1 & Hs2 & _
destruct Hdb reg b' reg' conjE L conjE' L' Hne ; left | right ; lia
–iNext
iIntros σ trace values s′ m′ w′ Hinv (%h & Hh & %Hf) (Hl & Hx & [%Hok Hs])
destruct Hf as Ha & Hd & Hr & Hw
destruct M.E.string_copy_invocation_ _ _ _ _ _ _ _ _ _ _ _ _ Hinv as _ & → & d′ & src′ & k & Hx′ & Hdom & Hres & He
injection Hx' as ← ←
iDestruct pts_lookup with Hh Hl as %Hll
iDestruct pts_lookup with Hh Hx as %Hlx
iDestruct pts_lookup with Hh Hs as %Hls
assert Hlv : live_atls_memσ b reg
{apply HaPLiveb VLivereg
apply Hll
apply elem_of_cons
left
reflexivity
assert Hx0 : all_agreels_memσ byte_psb o xs
intros l v Hin
exact Hal v Hlxl v Hin
assert Hs0 : all_agreels_memσ string_pssrc b' reg' ys
intros l v Hin
exact Hal v Hlsl v Hin
pose proof string_terminated_ _ _ _ _ Hok Hs0 as Ht
assert k = Z.of_natlengthys as →
{exact terminated_length_unique_ _ _ _ proj1Hdom Ht
injection He as →
destruct copy_string_afterls_memσ m' b reg o xs src b' reg' ys Hd Hlv Hx0 Hlen Hok Hs0 Hres as Hnew Hfr
destruct M.E.invoke_prefix_ _ _ _ _ _ _ _ _ _ _ _ _ Hinv as born & Hpre
destruct M.E.prefix_preserve_ _ _ _ _ _ _ _ _ _ _ Hpre Hr as Hr′ _
pose proof Hres as Hregs & _ & _
destruct R.address_space_ _ Hr b reg proj1Hlv as _ Hfit
assert Hok′ : string_okmkPtrb + o Objb b reg ys
{unfold string_ok
destruct Hok as _ & _ & _ & _ & _ & Hf
split ; left ; reflexivity |
repeat split ; try lia
exact Hf
assert Hk : byte_psb o ys ++ 0.*1 = byte_psb o xs.*1
{rewrite ! byte_ps_keys length_app Hlen
cbn [ length ]
rewrite Nat.add_1_r
reflexivity
iMod pts_update_ byte_psb o xs byte_psb o ys ++ 0 Hk with Hh Hx as [Hh Hx]
iModIntro
iExists _
iSplit ; iPureIntro ; reflexivity |
iSplitL Hh
+iExists _
iFrame Hh
iPureIntro
split ; | split ; | split
∗intros l v Hl′
destruct lookup_overwrite_ _ _ _ Hl' as Hin | Hnk Hh′
--exact all_agree_elem_ _ _ _ Hnew Hin
--apply Hfr ; | exact Hal v Hh'
rewrite <- Hk
exact Hnk
∗exact live_disjoint_regions_ _ Hregs Hd
∗exact Hr'
∗exact Hwi_ _ _ _ Hres Hlx Hw
+iApply HK with [Hl Hx] [Hs]
∗iApply block_string_ _ _ _ Hok' with Hl Hx
∗iSplit ; iPureIntro ; exact Hok | iExact Hs

strcpy's triple: wp_string_copy, binding d to the destination.

1071Lemma wp_strcpy
∀ f e ls lab d vd vs rest j b reg o xs src b′ reg′ ys Φ
registryTAtom"strcpy" = Somestrcpy_contractworld
find_fnge TAtom"strcpy" = None
lookupTAtom"strcpy" ge_globalsge = None
arg_xge e ArgP vd = SomeWPtrmkPtrb + o Objb
arg_xge e ArgP vs = SomeWPtrsrc
0 < b
0 ≤ o
b + o + Z.of_natlengthxs ≤ r_endreg
lengthxs = Slengthys
∀m m′ wd h, string_copy_resultm mkPtrb + o Objb src Z.of_natlengthys + 1 m′ → ∀l v, l, v ∈ byte_psb o xs → h !! l = Somev → wim wd h → wim′ wd overwritebyte_psb o ys ++ 0 h
liveb reg −∗ bytesb o xs −∗ stringsrc b′ reg′ ys −∗ ▷stringmkPtrb + o Objb b reg ys −∗ stringsrc b′ reg′ ys −∗ WPERunmkFramef putd WPtrmkPtrb + o Objb e ls None Execlab rest j : mexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd P GlobalTAtom"strcpy" ArgP vd; ArgP vs :: rest j : mexpr {Φ}
Explore proof 3 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
vd, vs :
rest :
listinst
j :
b :
Z
reg :
o :
Z
xs :
listZ
src :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
⊢
registryTAtom"strcpy" = Somestrcpy_contractworld → find_fnge TAtom"strcpy" = None → lookupTAtom"strcpy" ge_globalsge = None → arg_xge e ArgP vd = SomeWPtrptr_addr ≔ b + o; ptr_cap ≔ Objb → arg_xge e ArgP vs = SomeWPtrsrc → 0 < b → 0 ≤ o → b + o + lengthxs ≤ r_endreg → lengthxs = Slengthys → ∀m m′ : mem wd : world h : gmappiece pval, string_copy_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb src lengthys + 1 m′ → ∀l : piece v : pval, l, v ∈ byte_psb o xs → h !! l = Somev → wim wd h → wim′ wd overwritebyte_psb o ys ++ 0 h → liveb reg −∗ bytesb o xs −∗ stringsrc b′ reg′ ys −∗ ▷stringptr_addr ≔ b + o; ptr_cap ≔ Objb b reg ys −∗ stringsrc b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WPtrptr_addr ≔ b + o; ptr_cap ≔ Objb e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j : mexpr {v. Φv} −∗ WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab CallCResultd P GlobalTAtom"strcpy" ArgP vd; ArgP vs :: rest j : mexpr {v. Φv}

intros Hreg Hfn Hdata Hpd Hps Hb0 Ho Hend Hlen Hwi

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
vd, vs :
rest :
listinst
j :
b :
Z
reg :
o :
Z
xs :
listZ
src :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcpy" = Somestrcpy_contractworld
Hfn :
find_fnge TAtom"strcpy" = None
Hdata :
lookupTAtom"strcpy" ge_globalsge = None
Hpd :
arg_xge e ArgP vd = SomeWPtrptr_addr ≔ b + o; ptr_cap ≔ Objb
Hps :
arg_xge e ArgP vs = SomeWPtrsrc
Hb0 :
0 < b
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hlen :
lengthxs = Slengthys
Hwi :
∀m m′ : mem wd : world h : gmappiece pval, string_copy_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb src lengthys + 1 m′ → ∀l : piece v : pval, l, v ∈ byte_psb o xs → h !! l = Somev → wim wd h → wim′ wd overwritebyte_psb o ys ++ 0 h
⊢
liveb reg −∗ bytesb o xs −∗ stringsrc b′ reg′ ys −∗ ▷stringptr_addr ≔ b + o; ptr_cap ≔ Objb b reg ys −∗ stringsrc b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WPtrptr_addr ≔ b + o; ptr_cap ≔ Objb e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j : mexpr {v. Φv} −∗ WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab CallCResultd P GlobalTAtom"strcpy" ArgP vd; ArgP vs :: rest j : mexpr {v. Φv}

iIntros Hl Hx Hs 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 :
vd, vs :
rest :
listinst
j :
b :
Z
reg :
o :
Z
xs :
listZ
src :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"strcpy" = Somestrcpy_contractworld
Hfn :
find_fnge TAtom"strcpy" = None
Hdata :
lookupTAtom"strcpy" ge_globalsge = None
Hpd :
arg_xge e ArgP vd = SomeWPtrptr_addr ≔ b + o; ptr_cap ≔ Objb
Hps :
arg_xge e ArgP vs = SomeWPtrsrc
Hb0 :
0 < b
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hlen :
lengthxs = Slengthys
Hwi :
∀m m′ : mem wd : world h : gmappiece pval, string_copy_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb src lengthys + 1 m′ → ∀l : piece v : pval, l, v ∈ byte_psb o xs → h !! l = Somev → wim wd h → wim′ wd overwritebyte_psb o ys ++ 0 h
Hl :
liveb reg
Hx :
bytesb o xs
Hs :
stringsrc b′ reg′ ys
HK :
▷stringptr_addr ≔ b + o; ptr_cap ≔ Objb b reg ys −∗ stringsrc b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WPtrptr_addr ≔ b + o; ptr_cap ≔ Objb 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 P GlobalTAtom"strcpy" ArgP vd; ArgP vs :: rest j {v. Φv}

iApply wp_string_copyfalse TAtom"strcpy" with Hl Hx Hs HK ; done

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hreg Hfn Hdata Hpd Hps Hb0 Ho Hend Hlen Hwi
iIntros Hl Hx Hs HK
iApply wp_string_copyfalse TAtom"strcpy" with Hl Hx Hs HK ; done

stpcpy's triple: wp_string_copy, binding d to the copy's NUL.

1092Lemma wp_stpcpy
∀ f e ls lab d vd vs rest j b reg o xs src b′ reg′ ys Φ
registryTAtom"stpcpy" = Somestpcpy_contractworld
find_fnge TAtom"stpcpy" = None
lookupTAtom"stpcpy" ge_globalsge = None
arg_xge e ArgP vd = SomeWPtrmkPtrb + o Objb
arg_xge e ArgP vs = SomeWPtrsrc
0 < b
0 ≤ o
b + o + Z.of_natlengthxs ≤ r_endreg
lengthxs = Slengthys
∀m m′ wd h, string_copy_resultm mkPtrb + o Objb src Z.of_natlengthys + 1 m′ → ∀l v, l, v ∈ byte_psb o xs → h !! l = Somev → wim wd h → wim′ wd overwritebyte_psb o ys ++ 0 h
liveb reg −∗ bytesb o xs −∗ stringsrc b′ reg′ ys −∗ ▷stringmkPtrb + o Objb b reg ys −∗ stringsrc b′ reg′ ys −∗ WPERunmkFramef putd WPtrmkPtrb + o + Z.of_natlengthys Objb e ls None Execlab rest j : mexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd P GlobalTAtom"stpcpy" ArgP vd; ArgP vs :: rest j : mexpr {Φ}
Explore proof 3 tactics

Initial goal

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
vd, vs :
rest :
listinst
j :
b :
Z
reg :
o :
Z
xs :
listZ
src :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
⊢
registryTAtom"stpcpy" = Somestpcpy_contractworld → find_fnge TAtom"stpcpy" = None → lookupTAtom"stpcpy" ge_globalsge = None → arg_xge e ArgP vd = SomeWPtrptr_addr ≔ b + o; ptr_cap ≔ Objb → arg_xge e ArgP vs = SomeWPtrsrc → 0 < b → 0 ≤ o → b + o + lengthxs ≤ r_endreg → lengthxs = Slengthys → ∀m m′ : mem wd : world h : gmappiece pval, string_copy_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb src lengthys + 1 m′ → ∀l : piece v : pval, l, v ∈ byte_psb o xs → h !! l = Somev → wim wd h → wim′ wd overwritebyte_psb o ys ++ 0 h → liveb reg −∗ bytesb o xs −∗ stringsrc b′ reg′ ys −∗ ▷stringptr_addr ≔ b + o; ptr_cap ≔ Objb b reg ys −∗ stringsrc b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WPtrptr_addr ≔ b + o + lengthys; ptr_cap ≔ Objb e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j : mexpr {v. Φv} −∗ WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab CallCResultd P GlobalTAtom"stpcpy" ArgP vd; ArgP vs :: rest j : mexpr {v. Φv}

intros Hreg Hfn Hdata Hpd Hps Hb0 Ho Hend Hlen Hwi

hlc :
has_lc
Σ :
gFunctors
invGS_gen0 :
invGS_genhlc Σ
gen_heapGS0 :
gen_heapGSpiece pval Σ
world :
Type
registry :
name → optioncontractworld
wi :
mem → world → gmappiece pval → Prop
SafepointStable0 :
ge :
f :
e :
ls :
listname × optionZ
lab, d :
vd, vs :
rest :
listinst
j :
b :
Z
reg :
o :
Z
xs :
listZ
src :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"stpcpy" = Somestpcpy_contractworld
Hfn :
find_fnge TAtom"stpcpy" = None
Hdata :
lookupTAtom"stpcpy" ge_globalsge = None
Hpd :
arg_xge e ArgP vd = SomeWPtrptr_addr ≔ b + o; ptr_cap ≔ Objb
Hps :
arg_xge e ArgP vs = SomeWPtrsrc
Hb0 :
0 < b
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hlen :
lengthxs = Slengthys
Hwi :
∀m m′ : mem wd : world h : gmappiece pval, string_copy_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb src lengthys + 1 m′ → ∀l : piece v : pval, l, v ∈ byte_psb o xs → h !! l = Somev → wim wd h → wim′ wd overwritebyte_psb o ys ++ 0 h
⊢
liveb reg −∗ bytesb o xs −∗ stringsrc b′ reg′ ys −∗ ▷stringptr_addr ≔ b + o; ptr_cap ≔ Objb b reg ys −∗ stringsrc b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WPtrptr_addr ≔ b + o + lengthys; ptr_cap ≔ Objb e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab rest j : mexpr {v. Φv} −∗ WPERunfr_fn ≔ f; fr_env ≔ e; fr_locals ≔ ls; fr_doomed ≔ None; fr_at ≔ Execlab CallCResultd P GlobalTAtom"stpcpy" ArgP vd; ArgP vs :: rest j : mexpr {v. Φv}

iIntros Hl Hx Hs 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 :
vd, vs :
rest :
listinst
j :
b :
Z
reg :
o :
Z
xs :
listZ
src :
b′ :
Z
reg′ :
ys :
listZ
Φ :
valnanofil_langregistry ge → iPropIΣ
Hreg :
registryTAtom"stpcpy" = Somestpcpy_contractworld
Hfn :
find_fnge TAtom"stpcpy" = None
Hdata :
lookupTAtom"stpcpy" ge_globalsge = None
Hpd :
arg_xge e ArgP vd = SomeWPtrptr_addr ≔ b + o; ptr_cap ≔ Objb
Hps :
arg_xge e ArgP vs = SomeWPtrsrc
Hb0 :
0 < b
Ho :
0 ≤ o
Hend :
b + o + lengthxs ≤ r_endreg
Hlen :
lengthxs = Slengthys
Hwi :
∀m m′ : mem wd : world h : gmappiece pval, string_copy_resultm ptr_addr ≔ b + o; ptr_cap ≔ Objb src lengthys + 1 m′ → ∀l : piece v : pval, l, v ∈ byte_psb o xs → h !! l = Somev → wim wd h → wim′ wd overwritebyte_psb o ys ++ 0 h
Hl :
liveb reg
Hx :
bytesb o xs
Hs :
stringsrc b′ reg′ ys
HK :
▷stringptr_addr ≔ b + o; ptr_cap ≔ Objb b reg ys −∗ stringsrc b′ reg′ ys −∗ WPERunfr_fn ≔ f; fr_env ≔ putd WPtrptr_addr ≔ b + o + lengthys; ptr_cap ≔ Objb 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 P GlobalTAtom"stpcpy" ArgP vd; ArgP vs :: rest j {v. Φv}

iApply wp_string_copytrue TAtom"stpcpy" with Hl Hx Hs HK ; done

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros Hreg Hfn Hdata Hpd Hps Hb0 Ho Hend Hlen Hwi
iIntros Hl Hx Hs HK
iApply wp_string_copytrue TAtom"stpcpy" with Hl Hx Hs HK ; done

memcmp's triple, from memcmp_contract: owning the bytes xs from offset o of the live object b and the bytes ys, as many, from offset o' of the live object b', through read-write or read-only capabilities, where vp, vq and vn read as their pointers and length, the call binds d to an int. Which int does not matter to a caller that only branches on it.

1118Lemma wp_memcmp
∀ f e ls lab d vp vq vn rest j b reg o xs c b′ reg′ o′ ys c′ Φ
registryTAtom"memcmp" = Somememcmp_contractworld
find_fnge TAtom"memcmp" = None
lookupTAtom"memcmp" ge_globalsge = None
arg_xge e ArgP vp = SomeWPtrmkPtrb + o c
c = Objb ∨ c = Rob
arg_xge e ArgP vq = SomeWPtrmkPtrb′ + o′ c′
c′ = Objb′ ∨ c′ = Rob′
arg_xge e ArgL vn = SomeWIntZ.of_natlengthxs
lengthys = lengthxs
0 ≤ o
0 ≤ o′
b + o + Z.of_natlengthxs ≤ r_endreg
b′ + o′ + Z.of_natlengthxs ≤ r_endreg′
Forallλx ⇒ 0 ≤ x < 256 xs
Forallλx ⇒ 0 ≤ x < 256 ys
liveb reg −∗ bytesb o xs −∗ liveb′ reg′ −∗ bytesb′ o′ ys −∗ ▷∀bits, liveb reg −∗ bytesb o xs −∗ liveb′ reg′ −∗ bytesb′ o′ ys −∗ WPERunmkFramef putd WIntbits e ls None Execlab rest j : mexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd W GlobalTAtom"memcmp" ArgP vp; ArgP vq; ArgL vn :: rest j : mexpr {Φ}
Proof 28 steps Qed
intros Hreg Hfn Hdata Hp Hc Hq Hc′ Hn Hlen Ho Ho′ Hend Hend′ Hx Hy
iIntros Hl Hx Hl′ Hy HK
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ memcmp_contractworld WPtrmkPtrb + o c; WPtrmkPtrb' + o' c'; WIntZ.of_natlengthxs liveb reg ∗ bytesb o xs ∗ liveb' reg' ∗ bytesb' o' ys with [$Hl $Hx $Hl′ $Hy] [HK] ; done | done | done | done | cbn [ map_option ] ; rewrite Hp Hq Hn ; done | | |
–split ; right ; eexists ; reflexivity | do 3 eexists ; reflexivity
–iIntros σ Hσ (Hl & Hx & Hl′ & Hy)
iDestruct pts_facts with Hσ Hl as %Hlv _ & _ & Hfit
iDestruct pts_facts with Hσ Hx as %Hxa & _
iDestruct pts_facts with Hσ Hl′ as %Hlv′ _ & _ & _
iDestruct pts_facts with Hσ Hy as %Hya & _
iPureIntro
cbn [ fst snd agree_piece ] in Hlv , Hlv'
exists mkPtrb + o c, mkPtrb' + o' c', Z.of_natlengthxs
split ; reflexivity |
split ; exact proj1block_readable_ _ _ _ _ _ Hlv Hxa Hfit Hc Ho Hend Hx |
rewrite <- Hlen
rewrite <- Hlen in Hend'
exact proj1block_readable_ _ _ _ _ _ Hlv' Hya Hfit Hc' Ho' Hend' Hy
–iNext
iIntros σ trace values s′ m′ w′ Hinv Hσ (Hl & Hx & Hl′ & Hy)
destruct M.E.memcmp_invocation_ _ _ _ _ _ _ _ _ _ _ _ Hinv as _ & → & → & p′ & q′ & n′ & bits & Hxs & _ & 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 Hl Hx Hl′ Hy

memchr's triple, from memchr_contract: owning the bytes xs from offset o of the live object b, through a read-write or read-only capability c, where vp and vn read as their pointer and length, the call binds d to what it finds of the int k, which vk reads as (strchr_found of xs: the first byte equal to k's low byte, with c, or null).

1163Lemma wp_memchr
∀ f e ls lab d vp vk vn rest j b reg o xs c k Φ
registryTAtom"memchr" = Somememchr_contractworld
find_fnge TAtom"memchr" = None
lookupTAtom"memchr" ge_globalsge = None
arg_xge e ArgP vp = SomeWPtrmkPtrb + o c
c = Objb ∨ c = Rob
arg_xge e ArgW vk = SomeWIntk
0 ≤ k < 2 ^ 32
arg_xge e ArgL vn = SomeWIntZ.of_natlengthxs
0 ≤ o
b + o + Z.of_natlengthxs ≤ r_endreg
Forallλx ⇒ 0 ≤ x < 256 xs
liveb reg −∗ bytesb o xs −∗ ▷∀q, ⌜strchr_foundmkPtrb + o c xs k q⌝ −∗ liveb reg −∗ bytesb o xs −∗ WPERunmkFramef putd WPtrq e ls None Execlab rest j : mexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd P GlobalTAtom"memchr" ArgP vp; ArgW vk; ArgL vn :: rest j : mexpr {Φ}
Proof 52 steps Qed
intros Hreg Hfn Hdata Hp Hc Hk Hk32 Hn Ho Hend Hx
iIntros Hl Hx HK
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ memchr_contractworld WPtrmkPtrb + o c; WIntk; WIntZ.of_natlengthxs liveb reg ∗ bytesb o xs with [$Hl $Hx] [HK] ; done | done | done | done | cbn [ map_option ] ; rewrite Hp Hk Hn ; done | | |
–split ; right ; eexists ; reflexivity | do 3 eexists ; reflexivity
–iIntros σ Hσ (Hl & Hx)
iDestruct pts_facts with Hσ Hl as %Hlv _ & _ & Hfit
iDestruct pts_facts with Hσ Hx as %Hxa & _
iPureIntro
cbn [ fst snd agree_piece ] in Hlv
do 3 eexists
split ; reflexivity |
apply memchr_input_full ; exact Hk32 |
exact proj1block_readable_ _ _ _ _ _ Hlv Hxa Hfit Hc Ho Hend Hx
–iNext
iIntros σ trace values s′ m′ w′ Hinv Hσ (Hl & Hx)
iDestruct pts_facts with Hσ Hl as %Hlv _ & _ & Hfit
iDestruct pts_facts with Hσ Hx as %Hxa & _
cbn [ fst snd agree_piece ] in Hlv
destruct block_readable_ _ _ _ _ _ Hlv Hxa Hfit Hc Ho Hend Hx as _ Hv
destruct M.E.memchr_invocation_ _ _ _ _ _ _ _ _ _ _ _ Hinv as _ & → & → & p′ & k′ & n′ & q & Hxs & Hq & He
injection Hxs as ← ← ←
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 [%] Hl Hx
cbn [ ptr_addr ls_mem ] in Hq , Hv
destruct Hq as i & Hi & Hvi & Hbefore & → | Hnone & →
+left
destruct lookup_lt_is_Some_2xs Z.to_nati ltac:lia as x Hxi
exists Z.to_nati, x
split ; exact Hxi |
split
∗rewrite <- Hvi
rewrite <- Hv_ _ Hxi
rewrite Z2Nat.id ; reflexivity | lia
∗split ; | cbn [ ptr_addr ptr_cap ] ; rewrite Z2Nat.id ; reflexivity | lia
intros i′ x′ Hlt Hx′
rewrite <- Hv_ _ Hx'
apply Hbefore
lia
+right
split ; | reflexivity
intros i′ x′ Hx′
rewrite <- Hv_ _ Hx'
apply Hnone
split ; lia |
apply lookup_lt_Some in Hx'
lia

memchr's triple on a string, from memchr_contract: owning the string at p, which vp reads as, a search for the int k, which vk reads as and whose low byte is the NUL, bounded by n, which vn reads as, binds d to nul_found p bytes n. The search reads only through the NUL (memchr_input_bounded), so the bound may run past the string's object.

1213Lemma wp_memchr_string
∀ f e ls lab d vp vk vn rest j p b reg bytes k n Φ
registryTAtom"memchr" = Somememchr_contractworld
find_fnge TAtom"memchr" = None
lookupTAtom"memchr" ge_globalsge = None
arg_xge e ArgP vp = SomeWPtrp
arg_xge e ArgW vk = SomeWIntk
0 ≤ k < 2 ^ 32
k mod 256 = 0
arg_xge e ArgL vn = SomeWIntn
0 ≤ n < 2 ^ 64
stringp b reg bytes −∗ ▷stringp b reg bytes −∗ WPERunmkFramef putd WPtrnul_foundp bytes n e ls None Execlab rest j : mexpr {Φ} −∗ WPERunmkFramef e ls None Execlab CallCResultd P GlobalTAtom"memchr" ArgP vp; ArgW vk; ArgL vn :: rest j : mexpr {Φ}
Proof 25 steps Qed
intros Hreg Hfn Hdata Hp Hk Hk32 H0 Hn Hn64
iIntros Hs HK
iApply wp_external_ _ _ _ _ _ _ _ _ _ _ _ memchr_contractworld WPtrp; WIntk; WIntn stringp b reg bytes with Hs [HK] ; done | done | done | done | cbn [ map_option ] ; rewrite Hp Hk Hn ; done | | |
–split ; right ; eexists ; reflexivity | do 3 eexists ; reflexivity
–iIntros σ Hσ [%Hok Hs]
iDestruct pts_facts with Hσ Hs as %Ha & _
iPureIntro
do 3 eexists
split ; reflexivity |
exact memchr_input_bounded_ _ _ _ _ Hk32 H0 string_bounded_ _ _ _ _ n Hok Ha Hn64
–iNext
iIntros σ trace values s′ m′ w′ Hinv Hσ [%Hok Hs]
iDestruct pts_facts with Hσ Hs as %Ha & _
destruct M.E.memchr_invocation_ _ _ _ _ _ _ _ _ _ _ _ Hinv as _ & → & → & p′ & k′ & n′ & q & Hxs & Hq & He
injection Hxs as ← ← ←
injection He as →
rewrite memchr_result_string_ _ _ _ _ _ _ _ Hok Ha H0 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
by iSplit

MemLogicOn over a Logic instance of its own.

1249Module MemLogic R : Runtime
1250Module LG0 ≔ Logic R
Include MemLogicOn R LG0