cyclic proofs of program termination in separation logic
play

Cyclic Proofs of Program Termination in Separation Logic James - PowerPoint PPT Presentation

Cyclic Proofs of Program Termination in Separation Logic James Brotherston 1 , Richard Bornat 2 , and Cristiano Calcagno 1 1 Imperial College, London 2 Middlesex University, London Me 10 January, 2008 Overview We give a new method for


  1. Cyclic Proofs of Program Termination in Separation Logic James Brotherston ∗ 1 , Richard Bornat 2 , and Cristiano Calcagno 1 1 Imperial College, London 2 Middlesex University, London ∗ Me 10 January, 2008

  2. Overview • We give a new method for proving program termination. • We consider simple, heap-manipulating imperative programs. • We use separation logic with inductive definitions to express termination preconditions. • Our proofs of termination are cyclic proofs: cyclic derivations satisfying a soundness condition.

  3. TOY-C : a simple imperative programming language ::= nil | x ( x ∈ Var ) | . . . E ::= E = E | E � = E Cond ::= x := E | x := [ E ] | [ E ] := E | x := new () C | free ( E ) | if Cond goto j | stop A program in TOY-C is a finite sequence 1 : C 1 ; · · · n : C n . Example (Linked list traversal) 1 : if x = nil goto 4 , 2 : x := [ x ] , 3 : goto 1 , 4 : stop · · · x nil

  4. Semantics of TOY-C • A program state is a triple ( i, s, h ), where i is a index of the program, s is a stack and h is a heap. • The semantics of TOY-C programs is then given by a “one-step” binary relation � on program states. • We write ( i, s, h ) ↓ to mean there is no infinite � -sequence ( i, s, h ) � . . . , i.e., the program terminates (without faulting) when started in the state ( i, s, h ).

  5. A Hoare proof system for termination • We write termination judgements F ⊢ i ↓ where i is a program label and F is a formula of separation logic with inductive predicates. • E.g. we can define (possibly cyclic) linked list segments in separation logic by the definition: ⇒ ls x x emp x �→ x ′ ∗ ls x ′ y ⇒ ls x y • F ⊢ i ↓ is valid if for all s, h. s, h | = F implies ( i, s, h ) ↓

  6. Proof rules We have two types of proof rule: 1. logical rules similar to left-introduction rules in sequent calculus. Each inductive predicate also has a case-split rule, e.g. for ls : Γ( t 1 = t 2 ∧ emp ) ⊢ i ↓ Γ( t 1 �→ x ∗ ls x t 2 ) ⊢ i ↓ x fresh (Case ls ) Γ( ls t 1 t 2 ) ⊢ i ↓ 2. symbolic execution rules which simulate commands. E.g.: Cond ∧ F ⊢ j ↓ ¬ Cond ∧ F ⊢ i +1 ↓ C i ≡ if Cond goto j F ⊢ i ↓ Paths in a derivation thus correspond to program computations.

  7. Cyclic proofs of termination judgements • A cyclic pre-proof is a regular, infinite derivation tree, represented as a cyclic graph: • • (Axiom) • • • · · · • (Inference) • • • A cyclic proof is a pre-proof satisfying the condition: Every infinite path in the pre-proof has a tail on which one can “trace” some inductive definition that is unfolded infinitely often (using the case-split rules)

  8. Reversing a “frying-pan” list • The classical list reverse algorithm is: 1 . y := nil 4 . x := [ x ] 7 . goto 2 2 . if x = nil goto 8 5 . [ z ] := y 8 . stop 3 . z := x 6 . y := z • The invariant for this algorithm given a cyclic list is: ∃ k 1 , k 2 , k 3 · ( ls x j ∗ ls y nil ∗ j �→ k 1 ∗ ls k 1 j ) ∨ ( ls k 2 nil ∗ j �→ k 2 ∗ ls x j ∗ ls y j ) ∨ ( ls x nil ∗ ls y j ∗ j �→ k 3 ∗ ls k 3 j ) rev P0 rev P j j j P rev H0 H1 rev H0 H1 rev H y y x x x y P1 • We want to prove that the invariant implies termination.

  9. Reversing a “frying-pan” list — the cyclic proof A C ls y j ∗ ls x nil ∗ ls y j ∗ ls k2 nil ∗ ⊢ 2 ↓ E ⊢ 2 ↓ j �→ k3 ∗ ls k3 j j �→ k2 ∗ ls x j B goto 2 goto 2 ls y j ∗ ls x nil ∗ ls y j ∗ ls k2 nil ∗ ⊢ 7 ↓ ⊢ 7 ↓ j �→ k3 ∗ ls k3 j j �→ k2 ∗ ls x j D (Cut) (Cut) y = j ∧ y = j ∧ ls x nil ∗ ls y j ∗ ( ls x nil ∗ j �→ k3 ∗ ⊢ 2 ↓ ⊢ 7 ↓ ( emp ∗ ls k2 nil ∗ ⊢ 7 ↓ j �→ k3 ∗ ls k3 j ls y nil ∗ ls x j ∗ emp ∗ ls k3 j ) goto 2 j �→ k2 ∗ ls x j ) ⊢ 2 ↓ ( = ) ls x nil ∗ ls y j ∗ j �→ k1 ∗ ls k1 j ) ( = ) ls k2 nil ∗ j �→ k2 ∗ y = z ∧ z = j ∧ ⊢ 7 ↓ y = z ∧ z = j ∧ goto 2 ⊢ 2 ↓ j �→ k3 ∗ ls k3 j ( ls x nil ∗ z �→ y ′ ∗ ls x j ∗ ls y j ) ( emp ∗ ls y ′ nil ∗ ls y nil ∗ ls x j ∗ ⊢ 7 ↓ (Cut) ⊢ 7 ↓ ⊢ 7 ↓ y = z ∧ ( z �→ y ′ ∗ emp ∗ ls y ′ j ) goto 2 z �→ y ′ ∗ ls x j ) j �→ k1 ∗ ls k1 j ) ls k2 nil ∗ j �→ k2 ∗ ls x nil ∗ ls y ′ j ∗ (Cut) y := z ⊢ 7 ↓ ⊢ 7 ↓ y := z y = z ∧ ( z �→ y ′ ∗ ls x j ∗ ls y j ) z = j ∧ z = j ∧ j �→ k3 ∗ ls k3 j ls x j ∗ ls y ′ nil ∗ (Cut) ( ls x nil ∗ z �→ y ∗ ⊢ 7 ↓ ⊢ 6 ↓ ( emp ∗ ls y nil ∗ y := z ⊢ 6 ↓ y = z ∧ emp ∗ ls y j ) z �→ y ∗ ls x nil ∗ j �→ k1 ∗ ls k1 j ) z �→ y ∗ ls x j ) ( ls k2 nil ∗ j �→ k2 ∗ ⊢ 7 ↓ y := z [ z ] := y z �→ y ′ ∗ ls x j ∗ ls y ′ j ) ls y j ∗ j �→ k3 ∗ ⊢ 6 ↓ [ z ] := y z = j ∧ z �→ y ∗ z = j ∧ ls k3 j y := z ( ls x nil ∗ z �→ x ∗ ls x j ∗ ls y nil ∗ ⊢ 6 ↓ ⊢ 5 ↓ ( emp ∗ ls y nil ∗ [ z ] := y ⊢ 5 ↓ ls k2 nil ∗ j �→ k2 ∗ z �→ x ∗ ls x nil ∗ emp ∗ ls y j ) ⊢ 6 ↓ j �→ k1 ∗ ls k1 j z �→ x ∗ ls x j ) z �→ y ∗ ls x j ∗ ls y j [ z ] := y ( = ) ls y j ∗ j �→ k3 ∗ ⊢ 5 ↓ ( = ) [ z ] := y x = k2 ∧ z = j ∧ z �→ x ∗ x = k1 ∧ z = j ∧ ls k2 nil ∗ j �→ k2 ∗ ls k3 j x ′ = j ∧ ( ls k2 nil ∗ x ′ = j ∧ ( emp ∗ ls y nil ∗ ls x j ∗ ls y nil ∗ ⊢ 5 ↓ ⊢ 5 ↓ ⊢ 5 ↓ ( = ) ⊢ 5 ↓ z �→ x ∗ ls x j ∗ ls y j x = x ′ ∧ z = x ′′ ∧ x ′ �→ k2 ∗ emp ∗ ls y j ) x ′ �→ k1 ∗ ls k1 j ) j �→ k1 ∗ ls k1 j ( = ) ( x ′′ �→ x ′ ∗ ls x ′ nil ∗ x = x ′ ∧ z = x ′′ ∧ x := [ x ] ( = ) x := [ x ] z = x ′′ ∧ x = x ′ ∧ z = j ∧ x = j ∧ ⊢ 5 ↓ z = j ∧ x = j ∧ ( ls k2 nil ∗ j �→ k2 ∗ ls y j ∗ j �→ k3 ∗ ⊢ 5 ↓ ( x ′′ �→ x ′ ∗ ls x ′ j ∗ ls y nil ∗ ( ls k2 nil ∗ x �→ k2 ∗ ⊢ 4 ↓ ( emp ∗ ls y nil ∗ ⊢ 5 ↓ x ′′ �→ x ′ ∗ ls x ′ j ∗ ls y j ) ⊢ 4 ↓ ls k3 j ) emp ∗ ls y j ) = = = = = = = = = = = = = = = = = = = = = x := [ x ] x �→ k1 ∗ ls k1 j ) j �→ k1 ∗ ls k1 j ) ( ⊥ ) = = = = = = = = = = = = = = = = = = = = = = = = = x := [ x ] = = = = = = = = = = = = = = = = = = = = = = = = = = x := [ x ] ( = ) z = x ∧ x � = nil ∧ z = x ∧ x � = nil ∧ ( = ) z = x ∧ x = j ∧ z = x ∧ x � = j ∧ ( x �→ x ′ ∗ ls x ′ nil ∗ z = x ∧ x = j ∧ z = x ∧ x = nil ∧ ( emp ∗ ( x �→ x ′ ∗ ls x ′ j ∗ ls y nil ∗ ( ls k2 nil ∗ j �→ k2 ∗ ⊢ 4 ↓ ( ls k2 nil ∗ j �→ k2 ∗ ⊢ 4 ↓ ⊢ 4 ↓ ⊢ 4 ↓ ( emp ∗ ls y nil ∗ ⊢ 4 ↓ ⊢ 4 ↓ ls y j ∗ j �→ k3 ∗ ls y j ∗ j �→ k3 ∗ x �→ x ′ ∗ ls x ′ j ∗ ls y j ) emp ∗ ls y j ) j �→ k1 ∗ ls k1 j ) j �→ k1 ∗ ls k1 j ) ls k3 j ) ls k3 j ) = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = (Case ls ) = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = (Case ls ) ls z = x ∧ x � = nil ∧ z = x ∧ x � = nil ∧ z = x ∧ x � = nil ∧ ( ls x j ∗ ls y nil ∗ ( ls k2 nil ∗ j �→ k2 ∗ ⊢ 4 ↓ ⊢ 4 ↓ ( ls x nil ∗ ls y j ∗ ⊢ 4 ↓ ls x j ∗ ls y j ) j �→ k1 ∗ ls k1 j ) j �→ k3 ∗ ls k3 j ) ( ⊥ ) z := x ( ⊥ ) z := x z := x stop x = nil ∧ x � = nil ∧ x = nil ∧ x � = nil ∧ x = nil ∧ x � = nil ∧ ( ls x j ∗ ls y nil ∗ ⊢ 8 ↓ ( ls x j ∗ ls y nil ∗ ⊢ 3 ↓ ( ls k2 nil ∗ j �→ k2 ∗ ⊢ 8 ↓ ( ls k2 nil ∗ j �→ k2 ∗ ⊢ 3 ↓ ( ls x nil ∗ ls y j ∗ ⊢ 8 ↓ ( ls x nil ∗ ls y j ∗ ⊢ 3 ↓ j �→ k1 ∗ ls k1 j ) j �→ k1 ∗ ls k1 j ) ls x j ∗ ls y j ) ls x j ∗ ls y j ) j �→ k3 ∗ ls k3 j ) j �→ k3 ∗ ls k3 j ) if x = nil goto 8 if x = nil goto 8 if x = nil goto 8 ls x j ∗ ls y nil ∗ j �→ k1 ∗ ls k1 j ⊢ 2 ↓ ls k2 nil ∗ j �→ k2 ∗ ls x j ∗ ls y j ⊢ 2 ↓ ls x nil ∗ ls y j ∗ j �→ k3 ∗ ls k3 j ⊢ 2 ↓ ( ∨ ) ( ls x j ∗ ls y nil ∗ j �→ k1 ∗ ls k1 j ) ∨ ( ls k2 nil ∗ j �→ k2 ∗ ls x j ∗ ls y j ) ∨ ( ls x nil ∗ ls y j ∗ j �→ k3 ∗ ls k3 j ) ⊢ 2 ↓

  10. Properties of the proof system Theorem (Soundness) If there is a cyclic proof of F ⊢ i ↓ then F ⊢ i ↓ is valid. Proposition It is decidable whether a cyclic pre-proof is a cyclic proof, i.e. whether it satisfies the soundness condition. Theorem (Relative completeness) If F ⊢ i ↓ is valid then there is a formula G such that F ⊢ G is a valid implication of separation logic and: F ⊢ G provable ⇒ F ⊢ i ↓ provable

  11. Conclusion • We have developed a novel method for proving program termination, based on cyclic proof. • Use of the soundness condition for cyclic proofs means that termination measures are employed only implicitly. • We plan to extend the programming language we consider to include e.g. procedures. • We could also consider proving arbitrary postconditions. • Possibility of adapting the approach to other programming paradigms, e.g. functional programming.

Recommend


More recommend