270 likes | 388 Vues
This paper explores the challenges of automated termination proofs in software verification. It discusses basic properties of program computations, including reachability and termination, and classical reduction methods from temporal reasoning to first-order assertions. The work evaluates state-of-the-art tools for reachability and termination properties, highlighting existing checkers for various programming paradigms. We present an incremental algorithm for constructing necessary invariants and ranking functions, emphasizing the utility of effective auxiliary assertions in proving termination.
E N D
Termination Proofs for Systems Code Andrey Rybalchenko, EPFL/MPI joint work with Byron Cook, MSR and Andreas Podelski, MPI PLDI’2006, Ottawa
Temporal verification • Basic properties of program computations: • Reachability • Termination • Classical reduction: From: temporal reasoning about computations To: first-order reasoning over auxiliary assertions (e.g. invariants, ranking functions) • Proof rules: • conditions on auxiliary assertions implying the property • Challenge: • find adequate auxiliary assertions automatically
State-of-the-art • Tools for reachability properties of software: • Astree, BLAST, F-Soft, MAGIC, SatAbs, SLAM,... • Termination checkers for TRS, Prolog, functional languages, ‘toy’ imperative programs: • CiME, AProVE, TerminWeb, TerminLog, PolyRank, ... • Our goal: Termination tool for software verification
Overview • Classical assertions: • reachability (invariants) • termination (ranking functions) • limitations • Transition invariants • checking • incremental construction • Practical implementation
Invariants • Given program (Init, Next) and property Good • Q: Init [ Next^+(Init) µGood ? • Find invariant Invµ States • To prove: • Init µInv • Next(Inv) µInv • InvµGood transitive closure
Inv: automated construction • Incremental algorithm: Inv := Init while Next(Inv) *Inv do Inv := Inv[Inv od • Failed Next(Inv) µInv checks determine Inv • Keep Inv small wrt. Good • Classical fixpoint algorithms (w/ abstraction)
Ranking functions • Given program (Init, Next) • Q: do infinite computations exists ? • Find ranking function R: States -> Naturals • Define ranking relation Rank := { (s, s’) | R(s) ¸ 0 and R(s’) ·R(s)-1 } • To prove: Next µRank • Termination proof depends on reachability: Next Å Reach µRank Ranking function R(x, y) := x Ranking relation Rank := (x ¸ 0 Æ x’· x - 1) if (y ¸ 1) { while (x ¸ 0) { x = x – y; } }
Rank: automated construction • Incremental algorithm? Rank := ; while Next *Rank do Rank := Rank[Rank od • Termination is not preserved under union operation • Abstraction is not possible Rank[Rank: {a, b} [ {b, a} = {(a,a), ...} = a, a, a, a, a, a, ...
Alternative: Transition invariants Next Å Reach µ Rank vs. Next^+ Å Reach µ Rank1[ ... [ Rankn • Transition invariant T = Rank1[ ... [ Rankn transitive closure
Transition Invariant: automated construction • Incremental algorithm: T := ; while Next^+ Å Reach *T do T := T[T od • Failed Next^+Å ... µT checks determine T • Keep Twell-founded (aka terminating) • Q: practical implementation?
Implementation subtasks T := ; while Nex^+ Å Reach *T do T := T[T od • Checking: Next^+ Å Reach µT • Incremental construction: Find T if check fails
Checking Next^+ Å (Acc £ Acc) µ T Init 3 • Monitor for T • runs in parallel with the program • inspects pairs of states wrt. T • goes to error if observes (s, s’) T (s, s’) 2 T
Monitor for T • needs to store unbounded computation prefix • trade storage for non-determinism: [Biere’02] • select arbitrarystates • for each subsequent states’ check (s, s’) 2 T • proceed in two phases: • selection • checking (s, s’) 2 T
Monitor for T: pseudo-code Storage for program states var selected := ? var phase := SELECT while True { switch (phase) { SELECT: if ( nondet() ) { selected := current phase := CHECK } CHECK: if ( (selected, current) T ) { ERROR: } } } Current program state
Monitoring T: example if (y ¸ 1) { while (x ¸ 0) { x = x – y; } } Candidate to check: T = (x ¸ 0 Æ x’ · x - 1) x y
Checking transition invariant T • Given T construct monitor MT • Construct product PT = P || MT • Apply safety checker on PT: if success: done otherwise: counterexample PT is program with ERROR location
Implementation subtasks • Checking: Next+Å (Acc £ Acc) µ T • Incremental construction: Find T if check fails T := ; while Nex^+ Å Reach *T do T := T[T od
Counterexample for T if (y ¸ 1) { while (x ¸ 0) { x = x + y; } } Candidate to check: T = (x ¸ 0 Æ x’ · x - 1) Program trace: • assume(y ¸ 1) • assume(x ¸ 0) • x := x + y • x := x + y 7£6
Lasso = Stem + Cycle Selection phase Program trace: • assume(y ¸ 1) • assume(x ¸ 0) • x := x + y • x := x + y • Counterexample = Stem.Cycle.Cycle . ... (to termination) Stem Cycle Checking phase
From lasso to T • Counterexample is spurious if Cycle^is infeasible • if exist Rank ¶Cycle then T = Rank • else return “counterexample Stem.Cycle^” Algorithms and tools exist: PolyRank, RankFinder, ...
Example T if (y ¸ 1) { while (x · z) { if (nondet()) { x = x + y; } else z = z – y; } } } Candidate to check: T = ( x · z Æ x’ ¸ x + 1 ) Counterexample (lasso): • assume(y ¸ 1) • assume(x · z) • z := z – y • T = ( x · z Æ z’· z – 1 ) Transition invariant: T = ( x · z Æ x’ · x + 1 ) Ç ( x · z Æ z’· z – 1 )
Incremental algorithm for termination Creates program with error state T := ; while True do PT := P || MT if safe( PT) then return “terminates” else Stem, Cycle := counterexample if exists Rank ¶Cycle then T := T[ Rank else return “counterexample Stem.Cycle” od Applies temporal safety checker Applies termination checker on a single path
Terminator • Input: program written in C • Output: • termination proof: transition invariant • counterexample: lasso = stem + cycle • divergence (due to the halting problem) • Language features supported • nested loops, gotos • pointers, aliasing • (mutually) recursive function calls • Implementation based on SLAM/SDV • Scalability: (on drivers from WinDDK) • several TLOC in minutes
Experiments on WinDDK Lines of code (x1000) Termination proofs Cut-point set size Termination bugs
Termination bugs • True bugs recognized by developers • Sources of false bugs: • Heap modelling • Handling of bit operations
Conclusion • Proving termination can be easy: • Temporal reduction to transition invariants [lics’04] • Incremental computation guided by counterexamples [sas’05] • Checking using tools for reachability (abstraction, lazyness, precision,...) [this paper] • Next steps: • Advanced applicability: heap, bit operations,... • General liveness properties w/ fairness
Inductive transition invariants • Reachability check for PT succeeds • Invariant InvT for PT constructed over program and monitor variables • Meaning of InvT: TInd := { (s, s’) | (s’, s) 2 InvT } TIndµ T • Next Å (Init £ States) µTInd • TInd± Next µTInd Inductive transition invariant