The Relationship Between Separation Logic and Implicit Dynamic Frames
description
Transcript of The Relationship Between Separation Logic and Implicit Dynamic Frames
The Relationship Between Separation Logic and Implicit Dynamic Frames
Matthew Parkinson (MSR-Cambridge)Alex Summers (ETH Zurich)
ETAPS 2010What do you think about
Chalice?Isn’t it just like separation
logic?Not really, you can refer to heap with out permission
So what are the semantics of that then?
Does that mean we can translate separation logic
into Chalice?Maybe
Well, it is defined by this translation with VCs
I am sure we can give them a semantics with separation
logic
What?
• Separation Logic and Implicit Dynamic Frames are two program specification logics– pre/post conditions, modular verification
• Both have been adapted to support verification of concurrent programs– threads, locks/monitors, fork/join etc.
• Chalice is a verification tool based on IDF– encodes all verification to Boogie2, Z3 prover
• We wanted to formally connect two logics...
Overview
Kripke semantics over partial heaps
Weakest pre-condition definitions
Chalice : verification condition generation
Implicit Dynamic Frames (IDF)
Separation Logic(SL)
... ? ... ?
SL+⊂ ⊃
Overview
Kripke semantics over partial heaps
Weakest pre-condition definitions
Chalice : verification condition generation
Implicit Dynamic Frames (IDF)
Separation Logic(SL)
?
SL+⊂ ⊃Kripke semantics over total heaps
Overview
Kripke semantics over partial heaps
Weakest pre-condition definitions
Chalice : verification condition generation
Implicit Dynamic Frames (IDF)
Separation Logic(SL) SL+⊂ ⊃
Kripke semantics over total heaps
Kripke semantics over total heaps≡≡
Overview
Kripke semantics over partial heaps
Weakest pre-condition definitions
Chalice : verification condition generation
Implicit Dynamic Frames (IDF)
Separation Logic(SL) SL+⊂ ⊃
Kripke semantics over total heaps
Kripke semantics over total heaps≡≡
≡
Overview
Kripke semantics over total heaps
Kripke semantics over partial heaps
Weakest pre-condition definitions
Kripke semantics over total heaps
SL+Separation Logic(SL)
≡
≡≡
Chalice : verification condition generation
Implicit Dynamic Frames (IDF)
What is separation logic?
Four key things:• x.f ↦ v (“points-to predicate”)– Permission to access location x.f– Specifies value v currently stored at the location
• A * B : Splitting of heap into disjoint parts• A -̶ B : Hypothetical addition of disjoint part• { P } C { Q } : Frame rule { P * R} C { Q * R} (extra stuff unmodified)
Weakest preconditions• Standard weakest pre-condition world:
wp(assume A, B) = A ⇒ Bwp(assert A, B) = A ∧ B
• Other verification features can be “compiled” to assume/assert statements (e.g., method calls)
• In SL, there are two analogous commandswp(assume* A, B) = A - ̶ Bwp(assert* A, B) = A * B
Overview
Kripke semantics over total heaps
Kripke semantics over partial heaps
Weakest pre-condition definitions
Kripke semantics over total heaps
SL+Separation Logic(SL)
≡
≡≡
Chalice : verification condition generation
Implicit Dynamic Frames (IDF)
Implicit Dynamic Frames: permissions
• Idea: use permissions to control which threads can read/write to heap locations
• Permissions can be fractional, to allow multiple concurrent readers, but see paper
• Extend first-order assertions to additionally include “accessibility predicates”:acc(x.f) is an assertion : we have permission to x.f
• Assertions concern both heap and permissions
• For example (note * is written && in Chalice)acc(x.f) * x.f == 4 * acc(x.g)
Implicit Dynamic Frames: permissions
• For example (note * is written && in Chalice)acc(x.f) * x.f == 4 * acc(x.g)
Implicit Dynamic Frames: permissions
x.f
• For example (note * is written && in Chalice)acc(x.f) * x.f == 4 * acc(x.g)
Implicit Dynamic Frames: permissions
x.f
• For example (note * is written && in Chalice)acc(x.f) * x.f == 4 * acc(x.g)
Implicit Dynamic Frames: permissions
4
x.f
Implicit Dynamic Frames: permissions
• For example (note * is written && in Chalice)acc(x.f) * x.f == 4 * acc(x.g)
4
x.f x.g
Implicit Dynamic Frames: permissions
• For example (note * is written && in Chalice)acc(x.f) * x.f == 4 * acc(x.g)
• Expressions include heap dereferences
4
x.f x.g
Implicit Dynamic Frames: permissions
• For example (note * is written && in Chalice)acc(x.f) * x.f == 4 * acc(x.g)
• Expressions include heap dereferences• Permissions need not match “read footprint”
4
x.f x.g
Implicit Dynamic Frames: permissions
• For example (note * is written && in Chalice)acc(x.f) * x.f == 4 * acc(x.g) * y.f == 3
• Expressions include heap dereferences• Permissions need not match “read footprint”
4
x.f x.g
Implicit Dynamic Frames: permissions
• For example (note * is written && in Chalice)acc(x.f) * x.f == 4 * acc(x.g) * y.f == 3
• Expressions include heap dereferences• Permissions need not match “read footprint”
3y.f
x.g
4
x.f
Inhale and Exhale
• “inhale p” and “exhale p” are used in Chalice to encode transfers between threads/calls
• “inhale p” means:– assume heap properties in p– gain permissions in p– havoc newly-readable locations
• “exhale p” means:– assert heap properties in p– check and give up permissions
void m() requires pensures q { // inhale p ... // exhale p call m() // inhale q ... // exhale q}
Inhale and Exhale
• “inhale p” and “exhale p” are used in Chalice to encode transfers between threads/calls
• “inhale p” means:– assume heap properties in p– gain permissions in p– havoc newly-readable locations
• “exhale p” means:– assert heap properties in p– check and give up permissions
void m() requires pensures q { // inhale p ... // exhale p call m() // inhale q ... // exhale q}
Inhale and Exhale
• “inhale p” and “exhale p” are used in Chalice to encode transfers between threads/calls
• “inhale p” means:– assume heap properties in p– gain permissions in p– havoc newly-readable locations
• “exhale p” means:– assert heap properties in p– check and give up permissions
void m() requires pensures q { // inhale p ... // exhale p call m() // inhale q ... // exhale q}
Inhale and Exhale
• “inhale p” and “exhale p” are used in Chalice to encode transfers between threads/calls
• “inhale p” means:– assume heap properties in p– gain permissions in p– havoc newly-readable locations
• “exhale p” means:– assert heap properties in p– check and give up permissions
void m() requires pensures q { // inhale p ... // exhale p call m() // inhale q ... // exhale q}
Inhale and Exhale
• “inhale p” and “exhale p” are used in Chalice to encode transfers between threads/calls
• “inhale p” means:– assume heap properties in p– gain permissions in p– havoc newly-readable locations
• “exhale p” means:– assert heap properties in p– check and give up permissions
void m() requires pensures q { // inhale p ... // exhale p call m() // inhale q ... // exhale q}
Inhale and Exhale
• “inhale p” and “exhale p” are used in Chalice to encode transfers between threads/calls
• “inhale p” means:– assume heap properties in p– gain permissions in p– havoc newly-readable locations
• “exhale p” means:– assert heap properties in p– check and give up permissions
void m() requires pensures q { // inhale p ... // exhale p call m() // inhale q ... // exhale q}
Inhale and Exhale
• “inhale p” and “exhale p” are used in Chalice to encode transfers between threads/calls
• “inhale p” means:– assume heap properties in p– gain permissions in p– havoc newly-readable locations
• “exhale p” means:– assert heap properties in p– check and give up permissions
void m() requires pensures q { // inhale p ... // exhale p call m() // inhale q ... // exhale q}
Self-framing
• Inhaled assertions model new information from another thread (e.g., heap values)
• But, this information must be “framed” by suitable permissions, to be sound to assume
• Inhaled/exhaled assertions are required to be “self-framing”:– essentially, they include enough permissions to
preserve the truth of their heap assertions– e.g., acc(x.f)*x.f==4 but not x.f==4 alone
Overview
Kripke semantics over partial heaps
Weakest pre-condition definitions
Chalice : verification condition generation
Implicit Dynamic Frames (IDF)
Separation Logic(SL)
?
A common semantics?
Separation Logic• Controls access to heap
locations along with values• Semantics defined in terms
of partial heaps• Key connectives defined by
adding/removing heap fragments
Chalice• Controls permissions and
values separately• Semantics defined via
translation, and total heaps• Encoding defined by
modification of global maps for heap and permissions
How can we formally relate the two?
SL+
Basically, a union of the syntaxes of SL and IDFSemantics defined over total heaps...Expressions (can access the heap)
E ::= E.f | E + E | n | x | …Formulae (both acc and “points to” predicates)
A,B ::= acc(x.f) | x.f ↦ v | E = E | A * B | …Intuition: x.f ↦ v ⇔ acc(x.f) * x.f = v
A*B
Separation Logic partial heap
AB
IDF total heap
AB
A*B
Separation Logic partial heap IDF total heap
AB
AB
A*B
Separation Logic partial heap IDF total heap
AB
AB
4
3 2
7 4
3 2
7
4
3 2
7
0 0
A*B
Separation Logic partial heap IDF total heap
AB
AB
4
3 2
7 4
3 2
7
4
3 2
7
0 0
Heap agreement up to permissions
IDF total heapIDF total heap
4
3 2
7
4
3 2
7
0 0
IDF total heap
4
3 2
7
4
3 2
7
0 0
Heap agreement up to permissions
IDF total heap
4
3 2
7
9
3 2
1
4 1
9
IDF total heap
4
3 2
7
4
3 2
7
0 0
P ̶ Q
Separation Logic partial heap IDF total heap
Separation Logic partial heap IDF total heap
P
P ̶ Q
Separation Logic partial heap IDF total heap
P
P ̶ Q
Separation Logic partial heap IDF total heap
P
Q
P ̶ Q
Separation Logic partial heap IDF total heap
P
Q
P ̶ Q
Separation Logic partial heap IDF total heap
P ?
Q
P
P ̶ Q
Separation Logic partial heap IDF total heap
P
Q
P ̶ Q
Separation Logic partial heap IDF total heap
P
Q
P ̶ Q
Separation Logic partial heap IDF total heap
P
Q
P
P ̶ Q
Separation Logic partial heap IDF total heap
P
Q
P
Q
P ̶ Q
Self-framing revisitedAn assertion is self-
framing if:
Self-framing revisitedIDF total heap
4
3 2
7
4
3 2
7
0 0
An assertion is self-framing if:
For any heap and permission mask satisfying it,
assertion remains true if we replace the heap with any that agrees on the permissions
Self-framing revisitedIDF total heap An assertion is self-
framing if:For any heap and
permission mask satisfying it,
assertion remains true if we replace the heap with any that agrees on the permissions
4
3 2
7
9
3 2
1
4 1
9
Self-framing revisitedIDF total heap An assertion is self-
framing if:For any heap and
permission mask satisfying it,
assertion remains true if we replace the heap with any that agrees on the permissions
4
3 2
7
8 4
2 1
6 2
5
Self-framing revisitedIDF total heap
4
3 2
7
4
3 2
7
0 0
An assertion is self-framing if:
For any heap and permission mask satisfying it,
assertion remains true if we replace the heap with any that agrees on the permissions
Self-framing revisitedSeparation Logic partial heap An assertion is self-
framing if:For any heap and
permission mask satisfying it,
assertion remains true if we replace the heap with any that agrees on the permissions
4
3 2
7
In Separation Logic, there would be partial heap which canonically represents all the total ones in our semantics
Faithfully represents separation logic
Definition: the restriction of a total heap H to permissions P, is a partial heap H↾P defined by:
H↾P(x) = H(x) provided P(x) > 1, H↾P(x) is undefined otherwise.
Theorem If A is a separation logic assertion, then:
P ⊧ A in SL+ ⇔ H↾P ⊧ A in SL
Overview
Kripke semantics over partial heaps
Weakest pre-condition definitions
Chalice : verification condition generation
Implicit Dynamic Frames (IDF)
Separation Logic(SL)
Kripke semantics over total heaps
Kripke semantics over total heaps ≡≡
?
SL+
Chalice Weakest Pre-conditions
Encoded using two special variables• H : represents the values in the heap• P : represents the permissions to access heapFor example,
wpch(inhale(acc(E.f)), A)= wpch(P[E,f] += 1; assume (P[E,f]==1), A) wpch(inhale(a*b), A)= wpch(inhale(a);inhale(b), A)
Translating SL+ to many sorted FOL
Expressions ⌊⌊x⌋⌋ = x ⌊⌊ E.f ⌋⌋ = H [ ⌊⌊E⌋⌋ , f ]Formulae⌊⌊acc(E.f)⌋⌋ = P [⌊⌊E⌋⌋,f] == 1 ⌊⌊A*B⌋⌋ = ∃P1,P2. ⌊⌊A⌋⌋ [P1/P] ∧ ⌊⌊B⌋⌋[P2/P] ∧ P1 * P2 = P
P1 * P2 = P ⇔ ∀i. P1[i] + P2[i] = P[i] ∧ P[i] ≤ 1
Key points of the proof
All existentials of array type introduced by ⌊⌊ ⌋⌋ are witnessed in Chalice VCs.
Self-framing is checked in Chalice by a syntactic (left-to-right) criterion, which is stronger than the semantic notion.
Note: asymmetry (left-to-right checking) of self-framing is essential for Chalice VC for inhale.
Faithfully representing Chalice
Theoremwpch (exhale p, ⌊⌊ A ⌋⌋) ⇔ ⌊⌊wpsl(exhale p, A)⌋⌋If p is (syntactically) self-framing, then
wpch(inhale p, ⌊⌊ A ⌋⌋) ⇔ ⌊⌊wpsl(inhale p, A)⌋⌋
Summary
Kripke semantics over partial heaps
Weakest pre-condition definitions
Chalice : verification condition generation
Implicit Dynamic Frames (IDF)
Separation Logic(SL) SL+⊂ ⊃
Kripke semantics over total heaps
Kripke semantics over total heaps≡≡
≡
Summary
• We defined a direct semantics for IDF logic• We defined a total heaps semantics for SL• We have formally connected the two logics– We can encode SL assertions as IDF assertions– ... and back again, for self-framing IDF assertions
• This suggests we could verify SL specifications directly in Chalice, via Boogie2/Z3...
Automation
• We can use our work to provide a new way of verifying separation logic specifications
• Apply our encoding to convert to IDF, then feed the specification to Chalice
• Allows the verification of sep. logic directly using a first-order theorem prover
• Requires extension to handle predicates• Such experiments planned for future work..
Future/Ongoing work
• We found the (experimental) implementation of Chalice predicates to be unsound
• Once this is fixed, our connection will be extended to (partly) cover predicates
• Extending Chalice with more connectives can be aided by our concrete semantics
• Extending Separation Logic contracts with “old” expressions, using total heaps semantics
Thank you for listening..
Kripke semantics over total heaps
Kripke semantics over partial heaps
Weakest pre-condition definitions
Chalice : verification condition generation
Kripke semantics over total heaps
Implicit Dynamic Frames (IDF)SL+Separation Logic
(SL)
≡
≡≡⊂ ⊃