290 likes | 417 Views
Proving Mutual Termination of single-threaded programs. Dima Elenbogen Ofer Strichman Shmuel Katz Technion, Haifa, Israel. Notion of equivalence for this presentation. Goal: verification of the mutual termination of two similar programs . Mutual termination Given equal inputs,
E N D
Proving Mutual Terminationof single-threaded programs Dima Elenbogen Ofer Strichman Shmuel Katz Technion, Haifa, Israel
Notion of equivalence for this presentation Goal: verification of the mutualterminationoftwosimilar programs. Mutual termination • Given equal inputs, • P1 terminates ,P2 terminates • Undecidable 16:32:13
Alternative: termination of a single program • New tools have recently been developed: • Terminator • Mutant • … • Still, there are two major problems: • Incompleteness • Complexity 16:32:13
Mutual Termination vs. Proving Termination • Pros: • Computationally easier to check the mutual terminations of two programs than to prove the termination of each of them. • Fully automated. • It does not require finding a well-founded set. • Program do not necessarily terminate. • Termination check has nothing to say • Mutual termination can still say something useful. • Cons: • Defines a weaker notion. 16:32:13
Goals • Develop proof rules for mutual termination • Present an algorithm for checking mutual termination, that • uses the proof rules, and • is sensitive to the magnitude of change rather than the magnitude of the programs 16:32:13
Prerequisites • Assume: • no loops (but there are recursive functions); • 1-1 mapping mapbetween the functions of both sides: • must intersect all cycles in the call graphs; • the mapped functions have the same signature B: A: 2map f1’() f1() 2map f5’() f2’() f2() f5() f7’() 2map f6() f3() f4() f4’() 2map 16:32:13
Mutual termination (simple case) • Consider the call graphs: • We want to prove that A, B are mutually terminating • How shall we handle the recursion ? A B Side 1 Side 2 16:32:14
Call-equivalence • Definition: functions A,B are call-equivalent if… • For equal inputs: • For callees f,g s.t. (f,g) 2 map: • f is called ,g is called • f and g are called with the same arguments. B(x, y) { g(0,0) if (cond2) g(x,y) if (cond3) • g(x,y) • } A(x, y) { if (cond1) f(x,y) f(0, 0) } The order and the number of calls do not matter 16:32:14
Preliminary inference rule (simple case) B(w, z) { … if (cond2) B(w1,z1) else … .. } A(x, y) { … if (cond1) A(x1,y1) else … … } A B call-equiv(A,B) mutual-terminate(A, B) (M-TERM-REC) Side 1 Side 2 16:32:14
The premise is undecidable How can we prove the premise? B(w, z) { … if (B(w’, z’) > …) B(w1,z1) else … .. } A(x, y) { … if (A(x’, y’) > …) A(x1,y1) else … … } A B call-equiv(A,B) mutual-terminate(A, B) (M-TERM-REC) Side 1 Side 2 16:32:14
Uninterpreted functions • Replace the recursive calls with calls to functions that • over-approximateA, B,and • are terminating by construction • Natural candidates: Uninterpreted Functions • Abstract all functionality. • We only know they are consistent:x = y → UF(x) = UF(y) call-equiv(A,B) mutual-terminate(A, B) (M-TERM-REC) 16:32:14
Replacing recursive calls (1 / 2) • Let FUF , GUFbe F,G, after replacing the recursive call with a call to the corresponding uninterpreted functions. F(x, y) { … if (cond1) F(x1,y1) else … … } G(w, z) { … if (cond2) G(w1,z1) else … .. } F G Side 2 Side 1 16:32:14
Replacing recursive calls (2 / 2) • Let FUF , GUFbe F,G, after replacing the recursive call with a call to the corresponding uninterpreted functions. FUF(x, y) { … if (cond1) UF(F)(x1,y1) else … … } GUF(w, z) { … if (cond2) UF(G)(w1,z1) else … .. } FUF GUF UF(G) UF(F) Side 2 Side 1 16:32:14
Proving mutual termination • Let FUF , GUFbe F,G, after replacing the recursive calls with calls to uninterpreted functions. • We can now rewrite the rule: This premise is decidable call-equiv(FUF,GUF) mutual-terminate(F, G) (M-TERM-SIMPLE) 16:32:14
General inference rule Now we want to generalize from a single self loop to MSCCs in the call graphs: • Definition: is called in A] ∀(F, G) ∈ map. call-equiv(FUF,GUF) ∀(F, G) ∈ map. mutual-terminate(F, G) (M-TERM) 16:32:14
Connected MSCCs {(g,g’),(f,f’),(h,h’)} 2 map Connected MSCCs… • Prove bottom-up • Abstract mutually terminating functions • Inline g g’ h UF(h) UF(h’) h’ Side 2 Side 1 16:32:14
Decomposition algorithm Legend: Mutually terminating pair Mutual termination undecided yet Could not prove mutual termination Syntactically equivalent pair check Unpaired function B: A: check f1() f1’() f2’() f2() U U f5’() f5() f7’() f4() f4’() f3() f6() U U check 16:32:14
UF(g’) UF(g) Mutual recursion {(g,g’),(f,f’)} 2 map • Find a sub-map that intersects all cycles, e.g., {(g,g’)} • Only when calling functions in this sub-map, replace with uninterpreted functions g’ g f f ’ Side 2 Side 1 16:32:14
Decomposition with mutual recursion Legend: Mutually terminating pair Mutual termination undecided yet Could not prove mutual termination Syntactically equivalent pair Call-equivalent; mutual termination undecided yet A: B: check f1() f1’() f2() f5() U U U U U U f2’() f5’() U U U U U U 16:32:14
The Regression Verification Tool (RVT) • Given two C programs: • loops recursive functions. • Map functions, globals, etc. • After that: • Decompose to the granularity of pairs of functions • Use a C verification engine (CBMC) 16:32:14
RVT Version A Version B • Merge • Rename identical globals • Map functions/globals • Decompose • static analyses • call-equivalence • counterexample RVT C program feedback • enforce equality of inputs • replace with UFs • assert call-equivalence CBMC 16:32:14
Improvements of completeness (1 / 2) Partial equivalence • Terminating executions of P1 and P2 on equal inputsresult in equal outputs. • Taking advantage of the partial equivalence of functions: • If we know that (f, g) ∈ mapare partially equivalent, then UF(f) = UF(g) • We welcome additional ideas how to refine our UFs. 16:32:14
Improvements of completeness (2 / 2) • Ignoring input arguments that do not affect the call-equivalence of a function: • This improves mapping, as some mapped function pairs may have different prototypes. 16:32:14
Checking the termination of functions • Suppose we know that function A terminates. Can it help us to prove the termination of A’? • Define call-contain(A, A’) as: • For equal inputs : • For each pair (f, f’) 2map: f ‘ is called in A’ with argument x f is called in A with argument x ∀(F, F’) ∈ map. (term(F)∧call-contain(FUF ,F’UF)) ∀(F, F’) ∈ map. term(F’) (TERM) 16:32:14
Value of Mutual Termination Full equivalence • P1 and P2 are partially equivalent and mutually terminate. • Introduced in: • Luckham, Park, and M. Paterson 1970 [On formalized computer programs] • Pratt1971 [Kernel equivalence of programs and proving kernel equivalence and correctness by test cases] • Regression verificationof full equivalence is an important problem. • Proving mutual termination is a crucial sub-task. 16:32:14
Questions?.. 16:32:14
a, b) y) x, Using (M-TERM-SIMPLE): example (1/2) unsigned gcd1UF (unsigned a, unsigned b) { unsigned g; if (b == 0) g = a; else { a = a % b; g = gcd1(b, a); } return g; } unsigned gcd2UF (unsigned x, unsigned y) { unsigned z; z = x; if (y > 0) z = gcd2(y, z % y); } return z; } ? = UF2 term UF1 16:32:14
Using (M-TERM-SIMPLE): example (2/2) • Proving call-equiv(gcd1UF, gcd2UF) Equal inputs Equal guards if called then equal arguments • Valid. gcd1,gcd2aremutually terminating. 16:32:14