SLIDE 1 Automatic Cyclic Termination Proofs for Recursive Procedures in Separation Logic
Reuben Rowe and James Brotherston
University College London
TAPAS, Edinburgh, Wednesday 7th September 2016
SLIDE 2
Automatically Proving Termination: Challenges
proc shuffle(x) { if x != nil { y := *x; reverse(y); shuffle(y); } } heap manipulation intermediate procedures recursion
1/11
SLIDE 3
Automatically Proving Termination: Challenges
proc shuffle(x) { if x != nil { y := *x; reverse(y); shuffle(y); } } heap manipulation intermediate procedures recursion
1/11
SLIDE 4
Automatically Proving Termination: Challenges
proc shuffle(x) { if x != nil { y := *x; reverse(y); shuffle(y); } } heap manipulation intermediate procedures recursion
1/11
SLIDE 5
Automatically Proving Termination: Challenges
proc shuffle(x) { if x != nil { y := *x; reverse(y); shuffle(y); } } heap manipulation intermediate procedures recursion
1/11
SLIDE 6 Automatically Proving Termination: Some Solutions
- Mutant, Thor
- Julia, Costa, AProVE
- Dafny
- HipTNT
2/11
SLIDE 7 Automatically Proving Termination: Some Solutions
- Mutant, Thor
- Julia, Costa, AProVE
- Dafny
- HipTNT
2/11
SLIDE 8 Automatically Proving Termination: Some Solutions
- Mutant, Thor
- Julia, Costa, AProVE
- Dafny
- HipTNT
2/11
SLIDE 9 Automatically Proving Termination: Some Solutions
- Mutant, Thor
- Julia, Costa, AProVE
- Dafny
- HipTNT+
2/11
SLIDE 10 Automatically Proving Termination using Cyclic Proof
- Following the approach of Brotherston Et Al. (POPL ’08)
. . . . . . . .
(Inference)
· · φ ⊢ C
(Axiom)
· · ·
- We use the Cyclist framework for automation
3/11
SLIDE 11 Automatically Proving Termination using Cyclic Proof
- Following the approach of Brotherston Et Al. (POPL ’08)
. . . . . . . .
(Inference)
· · φ ⊢ C
(Axiom)
· · ·
- Separation Logic
- We use the Cyclist framework for automation
3/11
SLIDE 12 Automatically Proving Termination using Cyclic Proof
- Following the approach of Brotherston Et Al. (POPL ’08)
. . . . . . . .
(Inference)
· · φ ⊢ C
(Axiom)
· · ·
Inductive Predicates for data
- We use the Cyclist framework for automation
3/11
SLIDE 13 Automatically Proving Termination using Cyclic Proof
- Following the approach of Brotherston Et Al. (POPL ’08)
. . . . . . . .
(Inference)
· · φ ⊢ C
(Axiom)
· · ·
Inductive Predicates for data total correctness semantics
- We use the Cyclist framework for automation
3/11
SLIDE 14 Automatically Proving Termination using Cyclic Proof
- Following the approach of Brotherston Et Al. (POPL ’08)
. . . . . . . .
(Inference)
· · {φ} C {ψ}
(Axiom)
· · ·
Inductive Predicates for data total correctness semantics
- We use the Cyclist framework for automation
3/11
SLIDE 15 Automatically Proving Termination using Cyclic Proof
- Following the approach of Brotherston Et Al. (POPL ’08)
. . . . . . . .
(Inference)
· · {φ} C {ψ}
(Axiom)
· · ·
- We use the Cyclist framework for automation
3/11
SLIDE 16 Advantages of Using Cyclic Proof
- Termination measures extracted automatically
- Supports compositional reasoning
- Naturally encapsulates inductive principles
4/11
SLIDE 17 Advantages of Using Cyclic Proof
- Termination measures extracted automatically
- Supports compositional reasoning
- Naturally encapsulates inductive principles
4/11
SLIDE 18 Advantages of Using Cyclic Proof
- Termination measures extracted automatically
- Supports compositional reasoning
- Naturally encapsulates inductive principles
4/11
SLIDE 19
Ingredients of our Approach: Symbolic Execution
(free): {φ} C {ψ} {φ ∗ x → y} free(x); C {ψ} (load): x v x x y v x x C (x fresh) y v x := *y; C (proc): C (body proc C) proc(x)
5/11
SLIDE 20
Ingredients of our Approach: Symbolic Execution
(free): {φ} C {ψ} {φ ∗ x → y} free(x); C {ψ} (load): {x = v[x′/x] ∧ (φ ∗ y → v)[x′/x]} C {ψ} (x′ fresh) {φ ∗ y → v} x := *y; C {ψ} (proc): C (body proc C) proc(x)
5/11
SLIDE 21
Ingredients of our Approach: Symbolic Execution
(free): {φ} C {ψ} {φ ∗ x → y} free(x); C {ψ} (load): {x = v[x′/x] ∧ (φ ∗ y → v)[x′/x]} C {ψ} (x′ fresh) {φ ∗ y → v} x := *y; C {ψ} (proc): {φ} C {ψ} (body(proc) = C) {φ} proc( x) {ψ}
5/11
SLIDE 22 Ingredients of our Approach: Inductive Predicates
- We support user-defjned inductive predicates, e.g.
x = nil ∧ emp list(x) x → y ∗ list(y) list(x)
- Explicit approximations used as termination measures, e.g.
list x C
- A logical rule schema allows case split
x nil emp C x y list x C list x C
6/11
SLIDE 23 Ingredients of our Approach: Inductive Predicates
- We support user-defjned inductive predicates, e.g.
x = nil ∧ emp list(x) x → y ∗ list(y) list(x)
- Explicit approximations used as termination measures, e.g.
{listα(x) ∗ φ} C {ψ}
- A logical rule schema allows case split
x nil emp C x y list x C list x C
6/11
SLIDE 24 Ingredients of our Approach: Inductive Predicates
- We support user-defjned inductive predicates, e.g.
x = nil ∧ emp list(x) x → y ∗ list(y) list(x)
- Explicit approximations used as termination measures, e.g.
{listα(x) ∗ φ} C {ψ}
- A logical rule schema allows case split
{(x = nil ∧ emp) ∗ φ} C {ψ} {(β < α ∧ x → y ∗ listβ(x)) ∗ φ} C {ψ} {listα(x) ∗ φ} C {ψ}
6/11
SLIDE 25 Ingredients of our Approach: Inductive Predicates
- We support user-defjned inductive predicates, e.g.
x = nil ∧ emp list(x) x → y ∗ list(y) list(x)
- Explicit approximations used as termination measures, e.g.
{listα(x) ∗ φ} C {ψ}
- A logical rule schema allows case split
{(x = nil ∧ emp) ∗ φ} C {ψ} {(β < α ∧ x → y ∗ listβ(x)) ∗ φ} C {ψ} {listα(x) ∗ φ} C {ψ}
6/11
SLIDE 26
A Cyclic Termination Proof for shuffle
proc shuffle(x) { if x!=nil { y:=*x; reverse(y); shuffle(y); } } 7/11
SLIDE 27
A Cyclic Termination Proof for shuffle
proc shuffle(x) { if x!=nil { y:=*x; reverse(y); shuffle(y); } }
· · · {listβ(y)} reverse(y) {listβ(y)}
7/11
SLIDE 28
A Cyclic Termination Proof for shuffle
proc shuffle(x) { if x!=nil { y:=*x; reverse(y); shuffle(y); } }
{listα(x)} shuffle(x) {listα(x)}
7/11
SLIDE 29 A Cyclic Termination Proof for shuffle
proc shuffle(x) { if x!=nil { y:=*x; reverse(y); shuffle(y); } }
list y rev(y); list y frame x y list y rev(y); x y list y list x shuf(x); list x (subst) list y shuf(y); list y (frame) x y list y shuf(y); x y list y (conseq) x y list y shuf(y); list x (seq) x y list y rev(y); list x (load) x v list v y:=*x; list x (case list) x nil list x y:=*x; list x ( ) x nil list x list x (if) {listα(x)} if x!=nil { y:=*x; reverse(y); shuffle(y); *x:=y; } {listα(x)} (proc) {listα(x)} shuffle(x) {listα(x)}
7/11
SLIDE 30 A Cyclic Termination Proof for shuffle
proc shuffle(x) { if x!=nil { y:=*x; reverse(y); shuffle(y); } }
list y rev(y); list y frame x y list y rev(y); x y list y list x shuf(x); list x (subst) list y shuf(y); list y (frame) x y list y shuf(y); x y list y (conseq) x y list y shuf(y); list x (seq) x y list y rev(y); list x (load) x v list v y:=*x; list x (case list) x nil list x y:=*x; list x ( ) x nil list x list x (if) {listα(x)} if x!=nil . . . {listα(x)} (proc) {listα(x)} shuffle(x) {listα(x)}
7/11
SLIDE 31 A Cyclic Termination Proof for shuffle
proc shuffle(x) { if x!=nil { y:=*x; reverse(y); shuffle(y); } }
list y rev(y); list y frame x y list y rev(y); x y list y list x shuf(x); list x (subst) list y shuf(y); list y (frame) x y list y shuf(y); x y list y (conseq) x y list y shuf(y); list x (seq) x y list y rev(y); list x (load) x v list v y:=*x; list x (case list) {x = nil ∧ listα(x)} y:=*x; . . . {listα(x)} ( ) {x = nil ∧ listα(x)} ǫ {listα(x)} (if) {listα(x)} if x!=nil . . . {listα(x)} (proc) {listα(x)} shuffle(x) {listα(x)}
7/11
SLIDE 32 A Cyclic Termination Proof for shuffle
proc shuffle(x) { if x!=nil { y:=*x; reverse(y); shuffle(y); } }
list y rev(y); list y frame x y list y rev(y); x y list y list x shuf(x); list x (subst) list y shuf(y); list y (frame) x y list y shuf(y); x y list y (conseq) x y list y shuf(y); list x (seq) x y list y rev(y); list x (load) x v list v y:=*x; list x (case list) {x = nil ∧ listα(x)} y:=*x; . . . {listα(x)} (| =) {x = nil ∧ listα(x)} ǫ {listα(x)} (if) {listα(x)} if x!=nil . . . {listα(x)} (proc) {listα(x)} shuffle(x) {listα(x)}
7/11
SLIDE 33 A Cyclic Termination Proof for shuffle
proc shuffle(x) { if x!=nil { y:=*x; reverse(y); shuffle(y); } }
list y rev(y); list y frame x y list y rev(y); x y list y list x shuf(x); list x (subst) list y shuf(y); list y (frame) x y list y shuf(y); x y list y (conseq) x y list y shuf(y); list x (seq) x y list y rev(y); list x (load) {β < α ∧ x → v ∗ listβ(v)} y:=*x; . . . {listα(x)} (case list) {x = nil ∧ listα(x)} y:=*x; . . . {listα(x)} (| =) {x = nil ∧ listα(x)} ǫ {listα(x)} (if) {listα(x)} if x!=nil . . . {listα(x)} (proc) {listα(x)} shuffle(x) {listα(x)}
7/11
SLIDE 34 A Cyclic Termination Proof for shuffle
proc shuffle(x) { if x!=nil { y:=*x; reverse(y); shuffle(y); } }
list y rev(y); list y frame x y list y rev(y); x y list y list x shuf(x); list x (subst) list y shuf(y); list y (frame) x y list y shuf(y); x y list y (conseq) x y list y shuf(y); list x (seq) {β < α ∧ x → y ∗ listβ(y)} rev(y); . . . {listα(x)} (load) {β < α ∧ x → v ∗ listβ(v)} y:=*x; . . . {listα(x)} (case list) {x = nil ∧ listα(x)} y:=*x; . . . {listα(x)} (| =) {x = nil ∧ listα(x)} ǫ {listα(x)} (if) {listα(x)} if x!=nil . . . {listα(x)} (proc) {listα(x)} shuffle(x) {listα(x)}
7/11
SLIDE 35 A Cyclic Termination Proof for shuffle
proc shuffle(x) { if x!=nil { y:=*x; reverse(y); shuffle(y); } }
list y rev(y); list y frame β < α ∧ x → y ∗ listβ(y)
β < α ∧ x → y ∗ listβ(y)
x shuf(x); list x (subst) list y shuf(y); list y (frame) x y list y shuf(y); x y list y (conseq) {β < α ∧ x → y ∗ listβ(y)} shuf(y); {listα(x)} (seq) {β < α ∧ x → y ∗ listβ(y)} rev(y); . . . {listα(x)} (load) {β < α ∧ x → v ∗ listβ(v)} y:=*x; . . . {listα(x)} (case list) {x = nil ∧ listα(x)} y:=*x; . . . {listα(x)} (| =) {x = nil ∧ listα(x)} ǫ {listα(x)} (if) {listα(x)} if x!=nil . . . {listα(x)} (proc) {listα(x)} shuffle(x) {listα(x)}
7/11
SLIDE 36 A Cyclic Termination Proof for shuffle
proc shuffle(x) { if x!=nil { y:=*x; reverse(y); shuffle(y); } }
{listβ(y)} rev(y); {listβ(y)} (frame) β < α ∧ x → y ∗ listβ(y)
β < α ∧ x → y ∗ listβ(y)
x shuf(x); list x (subst) list y shuf(y); list y (frame) x y list y shuf(y); x y list y (conseq) {β < α ∧ x → y ∗ listβ(y)} shuf(y); {listα(x)} (seq) {β < α ∧ x → y ∗ listβ(y)} rev(y); . . . {listα(x)} (load) {β < α ∧ x → v ∗ listβ(v)} y:=*x; . . . {listα(x)} (case list) {x = nil ∧ listα(x)} y:=*x; . . . {listα(x)} (| =) {x = nil ∧ listα(x)} ǫ {listα(x)} (if) {listα(x)} if x!=nil . . . {listα(x)} (proc) {listα(x)} shuffle(x) {listα(x)}
7/11
SLIDE 37 A Cyclic Termination Proof for shuffle
proc shuffle(x) { if x!=nil { y:=*x; reverse(y); shuffle(y); } }
{listβ(y)} rev(y); {listβ(y)} (frame) β < α ∧ x → y ∗ listβ(y)
β < α ∧ x → y ∗ listβ(y)
x shuf(x); list x (subst) list y shuf(y); list y (frame) x y list y shuf(y); x y list y (conseq) {β < α ∧ x → y ∗ listβ(y)} shuf(y); {listα(x)} (seq) {β < α ∧ x → y ∗ listβ(y)} rev(y); . . . {listα(x)} (load) {β < α ∧ x → v ∗ listβ(v)} y:=*x; . . . {listα(x)} (case list) {x = nil ∧ listα(x)} y:=*x; . . . {listα(x)} (| =) {x = nil ∧ listα(x)} ǫ {listα(x)} (if) {listα(x)} if x!=nil . . . {listα(x)} (proc) {listα(x)} shuffle(x) {listα(x)}
7/11
SLIDE 38 A Cyclic Termination Proof for shuffle
proc shuffle(x) { if x!=nil { y:=*x; reverse(y); shuffle(y); } }
{listβ(y)} rev(y); {listβ(y)} (frame) β < α ∧ x → y ∗ listβ(y)
β < α ∧ x → y ∗ listβ(y)
x shuf(x); list x (subst) list y shuf(y); list y (frame) β < α ∧ x → y ∗ listβ(y)
β < α ∧ x → y ∗ listβ(y)
{β < α ∧ x → y ∗ listβ(y)} shuf(y); {listα(x)} (seq) {β < α ∧ x → y ∗ listβ(y)} rev(y); . . . {listα(x)} (load) {β < α ∧ x → v ∗ listβ(v)} y:=*x; . . . {listα(x)} (case list) {x = nil ∧ listα(x)} y:=*x; . . . {listα(x)} (| =) {x = nil ∧ listα(x)} ǫ {listα(x)} (if) {listα(x)} if x!=nil . . . {listα(x)} (proc) {listα(x)} shuffle(x) {listα(x)}
7/11
SLIDE 39 A Cyclic Termination Proof for shuffle
proc shuffle(x) { if x!=nil { y:=*x; reverse(y); shuffle(y); } }
{listβ(y)} rev(y); {listβ(y)} (frame) β < α ∧ x → y ∗ listβ(y)
β < α ∧ x → y ∗ listβ(y)
x shuf(x); list x (subst) {listβ(y)} shuf(y); {listβ(y)} (frame) β < α ∧ x → y ∗ listβ(y)
β < α ∧ x → y ∗ listβ(y)
{β < α ∧ x → y ∗ listβ(y)} shuf(y); {listα(x)} (seq) {β < α ∧ x → y ∗ listβ(y)} rev(y); . . . {listα(x)} (load) {β < α ∧ x → v ∗ listβ(v)} y:=*x; . . . {listα(x)} (case list) {x = nil ∧ listα(x)} y:=*x; . . . {listα(x)} (| =) {x = nil ∧ listα(x)} ǫ {listα(x)} (if) {listα(x)} if x!=nil . . . {listα(x)} (proc) {listα(x)} shuffle(x) {listα(x)}
7/11
SLIDE 40 A Cyclic Termination Proof for shuffle
proc shuffle(x) { if x!=nil { y:=*x; reverse(y); shuffle(y); } }
{listβ(y)} rev(y); {listβ(y)} (frame) β < α ∧ x → y ∗ listβ(y)
β < α ∧ x → y ∗ listβ(y)
- {listα(x)} shuf(x); {listα(x)}
(subst) {listβ(y)} shuf(y); {listβ(y)} (frame) β < α ∧ x → y ∗ listβ(y)
β < α ∧ x → y ∗ listβ(y)
{β < α ∧ x → y ∗ listβ(y)} shuf(y); {listα(x)} (seq) {β < α ∧ x → y ∗ listβ(y)} rev(y); . . . {listα(x)} (load) {β < α ∧ x → v ∗ listβ(v)} y:=*x; . . . {listα(x)} (case list) {x = nil ∧ listα(x)} y:=*x; . . . {listα(x)} (| =) {x = nil ∧ listα(x)} ǫ {listα(x)} (if) {listα(x)} if x!=nil . . . {listα(x)} (proc) {listα(x)} shuffle(x) {listα(x)}
7/11
SLIDE 41 A Cyclic Termination Proof for shuffle
proc shuffle(x) { if x!=nil { y:=*x; reverse(y); shuffle(y); } }
{listβ(y)} rev(y); {listβ(y)} (frame) β < α ∧ x → y ∗ listβ(y)
β < α ∧ x → y ∗ listβ(y)
- {listα(x)} shuf(x); {listα(x)}
(subst) {listβ(y)} shuf(y); {listβ(y)} (frame) β < α ∧ x → y ∗ listβ(y)
β < α ∧ x → y ∗ listβ(y)
{β < α ∧ x → y ∗ listβ(y)} shuf(y); {listα(x)} (seq) {β < α ∧ x → y ∗ listβ(y)} rev(y); . . . {listα(x)} (load) {β < α ∧ x → v ∗ listβ(v)} y:=*x; . . . {listα(x)} (case list) {x = nil ∧ listα(x)} y:=*x; . . . {listα(x)} (| =) {x = nil ∧ listα(x)} ǫ {listα(x)} (if) {listα(x)} if x!=nil . . . {listα(x)} (proc) {listα(x)} shuffle(x) {listα(x)}
7/11
SLIDE 42 A Cyclic Termination Proof for shuffle
proc shuffle(x) { if x!=nil { y:=*x; reverse(y); shuffle(y); } }
{listβ(y)} rev(y); {listβ(y)} (frame) β < α ∧ x → y ∗ listβ(y)
β < α ∧ x → y ∗ listβ(y)
- {listα(x)} shuf(x); {listα(x)}
(subst) {listβ(y)} shuf(y); {listβ(y)} (frame) β < α ∧ x → y ∗ listβ(y)
β < α ∧ x → y ∗ listβ(y)
{β < α ∧ x → y ∗ listβ(y)} shuf(y); {listα(x)} (seq) {β < α ∧ x → y ∗ listβ(y)} rev(y); . . . {listα(x)} (load) {β < α ∧ x → v ∗ listβ(v)} y:=*x; . . . {listα(x)} (case list) {x = nil ∧ listα(x)} y:=*x; . . . {listα(x)} (| =) {x = nil ∧ listα(x)} ǫ {listα(x)} (if) {listα(x)} if x!=nil . . . {listα(x)} (proc) {listα(x)} shuffle(x) {listα(x)}
7/11
SLIDE 43 Implementation
- Cyclist is a generic framework for cyclic proof search
- Entailment queries also handled by Cyclist
- Currently, we need to provide procedure summaries
- Procedure calls (and backlinks!) require frame inference
- Driven by unfolding predicates/matching atomic spatial
assertions
- Requires deciding entailment of sets of constraints
8/11
SLIDE 44 Implementation
- Cyclist is a generic framework for cyclic proof search
- Entailment queries also handled by Cyclist
- Currently, we need to provide procedure summaries
- Procedure calls (and backlinks!) require frame inference
- Driven by unfolding predicates/matching atomic spatial
assertions
- Requires deciding entailment of sets of constraints
8/11
SLIDE 45 Implementation
- Cyclist is a generic framework for cyclic proof search
- Entailment queries also handled by Cyclist
- Currently, we need to provide procedure summaries
- Procedure calls (and backlinks!) require frame inference
- Driven by unfolding predicates/matching atomic spatial
assertions
- Requires deciding entailment of sets of constraints
8/11
SLIDE 46 Implementation
- Cyclist is a generic framework for cyclic proof search
- Entailment queries also handled by Cyclist
- Currently, we need to provide procedure summaries
- Procedure calls (and backlinks!) require frame inference
- Driven by unfolding predicates/matching atomic spatial
assertions
- Requires deciding entailment of sets of constraints
8/11
SLIDE 47 Implementation
- Cyclist is a generic framework for cyclic proof search
- Entailment queries also handled by Cyclist
- Currently, we need to provide procedure summaries
- Procedure calls (and backlinks!) require frame inference
- Driven by unfolding predicates/matching atomic spatial
assertions
- Requires deciding entailment of sets of constraints
8/11
SLIDE 48 Implementation
- Cyclist is a generic framework for cyclic proof search
- Entailment queries also handled by Cyclist
- Currently, we need to provide procedure summaries
- Procedure calls (and backlinks!) require frame inference
- Driven by unfolding predicates/matching atomic spatial
assertions
- Requires deciding entailment of sets of constraints α < β
8/11
SLIDE 49
Empirical Evaluation: Comparison with HipTNT+
Benchmark Time (seconds) HipTNT+ Cyclist traverse acyclic linked list 0.31 0.02 traverse cyclic linked list 0.52 0.02 append acyclic linked lists 0.36 0.03 TPDB Shuffme 1.79 0.21 TPDB Alternate 6.33 1.47 TPDB UnionFind 4.03 1.21 9/11
SLIDE 50 Empirical Evaluation: Comparison with AProVE
Benchmark Time (seconds) Suite Test AProVE Cyclist Costa_Julia_09-Recursive Ackermann 3.82 0.14 BinarySearchTree 1.41 0.95 BTree 1.77 0.03 List 1.43 1.74 Julia_10-Recursive AckR 3.22 0.14 BTreeR 2.68 0.03 Test8 2.95 0.97 AProVE_11_Recursive CyclicAnalysisRec 2.61 5.21 RotateTree 5.86 0.32 SharingAnalysisRec 2.47 4.72 UnionFind TIMEOUT 1.21 BOG_RTA_11 Alternate 5.47 1.47 AppE 2.19 0.09 BinTreeChanger 3.38 3.33 CAppE 2.04 1.78 ConvertRec 3.72 0.06 DupTreeRec 4.18 0.03 GrowTreeR 3.53 0.05 MirrorBinTreeRec 4.96 0.02 MirrorMultiTreeRec 5.16 0.63 SearchTreeR 2.74 0.34 Shuffme 11.72 0.21 TwoWay 1.94 0.02
10/11
SLIDE 51 Conclusions & Future Work
- Cyclic proof-based termination analysis competes!
- More expressive contraints for predicate approximations
- Can we infer procedure specifjcations?
- Constraints on explicit approximations
- Entire pre-/post-conditions (bi-abduction)
11/11
SLIDE 52 Conclusions & Future Work
- Cyclic proof-based termination analysis competes!
- More expressive contraints for predicate approximations
- Can we infer procedure specifjcations?
- Constraints on explicit approximations
- Entire pre-/post-conditions (bi-abduction)
11/11
SLIDE 53 Conclusions & Future Work
- Cyclic proof-based termination analysis competes!
- More expressive contraints for predicate approximations
- Can we infer procedure specifjcations?
- Constraints on explicit approximations
- Entire pre-/post-conditions (bi-abduction)
11/11
SLIDE 54 Conclusions & Future Work
- Cyclic proof-based termination analysis competes!
- More expressive contraints for predicate approximations
- Can we infer procedure specifjcations?
- Constraints on explicit approximations
- Entire pre-/post-conditions (bi-abduction)
11/11
SLIDE 55 Conclusions & Future Work
- Cyclic proof-based termination analysis competes!
- More expressive contraints for predicate approximations
- Can we infer procedure specifjcations?
- Constraints on explicit approximations
- Entire pre-/post-conditions (bi-abduction)
11/11
SLIDE 56 Conclusions & Future Work
- Cyclic proof-based termination analysis competes!
- More expressive contraints for predicate approximations
- Can we infer procedure specifjcations?
- Constraints on explicit approximations
- Entire pre-/post-conditions (bi-abduction)
11/11
SLIDE 57
github.com/ngorogiannis/cyclist