A set of capability labels, representing an "authority": they are the set of capabilities a program at most uses.
- empty : CapabilitySet
- cap : ℕ → CapabilitySet
- union : CapabilitySet → CapabilitySet → CapabilitySet
Instances For
Equations
- CC.CapabilitySet.instMembership = { mem := fun (C : CC.CapabilitySet) (l : ℕ) => CC.CapabilitySet.mem l C }
Equations
- CC.CapabilitySet.instEmptyCollection = { emptyCollection := CC.CapabilitySet.empty }
Equations
- CC.CapabilitySet.instUnion = { union := CC.CapabilitySet.union }
Equations
Instances For
Equations
- CC.CapabilitySet.instSingleton = { singleton := CC.CapabilitySet.singleton }
- refl {C : CapabilitySet} : C.Subset C
- empty {C : CapabilitySet} : CapabilitySet.empty.Subset C
- trans {C1 C2 C3 : CapabilitySet} : C1.Subset C2 → C2.Subset C3 → C1.Subset C3
- union_left {C1 C3 C2 : CapabilitySet} : C1.Subset C3 → C2.Subset C3 → (C1 ∪ C2).Subset C3
- union_right_left {C1 C2 : CapabilitySet} : C1.Subset (C1 ∪ C2)
- union_right_right {C1 C2 : CapabilitySet} : C1.Subset (C2 ∪ C1)
Instances For
Equations
- CC.CapabilitySet.instHasSubset = { Subset := CC.CapabilitySet.Subset }
If an element is in a set, then the singleton of that element is a subset of the set.
Instances For
Equations
- CC.CapabilitySet.«term_≈_» = Lean.ParserDescr.trailingNode `CC.CapabilitySet.«term_≈_» 50 51 (Lean.ParserDescr.binary `andthen (Lean.ParserDescr.symbol " ≈ ") (Lean.ParserDescr.cat `term 51))
Instances For
If C1 ≈ C2 and C2 ⊆ C, then C1 ⊆ C. This allows transferring subset through equivalence.
A heap value. It must be a simple value, with a reachability set computed.
- isVal : self.unwrap.IsSimpleVal
- reachability : CapabilitySet
Instances For
Convert IsSimpleVal to IsVal
Equations
- CC.Heap.instEmptyCollection = { emptyCollection := CC.Heap.empty }
Equations
- h.extend_cap l l' = if l' = l then some (CC.Cell.capability CC.CapabilityInfo.basic) else h l'
Instances For
Auxiliary relation: one cell subsumes another. For mutable cells, the boolean value is irrelevant.
Equations
- (CC.Cell.capability (CC.CapabilityInfo.mcell a)).subsumes (CC.Cell.capability (CC.CapabilityInfo.mcell a_1)) = True
- x✝¹.subsumes x✝ = (x✝¹ = x✝)
Instances For
Monotonicity of postconditions.
Instances For
Updating an mcell with another mcell creates a heap that subsumes the original.
- wf_empty {s : Sig} {H : Heap} : ∅.WfInHeap H
- wf_union {s : Sig} {C1 : CaptureSet s} {H : Heap} {C2 : CaptureSet s} : C1.WfInHeap H → C2.WfInHeap H → (C1 ∪ C2).WfInHeap H
- wf_var_free {s : Sig} {H : Heap} {val : Cell} {x : ℕ} : H x = some val → (var (Var.free x)).WfInHeap H
- wf_var_bound {s : Sig} {x : BVar s Kind.var} {H : Heap} : (var (Var.bound x)).WfInHeap H
- wf_cvar {s : Sig} {x : BVar s Kind.cvar} {H : Heap} : (cvar x).WfInHeap H
Instances For
- wf_top {x✝ : Sig} {H : Heap} : top.WfInHeap H
- wf_tvar {x✝ : Sig} {x : BVar x✝ Kind.tvar} {H : Heap} : (tvar x).WfInHeap H
- wf_arrow {x✝ : Sig} {T1 : Ty TySort.capt x✝} {H : Heap} {T2 : Ty TySort.exi (x✝,x)} : T1.WfInHeap H → T2.WfInHeap H → (T1.arrow T2).WfInHeap H
- wf_poly {x✝ : Sig} {T1 : Ty TySort.shape x✝} {H : Heap} {T2 : Ty TySort.exi (x✝,X)} : T1.WfInHeap H → T2.WfInHeap H → (T1.poly T2).WfInHeap H
- wf_cpoly {x✝ : Sig} {cb : CaptureBound x✝} {H : Heap} {T : Ty TySort.exi (x✝,C)} : cb.WfInHeap H → T.WfInHeap H → (cpoly cb T).WfInHeap H
- wf_unit {x✝ : Sig} {H : Heap} : unit.WfInHeap H
- wf_cap {x✝ : Sig} {H : Heap} : cap.WfInHeap H
- wf_bool {x✝ : Sig} {H : Heap} : bool.WfInHeap H
- wf_cell {x✝ : Sig} {H : Heap} : cell.WfInHeap H
- wf_capt {x✝ : Sig} {cs : CaptureSet x✝} {H : Heap} {T : Ty TySort.shape x✝} : cs.WfInHeap H → T.WfInHeap H → (capt cs T).WfInHeap H
- wf_exi {x✝ : Sig} {T : Ty TySort.capt (x✝,C)} {H : Heap} : T.WfInHeap H → T.exi.WfInHeap H
- wf_typ {x✝ : Sig} {T : Ty TySort.capt x✝} {H : Heap} : T.WfInHeap H → T.typ.WfInHeap H
Instances For
- wf_var {s : Sig} {x : Var Kind.var s} {H : Heap} : x.WfInHeap H → (var x).WfInHeap H
- wf_abs {s : Sig} {cs : CaptureSet s} {H : Heap} {T : Ty TySort.capt s} {e : Exp (s,x)} : cs.WfInHeap H → T.WfInHeap H → e.WfInHeap H → (abs cs T e).WfInHeap H
- wf_tabs {s : Sig} {cs : CaptureSet s} {H : Heap} {T : Ty TySort.shape s} {e : Exp (s,X)} : cs.WfInHeap H → T.WfInHeap H → e.WfInHeap H → (tabs cs T e).WfInHeap H
- wf_cabs {s : Sig} {cs : CaptureSet s} {H : Heap} {cb : CaptureBound s} {e : Exp (s,C)} : cs.WfInHeap H → cb.WfInHeap H → e.WfInHeap H → (cabs cs cb e).WfInHeap H
- wf_pack {s : Sig} {cs : CaptureSet s} {H : Heap} {x : Var Kind.var s} : cs.WfInHeap H → x.WfInHeap H → (pack cs x).WfInHeap H
- wf_app {s : Sig} {x : Var Kind.var s} {H : Heap} {y : Var Kind.var s} : x.WfInHeap H → y.WfInHeap H → (app x y).WfInHeap H
- wf_tapp {s : Sig} {x : Var Kind.var s} {H : Heap} {T : Ty TySort.shape s} : x.WfInHeap H → T.WfInHeap H → (tapp x T).WfInHeap H
- wf_capp {s : Sig} {x : Var Kind.var s} {H : Heap} {cs : CaptureSet s} : x.WfInHeap H → cs.WfInHeap H → (capp x cs).WfInHeap H
- wf_letin {s : Sig} {e1 : Exp s} {H : Heap} {e2 : Exp (s,x)} : e1.WfInHeap H → e2.WfInHeap H → (e1.letin e2).WfInHeap H
- wf_unpack {s : Sig} {e1 : Exp s} {H : Heap} {e2 : Exp (s,C,x)} : e1.WfInHeap H → e2.WfInHeap H → (e1.unpack e2).WfInHeap H
- wf_unit {s : Sig} {H : Heap} : unit.WfInHeap H
- wf_btrue {s : Sig} {H : Heap} : btrue.WfInHeap H
- wf_bfalse {s : Sig} {H : Heap} : bfalse.WfInHeap H
- wf_read {s : Sig} {x : Var Kind.var s} {H : Heap} : x.WfInHeap H → (read x).WfInHeap H
- wf_write {s : Sig} {x : Var Kind.var s} {H : Heap} {y : Var Kind.var s} : x.WfInHeap H → y.WfInHeap H → (write x y).WfInHeap H
- wf_cond {s : Sig} {x : Var Kind.var s} {H : Heap} {e2 e3 : Exp s} : x.WfInHeap H → e2.WfInHeap H → e3.WfInHeap H → (cond x e2 e3).WfInHeap H
Instances For
Closedness implies well-formedness for capture sets.
Closedness implies well-formedness for capture bounds.
Inversion for lambda abstraction: if λ(cs) (x : T). e is well-formed,
then its capture set, type, and body are all well-formed.
Inversion for type abstraction: if Λ(cs) (X <: T). e is well-formed,
then its capture set, type bound, and body are all well-formed.
Inversion for capture abstraction: if λ[cs] (C <: cb). e is well-formed,
then its capture set, capture bound, and body are all well-formed.
Lookup the reachability set of a location.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Resolve reachability of each element of the capture set.
Equations
- CC.expand_captures h CC.CaptureSet.empty = ∅
- CC.expand_captures h (CC.CaptureSet.var (CC.Var.free loc)) = CC.reachability_of_loc h loc
- CC.expand_captures h (cs1.union cs2) = CC.expand_captures h cs1 ∪ CC.expand_captures h cs2
Instances For
Compute reachability for a heap value.
Equations
- CC.compute_reachability h (CC.Exp.abs cs a a_1) hv_2 = CC.expand_captures h cs
- CC.compute_reachability h (CC.Exp.tabs cs a a_1) hv_2 = CC.expand_captures h cs
- CC.compute_reachability h (CC.Exp.cabs cs a a_1) hv_2 = CC.expand_captures h cs
- CC.compute_reachability h CC.Exp.unit hv_2 = ∅
- CC.compute_reachability h CC.Exp.btrue hv_2 = ∅
- CC.compute_reachability h CC.Exp.bfalse hv_2 = ∅
Instances For
Equations
- One or more equations did not get rendered due to their size.
- CC.resolve x✝ (CC.Exp.var (CC.Var.free x_2)) = match x✝ x_2 with | some (CC.Cell.val v) => some v.unwrap | x => none
- CC.resolve x✝¹ x✝ = some x✝
Instances For
Equations
- CC.resolve_reachability H (CC.Exp.var (CC.Var.free x)) = CC.reachability_of_loc H x
- CC.resolve_reachability H (CC.Exp.abs cs a a_1) = CC.expand_captures H cs
- CC.resolve_reachability H (CC.Exp.tabs cs a a_1) = CC.expand_captures H cs
- CC.resolve_reachability H (CC.Exp.cabs cs a a_1) = CC.expand_captures H cs
- CC.resolve_reachability H e = ∅
Instances For
Expanding a capture set in a bigger heap yields the same result. Proof by induction on cs. Requires all free locations in cs to exist in h1.
Computing reachability of a value in a bigger heap yields the same result. Proof by cases on hv, using expand_captures_monotonic.
Updating an mcell preserves reachability_of_loc for all locations.
Updating an mcell preserves expand_captures.
Updating an mcell preserves compute_reachability.
A heap is well-formed if all values stored in it contain well-formed expressions.
- wf_reach (l : ℕ) (v : Exp ∅) (hv : v.IsSimpleVal) (R : CapabilitySet) : H l = some (Cell.val { unwrap := v, isVal := hv, reachability := R }) → R = compute_reachability H v hv
Instances For
Extending a well-formed heap with a well-formed value preserves well-formedness.
Renaming preserves well-formedness of capture sets.
Renaming preserves well-formedness of capture bounds.
Well-formed substitutions preserve well-formedness of capture sets.
Well-formed substitutions preserve well-formedness of capture bounds.
Opening substitution for type variables is well-formed if the type is well-formed.
Opening substitution for capture variables is well-formed if the capture set is well-formed.
Create an empty memory.
Equations
- CC.Memory.empty = { heap := ∅, wf := CC.Heap.wf_empty, findom := CC.Memory.empty._proof_1 }
Instances For
Extend memory with a new value. Requires proof that the value is well-formed and the location is fresh.
Instances For
Heap extension with capability subsumes original heap.
Extend memory with a capability cell.
Equations
- m.extend_cap l hfresh = { heap := m.heap.extend_cap l, wf := ⋯, findom := ⋯ }
Instances For
Extend memory with a value that's well-formed in the current heap.
This is often more convenient than extend in practice.
Instances For
Update a mutable cell in memory with a new boolean value. Requires proof that the location contains a mutable cell.
Equations
- m.update_mcell l b hexists = { heap := m.heap.update_cell l (CC.Cell.capability (CC.CapabilityInfo.mcell b)), wf := ⋯, findom := ⋯ }
Instances For
Updating a mutable cell creates a memory that subsumes the original.
Updating mcells in subsuming memories preserves subsumption.
Looking up from a memory after extension at the same location returns the value.
Extension with extend_val subsumes the original memory.
Capability extension subsumes the original memory.
Equations
- Q.is_bool_independent = ∀ {m : CC.Memory}, Q CC.Exp.btrue m ↔ Q CC.Exp.bfalse m
Instances For
A heap has a capability domain if all capabilities on this heap lives in the given domain.
Equations
- H.HasCapDom d = ∀ (l : ℕ), (∃ (info : CC.CapabilityInfo), H l = some (CC.Cell.capability info)) ↔ l ∈ d
Instances For
Masks capabilities in the heap outside of the given domain.
Equations
Instances For
Turns a capability set into a finite set of natural numbers.