Separation logic
AbbreviationHeap assertion#✓fully proved
A heap assertion is a predicate on a store and a heap: it assigns a proposition to every store \(s\) and every heap \(h\). Heap assertions serve as the preconditions and postconditions of separation logic.
abbrev HAssertion := State → Heap → Prop
abbrev State := Nat → Nat
CSLibExt/Languages/IMP/Syntax.lean:34
abbrev Heap := Finmap (fun _ : Nat => Nat)
CSLibExt/Languages/IMP/Heap.lean:35
Uses 2 · Used by 18
DefinitionEntailment of heap assertions#✓fully proved
A heap assertion \(P\) entails a heap assertion \(Q\) when, for every store \(s\) and every heap \(h\), if \(P\) holds of \(s\) and \(h\), then \(Q\) holds of \(s\) and \(h\).
def Entails (P Q : HAssertion) : Prop :=
∀ ⦃s h⦄, P s h → Q s h
abbrev HAssertion := State → Heap → Prop
CSLibExt/Languages/IMP/SeparationLogic.lean:39
Uses 3 · Used by 3
DefinitionEmpty-heap assertion#✓fully proved
The heap assertion \(\mathrm{emp}\) holds of a store \(s\) and a heap \(h\) exactly when \(h\) is the empty heap, whatever the store \(s\) is.
def emp : HAssertion := fun _ h => h = ∅
abbrev HAssertion := State → Heap → Prop
CSLibExt/Languages/IMP/SeparationLogic.lean:39
Uses 3
DefinitionPure assertion#✓fully proved
For a proposition \(p\), the pure assertion of \(p\) holds of a store \(s\) and a heap \(h\) exactly when \(h\) is the empty heap and \(p\) is true.
def pure (p : Prop) : HAssertion := fun _ h => h = ∅ ∧ p
abbrev HAssertion := State → Heap → Prop
CSLibExt/Languages/IMP/SeparationLogic.lean:39
Uses 3
DefinitionPoints-to assertion#✓fully proved
For natural numbers \(a\) and \(v\), the assertion \(a \mapsto v\) holds of a store \(s\) and a heap \(h\) exactly when \(h\) is the singleton heap that maps the address \(a\) to the value \(v\) and allocates no other address.
def pointsTo (a v : Nat) : HAssertion :=
fun _ h => h = Finmap.singleton a v
abbrev HAssertion := State → Heap → Prop
CSLibExt/Languages/IMP/SeparationLogic.lean:39
Uses 3 · Used by 1
DefinitionSeparating conjunction#✓fully proved
For heap assertions \(P\) and \(Q\), the assertion \(P \star Q\) holds of a store \(s\) and a heap \(h\) when there are disjoint heaps \(h_1\) and \(h_2\) with \(h = h_1 \cup h_2\) such that \(P(s, h_1)\) and \(Q(s, h_2)\).
def star (P Q : HAssertion) : HAssertion :=
fun s h => ∃ h₁ h₂, Heap.Disjoint h₁ h₂ ∧ h = h₁ ∪ h₂ ∧ P s h₁ ∧ Q s h₂
abbrev HAssertion := State → Heap → Prop
CSLibExt/Languages/IMP/SeparationLogic.lean:39
def Disjoint (h₁ h₂ : Heap) : Prop := ∀ a, a ∈ h₁ → a ∉ h₂
CSLibExt/Languages/IMP/Heap.lean:40
Uses 4 · Used by 4
DefinitionExistential heap assertion#✓fully proved
For a function \(p\) assigning a heap assertion \(p(n)\) to each natural number \(n\) (an address or a value), the assertion \(\exists n,\ p(n)\) holds of a store \(s\) and a heap \(h\) exactly when \(p(n)\) holds of \(s\) and \(h\) for some natural number \(n\).
def hexists (p : Nat → HAssertion) : HAssertion :=
fun s h => ∃ a, p a s h
abbrev HAssertion := State → Heap → Prop
CSLibExt/Languages/IMP/SeparationLogic.lean:39
Uses 3
DefinitionConjunction of heap assertions#✓fully proved
For heap assertions \(P\) and \(Q\), the assertion \(P \wedge Q\) holds of a store \(s\) and a heap \(h\) exactly when \(P\) holds of \(s\) and \(h\) and \(Q\) holds of \(s\) and the same heap \(h\).
def hand (P Q : HAssertion) : HAssertion :=
fun s h => P s h ∧ Q s h
abbrev HAssertion := State → Heap → Prop
CSLibExt/Languages/IMP/SeparationLogic.lean:39
Uses 3
DefinitionSeparation-logic triple validity#✓fully proved
For heap assertions \(P\), \(Q\) and a heap command \(c\), the triple \(\lbrace P \rbrace\ c\ \lbrace Q \rbrace\) is valid (in the fault-avoiding sense) when, for every store \(s\) and heap \(h\) with \(P(s, h)\), the configuration \((c, s, h)\) is safe (no configuration reachable from it is stuck at a command other than \(\mathtt{skip}\)), and whenever \((c, s, h)\) reaches \((\mathtt{skip}, s', h')\) in finitely many heap steps, \(Q(s', h')\) holds.
def SepValid (P : HAssertion) (c : HeapCmd) (Q : HAssertion) : Prop :=
∀ ⦃s h⦄, P s h → Safe (c, s, h) ∧
∀ ⦃s' h'⦄, HSteps (c, s, h) (.skip, s', h') → Q s' h'
abbrev HAssertion := State → Heap → Prop
CSLibExt/Languages/IMP/SeparationLogic.lean:39
inductive HeapCmd where
| skip
| assign (name : Nat) (value : AExp)
| seq (first second : HeapCmd)
| ite (guard : BExp) (thenBranch elseBranch : HeapCmd)
| while (guard : BExp) (body : HeapCmd)
| read (name : Nat) (addr : AExp)
| write (addr value : AExp)
| alloc (name : Nat) (value : AExp)
| free (addr : AExp)
deriving DecidableEq, Repr
CSLibExt/Languages/IMP/HeapStep.lean:40
def Safe (cfg : HConfig) : Prop :=
∀ cfg', HSteps cfg cfg' → cfg'.1 = .skip ∨ ∃ cfg'', HStep cfg' cfg''
CSLibExt/Languages/IMP/HeapStep.lean:97
abbrev HSteps : HConfig → HConfig → Prop := Relation.ReflTransGen HStep
CSLibExt/Languages/IMP/HeapStep.lean:93
Uses 6 · Used by 7
TheoremSeparation-logic while rule#✓fully proved
Let \(I\) be a heap assertion, \(b\) a Boolean expression and \(c\) a heap command. Write \(I \wedge b\) for the assertion that holds of a store \(s\) and a heap \(h\) when \(I(s, h)\) holds and \(b\) evaluates to true in \(s\), and \(I \wedge \neg b\) for the one that holds when \(I(s, h)\) holds and \(b\) evaluates to false in \(s\). If the triple \(\lbrace I \wedge b \rbrace\ c\ \lbrace I \rbrace\) is valid, then so is the triple \(\lbrace I \rbrace\ \mathtt{while}\ b\ \mathtt{do}\ c\ \lbrace I \wedge \neg b \rbrace\).
theorem whileLoop {I : HAssertion} {guard : BExp} {body : HeapCmd}
(hbody : SepValid (fun s h => I s h ∧ guard.eval s = true) body I) :
SepValid I (.while guard body)
(fun s h => I s h ∧ guard.eval s = false)
abbrev HAssertion := State → Heap → Prop
CSLibExt/Languages/IMP/SeparationLogic.lean:39
inductive BExp where
| truth (value : Bool)
| eq (left right : AExp)
| le (left right : AExp)
| not (body : BExp)
| and (left right : BExp)
deriving DecidableEq, Repr
CSLibExt/Languages/IMP/Syntax.lean:46
inductive HeapCmd where
| skip
| assign (name : Nat) (value : AExp)
| seq (first second : HeapCmd)
| ite (guard : BExp) (thenBranch elseBranch : HeapCmd)
| while (guard : BExp) (body : HeapCmd)
| read (name : Nat) (addr : AExp)
| write (addr value : AExp)
| alloc (name : Nat) (value : AExp)
| free (addr : AExp)
deriving DecidableEq, Repr
CSLibExt/Languages/IMP/HeapStep.lean:40
def SepValid (P : HAssertion) (c : HeapCmd) (Q : HAssertion) : Prop :=
∀ ⦃s h⦄, P s h → Safe (c, s, h) ∧
∀ ⦃s' h'⦄, HSteps (c, s, h) (.skip, s', h') → Q s' h'
CSLibExt/Languages/IMP/SeparationLogic.lean:251
Uses 13
TheoremFrame rule#✓fully proved
Let \(P\), \(Q\) and \(R\) be heap assertions and \(c\) a heap command. Suppose the separation-logic triple with precondition \(P\), command \(c\) and postcondition \(Q\) is valid, and suppose that whenever \(R\) holds of a store \(s\) and a heap \(h\), it also holds of \(s'\) and \(h\) for every store \(s'\) that agrees with \(s\) on every variable outside the set of variables that \(c\) may assign to. Then the triple with precondition \(P \star R\), command \(c\) and postcondition \(Q \star R\) is valid, where \(\star\) denotes separating conjunction.
theorem frame {P Q R : HAssertion} {c : HeapCmd}
(hvalid : SepValid P c Q)
(hR : ∀ ⦃s h s'⦄, R s h →
(∀ x, x ∉ c.modVars → s' x = s x) → R s' h) :
SepValid (P ⋆ R) c (Q ⋆ R)
abbrev HAssertion := State → Heap → Prop
CSLibExt/Languages/IMP/SeparationLogic.lean:39
inductive HeapCmd where
| skip
| assign (name : Nat) (value : AExp)
| seq (first second : HeapCmd)
| ite (guard : BExp) (thenBranch elseBranch : HeapCmd)
| while (guard : BExp) (body : HeapCmd)
| read (name : Nat) (addr : AExp)
| write (addr value : AExp)
| alloc (name : Nat) (value : AExp)
| free (addr : AExp)
deriving DecidableEq, Repr
CSLibExt/Languages/IMP/HeapStep.lean:40
def SepValid (P : HAssertion) (c : HeapCmd) (Q : HAssertion) : Prop :=
∀ ⦃s h⦄, P s h → Safe (c, s, h) ∧
∀ ⦃s' h'⦄, HSteps (c, s, h) (.skip, s', h') → Q s' h'
CSLibExt/Languages/IMP/SeparationLogic.lean:251
Uses 15 · Used by 1
TheoremHoare validity embeds into separation validity#✓fully proved
Let \(P\) and \(Q\) be store assertions and \(c\) a command of plain IMP. If the partial-correctness Hoare triple with precondition \(P\), command \(c\) and postcondition \(Q\) is valid, then the separation-logic triple for the embedding of \(c\) into heap IMP is valid with the precondition that holds of a store \(s\) and any heap exactly when \(P(s)\) holds and the postcondition that holds of a store \(s\) and any heap exactly when \(Q(s)\) holds.
Embedded commands are always safe, never change the heap, and terminate exactly when the plain command does.
theorem of_valid {P Q : Assertion} {c : Cmd} (hvalid : Valid P c Q) :
SepValid (fun s _ => P s) c.toHeap (fun s _ => Q s)
abbrev Assertion := State → Prop
CSLibExt/Languages/IMP/Hoare.lean:35
inductive Cmd where
| skip
| assign (name : Nat) (value : AExp)
| seq (first second : Cmd)
| ite (guard : BExp) (thenBranch elseBranch : Cmd)
| while (guard : BExp) (body : Cmd)
deriving DecidableEq, Repr
CSLibExt/Languages/IMP/Syntax.lean:55
def Valid (pre : Assertion) (command : Cmd) (post : Assertion) : Prop :=
∀ ⦃initial final⦄, pre initial → BigStep command initial final → post final
CSLibExt/Languages/IMP/Hoare.lean:57
def SepValid (P : HAssertion) (c : HeapCmd) (Q : HAssertion) : Prop :=
∀ ⦃s h⦄, P s h → Safe (c, s, h) ∧
∀ ⦃s' h'⦄, HSteps (c, s, h) (.skip, s', h') → Q s' h'
CSLibExt/Languages/IMP/SeparationLogic.lean:251
Uses 17 · Used by 1
TheoremFramed embedding of Hoare validity#✓fully proved
Let \(P\) and \(Q\) be store assertions, \(R\) a heap assertion and \(c\) a command of plain IMP, and write \(\hat c\) for the embedding of \(c\) into heap IMP. Suppose the partial-correctness Hoare triple with precondition \(P\), command \(c\) and postcondition \(Q\) is valid, and suppose that whenever \(R\) holds of a store \(s\) and a heap \(h\), it also holds of \(s'\) and \(h\) for every store \(s'\) that agrees with \(s\) on every variable outside the set of variables that \(\hat c\) may assign to. Write \(\tilde P\) and \(\tilde Q\) for the heap assertions that hold of a store \(s\) and any heap exactly when \(P(s)\), respectively \(Q(s)\), holds. Then the separation-logic triple with precondition \(\tilde P \star R\), command \(\hat c\) and postcondition \(\tilde Q \star R\) is valid, where \(\star\) denotes separating conjunction.
theorem of_valid_frame {P Q : Assertion} {R : HAssertion} {c : Cmd}
(h : Valid P c Q)
(hR : ∀ ⦃s h s'⦄, R s h →
(∀ x, x ∉ c.toHeap.modVars → s' x = s x) → R s' h) :
SepValid ((fun s _ => P s) ⋆ R) c.toHeap ((fun s _ => Q s) ⋆ R)
abbrev Assertion := State → Prop
CSLibExt/Languages/IMP/Hoare.lean:35
abbrev HAssertion := State → Heap → Prop
CSLibExt/Languages/IMP/SeparationLogic.lean:39
inductive Cmd where
| skip
| assign (name : Nat) (value : AExp)
| seq (first second : Cmd)
| ite (guard : BExp) (thenBranch elseBranch : Cmd)
| while (guard : BExp) (body : Cmd)
deriving DecidableEq, Repr
CSLibExt/Languages/IMP/Syntax.lean:55
def Valid (pre : Assertion) (command : Cmd) (post : Assertion) : Prop :=
∀ ⦃initial final⦄, pre initial → BigStep command initial final → post final
CSLibExt/Languages/IMP/Hoare.lean:57
def SepValid (P : HAssertion) (c : HeapCmd) (Q : HAssertion) : Prop :=
∀ ⦃s h⦄, P s h → Safe (c, s, h) ∧
∀ ⦃s' h'⦄, HSteps (c, s, h) (.skip, s', h') → Q s' h'
CSLibExt/Languages/IMP/SeparationLogic.lean:251
DefinitionStore-irrelevant heap assertions#✓fully proved
A heap assertion \(P\) is store-irrelevant when for all stores \(s, s'\) and every heap \(h\), \(P(s, h)\) implies \(P(s', h)\); that is, whether \(P\) holds does not depend on the store.
The empty-heap and points-to assertions are store-irrelevant, and so is the separating conjunction of two store-irrelevant assertions.
def StoreIrrel (P : HAssertion) : Prop :=
∀ (s s' : State) (h : Heap), P s h → P s' h
abbrev HAssertion := State → Heap → Prop
CSLibExt/Languages/IMP/SeparationLogic.lean:39
abbrev State := Nat → Nat
CSLibExt/Languages/IMP/Syntax.lean:34
abbrev Heap := Finmap (fun _ : Nat => Nat)
CSLibExt/Languages/IMP/Heap.lean:35
Uses 3 · Used by 2
TheoremStore-irrelevant frames satisfy the frame-rule side condition#✓fully proved
Let \(R\) be a store-irrelevant heap assertion and \(c\) a heap command. For all stores \(s, s'\) and every heap \(h\), if \(R(s, h)\) holds and \(s'(x) = s(x)\) for every variable \(x\) outside the set of variables that \(c\) may assign to, then \(R(s', h)\) holds.
This is the side condition on the frame in the frame rule.
theorem frame_of_storeIrrel {R : HAssertion} (hR : StoreIrrel R)
(c : HeapCmd) :
∀ ⦃s : State⦄ ⦃h : Heap⦄ ⦃s' : State⦄, R s h →
(∀ x, x ∉ c.modVars → s' x = s x) → R s' h
abbrev HAssertion := State → Heap → Prop
CSLibExt/Languages/IMP/SeparationLogic.lean:39
def StoreIrrel (P : HAssertion) : Prop :=
∀ (s s' : State) (h : Heap), P s h → P s' h
CSLibExt/Languages/IMP/SeparationAPI.lean:40
inductive HeapCmd where
| skip
| assign (name : Nat) (value : AExp)
| seq (first second : HeapCmd)
| ite (guard : BExp) (thenBranch elseBranch : HeapCmd)
| while (guard : BExp) (body : HeapCmd)
| read (name : Nat) (addr : AExp)
| write (addr value : AExp)
| alloc (name : Nat) (value : AExp)
| free (addr : AExp)
deriving DecidableEq, Repr
CSLibExt/Languages/IMP/HeapStep.lean:40
abbrev State := Nat → Nat
CSLibExt/Languages/IMP/Syntax.lean:34
abbrev Heap := Finmap (fun _ : Nat => Nat)
CSLibExt/Languages/IMP/Heap.lean:35
Uses 6
TheoremPulling a store fact out of a separating conjunction#✓fully proved
Let \(p\) be a predicate on stores and \(P\), \(R\) heap assertions. Write \(A \star B\) for the separating conjunction of heap assertions \(A\) and \(B\) (the heap splits into two disjoint parts satisfying \(A\) and \(B\), respectively, at the same store), and \(p \land P\) for the heap assertion that holds at store \(s\) and heap \(h\) when \(p(s)\) and \(P(s, h)\) both hold. Then \((p \land P) \star R = p \land (P \star R)\).
This lets framed local triples be stated with the store facts kept outside the separating conjunction.
theorem star_and_left {p : State → Prop} {P R : HAssertion} :
((fun s h => p s ∧ P s h) ⋆ R) = (fun s h => p s ∧ (P ⋆ R) s h)
abbrev State := Nat → Nat
CSLibExt/Languages/IMP/Syntax.lean:34
abbrev HAssertion := State → Heap → Prop
CSLibExt/Languages/IMP/SeparationLogic.lean:39
Uses 5
TheoremRearranging a separating conjunction#✓fully proved
For heap assertions \(P\), \(Q\) and \(R\), write \(A \star B\) for the separating conjunction of heap assertions \(A\) and \(B\) (the heap splits into two disjoint parts satisfying \(A\) and \(B\), respectively, at the same store). Then \(P \star (Q \star R)\) entails \((P \star R) \star Q\): every store and heap satisfying the first assertion satisfy the second.
theorem star_swap_right {P Q R : HAssertion} :
(P ⋆ (Q ⋆ R)).Entails ((P ⋆ R) ⋆ Q)
abbrev HAssertion := State → Heap → Prop
CSLibExt/Languages/IMP/SeparationLogic.lean:39
Uses 7
TheoremLocal rule for a heap read#✓fully proved
Let \(x\) and \(y\) be variables, let \(a\) and \(v\) be natural numbers, and let \(p\) and \(q\) be predicates on stores. Write \(s[x := n]\) for the store that agrees with \(s\) except that it maps \(x\) to \(n\), and \(a \mapsto v\) for the heap assertion that holds when the heap is the single cell at address \(a\) holding \(v\). If every store \(s\) satisfying \(p\) has \(s(y) = a\) and \(q(s[x := v])\), then the separation-logic triple for the heap read \(x := [y]\) (which loads into \(x\) the value stored at the address held in \(y\)) is valid with precondition "\(p(s)\) and \(a \mapsto v\) holds at \((s, h)\)" and postcondition "\(q(s)\) and \(a \mapsto v\) holds at \((s, h)\)", where \(s\) is the store and \(h\) the heap.
theorem read_local {name addrName a v : Nat} {p q : State → Prop}
(hpq : ∀ s, p s → s addrName = a ∧
q (Function.update s name v)) :
SepValid (fun s h => p s ∧ pointsTo a v s h)
(.read name (.var addrName))
(fun s h => q s ∧ pointsTo a v s h)
abbrev State := Nat → Nat
CSLibExt/Languages/IMP/Syntax.lean:34
def SepValid (P : HAssertion) (c : HeapCmd) (Q : HAssertion) : Prop :=
∀ ⦃s h⦄, P s h → Safe (c, s, h) ∧
∀ ⦃s' h'⦄, HSteps (c, s, h) (.skip, s', h') → Q s' h'
CSLibExt/Languages/IMP/SeparationLogic.lean:251
def pointsTo (a v : Nat) : HAssertion :=
fun _ h => h = Finmap.singleton a v
CSLibExt/Languages/IMP/SeparationLogic.lean:61
Uses 15
TheoremAssignment rule with a store-irrelevant heap assertion#✓fully proved
Let \(x\) and \(y\) be variables, let \(p\) and \(q\) be predicates on stores, and let \(H\) be a store-irrelevant heap assertion. Write \(s[x := n]\) for the store that agrees with \(s\) except that it maps \(x\) to \(n\). If every store \(s\) satisfying \(p\) has \(q(s[x := s(y)])\), then the separation-logic triple for the assignment \(x := y\) is valid with precondition "\(p(s)\) and \(H(s, h)\)" and postcondition "\(q(s)\) and \(H(s, h)\)", where \(s\) is the store and \(h\) the heap.
An assignment leaves the heap untouched, so no framing is needed.
theorem assign_step {name src : Nat} {p q : State → Prop}
{H : HAssertion} (hH : StoreIrrel H)
(hpq : ∀ s, p s → q (Function.update s name (s src))) :
SepValid (fun s h => p s ∧ H s h) (.assign name (.var src))
(fun s h => q s ∧ H s h)
abbrev State := Nat → Nat
CSLibExt/Languages/IMP/Syntax.lean:34
abbrev HAssertion := State → Heap → Prop
CSLibExt/Languages/IMP/SeparationLogic.lean:39
def StoreIrrel (P : HAssertion) : Prop :=
∀ (s s' : State) (h : Heap), P s h → P s' h
CSLibExt/Languages/IMP/SeparationAPI.lean:40
def SepValid (P : HAssertion) (c : HeapCmd) (Q : HAssertion) : Prop :=
∀ ⦃s h⦄, P s h → Safe (c, s, h) ∧
∀ ⦃s' h'⦄, HSteps (c, s, h) (.skip, s', h') → Q s' h'
CSLibExt/Languages/IMP/SeparationLogic.lean:251
Uses 15
TheoremExistential rule for separation-logic triples#✓fully proved
Let \(c\) be a heap command, let \(\iota\) be an arbitrary index (any type or proposition), and let \(P_i\) and \(Q_i\) be heap assertions for each \(i\) in \(\iota\). If for every \(i\) the triple with precondition \(P_i\), command \(c\) and postcondition \(Q_i\) is valid, then the triple with precondition "there is \(i\) with \(P_i\)", command \(c\) and postcondition "there is \(i\) with \(Q_i\)" is valid.
theorem SepValid.exists {ι : Sort*} {P Q : ι → HAssertion} {c : HeapCmd}
(hstep : ∀ i, SepValid (P i) c (Q i)) :
SepValid (fun s h => ∃ i, P i s h) c (fun s h => ∃ i, Q i s h)
abbrev HAssertion := State → Heap → Prop
CSLibExt/Languages/IMP/SeparationLogic.lean:39
inductive HeapCmd where
| skip
| assign (name : Nat) (value : AExp)
| seq (first second : HeapCmd)
| ite (guard : BExp) (thenBranch elseBranch : HeapCmd)
| while (guard : BExp) (body : HeapCmd)
| read (name : Nat) (addr : AExp)
| write (addr value : AExp)
| alloc (name : Nat) (value : AExp)
| free (addr : AExp)
deriving DecidableEq, Repr
CSLibExt/Languages/IMP/HeapStep.lean:40
def SepValid (P : HAssertion) (c : HeapCmd) (Q : HAssertion) : Prop :=
∀ ⦃s h⦄, P s h → Safe (c, s, h) ∧
∀ ⦃s' h'⦄, HSteps (c, s, h) (.skip, s', h') → Q s' h'
CSLibExt/Languages/IMP/SeparationLogic.lean:251
Uses 7
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.