5.58/2.34 NO 5.58/2.36 proof of /export/starexec/sandbox/benchmark/theBenchmark.jar 5.58/2.36 # AProVE Commit ID: 48fb2092695e11cc9f56e44b17a92a5f88ffb256 marcel 20180622 unpublished dirty 5.58/2.36 5.58/2.36 5.58/2.36 termination of the given Bare JBC problem could be disproven: 5.58/2.36 5.58/2.36 (0) Bare JBC problem 5.58/2.36 (1) BareJBCToJBCProof [EQUIVALENT, 95 ms] 5.58/2.36 (2) JBC problem 5.58/2.36 (3) JBCToGraph [EQUIVALENT, 281 ms] 5.58/2.36 (4) JBCTerminationGraph 5.58/2.36 (5) JBCNonTerm [COMPLETE, 119 ms] 5.58/2.36 (6) NO 5.58/2.36 5.58/2.36 5.58/2.36 ---------------------------------------- 5.58/2.36 5.58/2.36 (0) 5.58/2.36 Obligation: 5.58/2.36 need to prove termination of the following program: 5.58/2.36 package simple.even; 5.58/2.36 5.58/2.36 public class Even { 5.58/2.36 5.58/2.36 // does not terminate for negative numbers 5.58/2.36 5.58/2.36 public static boolean even(int i) { 5.58/2.36 while (i != 1 && i != 0) { 5.58/2.36 i = i-2; 5.58/2.36 } 5.58/2.36 return (i == 0); 5.58/2.36 } 5.58/2.36 } 5.58/2.36 5.58/2.36 5.58/2.36 package simple.even; 5.58/2.36 5.58/2.36 public class Main { 5.58/2.36 5.58/2.36 /** 5.58/2.36 * @param args 5.58/2.36 */ 5.58/2.36 public static void main(String[] args) { 5.58/2.36 int even = args[1].length(); 5.58/2.36 if (args[0].length() % 2 == 0) { 5.58/2.36 even = -even; 5.58/2.36 } 5.58/2.36 Even.even(even); 5.58/2.36 5.58/2.36 } 5.58/2.36 5.58/2.36 } 5.58/2.36 5.58/2.36 5.58/2.36 5.58/2.36 ---------------------------------------- 5.58/2.36 5.58/2.36 (1) BareJBCToJBCProof (EQUIVALENT) 5.58/2.36 initialized classpath 5.58/2.36 ---------------------------------------- 5.58/2.36 5.58/2.36 (2) 5.58/2.36 Obligation: 5.58/2.36 need to prove termination of the following program: 5.58/2.36 package simple.even; 5.58/2.36 5.58/2.36 public class Even { 5.58/2.36 5.58/2.36 // does not terminate for negative numbers 5.58/2.36 5.58/2.36 public static boolean even(int i) { 5.58/2.36 while (i != 1 && i != 0) { 5.58/2.36 i = i-2; 5.58/2.36 } 5.58/2.36 return (i == 0); 5.58/2.36 } 5.58/2.36 } 5.58/2.36 5.58/2.36 5.58/2.36 package simple.even; 5.58/2.36 5.58/2.36 public class Main { 5.58/2.36 5.58/2.36 /** 5.58/2.36 * @param args 5.58/2.36 */ 5.58/2.36 public static void main(String[] args) { 5.58/2.36 int even = args[1].length(); 5.58/2.36 if (args[0].length() % 2 == 0) { 5.58/2.36 even = -even; 5.58/2.36 } 5.58/2.36 Even.even(even); 5.58/2.36 5.58/2.36 } 5.58/2.36 5.58/2.36 } 5.58/2.36 5.58/2.36 5.58/2.36 5.58/2.36 ---------------------------------------- 5.58/2.36 5.58/2.36 (3) JBCToGraph (EQUIVALENT) 5.58/2.36 Constructed TerminationGraph. 5.58/2.36 ---------------------------------------- 5.58/2.36 5.58/2.36 (4) 5.58/2.36 Obligation: 5.58/2.36 Termination Graph based on JBC Program: 5.58/2.36 simple.even.Main.main([Ljava/lang/String;)V: Graph of 143 nodes with 2 SCCs. 5.58/2.36 5.58/2.36 5.58/2.36 5.58/2.36 5.58/2.36 5.58/2.36 ---------------------------------------- 5.58/2.36 5.58/2.36 (5) JBCNonTerm (COMPLETE) 5.58/2.36 Reached a loop using the following run: 5.58/2.36 5.58/2.36 0: 5.58/2.36 o33!: String(count=0, hash=#, offset=0, value=o34?) -->{java.lang.Object...} 5.58/2.36 a2([java.lang.String...]): {o33, o15} -->{java.lang.Object...} 5.58/2.36 o15!: String(count=1, hash=#, offset=0, value=o16?) -->{java.lang.Object...} 5.58/2.36 o34:: [CHAR] -->{java.lang.Object...} 5.58/2.36 o16:: [CHAR] -->{java.lang.Object...} 5.58/2.36 a2-><-o34 5.58/2.36 a2-><-o33 5.58/2.36 a2-><-o16 5.58/2.36 a2-><-o15 5.58/2.36 YES: (JL1) 5.58/2.36 1: 5.58/2.36 o33!: String(count=0, hash=#, offset=0, value=o34?) -->{java.lang.Object...} 5.58/2.36 a2([java.lang.String...]): {o33, o15} -->{java.lang.Object...} 5.58/2.36 o15!: String(count=1, hash=#, offset=0, value=o16?) -->{java.lang.Object...} 5.58/2.36 o34:: [CHAR] -->{java.lang.Object...} 5.58/2.36 o16:: [CHAR] -->{java.lang.Object...} 5.58/2.36 a2-><-o34 5.58/2.36 a2-><-o33 5.58/2.36 a2-><-o16 5.58/2.36 a2-><-o15 5.58/2.36 YES: (JL1) 5.58/2.36 2: 5.58/2.36 o33!: String(count=0, hash=#, offset=0, value=o34?) -->{java.lang.Object...} 5.58/2.36 a2([java.lang.String...]): {o33, o15} -->{java.lang.Object...} 5.58/2.36 o15!: String(count=1, hash=#, offset=0, value=o16?) -->{java.lang.Object...} 5.58/2.36 o34:: [CHAR] -->{java.lang.Object...} 5.58/2.36 o16:: [CHAR] -->{java.lang.Object...} 5.58/2.36 a2-><-o34 5.58/2.36 a2-><-o33 5.58/2.36 a2-><-o16 5.58/2.36 a2-><-o15 5.58/2.36 YES: (JL1) 5.58/2.36 3: 5.58/2.36 o33!: String(count=0, hash=#, offset=0, value=o34?) -->{java.lang.Object...} 5.58/2.36 a2([java.lang.String...]): {o33, o15} -->{java.lang.Object...} 5.58/2.36 o15!: String(count=1, hash=#, offset=0, value=o16?) -->{java.lang.Object...} 5.58/2.36 o34:: [CHAR] -->{java.lang.Object...} 5.58/2.36 o16:: [CHAR] -->{java.lang.Object...} 5.58/2.36 a2-><-o34 5.58/2.36 a2-><-o33 5.58/2.36 a2-><-o16 5.58/2.36 a2-><-o15 5.58/2.36 YES: (JL1) 5.58/2.36 4: 5.58/2.36 5.58/2.36 o33!: String(count=0, hash=#, offset=0, value=o34?) -->{java.lang.Object...} 5.58/2.36 a2([java.lang.String...]): {o33, o15} -->{java.lang.Object...} 5.58/2.36 o15!: String(count=1, hash=#, offset=0, value=o16?) -->{java.lang.Object...} 5.58/2.36 o34:: [CHAR] -->{java.lang.Object...} 5.58/2.36 o16:: [CHAR] -->{java.lang.Object...} 5.58/2.36 a2-><-o34 5.58/2.36 a2-><-o33 5.58/2.36 a2-><-o16 5.58/2.36 a2-><-o15 5.58/2.36 YES: (JL1) 5.58/2.36 5: 5.58/2.36 5.58/2.36 o33!: String(count=0, hash=#, offset=0, value=o34?) -->{java.lang.Object...} 5.58/2.36 a2([java.lang.String...]): {o33, o15} -->{java.lang.Object...} 5.58/2.36 o15!: String(count=1, hash=#, offset=0, value=o16?) -->{java.lang.Object...} 5.58/2.36 o34:: [CHAR] -->{java.lang.Object...} 5.58/2.36 o16:: [CHAR] -->{java.lang.Object...} 5.58/2.36 a2-><-o34 5.58/2.36 a2-><-o33 5.58/2.36 a2-><-o16 5.58/2.36 a2-><-o15 5.58/2.36 YES: (JL1) 5.58/2.36 6: 5.58/2.36 5.58/2.36 o33!: String(count=0, hash=#, offset=0, value=o34?) -->{java.lang.Object...} 5.58/2.36 a2([java.lang.String...]): {o33, o15} -->{java.lang.Object...} 5.58/2.36 o15!: String(count=1, hash=#, offset=0, value=o16?) -->{java.lang.Object...} 5.58/2.36 o34:: [CHAR] -->{java.lang.Object...} 5.58/2.36 o16:: [CHAR] -->{java.lang.Object...} 5.58/2.36 a2-><-o34 5.58/2.36 a2-><-o33 5.58/2.36 a2-><-o16 5.58/2.36 a2-><-o15 5.58/2.36 YES: (JL1) 5.58/2.36 7: 5.58/2.36 o33!: String(count=0, hash=#, offset=0, value=o34?) -->{java.lang.Object...} 5.58/2.36 a2([java.lang.String...]): {o33, o15} -->{java.lang.Object...} 5.58/2.36 o15!: String(count=1, hash=#, offset=0, value=o16?) -->{java.lang.Object...} 5.58/2.36 o34:: [CHAR] -->{java.lang.Object...} 5.58/2.36 o16:: [CHAR] -->{java.lang.Object...} 5.58/2.36 a2-><-o34 5.58/2.36 a2-><-o33 5.58/2.36 a2-><-o16 5.58/2.36 a2-><-o15 5.58/2.36 YES: (JL1) 5.58/2.36 8: 5.58/2.36 o33!: String(count=0, hash=#, offset=0, value=o34?) -->{java.lang.Object...} 5.58/2.36 a2([java.lang.String...]): {o33, o15} -->{java.lang.Object...} 5.58/2.36 o15!: String(count=1, hash=#, offset=0, value=o16?) -->{java.lang.Object...} 5.58/2.36 o34:: [CHAR] -->{java.lang.Object...} 5.58/2.36 o16:: [CHAR] -->{java.lang.Object...} 5.58/2.36 a2-><-o34 5.58/2.36 a2-><-o33 5.58/2.36 a2-><-o16 5.58/2.36 a2-><-o15 5.58/2.36 YES: (JL1) 5.58/2.36 9: 5.58/2.36 o33!: String(count=0, hash=#, offset=0, value=o34?) -->{java.lang.Object...} 5.58/2.36 a2([java.lang.String...]): {o33, o15} -->{java.lang.Object...} 5.58/2.36 o15!: String(count=1, hash=#, offset=0, value=o16?) -->{java.lang.Object...} 5.58/2.36 o34:: [CHAR] -->{java.lang.Object...} 5.58/2.36 o16:: [CHAR] -->{java.lang.Object...} 5.58/2.36 a2-><-o34 5.58/2.36 a2-><-o33 5.58/2.36 a2-><-o16 5.58/2.36 a2-><-o15 5.58/2.36 YES: (JL1) 5.58/2.36 10: 5.58/2.36 o33!: String(count=0, hash=#, offset=0, value=o34?) -->{java.lang.Object...} 5.58/2.36 a2([java.lang.String...]): {o33, o15} -->{java.lang.Object...} 5.58/2.36 o15!: String(count=1, hash=#, offset=0, value=o16?) -->{java.lang.Object...} 5.58/2.36 o34:: [CHAR] -->{java.lang.Object...} 5.58/2.36 o16:: [CHAR] -->{java.lang.Object...} 5.58/2.36 a2-><-o34 5.58/2.36 a2-><-o33 5.58/2.36 a2-><-o16 5.58/2.36 a2-><-o15 5.58/2.36 YES: (JL1) 5.58/2.36 11: 5.58/2.36 o33!: String(count=0, hash=#, offset=0, value=o34?) -->{java.lang.Object...} 5.58/2.36 o34:: [CHAR] -->{java.lang.Object...} 5.58/2.36 YES: (JL1) 5.58/2.36 12: 5.58/2.36 5.58/2.36 o33!: String(count=0, hash=#, offset=0, value=o34?) -->{java.lang.Object...} 5.58/2.36 o34:: [CHAR] -->{java.lang.Object...} 5.58/2.36 YES: (JL1) 5.58/2.36 13: 5.58/2.36 5.58/2.36 o33!: String(count=0, hash=#, offset=0, value=o34?) -->{java.lang.Object...} 5.58/2.36 o34:: [CHAR] -->{java.lang.Object...} 5.58/2.36 YES: (JL1) 5.58/2.36 14: 5.58/2.36 5.58/2.36 YES: (JL1) 5.58/2.36 15: 5.58/2.36 YES: (JL1) 5.58/2.36 16: 5.58/2.36 YES: (JL1) 5.58/2.36 17: 5.58/2.36 YES: (JL1) 5.58/2.36 18: 5.58/2.36 YES: (JL1) 5.58/2.36 19: 5.58/2.36 YES: (JL1) 5.58/2.36 20: 5.58/2.36 YES: (JL1) 5.58/2.36 21: 5.58/2.36 YES: (JL1) 5.58/2.36 22: 5.58/2.36 YES: (JL1) 5.58/2.36 23: 5.58/2.36 5.58/2.36 YES: (JL1) 5.58/2.36 Start state of loop: 5.58/2.36 5.58/2.36 5.58/2.36 [a2(lv_0_0)] 5.58/2.36 5.58/2.36 a2([java.lang.String...]): length i6 -->{java.lang.Object...} 5.58/2.36 i6: [2,+inf){0,+inf} 5.58/2.36 i36: (-inf,0]{-inf,+inf} 5.58/2.36 YES: (JL1) 5.58/2.36 5.58/2.36 5.58/2.36 In the loop head node, references [i36] were interesting. 5.58/2.36 5.58/2.36 All methods calls in the loop body are side-effect free, hence they can be ignored. 5.58/2.36 5.58/2.36 By SMT, we could prove 5.58/2.36 5.58/2.36 ((initial_i36 <= 0 and 2 <= initial_i6) and (((path1_i36 = path1_i45 and path1_i88 = (path1_i45 - 2) and path1_i88 = res_i36 and path1_i36 = initial_i36) and (path1_i36 < 1 and path1_i45 < 0)) and ((res1_i36 = res1_i45 and res1_i88 = (res1_i45 - 2) and res_i36 = res1_i36) and !(res1_i36 < 1 and res1_i45 < 0)))) 5.58/2.36 5.58/2.36 to be UNSAT. Consequently, the loop will not terminate. 5.58/2.36 ---------------------------------------- 5.58/2.36 5.58/2.36 (6) 5.58/2.36 NO 5.58/2.40 EOF