Demonstration of the Iris separation logic in Coq Robbert Krebbers 1 Delft University of Technology, The Netherlands January 21, 2017 @ Coq PL, Paris, France 1 Iris is joint work with: Ralf Jung, Jacques-Hendri Jourdan, Aleˇ s Bizjak, David Swasey, Filip Sieczkowski, Kasper Svendsen, Aaron Turon, Amin Timany, Derek Dreyer, and Lars Birkedal 1
Iris Proof Mode (IPM) Goal: reasoning in an object logic in the same style as reasoning in Coq 2
Iris Proof Mode (IPM) Goal: reasoning in an object logic in the same style as reasoning in Coq 2
Iris Proof Mode (IPM) Goal: reasoning in an object logic in the same style as reasoning in Coq How? ◮ Extend Coq with (spatial and non-spatial) named proof contexts for an object logic ◮ Tactics for introduction and elimination of all connectives of the object logic ◮ Entirely implemented using reflection, type classes and Ltac (no OCaml plugin needed) 2
Iris Proof Mode (IPM) Goal: reasoning in Iris in the same style as reasoning in Coq How? ◮ Extend Coq with (spatial and non-spatial) named proof contexts for Iris ◮ Tactics for introduction and elimination of all connectives of Iris ◮ Entirely implemented using reflection, type classes and Ltac (no OCaml plugin needed) Iris : language independent higher-order separation logic for modular reasoning about fine-grained concurrency in Coq 2
Demo 3
The setup of IPM in a nutshell ◮ Deep embedding of contexts as association lists: Record envs := Envs { env persistent : env iProp ; env spatial : env iProp } . Coercion of envs (∆ : envs ) : iProp := ( � envs wf ∆ � ∗ � [ ∗ ] env persistent ∆ ∗ [ ∗ ] env spatial ∆)% I . 4
The setup of IPM in a nutshell ◮ Deep embedding of contexts as association lists: Record envs := Envs { env persistent : env iProp ; env spatial : env iProp } . Coercion of envs (∆ : envs ) : iProp := ( � envs wf ∆ � ∗ � [ ∗ ] env persistent ∆ ∗ [ ∗ ] env spatial ∆)% I . Propositions that enjoy P ⇔ P ∗ P 4
The setup of IPM in a nutshell ◮ Deep embedding of contexts as association lists: Record envs := Envs { env persistent : env iProp ; env spatial : env iProp } . Coercion of envs (∆ : envs ) : iProp := ( � envs wf ∆ � ∗ � [ ∗ ] env persistent ∆ ∗ [ ∗ ] env spatial ∆)% I . Propositions that enjoy P ⇔ P ∗ P ◮ Tactics implemented by reflection: Lemma tac sep split ∆ ∆ 1 ∆ 2 lr js Q1 Q2 : envs split lr js ∆ = Some (∆ 1 ,∆ 2 ) → (∆ 1 ⊢ Q1 ) → (∆ 2 ⊢ Q2 ) → ∆ ⊢ Q1 ∗ Q2 . 4
The setup of IPM in a nutshell ◮ Deep embedding of contexts as association lists: Record envs := Envs { env persistent : env iProp ; env spatial : env iProp } . Coercion of envs (∆ : envs ) : iProp := ( � envs wf ∆ � ∗ � [ ∗ ] env persistent ∆ ∗ [ ∗ ] env spatial ∆)% I . Propositions that enjoy P ⇔ P ∗ P ◮ Tactics implemented by reflection: Lemma tac sep split ∆ ∆ 1 ∆ 2 lr js Q1 Q2 : envs split lr js ∆ = Some (∆ 1 ,∆ 2 ) → (∆ 1 ⊢ Q1 ) → (∆ 2 ⊢ Q2 ) → ∆ ⊢ Q1 ∗ Q2 . Context splitting implemented in Gallina 4
The setup of IPM in a nutshell ◮ Deep embedding of contexts as association lists: Record envs := Envs { env persistent : env iProp ; env spatial : env iProp } . Coercion of envs (∆ : envs ) : iProp := ( � envs wf ∆ � ∗ � [ ∗ ] env persistent ∆ ∗ [ ∗ ] env spatial ∆)% I . Propositions that enjoy P ⇔ P ∗ P ◮ Tactics implemented by reflection: Lemma tac sep split ∆ ∆ 1 ∆ 2 lr js Q1 Q2 : envs split lr js ∆ = Some (∆ 1 ,∆ 2 ) → (∆ 1 ⊢ Q1 ) → (∆ 2 ⊢ Q2 ) → ∆ ⊢ Q1 ∗ Q2 . Context splitting implemented in Gallina ◮ Ltac wrappers around reflective tactics: Tactic Notation "iSplitL" constr ( Hs ) := Report sensible error to the user let Hs := words Hs in ; eapply tac sep split with false Hs [ env cbv ; reflexivity | | fail "iSplitL: hypotheses" Hs "not found in the context" | (* goal 1 *) | (* goal 2 *) ] . 4
This talk Demonstrate some uses of IPM: ◮ Symbolic execution ◮ Lock based concurrency ◮ Verification of a spin lock 5
Part #1: symbolic execution 6
Hoare triples Hoare triples for partial program correctness: { P } e { w . Q } Precondition Postcondition Binder for return value If the initial state satisfies P , then: ◮ e does not get stuck/crash ◮ if e terminates with value v , the final state satisfies Q [ v / w ] 7
Separation logic [O’Hearn, Reynolds, Yang] The points-to connective x �→ v ◮ provides the knowledge that location x has value v , and ◮ provides exclusive ownership of x Separating conjunction P ∗ Q : the state consists of disjoint parts satisfying P and Q 8
Separation logic [O’Hearn, Reynolds, Yang] The points-to connective x �→ v ◮ provides the knowledge that location x has value v , and ◮ provides exclusive ownership of x Separating conjunction P ∗ Q : the state consists of disjoint parts satisfying P and Q Example: { x �→ v 1 ∗ y �→ v 2 } swap ( x , y ) { w . w = () ∧ x �→ v 2 ∗ y �→ v 1 } the ∗ ensures that x and y are different 8
Proving Hoare triples using IPM Consider: { x �→ v 1 ∗ y �→ v 2 } swap ( x , y ) { x �→ v 2 ∗ y �→ v 1 } How to use IPM to manipulate the precondition? 9
Proving Hoare triples using IPM Consider: { x �→ v 1 ∗ y �→ v 2 } swap ( x , y ) { x �→ v 2 ∗ y �→ v 1 } How to use IPM to manipulate the precondition? Solution: define Hoare triple in terms of weakest preconditions We let: { P } e { w . Q } � � ( P − ∗ wp e { w . Q } ) where wp e { w . Q } gives the weakest precondition under which: ◮ all executions of e are safe ◮ if e terminates with value v , the final state satisfies Q [ v / w ] 9
Rules for weakest precondition Rule of ‘consequence’: wp e { v . wp K [ v ] { Φ }} − ∗ wp K [ e ] { Φ } Value rule: Φ v − ∗ wp v { Φ } Lamda rule: wp e [ v / x ] { Φ } − ∗ wp ( λ x . e ) v { Φ } 10
Stateful rules for weakest preconditions Let us just translate the Hoare rules naively: ℓ �→ v − ∗ wp ! ℓ { w . w = v ∗ ℓ �→ v } ℓ �→ v 1 − ∗ wp ℓ := v 2 { w . w = () ∗ ℓ �→ v 2 } Problems: ◮ Having to frame and weaken to apply these rules ◮ Equalities in the postconditions 11
Stateful rules for weakest preconditions Let us just translate the Hoare rules naively: ℓ �→ v − ∗ wp ! ℓ { w . w = v ∗ ℓ �→ v } ℓ �→ v 1 − ∗ wp ℓ := v 2 { w . w = () ∗ ℓ �→ v 2 } Problems: ◮ Having to frame and weaken to apply these rules ◮ Equalities in the postconditions ‘Backwards’ or ‘predicate transformer’ formulation: ℓ �→ v ∗ ( ℓ �→ v − ∗ Φ v ) − ∗ wp ! ℓ { Φ } ℓ �→ v 1 ∗ ( ℓ �→ v 2 − ∗ Φ ()) − ∗ wp ℓ := v 2 { Φ } Resources that have to be given up Resources that are given back 11
Nicer definition of the Hoare triple [J-O. Kaiser] x RET w . Q } � � ( ∀ Φ. P − { P } e { � ∗ ( ∀ � x . Q − ∗ Φ w ) − ∗ wp e { Φ } ) Resources that have to be given up Resources that are given back 12
Demo 13
Part #2: lock based concurrency 14
Concurrent separation logic [O’Hearn] The par rule: { P 1 } e 1 { Q 1 } { P 2 } e 2 { Q 2 } { P 1 ∗ P 2 } e 1 || e 2 { Q 1 ∗ Q 2 } 15
Concurrent separation logic [O’Hearn] The par rule: { P 1 } e 1 { Q 1 } { P 2 } e 2 { Q 2 } { P 1 ∗ P 2 } e 1 || e 2 { Q 1 ∗ Q 2 } For example: { x �→ 4 ∗ y �→ 6 } x := ! x + 2 y := ! y + 2 { x �→ 6 ∗ y �→ 8 } 15
Concurrent separation logic [O’Hearn] The par rule: { P 1 } e 1 { Q 1 } { P 2 } e 2 { Q 2 } { P 1 ∗ P 2 } e 1 || e 2 { Q 1 ∗ Q 2 } For example: { x �→ 4 ∗ y �→ 6 } { x �→ 4 } { y �→ 6 } x := ! x + 2 y := ! y + 2 { x �→ 6 ∗ y �→ 8 } 15
Concurrent separation logic [O’Hearn] The par rule: { P 1 } e 1 { Q 1 } { P 2 } e 2 { Q 2 } { P 1 ∗ P 2 } e 1 || e 2 { Q 1 ∗ Q 2 } For example: { x �→ 4 ∗ y �→ 6 } { x �→ 4 } { y �→ 6 } x := ! x + 2 y := ! y + 2 { x �→ 6 } { y �→ 8 } { x �→ 6 ∗ y �→ 8 } 15
Concurrent separation logic [O’Hearn] The par rule: { P 1 } e 1 { Q 1 } { P 2 } e 2 { Q 2 } { P 1 ∗ P 2 } e 1 || e 2 { Q 1 ∗ Q 2 } For example: { x �→ 4 ∗ y �→ 6 } { x �→ 4 } { y �→ 6 } x := ! x + 2 y := ! y + 2 { x �→ 6 } { y �→ 8 } { x �→ 6 ∗ y �→ 8 } Works great for concurrent programs without shared memory: concurrent quick sort, concurrent merge sort, . . . 15
What about shared state? A simple problem: { True } let x = ref (0) in let y = ref (4) in swap x y assert (! x + ! y = 4) { True } 16
What about shared state? A simple problem: { True } let x = ref (0) in let y = ref (4) in let z = new lock () in acquire z acquire z swap x y assert (! x + ! y = 4) release z release z { True } 16
Specification of a lock Specifications of the operations: Lock invariant { P } new lock () { l . IsLock( l , P ) } { IsLock( l , P ) } acquire l { P } { IsLock( l , P ) ∗ P } release l { True } The IsLock predicate can be shared among threads: IsLock( l , P ) ⇔ IsLock( l , P ) ∗ IsLock( l , P ) 17
Recommend
More recommend