7.03/2.75 NO 7.24/2.81 proof of /export/starexec/sandbox/benchmark/theBenchmark.jar 7.24/2.81 # AProVE Commit ID: 48fb2092695e11cc9f56e44b17a92a5f88ffb256 marcel 20180622 unpublished dirty 7.24/2.81 7.24/2.81 7.24/2.81 termination of the given Bare JBC problem could be disproven: 7.24/2.81 7.24/2.81 (0) Bare JBC problem 7.24/2.81 (1) BareJBCToJBCProof [EQUIVALENT, 95 ms] 7.24/2.81 (2) JBC problem 7.24/2.81 (3) JBCNonTerm [COMPLETE, 455 ms] 7.24/2.81 (4) NO 7.24/2.81 7.24/2.81 7.24/2.81 ---------------------------------------- 7.24/2.81 7.24/2.81 (0) 7.24/2.81 Obligation: 7.24/2.81 need to prove termination of the following program: 7.24/2.81 package simple.middle; 7.24/2.81 7.24/2.81 public class Main { 7.24/2.81 7.24/2.81 /** 7.24/2.81 * @param args 7.24/2.81 */ 7.24/2.81 public static void main(String[] args) { 7.24/2.81 Middle.middle(args[0].length(), args[1].length()); 7.24/2.81 } 7.24/2.81 7.24/2.81 } 7.24/2.81 7.24/2.81 7.24/2.81 package simple.middle; 7.24/2.81 7.24/2.81 public class Middle { 7.24/2.81 7.24/2.81 /* 7.24/2.81 * returns the number which is exactly between the first and the second 7.24/2.81 * input number, does not work if one number is even and one is odd or if i < 7.24/2.81 * j 7.24/2.81 */ 7.24/2.81 public static int middle(int i, int j) { 7.24/2.81 while (i != j) { 7.24/2.81 i--; 7.24/2.81 j++; 7.24/2.81 } 7.24/2.81 return i; 7.24/2.81 } 7.24/2.81 } 7.24/2.81 7.24/2.81 7.24/2.81 7.24/2.81 ---------------------------------------- 7.24/2.81 7.24/2.81 (1) BareJBCToJBCProof (EQUIVALENT) 7.24/2.81 initialized classpath 7.24/2.81 ---------------------------------------- 7.24/2.81 7.24/2.81 (2) 7.24/2.81 Obligation: 7.24/2.81 need to prove termination of the following program: 7.24/2.81 package simple.middle; 7.24/2.81 7.24/2.81 public class Main { 7.24/2.81 7.24/2.81 /** 7.24/2.81 * @param args 7.24/2.81 */ 7.24/2.81 public static void main(String[] args) { 7.24/2.81 Middle.middle(args[0].length(), args[1].length()); 7.24/2.81 } 7.24/2.81 7.24/2.81 } 7.24/2.81 7.24/2.81 7.24/2.81 package simple.middle; 7.24/2.81 7.24/2.81 public class Middle { 7.24/2.81 7.24/2.81 /* 7.24/2.81 * returns the number which is exactly between the first and the second 7.24/2.81 * input number, does not work if one number is even and one is odd or if i < 7.24/2.81 * j 7.24/2.81 */ 7.24/2.81 public static int middle(int i, int j) { 7.24/2.81 while (i != j) { 7.24/2.81 i--; 7.24/2.81 j++; 7.24/2.81 } 7.24/2.81 return i; 7.24/2.81 } 7.24/2.81 } 7.24/2.81 7.24/2.81 7.24/2.81 7.24/2.81 ---------------------------------------- 7.24/2.81 7.24/2.81 (3) JBCNonTerm (COMPLETE) 7.24/2.81 Reached a loop using the following run: 7.24/2.81 7.24/2.81 0: 7.24/2.81 o35!: String(count=1, hash=#, offset=0, value=o36?) -->{java.lang.Object...} 7.24/2.81 a18([java.lang.String...]): {o15, o35} -->{java.lang.Object...} 7.24/2.81 o15!: String(count=0, hash=#, offset=0, value=o16?) -->{java.lang.Object...} 7.24/2.81 o36:: [CHAR] -->{java.lang.Object...} 7.24/2.81 o16:: [CHAR] -->{java.lang.Object...} 7.24/2.81 a18-><-o36 7.24/2.81 a18-><-o35 7.24/2.81 a18-><-o16 7.24/2.81 a18-><-o15 7.24/2.81 YES: (JL1) 7.24/2.81 1: 7.24/2.81 o35!: String(count=1, hash=#, offset=0, value=o36?) -->{java.lang.Object...} 7.24/2.81 a18([java.lang.String...]): {o15, o35} -->{java.lang.Object...} 7.24/2.81 o15!: String(count=0, hash=#, offset=0, value=o16?) -->{java.lang.Object...} 7.24/2.81 o36:: [CHAR] -->{java.lang.Object...} 7.24/2.81 o16:: [CHAR] -->{java.lang.Object...} 7.24/2.81 a18-><-o36 7.24/2.81 a18-><-o35 7.24/2.81 a18-><-o16 7.24/2.81 a18-><-o15 7.24/2.81 YES: (JL1) 7.24/2.81 2: 7.24/2.81 o35!: String(count=1, hash=#, offset=0, value=o36?) -->{java.lang.Object...} 7.24/2.81 a18([java.lang.String...]): {o15, o35} -->{java.lang.Object...} 7.24/2.81 o15!: String(count=0, hash=#, offset=0, value=o16?) -->{java.lang.Object...} 7.24/2.81 o36:: [CHAR] -->{java.lang.Object...} 7.24/2.81 o16:: [CHAR] -->{java.lang.Object...} 7.24/2.81 a18-><-o36 7.24/2.81 a18-><-o35 7.24/2.81 a18-><-o16 7.24/2.81 a18-><-o15 7.24/2.81 YES: (JL1) 7.24/2.81 3: 7.24/2.81 o35!: String(count=1, hash=#, offset=0, value=o36?) -->{java.lang.Object...} 7.24/2.81 a18([java.lang.String...]): {o15, o35} -->{java.lang.Object...} 7.24/2.81 o15!: String(count=0, hash=#, offset=0, value=o16?) -->{java.lang.Object...} 7.24/2.81 o36:: [CHAR] -->{java.lang.Object...} 7.24/2.81 o16:: [CHAR] -->{java.lang.Object...} 7.24/2.81 a18-><-o36 7.24/2.81 a18-><-o35 7.24/2.81 a18-><-o16 7.24/2.81 a18-><-o15 7.24/2.81 YES: (JL1) 7.24/2.81 4: 7.24/2.81 7.24/2.81 o35!: String(count=1, hash=#, offset=0, value=o36?) -->{java.lang.Object...} 7.24/2.81 a18([java.lang.String...]): {o15, o35} -->{java.lang.Object...} 7.24/2.81 o15!: String(count=0, hash=#, offset=0, value=o16?) -->{java.lang.Object...} 7.24/2.81 o36:: [CHAR] -->{java.lang.Object...} 7.24/2.81 o16:: [CHAR] -->{java.lang.Object...} 7.24/2.81 a18-><-o36 7.24/2.81 a18-><-o35 7.24/2.81 a18-><-o16 7.24/2.81 a18-><-o15 7.24/2.81 YES: (JL1) 7.24/2.81 5: 7.24/2.81 7.24/2.81 o35!: String(count=1, hash=#, offset=0, value=o36?) -->{java.lang.Object...} 7.24/2.81 a18([java.lang.String...]): {o15, o35} -->{java.lang.Object...} 7.24/2.81 o15!: String(count=0, hash=#, offset=0, value=o16?) -->{java.lang.Object...} 7.24/2.81 o36:: [CHAR] -->{java.lang.Object...} 7.24/2.81 o16:: [CHAR] -->{java.lang.Object...} 7.24/2.81 a18-><-o36 7.24/2.81 a18-><-o35 7.24/2.81 a18-><-o16 7.24/2.81 a18-><-o15 7.24/2.81 YES: (JL1) 7.24/2.81 6: 7.24/2.81 7.24/2.81 o35!: String(count=1, hash=#, offset=0, value=o36?) -->{java.lang.Object...} 7.24/2.81 a18([java.lang.String...]): {o15, o35} -->{java.lang.Object...} 7.24/2.81 o15!: String(count=0, hash=#, offset=0, value=o16?) -->{java.lang.Object...} 7.24/2.81 o36:: [CHAR] -->{java.lang.Object...} 7.24/2.81 o16:: [CHAR] -->{java.lang.Object...} 7.24/2.81 a18-><-o36 7.24/2.81 a18-><-o35 7.24/2.81 a18-><-o16 7.24/2.81 a18-><-o15 7.24/2.81 YES: (JL1) 7.24/2.81 7: 7.24/2.81 o35!: String(count=1, hash=#, offset=0, value=o36?) -->{java.lang.Object...} 7.24/2.81 a18([java.lang.String...]): {o15, o35} -->{java.lang.Object...} 7.24/2.81 o15!: String(count=0, hash=#, offset=0, value=o16?) -->{java.lang.Object...} 7.24/2.81 o36:: [CHAR] -->{java.lang.Object...} 7.24/2.81 o16:: [CHAR] -->{java.lang.Object...} 7.24/2.81 a18-><-o36 7.24/2.81 a18-><-o35 7.24/2.81 a18-><-o16 7.24/2.81 a18-><-o15 7.24/2.81 YES: (JL1) 7.24/2.81 8: 7.24/2.81 o35!: String(count=1, hash=#, offset=0, value=o36?) -->{java.lang.Object...} 7.24/2.81 a18([java.lang.String...]): {o15, o35} -->{java.lang.Object...} 7.24/2.81 o15!: String(count=0, hash=#, offset=0, value=o16?) -->{java.lang.Object...} 7.24/2.81 o36:: [CHAR] -->{java.lang.Object...} 7.24/2.81 o16:: [CHAR] -->{java.lang.Object...} 7.24/2.81 a18-><-o36 7.24/2.81 a18-><-o35 7.24/2.81 a18-><-o16 7.24/2.81 a18-><-o15 7.24/2.81 YES: (JL1) 7.24/2.81 9: 7.24/2.81 o35!: String(count=1, hash=#, offset=0, value=o36?) -->{java.lang.Object...} 7.24/2.81 a18([java.lang.String...]): {o15, o35} -->{java.lang.Object...} 7.24/2.81 o15!: String(count=0, hash=#, offset=0, value=o16?) -->{java.lang.Object...} 7.24/2.81 o36:: [CHAR] -->{java.lang.Object...} 7.24/2.81 o16:: [CHAR] -->{java.lang.Object...} 7.24/2.81 a18-><-o36 7.24/2.81 a18-><-o35 7.24/2.81 a18-><-o16 7.24/2.81 a18-><-o15 7.24/2.81 YES: (JL1) 7.24/2.81 10: 7.24/2.81 o35!: String(count=1, hash=#, offset=0, value=o36?) -->{java.lang.Object...} 7.24/2.81 o36:: [CHAR] -->{java.lang.Object...} 7.24/2.81 YES: (JL1) 7.24/2.81 11: 7.24/2.81 7.24/2.81 o35!: String(count=1, hash=#, offset=0, value=o36?) -->{java.lang.Object...} 7.24/2.81 o36:: [CHAR] -->{java.lang.Object...} 7.24/2.81 YES: (JL1) 7.24/2.81 12: 7.24/2.81 7.24/2.81 o35!: String(count=1, hash=#, offset=0, value=o36?) -->{java.lang.Object...} 7.24/2.81 o36:: [CHAR] -->{java.lang.Object...} 7.24/2.81 YES: (JL1) 7.24/2.81 13: 7.24/2.81 7.24/2.81 YES: (JL1) 7.24/2.81 14: 7.24/2.81 YES: (JL1) 7.24/2.81 15: 7.24/2.81 7.24/2.81 YES: (JL1) 7.24/2.81 Start state of loop: 7.24/2.81 7.24/2.81 7.24/2.81 [a7(lv_0_0)] 7.24/2.81 7.24/2.81 i59: # 7.24/2.81 i60: [0,+inf)(l3) 7.24/2.81 i15: [2,+inf){0,+inf} 7.24/2.81 a7([java.lang.String...]): length i15 -->{java.lang.Object...} 7.24/2.81 YES: (JL1) 7.24/2.81 7.24/2.81 7.24/2.81 In the loop head node, references [i59, i60] were interesting. 7.24/2.81 7.24/2.81 All methods calls in the loop body are side-effect free, hence they can be ignored. 7.24/2.81 7.24/2.81 By SMT, we could prove 7.24/2.81 7.24/2.81 ((0 <= initial_i60 and 2 <= initial_i15) and ((((path1_i65 = (path1_i59 + -1) and path1_i66 = (path1_i60 + 1) and path1_i65 = res_i59 and path1_i66 = res_i60 and path1_i59 = initial_i59 and path1_i60 = initial_i60) and (path1_i59 != path1_i60 and path1_i59 < path1_i60)) or ((path1_i65 = (path1_i59 + -1) and path1_i66 = (path1_i60 + 1) and path1_i65 = res_i59 and path1_i66 = res_i60 and path1_i59 = initial_i59 and path1_i60 = initial_i60) and (path1_i59 != path1_i60 and path1_i59 < path1_i60))) and (((res1_i65 = (res1_i59 + -1) and res1_i66 = (res1_i60 + 1) and res_i59 = res1_i59 and res_i60 = res1_i60) and !(res1_i59 != res1_i60 and res1_i59 < res1_i60)) and ((res1_i65 = (res1_i59 + -1) and res1_i66 = (res1_i60 + 1) and res_i59 = res1_i59 and res_i60 = res1_i60) and !(res1_i59 != res1_i60 and res1_i59 < res1_i60))))) 7.24/2.81 7.24/2.81 to be UNSAT. Consequently, the loop will not terminate. 7.24/2.81 ---------------------------------------- 7.24/2.81 7.24/2.81 (4) 7.24/2.81 NO 7.24/2.86 EOF