Fil-C on Nix

Filnix wiki

the formal campaign

rocq/theories/Runtime.v

The runtime as axioms: Campaign 2's module type Runtime, and the interpreter's instance of it (formal.md, runtime-axioms.md, which gives each axiom's source in the runtime).

The model of the checked IR is about one thread's program. What the Fil-C runtime does around that program, where it puts a new object, what free does to an object's header, what the collector may do at a safepoint, is not the model's to decide. Runtime states those facts as one page of axioms, read against the staging Fil-C the toolchain pins (mbrock/fil-c at 18b6663a2785c8eba6cc2a544a7711e19fc448c7, the coreRev of lib/filc-staging.json). Each axiom about Fil-C has a native test in tests/c/prog/axiom-*.c that fails if it is stated in the obvious stronger way that the runtime does not promise.

One thread's view

The model is one thread's. At a safepoint the collector acts, and what the program sees change there, the safepoint relation, is the collector's rewriting of stored capabilities to freed objects and nothing else: no region changes (collector_live). Fil-C's runtime never frees an object by itself. Only code the program brings in does: a signal handler it installed, which Fil-C runs only at pollchecks (tests/c/prog/axiom-safepoint.c), or a thread it started. Both are the program's code, not the runtime's, and a module that installs a handler or starts a thread calls an external with no contract, which ends its run in the model; a handler is to be verified as program code of its own. The model takes a run to be the program's whole execution after the trusted entry, with no handler installed and no other program thread when it starts: a constructor, a preloaded library or a native caller that installed one is outside it. A pointer store's aux exit is a native safepoint inside a check and its access, which the validator keeps facts across, so a handler a program installs could free a checked object there; a verified handler must not free an object whose check is in flight. Another thread is outside the model: its writes are (non_moving lets no byte change at a safepoint), and so are its frees, which natively show at any check, not only at a safepoint (tests/c/prog/axiom-threads.c). For a threaded program, native safety rests on Fil-C's own argument, not on the theorems proved over this module type: every check traps on a freed object, and an access whose check passed before the free reads retained memory (retention).

From Stdlib Require Import String ZArith List Bool Lia
From Nanofil Require Import Term Syntax Values Memory
Import ListNotations
Open Scope Z_scope

What the axioms speak of

How the runtime's free may change objects, from memory m to m': every identity of m' was one of m, unchanged, or a live heap object now freed, its bounds empty. No identity appears.

58Definition lifetime_stepm m′ : mem : Prop ≔
∀b reg′, object_regionb m_regionsm′ = Somereg′ → ∃reg, object_regionb m_regionsm = Somereg ∧ reg′ = reg ∨ r_kindreg = Heap ∧ r_lifereg = Live ∧ reg′ = mkRegionb b Heap Freed

The capability c is that of an object freed in the regions rs.

68Definition freed_inrs : listregion c : cap : Prop ≔
∃b reg, c = Objb ∨ c = Rob ∧ object_regionb rs = Somereg ∧ r_lifereg = Freed

Every nonempty access through the capability c, in the regions rs, traps out of bounds, as every access to a freed object does. The collector's free singleton is such a capability.

75Definition traps_as_freedrs : listregion c : cap : Prop ≔
∀a size r align, 0 < size → cap_access_resc rs a size r align = SomeRTrapOutOfBounds

Every object of the regions rs lies between 0 and 2^48, native Fil-C's address space (PAS_ADDRESS_BITS); a native address is unsigned, so no object starts below 0. An address inside one never wraps (raw_address/3), and two addresses of one object are less than 2^63 apart, so a near offset between them does not wrap either (hull_covered/7). A lower half check compares its address, read signed, with the object's base (half_bound/6), so an address that wrapped below 0 fails it.

86Definition objects_fitrs : listregion : Prop ≔
∀b reg, object_regionb rs = Somereg → 0 ≤ b ∧ r_endreg ≤ 2 ^ 48

Every freed object of the regions rs is empty. Free and the end of an invocation end an object's life and empty its bounds together (lifetime_step, region_step).

92Definition freed_emptyrs : listregion : Prop ≔
∀b reg, object_regionb rs = Somereg → r_lifereg = Freed → r_endreg = b

The address a is inside the current bounds of an object of the memory m.

97Definition in_objectm : mem a : Z : Prop ≔
∃b reg, object_regionb m_regionsm = Somereg ∧ b ≤ a < r_endreg

How the program may change objects, from memory m to m': every identity of m' was one of m, unchanged, or live and now ended, its bounds empty: a free, or the end of an invocation's locals. Unlike lifetime_step, an object of any kind may end.

104Definition region_stepm m′ : mem : Prop ≔
∀b reg′, object_regionb m_regionsm′ = Somereg′ → ∃reg, object_regionb m_regionsm = Somereg ∧ reg′ = reg ∨ r_lifereg = Live ∧ reg′ = mkRegionb b r_kindreg Freed

What the program itself may do to memory between allocations, from m to m': end objects (region_step), and write bytes and stored capabilities only inside objects' bounds.

114Definition keptm m′ : mem : Prop ≔
region_stepm m′ ∧ ∀a, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a

What a free that succeeds does: on the null pointer, nothing; on the base pointer of a live heap object at an address other than 0, it empties and frees that object's region and changes no other region, no byte and no stored capability. The axiom free_succeeds says the runtime's free does so.

123Definition frees_heapfree : word → mem → optionresunit × mem : Prop ≔
∀m, freeWPtrmkPtr0 CNone m = Someok, m ∧ ∀m b reg, object_regionb m_regionsm = Somereg ∧ r_lifereg = Live → r_kindreg = Heap → b ≠ 0 → ∃rs, replace_regionb mkRegionb b Heap Freed m_regionsm = Somers ∧ freeWPtrmkPtrb Objb m = Someok, mkMemm_bytesm rs m_auxm

The module type

What the model assumes of the Fil-C runtime: its allocator, its free, and what its collector may do at a safepoint. A runtime is any module with these parts that proves these axioms; Run.v's Driver and Machine.v's Machine run over any of them.

136Module Type Runtime

The runtime's own state, which the program never reads: the interpreter's Next.

140Parameter state : Type

The runtime's state when a run starts.

143Parameter start : state

The runtime in state s is ready to allocate in the memory m: its bookkeeping agrees with m, so a new object will be fresh there. For the interpreter, every object lies below Next and nothing above it has been written.

149Parameter ready : state → mem → Prop

The base of a new object for the request q, and the state after it; None when the runtime cannot hold the object, which ends the run with trap(out_of_memory).

154Parameter alloc : state → alloc_req → optionZ × state

The allocator gives each new object an address no other object uses. Where the runtime in state s is ready in memory m, a request q with a positive alignment and an extent of at least 0 that alloc grants gets a fresh base: a new identity, aligned, overlapping no object, ending at or below 2^64, reading as zero with no stored capability; and the runtime is ready in the memory with the new object. The model needs it so that a new object cannot alias an old one, and so the step relation's choice of any fresh base covers every runtime.

Natively a freed object's address can be a new object's once nothing names the old one; the model never reuses an identity, because a capability never dies in it. The two agree on whether each access through a capability the program still holds traps, not on its address bits after a collection. Native test: axiom − fresh.c.

172Axiom fresh_allocation
∀ s m q base s′
0 < req_alignq
0 ≤ req_extentq
allocs q = Somebase, s′
freshm q base ∧ readys′ allocatedm q base

Every object lies in native Fil-C's address space: where the runtime in state s is ready in memory m, every object of m lies between 0 and 2^48 (objects_fit). The model needs it so that no address inside an object wraps and a wrapped address fails a lower half check; an allocation the runtime cannot hold is refused, a trap. Native test: axiom − address.c.

185Axiom address_space

No freed object of a memory m the runtime is ready in has bounds (freed_empty). Every free and the end of every invocation empty them (lifetime_step, region_step), so it constrains only the memory a run starts in. It is about the runtime's own bookkeeping, not Fil-C, so it has no native test.

192Axiom freed_bounds

The program's own changes keep the runtime ready: if it is ready in m, and m' is m after the program wrote inside objects and ended some (kept), it is ready in m'. With fresh_allocation and safepoint_ready this makes ready hold in every state of a run (Machine.v). No native test: it is about the runtime's own bookkeeping.

200Axiom ready_kept
∀ s m m′
keptm m′
readys m′

Free of a pointer word: its result, and the memory after it. This is what a call of libc's free runs, the genv's ge_free.

204Parameter free : word → mem → optionresunit × mem

Free changes an object's bounds only by emptying a live heap object's, for every alias at once, and makes no new identity (lifetime_step). The model needs it so that a capability the program holds keeps its meaning across a free except for the freed object, whose every access then traps. Native test: axiom − lifetime.c.

212Axiom free_lifetime
∀ x m r m′
freex m = Somer, m′

Free changes no byte and no stored capability: a freed object's memory is retained while anything can name it. Machine.v uses it to show a free keeps the program's other memory; natively it is also what lets an access whose check passed before another thread's free read the same bytes. Native test: axiom − retention.c.

220Axiom retention
∀ x m r m′
freex m = Somer, m′
m_bytesm′ = m_bytesm ∧ m_auxm′ = m_auxm

Free reclaims nothing: every identity before it is one after it, the freed object's too. Only the collector reclaims, at a safepoint (rooting), and natively only of objects nothing can name, whose regions the model keeps. With fresh_allocation this keeps a later allocation from taking a freed object's base. Native test: axiom − identity.c.

229Axiom free_keeps_ids
∀ x m r m′ b
freex m = Somer, m′
object_regionb m_regionsm′ ≠ None

Free frees or traps; it never goes on having done something else, so it never answers unchecked, which the model keeps for a broken pass. Native test: axiom − free.c.

236Axiom free_checked
∀ x m w m′
freex m ≠ SomeRUncheckedw, m′

Free succeeds where a program frees what it owns: on the null pointer it does nothing, and on the base pointer of a live heap object it frees that object as frees_heap says. free_lifetime, retention and free_keeps_ids bound what any free may change; this says that such a free returns, so that a program logic can prove a call of free goes on (Logic.v's wp_free). The pointer carries the object's Obj capability, not a read-only one. The model's heap objects are what the IR's alloc makes (malloc-like calls, and the address-taken locals, VLAs and allocas nanofil leaves on the heap), what the malloc and strdup contracts make, and the startup argv and environ objects; natively each is an ordinary collected object, which free returns on. Free of a global, an mmap'd object, an interior pointer or a freed object traps. Native test: axiom − free − succeeds.c.

252Axiom free_succeeds

The runtime may act at the instruction i: the collector's handshake, a pollcheck callback, or a signal handler the program installed. Another thread's effects are outside the model (the header's One thread's view).

258Parameter at_safepoint : inst → bool

The runtime acts only at instructions that are not evidence_preserving/1: calls, polls, alloc and the rest. The model needs it because the validator keeps evidence across every other instruction, which would be unsound if the runtime could free or rewrite memory there. Native test: axiom − safepoint.c.

266Axiom safepoints
∀ i
at_safepointi = true

What the program may find changed when it reaches a safepoint with the runtime in state s and memory m: the runtime's state s' and memory m' after the collector acted.

272Parameter safepoint : state → mem → state → mem → Prop

At a safepoint no region changes: the collector frees no object, live or freed, and no identity appears. Natively the collector reclaims objects nothing can name; the model keeps their regions, as fresh_allocation explains. Only the program frees, by free or by code it brought in (a signal handler, a thread), and that is not the runtime's action. The model needs it so that an object live before a poll is live after it with the same bounds. Native test: axiom − collector − live.c.

282Axiom collector_live
∀ s m s′ m′
safepoints m s′ m′

At a safepoint, as at a free, an object's bounds change only by a live heap object's being freed, and no identity appears (lifetime_step); at a safepoint none changes at all (collector_live).

289Lemma safepoint_lifetime
∀ s m s′ m′
safepoints m s′ m′
Explore proof 3 tactics

Initial goal

⊢
∀s : state m : mem s′ : state m′ : mem, safepoints m s′ m′ → lifetime_stepm m′

intros s m s′ m′ H b reg′ E

m :
s′ :
m′ :
H :
safepoints m s′ m′
b :
Z
reg′ :
E :
object_regionb m_regionsm′ = Somereg′
⊢
∃reg : region, object_regionb m_regionsm = Somereg ∧ reg′ = reg ∨ r_kindreg = Heap ∧ r_lifereg = Live ∧ reg′ = r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed

rewrite collector_lives m s′ m′ H in E

m :
s′ :
m′ :
H :
safepoints m s′ m′
b :
Z
reg′ :
E :
object_regionb m_regionsm = Somereg′
⊢
∃reg : region, object_regionb m_regionsm = Somereg ∧ reg′ = reg ∨ r_kindreg = Heap ∧ r_lifereg = Live ∧ reg′ = r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed

eauto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros s m s′ m′ H b reg′ E
rewrite collector_lives m s′ m′ H in E
eauto

At a safepoint no byte moves or changes: the collector writes no object's contents and no address word. The model needs it so that the bytes a check passed stay readable, unchanged, until the program next looks at the header. Native test: axiom − nonmoving.c.

300Axiom non_moving
∀ s m s′ m′
safepoints m s′ m′

At a safepoint each stored capability (in the aux) stays, or, if its object was freed, becomes one that traps as a freed object does: the collector's free singleton. The model needs it so that a pointer loaded back after a collection behaves as the one stored, reading or trapping alike. Native test: axiom − aux.c.

309Axiom aux_round_trip
∀ s m s′ m′ a
safepoints m s′ m′
m_auxm′ a = m_auxm a ∨ freed_inm_regionsm′ m_auxm a ∧ traps_as_freedm_regionsm′ m_auxm′ a

At a safepoint the collector reclaims no identity the program can name: every object of m is still one of m'. The model needs it because a capability never dies in the model, so the object it names must stay. It follows from collector_live. Native test: axiom − rooting.c.

320Lemma rooting
∀ s m s′ m′ b
safepoints m s′ m′
object_regionb m_regionsm′ ≠ None
Explore proof 3 tactics

Initial goal

⊢
∀s : state m : mem s′ : state m′ : mem, safepoints m s′ m′ → ∀b : Z, object_regionb m_regionsm ≠ None → object_regionb m_regionsm′ ≠ None

intros s m s′ m′ H b

m :
s′ :
m′ :
H :
safepoints m s′ m′
b :
Z
⊢
object_regionb m_regionsm ≠ None → object_regionb m_regionsm′ ≠ None

rewrite collector_lives m s′ m′ H

m :
s′ :
m′ :
H :
safepoints m s′ m′
b :
Z
⊢
object_regionb m_regionsm ≠ None → object_regionb m_regionsm ≠ None

auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros s m s′ m′ H b
rewrite collector_lives m s′ m′ H
auto

The runtime's actions at a safepoint keep it ready. With fresh_allocation and ready_kept this makes ready hold in every state of a run (Machine.v). No native test: it is about the runtime's own bookkeeping.

329Axiom safepoint_ready
∀ s m s′ m′
safepoints m s′ m′
readys′ m′

Facts about Memory.v

Removing the object at base from the regions rs leaves every other base b's object as it was.

337Lemma object_region_remove
∀ b base rs
b ≠ base
Explore proof 9 tactics

Initial goal

⊢
∀b base : Z rs : listregion, b ≠ base → object_regionb remove_regionbase rs = object_regionb rs

intros b base rs Hne

b, base :
Z
rs :
listregion
Hne :
b ≠ base

induction rs as | r rs IH ; simpl ; auto

b, base :
Z
rs :
listregion
Hne :
b ≠ base
⊢
r_baser =? base
→
rs
else
r :: remove_regionbase rs
=
r_baser =? b
→
Somer

destruct Z.eqbr_baser base eqn: E

2 open

b, base :
Z
rs :
listregion
Hne :
b ≠ base
E :
r_baser =? base = true
⊢
=
r_baser =? b
→
Somer
focused goal
b, base :
Z
rs :
listregion
Hne :
b ≠ base
E :
r_baser =? base = false
⊢
=
r_baser =? b
→
Somer

–apply Z.eqb_eq in E

2 open

b, base :
Z
rs :
listregion
Hne :
b ≠ base
E :
r_baser = base
⊢
=
r_baser =? b
→
Somer
deferred goal
b, base :
Z
rs :
listregion
Hne :
b ≠ base
E :
r_baser =? base = false
⊢
=
r_baser =? b
→
Somer

destruct Z.eqbr_baser b eqn: E2 ; auto

2 open

b, base :
Z
rs :
listregion
Hne :
b ≠ base
E :
r_baser = base
E2 :
r_baser =? b = true
⊢
object_regionb rs = Somer
deferred goal
b, base :
Z
rs :
listregion
Hne :
b ≠ base
E :
r_baser =? base = false
⊢
=
r_baser =? b
→
Somer

apply Z.eqb_eq in E2

2 open

b, base :
Z
rs :
listregion
Hne :
b ≠ base
E :
r_baser = base
E2 :
r_baser = b
⊢
object_regionb rs = Somer
deferred goal
b, base :
Z
rs :
listregion
Hne :
b ≠ base
E :
r_baser =? base = false
⊢
=
r_baser =? b
→
Somer

lia

deferred goal
b, base :
Z
rs :
listregion
Hne :
b ≠ base
E :
r_baser =? base = false
⊢
=
r_baser =? b
→
Somer

–simpl

b, base :
Z
rs :
listregion
Hne :
b ≠ base
E :
r_baser =? base = false
⊢
r_baser =? b
→
Somer
=
r_baser =? b
→
Somer

destruct Z.eqbr_baser b ; auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros b base rs Hne
induction rs as | r rs IH ; simpl ; auto
destruct Z.eqbr_baser base eqn: E
–apply Z.eqb_eq in E
destruct Z.eqbr_baser b eqn: E2 ; auto
apply Z.eqb_eq in E2
lia
–simpl
destruct Z.eqbr_baser b ; auto

If replacing the object at base by the region r, whose base is base, gives rs', then the object at base in rs' is r and every other object is as in rs.

350Lemma object_region_replace
∀ base r rs rs′ b
replace_regionbase r rs = Somers′
r_baser = base
=
Z.eqbb base
→
Somer
Explore proof 14 tactics

Initial goal

⊢
∀ base : Z r : region rs rs′ : listregion b : Z  ,
replace_regionbase r rs = Somers′
→
r_baser = base
→
=
b =? base
→
Somer

unfold replace_region

⊢
∀ base : Z r : region rs rs′ : listregion b : Z  ,
match object_regionbase rs with
Some_
⇒
Somer :: remove_regionbase rs
None
⇒
None
=
Somers′
→
r_baser = base
→
=
b =? base
→
Somer

intros base r rs rs′ b H Hr

base :
Z
rs, rs′ :
listregion
b :
Z
H :
match object_regionbase rs with
Some_
⇒
Somer :: remove_regionbase rs
None
⇒
None
=
Somers′
Hr :
r_baser = base
⊢
=
b =? base
→
Somer

destruct object_regionbase rs ; inversion H ; subst ; clear H

rs :
listregion
b :
Z
r0 :
⊢
=
b =? r_baser
→
Somer

simpl

rs :
listregion
b :
Z
r0 :
⊢
=
b =? r_baser
→
Somer

destruct Z.eqbb r_baser eqn: E

2 open

rs :
listregion
b :
Z
r0 :
E :
b =? r_baser = true
⊢
=
Somer
focused goal
rs :
listregion
b :
Z
r0 :
E :
b =? r_baser = false

–apply Z.eqb_eq in E

2 open

rs :
listregion
b :
Z
r0 :
E :
b = r_baser
⊢
=
Somer
deferred goal
rs :
listregion
b :
Z
r0 :
E :
b =? r_baser = false

subst

2 open

rs :
listregion
r0 :
⊢
deferred goal
rs :
listregion
b :
Z
r0 :
E :
b =? r_baser = false

rewrite Z.eqb_refl

2 open

rs :
listregion
r0 :
⊢
Somer = Somer
deferred goal
rs :
listregion
b :
Z
r0 :
E :
b =? r_baser = false

reflexivity

deferred goal
rs :
listregion
b :
Z
r0 :
E :
b =? r_baser = false

–assert b ≠ r_baser by apply Z.eqb_neq ; auto

rs :
listregion
b :
Z
r0 :
E :
b =? r_baser = false
H :
b ≠ r_baser

destruct Z.eqbr_baser b eqn: E2

2 open

rs :
listregion
b :
Z
r0 :
E :
b =? r_baser = false
H :
b ≠ r_baser
E2 :
r_baser =? b = true
⊢
Somer = object_regionb rs
focused goal
rs :
listregion
b :
Z
r0 :
E :
b =? r_baser = false
H :
b ≠ r_baser
E2 :
r_baser =? b = false

+apply Z.eqb_eq in E2

2 open

rs :
listregion
b :
Z
r0 :
E :
b =? r_baser = false
H :
b ≠ r_baser
E2 :
r_baser = b
⊢
Somer = object_regionb rs
deferred goal
rs :
listregion
b :
Z
r0 :
E :
b =? r_baser = false
H :
b ≠ r_baser
E2 :
r_baser =? b = false

lia

deferred goal
rs :
listregion
b :
Z
r0 :
E :
b =? r_baser = false
H :
b ≠ r_baser
E2 :
r_baser =? b = false

+apply object_region_remove ; auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros base r rs rs′ b H Hr
destruct object_regionbase rs ; inversion H ; subst ; clear H
simpl
destruct Z.eqbb r_baser eqn: E
–apply Z.eqb_eq in E
subst
rewrite Z.eqb_refl
reflexivity
–assert b ≠ r_baser by apply Z.eqb_neq ; auto
destruct Z.eqbr_baser b eqn: E2
+apply Z.eqb_eq in E2
lia
+apply object_region_remove ; auto

What Memory.v's free_res (free_res/4) may do: change nothing, or free one live heap object, emptying its bounds, and change nothing else.

367Lemma free_res_frees
∀ x m r m′
free_resx m = Somer, m′
m′ = m ∨ ∃base reg, object_regionbase m_regionsm = Somereg ∧ r_kindreg = Heap ∧ r_lifereg = Live ∧ replace_regionbase mkRegionbase base Heap Freed m_regionsm = Somem_regionsm′ ∧ m_bytesm′ = m_bytesm ∧ m_auxm′ = m_auxm
Explore proof 5 tactics

Initial goal

⊢
∀x : word m : mem r : resunit m′ : mem, free_resx m = Somer, m′ → m′ = m ∨ ∃base : Z reg : region, object_regionbase m_regionsm = Somereg ∧ r_kindreg = Heap ∧ r_lifereg = Live ∧ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′ ∧ m_bytesm′ = m_bytesm ∧ m_auxm′ = m_auxm

intros x m r m′ H

x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
⊢
m′ = m ∨ ∃base : Z reg : region, object_regionbase m_regionsm = Somereg ∧ r_kindreg = Heap ∧ r_lifereg = Live ∧ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′ ∧ m_bytesm′ = m_bytesm ∧ m_auxm′ = m_auxm

destruct x as a | p | c size ; simpl in H ; try discriminate

2 open

a :
Z
m :
r :
resunit
m′ :
H :
Some
a =? 0
→
m
=
Somer, m′
⊢
m′ = m ∨ ∃base : Z reg : region, object_regionbase m_regionsm = Somereg ∧ r_kindreg = Heap ∧ r_lifereg = Live ∧ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′ ∧ m_bytesm′ = m_bytesm ∧ m_auxm′ = m_auxm
focused goal
p :
m :
r :
resunit
m′ :
H :
cap_free_resptr_capp ptr_addrp m = Somer, m′
⊢
m′ = m ∨ ∃base : Z reg : region, object_regionbase m_regionsm = Somereg ∧ r_kindreg = Heap ∧ r_lifereg = Live ∧ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′ ∧ m_bytesm′ = m_bytesm ∧ m_auxm′ = m_auxm

–inversion H ; auto

deferred goal
p :
m :
r :
resunit
m′ :
H :
cap_free_resptr_capp ptr_addrp m = Somer, m′
⊢
m′ = m ∨ ∃base : Z reg : region, object_regionbase m_regionsm = Somereg ∧ r_kindreg = Heap ∧ r_lifereg = Live ∧ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′ ∧ m_bytesm′ = m_bytesm ∧ m_auxm′ = m_auxm

–unfold cap_free_res in H

p :
m :
r :
resunit
m′ :
H :
match ptr_capp with
Objbase | Robase
⇒
⇒
None
_
⇒
Some
=
Somer, m′
⊢
m′ = m ∨ ∃base : Z reg : region, object_regionbase m_regionsm = Somereg ∧ r_kindreg = Heap ∧ r_lifereg = Live ∧ replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′ ∧ m_bytesm′ = m_bytesm ∧ m_auxm′ = m_auxm

destruct ptr_capp as | base | base | f | n ; try inversion H ; auto ; fail ; try discriminate ; unfold object_free_res in H ; destruct Z.eqbptr_addrp 0 ; try inversion H ; auto ; fail ; destruct object_regionbase m_regionsm as reg | eqn: Ereg ; try discriminate ; destruct kind_eqbr_kindreg Heap eqn: Ek ; simpl in H ; try inversion H ; auto ; fail ; destruct Z.eqbptr_addrp base ; simpl in H ; try inversion H ; auto ; fail ; destruct r_lifereg eqn: El ; try inversion H ; auto ; fail ; destruct replace_regionbase mkRegionbase base Heap Freed m_regionsm as rs | eqn: Er ; try discriminate ; inversion H ; subst ; right ; exists base, reg ; split ; auto | ; split ; destruct r_kindreg ; simpl in Ek ; congruence | ; simpl ; auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros x m r m′ H
destruct x as a | p | c size ; simpl in H ; try discriminate
–inversion H ; auto
–unfold cap_free_res in H
destruct ptr_capp as | base | base | f | n ; try inversion H ; auto ; fail ; try discriminate ; unfold object_free_res in H ; destruct Z.eqbptr_addrp 0 ; try inversion H ; auto ; fail ; destruct object_regionbase m_regionsm as reg | eqn: Ereg ; try discriminate ; destruct kind_eqbr_kindreg Heap eqn: Ek ; simpl in H ; try inversion H ; auto ; fail ; destruct Z.eqbptr_addrp base ; simpl in H ; try inversion H ; auto ; fail ; destruct r_lifereg eqn: El ; try inversion H ; auto ; fail ; destruct replace_regionbase mkRegionbase base Heap Freed m_regionsm as rs | eqn: Er ; try discriminate ; inversion H ; subst ; right ; exists base, reg ; split ; auto | ; split ; destruct r_kindreg ; simpl in Ek ; congruence | ; simpl ; auto

free_res changes objects only as lifetime_step allows: the interpreter's proof of free_lifetime.

394Lemma free_res_lifetime
∀ x m r m′
free_resx m = Somer, m′
Explore proof 15 tactics

Initial goal

⊢
∀x : word m : mem r : resunit m′ : mem, free_resx m = Somer, m′ → lifetime_stepm m′

intros x m r m′ H

x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
⊢

destruct free_res_freesx m r m′ H as → | base & reg & Hreg & Hk & Hl & Hr & _

2 open

x :
m :
r :
resunit
H :
free_resx m = Somer, m
focused goal
x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
base :
Z
reg :
Hreg :
object_regionbase m_regionsm = Somereg
Hk :
r_kindreg = Heap
Hl :
r_lifereg = Live
Hr :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′
⊢

–intros b reg′ Hb

2 open

x :
m :
r :
resunit
H :
free_resx m = Somer, m
b :
Z
reg′ :
Hb :
object_regionb m_regionsm = Somereg′
⊢
∃reg : region, object_regionb m_regionsm = Somereg ∧ reg′ = reg ∨ r_kindreg = Heap ∧ r_lifereg = Live ∧ reg′ = r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed
deferred goal
x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
base :
Z
reg :
Hreg :
object_regionbase m_regionsm = Somereg
Hk :
r_kindreg = Heap
Hl :
r_lifereg = Live
Hr :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′
⊢

exists reg′

2 open

x :
m :
r :
resunit
H :
free_resx m = Somer, m
b :
Z
reg′ :
Hb :
object_regionb m_regionsm = Somereg′
⊢
object_regionb m_regionsm = Somereg′ ∧ reg′ = reg′ ∨ r_kindreg′ = Heap ∧ r_lifereg′ = Live ∧ reg′ = r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed
deferred goal
x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
base :
Z
reg :
Hreg :
object_regionbase m_regionsm = Somereg
Hk :
r_kindreg = Heap
Hl :
r_lifereg = Live
Hr :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′
⊢

auto

deferred goal
x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
base :
Z
reg :
Hreg :
object_regionbase m_regionsm = Somereg
Hk :
r_kindreg = Heap
Hl :
r_lifereg = Live
Hr :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′
⊢

–intros b reg′ Hb

x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
base :
Z
reg :
Hreg :
object_regionbase m_regionsm = Somereg
Hk :
r_kindreg = Heap
Hl :
r_lifereg = Live
Hr :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′
b :
Z
reg′ :
Hb :
object_regionb m_regionsm′ = Somereg′
⊢
∃reg0 : region, object_regionb m_regionsm = Somereg0 ∧ reg′ = reg0 ∨ r_kindreg0 = Heap ∧ r_lifereg0 = Live ∧ reg′ = r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed

rewrite object_region_replace_ _ _ _ b Hr eq_refl in Hb

x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
base :
Z
reg :
Hreg :
object_regionbase m_regionsm = Somereg
Hk :
r_kindreg = Heap
Hl :
r_lifereg = Live
Hr :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′
b :
Z
reg′ :
Hb :
b =? base
→
Somer_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed
=
Somereg′
⊢
∃reg0 : region, object_regionb m_regionsm = Somereg0 ∧ reg′ = reg0 ∨ r_kindreg0 = Heap ∧ r_lifereg0 = Live ∧ reg′ = r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed

destruct Z.eqbb base eqn: E

2 open

x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
base :
Z
reg :
Hreg :
object_regionbase m_regionsm = Somereg
Hk :
r_kindreg = Heap
Hl :
r_lifereg = Live
Hr :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′
b :
Z
reg′ :
E :
b =? base = true
Hb :
Somer_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed = Somereg′
⊢
∃reg0 : region, object_regionb m_regionsm = Somereg0 ∧ reg′ = reg0 ∨ r_kindreg0 = Heap ∧ r_lifereg0 = Live ∧ reg′ = r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed
focused goal
x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
base :
Z
reg :
Hreg :
object_regionbase m_regionsm = Somereg
Hk :
r_kindreg = Heap
Hl :
r_lifereg = Live
Hr :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′
b :
Z
reg′ :
E :
b =? base = false
Hb :
object_regionb m_regionsm = Somereg′
⊢
∃reg0 : region, object_regionb m_regionsm = Somereg0 ∧ reg′ = reg0 ∨ r_kindreg0 = Heap ∧ r_lifereg0 = Live ∧ reg′ = r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed

+apply Z.eqb_eq in E

2 open

x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
base :
Z
reg :
Hreg :
object_regionbase m_regionsm = Somereg
Hk :
r_kindreg = Heap
Hl :
r_lifereg = Live
Hr :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′
b :
Z
reg′ :
E :
b = base
Hb :
Somer_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed = Somereg′
⊢
∃reg0 : region, object_regionb m_regionsm = Somereg0 ∧ reg′ = reg0 ∨ r_kindreg0 = Heap ∧ r_lifereg0 = Live ∧ reg′ = r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed
deferred goal
x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
base :
Z
reg :
Hreg :
object_regionbase m_regionsm = Somereg
Hk :
r_kindreg = Heap
Hl :
r_lifereg = Live
Hr :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′
b :
Z
reg′ :
E :
b =? base = false
Hb :
object_regionb m_regionsm = Somereg′
⊢
∃reg0 : region, object_regionb m_regionsm = Somereg0 ∧ reg′ = reg0 ∨ r_kindreg0 = Heap ∧ r_lifereg0 = Live ∧ reg′ = r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed

subst

2 open

x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
base :
Z
reg :
Hreg :
object_regionbase m_regionsm = Somereg
Hk :
r_kindreg = Heap
Hl :
r_lifereg = Live
Hr :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′
reg′ :
Hb :
Somer_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed = Somereg′
⊢
∃reg0 : region, object_regionbase m_regionsm = Somereg0 ∧ reg′ = reg0 ∨ r_kindreg0 = Heap ∧ r_lifereg0 = Live ∧ reg′ = r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed
deferred goal
x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
base :
Z
reg :
Hreg :
object_regionbase m_regionsm = Somereg
Hk :
r_kindreg = Heap
Hl :
r_lifereg = Live
Hr :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′
b :
Z
reg′ :
E :
b =? base = false
Hb :
object_regionb m_regionsm = Somereg′
⊢
∃reg0 : region, object_regionb m_regionsm = Somereg0 ∧ reg′ = reg0 ∨ r_kindreg0 = Heap ∧ r_lifereg0 = Live ∧ reg′ = r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed

inversion Hb ; subst

2 open

x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
base :
Z
reg :
Hreg :
object_regionbase m_regionsm = Somereg
Hk :
r_kindreg = Heap
Hl :
r_lifereg = Live
Hr :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′
Hb :
Somer_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed = Somer_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed
⊢
∃reg0 : region, object_regionbase m_regionsm = Somereg0 ∧ r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed = reg0 ∨ r_kindreg0 = Heap ∧ r_lifereg0 = Live ∧ r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed = r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed
deferred goal
x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
base :
Z
reg :
Hreg :
object_regionbase m_regionsm = Somereg
Hk :
r_kindreg = Heap
Hl :
r_lifereg = Live
Hr :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′
b :
Z
reg′ :
E :
b =? base = false
Hb :
object_regionb m_regionsm = Somereg′
⊢
∃reg0 : region, object_regionb m_regionsm = Somereg0 ∧ reg′ = reg0 ∨ r_kindreg0 = Heap ∧ r_lifereg0 = Live ∧ reg′ = r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed

exists reg

2 open

x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
base :
Z
reg :
Hreg :
object_regionbase m_regionsm = Somereg
Hk :
r_kindreg = Heap
Hl :
r_lifereg = Live
Hr :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′
Hb :
Somer_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed = Somer_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed
⊢
object_regionbase m_regionsm = Somereg ∧ r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed = reg ∨ r_kindreg = Heap ∧ r_lifereg = Live ∧ r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed = r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed
deferred goal
x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
base :
Z
reg :
Hreg :
object_regionbase m_regionsm = Somereg
Hk :
r_kindreg = Heap
Hl :
r_lifereg = Live
Hr :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′
b :
Z
reg′ :
E :
b =? base = false
Hb :
object_regionb m_regionsm = Somereg′
⊢
∃reg0 : region, object_regionb m_regionsm = Somereg0 ∧ reg′ = reg0 ∨ r_kindreg0 = Heap ∧ r_lifereg0 = Live ∧ reg′ = r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed

auto

deferred goal
x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
base :
Z
reg :
Hreg :
object_regionbase m_regionsm = Somereg
Hk :
r_kindreg = Heap
Hl :
r_lifereg = Live
Hr :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′
b :
Z
reg′ :
E :
b =? base = false
Hb :
object_regionb m_regionsm = Somereg′
⊢
∃reg0 : region, object_regionb m_regionsm = Somereg0 ∧ reg′ = reg0 ∨ r_kindreg0 = Heap ∧ r_lifereg0 = Live ∧ reg′ = r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed

+exists reg′

x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
base :
Z
reg :
Hreg :
object_regionbase m_regionsm = Somereg
Hk :
r_kindreg = Heap
Hl :
r_lifereg = Live
Hr :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′
b :
Z
reg′ :
E :
b =? base = false
Hb :
object_regionb m_regionsm = Somereg′
⊢
object_regionb m_regionsm = Somereg′ ∧ reg′ = reg′ ∨ r_kindreg′ = Heap ∧ r_lifereg′ = Live ∧ reg′ = r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed

auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros x m r m′ H
destruct free_res_freesx m r m′ H as → | base & reg & Hreg & Hk & Hl & Hr & _
–intros b reg′ Hb
exists reg′
auto
–intros b reg′ Hb
rewrite object_region_replace_ _ _ _ b Hr eq_refl in Hb
destruct Z.eqbb base eqn: E
+apply Z.eqb_eq in E
subst
inversion Hb ; subst
exists reg
auto
+exists reg′
auto

Every identity before a free_res is one after it: the interpreter's proof of free_keeps_ids.

407Lemma free_res_keeps_ids
∀ x m r m′ b
free_resx m = Somer, m′
object_regionb m_regionsm′ ≠ None
Explore proof 4 tactics

Initial goal

⊢
∀x : word m : mem r : resunit m′ : mem, free_resx m = Somer, m′ → ∀b : Z, object_regionb m_regionsm ≠ None → object_regionb m_regionsm′ ≠ None

intros x m r m′ H b Hb

x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
b :
Z
Hb :
⊢
object_regionb m_regionsm′ ≠ None

destruct free_res_freesx m r m′ H as → | base & reg & _ & _ & _ & Hr & _ ; exact Hb |

x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
b :
Z
Hb :
base :
Z
reg :
Hr :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′
⊢
object_regionb m_regionsm′ ≠ None

rewrite object_region_replace_ _ _ _ b Hr eq_refl

x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
b :
Z
Hb :
base :
Z
reg :
Hr :
replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somem_regionsm′
⊢
b =? base
→
Somer_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed
≠
None

destruct Z.eqbb base ; discriminate | exact Hb

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros x m r m′ H b Hb
destruct free_res_freesx m r m′ H as → | base & reg & _ & _ & _ & Hr & _ ; exact Hb |
rewrite object_region_replace_ _ _ _ b Hr eq_refl
destruct Z.eqbb base ; discriminate | exact Hb

free_res (free_res/4) answers ok or a trap, never unchecked: the interpreter's proof of free_checked.

417Lemma free_res_checked
∀ x m w m′
free_resx m ≠ SomeRUncheckedw, m′
Explore proof 4 tactics

Initial goal

⊢
∀x : word m : mem w : reason m′ : mem, free_resx m ≠ SomeRUncheckedw, m′

intros x m w m′ H

x :
m :
m′ :
H :
free_resx m = SomeRUncheckedw, m′
⊢
False

unfold free_res , cap_free_res , object_free_res in H

x :
m :
m′ :
H :
match x with
⇒
Some
a =? 0
→
m
⇒
match ptr_capp with
Objbase | Robase
⇒
ptr_addrp =? 0
→
Someok, m
else
match object_regionbase m_regionsm with
Somereg
⇒
negbptr_addrp =? base
→
else
match r_lifereg with
⇒
match replace_regionbase r_base ≔ base; r_end ≔ base; r_kind ≔ Heap; r_life ≔ Freed m_regionsm with
Somers
⇒
Someok, m_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
None
⇒
None
None
⇒
None
⇒
None
_
⇒
Some
⇒
None
=
SomeRUncheckedw, m′
⊢
False

repeat match type of H withcontext [match ?y with _ ⇒ _ end]⇒destruct y ; try discriminate Hend

No remaining goals.

all: injection H as H ; discriminate H

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros x m w m′ H
repeat match type of H withcontext [match ?y with _ ⇒ _ end]⇒destruct y ; try discriminate Hend
all: injection H as H ; discriminate H

free_res changes no byte and no stored capability: the interpreter's proof of retention.

428Lemma free_res_retention
∀ x m r m′
free_resx m = Somer, m′
m_bytesm′ = m_bytesm ∧ m_auxm′ = m_auxm
Explore proof 2 tactics

Initial goal

⊢
∀x : word m : mem r : resunit m′ : mem, free_resx m = Somer, m′ → m_bytesm′ = m_bytesm ∧ m_auxm′ = m_auxm

intros x m r m′ H

x :
m :
r :
resunit
m′ :
H :
free_resx m = Somer, m′
⊢
m_bytesm′ = m_bytesm ∧ m_auxm′ = m_auxm

destruct free_res_freesx m r m′ H as → | _ & _ & _ & _ & _ & _ & Hb & Ha ; auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros x m r m′ H
destruct free_res_freesx m r m′ H as → | _ & _ & _ & _ & _ & _ & Hb & Ha ; auto

free_res frees null and a live heap object's base as frees_heap says: the interpreter's proof of free_succeeds.

436Lemma free_res_succeeds
Explore proof 14 tactics

Initial goal

split ; reflexivity |

⊢
∀m : mem b : Z reg : region, object_regionb m_regionsm = Somereg ∧ r_lifereg = Live → r_kindreg = Heap → b ≠ 0 → ∃rs : listregion, replace_regionb r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somers ∧ free_resWPtrptr_addr ≔ b; ptr_cap ≔ Objb m = Someok, m_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm

intros m b reg Ereg Hlive Hk Hb

m :
b :
Z
reg :
Ereg :
Hlive :
r_lifereg = Live
Hk :
r_kindreg = Heap
Hb :
b ≠ 0
⊢
∃rs : listregion, replace_regionb r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed m_regionsm = Somers ∧ free_resWPtrptr_addr ≔ b; ptr_cap ≔ Objb m = Someok, m_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm

unfold replace_region

m :
b :
Z
reg :
Ereg :
Hlive :
r_lifereg = Live
Hk :
r_kindreg = Heap
Hb :
b ≠ 0
⊢
∃ rs : listregion  ,
Some_
⇒
Somer_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed :: remove_regionb m_regionsm
None
⇒
None
=
Somers
∧
free_resWPtrptr_addr ≔ b; ptr_cap ≔ Objb m = Someok, m_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm

rewrite Ereg

m :
b :
Z
reg :
Ereg :
Hlive :
r_lifereg = Live
Hk :
r_kindreg = Heap
Hb :
b ≠ 0
⊢
∃rs : listregion, Somer_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed :: remove_regionb m_regionsm = Somers ∧ free_resWPtrptr_addr ≔ b; ptr_cap ≔ Objb m = Someok, m_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm

eexists

2 open

m :
b :
Z
reg :
Ereg :
Hlive :
r_lifereg = Live
Hk :
r_kindreg = Heap
Hb :
b ≠ 0
⊢
Somer_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed :: remove_regionb m_regionsm = Some?rs ∧ free_resWPtrptr_addr ≔ b; ptr_cap ≔ Objb m = Someok, m_bytes ≔ m_bytesm; m_regions ≔ ?rs; m_aux ≔ m_auxm
shelved goal
m :
b :
Z
reg :
Ereg :
Hlive :
r_lifereg = Live
Hk :
r_kindreg = Heap
Hb :
b ≠ 0
⊢
listregion

split ; reflexivity |

m :
b :
Z
reg :
Ereg :
Hlive :
r_lifereg = Live
Hk :
r_kindreg = Heap
Hb :
b ≠ 0
⊢
free_resWPtrptr_addr ≔ b; ptr_cap ≔ Objb m = Someok, m_bytes ≔ m_bytesm; m_regions ≔ r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed :: remove_regionb m_regionsm; m_aux ≔ m_auxm

cbn

m :
b :
Z
reg :
Ereg :
Hlive :
r_lifereg = Live
Hk :
r_kindreg = Heap
Hb :
b ≠ 0
⊢
object_free_resb b m = Someok, m_bytes ≔ m_bytesm; m_regions ≔ r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed :: remove_regionb m_regionsm; m_aux ≔ m_auxm

unfold object_free_res

m :
b :
Z
reg :
Ereg :
Hlive :
r_lifereg = Live
Hk :
r_kindreg = Heap
Hb :
b ≠ 0
⊢
b =? 0
→
Someok, m
else
Somereg0
⇒
negbb =? b
→
else
match r_lifereg0 with
⇒
match replace_regionb r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed m_regionsm with
Somers
⇒
Someok, m_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
None
⇒
None
None
⇒
None
=
Someok, m_bytes ≔ m_bytesm; m_regions ≔ r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed :: remove_regionb m_regionsm; m_aux ≔ m_auxm

rewrite proj2Z.eqb_neqb 0 Hb

m :
b :
Z
reg :
Ereg :
Hlive :
r_lifereg = Live
Hk :
r_kindreg = Heap
Hb :
b ≠ 0
⊢
Somereg0
⇒
negbb =? b
→
else
match r_lifereg0 with
⇒
match replace_regionb r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed m_regionsm with
Somers
⇒
Someok, m_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
None
⇒
None
None
⇒
None
=
Someok, m_bytes ≔ m_bytesm; m_regions ≔ r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed :: remove_regionb m_regionsm; m_aux ≔ m_auxm

rewrite Ereg , Hk , Z.eqb_refl , Hlive

m :
b :
Z
reg :
Ereg :
Hlive :
r_lifereg = Live
Hk :
r_kindreg = Heap
Hb :
b ≠ 0
⊢
negbtrue
→
else
match replace_regionb r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed m_regionsm with
Somers
⇒
Someok, m_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
None
⇒
None
=
Someok, m_bytes ≔ m_bytesm; m_regions ≔ r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed :: remove_regionb m_regionsm; m_aux ≔ m_auxm

cbn

m :
b :
Z
reg :
Ereg :
Hlive :
r_lifereg = Live
Hk :
r_kindreg = Heap
Hb :
b ≠ 0
⊢
match replace_regionb r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed m_regionsm with
Somers
⇒
Someok, m_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
None
⇒
None
=
Someok, m_bytes ≔ m_bytesm; m_regions ≔ r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed :: remove_regionb m_regionsm; m_aux ≔ m_auxm

unfold replace_region

m :
b :
Z
reg :
Ereg :
Hlive :
r_lifereg = Live
Hk :
r_kindreg = Heap
Hb :
b ≠ 0
⊢
match match object_regionb m_regionsm with Some_ ⇒ Somer_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed :: remove_regionb m_regionsm | None ⇒ None end with
Somers
⇒
Someok, m_bytes ≔ m_bytesm; m_regions ≔ rs; m_aux ≔ m_auxm
None
⇒
None
=
Someok, m_bytes ≔ m_bytesm; m_regions ≔ r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed :: remove_regionb m_regionsm; m_aux ≔ m_auxm

rewrite Ereg

m :
b :
Z
reg :
Ereg :
Hlive :
r_lifereg = Live
Hk :
r_kindreg = Heap
Hb :
b ≠ 0
⊢
Someok, m_bytes ≔ m_bytesm; m_regions ≔ r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed :: remove_regionb m_regionsm; m_aux ≔ m_auxm = Someok, m_bytes ≔ m_bytesm; m_regions ≔ r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed :: remove_regionb m_regionsm; m_aux ≔ m_auxm

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
split ; reflexivity |
intros m b reg Ereg Hlive Hk Hb
rewrite Ereg
eexists
split ; reflexivity |
cbn
rewrite proj2Z.eqb_neqb 0 Hb
rewrite Ereg , Hk , Z.eqb_refl , Hlive
cbn
rewrite Ereg
reflexivity

The interpreter's runtime

a, rounded up to a multiple of a positive align, is at least a.

447Lemma align_up_ge
∀ a align
0 < align
a ≤ align_upa align
Explore proof 5 tactics

Initial goal

⊢
∀a align : Z, 0 < align → a ≤ align_upa align

intros a align H

a, align :
Z
H :
0 < align
⊢
a ≤ align_upa align

unfold align_up

a, align :
Z
H :
0 < align
⊢
a ≤ a + align − 1 / align × align

pose proof Z.div_moda + align − 1 align ltac:lia

a, align :
Z
H :
0 < align
H0 :
a + align − 1 = align × a + align − 1 / align + a + align − 1 mod align
⊢
a ≤ a + align − 1 / align × align

pose proof Z.mod_pos_bounda + align − 1 align H

a, align :
Z
H :
0 < align
H0 :
a + align − 1 = align × a + align − 1 / align + a + align − 1 mod align
H1 :
0 ≤ a + align − 1 mod align < align
⊢
a ≤ a + align − 1 / align × align

nia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros a align H
unfold align_up
pose proof Z.div_moda + align − 1 align ltac:lia
pose proof Z.mod_pos_bounda + align − 1 align H
nia

a, rounded up to a multiple of a positive align, is a multiple of align.

456Lemma align_up_mod
∀ a align
0 < align
align_upa align mod align = 0
Explore proof 4 tactics

Initial goal

⊢
∀a align : Z, 0 < align → align_upa align mod align = 0

intros a align H

a, align :
Z
H :
0 < align
⊢
align_upa align mod align = 0

unfold align_up

a, align :
Z
H :
0 < align
⊢
a + align − 1 / align × align mod align = 0

apply Z.mod_mul

a, align :
Z
H :
0 < align
⊢
align ≠ 0

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros a align H
unfold align_up
apply Z.mod_mul
lia

The interpreter's runtime: interp.pl's allocator (alloc_base/6), free as Memory.v states it (free_res), and no other thread or collector. It proves every axiom, so the module type is consistent; the extracted model is DriverInterpRuntime (Transport.v). It is left unsealed, so that what it does can be read off it; Transport.v's DriverInterpRuntime and Persistence.v's PersistenceInterpRuntime check it against Runtime.

467Module InterpRuntime

interp.pl's Next.

470Definition state ≔
Z

As stack_base/1: allocations start at 2^32, above the data.

473Definition start: state ≔
2 ^ 32

As address_space/2: Next stays at or below 2^48, libpas's address space (PAS_ADDRESS_BITS).

477Definition address_end: Z ≔
2 ^ 48

The interpreter, its Next being next, is ready in m: every object lies between 0 and Next, empty if freed, Next is within the address space, and nothing at or above Next has been written.

482Definition readynext : state m : mem : Prop ≔
0 < next ≤ address_end ∧ ∀b reg, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b ∧ ∀a, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone

As alloc_base/6: the base is Next rounded up to the request's alignment; Next then moves past the object, rounded up to 16, and a 16-byte gap. Where that would pass the address space's end, the runtime is out of memory.

492Definition allocnext : state q : alloc_req : optionZ × state ≔
let base ≔ align_upnext req_alignq in
let next′ ≔ base + align_upreq_extentq 16 + 16 in
next′ ≤? address_end
→
Somebase, next′
else
None

The interpreter's allocator gives a fresh base and stays ready: everything at or above Next is unwritten and owned by no object, and the new object lies there.

500Lemma fresh_allocation
∀ s m q base s′
0 < req_alignq
0 ≤ req_extentq
allocs q = Somebase, s′
freshm q base ∧ readys′ allocatedm q base
Explore proof 42 tactics

Initial goal

⊢
∀s : state m : mem q : alloc_req base : Z s′ : state, readys m → 0 < req_alignq → 0 ≤ req_extentq → allocs q = Somebase, s′ → freshm q base ∧ readys′ allocatedm q base

intros next m q base s′ Hpos & Hobj & Hbytes Ha He E

next :
m :
base :
Z
s′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
E :
allocnext q = Somebase, s′
⊢
freshm q base ∧ readys′ allocatedm q base

unfold alloc in E

next :
m :
base :
Z
s′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
E :
else
None
=
Somebase, s′
⊢
freshm q base ∧ readys′ allocatedm q base

destruct _ ≤? address_end eqn: Hend in E ; | discriminate E

next :
m :
base :
Z
s′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
Hend :
align_upnext req_alignq + align_upreq_extentq 16 + 16 ≤? address_end = true
E :
Somealign_upnext req_alignq, align_upnext req_alignq + align_upreq_extentq 16 + 16 = Somebase, s′
⊢
freshm q base ∧ readys′ allocatedm q base

injection E as ← ←

next :
m :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
Hend :
align_upnext req_alignq + align_upreq_extentq 16 + 16 ≤? address_end = true

apply Z.leb_le in Hend

next :
m :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
Hend :

unfold address_end in *

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
Hend :
align_upnext req_alignq + align_upreq_extentq 16 + 16 ≤ 2 ^ 48

pose proof align_up_genext req_alignq Ha as Hb

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
Hend :
align_upnext req_alignq + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ align_upnext req_alignq

pose proof align_up_gereq_extentq 16 ltac:lia as Hx

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
Hend :
align_upnext req_alignq + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ align_upnext req_alignq

set base := align_upnext req_alignq in *

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
freshm q base ∧ readybase + align_upreq_extentq 16 + 16 allocatedm q base

split

2 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
freshm q base
focused goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
readybase + align_upreq_extentq 16 + 16 allocatedm q base

–unfold fresh

2 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
0 < base ∧ base mod req_alignq = 0 ∧ base + req_extentq ≤ 2 ^ 64 ∧ object_regionbase m_regionsm = None ∧ ∀b : Z reg : region, object_regionb m_regionsm = Somereg → ¬base < r_endreg ∧ b < base + req_extentq ∧ ∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
readybase + align_upreq_extentq 16 + 16 allocatedm q base

split ; lia |

2 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
base mod req_alignq = 0 ∧ base + req_extentq ≤ 2 ^ 64 ∧ object_regionbase m_regionsm = None ∧ ∀b : Z reg : region, object_regionb m_regionsm = Somereg → ¬base < r_endreg ∧ b < base + req_extentq ∧ ∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
readybase + align_upreq_extentq 16 + 16 allocatedm q base

split ; apply align_up_mod ; auto |

2 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
base + req_extentq ≤ 2 ^ 64 ∧ object_regionbase m_regionsm = None ∧ ∀b : Z reg : region, object_regionb m_regionsm = Somereg → ¬base < r_endreg ∧ b < base + req_extentq ∧ ∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
readybase + align_upreq_extentq 16 + 16 allocatedm q base

split ; lia |

2 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
object_regionbase m_regionsm = None ∧ ∀b : Z reg : region, object_regionb m_regionsm = Somereg → ¬base < r_endreg ∧ b < base + req_extentq ∧ ∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
readybase + align_upreq_extentq 16 + 16 allocatedm q base

split

3 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
focused goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀b : Z reg : region, object_regionb m_regionsm = Somereg → ¬base < r_endreg ∧ b < base + req_extentq ∧ ∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
readybase + align_upreq_extentq 16 + 16 allocatedm q base

{destruct object_regionbase m_regionsm as reg | eqn: E ; auto

3 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
reg :
E :
object_regionbase m_regionsm = Somereg
⊢
Somereg = None
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀b : Z reg : region, object_regionb m_regionsm = Somereg → ¬base < r_endreg ∧ b < base + req_extentq ∧ ∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
readybase + align_upreq_extentq 16 + 16 allocatedm q base

destruct Hobj_ _ E

3 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
reg :
E :
object_regionbase m_regionsm = Somereg
H :
0 ≤ base < next
H0 :
r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = base
⊢
Somereg = None
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀b : Z reg : region, object_regionb m_regionsm = Somereg → ¬base < r_endreg ∧ b < base + req_extentq ∧ ∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
readybase + align_upreq_extentq 16 + 16 allocatedm q base

lia

2 open

deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀b : Z reg : region, object_regionb m_regionsm = Somereg → ¬base < r_endreg ∧ b < base + req_extentq ∧ ∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
readybase + align_upreq_extentq 16 + 16 allocatedm q base

split

3 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀b : Z reg : region, object_regionb m_regionsm = Somereg → ¬base < r_endreg ∧ b < base + req_extentq
focused goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
readybase + align_upreq_extentq 16 + 16 allocatedm q base

{intros b reg E H1 H2

3 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
b :
Z
reg :
E :
H1 :
base < r_endreg
H2 :
b < base + req_extentq
⊢
False
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
readybase + align_upreq_extentq 16 + 16 allocatedm q base

destruct Hobj_ _ E

3 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
b :
Z
reg :
E :
H1 :
base < r_endreg
H2 :
b < base + req_extentq
H :
0 ≤ b < next
H0 :
r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
⊢
False
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
readybase + align_upreq_extentq 16 + 16 allocatedm q base

lia

2 open

deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀a : Z, base ≤ a < base + req_extentq → m_bytesm a = 0 ∧ m_auxm a = CNone
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
readybase + align_upreq_extentq 16 + 16 allocatedm q base

intros a Hr

2 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
a :
Z
Hr :
base ≤ a < base + req_extentq
⊢
m_bytesm a = 0 ∧ m_auxm a = CNone
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
readybase + align_upreq_extentq 16 + 16 allocatedm q base

apply Hbytes

2 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
a :
Z
Hr :
base ≤ a < base + req_extentq
⊢
next ≤ a
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
readybase + align_upreq_extentq 16 + 16 allocatedm q base

lia

deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
readybase + align_upreq_extentq 16 + 16 allocatedm q base

–unfold ready , allocated , address_end

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
0 < base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48 ∧ ∀b : Z reg : region, object_regionb m_regionsm_bytes ≔ m_bytesm; m_regions ≔ r_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live :: m_regionsm; m_aux ≔ m_auxm = Somereg → 0 ≤ b < base + align_upreq_extentq 16 + 16 ∧ r_endreg ≤ base + align_upreq_extentq 16 + 16 ∧ r_lifereg = Freed → r_endreg = b ∧ ∀a : Z, base + align_upreq_extentq 16 + 16 ≤ a → m_bytesm_bytes ≔ m_bytesm; m_regions ≔ r_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live :: m_regionsm; m_aux ≔ m_auxm a = 0 ∧ m_auxm_bytes ≔ m_bytesm; m_regions ≔ r_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live :: m_regionsm; m_aux ≔ m_auxm a = CNone

simpl

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
0 < base + align_upreq_extentq 16 + 16 ≤ Z.pow_pos2 48
∧
∀ b : Z reg : region  ,
base =? b
→
Somer_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live
=
Somereg
→
0 ≤ b < base + align_upreq_extentq 16 + 16 ∧ r_endreg ≤ base + align_upreq_extentq 16 + 16 ∧ r_lifereg = Freed → r_endreg = b
∧
∀a : Z, base + align_upreq_extentq 16 + 16 ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone

split ; lia |

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀ b : Z reg : region  ,
base =? b
→
Somer_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live
=
Somereg
→
0 ≤ b < base + align_upreq_extentq 16 + 16 ∧ r_endreg ≤ base + align_upreq_extentq 16 + 16 ∧ r_lifereg = Freed → r_endreg = b
∧
∀a : Z, base + align_upreq_extentq 16 + 16 ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone

split

2 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀ b : Z reg : region  ,
base =? b
→
Somer_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live
=
Somereg
→
0 ≤ b < base + align_upreq_extentq 16 + 16 ∧ r_endreg ≤ base + align_upreq_extentq 16 + 16 ∧ r_lifereg = Freed → r_endreg = b
focused goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀a : Z, base + align_upreq_extentq 16 + 16 ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone

+intros b reg E

2 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
b :
Z
reg :
E :
base =? b
→
Somer_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live
=
Somereg
⊢
0 ≤ b < base + align_upreq_extentq 16 + 16 ∧ r_endreg ≤ base + align_upreq_extentq 16 + 16 ∧ r_lifereg = Freed → r_endreg = b
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀a : Z, base + align_upreq_extentq 16 + 16 ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone

destruct Z.eqbbase b eqn: Eb

3 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
b :
Z
reg :
Eb :
base =? b = true
E :
Somer_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live = Somereg
⊢
0 ≤ b < base + align_upreq_extentq 16 + 16 ∧ r_endreg ≤ base + align_upreq_extentq 16 + 16 ∧ r_lifereg = Freed → r_endreg = b
focused goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
b :
Z
reg :
Eb :
base =? b = false
E :
⊢
0 ≤ b < base + align_upreq_extentq 16 + 16 ∧ r_endreg ≤ base + align_upreq_extentq 16 + 16 ∧ r_lifereg = Freed → r_endreg = b
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀a : Z, base + align_upreq_extentq 16 + 16 ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone

∗injection E as ←

3 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
b :
Z
Eb :
base =? b = true
⊢
0 ≤ b < base + align_upreq_extentq 16 + 16 ∧ r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live ≤ base + align_upreq_extentq 16 + 16 ∧ r_lifer_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live = Freed → r_endr_base ≔ base; r_end ≔ base + req_extentq; r_kind ≔ req_kindq; r_life ≔ Live = b
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
b :
Z
reg :
Eb :
base =? b = false
E :
⊢
0 ≤ b < base + align_upreq_extentq 16 + 16 ∧ r_endreg ≤ base + align_upreq_extentq 16 + 16 ∧ r_lifereg = Freed → r_endreg = b
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀a : Z, base + align_upreq_extentq 16 + 16 ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone

simpl

3 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
b :
Z
Eb :
base =? b = true
⊢
0 ≤ b < base + align_upreq_extentq 16 + 16 ∧ base + req_extentq ≤ base + align_upreq_extentq 16 + 16 ∧ Live = Freed → base + req_extentq = b
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
b :
Z
reg :
Eb :
base =? b = false
E :
⊢
0 ≤ b < base + align_upreq_extentq 16 + 16 ∧ r_endreg ≤ base + align_upreq_extentq 16 + 16 ∧ r_lifereg = Freed → r_endreg = b
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀a : Z, base + align_upreq_extentq 16 + 16 ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone

apply Z.eqb_eq in Eb

3 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
b :
Z
Eb :
base = b
⊢
0 ≤ b < base + align_upreq_extentq 16 + 16 ∧ base + req_extentq ≤ base + align_upreq_extentq 16 + 16 ∧ Live = Freed → base + req_extentq = b
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
b :
Z
reg :
Eb :
base =? b = false
E :
⊢
0 ≤ b < base + align_upreq_extentq 16 + 16 ∧ r_endreg ≤ base + align_upreq_extentq 16 + 16 ∧ r_lifereg = Freed → r_endreg = b
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀a : Z, base + align_upreq_extentq 16 + 16 ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone

split ; lia |

3 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
b :
Z
Eb :
base = b
⊢
base + req_extentq ≤ base + align_upreq_extentq 16 + 16 ∧ Live = Freed → base + req_extentq = b
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
b :
Z
reg :
Eb :
base =? b = false
E :
⊢
0 ≤ b < base + align_upreq_extentq 16 + 16 ∧ r_endreg ≤ base + align_upreq_extentq 16 + 16 ∧ r_lifereg = Freed → r_endreg = b
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀a : Z, base + align_upreq_extentq 16 + 16 ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone

split ; lia | discriminate

2 open

deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
b :
Z
reg :
Eb :
base =? b = false
E :
⊢
0 ≤ b < base + align_upreq_extentq 16 + 16 ∧ r_endreg ≤ base + align_upreq_extentq 16 + 16 ∧ r_lifereg = Freed → r_endreg = b
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀a : Z, base + align_upreq_extentq 16 + 16 ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone

∗destruct Hobj_ _ E as ? & ? & Hf

2 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
b :
Z
reg :
Eb :
base =? b = false
E :
H :
0 ≤ b < next
H0 :
r_endreg ≤ next
Hf :
r_lifereg = Freed → r_endreg = b
⊢
0 ≤ b < base + align_upreq_extentq 16 + 16 ∧ r_endreg ≤ base + align_upreq_extentq 16 + 16 ∧ r_lifereg = Freed → r_endreg = b
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀a : Z, base + align_upreq_extentq 16 + 16 ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone

split ; lia |

2 open

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
b :
Z
reg :
Eb :
base =? b = false
E :
H :
0 ≤ b < next
H0 :
r_endreg ≤ next
Hf :
r_lifereg = Freed → r_endreg = b
⊢
r_endreg ≤ base + align_upreq_extentq 16 + 16 ∧ r_lifereg = Freed → r_endreg = b
deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀a : Z, base + align_upreq_extentq 16 + 16 ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone

split ; lia | exact Hf

deferred goal
next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
⊢
∀a : Z, base + align_upreq_extentq 16 + 16 ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone

+intros a Hr

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
a :
Z
Hr :
base + align_upreq_extentq 16 + 16 ≤ a
⊢
m_bytesm a = 0 ∧ m_auxm a = CNone

apply Hbytes

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Ha :
0 < req_alignq
He :
0 ≤ req_extentq
base :=
Hend :
base + align_upreq_extentq 16 + 16 ≤ 2 ^ 48
Hb :
next ≤ base
a :
Z
Hr :
base + align_upreq_extentq 16 + 16 ≤ a
⊢
next ≤ a

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros next m q base s′ Hpos & Hobj & Hbytes Ha He E
unfold alloc in E
destruct _ ≤? address_end eqn: Hend in E ; | discriminate E
injection E as ← ←
apply Z.leb_le in Hend
unfold address_end in *
pose proof align_up_genext req_alignq Ha as Hb
pose proof align_up_gereq_extentq 16 ltac:lia as Hx
set base := align_upnext req_alignq in *
split
–unfold fresh
split ; lia |
split ; apply align_up_mod ; auto |
split ; lia |
split
{destruct object_regionbase m_regionsm as reg | eqn: E ; auto
destruct Hobj_ _ E
lia
split
{intros b reg E H1 H2
destruct Hobj_ _ E
lia
intros a Hr
apply Hbytes
lia
simpl
split ; lia |
split
+intros b reg E
destruct Z.eqbbase b eqn: Eb
∗injection E as ←
simpl
apply Z.eqb_eq in Eb
split ; lia |
split ; lia | discriminate
∗destruct Hobj_ _ E as ? & ? & Hf
split ; lia |
split ; lia | exact Hf
+intros a Hr
apply Hbytes
lia

Objects lie between 0 and Next, which is within 2^48.

528Lemma address_space
Explore proof 4 tactics

Initial goal

⊢
∀s : state m : mem, readys m → objects_fitm_regionsm

intros next m Hpos & Hobj & _ b reg E

next :
m :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
b :
Z
reg :
E :
⊢
0 ≤ b ∧ r_endreg ≤ 2 ^ 48

destruct Hobj_ _ E as ? & ? & _

next :
m :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
b :
Z
reg :
E :
H :
0 ≤ b < next
H0 :
r_endreg ≤ next
⊢
0 ≤ b ∧ r_endreg ≤ 2 ^ 48

unfold address_end in *

next :
m :
Hpos :
0 < next ≤ 2 ^ 48
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
b :
Z
reg :
E :
H :
0 ≤ b < next
H0 :
r_endreg ≤ next
⊢
0 ≤ b ∧ r_endreg ≤ 2 ^ 48

lia

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros next m Hpos & Hobj & _ b reg E
destruct Hobj_ _ E as ? & ? & _
unfold address_end in *
lia

A freed object of a memory the interpreter is ready in is empty, as ready says.

535Lemma freed_bounds
Explore proof 2 tactics

Initial goal

⊢
∀s : state m : mem, readys m → freed_emptym_regionsm

intros next m _ & Hobj & _ b reg E

next :
m :
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
b :
Z
reg :
E :
⊢
r_lifereg = Freed → r_endreg = b

exact proj2proj2Hobj_ _ E

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros next m _ & Hobj & _ b reg E
exact proj2proj2Hobj_ _ E

Objects stay below Next as they end, and the program writes only inside them.

540Lemma ready_kept
∀ s m m′
keptm m′
readys m′
Explore proof 19 tactics

Initial goal

⊢
∀s : state m m′ : mem, readys m → keptm m′ → readys m′

intros next m m′ Hpos & Hobj & Hbytes Hreg & Hout

next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
⊢
readynext m′

split ; lia |

next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
⊢
∀b : Z reg : region, object_regionb m_regionsm′ = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b ∧ ∀a : Z, next ≤ a → m_bytesm′ a = 0 ∧ m_auxm′ a = CNone

split

2 open

next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
⊢
∀b : Z reg : region, object_regionb m_regionsm′ = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
focused goal
next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
⊢
∀a : Z, next ≤ a → m_bytesm′ a = 0 ∧ m_auxm′ a = CNone

–intros b reg′ E

2 open

next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
b :
Z
reg′ :
E :
object_regionb m_regionsm′ = Somereg′
⊢
0 ≤ b < next ∧ r_endreg′ ≤ next ∧ r_lifereg′ = Freed → r_endreg′ = b
deferred goal
next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
⊢
∀a : Z, next ≤ a → m_bytesm′ a = 0 ∧ m_auxm′ a = CNone

destruct Hreg_ _ E as reg & E0 & Hr

2 open

next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
b :
Z
reg′ :
E :
object_regionb m_regionsm′ = Somereg′
reg :
E0 :
Hr :
reg′ = reg ∨ r_lifereg = Live ∧ reg′ = r_base ≔ b; r_end ≔ b; r_kind ≔ r_kindreg; r_life ≔ Freed
⊢
0 ≤ b < next ∧ r_endreg′ ≤ next ∧ r_lifereg′ = Freed → r_endreg′ = b
deferred goal
next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
⊢
∀a : Z, next ≤ a → m_bytesm′ a = 0 ∧ m_auxm′ a = CNone

destruct Hobj_ _ E0 as ? & ? & Hf

2 open

next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
b :
Z
reg′ :
E :
object_regionb m_regionsm′ = Somereg′
reg :
E0 :
Hr :
reg′ = reg ∨ r_lifereg = Live ∧ reg′ = r_base ≔ b; r_end ≔ b; r_kind ≔ r_kindreg; r_life ≔ Freed
H :
0 ≤ b < next
H0 :
r_endreg ≤ next
Hf :
r_lifereg = Freed → r_endreg = b
⊢
0 ≤ b < next ∧ r_endreg′ ≤ next ∧ r_lifereg′ = Freed → r_endreg′ = b
deferred goal
next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
⊢
∀a : Z, next ≤ a → m_bytesm′ a = 0 ∧ m_auxm′ a = CNone

destruct Hr as → | _ & → ; simpl

3 open

next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
b :
Z
reg :
E :
object_regionb m_regionsm′ = Somereg
E0 :
H :
0 ≤ b < next
H0 :
r_endreg ≤ next
Hf :
r_lifereg = Freed → r_endreg = b
⊢
0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
focused goal
next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
b :
Z
reg :
E :
object_regionb m_regionsm′ = Somer_base ≔ b; r_end ≔ b; r_kind ≔ r_kindreg; r_life ≔ Freed
E0 :
H :
0 ≤ b < next
H0 :
r_endreg ≤ next
Hf :
r_lifereg = Freed → r_endreg = b
⊢
0 ≤ b < next ∧ b ≤ next ∧ Freed = Freed → b = b
deferred goal
next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
⊢
∀a : Z, next ≤ a → m_bytesm′ a = 0 ∧ m_auxm′ a = CNone

+split ; lia |

3 open

next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
b :
Z
reg :
E :
object_regionb m_regionsm′ = Somereg
E0 :
H :
0 ≤ b < next
H0 :
r_endreg ≤ next
Hf :
r_lifereg = Freed → r_endreg = b
⊢
r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
deferred goal
next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
b :
Z
reg :
E :
object_regionb m_regionsm′ = Somer_base ≔ b; r_end ≔ b; r_kind ≔ r_kindreg; r_life ≔ Freed
E0 :
H :
0 ≤ b < next
H0 :
r_endreg ≤ next
Hf :
r_lifereg = Freed → r_endreg = b
⊢
0 ≤ b < next ∧ b ≤ next ∧ Freed = Freed → b = b
deferred goal
next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
⊢
∀a : Z, next ≤ a → m_bytesm′ a = 0 ∧ m_auxm′ a = CNone

split ; lia | exact Hf

2 open

deferred goal
next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
b :
Z
reg :
E :
object_regionb m_regionsm′ = Somer_base ≔ b; r_end ≔ b; r_kind ≔ r_kindreg; r_life ≔ Freed
E0 :
H :
0 ≤ b < next
H0 :
r_endreg ≤ next
Hf :
r_lifereg = Freed → r_endreg = b
⊢
0 ≤ b < next ∧ b ≤ next ∧ Freed = Freed → b = b
deferred goal
next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
⊢
∀a : Z, next ≤ a → m_bytesm′ a = 0 ∧ m_auxm′ a = CNone

+split ; lia |

2 open

next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
b :
Z
reg :
E :
object_regionb m_regionsm′ = Somer_base ≔ b; r_end ≔ b; r_kind ≔ r_kindreg; r_life ≔ Freed
E0 :
H :
0 ≤ b < next
H0 :
r_endreg ≤ next
Hf :
r_lifereg = Freed → r_endreg = b
⊢
b ≤ next ∧ Freed = Freed → b = b
deferred goal
next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
⊢
∀a : Z, next ≤ a → m_bytesm′ a = 0 ∧ m_auxm′ a = CNone

split ; lia | reflexivity

deferred goal
next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
⊢
∀a : Z, next ≤ a → m_bytesm′ a = 0 ∧ m_auxm′ a = CNone

–intros a Ha

next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
a :
Z
Ha :
next ≤ a
⊢
m_bytesm′ a = 0 ∧ m_auxm′ a = CNone

assert Hn : ¬in_objectm a

2 open

next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
a :
Z
Ha :
next ≤ a
⊢
focused goal
next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
a :
Z
Ha :
next ≤ a
Hn :
⊢
m_bytesm′ a = 0 ∧ m_auxm′ a = CNone

{intros b & reg & E & Hr

2 open

next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
a :
Z
Ha :
next ≤ a
b :
Z
reg :
E :
Hr :
b ≤ a < r_endreg
⊢
False
deferred goal
next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
a :
Z
Ha :
next ≤ a
Hn :
⊢
m_bytesm′ a = 0 ∧ m_auxm′ a = CNone

destruct Hobj_ _ E

2 open

next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
a :
Z
Ha :
next ≤ a
b :
Z
reg :
E :
Hr :
b ≤ a < r_endreg
H :
0 ≤ b < next
H0 :
r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
⊢
False
deferred goal
next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
a :
Z
Ha :
next ≤ a
Hn :
⊢
m_bytesm′ a = 0 ∧ m_auxm′ a = CNone

lia

deferred goal
next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
a :
Z
Ha :
next ≤ a
Hn :
⊢
m_bytesm′ a = 0 ∧ m_auxm′ a = CNone

destruct Houta Hn as → →

next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
a :
Z
Ha :
next ≤ a
Hn :
⊢
m_bytesm a = 0 ∧ m_auxm a = CNone

apply Hbytes

next :
m, m′ :
Hpos :
0 < next ≤ address_end
Hobj :
∀b : Z reg : region, object_regionb m_regionsm = Somereg → 0 ≤ b < next ∧ r_endreg ≤ next ∧ r_lifereg = Freed → r_endreg = b
Hbytes :
∀a : Z, next ≤ a → m_bytesm a = 0 ∧ m_auxm a = CNone
Hreg :
Hout :
∀a : Z, ¬in_objectm a → m_bytesm′ a = m_bytesm a ∧ m_auxm′ a = m_auxm a
a :
Z
Ha :
next ≤ a
Hn :
⊢
next ≤ a

auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros next m m′ Hpos & Hobj & Hbytes Hreg & Hout
split ; lia |
split
–intros b reg′ E
destruct Hreg_ _ E as reg & E0 & Hr
destruct Hobj_ _ E0 as ? & ? & Hf
destruct Hr as → | _ & → ; simpl
+split ; lia |
split ; lia | exact Hf
+split ; lia |
split ; lia | reflexivity
–intros a Ha
assert Hn : ¬in_objectm a
{intros b & reg & E & Hr
destruct Hobj_ _ E
lia
destruct Houta Hn as → →
apply Hbytes
auto

Memory.v's free, the pinned runtime's as the interpreter has it.

553Definition free ≔

Free empties only a live heap object's bounds: free_res_lifetime.

557Definition free_lifetime ≔

Free changes no byte and no stored capability: free_res_retention.

560Definition retention ≔

Free reclaims no identity: free_res_keeps_ids.

562Definition free_keeps_ids ≔

Free never answers unchecked: free_res_checked.

564Definition free_checked ≔

Free succeeds on null and a live heap base: free_res_succeeds.

566Definition free_succeeds ≔

The interpreter's runtime may act wherever the compiler does not promise that it cannot.

570Definition at_safepointi : inst : bool ≔

A safepoint of the interpreter's runtime is not evidence preserving, by its definition.

574Lemma safepoints
∀ i
at_safepointi = true
Explore proof 3 tactics

Initial goal

⊢
∀i : inst, at_safepointi = true → evidence_preservingi = false

unfold at_safepoint

⊢
∀i : inst, negbevidence_preservingi = true → evidence_preservingi = false

intros i H

i :
H :
negbevidence_preservingi = true
⊢

destruct evidence_preservingi ; auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros i H
destruct evidence_preservingi ; auto

No other thread and no collector: nothing changes at a safepoint.

578Definition safepoints : state m : mem s′ : state m′ : mem : Prop ≔
s′ = s ∧ m′ = m

Nothing changes at a safepoint, so no region does.

581Lemma collector_live
∀ s m s′ m′
safepoints m s′ m′
Explore proof 2 tactics

Initial goal

⊢
∀s : state m : mem s′ : state m′ : mem, safepoints m s′ m′ → m_regionsm′ = m_regionsm

intros s m s′ m′ _ →

m :
s′ :

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros s m s′ m′ _ →
reflexivity

Nothing changes at a safepoint, so no object does.

585Lemma safepoint_lifetime
∀ s m s′ m′
safepoints m s′ m′
Explore proof 3 tactics

Initial goal

⊢
∀s : state m : mem s′ : state m′ : mem, safepoints m s′ m′ → lifetime_stepm m′

intros s m s′ m′ _ → b reg′ H

m :
s′ :
b :
Z
reg′ :
H :
object_regionb m_regionsm = Somereg′
⊢
∃reg : region, object_regionb m_regionsm = Somereg ∧ reg′ = reg ∨ r_kindreg = Heap ∧ r_lifereg = Live ∧ reg′ = r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed

exists reg′

m :
s′ :
b :
Z
reg′ :
H :
object_regionb m_regionsm = Somereg′
⊢
object_regionb m_regionsm = Somereg′ ∧ reg′ = reg′ ∨ r_kindreg′ = Heap ∧ r_lifereg′ = Live ∧ reg′ = r_base ≔ b; r_end ≔ b; r_kind ≔ Heap; r_life ≔ Freed

auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros s m s′ m′ _ → b reg′ H
exists reg′
auto

Nothing changes at a safepoint, so no byte does.

589Lemma non_moving
∀ s m s′ m′
safepoints m s′ m′
Explore proof 2 tactics

Initial goal

⊢
∀s : state m : mem s′ : state m′ : mem, safepoints m s′ m′ → m_bytesm′ = m_bytesm

intros s m s′ m′ _ →

m :
s′ :

reflexivity

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros s m s′ m′ _ →
reflexivity

Nothing changes at a safepoint, so every stored capability stays.

594Lemma aux_round_trip
∀ s m s′ m′ a
safepoints m s′ m′
m_auxm′ a = m_auxm a ∨ freed_inm_regionsm′ m_auxm a ∧ traps_as_freedm_regionsm′ m_auxm′ a
Explore proof 2 tactics

Initial goal

⊢
∀s : state m : mem s′ : state m′ : mem, safepoints m s′ m′ → ∀a : Z, m_auxm′ a = m_auxm a ∨ freed_inm_regionsm′ m_auxm a ∧ traps_as_freedm_regionsm′ m_auxm′ a

intros s m s′ m′ _ → a

m :
s′ :
a :
Z

auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros s m s′ m′ _ → a
auto

Nothing changes at a safepoint, so no identity is reclaimed.

602Lemma rooting
∀ s m s′ m′ b
safepoints m s′ m′
object_regionb m_regionsm′ ≠ None
Explore proof 2 tactics

Initial goal

⊢
∀s : state m : mem s′ : state m′ : mem, safepoints m s′ m′ → ∀b : Z, object_regionb m_regionsm ≠ None → object_regionb m_regionsm′ ≠ None

intros s m s′ m′ _ →

m :
s′ :
⊢
∀b : Z, object_regionb m_regionsm ≠ None → object_regionb m_regionsm ≠ None

auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros s m s′ m′ _ →
auto

Nothing changes at a safepoint, so the runtime stays ready.

608Lemma safepoint_ready
∀ s m s′ m′
safepoints m s′ m′
readys′ m′
Explore proof 2 tactics

Initial goal

⊢
∀s : state m : mem s′ : state m′ : mem, safepoints m s′ m′ → readys m → readys′ m′

intros s m s′ m′ → →

m :
⊢
readys m → readys m

auto

No remaining goals.

Qed

✓ Proof checked and closed by Rocq.

Source script
intros s m s′ m′ → →
auto