Termination Analysis for Imperative Programs Operating … · Termination Analysis for Imperative...
Transcript of Termination Analysis for Imperative Programs Operating … · Termination Analysis for Imperative...
Termination Analysis for Imperative Programs Operatingon the Heap
Marc Brockschmidt
November 2013
Termination! What is it good for?
1 Program: produces result
2 Input handler: system reacts
3 Mathematical proofs: induction is valid
4 Biological process: reaches stable state
Variations of same problem:
2 special case of 1
3 can be interpreted as 1
4 probabilistic version of 1
Termination! What is it good for?
1 Program: produces result
2 Input handler: system reacts
3 Mathematical proofs: induction is valid
4 Biological process: reaches stable state
Variations of same problem:
2 special case of 1
3 can be interpreted as 1
4 probabilistic version of 1
Termination! What is it good for?
1 Program: produces result
2 Input handler: system reacts
3 Mathematical proofs: induction is valid
4 Biological process: reaches stable state
Variations of same problem:
2 special case of 1
3 can be interpreted as 1
4 probabilistic version of 1
Termination! What is it good for?
1 Program: produces result
2 Input handler: system reacts
3 Mathematical proofs: induction is valid
4 Biological process: reaches stable state
Variations of same problem:
2 special case of 1
3 can be interpreted as 1
4 probabilistic version of 1
Termination! What is it good for?
1 Program: produces result
2 Input handler: system reacts
3 Mathematical proofs: induction is valid
4 Biological process: reaches stable state
Variations of same problem:
2 special case of 1
3 can be interpreted as 1
4 probabilistic version of 1
Termination! What is it good for?
1 Program: produces result
2 Input handler: system reacts
3 Mathematical proofs: induction is valid
4 Biological process: reaches stable state
Variations of same problem:
2 special case of 1
3 can be interpreted as 1
4 probabilistic version of 1
Program termination: Overview
Turing 1949
“Finally the checker has to verify that the process comes to an end. [...]This may take the form of a quantity which is asserted to decreasecontinually and vanish when the machine stops.”
1 Find rank function f (“quantity”)
2 Prove f to have a lower bound (“vanishes when the machine stops”)
3 Prove f to decrease over time
Example (Termination can be simple)
while x > 0 dox = x - 1
done
Program termination: Overview
Turing 1949
“Finally the checker has to verify that the process comes to an end. [...]This may take the form of a quantity which is asserted to decreasecontinually and vanish when the machine stops.”
1 Find rank function f (“quantity”)
2 Prove f to have a lower bound (“vanishes when the machine stops”)
3 Prove f to decrease over time
Example (Termination can be simple)
while x > 0 dox = x - 1
done
Program termination: Overview
Turing 1949
“Finally the checker has to verify that the process comes to an end. [...]This may take the form of a quantity which is asserted to decreasecontinually and vanish when the machine stops.”
1 Find rank function f (“quantity”)
2 Prove f to have a lower bound (“vanishes when the machine stops”)
3 Prove f to decrease over time
Example (Termination can be simple)
while x > 0 dox = x - 1
done
Program termination: Overview
Turing 1949
“Finally the checker has to verify that the process comes to an end. [...]This may take the form of a quantity which is asserted to decreasecontinually and vanish when the machine stops.”
1 Find rank function f (“quantity”)
2 Prove f to have a lower bound (“vanishes when the machine stops”)
3 Prove f to decrease over time
Example (Termination can be simple)
while x > 0 dox = x - 1
done
Program termination: Challenges
Real programs have
Sharing: Changing variable x influences y
User-defined data types: Data has unknown shape
Dynamic dispatch: Executed code chosen only at runtime
Example (Termination not always simple)
y = x
while not y.isEmpty() dox.pop()
done
Program termination: Challenges
Real programs have
Sharing: Changing variable x influences y
User-defined data types: Data has unknown shape
Dynamic dispatch: Executed code chosen only at runtime
Example (Termination not always simple)
y = x
while not y.isEmpty() dox.pop()
done
Program termination: Challenges
Real programs have
Sharing: Changing variable x influences y
User-defined data types: Data has unknown shape
Dynamic dispatch: Executed code chosen only at runtime
Example (Termination not always simple)
y = x
while not y.isEmpty() dox.pop()
done
Program termination: Challenges
Real programs have
Sharing: Changing variable x influences y
User-defined data types: Data has unknown shape
Dynamic dispatch: Executed code chosen only at runtime
Example (Termination not always simple)
y = x
while not y.isEmpty() dox.pop()
done
Program termination: Our approach
Program
1 Symbolic evaluation & abstraction
2 Translate graph edges to rules, data to terms
Program termination: Our approach
Program Termination Graph
1 Symbolic evaluation & abstraction
2 Translate graph edges to rules, data to terms
Program termination: Our approach
Program Termination Graph Simple Program
1 Symbolic evaluation & abstraction
2 Translate graph edges to rules, data to terms
Program termination: Our approach
Java Termination Graph Simple Program
while (x > 0)
x = x - 1;
1 Symbolic evaluation & abstraction
2 Translate graph edges to rules, data to terms
Program termination: Our approach
Java Termination Graph1 Simple Program
while (x > 0)
x = x - 1;
. . .A
. . .B
. . .D
. . .C
x > 0x≤
0
x=x−1
1 Symbolic evaluation & abstraction
2 Translate graph edges to rules, data to terms
Program termination: Our approach
Java Termination Graph1intTRS
2
while (x > 0)
x = x - 1;
. . .A
. . .B
. . .D
. . .C
x > 0x≤
0
x=x−1
fA(x)→ fA(x − 1)J x > 0 K
fA(x)→ fC(x)J x ≤ 0 K
1 Symbolic evaluation & abstraction
2 Translate graph edges to rules, data to terms
intTRS termination: Our approach
intTRS
g(List(n), i)→ g(n, i − 1)J i > 0 K
1 Restrict to terms
2 Restrict to integers (and/or replacing terms by their “sizes”)
intTRS termination: Our approach
intTRS
TRS
Integer Trans. Systemg(List(n), i)→ g(n, i − 1)
J i > 0 K
1 Restrict to terms
2 Restrict to integers (and/or replacing terms by their “sizes”)
intTRS termination: Our approach
intTRS
TRS
Integer Trans. System
1
g(List(n), i)→ g(n, i − 1)J i > 0 K
g(List(n))→ g(n)
1 Restrict to terms
2 Restrict to integers (and/or replacing terms by their “sizes”)
intTRS termination: Our approach
intTRS
TRS
Integer Trans. System
1
2
g(List(n), i)→ g(n, i − 1)J i > 0 K
g(List(n))→ g(n)
g
i > 0∧ i ′ = i − 1
1 Restrict to terms
2 Restrict to integers (and/or replacing terms by their “sizes”)
Integer Transition System termination: Our approach
ITS
1 Instrumentation (check initially empty termination argument)
2 Check termination argument
3 Synthesise better termination argument
4 Simplification & Instrumentation (check better termination argument)
Integer Transition System termination: Our approach
ITS Instrumented ITS1
1 Instrumentation (check initially empty termination argument)
2 Check termination argument
3 Synthesise better termination argument
4 Simplification & Instrumentation (check better termination argument)
Integer Transition System termination: Our approach
ITS Instrumented ITS
Counterexample
1
2
1 Instrumentation (check initially empty termination argument)
2 Check termination argument
3 Synthesise better termination argument
4 Simplification & Instrumentation (check better termination argument)
Integer Transition System termination: Our approach
ITS Instrumented ITS
Counterexample
Term. argument
1
2
3
1 Instrumentation (check initially empty termination argument)
2 Check termination argument
3 Synthesise better termination argument
4 Simplification & Instrumentation (check better termination argument)
Integer Transition System termination: Our approach
ITS Instrumented ITS
Counterexample
Term. argument
1
2
3
4
1 Instrumentation (check initially empty termination argument)
2 Check termination argument
3 Synthesise better termination argument
4 Simplification & Instrumentation (check better termination argument)
Related Work
Symbolic execution in program analysis:I Abstract InterpretationI Termination Graphs for Haskell, Prolog (AProVE)
Termination with heap:I Path-length (COSTA, Julia)I Separation Logic (Mutant, Thor, Cyclist)
Combining termination arguments:I Lexicographic (PolyRank, Rank, T2)I Dependency Pair Framework (AProVE, TTT2, Mu-Term,
CiME, Matchbox, KITTeL)I Transition Invariants (Terminator, ARMC, CProver,
TRex, T2, HSF, Acabar)
Related Work
Symbolic execution in program analysis:I Abstract InterpretationI Termination Graphs for Haskell, Prolog (AProVE)
Termination with heap:I Path-length (COSTA, Julia)I Separation Logic (Mutant, Thor, Cyclist)
Combining termination arguments:I Lexicographic (PolyRank, Rank, T2)I Dependency Pair Framework (AProVE, TTT2, Mu-Term,
CiME, Matchbox, KITTeL)I Transition Invariants (Terminator, ARMC, CProver,
TRex, T2, HSF, Acabar)
Related Work
Symbolic execution in program analysis:I Abstract InterpretationI Termination Graphs for Haskell, Prolog (AProVE)
Termination with heap:I Path-length (COSTA, Julia)I Separation Logic (Mutant, Thor, Cyclist)
Combining termination arguments:I Lexicographic (PolyRank, Rank, T2)I Dependency Pair Framework (AProVE, TTT2, Mu-Term,
CiME, Matchbox, KITTeL)I Transition Invariants (Terminator, ARMC, CProver,
TRex, T2, HSF, Acabar)
Overview
1 Introduction
2 Termination of JavaSymbolic statesConstructing Termination GraphsGenerating intTRSs from Termination Graphs
3 Termination of Integer Transition SystemsTermination by iterative strengtheningTermination by iterative simplificationCooperative termination proving
4 Conclusion
From Java to intTRSs: Challenges
Terms cannot fully represent the heap
:
1 Side-effects via sharing
2 No representation for cyclic structures
3 No measure of distances
Solutions:
1 Overapproximate
2 Handle in symbolic evaluation
3 Post-process: Make distances/cycles explicit via counters
From Java to intTRSs: Challenges
Terms cannot fully represent the heap:
1 Side-effects via sharing
2 No representation for cyclic structures
3 No measure of distances
Solutions:
1 Overapproximate
2 Handle in symbolic evaluation
3 Post-process: Make distances/cycles explicit via counters
From Java to intTRSs: Challenges
Terms cannot fully represent the heap:
1 Side-effects via sharing
2 No representation for cyclic structures
3 No measure of distances
Solutions:
1 Overapproximate
2 Handle in symbolic evaluation
3 Post-process: Make distances/cycles explicit via counters
length: the example
class L {L p, n;
static int length(L x) {int r = 0;
while (x != null) {x = x.n;
r++;
}return r; }}
length: the example
class L {L p, n;
static int length(L x) {int r = 0;
while (x != null) {x = x.n;
r++;
}return r; }}
null null
n n n
ppp
length: the example
class L {L p, n;
static int length(L x) {int r = 0;
while (x != null) {x = x.n;
r++;
}return r; }}
null null
x
n n n
ppp
length: the example
class L {L p, n;
static int length(L x) {int r = 0;
while (x != null) {x = x.n;
r++;
}return r; }}
null null
x
n n n
ppp
length: the example
class L {L p, n;
static int length(L x) {int r = 0;
while (x != null) {x = x.n;
r++;
}return r; }}
null null
x
n n n
ppp
length: the example
class L {L p, n;
static int length(L x) {int r = 0;
while (x != null) {x = x.n;
r++;
}return r; }}
null null
x
n n n
ppp
length: the example
class L {L p, n;
static int length(L x) {int r = 0;
while (x != null) {x = x.n;
r++;
}return r; }}
00: iconst 0 #load 0
01: istore 1 #store to r
02: aload 0 #load x
03: ifnull 17 #jump if x null
06: aload 0 #load x
07: getfield n #get n from x
10: astore 0 #store to x
11: iinc 1, 1 #increment r
14: goto 2
17: iload 1 #load r
18: ireturn #return r
The abstract domain: symbolic states
class L {L p, n;
static int length(L x) {int r = 0;
while (x != null) {x = x.n;
r++;
}return r; }}
00: iconst 0 #load 0
01: istore 1 #store to r
02: aload 0 #load x
03: ifnull 17 #jump if x null
06: aload 0 #load x
07: getfield n #get n from x
10: astore 0 #store to x
11: iinc 1, 1 #increment r
14: goto 2
17: iload 1 #load r
18: ireturn #return r
The abstract domain: symbolic states
class L {L p, n;
static int length(L x) {int r = 0;
while (x != null) {x = x.n;
r++;
}return r; }}
00: iconst 0 #load 0
01: istore 1 #store to r
02: aload 0 #load x
03: ifnull 17 #jump if x null
06: aload 0 #load x
07: getfield n #get n from x
10: astore 0 #store to x
11: iinc 1, 1 #increment r
14: goto 2
17: iload 1 #load r
18: ireturn #return r
00 | x :o1 | εo1:L(?) o1 {p,n}Stack frame:
Next program instruction
Local variables
Operand stack
Heap information:
o1 is L object or null
Known L object: o2 : L(p=o3,n=o4)
Symbolic integers: i1 : Z i2 : [>0]
Heap predicates:
Two references may be equal: o1 =? o2
Two references may share: o1%$o2Reference might have cycles containingall fields F : o1 F
The abstract domain: symbolic states
class L {L p, n;
static int length(L x) {int r = 0;
while (x != null) {x = x.n;
r++;
}return r; }}
00: iconst 0 #load 0
01: istore 1 #store to r
02: aload 0 #load x
03: ifnull 17 #jump if x null
06: aload 0 #load x
07: getfield n #get n from x
10: astore 0 #store to x
11: iinc 1, 1 #increment r
14: goto 2
17: iload 1 #load r
18: ireturn #return r
00 | x :o1 | εo1:L(?) o1 {p,n}Stack frame:
Next program instruction
Local variables
Operand stack
Heap information:
o1 is L object or null
Known L object: o2 : L(p=o3,n=o4)
Symbolic integers: i1 : Z i2 : [>0]
Heap predicates:
Two references may be equal: o1 =? o2
Two references may share: o1%$o2Reference might have cycles containingall fields F : o1 F
The abstract domain: symbolic states
class L {L p, n;
static int length(L x) {int r = 0;
while (x != null) {x = x.n;
r++;
}return r; }}
00: iconst 0 #load 0
01: istore 1 #store to r
02: aload 0 #load x
03: ifnull 17 #jump if x null
06: aload 0 #load x
07: getfield n #get n from x
10: astore 0 #store to x
11: iinc 1, 1 #increment r
14: goto 2
17: iload 1 #load r
18: ireturn #return r
00 | x :o1 | εo1:L(?) o1 {p,n}Stack frame:
Next program instruction
Local variables
Operand stack
Heap information:
o1 is L object or null
Known L object: o2 : L(p=o3,n=o4)
Symbolic integers: i1 : Z i2 : [>0]
Heap predicates:
Two references may be equal: o1 =? o2
Two references may share: o1%$o2Reference might have cycles containingall fields F : o1 F
The abstract domain: symbolic states
class L {L p, n;
static int length(L x) {int r = 0;
while (x != null) {x = x.n;
r++;
}return r; }}
00: iconst 0 #load 0
01: istore 1 #store to r
02: aload 0 #load x
03: ifnull 17 #jump if x null
06: aload 0 #load x
07: getfield n #get n from x
10: astore 0 #store to x
11: iinc 1, 1 #increment r
14: goto 2
17: iload 1 #load r
18: ireturn #return r
00 | x :o1 | εo1:L(?) o1 {p,n}Stack frame:
Next program instruction
Local variables
Operand stack
Heap information:
o1 is L object or null
Known L object: o2 : L(p=o3,n=o4)
Symbolic integers: i1 : Z i2 : [>0]
Heap predicates:
Two references may be equal: o1 =? o2
Two references may share: o1%$o2Reference might have cycles containingall fields F : o1 F
The abstract domain: symbolic states
class L {L p, n;
static int length(L x) {int r = 0;
while (x != null) {x = x.n;
r++;
}return r; }}
00: iconst 0 #load 0
01: istore 1 #store to r
02: aload 0 #load x
03: ifnull 17 #jump if x null
06: aload 0 #load x
07: getfield n #get n from x
10: astore 0 #store to x
11: iinc 1, 1 #increment r
14: goto 2
17: iload 1 #load r
18: ireturn #return r
00 | x :o1 | εo1:L(?) o1 {p,n}Stack frame:
Next program instruction
Local variables
Operand stack
Heap information:
o1 is L object or null
Known L object: o2 : L(p=o3,n=o4)
Symbolic integers: i1 : Z i2 : [>0]
Heap predicates:
Two references may be equal: o1 =? o2
Two references may share: o1%$o2Reference might have cycles containingall fields F : o1 F
The abstract domain: symbolic states
class L {L p, n;
static int length(L x) {int r = 0;
while (x != null) {x = x.n;
r++;
}return r; }}
00: iconst 0 #load 0
01: istore 1 #store to r
02: aload 0 #load x
03: ifnull 17 #jump if x null
06: aload 0 #load x
07: getfield n #get n from x
10: astore 0 #store to x
11: iinc 1, 1 #increment r
14: goto 2
17: iload 1 #load r
18: ireturn #return r
00 | x :o1 | εo1:L(?) o1 {p,n}Stack frame:
Next program instruction
Local variables
Operand stack
Heap information:
o1 is L object or null
Known L object: o2 : L(p=o3,n=o4)
Symbolic integers: i1 : Z i2 : [>0]
Heap predicates:
Two references may be equal: o1 =? o2
Two references may share: o1%$o2Reference might have cycles containingall fields F : o1 F
The abstract domain: symbolic states
class L {L p, n;
static int length(L x) {int r = 0;
while (x != null) {x = x.n;
r++;
}return r; }}
00: iconst 0 #load 0
01: istore 1 #store to r
02: aload 0 #load x
03: ifnull 17 #jump if x null
06: aload 0 #load x
07: getfield n #get n from x
10: astore 0 #store to x
11: iinc 1, 1 #increment r
14: goto 2
17: iload 1 #load r
18: ireturn #return r
00 | x :o1 | εo1:L(?) o1 {p,n}Stack frame:
Next program instruction
Local variables
Operand stack
Heap information:
o1 is L object or null
Known L object: o2 : L(p=o3,n=o4)
Symbolic integers: i1 : Z i2 : [>0]
Heap predicates:
Two references may be equal: o1 =? o2
Two references may share: o1%$o2Reference might have cycles containingall fields F : o1 F
Only explicit sharing
The abstract domain: symbolic states
class L {L p, n;
static int length(L x) {int r = 0;
while (x != null) {x = x.n;
r++;
}return r; }}
00: iconst 0 #load 0
01: istore 1 #store to r
02: aload 0 #load x
03: ifnull 17 #jump if x null
06: aload 0 #load x
07: getfield n #get n from x
10: astore 0 #store to x
11: iinc 1, 1 #increment r
14: goto 2
17: iload 1 #load r
18: ireturn #return r
00 | x :o1 | εo1:L(?) o1 {p,n}Stack frame:
Next program instruction
Local variables
Operand stack
Heap information:
o1 is L object or null
Known L object: o2 : L(p=o3,n=o4)
Symbolic integers: i1 : Z i2 : [>0]
Heap predicates:
Two references may be equal: o1 =? o2
Two references may share: o1%$o2Reference might have cycles containingall fields F : o1 F
Only explicit sharing
The abstract domain: symbolic states
class L {L p, n;
static int length(L x) {int r = 0;
while (x != null) {x = x.n;
r++;
}return r; }}
00: iconst 0 #load 0
01: istore 1 #store to r
02: aload 0 #load x
03: ifnull 17 #jump if x null
06: aload 0 #load x
07: getfield n #get n from x
10: astore 0 #store to x
11: iinc 1, 1 #increment r
14: goto 2
17: iload 1 #load r
18: ireturn #return r
00 | x :o1 | εo1:L(?) o1 {p,n}Stack frame:
Next program instruction
Local variables
Operand stack
Heap information:
o1 is L object or null
Known L object: o2 : L(p=o3,n=o4)
Symbolic integers: i1 : Z i2 : [>0]
Heap predicates:
Two references may be equal: o1 =? o2
Two references may share: o1%$o2
Reference might have cycles containingall fields F : o1 F
Only explicit sharing
The abstract domain: symbolic states
class L {L p, n;
static int length(L x) {int r = 0;
while (x != null) {x = x.n;
r++;
}return r; }}
00: iconst 0 #load 0
01: istore 1 #store to r
02: aload 0 #load x
03: ifnull 17 #jump if x null
06: aload 0 #load x
07: getfield n #get n from x
10: astore 0 #store to x
11: iinc 1, 1 #increment r
14: goto 2
17: iload 1 #load r
18: ireturn #return r
00 | x :o1 | εo1:L(?) o1 {p,n}Stack frame:
Next program instruction
Local variables
Operand stack
Heap information:
o1 is L object or null
Known L object: o2 : L(p=o3,n=o4)
Symbolic integers: i1 : Z i2 : [>0]
Heap predicates:
Two references may be equal: o1 =? o2
Two references may share: o1%$o2Reference might have cycles containingall fields F : o1 F
Only explicit sharing
00: iconst 0
01: istore 1
02: aload 0
03: ifnull 17
06: aload 0
07: getfield n
10: astore 0
11: iinc 1, 1
14: goto 2
17: iload 1
18: ireturn
00 |x :o1 |εo1:L(?) o1 {p,n}
A
State A:
x some list, might contain cycles using p and n
State B:
Initialized variable r to 0
State
s
C , D, E :
x (o1) null? We do not know!
⇒ RefinementI In D: o1 is null (y program ends)I In E : o1 replaced by o2, which exists and has fields:
Field values can share (y add %$)Field values can be cyclic again (y add )
int length(L x) {int r = 0;
while (x != null) {x = x.n; r++; }
return r; }
00: iconst 0
01: istore 1
02: aload 0
03: ifnull 17
06: aload 0
07: getfield n
10: astore 0
11: iinc 1, 1
14: goto 2
17: iload 1
18: ireturn
00 |x :o1 |εo1:L(?) o1 {p,n}
A
02 |x :o1, r : 0 |εo1:L(?) o1 {p,n}
B
State A:
x some list, might contain cycles using p and n
State B:
Initialized variable r to 0
State
s
C , D, E :
x (o1) null? We do not know!
⇒ RefinementI In D: o1 is null (y program ends)I In E : o1 replaced by o2, which exists and has fields:
Field values can share (y add %$)Field values can be cyclic again (y add )
int length(L x) {int r = 0;
while (x != null) {x = x.n; r++; }
return r; }
00: iconst 0
01: istore 1
02: aload 0
03: ifnull 17
06: aload 0
07: getfield n
10: astore 0
11: iinc 1, 1
14: goto 2
17: iload 1
18: ireturn
00 |x :o1 |εo1:L(?) o1 {p,n}
A
02 |x :o1, r : 0 |εo1:L(?) o1 {p,n}
B
03 |x :o1, r : 0 |o1o1:L(?) o1 {p,n}
C
State A:
x some list, might contain cycles using p and n
State B:
Initialized variable r to 0
State
s
C :
x (o1) null? We do not know!
⇒ RefinementI In D: o1 is null (y program ends)I In E : o1 replaced by o2, which exists and has fields:
Field values can share (y add %$)Field values can be cyclic again (y add )
int length(L x) {int r = 0;
while (x != null) {x = x.n; r++; }
return r; }
00: iconst 0
01: istore 1
02: aload 0
03: ifnull 17
06: aload 0
07: getfield n
10: astore 0
11: iinc 1, 1
14: goto 2
17: iload 1
18: ireturn
00 |x :o1 |εo1:L(?) o1 {p,n}
A
02 |x :o1, r : 0 |εo1:L(?) o1 {p,n}
B
03 |x :o1, r : 0 |o1o1:L(?) o1 {p,n}
C
03 |x :null, r : 0 |null D
03 |x :o2, r : 0 |o2o2:L(p=o3, n=o4)o3:L(?) o4:L(?)o2%$o3 o2%$o4 o3%$o4o2, o3, o4 {p,n}
E
State A:
x some list, might contain cycles using p and n
State B:
Initialized variable r to 0
States C , D, E :
x (o1) null? We do not know!
⇒ RefinementI In D: o1 is null (y program ends)I In E : o1 replaced by o2, which exists and has fields:
Field values can share (y add %$)Field values can be cyclic again (y add )
int length(L x) {int r = 0;
while (x != null) {x = x.n; r++; }
return r; }
00: iconst 0
01: istore 1
02: aload 0
03: ifnull 17
06: aload 0
07: getfield n
10: astore 0
11: iinc 1, 1
14: goto 2
17: iload 1
18: ireturn
00 |x :o1 |εo1:L(?) o1 {p,n}
A
02 |x :o1, r : 0 |εo1:L(?) o1 {p,n}
B
03 |x :o1, r : 0 |o1o1:L(?) o1 {p,n}
C
03 |x :null, r : 0 |null D
03 |x :o2, r : 0 |o2o2:L(p=o3, n=o4)o3:L(?) o4:L(?)o2%$o3 o2%$o4 o3%$o4o2, o3, o4 {p,n}
E 11 |x :o4, r : 0 |εo4:L(?) o4 {p,n}
F
State F :
Stored x.n to x (allowing for GC)
State
s
G , B ′:
Incremented r, back to position 02 (as B)
⇒ Generalization: “Merge” states B, G
States C ′,G ′:
Repetition of C ,G
int length(L x) {int r = 0;
while (x != null) {x = x.n; r++; }
return r; }
00: iconst 0
01: istore 1
02: aload 0
03: ifnull 17
06: aload 0
07: getfield n
10: astore 0
11: iinc 1, 1
14: goto 2
17: iload 1
18: ireturn
00 |x :o1 |εo1:L(?) o1 {p,n}
A
02 |x :o1, r : 0 |εo1:L(?) o1 {p,n}
B
03 |x :o1, r : 0 |o1o1:L(?) o1 {p,n}
C
03 |x :null, r : 0 |null D
03 |x :o2, r : 0 |o2o2:L(p=o3, n=o4)o3:L(?) o4:L(?)o2%$o3 o2%$o4 o3%$o4o2, o3, o4 {p,n}
E 11 |x :o4, r : 0 |εo4:L(?) o4 {p,n}
F
02 |x :o4, r : 1 |εo4:L(?) o4 {p,n}
G
State F :
Stored x.n to x (allowing for GC)
State
s
G :
Incremented r, back to position 02 (as B)
⇒ Generalization: “Merge” states B, G
States C ′,G ′:
Repetition of C ,G
int length(L x) {int r = 0;
while (x != null) {x = x.n; r++; }
return r; }
00: iconst 0
01: istore 1
02: aload 0
03: ifnull 17
06: aload 0
07: getfield n
10: astore 0
11: iinc 1, 1
14: goto 2
17: iload 1
18: ireturn
00 |x :o1 |εo1:L(?) o1 {p,n}
A
02 |x :o1, r : 0 |εo1:L(?) o1 {p,n}
B
03 |x :o1, r : 0 |o1o1:L(?) o1 {p,n}
C
03 |x :null, r : 0 |null D
03 |x :o2, r : 0 |o2o2:L(p=o3, n=o4)o3:L(?) o4:L(?)o2%$o3 o2%$o4 o3%$o4o2, o3, o4 {p,n}
E 11 |x :o4, r : 0 |εo4:L(?) o4 {p,n}
F
02 |x :o4, r : 1 |εo4:L(?) o4 {p,n}
G02 |x :o′1, r : i1 |εo′1:L(?) o′1 {p,n} i1: [≥0]
B′
State F :
Stored x.n to x (allowing for GC)
States G , B ′:
Incremented r, back to position 02 (as B)
⇒ Generalization: “Merge” states B, G
States C ′,G ′:
Repetition of C ,G
int length(L x) {int r = 0;
while (x != null) {x = x.n; r++; }
return r; }
00: iconst 0
01: istore 1
02: aload 0
03: ifnull 17
06: aload 0
07: getfield n
10: astore 0
11: iinc 1, 1
14: goto 2
17: iload 1
18: ireturn
00 |x :o1 |εo1:L(?) o1 {p,n}
A
02 |x :o1, r : 0 |εo1:L(?) o1 {p,n}
B
03 |x :o1, r : 0 |o1o1:L(?) o1 {p,n}
C
03 |x :null, r : 0 |null D
03 |x :o2, r : 0 |o2o2:L(p=o3, n=o4)o3:L(?) o4:L(?)o2%$o3 o2%$o4 o3%$o4o2, o3, o4 {p,n}
E 11 |x :o4, r : 0 |εo4:L(?) o4 {p,n}
F
02 |x :o4, r : 1 |εo4:L(?) o4 {p,n}
G02 |x :o′1, r : i1 |εo′1:L(?) o′1 {p,n} i1: [≥0]
B′
03 |x :o′1, r : i1 |o′1
o′1:L(?) o′1 {p,n} i1: [≥0]C ′
02 |x :o′4, r : i2 |o′4
o′4:L(?) o′4 {p,n} i2: [≥1]
G ′
i2= i1 + 1
State F :
Stored x.n to x (allowing for GC)
States G , B ′:
Incremented r, back to position 02 (as B)
⇒ Generalization: “Merge” states B, G
States C ′,G ′:
Repetition of C ,G
int length(L x) {int r = 0;
while (x != null) {x = x.n; r++; }
return r; }
00: iconst 0
01: istore 1
02: aload 0
03: ifnull 17
06: aload 0
07: getfield n
10: astore 0
11: iinc 1, 1
14: goto 2
17: iload 1
18: ireturn
00 |x :o1 |εo1:L(?) o1 {p,n}
A
02 |x :o1, r : 0 |εo1:L(?) o1 {p,n}
B
03 |x :o1, r : 0 |o1o1:L(?) o1 {p,n}
C
03 |x :null, r : 0 |null D
03 |x :o2, r : 0 |o2o2:L(p=o3, n=o4)o3:L(?) o4:L(?)o2%$o3 o2%$o4 o3%$o4o2, o3, o4 {p,n}
E 11 |x :o4, r : 0 |εo4:L(?) o4 {p,n}
F
02 |x :o4, r : 1 |εo4:L(?) o4 {p,n}
G02 |x :o′1, r : i1 |εo′1:L(?) o′1 {p,n} i1: [≥0]
B′
03 |x :o′1, r : i1 |o′1
o′1:L(?) o′1 {p,n} i1: [≥0]C ′
02 |x :o′4, r : i2 |o′4
o′4:L(?) o′4 {p,n} i2: [≥1]
G ′
i2= i1 + 1
State F :
Stored x.n to x (allowing for GC)
States G , B ′:
Incremented r, back to position 02 (as B)
⇒ Generalization: “Merge” states B, G
States C ′,G ′:
Repetition of C ,G
int length(L x) {int r = 0;
while (x != null) {x = x.n; r++; }
return r; }
Orientation: Term Rewriting
Generalized Functional Programming
Rules R define rewrite relation:
app(Cons(x , xs), ys)→ Cons(x , app(xs, ys)) (1)
app(Nil, ys)→ ys (2)
Rewriting of term t with rule l → r :1 Find subterm s of t2 Find variable instantiation σ with σ(l) = s3 Result t ′ is t with s replaced by σ(r)
app(Cons(1,Nil),Cons(2,Nil)) with (1), x = 1, xs = Nil,
ys = Cons(2,Nil)
→ Cons(1, app(Nil,Cons(2,Nil))) with (2), ys = Cons(2,Nil)
→ Cons(1,Cons(2,Nil))
Orientation: Term Rewriting
Generalized Functional ProgrammingRules R define rewrite relation:
app(Cons(x , xs), ys)→ Cons(x , app(xs, ys)) (1)
app(Nil, ys)→ ys (2)
Rewriting of term t with rule l → r :1 Find subterm s of t2 Find variable instantiation σ with σ(l) = s3 Result t ′ is t with s replaced by σ(r)
app(Cons(1,Nil),Cons(2,Nil)) with (1), x = 1, xs = Nil,
ys = Cons(2,Nil)
→ Cons(1, app(Nil,Cons(2,Nil))) with (2), ys = Cons(2,Nil)
→ Cons(1,Cons(2,Nil))
Orientation: Term Rewriting
Generalized Functional ProgrammingRules R define rewrite relation:
app(Cons(x , xs), ys)→ Cons(x , app(xs, ys)) (1)
app(Nil, ys)→ ys (2)
Rewriting of term t with rule l → r :1 Find subterm s of t2 Find variable instantiation σ with σ(l) = s3 Result t ′ is t with s replaced by σ(r)
app(Cons(1,Nil),Cons(2,Nil)) with (1), x = 1, xs = Nil,
ys = Cons(2,Nil)
→ Cons(1, app(Nil,Cons(2,Nil))) with (2), ys = Cons(2,Nil)
→ Cons(1,Cons(2,Nil))
Transforming values to terms
03 |x :o2, r :0 |o2o2:L(p=o3, n=o4)o3:L(?) o4:L(?)o2%$o3 o2%$o4 o3%$o4o2, o3, o4 {p,n}
E
Known integers transformed to themselves
Unknown values transformed to variables
Data structures transformed to nested constructor terms:Class Cl with n fields y symbol Cl of arity n
Encoding cycles: Special symbol © for repetition
fE (
o2︷ ︸︸ ︷
L(
o3,
o4), 0,
o2︷ ︸︸ ︷L(
o3,
o4)
) → fF (o4
′
, 0)
Transforming values to terms
03 |x :o2, r :0 |o2o2:L(p=o3, n=o4)o3:L(?) o4:L(?)o2%$o3 o2%$o4 o3%$o4o2, o3, o4 {p,n}
E
Known integers transformed to themselves
Unknown values transformed to variables
Data structures transformed to nested constructor terms:Class Cl with n fields y symbol Cl of arity n
Encoding cycles: Special symbol © for repetition
fE (
o2︷ ︸︸ ︷
L(
o3,
o4),
0
,
o2︷ ︸︸ ︷L(
o3,
o4)
) → fF (o4
′
, 0)
Transforming values to terms
03 |x :o2, r :0 |o2o2:L(p=o3, n=o4)o3:L(?) o4:L(?)o2%$o3 o2%$o4 o3%$o4o2, o3, o4 {p,n}
E
Known integers transformed to themselves
Unknown values transformed to variables
Data structures transformed to nested constructor terms:Class Cl with n fields y symbol Cl of arity n
Encoding cycles: Special symbol © for repetition
fE (
o2︷ ︸︸ ︷
L(
o3, o4
),
0
,
o2︷ ︸︸ ︷L(
o3,
o4)
) → fF (o4
′
, 0)
Transforming values to terms
03 |x :o2, r :0 |o2o2:L(p=o3, n=o4)o3:L(?) o4:L(?)o2%$o3 o2%$o4 o3%$o4o2, o3, o4 {p,n}
E
Known integers transformed to themselves
Unknown values transformed to variables
Data structures transformed to nested constructor terms:Class Cl with n fields y symbol Cl of arity n
Encoding cycles: Special symbol © for repetition
fE (
o2︷ ︸︸ ︷L(o3, o4)
,
0
,
o2︷ ︸︸ ︷L(
o3,
o4)
) → fF (o4
′
, 0)
Transforming values to terms
03 |x :o2, r :0 |o2o2:L(p=o3, n=o4)o3:L(?) o4:L(?)o2%$o3 o2%$o4 o3%$o4o2, o3, o4 {p,n}
E
Known integers transformed to themselves
Unknown values transformed to variables
Data structures transformed to nested constructor terms:Class Cl with n fields y symbol Cl of arity n
Encoding cycles: Special symbol © for repetition
fE (
o2︷ ︸︸ ︷
L(
o3,
o4), 0,
o2︷ ︸︸ ︷L(
o3,
o4)
) → fF (o4
′
, 0)
o5:L(p=null, n=o6)o6:L(p=o5, n=o7)o7:L(p=o6, n=null) null o5 o6 o7 null
n n n
ppp
Encoding of o5: L(null, L(©, L(©, null)))Encoding of o6: L(L(null,©), L(©, null))
Transforming states to terms
03 |x :o2, r :0 |o2o2:L(p=o3, n=o4)o3:L(?) o4:L(?)o2%$o3 o2%$o4 o3%$o4o2, o3, o4 {p,n}
E
State s term encoding:I Root symbol (≡ program position) fsI All local variables, stack entries as arguments
Evaluation edges: Encode states, put in →
I Problem: Cycle encoding changes y free var on rhsI Solution: Filter: Only encode non-cyclic parts!
Refinement edges: Encode target state twice, relabel
Instantiation edges: Encode source state twice, relabel
fE (
o2︷ ︸︸ ︷L(o3, o4), 0,
o2︷ ︸︸ ︷L(o3, o4))
→ fF (o4
′
, 0)
Transforming edges to rules
03 |x :o2, r :0 |o2o2:L(p=o3, n=o4)o3:L(?) o4:L(?)o2%$o3 o2%$o4 o3%$o4o2, o3, o4 {p,n}
E 11 |x :o4, r :0 |εo4 : L(?)o4 {p,n}
F
State s term encoding:I Root symbol (≡ program position) fsI All local variables, stack entries as arguments
Evaluation edges: Encode states, put in →
I Problem: Cycle encoding changes y free var on rhsI Solution: Filter: Only encode non-cyclic parts!
Refinement edges: Encode target state twice, relabel
Instantiation edges: Encode source state twice, relabel
fE (
o2︷ ︸︸ ︷L(o3, o4), 0,
o2︷ ︸︸ ︷L(o3, o4)) → fF (o4
′
, 0)
Transforming edges to rules
03 |x :o2, r :0 |o2o2:L(p=o3, n=o4)o3:L(?) o4:L(?)o2%$o3 o2%$o4 o3%$o4o2, o3, o4 {p,n}
E 11 |x :o4, r :0 |εo4 : L(?)o4 {p,n}
F
State s term encoding:I Root symbol (≡ program position) fsI All local variables, stack entries as arguments
Evaluation edges: Encode states, put in →I Problem: Cycle encoding changes y free var on rhs
I Solution: Filter: Only encode non-cyclic parts!
Refinement edges: Encode target state twice, relabel
Instantiation edges: Encode source state twice, relabel
fE (
o2︷ ︸︸ ︷L(o3, o4), 0,
o2︷ ︸︸ ︷L(o3, o4)) → fF (o4
′, 0)
Transforming edges to rules
03 |x :o2, r :0 |o2o2:L(p=o3, n=o4)o3:L(?) o4:L(?)o2%$o3 o2%$o4 o3%$o4o2, o3, o4 {p,n}
E 11 |x :o4, r :0 |εo4 : L(?)o4 {p,n}
F
State s term encoding:I Root symbol (≡ program position) fsI All local variables, stack entries as arguments
Evaluation edges: Encode states, put in →I Problem: Cycle encoding changes y free var on rhsI Solution: Filter: Only encode non-cyclic parts!
Refinement edges: Encode target state twice, relabel
Instantiation edges: Encode source state twice, relabel
fE (
o2︷ ︸︸ ︷L(
o3,
o4), 0,
o2︷ ︸︸ ︷L(
o3,
o4)) → fF (o4
′
, 0)
Transforming edges to rules
03 |x :o1, r :0 |o1o1 : L(?)o1 {p,n}
C
03 |x :o2, r :0 |o2o2:L(p=o3, n=o4)o3:L(?) o4:L(?)o2%$o3 o2%$o4 o3%$o4o2, o3, o4 {p,n}
E
State s term encoding:I Root symbol (≡ program position) fsI All local variables, stack entries as arguments
Evaluation edges: Encode states, put in →I Problem: Cycle encoding changes y free var on rhsI Solution: Filter: Only encode non-cyclic parts!
Refinement edges: Encode target state twice, relabel
Instantiation edges: Encode source state twice, relabel
fC (L(o4), 0, L(o4)) → fE (L(o4), 0, L(o4))
Transforming edges to rules
02 |x :o4, r :1 |εo4 : L(?)o4 {p,n}
G 02 |x :o ′1, r : i1 |εo ′1:L(?) o ′1 {p,n} i1: [≥0]
B ′
State s term encoding:I Root symbol (≡ program position) fsI All local variables, stack entries as arguments
Evaluation edges: Encode states, put in →I Problem: Cycle encoding changes y free var on rhsI Solution: Filter: Only encode non-cyclic parts!
Refinement edges: Encode target state twice, relabel
Instantiation edges: Encode source state twice, relabel
fG (o4, 2) → fB′(o4, 2)
The example TRS
00: iconst 1
01: istore 1
02: aload 0
03: ifnull 17
06: aload 0
07: getfield n
10: astore 0
11: iinc 1, 1
14: goto 2
17: iload 1
18: ireturn
00 |x :o1 |εo1:L(?) o1 {p,n}
A
02 |x :o1, r : 1 |εo1:L(?) o1 {p,n}
B
03 |x :o1, r : 1 |o1o1:L(?) o1 {p,n}
C
03 |x :null, r : 1 |null D
03 |x :o2, r : 1 |o2o2:L(p=o3, n=o4)o3:L(?) o4:L(?)o2%$o3 o2%$o4 o3%$o4o2, o3, o4 {p,n}
E 11 |x :o4, r : 1 |εo4:L(?) o4 {p,n}
F
02 |x :o4, r : 2 |εo4:L(?) o4 {p,n}
G02 |x :o′1, r : i1 |εo′1:L(?) o′1 {p,n} i1: [>0]
B′
03 |x :o′1, r : i1 |o′1
o′1:L(?) o′1 {p,n} i1: [>0]
C ′02 |x :o′4, r : i2 |o
′4
o′4:L(?) o′4 {p,n} i2: [>1]
G ′
i2= i1 + 1
1 Only consider SCCs!
2 Transform all edges as before, simplify:
fB′(L(o ′4), i1) → fB′(o′4, i1 + 1)
The example TRS
00: iconst 1
01: istore 1
02: aload 0
03: ifnull 17
06: aload 0
07: getfield n
10: astore 0
11: iinc 1, 1
14: goto 2
17: iload 1
18: ireturn
02 |x :o′1, r : i1 |εo′1:L(?) o′1 {p,n} i1: [>0]
B′
03 |x :o′1, r : i1 |o′1
o′1:L(?) o′1 {p,n} i1: [>0]
C ′02 |x :o′4, r : i2 |o
′4
o′4:L(?) o′4 {p,n} i2: [>1]
G ′
i2= i1 + 1
1 Only consider SCCs!
2 Transform all edges as before, simplify:
fB′(L(o ′4), i1) → fB′(o′4, i1 + 1)
The example TRS
00: iconst 1
01: istore 1
02: aload 0
03: ifnull 17
06: aload 0
07: getfield n
10: astore 0
11: iinc 1, 1
14: goto 2
17: iload 1
18: ireturn
02 |x :o′1, r : i1 |εo′1:L(?) o′1 {p,n} i1: [>0]
B′
03 |x :o′1, r : i1 |o′1
o′1:L(?) o′1 {p,n} i1: [>0]
C ′02 |x :o′4, r : i2 |o
′4
o′4:L(?) o′4 {p,n} i2: [>1]
G ′
i2= i1 + 1
1 Only consider SCCs!
2 Transform all edges as before, simplify:
fB′(L(o ′4), i1) → fB′(o′4, i1 + 1)
AProVE features for Java
Implementation for full Java without reflection and multithreading
Correctness proof w.r.t. JINJA [VITA’10]
Built-in, implicit analyses for nullness, aliasing, sharing, cyclicity
Termination analysis for algorithms
I on integers [RTA’10]I on acyclic user-defined data structures (trees, DAGs, . . . ) [RTA’10]I using recursion [RTA’11]I on cyclic data [CAV’12]
by measuring distancesby detecting (and ignoring) irrelevant cyclicityby automatically finding and counting markers
Non-termination analysis [FoVeOOS’11]
AProVE features for Java
Implementation for full Java without reflection and multithreading
Correctness proof w.r.t. JINJA [VITA’10]
Built-in, implicit analyses for nullness, aliasing, sharing, cyclicity
Termination analysis for algorithms
I on integers [RTA’10]I on acyclic user-defined data structures (trees, DAGs, . . . ) [RTA’10]I using recursion [RTA’11]I on cyclic data [CAV’12]
by measuring distancesby detecting (and ignoring) irrelevant cyclicityby automatically finding and counting markers
Non-termination analysis [FoVeOOS’11]
AProVE features for Java
Implementation for full Java without reflection and multithreading
Correctness proof w.r.t. JINJA [VITA’10]
Built-in, implicit analyses for nullness, aliasing, sharing, cyclicity
Termination analysis for algorithmsI on integers [RTA’10]I on acyclic user-defined data structures (trees, DAGs, . . . ) [RTA’10]
I using recursion [RTA’11]I on cyclic data [CAV’12]
by measuring distancesby detecting (and ignoring) irrelevant cyclicityby automatically finding and counting markers
Non-termination analysis [FoVeOOS’11]
AProVE features for Java
Implementation for full Java without reflection and multithreading
Correctness proof w.r.t. JINJA [VITA’10]
Built-in, implicit analyses for nullness, aliasing, sharing, cyclicity
Termination analysis for algorithmsI on integers [RTA’10]I on acyclic user-defined data structures (trees, DAGs, . . . ) [RTA’10]I using recursion [RTA’11]
I on cyclic data [CAV’12]
by measuring distancesby detecting (and ignoring) irrelevant cyclicityby automatically finding and counting markers
Non-termination analysis [FoVeOOS’11]
AProVE features for Java
Implementation for full Java without reflection and multithreading
Correctness proof w.r.t. JINJA [VITA’10]
Built-in, implicit analyses for nullness, aliasing, sharing, cyclicity
Termination analysis for algorithmsI on integers [RTA’10]I on acyclic user-defined data structures (trees, DAGs, . . . ) [RTA’10]I using recursion [RTA’11]I on cyclic data [CAV’12]
by measuring distancesby detecting (and ignoring) irrelevant cyclicityby automatically finding and counting markers
Non-termination analysis [FoVeOOS’11]
AProVE features for Java
Implementation for full Java without reflection and multithreading
Correctness proof w.r.t. JINJA [VITA’10]
Built-in, implicit analyses for nullness, aliasing, sharing, cyclicity
Termination analysis for algorithmsI on integers [RTA’10]I on acyclic user-defined data structures (trees, DAGs, . . . ) [RTA’10]I using recursion [RTA’11]I on cyclic data [CAV’12]
by measuring distancesby detecting (and ignoring) irrelevant cyclicityby automatically finding and counting markers
Non-termination analysis [FoVeOOS’11]
Experimental results
Evaluated on collection of 441 programs from Termination ProblemData Base
Yes No Fail Run (s)
AProVE 289 125 27 16.6Julia 205 79 157 6.5COSTA 163 0 278 13.1
Won Termination Competition 2012/2013
Open problems:I Abstraction refinementI Modular analysis
Specialized abstract domains:
easy to automate
very effective
Experimental results
Evaluated on collection of 441 programs from Termination ProblemData Base
Yes No Fail Run (s)
AProVE 289 125 27 16.6Julia 205 79 157 6.5COSTA 163 0 278 13.1
Won Termination Competition 2012/2013
Open problems:I Abstraction refinementI Modular analysis
Specialized abstract domains:
easy to automate
very effective
Experimental results
Evaluated on collection of 441 programs from Termination ProblemData Base
Yes No Fail Run (s)
AProVE 289 125 27 16.6Julia 205 79 157 6.5COSTA 163 0 278 13.1
Won Termination Competition 2012/2013
Open problems:I Abstraction refinementI Modular analysis
Specialized abstract domains:
easy to automate
very effective
Experimental results
Evaluated on collection of 441 programs from Termination ProblemData Base
Yes No Fail Run (s)
AProVE 289 125 27 16.6Julia 205 79 157 6.5COSTA 163 0 278 13.1
Won Termination Competition 2012/2013
Open problems:I Abstraction refinementI Modular analysis
Specialized abstract domains:
easy to automate
very effective
Termination Analysis: Invariants and Rank Functions
Example
y := 1;while x > 0 do
x := x − y;y := y + 1;
done
Invariant y > 0 and rank function x prove termination
How do we know that we need y > 0? y x requires it
How do we know that x is a RF? y y > 0 proves it
Termination Analysis: Invariants and Rank Functions
Example
y := 1;while x > 0 do
x := x − y;y := y + 1;
done
Invariant y > 0 and rank function x prove termination
How do we know that we need y > 0? y x requires it
How do we know that x is a RF? y y > 0 proves it
Termination by iterative strengthening: Idea
1 Safety: Provide samples (Counterexamples)
2 Rank tool: Find specific termination argument
3 Safety: Prove generality, or 1
Termination by iterative strengthening: Idea
1 Safety: Provide samples (Counterexamples)
2 Rank tool: Find specific termination argument
3 Safety: Prove generality, or 1
Termination by iterative strengthening
Loop states
Find counterexample
then strengthen argument
Termination by iterative strengthening
Loop states
Execution
Find counterexample
then strengthen argument
Termination by iterative strengthening
Loop statesTerminating states
Execution
Find counterexample
then strengthen argument
Termination by iterative strengthening
Loop statesTerminating states
Terminating states
Execution
Find counterexample
then strengthen argument
Termination by iterative strengthening
Loop statesTerminating states
Terminating states
Term
inat
ing
stat
esFind counterexample
then strengthen argument
Termination by iterative strengthening: Worst case
1 Safety: Look at everything, then return old sample
2 Rank tool: Find too specific termination argument
3 Safety: Can’t prove generality, repeat 1
Termination by iterative strengthening: Worst case
1 Safety: Look at everything, then return old sample
2 Rank tool: Find too specific termination argument
3 Safety: Can’t prove generality, repeat 1
Termination by iterative simplification
Loop trans.
Termination by iterative simplification
Loop trans.
Execution
Termination by iterative simplification
Loop trans.
Execution
Find rank function for SCC
Termination by iterative simplification
Loop trans.
Execution
Find rank function for SCC
then remove transitions
Termination by iterative simplification
Loop trans.
Execution
Find rank function for SCC
then remove transitions
Termination by iterative simplification
Looptrans.
Execution
Find rank function for SCC
then remove transitions
Termination by cooperation
1 Safety: Provide samples (Counterexamples)
2 Rank tool: Find termination argument in context
3 Rank tool: Mark definitely terminating parts (simplify)
4 Safety: Prove generality for rest, or 1
Cooperation: High-level view
Safety Termination
Cooperation: High-level view
Safety Termination
Cooperation: High-level view
Safety Termination
Term
inat
ing
stat
es
Cooperation: High-level view
Safety Termination
Term
inat
ing
stat
es
Cooperation: High-level view
start
`1
`2
τ0 : if(k ≥ 1);i := 0;
τ1 : if(i < n);j := 0;
τ2 : if(j > i);i := i + 1;
τ3 : if(j ≤ i);j := j + k;
Example (Source)
if k ≥ 1 theni := 0;
`1 while i < n do
j := 0;
`2 while j ≤ i do
j := j + k;done
i := i + 1;done
fi
Cooperation: High-level view
start
`1
`2
τ0 : if(k ≥ 1);i := 0;
τ1 : if(i < n);j := 0;
τ2 : if(j > i);i := i + 1;
τ3 : if(j ≤ i);j := j + k;
`t1
`t2
`d1
`d2
maybe take a
snapshot
maybe take a
snapshot
check decrease
check decrease
τt1: if(i<n);
j :=0;
τ t3 : if(j ≤ i);j := j + k;
τ t2 : if(j >
i);
i :=i +
1;
Cooperation
Intuition:
Safety subgraph: original program
Termination subgraph: instrumented copy
Ranking: Simplify problem, “point out hard bits”
Safety: Analyze whole program, “point out invariants”
Approach:
Analyze whole SCC, not counterexample slice
Remove transitions after proof
Cooperation
Intuition:
Safety subgraph: original program
Termination subgraph: instrumented copy
Ranking: Simplify problem, “point out hard bits”
Safety: Analyze whole program, “point out invariants”
Approach:
Analyze whole SCC, not counterexample slice
Remove transitions after proof
Cooperation
Intuition:
Safety subgraph: original program
Termination subgraph: instrumented copy
Ranking: Simplify problem, “point out hard bits”
Safety: Analyze whole program, “point out invariants”
Approach:
Analyze whole SCC, not counterexample slice
Remove transitions after proof
Cooperation
Intuition:
Safety subgraph: original program
Termination subgraph: instrumented copy
Ranking: Simplify problem, “point out hard bits”
Safety: Analyze whole program, “point out invariants”
Approach:
Analyze whole SCC, not counterexample slice
Remove transitions after proof
Cooperation
Intuition:
Safety subgraph: original program
Termination subgraph: instrumented copy
Ranking: Simplify problem, “point out hard bits”
Safety: Analyze whole program, “point out invariants”
Approach:
Analyze whole SCC, not counterexample slice
Remove transitions after proof
Cooperation: Simplification
start
`1
`2
τ0 : if(k ≥ 1);i := 0;
τ1 : if(i < n);j := 0;
τ2 : if(j > i);i := i + 1;
τ3 : if(j ≤ i);j := j + k;
`t1
`t2
`d1
`d2
maybe take a
snapshot
maybe take a
snapshot
check decrease
check decrease
τt1: if(i<n);
j :=0;
τ t3 : if(j ≤ i);j := j + k;
τ t2 : if(j >
i);
i :=i +
1;
Cooperation: Simplification
start
`1
`2
`t1
`t2
`d1
`d2
maybe take a
snapshot
maybe take a
snapshot
check decrease
check decrease
τt1: if(i<n);
j :=0;
τ t3 : if(j ≤ i);j := j + k;
τ t2 : if(j >
i);
i :=i +
1;
Simplification
1 Find SCC S intermination graph:
`t1, `d1 , `
t2, `
d2
2 Find S-orienting RF:
f 1`t1(i,j,k,n) = n− i + 1
f 1`d1
(i,j,k,n) = n− i + 1
f 1`t2(i,j,k,n) = n− i
f 1`d2
(i,j,k,n) = n− i
3 Delete decr./bounded
4 Clean up
Cooperation: Simplification
start
`1
`2
`t1
`t2
`d1
`d2
maybe take a
snapshot
maybe take a
snapshot
check decrease
check decrease
τt1: if(i<n);
j :=0;
τ t3 : if(j ≤ i);j := j + k;
τ t2 : if(j >
i);
i :=i +
1;
Simplification1 Find SCC S in
termination graph:
`t1, `d1 , `
t2, `
d2
2 Find S-orienting RF:
f 1`t1(i,j,k,n) = n− i + 1
f 1`d1
(i,j,k,n) = n− i + 1
f 1`t2(i,j,k,n) = n− i
f 1`d2
(i,j,k,n) = n− i
3 Delete decr./bounded
4 Clean up
Cooperation: Simplification
start
`1
`2
`t1
`t2
`d1
`d2
maybe take a
snapshot
maybe take a
snapshot
check decrease
check decrease
τt1: if(i<n);
j :=0;
τ t3 : if(j ≤ i);j := j + k;
τ t2 : if(j >
i);
i :=i +
1;
Simplification1 Find SCC S in
termination graph:
`t1, `d1 , `
t2, `
d2
2 Find S-orienting RF:
f 1`t1(i,j,k,n) = n− i + 1
f 1`d1
(i,j,k,n) = n− i + 1
f 1`t2(i,j,k,n) = n− i
f 1`d2
(i,j,k,n) = n− i
3 Delete decr./bounded
4 Clean up
Cooperation: Simplification
start
`1
`2
`t1
`t2
`d1
`d2
maybe take a
snapshot
maybe take a
snapshot
check decrease
check decrease
τt1: if(i<n);
j :=0;
τ t3 : if(j ≤ i);j := j + k;
τ t2 : if(j >
i);
i :=i +
1;
Simplification1 Find SCC S in
termination graph:
`t1, `d1 , `
t2, `
d2
2 Find S-orienting RF:
f 1`t1(i,j,k,n) = n− i + 1
f 1`d1
(i,j,k,n) = n− i + 1
f 1`t2(i,j,k,n) = n− i
f 1`d2
(i,j,k,n) = n− i
3 Delete decr./bounded
4 Clean up
Cooperation: Simplification
start
`1
`2
`t1
`t2
`d1
`d2
maybe take a
snapshot
maybe take a
snapshot
check decrease
check decrease
τ t3 : if(j ≤ i);j := j + k;
τ t2 : if(j >
i);
i :=i +
1;
Simplification1 Find SCC S in
termination graph:
`t1, `d1 , `
t2, `
d2
2 Find S-orienting RF:
f 1`t1(i,j,k,n) = n− i + 1
f 1`d1
(i,j,k,n) = n− i + 1
f 1`t2(i,j,k,n) = n− i
f 1`d2
(i,j,k,n) = n− i
3 Delete decr./bounded
4 Clean up
Cooperation: Simplification
start
`1
`2 `t2 `d2
maybe take a
snapshotcheck decrease
τ t3 : if(j ≤ i);j := j + k;
Simplification1 Find SCC S in
termination graph:
`t1, `d1 , `
t2, `
d2
2 Find S-orienting RF:
f 1`t1(i,j,k,n) = n− i + 1
f 1`d1
(i,j,k,n) = n− i + 1
f 1`t2(i,j,k,n) = n− i
f 1`d2
(i,j,k,n) = n− i
3 Delete decr./bounded
4 Clean up
Cooperation
start
`1
`2
τ0 : if(k ≥ 1);i := 0;
τ1 : if(i < n);j := 0;
τ2 : if(j > i);i := i + 1;
τ3 : if(j ≤ i);j := j + k;
`t2 `d2
maybe take a
snapshotcheck decrease
τ t3 : if(j ≤ i);j := j + k;
Cooperation: Invariants
start
`1
`2
τ0 : if(k ≥ 1);i := 0;
τ1 : if(i < n);j := 0;
τ2 : if(j > i);i := i + 1;
τ3 : if(j ≤ i);j := j + k;
`t2 `d2
maybe take a
snapshotcheck decrease
τ t3 : if(j ≤ i);j := j + k;
Construction/Checking1 No simplification possible
2 Obtain counterexample:
τ0 τ1 (snapshot) τ t3
3 Compute RF:
f 1`t2(i,j,k,n) = i− j
4 Add to instrumentation
Cooperation: Invariants
start
`1
`2
τ0 : if(k ≥ 1);i := 0;
τ1 : if(i < n);j := 0;
τ2 : if(j > i);i := i + 1;
τ3 : if(j ≤ i);j := j + k;
`t2 `d2
maybe take a
snapshotcheck decrease
τ t3 : if(j ≤ i);j := j + k;
Construction/Checking1 No simplification possible
2 Obtain counterexample:
τ0 τ1 (snapshot) τ t3
3 Compute RF:
f 1`t2(i,j,k,n) = i− j
4 Add to instrumentation
Cooperation: Invariants
start
`1
`2
τ0 : if(k ≥ 1);i := 0;
τ1 : if(i < n);j := 0;
τ2 : if(j > i);i := i + 1;
τ3 : if(j ≤ i);j := j + k;
`t2 `d2
maybe take a
snapshotcheck decrease
τ t3 : if(j ≤ i);j := j + k;
Construction/Checking1 No simplification possible
2 Obtain counterexample:
τ0 τ1 (snapshot) τ t3
3 Compute RF:
f 1`t2(i,j,k,n) = i− j
4 Add to instrumentation
Cooperation: Invariants
start
`1
`2
τ0 : if(k ≥ 1);i := 0;
τ1 : if(i < n);j := 0;
τ2 : if(j > i);i := i + 1;
τ3 : if(j ≤ i);j := j + k;
`t2 `d2
maybe take a
snapshotcheck decrease
τ t3 : if(j ≤ i);j := j + k;
Construction/Checking1 No simplification possible
2 Obtain counterexample:
τ0 τ1 (snapshot) τ t3
3 Compute RF:
f 1`t2(i,j,k,n) = i− j
4 Add to instrumentation
Cooperation: Invariants
start
`1
`2
τ0 : if(k ≥ 1);i := 0;
τ1 : if(i < n);j := 0;
τ2 : if(j > i);i := i + 1;
τ3 : if(j ≤ i);j := j + k;
`t2 `d2
ρ′2: i
f(cp
2≥1);
if(¬(ic−jc>i−
j));
if(¬(ic−jc>0));
maybe take a
snapshot
τ t3 : if(j ≤ i);j := j + k;
Cooperation: Evaluation
Evaluated on 449 termination proving benchmarks260 known terminating, 181 known non-terminating, 8 unknownSources: Windows drivers, Apache, PostgreSQL, . . .
Term (#) Term (avg. s)
Cooperating-T2 245 3.42AProVE 197 2.21KITTeL 196 4.65T2 189 5.15AProVE+Interproc 185 1.53Terminator 177 4.99Size-Change/MCNP 156 17.50ARMC 138 16.16
Sources available: http://research.microsoft.com/en-us/projects/t2/
Cooperation: Evaluation
Evaluated on 449 termination proving benchmarks260 known terminating, 181 known non-terminating, 8 unknownSources: Windows drivers, Apache, PostgreSQL, . . .
Term (#) Term (avg. s)
Cooperating-T2 245 3.42AProVE 197 2.21KITTeL 196 4.65T2 189 5.15AProVE+Interproc 185 1.53Terminator 177 4.99Size-Change/MCNP 156 17.50ARMC 138 16.16
Sources available: http://research.microsoft.com/en-us/projects/t2/
Cooperation: Evaluation
Evaluated on 449 termination proving benchmarks260 known terminating, 181 known non-terminating, 8 unknownSources: Windows drivers, Apache, PostgreSQL, . . .
Term (#) Term (avg. s)
Cooperating-T2 245 3.42AProVE 197 2.21KITTeL 196 4.65T2 189 5.15AProVE+Interproc 185 1.53Terminator 177 4.99Size-Change/MCNP 156 17.50ARMC 138 16.16
Sources available: http://research.microsoft.com/en-us/projects/t2/
Program termination: Our approach
Java Termination Graph1intTRS
2
1 Symbolic evaluation
2 Translation + post-processing
3 Restriction to terms
4 Restriction to integers & replacing terms by their “sizes”
Program termination: Our approach
Java Termination Graph1intTRS
2
TRS
3
ITS
4
1 Symbolic evaluation
2 Translation + post-processing
3 Restriction to terms
4 Restriction to integers & replacing terms by their “sizes”
Program termination: Contributions of this thesis
Proving termination of Java:1 Translation from Termination Graph to intTRS2 Post-processing Termination Graphs: Handle cycles, distances3 Non-termination proofs on Termination Graphs
Proving termination of intTRSs:4 Simplification of automatically generated intTRSs5 Abstracting terms to their height6 Termination proofs by alternating TRS/ITS techniques
Proving termination of Integer Transition Systems:7 Cooperative termination proving8 Alternating termination/non-termination proving
Implementations, most powerful in their fields:a AProVE: 1 - 6
b T2: 7 - 8
Program termination: Contributions of this thesis
Proving termination of Java:1 Translation from Termination Graph to intTRS2 Post-processing Termination Graphs: Handle cycles, distances3 Non-termination proofs on Termination Graphs
Proving termination of intTRSs:4 Simplification of automatically generated intTRSs5 Abstracting terms to their height6 Termination proofs by alternating TRS/ITS techniques
Proving termination of Integer Transition Systems:7 Cooperative termination proving8 Alternating termination/non-termination proving
Implementations, most powerful in their fields:a AProVE: 1 - 6
b T2: 7 - 8
Program termination: Contributions of this thesis
Proving termination of Java:1 Translation from Termination Graph to intTRS2 Post-processing Termination Graphs: Handle cycles, distances3 Non-termination proofs on Termination Graphs
Proving termination of intTRSs:4 Simplification of automatically generated intTRSs5 Abstracting terms to their height6 Termination proofs by alternating TRS/ITS techniques
Proving termination of Integer Transition Systems:7 Cooperative termination proving8 Alternating termination/non-termination proving
Implementations, most powerful in their fields:a AProVE: 1 - 6
b T2: 7 - 8
Program termination: Contributions of this thesis
Proving termination of Java:1 Translation from Termination Graph to intTRS2 Post-processing Termination Graphs: Handle cycles, distances3 Non-termination proofs on Termination Graphs
Proving termination of intTRSs:4 Simplification of automatically generated intTRSs5 Abstracting terms to their height6 Termination proofs by alternating TRS/ITS techniques
Proving termination of Integer Transition Systems:7 Cooperative termination proving8 Alternating termination/non-termination proving
Implementations, most powerful in their fields:a AProVE: 1 - 6
b T2: 7 - 8