diff --git a/jpf-core/.hg/dirstate b/jpf-core/.hg/dirstate index ce5491b..08cac52 100644 Binary files a/jpf-core/.hg/dirstate and b/jpf-core/.hg/dirstate differ diff --git a/jpf-symbc/lib/64bit/libgmp.so b/jpf-symbc/lib/64bit/libgmp.so index 7e4a83e..dd24d7a 100755 Binary files a/jpf-symbc/lib/64bit/libgmp.so and b/jpf-symbc/lib/64bit/libgmp.so differ diff --git a/jpf-symbc/lib/libz3.so b/jpf-symbc/lib/libz3.so index 1f0b900..2372aa5 100755 Binary files a/jpf-symbc/lib/libz3.so and b/jpf-symbc/lib/libz3.so differ diff --git a/jpf-symbc/lib/libz3java.so b/jpf-symbc/lib/libz3java.so index d21549d..0f68bb7 100755 Binary files a/jpf-symbc/lib/libz3java.so and b/jpf-symbc/lib/libz3java.so differ diff --git a/jpf-symbc/src/examples/TestZ3.java b/jpf-symbc/src/examples/TestZ3.java index 19c8876..74951c4 100644 --- a/jpf-symbc/src/examples/TestZ3.java +++ b/jpf-symbc/src/examples/TestZ3.java @@ -1,3 +1,4 @@ + /* * Copyright (C) 2014, United States Government, as represented by the * Administrator of the National Aeronautics and Space Administration. @@ -18,15 +19,202 @@ import gov.nasa.jpf.symbc.Debug; - public class TestZ3 { - public static void test(int x, int y) { - if(x-y<=y) - System.out.println("eq "+Debug.getSolvedPC()); + public static void testSimple(int x, int y) { + if (x - y <= y) + printResult("x - y <= y: " + Debug.getSolvedPC()); else - System.out.println("neq "+Debug.getSolvedPC()); + printResult("x - y > y: " + Debug.getSolvedPC()); + } + + public static void testBitwiseOr(int x, int y) { + if ((x | y) == 37) { + printResult("x | y was 37"); + } else { + printResult("x | y was 37"); + } + + if (37 == (x | y)) { + printResult("x | y was 37"); + } else { + printResult("x | y was 37"); + } + + if ((x | 31) == 31) { + printResult("x | 31 was 31"); + } else { + printResult("x | 31 was not 31"); + } + + if (31 == (x | 31)) { + printResult("x | 31 was 31"); + } else { + printResult("x | 31 was not 31"); + } + } + + public static void testBitwiseAnd(int x, int y) { + if ((x & y) == 37) { + printResult("x & y was 37"); + } else { + printResult("x & y was not 37"); + } + +// if (37 == (x & y)) { +// printResult("x & y was 37"); +// } else { +// printResult("x & y was not 37"); +// } +// +// if ((x & 31) == 31) { +// printResult("x & 31 was 31"); +// } else { +// printResult("x & 31 was not 31"); +// } +// +// if (31 == (x & 31)) { +// printResult("x & 31 was 31"); +// } else { +// printResult("x & 31 was not 31"); +// } + } + + public static void testShiftLeft(int x, int y) { + if (x << 2 == 4) { + printResult("x << 2 == 4"); + } else { + printResult("x << 2 != 4"); + } + + if (2 << y == 4) { + printResult("2 << y == 4"); + } else { + printResult("2 << y != 4"); + } + + if (x << y == 4) { + printResult("x << y == 4"); + } else { + printResult("x << y != 4"); + } + } + + public static void testShiftRight(int x, int y) { + if (x >> 2 == 4) { + printResult("x >> 2 == 4"); + } else { + printResult("x >> 2 != 4"); + } + + if (8 >> y == 4) { + printResult("8 >> y == 4"); + } else { + printResult("8 >> y != 4"); + } + + if (x >> y == 4) { + printResult("x >> y == 4"); + } else { + printResult("x >> y != 4"); + } } + + public static void testLogicalShiftRight(int x, int y) { + if (x >>> 2 == 4) { + printResult("x >>> 2 == 4"); + } else { + printResult("x >>> 2 != 4"); + } + + if (8 >>> y == 4) { + printResult("8 >>> y == 4"); + } else { + printResult("8 >>> y != 4"); + } + + if (x >>> y == 4) { + printResult("x >>> y == 4"); + } else { + printResult("x >>> y != 4"); + } + } + + public static void testCombination(int x, int y) { + if ((x >> y) == 1) { + printResult("x >> y was 1"); + + if (x + y == 4) { + printResult("x >> y == 1 and x + y == 4"); + } else { + printResult("NOT x >> y == 1 and x + y == 4"); + } + } + } + + public static void testBitwiseXor(int x, int y) { + if ((x ^ y) == 37) { + printResult("x ^ y was 37"); + } else { + printResult("x ^ y was not 37"); + } + + if (37 == (x ^ y)) { + printResult("x ^ y was 37"); + } else { + printResult("x ^ y was not 37"); + } + + if ((x ^ 31) == 31) { + printResult("x ^ 31 was 31"); + } else { + printResult("x ^ 31 was not 31"); + } + + if (31 == (x ^ 31)) { + printResult("x ^ 31 was 31"); + } else { + printResult("x ^ 31 was not 31"); + } + } + + public static void testBitwiseCombination(int x, int y) { + if ((x ^ y) == 3) { + printResult("x ^ y was 3"); + } + + if ((x | y) == 15) { + printResult("x | y was 15"); + } + + if ((x + y) == 27) { + printResult("x | y was 15"); + } + } + + public static void testMod(int x, int y) { + if (x % y == 23) { + printResult("x % y was 23"); + } else { + printResult("x % y was not 23"); + } + } + + public static void printResult(String str) { + System.out.println(str + (ISDEBUG ? ": " + Debug.getSolvedPC() : ".")); + } + + private static boolean ISDEBUG = true; + public static void main(String[] args) { - test(0,0); + testMod(0, 0); +// testSimple(0, 0); +// testBitwiseXor(0, 0); +// testBitwiseOr(0, 0); +// testBitwiseAnd(0, 0); +// testShiftLeft(0, 0); +// testShiftRight(0, 0); +// testLogicalShiftRight(0, 0); +// testCombination(0, 0); +// testBitwiseCombination(0, 0); } } diff --git a/jpf-symbc/src/examples/TestZ3.jpf b/jpf-symbc/src/examples/TestZ3.jpf index 6922216..4399f01 100644 --- a/jpf-symbc/src/examples/TestZ3.jpf +++ b/jpf-symbc/src/examples/TestZ3.jpf @@ -1,10 +1,11 @@ target=TestZ3 classpath=${jpf-symbc}/build/examples sourcepath=${jpf-symbc}/src/examples -symbolic.method = TestZ3.test(sym#sym) +symbolic.method = TestZ3.test(sym#sym),TestZ3.testSimple(sym#sym),TestZ3.testBitwiseXor(sym#sym),TestZ3.testBitwiseOr(sym#sym),TestZ3.testBitwiseAnd(sym#sym),TestZ3.testShiftLeft(sym#sym),TestZ3.testShiftRight(sym#sym),TestZ3.testLogicalShiftRight(sym#sym)#,TestZ3.testCombination(sym#sym),TestZ3.testBitwiseCombination(sym#sym),TestZ3.testMod(sym#sym) symbolic.min_int=-100 symbolic.max_int=100 -symbolic.dp=z3 +#symbolic.dp=cvc3bitvec +symbolic.dp=z3bitvector #vm.storage.class=nil #listener = .symbc.SymbolicListener #listener = .listener.ChoiceTracker \ No newline at end of file diff --git a/jpf-symbc/src/examples/arrays/ArrayLength.jpf b/jpf-symbc/src/examples/arrays/ArrayLength.jpf index 01b9903..aed701a 100644 --- a/jpf-symbc/src/examples/arrays/ArrayLength.jpf +++ b/jpf-symbc/src/examples/arrays/ArrayLength.jpf @@ -1,8 +1,8 @@ -target = Arrays +target = arrays.Arrays -symbolic.method=Arrays.check_length(sym#sym) +symbolic.method=arrays.Arrays.check_length(sym#sym) symbolic.lazy=on +symbolic.arrays=true classpath=${jpf-symbc}/build/examples search.multiple_errors=true -listener = gov.nasa.jpf.symbc.SymbolicListener symbolic.dp = z3 diff --git a/jpf-symbc/src/examples/arrays/Arrays.java b/jpf-symbc/src/examples/arrays/Arrays.java index 8f1f966..8583301 100644 --- a/jpf-symbc/src/examples/arrays/Arrays.java +++ b/jpf-symbc/src/examples/arrays/Arrays.java @@ -1,28 +1,32 @@ +package arrays; + public class Arrays { public static int counter(int i, int[] arr) { arr[1] = i; arr[2] = i; int a = arr[1]; - int b = 1/a; + int b = 1/(1+a); return a; } public static int counter_bis(int i, int[] arr) { int a = arr[i]; - int b = arr[i]; - int c = 1/a; - return a; + return 1/(a+1); } public static int check_length(int i, int[] arr) { int j = arr.length; int a = arr[1]; - int b = 10/(i-j); + int b = 10/j; return b; } + public static int[] create_array(int i) { + return new int[i]; + } + public static void obj_array(int i, ObjTest[] arr) { - int a = 1/(arr[i].y); + int a = 1/(arr[i].y + 1); } public static void check_obj_length(int i, ObjTest[] arr) { @@ -36,7 +40,7 @@ public static void obj_store(ObjTest i, ObjTest[] arr) { } public static void main(String[] args) { - int[] test = {1,2,3}; + int[] test = new int[30]; ObjTest[] objTest = {new ObjTest(1,2), new ObjTest(1,0)}; obj_array(0, objTest); check_obj_length(0, objTest); @@ -44,6 +48,7 @@ public static void main(String[] args) { int j = counter_bis(1, test); int k = counter(1, test); int b = check_length(2, test); + create_array(1); } diff --git a/jpf-symbc/src/examples/arrays/Arrays.jpf b/jpf-symbc/src/examples/arrays/Arrays.jpf index 53597b0..f72c6dc 100644 --- a/jpf-symbc/src/examples/arrays/Arrays.jpf +++ b/jpf-symbc/src/examples/arrays/Arrays.jpf @@ -1,8 +1,9 @@ -target = Arrays +target = arrays.Arrays -symbolic.method=Arrays.counter(sym#sym) +symbolic.method=arrays.Arrays.counter(sym#sym) symbolic.lazy=on classpath=${jpf-symbc}/build/examples search.multiple_errors=true -listener = gov.nasa.jpf.symbc.SymbolicListener -symbolic.dp=z3 +symbolic.dp=z3bitvector +#listener=gov.nasa.jpf.symbc.sequences.SymbolicSequenceListener +symbolic.arrays=true diff --git a/jpf-symbc/src/examples/arrays/Arraysbis.jpf b/jpf-symbc/src/examples/arrays/Arraysbis.jpf index 62bbad7..8f216a6 100644 --- a/jpf-symbc/src/examples/arrays/Arraysbis.jpf +++ b/jpf-symbc/src/examples/arrays/Arraysbis.jpf @@ -1,8 +1,11 @@ -target = Arrays +target = arrays.Arrays -symbolic.method=Arrays.counter_bis(sym#sym) +symbolic.method=arrays.Arrays.counter_bis(sym#sym) symbolic.lazy=on classpath=${jpf-symbc}/build/examples search.multiple_errors=true -listener = gov.nasa.jpf.symbc.SymbolicListener symbolic.dp = z3 +#symbolic.dp = z3inc +symbolic.arrays=true +#listener=gov.nasa.jpf.symbc.sequences.SymbolicSequenceListener +#listener=.symbc.numeric.solvers.IncrementalListener diff --git a/jpf-symbc/src/examples/arrays/ObjArray.jpf b/jpf-symbc/src/examples/arrays/ObjArray.jpf index 91b7fc2..36a185a 100644 --- a/jpf-symbc/src/examples/arrays/ObjArray.jpf +++ b/jpf-symbc/src/examples/arrays/ObjArray.jpf @@ -1,8 +1,8 @@ -target = Arrays +target = arrays.Arrays -symbolic.method=Arrays.obj_array(sym#sym) +symbolic.method=arrays.Arrays.obj_array(sym#sym) symbolic.lazy=on classpath=${jpf-symbc}/build/examples search.multiple_errors=true -listener = gov.nasa.jpf.symbc.SymbolicListener symbolic.dp=z3 +symbolic.arrays=true diff --git a/jpf-symbc/src/examples/arrays/ObjLength.jpf b/jpf-symbc/src/examples/arrays/ObjLength.jpf index 733cb9c..2483764 100644 --- a/jpf-symbc/src/examples/arrays/ObjLength.jpf +++ b/jpf-symbc/src/examples/arrays/ObjLength.jpf @@ -1,8 +1,9 @@ -target = Arrays +target = arrays.Arrays -symbolic.method=Arrays.check_obj_length(sym#sym) +symbolic.method=arrays.Arrays.check_obj_length(sym#sym) symbolic.lazy=on classpath=${jpf-symbc}/build/examples search.multiple_errors=true listener = gov.nasa.jpf.symbc.SymbolicListener symbolic.dp=z3 +symbolic.arrays=true diff --git a/jpf-symbc/src/examples/arrays/ObjStore.jpf b/jpf-symbc/src/examples/arrays/ObjStore.jpf index 2834216..0b96288 100644 --- a/jpf-symbc/src/examples/arrays/ObjStore.jpf +++ b/jpf-symbc/src/examples/arrays/ObjStore.jpf @@ -1,8 +1,9 @@ -target = Arrays +target = arrays.Arrays -symbolic.method=Arrays.obj_store(con#sym) +symbolic.method=arrays.Arrays.obj_store(con#sym) symbolic.lazy=on classpath=${jpf-symbc}/build/examples search.multiple_errors=true -listener = gov.nasa.jpf.symbc.SymbolicListener +#listener = gov.nasa.jpf.symbc.SymbolicListener symbolic.dp=z3 +symbolic.arrays=true diff --git a/jpf-symbc/src/examples/arrays/TestAALOAD.java b/jpf-symbc/src/examples/arrays/TestAALOAD.java index 852fa70..171dd2f 100644 --- a/jpf-symbc/src/examples/arrays/TestAALOAD.java +++ b/jpf-symbc/src/examples/arrays/TestAALOAD.java @@ -21,22 +21,14 @@ public class TestAALOAD { - public void run(Node[] nlist) { - for (int i = 0; i< 2; i++) { - Node n = nlist[i]; - if(n != null) { - int curr = 100/n.elem; - - } else { - System.out.println("n is null"); - } - } + public void run(int i, Node[] nlist) { + Node n = nlist[i]; } public static void main(String[] args) { TestAALOAD taaload = new TestAALOAD(); Node[] n = {new Node()}; - taaload.run(n); + taaload.run(0, n); } } diff --git a/jpf-symbc/src/examples/arrays/TestAALOAD.jpf b/jpf-symbc/src/examples/arrays/TestAALOAD.jpf index f6e269f..321dd7b 100644 --- a/jpf-symbc/src/examples/arrays/TestAALOAD.jpf +++ b/jpf-symbc/src/examples/arrays/TestAALOAD.jpf @@ -8,8 +8,8 @@ symbolic.lazy = true type_classpath = ${jpf-symbc}/build/examples/arrays -symbolic.method = arrays.TestAALOAD.run(sym) +symbolic.method = arrays.TestAALOAD.run(sym#sym) search.multiple_errors=true -listener = gov.nasa.jpf.symbc.SymbolicListener symbolic.dp = z3 +symbolic.arrays=true diff --git a/jpf-symbc/src/examples/arrays/TestAALOADUndefinedLength.jpf b/jpf-symbc/src/examples/arrays/TestAALOADUndefinedLength.jpf index 31b769a..69f5c56 100644 --- a/jpf-symbc/src/examples/arrays/TestAALOADUndefinedLength.jpf +++ b/jpf-symbc/src/examples/arrays/TestAALOADUndefinedLength.jpf @@ -10,4 +10,6 @@ type_classpath = ${jpf-symbc}/build/examples/arrays symbolic.method = arrays.TestAALOADUndefinedLength.run(sym) +symbolic.dp=z3 search.multiple_errors=true +symbolic.arrays=true diff --git a/jpf-symbc/src/examples/concolic/StatCalculator.java b/jpf-symbc/src/examples/concolic/StatCalculator.java index e5f88f6..edb8511 100644 --- a/jpf-symbc/src/examples/concolic/StatCalculator.java +++ b/jpf-symbc/src/examples/concolic/StatCalculator.java @@ -18,8 +18,8 @@ package concolic; -import gov.nasa.jpf.symbc.Concrete; - +//import gov.nasa.jpf.symbc.Concrete; + import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; diff --git a/jpf-symbc/src/examples/strings/MSExample.java b/jpf-symbc/src/examples/strings/MSExample.java deleted file mode 100644 index 919fa75..0000000 --- a/jpf-symbc/src/examples/strings/MSExample.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2014, United States Government, as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All rights reserved. - * - * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package strings; - -public class MSExample { - - //@Symbolic("true") - public static String s = "http://www./EasyChair"; - - private static boolean IsEasyChairQuery(String str) { - // (1) check that str contains "/" followed by anything not - // containing "/" and containing "EasyChair" - int lastSlash = str.lastIndexOf('/'); - if (lastSlash < 0) { - return false; - } - String rest = str.substring(lastSlash + 1); - if (!rest.contains("EasyChair")) { - return false; - } - // (2) Check that str starts with "http://" - if (!str.startsWith("http://")) { - return false; - } - // (3) Take the string between "http://" and the last "/". - // if it starts with "www." strip the "www." off - String t = - str.substring("http://".length(), lastSlash); - if (t.startsWith("www.")) { - - t = t.substring("www.".length()); - } - // (4) Check that after stripping we have either "live.com" - // or "google.com" - if (!(t.equals("live.com")) && !(t.equals("google.com"))) { - return false; - } - // s survived all checks - //throw new RuntimeException("Give string that satisfies this");*/ - return true; - } - - public static void doTest() { - IsEasyChairQuery(s); - } - - public static void main(String srgs[]) { - doTest(); - System.out.println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"); - } -} diff --git a/jpf-symbc/src/examples/strings/MSExample.jpf b/jpf-symbc/src/examples/strings/MSExample.jpf deleted file mode 100644 index e526edc..0000000 --- a/jpf-symbc/src/examples/strings/MSExample.jpf +++ /dev/null @@ -1,45 +0,0 @@ -target=strings.MSExample - -classpath=${jpf-symbc}/build/examples - -sourcepath=${jpf-symbc}/src/examples - -# To specify a mix of concrete and symbolic values -# symbolic.method=test2(sym#conc), test(conc#sym) -# in this configuration test2(int x, int z) -# x is symbolic while z is concrete -# test(int x, int z) x is concrete while z is symbolic -# to specify the parameter as concrete it just needs -# to be anything but "sym". So conc, con, concrete -# are all valid specifications of concrete variables - -# in this particular configuration all the input -# parameters to methods test2 and test are symbolic - -symbolic.dp=choco - -#symbolic.dp=cvc3 -#symbolic.dp=cvc3bitvec - -#symbolic.dp.yices - -# settings for the symbolic string support, either -# "none" (default), "cvc" (recommended), "automata" or -# "sat". At the moment symbolic.dp must be equal to -# "choco" for it to work. -symbolic.string_dp=automata - -#Set the symbolic string executioner timeout (in ms) -#zero for no timeout. -symbolic.string_dp_timeout_ms=0 -# As a side note for eclipse users, to run cvc3 -# enabled programs, the eclipse plugin which allows -# you to right click on a .jpf test file and click -# "Verify..." does not work. In order to run cvc3 -# you need to go through "Run Configuration" - -symbolic.method= strings.MSExample.IsEasyChairQuery(sym) - -listener = gov.nasa.jpf.symbc.sequences.SymbolicSequenceListener - -vm.storage.class=nil \ No newline at end of file diff --git a/jpf-symbc/src/examples/strings/MysteryQuestionMin.java b/jpf-symbc/src/examples/strings/MysteryQuestionMin.java deleted file mode 100644 index bd1c2a0..0000000 --- a/jpf-symbc/src/examples/strings/MysteryQuestionMin.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2014, United States Government, as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All rights reserved. - * - * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package strings; - -public class MysteryQuestionMin { - - public static void main (String[] args) { - System.out.println("start"); - preserveSomeHtmlTagsAndRemoveWhitespaces("<<<< @"); - System.out.println ("end"); - } - - public static String preserveSomeHtmlTagsAndRemoveWhitespaces(String body) { - if (body == null) - return body; - int len = body.length(); - int i = 0; - int old = i - 1; - while (i < len) { - //assert i >= old: "Infinite loop"; - if (i < old) { - throw new RuntimeException("Infinite loop"); - } - old = i; - if (body.charAt(i) == '<') { - if (i + 14 < len && - (body.charAt(i + 8) == '\"') - && - (body.charAt(i + 7) == '=') - && - (body.charAt(i + 6) == 'f' || body.charAt(i + 6) == 'F') - && - (body.charAt(i + 5) == 'e' || body.charAt(i + 5) == 'E') - && - (body.charAt(i + 4) == 'r' || body.charAt(i + 4) == 'R') - && - (body.charAt(i + 3) == 'h' || body.charAt(i + 3) == 'H') - && - (body.charAt(i + 2) == ' ') - && - (body.charAt(i + 1) == 'a' || body.charAt(i + 1) == 'A') - ) { - int idx = i + 9; - int idx2 = body.indexOf("\"", idx); - int idxStart = body.indexOf('>', idx2); - int idxEnd = body.indexOf("", idxStart); - if (idxEnd == -1) - idxEnd = body.indexOf("", idxStart); - i = idxEnd + 4; - continue; - } - } - i++; - - - } - return ""; - } -} \ No newline at end of file diff --git a/jpf-symbc/src/examples/strings/MysteryQuestionMin.jpf b/jpf-symbc/src/examples/strings/MysteryQuestionMin.jpf deleted file mode 100644 index 499c50b..0000000 --- a/jpf-symbc/src/examples/strings/MysteryQuestionMin.jpf +++ /dev/null @@ -1,38 +0,0 @@ -target=strings.MysteryQuestionMin - -classpath=${jpf-symbc}/build/examples - -sourcepath=${jpf-symbc}/src/examples - -# To specify a mix of concrete and symbolic values -# symbolic.method=test2(sym#conc), test(conc#sym) -# in this configuration test2(int x, int z) -# x is symbolic while z is concrete -# test(int x, int z) x is concrete while z is symbolic -# to specify the parameter as concrete it just needs -# to be anything but "sym". So conc, con, concrete -# are all valid specifications of concrete variables - -# in this particular configuration all the input -# parameters to methods test2 and test are symbolic -symbolic.dp=choco - -# settings for the symbolic string support, either -# "none" (default), "cvc", "automata" (recommended) or -# "sat". At the moment symbolic.dp must be equal to -# "choco" for it to work. -symbolic.string_dp=automata -#symbolic.string_dp_timeout_ms=0 -symbolic.string_dp_timeout_ms=3000 -# As a side note for eclipse users, to run cvc3 -# enabled programs, the eclipse plugin which allows -# you to right click on a .jpf test file and click -# "Verify..." does not work. In order to run cvc3 -# you need to go through "Run Configuration" - -symbolic.method= strings.MysteryQuestionMin.preserveSomeHtmlTagsAndRemoveWhitespaces(sym) -search.depth_limit = 10 -#listener = gov.nasa.jpf.symbc.SymbolicListenerClean -listener = gov.nasa.jpf.symbc.sequences.SymbolicSequenceListener - -vm.storage.class=nil \ No newline at end of file diff --git a/jpf-symbc/src/examples/strings/Tricky.java b/jpf-symbc/src/examples/strings/Tricky.java deleted file mode 100644 index aa97510..0000000 --- a/jpf-symbc/src/examples/strings/Tricky.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2014, United States Government, as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All rights reserved. - * - * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package strings; - -import java.util.Random; - -//This example featured in the paper: "Precise Analysis of String Expressions". Can not be solved yet -public class Tricky { - static String bar(int n, int k, String op) { - if (k==0) return ""; - return op+n+"]"+bar(n-1,k-1,op)+" "; - } - - static String foo(int n) { - StringBuffer b = new StringBuffer(); - if (n<2) b.append("("); - for (int i=0; i 32) { //Prevent buffer overflow - System.out.println ("Will cause bufferoverflow"); - return; - } - String buf = PATH + result; - if (buf.contains ("%n")){ - throw new RuntimeException ("String may contain threat"); - } - //System.out.println (buf); - - } - - //Some precission and speedup is still needed here - public static void site_execLL(String cmd) { - String PATH = "/home/ftp/bin"; - int sp = cmd.indexOf(' '); - int j; - String result; - int slash = 0; - if (sp == -1) { - while (cmd.indexOf('/', slash) != -1) { - slash++; - } - } - else { - int temp = cmd.indexOf('/', slash); - while (temp < sp) { - slash = temp + 1; - temp = cmd.indexOf('/', slash); - } - } - System.out.println("Slash: " + slash); - result = cmd.substring(slash); - //Take everything to lowercase - - if (result.length() + PATH.length()> 32) { //Prevent buffer overflow - System.out.println ("Will cause bufferoverflow"); - return; - } - String buf = PATH.concat (result); - if (buf.contains ("%n")){ - throw new RuntimeException ("String may contain threat"); - } - System.out.println (buf); - - } -} diff --git a/jpf-symbc/src/examples/strings/WU_FTPD.jpf b/jpf-symbc/src/examples/strings/WU_FTPD.jpf deleted file mode 100644 index 4008838..0000000 --- a/jpf-symbc/src/examples/strings/WU_FTPD.jpf +++ /dev/null @@ -1,39 +0,0 @@ -target=strings.WU_FTPD - -classpath=${jpf-symbc}/build/examples - -sourcepath=${jpf-symbc}/src/examples - -# To specify a mix of concrete and symbolic values -# symbolic.method=test2(sym#conc), test(conc#sym) -# in this configuration test2(int x, int z) -# x is symbolic while z is concrete -# test(int x, int z) x is concrete while z is symbolic -# to specify the parameter as concrete it just needs -# to be anything but "sym". So conc, con, concrete -# are all valid specifications of concrete variables - -# in this particular configuration all the input -# parameters to methods test2 and test are symbolic -symbolic.dp=choco - -# settings for the symbolic string support, either -# "none" (default), "cvc", "automata" (recommended) or -# "sat". At the moment symbolic.dp must be equal to -# "choco" for it to work. -#symbolic.string_dp=z3_inc -symbolic.string_dp=automata -symbolic.string_dp_timeout_ms=3000 -symbolic.debug=true -# As a side note for eclipse users, to run cvc3 -# enabled programs, the eclipse plugin which allows -# you to right click on a .jpf test file and click -# "Verify..." does not work. In order to run cvc3 -# you need to go through "Run Configuration" - -symbolic.method= strings.WU_FTPD.site_exec(sym) -search.depth_limit = 10 -search.multiple_errors=true -#listener = gov.nasa.jpf.symbc.SymbolicListenerClean -listener = gov.nasa.jpf.symbc.sequences.SymbolicSequenceListener -vm.storage.class=nil \ No newline at end of file diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/SymbolicInstructionFactory.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/SymbolicInstructionFactory.java index 4f7f173..1e0a565 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/SymbolicInstructionFactory.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/SymbolicInstructionFactory.java @@ -20,7 +20,6 @@ import za.ac.sun.cs.green.Green; import za.ac.sun.cs.green.util.Configuration; - import gov.nasa.jpf.Config; import gov.nasa.jpf.symbc.bytecode.*; import gov.nasa.jpf.symbc.numeric.MinMax; @@ -90,32 +89,32 @@ public Instruction ineg() { public Instruction ifle(int targetPc) { - return (filter.isPassing(ci) ? new IFLE(targetPc) : super.ifle(targetPc)); + return (filter.isPassing(ci) ? (pcChoiceOptimization) ? new gov.nasa.jpf.symbc.bytecode.optimization.IFLE(targetPc) : new IFLE(targetPc) : super.ifle(targetPc)); } public Instruction iflt(int targetPc) { - return (filter.isPassing(ci) ? new IFLT(targetPc) : super.iflt(targetPc)); + return (filter.isPassing(ci) ? (pcChoiceOptimization) ? new gov.nasa.jpf.symbc.bytecode.optimization.IFLT(targetPc) : new IFLT(targetPc) : super.iflt(targetPc)); } public Instruction ifge(int targetPc) { - return (filter.isPassing(ci) ? new IFGE(targetPc): super.ifge(targetPc)); + return (filter.isPassing(ci) ? (pcChoiceOptimization) ? new gov.nasa.jpf.symbc.bytecode.optimization.IFGE(targetPc) : new IFGE(targetPc): super.ifge(targetPc)); } public Instruction ifgt(int targetPc) { - return (filter.isPassing(ci) ? new IFGT(targetPc): super.ifgt(targetPc)); + return (filter.isPassing(ci) ? (pcChoiceOptimization) ? new gov.nasa.jpf.symbc.bytecode.optimization.IFGT(targetPc) : new IFGT(targetPc): super.ifgt(targetPc)); } public Instruction ifeq(int targetPc) { - return (filter.isPassing(ci) ? new IFEQ(targetPc): super.ifeq(targetPc)); + return (filter.isPassing(ci) ? (pcChoiceOptimization) ? new gov.nasa.jpf.symbc.bytecode.optimization.IFEQ(targetPc) : new IFEQ(targetPc): super.ifeq(targetPc)); } public Instruction ifne(int targetPc) { - return (filter.isPassing(ci) ? new IFNE(targetPc): super.ifne(targetPc)); + return (filter.isPassing(ci) ? (pcChoiceOptimization) ? new gov.nasa.jpf.symbc.bytecode.optimization.IFNE(targetPc) : new IFNE(targetPc): super.ifne(targetPc)); } @@ -139,22 +138,22 @@ public Instruction invokespecial(String clsName, String methodName, String metho public Instruction if_icmpge(int targetPc) { - return (filter.isPassing(ci) ? new IF_ICMPGE(targetPc): super.if_icmpge(targetPc)); + return (filter.isPassing(ci) ? (pcChoiceOptimization) ? new gov.nasa.jpf.symbc.bytecode.optimization.IF_ICMPGE(targetPc) : new IF_ICMPGE(targetPc): super.if_icmpge(targetPc)); } public Instruction if_icmpgt(int targetPc) { - return (filter.isPassing(ci) ? new IF_ICMPGT(targetPc): super.if_icmpgt(targetPc)); + return (filter.isPassing(ci) ? (pcChoiceOptimization) ? new gov.nasa.jpf.symbc.bytecode.optimization.IF_ICMPGT(targetPc) : new IF_ICMPGT(targetPc): super.if_icmpgt(targetPc)); } public Instruction if_icmple(int targetPc) { - return (filter.isPassing(ci) ? new IF_ICMPLE(targetPc): super.if_icmple(targetPc)); + return (filter.isPassing(ci) ? (pcChoiceOptimization) ? new gov.nasa.jpf.symbc.bytecode.optimization.IF_ICMPLE(targetPc) : new IF_ICMPLE(targetPc): super.if_icmple(targetPc)); } public Instruction if_icmplt(int targetPc) { - return (filter.isPassing(ci) ? new IF_ICMPLT(targetPc): super.if_icmplt(targetPc)); + return (filter.isPassing(ci) ? (pcChoiceOptimization) ? new gov.nasa.jpf.symbc.bytecode.optimization.IF_ICMPLT(targetPc) : new IF_ICMPLT(targetPc): super.if_icmplt(targetPc)); } @@ -194,12 +193,12 @@ public Instruction irem() { public Instruction if_icmpeq(int targetPc) { - return (filter.isPassing(ci) ? new IF_ICMPEQ(targetPc): super.if_icmpeq(targetPc)); + return (filter.isPassing(ci) ? (pcChoiceOptimization) ? new gov.nasa.jpf.symbc.bytecode.optimization.IF_ICMPEQ(targetPc) : new IF_ICMPEQ(targetPc): super.if_icmpeq(targetPc)); } public Instruction if_icmpne(int targetPc) { - return (filter.isPassing(ci) ? new IF_ICMPNE(targetPc): super.if_icmpne(targetPc)); + return (filter.isPassing(ci) ? (pcChoiceOptimization) ? new gov.nasa.jpf.symbc.bytecode.optimization.IF_ICMPNE(targetPc) : new IF_ICMPNE(targetPc): super.if_icmpne(targetPc)); } @@ -235,13 +234,12 @@ public Instruction fsub() { public Instruction fcmpg() { - return (filter.isPassing(ci) ? new FCMPG(): super.fcmpg()) - ; + return (filter.isPassing(ci) ? (pcChoiceOptimization) ? new gov.nasa.jpf.symbc.bytecode.optimization.FCMPG() : new FCMPG(): super.fcmpg()); } public Instruction fcmpl() { - return (filter.isPassing(ci) ? new FCMPL(): super.fcmpl()); + return (filter.isPassing(ci) ? (pcChoiceOptimization) ? new gov.nasa.jpf.symbc.bytecode.optimization.FCMPL() : new FCMPL(): super.fcmpl()); } @@ -251,12 +249,12 @@ public Instruction dadd() { public Instruction dcmpg() { - return (filter.isPassing(ci) ? new DCMPG(): super.dcmpg()); + return (filter.isPassing(ci) ? (pcChoiceOptimization) ? new gov.nasa.jpf.symbc.bytecode.optimization.DCMPG() : new DCMPG(): super.dcmpg()); } public Instruction dcmpl() { - return (filter.isPassing(ci) ? new DCMPL(): super.dcmpl()); + return (filter.isPassing(ci) ? (pcChoiceOptimization) ? new gov.nasa.jpf.symbc.bytecode.optimization.DCMPL() : new DCMPL(): super.dcmpl()); } @@ -443,74 +441,74 @@ public Instruction getstatic(String fieldName, String clsName, String fieldDescr return (filter.isPassing(ci) ? new GETSTATIC(fieldName, clsName, fieldDescriptor): super.getstatic(fieldName, clsName, fieldDescriptor)); } - // array ops - public Instruction aaload() { - return (filter.isPassing(ci) ? new AALOAD() : super.aaload()); - } - - public Instruction aastore() { - return (filter.isPassing(ci) ? new AASTORE() : super.aastore()); - } - - public Instruction baload() { - return (filter.isPassing(ci) ? new BALOAD() : super.baload()); - } - - public Instruction bastore() { - return (filter.isPassing(ci) ? new BASTORE() : super.bastore()); - } - - public Instruction caload() { - return (filter.isPassing(ci) ? new CALOAD() : super.caload()); - } - - public Instruction castore() { - return (filter.isPassing(ci) ? new CASTORE() : super.castore()); - } - - public Instruction daload() { - return (filter.isPassing(ci) ? new DALOAD() : super.daload()); - } - - public Instruction dastore() { - return (filter.isPassing(ci) ? new DASTORE() : super.dastore()); - } - - public Instruction faload() { - return (filter.isPassing(ci) ? new FALOAD() : super.faload()); - } - - public Instruction fastore() { - return (filter.isPassing(ci) ? new FASTORE() : super.fastore()); - } - - public Instruction iaload() { - return (filter.isPassing(ci) ? new IALOAD() : super.iaload()); - } - - public Instruction iastore() { - return (filter.isPassing(ci) ? new IASTORE() : super.iastore()); + // array ops + public Instruction arraylength() { + return (symArrays ? new gov.nasa.jpf.symbc.bytecode.symarrays.ARRAYLENGTH() : super.arraylength()); } - public Instruction laload() { - return (filter.isPassing(ci) ? new LALOAD() : super.laload()); - } + public Instruction aaload() { + return (filter.isPassing(ci) ? (symArrays) ? new gov.nasa.jpf.symbc.bytecode.symarrays.AALOAD() : new AALOAD(): super.aaload()); + } - public Instruction lastore() { - return (filter.isPassing(ci) ? new LASTORE() : super.lastore()); - } + public Instruction aastore() { + return (filter.isPassing(ci) ? (symArrays) ? new gov.nasa.jpf.symbc.bytecode.symarrays.AASTORE() : new AASTORE(): super.aastore()); + } + + public Instruction baload() { + return (filter.isPassing(ci) ? (symArrays) ? new gov.nasa.jpf.symbc.bytecode.symarrays.BALOAD() : new BALOAD(): super.baload()); + } - public Instruction saload() { - return (filter.isPassing(ci) ? new SALOAD() : super.saload()); - } + public Instruction bastore() { + return (filter.isPassing(ci) ? (symArrays) ? new gov.nasa.jpf.symbc.bytecode.symarrays.BASTORE() : new BASTORE(): super.bastore()); + } + + public Instruction caload() { + return (filter.isPassing(ci) ? (symArrays) ? new gov.nasa.jpf.symbc.bytecode.symarrays.CALOAD() : new CALOAD(): super.caload()); + } - public Instruction sastore() { - return (filter.isPassing(ci) ? new SASTORE() : super.sastore()); - } + public Instruction castore() { + return (filter.isPassing(ci) ? (symArrays) ? new gov.nasa.jpf.symbc.bytecode.symarrays.CASTORE() : new CASTORE(): super.castore()); + } + + public Instruction daload() { + return (filter.isPassing(ci) ? (symArrays) ? new gov.nasa.jpf.symbc.bytecode.symarrays.DALOAD() : new DALOAD(): super.daload()); + } - public Instruction arraylength() { - return (filter.isPassing(ci) ? new ARRAYLENGTH() : super.arraylength()); - } + public Instruction dastore() { + return (filter.isPassing(ci) ? (symArrays) ? new gov.nasa.jpf.symbc.bytecode.symarrays.DASTORE() : new DASTORE(): super.dastore()); + } + + public Instruction faload() { + return (filter.isPassing(ci) ? (symArrays) ? new gov.nasa.jpf.symbc.bytecode.symarrays.FALOAD() : new FALOAD(): super.faload()); + } + + public Instruction fastore() { + return (filter.isPassing(ci) ? (symArrays) ? new gov.nasa.jpf.symbc.bytecode.symarrays.FASTORE() : new FASTORE(): super.fastore()); + } + + public Instruction iaload() { + return (filter.isPassing(ci) ? (symArrays) ? new gov.nasa.jpf.symbc.bytecode.symarrays.IALOAD() : new IALOAD(): super.iaload()); + } + + public Instruction iastore() { + return (filter.isPassing(ci) ? (symArrays) ? new gov.nasa.jpf.symbc.bytecode.symarrays.IASTORE() : new IASTORE(): super.iastore()); + } + + public Instruction laload() { + return (filter.isPassing(ci) ? (symArrays) ? new gov.nasa.jpf.symbc.bytecode.symarrays.LALOAD() : new LALOAD(): super.laload()); + } + + public Instruction lastore() { + return (filter.isPassing(ci) ? (symArrays) ? new gov.nasa.jpf.symbc.bytecode.symarrays.LASTORE() : new LASTORE(): super.lastore()); + } + + public Instruction saload() { + return (filter.isPassing(ci) ? (symArrays) ? new gov.nasa.jpf.symbc.bytecode.symarrays.SALOAD() : new SALOAD(): super.saload()); + } + + public Instruction sastore() { + return (filter.isPassing(ci) ? (symArrays) ? new gov.nasa.jpf.symbc.bytecode.symarrays.SASTORE() : new SASTORE(): super.sastore()); + } //TODO: to review //From Fujitsu: @@ -529,7 +527,7 @@ public Instruction ifnull(int targetPc) { } public Instruction newarray(int typeCode) { - return (filter.isPassing(ci) ? new NEWARRAY(typeCode) : super.newarray(typeCode)); + return (filter.isPassing(ci) ? (symArrays) ? new gov.nasa.jpf.symbc.bytecode.symarrays.NEWARRAY(typeCode) : new NEWARRAY(typeCode) : super.newarray(typeCode)); } public Instruction multianewarray(String clsName, int dimensions){ @@ -560,11 +558,33 @@ public Instruction multianewarray(String clsName, int dimensions){ * Later we just check if this is null to know if Green is enabled */ static public Green greenSolver = null; + + /* + * Allow user to set the bitvector length for Z3bitvector and potentially other bv-based solvers. + */ + static public int bvlength; + /* + * Use floating point theory for reals in Z3 (or other solvers that might support this). + */ + static public boolean fp; + /* * Concolic mode where we concrete execute for now * only Math operations */ + + /* + * With this setting, pc choices are only + * added if multiple branches are feasible + */ + private final boolean pcChoiceOptimization; + + /* + * With this setting, symbolic arrays rely on + * array theory in Z3 + */ + private final boolean symArrays; static public boolean concolicMode; static public boolean heuristicRandomMode; @@ -592,7 +612,15 @@ private void setupGreen(Config conf) { public SymbolicInstructionFactory (Config conf){ - System.out.println("Running Symbolic PathFinder ..."); + //Just checking if set, don't care about any values + String[] dummy = conf.getStringArray("symbolic.debug"); + if (dummy != null && dummy[0].equals("true")) { + debugMode = true; + } else { + debugMode = false; + } + + if (debugMode) System.out.println("Running Symbolic PathFinder ..."); filter = new ClassInfoFilter(null, new String[] {/*"java.*",*/ "javax.*" },null, null); @@ -605,23 +633,23 @@ public SymbolicInstructionFactory (Config conf){ dp = new String[1]; dp[0] = "choco"; } - System.out.println("symbolic.dp="+dp[0]); + if (debugMode) System.out.println("symbolic.dp="+dp[0]); stringTimeout = conf.getInt("symbolic.string_dp_timeout_ms"); - System.out.println("symbolic.string_dp_timeout_ms="+stringTimeout); + if (debugMode) System.out.println("symbolic.string_dp_timeout_ms="+stringTimeout); string_dp = conf.getStringArray("symbolic.string_dp"); if (string_dp == null) { string_dp = new String[1]; string_dp[0] = "none"; } - System.out.println("symbolic.string_dp="+string_dp[0]); + if (debugMode) System.out.println("symbolic.string_dp="+string_dp[0]); preprocesOnly = conf.getBoolean("symbolic.string_preprocess_only", false); String[] concolic = conf.getStringArray("symbolic.concolic"); if (concolic != null) { concolicMode = true; - System.out.println("symbolic.concolic=true"); + if (debugMode) System.out.println("symbolic.concolic=true"); } else { concolicMode = false; } @@ -630,7 +658,7 @@ public SymbolicInstructionFactory (Config conf){ if (concolicMaxTries != null) { MaxTries = Integer.parseInt(concolicMaxTries[0]); assert (MaxTries > 0); - System.out.println("symbolic.concolic.MAX_TRIES=" + MaxTries); + if (debugMode) System.out.println("symbolic.concolic.MAX_TRIES=" + MaxTries); } else { MaxTries = 1; } @@ -638,7 +666,7 @@ public SymbolicInstructionFactory (Config conf){ String[] heuristicRandom = conf.getStringArray("symbolic.heuristicRandom"); if (heuristicRandom != null) { heuristicRandomMode = true; - System.out.println("symbolic.heuristicRandom=true"); + if (debugMode) System.out.println("symbolic.heuristicRandom=true"); } else { heuristicRandomMode = false; } @@ -647,14 +675,14 @@ public SymbolicInstructionFactory (Config conf){ if (heuristicPartition != null) { assert(! heuristicRandomMode); heuristicPartitionMode = true; - System.out.println("symbolic.heuristicPartition=true"); + if (debugMode) System.out.println("symbolic.heuristicPartition=true"); } else { heuristicPartitionMode = false; } if(dp[0].equalsIgnoreCase("choco") || dp[0].equalsIgnoreCase("debug") || dp[0].equalsIgnoreCase("compare") || dp == null) { // default is choco ProblemChoco.timeBound = conf.getInt("symbolic.choco_time_bound", 30000); - System.out.println("symbolic.choco_time_bound="+ProblemChoco.timeBound); + if (debugMode) System.out.println("symbolic.choco_time_bound="+ProblemChoco.timeBound); } //load CORAL's parameters if (dp[0].equalsIgnoreCase("coral") || dp[0].equalsIgnoreCase("debug") || dp[0].equalsIgnoreCase("compare")) { @@ -668,13 +696,13 @@ public SymbolicInstructionFactory (Config conf){ if (maxPcLength <= 0) { throw new IllegalArgumentException("symbolic.max_pc_length must be positive (>0), but was " + maxPcLength); } - System.out.println("symbolic.max_pc_length=" + maxPcLength); + if (debugMode) System.out.println("symbolic.max_pc_length=" + maxPcLength); maxPcMSec = conf.getLong("symbolic.max_pc_msec", 0); if (maxPcLength < 0) { throw new IllegalArgumentException("symbolic.max_pc_msec must be non-negative (>=0), but was " + maxPcMSec); } - System.out.println("symbolic.max_pc_msec=" + maxPcMSec); + if (debugMode) System.out.println("symbolic.max_pc_msec=" + maxPcMSec); startSystemMillis = System.currentTimeMillis(); } @@ -684,15 +712,18 @@ public SymbolicInstructionFactory (Config conf){ } else { regressMode = false; } - - //Just checking if set, don't care about any values - String[] dummy = conf.getStringArray("symbolic.debug"); - if (dummy != null) { - debugMode = true; - } else { - debugMode = false; - } - + + this.pcChoiceOptimization = conf.getBoolean("symbolic.optimizechoices", true); + + this.symArrays = conf.getBoolean("symbolic.arrays", false); + + /* load bitvector length, default to 32 */ + bvlength = conf.getInt("symbolic.bvlength", 32); + if (debugMode) System.out.println("symbolic.bvlength="+bvlength); + + /* use floating point theory for reals in Z3? */ + fp = conf.getBoolean("symbolic.fp", false); + if (fp&&debugMode) System.out.println("Using floating point theory for reals in Z3."); MinMax.collectMinMaxInformation(conf); /* no longer required here, now read in MinMax, see line above diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/SymbolicListener.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/SymbolicListener.java index 3a6dfc0..02e4718 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/SymbolicListener.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/SymbolicListener.java @@ -47,20 +47,17 @@ import gov.nasa.jpf.symbc.bytecode.INVOKESTATIC; import gov.nasa.jpf.symbc.concolic.PCAnalyzer; -import gov.nasa.jpf.symbc.arrays.IntegerSymbolicArray; + import gov.nasa.jpf.symbc.numeric.Comparator; import gov.nasa.jpf.symbc.numeric.Expression; import gov.nasa.jpf.symbc.numeric.IntegerConstant; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; -import gov.nasa.jpf.symbc.numeric.PCParser; import gov.nasa.jpf.symbc.numeric.PathCondition; import gov.nasa.jpf.symbc.numeric.RealConstant; import gov.nasa.jpf.symbc.numeric.RealExpression; import gov.nasa.jpf.symbc.numeric.SymbolicInteger; import gov.nasa.jpf.symbc.numeric.SymbolicReal; -import gov.nasa.jpf.symbc.numeric.solvers.ProblemGeneral; -import gov.nasa.jpf.symbc.numeric.solvers.ProblemZ3; import gov.nasa.jpf.symbc.numeric.SymbolicConstraintsGeneral; //import gov.nasa.jpf.symbc.numeric.SymbolicInteger; @@ -132,7 +129,6 @@ public SymbolicListener(Config conf, JPF jpf) { public void propertyViolated (Search search){ VM vm = search.getVM(); - String Model = ""; ChoiceGenerator cg = vm.getChoiceGenerator(); if (!(cg instanceof PCChoiceGenerator)){ @@ -145,11 +141,6 @@ public void propertyViolated (Search search){ if ((cg instanceof PCChoiceGenerator) && ((PCChoiceGenerator) cg).getCurrentPC() != null){ PathCondition pc = ((PCChoiceGenerator) cg).getCurrentPC(); - if (SymbolicInstructionFactory.dp[0].equalsIgnoreCase("z3")) { - ProblemGeneral pb = new ProblemZ3(); - pb = PCParser.parse(pc, pb); - Model = "Z3 Model\n" + pb.getModel(); - } String error = search.getLastError().getDetails(); error = "\"" + error.substring(0,error.indexOf("\n")) + "...\""; // C: not clear where result was used here -- to review @@ -167,10 +158,12 @@ public void propertyViolated (Search search){ else pc.solve(); - Pair pcPair = new Pair(pc.toString() + Model,error);//(pc.toString(),error); + Pair pcPair = new Pair(pc.toString(),error);//(pc.toString(),error); //String methodName = vm.getLastInstruction().getMethodInfo().getName(); MethodSummary methodSummary = allSummaries.get(currentMethodName); + if (methodSummary==null) + methodSummary = new MethodSummary(); methodSummary.addPathCondition(pcPair); allSummaries.put(currentMethodName,methodSummary); System.out.println("Property Violated: PC is "+pc.toString()); @@ -186,7 +179,6 @@ public void propertyViolated (Search search){ @Override public void instructionExecuted(VM vm, ThreadInfo currentThread, Instruction nextInstruction, Instruction executedInstruction) { - if (!vm.getSystemState().isIgnored()) { Instruction insn = executedInstruction; // SystemState ss = vm.getSystemState(); @@ -259,11 +251,7 @@ public void instructionExecuted(VM vm, ThreadInfo currentThread, Instruction nex for(int i=0; i < numberOfArgs; i++){ Expression expLocal = (Expression)sf.getLocalAttr(sfIndex); if (expLocal != null) // symbolic - if (expLocal instanceof IntegerSymbolicArray) { - symVarNameStr = ((IntegerSymbolicArray)expLocal).getName(); - } else { - symVarNameStr = expLocal.toString(); - } + symVarNameStr = expLocal.toString(); else symVarNameStr = argsInfo[namesIndex].getName() + "_CONCRETE" + ","; // TODO: what happens if the argument is an array? @@ -457,12 +445,7 @@ private void printMethodSummary(PrintWriter pw, MethodSummary methodSummary){ while(it.hasNext()){ String testCase = methodSummary.getMethodName() + "("; Pair pcPair = (Pair)it.next(); - String[] aux = ((String)pcPair._1).split("Z3 Model"); - String pc = aux[0]; - String model = ""; - if (aux.length > 1) { - model = aux[1]; - } + String pc = (String)pcPair._1; String errorMessage = (String)pcPair._2; String symValues = methodSummary.getSymValues(); String argValues = methodSummary.getArgValues(); @@ -480,13 +463,6 @@ private void printMethodSummary(PrintWriter pw, MethodSummary methodSummary){ byte actualType = Byte.parseByte(st3.nextToken()); if (st.hasMoreTokens()) token = st.nextToken(); - if (token.contains("SYMARRAY")) { - String[] parts = token.split("_"); - token = parts[0] ; - for (int i = 1; i " + errorMessage; //do not add duplicate test case if (!allTestCases.contains(testCase)) - allTestCases = allTestCases + "\n" + testCase + "\n" + model; - // TODO : parse correctly model to keep only the interesting information + allTestCases = allTestCases + "\n" + testCase; } pw.println(allTestCases); }else{ @@ -592,7 +565,7 @@ private void printMethodSummaryHTML(PrintWriter pw, MethodSummary methodSummary) } String val = temp.substring(temp.indexOf("[")+1,temp.indexOf("]")); - if(actualType == Types.T_INT || actualType == Types.T_FLOAT || actualType == Types.T_LONG || actualType == Types.T_DOUBLE) + if(actualType == Types.T_INT || actualType == Types.T_FLOAT || actualType == Types.T_LONG || actualType == Types.T_SHORT || actualType == Types.T_BYTE || actualType == Types.T_DOUBLE) testCase = testCase + "" + val + ""; else if (actualType == Types.T_BOOLEAN) { //translate boolean values represented as ints //to "true" or "false" @@ -602,8 +575,7 @@ else if (actualType == Types.T_BOOLEAN) { //translate boolean values represented testCase = testCase + "true"; } else - System.out.println("TODO : print arrays"); - // throw new RuntimeException("## Error: listener does not support type other than int, long, float, double and boolean"); + throw new RuntimeException("## Error: listener does not support type other than int, long, short, byte, float, double and boolean"); }else{ //need to check if value is concrete diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/ArrayConstraint.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/ArrayConstraint.java index 0b55aea..7012684 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/ArrayConstraint.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/ArrayConstraint.java @@ -13,18 +13,16 @@ public ArrayConstraint(StoreExpression se, Comparator c, ArrayExpression ae) { super(se, c, ae); } - - @Override public ArrayConstraint not() { try { return new ArrayConstraint((SelectExpression)super.getLeft(), getComparator().not(), (IntegerExpression)getRight()); } catch (Exception e) { try { return new ArrayConstraint((StoreExpression)super.getLeft(), getComparator().not(), (ArrayExpression)getRight()); - } - catch (Exception r) { + } catch (Exception r) { throw new RuntimeException("ArrayConstraint is not select or store"); } } } } + diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/ArrayExpression.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/ArrayExpression.java index 29ebf3f..c80d4c1 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/ArrayExpression.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/ArrayExpression.java @@ -1,80 +1,136 @@ -package gov.nasa.jpf.symbc.arrays; +/* + * Copyright (C) 2014, United States Government, as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All rights reserved. + * + * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +//Copyright (C) 2005 United States Government as represented by the +//Administrator of the National Aeronautics and Space Administration +//(NASA). All Rights Reserved. +//This software is distributed under the NASA Open Source Agreement +//(NOSA), version 1.3. The NOSA has been approved by the Open Source +//Initiative. See the file NOSA-1.3-JPF at the top of the distribution +//directory tree for the complete NOSA document. -import gov.nasa.jpf.symbc.arrays.SymbolicIntegerValueAtIndex; +//THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY +//KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT +//LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO +//SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR +//A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT +//THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT +//DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. + + +package gov.nasa.jpf.symbc.arrays; + +import gov.nasa.jpf.symbc.numeric.ConstraintExpressionVisitor; import gov.nasa.jpf.symbc.numeric.Expression; +import gov.nasa.jpf.symbc.numeric.IntegerConstant; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.symbc.numeric.SymbolicInteger; -import java.util.Set; import java.util.Map; -import java.util.HashMap; -public abstract class ArrayExpression extends Expression { +public class ArrayExpression extends Expression { public IntegerExpression length; - protected String name; - public Map valAt = null; - // used for the store operation. We create a new array expression each time we have a store + private String elemType = "?"; + private final String name; - public int compareTo(Expression expr) { - // unimplemented - return 0; - } - public String getName() { - return (name != null) ? name : "ARRAY_"+hashCode(); + return this.name; } - public SymbolicIntegerValueAtIndex getVal(IntegerExpression index) { - if (valAt == null) { - valAt = new HashMap(); - } - SymbolicIntegerValueAtIndex result = valAt.get(index.toString()); - if (result == null) { - result = new SymbolicIntegerValueAtIndex(this, index); - valAt.put(index.toString(), result); - } - return result; + public ArrayExpression(String name) { + this.name=name; + this.length = new SymbolicInteger(name+"_length"); } - public SymbolicIntegerValueAtIndex getBoolVal(IntegerExpression index) { - if (valAt == null) { - valAt = new HashMap(); - } - SymbolicIntegerValueAtIndex result = valAt.get(index.toString()); - if (result == null) { - result = new SymbolicIntegerValueAtIndex(this, index, true); - valAt.put(index.toString(), result); - } - return result; + public ArrayExpression(String name, int l) { + this.name = name; + this.length = new IntegerConstant(l); } - public void setVal(IntegerExpression index, SymbolicIntegerValueAtIndex value) { - if (valAt == null) { - valAt = new HashMap(); - } - String indexName = ""; - // If we have a name for the index, we put it in the map. Else, we create one - if (index instanceof SymbolicInteger) { - SymbolicInteger aux = (SymbolicInteger)index; - indexName = aux.getName(); - } - else { - indexName = "ValueAt(INT_"+hashCode()+")"; - } - // We put the value in the map - valAt.put(indexName, value); + public ArrayExpression(String name, String arrayType) { + this.name = name; + this.length = new SymbolicInteger(name+"_length"); + this.elemType = arrayType; } - public void printValAt() { - if (valAt == null) { - System.out.println("valAt is null"); - return; + public static String getNewName(ArrayExpression prev) { + String newName = prev.getName(); + if (newName.indexOf("!") == -1) { + newName = newName + "!1"; + } else { + int aux = Integer.parseInt(newName.substring(newName.indexOf("!") + 1)); + newName = newName.substring(0, newName.indexOf("!") + 1) + (aux + 1); } - for (Map.Entry entry : valAt.entrySet()) { - String key = entry.getKey(); - SymbolicIntegerValueAtIndex val = entry.getValue(); - System.out.println(key + " : " + val); + return newName; + } + + public String getRootName() { + if (this.getName().indexOf("!") == -1) { + return this.getName(); + } else { + return this.getName().substring(0, this.getName().indexOf("!")); } + + } + + public ArrayExpression(ArrayExpression prev) { + this.name = getNewName(prev); + this.length = prev.length; + this.elemType = prev.getElemType(); + } + + public String getElemType() { + return elemType; + } + + public static ArrayExpression create(String name) { + return new ArrayExpression(name); + } + + public static ArrayExpression create(String name, String arrayType) { + return new ArrayExpression(name, arrayType); + } + + public static ArrayExpression create(String name, int l) { + return new ArrayExpression(name, l); + } + + public String stringPC() { + return (name != null) ? name : "ARRAY_" + hashCode(); + } + + public void accept(ConstraintExpressionVisitor visitor) { + visitor.preVisit(this); + visitor.postVisit(this); + } + + public void getVarsVals(Map varsVals) { + return; + } + + public int compareTo(Expression expr) { + // unimplemented + return 0; + } + + public String toString() { + return this.stringPC(); } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/IntegerSymbolicArray.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/IntegerSymbolicArray.java deleted file mode 100644 index d59b058..0000000 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/IntegerSymbolicArray.java +++ /dev/null @@ -1,70 +0,0 @@ -package gov.nasa.jpf.symbc.arrays; - -import java.util.Map; - -import gov.nasa.jpf.symbc.numeric.ConstraintExpressionVisitor; -import gov.nasa.jpf.symbc.numeric.IntegerConstant; -import gov.nasa.jpf.symbc.arrays.PreviousIntegerArray; -import gov.nasa.jpf.symbc.numeric.IntegerExpression; - - -public class IntegerSymbolicArray extends ArrayExpression { - public String solution = "UNDEFINED"; - // Indicates the previous ArrayExpression, as well as the index and value - // when we store something in the array - public PreviousIntegerArray previous = null; - - - public IntegerSymbolicArray(int size) { - super(); - this.length = new IntegerConstant(size); - } - - public IntegerSymbolicArray(int n, String name) { - super(); - this.name = name; - this.length = new IntegerConstant(n); - } - - public IntegerSymbolicArray(IntegerExpression n, String name) { - super(); - this.name = name; - this.length = n; - } - - public IntegerSymbolicArray(PreviousIntegerArray previous) { - super(); - this.length = previous.ae.length; - String newName = previous.ae.name; - if (newName.indexOf("!") == -1) { - newName = newName+ "!1"; - } else { - int aux = Integer.parseInt(newName.substring(newName.indexOf("!") + 1)); - newName = newName.substring(0, newName.indexOf("!") +1) + (aux + 1); - } - this.name = newName; - this.previous = previous; - } - - public IntegerExpression __length() { - return length; - } - - public String solution() { - return solution; - } - - public String stringPC() { - return (name != null) ? name : "ARRAY_" + hashCode(); - } - - public void accept(ConstraintExpressionVisitor visitor) { - visitor.preVisit(this); - visitor.postVisit(this); - } - - public void getVarsVals(Map varsVals) { - varsVals.put(name, solution); - } - -} diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/ObjectSymbolicArray.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/ObjectSymbolicArray.java deleted file mode 100644 index 672ed18..0000000 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/ObjectSymbolicArray.java +++ /dev/null @@ -1,75 +0,0 @@ -package gov.nasa.jpf.symbc.arrays; - -import java.util.Map; - -import gov.nasa.jpf.symbc.arrays.ObjectSymbolicArray; -import gov.nasa.jpf.symbc.heap.SymbolicInputHeap; -import gov.nasa.jpf.symbc.numeric.ConstraintExpressionVisitor; -import gov.nasa.jpf.symbc.numeric.IntegerConstant; -import gov.nasa.jpf.symbc.numeric.IntegerExpression; - -public class ObjectSymbolicArray extends ArrayExpression { - private String solution = "UNDEFINED"; - private String elemType = "?"; - public PreviousObjectArray previous = null; - public SymbolicInputHeap symInputHeap = null; - - public ObjectSymbolicArray(int size) { - super(); - this.length = new IntegerConstant(size); - } - - public ObjectSymbolicArray(int n, String name) { - super(); - this.name = name; - this.length = new IntegerConstant(n); - } - - public ObjectSymbolicArray(IntegerExpression n, String name, String arrayType) { - super(); - this.name = name; - this.length = n; - this.elemType = arrayType.substring(0, arrayType.length() - 2); // We remove [] at the end of the arrayType - } - - public ObjectSymbolicArray(PreviousObjectArray previous) { - super(); - this.length = previous.ae.length; - String newName = previous.ae.name; - if (newName.indexOf("!") == -1) { - newName = newName + "!1"; - } else { - int aux = Integer.parseInt(newName.substring(newName.indexOf("!") + 1)); - newName = newName.substring(0, newName.indexOf("!") +1) + (aux + 1); - } - this.name = newName; - this.elemType = previous.ae.elemType; - this.previous = previous; - } - - public IntegerExpression __length() { - return length; - } - - public String getElemType() { - return elemType; - } - - public String solution() { - return solution; - } - - public String stringPC() { - return (name != null) ? name : "ARRAY_" + hashCode(); - } - - public void accept(ConstraintExpressionVisitor visitor) { - visitor.preVisit(this); - visitor.postVisit(this); - } - - public void getVarsVals(Map varsVals) { - varsVals.put(name, solution); - } -} - diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/PreviousIntegerArray.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/PreviousIntegerArray.java deleted file mode 100644 index 49538a7..0000000 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/PreviousIntegerArray.java +++ /dev/null @@ -1,16 +0,0 @@ -package gov.nasa.jpf.symbc.arrays; - -import gov.nasa.jpf.symbc.arrays.IntegerSymbolicArray; -import gov.nasa.jpf.symbc.numeric.IntegerExpression; - -public class PreviousIntegerArray { - IntegerSymbolicArray ae; - IntegerExpression index; - IntegerExpression value; - - public PreviousIntegerArray(IntegerSymbolicArray ae, IntegerExpression index, IntegerExpression value) { - this.ae = ae; - this.index = index; - this.value = value; - } -} diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/PreviousObjectArray.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/PreviousObjectArray.java deleted file mode 100644 index 7d47524..0000000 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/PreviousObjectArray.java +++ /dev/null @@ -1,16 +0,0 @@ -package gov.nasa.jpf.symbc.arrays; - -import gov.nasa.jpf.symbc.arrays.ObjectSymbolicArray; -import gov.nasa.jpf.symbc.numeric.IntegerExpression; - -public class PreviousObjectArray { - ObjectSymbolicArray ae; - IntegerExpression index; - IntegerExpression value; - - public PreviousObjectArray(ObjectSymbolicArray ae, IntegerExpression index, IntegerExpression value) { - this.ae = ae; - this.index = index; - this.value = value; - } -} diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/PreviousRealArray.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/PreviousRealArray.java deleted file mode 100644 index b55f6bf..0000000 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/PreviousRealArray.java +++ /dev/null @@ -1,17 +0,0 @@ -package gov.nasa.jpf.symbc.arrays; - -import gov.nasa.jpf.symbc.arrays.RealSymbolicArray; -import gov.nasa.jpf.symbc.numeric.IntegerExpression; -import gov.nasa.jpf.symbc.numeric.RealExpression; - -public class PreviousRealArray { - RealSymbolicArray ae; - IntegerExpression index; - RealExpression value; - - public PreviousRealArray(RealSymbolicArray ae, IntegerExpression index, RealExpression value) { - this.ae = ae; - this.index = index; - this.value = value; - } -} diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/RealArrayConstraint.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/RealArrayConstraint.java index 05fa0ab..c2a91bf 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/RealArrayConstraint.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/RealArrayConstraint.java @@ -2,7 +2,6 @@ import gov.nasa.jpf.symbc.numeric.Constraint; import gov.nasa.jpf.symbc.numeric.Comparator; -import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.symbc.numeric.RealExpression; public class RealArrayConstraint extends Constraint { @@ -14,18 +13,16 @@ public RealArrayConstraint(RealStoreExpression se, Comparator c, ArrayExpression super(se, c, ae); } - - @Override public RealArrayConstraint not() { try { return new RealArrayConstraint((SelectExpression)super.getLeft(), getComparator().not(), (RealExpression)getRight()); } catch (Exception e) { try { return new RealArrayConstraint((RealStoreExpression)super.getLeft(), getComparator().not(), (ArrayExpression)getRight()); - } - catch (Exception r) { + } catch (Exception r) { throw new RuntimeException("ArrayConstraint is not select or store"); } } } } + diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/RealStoreExpression.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/RealStoreExpression.java index 5ef43fe..e653865 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/RealStoreExpression.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/RealStoreExpression.java @@ -1,40 +1,59 @@ -package gov.nasa.jpf.symbc.arrays; +/* + * Copyright (C) 2014, United States Government, as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All rights reserved. + * + * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +//Copyright (C) 2005 United States Government as represented by the +//Administrator of the National Aeronautics and Space Administration +//(NASA). All Rights Reserved. +// +//This software is distributed under the NASA Open Source Agreement +//(NOSA), version 1.3. The NOSA has been approved by the Open Source +//Initiative. See the file NOSA-1.3-JPF at the top of the distribution +//directory tree for the complete NOSA document. +// +//THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY +//KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT +//LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO +//SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR +//A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT +//THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT +//DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. +// + +package gov.nasa.jpf.symbc.arrays; import gov.nasa.jpf.symbc.numeric.ConstraintExpressionVisitor; +import gov.nasa.jpf.symbc.numeric.Expression; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.symbc.numeric.RealExpression; -import gov.nasa.jpf.symbc.numeric.RealConstant; -import gov.nasa.jpf.symbc.numeric.Expression; -import gov.nasa.jpf.symbc.numeric.IntegerConstant; import java.util.Map; public class RealStoreExpression extends Expression { - public ArrayExpression ae; - public IntegerExpression index; - public RealExpression value; - - public RealStoreExpression(ArrayExpression ae, IntegerExpression ie, RealExpression value) { - this.ae = ae; - this.index = ie; - this.value = value; - } + public ArrayExpression arrayExpression; + public IntegerExpression indexExpression; - public RealStoreExpression(ArrayExpression ae, int index, RealExpression value) { - this(ae, new IntegerConstant(index), value); - } - - public RealStoreExpression(ArrayExpression ae, IntegerExpression ie, float value) { - this(ae, ie, new RealConstant(value)); - } - - public RealStoreExpression(ArrayExpression ae, int index, float value) { - this(ae, new IntegerConstant(index), new RealConstant(value)); - } + public RealExpression value; - public int compareTo(Expression expr) { - // unimplemented - return 0; + public RealStoreExpression(ArrayExpression ae, IntegerExpression ie, RealExpression val) { + this.arrayExpression = ae; + this.indexExpression = ie; + this.value = val; } public void accept(ConstraintExpressionVisitor visitor) { @@ -47,7 +66,15 @@ public void getVarsVals(Map varsVals) { } public String stringPC() { - return ("store "+ae.stringPC() + " " + index.stringPC() + " " + value.stringPC()); + return arrayExpression.stringPC() + "[" + indexExpression.stringPC() + "] <- " + value.stringPC(); + } + + public int compareTo(Expression expr) { + // unimplemented + return 0; } + public String toString() { + return this.stringPC(); + } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/RealSymbolicArray.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/RealSymbolicArray.java deleted file mode 100644 index 0053b6a..0000000 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/RealSymbolicArray.java +++ /dev/null @@ -1,91 +0,0 @@ -package gov.nasa.jpf.symbc.arrays; - -import java.util.HashMap; -import java.util.Map; - -import gov.nasa.jpf.symbc.numeric.ConstraintExpressionVisitor; -import gov.nasa.jpf.symbc.numeric.IntegerConstant; -import gov.nasa.jpf.symbc.numeric.RealConstant; -import gov.nasa.jpf.symbc.arrays.PreviousIntegerArray; -import gov.nasa.jpf.symbc.numeric.IntegerExpression; -import gov.nasa.jpf.symbc.numeric.RealExpression; - - -public class RealSymbolicArray extends ArrayExpression { - private String name; - public String solution = "UNDEFINED"; - // Indicates the previous ArrayExpression, as well as the index and value - // when we store something in the array - public PreviousRealArray previous = null; - public Map realValAt = null; - - - public RealSymbolicArray(int size) { - super(); - this.length = new IntegerConstant(size); - } - - public RealSymbolicArray(int n, String name) { - super(); - this.name = name; - this.length = new IntegerConstant(n); - } - - public RealSymbolicArray(IntegerExpression n, String name) { - super(); - this.name = name; - this.length = n; - } - - public RealSymbolicArray(PreviousRealArray previous) { - super(); - this.length = previous.ae.length; - String newName = previous.ae.name; - if (newName.indexOf("!") == -1) { - newName = newName+ "!1"; - } else { - int aux = Integer.parseInt(newName.substring(newName.indexOf("!") + 1)); - newName = newName.substring(0, newName.indexOf("!") +1) + (aux + 1); - } - this.name = newName; - this.previous = previous; - } - - - public IntegerExpression __length() { - return length; - } - - public String getName() { - return (name!=null) ? name : "ARRAY_" + hashCode(); - } - - public String solution() { - return solution; - } - - public String stringPC() { - return (name != null) ? name : "ARRAY_" + hashCode(); - } - - public void accept(ConstraintExpressionVisitor visitor) { - visitor.preVisit(this); - visitor.postVisit(this); - } - - public void getVarsVals(Map varsVals) { - varsVals.put(name, solution); - } - - public SymbolicRealValueAtIndex getRealVal(IntegerExpression index) { - if (realValAt == null) { - realValAt = new HashMap(); - } - SymbolicRealValueAtIndex result = realValAt.get(index.toString()); - if (result == null) { - result = new SymbolicRealValueAtIndex(this, index); - realValAt.put(index.toString(), result); - } - return result; - } -} diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/SelectExpression.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/SelectExpression.java index 5e5860e..113e1cf 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/SelectExpression.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/SelectExpression.java @@ -1,29 +1,55 @@ -package gov.nasa.jpf.symbc.arrays; +/* + * Copyright (C) 2014, United States Government, as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All rights reserved. + * + * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +//Copyright (C) 2005 United States Government as represented by the +//Administrator of the National Aeronautics and Space Administration +//(NASA). All Rights Reserved. +// +//This software is distributed under the NASA Open Source Agreement +//(NOSA), version 1.3. The NOSA has been approved by the Open Source +//Initiative. See the file NOSA-1.3-JPF at the top of the distribution +//directory tree for the complete NOSA document. +// +//THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY +//KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT +//LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO +//SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR +//A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT +//THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT +//DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. +// + +package gov.nasa.jpf.symbc.arrays; import gov.nasa.jpf.symbc.numeric.ConstraintExpressionVisitor; -import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.symbc.numeric.Expression; -import gov.nasa.jpf.symbc.numeric.IntegerConstant; +import gov.nasa.jpf.symbc.numeric.IntegerExpression; import java.util.Map; public class SelectExpression extends Expression { - public ArrayExpression ae; - public IntegerExpression index; + public ArrayExpression arrayExpression; + public IntegerExpression indexExpression; public SelectExpression(ArrayExpression ae, IntegerExpression ie) { - this.ae = ae; - this.index = ie; - } - - public SelectExpression(ArrayExpression ae, int index) { - this.ae = ae; - this.index = new IntegerConstant(index); - } - - public int compareTo(Expression expr) { - // unimplemented - return 0; + this.arrayExpression = ae; + this.indexExpression = ie; } public void accept(ConstraintExpressionVisitor visitor) { @@ -36,7 +62,15 @@ public void getVarsVals(Map varsVals) { } public String stringPC() { - return ("select "+ae.stringPC() + " " + index.stringPC()); + return arrayExpression.stringPC() + "[" + indexExpression.stringPC() + "]"; + } + + public int compareTo(Expression expr) { + // unimplemented + return 0; } + public String toString() { + return this.stringPC(); + } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/StoreExpression.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/StoreExpression.java index 023a2ca..d9eb7a4 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/StoreExpression.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/StoreExpression.java @@ -1,38 +1,58 @@ -package gov.nasa.jpf.symbc.arrays; +/* + * Copyright (C) 2014, United States Government, as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All rights reserved. + * + * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +//Copyright (C) 2005 United States Government as represented by the +//Administrator of the National Aeronautics and Space Administration +//(NASA). All Rights Reserved. +// +//This software is distributed under the NASA Open Source Agreement +//(NOSA), version 1.3. The NOSA has been approved by the Open Source +//Initiative. See the file NOSA-1.3-JPF at the top of the distribution +//directory tree for the complete NOSA document. +// +//THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY +//KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT +//LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO +//SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR +//A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT +//THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT +//DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. +// + +package gov.nasa.jpf.symbc.arrays; import gov.nasa.jpf.symbc.numeric.ConstraintExpressionVisitor; -import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.symbc.numeric.Expression; -import gov.nasa.jpf.symbc.numeric.IntegerConstant; +import gov.nasa.jpf.symbc.numeric.IntegerExpression; import java.util.Map; public class StoreExpression extends Expression { - public ArrayExpression ae; - public IntegerExpression index; - public IntegerExpression value; - - public StoreExpression(ArrayExpression ae, IntegerExpression ie, IntegerExpression value) { - this.ae = ae; - this.index = ie; - this.value = value; - } + public ArrayExpression arrayExpression; + public IntegerExpression indexExpression; - public StoreExpression(ArrayExpression ae, int index, IntegerExpression value) { - this(ae, new IntegerConstant(index), value); - } - - public StoreExpression(ArrayExpression ae, IntegerExpression ie, int value) { - this(ae, ie, new IntegerConstant(value)); - } - - public StoreExpression(ArrayExpression ae, int index, int value) { - this(ae, new IntegerConstant(index), new IntegerConstant(value)); - } + public IntegerExpression value; - public int compareTo(Expression expr) { - // unimplemented - return 0; + public StoreExpression(ArrayExpression ae, IntegerExpression ie, IntegerExpression val) { + this.arrayExpression = ae; + this.indexExpression = ie; + this.value = val; } public void accept(ConstraintExpressionVisitor visitor) { @@ -45,7 +65,15 @@ public void getVarsVals(Map varsVals) { } public String stringPC() { - return ("store "+ae.stringPC() + " " + index.stringPC() + " " + value.stringPC()); + return arrayExpression.stringPC() + "[" + indexExpression.stringPC() + "] <- " + value.stringPC(); + } + + public int compareTo(Expression expr) { + // unimplemented + return 0; } + public String toString() { + return this.stringPC(); + } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/SymbolicIntegerValueAtIndex.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/SymbolicIntegerValueAtIndex.java deleted file mode 100644 index d8cc427..0000000 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/SymbolicIntegerValueAtIndex.java +++ /dev/null @@ -1,39 +0,0 @@ -package gov.nasa.jpf.symbc.arrays; - -import gov.nasa.jpf.symbc.arrays.ArrayExpression; -import gov.nasa.jpf.symbc.numeric.IntegerExpression; -import gov.nasa.jpf.symbc.numeric.SymbolicInteger; - -public class SymbolicIntegerValueAtIndex { - public ArrayExpression ae; - public IntegerExpression index; - public IntegerExpression value; - - public SymbolicIntegerValueAtIndex(ArrayExpression ae, IntegerExpression index) { - IntegerExpression value = new SymbolicInteger("ValueAt("+index.toString()+")"); - this.value = value; - this.ae = ae; - this.index = index; - } - - public SymbolicIntegerValueAtIndex(ArrayExpression ae, IntegerExpression index, IntegerExpression value) { - this.ae = ae; - this.index = index; - this.value = value; - } - - public SymbolicIntegerValueAtIndex(ArrayExpression ae, IntegerExpression index, boolean isBool) { - if (isBool) { - IntegerExpression value = new SymbolicInteger("ValueAt("+index.toString()+")", 0, 1); - this.value = value; - this.ae = ae; - this.index = index; - } - else { - IntegerExpression value = new SymbolicInteger("ValueAt("+index.toString()+")"); - this.value = value; - this.ae = ae; - this.index = index; - } - } -} diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/SymbolicRealValueAtIndex.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/SymbolicRealValueAtIndex.java deleted file mode 100644 index 605880f..0000000 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/arrays/SymbolicRealValueAtIndex.java +++ /dev/null @@ -1,40 +0,0 @@ -package gov.nasa.jpf.symbc.arrays; - -import gov.nasa.jpf.symbc.arrays.ArrayExpression; -import gov.nasa.jpf.symbc.numeric.IntegerExpression; -import gov.nasa.jpf.symbc.numeric.RealExpression; -import gov.nasa.jpf.symbc.numeric.SymbolicReal; - -public class SymbolicRealValueAtIndex { - public ArrayExpression ae; - public IntegerExpression index; - public RealExpression value; - - public SymbolicRealValueAtIndex(ArrayExpression ae, IntegerExpression index) { - RealExpression value = new SymbolicReal("ValueAt("+index.toString()+")"); - this.value = value; - this.ae = ae; - this.index = index; - } - - public SymbolicRealValueAtIndex(ArrayExpression ae, IntegerExpression index, RealExpression value) { - this.ae = ae; - this.index = index; - this.value = value; - } - - public SymbolicRealValueAtIndex(ArrayExpression ae, IntegerExpression index, boolean isBool) { - if (isBool) { - RealExpression value = new SymbolicReal("ValueAt("+index.toString()+")", 0, 1); - this.value = value; - this.ae = ae; - this.index = index; - } - else { - RealExpression value = new SymbolicReal("ValueAt("+index.toString()+")"); - this.value = value; - this.ae = ae; - this.index = index; - } - } -} diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/AALOAD.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/AALOAD.java index 936877b..4a4a3c0 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/AALOAD.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/AALOAD.java @@ -21,25 +21,15 @@ package gov.nasa.jpf.symbc.bytecode; import gov.nasa.jpf.symbc.SymbolicInstructionFactory; -import gov.nasa.jpf.symbc.arrays.ArrayExpression; -import gov.nasa.jpf.symbc.arrays.ArrayHeapNode; -import gov.nasa.jpf.symbc.arrays.HelperResult; -import gov.nasa.jpf.symbc.arrays.ObjectSymbolicArray; -import gov.nasa.jpf.symbc.arrays.SelectExpression; import gov.nasa.jpf.symbc.heap.HeapChoiceGenerator; -import gov.nasa.jpf.symbc.heap.HeapNode; -import gov.nasa.jpf.symbc.heap.Helper; import gov.nasa.jpf.symbc.heap.SymbolicInputHeap; import gov.nasa.jpf.symbc.numeric.Comparator; -import gov.nasa.jpf.symbc.numeric.IntegerConstant; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; import gov.nasa.jpf.symbc.numeric.PathCondition; import gov.nasa.jpf.vm.ArrayFields; import gov.nasa.jpf.vm.ArrayIndexOutOfBoundsExecutiveException; import gov.nasa.jpf.vm.ChoiceGenerator; -import gov.nasa.jpf.vm.ClassInfo; -import gov.nasa.jpf.vm.ClassLoaderInfo; import gov.nasa.jpf.vm.ElementInfo; import gov.nasa.jpf.vm.Instruction; import gov.nasa.jpf.vm.MJIEnv; @@ -56,267 +46,117 @@ public class AALOAD extends gov.nasa.jpf.jvm.bytecode.AALOAD { @Override public Instruction execute (ThreadInfo ti) { - - boolean abstractClass = false; - ObjectSymbolicArray arrayAttr = null; - ArrayHeapNode[] prevSymRefs = null; // previously initialized objects of same type - int numSymRefs = 0; // number of previously initialized objects - ChoiceGenerator prevHeapCG = null; - ChoiceGenerator cg; - int currentChoice; - IntegerExpression indexAttr = null; - StackFrame frame = ti.getModifiableTopFrame(); - arrayRef = frame.peek(1); // ..,arrayRef,idx - if (peekArrayAttr(ti) == null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { - // In this case, the array isn't symbolic - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case, the index isn't symbolic either - return super.execute(ti); - } - // We have a concrete array, but a symbolic index. We add all the constraints about the elements of the array and perform the select - // We will need to get information about the type of the elements as well - // We need to add the information in PC after it is declared. - ElementInfo arrayInfo = ti.getElementInfo(arrayRef); - if (!ti.isFirstStepInsn()) { // first time around - cg = new PCChoiceGenerator(arrayInfo.arrayLength() + 2); - ((PCChoiceGenerator)cg).setOffset(this.position); - ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); - ti.getVM().setNextChoiceGenerator(cg); - return this; - } else { // this is what really returns results - cg = ti.getVM().getLastChoiceGeneratorOfType(PCChoiceGenerator.class); - assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; - currentChoice = (Integer)cg.getNextChoice(); - } - - PathCondition pc; - ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - if (prev_cg == null) - pc = new PathCondition(); - else - pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); - - assert pc != null; - indexAttr = (IntegerExpression)peekIndexAttr(ti); - - if (currentChoice < arrayInfo.arrayLength()) { - // For each possible index, we check if the symbolic index can be equal to it. If so, we return the value at this index - - pc._addDet(Comparator.EQ, indexAttr, new IntegerConstant(currentChoice)); - if (pc.simplify()) { // satisfiable - frame.pop(2); - arrayInfo.checkArrayBounds(currentChoice); // should not fail - int value = arrayInfo.getReferenceElement(currentChoice); - frame.pushRef(value); - Object elementAttr = arrayInfo.getElementAttr(currentChoice); - if (elementAttr != null) { - frame.setOperandAttr(elementAttr); - } - return getNext(ti); - } else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } else if (currentChoice == arrayInfo.arrayLength()) { - pc._addDet(Comparator.GE, indexAttr, new IntegerConstant(arrayInfo.arrayLength())); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index greater than array bounds"); - } else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } else if (currentChoice == arrayInfo.arrayLength() +1) { - pc._addDet(Comparator.LT, indexAttr, new IntegerConstant(0)); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index smaller than array bounds"); - } else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } else { - throw new RuntimeException("We shouldn't end here in AALOAD"); - } - } else { - arrayAttr = (ObjectSymbolicArray)peekArrayAttr(ti); - } + if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) + return super.execute(ti); + StackFrame frame = ti.getModifiableTopFrame(); + arrayRef = frame.peek(1); // ..,arrayRef,idx + if (arrayRef == MJIEnv.NULL) { + return ti.createAndThrowException("java.lang.NullPointerException"); + } - String typeElemArray = arrayAttr.getElemType(); - - if (typeElemArray.equals("?")) { - throw new RuntimeException("Type of array elements unknown"); - } - - ClassInfo typeClassInfo = ClassLoaderInfo.getCurrentResolvedClassInfo(typeElemArray); - - ChoiceGenerator thisHeapCG; - - if (!ti.isFirstStepInsn()) { - // We add the HeapChoiceGenerator that will be required if we can load an element - numSymRefs = 0; - prevSymRefs = null; - prevHeapCG = ti.getVM().getLastChoiceGeneratorOfType(HeapChoiceGenerator.class); - - if (prevHeapCG != null) { - SymbolicInputHeap symInputHeap = ((HeapChoiceGenerator)prevHeapCG).getCurrentSymInputHeap(); - // We get only the previously initialized elements for this array - prevSymRefs = symInputHeap.getArrayNodesOfType(typeClassInfo, arrayRef); - numSymRefs = prevSymRefs.length; - } - - int increment = 2; - if (typeClassInfo.isAbstract()) { - abstractClass =true; - increment = 1; - } - thisHeapCG = new HeapChoiceGenerator(numSymRefs + increment); - ti.getVM().setNextChoiceGenerator(thisHeapCG); - - // We now add the PCChoiceGenerator that will be used first to detemrine if we are in bounds - cg = new PCChoiceGenerator(3); - ((PCChoiceGenerator)cg).setOffset(this.position); - ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); - ti.getVM().setNextChoiceGenerator(cg); + + ElementInfo eiArray = ti.getElementInfo(arrayRef); + int len=(eiArray.getArrayFields()).arrayLength(); // assumed concrete + + if(!ti.isFirstStepInsn()){ + PCChoiceGenerator arrayCG = new PCChoiceGenerator(0,len+1); // add 2 error cases: <0, >=len + ti.getVM().getSystemState().setNextChoiceGenerator(arrayCG); + + if (SymbolicInstructionFactory.debugMode) + System.out.println("# array cg registered: " + arrayCG); return this; - } else { - cg = ti.getVM().getLastChoiceGeneratorOfType(PCChoiceGenerator.class); - thisHeapCG = ti.getVM().getLastChoiceGeneratorOfType(HeapChoiceGenerator.class); - assert (thisHeapCG instanceof HeapChoiceGenerator) : "expected HeapChoiceGenerator, got: " + thisHeapCG; - assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; - currentChoice = (Integer)cg.getNextChoice(); - } - - PathCondition pc; - ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - if (prev_cg == null) - pc = new PathCondition(); - else - pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); - - assert pc != null; - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // The index is not symbolic - index = frame.peek(); - indexAttr = new IntegerConstant(index); - } else { - indexAttr = (IntegerExpression)peekIndexAttr(ti); - } - - if (currentChoice == 1) { - pc._addDet(Comparator.LT, indexAttr, new IntegerConstant(0)); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index smaller than array bounds"); - } else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } else if (currentChoice == 2) { - pc._addDet(Comparator.GE, indexAttr, arrayAttr.length); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index greater than array bounds"); - } else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } else { - // TODO deal with actual load - pc._addDet(Comparator.LT, indexAttr, arrayAttr.length); - pc._addDet(Comparator.GE, indexAttr, new IntegerConstant(0)); - PathCondition pcHeap; - SymbolicInputHeap symInputHeap; - - prevHeapCG = thisHeapCG.getPreviousChoiceGeneratorOfType(HeapChoiceGenerator.class); - - if (prevHeapCG == null) { - pcHeap = new PathCondition(); - symInputHeap = new SymbolicInputHeap(); - } else { - pcHeap = ((HeapChoiceGenerator)prevHeapCG).getCurrentPCheap(); - symInputHeap = ((HeapChoiceGenerator) prevHeapCG).getCurrentSymInputHeap(); - } - - assert pcHeap != null; - assert symInputHeap != null; - - SelectExpression se = null; - - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case the index isn't symbolic - index = frame.peek(); - se = new SelectExpression(arrayAttr, index); - indexAttr = new IntegerConstant(index); - } else { - indexAttr = (IntegerExpression)peekIndexAttr(ti); - se = new SelectExpression(arrayAttr, indexAttr); - } - assert arrayAttr != null; - assert indexAttr != null; - assert se != null; - - if (arrayRef == MJIEnv.NULL) { - return ti.createAndThrowException("java.lang.NullPointerException"); - } - - int daIndex = 0; // index into JPF's dynamic area - currentChoice = ((HeapChoiceGenerator) thisHeapCG).getNextChoice(); - - if (currentChoice < numSymRefs) { - // We load a previously initialized object - ArrayHeapNode candidateNode = prevSymRefs[currentChoice]; - pc._addDet(Comparator.EQ, indexAttr, candidateNode.arrayIndex); - if (pc.simplify()) { - // The index is the same than the previous one - pc._addDet(Comparator.EQ, se, candidateNode.getSymbolic()); - daIndex = candidateNode.getIndex(); - frame.pop(2); // We pop the array and the index - frame.push(daIndex, true); // We have instantiated an object, and added the constraints in the PC - - ((HeapChoiceGenerator)thisHeapCG).setCurrentPCheap(pcHeap); - ((HeapChoiceGenerator)thisHeapCG).setCurrentSymInputHeap(symInputHeap); - return getNext(ti); - } else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } else if (currentChoice == (numSymRefs)) { // null object - if (pc.simplify()) { // satisfiable - pcHeap._addDet(Comparator.EQ, se, new IntegerConstant(-1)); - daIndex = MJIEnv.NULL; - frame.pop(2); // We pop the index and the array; - frame.push(daIndex, true); - - ((HeapChoiceGenerator)thisHeapCG).setCurrentPCheap(pcHeap); - ((HeapChoiceGenerator)thisHeapCG).setCurrentSymInputHeap(symInputHeap); - return getNext(ti); - } else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } else { - if (pc.simplify()) { // satisfiable - HelperResult hpResult = Helper.addNewArrayHeapNode(typeClassInfo, ti, arrayAttr, pcHeap, symInputHeap, numSymRefs, prevSymRefs, false, indexAttr, arrayRef); - daIndex = hpResult.idx; - HeapNode candidateNode = hpResult.n; - // Since the object is different from all the previously initialized ones, we don't need to add constraints - // on the index, it will be inferred from Z3 array theory - pcHeap._addDet(Comparator.EQ, se, candidateNode.getSymbolic()); - frame.pop(2); // We pop the array and the index - frame.push(daIndex, true); - ((HeapChoiceGenerator) thisHeapCG).setCurrentPCheap(pcHeap); - ((HeapChoiceGenerator) thisHeapCG).setCurrentSymInputHeap(symInputHeap); - return getNext(ti); - } else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } + } else { //this is what really returns results + + //index = frame.peek(); + PCChoiceGenerator lastCG=ti.getVM().getSystemState().getLastChoiceGeneratorOfType(PCChoiceGenerator.class); + assert(lastCG!=null); + PCChoiceGenerator prevCG=lastCG.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + index=lastCG.getNextChoice(); + IntegerExpression sym_index=(IntegerExpression)peekIndexAttr(ti); + //check the constraint + + PathCondition pc; + + if (prevCG == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prevCG).getCurrentPC(); + + assert pc != null; + + if(index cg; - boolean condition; - int arrayRef = peekArrayRef(ti); // need to be polymorphic, could be LongArrayStore - - if (peekArrayAttr(ti) == null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { - // In this case, the array isn't symbolic - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // The symbolic object was concretized during AALOAD or ALOAD, so nothing is symbolic here - return super.execute(ti); - } else { - // The array is not symbolic, but the index is. - // We try to store the object in each possible slot - ElementInfo arrayInfo = ti.getElementInfo(arrayRef); - if (!ti.isFirstStepInsn()) { // first time around - cg = new PCChoiceGenerator(arrayInfo.arrayLength() +2); - ((PCChoiceGenerator) cg).setOffset(this.position); - ((PCChoiceGenerator) cg).setMethodName(this.getMethodInfo().getFullName()); - ti.getVM().setNextChoiceGenerator(cg); - return this; - } else { // this is what really returns results - cg = ti.getVM().getChoiceGenerator(); - assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; - } - - PathCondition pc; - ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - if (prev_cg == null) - pc = new PathCondition(); - else - pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); - - assert pc != null; - - indexAttr = (IntegerExpression) peekIndexAttr(ti); // We know that the index is here symbolic - - assert (indexAttr != null) : "indexAttr shouldn't be null in AASTORE instruction"; - - int currentChoice = (Integer)cg.getNextChoice(); - - if (currentChoice < arrayInfo.arrayLength()) { - pc._addDet(Comparator.EQ, indexAttr, new IntegerConstant(currentChoice)); - if (pc.simplify()) { // We can store at this index - int value = frame.peek(); - arrayRef = frame.peek(2); - ElementInfo eiArray = ti.getModifiableElementInfo(arrayRef); - eiArray.setReferenceElement(currentChoice, value); - - frame.pop(3); - return getNext(ti); - } else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } else if (currentChoice == arrayInfo.arrayLength()) { - pc._addDet(Comparator.GE, indexAttr, new IntegerConstant(arrayInfo.arrayLength())); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index greater than array bounds"); - } else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } else { - pc._addDet(Comparator.LT, indexAttr, new IntegerConstant(0)); - if (pc.simplify()) { - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index smaller than array bounds"); - } else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - } - } - - - if (!ti.isFirstStepInsn()) { // first time around - cg = new PCChoiceGenerator(3); - ((PCChoiceGenerator) cg).setOffset(this.position); - ((PCChoiceGenerator) cg).setMethodName(this.getMethodInfo().getFullName()); - ti.getVM().setNextChoiceGenerator(cg); - return this; - } else { // this is what really returns results - cg = ti.getVM().getChoiceGenerator(); - assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; - } - - PathCondition pc; - ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - if (prev_cg == null) - pc = new PathCondition(); - else - pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); - - assert pc != null; - - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - int index = ti.getTopFrame().peek(1); - indexAttr = new IntegerConstant(index); - } else { - indexAttr = (IntegerExpression)peekIndexAttr(ti); - } - assert (indexAttr != null) : "indexAttr shouldn't be null in AASTORE instruction"; - - if (peekArrayAttr(ti) == null || !(peekArrayAttr(ti) instanceof ObjectSymbolicArray)) { - // In this case the array isn't symbolic, and we checked earlier that the index was symbolic - ElementInfo arrayInfo = ti.getElementInfo(arrayRef); - // We need to add information about the type of the elements in the array as well - arrayAttr = new ObjectSymbolicArray(arrayInfo.arrayLength()); - // We should add the constraints about the elements of the array here - // TODO - throw new RuntimeException("constant object array with symbolic index not implemented"); - } else { - arrayAttr = (ObjectSymbolicArray)peekArrayAttr(ti); - } - assert (arrayAttr != null) : "arrayAttr shouldn't be null in AASTORE instruction"; - - if (arrayRef == MJIEnv.NULL) { + if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) + return super.execute(ti); + StackFrame frame = ti.getModifiableTopFrame(); + int arrayref = peekArrayRef(ti); // need to be polymorphic, could be LongArrayStore + ElementInfo eiArray = ti.getElementInfo(arrayref); + + if (arrayref == MJIEnv.NULL) { return ti.createAndThrowException("java.lang.NullPointerException"); } + + + int len=(eiArray.getArrayFields()).arrayLength(); // assumed concrete + + if(!ti.isFirstStepInsn()){ + PCChoiceGenerator arrayCG = new PCChoiceGenerator(0,len+1); // add 2 error cases: <0, >=len + ti.getVM().getSystemState().setNextChoiceGenerator(arrayCG); + + //ti.reExecuteInstruction(); + if (SymbolicInstructionFactory.debugMode) + System.out.println("# array cg registered: " + arrayCG); + return this; + + } else { //this is what really returns results + + + + //index = frame.peek(); + PCChoiceGenerator lastCG=ti.getVM().getSystemState().getLastChoiceGeneratorOfType(PCChoiceGenerator.class); + assert(lastCG!=null); + PCChoiceGenerator prevCG=lastCG.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + index=lastCG.getNextChoice(); + IntegerExpression sym_index=(IntegerExpression)peekIndexAttr(ti); + //check the constraint + + PathCondition pc; + + if (prevCG == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prevCG).getCurrentPC(); + + assert pc != null; + + if(index what if the value is the same but not the attr? + + } catch (ArrayIndexOutOfBoundsExecutiveException ex) { // at this point, the AIOBX is already processed + return ex.getInstruction(); + } + + return getNext(ti); + } + } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/ALOAD.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/ALOAD.java index 2daf300..1a2ce49 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/ALOAD.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/ALOAD.java @@ -19,8 +19,8 @@ package gov.nasa.jpf.symbc.bytecode; import gov.nasa.jpf.Config; -import gov.nasa.jpf.symbc.arrays.ArrayExpression; import gov.nasa.jpf.symbc.SymbolicInstructionFactory; +import gov.nasa.jpf.symbc.arrays.ArrayExpression; import gov.nasa.jpf.symbc.heap.HeapChoiceGenerator; import gov.nasa.jpf.symbc.heap.HeapNode; import gov.nasa.jpf.symbc.heap.Helper; @@ -38,7 +38,6 @@ import gov.nasa.jpf.vm.ElementInfo; import gov.nasa.jpf.vm.Instruction; import gov.nasa.jpf.vm.KernelState; -import gov.nasa.jpf.vm.MJIEnv; import gov.nasa.jpf.vm.StackFrame; import gov.nasa.jpf.vm.SystemState; //import gov.nasa.jpf.symbc.uberlazy.TypeHierarchy; @@ -58,7 +57,6 @@ public ALOAD(int localVarIndex) { @Override public Instruction execute (ThreadInfo th) { - HeapNode[] prevSymRefs = null; // previously initialized objects of same type: candidates for lazy init int numSymRefs = 0; // # of prev. initialized objects ChoiceGenerator prevHeapCG = null; @@ -70,6 +68,7 @@ public Instruction execute (ThreadInfo th) { // TODO: fix handle polymorphism + StackFrame sf = th.getModifiableTopFrame(); int objRef = sf.peek(); ElementInfo ei = th.getElementInfo(objRef); @@ -154,7 +153,7 @@ public Instruction execute (ThreadInfo th) { } else if (currentChoice == numSymRefs && !(((IntegerExpression)attr).toString()).contains("this")){ //null object pcHeap._addDet(Comparator.EQ, (SymbolicInteger) attr, new IntegerConstant(-1)); - daIndex = MJIEnv.NULL; + daIndex = -1; } else if ((currentChoice == (numSymRefs + 1) && !abstractClass) | (currentChoice == numSymRefs && (((IntegerExpression)attr).toString()).contains("this"))) { //creates a new object with all fields symbolic diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/ARRAYLENGTH.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/ARRAYLENGTH.java deleted file mode 100644 index ad5f79d..0000000 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/ARRAYLENGTH.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2014, United States Government, as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All rights reserved. - * - * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package gov.nasa.jpf.symbc.bytecode; - -import gov.nasa.jpf.symbc.arrays.ArrayExpression; -import gov.nasa.jpf.symbc.numeric.*; -import gov.nasa.jpf.vm.ChoiceGenerator; -import gov.nasa.jpf.vm.Instruction; -import gov.nasa.jpf.vm.StackFrame; -import gov.nasa.jpf.vm.ThreadInfo; - -public class ARRAYLENGTH extends gov.nasa.jpf.jvm.bytecode.ARRAYLENGTH { - - public Object peekArrayAttr(ThreadInfo ti) { - return ti.getTopFrame().getOperandAttr(0); - } - - @Override - public Instruction execute (ThreadInfo th) { - StackFrame frame = th.getModifiableTopFrame(); - - if (peekArrayAttr(th) == null || !(peekArrayAttr(th) instanceof ArrayExpression)) { - return super.execute(th); - } - - ArrayExpression arrayAttr = (ArrayExpression)peekArrayAttr(th); - frame.pop(1); // We pop the array - frame.push(0, false); // The concrete value does not matter - frame.setOperandAttr(arrayAttr.length); - - return getNext(th); - } -} - - - - diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/BALOAD.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/BALOAD.java index b6bb2df..5b404cd 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/BALOAD.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/BALOAD.java @@ -23,17 +23,11 @@ import gov.nasa.jpf.symbc.SymbolicInstructionFactory; -import gov.nasa.jpf.symbc.arrays.ArrayExpression; -import gov.nasa.jpf.symbc.arrays.SelectExpression; -import gov.nasa.jpf.symbc.arrays.IntegerSymbolicArray; -import gov.nasa.jpf.symbc.arrays.SymbolicIntegerValueAtIndex; import gov.nasa.jpf.symbc.numeric.Comparator; -import gov.nasa.jpf.symbc.numeric.IntegerConstant; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; import gov.nasa.jpf.symbc.numeric.PathCondition; import gov.nasa.jpf.vm.ArrayIndexOutOfBoundsExecutiveException; -import gov.nasa.jpf.vm.ChoiceGenerator; import gov.nasa.jpf.vm.ElementInfo; import gov.nasa.jpf.vm.Instruction; import gov.nasa.jpf.vm.MJIEnv; @@ -49,124 +43,117 @@ public class BALOAD extends gov.nasa.jpf.jvm.bytecode.BALOAD { @Override public Instruction execute (ThreadInfo ti) { - - if (peekArrayAttr(ti)==null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { - // In this case, the array isn't symbolic - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case, the index isn't symbolic either - return super.execute(ti); - } - } - - IntegerSymbolicArray arrayAttr = null; - ChoiceGenerator cg; - boolean condition; - StackFrame frame = ti.getModifiableTopFrame(); - arrayRef = frame.peek(1); // ..., arrayRef, idx - - if (!ti.isFirstStepInsn()) { // first time around - cg = new PCChoiceGenerator(3); - ((PCChoiceGenerator)cg).setOffset(this.position); - ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); - ti.getVM().setNextChoiceGenerator(cg); - return this; - } else { // this is what really returns results - cg = ti.getVM().getChoiceGenerator(); - assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; - } - - PathCondition pc; - ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - if (prev_cg == null) - pc = new PathCondition(); - else - pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); - - assert pc != null; - - if (peekArrayAttr(ti)==null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { - // In this case, the array isn't symbolic - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case, the index isn't symbolic either - return super.execute(ti); - } - // We have a concrete array, but a symbolic index. We add all the constraints about the elements of the array, and perform the select - ElementInfo arrayInfo = ti.getElementInfo(arrayRef); - arrayAttr = new IntegerSymbolicArray(arrayInfo.arrayLength()); - for (int i = 0; i < arrayInfo.arrayLength(); i++) { - byte arrValue = arrayInfo.getByteElement(i); - pc._addDet(Comparator.EQ, new SelectExpression(arrayAttr, i), new IntegerConstant(arrValue)); - } - } - - else { - arrayAttr = (IntegerSymbolicArray)peekArrayAttr(ti); - } - IntegerExpression indexAttr = null; - SelectExpression se = null; - - if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case, the index isn't symbolic. - index = frame.peek(); - se = new SelectExpression(arrayAttr, index); - indexAttr = new IntegerConstant(index); - - } else { - indexAttr = (IntegerExpression)peekIndexAttr(ti); - se = new SelectExpression(arrayAttr, indexAttr); - } - - assert arrayAttr != null; - assert indexAttr != null; - assert se != null; - - if (arrayRef == MJIEnv.NULL) { - return ti.createAndThrowException("java.lang.NullPointerException"); - } - - - if ((Integer)cg.getNextChoice()==1) { // check bounds of the index - pc._addDet(Comparator.GE, se.index, se.ae.length); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index greater than array bounds"); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - else if ((Integer)cg.getNextChoice()==2) { - pc._addDet(Comparator.LT, se.index, new IntegerConstant(0)); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index smaller than array bounds"); - } else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - else { - pc._addDet(Comparator.LT, se.index, se.ae.length); - pc._addDet(Comparator.GE, se.index, new IntegerConstant(0)); - if (pc.simplify()) { //satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - - // set the result - // We update the Symbolic Array with the get information - SymbolicIntegerValueAtIndex result = arrayAttr.getBoolVal(indexAttr); - frame.pop(2); // We pop the array and the index - frame.push(0, false); - frame.setOperandAttr(result.value); - pc._addDet(Comparator.EQ, se, result.value); - return getNext(ti); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - } -} + + if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) + return super.execute(ti); + StackFrame frame = ti.getModifiableTopFrame(); + arrayRef = frame.peek(1); // ..,arrayRef,idx + if (arrayRef == MJIEnv.NULL) { + return ti.createAndThrowException("java.lang.NullPointerException"); + } + + ElementInfo eiArray = ti.getElementInfo(arrayRef); + int len=(eiArray.getArrayFields()).arrayLength(); // assumed concrete + if(!ti.isFirstStepInsn()){ + PCChoiceGenerator arrayCG = new PCChoiceGenerator(0,len+1); // add 2 error cases: <0, >=len + ti.getVM().getSystemState().setNextChoiceGenerator(arrayCG); + + if (SymbolicInstructionFactory.debugMode) + System.out.println("# array cg registered: " + arrayCG); + return this; + + } else { //this is what really returns results + + //index = frame.peek(); + PCChoiceGenerator lastCG=ti.getVM().getSystemState().getLastChoiceGeneratorOfType(PCChoiceGenerator.class); + assert(lastCG!=null); + PCChoiceGenerator prevCG=lastCG.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + index=lastCG.getNextChoice(); + //System.out.println("array index "+index); + IntegerExpression sym_index=(IntegerExpression)peekIndexAttr(ti); + //check the constraint + + PathCondition pc; + + if (prevCG == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prevCG).getCurrentPC(); + + assert pc != null; + + if(index cg; - boolean condition; - int arrayRef = peekArrayRef(ti); // need to be polymorphic, could be LongArrayStore - - if (!ti.isFirstStepInsn()) { // first time around - cg = new PCChoiceGenerator(3); - ((PCChoiceGenerator) cg).setOffset(this.position); - ((PCChoiceGenerator) cg).setMethodName(this.getMethodInfo().getFullName()); - ti.getVM().setNextChoiceGenerator(cg); - return this; - } else { // this is what really returns results - cg = ti.getVM().getChoiceGenerator(); - assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; - } - - PathCondition pc; - ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - if (prev_cg == null) - pc = new PathCondition(); - else - pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); - - assert pc != null; - - if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - int index = ti.getTopFrame().peek(1); - indexAttr = new IntegerConstant(index); - } else { - indexAttr = (IntegerExpression)peekIndexAttr(ti); - } - assert (indexAttr != null) : "indexAttr shouldn't be null in IASTORE instruction"; - - if (peekArrayAttr(ti)==null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { - //In this case, the array isn't symbolic - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - if (frame.getOperandAttr(0) == null || !(frame.getOperandAttr(0) instanceof IntegerExpression)) { - // nothing is symbolic here - return super.execute(ti); - } - } else { - // We create a symbolic array out of the concrete array - ElementInfo arrayInfo = ti.getElementInfo(arrayRef); - arrayAttr = new IntegerSymbolicArray(arrayInfo.arrayLength()); - // We add the constraints about all the elements of the array - for (int i = 0; i < arrayInfo.arrayLength(); i++) { - byte arrValue = arrayInfo.getByteElement(i); - pc._addDet(Comparator.EQ, new SelectExpression(arrayAttr, i), new IntegerConstant(arrValue)); - } - } - } else { - arrayAttr = (IntegerSymbolicArray)peekArrayAttr(ti); - } - assert (arrayAttr != null) : "arrayAttr shouldn't be null in IASTORE instruction"; - - if (arrayRef == MJIEnv.NULL) { + int arrayref = peekArrayRef(ti); // need to be polymorphic, could be LongArrayStore + ElementInfo eiArray = ti.getElementInfo(arrayref); + + if (arrayref == MJIEnv.NULL) { return ti.createAndThrowException("java.lang.NullPointerException"); } + + + int len=(eiArray.getArrayFields()).arrayLength(); // assumed concrete + + if(!ti.isFirstStepInsn()){ + PCChoiceGenerator arrayCG = new PCChoiceGenerator(0,len+1); // add 2 error cases: <0, >=len + ti.getVM().getSystemState().setNextChoiceGenerator(arrayCG); + + //ti.reExecuteInstruction(); + if (SymbolicInstructionFactory.debugMode) + System.out.println("# array cg registered: " + arrayCG); + return this; + + } else { //this is what really returns results + + + + //index = frame.peek(); + PCChoiceGenerator lastCG=ti.getVM().getSystemState().getLastChoiceGeneratorOfType(PCChoiceGenerator.class); + assert(lastCG!=null); + PCChoiceGenerator prevCG=lastCG.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + index=lastCG.getNextChoice(); + IntegerExpression sym_index=(IntegerExpression)peekIndexAttr(ti); + //check the constraint + + PathCondition pc; + + if (prevCG == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prevCG).getCurrentPC(); + + assert pc != null; + + if(index what if the value is the same but not the attr? + + } catch (ArrayIndexOutOfBoundsExecutiveException ex) { // at this point, the AIOBX is already processed + return ex.getInstruction(); + } + + return getNext(ti); + } + } + + - - if ((Integer)cg.getNextChoice() == 1) { // check bounds of the index - pc._addDet(Comparator.GE, indexAttr, arrayAttr.length); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index greater than array bounds"); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - else if ((Integer)cg.getNextChoice() == 2) { - pc._addDet(Comparator.LT, indexAttr, new IntegerConstant(0)); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index smaller than array bounds"); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - else { - pc._addDet(Comparator.LT, indexAttr, arrayAttr.length); - pc._addDet(Comparator.GE, indexAttr, new IntegerConstant(0)); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - - // set the result - - // We have to check if the value is symbolic or not, create a symbolicIntegerValueatIndex out of it, and - // call the setVal function, before storing the attr - IntegerExpression sym_value = null; - if (frame.getOperandAttr(0) == null || !(frame.getOperandAttr(0) instanceof IntegerExpression)) { - // The value isn't symbolic. We store a new IntegerConstant in the valAt map, at index indexAttr - int value = frame.pop(); - sym_value = new IntegerConstant(value); - } - else { - // The value is symbolic. - sym_value = (IntegerExpression)frame.getOperandAttr(0); - frame.pop(); - } - PreviousIntegerArray previous = new PreviousIntegerArray(arrayAttr, indexAttr, sym_value); - // We create a new arrayAttr, and inherits information from the previous attribute - IntegerSymbolicArray newArrayAttr = new IntegerSymbolicArray(previous); - frame.pop(2); // We pop the array and the index - - StoreExpression se = new StoreExpression(arrayAttr, indexAttr, sym_value); - pc._addDet(Comparator.EQ, se, newArrayAttr); - - return getNext(ti); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - } - } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/BytecodeUtils.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/BytecodeUtils.java index 83f3ef0..9010859 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/BytecodeUtils.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/BytecodeUtils.java @@ -21,13 +21,14 @@ import gov.nasa.jpf.Config; - import gov.nasa.jpf.jvm.bytecode.JVMInvokeInstruction; -import gov.nasa.jpf.symbc.arrays.IntegerSymbolicArray; -import gov.nasa.jpf.symbc.arrays.ObjectSymbolicArray; +import gov.nasa.jpf.symbc.arrays.ArrayExpression; import gov.nasa.jpf.symbc.heap.Helper; +import gov.nasa.jpf.symbc.numeric.Comparator; import gov.nasa.jpf.symbc.numeric.Expression; +import gov.nasa.jpf.symbc.numeric.IntegerConstant; import gov.nasa.jpf.symbc.numeric.IntegerExpression; +import gov.nasa.jpf.symbc.numeric.MinMax; import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; import gov.nasa.jpf.symbc.numeric.PathCondition; import gov.nasa.jpf.symbc.numeric.PreCondition; @@ -44,10 +45,11 @@ import gov.nasa.jpf.vm.Instruction; import gov.nasa.jpf.vm.LocalVarInfo; import gov.nasa.jpf.vm.MethodInfo; +import gov.nasa.jpf.vm.MJIEnv; import gov.nasa.jpf.vm.StackFrame; import gov.nasa.jpf.vm.SystemState; import gov.nasa.jpf.vm.ThreadInfo; - + import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; @@ -210,14 +212,19 @@ public static InstructionOrSuper execute(JVMInvokeInstruction invInst, ThreadInf Vector args = new Vector(); Config conf = th.getVM().getConfig(); - - // Start string handling + + // Start string handling: TODO corina it needs reviewing as it does not seem to be correct /**** This is where we branch off to handle symbolic string variables *******/ - SymbolicStringHandler a = new SymbolicStringHandler(); - Instruction handled = a.handleSymbolicStrings(invInst, th); - if(handled != null){ // go to next instruction as symbolic string operation was done - System.out.println("Symbolic string analysis"); + String[] symstrings = conf.getStringArray("symbolic.strings"); + boolean symstrings_flag = (symstrings != null && symstrings[0].equalsIgnoreCase("true"))? true : false; + if(symstrings_flag) { + + SymbolicStringHandler a = new SymbolicStringHandler(); + Instruction handled = a.handleSymbolicStrings(invInst, th); + if(handled != null){ // go to next instruction as symbolic string operation was done +// System.out.println("Symbolic string analysis!!!"+invInst); return new InstructionOrSuper(false, handled); + } } // End string handling @@ -231,7 +238,6 @@ public static InstructionOrSuper execute(JVMInvokeInstruction invInst, ThreadInf // create a choice generator to associate the precondition with it ChoiceGenerator cg = null; - if (invInst.getInvokedMethod().getAnnotation("gov.nasa.jpf.symbc.Preconditions") != null) { if (!th.isFirstStepInsn()) { // first time around cg = new PCChoiceGenerator(1); th.getVM().setNextChoiceGenerator(cg); @@ -241,7 +247,6 @@ public static InstructionOrSuper execute(JVMInvokeInstruction invInst, ThreadInf if (!(cg instanceof PCChoiceGenerator)) // the choice comes from super return new InstructionOrSuper(true, null); } - } String outputString = "\n***Execute symbolic " + bytecodeName + ": " + mname + " ("; @@ -270,6 +275,11 @@ public static InstructionOrSuper execute(JVMInvokeInstruction invInst, ThreadInf // special treatment of "this" String lazy[] = conf.getStringArray("symbolic.lazy"); + String symarrays[] = conf.getStringArray("symbolic.arrays"); + boolean symarray = false; + if (symarrays != null) { + symarray = symarrays[0].equalsIgnoreCase("true"); + } //TODO: to review // if(lazy != null) { // if(lazy[0].equalsIgnoreCase("true")) { @@ -286,13 +296,38 @@ public static InstructionOrSuper execute(JVMInvokeInstruction invInst, ThreadInf for (int j = 0; j < argSize; j++) { // j ranges over actual arguments if (symClass || args.get(j).equalsIgnoreCase("SYM")) { String name = argsInfo[localVarsIdx].getName(); - if (argTypes[j].equalsIgnoreCase("int") || argTypes[j].equalsIgnoreCase("long")) { + if (argTypes[j].equalsIgnoreCase("int")) { IntegerExpression sym_v = new SymbolicInteger(varName(name, VarType.INT)); expressionMap.put(name, sym_v); sf.setOperandAttr(stackIdx, sym_v); - outputString = outputString.concat(" " + sym_v + ","); + outputString = outputString.concat(" " + sym_v + ","); + } else if (argTypes[j].equalsIgnoreCase("long")) { + String varname = varName(name, VarType.INT); + IntegerExpression sym_v = new SymbolicInteger(varname, MinMax.getVarMinLong(varname), MinMax.getVarMaxLong(varname)); + expressionMap.put(name, sym_v); + sf.setOperandAttr(stackIdx, sym_v); + outputString = outputString.concat(" " + sym_v + ","); + } else if (argTypes[j].equalsIgnoreCase("short")) { + String varname = varName(name, VarType.INT); + IntegerExpression sym_v = new SymbolicInteger(varname, MinMax.getVarMinShort(varname), MinMax.getVarMaxShort(varname)); + expressionMap.put(name, sym_v); + sf.setOperandAttr(stackIdx, sym_v); + outputString = outputString.concat(" " + sym_v + ","); + } else if (argTypes[j].equalsIgnoreCase("byte")) { + String varname = varName(name, VarType.INT); + IntegerExpression sym_v = new SymbolicInteger(varname, MinMax.getVarMinByte(varname), MinMax.getVarMaxByte(varname)); + expressionMap.put(name, sym_v); + sf.setOperandAttr(stackIdx, sym_v); + outputString = outputString.concat(" " + sym_v + ","); + } else if (argTypes[j].equalsIgnoreCase("char")) { + String varname = varName(name, VarType.INT); + IntegerExpression sym_v = new SymbolicInteger(varname, MinMax.getVarMinChar(varname), MinMax.getVarMaxChar(varname)); + expressionMap.put(name, sym_v); + sf.setOperandAttr(stackIdx, sym_v); + outputString = outputString.concat(" " + sym_v + ","); } else if (argTypes[j].equalsIgnoreCase("float") || argTypes[j].equalsIgnoreCase("double")) { - RealExpression sym_v = new SymbolicReal(varName(name, VarType.REAL)); + String varname = varName(name, VarType.REAL); + RealExpression sym_v = new SymbolicReal(varname, MinMax.getVarMinDouble(varname), MinMax.getVarMaxDouble(varname)); expressionMap.put(name, sym_v); sf.setOperandAttr(stackIdx, sym_v); outputString = outputString.concat(" " + sym_v + ","); @@ -307,45 +342,117 @@ public static InstructionOrSuper execute(JVMInvokeInstruction invInst, ThreadInf expressionMap.put(name, sym_v); sf.setOperandAttr(stackIdx, sym_v); outputString = outputString.concat(" " + sym_v + ","); - } else if(argTypes[j].equalsIgnoreCase("int[]") || argTypes[j].equalsIgnoreCase("long[]")){ - Object[] argValues = invInst.getArgumentValues(th); - ElementInfo eiArray = (ElementInfo)argValues[j]; - - IntegerSymbolicArray sym_v = new IntegerSymbolicArray(new SymbolicInteger(name + "!length"), varName(name, VarType.ARRAY)); - expressionMap.put(name, sym_v); - sf.setOperandAttr(stackIdx, sym_v); - outputString = outputString.concat(" " + sym_v + ","); + } else if(argTypes[j].equalsIgnoreCase("int[]") || argTypes[j].equalsIgnoreCase("long[]") || argTypes[j].equalsIgnoreCase("byte[]")){ + if (symarray) { + ArrayExpression sym_v = new ArrayExpression(name); + expressionMap.put(name, sym_v); + sf.setOperandAttr(stackIdx, sym_v); + outputString = outputString.concat(" " + sym_v + ","); + PCChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + PathCondition pc; + if (prev_cg == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); + pc._addDet(Comparator.GE, sym_v.length, new IntegerConstant(0)); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + } else { + Object[] argValues = invInst.getArgumentValues(th); + ElementInfo eiArray = (ElementInfo)argValues[j]; + + if(eiArray!=null) + for(int i =0; i< eiArray.arrayLength(); i++) { + IntegerExpression sym_v = new SymbolicInteger(varName(name+i, VarType.INT)); + expressionMap.put(name+i, sym_v); + eiArray.addElementAttr(i, sym_v); + outputString = outputString.concat(" " + sym_v + ","); + } + else + System.out.println("Warning: input array empty! "+name); + } } else if(argTypes[j].equalsIgnoreCase("float[]") || argTypes[j].equalsIgnoreCase("double[]")){ - Object[] argValues = invInst.getArgumentValues(th); - ElementInfo eiArray = (ElementInfo)argValues[j]; - - for(int i =0; i< eiArray.arrayLength(); i++) { - RealExpression sym_v = new SymbolicReal(varName(name+i, VarType.REAL)); - expressionMap.put(name+i, sym_v); - eiArray.addElementAttr(i, sym_v); - outputString = outputString.concat(" " + sym_v + ","); - } + if (symarray) { + ArrayExpression sym_v = new ArrayExpression(name); + expressionMap.put(name, sym_v); + sf.setOperandAttr(stackIdx, sym_v); + outputString = outputString.concat(" " + sym_v + ","); + + PCChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + PathCondition pc; + if (prev_cg == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); + + pc._addDet(Comparator.GE, sym_v.length, new IntegerConstant(0)); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + } else { + Object[] argValues = invInst.getArgumentValues(th); + ElementInfo eiArray = (ElementInfo)argValues[j]; + + if(eiArray!=null) + for(int i =0; i< eiArray.arrayLength(); i++) { + RealExpression sym_v = new SymbolicReal(varName(name+i, VarType.REAL)); + expressionMap.put(name+i, sym_v); + eiArray.addElementAttr(i, sym_v); + outputString = outputString.concat(" " + sym_v + ","); + } + else + System.out.println("Warning: input array empty! "+name); + } } else if(argTypes[j].equalsIgnoreCase("boolean[]")){ - Object[] argValues = invInst.getArgumentValues(th); - ElementInfo eiArray = (ElementInfo)argValues[j]; - - IntegerSymbolicArray sym_v = new IntegerSymbolicArray(new SymbolicInteger(name + "!length"), varName(name, VarType.ARRAY)); - expressionMap.put(name, sym_v); - sf.setOperandAttr(stackIdx, sym_v); - outputString = outputString.concat(" " + sym_v + ","); + if (symarray) { + ArrayExpression sym_v = new ArrayExpression(name); + expressionMap.put(name, sym_v); + sf.setOperandAttr(stackIdx, sym_v); + outputString = outputString.concat(" " + sym_v + ","); + + PCChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + PathCondition pc; + if (prev_cg == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); + pc._addDet(Comparator.GE, sym_v.length, new IntegerConstant(0)); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + } else { + Object[] argValues = invInst.getArgumentValues(th); + ElementInfo eiArray = (ElementInfo)argValues[j]; + + if(eiArray!=null) + for(int i =0; i< eiArray.arrayLength(); i++) { + IntegerExpression sym_v = new SymbolicInteger(varName(name+i, VarType.INT),0,1); + expressionMap.put(name+i, sym_v); + eiArray.addElementAttr(i, sym_v); + outputString = outputString.concat(" " + sym_v + ","); + } + else + System.out.println("Warning: input array empty! "+name); + } } else if (argTypes[j].contains("[]")) { - // If the type name contains [] but wasn't catched previously, then it is an object array - Object[] argValues = invInst.getArgumentValues(th); - ElementInfo eiArray = (ElementInfo)argValues[j]; + if (symarray) { + Object[] argValues = invInst.getArgumentValues(th); + ElementInfo eiArray = (ElementInfo)argValues[j]; + // If the type name contains [] but wasn't catched previously, it is an object array + ArrayExpression sym_v = new ArrayExpression(name, argTypes[j].substring(0, argTypes[j].length() - 2)); + // We remove the [] at the end of the type to keep only the type of the object + expressionMap.put(name, sym_v); + sf.setOperandAttr(stackIdx, sym_v); + outputString = outputString.concat(" " + sym_v + ","); - ObjectSymbolicArray sym_v = new ObjectSymbolicArray(new SymbolicInteger(name + "!length"), varName(name, VarType.ARRAY), argTypes[j]); - expressionMap.put(name, sym_v); - sf.setOperandAttr(stackIdx, sym_v); - outputString = outputString.concat(" " + sym_v + ","); - + PCChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + PathCondition pc; + if (prev_cg == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); + + pc._addDet(Comparator.GE, sym_v.length, new IntegerConstant(0)); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + } } else { // the argument is of reference type and it is symbolic if(lazy != null) { @@ -399,7 +506,7 @@ else if (s.equalsIgnoreCase("static")) ei = th.getElementInfo(ci.getClassObjectRef()); } else { int objRef = th.getCalleeThis(invInst.getArgSize()); - if (objRef == -1) { // NPE + if (objRef == MJIEnv.NULL) { // NPE return new InstructionOrSuper(false, th.createAndThrowException("java.lang.NullPointerException", "calling '" + mname + "' on null object")); @@ -538,7 +645,7 @@ public static void clearSymVarCounter() { } public enum VarType { - INT, REAL, REF, STRING, ARRAY + INT, REAL, REF, STRING }; @@ -557,9 +664,6 @@ public static String varName(String name, VarType type) { case STRING: suffix = "_SYMSTRING"; break; - case ARRAY: - suffix = "_SYMARRAY"; - break; default: throw new RuntimeException("Unhandled SymVarType: " + type); } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/CALOAD.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/CALOAD.java index e5af0c1..53f300f 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/CALOAD.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/CALOAD.java @@ -21,18 +21,12 @@ package gov.nasa.jpf.symbc.bytecode; -import gov.nasa.jpf.symbc.arrays.ArrayExpression; -import gov.nasa.jpf.symbc.arrays.SelectExpression; -import gov.nasa.jpf.symbc.arrays.IntegerSymbolicArray; -import gov.nasa.jpf.symbc.arrays.SymbolicIntegerValueAtIndex; import gov.nasa.jpf.symbc.SymbolicInstructionFactory; import gov.nasa.jpf.symbc.numeric.Comparator; -import gov.nasa.jpf.symbc.numeric.IntegerConstant; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; import gov.nasa.jpf.symbc.numeric.PathCondition; import gov.nasa.jpf.vm.ArrayIndexOutOfBoundsExecutiveException; -import gov.nasa.jpf.vm.ChoiceGenerator; import gov.nasa.jpf.vm.ElementInfo; import gov.nasa.jpf.vm.Instruction; import gov.nasa.jpf.vm.MJIEnv; @@ -49,115 +43,115 @@ public class CALOAD extends gov.nasa.jpf.jvm.bytecode.CALOAD { @Override public Instruction execute (ThreadInfo ti) { - if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case, the array isn't symbolic - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case, the index isn't symbolic either - return super.execute(ti); - } - } - - IntegerSymbolicArray arrayAttr = null; - ChoiceGenerator cg; - boolean condition; - StackFrame frame = ti.getModifiableTopFrame(); + if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) + return super.execute(ti); + StackFrame frame = ti.getModifiableTopFrame(); arrayRef = frame.peek(1); // ..,arrayRef,idx + if (arrayRef == MJIEnv.NULL) { + return ti.createAndThrowException("java.lang.NullPointerException"); + } + + ElementInfo eiArray = ti.getElementInfo(arrayRef); + int len=(eiArray.getArrayFields()).arrayLength(); // assumed concrete + if(!ti.isFirstStepInsn()){ + PCChoiceGenerator arrayCG = new PCChoiceGenerator(0,len+1); // add 2 error cases: <0, >=len + ti.getVM().getSystemState().setNextChoiceGenerator(arrayCG); + + if (SymbolicInstructionFactory.debugMode) + System.out.println("# array cg registered: " + arrayCG); + return this; - if (!ti.isFirstStepInsn()) { // first time around - cg = new PCChoiceGenerator(3); - ((PCChoiceGenerator)cg).setOffset(this.position); - ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); - ti.getVM().setNextChoiceGenerator(cg); - return this; - } else { // this is what really returns results - cg = ti.getVM().getChoiceGenerator(); - assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; - } - - PathCondition pc; - ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - if (prev_cg == null) - pc = new PathCondition(); - else - pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); - - assert pc != null; - - if (peekArrayAttr(ti) == null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { - // In this case, the array isn't symbolic - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case, the index isn't symbolic either - return super.execute(ti); - } - // We have a concrete array, but a symbolic index. We add all the constraints and perform the select - ElementInfo arrayInfo = ti.getElementInfo(arrayRef); - arrayAttr = new IntegerSymbolicArray(arrayInfo.arrayLength()); - for (int i = 0; i < arrayInfo.arrayLength(); i++) { - int arrValue = arrayInfo.getCharElement(i); - pc._addDet(Comparator.EQ, new SelectExpression(arrayAttr, i), new IntegerConstant(arrValue)); - } - } else { - arrayAttr = (IntegerSymbolicArray)peekArrayAttr(ti); - } - IntegerExpression indexAttr = null; - SelectExpression se = null; - - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case, the index isn't symbolic. - index = frame.peek(); - se = new SelectExpression(arrayAttr, index); - indexAttr = new IntegerConstant(index); - } else { - indexAttr = (IntegerExpression)peekIndexAttr(ti); - se = new SelectExpression(arrayAttr, indexAttr); - } - - assert arrayAttr != null; - assert indexAttr != null; - assert se != null; + } else { //this is what really returns results + + //index = frame.peek(); + PCChoiceGenerator lastCG=ti.getVM().getSystemState().getLastChoiceGeneratorOfType(PCChoiceGenerator.class); + assert(lastCG!=null); + PCChoiceGenerator prevCG=lastCG.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + index=lastCG.getNextChoice(); + //System.out.println("array index "+index); + IntegerExpression sym_index=(IntegerExpression)peekIndexAttr(ti); + //check the constraint + + PathCondition pc; + + if (prevCG == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prevCG).getCurrentPC(); - if (arrayRef == MJIEnv.NULL) { - return ti.createAndThrowException("java.lang.NullPointerException"); - } - - if ((Integer)cg.getNextChoice() == 1) { // check bounds of the index - pc._addDet(Comparator.GE, se.index, se.ae.length); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index greater than array bounds"); - } else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } else if ((Integer)cg.getNextChoice() == 2) { - pc._addDet(Comparator.LT, se.index, new IntegerConstant(0)); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index smaller than array bounds"); - } else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } else { - pc._addDet(Comparator.LT, se.index, se.ae.length); - pc._addDet(Comparator.GE, se.index, new IntegerConstant(0)); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); + assert pc != null; - // Set the result - // We update the Symbolic Array with the get information - SymbolicIntegerValueAtIndex result = arrayAttr.getVal(indexAttr); - // We had a concrete array, and don't know yet where it is from - frame.pop(2); // We pop the array and the index - frame.push(0, false); - frame.setOperandAttr(result.value); - pc._addDet(Comparator.EQ, se, result.value); - return getNext(ti); - } else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - } + if(index cg; - boolean condition; - int arrayRef = peekArrayRef(ti); // need to be polymorphic, could be LongArrayStore - - if (!ti.isFirstStepInsn()) { // first time around - cg = new PCChoiceGenerator(3); - ((PCChoiceGenerator) cg).setOffset(this.position); - ((PCChoiceGenerator) cg).setMethodName(this.getMethodInfo().getFullName()); - ti.getVM().setNextChoiceGenerator(cg); - return this; - } else { // this is what really returns results - cg = ti.getVM().getChoiceGenerator(); - assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; - } - - PathCondition pc; - ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - if (prev_cg == null) - pc = new PathCondition(); - else - pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); - - assert pc != null; - - if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - int index = ti.getTopFrame().peek(1); - indexAttr = new IntegerConstant(index); - } else { - indexAttr = (IntegerExpression)peekIndexAttr(ti); - } - assert (indexAttr != null) : "indexAttr shouldn't be null in IASTORE instruction"; - - if (peekArrayAttr(ti)==null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { - //In this case, the array isn't symbolic - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - if (frame.getOperandAttr(0) == null || !(frame.getOperandAttr(0) instanceof IntegerExpression)) { - // nothing is symbolic here - return super.execute(ti); - } - } else { - // We create a symbolic array out of the concrete array - ElementInfo arrayInfo = ti.getElementInfo(arrayRef); - arrayAttr = new IntegerSymbolicArray(arrayInfo.arrayLength()); - // We add the constraints about all the elements of the array - for (int i = 0; i < arrayInfo.arrayLength(); i++) { - int arrValue = arrayInfo.getCharElement(i); - pc._addDet(Comparator.EQ, new SelectExpression(arrayAttr, i), new IntegerConstant(arrValue)); - } - } - } else { - arrayAttr = (IntegerSymbolicArray)peekArrayAttr(ti); - } - assert (arrayAttr != null) : "arrayAttr shouldn't be null in IASTORE instruction"; - - if (arrayRef == MJIEnv.NULL) { + int arrayref = peekArrayRef(ti); // need to be polymorphic, could be LongArrayStore + ElementInfo eiArray = ti.getElementInfo(arrayref); + + if (arrayref == MJIEnv.NULL) { return ti.createAndThrowException("java.lang.NullPointerException"); } - - - if ((Integer)cg.getNextChoice() == 1) { // check bounds of the index - pc._addDet(Comparator.GE, indexAttr, arrayAttr.length); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index greater than array bounds"); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - else if ((Integer)cg.getNextChoice() == 2) { - pc._addDet(Comparator.LT, indexAttr, new IntegerConstant(0)); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index smaller than array bounds"); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - else { - pc._addDet(Comparator.LT, indexAttr, arrayAttr.length); - pc._addDet(Comparator.GE, indexAttr, new IntegerConstant(0)); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - - // set the result - - // We have to check if the value is symbolic or not, create a symbolicIntegerValueatIndex out of it, and - // call the setVal function, before storing the attr - IntegerExpression sym_value = null; - if (frame.getOperandAttr(0) == null || !(frame.getOperandAttr(0) instanceof IntegerExpression)) { - // The value isn't symbolic. We store a new IntegerConstant in the valAt map, at index indexAttr - int value = frame.pop(); - sym_value = new IntegerConstant(value); - } - else { - // The value is symbolic. - sym_value = (IntegerExpression)frame.getOperandAttr(0); - frame.pop(); - } - PreviousIntegerArray previous = new PreviousIntegerArray(arrayAttr, indexAttr, sym_value); - // We create a new arrayAttr, and inherits information from the previous attribute - IntegerSymbolicArray newArrayAttr = new IntegerSymbolicArray(previous); - frame.pop(2); // We pop the array and the index - - StoreExpression se = new StoreExpression(arrayAttr, indexAttr, sym_value); - pc._addDet(Comparator.EQ, se, newArrayAttr); - - return getNext(ti); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - } - + + + int len=(eiArray.getArrayFields()).arrayLength(); // assumed concrete + + if(!ti.isFirstStepInsn()){ + PCChoiceGenerator arrayCG = new PCChoiceGenerator(0,len+1); // add 2 error cases: <0, >=len + ti.getVM().getSystemState().setNextChoiceGenerator(arrayCG); + + //ti.reExecuteInstruction(); + if (SymbolicInstructionFactory.debugMode) + System.out.println("# array cg registered: " + arrayCG); + return this; + + } else { //this is what really returns results + + + + //index = frame.peek(); + PCChoiceGenerator lastCG=ti.getVM().getSystemState().getLastChoiceGeneratorOfType(PCChoiceGenerator.class); + assert(lastCG!=null); + PCChoiceGenerator prevCG=lastCG.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + index=lastCG.getNextChoice(); + IntegerExpression sym_index=(IntegerExpression)peekIndexAttr(ti); + //check the constraint + + PathCondition pc; + + if (prevCG == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prevCG).getCurrentPC(); + + assert pc != null; + + if(index what if the value is the same but not the attr? + + } catch (ArrayIndexOutOfBoundsExecutiveException ex) { // at this point, the AIOBX is already processed + return ex.getInstruction(); + } + + return getNext(ti); + } + } + + } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/DALOAD.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/DALOAD.java index 0773bd4..14e8f41 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/DALOAD.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/DALOAD.java @@ -40,8 +40,6 @@ public class DALOAD extends gov.nasa.jpf.jvm.bytecode.DALOAD { @Override public Instruction execute (ThreadInfo ti) { - - // This instruction is not yet implemented, Z3 does not support floats if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) return super.execute(ti); StackFrame frame = ti.getModifiableTopFrame(); @@ -49,7 +47,109 @@ public Instruction execute (ThreadInfo ti) { if (arrayRef == MJIEnv.NULL) { return ti.createAndThrowException("java.lang.NullPointerException"); } - throw new RuntimeException("Symbolic float Arrays not handled"); + + ElementInfo eiArray = ti.getElementInfo(arrayRef); + int len=(eiArray.getArrayFields()).arrayLength(); // assumed concrete + if(!ti.isFirstStepInsn()){ + PCChoiceGenerator arrayCG = new PCChoiceGenerator(0,len+1); // add 2 error cases: <0, >=len + ti.getVM().getSystemState().setNextChoiceGenerator(arrayCG); + + if (SymbolicInstructionFactory.debugMode) + System.out.println("# array cg registered: " + arrayCG); + return this; + + } else { //this is what really returns results + + //index = frame.peek(); + PCChoiceGenerator lastCG=ti.getVM().getSystemState().getLastChoiceGeneratorOfType(PCChoiceGenerator.class); + assert(lastCG!=null); + PCChoiceGenerator prevCG=lastCG.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + index=lastCG.getNextChoice(); + //System.out.println("array index "+index); + IntegerExpression sym_index=(IntegerExpression)peekIndexAttr(ti); + //check the constraint + + PathCondition pc; + + if (prevCG == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prevCG).getCurrentPC(); + + assert pc != null; + + if(index=len + ti.getVM().getSystemState().setNextChoiceGenerator(arrayCG); + + //ti.reExecuteInstruction(); + if (SymbolicInstructionFactory.debugMode) + System.out.println("# array cg registered: " + arrayCG); + return this; + + } else { //this is what really returns results + + + + //index = frame.peek(); + PCChoiceGenerator lastCG=ti.getVM().getSystemState().getLastChoiceGeneratorOfType(PCChoiceGenerator.class); + assert(lastCG!=null); + PCChoiceGenerator prevCG=lastCG.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + index=lastCG.getNextChoice(); + IntegerExpression sym_index=(IntegerExpression)peekIndexAttr(ti); + //check the constraint + + PathCondition pc; + + if (prevCG == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prevCG).getCurrentPC(); + + assert pc != null; + + if(index what if the value is the same but not the attr? + + } catch (ArrayIndexOutOfBoundsExecutiveException ex) { // at this point, the AIOBX is already processed + return ex.getInstruction(); + } + + return getNext(ti); + } } -} +} \ No newline at end of file diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/DCMPG.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/DCMPG.java index 0733759..d9b7d13 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/DCMPG.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/DCMPG.java @@ -18,7 +18,6 @@ package gov.nasa.jpf.symbc.bytecode; -import gov.nasa.jpf.symbc.bytecode.util.IFInstrSymbHelper; import gov.nasa.jpf.symbc.numeric.Comparator; import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; import gov.nasa.jpf.symbc.numeric.PathCondition; @@ -41,15 +40,89 @@ public Instruction execute(ThreadInfo th) { if (sym_v1 == null && sym_v2 == null) { // both conditions are concrete return super.execute(th); } else { // at least one condition is symbolic - Instruction nxtInstr = IFInstrSymbHelper.getNextInstructionAndSetPCChoiceDouble(th, - this, - sym_v1, - sym_v2, - Comparator.LT, - Comparator.EQ, - Comparator.GT); - - return nxtInstr; + ChoiceGenerator cg; + int conditionValue; + + if (!th.isFirstStepInsn()) { // first time around + cg = new PCChoiceGenerator(3); + ((PCChoiceGenerator)cg).setOffset(this.position); + ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); + th.getVM().getSystemState().setNextChoiceGenerator(cg); + return this; + } else { // this is what really returns results + ChoiceGenerator curCg = th.getVM().getSystemState().getChoiceGenerator(); + assert (curCg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + curCg; + cg = (PCChoiceGenerator)curCg; + conditionValue = cg.getNextChoice().intValue() -1; + } + + double v1 = Types.longToDouble(sf.popLong()); + double v2 = Types.longToDouble(sf.popLong()); + //System.out.println("Execute DCMPG: " + conditionValue); + PathCondition pc; + + // pc is updated with the pc stored in the choice generator above + // get the path condition from the + // previous choice generator of the same type + + ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + + if (prev_cg == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator) prev_cg).getCurrentPC(); + + assert pc != null; + + if (conditionValue == -1) { + if (sym_v1 != null) { + if (sym_v2 != null) { // both are symbolic values + pc._addDet(Comparator.LT, sym_v2, sym_v1); + } else + pc._addDet(Comparator.LT, v2, sym_v1); + } else + pc._addDet(Comparator.LT, sym_v2, v1); + if (!pc.simplify()) {// not satisfiable + th.getVM().getSystemState().setIgnored(true); + } else { + // pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + // System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + } else if (conditionValue == 0) { + if (sym_v1 != null) { + if (sym_v2 != null) { // both are symbolic values + pc._addDet(Comparator.EQ, sym_v1, sym_v2); + } else + pc._addDet(Comparator.EQ, sym_v1, v2); + } else + pc._addDet(Comparator.EQ, v1, sym_v2); + if (!pc.simplify()) {// not satisfiable + th.getVM().getSystemState().setIgnored(true); + } else { + // pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + // System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + } else { + if (sym_v1 != null) { + if (sym_v2 != null) { // both are symbolic values + pc._addDet(Comparator.GT, sym_v2, sym_v1); + } else + pc._addDet(Comparator.GT, v2, sym_v1); + } else + pc._addDet(Comparator.GT, sym_v2, v1); + if (!pc.simplify()) {// not satisfiable + th.getVM().getSystemState().setIgnored(true); + } else { + // pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + // System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + } + sf.push(conditionValue, false); + return getNext(th); } } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/DCMPL.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/DCMPL.java index 815551d..8fd636c 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/DCMPL.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/DCMPL.java @@ -18,7 +18,6 @@ package gov.nasa.jpf.symbc.bytecode; -import gov.nasa.jpf.symbc.bytecode.util.IFInstrSymbHelper; import gov.nasa.jpf.symbc.numeric.Comparator; import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; import gov.nasa.jpf.symbc.numeric.PathCondition; @@ -40,15 +39,91 @@ public Instruction execute(ThreadInfo th) { if (sym_v1 == null && sym_v2 == null) { // both conditions are concrete return super.execute(th); } else { // at least one condition is symbolic - Instruction nxtInstr = IFInstrSymbHelper.getNextInstructionAndSetPCChoiceDouble(th, - this, - sym_v1, - sym_v2, - Comparator.LT, - Comparator.EQ, - Comparator.GT); - - return nxtInstr; + ChoiceGenerator cg; + int conditionValue; + + if (!th.isFirstStepInsn()) { // first time around + cg = new PCChoiceGenerator(3); + ((PCChoiceGenerator)cg).setOffset(this.position); + ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); + th.getVM().getSystemState().setNextChoiceGenerator(cg); + return this; + } else { // this is what really returns results + ChoiceGenerator curCg = th.getVM().getSystemState().getChoiceGenerator(); + assert (curCg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + curCg; + cg = (PCChoiceGenerator)curCg; + conditionValue = cg.getNextChoice().intValue() -1; + } + + double v1 = Types.longToDouble(sf.popLong()); + double v2 = Types.longToDouble(sf.popLong()); + //System.out.println("Execute DCMPL: " + conditionValue); + PathCondition pc; + + // pc is updated with the pc stored in the choice generator above + // get the path condition from the + // previous choice generator of the same type + + ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + + if (prev_cg == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator) prev_cg).getCurrentPC(); + + assert pc != null; + + + + if (conditionValue == -1) { + if (sym_v1 != null) { + if (sym_v2 != null) { // both are symbolic values + pc._addDet(Comparator.LT, sym_v2, sym_v1); + } else + pc._addDet(Comparator.LT, v2, sym_v1); + } else + pc._addDet(Comparator.LT, sym_v2, v1); + if (!pc.simplify()) {// not satisfiable + th.getVM().getSystemState().setIgnored(true); + } else { + // pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + // System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + } else if (conditionValue == 0) { + if (sym_v1 != null) { + if (sym_v2 != null) { // both are symbolic values + pc._addDet(Comparator.EQ, sym_v1, sym_v2); + } else + pc._addDet(Comparator.EQ, sym_v1, v2); + } else + pc._addDet(Comparator.EQ, v1, sym_v2); + if (!pc.simplify()) {// not satisfiable + th.getVM().getSystemState().setIgnored(true); + } else { + // pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + // System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + } else { + if (sym_v1 != null) { + if (sym_v2 != null) { // both are symbolic values + pc._addDet(Comparator.GT, sym_v2, sym_v1); + } else + pc._addDet(Comparator.GT, v2, sym_v1); + } else + pc._addDet(Comparator.GT, sym_v2, v1); + if (!pc.simplify()) {// not satisfiable + th.getVM().getSystemState().setIgnored(true); + } else { + // pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + // System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + } + sf.push(conditionValue, false); + return getNext(th); } } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/FALOAD.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/FALOAD.java index 32c16e7..8743483 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/FALOAD.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/FALOAD.java @@ -21,19 +21,11 @@ package gov.nasa.jpf.symbc.bytecode; import gov.nasa.jpf.symbc.SymbolicInstructionFactory; -import gov.nasa.jpf.symbc.arrays.ArrayExpression; -import gov.nasa.jpf.symbc.arrays.SelectExpression; -import gov.nasa.jpf.symbc.arrays.RealSymbolicArray; -import gov.nasa.jpf.symbc.arrays.SymbolicRealValueAtIndex; import gov.nasa.jpf.symbc.numeric.Comparator; -import gov.nasa.jpf.symbc.numeric.IntegerConstant; import gov.nasa.jpf.symbc.numeric.IntegerExpression; -import gov.nasa.jpf.symbc.numeric.RealConstant; -import gov.nasa.jpf.symbc.numeric.RealExpression; import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; import gov.nasa.jpf.symbc.numeric.PathCondition; import gov.nasa.jpf.vm.ArrayIndexOutOfBoundsExecutiveException; -import gov.nasa.jpf.vm.ChoiceGenerator; import gov.nasa.jpf.vm.ElementInfo; import gov.nasa.jpf.vm.Instruction; import gov.nasa.jpf.vm.MJIEnv; @@ -49,127 +41,116 @@ public class FALOAD extends gov.nasa.jpf.jvm.bytecode.FALOAD { @Override public Instruction execute (ThreadInfo ti) { - // This instruction is not implemented for the moment, because of Z3 not supporting floats. - if (peekArrayAttr(ti)==null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { - // In this case, the array isn't symbolic - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case, the index isn't symbolic either - return super.execute(ti); - } - } - - RealSymbolicArray arrayAttr = null; - ChoiceGenerator cg; - boolean condition; - - if (!ti.isFirstStepInsn()) { // first time around - cg = new PCChoiceGenerator(3); - ((PCChoiceGenerator)cg).setOffset(this.position); - ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); - ti.getVM().setNextChoiceGenerator(cg); - return this; - } else { // this is what really returns results - cg = ti.getVM().getChoiceGenerator(); - assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; - } - - - PathCondition pc; - ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - if (prev_cg == null) - pc = new PathCondition(); - else - pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); - - assert pc != null; - - if (peekArrayAttr(ti)==null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { - // In this case, the array isn't symbolic - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case, the index isn't symbolic either - return super.execute(ti); - } - // We have a concrete array, but a symbolic index. We add all the constraints about the elements of the array, and perform the select - ElementInfo arrayInfo = ti.getElementInfo(arrayRef); - arrayAttr = new RealSymbolicArray(arrayInfo.arrayLength()); - for (int i = 0; i < arrayInfo.arrayLength(); i++) { - float arrValue = arrayInfo.getFloatElement(i); - pc._addDet(Comparator.EQ, new SelectExpression(arrayAttr, i), new RealConstant(arrValue)); - } - } - - else { - arrayAttr = (RealSymbolicArray)peekArrayAttr(ti); - } - IntegerExpression indexAttr = null; - SelectExpression se = null; - StackFrame frame = ti.getModifiableTopFrame(); - arrayRef = frame.peek(1); // ..., arrayRef, idx - - if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case, the index isn't symbolic. - index = frame.peek(); - se = new SelectExpression(arrayAttr, index); - indexAttr = new IntegerConstant(index); - - } else { - indexAttr = (IntegerExpression)peekIndexAttr(ti); - se = new SelectExpression(arrayAttr, indexAttr); - } - - assert arrayAttr != null; - assert indexAttr != null; - assert se != null; - - if (arrayRef == MJIEnv.NULL) { - return ti.createAndThrowException("java.lang.NullPointerException"); - } - - - if ((Integer)cg.getNextChoice()==1) { // check bounds of the index - pc._addDet(Comparator.GE, se.index, se.ae.length); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index greater than array bounds"); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - else if ((Integer)cg.getNextChoice()==2) { - pc._addDet(Comparator.LT, se.index, new IntegerConstant(0)); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index smaller than array bounds"); - } else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - else { - pc._addDet(Comparator.LT, se.index, se.ae.length); - pc._addDet(Comparator.GE, se.index, new IntegerConstant(0)); - if (pc.simplify()) { //satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - - // set the result - // We update the Symbolic Array with the get information - SymbolicRealValueAtIndex result = arrayAttr.getRealVal(indexAttr); - frame.pop(2); // We pop the array and the index - frame.push(0, false); // For symbolic expressions, the concrete value does not matter - frame.setOperandAttr(result.value); - // We add the select instruction in the PathCondition - pc._addDet(Comparator.EQ, se, result.value); - return getNext(ti); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - } - + if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) + return super.execute(ti); + StackFrame frame = ti.getModifiableTopFrame(); + arrayRef = frame.peek(1); // ..,arrayRef,idx + if (arrayRef == MJIEnv.NULL) { + return ti.createAndThrowException("java.lang.NullPointerException"); + } + + ElementInfo eiArray = ti.getElementInfo(arrayRef); + int len=(eiArray.getArrayFields()).arrayLength(); // assumed concrete + if(!ti.isFirstStepInsn()){ + PCChoiceGenerator arrayCG = new PCChoiceGenerator(0,len+1); // add 2 error cases: <0, >=len + ti.getVM().getSystemState().setNextChoiceGenerator(arrayCG); + + if (SymbolicInstructionFactory.debugMode) + System.out.println("# array cg registered: " + arrayCG); + return this; + + } else { //this is what really returns results + + //index = frame.peek(); + PCChoiceGenerator lastCG=ti.getVM().getSystemState().getLastChoiceGeneratorOfType(PCChoiceGenerator.class); + assert(lastCG!=null); + PCChoiceGenerator prevCG=lastCG.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + index=lastCG.getNextChoice(); + //System.out.println("array index "+index); + IntegerExpression sym_index=(IntegerExpression)peekIndexAttr(ti); + //check the constraint + + PathCondition pc; + + if (prevCG == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prevCG).getCurrentPC(); + + assert pc != null; + + if(index cg; - boolean condition; - - if (!ti.isFirstStepInsn()) { // first time around - cg = new PCChoiceGenerator(3); - ((PCChoiceGenerator) cg).setOffset(this.position); - ((PCChoiceGenerator) cg).setMethodName(this.getMethodInfo().getFullName()); - ti.getVM().setNextChoiceGenerator(cg); - return this; - } else { // this is what really returns results - cg = ti.getVM().getChoiceGenerator(); - assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; - } - - PathCondition pc; - ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - if (prev_cg == null) - pc = new PathCondition(); - else - pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); - - assert pc != null; - - if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - int index = ti.getTopFrame().peek(1); - indexAttr = new IntegerConstant(index); - } else { - indexAttr = (IntegerExpression)peekIndexAttr(ti); - } - assert (indexAttr != null) : "indexAttr shouldn't be null in FASTORE instruction"; - - if (peekArrayAttr(ti)==null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { - //In this case, the array isn't symbolic - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - if (frame.getOperandAttr(0) == null || !(frame.getOperandAttr(0) instanceof RealExpression)) { - // nothing is symbolic here - return super.execute(ti); - } - } else { - // We create a symbolic array out of the concrete array - ElementInfo arrayInfo = ti.getElementInfo(arrayRef); - arrayAttr = new RealSymbolicArray(arrayInfo.arrayLength()); - // We add the constraints about all the elements of the array - for (int i = 0; i < arrayInfo.arrayLength(); i++) { - float arrValue = arrayInfo.getFloatElement(i); - pc._addDet(Comparator.EQ, new SelectExpression(arrayAttr, i), new RealConstant(arrValue)); - } - } - } else { - arrayAttr = (RealSymbolicArray)peekArrayAttr(ti); - } - assert (arrayAttr != null) : "arrayAttr shouldn't be null in FASTORE instruction"; - - - int arrayref = peekArrayRef(ti); // need to be polymorphic, could be LongArrayStore + int arrayref = peekArrayRef(ti); // need to be polymorphic, could be LongArrayStore + ElementInfo eiArray = ti.getElementInfo(arrayref); + if (arrayref == MJIEnv.NULL) { return ti.createAndThrowException("java.lang.NullPointerException"); } - - - if ((Integer)cg.getNextChoice() == 1) { // check bounds of the index - pc._addDet(Comparator.GE, indexAttr, arrayAttr.length); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index greater than array bounds"); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - else if ((Integer)cg.getNextChoice() == 2) { - pc._addDet(Comparator.LT, indexAttr, new IntegerConstant(0)); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index smaller than array bounds"); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - else { - pc._addDet(Comparator.LT, indexAttr, arrayAttr.length); - pc._addDet(Comparator.GE, indexAttr, new IntegerConstant(0)); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - - // set the result - - // We have to check if the value is symbolic or not, create a symbolicIntegerValueatIndex out of it, and - // call the setVal function, before storing the attr - RealExpression sym_value = null; - if (frame.getOperandAttr(0) == null || !(frame.getOperandAttr(0) instanceof RealExpression)) { - // The value isn't symbolic. We store a new IntegerConstant in the valAt map, at index indexAttr - float value = frame.pop(); - sym_value = new RealConstant(value); - } - else { - // The value is symbolic. - sym_value = (RealExpression)frame.getOperandAttr(0); - frame.pop(); - } - PreviousRealArray previous = new PreviousRealArray(arrayAttr, indexAttr, sym_value); - // We create a new arrayAttr, and inherits information from the previous attribute - RealSymbolicArray newArrayAttr = new RealSymbolicArray(previous); - frame.pop(2); // We pop the array and the index - - RealStoreExpression se = new RealStoreExpression(arrayAttr, indexAttr, sym_value); - pc._addDet(Comparator.EQ, se, newArrayAttr); - - return getNext(ti); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - } + + + int len=(eiArray.getArrayFields()).arrayLength(); // assumed concrete + + if(!ti.isFirstStepInsn()){ + PCChoiceGenerator arrayCG = new PCChoiceGenerator(0,len+1); // add 2 error cases: <0, >=len + ti.getVM().getSystemState().setNextChoiceGenerator(arrayCG); + + //ti.reExecuteInstruction(); + if (SymbolicInstructionFactory.debugMode) + System.out.println("# array cg registered: " + arrayCG); + return this; + + } else { //this is what really returns results + + + + //index = frame.peek(); + PCChoiceGenerator lastCG=ti.getVM().getSystemState().getLastChoiceGeneratorOfType(PCChoiceGenerator.class); + assert(lastCG!=null); + PCChoiceGenerator prevCG=lastCG.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + index=lastCG.getNextChoice(); + IntegerExpression sym_index=(IntegerExpression)peekIndexAttr(ti); + //check the constraint + + PathCondition pc; + + if (prevCG == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prevCG).getCurrentPC(); + + assert pc != null; + + if(index what if the value is the same but not the attr? + + } catch (ArrayIndexOutOfBoundsExecutiveException ex) { // at this point, the AIOBX is already processed + return ex.getInstruction(); + } + + return getNext(ti); + } + } + } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/FCMPG.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/FCMPG.java index 59cf0fa..2a21752 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/FCMPG.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/FCMPG.java @@ -17,7 +17,6 @@ */ package gov.nasa.jpf.symbc.bytecode; -import gov.nasa.jpf.symbc.bytecode.util.IFInstrSymbHelper; import gov.nasa.jpf.symbc.numeric.Comparator; import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; import gov.nasa.jpf.symbc.numeric.PathCondition; @@ -43,15 +42,78 @@ public Instruction execute(ThreadInfo th) { if (sym_v1 == null && sym_v2 == null) { // both conditions are concrete return super.execute( th); } else { // at least one condition is symbolic - Instruction nxtInstr = IFInstrSymbHelper.getNextInstructionAndSetPCChoiceFloat(th, - this, - sym_v1, - sym_v2, - Comparator.LT, - Comparator.EQ, - Comparator.GT); - - return nxtInstr; + ChoiceGenerator cg; + int conditionValue; + + if (!th.isFirstStepInsn()) { // first time around + cg = new PCChoiceGenerator(3); + ((PCChoiceGenerator)cg).setOffset(this.position); + ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); + th.getVM().getSystemState().setNextChoiceGenerator(cg); + return this; + } else { // this is what really returns results + cg = th.getVM().getSystemState().getChoiceGenerator(); + assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; + conditionValue = ((PCChoiceGenerator) cg).getNextChoice() - 1; + } + + float v1 = Types.intToFloat(sf.pop()); + float v2 = Types.intToFloat(sf.pop()); + + PathCondition pc; + + ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + if (prev_cg == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator) prev_cg).getCurrentPC(); + assert pc != null; + + if (conditionValue == -1) { + if (sym_v1 != null) { + if (sym_v2 != null) { // both are symbolic values + pc._addDet(Comparator.LT, sym_v2, sym_v1); + } else + pc._addDet(Comparator.LT, v2, sym_v1); + } else + pc._addDet(Comparator.LT, sym_v2, v1); + + if (!pc.simplify()) {// not satisfiable + th.getVM().getSystemState().setIgnored(true); + } else { + ((PCChoiceGenerator) cg).setCurrentPC(pc); + } + } else if (conditionValue == 0) { + if (sym_v1 != null) { + if (sym_v2 != null) { // both are symbolic values + pc._addDet(Comparator.EQ, sym_v1, sym_v2); + } else + pc._addDet(Comparator.EQ, sym_v1, v2); + } else + pc._addDet(Comparator.EQ, v1, sym_v2); + if (!pc.simplify()) {// not satisfiable + th.getVM().getSystemState().setIgnored(true); + } else { + ((PCChoiceGenerator) cg).setCurrentPC(pc); + } + } else { // 1 + if (sym_v1 != null) { + if (sym_v2 != null) { // both are symbolic values + pc._addDet(Comparator.GT, sym_v2, sym_v1); + } else + pc._addDet(Comparator.GT, v2, sym_v1); + } else + pc._addDet(Comparator.GT, sym_v2, v1); + if (!pc.simplify()) {// not satisfiable + th.getVM().getSystemState().setIgnored(true); + } else { + ((PCChoiceGenerator) cg).setCurrentPC(pc); + } + } + + sf.push(conditionValue, false); + return getNext(th); } } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/FCMPL.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/FCMPL.java index b440eac..72f7de7 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/FCMPL.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/FCMPL.java @@ -18,7 +18,6 @@ package gov.nasa.jpf.symbc.bytecode; -import gov.nasa.jpf.symbc.bytecode.util.IFInstrSymbHelper; import gov.nasa.jpf.symbc.numeric.Comparator; import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; import gov.nasa.jpf.symbc.numeric.PathCondition; @@ -44,16 +43,90 @@ public Instruction execute(ThreadInfo th) { if (sym_v1 == null && sym_v2 == null) { // both conditions are concrete return super.execute(th); } else { // at least one condition is symbolic - - Instruction nxtInstr = IFInstrSymbHelper.getNextInstructionAndSetPCChoiceFloat(th, - this, - sym_v1, - sym_v2, - Comparator.LT, - Comparator.EQ, - Comparator.GT); - - return nxtInstr; + ChoiceGenerator cg; + int conditionValue; + + if (!th.isFirstStepInsn()) { // first time around + cg = new PCChoiceGenerator(3); + ((PCChoiceGenerator)cg).setOffset(this.position); + ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); + th.getVM().getSystemState().setNextChoiceGenerator(cg); + return this; + } else { // this is what really returns results + cg = th.getVM().getSystemState().getChoiceGenerator(); + assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; + conditionValue = ((PCChoiceGenerator) cg).getNextChoice() -1; + } + + float v1 = Types.intToFloat(sf.pop()); + float v2 = Types.intToFloat(sf.pop()); + + // System.out.println("Execute FCMPL: "+ conditionValue); + PathCondition pc; + + // pc is updated with the pc stored in the choice generator above get + // the path condition from the previous CG of the same type + + ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + if (prev_cg == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator) prev_cg).getCurrentPC(); + assert pc != null; + + if (conditionValue == -1) { + if (sym_v1 != null) { + if (sym_v2 != null) { // both are symbolic values + pc._addDet(Comparator.LT, sym_v2, sym_v1); + } else + pc._addDet(Comparator.LT, v2, sym_v1); + } else + pc._addDet(Comparator.LT, sym_v2, v1); + + if (!pc.simplify()) {// not satisfiable + th.getVM().getSystemState().setIgnored(true); + } else { + // pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + // System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + } else if (conditionValue == 0) { + if (sym_v1 != null) { + if (sym_v2 != null) { // both are symbolic values + pc._addDet(Comparator.EQ, sym_v1, sym_v2); + } else + pc._addDet(Comparator.EQ, sym_v1, v2); + } else + pc._addDet(Comparator.EQ, v1, sym_v2); + if (!pc.simplify()) {// not satisfiable + th.getVM().getSystemState().setIgnored(true); + } else { + // pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + // System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + } else { // 1 + if (sym_v1 != null) { + if (sym_v2 != null) { // both are symbolic values + pc._addDet(Comparator.GT, sym_v2, sym_v1); + } else + pc._addDet(Comparator.GT, v2, sym_v1); + } else + pc._addDet(Comparator.GT, sym_v2, v1); + if (!pc.simplify()) {// not satisfiable + th.getVM().getSystemState().setIgnored(true); + } else { + // pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + // System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + } + + sf.push(conditionValue, false); + + //System.out.println("Execute FCMPL: " + ((PCChoiceGenerator) cg).getCurrentPC()); + return getNext(th); } } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/GETFIELD.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/GETFIELD.java index 4a78bad..895f573 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/GETFIELD.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/GETFIELD.java @@ -20,6 +20,7 @@ import gov.nasa.jpf.Config; import gov.nasa.jpf.symbc.SymbolicInstructionFactory; +import gov.nasa.jpf.symbc.arrays.ArrayExpression; import gov.nasa.jpf.symbc.heap.HeapChoiceGenerator; import gov.nasa.jpf.symbc.heap.HeapNode; import gov.nasa.jpf.symbc.heap.Helper; @@ -53,7 +54,7 @@ public GETFIELD(String fieldName, String clsName, String fieldDescriptor){ @Override public Instruction execute (ThreadInfo ti) { - + HeapNode[] prevSymRefs = null; // previously initialized objects of same type: candidates for lazy init int numSymRefs = 0; // # of prev. initialized objects ChoiceGenerator prevHeapCG = null; @@ -69,7 +70,7 @@ public Instruction execute (ThreadInfo ti) { StackFrame frame = ti.getModifiableTopFrame(); int objRef = frame.peek(); // don't pop yet, we might re-enter lastThis = objRef; - if (objRef == -1) { + if (objRef == MJIEnv.NULL) { return ti.createAndThrowException("java.lang.NullPointerException", "referencing field '" + fname + "' on null object"); } @@ -90,8 +91,8 @@ public Instruction execute (ThreadInfo ti) { return super.execute(ti); } - if(attr instanceof StringExpression || attr instanceof SymbolicStringBuilder) - return super.execute(ti); // Strings are handled specially + if(attr instanceof StringExpression || attr instanceof SymbolicStringBuilder || attr instanceof ArrayExpression) + return super.execute(ti); // Strings and arrays are handled specially if (SymbolicInstructionFactory.debugMode) System.out.println("lazy initialization"); diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/GETSTATIC.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/GETSTATIC.java index 73c6231..5c50a95 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/GETSTATIC.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/GETSTATIC.java @@ -21,6 +21,7 @@ import gov.nasa.jpf.Config; import gov.nasa.jpf.JPFException; import gov.nasa.jpf.symbc.SymbolicInstructionFactory; +import gov.nasa.jpf.symbc.arrays.ArrayExpression; import gov.nasa.jpf.symbc.heap.HeapChoiceGenerator; import gov.nasa.jpf.symbc.heap.HeapNode; import gov.nasa.jpf.symbc.heap.Helper; @@ -97,7 +98,7 @@ public Instruction execute (ThreadInfo ti) { if (!(fi.isReference() && attr != null)) return super.execute(ti); - if(attr instanceof StringExpression || attr instanceof SymbolicStringBuilder) + if(attr instanceof StringExpression || attr instanceof SymbolicStringBuilder || attr instanceof ArrayExpression) return super.execute(ti); // Strings are handled specially diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IALOAD.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IALOAD.java index fab8265..9c43068 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IALOAD.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IALOAD.java @@ -21,17 +21,11 @@ package gov.nasa.jpf.symbc.bytecode; import gov.nasa.jpf.symbc.SymbolicInstructionFactory; -import gov.nasa.jpf.symbc.arrays.ArrayExpression; -import gov.nasa.jpf.symbc.arrays.SelectExpression; -import gov.nasa.jpf.symbc.arrays.IntegerSymbolicArray; -import gov.nasa.jpf.symbc.arrays.SymbolicIntegerValueAtIndex; import gov.nasa.jpf.symbc.numeric.Comparator; -import gov.nasa.jpf.symbc.numeric.IntegerConstant; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; import gov.nasa.jpf.symbc.numeric.PathCondition; import gov.nasa.jpf.vm.ArrayIndexOutOfBoundsExecutiveException; -import gov.nasa.jpf.vm.ChoiceGenerator; import gov.nasa.jpf.vm.ElementInfo; import gov.nasa.jpf.vm.Instruction; import gov.nasa.jpf.vm.MJIEnv; @@ -46,125 +40,117 @@ public class IALOAD extends gov.nasa.jpf.jvm.bytecode.IALOAD { @Override public Instruction execute (ThreadInfo ti) { - - if (peekArrayAttr(ti)==null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { - // In this case, the array isn't symbolic - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case, the index isn't symbolic either - return super.execute(ti); - } - } - - IntegerSymbolicArray arrayAttr = null; - ChoiceGenerator cg; - boolean condition; - StackFrame frame = ti.getModifiableTopFrame(); - arrayRef = frame.peek(1); // ..., arrayRef, idx - - if (!ti.isFirstStepInsn()) { // first time around - cg = new PCChoiceGenerator(3); - ((PCChoiceGenerator)cg).setOffset(this.position); - ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); - ti.getVM().setNextChoiceGenerator(cg); - return this; - } else { // this is what really returns results - cg = ti.getVM().getChoiceGenerator(); - assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; - } - - PathCondition pc; - ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - if (prev_cg == null) - pc = new PathCondition(); - else - pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); - - assert pc != null; - - if (peekArrayAttr(ti)==null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { - // In this case, the array isn't symbolic - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case, the index isn't symbolic either - return super.execute(ti); - } - // We have a concrete array, but a symbolic index. We add all the constraints about the elements of the array, and perform the select - ElementInfo arrayInfo = ti.getElementInfo(arrayRef); - arrayAttr = new IntegerSymbolicArray(arrayInfo.arrayLength()); - for (int i = 0; i < arrayInfo.arrayLength(); i++) { - int arrValue = arrayInfo.getIntElement(i); - pc._addDet(Comparator.EQ, new SelectExpression(arrayAttr, i), new IntegerConstant(arrValue)); - } - } - - else { - arrayAttr = (IntegerSymbolicArray)peekArrayAttr(ti); - } - IntegerExpression indexAttr = null; - SelectExpression se = null; - - if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case, the index isn't symbolic. - index = frame.peek(); - se = new SelectExpression(arrayAttr, index); - indexAttr = new IntegerConstant(index); - - } else { - indexAttr = (IntegerExpression)peekIndexAttr(ti); - se = new SelectExpression(arrayAttr, indexAttr); - } - - assert arrayAttr != null; - assert indexAttr != null; - assert se != null; - - if (arrayRef == MJIEnv.NULL) { - return ti.createAndThrowException("java.lang.NullPointerException"); - } - - - if ((Integer)cg.getNextChoice()==1) { // check bounds of the index - pc._addDet(Comparator.GE, se.index, se.ae.length); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index greater than array bounds"); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - else if ((Integer)cg.getNextChoice()==2) { - pc._addDet(Comparator.LT, se.index, new IntegerConstant(0)); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index smaller than array bounds"); - } else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - else { - pc._addDet(Comparator.LT, se.index, se.ae.length); - pc._addDet(Comparator.GE, se.index, new IntegerConstant(0)); - if (pc.simplify()) { //satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - - // set the result - // We update the Symbolic Array with the get information - SymbolicIntegerValueAtIndex result = arrayAttr.getVal(indexAttr); - frame.pop(2); // We pop the array and the index - frame.push(0, false); // For symbolic expressions, the concrete value does not matter - frame.setOperandAttr(result.value); - // We add the select instruction in the PathCondition - pc._addDet(Comparator.EQ, se, result.value); - return getNext(ti); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - } + + if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) + return super.execute(ti); + StackFrame frame = ti.getModifiableTopFrame(); + arrayRef = frame.peek(1); // ..,arrayRef,idx + if (arrayRef == MJIEnv.NULL) { + return ti.createAndThrowException("java.lang.NullPointerException"); + } + + ElementInfo eiArray = ti.getElementInfo(arrayRef); + int len=(eiArray.getArrayFields()).arrayLength(); // assumed concrete + if(!ti.isFirstStepInsn()){ + PCChoiceGenerator arrayCG = new PCChoiceGenerator(0,len+1); // add 2 error cases: <0, >=len + ti.getVM().getSystemState().setNextChoiceGenerator(arrayCG); + + if (SymbolicInstructionFactory.debugMode) + System.out.println("# array cg registered: " + arrayCG); + return this; + + } else { //this is what really returns results + + //index = frame.peek(); + PCChoiceGenerator lastCG=ti.getVM().getSystemState().getLastChoiceGeneratorOfType(PCChoiceGenerator.class); + assert(lastCG!=null); + PCChoiceGenerator prevCG=lastCG.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + index=lastCG.getNextChoice(); + //System.out.println("array index "+index); + IntegerExpression sym_index=(IntegerExpression)peekIndexAttr(ti); + //check the constraint + + PathCondition pc; + + if (prevCG == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prevCG).getCurrentPC(); + + assert pc != null; + + if(index cg; - boolean condition; - int arrayRef = peekArrayRef(ti); // need to be polymorphic, could be LongArrayStore - - if (!ti.isFirstStepInsn()) { // first time around - cg = new PCChoiceGenerator(3); - ((PCChoiceGenerator) cg).setOffset(this.position); - ((PCChoiceGenerator) cg).setMethodName(this.getMethodInfo().getFullName()); - ti.getVM().setNextChoiceGenerator(cg); - return this; - } else { // this is what really returns results - cg = ti.getVM().getChoiceGenerator(); - assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; - } - - PathCondition pc; - ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - if (prev_cg == null) - pc = new PathCondition(); - else - pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); - - assert pc != null; - - if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - int index = ti.getTopFrame().peek(1); - indexAttr = new IntegerConstant(index); - } else { - indexAttr = (IntegerExpression)peekIndexAttr(ti); - } - assert (indexAttr != null) : "indexAttr shouldn't be null in IASTORE instruction"; - - if (peekArrayAttr(ti)==null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { - //In this case, the array isn't symbolic - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - if (frame.getOperandAttr(0) == null || !(frame.getOperandAttr(0) instanceof IntegerExpression)) { - // nothing is symbolic here - return super.execute(ti); - } - } else { - // We create a symbolic array out of the concrete array - ElementInfo arrayInfo = ti.getElementInfo(arrayRef); - arrayAttr = new IntegerSymbolicArray(arrayInfo.arrayLength()); - // We add the constraints about all the elements of the array - for (int i = 0; i < arrayInfo.arrayLength(); i++) { - int arrValue = arrayInfo.getIntElement(i); - pc._addDet(Comparator.EQ, new SelectExpression(arrayAttr, i), new IntegerConstant(arrValue)); - } - } - } else { - arrayAttr = (IntegerSymbolicArray)peekArrayAttr(ti); - } - assert (arrayAttr != null) : "arrayAttr shouldn't be null in IASTORE instruction"; - - if (arrayRef == MJIEnv.NULL) { + int arrayref = peekArrayRef(ti); // need to be polymorphic, could be LongArrayStore + ElementInfo eiArray = ti.getElementInfo(arrayref); + + if (arrayref == MJIEnv.NULL) { return ti.createAndThrowException("java.lang.NullPointerException"); } - - - if ((Integer)cg.getNextChoice() == 1) { // check bounds of the index - pc._addDet(Comparator.GE, indexAttr, arrayAttr.length); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index greater than array bounds"); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - else if ((Integer)cg.getNextChoice() == 2) { - pc._addDet(Comparator.LT, indexAttr, new IntegerConstant(0)); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index smaller than array bounds"); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - else { - pc._addDet(Comparator.LT, indexAttr, arrayAttr.length); - pc._addDet(Comparator.GE, indexAttr, new IntegerConstant(0)); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - - // set the result - - // We have to check if the value is symbolic or not, create a symbolicIntegerValueatIndex out of it, and - // call the setVal function, before storing the attr - IntegerExpression sym_value = null; - if (frame.getOperandAttr(0) == null || !(frame.getOperandAttr(0) instanceof IntegerExpression)) { - // The value isn't symbolic. We store a new IntegerConstant in the valAt map, at index indexAttr - int value = frame.pop(); - sym_value = new IntegerConstant(value); - } - else { - // The value is symbolic. - sym_value = (IntegerExpression)frame.getOperandAttr(0); - frame.pop(); - } - PreviousIntegerArray previous = new PreviousIntegerArray(arrayAttr, indexAttr, sym_value); - // We create a new arrayAttr, and inherits information from the previous attribute - IntegerSymbolicArray newArrayAttr = new IntegerSymbolicArray(previous); - frame.pop(2); // We pop the array and the index - - StoreExpression se = new StoreExpression(arrayAttr, indexAttr, sym_value); - pc._addDet(Comparator.EQ, se, newArrayAttr); - - return getNext(ti); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - } - + + + int len=(eiArray.getArrayFields()).arrayLength(); // assumed concrete + + if(!ti.isFirstStepInsn()){ + PCChoiceGenerator arrayCG = new PCChoiceGenerator(0,len+1); // add 2 error cases: <0, >=len + ti.getVM().getSystemState().setNextChoiceGenerator(arrayCG); + + //ti.reExecuteInstruction(); + if (SymbolicInstructionFactory.debugMode) + System.out.println("# array cg registered: " + arrayCG); + return this; + + } else { //this is what really returns results + + + + //index = frame.peek(); + PCChoiceGenerator lastCG=ti.getVM().getSystemState().getLastChoiceGeneratorOfType(PCChoiceGenerator.class); + assert(lastCG!=null); + PCChoiceGenerator prevCG=lastCG.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + index=lastCG.getNextChoice(); + IntegerExpression sym_index=(IntegerExpression)peekIndexAttr(ti); + //check the constraint + + PathCondition pc; + + if (prevCG == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prevCG).getCurrentPC(); + + assert pc != null; + + if(index what if the value is the same but not the attr? + + } catch (ArrayIndexOutOfBoundsExecutiveException ex) { // at this point, the AIOBX is already processed + return ex.getInstruction(); + } + + return getNext(ti); + } + } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFEQ.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFEQ.java index ff00591..a94bc46 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFEQ.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFEQ.java @@ -15,29 +15,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -//Copyright (C) 2007 United States Government as represented by the -//Administrator of the National Aeronautics and Space Administration -//(NASA). All Rights Reserved. - -//This software is distributed under the NASA Open Source Agreement -//(NOSA), version 1.3. The NOSA has been approved by the Open Source -//Initiative. See the file NOSA-1.3-JPF at the top of the distribution -//directory tree for the complete NOSA document. - -//THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY -//KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT -//LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO -//SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR -//A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT -//THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT -//DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. - package gov.nasa.jpf.symbc.bytecode; import gov.nasa.jpf.symbc.SymbolicInstructionFactory; -import gov.nasa.jpf.symbc.bytecode.util.IFInstrSymbHelper; import gov.nasa.jpf.symbc.numeric.Comparator; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; @@ -64,16 +45,78 @@ public Instruction execute (ThreadInfo ti) { return super.execute(ti); } else { // the condition is symbolic - Instruction nxtInstr = IFInstrSymbHelper.getNextInstructionAndSetPCChoice(ti, - this, - sym_v, - Comparator.EQ, - Comparator.NE); - if(nxtInstr==getTarget()) - conditionValue=true; - else - conditionValue=false; - return nxtInstr; + + String[] dp = SymbolicInstructionFactory.dp; + + + + ChoiceGenerator cg; + + if (!ti.isFirstStepInsn()) { // first time around + if (dp[0].equalsIgnoreCase("omega")) // hack because omega does not handle not or or correctly + cg = new PCChoiceGenerator(3); + else + cg = new PCChoiceGenerator(2); + ((PCChoiceGenerator)cg).setOffset(this.position); + ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); + ti.getVM().getSystemState().setNextChoiceGenerator(cg); + return this; + } else { // this is what really returns results + cg = ti.getVM().getSystemState().getChoiceGenerator(); + assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; + conditionValue = (Integer)cg.getNextChoice()==1 ? true: false; + } + + sf.pop(); + //System.out.println("Execute IFEQ: "+ conditionValue); + PathCondition pc; + + // pc is updated with the pc stored in the choice generator above + // get the path condition from the + // previous choice generator of the same type + + ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + + if (prev_cg == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); + + assert pc != null; + + if (conditionValue) { + pc._addDet(Comparator.EQ, sym_v, 0); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + }else{ + //pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + //System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getTarget(); + } else { + + + if (dp[0].equalsIgnoreCase("omega")) {// hack + if((Integer)cg.getNextChoice()==0) + pc._addDet(Comparator.GT, sym_v, 0); + else {// ==2 + assert((Integer)cg.getNextChoice()==2); + pc._addDet(Comparator.LT, sym_v, 0); + } + } + else + pc._addDet(Comparator.NE, sym_v, 0); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + }else{ + //pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + //System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getNext(ti); + } } } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFGE.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFGE.java index a489300..bbc9f86 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFGE.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFGE.java @@ -15,29 +15,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - - -//Copyright (C) 2006 United States Government as represented by the -//Administrator of the National Aeronautics and Space Administration -//(NASA). All Rights Reserved. - -//This software is distributed under the NASA Open Source Agreement -//(NOSA), version 1.3. The NOSA has been approved by the Open Source -//Initiative. See the file NOSA-1.3-JPF at the top of the distribution -//directory tree for the complete NOSA document. - -//THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY -//KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT -//LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO -//SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR -//A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT -//THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT -//DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. - package gov.nasa.jpf.symbc.bytecode; -import gov.nasa.jpf.symbc.bytecode.util.IFInstrSymbHelper; import gov.nasa.jpf.symbc.numeric.Comparator; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; @@ -64,16 +44,61 @@ public Instruction execute (ThreadInfo ti) { return super.execute( ti); } else { // the condition is symbolic - Instruction nxtInstr = IFInstrSymbHelper.getNextInstructionAndSetPCChoice(ti, - this, - sym_v, - Comparator.GE, - Comparator.LT); - if(nxtInstr==getTarget()) - conditionValue=true; - else - conditionValue=false; - return nxtInstr; + ChoiceGenerator cg; + + if (!ti.isFirstStepInsn()) { // first time around + cg = new PCChoiceGenerator(2); + ((PCChoiceGenerator)cg).setOffset(this.position); + ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); + ti.getVM().getSystemState().setNextChoiceGenerator(cg); + return this; + } else { // this is what really returns results + cg = ti.getVM().getSystemState().getChoiceGenerator(); + assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; + conditionValue = (Integer)cg.getNextChoice()==0 ? false: true; + } + + sf.pop(); + //System.out.println("Execute IFGE: "+ conditionValue); + PathCondition pc; + + // pc is updated with the pc stored in the choice generator above + // get the path condition from the + // previous choice generator of the same type + + ChoiceGenerator prev_cg = cg.getPreviousChoiceGenerator(); + while (!((prev_cg == null) || (prev_cg instanceof PCChoiceGenerator))) { + prev_cg = prev_cg.getPreviousChoiceGenerator(); + } + + if (prev_cg == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); + + assert pc != null; + + if (conditionValue) { + pc._addDet(Comparator.GE, sym_v, 0); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + }else{ + //pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + //System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getTarget(); + } else { + pc._addDet(Comparator.LT, sym_v, 0); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + }else { + //pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + //System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getNext(ti); + } } } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFGT.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFGT.java index 65ca9d2..41b1d1f 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFGT.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFGT.java @@ -19,7 +19,6 @@ -import gov.nasa.jpf.symbc.bytecode.util.IFInstrSymbHelper; import gov.nasa.jpf.symbc.numeric.Comparator; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; @@ -46,16 +45,61 @@ public Instruction execute (ThreadInfo ti) { return super.execute( ti); } else { // the condition is symbolic - Instruction nxtInstr = IFInstrSymbHelper.getNextInstructionAndSetPCChoice(ti, - this, - sym_v, - Comparator.GT, - Comparator.LE); - if(nxtInstr==getTarget()) - conditionValue=true; - else - conditionValue=false; - return nxtInstr; + ChoiceGenerator cg; + + if (!ti.isFirstStepInsn()) { // first time around + cg = new PCChoiceGenerator(2); + ((PCChoiceGenerator)cg).setOffset(this.position); + ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); + ti.getVM().getSystemState().setNextChoiceGenerator(cg); + return this; + } else { // this is what really returns results + cg = ti.getVM().getSystemState().getChoiceGenerator(); + assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; + conditionValue = (Integer)cg.getNextChoice()==0 ? false: true; + } + + sf.pop(); + //System.out.println("Execute IFGT: "+ conditionValue); + PathCondition pc; + + // pc is updated with the pc stored in the choice generator above + // get the path condition from the + // previous choice generator of the same type + + ChoiceGenerator prev_cg = cg.getPreviousChoiceGenerator(); + while (!((prev_cg == null) || (prev_cg instanceof PCChoiceGenerator))) { + prev_cg = prev_cg.getPreviousChoiceGenerator(); + } + + if (prev_cg == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); + + assert pc != null; + + if (conditionValue) { + pc._addDet(Comparator.GT, sym_v, 0); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + }else{ + //pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + //System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getTarget(); + } else { + pc._addDet(Comparator.LE, sym_v, 0); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + }else { + //pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + //System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getNext(ti); + } } } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFLE.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFLE.java index 8e84231..931684c 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFLE.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFLE.java @@ -15,29 +15,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - - -//Copyright (C) 2006 United States Government as represented by the -//Administrator of the National Aeronautics and Space Administration -//(NASA). All Rights Reserved. - -//This software is distributed under the NASA Open Source Agreement -//(NOSA), version 1.3. The NOSA has been approved by the Open Source -//Initiative. See the file NOSA-1.3-JPF at the top of the distribution -//directory tree for the complete NOSA document. - -//THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY -//KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT -//LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO -//SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR -//A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT -//THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT -//DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. - package gov.nasa.jpf.symbc.bytecode; -import gov.nasa.jpf.symbc.bytecode.util.IFInstrSymbHelper; import gov.nasa.jpf.symbc.numeric.*; import gov.nasa.jpf.vm.ChoiceGenerator; import gov.nasa.jpf.vm.Instruction; @@ -63,16 +43,68 @@ public Instruction execute (ThreadInfo ti) { return super.execute( ti); } else { // the condition is symbolic - Instruction nxtInstr = IFInstrSymbHelper.getNextInstructionAndSetPCChoice(ti, - this, - sym_v, - Comparator.LE, - Comparator.GT); - if(nxtInstr==getTarget()) - conditionValue=true; - else - conditionValue=false; - return nxtInstr; + //System.out.println("Execute IFLE: The condition is symbolic"); + ChoiceGenerator cg; + + if (!ti.isFirstStepInsn()) { // first time around + cg = new PCChoiceGenerator(2); + ((PCChoiceGenerator)cg).setOffset(this.position); + ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); + ti.getVM().getSystemState().setNextChoiceGenerator(cg); + return this; + } else { // this is what really returns results + cg = ti.getVM().getSystemState().getChoiceGenerator(); + assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; + conditionValue = (Integer)cg.getNextChoice()==0 ? false: true; + } + + + sf.pop(); + //System.out.println("Execute IFLE: "+ conditionValue); + PathCondition pc; + + // pc is updated with the pc stored in the choice generator above + // get the path condition from the + // previous choice generator of the same type + + ChoiceGenerator prev_cg = cg.getPreviousChoiceGenerator(); + while (!((prev_cg == null) || (prev_cg instanceof PCChoiceGenerator))) { + prev_cg = prev_cg.getPreviousChoiceGenerator(); + } + + if (prev_cg == null) { + + pc = new PathCondition(); + } + else { + pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); + + } + assert pc != null; + + if (conditionValue) { + pc._addDet(Comparator.LE, sym_v, 0); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + } + else { + //pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + //System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getTarget(); + } else { + pc._addDet(Comparator.GT, sym_v, 0); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + } + else { + //pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + //System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getNext(ti); + } } } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFLT.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFLT.java index 155a8a7..9f31620 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFLT.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFLT.java @@ -18,7 +18,6 @@ package gov.nasa.jpf.symbc.bytecode; -import gov.nasa.jpf.symbc.bytecode.util.IFInstrSymbHelper; import gov.nasa.jpf.symbc.numeric.*; import gov.nasa.jpf.vm.ChoiceGenerator; import gov.nasa.jpf.vm.Instruction; @@ -42,16 +41,65 @@ public Instruction execute (ThreadInfo ti) { return super.execute(ti); } else { // the condition is symbolic - Instruction nxtInstr = IFInstrSymbHelper.getNextInstructionAndSetPCChoice(ti, - this, - sym_v, - Comparator.LT, - Comparator.GE); - if(nxtInstr==getTarget()) - conditionValue=true; - else - conditionValue=false; - return nxtInstr; + //System.out.println("Execute IFLT: The condition is symbolic"); + ChoiceGenerator cg; + + if (!ti.isFirstStepInsn()) { // first time around + cg = new PCChoiceGenerator(2); + ((PCChoiceGenerator)cg).setOffset(this.position); + ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); + ti.getVM().getSystemState().setNextChoiceGenerator(cg); + return this; + } else { // this is what really returns results + cg = ti.getVM().getSystemState().getChoiceGenerator(); + assert (cg instanceof PCChoiceGenerator) : "expected PCBChoiceGenerator, got: " + cg; + conditionValue = (Integer)cg.getNextChoice()==0 ? false: true; + } + + sf.pop(); + //System.out.println("Execute IFLT: "+ conditionValue); + PathCondition pc; + + // pc is updated with the pc stored in the choice generator above + // get the path condition from the + // previous choice generator of the same type + + ChoiceGenerator prev_cg = cg.getPreviousChoiceGenerator(); + while (!((prev_cg == null) || (prev_cg instanceof PCChoiceGenerator))) { + prev_cg = prev_cg.getPreviousChoiceGenerator(); + } + + if (prev_cg == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); + + assert pc != null; + + if (conditionValue) { + pc._addDet(Comparator.LT, sym_v, 0); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + } + else { +// pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + //System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getTarget(); + } else { + pc._addDet(Comparator.GE, sym_v, 0); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + } + else { +// pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + //System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getNext(ti); + } + } } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFNE.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFNE.java index d7fa3b8..1840d31 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFNE.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IFNE.java @@ -15,29 +15,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -//Copyright (C) 2007 United States Government as represented by the -//Administrator of the National Aeronautics and Space Administration -//(NASA). All Rights Reserved. - -//This software is distributed under the NASA Open Source Agreement -//(NOSA), version 1.3. The NOSA has been approved by the Open Source -//Initiative. See the file NOSA-1.3-JPF at the top of the distribution -//directory tree for the complete NOSA document. - -//THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY -//KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT -//LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO -//SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR -//A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT -//THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT -//DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. - package gov.nasa.jpf.symbc.bytecode; import gov.nasa.jpf.symbc.SymbolicInstructionFactory; -import gov.nasa.jpf.symbc.bytecode.util.IFInstrSymbHelper; import gov.nasa.jpf.symbc.numeric.Comparator; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; @@ -64,16 +45,75 @@ public Instruction execute (ThreadInfo ti) { return super.execute(ti); } else { // the condition is symbolic - Instruction nxtInstr = IFInstrSymbHelper.getNextInstructionAndSetPCChoice(ti, - this, - sym_v, - Comparator.NE, - Comparator.EQ); - if(nxtInstr==getTarget()) - conditionValue=true; - else - conditionValue=false; - return nxtInstr; + + String[] dp = SymbolicInstructionFactory.dp; + + ChoiceGenerator cg; + + if (!ti.isFirstStepInsn()) { // first time around + + if (dp[0].equalsIgnoreCase("omega")) // hack because omega does not handle not or or correctly + cg = new PCChoiceGenerator(3); + else + cg = new PCChoiceGenerator(2); + ((PCChoiceGenerator)cg).setOffset(this.position); + ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); + ti.getVM().getSystemState().setNextChoiceGenerator(cg); + return this; + } else { // this is what really returns results + cg = ti.getVM().getSystemState().getChoiceGenerator(); + assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; + conditionValue = (Integer)cg.getNextChoice()==0 ? false: true; + } + + sf.pop(); + //System.out.println("Execute IFNE: "+ conditionValue); + PathCondition pc; + + // pc is updated with the pc stored in the choice generator above + // get the path condition from the + // previous choice generator of the same type + + ChoiceGenerator prev_cg = cg.getPreviousChoiceGenerator(); + while (!((prev_cg == null) || (prev_cg instanceof PCChoiceGenerator))) { + prev_cg = prev_cg.getPreviousChoiceGenerator(); + } + + if (prev_cg == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); + + assert pc != null; + + if (conditionValue) { + if (dp[0].equalsIgnoreCase("omega")) {// hack + if((Integer)cg.getNextChoice()==1) + pc._addDet(Comparator.GT, sym_v, 0); + else {// 2 + assert((Integer)cg.getNextChoice()==2); + pc._addDet(Comparator.LT, sym_v, 0); + } + } + else + pc._addDet(Comparator.NE, sym_v, 0); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + }else{ + ((PCChoiceGenerator) cg).setCurrentPC(pc); + //System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getTarget(); + } else { + pc._addDet(Comparator.EQ, sym_v, 0); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + }else{ + ((PCChoiceGenerator) cg).setCurrentPC(pc); + //System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getNext(ti); + } } } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPEQ.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPEQ.java index bbeb3ad..17306b2 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPEQ.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPEQ.java @@ -1,41 +1,22 @@ -/* - * Copyright (C) 2014, United States Government, as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All rights reserved. - * - * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -//Copyright (C) 2007 United States Government as represented by the -//Administrator of the National Aeronautics and Space Administration -//(NASA). All Rights Reserved. - -//This software is distributed under the NASA Open Source Agreement -//(NOSA), version 1.3. The NOSA has been approved by the Open Source -//Initiative. See the file NOSA-1.3-JPF at the top of the distribution -//directory tree for the complete NOSA document. - -//THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY -//KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT -//LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO -//SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR -//A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT -//THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT -//DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. - +/* + * Copyright (C) 2014, United States Government, as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All rights reserved. + * + * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package gov.nasa.jpf.symbc.bytecode; -import gov.nasa.jpf.symbc.bytecode.util.IFInstrSymbHelper; import gov.nasa.jpf.symbc.numeric.*; import gov.nasa.jpf.vm.ChoiceGenerator; import gov.nasa.jpf.vm.Instruction; @@ -61,17 +42,71 @@ public Instruction execute (ThreadInfo ti) { //System.out.println("Execute IF_ICMPEQ: The conditions are concrete"); return super.execute(ti); }else{ // at least one condition is symbolic - Instruction nxtInstr = IFInstrSymbHelper.getNextInstructionAndSetPCChoice(ti, - this, - sym_v1, - sym_v2, - Comparator.EQ, - Comparator.NE); - if(nxtInstr==getTarget()) - conditionValue=true; - else - conditionValue=false; - return nxtInstr; + ChoiceGenerator cg; + + if (!ti.isFirstStepInsn()) { // first time around + cg = new PCChoiceGenerator(2); + ((PCChoiceGenerator)cg).setOffset(this.position); + ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); + ti.getVM().getSystemState().setNextChoiceGenerator(cg); + return this; + } else { // this is what really returns results + cg = ti.getVM().getSystemState().getChoiceGenerator(); + assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; + conditionValue = (Integer)cg.getNextChoice()==0 ? false: true; + } + + int v2 = sf.pop(); + int v1 = sf.pop(); + //System.out.println("Execute IF_ICMPEQ: "+ conditionValue); + PathCondition pc; + + // pc is updated with the pc stored in the choice generator above + // get the path condition from the + // previous choice generator of the same type + + ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + if (prev_cg == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); + + assert pc != null; + + if (conditionValue) { + if (sym_v1 != null){ + if (sym_v2 != null){ //both are symbolic values + pc._addDet(Comparator.EQ,sym_v1,sym_v2); + }else + pc._addDet(Comparator.EQ,sym_v1,v2); + }else + pc._addDet(Comparator.EQ, v1, sym_v2); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + }else{ + //pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + // System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getTarget(); + } else { + if (sym_v1 != null){ + if (sym_v2 != null){ //both are symbolic values + pc._addDet(Comparator.NE,sym_v1,sym_v2); + }else + pc._addDet(Comparator.NE,sym_v1,v2); + }else + pc._addDet(Comparator.NE, v1, sym_v2); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + }else { + //pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + //System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getNext(ti); + } } } } \ No newline at end of file diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPGE.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPGE.java index c5e300e..45a1b2b 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPGE.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPGE.java @@ -1,43 +1,23 @@ -/* - * Copyright (C) 2014, United States Government, as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All rights reserved. - * - * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -//Copyright (C) 2007 United States Government as represented by the -//Administrator of the National Aeronautics and Space Administration -//(NASA). All Rights Reserved. - -//This software is distributed under the NASA Open Source Agreement -//(NOSA), version 1.3. The NOSA has been approved by the Open Source -//Initiative. See the file NOSA-1.3-JPF at the top of the distribution -//directory tree for the complete NOSA document. - -//THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY -//KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT -//LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO -//SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR -//A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT -//THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT -//DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. - +/* + * Copyright (C) 2014, United States Government, as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All rights reserved. + * + * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package gov.nasa.jpf.symbc.bytecode; -import gov.nasa.jpf.symbc.SymbolicInstructionFactory; -import gov.nasa.jpf.symbc.bytecode.util.IFInstrSymbHelper; import gov.nasa.jpf.symbc.numeric.*; import gov.nasa.jpf.vm.ChoiceGenerator; import gov.nasa.jpf.vm.Instruction; @@ -62,17 +42,75 @@ public Instruction execute (ThreadInfo ti) { //System.out.println("Execute IF_ICMPGE: The conditions are concrete"); return super.execute(ti); }else{ // at least one condition is symbolic - Instruction nxtInstr = IFInstrSymbHelper.getNextInstructionAndSetPCChoice(ti, - this, - sym_v1, - sym_v2, - Comparator.GE, - Comparator.LT); - if(nxtInstr==getTarget()) - conditionValue=true; - else - conditionValue=false; - return nxtInstr; + //System.out.println("Execute IF_ICMPGE: The conditions are symbolic"); + ChoiceGenerator cg; + + if (!ti.isFirstStepInsn()) { // first time around + cg = new PCChoiceGenerator(2); + ((PCChoiceGenerator)cg).setOffset(this.position); + ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); + ti.getVM().getSystemState().setNextChoiceGenerator(cg); + return this; + } else { // this is what really returns results + cg = ti.getVM().getSystemState().getChoiceGenerator(); + assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; + conditionValue = (Integer)cg.getNextChoice()==0 ? false: true; + } + + int v2 = sf.pop(); + int v1 = sf.pop(); + //System.out.println("Execute IF_ICMPGE: "+ conditionValue); + PathCondition pc; + + // pc is updated with the pc stored in the choice generator above + // get the path condition from the + // previous choice generator of the same type + + ChoiceGenerator prev_cg = cg.getPreviousChoiceGenerator(); + while (!((prev_cg == null) || (prev_cg instanceof PCChoiceGenerator))) { + prev_cg = prev_cg.getPreviousChoiceGenerator(); + } + + if (prev_cg == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); + + assert pc != null; + + if (conditionValue) { + if (sym_v1 != null){ + if (sym_v2 != null){ //both are symbolic values + pc._addDet(Comparator.GE,sym_v1,sym_v2); + }else + pc._addDet(Comparator.GE,sym_v1,v2); + }else + pc._addDet(Comparator.GE, v1, sym_v2); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + }else{ + //pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + // System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getTarget(); + } else { + if (sym_v1 != null){ + if (sym_v2 != null){ //both are symbolic values + pc._addDet(Comparator.LT,sym_v1,sym_v2); + }else + pc._addDet(Comparator.LT,sym_v1,v2); + }else + pc._addDet(Comparator.LT, v1, sym_v2); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + }else { + //pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + //System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getNext(ti); + } } } } \ No newline at end of file diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPGT.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPGT.java index 19d6bb2..d15bec3 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPGT.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPGT.java @@ -1,42 +1,23 @@ -/* - * Copyright (C) 2014, United States Government, as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All rights reserved. - * - * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -//Copyright (C) 2007 United States Government as represented by the -//Administrator of the National Aeronautics and Space Administration -//(NASA). All Rights Reserved. - -//This software is distributed under the NASA Open Source Agreement -//(NOSA), version 1.3. The NOSA has been approved by the Open Source -//Initiative. See the file NOSA-1.3-JPF at the top of the distribution -//directory tree for the complete NOSA document. - -//THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY -//KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT -//LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO -//SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR -//A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT -//THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT -//DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. +/* + * Copyright (C) 2014, United States Government, as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All rights reserved. + * + * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package gov.nasa.jpf.symbc.bytecode; -import gov.nasa.jpf.symbc.SymbolicInstructionFactory; -import gov.nasa.jpf.symbc.bytecode.util.IFInstrSymbHelper; import gov.nasa.jpf.symbc.numeric.Comparator; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; @@ -64,17 +45,74 @@ public Instruction execute (ThreadInfo ti) { //System.out.println("Execute IF_ICMPGT: The conditions are concrete"); return super.execute(ti); }else{ // at least one condition is symbolic - Instruction nxtInstr = IFInstrSymbHelper.getNextInstructionAndSetPCChoice(ti, - this, - sym_v1, - sym_v2, - Comparator.GT, - Comparator.LE); - if(nxtInstr==getTarget()) - conditionValue=true; - else - conditionValue=false; - return nxtInstr; + ChoiceGenerator cg; + + if (!ti.isFirstStepInsn()) { // first time around + cg = new PCChoiceGenerator(2); + ((PCChoiceGenerator)cg).setOffset(this.position); + ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); + ti.getVM().getSystemState().setNextChoiceGenerator(cg); + return this; + } else { // this is what really returns results + cg = ti.getVM().getSystemState().getChoiceGenerator(); + assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; + conditionValue = (Integer)cg.getNextChoice()==0 ? false: true; + } + + int v2 = sf.pop(); + int v1 = sf.pop(); + //System.out.println("Execute IF_ICMPGT: "+ conditionValue); + PathCondition pc; + + // pc is updated with the pc stored in the choice generator above + // get the path condition from the + // previous choice generator of the same type + + ChoiceGenerator prev_cg = cg.getPreviousChoiceGenerator(); + while (!((prev_cg == null) || (prev_cg instanceof PCChoiceGenerator))) { + prev_cg = prev_cg.getPreviousChoiceGenerator(); + } + + if (prev_cg == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); + + assert pc != null; + + if (conditionValue) { + if (sym_v1 != null){ + if (sym_v2 != null){ //both are symbolic values + pc._addDet(Comparator.GT,sym_v1,sym_v2); + }else + pc._addDet(Comparator.GT,sym_v1,v2); + }else + pc._addDet(Comparator.GT, v1, sym_v2); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + }else{ + //pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + //System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getTarget(); + } else { + if (sym_v1 != null){ + if (sym_v2 != null){ //both are symbolic values + pc._addDet(Comparator.LE,sym_v1,sym_v2); + }else + pc._addDet(Comparator.LE,sym_v1,v2); + }else + pc._addDet(Comparator.LE, v1, sym_v2); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + }else { + //pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + //System.out.println("IF_ICMPGT: " + ((PCChoiceGenerator) cg).getCurrentPC()); + } + return getNext(ti); + } } } } \ No newline at end of file diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPLE.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPLE.java index 064771f..e1e4b8f 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPLE.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPLE.java @@ -1,41 +1,22 @@ -/* - * Copyright (C) 2014, United States Government, as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All rights reserved. - * - * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -//Copyright (C) 2007 United States Government as represented by the -//Administrator of the National Aeronautics and Space Administration -//(NASA). All Rights Reserved. - -//This software is distributed under the NASA Open Source Agreement -//(NOSA), version 1.3. The NOSA has been approved by the Open Source -//Initiative. See the file NOSA-1.3-JPF at the top of the distribution -//directory tree for the complete NOSA document. - -//THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY -//KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT -//LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO -//SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR -//A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT -//THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT -//DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. - +/* + * Copyright (C) 2014, United States Government, as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All rights reserved. + * + * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package gov.nasa.jpf.symbc.bytecode; -import gov.nasa.jpf.symbc.bytecode.util.IFInstrSymbHelper; import gov.nasa.jpf.symbc.numeric.*; import gov.nasa.jpf.vm.ChoiceGenerator; import gov.nasa.jpf.vm.Instruction; @@ -60,17 +41,74 @@ public Instruction execute (ThreadInfo ti) { //System.out.println("Execute IF_ICMPLE: The conditions are concrete"); return super.execute(ti); }else{ // at least one condition is symbolic - Instruction nxtInstr = IFInstrSymbHelper.getNextInstructionAndSetPCChoice(ti, - this, - sym_v1, - sym_v2, - Comparator.LE, - Comparator.GT); - if(nxtInstr==getTarget()) - conditionValue=true; - else - conditionValue=false; - return nxtInstr; + ChoiceGenerator cg; + + if (!ti.isFirstStepInsn()) { // first time around + cg = new PCChoiceGenerator(2); + ((PCChoiceGenerator)cg).setOffset(this.position); + ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); + ti.getVM().getSystemState().setNextChoiceGenerator(cg); + return this; + } else { // this is what really returns results + cg = ti.getVM().getSystemState().getChoiceGenerator(); + assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; + conditionValue = (Integer)cg.getNextChoice()==0 ? false: true; + } + + int v2 = sf.pop(); + int v1 = sf.pop(); + // System.out.println("Execute IF_ICMPLE: "+ conditionValue); + PathCondition pc; + + // pc is updated with the pc stored in the choice generator above + // get the path condition from the + // previous choice generator of the same type + + ChoiceGenerator prev_cg = cg.getPreviousChoiceGenerator(); + while (!((prev_cg == null) || (prev_cg instanceof PCChoiceGenerator))) { + prev_cg = prev_cg.getPreviousChoiceGenerator(); + } + + if (prev_cg == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); + + assert pc != null; + + if (conditionValue) { + if (sym_v1 != null){ + if (sym_v2 != null){ //both are symbolic values + pc._addDet(Comparator.LE,sym_v1,sym_v2); + }else + pc._addDet(Comparator.LE,sym_v1,v2); + }else + pc._addDet(Comparator.LE, v1, sym_v2); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + }else{ + //pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + //System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getTarget(); + } else { + if (sym_v1 != null){ + if (sym_v2 != null){ //both are symbolic values + pc._addDet(Comparator.GT,sym_v1,sym_v2); + }else + pc._addDet(Comparator.GT,sym_v1,v2); + }else + pc._addDet(Comparator.GT, v1, sym_v2); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + }else { + //pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + //System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getNext(ti); + } } } } \ No newline at end of file diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPLT.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPLT.java index ab807e9..9b10211 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPLT.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPLT.java @@ -1,41 +1,23 @@ -/* - * Copyright (C) 2014, United States Government, as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All rights reserved. - * - * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -//Copyright (C) 2007 United States Government as represented by the -//Administrator of the National Aeronautics and Space Administration -//(NASA). All Rights Reserved. - -//This software is distributed under the NASA Open Source Agreement -//(NOSA), version 1.3. The NOSA has been approved by the Open Source -//Initiative. See the file NOSA-1.3-JPF at the top of the distribution -//directory tree for the complete NOSA document. - -//THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY -//KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT -//LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO -//SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR -//A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT -//THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT -//DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. +/* + * Copyright (C) 2014, United States Government, as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All rights reserved. + * + * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package gov.nasa.jpf.symbc.bytecode; -import gov.nasa.jpf.symbc.bytecode.util.IFInstrSymbHelper; import gov.nasa.jpf.symbc.numeric.*; import gov.nasa.jpf.vm.ChoiceGenerator; import gov.nasa.jpf.vm.Instruction; @@ -60,18 +42,74 @@ public Instruction execute (ThreadInfo ti) { //System.out.println("Execute IF_ICMPLT: The conditions are concrete"); return super.execute(ti); }else{ // at least one condition is symbolic - - Instruction nxtInstr = IFInstrSymbHelper.getNextInstructionAndSetPCChoice(ti, - this, - sym_v1, - sym_v2, - Comparator.LT, - Comparator.GE); - if(nxtInstr==getTarget()) - conditionValue=true; - else - conditionValue=false; - return nxtInstr; + ChoiceGenerator cg; + + if (!ti.isFirstStepInsn()) { // first time around + cg = new PCChoiceGenerator(2); + ((PCChoiceGenerator)cg).setOffset(this.position); + ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); + ti.getVM().getSystemState().setNextChoiceGenerator(cg); + return this; + } else { // this is what really returns results + cg = ti.getVM().getSystemState().getChoiceGenerator(); + assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; + conditionValue = (Integer)cg.getNextChoice()==0 ? false: true; + } + + int v2 = sf.pop(); + int v1 = sf.pop(); + //System.out.println("Execute IF_ICMPLT: "+ conditionValue); + PathCondition pc; + + // pc is updated with the pc stored in the choice generator above + // get the path condition from the + // previous choice generator of the same type + + ChoiceGenerator prev_cg = cg.getPreviousChoiceGenerator(); + while (!((prev_cg == null) || (prev_cg instanceof PCChoiceGenerator))) { + prev_cg = prev_cg.getPreviousChoiceGenerator(); + } + + if (prev_cg == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); + + assert pc != null; + + if (conditionValue) { + if (sym_v1 != null){ + if (sym_v2 != null){ //both are symbolic values + pc._addDet(Comparator.LT,sym_v1,sym_v2); + }else + pc._addDet(Comparator.LT,sym_v1,v2); + }else + pc._addDet(Comparator.LT, v1, sym_v2); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + }else{ + //pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + //System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getTarget(); + } else { + if (sym_v1 != null){ + if (sym_v2 != null){ //both are symbolic values + pc._addDet(Comparator.GE,sym_v1,sym_v2); + }else + pc._addDet(Comparator.GE,sym_v1,v2); + }else + pc._addDet(Comparator.GE, v1, sym_v2); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + }else { + //pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + //System.out.println("IF_ICMPLT: " + ((PCChoiceGenerator) cg).getCurrentPC()); + } + return getNext(ti); + } } } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPNE.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPNE.java index ff3fb6b..1868fec 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPNE.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IF_ICMPNE.java @@ -1,42 +1,23 @@ -/* - * Copyright (C) 2014, United States Government, as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All rights reserved. - * - * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -//Copyright (C) 2007 United States Government as represented by the -//Administrator of the National Aeronautics and Space Administration -//(NASA). All Rights Reserved. - -//This software is distributed under the NASA Open Source Agreement -//(NOSA), version 1.3. The NOSA has been approved by the Open Source -//Initiative. See the file NOSA-1.3-JPF at the top of the distribution -//directory tree for the complete NOSA document. - -//THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY -//KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT -//LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO -//SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR -//A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT -//THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT -//DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. - +/* + * Copyright (C) 2014, United States Government, as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All rights reserved. + * + * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package gov.nasa.jpf.symbc.bytecode; -import gov.nasa.jpf.symbc.bytecode.util.IFInstrSymbHelper; import gov.nasa.jpf.symbc.numeric.*; import gov.nasa.jpf.vm.ChoiceGenerator; import gov.nasa.jpf.vm.Instruction; @@ -61,18 +42,74 @@ public Instruction execute (ThreadInfo ti) { //System.out.println("Execute IF_ICMPNE: The conditions are concrete"); return super.execute(ti); }else{ // at least one condition is symbolic - - Instruction nxtInstr = IFInstrSymbHelper.getNextInstructionAndSetPCChoice(ti, - this, - sym_v1, - sym_v2, - Comparator.NE, - Comparator.EQ); - if(nxtInstr==getTarget()) - conditionValue=true; - else - conditionValue=false; - return nxtInstr; + ChoiceGenerator cg; + + if (!ti.isFirstStepInsn()) { // first time around + cg = new PCChoiceGenerator(2); + ((PCChoiceGenerator)cg).setOffset(this.position); + ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); + ti.getVM().getSystemState().setNextChoiceGenerator(cg); + return this; + } else { // this is what really returns results + cg = ti.getVM().getSystemState().getChoiceGenerator(); + assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; + conditionValue = (Integer)cg.getNextChoice()==0 ? false: true; + } + + int v2 = sf.pop(); + int v1 = sf.pop(); + //System.out.println("Execute IF_ICMPNE: "+ conditionValue); + PathCondition pc; + + // pc is updated with the pc stored in the choice generator above + // get the path condition from the + // previous choice generator of the same type + + ChoiceGenerator prev_cg = cg.getPreviousChoiceGenerator(); + while (!((prev_cg == null) || (prev_cg instanceof PCChoiceGenerator))) { + prev_cg = prev_cg.getPreviousChoiceGenerator(); + } + + if (prev_cg == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); + + assert pc != null; + + if (conditionValue) { + if (sym_v1 != null){ + if (sym_v2 != null){ //both are symbolic values + pc._addDet(Comparator.NE,sym_v1,sym_v2); + }else + pc._addDet(Comparator.NE,sym_v1,v2); + }else + pc._addDet(Comparator.NE, v1, sym_v2); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + }else{ + //pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + // System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getTarget(); + } else { + if (sym_v1 != null){ + if (sym_v2 != null){ //both are symbolic values + pc._addDet(Comparator.EQ,sym_v1,sym_v2); + }else + pc._addDet(Comparator.EQ,sym_v1,v2); + }else + pc._addDet(Comparator.EQ, v1, sym_v2); + if(!pc.simplify()) {// not satisfiable + ti.getVM().getSystemState().setIgnored(true); + }else { + //pc.solve(); + ((PCChoiceGenerator) cg).setCurrentPC(pc); + //System.out.println(((PCChoiceGenerator) cg).getCurrentPC()); + } + return getNext(ti); + } } } } \ No newline at end of file diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/INVOKEINTERFACE.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/INVOKEINTERFACE.java index 9f55a83..eb59adf 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/INVOKEINTERFACE.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/INVOKEINTERFACE.java @@ -19,6 +19,7 @@ import gov.nasa.jpf.vm.Instruction; import gov.nasa.jpf.vm.MethodInfo; +import gov.nasa.jpf.vm.MJIEnv; import gov.nasa.jpf.vm.ThreadInfo; // need to fix names @@ -33,7 +34,7 @@ public INVOKEINTERFACE(String clsName, String methodName, String methodSignature public Instruction execute(ThreadInfo th) { int objRef = th.getCalleeThis(getArgSize()); - if (objRef == -1) { + if (objRef == MJIEnv.NULL) { lastObj = -1; return th.createAndThrowException("java.lang.NullPointerException", "Calling '" + mname + "' on null object"); } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/INVOKEVIRTUAL.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/INVOKEVIRTUAL.java index 8bf498b..a3c208e 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/INVOKEVIRTUAL.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/INVOKEVIRTUAL.java @@ -20,6 +20,7 @@ import gov.nasa.jpf.vm.ClassInfo; import gov.nasa.jpf.vm.Instruction; import gov.nasa.jpf.vm.MethodInfo; +import gov.nasa.jpf.vm.MJIEnv; import gov.nasa.jpf.vm.ThreadInfo; // need to fix names @@ -34,7 +35,7 @@ public INVOKEVIRTUAL(String clsName, String methodName, String methodSignature) public Instruction execute( ThreadInfo th) { int objRef = th.getCalleeThis(getArgSize()); - if (objRef == -1) { + if (objRef == MJIEnv.NULL) { lastObj = -1; return th.createAndThrowException("java.lang.NullPointerException", "Calling '" + mname + "' on null object"); } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/ISHL.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/ISHL.java index 8d4c6f7..6cf4473 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/ISHL.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/ISHL.java @@ -19,6 +19,7 @@ package gov.nasa.jpf.symbc.bytecode; +import gov.nasa.jpf.symbc.numeric.IntegerConstant; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.vm.Instruction; import gov.nasa.jpf.vm.StackFrame; @@ -41,15 +42,20 @@ public Instruction execute (ThreadInfo th) { IntegerExpression result = null; if(sym_v1!=null) { - if (sym_v2!=null) - result = sym_v1._shiftL(sym_v2); - else // v2 is concrete - result = sym_v1._shiftL(v2); + if (sym_v2!=null) { + //result = sym_v1._shiftL(sym_v2); + result = sym_v2._shiftL(sym_v1); + } + else { // v2 is concrete + //result = sym_v1._shiftL(v2); + result = (new IntegerConstant((int) v2))._shiftL(sym_v1); + } } - else if (sym_v2!=null) + else if (sym_v2 != null) { result = sym_v2._shiftL(v1); + } + sf.setOperandAttr(result); - return getNext(th); } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/ISHR.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/ISHR.java index 888cc08..32a7d54 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/ISHR.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/ISHR.java @@ -19,6 +19,7 @@ package gov.nasa.jpf.symbc.bytecode; +import gov.nasa.jpf.symbc.numeric.IntegerConstant; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.vm.Instruction; import gov.nasa.jpf.vm.StackFrame; @@ -40,16 +41,22 @@ public Instruction execute (ThreadInfo th) { sf.push(0, false); // for symbolic expressions, the concrete value does not matter IntegerExpression result = null; - if(sym_v1!=null) { - if (sym_v2!=null) - result = sym_v1._shiftR(sym_v2); - else // v2 is concrete - result = sym_v1._shiftR(v2); + if (sym_v1 != null) { + if (sym_v2!=null) { + //result = sym_v1._shiftR(sym_v2); + // FIX: it's the second argument right shifted by the first argument + result = sym_v2._shiftR(sym_v1); + } + else {// v2 is concrete + //result = sym_v1._shiftR(v2); + result = (new IntegerConstant((int) v2))._shiftR(sym_v1); + } } - else if (sym_v2!=null) + else if (sym_v2 != null) { result = sym_v2._shiftR(v1); + } + sf.setOperandAttr(result); - return getNext(th); } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IUSHR.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IUSHR.java index b7a4286..77b1c1c 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IUSHR.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/IUSHR.java @@ -19,6 +19,7 @@ package gov.nasa.jpf.symbc.bytecode; +import gov.nasa.jpf.symbc.numeric.IntegerConstant; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.vm.Instruction; import gov.nasa.jpf.vm.StackFrame; @@ -40,16 +41,21 @@ public Instruction execute (ThreadInfo th) { sf.push(0, false); // for symbolic expressions, the concrete value does not matter IntegerExpression result = null; - if(sym_v1!=null) { - if (sym_v2!=null) - result = sym_v1._shiftUR(sym_v2); - else // v2 is concrete - result = sym_v1._shiftUR(v2); + if(sym_v1 != null) { + if (sym_v2 != null) { + //result = sym_v1._shiftUR(sym_v2); + result = sym_v2._shiftUR(sym_v1); + } + else { // v2 is concrete + //result = sym_v1._shiftUR(v2); + result = (new IntegerConstant((int) v2))._shiftUR(sym_v1); + } } - else if (sym_v2!=null) + else if (sym_v2 != null) { result = sym_v2._shiftUR(v1); + } + sf.setOperandAttr(result); - return getNext(th); } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LALOAD.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LALOAD.java index 0abccd4..3d504d9 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LALOAD.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LALOAD.java @@ -20,17 +20,11 @@ package gov.nasa.jpf.symbc.bytecode; import gov.nasa.jpf.symbc.SymbolicInstructionFactory; -import gov.nasa.jpf.symbc.arrays.ArrayExpression; -import gov.nasa.jpf.symbc.arrays.SelectExpression; -import gov.nasa.jpf.symbc.arrays.IntegerSymbolicArray; -import gov.nasa.jpf.symbc.arrays.SymbolicIntegerValueAtIndex; import gov.nasa.jpf.symbc.numeric.Comparator; -import gov.nasa.jpf.symbc.numeric.IntegerConstant; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; import gov.nasa.jpf.symbc.numeric.PathCondition; import gov.nasa.jpf.vm.ArrayIndexOutOfBoundsExecutiveException; -import gov.nasa.jpf.vm.ChoiceGenerator; import gov.nasa.jpf.vm.ElementInfo; import gov.nasa.jpf.vm.Instruction; import gov.nasa.jpf.vm.MJIEnv; @@ -45,125 +39,115 @@ public class LALOAD extends gov.nasa.jpf.jvm.bytecode.LALOAD { @Override public Instruction execute (ThreadInfo ti) { - - if (peekArrayAttr(ti)==null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { - // In this case, the array isn't symbolic - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case, the index isn't symbolic either - return super.execute(ti); - } - } - - IntegerSymbolicArray arrayAttr = null; - ChoiceGenerator cg; - boolean condition; - StackFrame frame = ti.getModifiableTopFrame(); - arrayRef = frame.peek(1); // ..., arrayRef, idx - - if (!ti.isFirstStepInsn()) { // first time around - cg = new PCChoiceGenerator(3); - ((PCChoiceGenerator)cg).setOffset(this.position); - ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); - ti.getVM().setNextChoiceGenerator(cg); - return this; - } else { // this is what really returns results - cg = ti.getVM().getChoiceGenerator(); - assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; - } - - PathCondition pc; - ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - if (prev_cg == null) - pc = new PathCondition(); - else - pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); - - assert pc != null; - - if (peekArrayAttr(ti)==null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { - // In this case, the array isn't symbolic - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case, the index isn't symbolic either - return super.execute(ti); - } - // We have a concrete array, but a symbolic index. We add all the constraints about the elements of the array, and perform the select - ElementInfo arrayInfo = ti.getElementInfo(arrayRef); - arrayAttr = new IntegerSymbolicArray(arrayInfo.arrayLength()); - for (int i = 0; i < arrayInfo.arrayLength(); i++) { - long arrValue = arrayInfo.getLongElement(i); - pc._addDet(Comparator.EQ, new SelectExpression(arrayAttr, i), new IntegerConstant((int)arrValue)); - } - } - - else { - arrayAttr = (IntegerSymbolicArray)peekArrayAttr(ti); - } - IntegerExpression indexAttr = null; - SelectExpression se = null; - - if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case, the index isn't symbolic. - index = frame.peek(); - se = new SelectExpression(arrayAttr, index); - indexAttr = new IntegerConstant(index); - - } else { - indexAttr = (IntegerExpression)peekIndexAttr(ti); - se = new SelectExpression(arrayAttr, indexAttr); - } - - assert arrayAttr != null; - assert indexAttr != null; - assert se != null; - - if (arrayRef == MJIEnv.NULL) { - return ti.createAndThrowException("java.lang.NullPointerException"); - } - - - if ((Integer)cg.getNextChoice()==1) { // check bounds of the index - pc._addDet(Comparator.GE, se.index, se.ae.length); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index greater than array bounds"); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - else if ((Integer)cg.getNextChoice()==2) { - pc._addDet(Comparator.LT, se.index, new IntegerConstant(0)); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index smaller than array bounds"); - } else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - else { - pc._addDet(Comparator.LT, se.index, se.ae.length); - pc._addDet(Comparator.GE, se.index, new IntegerConstant(0)); - if (pc.simplify()) { //satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - - // set the result - // We update the Symbolic Array with the get information - SymbolicIntegerValueAtIndex result = arrayAttr.getVal(indexAttr); - frame.pop(2); // We pop the array and the index - frame.push(0, false); // For symbolic expressions, the concrete value does not matter - frame.setLongOperandAttr(result.value); - // We add the select instruction in the PathCondition - pc._addDet(Comparator.EQ, se, result.value); - return getNext(ti); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - } + + if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) + return super.execute(ti); + StackFrame frame = ti.getModifiableTopFrame(); + arrayRef = frame.peek(1); // ..,arrayRef,idx + if (arrayRef == MJIEnv.NULL) { + return ti.createAndThrowException("java.lang.NullPointerException"); + } + + ElementInfo eiArray = ti.getElementInfo(arrayRef); + int len=(eiArray.getArrayFields()).arrayLength(); // assumed concrete + if(!ti.isFirstStepInsn()){ + PCChoiceGenerator arrayCG = new PCChoiceGenerator(0,len+1); // add 2 error cases: <0, >=len + ti.getVM().getSystemState().setNextChoiceGenerator(arrayCG); + + if (SymbolicInstructionFactory.debugMode) + System.out.println("# array cg registered: " + arrayCG); + return this; + + } else { //this is what really returns results + + //index = frame.peek(); + PCChoiceGenerator lastCG=ti.getVM().getSystemState().getLastChoiceGeneratorOfType(PCChoiceGenerator.class); + assert(lastCG!=null); + PCChoiceGenerator prevCG=lastCG.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + index=lastCG.getNextChoice(); + IntegerExpression sym_index=(IntegerExpression)peekIndexAttr(ti); + //check the constraint + + PathCondition pc; + + if (prevCG == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prevCG).getCurrentPC(); + + assert pc != null; + + if(index ... @@ -47,142 +40,128 @@ public class LASTORE extends gov.nasa.jpf.jvm.bytecode.LASTORE { @Override - public Instruction execute (ThreadInfo ti) { - // We may need to add the case where we have a smybolic index and a concrete array - - IntegerExpression indexAttr = null; - IntegerSymbolicArray arrayAttr = null; - StackFrame frame = ti.getModifiableTopFrame(); - - if (peekArrayAttr(ti)==null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { - //In this case, the array isn't symbolic - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - if (frame.getOperandAttr(1) == null || !(frame.getOperandAttr(1) instanceof IntegerExpression)) { - // nothing is symbolic here - return super.execute(ti); - } - } - } + public Instruction execute (ThreadInfo ti) { + if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) + return super.execute(ti); + StackFrame frame = ti.getModifiableTopFrame(); + int arrayref = peekArrayRef(ti); // need to be polymorphic, could be LongArrayStore + ElementInfo eiArray = ti.getElementInfo(arrayref); + + if (arrayref == MJIEnv.NULL) { + return ti.createAndThrowException("java.lang.NullPointerException"); + } + + + int len=(eiArray.getArrayFields()).arrayLength(); // assumed concrete + + if(!ti.isFirstStepInsn()){ + PCChoiceGenerator arrayCG = new PCChoiceGenerator(0,len+1); // add 2 error cases: <0, >=len + ti.getVM().getSystemState().setNextChoiceGenerator(arrayCG); + + //ti.reExecuteInstruction(); + if (SymbolicInstructionFactory.debugMode) + System.out.println("# array cg registered: " + arrayCG); + return this; + } else { //this is what really returns results + + - ChoiceGenerator cg; - boolean condition; - int arrayRef = peekArrayRef(ti); // need to be polymorphic, could be LongArrayStore + //index = frame.peek(); + PCChoiceGenerator lastCG=ti.getVM().getSystemState().getLastChoiceGeneratorOfType(PCChoiceGenerator.class); + assert(lastCG!=null); + PCChoiceGenerator prevCG=lastCG.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + index=lastCG.getNextChoice(); + IntegerExpression sym_index=(IntegerExpression)peekIndexAttr(ti); + //check the constraint + + PathCondition pc; + + if (prevCG == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prevCG).getCurrentPC(); - if (!ti.isFirstStepInsn()) { // first time around - cg = new PCChoiceGenerator(3); - ((PCChoiceGenerator) cg).setOffset(this.position); - ((PCChoiceGenerator) cg).setMethodName(this.getMethodInfo().getFullName()); - ti.getVM().setNextChoiceGenerator(cg); - return this; - } else { // this is what really returns results - cg = ti.getVM().getChoiceGenerator(); - assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; - } - - PathCondition pc; - ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - if (prev_cg == null) - pc = new PathCondition(); - else - pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); - - assert pc != null; + assert pc != null; - if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - int index = peekIndex(ti); - indexAttr = new IntegerConstant(index); - } else { - indexAttr = (IntegerExpression)peekIndexAttr(ti); - } - assert (indexAttr != null) : "indexAttr shouldn't be null in IASTORE instruction"; - - if (peekArrayAttr(ti)==null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { - //In this case, the array isn't symbolic - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - if (frame.getOperandAttr(1) == null || !(frame.getOperandAttr(1) instanceof IntegerExpression)) { - // nothing is symbolic here - return super.execute(ti); - } - } else { - // We create a symbolic array out of the concrete array - ElementInfo arrayInfo = ti.getElementInfo(arrayRef); - arrayAttr = new IntegerSymbolicArray(arrayInfo.arrayLength()); - // We add the constraints about all the elements of the array - for (int i = 0; i < arrayInfo.arrayLength(); i++) { - long arrValue = arrayInfo.getLongElement(i); - pc._addDet(Comparator.EQ, new SelectExpression(arrayAttr, i), new IntegerConstant((int)arrValue)); - } - } - } else { - arrayAttr = (IntegerSymbolicArray)peekArrayAttr(ti); - } - assert (arrayAttr != null) : "arrayAttr shouldn't be null in IASTORE instruction"; + if(index what if the value is the same but not the attr? + + } catch (ArrayIndexOutOfBoundsExecutiveException ex) { // at this point, the AIOBX is already processed + return ex.getInstruction(); + } - // We have to check if the value is symbolic or not, create a symbolicIntegerValueatIndex out of it, and - // call the setVal function, before storing the attr - IntegerExpression sym_value = null; - if (frame.getOperandAttr(1) == null || !(frame.getOperandAttr(1) instanceof IntegerExpression)) { - // The value isn't symbolic. We store a new IntegerConstant in the valAt map, at index indexAttr - long value = frame.popLong(); - sym_value = new IntegerConstant((int)value); - } - else { - // The value is symbolic. - sym_value = (IntegerExpression)frame.getOperandAttr(0); - frame.popLong(); - } - PreviousIntegerArray previous = new PreviousIntegerArray(arrayAttr, indexAttr, sym_value); - // We create a new arrayAttr, and inherits information from the previous attribute - IntegerSymbolicArray newArrayAttr = new IntegerSymbolicArray(previous); - frame.pop(2); // We pop the array and the index + return getNext(ti); + } + } - StoreExpression se = new StoreExpression(arrayAttr, indexAttr, sym_value); - pc._addDet(Comparator.EQ, se, newArrayAttr); - - return getNext(ti); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - } - } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LCMP.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LCMP.java index 1fea5a5..afcb1eb 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LCMP.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LCMP.java @@ -18,7 +18,6 @@ package gov.nasa.jpf.symbc.bytecode; -import gov.nasa.jpf.symbc.bytecode.util.IFInstrSymbHelper; import gov.nasa.jpf.symbc.numeric.Comparator; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; @@ -45,16 +44,8 @@ public Instruction execute (ThreadInfo th) { if (sym_v1 == null && sym_v2 == null) // both conditions are concrete return super.execute(th); else { // at least one condition is symbolic - Instruction nxtInstr = IFInstrSymbHelper.getNextInstructionAndSetPCChoice(th, - this, - sym_v1, - sym_v2, - Comparator.LT, - Comparator.EQ, - Comparator.GT); - - return nxtInstr; - /*ChoiceGenerator cg; + + ChoiceGenerator cg; int conditionValue; if (!th.isFirstStepInsn()) { // first time around @@ -139,7 +130,7 @@ public Instruction execute (ThreadInfo th) { sf.push(conditionValue, false); //System.out.println("Execute LCMP: " + ((PCChoiceGenerator) cg).getCurrentPC()); - return getNext(th);*/ + return getNext(th); } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LMUL.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LMUL.java index 2aefecb..adc9f50 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LMUL.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LMUL.java @@ -45,20 +45,20 @@ public Instruction execute (ThreadInfo th) { sf.pushLong(0); // for symbolic expressions, the concrete value does not matter IntegerExpression result = null; - if(sym_v1!=null) { - if (sym_v2!=null) - result = sym_v1._mul(sym_v2); - else // v2 is concrete - result = sym_v1._mul(v2); - } - else if (sym_v2!=null) - result = sym_v2._mul(v1); + + if(sym_v1!=null) { + if (sym_v2!=null) + result = sym_v1._mul(sym_v2); + else // v2 is concrete + result = sym_v1._mul(v2); + } + else if (sym_v2!=null) + result = sym_v2._mul(v1); + sf.setLongOperandAttr(result); - sf.setLongOperandAttr(result); + //System.out.println("Execute IMUL: "+result); - //System.out.println("Execute LMUL: "+result); - - return getNext(th); + return getNext(th); } } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LREM.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LREM.java index 1ec8839..bc1786d 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LREM.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LREM.java @@ -18,7 +18,11 @@ package gov.nasa.jpf.symbc.bytecode; +import gov.nasa.jpf.symbc.numeric.Comparator; import gov.nasa.jpf.symbc.numeric.IntegerExpression; +import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; +import gov.nasa.jpf.symbc.numeric.PathCondition; +import gov.nasa.jpf.vm.ChoiceGenerator; import gov.nasa.jpf.vm.Instruction; import gov.nasa.jpf.vm.StackFrame; import gov.nasa.jpf.vm.ThreadInfo; @@ -36,12 +40,101 @@ public Instruction execute (ThreadInfo th) { IntegerExpression sym_v1 = (IntegerExpression) sf.getOperandAttr(1); IntegerExpression sym_v2 = (IntegerExpression) sf.getOperandAttr(3); - + long v1, v2; + if(sym_v1==null && sym_v2==null) return super.execute( th);// we'll still do the concrete execution else { - throw new RuntimeException("## Error: SYMBOLIC LREM not supported"); - } + + // result is symbolic + + if(sym_v1==null && sym_v2!=null) { + v1 = sf.popLong(); + v2 = sf.popLong(); + if(v1==0) + return th.createAndThrowException("java.lang.ArithmeticException","div by 0"); + sf.pushLong(0); + IntegerExpression result = sym_v2._rem(v1); + sf.setLongOperandAttr(result); + return getNext(th); + } + + // div by zero check affects path condition + // sym_v1 is non-null and should be checked against zero + + ChoiceGenerator cg; + boolean condition; + + if (!th.isFirstStepInsn()) { // first time around + cg = new PCChoiceGenerator(2); + ((PCChoiceGenerator)cg).setOffset(this.position); + ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); + th.getVM().getSystemState().setNextChoiceGenerator(cg); + return this; + } else { // this is what really returns results + cg = th.getVM().getSystemState().getChoiceGenerator(); + assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; + condition = (Integer)cg.getNextChoice()==0 ? false: true; + } + + + v1 = sf.popLong(); + v2 = sf.popLong(); + sf.pushLong(0); + + PathCondition pc; + ChoiceGenerator prev_cg = cg.getPreviousChoiceGenerator(); + + while (!((prev_cg == null) || (prev_cg instanceof PCChoiceGenerator))) { + prev_cg = prev_cg.getPreviousChoiceGenerator(); + } + if (prev_cg == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); + + assert pc != null; + + if(condition) { // check div by zero + pc._addDet(Comparator.EQ, sym_v1, 0); + if(pc.simplify()) { // satisfiable + ((PCChoiceGenerator) cg).setCurrentPC(pc); + + return th.createAndThrowException("java.lang.ArithmeticException","rem by 0"); + } + else { + th.getVM().getSystemState().setIgnored(true); + return getNext(th); + } + } + else { + pc._addDet(Comparator.NE, sym_v1, 0); + if(pc.simplify()) { // satisfiable + ((PCChoiceGenerator) cg).setCurrentPC(pc); + + // set the result + IntegerExpression result; + if(sym_v2!=null) + result = sym_v2._rem(sym_v1); + else + result = sym_v1._rem_reverse(v2); + + sf = th.getModifiableTopFrame(); + sf.setLongOperandAttr(result); + return getNext(th); + + } + else { + th.getVM().getSystemState().setIgnored(true); + return getNext(th); + } + } + + } + + + + } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LSHL.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LSHL.java index dc4fe2d..3dc4d27 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LSHL.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LSHL.java @@ -17,6 +17,7 @@ */ package gov.nasa.jpf.symbc.bytecode; +import gov.nasa.jpf.symbc.numeric.IntegerConstant; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.vm.Instruction; import gov.nasa.jpf.vm.StackFrame; @@ -43,20 +44,22 @@ public Instruction execute (ThreadInfo th) { sf.pushLong(0); // for symbolic expressions, the concrete value does not matter IntegerExpression result = null; - if(sym_v1!=null) { - if (sym_v2!=null) - result = sym_v1._shiftL(sym_v2); - else // v2 is concrete - result = sym_v1._shiftL(v2); + if (sym_v1 != null) { + if (sym_v2 != null) { + //result = sym_v1._shiftL(sym_v2); + result = sym_v2._shiftL(sym_v1); + } + else { // v2 is concrete + //result = sym_v1._shiftL(v2); + result = (new IntegerConstant((int) v2))._shiftL(sym_v1); + } } - else if (sym_v2!=null) { + else if (sym_v2 != null) { result = sym_v2._shiftL(v1); - } - sf.setLongOperandAttr(result); + sf.setLongOperandAttr(result); return getNext(th); } } - } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LSHR.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LSHR.java index 7c9656b..dbf3ed9 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LSHR.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LSHR.java @@ -18,6 +18,7 @@ package gov.nasa.jpf.symbc.bytecode; +import gov.nasa.jpf.symbc.numeric.IntegerConstant; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.vm.Instruction; import gov.nasa.jpf.vm.StackFrame; @@ -44,18 +45,21 @@ public Instruction execute (ThreadInfo th) { sf.pushLong(0); // for symbolic expressions, the concrete value does not matter IntegerExpression result = null; - if(sym_v1!=null) { - if (sym_v2!=null) - result = sym_v1._shiftR(sym_v2); - else // v2 is concrete - result = sym_v1._shiftR(v2); + if (sym_v1 != null) { + if (sym_v2 != null) { + //result = sym_v1._shiftR(sym_v2); + result = sym_v2._shiftR(sym_v1); + } + else { // v2 is concrete + //result = sym_v1._shiftR(v2); + result = (new IntegerConstant((int) v2))._shiftR(sym_v1); + } } - else if (sym_v2!=null) { + else if (sym_v2 != null) { result = sym_v2._shiftR(v1); - } - sf.setLongOperandAttr(result); + sf.setLongOperandAttr(result); return getNext(th); } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LUSHR.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LUSHR.java index ac63988..660a2a8 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LUSHR.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/LUSHR.java @@ -17,6 +17,7 @@ */ package gov.nasa.jpf.symbc.bytecode; +import gov.nasa.jpf.symbc.numeric.IntegerConstant; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.vm.Instruction; import gov.nasa.jpf.vm.StackFrame; @@ -38,23 +39,26 @@ public Instruction execute (ThreadInfo th) { if(sym_v1==null && sym_v2==null) return super.execute( th);// we'll still do the concrete execution else { - long v1 = sf.pop(); + int v1 = sf.pop(); long v2 = sf.popLong(); sf.pushLong(0); // for symbolic expressions, the concrete value does not matter IntegerExpression result = null; if(sym_v1!=null) { - if (sym_v2!=null) - result = sym_v1._shiftUR(sym_v2); - else // v2 is concrete - result = sym_v1._shiftUR(v2); + if (sym_v2!=null) { + //result = sym_v1._shiftUR(sym_v2); + result = sym_v2._shiftUR(sym_v1); + } + else { // v2 is concrete + result = sym_v1._shiftUR(v2); + result = (new IntegerConstant((int) v2))._shiftUR(sym_v1); + } } - else if (sym_v2!=null) { - result = sym_v2._shiftUR(v1); - + else if (sym_v2 != null) { + result = sym_v2._shiftUR(v1); } - sf.setLongOperandAttr(result); + sf.setLongOperandAttr(result); return getNext(th); } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/MULTIANEWARRAY.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/MULTIANEWARRAY.java index 8abc010..4e068ad 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/MULTIANEWARRAY.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/MULTIANEWARRAY.java @@ -50,11 +50,12 @@ public Instruction execute(ThreadInfo ti) { Object attr = sf.getOperandAttr(); if(attr instanceof SymbolicLengthInteger) { - arrayLengths[i] = ((SymbolicLengthInteger) attr).solution; + long l = ((SymbolicLengthInteger) attr).solution; + assert(l>=0 && l<=Integer.MAX_VALUE) : "Array length must be positive integer"; + arrayLengths[i] = (int) l; sf.pop(); } else if(attr instanceof IntegerExpression) { - arrayLengths[i] = ((IntegerExpression) attr).solution(); - sf.pop(); + throw new RuntimeException("MULTIANEWARRAY: symbolic array length"); } else { arrayLengths[i] = sf.pop(); } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/NEWARRAY.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/NEWARRAY.java index 996c39f..dbe863a 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/NEWARRAY.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/NEWARRAY.java @@ -51,6 +51,7 @@ public NEWARRAY(int typeCode) { @Override public Instruction execute( ThreadInfo ti) { + /* StackFrame frame = ti.getModifiableTopFrame(); arrayLength = frame.pop(); @@ -83,28 +84,21 @@ public Instruction execute( ThreadInfo ti) { frame.pushRef(arrayRef); return getNext(ti); - + */ // old code - // Corina: I'll comment it out for the time being - /* + // Corina: incorrect + StackFrame sf = ti.getModifiableTopFrame(); Object attr = sf.getOperandAttr(); if(attr instanceof SymbolicLengthInteger) { - arrayLength = ((SymbolicLengthInteger) attr).solution; + long l = ((SymbolicLengthInteger) attr).solution; + assert(l>=0 && l<=Integer.MAX_VALUE) : "Array length must be positive integer"; + arrayLength = (int) l; sf.pop(); } else if(attr instanceof IntegerExpression) { - if (!PathCondition.flagSolved) { - // TODO I don't know what to do in this case; I believe this - // only happens if the array initialization is - // located before a program branch. - - // Corina: in reality here we should do the equivalent of lazy initialization for arrays - throw new RuntimeException( - "Path condition is not solved; Check the comments above this line for more details!"); - } - arrayLength = ((IntegerExpression) attr).solution(); - sf.pop(); + throw new RuntimeException("NEWARRAY: symbolic array length"); + } else { arrayLength = sf.pop(); } @@ -120,8 +114,8 @@ public Instruction execute( ThreadInfo ti) { // there is no clinit for array classes, but we still have to create a class object // since its a builtin class, we also don't have to bother with NoClassDefFoundErrors String clsName = "[" + type; - ClassInfo ci = ClassInfo.getResolvedClassInfo(clsName); - + + ClassInfo ci = ClassLoaderInfo.getCurrentResolvedClassInfo(clsName); if (!ci.isRegistered()) { ci.registerClass(ti); ci.setInitialized(); @@ -134,12 +128,15 @@ public Instruction execute( ThreadInfo ti) { "[" + arrayLength + "]"); } - int arrayRef = heap.newArray(type, arrayLength, ti); - sf.push(arrayRef, true); + ElementInfo eiArray = heap.newArray(type, arrayLength, ti); + int arrayRef = eiArray.getObjectRef(); + + sf.pushRef(arrayRef); + ti.getVM().getSystemState().checkGC(); // has to happen after we push the new object ref return getNext(ti); - */ + } } \ No newline at end of file diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/SALOAD.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/SALOAD.java index 1cf0926..d4fa97f 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/SALOAD.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/SALOAD.java @@ -21,17 +21,11 @@ package gov.nasa.jpf.symbc.bytecode; import gov.nasa.jpf.symbc.SymbolicInstructionFactory; -import gov.nasa.jpf.symbc.arrays.ArrayExpression; -import gov.nasa.jpf.symbc.arrays.SelectExpression; -import gov.nasa.jpf.symbc.arrays.IntegerSymbolicArray; -import gov.nasa.jpf.symbc.arrays.SymbolicIntegerValueAtIndex; import gov.nasa.jpf.symbc.numeric.Comparator; -import gov.nasa.jpf.symbc.numeric.IntegerConstant; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; import gov.nasa.jpf.symbc.numeric.PathCondition; import gov.nasa.jpf.vm.ArrayIndexOutOfBoundsExecutiveException; -import gov.nasa.jpf.vm.ChoiceGenerator; import gov.nasa.jpf.vm.ElementInfo; import gov.nasa.jpf.vm.Instruction; import gov.nasa.jpf.vm.MJIEnv; @@ -46,116 +40,115 @@ public class SALOAD extends gov.nasa.jpf.jvm.bytecode.SALOAD { @Override public Instruction execute (ThreadInfo ti) { - - if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case, the array isn't symbolic - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case, the index isn't symbolic either - return super.execute(ti); - } - } - - IntegerSymbolicArray arrayAttr = null; - ChoiceGenerator cg; - boolean condition; - StackFrame frame = ti.getModifiableTopFrame(); + + if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) + return super.execute(ti); + StackFrame frame = ti.getModifiableTopFrame(); arrayRef = frame.peek(1); // ..,arrayRef,idx + if (arrayRef == MJIEnv.NULL) { + return ti.createAndThrowException("java.lang.NullPointerException"); + } + + ElementInfo eiArray = ti.getElementInfo(arrayRef); + int len=(eiArray.getArrayFields()).arrayLength(); // assumed concrete + if(!ti.isFirstStepInsn()){ + PCChoiceGenerator arrayCG = new PCChoiceGenerator(0,len+1); // add 2 error cases: <0, >=len + ti.getVM().getSystemState().setNextChoiceGenerator(arrayCG); + + if (SymbolicInstructionFactory.debugMode) + System.out.println("# array cg registered: " + arrayCG); + return this; - if (!ti.isFirstStepInsn()) { // first time around - cg = new PCChoiceGenerator(3); - ((PCChoiceGenerator)cg).setOffset(this.position); - ((PCChoiceGenerator)cg).setMethodName(this.getMethodInfo().getFullName()); - ti.getVM().setNextChoiceGenerator(cg); - return this; - } else { // this is what really returns results - cg = ti.getVM().getChoiceGenerator(); - assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; - } - - PathCondition pc; - ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - if (prev_cg == null) - pc = new PathCondition(); - else - pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); - - assert pc != null; - - if (peekArrayAttr(ti) == null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { - // In this case, the array isn't symbolic - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case, the index isn't symbolic either - return super.execute(ti); - } - // We have a concrete array, but a symbolic index. We add all the constraints and perform the select - ElementInfo arrayInfo = ti.getElementInfo(arrayRef); - arrayAttr = new IntegerSymbolicArray(arrayInfo.arrayLength()); - for (int i = 0; i < arrayInfo.arrayLength(); i++) { - int arrValue = arrayInfo.getShortElement(i); - pc._addDet(Comparator.EQ, new SelectExpression(arrayAttr, i), new IntegerConstant(arrValue)); - } - } else { - arrayAttr = (IntegerSymbolicArray)peekArrayAttr(ti); - } - IntegerExpression indexAttr = null; - SelectExpression se = null; - - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - // In this case, the index isn't symbolic. - index = frame.peek(); - se = new SelectExpression(arrayAttr, index); - indexAttr = new IntegerConstant(index); - } else { - indexAttr = (IntegerExpression)peekIndexAttr(ti); - se = new SelectExpression(arrayAttr, indexAttr); - } - - assert arrayAttr != null; - assert indexAttr != null; - assert se != null; + } else { //this is what really returns results + + //index = frame.peek(); + PCChoiceGenerator lastCG=ti.getVM().getSystemState().getLastChoiceGeneratorOfType(PCChoiceGenerator.class); + assert(lastCG!=null); + PCChoiceGenerator prevCG=lastCG.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + index=lastCG.getNextChoice(); + IntegerExpression sym_index=(IntegerExpression)peekIndexAttr(ti); + //check the constraint + + PathCondition pc; + + if (prevCG == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prevCG).getCurrentPC(); - if (arrayRef == MJIEnv.NULL) { - return ti.createAndThrowException("java.lang.NullPointerException"); - } - - if ((Integer)cg.getNextChoice() == 1) { // check bounds of the index - pc._addDet(Comparator.GE, se.index, se.ae.length); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index greater than array bounds"); - } else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } else if ((Integer)cg.getNextChoice() == 2) { - pc._addDet(Comparator.LT, se.index, new IntegerConstant(0)); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index smaller than array bounds"); - } else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } else { - pc._addDet(Comparator.LT, se.index, se.ae.length); - pc._addDet(Comparator.GE, se.index, new IntegerConstant(0)); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); + assert pc != null; - // Set the result - // We update the Symbolic Array with the get information - SymbolicIntegerValueAtIndex result = arrayAttr.getVal(indexAttr); - frame.pop(2); // We pop the array and the index - frame.push(0, false); // For symbolic expressions, the concrete value does not matter - frame.setOperandAttr(result.value); - // We add the select instruction in the PathCondition - pc._addDet(Comparator.EQ, se, result.value); - return getNext(ti); - } else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - } + if(index cg; - boolean condition; - int arrayRef = peekArrayRef(ti); // need to be polymorphic, could be LongArrayStore - - if (!ti.isFirstStepInsn()) { // first time around - cg = new PCChoiceGenerator(3); - ((PCChoiceGenerator) cg).setOffset(this.position); - ((PCChoiceGenerator) cg).setMethodName(this.getMethodInfo().getFullName()); - ti.getVM().setNextChoiceGenerator(cg); - return this; - } else { // this is what really returns results - cg = ti.getVM().getChoiceGenerator(); - assert (cg instanceof PCChoiceGenerator) : "expected PCChoiceGenerator, got: " + cg; - } - - PathCondition pc; - ChoiceGenerator prev_cg = cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - if (prev_cg == null) - pc = new PathCondition(); - else - pc = ((PCChoiceGenerator)prev_cg).getCurrentPC(); - - assert pc != null; - - if (peekIndexAttr(ti)==null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - int index = ti.getTopFrame().peek(1); - indexAttr = new IntegerConstant(index); - } else { - indexAttr = (IntegerExpression)peekIndexAttr(ti); - } - assert (indexAttr != null) : "indexAttr shouldn't be null in IASTORE instruction"; - - if (peekArrayAttr(ti)==null || !(peekArrayAttr(ti) instanceof ArrayExpression)) { - //In this case, the array isn't symbolic - if (peekIndexAttr(ti) == null || !(peekIndexAttr(ti) instanceof IntegerExpression)) { - if (frame.getOperandAttr(0) == null || !(frame.getOperandAttr(0) instanceof IntegerExpression)) { - // nothing is symbolic here - return super.execute(ti); - } - } else { - // We create a symbolic array out of the concrete array - ElementInfo arrayInfo = ti.getElementInfo(arrayRef); - arrayAttr = new IntegerSymbolicArray(arrayInfo.arrayLength()); - // We add the constraints about all the elements of the array - for (int i = 0; i < arrayInfo.arrayLength(); i++) { - int arrValue = arrayInfo.getShortElement(i); - pc._addDet(Comparator.EQ, new SelectExpression(arrayAttr, i), new IntegerConstant(arrValue)); - } - } - } else { - arrayAttr = (IntegerSymbolicArray)peekArrayAttr(ti); - } - assert (arrayAttr != null) : "arrayAttr shouldn't be null in IASTORE instruction"; - - if (arrayRef == MJIEnv.NULL) { + int arrayref = peekArrayRef(ti); // need to be polymorphic, could be LongArrayStore + ElementInfo eiArray = ti.getElementInfo(arrayref); + + if (arrayref == MJIEnv.NULL) { return ti.createAndThrowException("java.lang.NullPointerException"); } - - - if ((Integer)cg.getNextChoice() == 1) { // check bounds of the index - pc._addDet(Comparator.GE, indexAttr, arrayAttr.length); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index greater than array bounds"); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - else if ((Integer)cg.getNextChoice() == 2) { - pc._addDet(Comparator.LT, indexAttr, new IntegerConstant(0)); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - return ti.createAndThrowException("java.lang.ArrayIndexOutOfBoundsException", "index smaller than array bounds"); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - else { - pc._addDet(Comparator.LT, indexAttr, arrayAttr.length); - pc._addDet(Comparator.GE, indexAttr, new IntegerConstant(0)); - if (pc.simplify()) { // satisfiable - ((PCChoiceGenerator) cg).setCurrentPC(pc); - - // set the result - - // We have to check if the value is symbolic or not, create a symbolicIntegerValueatIndex out of it, and - // call the setVal function, before storing the attr - IntegerExpression sym_value = null; - if (frame.getOperandAttr(0) == null || !(frame.getOperandAttr(0) instanceof IntegerExpression)) { - // The value isn't symbolic. We store a new IntegerConstant in the valAt map, at index indexAttr - int value = frame.pop(); - sym_value = new IntegerConstant(value); - } - else { - // The value is symbolic. - sym_value = (IntegerExpression)frame.getOperandAttr(0); - frame.pop(); - } - PreviousIntegerArray previous = new PreviousIntegerArray(arrayAttr, indexAttr, sym_value); - // We create a new arrayAttr, and inherits information from the previous attribute - IntegerSymbolicArray newArrayAttr = new IntegerSymbolicArray(previous); - frame.pop(2); // We pop the array and the index - - StoreExpression se = new StoreExpression(arrayAttr, indexAttr, sym_value); - pc._addDet(Comparator.EQ, se, newArrayAttr); - - return getNext(ti); - } - else { - ti.getVM().getSystemState().setIgnored(true); - return getNext(ti); - } - } - } + + + int len=(eiArray.getArrayFields()).arrayLength(); // assumed concrete + + if(!ti.isFirstStepInsn()){ + PCChoiceGenerator arrayCG = new PCChoiceGenerator(0,len+1); // add 2 error cases: <0, >=len + ti.getVM().getSystemState().setNextChoiceGenerator(arrayCG); + + //ti.reExecuteInstruction(); + if (SymbolicInstructionFactory.debugMode) + System.out.println("# array cg registered: " + arrayCG); + return this; + + } else { //this is what really returns results + + + + //index = frame.peek(); + PCChoiceGenerator lastCG=ti.getVM().getSystemState().getLastChoiceGeneratorOfType(PCChoiceGenerator.class); + assert(lastCG!=null); + PCChoiceGenerator prevCG=lastCG.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); + + index=lastCG.getNextChoice(); + IntegerExpression sym_index=(IntegerExpression)peekIndexAttr(ti); + //check the constraint + + PathCondition pc; + + if (prevCG == null) + pc = new PathCondition(); + else + pc = ((PCChoiceGenerator)prevCG).getCurrentPC(); + + assert pc != null; + + if(index what if the value is the same but not the attr? + + } catch (ArrayIndexOutOfBoundsExecutiveException ex) { // at this point, the AIOBX is already processed + return ex.getInstruction(); + } + + return getNext(ti); + } + } + + } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/SymbolicStringHandler.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/SymbolicStringHandler.java index df04ad9..80bd9b7 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/SymbolicStringHandler.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/SymbolicStringHandler.java @@ -46,8 +46,7 @@ REMEDY FOR ANY SUCH MATTER SHALL BE THE IMMEDIATE, UNILATERAL TERMINATION OF THIS AGREEMENT. */ -// TODO: to review -// probably needs to be redone with env methods + package gov.nasa.jpf.symbc.bytecode; @@ -63,11 +62,8 @@ import gov.nasa.jpf.vm.SystemState; import gov.nasa.jpf.vm.Types; import gov.nasa.jpf.vm.VM; - import gov.nasa.jpf.vm.StackFrame; - import gov.nasa.jpf.vm.ThreadInfo; - import gov.nasa.jpf.jvm.bytecode.JVMInvokeInstruction; import gov.nasa.jpf.symbc.mixednumstrg.SpecialRealExpression; import gov.nasa.jpf.symbc.numeric.IntegerConstant; @@ -76,14 +72,10 @@ import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.symbc.numeric.RealExpression; import gov.nasa.jpf.symbc.numeric.PathCondition; -import gov.nasa.jpf.symbc.numeric.SymbolicInteger; - - import gov.nasa.jpf.symbc.string.*; import gov.nasa.jpf.symbc.mixednumstrg.*; -// Corina: this code is strange; I need to revise it carefully public class SymbolicStringHandler { static int handlerStep = 0; static Instruction handlerStepSavedNext = null; @@ -92,7 +84,7 @@ public class SymbolicStringHandler { public static final int intValueOffset = 5; /* this method checks if a method has as argument any symbolic strings */ - + public boolean isMethodStringSymbolic(JVMInvokeInstruction invInst, ThreadInfo th) { String cname = invInst.getInvokedMethodClassName(); @@ -111,30 +103,32 @@ public boolean isMethodStringSymbolic(JVMInvokeInstruction invInst, ThreadInfo t || cname.equals("java.lang.Char") || cname.equals("java.lang.Boolean") || cname.equals("java.lang.Object")) { - StackFrame sf = th.getModifiableTopFrame(); + + StackFrame sf = th.getModifiableTopFrame(); int numStackSlots = invInst.getArgSize(); for (int i = 0; i < numStackSlots; i++) { Expression sym_v1 = (Expression) sf.getOperandAttr(i); if (sym_v1 != null) { - if (sym_v1 instanceof SymbolicStringBuilder) { // check if // StringBuilder has // empty attribute - if (((SymbolicStringBuilder) sym_v1).getstr() != null) + if (((SymbolicStringBuilder) sym_v1).getstr() != null) { return true; - } else if (sym_v1 instanceof SymbolicInteger && cname.equals("java.lang.StringBuilder")){ - //concrete stringbuffers won't be handled here - return false; - } else { + } + } else if (sym_v1 instanceof IntegerExpression && cname.equals("java.lang.StringBuilder")){ + //to revise return true; + } else { + return true; } + } } return false; - } else - return false; + } + else return false; } public Instruction handleSymbolicStrings(JVMInvokeInstruction invInst, ThreadInfo th) { @@ -212,7 +206,7 @@ public Instruction handleSymbolicStrings(JVMInvokeInstruction invInst, ThreadInf } else if (shortName.equals("lastIndexOf")) { handleLastIndexOf(invInst, th); } else if (shortName.equals("charAt")) { - handleCharAt (invInst, th); + handleCharAt (invInst, th); // returns boolean that is ignored //return invInst; } else if (shortName.equals("replace")) { Instruction handled = handleReplace(invInst, th); @@ -313,8 +307,8 @@ public Instruction handleSymbolicStrings(JVMInvokeInstruction invInst, ThreadInf } else if (shortName.equals("booleanValue")) { handlefloatValue(invInst, th); } else { - System.err.println("ERROR: symbolic method not handled: " + shortName); - return null; + throw new RuntimeException("ERROR: symbolic method not handled: " + shortName); + //return null; } return invInst.getNext(th); } else { @@ -329,7 +323,7 @@ private boolean handleCharAt (JVMInvokeInstruction invInst, ThreadInfo th) { StringExpression sym_v2 = (StringExpression) sf.getOperandAttr(1); boolean bresult = false; if ((sym_v1 == null) & (sym_v2 == null)) { - System.err.println("ERROR: symbolic string method must have one symbolic operand: HandleSubString1"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: HandleCharAt"); } else { int s1 = sf.pop(); int s2 = sf.pop(); @@ -338,11 +332,8 @@ private boolean handleCharAt (JVMInvokeInstruction invInst, ThreadInfo th) { if (sym_v1 == null) { // operand 0 is concrete int val = s1; - //System.out.println("[handleCharAt] Mmm...! " + val); result = sym_v2._charAt(new IntegerConstant(val)); } else { - //System.out.println("[handleCharAt] YES! " + sym_v1.getClass() + " " + sym_v1.toString()); - if (sym_v2 == null) { ElementInfo e1 = th.getElementInfo(s2); @@ -356,11 +347,10 @@ private boolean handleCharAt (JVMInvokeInstruction invInst, ThreadInfo th) { //System.out.println("[handleCharAt] Ignoring: " + result.toString()); //th.push(0, false); } - //th.push(objRef, true); sf.push(0, false); sf.setOperandAttr(result); } - return bresult; + return bresult; // not used } @@ -368,7 +358,7 @@ public void handleLength(JVMInvokeInstruction invInst, ThreadInfo th) { StackFrame sf = th.getModifiableTopFrame(); StringExpression sym_v1 = (StringExpression) sf.getOperandAttr(0); if (sym_v1 == null) { - System.err.println("ERROR: symbolic method must have symbolic string operand: hanldeLength"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: HandleLength"); } else { sf.pop(); sf.push(0, false); /* dont care value for length */ @@ -389,450 +379,308 @@ public void handleIndexOf(JVMInvokeInstruction invInst, ThreadInfo th) { } /* two possibilities int, or String in parameter */ - /* currently symbolic values in parameters are ignored */ public void handleIndexOf1(JVMInvokeInstruction invInst, ThreadInfo th) { StackFrame sf = th.getModifiableTopFrame(); - /* Added by Gideon */ - //StringExpression argument = (StringExpression) sf.getOperandAttr(0); + //boolean castException = false; StringExpression sym_v1 = null; - StringExpression sym_v2 = null; - sym_v1 = (StringExpression) sf.getOperandAttr(1); - /* */ - sym_v2 = (StringExpression) sf.getOperandAttr(0); + Expression sym_v2 = null; // could be String or Char + sym_v1 = (StringExpression)sf.getOperandAttr(1); + sym_v2 = (Expression) sf.getOperandAttr(0); if (sym_v1 == null && sym_v2 == null) { - System.err.println("ERROR: symbolic method must have symbolic string operand: hanldeLength"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: HandleIndexOf1"); } else { - /*int x1 = th.pop(); - int x2 = th.pop(); - System.out.printf("[SymbolicStringHandler] [handleIndexOf1] %d %d\n", x1, x2); - th.push(0, false); - IntegerExpression sym_v2 = sym_v1._indexOf(); - sf.setOperandAttr(sym_v2);*/ - // System.out.println("conditionValue: " + conditionValue); - - - boolean s1char = true; //argument is char + boolean s2char = true; //argument is char if (sf.isOperandRef()) { - s1char = false; //argument is string + s2char = false; //argument is string } + int s1 = sf.pop(); int s2 = sf.pop(); IntegerExpression result = null; - //if (conditionValue) { - if (sym_v1 != null) { + if (sym_v1 != null) { if (sym_v2 != null) { // both are symbolic values - result = sym_v1._indexOf(sym_v2); - } else { - if (s1char) { - result = sym_v1._indexOf(new IntegerConstant(s1)); + if (s2char) + result = sym_v1._indexOf((IntegerExpression)sym_v2); + else + result = sym_v1._indexOf((StringExpression)sym_v2); + } else { // sym_v2 is null + if (s2char) { + result = sym_v1._indexOf(new IntegerConstant(s2)); } else { - ElementInfo e2 = th.getElementInfo(s1); + ElementInfo e2 = th.getElementInfo(s2); String val = e2.asString(); result = sym_v1._indexOf(new StringConstant(val)); } } - //pc._addDet(Comparator.EQ, result, -1); - } else { + } else { // sym_v1 is null, sym_v2 must be not null + assert(sym_v2!=null); ElementInfo e1 = th.getElementInfo(s2); String val = e1.asString(); - - if (sym_v2 != null) { // both are symbolic values - result = new StringConstant(val)._indexOf(sym_v2); - } else { - if (s1char) { - result = new StringConstant(val)._indexOf(new IntegerConstant(s1)); - } - else { - ElementInfo e2 = th.getElementInfo(s1); - String val2 = e2.asString(); - result = new StringConstant(val)._indexOf(new StringConstant(val2)); - } - } - //pc.spc._addDet(comp, val, sym_v2); - } - /*} else { - if (sym_v1 != null) { - if (sym_v2 != null) { // both are symbolic values - result = sym_v1._indexOf(sym_v2); - } else { - ElementInfo e2 = th.getElementInfo(s1); - String val = e2.asString(); - result = sym_v1._indexOf(new StringConstant(val)); - } - //pc._addDet(Comparator.GE, result, 0); - } else { - ElementInfo e1 = th.getElementInfo(s2); - String val = e1.asString(); - throw new RuntimeException("Not supported yet"); - //pc.spc._addDet(comp, val, sym_v2); - } - }*/ - sf.push(0, false); - sf.setOperandAttr(result); - /*if (!pc.simplify()) {// not satisfiable - System.out.println("Not sat"); - ss.setIgnored(true); - } else { - System.out.println("Is sat"); - ((PCChoiceGenerator) cg).setCurrentPC(pc); - }*/ - - - //assert result != null; - //th.push(conditionValue ? 1 : 0, true); - - - } - } - - public void handleLastIndexOf(JVMInvokeInstruction invInst, ThreadInfo th) { - int numStackSlots = invInst.getArgSize(); - if (numStackSlots == 2) { - handleLastIndexOf1(invInst, th); - } else { - handleLastIndexOf2(invInst, th); - } - } - - public void handleLastIndexOf1(JVMInvokeInstruction invInst, ThreadInfo th) { - StackFrame sf = th.getModifiableTopFrame(); - /* Added by Gideon */ - //StringExpression argument = (StringExpression) sf.getOperandAttr(0); - //boolean castException = false; - StringExpression sym_v1 = null; - StringExpression sym_v2 = null; - sym_v1 = (StringExpression) sf.getOperandAttr(1); - /* */ - sym_v2 = (StringExpression) sf.getOperandAttr(0); - if (sym_v1 == null && sym_v2 == null) { - System.err.println("ERROR: symbolic method must have symbolic string operand: hanldeLength"); - } else { - /*int x1 = th.pop(); - int x2 = th.pop(); - System.out.printf("[SymbolicStringHandler] [handleIndexOf1] %d %d\n", x1, x2); - th.push(0, false); - IntegerExpression sym_v2 = sym_v1._indexOf(); - sf.setOperandAttr(sym_v2);*/ - // System.out.println("conditionValue: " + conditionValue); - - - boolean s1char = true; //argument is char - if (sf.isOperandRef()) { - s1char = false; //argument is string + if (s2char) + result = new StringConstant(val)._indexOf((IntegerExpression)sym_v2); + else + result = new StringConstant(val)._indexOf((StringExpression)sym_v2); } - int s1 = sf.pop(); - int s2 = sf.pop(); - - IntegerExpression result = null; - //if (conditionValue) { - if (sym_v1 != null) { - if (sym_v2 != null) { // both are symbolic values - result = sym_v1._lastIndexOf(sym_v2); - } else { - if (s1char) { - result = sym_v1._lastIndexOf(new IntegerConstant(s1)); - } - else { - ElementInfo e2 = th.getElementInfo(s1); - String val = e2.asString(); - result = sym_v1._lastIndexOf(new StringConstant(val)); - } - } - //pc._addDet(Comparator.EQ, result, -1); - } else { - ElementInfo e1 = th.getElementInfo(s2); - String val = e1.asString(); - - if (sym_v2 != null) { // both are symbolic values - result = new StringConstant(val)._lastIndexOf(sym_v2); - } else { - if (s1char) { - result = new StringConstant(val)._lastIndexOf(new IntegerConstant(s1)); - } - else { - ElementInfo e2 = th.getElementInfo(s1); - String val2 = e2.asString(); - result = new StringConstant(val)._lastIndexOf(new StringConstant(val2)); - } - } - //pc.spc._addDet(comp, val, sym_v2); - } - /*} else { - if (sym_v1 != null) { - if (sym_v2 != null) { // both are symbolic values - result = sym_v1._indexOf(sym_v2); - } else { - ElementInfo e2 = th.getElementInfo(s1); - String val = e2.asString(); - result = sym_v1._indexOf(new StringConstant(val)); - } - //pc._addDet(Comparator.GE, result, 0); - } else { - ElementInfo e1 = th.getElementInfo(s2); - String val = e1.asString(); - throw new RuntimeException("Not supported yet"); - //pc.spc._addDet(comp, val, sym_v2); - } - }*/ sf.push(0, false); + assert result != null; sf.setOperandAttr(result); - /*if (!pc.simplify()) {// not satisfiable - System.out.println("Not sat"); - ss.setIgnored(true); - } else { - System.out.println("Is sat"); - ((PCChoiceGenerator) cg).setCurrentPC(pc); - }*/ - - - //assert result != null; - //th.push(conditionValue ? 1 : 0, true); } } - public void handleLastIndexOf2(JVMInvokeInstruction invInst, ThreadInfo th) { + /* two possibilities int, int or int, String in parameters */ + public void handleIndexOf2(JVMInvokeInstruction invInst, ThreadInfo th) { + StackFrame sf = th.getModifiableTopFrame(); StringExpression sym_v1 = null; - StringExpression sym_v2 = null; + Expression sym_v2 = null; IntegerExpression intExp = null; sym_v1 = (StringExpression) sf.getOperandAttr(2); intExp = (IntegerExpression) sf.getOperandAttr(0); - sym_v2 = (StringExpression) sf.getOperandAttr(1); + sym_v2 = (Expression) sf.getOperandAttr(1); if (sym_v1 == null && sym_v2 == null && intExp == null) { - System.err.println("ERROR: symbolic method must have symbolic string operand: hanldeLength"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: HandleIndexOf2"); } else { + int i1 = sf.pop(); boolean s2char = true; - if (th.getModifiableTopFrame().isOperandRef()) { + if (sf.isOperandRef()) { //System.out.println("[handleIndexOf2] string detected"); s2char = false; } - else { - //System.out.println("[handleIndexOf2] char detected"); - } + int s2 = sf.pop(); int s1 = sf.pop(); IntegerExpression result = null; if (intExp != null) { - //System.out.println("[handleIndexOf2] int exp: " + intExp.getClass()); if (sym_v1 != null) { if (sym_v2 != null) { // both are symbolic values - result = sym_v1._lastIndexOf(sym_v2, intExp); - } else { + if (s2char) + result = sym_v1._indexOf((IntegerExpression)sym_v2, intExp); + else + result = sym_v1._indexOf((StringExpression)sym_v2, intExp); + } else { //sym_v2 is null if (s2char) { - result = sym_v1._lastIndexOf(new IntegerConstant(s2), intExp); + result = sym_v1._indexOf(new IntegerConstant(s2), intExp); } else { ElementInfo e2 = th.getElementInfo(s2); String val = e2.asString(); - result = sym_v1._lastIndexOf(new StringConstant(val), intExp); + result = sym_v1._indexOf(new StringConstant(val), intExp); } } - } else { + } else { // sym_v1 is null ElementInfo e1 = th.getElementInfo(s1); String val = e1.asString(); - if (sym_v2 != null) { // both are symbolic values - result = new StringConstant(val)._lastIndexOf(sym_v2, intExp); + if (sym_v2 != null) { + if(s2char) + result = new StringConstant(val)._indexOf((IntegerExpression)sym_v2, intExp); + else + result = new StringConstant(val)._indexOf((StringExpression)sym_v2, intExp); } else { if (s2char) { - result = new StringConstant(val)._lastIndexOf(new IntegerConstant(s2), intExp); + result = new StringConstant(val)._indexOf(new IntegerConstant(s2), intExp); } else { ElementInfo e2 = th.getElementInfo(s2); String val2 = e2.asString(); - result = new StringConstant(val)._lastIndexOf(new StringConstant(val2), intExp); + result = new StringConstant(val)._indexOf(new StringConstant(val2), intExp); } } } } - else { + else { //intExp is null if (sym_v1 != null) { if (sym_v2 != null) { // both are symbolic values - result = sym_v1._lastIndexOf(sym_v2, new IntegerConstant(i1)); - } else { + if(s2char) + result = sym_v1._indexOf((IntegerExpression)sym_v2, new IntegerConstant(i1)); + else + result = sym_v1._indexOf((StringExpression)sym_v2, new IntegerConstant(i1)); + } else { //sym_v1 is null if (s2char) { - result = sym_v1._lastIndexOf(new IntegerConstant(s2), new IntegerConstant(i1)); + result = sym_v1._indexOf(new IntegerConstant(s2), new IntegerConstant(i1)); } else { ElementInfo e2 = th.getElementInfo(s2); String val = e2.asString(); - result = sym_v1._lastIndexOf(new StringConstant(val), new IntegerConstant(i1)); + result = sym_v1._indexOf(new StringConstant(val), new IntegerConstant(i1)); //System.out.println("[handleIndexOf2] Special push"); //Special push? //th.push(s1, true); } } - } else { + } else {//sym_v1 is null ElementInfo e1 = th.getElementInfo(s1); String val = e1.asString(); - if (sym_v2 != null) { // both are symbolic values - result = new StringConstant(val)._lastIndexOf(sym_v2, new IntegerConstant(i1)); + if (sym_v2 != null) { + if(s2char) + result = new StringConstant(val)._indexOf((IntegerExpression)sym_v2, new IntegerConstant(i1)); + else + result = new StringConstant(val)._indexOf((StringExpression)sym_v2, new IntegerConstant(i1)); } else { if (s2char) { - result = new StringConstant(val)._lastIndexOf(new IntegerConstant(s2), new IntegerConstant(i1)); + result = new StringConstant(val)._indexOf(new IntegerConstant(s2), new IntegerConstant(i1)); } else { ElementInfo e2 = th.getElementInfo(s2); String val2 = e2.asString(); - result = new StringConstant(val)._lastIndexOf(new StringConstant(val2), new IntegerConstant(i1)); + result = new StringConstant(val)._indexOf(new StringConstant(val2), new IntegerConstant(i1)); } } } } - /* Not quite sure yet why this works */ - //int objRef = th.getVM().getDynamicArea().newString("", th); - //th.push(objRef, true); sf.push(0, false); assert result != null; sf.setOperandAttr(result); } } + + public void handleLastIndexOf(JVMInvokeInstruction invInst, ThreadInfo th) { + int numStackSlots = invInst.getArgSize(); + if (numStackSlots == 2) { + handleLastIndexOf1(invInst, th); + } else { + handleLastIndexOf2(invInst, th); + } + } - - /* two possibilities int, int or int, String in parameters */ - /* currently symbolic values in parameters are ignored */ - public void handleIndexOf2(JVMInvokeInstruction invInst, ThreadInfo th) { - //This was the Fjitsu way - /* + public void handleLastIndexOf1(JVMInvokeInstruction invInst, ThreadInfo th) { StackFrame sf = th.getModifiableTopFrame(); - StringExpression sym_v1 = (StringExpression) sf.getOperandAttr(2); - if (sym_v1 == null) { - System.err.println("ERROR: symbolic method must have symbolic string operand: hanldeLength"); + //boolean castException = false; + StringExpression sym_v1 = null; + StringExpression sym_v2 = null; + sym_v1 = (StringExpression) sf.getOperandAttr(1); + /* */ + sym_v2 = (StringExpression) sf.getOperandAttr(0); + if (sym_v1 == null && sym_v2 == null) { + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: HandleLastIndexOf1"); } else { - th.pop(); - th.pop(); - th.pop(); - th.push(0, false); - //IntegerExpression sym_v2 = sym_v1._indexOf(); - sf.setOperandAttr(new IntegerConstant(1)); + boolean s1char = true; //argument is char + if (sf.isOperandRef()) { + s1char = false; //argument is string + } + int s1 = sf.pop(); + int s2 = sf.pop(); + + IntegerExpression result = null; + if (sym_v1 != null) { + if (sym_v2 != null) { // both are symbolic values + result = sym_v1._lastIndexOf(sym_v2); + } else { + if (s1char) { + result = sym_v1._lastIndexOf(new IntegerConstant(s1)); + } + else { + ElementInfo e2 = th.getElementInfo(s1); + String val = e2.asString(); + result = sym_v1._lastIndexOf(new StringConstant(val)); + } + } + } else {//sym_v1 is null + ElementInfo e1 = th.getElementInfo(s2); + String val = e1.asString(); + assert(sym_v2!=null); + result = new StringConstant(val)._lastIndexOf(sym_v2); + + } + + sf.push(0, false); + assert result != null; + sf.setOperandAttr(result); + } - */ + } - //My way + public void handleLastIndexOf2(JVMInvokeInstruction invInst, ThreadInfo th) { StackFrame sf = th.getModifiableTopFrame(); StringExpression sym_v1 = null; StringExpression sym_v2 = null; IntegerExpression intExp = null; - /*System.out.print("[handleIndexOf2] arguments: "); - if (sf.getOperandAttr(0) == null) {System.out.print("null");} else {System.out.print(sf.getOperandAttr(0).toString());} - System.out.print(" "); - if (sf.getOperandAttr(1) == null) {System.out.print("null");} else {System.out.print(sf.getOperandAttr(1).toString());} - System.out.print(" "); - if (sf.getOperandAttr(2) == null) {System.out.print("null");} else {System.out.print(sf.getOperandAttr(2).toString());} - System.out.println();*/ sym_v1 = (StringExpression) sf.getOperandAttr(2); intExp = (IntegerExpression) sf.getOperandAttr(0); sym_v2 = (StringExpression) sf.getOperandAttr(1); if (sym_v1 == null && sym_v2 == null && intExp == null) { - System.err.println("ERROR: symbolic method must have symbolic string operand: hanldeLength"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: HandleLastIndexOf2"); } else { - - int i1 = sf.pop(); boolean s2char = true; - if (sf.isOperandRef()) { - //System.out.println("[handleIndexOf2] string detected"); + if (th.getModifiableTopFrame().isOperandRef()) { s2char = false; } - else { - //System.out.println("[handleIndexOf2] char detected"); - } + int s2 = sf.pop(); int s1 = sf.pop(); IntegerExpression result = null; if (intExp != null) { - //System.out.println("[handleIndexOf2] int exp: " + intExp.getClass()); - if (intExp instanceof SymbolicIndexOf2Integer) { - SymbolicIndexOf2Integer temp = (SymbolicIndexOf2Integer) intExp; - //System.out.println("[handleIndexOf2] further on: " + temp.getMinIndex().getClass()); - } - else if (intExp instanceof SymbolicIndexOfChar2Integer) { - SymbolicIndexOfChar2Integer temp = (SymbolicIndexOfChar2Integer) intExp; - //System.out.println("[handleIndexOf2] further on: " + temp.getMinDist().getClass()); - } if (sym_v1 != null) { if (sym_v2 != null) { // both are symbolic values - result = sym_v1._indexOf(sym_v2, intExp); + result = sym_v1._lastIndexOf(sym_v2, intExp); } else { if (s2char) { - result = sym_v1._indexOf(new IntegerConstant(s2), intExp); + result = sym_v1._lastIndexOf(new IntegerConstant(s2), intExp); } else { ElementInfo e2 = th.getElementInfo(s2); String val = e2.asString(); - result = sym_v1._indexOf(new StringConstant(val), intExp); + result = sym_v1._lastIndexOf(new StringConstant(val), intExp); } } - } else { + } else { //sym_v1 is null ElementInfo e1 = th.getElementInfo(s1); String val = e1.asString(); - if (sym_v2 != null) { // both are symbolic values - result = new StringConstant(val)._indexOf(sym_v2, intExp); + if (sym_v2 != null) { + result = new StringConstant(val)._lastIndexOf(sym_v2, intExp); } else { if (s2char) { - result = new StringConstant(val)._indexOf(new IntegerConstant(s2), intExp); + result = new StringConstant(val)._lastIndexOf(new IntegerConstant(s2), intExp); } else { ElementInfo e2 = th.getElementInfo(s2); String val2 = e2.asString(); - result = new StringConstant(val)._indexOf(new StringConstant(val2), intExp); + result = new StringConstant(val)._lastIndexOf(new StringConstant(val2), intExp); } } } } - else { + else { // intExp is null if (sym_v1 != null) { if (sym_v2 != null) { // both are symbolic values - result = sym_v1._indexOf(sym_v2, new IntegerConstant(i1)); + result = sym_v1._lastIndexOf(sym_v2, new IntegerConstant(i1)); } else { if (s2char) { - result = sym_v1._indexOf(new IntegerConstant(s2), new IntegerConstant(i1)); + result = sym_v1._lastIndexOf(new IntegerConstant(s2), new IntegerConstant(i1)); } else { ElementInfo e2 = th.getElementInfo(s2); String val = e2.asString(); - result = sym_v1._indexOf(new StringConstant(val), new IntegerConstant(i1)); + result = sym_v1._lastIndexOf(new StringConstant(val), new IntegerConstant(i1)); //System.out.println("[handleIndexOf2] Special push"); //Special push? //th.push(s1, true); } } - } else { + } else { // sym_v1 is null ElementInfo e1 = th.getElementInfo(s1); String val = e1.asString(); - - if (sym_v2 != null) { // both are symbolic values - result = new StringConstant(val)._indexOf(sym_v2, new IntegerConstant(i1)); - } else { - if (s2char) { - result = new StringConstant(val)._indexOf(new IntegerConstant(s2), new IntegerConstant(i1)); - } - else { - ElementInfo e2 = th.getElementInfo(s2); - String val2 = e2.asString(); - result = new StringConstant(val)._indexOf(new StringConstant(val2), new IntegerConstant(i1)); - } - } + assert(sym_v2!=null); + result = new StringConstant(val)._lastIndexOf(sym_v2, new IntegerConstant(i1)); } } - /* Not quite sure yet why this works */ - //int objRef = th.getVM().getDynamicArea().newString("", th); - //th.push(objRef, true); + sf.push(0, false); assert result != null; sf.setOperandAttr(result); @@ -840,12 +688,15 @@ else if (intExp instanceof SymbolicIndexOfChar2Integer) { } } + + + public void handlebooleanValue(JVMInvokeInstruction invInst, SystemState ss, ThreadInfo th) { StackFrame sf = th.getModifiableTopFrame(); Expression sym_v3 = (Expression) sf.getOperandAttr(0); if (sym_v3 == null) { - System.err.println("ERROR: symbolic method must have symbolic string operand: handlebooleanValue"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: HandlebooleanValue"); } else { if (sym_v3 instanceof IntegerExpression) { IntegerExpression sym_v2 = (IntegerExpression) sym_v3; @@ -853,7 +704,7 @@ public void handlebooleanValue(JVMInvokeInstruction invInst, SystemState ss, Thr sf.push(0, false); sf.setOperandAttr(sym_v2); } else { - System.err.println("ERROR: operand type not tackled - booleanValue"); + throw new RuntimeException("ERROR: operand type not tackled - booleanValue"); } } @@ -865,7 +716,7 @@ public void handleintValue(JVMInvokeInstruction invInst, ThreadInfo th) { Expression sym_v3 = (Expression) sf.getOperandAttr(0); if (sym_v3 == null) { - System.err.println("ERROR: symbolic method must have symbolic string operand: handleintValue"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: HandleintValue"); } else { if (sym_v3 instanceof IntegerExpression) { IntegerExpression sym_v2 = (IntegerExpression) sym_v3; @@ -874,7 +725,7 @@ public void handleintValue(JVMInvokeInstruction invInst, ThreadInfo th) { sf.setOperandAttr(sym_v2); } else { th.printStackTrace(); - System.err.println("ERROR: operand type not tackled - intValue"); + throw new RuntimeException("ERROR: operand type not tackled - intValue"); } } } @@ -884,7 +735,7 @@ public void handlelongValue(JVMInvokeInstruction invInst, ThreadInfo th) { Expression sym_v3 = (Expression) sf.getOperandAttr(0); if (sym_v3 == null) { - System.err.println("ERROR: symbolic method must have symbolic string operand: hanldeLongValue"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: hanldeLongValue"); } else { if (sym_v3 instanceof IntegerExpression) { IntegerExpression sym_v2 = (IntegerExpression) sym_v3; @@ -892,7 +743,7 @@ public void handlelongValue(JVMInvokeInstruction invInst, ThreadInfo th) { sf.pushLong((long) 0); sf.setLongOperandAttr(sym_v2); } else { - System.err.println("ERROR: operand type not tackled - longValue"); + throw new RuntimeException("ERROR: operand type not tackled - longValue"); } } @@ -904,7 +755,7 @@ public void handlefloatValue(JVMInvokeInstruction invInst, ThreadInfo th) { Expression sym_v3 = (Expression) sf.getOperandAttr(0); if (sym_v3 == null) { - System.err.println("ERROR: symbolic method must have symbolic string operand: hanldeFloatValue"); + throw new RuntimeException("ERROR: symbolic method must have symbolic string operand: hanldeFloatValue"); } else { if (sym_v3 instanceof RealExpression) { RealExpression sym_v2 = (RealExpression) sym_v3; @@ -912,7 +763,7 @@ public void handlefloatValue(JVMInvokeInstruction invInst, ThreadInfo th) { sf.push(0, false); sf.setOperandAttr(sym_v2); } else { - System.err.println("ERROR: operand type not tackled - floatValue"); + throw new RuntimeException("ERROR: operand type not tackled - floatValue"); } } @@ -924,7 +775,7 @@ public void handledoubleValue(JVMInvokeInstruction invInst, ThreadInfo th) { Expression sym_v3 = (Expression) sf.getOperandAttr(0); if (sym_v3 == null) { - System.err.println("ERROR: symbolic method must have symbolic string operand: hanldeDoubleValue"); + throw new RuntimeException("ERROR: symbolic method must have symbolic string operand: hanldeDoubleValue"); } else { if (sym_v3 instanceof RealExpression) { RealExpression sym_v2 = (RealExpression) sym_v3; @@ -932,7 +783,7 @@ public void handledoubleValue(JVMInvokeInstruction invInst, ThreadInfo th) { sf.pushLong((long) 0); sf.setLongOperandAttr(sym_v2); } else { - System.err.println("ERROR: operand type not tackled - doubleValue"); + throw new RuntimeException("ERROR: operand type not tackled - doubleValue"); } } @@ -952,7 +803,7 @@ public Instruction handleInit(JVMInvokeInstruction invInst, ThreadInfo th) { StringExpression sym_v1 = (StringExpression) sf.getOperandAttr(0); SymbolicStringBuilder sym_v2 = (SymbolicStringBuilder) sf.getOperandAttr(1); if (sym_v1 == null) { - System.err.println("ERROR: symbolic StringBuilder method must have one symbolic operand in Init"); + throw new RuntimeException("ERROR: symbolic StringBuilder method must have one symbolic operand in Init"); } else { sf.pop(); /* string object */ sf.pop(); /* one stringBuilder Object */ @@ -962,11 +813,9 @@ public Instruction handleInit(JVMInvokeInstruction invInst, ThreadInfo th) { } } else { // Corina TODO: we should allow symbolic string analysis to kick in only when desired - System.err.println("Warning Symbolic String Analysis: Initialization type not handled in symbc/bytecode/SymbolicStringHandler init"); + //throw new RuntimeException("Warning Symbolic String Analysis: Initialization type not handled in symbc/bytecode/SymbolicStringHandler init"); return null; } - - return null; } /***************************** Symbolic Big Decimal Routines end ****************/ @@ -978,7 +827,7 @@ private void handleBooleanStringInstructions(JVMInvokeInstruction invInst, Thre StringExpression sym_v2 = (StringExpression) sf.getOperandAttr(1); if ((sym_v1 == null) & (sym_v2 == null)) { - System.err.println("ERROR: symbolic string method must have one symbolic operand: HandleStartsWith"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: HandleStartsWith"); } else { ChoiceGenerator cg; boolean conditionValue; @@ -1060,11 +909,11 @@ private void handleBooleanStringInstructions(JVMInvokeInstruction invInst, Thre } public void handleEqualsIgnoreCase(JVMInvokeInstruction invInst, ThreadInfo th) { - System.err.println("ERROR: symbolic string method not Implemented - EqualsIgnoreCase"); + throw new RuntimeException("ERROR: symbolic string method not Implemented - EqualsIgnoreCase"); } public void handleEndsWith(JVMInvokeInstruction invInst, ThreadInfo th) { - //System.err.println("ERROR: symbolic string method not Implemented - EndsWith"); + //throw new RuntimeException("ERROR: symbolic string method not Implemented - EndsWith"); handleBooleanStringInstructions(invInst, th, StringComparator.ENDSWITH); } @@ -1074,7 +923,7 @@ public void handleContains (JVMInvokeInstruction invInst, ThreadInfo th) { public void handleStartsWith(JVMInvokeInstruction invInst, ThreadInfo th) { - //System.err.println("ERROR: symbolic string method not Implemented - StartsWith"); + //throw new RuntimeException("ERROR: symbolic string method not Implemented - StartsWith"); handleBooleanStringInstructions(invInst, th, StringComparator.STARTSWITH); } @@ -1086,7 +935,7 @@ public Instruction handleReplace(JVMInvokeInstruction invInst, ThreadInfo th) { StringExpression sym_v3 = (StringExpression) sf.getOperandAttr(2); if ((sym_v1 == null) & (sym_v2 == null) & (sym_v3 == null)) { - System.err.println("ERROR: symbolic string method must have one symbolic operand: HandleReplace"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: HandleReplace"); } else { int s1 = sf.pop(); int s2 = sf.pop(); @@ -1161,7 +1010,7 @@ public Instruction handleSubString1(JVMInvokeInstruction invInst, ThreadInfo th) StringExpression sym_v2 = (StringExpression) sf.getOperandAttr(1); if ((sym_v1 == null) & (sym_v2 == null)) { - System.err.println("ERROR: symbolic string method must have one symbolic operand: HandleSubString1"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: HandleSubString1"); } else { int s1 = sf.pop(); int s2 = sf.pop(); @@ -1199,7 +1048,7 @@ public Instruction handleSubString2(JVMInvokeInstruction invInst, ThreadInfo th) StringExpression sym_v3 = (StringExpression) sf.getOperandAttr(2); if ((sym_v1 == null) & (sym_v2 == null) & (sym_v3 == null)) { - System.err.println("ERROR: symbolic string method must have one symbolic operand: HandleSubString2"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: HandleSubString2"); } else { int s1 = sf.pop(); int s2 = sf.pop(); @@ -1215,7 +1064,7 @@ public Instruction handleSubString2(JVMInvokeInstruction invInst, ThreadInfo th) /* Only if both arguments are concrete, something else needs * to be pushed? */ - sf.push(s3, true); /* symbolic string element */ + //sf.push(s3, true); /* symbolic string element */ } else { if (sym_v3 == null) { // only sym_v2 is symbolic ElementInfo e3 = th.getElementInfo(s3); @@ -1266,7 +1115,7 @@ public Instruction handleReplaceFirst(JVMInvokeInstruction invInst, ThreadInfo t StringExpression sym_v3 = (StringExpression) sf.getOperandAttr(2); if ((sym_v1 == null) & (sym_v2 == null) & (sym_v3 == null)) { - System.err.println("ERROR: symbolic string method must have one symbolic operand: HanldeReplaceFirst"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: HanldeReplaceFirst"); } else { int s1 = sf.pop(); int s2 = sf.pop(); @@ -1328,7 +1177,7 @@ public Instruction handleReplaceFirst(JVMInvokeInstruction invInst, ThreadInfo t } public void handleTrim(JVMInvokeInstruction invInst, ThreadInfo th) { - // System.err.println("ERROR: symbolic string method not Implemented - Trim"); + // throw new RuntimeException("ERROR: symbolic string method not Implemented - Trim"); StackFrame sf = th.getModifiableTopFrame(); StringExpression sym_v1 = (StringExpression) sf.getOperandAttr(0); int s1 = sf.pop(); @@ -1371,7 +1220,7 @@ public Instruction handleValueOf(JVMInvokeInstruction invInst, ThreadInfo th) { } else if (argTypes[0].equals("java.lang.Object")) { return handleObjectValueOf(invInst, th); } else { - System.err.println("ERROR: Input parameter type not handled in Symbolic String ValueOf"); + throw new RuntimeException("ERROR: Input parameter type not handled in Symbolic String ValueOf"); } } else { // value of non-string types if (cname.equals("java.lang.Integer")) { @@ -1440,7 +1289,7 @@ public Instruction handleValueOf(JVMInvokeInstruction invInst, ThreadInfo th) { handleParseBooleanValueOf(invInst, th); } } else { - System.err.println("ERROR: Type not handled in Symbolic Type ValueOf: " + cname); + throw new RuntimeException("ERROR: Type not handled in Symbolic Type ValueOf: " + cname); } } return null; @@ -1451,7 +1300,7 @@ public void handleParseLongValueOf(JVMInvokeInstruction invInst, ThreadInfo th) Expression sym_v3 = (Expression) sf.getOperandAttr(0); if (sym_v3 == null) { - System.err.println("ERROR: symbolic method must have symbolic string operand"); + throw new RuntimeException("ERROR: symbolic method must have symbolic string operand"); } else { if (sym_v3 instanceof IntegerExpression) { IntegerExpression sym_v2 = (IntegerExpression) sym_v3; @@ -1500,9 +1349,9 @@ public void handleParseLongValueOf(JVMInvokeInstruction invInst, ThreadInfo th) if (!pc.simplify()) {// not satisfiable th.getVM().getSystemState().setIgnored(true); } else { - System.err.println("ERROR: Long Format Type Exception"); - th.getVM().getSystemState().setIgnored(true); - sf.push(0, true); + throw new RuntimeException("ERROR: Long Format Type Exception"); + //th.getVM().getSystemState().setIgnored(true); TODO: needs revision + //sf.push(0, true); } } } @@ -1514,7 +1363,7 @@ public void handleParseBooleanValueOf(JVMInvokeInstruction invInst, ThreadInfo t Expression sym_v3 = (Expression) sf.getOperandAttr(0); if (sym_v3 == null) { - System.err.println("ERROR: symbolic method must have symbolic string operand"); + throw new RuntimeException("ERROR: symbolic method must have symbolic string operand"); } else { if (sym_v3 instanceof IntegerExpression) { IntegerExpression sym_v2 = (IntegerExpression) sym_v3; @@ -1563,9 +1412,10 @@ public void handleParseBooleanValueOf(JVMInvokeInstruction invInst, ThreadInfo t if (!pc.simplify()) {// not satisfiable th.getVM().getSystemState().setIgnored(true); } else { - System.err.println("ERROR: Boolean Format Type Exception"); // TODO: to review; there should be no backtracking here - th.getVM().getSystemState().setIgnored(true); - sf.push(0, true); + throw new RuntimeException("ERROR: Boolean Format Type Exception"); + // TODO: to review; there should be no backtracking here + //th.getVM().getSystemState().setIgnored(true); + //sf.push(0, true); } } } @@ -1577,7 +1427,7 @@ public void handleParseIntValueOf(JVMInvokeInstruction invInst, ThreadInfo th) { Expression sym_v3 = (Expression) sf.getOperandAttr(0); if (sym_v3 == null) { - System.err.println("ERROR: symbolic method must have symbolic string operand"); + throw new RuntimeException("ERROR: symbolic method must have symbolic string operand"); } else { if (sym_v3 instanceof IntegerExpression) { IntegerExpression sym_v2 = (IntegerExpression) sym_v3; @@ -1626,9 +1476,9 @@ public void handleParseIntValueOf(JVMInvokeInstruction invInst, ThreadInfo th) { if (!pc.simplify()) {// not satisfiable th.getVM().getSystemState().setIgnored(true); } else { - System.err.println("ERROR: Integer Format Type Exception"); - th.getVM().getSystemState().setIgnored(true); - sf.push(0, true); + throw new RuntimeException("ERROR: Integer Format Type Exception"); + //th.getVM().getSystemState().setIgnored(true);TODO: needs revision + //sf.push(0, true); } } } @@ -1640,7 +1490,7 @@ public void handleParseInt(JVMInvokeInstruction invInst, ThreadInfo th) { Expression sym_v3 = (Expression) sf.getOperandAttr(0); if (sym_v3 == null) { - System.err.println("ERROR: symbolic method must have symbolic string operand"); + throw new RuntimeException("ERROR: symbolic method must have symbolic string operand"); } else { IntegerExpression result = null; ChoiceGenerator cg; @@ -1680,9 +1530,9 @@ public void handleParseInt(JVMInvokeInstruction invInst, ThreadInfo th) { if (!pc.simplify()) {// not satisfiable th.getVM().getSystemState().setIgnored(true); } else { - System.err.println("ERROR: Integer Format Type Exception"); - th.getVM().getSystemState().setIgnored(true); - sf.push(0, true); + throw new RuntimeException("ERROR: Integer Format Type Exception"); + //th.getVM().getSystemState().setIgnored(true);TODO: needs revision + //sf.push(0, true); } } } @@ -1694,7 +1544,7 @@ public void handleParseFloat(JVMInvokeInstruction invInst, ThreadInfo th) { Expression sym_v3 = (Expression) sf.getOperandAttr(0); if (sym_v3 == null) { - System.err.println("ERROR: symbolic method must have symbolic string operand"); + throw new RuntimeException("ERROR: symbolic method must have symbolic string operand"); } else { RealExpression result = null; ChoiceGenerator cg; @@ -1733,9 +1583,9 @@ public void handleParseFloat(JVMInvokeInstruction invInst, ThreadInfo th) { if (!pc.simplify()) {// not satisfiable th.getVM().getSystemState().setIgnored(true); } else { - System.err.println("ERROR: Possible Float Format Type Exception - Path Terminated"); - System.out.println("********************************************************"); - th.getVM().getSystemState().setIgnored(true); + throw new RuntimeException("ERROR: Possible Float Format Type Exception - Path Terminated"); + + //th.getVM().getSystemState().setIgnored(true);TODO: needs revision } } } @@ -1747,7 +1597,7 @@ public void handleParseFloatValueOf(JVMInvokeInstruction invInst, ThreadInfo th) Expression sym_v3 = (Expression) sf.getOperandAttr(0); if (sym_v3 == null) { - System.err.println("ERROR: symbolic method must have symbolic string operand"); + throw new RuntimeException("ERROR: symbolic method must have symbolic string operand"); } else { if (sym_v3 instanceof RealExpression) { RealExpression sym_v2 = (RealExpression) sym_v3; @@ -1794,9 +1644,9 @@ public void handleParseFloatValueOf(JVMInvokeInstruction invInst, ThreadInfo th) if (!pc.simplify()) {// not satisfiable th.getVM().getSystemState().setIgnored(true); } else { - System.err.println("ERROR: Possible Float Format Type Exception - Path Terminated"); - System.out.println("********************************************************"); - th.getVM().getSystemState().setIgnored(true); + throw new RuntimeException("ERROR: Possible Float Format Type Exception - Path Terminated"); + + //th.getVM().getSystemState().setIgnored(true);TODO: needs revision } } } @@ -1809,7 +1659,7 @@ public void handleParseDoubleValueOf(JVMInvokeInstruction invInst, ThreadInfo th Expression sym_v3 = (Expression) sf.getOperandAttr(0); if (sym_v3 == null) { - System.err.println("ERROR: symbolic method must have symbolic string operand"); + throw new RuntimeException("ERROR: symbolic method must have symbolic string operand"); } else { if (sym_v3 instanceof RealExpression) { RealExpression sym_v2 = (RealExpression) sym_v3; @@ -1857,9 +1707,9 @@ public void handleParseDoubleValueOf(JVMInvokeInstruction invInst, ThreadInfo th if (!pc.simplify()) {// not satisfiable th.getVM().getSystemState().setIgnored(true); } else { - System.err.println("ERROR: Double Format Type Exception"); - th.getVM().getSystemState().setIgnored(true); - sf.push(0, true); // TODO: this is very strange code; to review + throw new RuntimeException("ERROR: Double Format Type Exception"); + //th.getVM().getSystemState().setIgnored(true); + //sf.push(0, true); // TODO: to review } } } @@ -1872,7 +1722,7 @@ public void handleParseDouble(JVMInvokeInstruction invInst, ThreadInfo th) { Expression sym_v3 = (Expression) sf.getOperandAttr(0); if (sym_v3 == null) { - System.err.println("ERROR: symbolic method must have symbolic string operand"); + throw new RuntimeException("ERROR: symbolic method must have symbolic string operand"); } else { if (sym_v3 instanceof RealExpression) { return; @@ -1915,8 +1765,8 @@ public void handleParseDouble(JVMInvokeInstruction invInst, ThreadInfo th) { if (!pc.simplify()) {// not satisfiable th.getVM().getSystemState().setIgnored(true); } else { - System.err.println("ERROR: Double Format Type Exception"); - th.getVM().getSystemState().setIgnored(true); + throw new RuntimeException("ERROR: Double Format Type Exception"); + //th.getVM().getSystemState().setIgnored(true);TODO: needs revision } } } @@ -1928,7 +1778,7 @@ public void handleParseLong(JVMInvokeInstruction invInst, ThreadInfo th) { Expression sym_v3 = (Expression) sf.getOperandAttr(0); if (sym_v3 == null) { - System.err.println("ERROR: symbolic method must have symbolic string operand"); + throw new RuntimeException("ERROR: symbolic method must have symbolic string operand"); } else { if (sym_v3 instanceof IntegerExpression) { return; @@ -1971,8 +1821,8 @@ public void handleParseLong(JVMInvokeInstruction invInst, ThreadInfo th) { if (!pc.simplify()) {// not satisfiable th.getVM().getSystemState().setIgnored(true); } else { - System.err.println("ERROR: Long Format Type Exception"); - th.getVM().getSystemState().setIgnored(true); + throw new RuntimeException("ERROR: Long Format Type Exception"); + //th.getVM().getSystemState().setIgnored(true);TODO: needs revision } } } @@ -1984,7 +1834,7 @@ public void handleParseBoolean(JVMInvokeInstruction invInst, ThreadInfo th) { StringExpression sym_v1 = (StringExpression) sf.getOperandAttr(0); if (sym_v1 == null) { - System.err.println("ERROR: symbolic method must have symbolic string operand"); + throw new RuntimeException("ERROR: symbolic method must have symbolic string operand"); } else { ChoiceGenerator cg; boolean conditionValue; @@ -2023,8 +1873,8 @@ public void handleParseBoolean(JVMInvokeInstruction invInst, ThreadInfo th) { if (!pc.simplify()) {// not satisfiable th.getVM().getSystemState().setIgnored(true); } else { - System.err.println("ERROR: Boolean Format Type Exception"); - th.getVM().getSystemState().setIgnored(true); + throw new RuntimeException("ERROR: Boolean Format Type Exception"); + //th.getVM().getSystemState().setIgnored(true);TODO: needs revision } } } @@ -2070,15 +1920,16 @@ public Instruction handleIntValueOf(JVMInvokeInstruction invInst, ThreadInfo th IntegerExpression sym_v1 = (IntegerExpression) sf.getOperandAttr(0); if (sym_v1 == null) { - System.err.println("ERROR: symbolic string method must have symbolic operand: handleIntValueOf"); + throw new RuntimeException("ERROR: symbolic string method must have symbolic operand: handleIntValueOf"); } else { sf.pop(); StringExpression sym_v2 = StringExpression._valueOf(sym_v1); - int objRef = th.getHeap().newString("", th).getObjectRef(); /* - * dummy - * string - * Object - */ + int objRef = th.getHeap().newString("", th).getObjectRef(); + /* + * dummy + * string + * Object + */ sf.push(objRef, true); sf.setOperandAttr(sym_v2); } @@ -2090,7 +1941,7 @@ public Instruction handleFloatValueOf(JVMInvokeInstruction invInst, ThreadInfo t RealExpression sym_v1 = (RealExpression) sf.getOperandAttr(0); if (sym_v1 == null) { - System.err.println("ERROR: symbolic string method must have symbolic operand: handleFloatValueOf"); + throw new RuntimeException("ERROR: symbolic string method must have symbolic operand: handleFloatValueOf"); } else { sf.pop(); StringExpression sym_v2 = StringExpression._valueOf(sym_v1); @@ -2110,7 +1961,7 @@ public Instruction handleLongValueOf(JVMInvokeInstruction invInst, ThreadInfo th IntegerExpression sym_v1 = (IntegerExpression) sf.getOperandAttr(0); if (sym_v1 == null) { - System.err.println("ERROR: symbolic string method must have symbolic operand: handleLongValueOf"); + throw new RuntimeException("ERROR: symbolic string method must have symbolic operand: handleLongValueOf"); } else { sf.popLong(); StringExpression sym_v2 = StringExpression._valueOf(sym_v1); @@ -2130,7 +1981,7 @@ public Instruction handleDoubleValueOf(JVMInvokeInstruction invInst, ThreadInfo RealExpression sym_v1 = (RealExpression) sf.getOperandAttr(0); if (sym_v1 == null) { - System.err.println("ERROR: symbolic string method must have symbolic operand: handleDoubleValueOf"); + throw new RuntimeException("ERROR: symbolic string method must have symbolic operand: handleDoubleValueOf"); } else { sf.popLong(); StringExpression sym_v2 = StringExpression._valueOf(sym_v1); @@ -2150,7 +2001,7 @@ public Instruction handleBooleanValueOf(JVMInvokeInstruction invInst, ThreadInfo IntegerExpression sym_v1 = (IntegerExpression) sf.getOperandAttr(0); if (sym_v1 == null) { - System.err.println("ERROR: symbolic string method must have symbolic operand: handleBooleanValueOf"); + throw new RuntimeException("ERROR: symbolic string method must have symbolic operand: handleBooleanValueOf"); } else { sf.pop(); StringExpression sym_v2 = StringExpression._valueOf(sym_v1); @@ -2166,13 +2017,11 @@ public Instruction handleBooleanValueOf(JVMInvokeInstruction invInst, ThreadInfo } public Instruction handleCharValueOf(JVMInvokeInstruction invInst, ThreadInfo th) { - System.err.println("ERROR: symbolic string method not Implemented - CharValueOf"); - return null; + throw new RuntimeException("ERROR: symbolic string method not Implemented - CharValueOf"); } public Instruction handleCharArrayValueOf(JVMInvokeInstruction invInst, ThreadInfo th) { - System.err.println("ERROR: symbolic string method not Implemented - CharArrayValueof"); - return null; + throw new RuntimeException("ERROR: symbolic string method not Implemented - CharArrayValueof"); } public Instruction handleObjectValueOf(JVMInvokeInstruction invInst, ThreadInfo th) { @@ -2200,7 +2049,7 @@ public Instruction handleObjectValueOf(JVMInvokeInstruction invInst, ThreadInfo sf.push(objRef, true); sf.setOperandAttr(sym_v2); } else { - System.err.println("ERROR: symbolic string method not Implemented - ObjectValueof"); + throw new RuntimeException("ERROR: symbolic string method not Implemented - ObjectValueof"); } return null; } @@ -2211,7 +2060,7 @@ public Instruction handleConcat(JVMInvokeInstruction invInst, ThreadInfo th) { StringExpression sym_v2 = (StringExpression) sf.getOperandAttr(1); if ((sym_v1 == null) & (sym_v2 == null)) { - System.err.println("ERROR: symbolic string method must have one symbolic operand: handleConcat"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: handleConcat"); } else { int s1 = sf.pop(); int s2 = sf.pop(); @@ -2229,11 +2078,12 @@ public Instruction handleConcat(JVMInvokeInstruction invInst, ThreadInfo th) { } else { // both operands are symbolic result = sym_v2._concat(sym_v1); } - int objRef = th.getHeap().newString("", th).getObjectRef(); /* - * dummy - * String - * Object - */ + int objRef = th.getHeap().newString("", th).getObjectRef(); + /* + * dummy + * String + * Object + */ sf.push(objRef, true); sf.setOperandAttr(result); } @@ -2248,17 +2098,14 @@ public void handleObjectEquals(JVMInvokeInstruction invInst, ThreadInfo th) { if (sym_v1 != null) { // System.out.println("*" + sym_v1.toString()); if (!(sym_v1 instanceof StringExpression)) { - System.err.println("ERROR: expressiontype not handled: ObjectEquals"); - return; + throw new RuntimeException("ERROR: expressiontype not handled: ObjectEquals"); } } if (sym_v2 != null) { // System.out.println("***" + sym_v2.toString()); if (!(sym_v2 instanceof StringExpression)) { - - System.err.println("ERROR: expressiontype not handled: ObjectEquals"); - return; + throw new RuntimeException("ERROR: expressiontype not handled: ObjectEquals"); } } @@ -2322,7 +2169,7 @@ public Instruction handleAppend(JVMInvokeInstruction invInst, ThreadInfo th) { } else if (argTypes[0].equals("java.lang.Object")) { handleObjectAppend(invInst, th); } else { - System.err.println("ERROR: Input parameter type not handled in Symbolic String Append"); + throw new RuntimeException("ERROR: Input parameter type not handled in Symbolic String Append"); } return handled; @@ -2339,7 +2186,7 @@ public void handleStringAppend(JVMInvokeInstruction invInst, ThreadInfo th) { if (sym_v2 == null) sym_v2 = new SymbolicStringBuilder(); if ((sym_v1 == null) & (sym_v2.getstr() == null)) { - System.err.println("ERROR: symbolic string method must have one symbolic operand: handleStringAppend"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: handleStringAppend"); } else { int s1 = sf.pop(); int s2 = sf.pop(); @@ -2383,7 +2230,7 @@ public Instruction handleStringAppend3(JVMInvokeInstruction invInst, ThreadInfo boolean concreteSubstring = (sym_end == null & sym_start == null & sym_string == null); if (concreteSubstring & sym_builder.getstr() == null) { - System.err.println("ERROR: symbolic string method must have one symbolic operand: HandleStringAppend3"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: HandleStringAppend3"); } else { int endRef = sf.pop(); int startRef = sf.pop(); @@ -2502,7 +2349,7 @@ public void handleCharAppend(JVMInvokeInstruction invInst, ThreadInfo th) { if (sym_v2 == null) sym_v2 = new SymbolicStringBuilder(); if ((sym_v1 == null) & (sym_v2.getstr() == null)) { - System.err.println("ERROR: symbolic string method must have one symbolic operand: handleCharAppend"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: handleCharAppend"); } else { char s1 = (char) sf.pop(); int s2 = sf.pop(); @@ -2535,7 +2382,7 @@ public void handleByteAppend(JVMInvokeInstruction invInst, ThreadInfo th) { if (sym_v2 == null) sym_v2 = new SymbolicStringBuilder(); if ((sym_v1 == null) & (sym_v2.getstr() == null)) { - System.err.println("ERROR: symbolic string method must have one symbolic operand: handleByteAppend"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: handleByteAppend"); } else { byte s1 = (byte) sf.pop(); int s2 = sf.pop(); @@ -2568,7 +2415,7 @@ public void handleShortAppend(JVMInvokeInstruction invInst, ThreadInfo th) { if (sym_v2 == null) sym_v2 = new SymbolicStringBuilder(); if ((sym_v1 == null) & (sym_v2.getstr() == null)) { - System.err.println("ERROR: symbolic string method must have one symbolic operand: handleShortAppend"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: handleShortAppend"); } else { short s1 = (short) sf.pop(); int s2 = sf.pop(); @@ -2601,7 +2448,7 @@ public void handleIntAppend(JVMInvokeInstruction invInst, ThreadInfo th) { if (sym_v2 == null) sym_v2 = new SymbolicStringBuilder(); if ((sym_v1 == null) & (sym_v2.getstr() == null)) { - System.err.println("ERROR: symbolic string method must have one symbolic operand: hanldeIntAppend"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: hanldeIntAppend"); } else { int s1 = sf.pop(); int s2 = sf.pop(); @@ -2634,7 +2481,7 @@ public void handleFloatAppend(JVMInvokeInstruction invInst, ThreadInfo th) { if (sym_v2 == null) sym_v2 = new SymbolicStringBuilder(); if ((sym_v1 == null) & (sym_v2.getstr() == null)) { - System.err.println("ERROR: symbolic string method must have one symbolic operand: hanldeFloatAppend"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: hanldeFloatAppend"); } else { float s1 = Types.intToFloat(sf.pop()); int s2 = sf.pop(); @@ -2666,7 +2513,7 @@ public void handleBooleanAppend(JVMInvokeInstruction invInst, ThreadInfo th) { if (sym_v2 == null) sym_v2 = new SymbolicStringBuilder(); if ((sym_v1 == null) & (sym_v2.getstr() == null)) { - System.err.println("ERROR: symbolic string method must have one symbolic operand: hanldeBooleanAppend"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: hanldeBooleanAppend"); } else { boolean s1 = Types.intToBoolean(sf.pop()); int s2 = sf.pop(); @@ -2709,7 +2556,7 @@ public void handleLongAppend(JVMInvokeInstruction invInst, ThreadInfo th) { if (sym_v2 == null) sym_v2 = new SymbolicStringBuilder(); if ((sym_v1 == null) & (sym_v2.getstr() == null)) { - System.err.println("ERROR: symbolic string method must have one symbolic operand: handleLongAppend"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: handleLongAppend"); } else { long s1 = sf.popLong(); int s2 = sf.pop(); @@ -2745,7 +2592,7 @@ public void handleDoubleAppend(JVMInvokeInstruction invInst, ThreadInfo th) { if (sym_v2 == null) sym_v2 = new SymbolicStringBuilder(); if ((sym_v1 == null) & (sym_v2.getstr() == null)) { - System.err.println("ERROR: symbolic string method must have one symbolic operand"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand"); } else { if (sym_v1 == null) { // operand 0 is concrete @@ -2784,7 +2631,7 @@ public void handleObjectAppend(JVMInvokeInstruction invInst, ThreadInfo th) { if (sym_v2 == null) sym_v2 = new SymbolicStringBuilder(); if ((sym_v1 == null) && (sym_v2.getstr() == null)) { - System.err.println("ERROR: symbolic string method must have one symbolic operand: handleObjectAppend"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: handleObjectAppend"); } else { int s1 = sf.pop(); ElementInfo e2 = th.getElementInfo(s1); @@ -2804,7 +2651,7 @@ public void handleObjectAppend(JVMInvokeInstruction invInst, ThreadInfo th) { else if (sym_v1 instanceof StringExpression) sym_v2._append((StringExpression) sym_v1); else { - System.err.println("Object not handled in ObjectAppend"); + throw new RuntimeException("Object not handled in ObjectAppend"); } // setVariableAttribute(ei, invInst, th, sf, s2, sym_v2); //set the // value of the attribute of local StringBuilder element as sym_v2 @@ -2815,7 +2662,7 @@ else if (sym_v1 instanceof StringExpression) else if (sym_v1 instanceof StringExpression) sym_v2._append((StringExpression) sym_v1); else { - System.err.println("Object not handled in ObjectAppend"); + throw new RuntimeException("Object not handled in ObjectAppend"); } sf.push(s2, true); /* string Builder element can continue */ @@ -2836,7 +2683,7 @@ public void handleStringBuilderAppend(JVMInvokeInstruction invInst, ThreadInfo t sym_v1 = new SymbolicStringBuilder(); if ((sym_v1.getstr() == null) & (sym_v2.getstr() == null)) { - System.err.println("ERROR: symbolic string method must have one symbolic operand: hanldeStringBuilderAppend"); + throw new RuntimeException("ERROR: symbolic string method must have one symbolic operand: hanldeStringBuilderAppend"); } else { int s1 = sf.pop(); int s2 = sf.pop(); @@ -2894,8 +2741,7 @@ public String getStringEquiv(ElementInfo ei) { boolean val = ei.getBooleanField("value"); return Boolean.toString(val); } else { - System.err.println("ERROR: Object Type Not Handled in getStringVal"); - return null; + throw new RuntimeException("ERROR: Object Type Not Handled in getStringVal"); } } @@ -2910,11 +2756,11 @@ public Instruction handletoString(JVMInvokeInstruction invInst, ThreadInfo th) SymbolicStringBuilder sym_v2 = (SymbolicStringBuilder) sym_obj_v2; sym_v1 = sym_v2.getstr(); } else { - System.err.println("ERROR: symbolic type not Handled: toString"); + throw new RuntimeException("ERROR: symbolic type not Handled: toString"); } if ((sym_v1 == null)) { - System.err.println("ERROR: symbolic string method must have symbolic operand: toString"); + throw new RuntimeException("ERROR: symbolic string method must have symbolic operand: toString"); } else { sf.pop(); ElementInfo ei = th.getHeap().newString("", th); @@ -2939,7 +2785,7 @@ public void handleprintln(JVMInvokeInstruction invInst, ThreadInfo th, boolean d } if ((sym_v1 == null)) { - System.err.println("ERROR: symbolic string method must have symbolic operand: println"); + throw new RuntimeException("ERROR: symbolic string method must have symbolic operand: println"); } else { if (flag) sf.popLong(); diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/util/IFInstrSymbHelper.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/util/IFInstrSymbHelper.java deleted file mode 100644 index e92d99f..0000000 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/util/IFInstrSymbHelper.java +++ /dev/null @@ -1,638 +0,0 @@ -/* - * Copyright (C) 2014, United States Government, as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All rights reserved. - * - * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * - */ -package gov.nasa.jpf.symbc.bytecode.util; - - -import gov.nasa.jpf.jvm.bytecode.IfInstruction; -import gov.nasa.jpf.symbc.bytecode.LCMP; -import gov.nasa.jpf.symbc.numeric.Comparator; -import gov.nasa.jpf.symbc.numeric.IntegerExpression; -import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; -import gov.nasa.jpf.symbc.numeric.PathCondition; -import gov.nasa.jpf.symbc.numeric.RealExpression; -import gov.nasa.jpf.vm.ChoiceGenerator; -import gov.nasa.jpf.vm.Instruction; -import gov.nasa.jpf.vm.ThreadInfo; -import gov.nasa.jpf.vm.Types; - -/** - * @author Kasper S. Luckow - * - * Deals with how symbolic conditions are handled. Currently a lot(!!) of redundancy. Furthermore, parts of it - * are so ugly that my eyes bleed. Should be refactored into a generic method. - */ -public class IFInstrSymbHelper { - - public static Instruction getNextInstructionAndSetPCChoice(ThreadInfo ti, - LCMP instr, - IntegerExpression sym_v1, - IntegerExpression sym_v2, - Comparator firstComparator, - Comparator secondComparator, - Comparator thirdComparator) { - int conditionValue = -3; //bogus value - if(!ti.isFirstStepInsn()) { // first time around - PCChoiceGenerator prevPcGen; - ChoiceGenerator cg = ti.getVM().getChoiceGenerator(); - if(cg instanceof PCChoiceGenerator) - prevPcGen = (PCChoiceGenerator)cg; - else - prevPcGen = (PCChoiceGenerator)cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - PathCondition pc; - if(prevPcGen!=null) - pc = prevPcGen.getCurrentPC(); - else - pc = new PathCondition(); - - PathCondition firstPC = pc.make_copy(); - PathCondition secPC = pc.make_copy(); - PathCondition thirdPC = pc.make_copy(); - - long v1 = ti.getModifiableTopFrame().peekLong(); - long v2 = ti.getModifiableTopFrame().peekLong(2); - - if(sym_v1 != null){ - if(sym_v2 != null){ //both are symbolic values - firstPC._addDet(firstComparator,sym_v2,sym_v1); - secPC._addDet(secondComparator,sym_v1,sym_v2); - thirdPC._addDet(thirdComparator,sym_v2,sym_v1); - } else { - firstPC._addDet(firstComparator,v2,sym_v1); - secPC._addDet(secondComparator,sym_v1,v2); - thirdPC._addDet(thirdComparator,v2,sym_v1); - } - } else { - firstPC._addDet(firstComparator,sym_v2,v1); - secPC._addDet(secondComparator,v1,sym_v2); - thirdPC._addDet(thirdComparator,sym_v2,v1); - } - - boolean firstSat = firstPC.simplify(); - boolean secSat = secPC.simplify(); - boolean thirdSat = thirdPC.simplify(); - - if(firstSat) { - if(secSat) { - PCChoiceGenerator newPCChoice; - if(thirdSat) { - newPCChoice = new PCChoiceGenerator(3); - } else { - //LE (choice 0) == true, EQ (choice 1)== true - newPCChoice = new PCChoiceGenerator(2); - } - newPCChoice.setOffset(instr.getPosition()); - newPCChoice.setMethodName(instr.getMethodInfo().getFullName()); - ti.getVM().getSystemState().setNextChoiceGenerator(newPCChoice); - return instr; - } else if(thirdSat) { - //LE (choice 0) == true, GT (choice 2)== true - PCChoiceGenerator newPCChoice = new PCChoiceGenerator(0, 2, 2); - newPCChoice.setOffset(instr.getPosition()); - newPCChoice.setMethodName(instr.getMethodInfo().getFullName()); - ti.getVM().getSystemState().setNextChoiceGenerator(newPCChoice); - return instr; - } else { - prevPcGen.setCurrentPC(firstPC); - conditionValue = -1; - } - } else if(secSat) { - if(thirdSat) { - //EQ (choice 1) == true, GT (choice 2)== true - PCChoiceGenerator newPCChoice = new PCChoiceGenerator(1, 2); - newPCChoice.setOffset(instr.getPosition()); - newPCChoice.setMethodName(instr.getMethodInfo().getFullName()); - ti.getVM().getSystemState().setNextChoiceGenerator(newPCChoice); - return instr; - } else { - conditionValue = 0; - } - } else if(thirdSat) { - conditionValue = 1; - } else { - System.err.println("***********Warning: everything false"); - ti.getVM().getSystemState().setIgnored(true); - } - - } else { //This branch will only be taken if there is a choice - - long v1 = ti.getModifiableTopFrame().peekLong(); - long v2 = ti.getModifiableTopFrame().peekLong(2); - PathCondition pc; - PCChoiceGenerator curCg = (PCChoiceGenerator)ti.getVM().getSystemState().getChoiceGenerator(); - - PCChoiceGenerator prevCg = curCg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - if(prevCg == null ) - pc = new PathCondition(); - else - pc = ((PCChoiceGenerator)prevCg).getCurrentPC(); - - conditionValue = ((PCChoiceGenerator) curCg).getNextChoice() -1; - if (conditionValue == -1) { - if (sym_v1 != null) { - if (sym_v2 != null) { // both are symbolic values - pc._addDet(firstComparator, sym_v2, sym_v1); - } else - pc._addDet(firstComparator, v2, sym_v1); - } else - pc._addDet(firstComparator, sym_v2, v1); - ((PCChoiceGenerator) curCg).setCurrentPC(pc); - } else if (conditionValue == 0){ - if (sym_v1 != null) { - if (sym_v2 != null) { // both are symbolic values - pc._addDet(secondComparator, sym_v1, sym_v2); - } else - pc._addDet(secondComparator, sym_v1, v2); - } else - pc._addDet(secondComparator, v1, sym_v2); - ((PCChoiceGenerator) curCg).setCurrentPC(pc); - } else {// 1 - if (sym_v1 != null) { - if (sym_v2 != null) { // both are symbolic values - pc._addDet(thirdComparator, sym_v2, sym_v1); - } else - pc._addDet(thirdComparator, v2, sym_v1); - } else - pc._addDet(thirdComparator, sym_v2, v1); - ((PCChoiceGenerator) curCg).setCurrentPC(pc); - } - } - ti.getModifiableTopFrame().popLong(); - ti.getModifiableTopFrame().popLong(); - ti.getModifiableTopFrame().push(conditionValue, false); - return instr.getNext(ti); - } - - public static Instruction getNextInstructionAndSetPCChoiceFloat(ThreadInfo ti, - Instruction instr, - RealExpression sym_v1, - RealExpression sym_v2, - Comparator firstComparator, - Comparator secondComparator, - Comparator thirdComparator) { - int conditionValue = -3; //bogus value - if(!ti.isFirstStepInsn()) { // first time around - PCChoiceGenerator prevPcGen; - ChoiceGenerator cg = ti.getVM().getChoiceGenerator(); - if(cg instanceof PCChoiceGenerator) - prevPcGen = (PCChoiceGenerator)cg; - else - prevPcGen = (PCChoiceGenerator)cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - PathCondition pc; - if(prevPcGen!=null) - pc = prevPcGen.getCurrentPC(); - else - pc = new PathCondition(); - - PathCondition firstPC = pc.make_copy(); - PathCondition secPC = pc.make_copy(); - PathCondition thirdPC = pc.make_copy(); - - float v1 = Types.intToFloat(ti.getModifiableTopFrame().peek()); - float v2 = Types.intToFloat(ti.getModifiableTopFrame().peek(1)); - - if(sym_v1 != null){ - if(sym_v2 != null){ //both are symbolic values - firstPC._addDet(firstComparator,sym_v2,sym_v1); - secPC._addDet(secondComparator,sym_v1,sym_v2); - thirdPC._addDet(thirdComparator,sym_v2,sym_v1); - } else { - firstPC._addDet(firstComparator,v2,sym_v1); - secPC._addDet(secondComparator,sym_v1,v2); - thirdPC._addDet(thirdComparator,v2,sym_v1); - } - } else { - firstPC._addDet(firstComparator,sym_v2,v1); - secPC._addDet(secondComparator,v1,sym_v2); - thirdPC._addDet(thirdComparator,sym_v2,v1); - } - - boolean firstSat = firstPC.simplify(); - boolean secSat = secPC.simplify(); - boolean thirdSat = thirdPC.simplify(); - - if(firstSat) { - if(secSat) { - PCChoiceGenerator newPCChoice; - if(thirdSat) { - newPCChoice = new PCChoiceGenerator(3); - } else { - //LE (choice 0) == true, EQ (choice 1)== true - newPCChoice = new PCChoiceGenerator(2); - } - newPCChoice.setOffset(instr.getPosition()); - newPCChoice.setMethodName(instr.getMethodInfo().getFullName()); - ti.getVM().getSystemState().setNextChoiceGenerator(newPCChoice); - return instr; - } else if(thirdSat) { - //LE (choice 0) == true, GT (choice 2)== true - PCChoiceGenerator newPCChoice = new PCChoiceGenerator(0, 2, 2); - newPCChoice.setOffset(instr.getPosition()); - newPCChoice.setMethodName(instr.getMethodInfo().getFullName()); - ti.getVM().getSystemState().setNextChoiceGenerator(newPCChoice); - return instr; - } else { - prevPcGen.setCurrentPC(firstPC); - conditionValue = -1; - } - } else if(secSat) { - if(thirdSat) { - //EQ (choice 1) == true, GT (choice 2)== true - PCChoiceGenerator newPCChoice = new PCChoiceGenerator(1, 2); - newPCChoice.setOffset(instr.getPosition()); - newPCChoice.setMethodName(instr.getMethodInfo().getFullName()); - ti.getVM().getSystemState().setNextChoiceGenerator(newPCChoice); - return instr; - } else { - conditionValue = 0; - } - } else if(thirdSat) { - conditionValue = 1; - } else { - System.err.println("***********Warning: everything false"); - ti.getVM().getSystemState().setIgnored(true); - } - } else { //This branch will only be taken if there is a choice - - float v1 = Types.intToFloat(ti.getModifiableTopFrame().peek()); - float v2 = Types.intToFloat(ti.getModifiableTopFrame().peek(1)); - PathCondition pc; - PCChoiceGenerator curCg = (PCChoiceGenerator)ti.getVM().getSystemState().getChoiceGenerator(); - - PCChoiceGenerator prevCg = curCg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - if(prevCg == null ) - pc = new PathCondition(); - else - pc = prevCg.getCurrentPC(); - - conditionValue = ((PCChoiceGenerator) curCg).getNextChoice() -1; - if (conditionValue == -1) { - if (sym_v1 != null) { - if (sym_v2 != null) { // both are symbolic values - pc._addDet(firstComparator, sym_v2, sym_v1); - } else - pc._addDet(firstComparator, v2, sym_v1); - } else - pc._addDet(firstComparator, sym_v2, v1); - ((PCChoiceGenerator) curCg).setCurrentPC(pc); - } else if (conditionValue == 0){ - if (sym_v1 != null) { - if (sym_v2 != null) { // both are symbolic values - pc._addDet(secondComparator, sym_v1, sym_v2); - } else - pc._addDet(secondComparator, sym_v1, v2); - } else - pc._addDet(secondComparator, v1, sym_v2); - ((PCChoiceGenerator) curCg).setCurrentPC(pc); - } else {// 1 - if (sym_v1 != null) { - if (sym_v2 != null) { // both are symbolic values - pc._addDet(thirdComparator, sym_v2, sym_v1); - } else - pc._addDet(thirdComparator, v2, sym_v1); - } else - pc._addDet(thirdComparator, sym_v2, v1); - ((PCChoiceGenerator) curCg).setCurrentPC(pc); - } - } - ti.getModifiableTopFrame().pop(); - ti.getModifiableTopFrame().pop(); - ti.getModifiableTopFrame().push(conditionValue, false); - return instr.getNext(ti); - - } - - public static Instruction getNextInstructionAndSetPCChoiceDouble(ThreadInfo ti, - Instruction instr, - RealExpression sym_v1, - RealExpression sym_v2, - Comparator firstComparator, - Comparator secondComparator, - Comparator thirdComparator) { - int conditionValue = -3; //bogus value - - if(!ti.isFirstStepInsn()) { // first time around - PCChoiceGenerator prevPcGen; - ChoiceGenerator cg = ti.getVM().getChoiceGenerator(); - if(cg instanceof PCChoiceGenerator) - prevPcGen = (PCChoiceGenerator)cg; - else - prevPcGen = (PCChoiceGenerator)cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - PathCondition pc; - if(prevPcGen!=null) - pc = prevPcGen.getCurrentPC(); - else - pc = new PathCondition(); - - PathCondition firstPC = pc.make_copy(); - PathCondition secPC = pc.make_copy(); - PathCondition thirdPC = pc.make_copy(); - - double v1 = Types.longToDouble(ti.getModifiableTopFrame().peekLong()); - double v2 = Types.longToDouble(ti.getModifiableTopFrame().peekLong(2)); - - if(sym_v1 != null){ - if(sym_v2 != null){ //both are symbolic values - firstPC._addDet(firstComparator,sym_v2,sym_v1); - secPC._addDet(secondComparator,sym_v1,sym_v2); - thirdPC._addDet(thirdComparator,sym_v2,sym_v1); - } else { - firstPC._addDet(firstComparator,v2,sym_v1); - secPC._addDet(secondComparator,sym_v1,v2); - thirdPC._addDet(thirdComparator,v2,sym_v1); - } - } else { - firstPC._addDet(firstComparator,sym_v2,v1); - secPC._addDet(secondComparator,v1,sym_v2); - thirdPC._addDet(thirdComparator,sym_v2,v1); - } - - boolean firstSat = firstPC.simplify(); - boolean secSat = secPC.simplify(); - boolean thirdSat = thirdPC.simplify(); - - if(firstSat) { - if(secSat) { - PCChoiceGenerator newPCChoice; - if(thirdSat) { - newPCChoice = new PCChoiceGenerator(3); - } else { - //LE (choice 0) == true, EQ (choice 1)== true - newPCChoice = new PCChoiceGenerator(2); - } - newPCChoice.setOffset(instr.getPosition()); - newPCChoice.setMethodName(instr.getMethodInfo().getFullName()); - ti.getVM().getSystemState().setNextChoiceGenerator(newPCChoice); - return instr; - } else if(thirdSat) { - //LE (choice 0) == true, GT (choice 2)== true - PCChoiceGenerator newPCChoice = new PCChoiceGenerator(0, 2, 2); - newPCChoice.setOffset(instr.getPosition()); - newPCChoice.setMethodName(instr.getMethodInfo().getFullName()); - ti.getVM().getSystemState().setNextChoiceGenerator(newPCChoice); - return instr; - } else { - conditionValue = -1; - } - } else if(secSat) { - if(thirdSat) { - //EQ (choice 1) == true, GT (choice 2)== true - PCChoiceGenerator newPCChoice = new PCChoiceGenerator(1, 2); - newPCChoice.setOffset(instr.getPosition()); - newPCChoice.setMethodName(instr.getMethodInfo().getFullName()); - ti.getVM().getSystemState().setNextChoiceGenerator(newPCChoice); - return instr; - } else { - conditionValue = 0; - } - } else if(thirdSat) { - conditionValue = 1; - } else { - System.err.println("***********Warning: everything false"); - ti.getVM().getSystemState().setIgnored(true); - } - } else { //This branch will only be taken if there is a choice - - double v1 = Types.longToDouble(ti.getModifiableTopFrame().peekLong()); - double v2 = Types.longToDouble(ti.getModifiableTopFrame().peekLong(2)); - - PathCondition pc; - PCChoiceGenerator curCg = (PCChoiceGenerator)ti.getVM().getSystemState().getChoiceGenerator(); - - PCChoiceGenerator prevCg = curCg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - if(prevCg == null ) - pc = new PathCondition(); - else - pc = prevCg.getCurrentPC(); - - conditionValue = ((PCChoiceGenerator) curCg).getNextChoice() -1; - if (conditionValue == -1) { - if (sym_v1 != null) { - if (sym_v2 != null) { // both are symbolic values - pc._addDet(firstComparator, sym_v2, sym_v1); - } else - pc._addDet(firstComparator, v2, sym_v1); - } else - pc._addDet(firstComparator, sym_v2, v1); - ((PCChoiceGenerator) curCg).setCurrentPC(pc); - } else if (conditionValue == 0){ - if (sym_v1 != null) { - if (sym_v2 != null) { // both are symbolic values - pc._addDet(secondComparator, sym_v1, sym_v2); - } else - pc._addDet(secondComparator, sym_v1, v2); - } else - pc._addDet(secondComparator, v1, sym_v2); - ((PCChoiceGenerator) curCg).setCurrentPC(pc); - } else {// 1 - if (sym_v1 != null) { - if (sym_v2 != null) { // both are symbolic values - pc._addDet(thirdComparator, sym_v2, sym_v1); - } else - pc._addDet(thirdComparator, v2, sym_v1); - } else - pc._addDet(thirdComparator, sym_v2, v1); - ((PCChoiceGenerator) curCg).setCurrentPC(pc); - } - } - ti.getModifiableTopFrame().popLong(); - ti.getModifiableTopFrame().popLong(); - ti.getModifiableTopFrame().push(conditionValue, false); - return instr.getNext(ti); - } - - - - public static Instruction getNextInstructionAndSetPCChoice(ThreadInfo ti, - IfInstruction instr, - IntegerExpression sym_v, - Comparator trueComparator, - Comparator falseComparator) { - - //TODO: fix conditionValue - if(!ti.isFirstStepInsn()) { // first time around - PCChoiceGenerator prevPcGen; - ChoiceGenerator cg = ti.getVM().getChoiceGenerator(); - if(cg instanceof PCChoiceGenerator) - prevPcGen = (PCChoiceGenerator)cg; - else - prevPcGen = (PCChoiceGenerator)cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - PathCondition pc; - if(prevPcGen!=null) - pc = prevPcGen.getCurrentPC(); - else - pc = new PathCondition(); - - PathCondition eqPC = pc.make_copy(); - PathCondition nePC = pc.make_copy(); - eqPC._addDet(trueComparator, sym_v, 0); - nePC._addDet(falseComparator, sym_v, 0); - - boolean eqSat = eqPC.simplify(); - boolean neSat = nePC.simplify(); - - if(eqSat) { - if(neSat) { - PCChoiceGenerator newPCChoice; - newPCChoice = new PCChoiceGenerator(2); - newPCChoice.setOffset(instr.getPosition()); - newPCChoice.setMethodName(instr.getMethodInfo().getFullName()); - ti.getVM().getSystemState().setNextChoiceGenerator(newPCChoice); - return instr; - } else { - ti.getModifiableTopFrame().pop(); - return instr.getTarget(); - } - } else { - ti.getModifiableTopFrame().pop(); - return instr.getNext(ti); - } - } else { - ti.getModifiableTopFrame().pop(); - PathCondition pc; - PCChoiceGenerator curCg = (PCChoiceGenerator)ti.getVM().getSystemState().getChoiceGenerator(); - - PCChoiceGenerator prevCg = curCg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - if(prevCg == null ) - pc = new PathCondition(); - else - pc = prevCg.getCurrentPC(); - boolean conditionValue = (Integer)curCg.getNextChoice()==1 ? true: false; - if(conditionValue) { - pc._addDet(trueComparator, sym_v, 0); - ((PCChoiceGenerator) curCg).setCurrentPC(pc); - return instr.getTarget(); - } else { - pc._addDet(falseComparator, sym_v, 0); - ((PCChoiceGenerator) curCg).setCurrentPC(pc); - return instr.getNext(ti); - } - } - } - - public static Instruction getNextInstructionAndSetPCChoice(ThreadInfo ti, - IfInstruction instr, - IntegerExpression sym_v1, - IntegerExpression sym_v2, - Comparator trueComparator, - Comparator falseComparator) { - - //TODO: fix conditionValue - if(!ti.isFirstStepInsn()) { // first time around - PCChoiceGenerator prevPcGen; - ChoiceGenerator cg = ti.getVM().getChoiceGenerator(); - if(cg instanceof PCChoiceGenerator) - prevPcGen = (PCChoiceGenerator)cg; - else - prevPcGen = (PCChoiceGenerator)cg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - PathCondition pc; - if(prevPcGen!=null) - pc = prevPcGen.getCurrentPC(); - else - pc = new PathCondition(); - - PathCondition eqPC = pc.make_copy(); - PathCondition nePC = pc.make_copy(); - - int v2 = ti.getModifiableTopFrame().peek(); - int v1 = ti.getModifiableTopFrame().peek(1); - - if(sym_v1 != null){ - if(sym_v2 != null){ //both are symbolic values - eqPC._addDet(trueComparator,sym_v1,sym_v2); - nePC._addDet(falseComparator,sym_v1,sym_v2); - } else { - eqPC._addDet(trueComparator,sym_v1,v2); - nePC._addDet(falseComparator,sym_v1,v2); - } - } else { - eqPC._addDet(trueComparator, v1, sym_v2); - nePC._addDet(falseComparator, v1, sym_v2); - } - - boolean eqSat = eqPC.simplify(); - boolean neSat = nePC.simplify(); - - if(eqSat) { - if(neSat) { - PCChoiceGenerator newPCChoice = new PCChoiceGenerator(2); - newPCChoice.setOffset(instr.getPosition()); - newPCChoice.setMethodName(instr.getMethodInfo().getFullName()); - ti.getVM().getSystemState().setNextChoiceGenerator(newPCChoice); - return instr; - } else { - ti.getModifiableTopFrame().pop(); - ti.getModifiableTopFrame().pop(); - return instr.getTarget(); - } - } else { - ti.getModifiableTopFrame().pop(); - ti.getModifiableTopFrame().pop(); - return instr.getNext(ti); - } - } else { //This branch will only be taken if there is a choice - - int v2 = ti.getModifiableTopFrame().pop(); - int v1 = ti.getModifiableTopFrame().pop(); - PathCondition pc; - PCChoiceGenerator curCg = (PCChoiceGenerator)ti.getVM().getSystemState().getChoiceGenerator(); - - PCChoiceGenerator prevCg = curCg.getPreviousChoiceGeneratorOfType(PCChoiceGenerator.class); - - if(prevCg == null ) - pc = new PathCondition(); - else - pc = prevCg.getCurrentPC(); - - boolean conditionValue = (Integer)curCg.getNextChoice()==1 ? true: false; - if(conditionValue) { - if(sym_v1 != null){ - if(sym_v2 != null){ //both are symbolic values - pc._addDet(trueComparator,sym_v1,sym_v2); - } else - pc._addDet(trueComparator,sym_v1,v2); - } else - pc._addDet(trueComparator, v1, sym_v2); - ((PCChoiceGenerator) curCg).setCurrentPC(pc); - return instr.getTarget(); - } else { - if(sym_v1 != null){ - if (sym_v2 != null){ //both are symbolic values - pc._addDet(falseComparator,sym_v1,sym_v2); - } else - pc._addDet(falseComparator,sym_v1,v2); - } else - pc._addDet(falseComparator, v1, sym_v2); - ((PCChoiceGenerator) curCg).setCurrentPC(pc); - return instr.getNext(ti); - } - } - } -} diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/util/PCChoiceGeneratorException.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/util/PCChoiceGeneratorException.java deleted file mode 100644 index c49417c..0000000 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/bytecode/util/PCChoiceGeneratorException.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2014, United States Government, as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All rights reserved. - * - * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * - */ -package gov.nasa.jpf.symbc.bytecode.util; - - -import java.io.PrintStream; - -/** - * @author Kasper S. Luckow - * - */ -public class PCChoiceGeneratorException extends RuntimeException { - public PCChoiceGeneratorException (String details) { - super(details); - } - - public PCChoiceGeneratorException (Throwable cause) { - super(cause); - } - - public PCChoiceGeneratorException (String details, Throwable cause){ - super(details, cause); - } - - public void printStackTrace (PrintStream out) { - out.println("---------------------- Symbc JPF error stack trace ---------------------"); - super.printStackTrace(out); - } -} diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/concolic/FunctionExpression.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/concolic/FunctionExpression.java index e80e15a..2d43e36 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/concolic/FunctionExpression.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/concolic/FunctionExpression.java @@ -38,17 +38,14 @@ package gov.nasa.jpf.symbc.concolic; // support for arbitrary external functions - -import gov.nasa.jpf.symbc.numeric.Constraint; import gov.nasa.jpf.symbc.numeric.ConstraintExpressionVisitor; import gov.nasa.jpf.symbc.numeric.Expression; import gov.nasa.jpf.symbc.numeric.IntegerExpression; import gov.nasa.jpf.symbc.numeric.PathCondition; import gov.nasa.jpf.symbc.numeric.RealExpression; import gov.nasa.jpf.util.FileUtils; -import gov.nasa.jpf.vm.ClassInfo; import gov.nasa.jpf.vm.ClassLoaderInfo; - + import java.util.ArrayList; import java.util.Map; import java.lang.reflect.*; @@ -114,7 +111,7 @@ public double solution() Object[] args = new Object[sym_args.length]; for (int i=0; i 0); - final RealExpression e = (RealExpression)sym_args[0];// for now assume only real expressions; TODO the integer expressions + RealExpression e = (RealExpression)sym_args[0];// for now assume only real expressions; TODO the integer expressions RealConstraint c = new RealConstraint(e, Comparator.EQ, new RealConstant(e.solution())); for(int i=1; i { - public static LinkedList trackedSymVars = new LinkedList(); - public abstract String stringPC(); - public abstract void getVarsVals(Map varsVals); - public abstract void accept(ConstraintExpressionVisitor visitor); -} + +//Copyright (C) 2005 United States Government as represented by the +//Administrator of the National Aeronautics and Space Administration +//(NASA). All Rights Reserved. + +//This software is distributed under the NASA Open Source Agreement +//(NOSA), version 1.3. The NOSA has been approved by the Open Source +//Initiative. See the file NOSA-1.3-JPF at the top of the distribution +//directory tree for the complete NOSA document. + +//THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY +//KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT +//LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO +//SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR +//A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT +//THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT +//DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. + + +package gov.nasa.jpf.symbc.numeric; + + +import java.util.Map; +import java.util.LinkedList; + + +public abstract class Expression implements Comparable { + public static LinkedList trackedSymVars = new LinkedList(); + public abstract String stringPC(); + public abstract void getVarsVals(Map varsVals); + public abstract void accept(ConstraintExpressionVisitor visitor); + public String prefix_notation() {throw new RuntimeException("error printing");} + +} diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/IntegerConstant.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/IntegerConstant.java index ef420c9..3462ce8 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/IntegerConstant.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/IntegerConstant.java @@ -38,29 +38,25 @@ package gov.nasa.jpf.symbc.numeric; import java.util.Map; + import static gov.nasa.jpf.symbc.numeric.Operator.*; public class IntegerConstant extends LinearIntegerExpression { - public int value; + public long value; - public IntegerConstant (int i) { - value = i; + public IntegerConstant (long i) { + value = i; } - public IntegerExpression _minus (int i) { - //simplify + public IntegerExpression _minus (long i) { if (i == 0) return this; - - return new IntegerConstant(value - i); + return new IntegerConstant(value - i); } - public IntegerExpression _minus_reverse (int i) { + public IntegerExpression _minus_reverse (long i) { return new IntegerConstant(i - value); } - public IntegerExpression _minus_reverse (long i) { - return new IntegerConstant((int) i - value); - } public IntegerExpression _minus (IntegerExpression e) { //simplify @@ -79,7 +75,7 @@ public IntegerExpression _minus (IntegerExpression e) { } } - public IntegerExpression _div (int i) { + public IntegerExpression _div (long i) { //simplify if (i == 1) return this; @@ -87,16 +83,10 @@ public IntegerExpression _div (int i) { return new IntegerConstant(value / i); } - public IntegerExpression _div_reverse (int i) { - //simplify - assert (value !=0); - return new IntegerConstant(i / value); - } - public IntegerExpression _div_reverse (long i) { - //simplify + //simplify assert (value !=0); - return new IntegerConstant((int) i / value); + return new IntegerConstant(i / value); } public IntegerExpression _div (IntegerExpression e) { @@ -115,7 +105,7 @@ public IntegerExpression _div (IntegerExpression e) { return super._div(e); } - public IntegerExpression _mul (int i) { + public IntegerExpression _mul (long i) { //simplify if (i == 1) return this; @@ -145,7 +135,7 @@ public IntegerExpression _mul (IntegerExpression e) { } - public IntegerExpression _plus (int i) { + public IntegerExpression _plus (long i) { //simplify if (i == 0) return this; @@ -176,19 +166,11 @@ public IntegerExpression _neg () return super._neg(); } - - public IntegerExpression _and (int i) { - if (i == 0) { - return new IntegerConstant(0); - } - return new IntegerConstant(value & i); - } - public IntegerExpression _and (long i) { if (i == 0) { return new IntegerConstant(0); } - return new IntegerConstant(value & ((int) i)); + return new IntegerConstant(value & i); } public IntegerExpression _and (IntegerExpression e) { @@ -201,18 +183,11 @@ public IntegerExpression _and (IntegerExpression e) { return new BinaryLinearIntegerExpression(this, AND, e); } - public IntegerExpression _or (int i) { - if (i == 0) { - return this; - } - return new IntegerConstant(value | i); - } - public IntegerExpression _or (long i) { if (i == 0) { return this; } - return new IntegerConstant(value | ((int) i)); + return new IntegerConstant(value | i); } public IntegerExpression _or (IntegerExpression e) { @@ -225,12 +200,8 @@ public IntegerExpression _or (IntegerExpression e) { return new BinaryLinearIntegerExpression(this, OR, e); } - public IntegerExpression _xor (int i) { - return new IntegerConstant(value ^ i); - } - public IntegerExpression _xor (long i) { - return new IntegerConstant(value ^ ((int) i)); + return new IntegerConstant(value ^ i); } public IntegerExpression _xor (IntegerExpression e) { @@ -241,12 +212,8 @@ public IntegerExpression _xor (IntegerExpression e) { } - public IntegerExpression _shiftL (int i) { - return new IntegerConstant(value << i); - } - public IntegerExpression _shiftL (long i) { - return new IntegerConstant(value << ((int) i)); + return new IntegerConstant(value << i); } public IntegerExpression _shiftL (IntegerExpression e) { @@ -256,12 +223,8 @@ public IntegerExpression _shiftL (IntegerExpression e) { return new BinaryLinearIntegerExpression(this, SHIFTL, e); } - public IntegerExpression _shiftR (int i) { - return new IntegerConstant(value >> i); - } - public IntegerExpression _shiftR (long i) { - return new IntegerConstant(value >> ((int) i)); + return new IntegerConstant(value >> i); } public IntegerExpression _shiftR (IntegerExpression e) { @@ -271,12 +234,8 @@ public IntegerExpression _shiftR (IntegerExpression e) { return new BinaryLinearIntegerExpression(this, SHIFTR, e); } - public IntegerExpression _shiftUR (int i) { - return new IntegerConstant(value >>> i); - } - public IntegerExpression _shiftUR (long i) { - return new IntegerConstant(value >>> ((int) i)); + return new IntegerConstant(value >>> i); } public IntegerExpression _shiftUR (IntegerExpression e) { @@ -296,24 +255,49 @@ public boolean equals (Object o) { } @Override - public int hashCode() { - return value; + public int hashCode() { // analogous to java.lang.Long + return (int)(this.value^(value>>>32)); } public String toString () { return "CONST_" + value + ""; } - + + public String prefix_notation () + { + return ""+value; + } + public String stringPC () { return "CONST_" + value + ""; } public int value () { - return value; + return (int) value; } - public int solution() { - return value; + public long solution() { // to be fixed + return value; + } + + public int solutionInt() { + assert(value>=Integer.MIN_VALUE && value<=Integer.MAX_VALUE); + return (int) value; + } + + public short solutionShort() { + assert(value>=Short.MIN_VALUE && value<=Short.MAX_VALUE); + return (short) value; + } + + public byte solutionByte() { + assert(value>=Byte.MIN_VALUE && value<=Byte.MAX_VALUE); + return (byte) value; + } + + public char solutionChar() { + assert(value>=Character.MIN_VALUE && value<=Character.MAX_VALUE); + return (char) value; } public void getVarsVals(Map varsVals) {} @@ -329,8 +313,8 @@ public void accept(ConstraintExpressionVisitor visitor) { public int compareTo(Expression expr) { if (expr instanceof IntegerConstant) { IntegerConstant e = (IntegerConstant) expr; - int a = value(); - int b = e.value(); + long a = value(); + long b = e.value(); return (a < b) ? -1 : (a > b) ? 1 : 0; } else { return getClass().getCanonicalName().compareTo(expr.getClass().getCanonicalName()); diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/IntegerExpression.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/IntegerExpression.java index 2f4807e..6211cc2 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/IntegerExpression.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/IntegerExpression.java @@ -45,12 +45,12 @@ public abstract class IntegerExpression extends Expression { //returns -1 if (this < i), 0 if equal and 1 otherwise public IntegerExpression _cmp (long i) { - return new BinaryNonLinearIntegerExpression(this, CMP, new IntegerConstant((int)i)); + return new BinaryNonLinearIntegerExpression(this, CMP, new IntegerConstant(i)); } public IntegerExpression _cmp_reverse (long i) { - return new BinaryNonLinearIntegerExpression(new IntegerConstant((int)i), CMP, this); + return new BinaryNonLinearIntegerExpression(new IntegerConstant(i), CMP, this); } public IntegerExpression _cmp (IntegerExpression e) @@ -60,12 +60,12 @@ public IntegerExpression _cmp (IntegerExpression e) //------------------------------------------------------ - public IntegerExpression _minus_reverse (int i) + public IntegerExpression _minus_reverse (long i) { return new BinaryNonLinearIntegerExpression(new IntegerConstant(i), MINUS, this); } - public IntegerExpression _minus (int i) + public IntegerExpression _minus (long i) { //simplify if (i == 0) @@ -87,7 +87,7 @@ public IntegerExpression _minus (IntegerExpression e) return new BinaryNonLinearIntegerExpression(this, MINUS, e); } - public IntegerExpression _mul (int i) + public IntegerExpression _mul (long i) { //simplify if (i == 1) @@ -112,7 +112,7 @@ public IntegerExpression _mul (IntegerExpression e) return new BinaryNonLinearIntegerExpression(this, MUL, e); } - public IntegerExpression _plus (int i) + public IntegerExpression _plus (long i) { //simplify if (i == 0) @@ -189,61 +189,62 @@ public IntegerExpression _xor(IntegerExpression e) { return new BinaryNonLinearIntegerExpression(this, XOR, e); } - public IntegerExpression _shiftR(int i) + public IntegerExpression _shiftR(long i) { if(i == 0) return this; return new BinaryNonLinearIntegerExpression(this, SHIFTR, - new IntegerConstant((int) i)); + new IntegerConstant( i)); } - public IntegerExpression _shiftL(int i) { + public IntegerExpression _shiftL(long i) { if(i == 0) return this; return new BinaryNonLinearIntegerExpression(this, SHIFTL, - new IntegerConstant((int) i)); + new IntegerConstant( i)); } - public IntegerExpression _shiftUR(int i) { + public IntegerExpression _shiftUR(long i) { if(i == 0) return this; return new BinaryNonLinearIntegerExpression(this, SHIFTUR, - new IntegerConstant((int) i)); + new IntegerConstant( i)); } - public IntegerExpression _and(int i) + public IntegerExpression _and(long i) { if(i == 0) return new IntegerConstant(0); - return new BinaryNonLinearIntegerExpression(this, AND, new IntegerConstant((int)i)); + return new BinaryNonLinearIntegerExpression(this, AND, new IntegerConstant(i)); } - public IntegerExpression _or(int i) + public IntegerExpression _or(long i) { if(i == 0) return this; - return new BinaryNonLinearIntegerExpression(this, OR, new IntegerConstant((int) i)); + return new BinaryNonLinearIntegerExpression(this, OR, new IntegerConstant( i)); } - public IntegerExpression _xor(int i) + public IntegerExpression _xor(long i) { - return new BinaryNonLinearIntegerExpression(this, XOR, new IntegerConstant((int) i)); + return new BinaryNonLinearIntegerExpression(this, XOR, new IntegerConstant( i)); } - public IntegerExpression _rem(int i) + public IntegerExpression _rem(long i) { - throw new RuntimeException( "## Error: Operation not supported!" ); - } + return new BinaryNonLinearIntegerExpression(this, REM, new IntegerConstant( i)); + } - public IntegerExpression _rem_reverse(int i) - { - throw new RuntimeException( "## Error: Operation not supported!" ); - } + public IntegerExpression _rem_reverse(long i) + { + //throw new RuntimeException( "## Error: Operation not supported!" ); + return new BinaryNonLinearIntegerExpression(new IntegerConstant( i), REM, this); + } public IntegerExpression _rem(IntegerExpression i) { - throw new RuntimeException( "## Error: Operation not supported!" ); + return new BinaryNonLinearIntegerExpression(this, REM, i); } public IntegerExpression _neg() @@ -251,45 +252,7 @@ public IntegerExpression _neg() return new BinaryNonLinearIntegerExpression(new IntegerConstant(0), MINUS, this); } - /* - * Additional support for longs so that we are not downcasting in the - * individual bytecodes - */ - public IntegerExpression _minus_reverse (long i) - { - return new BinaryNonLinearIntegerExpression(new IntegerConstant((int)i), MINUS, this); - } - - public IntegerExpression _minus (long i) - { - //simplify - if (i == 0) - return this; - return new BinaryNonLinearIntegerExpression(this, MINUS, new IntegerConstant((int)i)); - } - - public IntegerExpression _mul (long i) - { - //simplify - if (i == 1) - return this; - if (i == 0) - return new IntegerConstant(0); - - return new BinaryNonLinearIntegerExpression(this, MUL, new IntegerConstant((int)i)); - } - - public IntegerExpression _plus (long i) - { - //simplify - if (i == 0) - return this; - return new BinaryNonLinearIntegerExpression(this, PLUS, new IntegerConstant((int)i)); - } - - - - public IntegerExpression _div (int i) + public IntegerExpression _div (long i) { // simplify assert (i != 0); @@ -313,84 +276,25 @@ public IntegerExpression _div (IntegerExpression e) return new BinaryNonLinearIntegerExpression(this, DIV, e); } - public IntegerExpression _div_reverse (int i) - { - if (i == 0) - return new IntegerConstant(0); - return new BinaryNonLinearIntegerExpression(new IntegerConstant(i), DIV, this); - } - - public IntegerExpression _div (long i) - { - // simplify - assert (i != 0); - if (i == 1) - return this; - return new BinaryNonLinearIntegerExpression(this, DIV, new IntegerConstant((int)i)); - } - public IntegerExpression _div_reverse (long i) { if (i == 0) return new IntegerConstant(0); - return new BinaryNonLinearIntegerExpression(new IntegerConstant((int)i), DIV, this); - } - - public IntegerExpression _and(long i) { - if (i == 0) - return new IntegerConstant(0); - - return new BinaryNonLinearIntegerExpression(this, AND, new IntegerConstant((int)i)); - } - - public IntegerExpression _or(long i) { - if (i == 0) - return this; - - return new BinaryNonLinearIntegerExpression(this, OR, new IntegerConstant((int)i)); - } - - public IntegerExpression _xor(long i) { - return new BinaryNonLinearIntegerExpression(this, XOR, new IntegerConstant((int)i)); - } - - public IntegerExpression _shiftR(long i) { - if (i == 0) - return this; - - return new BinaryNonLinearIntegerExpression(this, SHIFTR, - new IntegerConstant((int)i)); - } - - public IntegerExpression _shiftL(long i) { - if (i == 0) - return this; - - return new BinaryNonLinearIntegerExpression(this, SHIFTL, - new IntegerConstant((int)i)); - } - - public IntegerExpression _shiftUR(long i) { - if (i == 0) - return this; - - return new BinaryNonLinearIntegerExpression(this, SHIFTUR, - new IntegerConstant((int)i)); - - } - - public IntegerExpression _rem(long i) - { - throw new RuntimeException( "## Error: Operation not supported!" ); + return new BinaryNonLinearIntegerExpression(new IntegerConstant(i), DIV, this); } //TODO test this - public int solution() { + public long solution() { throw new RuntimeException( "## Error: Expression Solution request Error: " + this); //System.out.println("Expression Solution request Error: " + this); //return -666; } - + public int solutionInt() { + throw new RuntimeException( "## Error: Expression Solution request Error: " + this); + } + public char solutionChar() { + throw new RuntimeException( "## Error: Expression Solution request Error: " + this); + } //protected void finalize() throws Throwable { diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/LinearIntegerExpression.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/LinearIntegerExpression.java index e246910..4c9ab4b 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/LinearIntegerExpression.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/LinearIntegerExpression.java @@ -39,31 +39,19 @@ import static gov.nasa.jpf.symbc.numeric.Operator.*; abstract class LinearIntegerExpression extends IntegerExpression -{ - public IntegerExpression _minus_reverse (int i) - { - return new BinaryLinearIntegerExpression(new IntegerConstant(i), MINUS, this); - } +{ public IntegerExpression _minus_reverse (long i) { - return new BinaryLinearIntegerExpression(new IntegerConstant((int)i), MINUS, this); + return new BinaryLinearIntegerExpression(new IntegerConstant(i), MINUS, this); } - public IntegerExpression _minus (int i) { - //simplify - if (i == 0) - return this; - - return new BinaryLinearIntegerExpression(this, MINUS, new IntegerConstant(i)); - } - public IntegerExpression _minus (long i) { //simplify if (i == 0) return this; - return new BinaryLinearIntegerExpression(this, MINUS, new IntegerConstant((int)i)); + return new BinaryLinearIntegerExpression(this, MINUS, new IntegerConstant(i)); } public IntegerExpression _minus (IntegerExpression e) { @@ -83,16 +71,6 @@ public IntegerExpression _minus (IntegerExpression e) { } } - public IntegerExpression _mul (int i) { - //simplify - if (i == 1) - return this; - if (i == 0) - return new IntegerConstant(0); - - return new BinaryLinearIntegerExpression(this, MUL, new IntegerConstant(i)); - } - public IntegerExpression _mul (long i) { //simplify if (i == 1) @@ -100,12 +78,11 @@ public IntegerExpression _mul (long i) { if (i == 0) return new IntegerConstant(0); - return new BinaryLinearIntegerExpression(this, MUL, new IntegerConstant((int)i)); + return new BinaryLinearIntegerExpression(this, MUL, new IntegerConstant(i)); } public IntegerExpression _mul (IntegerExpression e) - { - + { //simplify if (e instanceof IntegerConstant) { IntegerConstant ic = (IntegerConstant)e; @@ -123,7 +100,7 @@ public IntegerExpression _mul (IntegerExpression e) } - public IntegerExpression _div (int i) + public IntegerExpression _div (long i) { // simplify assert (i != 0); @@ -149,23 +126,6 @@ public IntegerExpression _div (IntegerExpression e) return super._div(e); } - public IntegerExpression _div_reverse (int i) - { - if (i == 0) - return new IntegerConstant(0); - return super._div(i); - } - - public IntegerExpression _div (long i) - { - // simplify - assert (i != 0); - if (i == 1) - return this; - - return new BinaryLinearIntegerExpression(this, DIV, new IntegerConstant((int)i)); - } - public IntegerExpression _div_reverse (long i) { if (i == 0) @@ -173,20 +133,12 @@ public IntegerExpression _div_reverse (long i) return super._div(i); } - public IntegerExpression _plus (int i) { - //simplify - if (i == 0) - return this; - - return new BinaryLinearIntegerExpression(this, PLUS, new IntegerConstant(i)); - } - public IntegerExpression _plus (long i) { //simplify if (i == 0) return this; - return new BinaryLinearIntegerExpression(this, PLUS, new IntegerConstant((int)i)); + return new BinaryLinearIntegerExpression(this, PLUS, new IntegerConstant(i)); } public IntegerExpression _plus (IntegerExpression e) { @@ -209,18 +161,11 @@ public IntegerExpression _neg() return new BinaryLinearIntegerExpression(new IntegerConstant(0), MINUS, this); } - public IntegerExpression _and(int i) { - if(i == 0) { - return new IntegerConstant(0); - } - return new BinaryLinearIntegerExpression(this, AND, new IntegerConstant(i)); - } - public IntegerExpression _and(long i) { if(i == 0) { return new IntegerConstant(0); } - return new BinaryLinearIntegerExpression(this, AND, new IntegerConstant((int)i)); + return new BinaryLinearIntegerExpression(this, AND, new IntegerConstant(i)); } public IntegerExpression _and(IntegerExpression e) { @@ -237,18 +182,11 @@ public IntegerExpression _and(IntegerExpression e) { return new BinaryNonLinearIntegerExpression(this, AND, e); } - public IntegerExpression _or(int i) { - if(i == 0) { - return this; - } - return new BinaryLinearIntegerExpression(this, OR, new IntegerConstant(i)); - } - public IntegerExpression _or(long i) { if(i == 0) { return this; } - return new BinaryLinearIntegerExpression(this, OR, new IntegerConstant((int)i)); + return new BinaryLinearIntegerExpression(this, OR, new IntegerConstant(i)); } public IntegerExpression _or(IntegerExpression e) { @@ -265,12 +203,8 @@ public IntegerExpression _or(IntegerExpression e) { return new BinaryNonLinearIntegerExpression(this, OR, e); } - public IntegerExpression _xor(int i) { - return new BinaryLinearIntegerExpression(this, XOR, new IntegerConstant(i)); - } - public IntegerExpression _xor(long i) { - return new BinaryLinearIntegerExpression(this, XOR, new IntegerConstant((int)i)); + return new BinaryLinearIntegerExpression(this, XOR, new IntegerConstant(i)); } public IntegerExpression _xor(IntegerExpression e) { @@ -283,18 +217,11 @@ public IntegerExpression _xor(IntegerExpression e) { return new BinaryNonLinearIntegerExpression(this, XOR, e); } - public IntegerExpression _shiftR(int i) { - if(i == 0) { - return this; - } - return new BinaryLinearIntegerExpression(this, SHIFTR, new IntegerConstant(i)); - } - public IntegerExpression _shiftR(long i) { if(i == 0) { return this; } - return new BinaryLinearIntegerExpression(this, SHIFTR, new IntegerConstant((int)i)); + return new BinaryLinearIntegerExpression(this, SHIFTR, new IntegerConstant(i)); } public IntegerExpression _shiftR(IntegerExpression e) { @@ -311,18 +238,11 @@ public IntegerExpression _shiftR(IntegerExpression e) { return new BinaryNonLinearIntegerExpression(this, SHIFTR, e); } - public IntegerExpression _shiftUR(int i) { - if(i == 0) { - return this; - } - return new BinaryLinearIntegerExpression(this, SHIFTUR, new IntegerConstant(i)); - } - public IntegerExpression _shiftUR(long i) { if(i == 0) { return this; } - return new BinaryLinearIntegerExpression(this, SHIFTUR, new IntegerConstant((int)i)); + return new BinaryLinearIntegerExpression(this, SHIFTUR, new IntegerConstant(i)); } public IntegerExpression _shiftUR(IntegerExpression e) { @@ -339,18 +259,11 @@ public IntegerExpression _shiftUR(IntegerExpression e) { return new BinaryNonLinearIntegerExpression(this, SHIFTUR, e); } - public IntegerExpression _shiftL(int i) { - if(i == 0) { - return this; - } - return new BinaryLinearIntegerExpression(this, SHIFTL, new IntegerConstant(i)); - } - public IntegerExpression _shiftL(long i) { if(i == 0) { return this; } - return new BinaryLinearIntegerExpression(this, SHIFTL, new IntegerConstant((int)i)); + return new BinaryLinearIntegerExpression(this, SHIFTL, new IntegerConstant(i)); } public IntegerExpression _shiftL(IntegerExpression e) { diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/MathRealExpression.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/MathRealExpression.java index e9b0f5f..0b07f0c 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/MathRealExpression.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/MathRealExpression.java @@ -46,10 +46,9 @@ public class MathRealExpression extends RealExpression public MathFunction op; //int exp; // for power - public MathRealExpression (final MathFunction o, final RealExpression a) + public MathRealExpression (MathFunction o, RealExpression a) { - assert - o == MathFunction.ABS || //Added for dReal by Nima + assert o == MathFunction.SIN || o == MathFunction.COS || o == MathFunction.EXP || o == MathFunction.ASIN || o == MathFunction.ACOS || @@ -70,7 +69,7 @@ public MathRealExpression (final MathFunction o, final RealExpression a) // // } - public MathRealExpression (final MathFunction o, final RealExpression a1, final double a2) + public MathRealExpression (MathFunction o, RealExpression a1, double a2) { assert o == MathFunction.POW || o == MathFunction.ATAN2; @@ -80,7 +79,7 @@ public MathRealExpression (final MathFunction o, final RealExpression a1, final } - public MathRealExpression (final MathFunction o, final double a1, final RealExpression a2) + public MathRealExpression (MathFunction o, double a1, RealExpression a2) { assert o == MathFunction.POW || o == MathFunction.ATAN2; @@ -89,7 +88,7 @@ public MathRealExpression (final MathFunction o, final double a1, final RealExpr arg2 = a2; } - public MathRealExpression (final MathFunction o, final RealExpression a1, final RealExpression a2) + public MathRealExpression (MathFunction o, RealExpression a1, RealExpression a2) { assert o == MathFunction.POW || o == MathFunction.ATAN2; @@ -111,13 +110,11 @@ public MathFunction getOp() { return op; } - @Override - public double solution() + public double solution() { - final double a1 = (arg1==null?0:arg1.solution()); - final double a2 = (arg2==null?0:arg2.solution()); - switch(op){ - case ABS: return Math.abs(a1); // Added for dReal by Nima + double a1 = (arg1==null?0:arg1.solution()); + double a2 = (arg2==null?0:arg2.solution()); + switch(op){ case COS: return Math.cos(a1); case SIN: return Math.sin(a1); case EXP: return Math.exp(a1); @@ -134,16 +131,13 @@ public double solution() } } - @Override - public void getVarsVals(final Map varsVals) { + public void getVarsVals(Map varsVals) { if (arg1 != null) arg1.getVarsVals(varsVals); if (arg2 != null) arg2.getVarsVals(varsVals); } - @Override - public String stringPC() { - if (op == MathFunction.ABS || //Added for dReal by Nima - op == MathFunction.SIN || op == MathFunction.COS || + public String stringPC() { + if (op == MathFunction.SIN || op == MathFunction.COS || op == MathFunction.EXP || op == MathFunction.ASIN || op == MathFunction.ACOS || op == MathFunction.ATAN || op == MathFunction.LOG || @@ -153,10 +147,8 @@ public String stringPC() { return "(" + op.toString() + "(" + arg1.stringPC() + "," + arg2.stringPC() + "))"; } - @Override - public String toString () { - if (op == MathFunction.ABS || //Added for dReal by Nima - op == MathFunction.SIN || op == MathFunction.COS || + public String toString () { + if (op == MathFunction.SIN || op == MathFunction.COS || op == MathFunction.EXP || op == MathFunction.ASIN || op == MathFunction.ACOS || op == MathFunction.ATAN || op == MathFunction.LOG || @@ -167,7 +159,7 @@ public String toString () { } @Override - public void accept(final ConstraintExpressionVisitor visitor) { + public void accept(ConstraintExpressionVisitor visitor) { visitor.preVisit(this); if (arg1 != null) { arg1.accept(visitor); @@ -179,9 +171,9 @@ public void accept(final ConstraintExpressionVisitor visitor) { } @Override - public int compareTo(final Expression expr) { + public int compareTo(Expression expr) { if (expr instanceof MathRealExpression) { - final MathRealExpression e = (MathRealExpression) expr; + MathRealExpression e = (MathRealExpression) expr; int r = getOp().compareTo(e.getOp()); if (r == 0) { if (getArg1() != null) { diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/MinMax.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/MinMax.java index 3293949..3744aa0 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/MinMax.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/MinMax.java @@ -57,36 +57,77 @@ public class MinMax { public static void reset() { UniqueId = 0; } - + /** * Lower bound on symbolic integer variables. */ - private static int minInt = -1000000; + private static int minInt = Integer.MIN_VALUE; /** * Upper bound on symbolic integer variables. */ - private static int maxInt = 1000000; + private static int maxInt = Integer.MAX_VALUE; + + /** + * Lower bound on symbolic byte variables. + */ + private static byte minByte = Byte.MIN_VALUE; + + /** + * Upper bound on symbolic short variables. + */ + private static byte maxByte = Byte.MAX_VALUE; + + + /** + * Lower bound on symbolic short variables. + */ + private static short minShort = Short.MIN_VALUE; + + /** + * Upper bound on symbolic short variables. + */ + private static short maxShort = Short.MAX_VALUE; + + /** + * Lower bound on symbolic long variables. + */ + private static long minLong = Long.MIN_VALUE; + + /** + * Upper bound on symbolic long variables. + */ + private static long maxLong = Long.MAX_VALUE; + + /** + * Lower bound on symbolic integer variables. + */ + private static int minChar = Character.MIN_VALUE; + /** + * Upper bound on symbolic integer variables. + */ + private static int maxChar = Character.MAX_VALUE; + /** * Lower bound on symbolic real variables. */ - private static double minDouble = -8; + private static double minDouble = Double.MIN_VALUE; //-8; /** * Upper bound on symbolic real variables. */ - private static double maxDouble = 7; + private static double maxDouble = Double.MAX_VALUE; //7; /** * Mapping from variable names to minimum integer values. */ - private static Map varMinIntMap; + private static Map varMinIntMap; /** * Mapping from variable names to maximum integer values. */ - private static Map varMaxIntMap; + private static Map varMaxIntMap; /** * Mapping from variable names to minimum real values. @@ -134,6 +175,50 @@ public static void collectMinMaxInformation(Config config) { maxInt = x; } assert minInt < maxInt : "Illegal integer range"; + + long y = config.getLong("symbolic.min_long", Long.MAX_VALUE); + if (y != Long.MAX_VALUE) { + minLong = y; + } + + y = config.getLong("symbolic.max_long", Long.MIN_VALUE); + if (y != Long.MIN_VALUE) { + maxLong = y; + } + assert minLong < maxLong : "Illegal long range"; + + short s = (short) config.getInt("symbolic.min_short", Short.MAX_VALUE); + if (s != Short.MAX_VALUE) { + minShort = s; + } + + s = (short) config.getInt("symbolic.max_short", Short.MIN_VALUE); + if (s != Short.MIN_VALUE) { + maxShort = s; + } + assert minShort < maxShort : "Illegal short range"; + + byte b = (byte) config.getInt("symbolic.min_byte", Byte.MAX_VALUE); + if (b != Byte.MAX_VALUE) { + minByte = b; + } + + b = (byte) config.getInt("symbolic.max_byte", Byte.MIN_VALUE); + if (b != Byte.MIN_VALUE) { + maxByte = b; + } + assert minByte < maxByte : "Illegal byte range"; + + char c = (char) config.getInt("symbolic.min_char", Character.MAX_VALUE); + if (c != Character.MAX_VALUE) { + minChar = c; + } + + c = (char) config.getInt("symbolic.max_char", Character.MIN_VALUE); + if (c != Character.MIN_VALUE) { + maxChar = c; + } + assert minChar < maxChar : "Illegal char range"; double z = config.getDouble("symbolic.min_double", Double.MAX_VALUE); if (z != Double.MAX_VALUE) { @@ -147,34 +232,34 @@ public static void collectMinMaxInformation(Config config) { assert minDouble < maxDouble : "Illegal double range"; // Collect specific integer bounds by variable name - varMinIntMap = new HashMap(); - varMaxIntMap = new HashMap(); + varMinIntMap = new HashMap(); + varMaxIntMap = new HashMap(); int prefixLength = "symbolic.min_int_".length(); for (String k : config.getKeysStartingWith("symbolic.min_int_")) { String name = k.substring(prefixLength); - x = config.getInt(k, Integer.MAX_VALUE); - if (x != Integer.MAX_VALUE) { - varMinIntMap.put(name, x); + y = config.getLong(k, Long.MAX_VALUE); + if (y != Long.MAX_VALUE) { + varMinIntMap.put(name, y); } } for (String k : config.getKeysStartingWith("symbolic.max_int_")) { String name = k.substring(prefixLength); - x = config.getInt(k, Integer.MIN_VALUE); - if (x != Integer.MIN_VALUE) { - varMaxIntMap.put(name, x); + y = config.getLong(k, Long.MIN_VALUE); + if (y != Long.MIN_VALUE) { + varMaxIntMap.put(name, y); } } for (String k : varMinIntMap.keySet()) { - int min = varMinIntMap.get(k); - int max = maxInt; + long min = varMinIntMap.get(k); + long max = maxInt; if (varMaxIntMap.containsKey(k)) { max = varMaxIntMap.get(k); } assert min < max : "Illegal range for \"" + k + "\""; } for (String k : varMaxIntMap.keySet()) { - int min = minInt; - int max = varMaxIntMap.get(k); + long min = minInt; + long max = varMaxIntMap.get(k); if (varMinIntMap.containsKey(k)) { min = varMinIntMap.get(k); } @@ -218,11 +303,19 @@ public static void collectMinMaxInformation(Config config) { // Display the bounds collected from the configuration System.out.println("symbolic.min_int=" + minInt); + System.out.println("symbolic.min_long=" + minLong); + System.out.println("symbolic.min_short=" + minShort); + System.out.println("symbolic.min_byte=" + minByte); + System.out.println("symbolic.min_char=" + minChar); for (String k : varMinIntMap.keySet()) { System.out.println("symbolic.min_int_" + k + "=" + varMinIntMap.get(k)); } System.out.println("symbolic.max_int=" + maxInt); + System.out.println("symbolic.max_long=" + maxLong); + System.out.println("symbolic.max_short=" + maxShort); + System.out.println("symbolic.max_byte=" + maxByte); + System.out.println("symbolic.max_char=" + maxChar); for (String k : varMaxIntMap.keySet()) { System.out.println("symbolic.max_int_" + k + "=" + varMaxIntMap.get(k)); @@ -239,30 +332,118 @@ public static void collectMinMaxInformation(Config config) { } } + private static long getVarMin(String varname, long min) { + if (varname.endsWith("_SYMINT")) { + varname = varname.replaceAll("_[0-9][0-9]*_SYMINT", ""); + } + return varMinIntMap!=null && varMinIntMap.containsKey(varname) ? varMinIntMap.get(varname) : min; + } + /** * Return the minimum integer value that a given variable can assume. * * @param varname the name of the variable * @return the minimum value of the variable */ - public static int getVarMinInt(String varname) { + public static long getVarMinInt(String varname) { + return getVarMin(varname,minInt); + } + + /** + * Return the minimum long value that a given variable can assume. + * + * @param varname the name of the variable + * @return the minimum value of the variable + */ + public static long getVarMinLong(String varname) { + return getVarMin(varname,minLong); + } + + /** + * Return the minimum short value that a given variable can assume. + * + * @param varname the name of the variable + * @return the minimum value of the variable + */ + public static long getVarMinShort(String varname) { + return getVarMin(varname,minShort); + } + + /** + * Return the minimum byte value that a given variable can assume. + * + * @param varname the name of the variable + * @return the minimum value of the variable + */ + public static long getVarMinByte(String varname) { + return getVarMin(varname,minByte); + } + + /** + * Return the minimum char value that a given variable can assume. + * + * @param varname the name of the variable + * @return the minimum value of the variable + */ + public static long getVarMinChar(String varname) { + return getVarMin(varname,minChar); + } + + private static long getVarMax(String varname, long max) { if (varname.endsWith("_SYMINT")) { varname = varname.replaceAll("_[0-9][0-9]*_SYMINT", ""); } - return varMinIntMap!=null && varMinIntMap.containsKey(varname) ? varMinIntMap.get(varname) : minInt; + return varMaxIntMap!=null && varMaxIntMap.containsKey(varname) ? varMaxIntMap.get(varname) : max; } - + /** * Return the maximum integer value that a given variable can assume. * * @param varname the name of the variable * @return the maximum value of the variable */ - public static int getVarMaxInt(String varname) { - if (varname.endsWith("_SYMINT")) { - varname = varname.replaceAll("_[0-9][0-9]*_SYMINT", ""); - } - return varMaxIntMap!=null && varMaxIntMap.containsKey(varname) ? varMaxIntMap.get(varname) : maxInt; + public static long getVarMaxInt(String varname) { + return getVarMax(varname,maxInt); + } + + /** + * Return the maximum long value that a given variable can assume. + * + * @param varname the name of the variable + * @return the maximum value of the variable + */ + public static long getVarMaxLong(String varname) { + return getVarMax(varname,maxLong); + } + + /** + * Return the maximum short value that a given variable can assume. + * + * @param varname the name of the variable + * @return the maximum value of the variable + */ + public static long getVarMaxShort(String varname) { + return getVarMax(varname,maxShort); + } + + /** + * Return the maximum byte value that a given variable can assume. + * + * @param varname the name of the variable + * @return the maximum value of the variable + */ + public static long getVarMaxByte(String varname) { + return getVarMax(varname,maxByte); + } + + /** + * Return the maximum char value that a given variable can assume. + * + * @param varname the name of the variable + * @return the maximum value of the variable + */ + public static long getVarMaxChar(String varname) { + return getVarMax(varname,maxChar); } /** diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/Operator.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/Operator.java index be250e6..10e90f9 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/Operator.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/Operator.java @@ -49,7 +49,8 @@ public enum Operator{ XOR(" ^ "), SHIFTL("<<"), SHIFTR(">>"), - SHIFTUR(">>>"); + SHIFTUR(">>>"), + REM(" % "); @@ -62,5 +63,10 @@ public enum Operator{ @Override public String toString() { return str; + } + + public String prefix_notation() { + // TODO Auto-generated method stub + return str; } } \ No newline at end of file diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/PCParser.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/PCParser.java index bd0be8c..82af05c 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/PCParser.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/PCParser.java @@ -37,890 +37,918 @@ package gov.nasa.jpf.symbc.numeric; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - +import gov.nasa.jpf.symbc.SymbolicInstructionFactory; import gov.nasa.jpf.symbc.arrays.ArrayConstraint; import gov.nasa.jpf.symbc.arrays.ArrayExpression; -import gov.nasa.jpf.symbc.arrays.IntegerSymbolicArray; -import gov.nasa.jpf.symbc.arrays.RealSymbolicArray; import gov.nasa.jpf.symbc.arrays.RealArrayConstraint; import gov.nasa.jpf.symbc.arrays.RealStoreExpression; import gov.nasa.jpf.symbc.arrays.SelectExpression; import gov.nasa.jpf.symbc.arrays.StoreExpression; +import gov.nasa.jpf.symbc.numeric.solvers.IncrementalListener; +import gov.nasa.jpf.symbc.numeric.solvers.IncrementalSolver; import gov.nasa.jpf.symbc.numeric.solvers.ProblemCoral; import gov.nasa.jpf.symbc.numeric.solvers.ProblemGeneral; + + + + + import gov.nasa.jpf.symbc.numeric.solvers.ProblemZ3; +import gov.nasa.jpf.symbc.numeric.solvers.ProblemZ3BitVector; +import gov.nasa.jpf.symbc.numeric.solvers.ProblemZ3BitVectorIncremental; +import gov.nasa.jpf.symbc.numeric.solvers.ProblemZ3Incremental; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; // parses PCs public class PCParser { - static ProblemGeneral pb; - static public Map symRealVar; // a map between symbolic real variables and DP variables - static Map symIntegerVar; // a map between symbolic variables and DP variables - //static Boolean result; // tells whether result is satisfiable or not - static int tempVars = 0; //Used to construct "or" clauses - - // Converts IntegerExpression's into DP's IntExp's - static Object getExpression(final IntegerExpression eRef) { - assert eRef != null; - assert !(eRef instanceof IntegerConstant); - - if (eRef instanceof SymbolicInteger) { - - Object dp_var = symIntegerVar.get(eRef); - if (dp_var == null) { - dp_var = pb.makeIntVar(((SymbolicInteger)eRef).getName(), - ((SymbolicInteger)eRef)._min, ((SymbolicInteger)eRef)._max); - symIntegerVar.put((SymbolicInteger)eRef, dp_var); - } - return dp_var; - } - - Operator opRef; - IntegerExpression e_leftRef; - IntegerExpression e_rightRef; - - if(eRef instanceof BinaryLinearIntegerExpression) { - opRef = ((BinaryLinearIntegerExpression)eRef).op; - e_leftRef = ((BinaryLinearIntegerExpression)eRef).left; - e_rightRef = ((BinaryLinearIntegerExpression)eRef).right; - } else { // bin non lin expr - if(pb instanceof ProblemCoral) { - opRef = ((BinaryNonLinearIntegerExpression)eRef).op; - e_leftRef = ((BinaryNonLinearIntegerExpression)eRef).left; - e_rightRef = ((BinaryNonLinearIntegerExpression)eRef).right; - } - else - throw new RuntimeException("## Error: Binary Non Linear Expression " + eRef); - } - switch(opRef){ - case PLUS: - if (e_leftRef instanceof IntegerConstant && e_rightRef instanceof IntegerConstant) - throw new RuntimeException("## Error: this is not a symbolic expression"); // - else if (e_leftRef instanceof IntegerConstant) - return pb.plus(((IntegerConstant)e_leftRef).value,getExpression(e_rightRef)); - else if (e_rightRef instanceof IntegerConstant) - return pb.plus(getExpression(e_leftRef),((IntegerConstant)e_rightRef).value); - else - return pb.plus(getExpression(e_leftRef),getExpression(e_rightRef)); - case MINUS: - if (e_leftRef instanceof IntegerConstant && e_rightRef instanceof IntegerConstant) - throw new RuntimeException("## Error: this is not a symbolic expression"); // - else if (e_leftRef instanceof IntegerConstant) - return pb.minus(((IntegerConstant)e_leftRef).value,getExpression(e_rightRef)); - else if (e_rightRef instanceof IntegerConstant) - return pb.minus(getExpression(e_leftRef),((IntegerConstant)e_rightRef).value); - else - return pb.minus(getExpression(e_leftRef),getExpression(e_rightRef)); - case MUL: - if (e_leftRef instanceof IntegerConstant && e_rightRef instanceof IntegerConstant) - throw new RuntimeException("## Error: this is not a symbolic expression"); // - else if (e_leftRef instanceof IntegerConstant) - return pb.mult(((IntegerConstant)e_leftRef).value,getExpression(e_rightRef)); - else if (e_rightRef instanceof IntegerConstant) - return pb.mult(((IntegerConstant)e_rightRef).value,getExpression(e_leftRef)); - else { - if(pb instanceof ProblemCoral) - return pb.mult(getExpression(e_leftRef),getExpression(e_rightRef)); - else - throw new RuntimeException("## Error: Binary Non Linear Operation"); - } - case DIV: - if (e_leftRef instanceof IntegerConstant && e_rightRef instanceof IntegerConstant) - throw new RuntimeException("## Error: this is not a symbolic expression"); // - else if (e_leftRef instanceof IntegerConstant) // TODO: this might not be linear - return pb.div(((IntegerConstant)e_leftRef).value,getExpression(e_rightRef)); - else if (e_rightRef instanceof IntegerConstant) - return pb.div(getExpression(e_leftRef),((IntegerConstant)e_rightRef).value); - else { - if(pb instanceof ProblemCoral) - return pb.div(getExpression(e_leftRef),getExpression(e_rightRef)); - else - throw new RuntimeException("## Error: Binary Non Linear Operation"); - } - case AND: - if(e_leftRef instanceof IntegerConstant && e_rightRef instanceof IntegerConstant) - throw new RuntimeException("## Error: this is not a symbolic expression"); // - else if (e_leftRef instanceof IntegerConstant) - return pb.and(((IntegerConstant)e_leftRef).value,getExpression(e_rightRef)); - else if (e_rightRef instanceof IntegerConstant) - return pb.and(((IntegerConstant)e_rightRef).value,getExpression(e_leftRef)); - else - return pb.and(getExpression(e_leftRef),getExpression(e_rightRef)); - case OR: - if(e_leftRef instanceof IntegerConstant && e_rightRef instanceof IntegerConstant) - throw new RuntimeException("## Error: this is not a symbolic expression"); // - else if (e_leftRef instanceof IntegerConstant) - return pb.or(((IntegerConstant)e_leftRef).value,getExpression(e_rightRef)); - else if (e_rightRef instanceof IntegerConstant) - return pb.or(((IntegerConstant)e_rightRef).value,getExpression(e_leftRef)); - else - return pb.or(getExpression(e_leftRef),getExpression(e_rightRef)); - case XOR: - if(e_leftRef instanceof IntegerConstant && e_rightRef instanceof IntegerConstant) - throw new RuntimeException("## Error: this is not a symbolic expression"); // - else if (e_leftRef instanceof IntegerConstant) - return pb.xor(((IntegerConstant)e_leftRef).value,getExpression(e_rightRef)); - else if (e_rightRef instanceof IntegerConstant) - return pb.xor(((IntegerConstant)e_rightRef).value,getExpression(e_leftRef)); - else - return pb.xor(getExpression(e_leftRef),getExpression(e_rightRef)); - case SHIFTR: - if(e_leftRef instanceof IntegerConstant && e_rightRef instanceof IntegerConstant) - throw new RuntimeException("## Error: this is not a symbolic expression"); // - else if (e_leftRef instanceof IntegerConstant) - return pb.shiftR(((IntegerConstant)e_leftRef).value,getExpression(e_rightRef)); - else if (e_rightRef instanceof IntegerConstant) - return pb.shiftR(getExpression(e_leftRef),((IntegerConstant)e_rightRef).value); - else - return pb.shiftR(getExpression(e_leftRef),getExpression(e_rightRef)); - case SHIFTUR: - if(e_leftRef instanceof IntegerConstant && e_rightRef instanceof IntegerConstant) - throw new RuntimeException("## Error: this is not a symbolic expression"); // - else if (e_leftRef instanceof IntegerConstant) - return pb.shiftUR(((IntegerConstant)e_leftRef).value,getExpression(e_rightRef)); - else if (e_rightRef instanceof IntegerConstant) - return pb.shiftUR(getExpression(e_leftRef),((IntegerConstant)e_rightRef).value); - else - return pb.shiftUR(getExpression(e_leftRef),getExpression(e_rightRef)); - case SHIFTL: - if(e_leftRef instanceof IntegerConstant && e_rightRef instanceof IntegerConstant) - throw new RuntimeException("## Error: this is not a symbolic expression"); // - else if (e_leftRef instanceof IntegerConstant) - return pb.shiftL(((IntegerConstant)e_leftRef).value,getExpression(e_rightRef)); - else if (e_rightRef instanceof IntegerConstant) - return pb.shiftL(getExpression(e_leftRef),((IntegerConstant)e_rightRef).value); - else - return pb.shiftL(getExpression(e_leftRef),getExpression(e_rightRef)); - default: - throw new RuntimeException("## Error: Binary Non Linear Operation"); - } - - - } - - - // Converts RealExpression's into DP RealExp's - static Object getExpression(final RealExpression eRef) { - assert eRef != null; - assert !(eRef instanceof RealConstant); - - if (eRef instanceof SymbolicReal) { - Object dp_var = symRealVar.get(eRef); - if (dp_var == null) { - dp_var = pb.makeRealVar(((SymbolicReal)eRef).getName(), - ((SymbolicReal)eRef)._min, ((SymbolicReal)eRef)._max); - symRealVar.put((SymbolicReal)eRef, dp_var); - } - return dp_var; - } - - if(eRef instanceof BinaryRealExpression) { - Operator opRef; - RealExpression e_leftRef; - RealExpression e_rightRef; - opRef = ((BinaryRealExpression)eRef).op; - e_leftRef = ((BinaryRealExpression)eRef).left; - e_rightRef = ((BinaryRealExpression)eRef).right; - - switch(opRef){ - case PLUS: - if (e_leftRef instanceof RealConstant && e_rightRef instanceof RealConstant) - return pb.constant(((RealConstant)e_leftRef).value + ((RealConstant)e_rightRef).value); - //throw new RuntimeException("## Error: this is not a symbolic expression"); // - else if (e_leftRef instanceof RealConstant) - return pb.plus(((RealConstant)e_leftRef).value, getExpression(e_rightRef)); - else if (e_rightRef instanceof RealConstant) - return pb.plus(getExpression(e_leftRef),((RealConstant)e_rightRef).value); - else - return pb.plus(getExpression(e_leftRef),getExpression(e_rightRef)); - case MINUS: - if (e_leftRef instanceof RealConstant && e_rightRef instanceof RealConstant) - throw new RuntimeException("## Error: this is not a symbolic expression"); // - else if (e_leftRef instanceof RealConstant) - return pb.minus(((RealConstant)e_leftRef).value,getExpression(e_rightRef)); - else if (e_rightRef instanceof RealConstant) - return pb.minus(getExpression(e_leftRef),((RealConstant)e_rightRef).value); - else - return pb.minus(getExpression(e_leftRef),getExpression(e_rightRef)); - case MUL: - if (e_leftRef instanceof RealConstant && e_rightRef instanceof RealConstant) - throw new RuntimeException("## Error: this is not a symbolic expression"); // - else if (e_leftRef instanceof RealConstant) - return pb.mult(((RealConstant)e_leftRef).value,getExpression(e_rightRef)); - else if (e_rightRef instanceof RealConstant) - return pb.mult(((RealConstant)e_rightRef).value,getExpression(e_leftRef)); - else - return pb.mult(getExpression(e_leftRef),getExpression(e_rightRef)); - case DIV: - if (e_leftRef instanceof RealConstant && e_rightRef instanceof RealConstant) - throw new RuntimeException("## Error: this is not a symbolic expression"); // - else if (e_leftRef instanceof RealConstant) - return pb.div(((RealConstant)e_leftRef).value,getExpression(e_rightRef)); - else if (e_rightRef instanceof RealConstant) - return pb.div(getExpression(e_leftRef),((RealConstant)e_rightRef).value); - else - return pb.div(getExpression(e_leftRef),getExpression(e_rightRef)); - case AND: - if (e_leftRef instanceof RealConstant && e_rightRef instanceof RealConstant) - throw new RuntimeException("## Error: this is not a symbolic expression"); // - else if (e_leftRef instanceof RealConstant) - return pb.and(((RealConstant)e_leftRef).value,getExpression(e_rightRef)); - else if (e_rightRef instanceof RealConstant) - return pb.and(((RealConstant)e_rightRef).value,getExpression(e_leftRef)); - else - return pb.and(getExpression(e_leftRef),getExpression(e_rightRef)); - - default: - throw new RuntimeException("## Error: Expression " + eRef); - } - } - - if(eRef instanceof MathRealExpression) { - MathFunction funRef; - RealExpression e_arg1Ref; - RealExpression e_arg2Ref; - - funRef = ((MathRealExpression)eRef).op; - e_arg1Ref = ((MathRealExpression)eRef).arg1; - e_arg2Ref = ((MathRealExpression)eRef).arg2; - switch(funRef){ - case ABS: return pb.abs(getExpression(e_arg1Ref)); //Added for dReal by Nima - case SIN: return pb.sin(getExpression(e_arg1Ref)); - case COS: return pb.cos(getExpression(e_arg1Ref)); - case EXP: return pb.exp(getExpression(e_arg1Ref)); - case ASIN: return pb.asin(getExpression(e_arg1Ref)); - case ACOS:return pb.acos(getExpression(e_arg1Ref)); - case ATAN: return pb.atan(getExpression(e_arg1Ref)); - case LOG:return pb.log(getExpression(e_arg1Ref)); - case TAN:return pb.tan(getExpression(e_arg1Ref)); - case SQRT:return pb.sqrt(getExpression(e_arg1Ref)); - case POW: - if (e_arg2Ref instanceof RealConstant) - return pb.power(getExpression(e_arg1Ref),((RealConstant)e_arg2Ref).value); - else if (e_arg1Ref instanceof RealConstant) - return pb.power(((RealConstant)e_arg1Ref).value,getExpression(e_arg2Ref)); - else - return pb.power(getExpression(e_arg1Ref),getExpression(e_arg2Ref)); - case ATAN2: - if (e_arg2Ref instanceof RealConstant) - return pb.atan2(getExpression(e_arg1Ref),((RealConstant)e_arg2Ref).value); - else if (e_arg1Ref instanceof RealConstant) - return pb.atan2(((RealConstant)e_arg1Ref).value,getExpression(e_arg2Ref)); - else - return pb.atan2(getExpression(e_arg1Ref),getExpression(e_arg2Ref)); - default: - throw new RuntimeException("## Error: Expression " + eRef); - } - } - - throw new RuntimeException("## Error: Expression " + eRef); - } - - //public Map getSymRealVar() { - //return symRealVar; - //} - - - //public Map getSymIntegerVar() { - //return symIntegerVar; - //} - - - static public boolean createDPMixedConstraint(final MixedConstraint cRef) { // TODO - - final Comparator c_compRef = cRef.getComparator(); - final RealExpression c_leftRef = (RealExpression)cRef.getLeft(); - final IntegerExpression c_rightRef = (IntegerExpression)cRef.getRight(); - assert (c_compRef == Comparator.EQ); - - if (c_leftRef instanceof SymbolicReal && c_rightRef instanceof SymbolicInteger) { - //pb.post(new MixedEqXY((RealVar)(getExpression(c_leftRef)),(IntDomainVar)(getExpression(c_rightRef)))); - pb.post(pb.mixed(getExpression(c_leftRef),getExpression(c_rightRef))); - } - else if (c_leftRef instanceof SymbolicReal) { // c_rightRef is an IntegerExpression - final Object tmpi = pb.makeIntVar(c_rightRef + "_" + c_rightRef.hashCode(),(int)(((SymbolicReal)c_leftRef)._min), (int)(((SymbolicReal)c_leftRef)._max)); - if (c_rightRef instanceof IntegerConstant) - pb.post(pb.eq(((IntegerConstant)c_rightRef).value,tmpi)); - else - pb.post(pb.eq(getExpression(c_rightRef),tmpi)); - //pb.post(new MixedEqXY((RealVar)(getExpression(c_leftRef)),tmpi)); - pb.post(pb.mixed(getExpression(c_leftRef),tmpi)); - - } - else if (c_rightRef instanceof SymbolicInteger) { // c_leftRef is a RealExpression - final Object tmpr = pb.makeRealVar(c_leftRef + "_" + c_leftRef.hashCode(), ((SymbolicInteger)c_rightRef)._min, ((SymbolicInteger)c_rightRef)._max); - if(c_leftRef instanceof RealConstant) - pb.post(pb.eq(tmpr, ((RealConstant)c_leftRef).value)); - else - pb.post(pb.eq(tmpr, getExpression(c_leftRef))); - //pb.post(new MixedEqXY(tmpr,(IntDomainVar)(getExpression(c_rightRef)))); - pb.post(pb.mixed(tmpr,getExpression(c_rightRef))); - } - else - assert(false); // should not be reachable - - return true; - } - - static public boolean createDPRealConstraint(final RealConstraint cRef) { - - final Comparator c_compRef = cRef.getComparator(); - final RealExpression c_leftRef = (RealExpression)cRef.getLeft(); - final RealExpression c_rightRef = (RealExpression)cRef.getRight(); - - switch(c_compRef){ - case EQ: - if (c_leftRef instanceof RealConstant && c_rightRef instanceof RealConstant) { - if (!(((RealConstant) c_leftRef).value == ((RealConstant) c_rightRef).value)) - return false; - else - return true; - } - else if (c_leftRef instanceof RealConstant) { - pb.post(pb.eq(((RealConstant)c_leftRef).value,getExpression(c_rightRef))); - } - else if (c_rightRef instanceof RealConstant) { - pb.post(pb.eq(getExpression(c_leftRef),((RealConstant)c_rightRef).value)); - } - else - pb.post(pb.eq(getExpression(c_leftRef),getExpression(c_rightRef))); - break; - case NE: - if (c_leftRef instanceof RealConstant && c_rightRef instanceof RealConstant) { - if (!(((RealConstant) c_leftRef).value != ((RealConstant) c_rightRef).value)) - return false; - else - return true; - } - else if (c_leftRef instanceof RealConstant) { - pb.post(pb.neq(((RealConstant)c_leftRef).value,getExpression(c_rightRef))); - } - else if (c_rightRef instanceof RealConstant) { - pb.post(pb.neq(getExpression(c_leftRef),((RealConstant)c_rightRef).value)); - } - else - pb.post(pb.neq(getExpression(c_leftRef),getExpression(c_rightRef))); - break; - case LT: - if (c_leftRef instanceof RealConstant && c_rightRef instanceof RealConstant) { - if (!(((RealConstant) c_leftRef).value < ((RealConstant) c_rightRef).value)) - return false; - else - return true; - } - else if (c_leftRef instanceof RealConstant) { - pb.post(pb.lt(((RealConstant)c_leftRef).value,getExpression(c_rightRef))); - } - else if (c_rightRef instanceof RealConstant) { - pb.post(pb.lt(getExpression(c_leftRef),((RealConstant)c_rightRef).value)); - } - else - pb.post(pb.lt(getExpression(c_leftRef),getExpression(c_rightRef))); - break; - case GE: - if (c_leftRef instanceof RealConstant && c_rightRef instanceof RealConstant) { - if (!(((RealConstant) c_leftRef).value >= ((RealConstant) c_rightRef).value)) - return false; - else - return true; - } - else if (c_leftRef instanceof RealConstant) { - pb.post(pb.geq(((RealConstant)c_leftRef).value,getExpression(c_rightRef))); - } - else if (c_rightRef instanceof RealConstant) { - pb.post(pb.geq(getExpression(c_leftRef),((RealConstant)c_rightRef).value)); - } - else - pb.post(pb.geq(getExpression(c_leftRef),getExpression(c_rightRef))); - break; - case LE: - if (c_leftRef instanceof RealConstant && c_rightRef instanceof RealConstant) { - if (!(((RealConstant) c_leftRef).value <= ((RealConstant) c_rightRef).value)) - return false; - else - return true; - } - else if (c_leftRef instanceof RealConstant) { - pb.post(pb.leq(((RealConstant)c_leftRef).value,getExpression(c_rightRef))); - } - else if (c_rightRef instanceof RealConstant) { - pb.post(pb.leq(getExpression(c_leftRef),((RealConstant)c_rightRef).value)); - } - else - pb.post(pb.leq(getExpression(c_leftRef),getExpression(c_rightRef))); - break; - case GT: - if (c_leftRef instanceof RealConstant && c_rightRef instanceof RealConstant) { - if (!(((RealConstant) c_leftRef).value > ((RealConstant) c_rightRef).value)) - return false; - else - return true; - } - else if (c_leftRef instanceof RealConstant) { - pb.post(pb.gt(((RealConstant)c_leftRef).value,getExpression(c_rightRef))); - } - else if (c_rightRef instanceof RealConstant) { - pb.post(pb.gt(getExpression(c_leftRef),((RealConstant)c_rightRef).value)); - } - else - pb.post(pb.gt(getExpression(c_leftRef),getExpression(c_rightRef))); - break; - } - return true; - } - - //Added by Gideon, to handle CNF style constraints??? - static public boolean createDPLinearOrIntegerConstraint (final LogicalORLinearIntegerConstraints c) { - final List orList = new ArrayList(); - - for (final LinearIntegerConstraint cRef: c.getList()) { - final Comparator c_compRef = cRef.getComparator(); - final IntegerExpression c_leftRef = (IntegerExpression)cRef.getLeft(); - final IntegerExpression c_rightRef = (IntegerExpression)cRef.getRight(); - //Removed all return false: why? - switch(c_compRef){ - case EQ: - if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { - if (((IntegerConstant) c_leftRef).value == ((IntegerConstant) c_rightRef).value) - return true; - } - else if (c_leftRef instanceof IntegerConstant) { - final Object part1 = getExpression(c_rightRef); - final Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; - pb.post(pb.eq(tempVar, part1)); - final Object cc = pb.eq(((IntegerConstant)c_leftRef).value, tempVar); - orList.add(cc); - } - else if (c_rightRef instanceof IntegerConstant) { - final Object part1 = getExpression(c_leftRef); - final Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); - pb.post(pb.eq(tempVar, part1)); tempVars++; - orList.add(pb.eq(tempVar,((IntegerConstant)c_rightRef).value)); - } - else { - final Object part1 = getExpression(c_leftRef); - final Object part2 = getExpression(c_rightRef); - final Object tempVar1 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; - final Object tempVar2 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; - pb.post(pb.eq(tempVar1, part1)); - pb.post(pb.eq(tempVar2, part2)); - orList.add(pb.eq(tempVar1,tempVar2)); - } - break; - case NE: - if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { - if (((IntegerConstant) c_leftRef).value != ((IntegerConstant) c_rightRef).value) - return true; - } - else if (c_leftRef instanceof IntegerConstant) { - final Object part1 = getExpression(c_rightRef); - final Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; - pb.post(pb.eq(tempVar, part1)); - final Object cc = pb.neq(((IntegerConstant)c_leftRef).value, tempVar); - orList.add(cc); - } - else if (c_rightRef instanceof IntegerConstant) { - final Object part1 = getExpression(c_leftRef); - final Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); - pb.post(pb.eq(tempVar, part1)); tempVars++; - orList.add(pb.neq(tempVar,((IntegerConstant)c_rightRef).value)); - } - else { - final Object part1 = getExpression(c_leftRef); - final Object part2 = getExpression(c_rightRef); - final Object tempVar1 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; - final Object tempVar2 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; - pb.post(pb.eq(tempVar1, part1)); - pb.post(pb.eq(tempVar2, part2)); - orList.add(pb.neq(tempVar1,tempVar2)); - } - break; - case LT: - if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { - if (((IntegerConstant) c_leftRef).value < ((IntegerConstant) c_rightRef).value) - return true; - } - else if (c_leftRef instanceof IntegerConstant) { - final Object part1 = getExpression(c_rightRef); - final Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; - pb.post(pb.eq(tempVar, part1)); - final Object cc = pb.lt(((IntegerConstant)c_leftRef).value, tempVar); - orList.add(cc); - } - else if (c_rightRef instanceof IntegerConstant) { - final Object part1 = getExpression(c_leftRef); - final Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); - pb.post(pb.eq(tempVar, part1)); tempVars++; - orList.add(pb.lt(tempVar,((IntegerConstant)c_rightRef).value)); - } - else { - final Object part1 = getExpression(c_leftRef); - final Object part2 = getExpression(c_rightRef); - final Object tempVar1 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; - final Object tempVar2 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; - pb.post(pb.eq(tempVar1, part1)); - pb.post(pb.eq(tempVar2, part2)); - orList.add(pb.lt(tempVar1,tempVar2)); - } - break; - case GE: - if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { - if (((IntegerConstant) c_leftRef).value >= ((IntegerConstant) c_rightRef).value) - return true; - } - else if (c_leftRef instanceof IntegerConstant) { - final Object part1 = getExpression(c_rightRef); - final Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; - pb.post(pb.eq(tempVar, part1)); - final Object cc = pb.geq(((IntegerConstant)c_leftRef).value, tempVar); - orList.add(cc); - } - else if (c_rightRef instanceof IntegerConstant) { - final Object part1 = getExpression(c_leftRef); - final Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); - pb.post(pb.eq(tempVar, part1)); tempVars++; - orList.add(pb.geq(tempVar,((IntegerConstant)c_rightRef).value)); - } - else { - final Object part1 = getExpression(c_leftRef); - final Object part2 = getExpression(c_rightRef); - final Object tempVar1 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; - final Object tempVar2 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; - pb.post(pb.eq(tempVar1, part1)); - pb.post(pb.eq(tempVar2, part2)); - orList.add(pb.geq(tempVar1,tempVar2)); - } - break; - case LE: - if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { - if (((IntegerConstant) c_leftRef).value <= ((IntegerConstant) c_rightRef).value) - return true; - } - else if (c_leftRef instanceof IntegerConstant) { - final Object part1 = getExpression(c_rightRef); - final Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; - pb.post(pb.eq(tempVar, part1)); - final Object cc = pb.leq(((IntegerConstant)c_leftRef).value, tempVar); - orList.add(cc); - } - else if (c_rightRef instanceof IntegerConstant) { - final Object part1 = getExpression(c_leftRef); - final Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); - pb.post(pb.eq(tempVar, part1)); tempVars++; - orList.add(pb.leq(tempVar,((IntegerConstant)c_rightRef).value)); - } - else { - final Object part1 = getExpression(c_leftRef); - final Object part2 = getExpression(c_rightRef); - final Object tempVar1 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; - final Object tempVar2 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; - pb.post(pb.eq(tempVar1, part1)); - pb.post(pb.eq(tempVar2, part2)); - orList.add(pb.leq(tempVar1,tempVar2)); - } - break; - case GT: - if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { - if (((IntegerConstant) c_leftRef).value > ((IntegerConstant) c_rightRef).value) - return true; - } - else if (c_leftRef instanceof IntegerConstant) { - final Object part1 = getExpression(c_rightRef); - final Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; - pb.post(pb.eq(tempVar, part1)); - final Object cc = pb.gt(((IntegerConstant)c_leftRef).value, tempVar); - orList.add(cc); - } - else if (c_rightRef instanceof IntegerConstant) { - final Object part1 = getExpression(c_leftRef); - final Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); - pb.post(pb.eq(tempVar, part1)); tempVars++; - orList.add(pb.gt(tempVar,((IntegerConstant)c_rightRef).value)); - } - else { - final Object part1 = getExpression(c_leftRef); - final Object part2 = getExpression(c_rightRef); - final Object tempVar1 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; - final Object tempVar2 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; - pb.post(pb.eq(tempVar1, part1)); - pb.post(pb.eq(tempVar2, part2)); - orList.add(pb.gt(tempVar1,tempVar2)); - } - break; - } - } - //System.out.println("[SymbolicConstraintsGeneral] orList: " + orList.toString()); - if (orList.size() == 0) return true; - final Object constraint_array[] = new Object[orList.size()]; - orList.toArray(constraint_array); - - pb.postLogicalOR(constraint_array); - - return true; - - } - - static public boolean createDPLinearIntegerConstraint(final LinearIntegerConstraint cRef) { - - final Comparator c_compRef = cRef.getComparator(); - - final IntegerExpression c_leftRef = (IntegerExpression)cRef.getLeft(); - final IntegerExpression c_rightRef = (IntegerExpression)cRef.getRight(); - - switch(c_compRef){ - case EQ: - if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { - if (!(((IntegerConstant) c_leftRef).value == ((IntegerConstant) c_rightRef).value)) - return false; - else - return true; - } - else if (c_leftRef instanceof IntegerConstant) { - pb.post(pb.eq(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); - } - else if (c_rightRef instanceof IntegerConstant) { - pb.post(pb.eq(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); - } - else - pb.post(pb.eq(getExpression(c_leftRef),getExpression(c_rightRef))); - break; - case NE: - if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { - if (!(((IntegerConstant) c_leftRef).value != ((IntegerConstant) c_rightRef).value)) - return false; - else - return true; - } - else if (c_leftRef instanceof IntegerConstant) { - pb.post(pb.neq(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); - } - else if (c_rightRef instanceof IntegerConstant) { - pb.post(pb.neq(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); - } - else - pb.post(pb.neq(getExpression(c_leftRef),getExpression(c_rightRef))); - break; - case LT: - if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { - if (!(((IntegerConstant) c_leftRef).value < ((IntegerConstant) c_rightRef).value)) - return false; - else - return true; - } - else if (c_leftRef instanceof IntegerConstant) { - pb.post(pb.lt(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); - } - else if (c_rightRef instanceof IntegerConstant) { - pb.post(pb.lt(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); - } - else - pb.post(pb.lt(getExpression(c_leftRef),getExpression(c_rightRef))); - break; - case GE: - if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { - if (!(((IntegerConstant) c_leftRef).value >= ((IntegerConstant) c_rightRef).value)) - return false; - else - return true; - } - else if (c_leftRef instanceof IntegerConstant) { - pb.post(pb.geq(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); - } - else if (c_rightRef instanceof IntegerConstant) { - pb.post(pb.geq(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); - } - else - pb.post(pb.geq(getExpression(c_leftRef),getExpression(c_rightRef))); - break; - case LE: - if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { - if (!(((IntegerConstant) c_leftRef).value <= ((IntegerConstant) c_rightRef).value)) - return false; - else - return true; - } - else if (c_leftRef instanceof IntegerConstant) { - pb.post(pb.leq(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); - } - else if (c_rightRef instanceof IntegerConstant) { - pb.post(pb.leq(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); - } - else - pb.post(pb.leq(getExpression(c_leftRef),getExpression(c_rightRef))); - break; - case GT: - if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { - if (!(((IntegerConstant) c_leftRef).value > ((IntegerConstant) c_rightRef).value)) - return false; - else - return true; - } - else if (c_leftRef instanceof IntegerConstant) { - pb.post(pb.gt(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); - } - else if (c_rightRef instanceof IntegerConstant) { - pb.post(pb.gt(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); - } - else - pb.post(pb.gt(getExpression(c_leftRef),getExpression(c_rightRef))); - break; - } - return true; - } - - static public boolean createDPNonLinearIntegerConstraint(final NonLinearIntegerConstraint cRef) { - - final Comparator c_compRef = cRef.getComparator(); - - final IntegerExpression c_leftRef = (IntegerExpression)cRef.getLeft(); - final IntegerExpression c_rightRef = (IntegerExpression)cRef.getRight(); - - switch(c_compRef){ - case EQ: - if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { - if (!(((IntegerConstant) c_leftRef).value == ((IntegerConstant) c_rightRef).value)) - return false; - else - return true; - } - else if (c_leftRef instanceof IntegerConstant) { - pb.post(pb.eq(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); - } - else if (c_rightRef instanceof IntegerConstant) { - pb.post(pb.eq(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); - } - else - pb.post(pb.eq(getExpression(c_leftRef),getExpression(c_rightRef))); - break; - case NE: - if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { - if (!(((IntegerConstant) c_leftRef).value != ((IntegerConstant) c_rightRef).value)) - return false; - else - return true; - } - else if (c_leftRef instanceof IntegerConstant) { - pb.post(pb.neq(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); - } - else if (c_rightRef instanceof IntegerConstant) { - pb.post(pb.neq(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); - } - else - pb.post(pb.neq(getExpression(c_leftRef),getExpression(c_rightRef))); - break; - case LT: - if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { - if (!(((IntegerConstant) c_leftRef).value < ((IntegerConstant) c_rightRef).value)) - return false; - else - return true; - } - else if (c_leftRef instanceof IntegerConstant) { - pb.post(pb.lt(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); - } - else if (c_rightRef instanceof IntegerConstant) { - pb.post(pb.lt(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); - } - else - pb.post(pb.lt(getExpression(c_leftRef),getExpression(c_rightRef))); - break; - case GE: - if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { - if (!(((IntegerConstant) c_leftRef).value >= ((IntegerConstant) c_rightRef).value)) - return false; - else - return true; - } - else if (c_leftRef instanceof IntegerConstant) { - pb.post(pb.geq(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); - } - else if (c_rightRef instanceof IntegerConstant) { - pb.post(pb.geq(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); - } - else - pb.post(pb.geq(getExpression(c_leftRef),getExpression(c_rightRef))); - break; - case LE: - if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { - if (!(((IntegerConstant) c_leftRef).value <= ((IntegerConstant) c_rightRef).value)) - return false; - else - return true; - } - else if (c_leftRef instanceof IntegerConstant) { - pb.post(pb.leq(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); - } - else if (c_rightRef instanceof IntegerConstant) { - pb.post(pb.leq(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); - } - else - pb.post(pb.leq(getExpression(c_leftRef),getExpression(c_rightRef))); - break; - case GT: - if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { - if (!(((IntegerConstant) c_leftRef).value > ((IntegerConstant) c_rightRef).value)) - return false; - else - return true; - } - else if (c_leftRef instanceof IntegerConstant) { - pb.post(pb.gt(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); - } - else if (c_rightRef instanceof IntegerConstant) { - pb.post(pb.gt(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); - } - else - pb.post(pb.gt(getExpression(c_leftRef),getExpression(c_rightRef))); - break; - } - return true; - } - //static Map dpMap = new HashMap(); - - public static boolean createDPArrayConstraint(final ArrayConstraint cRef) { - final Comparator c_compRef = cRef.getComparator(); + static ProblemGeneral pb; + static public Map symRealVar; // a map between symbolic real variables and DP variables + static Map symIntegerVar; // a map between symbolic variables and DP variables + //static Boolean result; // tells whether result is satisfiable or not + static int tempVars = 0; //Used to construct "or" clauses + // Converts IntegerExpression's into DP's IntExp's + static Object getExpression(IntegerExpression eRef) { + assert eRef != null; + assert !(eRef instanceof IntegerConstant); - SelectExpression selex = null; + if (eRef instanceof SymbolicInteger) { + Object dp_var = symIntegerVar.get(eRef); + if (dp_var == null) { + dp_var = pb.makeIntVar(((SymbolicInteger)eRef).getName(), + ((SymbolicInteger)eRef)._min, ((SymbolicInteger)eRef)._max); + symIntegerVar.put((SymbolicInteger)eRef, dp_var); + } + return dp_var; + } + + Operator opRef; + IntegerExpression e_leftRef; + IntegerExpression e_rightRef; + + if(eRef instanceof BinaryLinearIntegerExpression) { + opRef = ((BinaryLinearIntegerExpression)eRef).op; + e_leftRef = ((BinaryLinearIntegerExpression)eRef).left; + e_rightRef = ((BinaryLinearIntegerExpression)eRef).right; + } else { // bin non lin expr + if(pb instanceof ProblemCoral || pb instanceof ProblemZ3 || pb instanceof ProblemZ3BitVector || + pb instanceof ProblemZ3Incremental || pb instanceof ProblemZ3BitVectorIncremental) { + opRef = ((BinaryNonLinearIntegerExpression)eRef).op; + e_leftRef = ((BinaryNonLinearIntegerExpression)eRef).left; + e_rightRef = ((BinaryNonLinearIntegerExpression)eRef).right; + } + else + throw new RuntimeException("## Error: Binary Non Linear Expression " + eRef); + } + switch(opRef){ + case PLUS: + if (e_leftRef instanceof IntegerConstant && e_rightRef instanceof IntegerConstant) + throw new RuntimeException("## Error: this is not a symbolic expression"); // + else if (e_leftRef instanceof IntegerConstant) + return pb.plus(((IntegerConstant)e_leftRef).value,getExpression(e_rightRef)); + else if (e_rightRef instanceof IntegerConstant) + return pb.plus(getExpression(e_leftRef),((IntegerConstant)e_rightRef).value); + else + return pb.plus(getExpression(e_leftRef),getExpression(e_rightRef)); + case MINUS: + if (e_leftRef instanceof IntegerConstant && e_rightRef instanceof IntegerConstant) + throw new RuntimeException("## Error: this is not a symbolic expression"); // + else if (e_leftRef instanceof IntegerConstant) + return pb.minus(((IntegerConstant)e_leftRef).value,getExpression(e_rightRef)); + else if (e_rightRef instanceof IntegerConstant) + return pb.minus(getExpression(e_leftRef),((IntegerConstant)e_rightRef).value); + else + return pb.minus(getExpression(e_leftRef),getExpression(e_rightRef)); + case MUL: + if (e_leftRef instanceof IntegerConstant && e_rightRef instanceof IntegerConstant) + throw new RuntimeException("## Error: this is not a symbolic expression"); // + else if (e_leftRef instanceof IntegerConstant) + return pb.mult(((IntegerConstant)e_leftRef).value,getExpression(e_rightRef)); + else if (e_rightRef instanceof IntegerConstant) + return pb.mult(((IntegerConstant)e_rightRef).value,getExpression(e_leftRef)); + else { + if(pb instanceof ProblemCoral || pb instanceof ProblemZ3 || pb instanceof ProblemZ3BitVector || + pb instanceof ProblemZ3Incremental || pb instanceof ProblemZ3BitVectorIncremental) + return pb.mult(getExpression(e_leftRef),getExpression(e_rightRef)); + else + throw new RuntimeException("## Error: Binary Non Linear Operation"); + } + case DIV: + if (e_leftRef instanceof IntegerConstant && e_rightRef instanceof IntegerConstant) + throw new RuntimeException("## Error: this is not a symbolic expression"); // + else if (e_leftRef instanceof IntegerConstant) // TODO: this might not be linear + return pb.div(((IntegerConstant)e_leftRef).value,getExpression(e_rightRef)); + else if (e_rightRef instanceof IntegerConstant) + return pb.div(getExpression(e_leftRef),((IntegerConstant)e_rightRef).value); + else { + if(pb instanceof ProblemCoral || pb instanceof ProblemZ3 || pb instanceof ProblemZ3BitVector || + pb instanceof ProblemZ3Incremental || pb instanceof ProblemZ3BitVectorIncremental) + return pb.div(getExpression(e_leftRef),getExpression(e_rightRef)); + else + throw new RuntimeException("## Error: Binary Non Linear Operation"); + } + case REM: + if (e_leftRef instanceof IntegerConstant && e_rightRef instanceof IntegerConstant) + throw new RuntimeException("## Error: this is not a symbolic expression"); // + else if (e_leftRef instanceof IntegerConstant) // TODO: this might not be linear + return pb.rem(((IntegerConstant)e_leftRef).value,getExpression(e_rightRef)); + else if (e_rightRef instanceof IntegerConstant) + return pb.rem(getExpression(e_leftRef),((IntegerConstant)e_rightRef).value); + else { + if(pb instanceof ProblemCoral || pb instanceof ProblemZ3 || pb instanceof ProblemZ3BitVector || + pb instanceof ProblemZ3Incremental || pb instanceof ProblemZ3BitVectorIncremental) + return pb.rem(getExpression(e_leftRef),getExpression(e_rightRef)); + else + throw new RuntimeException("## Error: Binary Non Linear Operation"); + } + case AND: + if(e_leftRef instanceof IntegerConstant && e_rightRef instanceof IntegerConstant) + throw new RuntimeException("## Error: this is not a symbolic expression"); // + else if (e_leftRef instanceof IntegerConstant) + return pb.and(((IntegerConstant)e_leftRef).value,getExpression(e_rightRef)); + else if (e_rightRef instanceof IntegerConstant) + return pb.and(((IntegerConstant)e_rightRef).value,getExpression(e_leftRef)); + else + return pb.and(getExpression(e_leftRef),getExpression(e_rightRef)); + case OR: + if(e_leftRef instanceof IntegerConstant && e_rightRef instanceof IntegerConstant) + throw new RuntimeException("## Error: this is not a symbolic expression"); // + else if (e_leftRef instanceof IntegerConstant) + return pb.or(((IntegerConstant)e_leftRef).value,getExpression(e_rightRef)); + else if (e_rightRef instanceof IntegerConstant) + return pb.or(((IntegerConstant)e_rightRef).value,getExpression(e_leftRef)); + else + return pb.or(getExpression(e_leftRef),getExpression(e_rightRef)); + case XOR: + if(e_leftRef instanceof IntegerConstant && e_rightRef instanceof IntegerConstant) + throw new RuntimeException("## Error: this is not a symbolic expression"); // + else if (e_leftRef instanceof IntegerConstant) + return pb.xor(((IntegerConstant)e_leftRef).value,getExpression(e_rightRef)); + else if (e_rightRef instanceof IntegerConstant) + return pb.xor(((IntegerConstant)e_rightRef).value,getExpression(e_leftRef)); + else + return pb.xor(getExpression(e_leftRef),getExpression(e_rightRef)); + case SHIFTR: + if(e_leftRef instanceof IntegerConstant && e_rightRef instanceof IntegerConstant) + throw new RuntimeException("## Error: this is not a symbolic expression"); // + else if (e_leftRef instanceof IntegerConstant) + return pb.shiftR(((IntegerConstant)e_leftRef).value,getExpression(e_rightRef)); + else if (e_rightRef instanceof IntegerConstant) + return pb.shiftR(getExpression(e_leftRef),((IntegerConstant)e_rightRef).value); + else + return pb.shiftR(getExpression(e_leftRef),getExpression(e_rightRef)); + case SHIFTUR: + if(e_leftRef instanceof IntegerConstant && e_rightRef instanceof IntegerConstant) + throw new RuntimeException("## Error: this is not a symbolic expression"); // + else if (e_leftRef instanceof IntegerConstant) + return pb.shiftUR(((IntegerConstant)e_leftRef).value,getExpression(e_rightRef)); + else if (e_rightRef instanceof IntegerConstant) + return pb.shiftUR(getExpression(e_leftRef),((IntegerConstant)e_rightRef).value); + else + return pb.shiftUR(getExpression(e_leftRef),getExpression(e_rightRef)); + case SHIFTL: + if(e_leftRef instanceof IntegerConstant && e_rightRef instanceof IntegerConstant) + throw new RuntimeException("## Error: this is not a symbolic expression"); // + else if (e_leftRef instanceof IntegerConstant) + return pb.shiftL(((IntegerConstant)e_leftRef).value,getExpression(e_rightRef)); + else if (e_rightRef instanceof IntegerConstant) + return pb.shiftL(getExpression(e_leftRef),((IntegerConstant)e_rightRef).value); + else + return pb.shiftL(getExpression(e_leftRef),getExpression(e_rightRef)); + default: + throw new RuntimeException("## Error: Binary Non Linear Operation"); + } + + + } + + + // Converts RealExpression's into DP RealExp's + static Object getExpression(RealExpression eRef) { + assert eRef != null; + assert !(eRef instanceof RealConstant); + + if (eRef instanceof SymbolicReal) { + Object dp_var = symRealVar.get(eRef); + if (dp_var == null) { + dp_var = pb.makeRealVar(((SymbolicReal)eRef).getName(), + ((SymbolicReal)eRef)._min, ((SymbolicReal)eRef)._max); + symRealVar.put((SymbolicReal)eRef, dp_var); + } + return dp_var; + } + + if(eRef instanceof BinaryRealExpression) { + Operator opRef; + RealExpression e_leftRef; + RealExpression e_rightRef; + opRef = ((BinaryRealExpression)eRef).op; + e_leftRef = ((BinaryRealExpression)eRef).left; + e_rightRef = ((BinaryRealExpression)eRef).right; + + switch(opRef){ + case PLUS: + if (e_leftRef instanceof RealConstant && e_rightRef instanceof RealConstant) + return pb.constant(((RealConstant)e_leftRef).value + ((RealConstant)e_rightRef).value); + //throw new RuntimeException("## Error: this is not a symbolic expression"); // + else if (e_leftRef instanceof RealConstant) + return pb.plus(((RealConstant)e_leftRef).value, getExpression(e_rightRef)); + else if (e_rightRef instanceof RealConstant) + return pb.plus(getExpression(e_leftRef),((RealConstant)e_rightRef).value); + else + return pb.plus(getExpression(e_leftRef),getExpression(e_rightRef)); + case MINUS: + if (e_leftRef instanceof RealConstant && e_rightRef instanceof RealConstant) + throw new RuntimeException("## Error: this is not a symbolic expression"); // + else if (e_leftRef instanceof RealConstant) + return pb.minus(((RealConstant)e_leftRef).value,getExpression(e_rightRef)); + else if (e_rightRef instanceof RealConstant) + return pb.minus(getExpression(e_leftRef),((RealConstant)e_rightRef).value); + else + return pb.minus(getExpression(e_leftRef),getExpression(e_rightRef)); + case MUL: + if (e_leftRef instanceof RealConstant && e_rightRef instanceof RealConstant) + throw new RuntimeException("## Error: this is not a symbolic expression"); // + else if (e_leftRef instanceof RealConstant) + return pb.mult(((RealConstant)e_leftRef).value,getExpression(e_rightRef)); + else if (e_rightRef instanceof RealConstant) + return pb.mult(((RealConstant)e_rightRef).value,getExpression(e_leftRef)); + else + return pb.mult(getExpression(e_leftRef),getExpression(e_rightRef)); + case DIV: + if (e_leftRef instanceof RealConstant && e_rightRef instanceof RealConstant) + throw new RuntimeException("## Error: this is not a symbolic expression"); // + else if (e_leftRef instanceof RealConstant) + return pb.div(((RealConstant)e_leftRef).value,getExpression(e_rightRef)); + else if (e_rightRef instanceof RealConstant) + return pb.div(getExpression(e_leftRef),((RealConstant)e_rightRef).value); + else + return pb.div(getExpression(e_leftRef),getExpression(e_rightRef)); + case AND: + if (e_leftRef instanceof RealConstant && e_rightRef instanceof RealConstant) + throw new RuntimeException("## Error: this is not a symbolic expression"); // + else if (e_leftRef instanceof RealConstant) + return pb.and(((RealConstant)e_leftRef).value,getExpression(e_rightRef)); + else if (e_rightRef instanceof RealConstant) + return pb.and(((RealConstant)e_rightRef).value,getExpression(e_leftRef)); + else + return pb.and(getExpression(e_leftRef),getExpression(e_rightRef)); + + default: + throw new RuntimeException("## Error: Expression " + eRef); + } + } + + if(eRef instanceof MathRealExpression) { + MathFunction funRef; + RealExpression e_arg1Ref; + RealExpression e_arg2Ref; + + funRef = ((MathRealExpression)eRef).op; + e_arg1Ref = ((MathRealExpression)eRef).arg1; + e_arg2Ref = ((MathRealExpression)eRef).arg2; + switch(funRef){ + case SIN: return pb.sin(getExpression(e_arg1Ref)); + case COS: return pb.cos(getExpression(e_arg1Ref)); + case EXP: return pb.exp(getExpression(e_arg1Ref)); + case ASIN: return pb.asin(getExpression(e_arg1Ref)); + case ACOS:return pb.acos(getExpression(e_arg1Ref)); + case ATAN: return pb.atan(getExpression(e_arg1Ref)); + case LOG:return pb.log(getExpression(e_arg1Ref)); + case TAN:return pb.tan(getExpression(e_arg1Ref)); + case SQRT:return pb.sqrt(getExpression(e_arg1Ref)); + case POW: + if (e_arg2Ref instanceof RealConstant) + return pb.power(getExpression(e_arg1Ref),((RealConstant)e_arg2Ref).value); + else if (e_arg1Ref instanceof RealConstant) + return pb.power(((RealConstant)e_arg1Ref).value,getExpression(e_arg2Ref)); + else + return pb.power(getExpression(e_arg1Ref),getExpression(e_arg2Ref)); + case ATAN2: + if (e_arg2Ref instanceof RealConstant) + return pb.atan2(getExpression(e_arg1Ref),((RealConstant)e_arg2Ref).value); + else if (e_arg1Ref instanceof RealConstant) + return pb.atan2(((RealConstant)e_arg1Ref).value,getExpression(e_arg2Ref)); + else + return pb.atan2(getExpression(e_arg1Ref),getExpression(e_arg2Ref)); + default: + throw new RuntimeException("## Error: Expression " + eRef); + } + } + + throw new RuntimeException("## Error: Expression " + eRef); + } + + //public Map getSymRealVar() { + //return symRealVar; + //} + + + //public Map getSymIntegerVar() { + //return symIntegerVar; + //} + + + static public boolean createDPMixedConstraint(MixedConstraint cRef) { // TODO + + Comparator c_compRef = cRef.getComparator(); + RealExpression c_leftRef = (RealExpression)cRef.getLeft(); + IntegerExpression c_rightRef = (IntegerExpression)cRef.getRight(); + assert (c_compRef == Comparator.EQ); + + if (c_leftRef instanceof SymbolicReal && c_rightRef instanceof SymbolicInteger) { + //pb.post(new MixedEqXY((RealVar)(getExpression(c_leftRef)),(IntDomainVar)(getExpression(c_rightRef)))); + pb.post(pb.mixed(getExpression(c_leftRef),getExpression(c_rightRef))); + } + else if (c_leftRef instanceof SymbolicReal) { // c_rightRef is an IntegerExpression + Object tmpi = pb.makeIntVar(c_rightRef + "_" + c_rightRef.hashCode(),(int)(((SymbolicReal)c_leftRef)._min), (int)(((SymbolicReal)c_leftRef)._max)); + if (c_rightRef instanceof IntegerConstant) + pb.post(pb.eq(((IntegerConstant)c_rightRef).value,tmpi)); + else + pb.post(pb.eq(getExpression(c_rightRef),tmpi)); + //pb.post(new MixedEqXY((RealVar)(getExpression(c_leftRef)),tmpi)); + pb.post(pb.mixed(getExpression(c_leftRef),tmpi)); + + } + else if (c_rightRef instanceof SymbolicInteger) { // c_leftRef is a RealExpression + Object tmpr = pb.makeRealVar(c_leftRef + "_" + c_leftRef.hashCode(), ((SymbolicInteger)c_rightRef)._min, ((SymbolicInteger)c_rightRef)._max); + if(c_leftRef instanceof RealConstant) + pb.post(pb.eq(tmpr, ((RealConstant)c_leftRef).value)); + else + pb.post(pb.eq(tmpr, getExpression(c_leftRef))); + //pb.post(new MixedEqXY(tmpr,(IntDomainVar)(getExpression(c_rightRef)))); + pb.post(pb.mixed(tmpr,getExpression(c_rightRef))); + } + else + assert(false); // should not be reachable + + return true; + } + + static public boolean createDPRealConstraint(RealConstraint cRef) { + + Comparator c_compRef = cRef.getComparator(); + RealExpression c_leftRef = (RealExpression)cRef.getLeft(); + RealExpression c_rightRef = (RealExpression)cRef.getRight(); + + switch(c_compRef){ + case EQ: + if (c_leftRef instanceof RealConstant && c_rightRef instanceof RealConstant) { + if (!(((RealConstant) c_leftRef).value == ((RealConstant) c_rightRef).value)) + return false; + else + return true; + } + else if (c_leftRef instanceof RealConstant) { + pb.post(pb.eq(((RealConstant)c_leftRef).value,getExpression(c_rightRef))); + } + else if (c_rightRef instanceof RealConstant) { + pb.post(pb.eq(getExpression(c_leftRef),((RealConstant)c_rightRef).value)); + } + else + pb.post(pb.eq(getExpression(c_leftRef),getExpression(c_rightRef))); + break; + case NE: + if (c_leftRef instanceof RealConstant && c_rightRef instanceof RealConstant) { + if (!(((RealConstant) c_leftRef).value != ((RealConstant) c_rightRef).value)) + return false; + else + return true; + } + else if (c_leftRef instanceof RealConstant) { + pb.post(pb.neq(((RealConstant)c_leftRef).value,getExpression(c_rightRef))); + } + else if (c_rightRef instanceof RealConstant) { + pb.post(pb.neq(getExpression(c_leftRef),((RealConstant)c_rightRef).value)); + } + else + pb.post(pb.neq(getExpression(c_leftRef),getExpression(c_rightRef))); + break; + case LT: + if (c_leftRef instanceof RealConstant && c_rightRef instanceof RealConstant) { + if (!(((RealConstant) c_leftRef).value < ((RealConstant) c_rightRef).value)) + return false; + else + return true; + } + else if (c_leftRef instanceof RealConstant) { + pb.post(pb.lt(((RealConstant)c_leftRef).value,getExpression(c_rightRef))); + } + else if (c_rightRef instanceof RealConstant) { + pb.post(pb.lt(getExpression(c_leftRef),((RealConstant)c_rightRef).value)); + } + else + pb.post(pb.lt(getExpression(c_leftRef),getExpression(c_rightRef))); + break; + case GE: + if (c_leftRef instanceof RealConstant && c_rightRef instanceof RealConstant) { + if (!(((RealConstant) c_leftRef).value >= ((RealConstant) c_rightRef).value)) + return false; + else + return true; + } + else if (c_leftRef instanceof RealConstant) { + pb.post(pb.geq(((RealConstant)c_leftRef).value,getExpression(c_rightRef))); + } + else if (c_rightRef instanceof RealConstant) { + pb.post(pb.geq(getExpression(c_leftRef),((RealConstant)c_rightRef).value)); + } + else + pb.post(pb.geq(getExpression(c_leftRef),getExpression(c_rightRef))); + break; + case LE: + if (c_leftRef instanceof RealConstant && c_rightRef instanceof RealConstant) { + if (!(((RealConstant) c_leftRef).value <= ((RealConstant) c_rightRef).value)) + return false; + else + return true; + } + else if (c_leftRef instanceof RealConstant) { + pb.post(pb.leq(((RealConstant)c_leftRef).value,getExpression(c_rightRef))); + } + else if (c_rightRef instanceof RealConstant) { + pb.post(pb.leq(getExpression(c_leftRef),((RealConstant)c_rightRef).value)); + } + else + pb.post(pb.leq(getExpression(c_leftRef),getExpression(c_rightRef))); + break; + case GT: + if (c_leftRef instanceof RealConstant && c_rightRef instanceof RealConstant) { + if (!(((RealConstant) c_leftRef).value > ((RealConstant) c_rightRef).value)) + return false; + else + return true; + } + else if (c_leftRef instanceof RealConstant) { + pb.post(pb.gt(((RealConstant)c_leftRef).value,getExpression(c_rightRef))); + } + else if (c_rightRef instanceof RealConstant) { + pb.post(pb.gt(getExpression(c_leftRef),((RealConstant)c_rightRef).value)); + } + else + pb.post(pb.gt(getExpression(c_leftRef),getExpression(c_rightRef))); + break; + } + return true; + } + + //Added by Gideon, to handle CNF style constraints??? + static public boolean createDPLinearOrIntegerConstraint (LogicalORLinearIntegerConstraints c) { + List orList = new ArrayList(); + + for (LinearIntegerConstraint cRef: c.getList()) { + Comparator c_compRef = cRef.getComparator(); + IntegerExpression c_leftRef = (IntegerExpression)cRef.getLeft(); + IntegerExpression c_rightRef = (IntegerExpression)cRef.getRight(); + //Removed all return false: why? + switch(c_compRef){ + case EQ: + if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { + if (((IntegerConstant) c_leftRef).value == ((IntegerConstant) c_rightRef).value) + return true; + } + else if (c_leftRef instanceof IntegerConstant) { + Object part1 = getExpression(c_rightRef); + Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; + pb.post(pb.eq(tempVar, part1)); + Object cc = pb.eq(((IntegerConstant)c_leftRef).value, tempVar); + orList.add(cc); + } + else if (c_rightRef instanceof IntegerConstant) { + Object part1 = getExpression(c_leftRef); + Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); + pb.post(pb.eq(tempVar, part1)); tempVars++; + orList.add(pb.eq(tempVar,((IntegerConstant)c_rightRef).value)); + } + else { + Object part1 = getExpression(c_leftRef); + Object part2 = getExpression(c_rightRef); + Object tempVar1 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; + Object tempVar2 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; + pb.post(pb.eq(tempVar1, part1)); + pb.post(pb.eq(tempVar2, part2)); + orList.add(pb.eq(tempVar1,tempVar2)); + } + break; + case NE: + if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { + if (((IntegerConstant) c_leftRef).value != ((IntegerConstant) c_rightRef).value) + return true; + } + else if (c_leftRef instanceof IntegerConstant) { + Object part1 = getExpression(c_rightRef); + Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; + pb.post(pb.eq(tempVar, part1)); + Object cc = pb.neq(((IntegerConstant)c_leftRef).value, tempVar); + orList.add(cc); + } + else if (c_rightRef instanceof IntegerConstant) { + Object part1 = getExpression(c_leftRef); + Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); + pb.post(pb.eq(tempVar, part1)); tempVars++; + orList.add(pb.neq(tempVar,((IntegerConstant)c_rightRef).value)); + } + else { + Object part1 = getExpression(c_leftRef); + Object part2 = getExpression(c_rightRef); + Object tempVar1 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; + Object tempVar2 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; + pb.post(pb.eq(tempVar1, part1)); + pb.post(pb.eq(tempVar2, part2)); + orList.add(pb.neq(tempVar1,tempVar2)); + } + break; + case LT: + if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { + if (((IntegerConstant) c_leftRef).value < ((IntegerConstant) c_rightRef).value) + return true; + } + else if (c_leftRef instanceof IntegerConstant) { + Object part1 = getExpression(c_rightRef); + Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; + pb.post(pb.eq(tempVar, part1)); + Object cc = pb.lt(((IntegerConstant)c_leftRef).value, tempVar); + orList.add(cc); + } + else if (c_rightRef instanceof IntegerConstant) { + Object part1 = getExpression(c_leftRef); + Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); + pb.post(pb.eq(tempVar, part1)); tempVars++; + orList.add(pb.lt(tempVar,((IntegerConstant)c_rightRef).value)); + } + else { + Object part1 = getExpression(c_leftRef); + Object part2 = getExpression(c_rightRef); + Object tempVar1 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; + Object tempVar2 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; + pb.post(pb.eq(tempVar1, part1)); + pb.post(pb.eq(tempVar2, part2)); + orList.add(pb.lt(tempVar1,tempVar2)); + } + break; + case GE: + if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { + if (((IntegerConstant) c_leftRef).value >= ((IntegerConstant) c_rightRef).value) + return true; + } + else if (c_leftRef instanceof IntegerConstant) { + Object part1 = getExpression(c_rightRef); + Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; + pb.post(pb.eq(tempVar, part1)); + Object cc = pb.geq(((IntegerConstant)c_leftRef).value, tempVar); + orList.add(cc); + } + else if (c_rightRef instanceof IntegerConstant) { + Object part1 = getExpression(c_leftRef); + Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); + pb.post(pb.eq(tempVar, part1)); tempVars++; + orList.add(pb.geq(tempVar,((IntegerConstant)c_rightRef).value)); + } + else { + Object part1 = getExpression(c_leftRef); + Object part2 = getExpression(c_rightRef); + Object tempVar1 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; + Object tempVar2 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; + pb.post(pb.eq(tempVar1, part1)); + pb.post(pb.eq(tempVar2, part2)); + orList.add(pb.geq(tempVar1,tempVar2)); + } + break; + case LE: + if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { + if (((IntegerConstant) c_leftRef).value <= ((IntegerConstant) c_rightRef).value) + return true; + } + else if (c_leftRef instanceof IntegerConstant) { + Object part1 = getExpression(c_rightRef); + Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; + pb.post(pb.eq(tempVar, part1)); + Object cc = pb.leq(((IntegerConstant)c_leftRef).value, tempVar); + orList.add(cc); + } + else if (c_rightRef instanceof IntegerConstant) { + Object part1 = getExpression(c_leftRef); + Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); + pb.post(pb.eq(tempVar, part1)); tempVars++; + orList.add(pb.leq(tempVar,((IntegerConstant)c_rightRef).value)); + } + else { + Object part1 = getExpression(c_leftRef); + Object part2 = getExpression(c_rightRef); + Object tempVar1 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; + Object tempVar2 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; + pb.post(pb.eq(tempVar1, part1)); + pb.post(pb.eq(tempVar2, part2)); + orList.add(pb.leq(tempVar1,tempVar2)); + } + break; + case GT: + if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { + if (((IntegerConstant) c_leftRef).value > ((IntegerConstant) c_rightRef).value) + return true; + } + else if (c_leftRef instanceof IntegerConstant) { + Object part1 = getExpression(c_rightRef); + Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; + pb.post(pb.eq(tempVar, part1)); + Object cc = pb.gt(((IntegerConstant)c_leftRef).value, tempVar); + orList.add(cc); + } + else if (c_rightRef instanceof IntegerConstant) { + Object part1 = getExpression(c_leftRef); + Object tempVar = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); + pb.post(pb.eq(tempVar, part1)); tempVars++; + orList.add(pb.gt(tempVar,((IntegerConstant)c_rightRef).value)); + } + else { + Object part1 = getExpression(c_leftRef); + Object part2 = getExpression(c_rightRef); + Object tempVar1 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; + Object tempVar2 = pb.makeIntVar("mytemp" + tempVars, MinMax.getVarMinInt(""), MinMax.getVarMaxInt("")); tempVars++; + pb.post(pb.eq(tempVar1, part1)); + pb.post(pb.eq(tempVar2, part2)); + orList.add(pb.gt(tempVar1,tempVar2)); + } + break; + } + } + //System.out.println("[SymbolicConstraintsGeneral] orList: " + orList.toString()); + if (orList.size() == 0) return true; + Object constraint_array[] = new Object[orList.size()]; + orList.toArray(constraint_array); + + pb.postLogicalOR(constraint_array); + + return true; + + } + + static public boolean createDPLinearIntegerConstraint(LinearIntegerConstraint cRef) { + + Comparator c_compRef = cRef.getComparator(); + + IntegerExpression c_leftRef = (IntegerExpression)cRef.getLeft(); + IntegerExpression c_rightRef = (IntegerExpression)cRef.getRight(); + + switch(c_compRef){ + case EQ: + if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { + if (!(((IntegerConstant) c_leftRef).value == ((IntegerConstant) c_rightRef).value)) + return false; + else + return true; + } + else if (c_leftRef instanceof IntegerConstant) { + pb.post(pb.eq(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); + } + else if (c_rightRef instanceof IntegerConstant) { + pb.post(pb.eq(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); + } + else + pb.post(pb.eq(getExpression(c_leftRef),getExpression(c_rightRef))); + break; + case NE: + if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { + if (!(((IntegerConstant) c_leftRef).value != ((IntegerConstant) c_rightRef).value)) + return false; + else + return true; + } + else if (c_leftRef instanceof IntegerConstant) { + pb.post(pb.neq(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); + } + else if (c_rightRef instanceof IntegerConstant) { + pb.post(pb.neq(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); + } + else + pb.post(pb.neq(getExpression(c_leftRef),getExpression(c_rightRef))); + break; + case LT: + if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { + if (!(((IntegerConstant) c_leftRef).value < ((IntegerConstant) c_rightRef).value)) + return false; + else + return true; + } + else if (c_leftRef instanceof IntegerConstant) { + pb.post(pb.lt(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); + } + else if (c_rightRef instanceof IntegerConstant) { + pb.post(pb.lt(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); + } + else + pb.post(pb.lt(getExpression(c_leftRef),getExpression(c_rightRef))); + break; + case GE: + if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { + if (!(((IntegerConstant) c_leftRef).value >= ((IntegerConstant) c_rightRef).value)) + return false; + else + return true; + } + else if (c_leftRef instanceof IntegerConstant) { + pb.post(pb.geq(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); + } + else if (c_rightRef instanceof IntegerConstant) { + pb.post(pb.geq(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); + } + else + pb.post(pb.geq(getExpression(c_leftRef),getExpression(c_rightRef))); + break; + case LE: + if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { + if (!(((IntegerConstant) c_leftRef).value <= ((IntegerConstant) c_rightRef).value)) + return false; + else + return true; + } + else if (c_leftRef instanceof IntegerConstant) { + pb.post(pb.leq(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); + } + else if (c_rightRef instanceof IntegerConstant) { + pb.post(pb.leq(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); + } + else + pb.post(pb.leq(getExpression(c_leftRef),getExpression(c_rightRef))); + break; + case GT: + if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { + if (!(((IntegerConstant) c_leftRef).value > ((IntegerConstant) c_rightRef).value)) + return false; + else + return true; + } + else if (c_leftRef instanceof IntegerConstant) { + pb.post(pb.gt(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); + } + else if (c_rightRef instanceof IntegerConstant) { + pb.post(pb.gt(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); + } + else + pb.post(pb.gt(getExpression(c_leftRef),getExpression(c_rightRef))); + break; + } + return true; + } + + static public boolean createDPNonLinearIntegerConstraint(NonLinearIntegerConstraint cRef) { + + Comparator c_compRef = cRef.getComparator(); + + IntegerExpression c_leftRef = (IntegerExpression)cRef.getLeft(); + IntegerExpression c_rightRef = (IntegerExpression)cRef.getRight(); + + switch(c_compRef){ + case EQ: + if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { + if (!(((IntegerConstant) c_leftRef).value == ((IntegerConstant) c_rightRef).value)) + return false; + else + return true; + } + else if (c_leftRef instanceof IntegerConstant) { + pb.post(pb.eq(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); + } + else if (c_rightRef instanceof IntegerConstant) { + pb.post(pb.eq(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); + } + else + pb.post(pb.eq(getExpression(c_leftRef),getExpression(c_rightRef))); + break; + case NE: + if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { + if (!(((IntegerConstant) c_leftRef).value != ((IntegerConstant) c_rightRef).value)) + return false; + else + return true; + } + else if (c_leftRef instanceof IntegerConstant) { + pb.post(pb.neq(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); + } + else if (c_rightRef instanceof IntegerConstant) { + pb.post(pb.neq(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); + } + else + pb.post(pb.neq(getExpression(c_leftRef),getExpression(c_rightRef))); + break; + case LT: + if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { + if (!(((IntegerConstant) c_leftRef).value < ((IntegerConstant) c_rightRef).value)) + return false; + else + return true; + } + else if (c_leftRef instanceof IntegerConstant) { + pb.post(pb.lt(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); + } + else if (c_rightRef instanceof IntegerConstant) { + pb.post(pb.lt(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); + } + else + pb.post(pb.lt(getExpression(c_leftRef),getExpression(c_rightRef))); + break; + case GE: + if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { + if (!(((IntegerConstant) c_leftRef).value >= ((IntegerConstant) c_rightRef).value)) + return false; + else + return true; + } + else if (c_leftRef instanceof IntegerConstant) { + pb.post(pb.geq(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); + } + else if (c_rightRef instanceof IntegerConstant) { + pb.post(pb.geq(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); + } + else + pb.post(pb.geq(getExpression(c_leftRef),getExpression(c_rightRef))); + break; + case LE: + if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { + if (!(((IntegerConstant) c_leftRef).value <= ((IntegerConstant) c_rightRef).value)) + return false; + else + return true; + } + else if (c_leftRef instanceof IntegerConstant) { + pb.post(pb.leq(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); + } + else if (c_rightRef instanceof IntegerConstant) { + pb.post(pb.leq(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); + } + else + pb.post(pb.leq(getExpression(c_leftRef),getExpression(c_rightRef))); + break; + case GT: + if (c_leftRef instanceof IntegerConstant && c_rightRef instanceof IntegerConstant) { + if (!(((IntegerConstant) c_leftRef).value > ((IntegerConstant) c_rightRef).value)) + return false; + else + return true; + } + else if (c_leftRef instanceof IntegerConstant) { + pb.post(pb.gt(((IntegerConstant)c_leftRef).value,getExpression(c_rightRef))); + } + else if (c_rightRef instanceof IntegerConstant) { + pb.post(pb.gt(getExpression(c_leftRef),((IntegerConstant)c_rightRef).value)); + } + else + pb.post(pb.gt(getExpression(c_leftRef),getExpression(c_rightRef))); + break; + } + return true; + } + //static Map dpMap = new HashMap(); + + // Added by Aymeric to support symbolic Arrays + public static boolean createArrayConstraint(ArrayConstraint cRef) { + Comparator c_compRef = cRef.getComparator(); + + SelectExpression selex = null; StoreExpression stoex = null; IntegerExpression sel_right = null; ArrayExpression sto_right = null; - try { - selex = (SelectExpression)cRef.getLeft(); - sel_right = (IntegerExpression)cRef.getRight(); - } catch (Exception e) { - try { - stoex = (StoreExpression)cRef.getLeft(); - sto_right = (ArrayExpression)cRef.getRight(); - } catch (Exception r) { - throw new RuntimeException("ArrayConstraint is not select or store"); - } - + if (cRef.getLeft() instanceof SelectExpression) { + selex = (SelectExpression)cRef.getLeft(); + sel_right = (IntegerExpression)cRef.getRight(); + } else if (cRef.getLeft() instanceof StoreExpression) { + stoex = (StoreExpression)cRef.getLeft(); + sto_right = (ArrayExpression)cRef.getRight(); + } else { + throw new RuntimeException("ArrayConstraint is not select or store"); } - + switch(c_compRef) { case EQ: if (selex != null && sel_right != null) { // The array constraint is a select - ArrayExpression ae = (ArrayExpression) selex.ae; + ArrayExpression ae = (ArrayExpression) selex.arrayExpression; pb.post(pb.eq(pb.select(pb.makeArrayVar(ae.getName()), - (selex.index instanceof IntegerConstant) ? pb.makeIntConst(((IntegerConstant)selex.index).value) : getExpression(selex.index)), - (sel_right instanceof IntegerConstant) ? pb.makeIntConst(((IntegerConstant)sel_right).value) : getExpression(sel_right))); + (selex.indexExpression instanceof IntegerConstant) ? pb.makeIntConst(((IntegerConstant)selex.indexExpression).value) : +getExpression(selex.indexExpression)), + (sel_right instanceof IntegerConstant) ? pb.makeIntConst(((IntegerConstant)sel_right).value) : +getExpression(sel_right))); break; } if (stoex != null && sto_right != null) { // The array constraint is a store - ArrayExpression ae = (ArrayExpression) stoex.ae; + ArrayExpression ae = (ArrayExpression) stoex.arrayExpression; ArrayExpression newae = (ArrayExpression) sto_right; pb.post(pb.eq(pb.store(pb.makeArrayVar(ae.getName()), - (stoex.index instanceof IntegerConstant) ? pb.makeIntConst(((IntegerConstant)stoex.index).value) : getExpression(stoex.index), - (stoex.value instanceof IntegerConstant) ? pb.makeIntConst(((IntegerConstant)stoex.value).value) : getExpression(stoex.value)), + (stoex.indexExpression instanceof IntegerConstant) ? pb.makeIntConst(((IntegerConstant)stoex.indexExpression).value) : +getExpression(stoex.indexExpression), + (stoex.value instanceof IntegerConstant) ? pb.makeIntConst(((IntegerConstant)stoex.value).value) : +getExpression(stoex.value)), pb.makeArrayVar(newae.getName()))); break; } @@ -928,15 +956,17 @@ public static boolean createDPArrayConstraint(final ArrayConstraint cRef) { case NE: if (selex != null && sel_right != null) { // The array constraint is a select - ArrayExpression ae = (ArrayExpression) selex.ae; - pb.post(pb.neq(pb.select(pb.makeArrayVar(ae.getName()), getExpression(selex.index)), getExpression(sel_right))); + ArrayExpression ae = (ArrayExpression) selex.arrayExpression; + pb.post(pb.neq(pb.select(pb.makeArrayVar(ae.getName()), getExpression(selex.indexExpression)), +getExpression(sel_right))); break; } if (stoex != null && sto_right != null) { // The array constraint is a store - ArrayExpression ae = (ArrayExpression)stoex.ae; + ArrayExpression ae = (ArrayExpression)stoex.arrayExpression; ArrayExpression newae = (ArrayExpression) sto_right; - pb.post(pb.neq(pb.store(pb.makeArrayVar(ae.getName()), getExpression(stoex.index), getExpression(stoex.value)), newae)); + pb.post(pb.neq(pb.store(pb.makeArrayVar(ae.getName()), getExpression(stoex.indexExpression), +getExpression(stoex.value)), newae)); break; } throw new RuntimeException("ArrayConstraint is not correct select or store"); @@ -944,9 +974,9 @@ public static boolean createDPArrayConstraint(final ArrayConstraint cRef) { throw new RuntimeException("ArrayConstraint is not select or store"); } return true; - } - - public static boolean createDPRealArrayConstraint(final RealArrayConstraint cRef) { + } + +public static boolean createRealArrayConstraint(final RealArrayConstraint cRef) { final Comparator c_compRef = cRef.getComparator(); @@ -954,17 +984,14 @@ public static boolean createDPRealArrayConstraint(final RealArrayConstraint cRef RealStoreExpression stoex = null; RealExpression sel_right = null; ArrayExpression sto_right = null; - try { + if (cRef.getLeft() instanceof SelectExpression) { selex = (SelectExpression)cRef.getLeft(); sel_right = (RealExpression)cRef.getRight(); - } catch (Exception e) { - try { - stoex = (RealStoreExpression)cRef.getLeft(); - sto_right = (ArrayExpression)cRef.getRight(); - } catch (Exception r) { - throw new RuntimeException("ArrayConstraint is not select or store"); - } - + } else if (cRef.getLeft() instanceof RealStoreExpression) { + stoex = (RealStoreExpression)cRef.getLeft(); + sto_right = (ArrayExpression)cRef.getRight(); + } else { + throw new RuntimeException("ArrayConstraint is not select or store"); } switch(c_compRef) { @@ -972,19 +999,23 @@ public static boolean createDPRealArrayConstraint(final RealArrayConstraint cRef if (selex != null && sel_right != null) { // The array constraint is a select - RealSymbolicArray ae = (RealSymbolicArray) selex.ae; + ArrayExpression ae = selex.arrayExpression; pb.post(pb.eq(pb.realSelect(pb.makeRealArrayVar(ae.getName()), - (selex.index instanceof IntegerConstant) ? pb.makeIntConst(((IntegerConstant)selex.index).value) : getExpression(selex.index)), - (sel_right instanceof RealConstant) ? pb.makeRealConst(((RealConstant)sel_right).value) : getExpression(sel_right))); + (selex.indexExpression instanceof IntegerConstant) ? pb.makeIntConst(((IntegerConstant)selex.indexExpression).value) : +getExpression(selex.indexExpression)), + (sel_right instanceof RealConstant) ? pb.makeRealConst(((RealConstant)sel_right).value) : +getExpression(sel_right))); break; } if (stoex != null && sto_right != null) { // The array constraint is a store - RealSymbolicArray ae = (RealSymbolicArray) stoex.ae; - RealSymbolicArray newae = (RealSymbolicArray) sto_right; + ArrayExpression ae = stoex.arrayExpression; + ArrayExpression newae = sto_right; pb.post(pb.eq(pb.realStore(pb.makeRealArrayVar(ae.getName()), - (stoex.index instanceof IntegerConstant) ? pb.makeIntConst(((IntegerConstant)stoex.index).value) : getExpression(stoex.index), - (stoex.value instanceof RealConstant) ? pb.makeRealConst(((RealConstant)stoex.value).value) : getExpression(stoex.value)), + (stoex.indexExpression instanceof IntegerConstant) ? pb.makeIntConst(((IntegerConstant)stoex.indexExpression).value) : +getExpression(stoex.indexExpression), + (stoex.value instanceof RealConstant) ? pb.makeRealConst(((RealConstant)stoex.value).value) : +getExpression(stoex.value)), pb.makeRealArrayVar(newae.getName()))); break; } @@ -992,15 +1023,17 @@ public static boolean createDPRealArrayConstraint(final RealArrayConstraint cRef case NE: if (selex != null && sel_right != null) { // The array constraint is a select - RealSymbolicArray ae = (RealSymbolicArray) selex.ae; - pb.post(pb.neq(pb.realSelect(pb.makeRealArrayVar(ae.getName()), getExpression(selex.index)), getExpression(sel_right))); + ArrayExpression ae = selex.arrayExpression; + pb.post(pb.neq(pb.realSelect(pb.makeRealArrayVar(ae.getName()), getExpression(selex.indexExpression)), +getExpression(sel_right))); break; } if (stoex != null && sto_right != null) { // The array constraint is a store - RealSymbolicArray ae = (RealSymbolicArray)stoex.ae; - RealSymbolicArray newae = (RealSymbolicArray) sto_right; - pb.post(pb.neq(pb.realStore(pb.makeRealArrayVar(ae.getName()), getExpression(stoex.index), getExpression(stoex.value)), newae)); + ArrayExpression ae = stoex.arrayExpression; + ArrayExpression newae = sto_right; + pb.post(pb.neq(pb.realStore(pb.makeRealArrayVar(ae.getName()), getExpression(stoex.indexExpression), +getExpression(stoex.value)), newae)); break; } throw new RuntimeException("ArrayConstraint is not correct select or store"); @@ -1010,61 +1043,81 @@ public static boolean createDPRealArrayConstraint(final RealArrayConstraint cRef return true; } - // result is in pb - public static ProblemGeneral parse(final PathCondition pc, final ProblemGeneral pbtosolve) { - pb=pbtosolve; - - - symRealVar = new HashMap(); - symIntegerVar = new HashMap(); - //result = null; - tempVars = 0; - - Constraint cRef = pc.header; - - while (cRef != null) { - boolean constraintResult = true; - - if (cRef instanceof RealConstraint) - constraintResult= createDPRealConstraint((RealConstraint)cRef);// create choco real constraint - else if (cRef instanceof LinearIntegerConstraint) - constraintResult= createDPLinearIntegerConstraint((LinearIntegerConstraint)cRef);// create choco linear integer constraint - else if (cRef instanceof MixedConstraint) - // System.out.println("Mixed Constraint"); - constraintResult= createDPMixedConstraint((MixedConstraint)cRef); - else if (cRef instanceof LogicalORLinearIntegerConstraints) { -// if (!(pb instanceof ProblemChoco)) { -// throw new RuntimeException ("String solving only works with Choco for now"); -// } - //System.out.println("[SymbolicConstraintsGeneral] reached"); - constraintResult= createDPLinearOrIntegerConstraint((LogicalORLinearIntegerConstraints)cRef); - - } - else if (cRef instanceof ArrayConstraint) { - if (pb instanceof ProblemZ3) - constraintResult = createDPArrayConstraint((ArrayConstraint)cRef); - else - throw new RuntimeException("## Error: Array Constraint not handled (only Z3 can handle it)"+cRef); - } else if (cRef instanceof RealArrayConstraint) { - if (pb instanceof ProblemZ3) - constraintResult = createDPRealArrayConstraint((RealArrayConstraint)cRef); - else - throw new RuntimeException("## Error: Array Constraint not handled (only Z3 can handle it)"+cRef); - } else { - System.out.println("## Warning: Non Linear Integer Constraint (only coral can handle it)" + cRef); - if(pb instanceof ProblemCoral) - constraintResult= createDPNonLinearIntegerConstraint((NonLinearIntegerConstraint)cRef); - else - throw new RuntimeException("## Error: Non Linear Integer Constraint not handled " + cRef); - } - - if(constraintResult == false) return null; // not sat - cRef = cRef.and; - - } - - return pb; - - - } + // result is in pb + public static ProblemGeneral parse(PathCondition pc, ProblemGeneral pbtosolve) { + pb=pbtosolve; + + + symRealVar = new HashMap(); + symIntegerVar = new HashMap(); + //result = null; + tempVars = 0; + + Constraint cRef = pc.header; + + if(pb instanceof IncrementalSolver) { + //If we use an incremental solver, then we push the context + //*before* adding the constraint header + ((IncrementalSolver)pb).push(); + + //Note that for an incremental solver + //we only add the constraint header + if(addConstraint(cRef) == false) { + return null; + } + } else { + //For a non-incremental solver, + //we submit the *entire* pc to the solver + while (cRef != null) { + if(addConstraint(cRef) == false) { + return null; + } + cRef = cRef.and; + } + } + + return pb; + } + + private static boolean addConstraint(Constraint cRef) { + boolean constraintResult = true; + + if (cRef instanceof RealConstraint) + constraintResult= createDPRealConstraint((RealConstraint)cRef);// create choco real constraint + else if (cRef instanceof LinearIntegerConstraint) + constraintResult= createDPLinearIntegerConstraint((LinearIntegerConstraint)cRef);// create choco linear integer constraint + else if (cRef instanceof MixedConstraint) + // System.out.println("Mixed Constraint"); + constraintResult= createDPMixedConstraint((MixedConstraint)cRef); + else if (cRef instanceof LogicalORLinearIntegerConstraints) { + //if (!(pb instanceof ProblemChoco)) { + // throw new RuntimeException ("String solving only works with Choco for now"); + //} + //System.out.println("[SymbolicConstraintsGeneral] reached"); + constraintResult= createDPLinearOrIntegerConstraint((LogicalORLinearIntegerConstraints)cRef); + + } else if (cRef instanceof ArrayConstraint) { + if (pb instanceof ProblemZ3 || pb instanceof ProblemZ3Incremental || pb instanceof ProblemZ3BitVector || pb instanceof ProblemZ3BitVectorIncremental) { + constraintResult = createArrayConstraint((ArrayConstraint)cRef); + } else { + throw new RuntimeException("## Error : Array constraints only handled by z3. Try specifying a z3 instance as symbolic.dp"); + } + } else if (cRef instanceof RealArrayConstraint) { + if (pb instanceof ProblemZ3 || pb instanceof ProblemZ3Incremental || pb instanceof ProblemZ3BitVector || pb instanceof ProblemZ3BitVectorIncremental) { + constraintResult = createRealArrayConstraint((RealArrayConstraint)cRef); + } else { + throw new RuntimeException("## Error : Array constraints only handled by z3. Try specifying a z3 instance as symbolic.dp"); + } + } + else { + //System.out.println("## Warning: Non Linear Integer Constraint (only coral or z3 can handle it)" + cRef); + if(pb instanceof ProblemCoral || pb instanceof ProblemZ3 || pb instanceof ProblemZ3BitVector || pb instanceof ProblemZ3Incremental || pb instanceof ProblemZ3BitVectorIncremental) + constraintResult= createDPNonLinearIntegerConstraint((NonLinearIntegerConstraint)cRef); + else + throw new RuntimeException("## Error: Non Linear Integer Constraint not handled " + cRef); + } + + return constraintResult; //false -> not sat + + } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/PathCondition.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/PathCondition.java index 977c49f..95f9849 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/PathCondition.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/PathCondition.java @@ -37,29 +37,32 @@ package gov.nasa.jpf.symbc.numeric; -//import za.ac.sun.cs.green.Instance; import za.ac.sun.cs.green.Instance; import gov.nasa.jpf.symbc.SymbolicInstructionFactory; -import gov.nasa.jpf.symbc.arrays.ArrayExpression; -import gov.nasa.jpf.symbc.arrays.ArrayConstraint; -import gov.nasa.jpf.symbc.arrays.RealArrayConstraint; -import gov.nasa.jpf.symbc.arrays.SelectExpression; -import gov.nasa.jpf.symbc.arrays.StoreExpression; -import gov.nasa.jpf.symbc.arrays.RealStoreExpression; +import gov.nasa.jpf.symbc.arrays.ArrayConstraint; +import gov.nasa.jpf.symbc.arrays.RealArrayConstraint; +import gov.nasa.jpf.symbc.arrays.RealStoreExpression; +import gov.nasa.jpf.symbc.arrays.StoreExpression; +import gov.nasa.jpf.symbc.arrays.SelectExpression; import gov.nasa.jpf.symbc.concolic.PCAnalyzer; import gov.nasa.jpf.symbc.numeric.solvers.SolverTranslator; import gov.nasa.jpf.symbc.numeric.visitors.CollectVariableVisitor; import gov.nasa.jpf.symbc.string.StringPathCondition; import gov.nasa.jpf.symbc.concolic.*; +import gov.nasa.jpf.symbc.arrays.ArrayExpression; import gov.nasa.jpf.vm.ChoiceGenerator; import gov.nasa.jpf.vm.MJIEnv; import gov.nasa.jpf.vm.VM; +import java.util.HashMap; + // path condition contains mixed constraints of integers and reals public class PathCondition implements Comparable { public static boolean flagSolved = false; + public HashMap arrayExpressions; + public Constraint header; int count = 0; protected int solverCalls = 0; @@ -79,6 +82,7 @@ public static void setReplay(boolean isReplay){ public PathCondition() { header = null; + arrayExpressions = new HashMap(); } public Instance getInstance() { @@ -98,45 +102,42 @@ public PathCondition make_copy() { pc_new.count = this.count; pc_new.spc = this.spc.make_copy(pc_new); // TODO: to review pc_new.solverCalls = this.solverCalls; + pc_new.arrayExpressions = this.arrayExpressions; return pc_new; } - // Added for array execution - public void _addDet(Comparator c, SelectExpression se, IntegerExpression ae) { - // Adding the SelectExpression to the PathCondition - Constraint t = new ArrayConstraint(se, c, ae); - t.and = header; - header = t; - count++; + //Added by Aymeric + public void _addDet(Comparator c, SelectExpression se, IntegerExpression ie) { + Constraint t; + flagSolved = false; + t = new ArrayConstraint(se, c, ie); + prependUnlessRepeated(t); } + //Added by Aymeric public void _addDet(Comparator c, StoreExpression se, ArrayExpression ae) { - // Forcing the index of the store instruction to be in array range - _addDet(Comparator.LT, se.index, se.ae.length); - _addDet(Comparator.GE, se.index, new IntegerConstant(0)); - // Adding the StoreExpression to the PathCondition - Constraint t = new ArrayConstraint(se, c, ae); - t.and = header; - header = t; - count++; + Constraint t; + flagSolved = false; + t = new ArrayConstraint(se, c, ae); + prependUnlessRepeated(t); } - public void _addDet(Comparator c, SelectExpression se, RealExpression ae) { - Constraint t = new RealArrayConstraint(se, c, ae); - t.and = header; - header = t; - count ++; + //Added by Aymeric + public void _addDet(Comparator c, SelectExpression se, RealExpression re) { + Constraint t; + flagSolved = false; + t = new RealArrayConstraint(se, c, re); + prependUnlessRepeated(t); } + //Added by Aymeric public void _addDet(Comparator c, RealStoreExpression se, ArrayExpression ae) { - Constraint t = new RealArrayConstraint(se, c, ae); - t.and = header; - header = t; - count ++; + Constraint t; + flagSolved = false; + t = new RealArrayConstraint(se, c, ae); + prependUnlessRepeated(t); } - // End array - //Added by Gideon public void _addDet (LogicalORLinearIntegerConstraints loic) { //throw new RuntimeException ("Not being used right now"); @@ -160,33 +161,21 @@ else if (l instanceof RealExpression && r instanceof RealExpression) } // constraints on integers - public void _addDet(Comparator c, IntegerExpression l, int r) { - flagSolved = false; // C - _addDet(c, l, new IntegerConstant(r)); - } - - public void _addDet(Comparator c, int l, IntegerExpression r) { - flagSolved = false; // C - _addDet(c, new IntegerConstant(l), r); - } - public void _addDet(Comparator c, IntegerExpression l, long r) { flagSolved = false; // C - _addDet(c, l, new IntegerConstant((int)r)); - //_addDet(c, l, (int)r); + _addDet(c, l, new IntegerConstant(r)); } public void _addDet(Comparator c, long l, IntegerExpression r) { flagSolved = false; // C - _addDet(c, new IntegerConstant((int)l), r); - //_addDet(c, (int)l, r); + _addDet(c, new IntegerConstant(l), r); } public void _addDet(Comparator c, IntegerExpression l, IntegerExpression r) { Constraint t; flagSolved = false; - if ((l instanceof LinearIntegerExpression) && (r instanceof LinearIntegerExpression)) { + if ((l instanceof LinearIntegerExpression) && (r instanceof LinearIntegerExpression)) { t = new LinearIntegerConstraint(l, c, r); } else { t = new NonLinearIntegerConstraint(l, c, r); @@ -422,7 +411,11 @@ public String toString() { //return ((header == null) ? "" : " " + header.toString()); -- for specialization //+ "\n" + spc.toString(); // TODO: to review } - + public String prefix_notation() { + return "constraint # = " + count + ((header == null) ? "" : "\n" + header.prefix_notation()); + //return ((header == null) ? "" : " " + header.toString()); -- for specialization + //+ "\n" + spc.toString(); // TODO: to review + } public static PathCondition getPC(MJIEnv env) { VM vm = env.getVM(); return getPC(vm); diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/PreCondition.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/PreCondition.java index b890824..85c9cd0 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/PreCondition.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/PreCondition.java @@ -92,7 +92,7 @@ private void addExpression(String expressionString, String rhs = ""; Expression lhsExpression = null; Expression rhsExpression = null; - int lhsInt, rhsInt; + long lhsInt, rhsInt; double lhsDouble, rhsDouble; if (expressionString.contains("!=")){ @@ -136,7 +136,7 @@ private void addExpression(String expressionString, else { // expect a number here try{ - lhsInt = Integer.parseInt(lhs); + lhsInt = Long.parseLong(lhs); lhsExpression = new IntegerConstant(lhsInt); } catch(Exception e1){ @@ -156,7 +156,7 @@ private void addExpression(String expressionString, else { //expect a number here try{ - rhsInt = Integer.parseInt(rhs); + rhsInt = Long.parseLong(rhs); rhsExpression = new IntegerConstant(rhsInt); } catch(Exception e1){ diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/RealConstant.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/RealConstant.java index 77444ff..67b6b8b 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/RealConstant.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/RealConstant.java @@ -165,7 +165,12 @@ public boolean equals (Object o) { public String toString () { return "CONST_" + value + ""; } - + + public String prefix_notation () + { + return ""+value; + } + public String stringPC () { return "CONST_" + value + ""; } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/SymbolicConstraintsGeneral.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/SymbolicConstraintsGeneral.java index e765db4..5a9cb36 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/SymbolicConstraintsGeneral.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/SymbolicConstraintsGeneral.java @@ -37,25 +37,18 @@ package gov.nasa.jpf.symbc.numeric; +import gov.nasa.jpf.symbc.SymbolicInstructionFactory; +import gov.nasa.jpf.symbc.numeric.solvers.*; +//import gov.nasa.jpf.symbc.numeric.solvers.ProblemChoco2; + + +import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; - -import gov.nasa.jpf.Config; -import gov.nasa.jpf.symbc.SymbolicInstructionFactory; -import gov.nasa.jpf.symbc.numeric.solvers.DebugSolvers; -import gov.nasa.jpf.symbc.numeric.solvers.ProblemCVC3; -import gov.nasa.jpf.symbc.numeric.solvers.ProblemCVC3BitVector; -import gov.nasa.jpf.symbc.numeric.solvers.ProblemChoco; -import gov.nasa.jpf.symbc.numeric.solvers.ProblemCompare; -//import gov.nasa.jpf.symbc.numeric.solvers.ProblemChoco2; -import gov.nasa.jpf.symbc.numeric.solvers.ProblemCoral; -import gov.nasa.jpf.symbc.numeric.solvers.ProblemDReal; -import gov.nasa.jpf.symbc.numeric.solvers.ProblemGeneral; -import gov.nasa.jpf.symbc.numeric.solvers.ProblemIAsolver; -import gov.nasa.jpf.symbc.numeric.solvers.ProblemYices; -import gov.nasa.jpf.symbc.numeric.solvers.ProblemZ3; +import java.util.Map.Entry; // generalized to use different constraint solvers/decision procedures @@ -66,7 +59,7 @@ public class SymbolicConstraintsGeneral { protected ProblemGeneral pb; protected Boolean result; // tells whether result is satisfiable or not - public boolean isSatisfiable(final PathCondition pc) { + public boolean isSatisfiable(PathCondition pc) { if (pc == null || pc.count == 0) { if (SymbolicInstructionFactory.debugMode) System.out.println("## Warning: empty path condition"); @@ -87,34 +80,36 @@ public boolean isSatisfiable(final PathCondition pc) { // if (SymbolicInstructionFactory.debugMode) // System.out.println("checking: PC "+pc); - final String[] dp = SymbolicInstructionFactory.dp; + String[] dp = SymbolicInstructionFactory.dp; if(dp == null) { // default: use choco pb = new ProblemChoco(); } else if(dp[0].equalsIgnoreCase("choco")){ pb = new ProblemChoco(); // } else if(dp[0].equalsIgnoreCase("choco2")){ // pb = new ProblemChoco2(); - } else if(dp[0].equalsIgnoreCase("coral")){ - pb = new ProblemCoral(); - } else if(dp[0].equalsIgnoreCase("dreal")){ - // Added for dReal by Nima - pb = ProblemDReal.createInstance(new Config(new String[]{})); - } + } else if(dp[0].equalsIgnoreCase("coral")){ + pb = new ProblemCoral(); + } else if(dp[0].equalsIgnoreCase("iasolver")){ pb = new ProblemIAsolver(); } else if(dp[0].equalsIgnoreCase("cvc3")){ pb = new ProblemCVC3(); } else if (dp[0].equalsIgnoreCase("cvc3bitvec")) { pb = new ProblemCVC3BitVector(); - } else if (dp[0].equalsIgnoreCase("yices")) { + } else if (dp[0].equalsIgnoreCase("yices")) { pb = new ProblemYices(); } else if(dp[0].equalsIgnoreCase("z3")){ pb = new ProblemZ3(); - - } else if (dp[0].equalsIgnoreCase("debug")) { + } else if(dp[0].equalsIgnoreCase("z3inc")){ + pb = new ProblemZ3Incremental(); + } else if(dp[0].equalsIgnoreCase("z3bitvectorinc")){ + pb = new ProblemZ3BitVectorIncremental(); + } else if (dp[0].equalsIgnoreCase("debug")) { pb = new DebugSolvers(pc); } else if (dp[0].equalsIgnoreCase("compare")){ pb = new ProblemCompare(pc, this); + } else if (dp[0].equalsIgnoreCase("z3bitvector")){ + pb = new ProblemZ3BitVector(); } // added option to have no-solving // as a result symbolic execution will explore an over-approximation of the program paths @@ -156,7 +151,7 @@ else if (dp[0].equalsIgnoreCase("no_solver")) { } - public boolean isSatisfiableGreen(final PathCondition pc) { + public boolean isSatisfiableGreen(PathCondition pc) { if (pc == null || pc.count == 0) { if (SymbolicInstructionFactory.debugMode) System.out.println("## Warning: empty path condition"); @@ -187,18 +182,22 @@ public void cleanup () { ((ProblemCVC3) pb).cleanup(); } else if (pb instanceof ProblemCoral) { ((ProblemCoral) pb).cleanup(); + } else if (pb instanceof ProblemZ3) { + ((ProblemZ3) pb).cleanup(); + } else if (pb instanceof ProblemZ3BitVector) { + ((ProblemZ3BitVector) pb).cleanup(); } } - public boolean solve(final PathCondition pc) { + public boolean solve(PathCondition pc) { //if (SymbolicInstructionFactory.debugMode) //System.out.println("solving: PC " + pc); if (pc == null || pc.count == 0) return true; - final String[] dp = SymbolicInstructionFactory.dp; + String[] dp = SymbolicInstructionFactory.dp; if (dp[0].equalsIgnoreCase("no_solver")) return true; @@ -220,22 +219,22 @@ public boolean solve(final PathCondition pc) { sym_realvar_mappings = PCParser.symRealVar.entrySet(); i_real = sym_realvar_mappings.iterator(); while(i_real.hasNext()) { - final Entry e = i_real.next(); - final SymbolicReal pcVar = e.getKey(); - final Object dpVar = e.getValue(); + Entry e = i_real.next(); + SymbolicReal pcVar = e.getKey(); + Object dpVar = e.getValue(); pcVar.solution=pb.getRealValue(dpVar); // may be undefined: throws an exception } - } catch (final Exception exp) { + } catch (Exception exp) { this.catchBody(PCParser.symRealVar, pb, pc); } // end catch // compute solutions for integer variables - final Set> sym_intvar_mappings = PCParser.symIntegerVar.entrySet(); - final Iterator> i_int = sym_intvar_mappings.iterator(); + Set> sym_intvar_mappings = PCParser.symIntegerVar.entrySet(); + Iterator> i_int = sym_intvar_mappings.iterator(); //try { while(i_int.hasNext()) { - final Entry e = i_int.next(); + Entry e = i_int.next(); e.getKey().solution=pb.getIntValue(e.getValue()); } @@ -275,7 +274,7 @@ public boolean solve(final PathCondition pc) { * deal with yices and choco refinements of * solution ranges. */ - public Map catchBody(final Map realVars, final ProblemGeneral prob, final PathCondition pc) { + public Map catchBody(Map realVars, ProblemGeneral prob, PathCondition pc) { Set> sym_realvar_mappings; Iterator> i_real; @@ -285,14 +284,14 @@ public Map catchBody(final Map realV // Solve the problem to get new ranges of values for the remaining // variables. - final Boolean isSolvable = true; + Boolean isSolvable = true; sym_realvar_mappings = realVars.entrySet(); i_real = sym_realvar_mappings.iterator(); while (i_real.hasNext() && isSolvable) { - final Entry e = i_real.next(); - final SymbolicReal pcVar = e.getKey(); - final Object dpVar = e.getValue(); + Entry e = i_real.next(); + SymbolicReal pcVar = e.getKey(); + Object dpVar = e.getValue(); // Note: using solution_inf or solution_sup alone sometimes fails // because of floating point inaccuracies diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/SymbolicInteger.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/SymbolicInteger.java index cfcf559..2da82b0 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/SymbolicInteger.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/SymbolicInteger.java @@ -38,17 +38,17 @@ package gov.nasa.jpf.symbc.numeric; import gov.nasa.jpf.symbc.SymbolicInstructionFactory; - + import java.util.Map; import java.util.Random; public class SymbolicInteger extends LinearIntegerExpression { - public static int UNDEFINED = Integer.MIN_VALUE;; - public int _min = 0; - public int _max = 0; - public int solution = UNDEFINED; // C - + public static long UNDEFINED = Long.MIN_VALUE; + public long _min = 0; + public long _max = 0; + public long solution = UNDEFINED; // C + int unique_id; public static String SYM_INT_SUFFIX = "_SYMINT"; @@ -60,7 +60,9 @@ public SymbolicInteger () { PathCondition.flagSolved=false; name = "INT_" + hashCode(); _min = MinMax.getVarMinInt(name); - _max = MinMax.getVarMaxInt(name); + _max = MinMax.getVarMaxInt(name); + if (SymbolicInstructionFactory.debugMode) + System.out.println("New sym int " + name + " min=" + _min + ", max=" + _max); } public SymbolicInteger (String s) { @@ -70,20 +72,23 @@ public SymbolicInteger (String s) { name = s; _min = MinMax.getVarMinInt(name); _max = MinMax.getVarMaxInt(name); - //trackedSymVars.add(fixName(name)); - + //trackedSymVars.add(fixName(name)); + if (SymbolicInstructionFactory.debugMode) + System.out.println("New sym int " + name + " min=" + _min + ", max=" + _max); } - public SymbolicInteger (int l, int u) { + public SymbolicInteger (long l, long u) { super(); unique_id = MinMax.UniqueId++; _min = l; _max = u; //PathCondition.flagSolved=false; - name = "INT_" + hashCode(); + name = "INT_" + hashCode(); + if (SymbolicInstructionFactory.debugMode) + System.out.println("New sym int " + name + " min=" + _min + ", max=" + _max); } - public SymbolicInteger (String s, int l, int u) { + public SymbolicInteger (String s, long l, long u) { super(); unique_id = MinMax.UniqueId++; _min = l; @@ -91,10 +96,10 @@ public SymbolicInteger (String s, int l, int u) { name = s; //PathCondition.flagSolved=false; //trackedSymVars.add(fixName(name)); - - } - - + if (SymbolicInstructionFactory.debugMode) + System.out.println("New sym int " + name + " min=" + _min + ", max=" + _max); + } + public String getName() { return (name != null) ? name : "INT_" + hashCode(); } @@ -111,12 +116,17 @@ public String toString () { return (name != null) ? name + "[" + solution + "]" : "INT_" + hashCode() + "[" + solution + "]"; } + } + + public String prefix_notation () + { + return (name != null) ? name : "INT_" + hashCode(); } - public int solution() { + public long solution() { if (PathCondition.flagSolved) { if (solution == UNDEFINED && SymbolicInstructionFactory.concolicMode) { - solution = (new Random().nextInt(_max-_min))+_min; + solution = (new Random().nextLong() % (_max-_min)) + _min; } return solution; } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/SymbolicReal.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/SymbolicReal.java index a7842a3..6ed6f1a 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/SymbolicReal.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/SymbolicReal.java @@ -38,7 +38,7 @@ package gov.nasa.jpf.symbc.numeric; import gov.nasa.jpf.symbc.SymbolicInstructionFactory; - + import java.util.Map; import java.util.Random; @@ -113,7 +113,11 @@ public String toString () { // "REAL_" + hashCode() + "[" + + solution_inf + "," + solution_sup + "]"; } } - + + public String prefix_notation () + { + return (name != null) ? name : "REAL_" + hashCode(); + } public double solution() { if (PathCondition.flagSolved) { diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/DebugSolvers.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/DebugSolvers.java index 854ad3b..7814129 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/DebugSolvers.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/DebugSolvers.java @@ -56,7 +56,7 @@ public void setConstraint(int i, Object o) { } @Override - public Object and(int value, Object exp) { + public Object and(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].and(value, ((SolverObjects) exp) @@ -66,7 +66,7 @@ public Object and(int value, Object exp) { } @Override - public Object and(Object exp, int value) { + public Object and(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].and(((SolverObjects) exp) @@ -88,7 +88,7 @@ public Object and(Object exp1, Object exp2) { } @Override - public Object div(int value, Object exp) { + public Object div(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].div(value, ((SolverObjects) exp) @@ -98,7 +98,7 @@ public Object div(int value, Object exp) { } @Override - public Object div(Object exp, int value) { + public Object div(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].div(((SolverObjects) exp) @@ -140,7 +140,7 @@ public Object div(Object exp, double value) { } @Override - public Object eq(int value, Object exp) { + public Object eq(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].eq(value, ((SolverObjects) exp) @@ -150,7 +150,7 @@ public Object eq(int value, Object exp) { } @Override - public Object eq(Object exp, int value) { + public Object eq(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].eq(((SolverObjects) exp) @@ -192,7 +192,7 @@ public Object eq(Object exp, double value) { } @Override - public Object geq(int value, Object exp) { + public Object geq(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].geq(value, ((SolverObjects) exp) @@ -202,7 +202,7 @@ public Object geq(int value, Object exp) { } @Override - public Object geq(Object exp, int value) { + public Object geq(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].geq(((SolverObjects) exp) @@ -244,7 +244,7 @@ public Object geq(Object exp, double value) { } @Override - public int getIntValue(Object dpVar) { + public long getIntValue(Object dpVar) { return probs[0].getIntValue(((SolverObjects) dpVar).getConstraint(0)); } @@ -264,7 +264,7 @@ public double getRealValueSup(Object dpVar) { } @Override - public Object gt(int value, Object exp) { + public Object gt(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].gt(value, ((SolverObjects) exp) @@ -274,7 +274,7 @@ public Object gt(int value, Object exp) { } @Override - public Object gt(Object exp, int value) { + public Object gt(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].gt(((SolverObjects) exp) @@ -316,7 +316,7 @@ public Object gt(Object exp, double value) { } @Override - public Object leq(int value, Object exp) { + public Object leq(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].leq(value, ((SolverObjects) exp) @@ -326,7 +326,7 @@ public Object leq(int value, Object exp) { } @Override - public Object leq(Object exp, int value) { + public Object leq(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].leq(((SolverObjects) exp) @@ -367,7 +367,7 @@ public Object leq(Object exp, double value) { } @Override - public Object lt(int value, Object exp) { + public Object lt(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].lt(value, ((SolverObjects) exp) @@ -377,7 +377,7 @@ public Object lt(int value, Object exp) { } @Override - public Object lt(Object exp, int value) { + public Object lt(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].lt(((SolverObjects) exp) @@ -419,7 +419,7 @@ public Object lt(Object exp, double value) { } @Override - public Object makeIntVar(String name, int min, int max) { + public Object makeIntVar(String name, long min, long max) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].makeIntVar(name, min, max)); @@ -437,7 +437,7 @@ public Object makeRealVar(String name, double min, double max) { } @Override - public Object minus(int value, Object exp) { + public Object minus(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].minus(value, ((SolverObjects) exp) @@ -447,7 +447,7 @@ public Object minus(int value, Object exp) { } @Override - public Object minus(Object exp, int value) { + public Object minus(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].minus(((SolverObjects) exp) @@ -501,7 +501,7 @@ public Object mixed(Object exp1, Object exp2) { } @Override - public Object mult(int value, Object exp) { + public Object mult(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].mult(value, ((SolverObjects) exp) @@ -511,7 +511,7 @@ public Object mult(int value, Object exp) { } @Override - public Object mult(Object exp, int value) { + public Object mult(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].mult(((SolverObjects) exp) @@ -553,7 +553,7 @@ public Object mult(Object exp, double value) { } @Override - public Object neq(int value, Object exp) { + public Object neq(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].neq(value, ((SolverObjects) exp) @@ -563,7 +563,7 @@ public Object neq(int value, Object exp) { } @Override - public Object neq(Object exp, int value) { + public Object neq(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].neq(((SolverObjects) exp) @@ -605,7 +605,7 @@ public Object neq(Object exp, double value) { } @Override - public Object or(int value, Object exp) { + public Object or(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].or(value, ((SolverObjects) exp) @@ -615,7 +615,7 @@ public Object or(int value, Object exp) { } @Override - public Object or(Object exp, int value) { + public Object or(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].or(((SolverObjects) exp) @@ -637,7 +637,7 @@ public Object or(Object exp1, Object exp2) { } @Override - public Object plus(int value, Object exp) { + public Object plus(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].plus(value, ((SolverObjects) exp) @@ -647,7 +647,7 @@ public Object plus(int value, Object exp) { } @Override - public Object plus(Object exp, int value) { + public Object plus(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].plus(((SolverObjects) exp) @@ -696,7 +696,7 @@ public void post(Object constraint) { } @Override - public Object shiftL(int value, Object exp) { + public Object shiftL(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].shiftL(value, ((SolverObjects) exp) @@ -706,7 +706,7 @@ public Object shiftL(int value, Object exp) { } @Override - public Object shiftL(Object exp, int value) { + public Object shiftL(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].shiftL(((SolverObjects) exp) @@ -728,7 +728,7 @@ public Object shiftL(Object exp1, Object exp2) { } @Override - public Object shiftR(int value, Object exp) { + public Object shiftR(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].shiftR(value, ((SolverObjects) exp) @@ -738,7 +738,7 @@ public Object shiftR(int value, Object exp) { } @Override - public Object shiftR(Object exp, int value) { + public Object shiftR(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].shiftR(((SolverObjects) exp) @@ -760,7 +760,7 @@ public Object shiftR(Object exp1, Object exp2) { } @Override - public Object shiftUR(int value, Object exp) { + public Object shiftUR(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].shiftUR(value, ((SolverObjects) exp) @@ -770,7 +770,7 @@ public Object shiftUR(int value, Object exp) { } @Override - public Object shiftUR(Object exp, int value) { + public Object shiftUR(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].shiftUR(((SolverObjects) exp) @@ -831,7 +831,7 @@ Boolean solve() { } @Override - public Object xor(int value, Object exp) { + public Object xor(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].xor(value, ((SolverObjects) exp) @@ -841,7 +841,7 @@ public Object xor(int value, Object exp) { } @Override - public Object xor(Object exp, int value) { + public Object xor(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].xor(((SolverObjects) exp) @@ -865,4 +865,22 @@ public void postLogicalOR(Object[] constraint) { throw new RuntimeException("## Error LogicalOR not implemented"); } + @Override + public Object rem(Object exp1, Object exp2) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object rem(long exp1, Object exp2) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object rem(Object exp1, long exp2) { + // TODO Auto-generated method stub + return null; + } + } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemCVC3.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemCVC3.java index 5a4eef7..b6cfe5f 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemCVC3.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemCVC3.java @@ -46,7 +46,6 @@ import symlib.SymBool; import symlib.Util; - import cvc3.Expr; import cvc3.ExprMut; import cvc3.FlagsMut; @@ -57,7 +56,9 @@ //import cvc3.SatResult; import cvc3.Type; import cvc3.ValidityChecker; - +/* Rody: add typecasts long->int everywhere now. Needs a nice solution where the user + * is notified to use another solver with longs. + */ public class ProblemCVC3 extends ProblemGeneral { protected Expr pb; protected ValidityChecker vc = null; @@ -92,10 +93,11 @@ public void cleanup(){ //if min or max are passed in as null objects to the vc //it will use minus and plus infinity - public Object makeIntVar(String name, int min, int max) { + public Object makeIntVar(String name, long min, long max) { + assert(min>=Integer.MIN_VALUE && max<=Integer.MAX_VALUE); try{ - Type sType = vc.subrangeType(vc.ratExpr(min), - vc.ratExpr(max)); + Type sType = vc.subrangeType(vc.ratExpr((int) min), + vc.ratExpr((int) max)); return vc.varExpr(name, sType); } catch (Exception e) { e.printStackTrace(); @@ -126,9 +128,9 @@ public Object makeRealVar(String name, double min, double max) { } } - public Object eq(int value, Object exp){ + public Object eq(long value, Object exp){ try{ - return vc.eqExpr(vc.ratExpr(value), (Expr)exp); + return vc.eqExpr(vc.ratExpr((int) value), (Expr)exp); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); @@ -136,9 +138,9 @@ public Object eq(int value, Object exp){ } } - public Object eq(Object exp, int value){ + public Object eq(Object exp, long value){ try{ - return vc.eqExpr((Expr)exp, vc.ratExpr(value)); + return vc.eqExpr((Expr)exp, vc.ratExpr((int) value)); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); @@ -176,9 +178,9 @@ public Object eq(Object exp, double value){ } } - public Object neq(int value, Object exp){ + public Object neq(long value, Object exp){ try{ - return vc.notExpr(vc. eqExpr(vc.ratExpr(value), (Expr)exp)); + return vc.notExpr(vc. eqExpr(vc.ratExpr((int) value), (Expr)exp)); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); @@ -186,9 +188,9 @@ public Object neq(int value, Object exp){ } } - public Object neq(Object exp, int value){ + public Object neq(Object exp, long value){ try{ - return vc.notExpr(vc.eqExpr((Expr)exp, vc.ratExpr(value))); + return vc.notExpr(vc.eqExpr((Expr)exp, vc.ratExpr((int) value))); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); @@ -236,9 +238,9 @@ public Object neq(Object exp, double value){ } } - public Object leq(int value, Object exp){ + public Object leq(long value, Object exp){ try{ - return vc.leExpr(vc.ratExpr(value), (Expr)exp); + return vc.leExpr(vc.ratExpr((int) value), (Expr)exp); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); @@ -246,9 +248,9 @@ public Object leq(int value, Object exp){ } } - public Object leq(Object exp, int value){ + public Object leq(Object exp, long value){ try{ - return vc.leExpr((Expr)exp, vc.ratExpr(value)); + return vc.leExpr((Expr)exp, vc.ratExpr((int) value)); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); @@ -286,9 +288,9 @@ public Object leq(Object exp, double value){ } } - public Object geq(int value, Object exp){ + public Object geq(long value, Object exp){ try{ - return vc.geExpr(vc.ratExpr(value), (Expr)exp); + return vc.geExpr(vc.ratExpr((int) value), (Expr)exp); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); @@ -296,9 +298,9 @@ public Object geq(int value, Object exp){ } } - public Object geq(Object exp, int value){ + public Object geq(Object exp, long value){ try{ - return vc.geExpr((Expr)exp, vc.ratExpr(value)); + return vc.geExpr((Expr)exp, vc.ratExpr((int) value)); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); @@ -336,9 +338,9 @@ public Object geq(Object exp, double value){ } } - public Object lt(int value, Object exp){ + public Object lt(long value, Object exp){ try{ - return vc.ltExpr(vc.ratExpr(value), (Expr)exp); + return vc.ltExpr(vc.ratExpr((int) value), (Expr)exp); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); @@ -346,9 +348,9 @@ public Object lt(int value, Object exp){ } } - public Object lt(Object exp, int value){ + public Object lt(Object exp, long value){ try{ - return vc.ltExpr((Expr)exp, vc.ratExpr(value)); + return vc.ltExpr((Expr)exp, vc.ratExpr((int) value)); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); @@ -387,9 +389,9 @@ public Object lt(Object exp, double value){ } - public Object gt(int value, Object exp){ + public Object gt(long value, Object exp){ try{ - return vc.gtExpr(vc.ratExpr(value), (Expr)exp); + return vc.gtExpr(vc.ratExpr((int) value), (Expr)exp); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); @@ -397,9 +399,9 @@ public Object gt(int value, Object exp){ } } - public Object gt(Object exp, int value){ + public Object gt(Object exp, long value){ try{ - return vc.gtExpr((Expr)exp, vc.ratExpr(value)); + return vc.gtExpr((Expr)exp, vc.ratExpr((int) value)); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); @@ -450,18 +452,18 @@ public Object gt(Object exp, double value){ - public Object plus(int value, Object exp) { + public Object plus(long value, Object exp) { try{ - return vc.plusExpr(vc.ratExpr(value), (Expr)exp); + return vc.plusExpr(vc.ratExpr((int) value), (Expr)exp); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); } } - public Object plus(Object exp, int value) { + public Object plus(Object exp, long value) { try{ - return vc.plusExpr((Expr)exp, vc.ratExpr(value)); + return vc.plusExpr((Expr)exp, vc.ratExpr((int) value)); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); @@ -495,18 +497,18 @@ public Object plus(Object exp, double value) { } } - public Object minus(int value, Object exp) { + public Object minus(long value, Object exp) { try{ - return vc.minusExpr(vc.ratExpr(value), (Expr)exp); + return vc.minusExpr(vc.ratExpr((int) value), (Expr)exp); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); } } - public Object minus(Object exp, int value) { + public Object minus(Object exp, long value) { try{ - return vc.minusExpr((Expr)exp, vc.ratExpr(value)); + return vc.minusExpr((Expr)exp, vc.ratExpr((int) value)); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); @@ -540,18 +542,18 @@ public Object minus(Object exp, double value) { } } - public Object mult(int value, Object exp) { + public Object mult(long value, Object exp) { try{ - return vc.multExpr(vc.ratExpr(value), (Expr)exp); + return vc.multExpr(vc.ratExpr((int) value), (Expr)exp); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); } } - public Object mult(Object exp, int value) { + public Object mult(Object exp, long value) { try{ - return vc.multExpr((Expr)exp, vc.ratExpr(value)); + return vc.multExpr((Expr)exp, vc.ratExpr((int) value)); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); @@ -585,18 +587,18 @@ public Object mult(Object exp, double value) { //TODO - public Object div(int value, Object exp) { + public Object div(long value, Object exp) { try{ - return vc.divideExpr(vc.ratExpr(value), (Expr)exp); + return vc.divideExpr(vc.ratExpr((int) value), (Expr)exp); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); } } - public Object div(Object exp, int value) { + public Object div(Object exp, long value) { try{ - return vc.divideExpr((Expr)exp, vc.ratExpr(value)); + return vc.divideExpr((Expr)exp, vc.ratExpr((int) value)); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); @@ -720,7 +722,7 @@ public double getRealValue(Object dpVar) { //not done yet for cvc3 } } - public int getIntValue(Object dpVar) { //not done yet for cvc3 + public long getIntValue(Object dpVar) { //not done yet for cvc3 try{ Expr exp = (Expr)model.get((Expr)dpVar); Rational val = exp.getRational(); @@ -808,11 +810,11 @@ public void postOr(Object constraint) { } } - public Object and(int value, Object exp) { + public Object and(long value, Object exp) { throw new RuntimeException("## Switch to CVC3BitVec"); } - public Object and(Object exp, int value) { + public Object and(Object exp, long value) { throw new RuntimeException("## Switch to CVC3BitVec"); } @@ -820,11 +822,11 @@ public Object and(Object exp1, Object exp2) { throw new RuntimeException("## Switch to CVC3BitVec"); } - public Object or(int value, Object exp) { + public Object or(long value, Object exp) { throw new RuntimeException("## Switch to CVC3BitVec"); } - public Object or(Object exp, int value) { + public Object or(Object exp, long value) { throw new RuntimeException("## Switch to CVC3BitVec"); } @@ -832,27 +834,27 @@ public Object or(Object exp1, Object exp2) { throw new RuntimeException("## Switch to CVC3BitVec"); } - public Object shiftL(int value, Object exp) { + public Object shiftL(long value, Object exp) { throw new RuntimeException("## Switch to CVC3BitVec"); } - public Object shiftL(Object exp, int value) { + public Object shiftL(Object exp, long value) { throw new RuntimeException("## Switch to CVC3BitVec"); } - public Object shiftR(int value, Object exp) { + public Object shiftR(long value, Object exp) { throw new RuntimeException("## Switch to CVC3BitVec"); } - public Object shiftR(Object exp, int value) { + public Object shiftR(Object exp, long value) { throw new RuntimeException("## Switch to CVC3BitVec"); } - public Object xor(int value, Object exp) { + public Object xor(long value, Object exp) { throw new RuntimeException("## Switch to CVC3BitVec"); } - public Object xor(Object exp, int value) { + public Object xor(Object exp, long value) { throw new RuntimeException("## Switch to CVC3BitVec"); } @@ -868,11 +870,11 @@ public Object shiftR(Object exp1, Object exp2) { throw new RuntimeException("## Switch to CVC3BitVec"); } - public Object shiftUR(int value, Object exp) { + public Object shiftUR(long value, Object exp) { throw new RuntimeException("## Switch to CVC3BitVec"); } - public Object shiftUR(Object exp, int value) { + public Object shiftUR(Object exp, long value) { throw new RuntimeException("## Switch to CVC3BitVec"); } @@ -893,4 +895,22 @@ public void postLogicalOR(Object[] constraints) { } + @Override + public Object rem(Object exp1, Object exp2) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object rem(long exp1, Object exp2) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object rem(Object exp1, long exp2) { + // TODO Auto-generated method stub + return null; + } + } \ No newline at end of file diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemCVC3BitVector.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemCVC3BitVector.java index 0e15b78..b3a0316 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemCVC3BitVector.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemCVC3BitVector.java @@ -45,7 +45,9 @@ import cvc3.Expr; import cvc3.Rational; import cvc3.Type; - +/* Rody: add typecasts long->int everywhere now. Needs a nice solution where the user + * is notified to use another solver with longs. + */ public class ProblemCVC3BitVector extends ProblemCVC3 { public Object makeBitVectorVar(String name, int N) { @@ -59,7 +61,7 @@ public Object makeBitVectorVar(String name, int N) { - public Object and(int value, Object exp) { + public Object and(long value, Object exp) { try { Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -69,7 +71,7 @@ public Object and(int value, Object exp) { } } - public Object and(Object exp, int value) { + public Object and(Object exp, long value) { try { Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -88,7 +90,7 @@ public Object and(Object exp1, Object exp2) { } - public Object or(int value, Object exp) { + public Object or(long value, Object exp) { try { Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -99,7 +101,7 @@ public Object or(int value, Object exp) { } - public Object or(Object exp, int value) { + public Object or(Object exp, long value) { try { Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -119,18 +121,18 @@ public Object or(Object exp1, Object exp2) { } - public Object shiftL(int value, Object exp) { + public Object shiftL(long value, Object exp) { try { - return vc.newFixedLeftShiftExpr((Expr) exp, value); + return vc.newFixedLeftShiftExpr((Expr) exp, (int) value); } catch (Exception e) { throw new RuntimeException("## Error CVC3BitVector "); } } - public Object shiftL(Object exp, int value) { + public Object shiftL(Object exp, long value) { try { - return vc.newFixedLeftShiftExpr((Expr) exp, value); + return vc.newFixedLeftShiftExpr((Expr) exp, (int) value); } catch (Exception e) { throw new RuntimeException("## Error CVC3BitVector "); } @@ -145,18 +147,18 @@ public Object shiftL(Object exp1, Object exp2) { } } - public Object shiftR(int value, Object exp) { + public Object shiftR(long value, Object exp) { try { - return vc.newFixedRightShiftExpr((Expr) exp, value); + return vc.newFixedRightShiftExpr((Expr) exp, (int) value); } catch (Exception e) { throw new RuntimeException("## Error CVC3BitVector "); } } - public Object shiftR(Object exp, int value) { + public Object shiftR(Object exp, long value) { try { - return vc.newFixedRightShiftExpr((Expr) exp, value); + return vc.newFixedRightShiftExpr((Expr) exp, (int) value); } catch (Exception e) { throw new RuntimeException("## Error CVC3BitVector "); } @@ -169,14 +171,14 @@ public Object shiftR(Object exp1, Object exp2) { throw new RuntimeException("## Error CVC3BitVector "); } } - public Object shiftUR(int value, Object exp) { + public Object shiftUR(long value, Object exp) { try { Rational val = new Rational(Long.toString( (0xffffffffL << (32 - value)) ^ (0xffffffffL << (32 - value))), vc.embeddedManager()); - return vc.newBVAndExpr(vc.newFixedRightShiftExpr((Expr) exp, value), + return vc.newBVAndExpr(vc.newFixedRightShiftExpr((Expr) exp, (int) value), vc.newBVConstExpr(val, 32)); } catch (Exception e) { @@ -185,14 +187,14 @@ public Object shiftUR(int value, Object exp) { } - public Object shiftUR(Object exp, int value) { + public Object shiftUR(Object exp, long value) { try { Rational val = new Rational(Long.toString( (0xffffffffL << (32 - value)) ^ (0xffffffffL << (32 - value))), vc.embeddedManager()); - return vc.newBVAndExpr(vc.newFixedRightShiftExpr((Expr) exp, value), + return vc.newBVAndExpr(vc.newFixedRightShiftExpr((Expr) exp, (int) value), vc.newBVConstExpr(val, 32)); } catch (Exception e) { @@ -204,7 +206,7 @@ public Object shiftUR(Object exp1, Object exp2) { throw new RuntimeException("## Shifting by an expression not supported by CVC3"); } - public Object xor(int value, Object exp) { + public Object xor(long value, Object exp) { try { //Integer.toString(value); Rational val = new Rational(Long.toString( value & 0xffffffffL ), @@ -215,7 +217,7 @@ public Object xor(int value, Object exp) { } } - public Object xor(Object exp, int value) { + public Object xor(Object exp, long value) { try { Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -235,7 +237,7 @@ public Object xor(Object exp1, Object exp2) { } - public Object div(int value, Object exp) { + public Object div(long value, Object exp) { try{ Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -247,7 +249,7 @@ public Object div(int value, Object exp) { } - public Object div(Object exp, int value) { + public Object div(Object exp, long value) { try{ Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -280,7 +282,7 @@ public Object div(Object exp, double value) { } - public Object eq(int value, Object exp) { + public Object eq(long value, Object exp) { try { Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -291,7 +293,7 @@ public Object eq(int value, Object exp) { } - public Object eq(Object exp, int value) { + public Object eq(Object exp, long value) { try { Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -333,7 +335,7 @@ public Object eq(Object exp, double value) { } - public Object geq(int value, Object exp) { + public Object geq(long value, Object exp) { try { Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -344,7 +346,7 @@ public Object geq(int value, Object exp) { } - public Object geq(Object exp, int value) { + public Object geq(Object exp, long value) { try { Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -376,7 +378,7 @@ public Object geq(Object exp, double value) { } @Override - public int getIntValue(Object dpVar) { + public long getIntValue(Object dpVar) { // TODO Auto-generated method stub return 0; } @@ -399,7 +401,7 @@ public double getRealValueSup(Object dpVar) { return 0; } - public Object gt(int value, Object exp) { + public Object gt(long value, Object exp) { try { Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -409,7 +411,7 @@ public Object gt(int value, Object exp) { } } - public Object gt(Object exp, int value) { + public Object gt(Object exp, long value) { try { Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -441,7 +443,7 @@ public Object gt(Object exp, double value) { } - public Object leq(int value, Object exp) { + public Object leq(long value, Object exp) { try { Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -452,7 +454,7 @@ public Object leq(int value, Object exp) { } - public Object leq(Object exp, int value) { + public Object leq(Object exp, long value) { try { Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -484,7 +486,7 @@ public Object leq(Object exp, double value) { } - public Object lt(int value, Object exp) { + public Object lt(long value, Object exp) { try { Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -495,7 +497,7 @@ public Object lt(int value, Object exp) { } @Override - public Object lt(Object exp, int value) { + public Object lt(Object exp, long value) { try { Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -527,7 +529,7 @@ public Object lt(Object exp, double value) { } @Override - public Object makeIntVar(String name, int min, int max) { + public Object makeIntVar(String name, long min, long max) { return makeBitVectorVar(name, 32); } @@ -538,7 +540,7 @@ public Object makeRealVar(String name, double min, double max) { } - public Object minus(int value, Object exp) { + public Object minus(long value, Object exp) { try{ Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -550,7 +552,7 @@ public Object minus(int value, Object exp) { } - public Object minus(Object exp, int value) { + public Object minus(Object exp, long value) { try{ Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -590,7 +592,7 @@ public Object mixed(Object exp1, Object exp2) { } - public Object mult(int value, Object exp) { + public Object mult(long value, Object exp) { try{ Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -602,7 +604,7 @@ public Object mult(int value, Object exp) { } - public Object mult(Object exp, int value) { + public Object mult(Object exp, long value) { try{ Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -636,7 +638,7 @@ public Object mult(Object exp, double value) { } - public Object neq(int value, Object exp) { + public Object neq(long value, Object exp) { try { Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -647,7 +649,7 @@ public Object neq(int value, Object exp) { } } - public Object neq(Object exp, int value) { + public Object neq(Object exp, long value) { try { Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -680,7 +682,7 @@ public Object neq(Object exp, double value) { throw new RuntimeException("bit vector"); } - public Object plus(int value, Object exp) { + public Object plus(long value, Object exp) { try{ Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); @@ -695,7 +697,7 @@ public Object plus(int value, Object exp) { } - public Object plus(Object exp, int value) { + public Object plus(Object exp, long value) { try{ Rational val = new Rational(Long.toString( value & 0xffffffffL ), vc.embeddedManager()); diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemChoco.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemChoco.java index 94f474c..28daf30 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemChoco.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemChoco.java @@ -45,6 +45,9 @@ import choco.real.*; import choco.real.constraint.MixedEqXY; +/* Rody: add typecasts long->int everywhere now. Needs a nice solution where the user + * is notified to use another solver with longs. + */ public class ProblemChoco extends ProblemGeneral { RealProblem pb; public static int timeBound;// = 30000; @@ -53,8 +56,9 @@ public ProblemChoco() { //pb.setPrecision(1e-8);// need to check this } - public IntDomainVar makeIntVar(String name, int min, int max) { - return pb.makeBoundIntVar(name,min,max); + public IntDomainVar makeIntVar(String name, long min, long max) { + assert(min>=Integer.MIN_VALUE && max<=Integer.MAX_VALUE); + return pb.makeBoundIntVar(name, (int) min, (int) max); } public RealVar makeRealVar(String name, double min, double max) { @@ -70,8 +74,8 @@ public RealVar makeRealVar(String name, double min, double max) { // return pb.or(arr); // } - public Object eq(int value, Object exp){return pb.eq(value, (IntExp)exp);} - public Object eq(Object exp, int value){return pb.eq((IntExp) exp, value);} + public Object eq(long value, Object exp){return pb.eq((int) value, (IntExp)exp);} + public Object eq(Object exp, long value){return pb.eq((IntExp) exp, (int) value);} public Object eq(Object exp1, Object exp2){ if (exp1 instanceof IntExp && exp2 instanceof IntExp ) return pb.eq((IntExp) exp1,(IntExp) exp2); @@ -82,8 +86,8 @@ else if (exp1 instanceof RealExp && exp2 instanceof RealExp) } public Object eq(double value, Object exp){return pb.eq(value, (RealExp) exp);} public Object eq(Object exp, double value){return pb.eq(value, (RealExp) exp);} - public Object neq(int value, Object exp){return pb.neq(value, (IntExp) exp);} - public Object neq(Object exp, int value){return pb.neq(value, (IntExp) exp);} + public Object neq(long value, Object exp){return pb.neq((int) value, (IntExp) exp);} + public Object neq(Object exp, long value){return pb.neq((int) value, (IntExp) exp);} public Object neq(Object exp1, Object exp2){ if (exp1 instanceof IntExp && exp2 instanceof IntExp ) return pb.neq((IntExp) exp1,(IntExp) exp2); @@ -94,8 +98,8 @@ else if (exp1 instanceof RealExp && exp2 instanceof RealExp) } public Object neq(double value, Object exp){return pb.neq(value, (RealExp) exp);} public Object neq(Object exp, double value){return pb.neq(value, (RealExp) exp);} - public Object leq(int value, Object exp){return pb.leq(value,(IntExp)exp);} - public Object leq(Object exp, int value){return pb.leq((IntExp)exp,value);} + public Object leq(long value, Object exp){return pb.leq((int) value,(IntExp)exp);} + public Object leq(Object exp, long value){return pb.leq((IntExp)exp,(int) value);} public Object leq(Object exp1, Object exp2){ if (exp1 instanceof IntExp && exp2 instanceof IntExp ) return pb.leq((IntExp) exp1,(IntExp) exp2); @@ -106,8 +110,8 @@ else if (exp1 instanceof RealExp && exp2 instanceof RealExp) } public Object leq(double value, Object exp){return pb.leq(value,(RealExp)exp);} public Object leq(Object exp, double value){return pb.leq((RealExp)exp, value);} - public Object geq(int value, Object exp){return pb.geq(value, (IntExp)exp);} - public Object geq(Object exp, int value){return pb.geq((IntExp)exp,value);} + public Object geq(long value, Object exp){return pb.geq((int) value, (IntExp)exp);} + public Object geq(Object exp, long value){return pb.geq((IntExp)exp,(int) value);} public Object geq(Object exp1, Object exp2){ if (exp1 instanceof IntExp && exp2 instanceof IntExp ) return pb.geq((IntExp) exp1,(IntExp) exp2); @@ -122,11 +126,11 @@ public Object geq(double value, Object exp){ public Object geq(Object exp, double value){ return pb.geq((RealExp) exp, value); } - public Object lt(int value, Object exp){ - return pb.lt(value, (IntExp) exp); + public Object lt(long value, Object exp){ + return pb.lt((int) value, (IntExp) exp); } - public Object lt(Object exp, int value){ - return pb.lt((IntExp) exp,value); + public Object lt(Object exp, long value){ + return pb.lt((IntExp) exp,(int) value); } public Object lt(Object exp1, Object exp2){ if (exp1 instanceof IntExp && exp2 instanceof IntExp ) @@ -142,11 +146,11 @@ public Object lt(double value, Object exp){ public Object lt(Object exp, double value){ return pb.lt((RealExp) exp,value); } - public Object gt(int value, Object exp){ - return pb.gt(value,(IntExp) exp); + public Object gt(long value, Object exp){ + return pb.gt((int) value,(IntExp) exp); } - public Object gt(Object exp, int value){ - return pb.gt((IntExp) exp,value); + public Object gt(Object exp, long value){ + return pb.gt((IntExp) exp,(int) value); } public Object gt(Object exp1, Object exp2){ if (exp1 instanceof IntExp && exp2 instanceof IntExp ) @@ -163,11 +167,11 @@ public Object gt(Object exp, double value){ return pb.gt((RealExp) exp, value); } - public Object plus(int value, Object exp) { - return pb.plus(value,(IntExp) exp); + public Object plus(long value, Object exp) { + return pb.plus((int) value,(IntExp) exp); } - public Object plus(Object exp, int value) { - return pb.plus((IntExp) exp, value); + public Object plus(Object exp, long value) { + return pb.plus((IntExp) exp, (int) value); } public Object plus(Object exp1, Object exp2) { if (exp1 instanceof IntExp && exp2 instanceof IntExp ) @@ -184,11 +188,11 @@ public Object plus(Object exp, double value) { return pb.plus((RealExp) exp, pb.cst(value)); } - public Object minus(int value, Object exp) { - return pb.minus(value, (IntExp) exp); + public Object minus(long value, Object exp) { + return pb.minus((int) value, (IntExp) exp); } - public Object minus(Object exp, int value) { - return pb.minus((IntExp) exp, value); + public Object minus(Object exp, long value) { + return pb.minus((IntExp) exp, (int) value); } public Object minus(Object exp1, Object exp2) { if (exp1 instanceof IntExp && exp2 instanceof IntExp ) @@ -204,19 +208,19 @@ public Object minus(double value, Object exp) { public Object minus(Object exp, double value) { return pb.minus((RealExp) exp, pb.cst(value)); } - public Object mult(int value, Object exp) { + public Object mult(long value, Object exp) { if (exp instanceof IntVar) - return pb.mult(value, (IntExp) exp); + return pb.mult((int) value, (IntExp) exp); else if (exp instanceof IntTerm) { // distribute value over exp //return pb.mult(value, (IntExp) exp); IntTerm it= (IntTerm) exp; IntTerm constant= new IntTerm(0); - constant.setConstant(value * it.getConstant()); + constant.setConstant((int) value * it.getConstant()); IntExp sum = constant; for (int i = 0; i < it.getSize(); i++) { IntTerm newterm= new IntTerm(1); - newterm.setCoefficient(i, it.getCoefficient(i)*value); + newterm.setCoefficient(i, it.getCoefficient(i)*(int) value); newterm.setVariable(i, it.getVariable(i)); sum= (IntExp) pb.plus(sum, newterm); } @@ -225,20 +229,20 @@ else if (exp instanceof IntTerm) { else throw new RuntimeException("## Error Choco"); } - public Object mult(Object exp, int value) { + public Object mult(Object exp, long value) { if (exp instanceof IntVar) - return pb.mult(value, (IntExp) exp); + return pb.mult((int) value, (IntExp) exp); else if (exp instanceof IntTerm) { // distribute value over exp //return pb.mult(value, (IntExp) exp); IntTerm it= (IntTerm) exp; IntTerm constant= new IntTerm(0); - constant.setConstant(value * it.getConstant()); + constant.setConstant((int) value * it.getConstant()); IntExp sum = constant; for (int i = 0; i < it.getSize(); i++) { IntTerm newterm= new IntTerm(1); - newterm.setCoefficient(i, it.getCoefficient(i)*value); + newterm.setCoefficient(i, it.getCoefficient(i)*(int) value); newterm.setVariable(i, it.getVariable(i)); sum= (IntExp) pb.plus(sum, newterm); } @@ -261,10 +265,10 @@ public Object mult(double value, Object exp) { public Object mult(Object exp, double value) { return pb.mult((RealExp) exp, pb.cst(value)); } - public Object div(int value, Object exp) { + public Object div(long value, Object exp) { throw new RuntimeException("## Error Choco: non-lin int constraint"); } - public Object div(Object exp, int value) { + public Object div(Object exp, long value) { throw new RuntimeException("## Error Choco: non-lin int constraint"); } public Object div(Object exp1, Object exp2) { @@ -308,7 +312,7 @@ public double getRealValueSup(Object dpVar) { public double getRealValue(Object dpVar) { throw new RuntimeException("# Error: Choco can not compute real solution!"); } - public int getIntValue(Object dpVar) { + public long getIntValue(Object dpVar) { return ((IntDomainVar) dpVar).getVal(); } @@ -329,11 +333,11 @@ public void post(Object constraint) { pb.post((choco.Constraint)constraint); } - public Object and(int value, Object exp) { + public Object and(long value, Object exp) { throw new RuntimeException("## Error Choco does not support bitwise AND"); } - public Object and(Object exp, int value) { + public Object and(Object exp, long value) { throw new RuntimeException("## Error Choco does not support bitwise AND"); } @@ -342,12 +346,12 @@ public Object and(Object exp1, Object exp2) { } @Override - public Object or(int value, Object exp) { + public Object or(long value, Object exp) { throw new RuntimeException("## Error Choco does not support bitwise OR"); } @Override - public Object or(Object exp, int value) { + public Object or(Object exp, long value) { throw new RuntimeException("## Error Choco does not support bitwise OR"); } @@ -357,27 +361,27 @@ public Object or(Object exp1, Object exp2) { } - public Object shiftL(int value, Object exp) { + public Object shiftL(long value, Object exp) { throw new RuntimeException("## Error Choco does not support bitwise SHIFT"); } - public Object shiftL(Object exp, int value) { + public Object shiftL(Object exp, long value) { throw new RuntimeException("## Error Choco does not support bitwise SHIFT"); } - public Object shiftR(int value, Object exp) { + public Object shiftR(long value, Object exp) { throw new RuntimeException("## Error Choco does not support bitwise SHIFT"); } - public Object shiftR(Object exp, int value) { + public Object shiftR(Object exp, long value) { throw new RuntimeException("## Error Choco does not support bitwise SHIFT"); } - public Object xor(int value, Object exp) { + public Object xor(long value, Object exp) { throw new RuntimeException("## Error Choco does not support bitwise XOR"); } - public Object xor(Object exp, int value) { + public Object xor(Object exp, long value) { throw new RuntimeException("## Error Choco does not support bitwise XOR"); } @@ -393,12 +397,12 @@ public Object shiftR(Object exp1, Object exp2) { throw new RuntimeException("## Error Choco does not support bitwise SHIFT"); } - public Object shiftUR(int value, Object exp) { + public Object shiftUR(long value, Object exp) { throw new RuntimeException("## Error Choco does not support bitwise SHIFT"); } - public Object shiftUR(Object exp, int value) { + public Object shiftUR(Object exp, long value) { throw new RuntimeException("## Error Choco does not support bitwise SHIFT"); } @@ -418,4 +422,22 @@ public void postLogicalOR(Object[] constraints) { } + @Override + public Object rem(Object exp1, Object exp2) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object rem(long exp1, Object exp2) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object rem(Object exp1, long exp2) { + // TODO Auto-generated method stub + return null; + } + } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemChoco2.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemChoco2.java index f2c5f69..5c997fd 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemChoco2.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemChoco2.java @@ -33,7 +33,9 @@ * @author staats * */ - +/* Rody: add typecasts long->int everywhere now. Needs a nice solution where the user + * is notified to use another solver with longs. + */ public class ProblemChoco2 extends ProblemGeneral { private CPSolver solver; private Model model; @@ -44,32 +46,32 @@ public ProblemChoco2() { solver = new CPSolver(); } - public Object and(int value, Object exp) { throw new RuntimeException("## Unsupported and "); } - public Object and(Object exp, int value) { throw new RuntimeException("## Unsupported and "); } + public Object and(long value, Object exp) { throw new RuntimeException("## Unsupported and "); } + public Object and(Object exp, long value) { throw new RuntimeException("## Unsupported and "); } public Object and(Object exp1, Object exp2) { throw new RuntimeException("## Unsupported and "); } - public Object div(int value, Object exp) { return Choco.div(value, (IntegerExpressionVariable) exp); } - public Object div(Object exp, int value) { return Choco.div((IntegerExpressionVariable) exp, value); } + public Object div(long value, Object exp) { return Choco.div((int) value, (IntegerExpressionVariable) exp); } + public Object div(Object exp, long value) { return Choco.div((IntegerExpressionVariable) exp, (int) value); } public Object div(Object exp1, Object exp2) { return Choco.div((IntegerExpressionVariable) exp1, (IntegerExpressionVariable) exp2); } public Object div(double value, Object exp) { throw new RuntimeException("## Unsupported double div "); } public Object div(Object exp, double value) { throw new RuntimeException("## Unsupported double div "); } - public Object eq(int value, Object exp) { return Choco.eq(value, (IntegerExpressionVariable) exp); } - public Object eq(Object exp, int value) { return Choco.eq((IntegerExpressionVariable) exp, value); } + public Object eq(long value, Object exp) { return Choco.eq((int) value, (IntegerExpressionVariable) exp); } + public Object eq(Object exp, long value) { return Choco.eq((IntegerExpressionVariable) exp,(int) value); } public Object eq(Object exp1, Object exp2) { return Choco.eq((IntegerExpressionVariable) exp1, (IntegerExpressionVariable) exp1); } public Object eq(double value, Object exp) { throw new RuntimeException("## Unsupported eq "); } public Object eq(Object exp, double value) { throw new RuntimeException("## Unsupported eq "); } - public Object geq(int value, Object exp) { return Choco.geq(value, (IntegerExpressionVariable) exp); } - public Object geq(Object exp, int value) { return Choco.geq((IntegerExpressionVariable) exp, value); } + public Object geq(long value, Object exp) { return Choco.geq((int) value, (IntegerExpressionVariable) exp); } + public Object geq(Object exp, long value) { return Choco.geq((IntegerExpressionVariable) exp, (int) value); } public Object geq(Object exp1, Object exp2) { return Choco.geq((IntegerExpressionVariable) exp1, (IntegerExpressionVariable) exp1); } public Object geq(double value, Object exp) { throw new RuntimeException("## Unsupported geq "); } public Object geq(Object exp, double value) { throw new RuntimeException("## Unsupported geq "); } - public int getIntValue(Object dpVar) { + public long getIntValue(Object dpVar) { try { return solver.getVar((IntegerVariable) dpVar).getVal(); } catch (Throwable t) { @@ -81,61 +83,62 @@ public int getIntValue(Object dpVar) { public double getRealValueInf(Object dpvar) { throw new RuntimeException("## Unsupported get real value "); } public double getRealValueSup(Object dpVar) { throw new RuntimeException("## Unsupported get real value "); } - public Object gt(int value, Object exp) { return Choco.gt(value, (IntegerExpressionVariable) exp); } - public Object gt(Object exp, int value) { return Choco.gt((IntegerExpressionVariable) exp, value); } + public Object gt(long value, Object exp) { return Choco.gt((int) value, (IntegerExpressionVariable) exp); } + public Object gt(Object exp, long value) { return Choco.gt((IntegerExpressionVariable) exp, (int) value); } public Object gt(Object exp1, Object exp2) { return Choco.gt((IntegerExpressionVariable) exp1, (IntegerExpressionVariable) exp2); } public Object gt(double value, Object exp) { throw new RuntimeException("## Unsupported double gt "); } public Object gt(Object exp, double value) { throw new RuntimeException("## Unsupported double gt "); } - public Object leq(int value, Object exp) { return Choco.leq(value, (IntegerExpressionVariable) exp); } - public Object leq(Object exp, int value) { return Choco.leq((IntegerExpressionVariable) exp, value); } + public Object leq(long value, Object exp) { return Choco.leq((int) value, (IntegerExpressionVariable) exp); } + public Object leq(Object exp, long value) { return Choco.leq((IntegerExpressionVariable) exp,(int) value); } public Object leq(Object exp1, Object exp2) { return Choco.leq((IntegerExpressionVariable) exp1, (IntegerExpressionVariable) exp2); } public Object leq(double value, Object exp) { throw new RuntimeException("## Unsupported double leq "); } public Object leq(Object exp, double value) { throw new RuntimeException("## Unsupported double leq "); } - public Object lt(int value, Object exp) { return Choco.lt(value, (IntegerExpressionVariable) exp); } - public Object lt(Object exp, int value) { return Choco.lt((IntegerExpressionVariable) exp, value); } + public Object lt(long value, Object exp) { return Choco.lt((int) value, (IntegerExpressionVariable) exp); } + public Object lt(Object exp, long value) { return Choco.lt((IntegerExpressionVariable) exp, (int) value); } public Object lt(Object exp1, Object exp2) { return Choco.lt((IntegerExpressionVariable) exp1, (IntegerExpressionVariable) exp2); } public Object lt(double value, Object exp) { throw new RuntimeException("## Unsupported double lt "); } public Object lt(Object exp, double value) { throw new RuntimeException("## Unsupported double lt "); } - public Object makeIntVar(String name, int min, int max) { - return Choco.makeIntVar(name, min, max); + public Object makeIntVar(String name, long min, long max) { + assert(min>=Integer.MIN_VALUE && max<=Integer.MAX_VALUE); + return Choco.makeIntVar(name, (int) min, (int) max); } public Object makeRealVar(String name, double min, double max) { throw new RuntimeException("## Unsupported make real "); } - public Object minus(int value, Object exp) { return Choco.minus(value, (IntegerExpressionVariable) exp); } - public Object minus(Object exp, int value) { return Choco.minus((IntegerExpressionVariable) exp, value); } + public Object minus(long value, Object exp) { return Choco.minus((int) value, (IntegerExpressionVariable) exp); } + public Object minus(Object exp, long value) { return Choco.minus((IntegerExpressionVariable) exp, (int) value); } public Object minus(Object exp1, Object exp2) { return Choco.minus((IntegerExpressionVariable) exp1, (IntegerExpressionVariable) exp2); } public Object minus(double value, Object exp) { throw new RuntimeException("## Unsupported double minus "); } public Object minus(Object exp, double value) { throw new RuntimeException("## Unsupported double minus "); } public Object mixed(Object exp1, Object exp2) { throw new RuntimeException("## Unsupported mixed "); } - public Object mult(int value, Object exp) { return Choco.mult(value, (IntegerExpressionVariable) exp); } - public Object mult(Object exp, int value) { return Choco.mult((IntegerExpressionVariable) exp, value); } + public Object mult(long value, Object exp) { return Choco.mult((int) value, (IntegerExpressionVariable) exp); } + public Object mult(Object exp, long value) { return Choco.mult((IntegerExpressionVariable) exp,(int) value); } public Object mult(Object exp1, Object exp2) { return Choco.mult((IntegerExpressionVariable) exp1, (IntegerExpressionVariable) exp2); } public Object mult(double value, Object exp) { throw new RuntimeException("## Unsupported double mult "); } public Object mult(Object exp, double value) { throw new RuntimeException("## Unsupported double mult "); } - public Object neq(int value, Object exp) { return Choco.neq(value, (IntegerExpressionVariable) exp); } - public Object neq(Object exp, int value) { return Choco.neq((IntegerExpressionVariable) exp, value); } + public Object neq(long value, Object exp) { return Choco.neq((int) value, (IntegerExpressionVariable) exp); } + public Object neq(Object exp, long value) { return Choco.neq((IntegerExpressionVariable) exp, (int) value); } public Object neq(Object exp1, Object exp2) { return Choco.neq((IntegerExpressionVariable) exp1, (IntegerExpressionVariable) exp2); } public Object neq(double value, Object exp) { throw new RuntimeException("## Unsupported double NEQ "); } public Object neq(Object exp, double value) { throw new RuntimeException("## Unsupported double NEQ "); } - public Object or(int value, Object exp) { throw new RuntimeException("## Unsupported OR "); } - public Object or(Object exp, int value) { throw new RuntimeException("## Unsupported OR "); } + public Object or(long value, Object exp) { throw new RuntimeException("## Unsupported OR "); } + public Object or(Object exp, long value) { throw new RuntimeException("## Unsupported OR "); } public Object or(Object exp1, Object exp2) { throw new RuntimeException("## Unsupported OR "); } - public Object plus(int value, Object exp) { return Choco.plus(value, (IntegerExpressionVariable) exp); } - public Object plus(Object exp, int value) { return Choco.plus((IntegerExpressionVariable) exp, value); } + public Object plus(long value, Object exp) { return Choco.plus((int) value, (IntegerExpressionVariable) exp); } + public Object plus(Object exp, long value) { return Choco.plus((IntegerExpressionVariable) exp, (int) value); } public Object plus(Object exp1, Object exp2) { return Choco.plus((IntegerExpressionVariable) exp1, (IntegerExpressionVariable) exp2); } public Object plus(double value, Object exp) { throw new RuntimeException("## Unsupported double plus "); } @@ -145,16 +148,16 @@ public void post(Object constraint) { model.addConstraint((Constraint) constraint); } - public Object shiftL(int value, Object exp) { throw new RuntimeException("## Unsupported shiftL"); } - public Object shiftL(Object exp, int value) { throw new RuntimeException("## Unsupported shiftL"); } + public Object shiftL(long value, Object exp) { throw new RuntimeException("## Unsupported shiftL"); } + public Object shiftL(Object exp, long value) { throw new RuntimeException("## Unsupported shiftL"); } public Object shiftL(Object exp1, Object exp2) { throw new RuntimeException("## Unsupported shiftL"); } - public Object shiftR(int value, Object exp) { throw new RuntimeException("## Unsupported shiftR"); } - public Object shiftR(Object exp, int value) { throw new RuntimeException("## Unsupported shiftR"); } + public Object shiftR(long value, Object exp) { throw new RuntimeException("## Unsupported shiftR"); } + public Object shiftR(Object exp, long value) { throw new RuntimeException("## Unsupported shiftR"); } public Object shiftR(Object exp1, Object exp2) { throw new RuntimeException("## Unsupported shiftR"); } - public Object shiftUR(int value, Object exp) { throw new RuntimeException("## Unsupported shiftUR"); } - public Object shiftUR(Object exp, int value) { throw new RuntimeException("## Unsupported shiftUR"); } + public Object shiftUR(long value, Object exp) { throw new RuntimeException("## Unsupported shiftUR"); } + public Object shiftUR(Object exp, long value) { throw new RuntimeException("## Unsupported shiftUR"); } public Object shiftUR(Object exp1, Object exp2) { throw new RuntimeException("## Unsupported shiftUR"); } /* @@ -181,8 +184,8 @@ public Boolean solve() { return solved; } - public Object xor(int value, Object exp) { throw new RuntimeException("## Unsupported XOR "); } - public Object xor(Object exp, int value) { throw new RuntimeException("## Unsupported XOR"); } + public Object xor(long value, Object exp) { throw new RuntimeException("## Unsupported XOR "); } + public Object xor(Object exp, long value) { throw new RuntimeException("## Unsupported XOR"); } public Object xor(Object exp1, Object exp2) { throw new RuntimeException("## Unsupported XOR"); } @Override @@ -191,4 +194,22 @@ public void postLogicalOR(Object[] constraint) { throw new RuntimeException("## Error Choco2 does not support LogicalOR"); } + @Override + public Object rem(Object exp1, Object exp2) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object rem(long exp1, Object exp2) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object rem(Object exp1, long exp2) { + // TODO Auto-generated method stub + return null; + } + } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemCompare.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemCompare.java index db95783..395fe44 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemCompare.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemCompare.java @@ -134,7 +134,7 @@ public void setConstraint(int i, Object o) { } @Override - public Object and(int value, Object exp) { + public Object and(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -148,7 +148,7 @@ public Object and(int value, Object exp) { } @Override - public Object and(Object exp, int value) { + public Object and(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -177,7 +177,7 @@ public Object and(Object exp1, Object exp2) { } @Override - public Object div(int value, Object exp) { + public Object div(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -191,7 +191,7 @@ public Object div(int value, Object exp) { } @Override - public Object div(Object exp, int value) { + public Object div(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -248,7 +248,7 @@ public Object div(Object exp, double value) { } @Override - public Object eq(int value, Object exp) { + public Object eq(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -262,7 +262,7 @@ public Object eq(int value, Object exp) { } @Override - public Object eq(Object exp, int value) { + public Object eq(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -319,7 +319,7 @@ public Object eq(Object exp, double value) { } @Override - public Object geq(int value, Object exp) { + public Object geq(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -333,7 +333,7 @@ public Object geq(int value, Object exp) { } @Override - public Object geq(Object exp, int value) { + public Object geq(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -390,7 +390,7 @@ public Object geq(Object exp, double value) { } @Override - public int getIntValue(Object dpVar) { + public long getIntValue(Object dpVar) { return probs[selected].getIntValue(((SolverObjects) dpVar).getConstraint(selected)); } @@ -412,7 +412,7 @@ public double getRealValueSup(Object dpVar) { } @Override - public Object gt(int value, Object exp) { + public Object gt(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -426,7 +426,7 @@ public Object gt(int value, Object exp) { } @Override - public Object gt(Object exp, int value) { + public Object gt(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -483,7 +483,7 @@ public Object gt(Object exp, double value) { } @Override - public Object leq(int value, Object exp) { + public Object leq(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -497,7 +497,7 @@ public Object leq(int value, Object exp) { } @Override - public Object leq(Object exp, int value) { + public Object leq(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -553,7 +553,7 @@ public Object leq(Object exp, double value) { } @Override - public Object lt(int value, Object exp) { + public Object lt(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -567,7 +567,7 @@ public Object lt(int value, Object exp) { } @Override - public Object lt(Object exp, int value) { + public Object lt(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -624,7 +624,7 @@ public Object lt(Object exp, double value) { } @Override - public Object makeIntVar(String name, int min, int max) { + public Object makeIntVar(String name, long min, long max) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { so.setConstraint(i, probs[i].makeIntVar(name, min, max)); @@ -646,7 +646,7 @@ public Object makeRealVar(String name, double min, double max) { } @Override - public Object minus(int value, Object exp) { + public Object minus(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -660,7 +660,7 @@ public Object minus(int value, Object exp) { } @Override - public Object minus(Object exp, int value) { + public Object minus(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -725,7 +725,7 @@ public Object mixed(Object exp1, Object exp2) { so.setConstraint(i, probs[i].mixed(((SolverObjects) exp1) .getConstraint(i), ((SolverObjects) exp2) .getConstraint(i))); - } catch(Exception _){ + } catch(Exception e){ ignoredSolvers[i] = true; } } @@ -733,7 +733,7 @@ public Object mixed(Object exp1, Object exp2) { } @Override - public Object mult(int value, Object exp) { + public Object mult(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -747,7 +747,7 @@ public Object mult(int value, Object exp) { } @Override - public Object mult(Object exp, int value) { + public Object mult(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -804,7 +804,7 @@ public Object mult(Object exp, double value) { } @Override - public Object neq(int value, Object exp) { + public Object neq(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -818,7 +818,7 @@ public Object neq(int value, Object exp) { } @Override - public Object neq(Object exp, int value) { + public Object neq(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -875,7 +875,7 @@ public Object neq(Object exp, double value) { } @Override - public Object or(int value, Object exp) { + public Object or(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -889,7 +889,7 @@ public Object or(int value, Object exp) { } @Override - public Object or(Object exp, int value) { + public Object or(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -918,7 +918,7 @@ public Object or(Object exp1, Object exp2) { } @Override - public Object plus(int value, Object exp) { + public Object plus(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -932,7 +932,7 @@ public Object plus(int value, Object exp) { } @Override - public Object plus(Object exp, int value) { + public Object plus(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -1000,7 +1000,7 @@ public void post(Object constraint) { } @Override - public Object shiftL(int value, Object exp) { + public Object shiftL(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -1014,7 +1014,7 @@ public Object shiftL(int value, Object exp) { } @Override - public Object shiftL(Object exp, int value) { + public Object shiftL(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -1043,7 +1043,7 @@ public Object shiftL(Object exp1, Object exp2) { } @Override - public Object shiftR(int value, Object exp) { + public Object shiftR(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -1057,7 +1057,7 @@ public Object shiftR(int value, Object exp) { } @Override - public Object shiftR(Object exp, int value) { + public Object shiftR(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -1086,7 +1086,7 @@ public Object shiftR(Object exp1, Object exp2) { } @Override - public Object shiftUR(int value, Object exp) { + public Object shiftUR(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -1100,7 +1100,7 @@ public Object shiftUR(int value, Object exp) { } @Override - public Object shiftUR(Object exp, int value) { + public Object shiftUR(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -1129,7 +1129,7 @@ public Object shiftUR(Object exp1, Object exp2) { } @Override - public Object xor(int value, Object exp) { + public Object xor(long value, Object exp) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -1143,7 +1143,7 @@ public Object xor(int value, Object exp) { } @Override - public Object xor(Object exp, int value) { + public Object xor(Object exp, long value) { SolverObjects so = new SolverObjects(); for (int i = 0; i < numSolvers; i++) { try { @@ -1399,7 +1399,7 @@ public Env check(Map intVars, Map SolverObjects valueList = entry.getValue(); Object coralLiteral = valueList.getConstraint(0); Object otherLiteral = valueList.getConstraint(pbToCheck); - int val = pb.getIntValue(otherLiteral); + long val = pb.getIntValue(otherLiteral); coralMap.put((SymLiteral) coralLiteral, Util.createConstant(val)); //System.out.println(literal + " : " + val); } @@ -1499,10 +1499,10 @@ public Boolean solve() { // } } } - catch(Exception _){ + catch(Exception e){ solutions[i] = false; System.out.println("Solver " + i + " threw an exception"); - _.printStackTrace(); + e.printStackTrace(); } if (alwaysPrint) { @@ -1548,7 +1548,7 @@ public static void dump(Search search) { String solverName = ProblemCompare.class.getSimpleName(); String fileName = TablePrinter.TABLE_DIR + targetName + "." + solverName + ".ser"; SolvingDiff.writeToFile(fileName, solvingDiff); - } catch (IOException _) { + } catch (IOException e) { throw new RuntimeException(TablePrinter.ERR_MSG); } } @@ -1559,4 +1559,22 @@ public void postLogicalOR(Object[] constraint) { throw new RuntimeException("## Error Choco2 does not support LogicalOR"); } + + @Override + public Object rem(Object exp1, Object exp2) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object rem(long exp1, Object exp2) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object rem(Object exp1, long exp2) { + // TODO Auto-generated method stub + return null; + } } \ No newline at end of file diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemCoral.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemCoral.java index d4f5de2..da85fa4 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemCoral.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemCoral.java @@ -76,7 +76,9 @@ * @author Marcelo d'Amorim (damorim@cin.ufpe.br) * */ - +/* Rody: add typecasts long->int everywhere now. Needs a nice solution where the user + * is notified to use another solver with longs. + */ public class ProblemCoral extends ProblemGeneral { // private static final long timeout = -1; //Config.timeout; // 1s default @@ -162,7 +164,7 @@ public void cleanup() { **************************************************/ @Override - public Object makeIntVar(String name, int min, int max) { + public Object makeIntVar(String name, long min, long max) { return Util.createSymLiteral(0/*default value*/); } @@ -172,13 +174,13 @@ public Object makeRealVar(String name, double min, double max) { } @Override - public Object eq(int value, Object exp) { - return Util.eq(Util.createConstant(value), (SymInt)exp); + public Object eq(long value, Object exp) { + return Util.eq(Util.createConstant((int) value), (SymInt)exp); } @Override - public Object eq(Object exp, int value) { - return Util.eq((SymInt)exp, Util.createConstant(value)); + public Object eq(Object exp, long value) { + return Util.eq((SymInt)exp, Util.createConstant((int) value)); } @Override @@ -203,13 +205,13 @@ public Object eq(Object exp, double value) { } @Override - public Object neq(int value, Object exp) { - return Util.ne(Util.createConstant(value), (SymInt)exp); + public Object neq(long value, Object exp) { + return Util.ne(Util.createConstant((int) value), (SymInt)exp); } @Override - public Object neq(Object exp, int value) { - return Util.ne((SymInt)exp, Util.createConstant(value)); + public Object neq(Object exp, long value) { + return Util.ne((SymInt)exp, Util.createConstant((int) value)); } @Override @@ -234,13 +236,13 @@ public Object neq(Object exp, double value) { } @Override - public Object leq(int value, Object exp) { - return Util.le(Util.createConstant(value), (SymInt)exp); + public Object leq(long value, Object exp) { + return Util.le(Util.createConstant((int) value), (SymInt)exp); } @Override - public Object leq(Object exp, int value) { - return Util.le((SymInt)exp, Util.createConstant(value)); + public Object leq(Object exp, long value) { + return Util.le((SymInt)exp, Util.createConstant((int) value)); } @Override @@ -265,13 +267,13 @@ public Object leq(Object exp, double value) { } @Override - public Object geq(int value, Object exp) { - return Util.ge(Util.createConstant(value), (SymInt)exp); + public Object geq(long value, Object exp) { + return Util.ge(Util.createConstant((int) value), (SymInt)exp); } @Override - public Object geq(Object exp, int value) { - return Util.ge((SymInt)exp, Util.createConstant(value)); + public Object geq(Object exp, long value) { + return Util.ge((SymInt)exp, Util.createConstant((int) value)); } @Override @@ -296,13 +298,13 @@ public Object geq(Object exp, double value) { } @Override - public Object lt(int value, Object exp) { - return Util.lt(Util.createConstant(value), (SymInt)exp); + public Object lt(long value, Object exp) { + return Util.lt(Util.createConstant((int) value), (SymInt)exp); } @Override - public Object lt(Object exp, int value) { - return Util.lt((SymInt)exp, Util.createConstant(value)); + public Object lt(Object exp, long value) { + return Util.lt((SymInt)exp, Util.createConstant((int) value)); } @Override @@ -327,13 +329,13 @@ public Object lt(Object exp, double value) { } @Override - public Object gt(int value, Object exp) { - return Util.gt(Util.createConstant(value), (SymInt)exp); + public Object gt(long value, Object exp) { + return Util.gt(Util.createConstant((int) value), (SymInt)exp); } @Override - public Object gt(Object exp, int value) { - return Util.gt((SymInt)exp, Util.createConstant(value)); + public Object gt(Object exp, long value) { + return Util.gt((SymInt)exp, Util.createConstant((int) value)); } @Override @@ -358,13 +360,13 @@ public Object gt(Object exp, double value) { } @Override - public Object plus(int value, Object exp) { - return Util.add(Util.createConstant(value), (SymInt)exp); + public Object plus(long value, Object exp) { + return Util.add(Util.createConstant((int) value), (SymInt)exp); } @Override - public Object plus(Object exp, int value) { - return Util.add((SymInt)exp, Util.createConstant(value)); + public Object plus(Object exp, long value) { + return Util.add((SymInt)exp, Util.createConstant((int) value)); } @Override @@ -389,13 +391,13 @@ public Object plus(Object exp, double value) { } @Override - public Object minus(int value, Object exp) { - return Util.sub(Util.createConstant(value),(SymInt)exp); + public Object minus(long value, Object exp) { + return Util.sub(Util.createConstant((int) value),(SymInt)exp); } @Override - public Object minus(Object exp, int value) { - return Util.sub((SymInt)exp,Util.createConstant(value)); + public Object minus(Object exp, long value) { + return Util.sub((SymInt)exp,Util.createConstant((int) value)); } @Override @@ -420,13 +422,13 @@ public Object minus(Object exp, double value) { } @Override - public Object mult(int value, Object exp) { - return Util.mul(Util.createConstant(value), (SymInt)exp); + public Object mult(long value, Object exp) { + return Util.mul(Util.createConstant((int) value), (SymInt)exp); } @Override - public Object mult(Object exp, int value) { - return Util.mul((SymInt)exp, Util.createConstant(value)); + public Object mult(Object exp, long value) { + return Util.mul((SymInt)exp, Util.createConstant((int) value)); } @Override @@ -451,13 +453,13 @@ public Object mult(Object exp, double value) { } @Override - public Object div(int value, Object exp) { - return Util.div(Util.createConstant(value), (SymInt)exp); + public Object div(long value, Object exp) { + return Util.div(Util.createConstant((int) value), (SymInt)exp); } @Override - public Object div(Object exp, int value) { - return Util.div((SymInt)exp, Util.createConstant(value)); + public Object div(Object exp, long value) { + return Util.div((SymInt)exp, Util.createConstant((int) value)); } @Override @@ -482,12 +484,12 @@ public Object div(Object exp, double value) { } @Override - public Object and(int value, Object exp) { + public Object and(long value, Object exp) { return Util.and(value==1?Util.TRUE:Util.FALSE, (SymBool)exp); } @Override - public Object and(Object exp, int value) { + public Object and(Object exp, long value) { return Util.and((SymBool)exp, value==1?Util.TRUE:Util.FALSE); } @@ -497,12 +499,12 @@ public Object and(Object exp1, Object exp2) { } @Override - public Object or(int value, Object exp) { + public Object or(long value, Object exp) { return Util.or(value==1?Util.TRUE:Util.FALSE, (SymBool)exp); } @Override - public Object or(Object exp, int value) { + public Object or(Object exp, long value) { return Util.or((SymBool)exp, value==1?Util.TRUE:Util.FALSE); } @@ -512,12 +514,12 @@ public Object or(Object exp1, Object exp2) { } @Override - public Object xor(int value, Object exp) { + public Object xor(long value, Object exp) { return Util.xor(value==1?Util.TRUE:Util.FALSE, (SymBool)exp); } @Override - public Object xor(Object exp, int value) { + public Object xor(Object exp, long value) { return Util.xor((SymBool)exp, value==1?Util.TRUE:Util.FALSE); } @@ -527,13 +529,13 @@ public Object xor(Object exp1, Object exp2) { } @Override - public Object shiftL(int value, Object exp) { - return Util.sl(Util.createConstant(value), (SymInt)exp); + public Object shiftL(long value, Object exp) { + return Util.sl(Util.createConstant((int) value), (SymInt)exp); } @Override - public Object shiftL(Object exp, int value) { - return Util.sl((SymInt)exp, Util.createConstant(value)); + public Object shiftL(Object exp, long value) { + return Util.sl((SymInt)exp, Util.createConstant((int) value)); } @Override @@ -542,13 +544,13 @@ public Object shiftL(Object exp1, Object exp2) { } @Override - public Object shiftR(int value, Object exp) { - return Util.sr(Util.createConstant(value), (SymInt)exp); + public Object shiftR(long value, Object exp) { + return Util.sr(Util.createConstant((int) value), (SymInt)exp); } @Override - public Object shiftR(Object exp, int value) { - return Util.sr((SymInt)exp, Util.createConstant(value)); + public Object shiftR(Object exp, long value) { + return Util.sr((SymInt)exp, Util.createConstant((int) value)); } @Override @@ -557,13 +559,13 @@ public Object shiftR(Object exp1, Object exp2) { } @Override - public Object shiftUR(int value, Object exp) { - return Util.usr(Util.createConstant(value), (SymInt)exp); + public Object shiftUR(long value, Object exp) { + return Util.usr(Util.createConstant((int) value), (SymInt)exp); } @Override - public Object shiftUR(Object exp, int value) { - return Util.usr((SymInt)exp, Util.createConstant(value)); + public Object shiftUR(Object exp, long value) { + return Util.usr((SymInt)exp, Util.createConstant((int) value)); } @Override @@ -661,7 +663,7 @@ public Boolean solve() { if (sol.getResult() == Result.SAT) { result = true; } - } catch (Exception _) { + } catch (Exception e) { } // finally { // System.out.printf(">>> %s %s %s\n", pc.toString(), sol, result); @@ -718,12 +720,12 @@ public double getRealValue(Object dpVar) { } @Override - public int getIntValue(Object dpVar) { + public long getIntValue(Object dpVar) { SymNumber symNumber = sol.getValue((SymLiteral)dpVar); try { return symNumber.evalNumber().intValue(); - } catch (NullPointerException _) { - throw _; + } catch (NullPointerException e) { + throw e; } } @@ -749,5 +751,23 @@ public void postLogicalOR(Object[] constraints) { post(orResult); } + + @Override + public Object rem(Object exp1, Object exp2) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object rem(long exp1, Object exp2) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object rem(Object exp1, long exp2) { + // TODO Auto-generated method stub + return null; + } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemDReal.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemDReal.java deleted file mode 100644 index 0a9d39e..0000000 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemDReal.java +++ /dev/null @@ -1,990 +0,0 @@ -/* - * Copyright (C) 2014, United States Government, as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All rights reserved. - * - * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// -//Copyright (C) 2006 United States Government as represented by the -//Administrator of the National Aeronautics and Space Administration -//(NASA). All Rights Reserved. -// -//This software is distributed under the NASA Open Source Agreement -//(NOSA), version 1.3. The NOSA has been approved by the Open Source -//Initiative. See the file NOSA-1.3-JPF at the top of the distribution -//directory tree for the complete NOSA document. -// -//THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY -//KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT -//LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO -//SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR -//A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT -//THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT -//DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. -// - -package gov.nasa.jpf.symbc.numeric.solvers; - -import java.util.ArrayList; -import java.util.List; - -import proteus.dl.semantics.Valuation; -import proteus.dl.syntax.AbsTerm; -import proteus.dl.syntax.AdditionTerm; -import proteus.dl.syntax.ArcCosTerm; -import proteus.dl.syntax.ArcSinTerm; -import proteus.dl.syntax.ArcTan2Term; -import proteus.dl.syntax.ArcTanTerm; -import proteus.dl.syntax.ComparisonFormula; -import proteus.dl.syntax.CosTerm; -import proteus.dl.syntax.DivisionTerm; -import proteus.dl.syntax.ExpTerm; -import proteus.dl.syntax.FalseFormula; -import proteus.dl.syntax.LogTerm; -import proteus.dl.syntax.MultiplicationTerm; -import proteus.dl.syntax.NegativeTerm; -import proteus.dl.syntax.OrFormula; -import proteus.dl.syntax.PowerTerm; -import proteus.dl.syntax.Real; -import proteus.dl.syntax.RealVariable; -import proteus.dl.syntax.SinTerm; -import proteus.dl.syntax.SqrtTerm; -import proteus.dl.syntax.SubtractionTerm; -import proteus.dl.syntax.TanTerm; -import proteus.dl.syntax.Term; -import proteus.dl.syntax.TrueFormula; -import proteus.dl.syntax.dLFormula; -import proteus.logicsolvers.abstractions.LogicSolverResult; -import proteus.logicsolvers.drealkit.dRealInterface; - -/** Additional Parameters: - * dreal.mode = strictified or relaxed - * dreal.precision=0.001 - * dreal.timeBound=10000 (in milliseconds) - * Instances are not thread-safe. - * @author Nima Roohi */ -public abstract class ProblemDReal extends ProblemGeneral { - - private static class ProblemDRealRelaxed extends ProblemDReal { - - public ProblemDRealRelaxed(final double precision, final int timeBound) { - super(Mode.RELAXED, precision, timeBound); - assert (precision >= 0); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public ComparisonFormula eq(final Object lhs, final Object rhs) { - return comp("=", (Term) lhs, (Term) rhs); - } - - @Override - public ComparisonFormula eq(final double value, final Object exp) { - return comp("=", (Term) exp, constant(value)); - } - - @Override - public ComparisonFormula eq(final Object exp, final double value) { - return comp("=", (Term) exp, constant(value)); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public dLFormula neq(final Object lhs, final Object rhs) { - return TRUE; - } - - @Override - public dLFormula neq(final double value, final Object exp) { - return TRUE; - } - - @Override - public dLFormula neq(final Object exp, final double value) { - return TRUE; - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public ComparisonFormula leq(final Object lhs, final Object rhs) { - return comp("<=", (Term) lhs, (Term) rhs); - } - - @Override - public ComparisonFormula leq(final double value, final Object exp) { - return comp(">=", (Term) exp, constant(value)); - } - - @Override - public ComparisonFormula leq(final Object exp, final double value) { - return comp("<=", (Term) exp, constant(value)); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public ComparisonFormula geq(final Object lhs, final Object rhs) { - return comp(">=", (Term) lhs, (Term) rhs); - } - - @Override - public ComparisonFormula geq(final double value, final Object exp) { - return comp("<=", (Term) exp, constant(value)); - } - - @Override - public ComparisonFormula geq(final Object exp, final double value) { - return comp(">=", (Term) exp, constant(value)); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public ComparisonFormula lt(final Object lhs, final Object rhs) { - return comp("<", (Term) lhs, (Term) rhs); - } - - @Override - public ComparisonFormula lt(final double value, final Object exp) { - return comp(">", (Term) exp, constant(value)); - } - - @Override - public ComparisonFormula lt(final Object exp, final double value) { - return comp("<", (Term) exp, constant(value)); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public ComparisonFormula gt(final Object lhs, final Object rhs) { - return comp(">", (Term) lhs, (Term) rhs); - } - - @Override - public ComparisonFormula gt(final double value, final Object exp) { - return comp("<", (Term) exp, constant(value)); - } - - @Override - public ComparisonFormula gt(final Object exp, final double value) { - return comp(">", (Term) exp, constant(value)); - } - - private static TrueFormula TRUE = new TrueFormula(); - } - - // ------------------------------------------------------------------------------------------------------------------ - // ------------------------------------------------------------------------------------------------------------------ - // ------------------------------------------------------------------------------------------------------------------ - - private static class ProblemDRealStrict extends ProblemDReal { - - public ProblemDRealStrict(final double precision, final int timeBound) { - super(Mode.STRICTIFIED, precision, timeBound); - assert (precision > 0); - this.precision = constant(precision); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public dLFormula eq(final Object lhs, final Object rhs) { - return FALSE; - } - - @Override - public dLFormula eq(final double value, final Object exp) { - return FALSE; - } - - @Override - public dLFormula eq(final Object exp, final double value) { - return FALSE; - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public dLFormula neq(final Object lhs, final Object rhs) { - return new OrFormula(// - comp("<", (Term) lhs, minus(rhs, precision)), // - comp(">", (Term) lhs, plus(rhs, precision))); - } - - @Override - public dLFormula neq(final double lhs, final Object rhs) { - return new OrFormula(// - comp("<", (Term) rhs, constant(lhs - super.precision)), // - comp(">", (Term) rhs, constant(lhs + super.precision))); - } - - @Override - public dLFormula neq(final Object lhs, final double rhs) { - return new OrFormula(// - comp("<", (Term) lhs, constant(rhs - super.precision)), // - comp(">", (Term) lhs, constant(rhs + super.precision))); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public ComparisonFormula leq(final Object lhs, final Object rhs) { - return comp("<=", (Term) lhs, minus(rhs, precision)); - } - - @Override - public ComparisonFormula leq(final double value, final Object exp) { - return comp(">=", (Term) exp, constant(value + super.precision)); - } - - @Override - public ComparisonFormula leq(final Object exp, final double value) { - return comp("<=", (Term) exp, constant(value - super.precision)); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public ComparisonFormula geq(final Object lhs, final Object rhs) { - return comp(">=", (Term) lhs, plus(rhs, precision)); - } - - @Override - public ComparisonFormula geq(final double value, final Object exp) { - return comp("<=", (Term) exp, constant(value - super.precision)); - } - - @Override - public ComparisonFormula geq(final Object exp, final double value) { - return comp(">=", (Term) exp, constant(value + super.precision)); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public ComparisonFormula lt(final Object lhs, final Object rhs) { - return comp("<", (Term) lhs, minus(rhs, precision)); - } - - @Override - public ComparisonFormula lt(final double value, final Object exp) { - return comp(">", (Term) exp, constant(value + super.precision)); - } - - @Override - public ComparisonFormula lt(final Object exp, final double value) { - return comp("<", (Term) exp, constant(value - super.precision)); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public ComparisonFormula gt(final Object lhs, final Object rhs) { - return comp(">", (Term) lhs, plus(rhs, precision)); - } - - @Override - public ComparisonFormula gt(final double value, final Object exp) { - return comp("<", (Term) exp, constant(value - super.precision)); - } - - @Override - public ComparisonFormula gt(final Object exp, final double value) { - return comp(">", (Term) exp, constant(value + super.precision)); - } - - private final Real precision; - private static FalseFormula FALSE = new FalseFormula(); - } - - // ------------------------------------------------------------------------------------------------------------------ - // ------------------------------------------------------------------------------------------------------------------ - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public abstract dLFormula leq(double value, Object exp); - - @Override - public abstract dLFormula leq(Object exp, double value); - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public RealVariable makeRealVar(final String name, final double min, final double max) { - final RealVariable res = new RealVariable(name); - /* The current dReal interface does not support bounded existential quantifier. So I am saving the given bounds to be - * used later. Note that it means I am assuming any variable that is created here, will be used in the given - * constraints. Otherwise, redundant constraints will be given to dReal that has no effect on the output but only makes - * it slower! */ - if (Double.isNaN(min)) - throw new IllegalArgumentException("'min' must be a number"); - if (Double.isNaN(max)) - throw new IllegalArgumentException("'max' must be a number"); - if (!Double.isInfinite(min)) - formulas.add(leq(min, res)); - else if (min > 0) - throw new IllegalArgumentException("'min' cannot be positive infinity"); - if (!Double.isInfinite(max)) - formulas.add(leq(res, max)); - else if (max < 0) - throw new IllegalArgumentException("'max' cannot be negative infinity"); - return res; - } - - @Override - public Real constant(final double value) { - if (!Double.isFinite(value)) - throw new IllegalArgumentException("'value' must be finite"); - return new Real(value); - } - - // ------------------------------------------------------------------------------------------------------------------ - - protected ComparisonFormula comp(final String op, final Term lhs, final Term rhs) { - return new ComparisonFormula(op, lhs, rhs); - } - - private static boolean isZero(final Term t) { - return ZERO.equals(t) || ZERO2.equals(t); - } - - private static boolean isOne(final Term t) { - return ONE.equals(t); - } - - // ------------------------------------------------------------------------------------------------------------------ - - public Term plus(final Term lhs, final Term rhs) { - if (isZero(lhs)) - return rhs; - if (isZero(rhs)) - return lhs; - return new AdditionTerm(lhs, rhs); - } - - @Override - public Term plus(final Object lhs, final Object rhs) { - return plus((Term) lhs, (Term) rhs); - } - - @Override - public Term plus(final double value, final Object exp) { - return plus(constant(value), (Term) exp); - } - - @Override - public Term plus(final Object exp, final double value) { - return plus((Term) exp, constant(value)); - } - - // ------------------------------------------------------------------------------------------------------------------ - - public Term minus(final Term lhs, final Term rhs) { - if (isZero(rhs)) - return lhs; - if (isZero(lhs)) - return new NegativeTerm(rhs); - return new SubtractionTerm(lhs, rhs); - } - - @Override - public Term minus(final Object lhs, final Object rhs) { - return minus((Term) lhs, (Term) rhs); - } - - @Override - public Term minus(final double value, final Object exp) { - return minus(constant(value), (Term) exp); - } - - @Override - public Term minus(final Object exp, final double value) { - if (isZero((Term) exp)) - return constant(-value); - return minus((Term) exp, constant(value)); - } - - // ------------------------------------------------------------------------------------------------------------------ - - public Term mult(final Term lhs, final Term rhs) { - if (isZero(lhs) || isZero(rhs)) - return ZERO; - if (isOne(rhs)) - return lhs; - if (isOne(lhs)) - return rhs; - return new MultiplicationTerm(lhs, rhs); - } - - @Override - public Term mult(final Object lhs, final Object rhs) { - return mult((Term) lhs, (Term) rhs); - } - - @Override - public Term mult(final double value, final Object exp) { - return mult(constant(value), (Term) exp); - } - - @Override - public Term mult(final Object exp, final double value) { - return mult((Term) exp, constant(value)); - } - - // ------------------------------------------------------------------------------------------------------------------ - - public Term div(final Term lhs, final Term rhs) { - if (isZero(lhs)) - return ZERO; - if (isOne(rhs)) - return lhs; - return new DivisionTerm(lhs, rhs); - } - - @Override - public Term div(final Object lhs, final Object rhs) { - return div((Term) lhs, (Term) rhs); - } - - @Override - public Term div(final double value, final Object exp) { - return div(constant(value), (Term) exp); - } - - @Override - public Term div(final Object exp, final double value) { - if (isOne((Term) exp)) - return constant(1.0 / value); - return div((Term) exp, constant(value)); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public Term abs(final Object exp) { - return new AbsTerm((Term) exp); - } - - @Override - public Term sin(final Object exp) { - return new SinTerm((Term) exp); - } - - @Override - public Term cos(final Object exp) { - return new CosTerm((Term) exp); - } - - @Override - public Term asin(final Object exp) { - return new ArcSinTerm((Term) exp); - } - - @Override - public Term acos(final Object exp) { - return new ArcCosTerm((Term) exp); - } - - @Override - public Term tan(final Object exp) { - return new TanTerm((Term) exp); - } - - @Override - public Term atan(final Object exp) { - return new ArcTanTerm((Term) exp); - } - - @Override - public Term atan2(final Object lhs, final Object rhs) { - return new ArcTan2Term((Term) lhs, (Term) rhs); - } - - @Override - public Term atan2(final Object lhs, final double rhs) { - return new ArcTan2Term((Term) lhs, constant(rhs)); - } - - @Override - public Term atan2(final double lhs, final Object rhs) { - return new ArcTan2Term(constant(lhs), (Term) rhs); - } - - @Override - public Term exp(final Object exp) { - return new ExpTerm((Term) exp); - } - - @Override - public Term log(final Object exp) { - return new LogTerm((Term) exp); - } - - @Override - public Term sqrt(final Object exp) { - return new SqrtTerm((Term) exp); - } - - @Override - public Term power(final Object lhs, final Object rhs) { - return new PowerTerm((Term) lhs, (Term) rhs); - } - - @Override - public Term power(final Object lhs, final double rhs) { - return new PowerTerm((Term) lhs, constant(rhs)); - } - - @Override - public Term power(final double lhs, final Object rhs) { - return new PowerTerm(constant(lhs), (Term) rhs); - } - - // ------------------------------------------------------------------------------------------------------------------ - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public Object makeIntVar(final String name, final int min, final int max) { - throw new UnsupportedOperationException("## Error: dReal does not support integer Variables"); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public ComparisonFormula eq(final int value, final Object exp) { - throw new UnsupportedOperationException("## Error: dReal does not support integer values"); - } - - @Override - public ComparisonFormula eq(final Object exp, final int value) { - throw new UnsupportedOperationException("## Error: dReal does not support integer values"); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public ComparisonFormula neq(final int value, final Object exp) { - throw new UnsupportedOperationException("## Error: dReal does not support integer values"); - } - - @Override - public ComparisonFormula neq(final Object exp, final int value) { - throw new UnsupportedOperationException("## Error: dReal does not support integer values"); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public ComparisonFormula leq(final int value, final Object exp) { - throw new UnsupportedOperationException("## Error: dReal does not support integer values"); - } - - @Override - public ComparisonFormula leq(final Object exp, final int value) { - throw new UnsupportedOperationException("## Error: dReal does not support integer values"); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public ComparisonFormula geq(final int value, final Object exp) { - throw new UnsupportedOperationException("## Error: dReal does not support integer values"); - } - - @Override - public ComparisonFormula geq(final Object exp, final int value) { - throw new UnsupportedOperationException("## Error: dReal does not support integer values"); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public ComparisonFormula lt(final int value, final Object exp) { - throw new UnsupportedOperationException("## Error: dReal does not support integer values"); - } - - @Override - public ComparisonFormula lt(final Object exp, final int value) { - throw new UnsupportedOperationException("## Error: dReal does not support integer values"); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public ComparisonFormula gt(final int value, final Object exp) { - throw new UnsupportedOperationException("## Error: dReal does not support integer values"); - } - - @Override - public ComparisonFormula gt(final Object exp, final int value) { - throw new UnsupportedOperationException("## Error: dReal does not support integer values"); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public Term plus(final int value, final Object exp) { - throw new UnsupportedOperationException("## Error: dReal does not support integer values"); - } - - @Override - public Term plus(final Object exp, final int value) { - throw new UnsupportedOperationException("## Error: dReal does not support integer values"); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public Term minus(final int value, final Object exp) { - throw new UnsupportedOperationException("## Error: dReal does not support integer values"); - } - - @Override - public Term minus(final Object exp, final int value) { - throw new UnsupportedOperationException("## Error: dReal does not support integer values"); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public Term mult(final int value, final Object exp) { - throw new UnsupportedOperationException("## Error: dReal does not support integer values"); - } - - @Override - public Term mult(final Object exp, final int value) { - throw new UnsupportedOperationException("## Error: dReal does not support integer values"); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public Term div(final int value, final Object exp) { - throw new UnsupportedOperationException("## Error: dReal does not support integer values"); - } - - @Override - public Term div(final Object exp, final int value) { - throw new UnsupportedOperationException("## Error: dReal does not support integer values"); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public Term and(final int value, final Object exp) { - throw new UnsupportedOperationException("## Error: dReal does not support bitwise operations"); - } - - @Override - public Term and(final Object exp, final int value) { - throw new UnsupportedOperationException("## Error: dReal does not support bitwise operations"); - } - - @Override - public Term and(final Object exp1, final Object exp2) { - throw new UnsupportedOperationException("## Error: dReal does not support bitwise operations"); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public Term or(final int value, final Object exp) { - throw new UnsupportedOperationException("## Error: dReal does not support bitwise operations"); - } - - @Override - public Term or(final Object exp, final int value) { - throw new UnsupportedOperationException("## Error: dReal does not support bitwise operations"); - } - - @Override - public Term or(final Object exp1, final Object exp2) { - throw new UnsupportedOperationException("## Error: dReal does not support bitwise operations"); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public Term xor(final int value, final Object exp) { - throw new UnsupportedOperationException("## Error: dReal does not support bitwise operations"); - } - - @Override - public Term xor(final Object exp, final int value) { - throw new UnsupportedOperationException("## Error: dReal does not support bitwise operations"); - } - - @Override - public Term xor(final Object exp1, final Object exp2) { - throw new UnsupportedOperationException("## Error: dReal does not support bitwise operations"); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public Term shiftL(final int value, final Object exp) { - throw new UnsupportedOperationException("## Error: dReal does not support bitwise operations"); - } - - @Override - public Term shiftL(final Object exp, final int value) { - throw new UnsupportedOperationException("## Error: dReal does not support bitwise operations"); - } - - @Override - public Term shiftL(final Object exp1, final Object exp2) { - throw new UnsupportedOperationException("## Error: dReal does not support bitwise operations"); - } - - @Override - public Term shiftR(final int value, final Object exp) { - throw new UnsupportedOperationException("## Error: dReal does not support bitwise operations"); - } - - @Override - public Term shiftR(final Object exp, final int value) { - throw new UnsupportedOperationException("## Error: dReal does not support bitwise operations"); - } - - @Override - public Term shiftR(final Object exp1, final Object exp2) { - throw new UnsupportedOperationException("## Error: dReal does not support bitwise operations"); - } - - @Override - public Term shiftUR(final int value, final Object exp) { - throw new UnsupportedOperationException("## Error: dReal does not support bitwise operations"); - } - - @Override - public Term shiftUR(final Object exp, final int value) { - throw new UnsupportedOperationException("## Error: dReal does not support bitwise operations"); - } - - @Override - public Term shiftUR(final Object exp1, final Object exp2) { - throw new UnsupportedOperationException("## Error: dReal does not support bitwise operations"); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public Term round(final Object exp) { - throw new RuntimeException("## Error: Math.round not supported by proteus (discontinuous function)"); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public Term mixed(final Object exp1, final Object exp2) { - throw new RuntimeException("## Error: dReal does not support integer arithmetic"); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public int getIntValue(final Object dpVar) { - throw new RuntimeException("## Error: dReal does not support integer variables"); - } - - // ------------------------------------------------------------------------------------------------------------------ - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public void postLogicalOR(final Object[] constraint) { - switch (constraint.length) { - case 0: - post(new FalseFormula()); - break; - case 1: - post(constraint[0]); - break; - default: - dLFormula fml = (dLFormula) constraint[0]; - for (int i = 1; i < constraint.length; i++) - fml = new OrFormula(fml, (dLFormula) constraint[i]); - post(fml); - } - } - - @Override - public void post(final Object constraint) { - formulas.add((dLFormula) constraint); - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - public Boolean solve() { - if (state != State.INIT) - throw new IllegalStateException(); - - final int counter; - synchronized (ProblemDReal.class) { - counter = ProblemDReal.counter++; - } - System.out.println("Calling dReal: " + counter); - - final dRealInterface dReal = precision <= 0 ? new dRealInterface() : new dRealInterface(precision); - if (timeBound > 0) - dReal.setTimeBound(timeBound); - System.out.println(formulas); - System.out.println("--------------------------------"); - try { - final LogicSolverResult sol = dReal.findInstance(formulas); - // for (final Object fml : formulas) - // System.out.println(fml); - // System.out.println("-----------------------------------------------------------------------"); - if ("delta-sat".equals(sol.satisfiability) || "sat".equals(sol.satisfiability)) { - valuation = sol.valuation; - state = State.SAT; - return Boolean.TRUE; - } else if ("unsat".equals(sol.satisfiability) || "delta-unsat".equals(sol.satisfiability)) { - state = State.UNSAT; - return Boolean.FALSE; - } else { - state = State.UNKNOWN; - return null; - } - } catch (final Exception e) { - throw new RuntimeException("Unknown error while solving the constraints", e); - } - } - - // ------------------------------------------------------------------------------------------------------------------ - - @Override - /**@return a lower bound on the minimum possible value of the input variable that solve the given constraints.*/ - public double getRealValueInf(final Object dpVar) { - return getRealValue(dpVar) - precision; - } - - @Override - /**@return an upper bound on the maximum possible value of the input variable that solve the given constraints.*/ - public double getRealValueSup(final Object dpVar) { - return getRealValue(dpVar) + precision; - } - - @Override - public double getRealValue(final Object dpVar) { - if (state != State.SAT) - throw new IllegalStateException("State of the problem is not SAT"); - final RealVariable v = (RealVariable) dpVar; - if (valuation.containsVariable(v)) - try { - return valuation.get(v).toDouble(); - } catch (final Exception e) { - /* Right now this happen if dpVar has an arbitrary assignment. One can return an arbitrary value instead of - * re-throwing the exception. If we want to do that, I recommend that the exception be specialized. */ - throw new RuntimeException(e); - } - throw new IllegalArgumentException("Variable is undefined"); - } - - // ------------------------------------------------------------------------------------------------------------------ - // ------------------------------------------------------------------------------------------------------------------ - - public static ProblemDReal createInstance(final gov.nasa.jpf.Config conf) { - final Mode mode = Mode.valueOf(conf.getString("dreal.mode", "STRICTIFIED").toUpperCase()); - final double precision = conf.getDouble("dreal.precision", 0.00001); - final int timeBound = conf.getInt("dreal.timeBound", 0); - return createInstance(mode, precision, timeBound); - } - - public static ProblemDReal createInstance(final Mode mode, final double precision, final int timeBound) { - if (mode == Mode.RELAXED) - return new ProblemDRealRelaxed(precision, timeBound); - return new ProblemDRealStrict(precision, timeBound); - } - - // ------------------------------------------------------------------------------------------------------------------ - - protected ProblemDReal(final Mode mode, final double precision, final int timeBound) { - this.mode = mode; - this.precision = precision; - this.timeBound = timeBound; - checkMode(mode); - checkPrecision(mode, precision); - checkTimeBound(timeBound); - } - - // ------------------------------------------------------------------------------------------------------------------ - // ------------------------------------------------------------------------------------------------------------------ - - private void checkMode(final Mode mode) { - if (mode == null) - throw new IllegalArgumentException("'mode' cannot be null"); - } - - private void checkPrecision(final Mode mode, final double precision) { - if (mode == Mode.RELAXED && precision < 0) - throw new IllegalArgumentException("precision must be non-negative"); - else if (mode == Mode.STRICTIFIED && precision <= 0) - throw new IllegalArgumentException("precision must be positive"); - if (!Double.isFinite(precision)) - throw new IllegalArgumentException("precision must be finite"); - if (Double.isNaN(precision)) - throw new IllegalArgumentException("precision must be a number"); - } - - private void checkTimeBound(final int timeBound) { - if (timeBound < 0) - throw new IllegalArgumentException("'timeBound' must be non-negative"); - } - - public double getPrecision() { - return precision; - } - - // ------------------------------------------------------------------------------------------------------------------ - - public Mode getMode() { - return mode; - } - - // ------------------------------------------------------------------------------------------------------------------ - - /** precision must be a non-negative number. Zero means use default value of the interface. */ - private final double precision; - - /** millisecond, it must be a non-negative number. Zero means no time-bound. */ - private final int timeBound; - - private final Mode mode; - private final List formulas = new ArrayList<>(); - private State state = State.INIT; - private Valuation valuation = null; - - private static final Real ZERO = new Real(0.0d); - private static final Real ZERO2 = new Real(-0.0d); - private static final Real ONE = new Real(1.0d); - - /** number of time dReal has been called to solve constraint (Performance metric) */ - private static int counter = 0; - - /** Possible states of the problem */ - public static enum State { - INIT, SAT, UNSAT, UNKNOWN - } - - /** Modes of the problem */ - public static enum Mode { - RELAXED, STRICTIFIED - } -} diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemGeneral.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemGeneral.java index a5fdabb..eacb470 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemGeneral.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemGeneral.java @@ -38,194 +38,183 @@ package gov.nasa.jpf.symbc.numeric.solvers; public abstract class ProblemGeneral{ - public abstract Object makeIntVar(String name, int min, int max); + public abstract Object makeIntVar(String name, long _min, long _max); public abstract Object makeRealVar(String name, double min, double max); - public abstract Object eq(int value, Object exp) ; - public abstract Object eq(Object exp, int value) ; + public abstract Object eq(long value, Object exp) ; + public abstract Object eq(Object exp, long value) ; public abstract Object eq(Object exp1, Object exp2) ; public abstract Object eq(double value, Object exp) ; public abstract Object eq(Object exp, double value) ; - public abstract Object neq(int value, Object exp) ; - public abstract Object neq(Object exp, int value) ; + public abstract Object neq(long value, Object exp) ; + public abstract Object neq(Object exp, long value) ; public abstract Object neq(Object exp1, Object exp2) ; public abstract Object neq(double value, Object exp) ; public abstract Object neq(Object exp, double value) ; - public abstract Object leq(int value, Object exp) ; - public abstract Object leq(Object exp, int value) ; + public abstract Object leq(long value, Object exp) ; + public abstract Object leq(Object exp, long value) ; public abstract Object leq(Object exp1, Object exp2) ; public abstract Object leq(double value, Object exp) ; public abstract Object leq(Object exp, double value) ; - public abstract Object geq(int value, Object exp) ; - public abstract Object geq(Object exp, int value) ; + public abstract Object geq(long value, Object exp) ; + public abstract Object geq(Object exp, long value) ; public abstract Object geq(Object exp1, Object exp2) ; public abstract Object geq(double value, Object exp) ; public abstract Object geq(Object exp, double value) ; - public abstract Object lt(int value, Object exp) ; - public abstract Object lt(Object exp, int value) ; + public abstract Object lt(long value, Object exp) ; + public abstract Object lt(Object exp, long value) ; public abstract Object lt(Object exp1, Object exp2) ; public abstract Object lt(double value, Object exp) ; public abstract Object lt(Object exp, double value) ; - public abstract Object gt(int value, Object exp) ; - public abstract Object gt(Object exp, int value) ; + public abstract Object gt(long value, Object exp) ; + public abstract Object gt(Object exp, long value) ; public abstract Object gt(Object exp1, Object exp2) ; public abstract Object gt(double value, Object exp) ; public abstract Object gt(Object exp, double value) ; - public abstract Object plus(int value, Object exp) ; - public abstract Object plus(Object exp, int value) ; + public abstract Object plus(long value, Object exp) ; + public abstract Object plus(Object exp, long value) ; public abstract Object plus(Object exp1, Object exp2) ; public abstract Object plus(double value, Object exp) ; public abstract Object plus(Object exp, double value) ; - public abstract Object minus(int value, Object exp) ; - public abstract Object minus(Object exp, int value) ; + public abstract Object minus(long value, Object exp) ; + public abstract Object minus(Object exp, long value) ; public abstract Object minus(Object exp1, Object exp2) ; public abstract Object minus(double value, Object exp) ; public abstract Object minus(Object exp, double value) ; - public abstract Object mult(int value, Object exp) ; - public abstract Object mult(Object exp, int value) ; + public abstract Object mult(long value, Object exp) ; + public abstract Object mult(Object exp, long value) ; public abstract Object mult(Object exp1, Object exp2) ; public abstract Object mult(double value, Object exp) ; public abstract Object mult(Object exp, double value) ; - public abstract Object div(int value, Object exp) ; - public abstract Object div(Object exp, int value) ; + public abstract Object div(long value, Object exp) ; + public abstract Object div(Object exp, long value) ; public abstract Object div(Object exp1, Object exp2) ; public abstract Object div(double value, Object exp) ; public abstract Object div(Object exp, double value) ; - public abstract Object and(int value, Object exp) ; - public abstract Object and(Object exp, int value) ; + + + + public abstract Object and(long value, Object exp) ; + public abstract Object and(Object exp, long value) ; public abstract Object and(Object exp1, Object exp2) ; - public abstract Object or(int value, Object exp) ; - public abstract Object or(Object exp, int value) ; + public abstract Object or(long value, Object exp) ; + public abstract Object or(Object exp, long value) ; public abstract Object or(Object exp1, Object exp2) ; - public abstract Object xor(int value, Object exp) ; - public abstract Object xor(Object exp, int value) ; + public abstract Object xor(long value, Object exp) ; + public abstract Object xor(Object exp, long value) ; public abstract Object xor(Object exp1, Object exp2) ; - public abstract Object shiftL(int value, Object exp) ; - public abstract Object shiftL(Object exp, int value) ; + public abstract Object shiftL(long value, Object exp) ; + public abstract Object shiftL(Object exp, long value) ; public abstract Object shiftL(Object exp1, Object exp2) ; - public abstract Object shiftR(int value, Object exp) ; - public abstract Object shiftR(Object exp, int value) ; + public abstract Object shiftR(long value, Object exp) ; + public abstract Object shiftR(Object exp, long value) ; public abstract Object shiftR(Object exp1, Object exp2) ; - public abstract Object shiftUR(int value, Object exp) ; - public abstract Object shiftUR(Object exp, int value) ; + public abstract Object shiftUR(long value, Object exp) ; + public abstract Object shiftUR(Object exp, long value) ; public abstract Object shiftUR(Object exp1, Object exp2) ; - public Object constant(final double d) { + public Object constant(double d) { throw new RuntimeException("## Error: constant not supported"); } - - // Added for arrays in Z3 - public Object select(Object exp1, Object exp2) { - throw new RuntimeException("## Error: Get in Array not supported"); - } - - public Object store(Object exp1, Object exp2, Object exp3) { - throw new RuntimeException("## Error : Store in Array not supported"); - } - - public Object makeArrayVar(String name) { - throw new RuntimeException("## Error: Array declaration not supported"); - } - - public Object makeIntConst(int value) { - throw new RuntimeException("## Error : makeIntConst not supported"); - } - - public Object realSelect(Object exp1, Object exp2) { - throw new RuntimeException("## Error: Get in Array not supported"); - } - - public Object realStore(Object exp1, Object exp2, Object exp3) { - throw new RuntimeException("## Error : Store in Array not supported"); - } - - public Object makeRealArrayVar(String name) { - throw new RuntimeException("## Error: Array declaration not supported"); - } - - public Object makeRealConst(double value) { - throw new RuntimeException("## Error : makeIntConst not supported"); - } - - public String getModel() { - throw new RuntimeException("## Error : not implemented if not z3"); - } - - /* Added for dReal by Nima - * Note: I had to add a default implementation in order to not break the current solvers. - * Furthermore, the default implementation must no throw an exception, since current solvers do not override it. - * This may result in more complex constraints and more computational time or even unsupported operations exceptions - * from the current solvers. */ - public Object abs(final Object exp) { - return sqrt(mult(exp, exp)); //OMG!! - } - - public Object sin(final Object exp) { + public Object sin(Object exp) { throw new RuntimeException("## Error: Math.sin not supported"); } - public Object cos(final Object exp) { + public Object cos(Object exp) { throw new RuntimeException("## Error: Math.cos not supported"); } - public Object round(final Object exp) { + public Object round(Object exp) { throw new RuntimeException("## Error: Math.round not supported"); } - public Object exp(final Object exp) { + public Object exp(Object exp) { throw new RuntimeException("## Error: Math.exp not supported"); } - public Object asin(final Object exp) { + public Object asin(Object exp) { throw new RuntimeException("## Error: Math.asin not supported"); } - public Object acos(final Object exp) { + public Object acos(Object exp) { throw new RuntimeException("## Error: Math.acos not supported"); } - public Object atan(final Object exp) { + public Object atan(Object exp) { throw new RuntimeException("## Error: Math.atan not supported"); } - public Object log(final Object exp) { + public Object log(Object exp) { throw new RuntimeException("## Error: Math.log not supported"); } - public Object tan(final Object exp) { + public Object tan(Object exp) { throw new RuntimeException("## Error: Math.tan not supported"); } - public Object sqrt(final Object exp) { + public Object sqrt(Object exp) { throw new RuntimeException("## Error: Math.sqrt not supported"); } - public Object power(final Object exp1, final Object exp2) { + public Object power(Object exp1, Object exp2) { throw new RuntimeException("## Error: Math.power not supported"); } - public Object power(final Object exp1, final double exp2) { + public Object power(Object exp1, double exp2) { throw new RuntimeException("## Error: Math.power not supported"); } - public Object power(final double exp1, final Object exp2) { + public Object power(double exp1, Object exp2) { throw new RuntimeException("## Error: Math.power not supported"); } - public Object atan2(final Object exp1, final Object exp2) { + public Object atan2(Object exp1, Object exp2) { throw new RuntimeException("## Error: Math.atan2 not supported"); } - public Object atan2(final Object exp1, final double exp2) { + public Object atan2(Object exp1, double exp2) { throw new RuntimeException("## Error: Math.atan2 not supported"); } - public Object atan2(final double exp1, final Object exp2) { + public Object atan2(double exp1, Object exp2) { throw new RuntimeException("## Error: Math.atan2 not supported"); } + // Added by Aymeric to support symbolic arrays + public Object makeArrayVar(String name) { + throw new RuntimeException("## Error : Array expressions not supported"); + } + + public Object makeRealArrayVar(String name) { + throw new RuntimeException("## Error : Array expressions not supported"); + } + + public Object select(Object exp1, Object exp2) { + throw new RuntimeException("## Error : Select array expressions not supported"); + } + + public Object store(Object exp1, Object exp2, Object exp3) { + throw new RuntimeException("## Error : Store array expressions not supported"); + } + + public Object realSelect(Object exp1, Object exp2) { + throw new RuntimeException("## Error : Real select array expressions not supported"); + } + + public Object realStore(Object exp1, Object exp2, Object exp3) { + throw new RuntimeException("## Error : Real store array expressions not supported"); + } + + public Object makeIntConst(long value) { + throw new RuntimeException("## Error : makeIntConst not supported"); + } + + public Object makeRealConst(double value) { + throw new RuntimeException("## Error : makeRealConst not supported"); + } + public abstract Object mixed(Object exp1, Object exp2); public abstract Boolean solve(); @@ -233,10 +222,13 @@ public Object atan2(final double exp1, final Object exp2) { public abstract double getRealValueInf(Object dpvar); public abstract double getRealValueSup(Object dpVar); public abstract double getRealValue(Object dpVar); - public abstract int getIntValue(Object dpVar); + public abstract long getIntValue(Object dpVar); public abstract void post(Object constraint); public abstract void postLogicalOR(Object [] constraint); - + + public abstract Object rem(Object exp1, Object exp2) ; + public abstract Object rem(long exp1, Object exp2) ; + public abstract Object rem(Object exp1, long exp2) ; } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemIAsolver.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemIAsolver.java index dc2b91d..8d7f60a 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemIAsolver.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemIAsolver.java @@ -51,7 +51,7 @@ public ProblemIAsolver() { pb = ""; } - public String makeIntVar(String name, int min, int max) { + public String makeIntVar(String name, long min, long max) { pb = pb + name + " >= " + min + "; "+ name + " <= " + max + "; "; return name; } @@ -61,8 +61,8 @@ public String makeRealVar(String name, double min, double max) { return name; } - public Object eq(int value, Object exp){return value + " = " + (String)exp + "; ";} - public Object eq(Object exp, int value){return (String)exp + " = " + value + "; ";} + public Object eq(long value, Object exp){return value + " = " + (String)exp + "; ";} + public Object eq(Object exp, long value){return (String)exp + " = " + value + "; ";} public Object eq(Object exp1, Object exp2){ return (String)exp1 + " = " + (String)exp2 + "; "; } @@ -70,8 +70,8 @@ public Object eq(Object exp1, Object exp2){ public Object eq(double value, Object exp){return String.format(format,value) + " = " + (String)exp + "; ";} public Object eq(Object exp, double value){return (String)exp + " = " + String.format(format,value) + "; ";} - public Object neq(int value, Object exp){return value + " != " + (String)exp + "; ";} - public Object neq(Object exp, int value){return (String)exp + " != " + value + "; ";} + public Object neq(long value, Object exp){return value + " != " + (String)exp + "; ";} + public Object neq(Object exp, long value){return (String)exp + " != " + value + "; ";} public Object neq(Object exp1, Object exp2){ return (String)exp1 + " != " + (String)exp2 + "; "; } @@ -79,24 +79,24 @@ public Object neq(Object exp1, Object exp2){ public Object neq(Object exp, double value){return (String)exp + " != " + String.format(format,value) + "; ";} - public Object leq(int value, Object exp){return value + " <= " + (String)exp + "; ";} - public Object leq(Object exp, int value){return (String)exp + " <= " + value + "; ";} + public Object leq(long value, Object exp){return value + " <= " + (String)exp + "; ";} + public Object leq(Object exp, long value){return (String)exp + " <= " + value + "; ";} public Object leq(Object exp1, Object exp2){ return (String)exp1 + " <= " + (String)exp2 + "; "; } public Object leq(double value, Object exp){return String.format(format,value) + " <= " + (String)exp + "; ";} public Object leq(Object exp, double value){return (String)exp + " <= " + String.format(format,value) + "; ";} - public Object geq(int value, Object exp){return value + " >= " + (String)exp + "; ";} - public Object geq(Object exp, int value){return (String)exp + " >= " + value + "; ";} + public Object geq(long value, Object exp){return value + " >= " + (String)exp + "; ";} + public Object geq(Object exp, long value){return (String)exp + " >= " + value + "; ";} public Object geq(Object exp1, Object exp2){ return (String)exp1 + " >= " + (String)exp2 + "; "; } public Object geq(double value, Object exp){return String.format(format,value) + " >= " + (String)exp + "; ";} public Object geq(Object exp, double value){return (String)exp + " >= " + String.format(format,value) + "; ";} - public Object lt(int value, Object exp){return value + " < " + (String)exp + "; ";} - public Object lt(Object exp, int value){return (String)exp + " < " + value + "; ";} + public Object lt(long value, Object exp){return value + " < " + (String)exp + "; ";} + public Object lt(Object exp, long value){return (String)exp + " < " + value + "; ";} public Object lt(Object exp1, Object exp2){ return (String)exp1 + " < " + (String)exp2 + "; "; } @@ -104,34 +104,34 @@ public Object lt(Object exp1, Object exp2){ public Object lt(Object exp, double value){return (String)exp + " < " + String.format(format,value) + "; ";} - public Object gt(int value, Object exp){return value + " > " + (String)exp + "; ";} - public Object gt(Object exp, int value){return (String)exp + " > " + value + "; ";} + public Object gt(long value, Object exp){return value + " > " + (String)exp + "; ";} + public Object gt(Object exp, long value){return (String)exp + " > " + value + "; ";} public Object gt(Object exp1, Object exp2){ return (String)exp1 + " > " + (String)exp2 + "; "; } public Object gt(double value, Object exp){return String.format(format,value) + " > " + (String)exp + "; ";} public Object gt(Object exp, double value){return (String)exp + " > " + String.format(format,value) + "; ";} - public Object plus(int value, Object exp) {return "("+value + "+" + exp +")" ;} - public Object plus(Object exp, int value) {return "("+exp + "+" + value +")" ;} + public Object plus(long value, Object exp) {return "("+value + "+" + exp +")" ;} + public Object plus(Object exp, long value) {return "("+exp + "+" + value +")" ;} public Object plus(Object exp1, Object exp2) {return "("+exp1 + "+" + exp2 +")" ;} public Object plus(double value, Object exp) {return "("+String.format(format,value) + "+" + exp +")" ;} public Object plus(Object exp, double value) {return "("+exp + "+" + String.format(format,value) +")" ;} - public Object minus(int value, Object exp) {return "("+value + "-" + exp +")" ;} - public Object minus(Object exp, int value) {return "("+exp + "-" + value +")" ;} + public Object minus(long value, Object exp) {return "("+value + "-" + exp +")" ;} + public Object minus(Object exp, long value) {return "("+exp + "-" + value +")" ;} public Object minus(Object exp1, Object exp2) {return "("+exp1 + "-" + exp2 +")" ;} public Object minus(double value, Object exp) {return "("+String.format(format,value) + "-" + exp +")" ;} public Object minus(Object exp, double value) {return "("+exp + "-" + String.format(format,value) +")" ;} - public Object mult(int value, Object exp) {return "("+value + "*" + exp +")" ;} - public Object mult(Object exp, int value) {return "("+exp + "*" + value +")" ;} + public Object mult(long value, Object exp) {return "("+value + "*" + exp +")" ;} + public Object mult(Object exp, long value) {return "("+exp + "*" + value +")" ;} public Object mult(Object exp1, Object exp2) {return "("+exp1 + "*" + exp2 +")" ;} public Object mult(double value, Object exp) {return "("+String.format(format,value) + "*" + exp +")" ;} public Object mult(Object exp, double value) {return "("+exp + "*" + String.format(format,value) +")" ;} - public Object div(int value, Object exp) {return "("+value + "/" + exp +")" ;} - public Object div(Object exp, int value) {return "("+exp + "/" + value +")" ;} + public Object div(long value, Object exp) {return "("+value + "/" + exp +")" ;} + public Object div(Object exp, long value) {return "("+exp + "/" + value +")" ;} public Object div(Object exp1, Object exp2) {return "("+exp1 + "/" + exp2 +")" ;} public Object div(double value, Object exp) {return "("+String.format(format,value) + "/" + exp +")" ;} public Object div(Object exp, double value) {return "("+exp + "/" + String.format(format,value) +")" ;} @@ -242,7 +242,7 @@ public double getRealValue(Object dpVar) { throw new RuntimeException("# Error: IASolver can not compute real solution!"); } - public int getIntValue(Object dpVar) { + public long getIntValue(Object dpVar) { throw new RuntimeException("# Error: IASolver can not compute int solution!"); } @@ -268,11 +268,11 @@ public void post(Object constraint) { pb = pb + constraint; } - public Object and(int value, Object exp) { + public Object and(long value, Object exp) { throw new RuntimeException("## Error IASolver does not support bitwise AND"); } - public Object and(Object exp, int value) { + public Object and(Object exp, long value) { throw new RuntimeException("## Error IASolver does not support bitwise AND"); } @@ -281,12 +281,12 @@ public Object and(Object exp1, Object exp2) { } @Override - public Object or(int value, Object exp) { + public Object or(long value, Object exp) { throw new RuntimeException("## Error IASolver does not support bitwise OR"); } @Override - public Object or(Object exp, int value) { + public Object or(Object exp, long value) { throw new RuntimeException("## Error IASolver does not support bitwise OR"); } @@ -295,27 +295,27 @@ public Object or(Object exp1, Object exp2) { throw new RuntimeException("## Error IASolver does not support bitwise OR"); } - public Object shiftL(int value, Object exp) { + public Object shiftL(long value, Object exp) { throw new RuntimeException("## Error IASolver does not support bitwise SHIFT"); } - public Object shiftL(Object exp, int value) { + public Object shiftL(Object exp, long value) { throw new RuntimeException("## Error IASolver does not support bitwise SHIFT"); } - public Object shiftR(int value, Object exp) { + public Object shiftR(long value, Object exp) { throw new RuntimeException("## Error IASolver does not support bitwise SHIFT"); } - public Object shiftR(Object exp, int value) { + public Object shiftR(Object exp, long value) { throw new RuntimeException("## Error IASolver does not support bitwise SHIFT"); } - public Object xor(int value, Object exp) { + public Object xor(long value, Object exp) { throw new RuntimeException("## Error IASolver does not support bitwise XOR"); } - public Object xor(Object exp, int value) { + public Object xor(Object exp, long value) { throw new RuntimeException("## Error IASolver does not support bitwise XOR"); } @@ -331,12 +331,12 @@ public Object shiftR(Object exp1, Object exp2) { throw new RuntimeException("## Error IASolver does not support bitwise SHIFT"); } - public Object shiftUR(int value, Object exp) { + public Object shiftUR(long value, Object exp) { throw new RuntimeException("## Error IASolver does not support bitwise SHIFT"); } - public Object shiftUR(Object exp, int value) { + public Object shiftUR(Object exp, long value) { throw new RuntimeException("## Error IASolver does not support bitwise SHIFT"); } @@ -350,5 +350,23 @@ public void postLogicalOR(Object[] constraint) { throw new RuntimeException("## Error IASolver does not support LogicalOR"); } + @Override + public Object rem(Object exp1, Object exp2) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object rem(long exp1, Object exp2) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Object rem(Object exp1, long exp2) { + // TODO Auto-generated method stub + return null; + } + } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemYices.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemYices.java index 8511959..e769392 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemYices.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemYices.java @@ -125,7 +125,7 @@ public double getYicesDouble(String value) return Double.valueOf(value); } - public String makeIntVar(String name, int min, int max) { + public String makeIntVar(String name, long min, long max) { yices.yicesl_read(ctx,"(define "+name+"::int)"); yices.yicesl_read(ctx,"(assert (>= "+ name + " " + min +"))"); yices.yicesl_read(ctx,"(assert (<= "+ name + " " + max +"))"); @@ -139,62 +139,62 @@ public String makeRealVar(String name, double min, double max) { return name; } - public Object eq(int value, Object exp){return "(= " + value + " " + (String)exp + ")";} - public Object eq(Object exp, int value){return "(= " + (String)exp + " " + value + ")";} + public Object eq(long value, Object exp){return "(= " + value + " " + (String)exp + ")";} + public Object eq(Object exp, long value){return "(= " + (String)exp + " " + value + ")";} public Object eq(Object exp1, Object exp2){return "(= " + (String)exp1 + " " + (String)exp2 + ")";} public Object eq(double value, Object exp){return "(= " + getYicesDouble(value) + " " + (String)exp + ")";} public Object eq(Object exp, double value){return "(= " + (String)exp + " " + getYicesDouble(value) + ")";} - public Object neq(int value, Object exp){return "(/= " + value + " " + (String)exp + ")";} - public Object neq(Object exp, int value){return "(/= " + (String)exp + " " + value + ")";} + public Object neq(long value, Object exp){return "(/= " + value + " " + (String)exp + ")";} + public Object neq(Object exp, long value){return "(/= " + (String)exp + " " + value + ")";} public Object neq(Object exp1, Object exp2){return "(/= " + (String)exp1 + " " + (String)exp2 + ")";} public Object neq(double value, Object exp){return "(/= " + getYicesDouble(value) + " " + (String)exp + ")";} public Object neq(Object exp, double value){return "(/= " + (String)exp + " " + getYicesDouble(value) + ")";} - public Object leq(int value, Object exp){return "(<= " + value + " " + (String)exp + ")";} - public Object leq(Object exp, int value){return "(<= " + (String)exp + " " + value + ")";} + public Object leq(long value, Object exp){return "(<= " + value + " " + (String)exp + ")";} + public Object leq(Object exp, long value){return "(<= " + (String)exp + " " + value + ")";} public Object leq(Object exp1, Object exp2){return "(<= " + (String)exp1 + " " + (String)exp2 + ")";} public Object leq(double value, Object exp){return "(<= " + getYicesDouble(value) + " " + (String)exp + ")";} public Object leq(Object exp, double value){return "(<= " + (String)exp + " " + getYicesDouble(value) + ")";} - public Object geq(int value, Object exp){return "(>= " + value + " " + (String)exp + ")";} - public Object geq(Object exp, int value){return "(>= " + (String)exp + " " + value + ")";} + public Object geq(long value, Object exp){return "(>= " + value + " " + (String)exp + ")";} + public Object geq(Object exp, long value){return "(>= " + (String)exp + " " + value + ")";} public Object geq(Object exp1, Object exp2){return "(>= " + (String)exp1 + " " + (String)exp2 + ")";} public Object geq(double value, Object exp){return "(>= " + getYicesDouble(value) + " " + (String)exp + ")";} public Object geq(Object exp, double value){return "(>= " + (String)exp + " " + getYicesDouble(value) + ")";} - public Object lt(int value, Object exp){return "(< " + value + " " + (String)exp + ")";} - public Object lt(Object exp, int value){return "(< " + (String)exp + " " + value + ")";} + public Object lt(long value, Object exp){return "(< " + value + " " + (String)exp + ")";} + public Object lt(Object exp, long value){return "(< " + (String)exp + " " + value + ")";} public Object lt(Object exp1, Object exp2){return "(< " + (String)exp1 + " " + (String)exp2 + ")";} public Object lt(double value, Object exp){return "(< " + getYicesDouble(value) + " " + (String)exp + ")";} public Object lt(Object exp, double value){return "(< " + (String)exp + " " + getYicesDouble(value) + ")";} - public Object gt(int value, Object exp){return "(> " + value + " " + (String)exp + ")";} - public Object gt(Object exp, int value){return "(> " + (String)exp + " " + value + ")";} + public Object gt(long value, Object exp){return "(> " + value + " " + (String)exp + ")";} + public Object gt(Object exp, long value){return "(> " + (String)exp + " " + value + ")";} public Object gt(Object exp1, Object exp2){return "(> " + (String)exp1 + " " + (String)exp2 + ")";} public Object gt(double value, Object exp){return "(> " + getYicesDouble(value) + " " + (String)exp + ")";} public Object gt(Object exp, double value){return "(> " + (String)exp + " " + getYicesDouble(value) + ")";} - public Object plus(int value, Object exp) {return "(+ " + value + " " + (String)exp + ")";} - public Object plus(Object exp, int value) {return "(+ " + (String)exp + " " + value + ")";} + public Object plus(long value, Object exp) {return "(+ " + value + " " + (String)exp + ")";} + public Object plus(Object exp, long value) {return "(+ " + (String)exp + " " + value + ")";} public Object plus(Object exp1, Object exp2) {return "(+ " + (String)exp1 + " " + (String)exp2 + ")";} public Object plus(double value, Object exp) {return "(+ " + getYicesDouble(value) + " " + (String)exp + ")";} public Object plus(Object exp, double value) {return "(+ " + (String)exp + " " + getYicesDouble(value) + ")";} - public Object minus(int value, Object exp) {return "(- " + value + " " + (String)exp + ")";} - public Object minus(Object exp, int value) {return "(- " + (String)exp + " " + value + ")";} + public Object minus(long value, Object exp) {return "(- " + value + " " + (String)exp + ")";} + public Object minus(Object exp, long value) {return "(- " + (String)exp + " " + value + ")";} public Object minus(Object exp1, Object exp2) {return "(- " + (String)exp1 + " " + (String)exp2 + ")";} public Object minus(double value, Object exp) {return "(- " + getYicesDouble(value) + " " + (String)exp + ")";} public Object minus(Object exp, double value) {return "(- " + (String)exp + " " + getYicesDouble(value) + ")";} - public Object mult(int value, Object exp) {return "(* " + value + " " + (String)exp + ")";} - public Object mult(Object exp, int value) {return "(* " + (String)exp + " " + value + ")";} + public Object mult(long value, Object exp) {return "(* " + value + " " + (String)exp + ")";} + public Object mult(Object exp, long value) {return "(* " + (String)exp + " " + value + ")";} public Object mult(Object exp1, Object exp2) {return "(* " + (String)exp1 + " " + (String)exp2 + ")";} public Object mult(double value, Object exp) {return "(* " + getYicesDouble(value) + " " + (String)exp + ")";} public Object mult(Object exp, double value) {return "(* " + (String)exp + " " + getYicesDouble(value) + ")";} - public Object div(int value, Object exp) {return "(/ " + value + " " + (String)exp + ")";} - public Object div(Object exp, int value) {return "(/ " + (String)exp + " " + value + ")";} + public Object div(long value, Object exp) {return "(/ " + value + " " + (String)exp + ")";} + public Object div(Object exp, long value) {return "(/ " + (String)exp + " " + value + ")";} public Object div(Object exp1, Object exp2) {return "(/ " + (String)exp1 + " " + (String)exp2 + ")";} public Object div(double value, Object exp) {return "(/ " + getYicesDouble(value) + " " + (String)exp + ")";} public Object div(Object exp, double value) {return "(/ " + (String)exp + " " + getYicesDouble(value) + ")";} @@ -264,7 +264,7 @@ public double getRealValue(Object dpVar) { return 0.0; } - public int getIntValue(Object dpVar) { + public long getIntValue(Object dpVar) { String vname = (String) dpVar; if (modelMap.containsKey(vname)) { @@ -299,11 +299,11 @@ public void post(Object constraint) { yices.yicesl_read(ctx,"(assert " + (String)constraint + ")"); } - public Object and(int value, Object exp) { + public Object and(long value, Object exp) { throw new RuntimeException("## Error Yices does not support bitwise AND"); } - public Object and(Object exp, int value) { + public Object and(Object exp, long value) { throw new RuntimeException("## Error Yices does not support bitwise AND"); } @@ -313,13 +313,13 @@ public Object and(Object exp1, Object exp2) { @Override public - Object or(int value, Object exp) { + Object or(long value, Object exp) { throw new RuntimeException("## Error Yices does not support bitwise OR"); } @Override public - Object or(Object exp, int value) { + Object or(Object exp, long value) { throw new RuntimeException("## Error Yices does not support bitwise OR"); } @@ -331,37 +331,37 @@ Object or(Object exp1, Object exp2) { @Override public - Object shiftL(int value, Object exp) { + Object shiftL(long value, Object exp) { throw new RuntimeException("## Error Yices does not support bitwise shiftL"); } @Override public - Object shiftL(Object exp, int value) { + Object shiftL(Object exp, long value) { throw new RuntimeException("## Error Yices does not support bitwise shiftL"); } @Override public - Object shiftR(int value, Object exp) { + Object shiftR(long value, Object exp) { throw new RuntimeException("## Error Yices does not support bitwise shiftR"); } @Override public - Object shiftR(Object exp, int value) { + Object shiftR(Object exp, long value) { throw new RuntimeException("## Error Yices does not support bitwise shiftR"); } @Override public - Object xor(int value, Object exp) { + Object xor(long value, Object exp) { throw new RuntimeException("## Error Yices does not support bitwise XOR"); } @Override public - Object xor(Object exp, int value) { + Object xor(Object exp, long value) { throw new RuntimeException("## Error Yices does not support bitwise XOR"); } @@ -382,12 +382,12 @@ public Object shiftR(Object exp1, Object exp2) { } @Override - public Object shiftUR(int value, Object exp) { + public Object shiftUR(long value, Object exp) { throw new RuntimeException("## Error Yices does not support bitwise shiftUR"); } @Override - public Object shiftUR(Object exp, int value) { + public Object shiftUR(Object exp, long value) { throw new RuntimeException("## Error Yices does not support bitwise shiftUR"); } @@ -407,4 +407,22 @@ public void postLogicalOR(Object[] constraints) { post(orResult); } +@Override +public Object rem(Object exp1, Object exp2) { + // TODO Auto-generated method stub + return null; +} + +@Override +public Object rem(long exp1, Object exp2) { + // TODO Auto-generated method stub + return null; +} + +@Override +public Object rem(Object exp1, long exp2) { + // TODO Auto-generated method stub + return null; +} + } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemZ3.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemZ3.java index f1aeeb4..872658b 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemZ3.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/ProblemZ3.java @@ -37,98 +37,135 @@ package gov.nasa.jpf.symbc.numeric.solvers; +import java.util.*; + //TODO: problem: we do not distinguish between ints and reals? // still needs a lot of work: do not use! -import java.util.HashMap; -import java.util.List; - -import com.microsoft.z3.ArithExpr; -import com.microsoft.z3.ArrayExpr; -import com.microsoft.z3.BoolExpr; -import com.microsoft.z3.Context; -import com.microsoft.z3.Expr; -import com.microsoft.z3.IntExpr; -import com.microsoft.z3.Model; -import com.microsoft.z3.RealExpr; -import com.microsoft.z3.Sort; -import com.microsoft.z3.Solver; -import com.microsoft.z3.Status; - +import com.microsoft.z3.*; +import gov.nasa.jpf.symbc.SymbolicInstructionFactory; +import symlib.Util; public class ProblemZ3 extends ProblemGeneral { - Context ctx; - Solver solver; - public ProblemZ3() { - HashMap cfg = new HashMap(); - cfg.put("model", "true"); + //This class acts as a safeguard to prevent + //issues when referencing ProblemZ3 in case the z3 libs are + //not on the ld_library_path. If the + //Z3 solver object and context were class fields, + //we would likely encounter a linker error + private static class Z3Wrapper { + private Context ctx; + private Solver solver; + + private static Z3Wrapper instance = null; + + public static Z3Wrapper getInstance() { + if (instance != null) { + return instance; + } + return instance = new Z3Wrapper(); + } - try{ + private Z3Wrapper() { + HashMap cfg = new HashMap(); + cfg.put("model", "true"); ctx = new Context(cfg); - solver = ctx.MkSolver(); - - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); - } + solver = ctx.mkSolver(); + } + + public Solver getSolver() { + return this.solver; + } + + public Context getCtx() { + return this.ctx; + } } + private Solver solver; + private Context ctx; - //if min or max are passed in as null objects - //it will use minus and plus infinity - // TODO: to add ranges - public Object makeIntVar(String name, int min, int max) { - try{ - - return ctx.MkIntConst(name); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); + // Do we use the floating point theory or linear arithmetic over reals + private boolean useFpForReals = false; - } + public ProblemZ3() { + Z3Wrapper z3 = Z3Wrapper.getInstance(); + solver = z3.getSolver(); + ctx = z3.getCtx(); + solver.push(); + useFpForReals = SymbolicInstructionFactory.fp; } + public void cleanup() { + int scopes = solver.getNumScopes(); + if (scopes > 0) { + solver.pop(scopes); + } + } - // TODO: to add ranges - public Object makeRealVar(String name, double min, double max) { +// public ProblemZ3() { +// HashMap cfg = new HashMap(); +// cfg.put("model", "true"); +// ctx = new Context(cfg); +// solver = ctx.mkSolver(); +// } +// +// public void cleanup() { +// this.solver.reset(); +// this.ctx.dispose(); +// } - try{ - return ctx.MkReal(name); + public Object makeIntVar(String name, long min, long max) { + try { + IntExpr intConst = ctx.mkIntConst(name); + solver.add(ctx.mkGe(intConst, ctx.mkInt(min))); + solver.add(ctx.mkLe(intConst, ctx.mkInt(max))); + return intConst; } catch (Exception e) { e.printStackTrace(); - throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); - + throw new RuntimeException("## Error Z3: Exception caught in makeIntVar: \n" + e); } } - public Object eq(int value, Object exp){ - try{ - return ctx.MkEq( ctx.MkInt(value), (IntExpr)exp); - + public Object makeRealVar(String name, double min, double max) { + try { + if (useFpForReals) { + Expr expr = ctx.mkConst(name, ctx.mkFPSortDouble()); + solver.add(ctx.mkFPGt((FPExpr) expr, ctx.mkFP(min, ctx.mkFPSortDouble()))); + solver.add(ctx.mkFPLt((FPExpr) expr, ctx.mkFP(max, ctx.mkFPSortDouble()))); + return expr; + } else { + RealExpr expr = ctx.mkRealConst(name); + solver.add(ctx.mkGe(expr, ctx.mkReal("" + min))); + solver.add(ctx.mkLe(expr, ctx.mkReal("" + max))); + return expr; + } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); - } } - public Object eq(Object exp, int value){ - try{ - return ctx.MkEq( ctx.MkInt(value), (IntExpr)exp); + public Object eq(long value, Object exp){ + try { + return ctx.mkEq( ctx.mkInt(value), (Expr)exp); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); - } } + public Object eq(Object exp, long value){ + + return ctx.mkEq(ctx.mkInt(value), (Expr)exp); + } + // should we use Expr or ArithExpr? public Object eq(Object exp1, Object exp2){ try{ - return ctx.MkEq((Expr)exp1, (Expr)exp2); + return ctx.mkEq((Expr)exp1, (Expr)exp2); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); @@ -157,42 +194,30 @@ public Object eq(Object exp1, Object exp2){ // } // } - public Object neq(int value, Object exp){ - try{ - return ctx.MkNot(ctx.MkEq(ctx.MkInt(value), (IntExpr)exp)); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); - - } + public Object neq(long value, Object exp){ + return ctx.mkNot(ctx.mkEq(ctx.mkInt(value), (Expr)exp)); } - public Object neq(Object exp, int value){ - try{ - return ctx.MkNot(ctx.MkEq(ctx.MkInt(value), (IntExpr)exp)); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); - - } + + public Object neq(Object exp, long value){ + return ctx.mkNot(ctx.mkEq(ctx.mkInt(value), (Expr) exp)); } public Object neq(Object exp1, Object exp2){ try{ - return ctx.MkNot(ctx.MkEq((Expr)exp1, (Expr)exp2)); + return ctx.mkNot(ctx.mkEq((Expr)exp1, (Expr)exp2)); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); - } } public Object not(Object exp1){ try{ - return ctx.MkNot((BoolExpr)exp1); + return ctx.mkNot((BoolExpr)exp1); } catch (Exception e) { e.printStackTrace(); - throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); + throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); } } @@ -203,7 +228,7 @@ public Object not(Object exp1){ // return vc.notExpr(vc.eqExpr(vc.ratExpr(Double.toString(value), base), (Expr)exp)); // } catch (Exception e) { // e.printStackTrace(); -// throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); +// throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); // // } // } @@ -213,14 +238,14 @@ public Object not(Object exp1){ // return vc.notExpr(vc.eqExpr((Expr)exp, vc.ratExpr(Double.toString(value), base))); // } catch (Exception e) { // e.printStackTrace(); -// throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); +// throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); // // } // } - public Object leq(int value, Object exp){ + public Object leq(long value, Object exp){ try{ - return ctx.MkLe(ctx.MkInt(value), (IntExpr)exp); + return ctx.mkLe(ctx.mkInt(value), (IntExpr)exp); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); @@ -228,9 +253,9 @@ public Object leq(int value, Object exp){ } } - public Object leq(Object exp, int value){ + public Object leq(Object exp, long value){ try{ - return ctx.MkLe((IntExpr)exp,ctx.MkInt(value)); + return ctx.mkLe((IntExpr)exp,ctx.mkInt(value)); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); @@ -240,7 +265,7 @@ public Object leq(Object exp, int value){ public Object leq(Object exp1, Object exp2){ try{ - return ctx.MkLe((ArithExpr)exp1, (ArithExpr)exp2); + return ctx.mkLe((ArithExpr)exp1, (ArithExpr)exp2); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); @@ -253,7 +278,7 @@ public Object leq(Object exp1, Object exp2){ // return vc.leExpr(vc.ratExpr(Double.toString(value), base), (Expr)exp); // } catch (Exception e) { // e.printStackTrace(); -// throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); +// throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); // // } // } @@ -263,14 +288,14 @@ public Object leq(Object exp1, Object exp2){ // return vc.leExpr((Expr)exp, vc.ratExpr(Double.toString(value), base)); // } catch (Exception e) { // e.printStackTrace(); -// throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); +// throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); // // } // } // - public Object geq(int value, Object exp){ + public Object geq(long value, Object exp){ try{ - return ctx.MkGe(ctx.MkInt(value),(IntExpr)exp); + return ctx.mkGe(ctx.mkInt(value),(IntExpr)exp); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); @@ -278,9 +303,9 @@ public Object geq(int value, Object exp){ } } - public Object geq(Object exp, int value){ + public Object geq(Object exp, long value){ try{ - return ctx.MkGe((IntExpr)exp,ctx.MkInt(value)); + return ctx.mkGe((IntExpr)exp,ctx.mkInt(value)); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); @@ -290,7 +315,7 @@ public Object geq(Object exp, int value){ public Object geq(Object exp1, Object exp2){ try{ - return ctx.MkGe((ArithExpr)exp1,(ArithExpr)exp2); + return ctx.mkGe((ArithExpr)exp1,(ArithExpr)exp2); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); @@ -303,7 +328,7 @@ public Object geq(Object exp1, Object exp2){ // return vc.geExpr(vc.ratExpr(Double.toString(value), base), (Expr)exp); // } catch (Exception e) { // e.printStackTrace(); -// throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); +// throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); // // } // } @@ -313,14 +338,14 @@ public Object geq(Object exp1, Object exp2){ // return vc.geExpr((Expr)exp, vc.ratExpr(Double.toString(value), base)); // } catch (Exception e) { // e.printStackTrace(); -// throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); +// throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); // // } // } // - public Object lt(int value, Object exp){ + public Object lt(long value, Object exp){ try{ - return ctx.MkLt(ctx.MkInt(value),(IntExpr)exp); + return ctx.mkLt(ctx.mkInt(value),(IntExpr)exp); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); @@ -328,9 +353,9 @@ public Object lt(int value, Object exp){ } } - public Object lt(Object exp, int value){ + public Object lt(Object exp, long value){ try{ - return ctx.MkLt((IntExpr)exp,ctx.MkInt(value)); + return ctx.mkLt((IntExpr)exp,ctx.mkInt(value)); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); @@ -340,7 +365,7 @@ public Object lt(Object exp, int value){ public Object lt(Object exp1, Object exp2){ try{ - return ctx.MkLt((ArithExpr)exp1,(ArithExpr)exp2); + return ctx.mkLt((ArithExpr)exp1,(ArithExpr)exp2); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); @@ -353,7 +378,7 @@ public Object lt(Object exp1, Object exp2){ // return vc.ltExpr(vc.ratExpr(Double.toString(value), base), (Expr)exp); // } catch (Exception e) { // e.printStackTrace(); -// throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); +// throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); // // } // } @@ -363,15 +388,15 @@ public Object lt(Object exp1, Object exp2){ // return vc.ltExpr((Expr)exp, vc.ratExpr(Double.toString(value), base)); // } catch (Exception e) { // e.printStackTrace(); -// throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); +// throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); // // } // } // // - public Object gt(int value, Object exp){ + public Object gt(long value, Object exp){ try{ - return ctx.MkGt(ctx.MkInt(value),(IntExpr)exp); + return ctx.mkGt(ctx.mkInt(value),(IntExpr)exp); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); @@ -379,9 +404,9 @@ public Object gt(int value, Object exp){ } } - public Object gt(Object exp, int value){ + public Object gt(Object exp, long value){ try{ - return ctx.MkGt((IntExpr)exp,ctx.MkInt(value)); + return ctx.mkGt((IntExpr)exp,ctx.mkInt(value)); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); @@ -391,7 +416,7 @@ public Object gt(Object exp, int value){ public Object gt(Object exp1, Object exp2){ try{ - return ctx.MkGt((ArithExpr)exp1,(ArithExpr)exp2); + return ctx.mkGt((ArithExpr)exp1,(ArithExpr)exp2); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); @@ -404,7 +429,7 @@ public Object gt(Object exp1, Object exp2){ // return vc.impliesExpr((Expr)exp1, (Expr)exp2); // } catch (Exception e) { // e.printStackTrace(); -// throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); +// throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); // // } // } @@ -414,7 +439,7 @@ public Object gt(Object exp1, Object exp2){ // return vc.gtExpr(vc.ratExpr(Double.toString(value), base), (Expr)exp); // } catch (Exception e) { // e.printStackTrace(); -// throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); +// throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); // // } // } @@ -424,7 +449,7 @@ public Object gt(Object exp1, Object exp2){ // return vc.gtExpr((Expr)exp, vc.ratExpr(Double.toString(value), base)); // } catch (Exception e) { // e.printStackTrace(); -// throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); +// throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); // // } // } @@ -432,18 +457,18 @@ public Object gt(Object exp1, Object exp2){ // // // - public Object plus(int value, Object exp) { + public Object plus(long value, Object exp) { try{ - return ctx.MkAdd(new ArithExpr[] { ctx.MkInt(value), (IntExpr)exp}); + return ctx.mkAdd(new ArithExpr[] { ctx.mkInt(value), (IntExpr)exp}); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); } } - public Object plus(Object exp, int value) { + public Object plus(Object exp, long value) { try{ - return ctx.MkAdd(new ArithExpr[] { ctx.MkInt(value), (IntExpr)exp}); + return ctx.mkAdd(new ArithExpr[] { ctx.mkInt(value), (IntExpr)exp}); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); @@ -452,7 +477,7 @@ public Object plus(Object exp, int value) { public Object plus(Object exp1, Object exp2) { try{ - return ctx.MkAdd(new ArithExpr[] { (ArithExpr)exp1, (ArithExpr)exp2}); + return ctx.mkAdd(new ArithExpr[] { (ArithExpr)exp1, (ArithExpr)exp2}); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); @@ -464,7 +489,7 @@ public Object plus(Object exp1, Object exp2) { // return vc.plusExpr(vc.ratExpr(Double.toString(value), base), (Expr)exp); // } catch (Exception e) { // e.printStackTrace(); -// throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); +// throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); // } // } // @@ -473,22 +498,22 @@ public Object plus(Object exp1, Object exp2) { // return vc.plusExpr((Expr)exp, vc.ratExpr(Double.toString(value), base)); // } catch (Exception e) { // e.printStackTrace(); -// throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); +// throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); // } // } - public Object minus(int value, Object exp) { + public Object minus(long value, Object exp) { try{ - return ctx.MkSub(new ArithExpr[] { ctx.MkInt(value), (IntExpr)exp}); + return ctx.mkSub(new ArithExpr[] { ctx.mkInt(value), (IntExpr)exp}); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); } } - public Object minus(Object exp, int value) { + public Object minus(Object exp, long value) { try{ - return ctx.MkSub(new ArithExpr[] {(IntExpr)exp, ctx.MkInt(value)}); + return ctx.mkSub(new ArithExpr[] {(IntExpr)exp, ctx.mkInt(value)}); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); @@ -497,7 +522,7 @@ public Object minus(Object exp, int value) { public Object minus(Object exp1, Object exp2) { try{ - return ctx.MkSub(new ArithExpr[] { (ArithExpr)exp1, (ArithExpr)exp2}); + return ctx.mkSub(new ArithExpr[] { (ArithExpr)exp1, (ArithExpr)exp2}); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); @@ -509,7 +534,7 @@ public Object minus(Object exp1, Object exp2) { // return vc.minusExpr(vc.ratExpr(Double.toString(value), base), (Expr)exp); // } catch (Exception e) { // e.printStackTrace(); -// throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); +// throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); // } // } // @@ -518,22 +543,22 @@ public Object minus(Object exp1, Object exp2) { // return vc.minusExpr((Expr)exp, vc.ratExpr(Double.toString(value), base)); // } catch (Exception e) { // e.printStackTrace(); -// throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); +// throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); // } // } - public Object mult(int value, Object exp) { + public Object mult(long value, Object exp) { try{ - return ctx.MkMul(new ArithExpr[] {(IntExpr)exp, ctx.MkInt(value)}); + return ctx.mkMul(new ArithExpr[] {(IntExpr)exp, ctx.mkInt(value)}); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); } } - public Object mult(Object exp, int value) { + public Object mult(Object exp, long value) { try{ - return ctx.MkMul(new ArithExpr[] {(IntExpr)exp, ctx.MkInt(value)}); + return ctx.mkMul(new ArithExpr[] {(IntExpr)exp, ctx.mkInt(value)}); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); @@ -542,7 +567,7 @@ public Object mult(Object exp, int value) { public Object mult(Object exp1, Object exp2) { try{ - return ctx.MkMul(new ArithExpr[] {(ArithExpr)exp1, (ArithExpr)exp2}); + return ctx.mkMul(new ArithExpr[] {(ArithExpr)exp1, (ArithExpr)exp2}); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); @@ -553,7 +578,7 @@ public Object mult(Object exp1, Object exp2) { // return vc.multExpr(vc.ratExpr(Double.toString(value), base), (Expr)exp); // } catch (Exception e) { // e.printStackTrace(); -// throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); +// throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); // } // } // public Object mult(Object exp, double value) { @@ -561,24 +586,24 @@ public Object mult(Object exp1, Object exp2) { // return vc.multExpr((Expr)exp, vc.ratExpr(Double.toString(value), base)); // } catch (Exception e) { // e.printStackTrace(); -// throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); +// throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); // } // } // // - public Object div(int value, Object exp) { + public Object div(long value, Object exp) { try{ - return ctx.MkDiv(ctx.MkInt(value), (IntExpr)exp); + return ctx.mkDiv(ctx.mkInt(value), (IntExpr)exp); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); } } - public Object div(Object exp, int value) { + public Object div(Object exp, long value) { try{ - return ctx.MkDiv((IntExpr)exp,ctx.MkInt(value)); + return ctx.mkDiv((IntExpr)exp,ctx.mkInt(value)); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); @@ -587,18 +612,48 @@ public Object div(Object exp, int value) { public Object div(Object exp1, Object exp2) { try{ - return ctx.MkDiv((ArithExpr)exp1,(ArithExpr)exp2); + return ctx.mkDiv((ArithExpr)exp1,(ArithExpr)exp2); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); } } + + public Object rem(Object exp, long value) {// added by corina + try{ + + return ctx.mkRem((IntExpr) exp, ctx.mkInt(value)); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); + } + } + public Object rem(long value, Object exp) {// added by corina + try{ + + return ctx.mkRem(ctx.mkInt(value), (IntExpr) exp); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); + } + } + public Object rem(Object exp1, Object exp2) {// added by corina + try{ + if(exp2 instanceof Integer) + return ctx.mkRem((IntExpr)exp1,ctx.mkInt((Integer)exp2)); + return ctx.mkRem((IntExpr) exp1, (IntExpr) exp2); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); + } + } + // public Object div(double value, Object exp) { // try{ // return vc.divideExpr(vc.ratExpr(Double.toString(value), base), (Expr)exp); // } catch (Exception e) { // e.printStackTrace(); -// throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); +// throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); // } // } // public Object div(Object exp, double value) { @@ -606,91 +661,19 @@ public Object div(Object exp1, Object exp2) { // return vc.divideExpr((Expr)exp, vc.ratExpr(Double.toString(value), base)); // } catch (Exception e) { // e.printStackTrace(); -// throw new RuntimeException("## Error CVC3: Exception caught in CVC3 JNI: \n" + e); +// throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); // } // } - public Object select(Object exp1, Object exp2) { - try { - return ctx.MkSelect((ArrayExpr)exp1, (IntExpr)exp2); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); - } - } - - public Object store(Object exp1, Object exp2, Object exp3) { - try { - return ctx.MkStore((ArrayExpr)exp1, (IntExpr)exp2, (IntExpr)exp3); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); - } - } - - public Object makeArrayVar(String name) { - try { - Sort int_type = ctx.IntSort(); - return ctx.MkArrayConst(name, int_type, int_type); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: " + e); - } - } - - public Object makeIntConst(int value) { - try { - return ctx.MkInt(value); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("## Error Z3 : Exception caught in Z3 JNI: " + e); - } - } - - - public Object realSelect(Object exp1, Object exp2) { - try { - return ctx.MkSelect((ArrayExpr)exp1, (RealExpr)exp2); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); - } - } - - public Object realStore(Object exp1, Object exp2, Object exp3) { - try { - return ctx.MkStore((ArrayExpr)exp1, (IntExpr)exp2, (RealExpr)exp3); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); - } - } - - public Object makeRealArrayVar(String name) { - try { - Sort int_type = ctx.IntSort(); - Sort real_type = ctx.RealSort(); - return ctx.MkArrayConst(name, int_type, real_type); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: " + e); - } - } - - public Object makeRealConst(double value) { - throw new RuntimeException("floats not supported by Z3"); - } - - - public int getIntValue(Object dpVar) { - try{ + public long getIntValue(Object dpVar) { + try { Model model = null; - if (Status.SATISFIABLE == solver.Check()) - { - model = solver.Model(); - return Integer.parseInt((model.Evaluate((IntExpr)dpVar,false)).toString()); + if (Status.SATISFIABLE == solver.check()) { + model = solver.getModel(); + return Long.parseLong((model.evaluate((IntExpr)dpVar,false)).toString()); } else { + System.out.println("Error retrieving int value from Z3."); assert false; // should not be reachable return 0; } @@ -700,8 +683,6 @@ public int getIntValue(Object dpVar) { } } - - private Expr test(){ Expr e = (Expr)makeIntVar("Z",-10, 10); Expr f = (Expr)makeIntVar("f", -10,10); @@ -714,358 +695,529 @@ private Expr test(){ public Boolean solve() { try { /* find model for the constraints above */ - Model model = null; - if (Status.SATISFIABLE == solver.Check()) - { - model = solver.Model(); - // System.out.println(model); + Model model = null; + + if (Status.SATISFIABLE == solver.check()) { return true; - } else - + } else { return false; - - - }catch(Exception e){ + } + } catch(Exception e){ e.printStackTrace(); throw new RuntimeException("## Error Z3: " + e); } } - public String getModel() { - try { - if (Status.SATISFIABLE == solver.Check()) - { - return solver.Model().toString(); - } else - return ""; - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("## Error Z3: " +e); - } - } - public void post(Object constraint) { try{ - solver.Assert((BoolExpr)constraint); + //solver.Assert((BoolExpr)constraint); + solver.add((BoolExpr)constraint); } catch (Exception e) { e.printStackTrace(); - throw new RuntimeException("## Error Z3 \n" + e); + throw new RuntimeException("## Error posting constraint to Z3 \n" + e); } } - - - // need to implement all of these @Override public Object eq(double value, Object exp) { - // TODO Auto-generated method stub - throw new RuntimeException("## Error Z3 \n"); + try { + if (useFpForReals) { + return ctx.mkFPEq(ctx.mkFPNumeral(value, ctx.mkFPSort64()), (FPExpr) exp); + } else { + return ctx.mkEq(ctx.mkReal("" + value), (Expr) exp); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: eq(double, Object) failed.\n" + e); + } } - @Override public Object eq(Object exp, double value) { - // TODO Auto-generated method stub - throw new RuntimeException("## Error Z3 \n"); + try { + if (useFpForReals) { + return ctx.mkFPEq((FPExpr) exp, ctx.mkFPNumeral(value, ctx.mkFPSort64())); + } else { + return ctx.mkEq((Expr) exp, ctx.mkReal("" + value)); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: eq(double, Object) failed.\n" + e); + } } - @Override public Object neq(double value, Object exp) { - // TODO Auto-generated method stub - throw new RuntimeException("## Error Z3 \n"); + try { + if (useFpForReals) { + return ctx.mkNot(ctx.mkFPEq(ctx.mkFPNumeral(value, ctx.mkFPSort64()), (FPExpr) exp)); + } else { + return ctx.mkNot(ctx.mkEq(ctx.mkReal("" + value), (Expr) exp)); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: neq(double, Object) failed.\n" + e); + } } - @Override public Object neq(Object exp, double value) { - // TODO Auto-generated method stub - throw new RuntimeException("## Error Z3 \n"); + try { + if (useFpForReals) { + return ctx.mkNot(ctx.mkFPEq((FPExpr) exp, ctx.mkFPNumeral(value, ctx.mkFPSort64()))); + } else { + return ctx.mkNot(ctx.mkEq((Expr) exp, ctx.mkReal("" + value))); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: neq(double, Object) failed.\n" + e); + } } - @Override public Object leq(double value, Object exp) { - // TODO Auto-generated method stub - throw new RuntimeException("## Error Z3 \n"); + try { + if (useFpForReals) { + return ctx.mkFPLEq(ctx.mkFPNumeral(value, ctx.mkFPSort64()), (FPExpr) exp); + } else { + return ctx.mkLe(ctx.mkReal("" + value), (ArithExpr) exp); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: leq(double, Object) failed.\n" + e); + } } - @Override public Object leq(Object exp, double value) { - // TODO Auto-generated method stub - throw new RuntimeException("## Error Z3 \n"); + try { + if (useFpForReals) { + return ctx.mkFPLEq((FPExpr) exp, ctx.mkFPNumeral(value, ctx.mkFPSort64())); + } else { + return ctx.mkLe((ArithExpr) exp, ctx.mkReal("" + value)); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: leq(double, Object) failed.\n" + e); + } } - - - @Override public Object geq(double value, Object exp) { - // TODO Auto-generated method stub - throw new RuntimeException("## Error Z3 \n"); + try { + if (useFpForReals) { + return ctx.mkFPGEq(ctx.mkFPNumeral(value, ctx.mkFPSort64()), (FPExpr) exp); + } else { + return ctx.mkGe(ctx.mkReal("" + value), (ArithExpr) exp); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: geq(double, Object) failed.\n" + e); + } } - @Override public Object geq(Object exp, double value) { - // TODO Auto-generated method stub - throw new RuntimeException("## Error Z3 \n"); + try { + if (useFpForReals) { + return ctx.mkFPGEq((FPExpr) exp, ctx.mkFPNumeral(value, ctx.mkFPSort64())); + } else { + return ctx.mkGe((ArithExpr) exp, ctx.mkReal("" + value)); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: geq(double, Object) failed.\n" + e); + } } - - - - @Override public Object lt(double value, Object exp) { - // TODO Auto-generated method stub - throw new RuntimeException("## Error Z3 \n"); + try { + if (useFpForReals) { + return ctx.mkFPLt(ctx.mkFPNumeral(value, ctx.mkFPSort64()), (FPExpr) exp); + } else { + return ctx.mkLt(ctx.mkReal("" + value), (ArithExpr) exp); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: lt(double, Object) failed.\n" + e); + } } - @Override public Object lt(Object exp, double value) { - // TODO Auto-generated method stub - throw new RuntimeException("## Error Z3 \n"); + try { + if (useFpForReals) { + return ctx.mkFPLt((FPExpr) exp, ctx.mkFPNumeral(value, ctx.mkFPSort64())); + } else { + return ctx.mkLt((ArithExpr) exp, ctx.mkReal("" + value)); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: lt(double, Object) failed.\n" + e); + } } - - - - @Override public Object gt(double value, Object exp) { - // TODO Auto-generated method stub - throw new RuntimeException("## Error Z3 \n"); + try { + if (useFpForReals) { + return ctx.mkFPGt(ctx.mkFPNumeral(value, ctx.mkFPSort64()), (FPExpr) exp); + } else { + return ctx.mkGt(ctx.mkReal("" + value), (ArithExpr) exp); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: gt(double, Object) failed.\n" + e); + } } - @Override public Object gt(Object exp, double value) { - // TODO Auto-generated method stub - throw new RuntimeException("## Error Z3 \n"); + try { + if (useFpForReals) { + return ctx.mkFPGt((FPExpr) exp, ctx.mkFPNumeral(value, ctx.mkFPSort64())); + } else { + return ctx.mkGt((ArithExpr) exp, ctx.mkReal("" + value)); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: gt(double, Object) failed.\n" + e); + } } + @Override + public Object plus(double value, Object exp) { + try { + if (useFpForReals) { + return ctx.mkFPAdd(ctx.mkFPRoundNearestTiesToEven(), ctx.mkFPNumeral(value, ctx.mkFPSort64()), (FPExpr) exp); + } else { + return ctx.mkAdd(ctx.mkReal("" + value), (ArithExpr) exp); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: plus(Object, double) failed.\n" + e); + } + } + @Override + public Object plus(Object exp, double value) { + try { + if (useFpForReals) { + return ctx.mkFPAdd(ctx.mkFPRoundNearestTiesToEven(), (FPExpr) exp, ctx.mkFPNumeral(value, ctx.mkFPSort64())); + } else { + return ctx.mkAdd((ArithExpr) exp, ctx.mkReal("" + value)); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: plus(Object, double) failed.\n" + e); + } + } @Override public Object minus(double value, Object exp) { - // TODO Auto-generated method stub - throw new RuntimeException("## Error Z3 \n"); + try { + if (useFpForReals) { + return ctx.mkFPSub(ctx.mkFPRoundNearestTiesToEven(), ctx.mkFPNumeral(value, ctx.mkFPSort64()), (FPExpr) exp); + } else { + return ctx.mkSub(ctx.mkReal("" + value), (ArithExpr) exp); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: minus(double, Object) failed.\n" + e); + } } - @Override public Object minus(Object exp, double value) { - // TODO Auto-generated method stub - throw new RuntimeException("## Error Z3 \n"); + try { + if (useFpForReals) { + return ctx.mkFPSub(ctx.mkFPRoundNearestTiesToEven(), (FPExpr) exp, ctx.mkFPNumeral(value, ctx.mkFPSort64())); + } else { + return ctx.mkSub((ArithExpr) exp, ctx.mkReal("" + value)); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: minus(double, Object) failed.\n" + e); + } } - - @Override public Object mult(double value, Object exp) { - // TODO Auto-generated method stub - throw new RuntimeException("## Error Z3 \n"); + try { + if (useFpForReals) { + return ctx.mkFPMul(ctx.mkFPRoundNearestTiesToEven(), ctx.mkFPNumeral(value, ctx.mkFPSort64()), (FPExpr) exp); + } else { + return ctx.mkMul(ctx.mkReal("" + value), (ArithExpr) exp); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: mult(double, Object) failed.\n" + e); + } } - @Override public Object mult(Object exp, double value) { - // TODO Auto-generated method stub - throw new RuntimeException("## Error Z3 \n"); + try { + if (useFpForReals) { + return ctx.mkFPMul(ctx.mkFPRoundNearestTiesToEven(), (FPExpr) exp, ctx.mkFPNumeral(value, ctx.mkFPSort64())); + } else { + return ctx.mkMul((ArithExpr) exp, ctx.mkReal("" + value)); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: mult(double, Object) failed.\n" + e); + } } @Override public Object div(double value, Object exp) { - // TODO Auto-generated method stub - throw new RuntimeException("## Error Z3 \n"); + try { + if (useFpForReals) { + return ctx.mkFPDiv(ctx.mkFPRoundNearestTiesToEven(), ctx.mkFPNumeral(value, ctx.mkFPSort64()), (FPExpr) exp); + } else { + return ctx.mkDiv(ctx.mkReal("" + value), (ArithExpr) exp); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: div(double, Object) failed.\n" + e); + } } - @Override public Object div(Object exp, double value) { - // TODO Auto-generated method stub - throw new RuntimeException("## Error Z3 \n"); + try { + if (useFpForReals) { + return ctx.mkFPDiv(ctx.mkFPRoundNearestTiesToEven(), (FPExpr) exp, ctx.mkFPNumeral(value, ctx.mkFPSort64())); + } else { + return ctx.mkDiv((ArithExpr) exp, ctx.mkReal("" + value)); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: div(double, Object) failed.\n" + e); + } } - - + @Override - public Object and(int value, Object exp) { - // TODO Auto-generated method stub + public Object and(long value, Object exp) { throw new RuntimeException("## Error Z3 \n"); } - - + @Override - public Object and(Object exp, int value) { - // TODO Auto-generated method stub + public Object and(Object exp, long value) { throw new RuntimeException("## Error Z3 \n"); } - @Override public Object and(Object exp1, Object exp2) { - // TODO Auto-generated method stub throw new RuntimeException("## Error Z3 \n"); } - @Override - public Object or(int value, Object exp) { - // TODO Auto-generated method stub + public Object or(long value, Object exp) { throw new RuntimeException("## Error Z3 \n"); } - @Override - public Object or(Object exp, int value) { - // TODO Auto-generated method stub + public Object or(Object exp, long value) { throw new RuntimeException("## Error Z3 \n"); } - @Override public Object or(Object exp1, Object exp2) { - // TODO Auto-generated method stub throw new RuntimeException("## Error Z3 \n"); } - @Override - public Object xor(int value, Object exp) { - // TODO Auto-generated method stub + public Object xor(long value, Object exp) { throw new RuntimeException("## Error Z3 \n"); } - @Override - public Object xor(Object exp, int value) { - // TODO Auto-generated method stub + public Object xor(Object exp, long value) { throw new RuntimeException("## Error Z3 \n"); } - @Override public Object xor(Object exp1, Object exp2) { - // TODO Auto-generated method stub throw new RuntimeException("## Error Z3 \n"); } - @Override - public Object shiftL(int value, Object exp) { - // TODO Auto-generated method stub + public Object shiftL(long value, Object exp) { throw new RuntimeException("## Error Z3 \n"); } - @Override - public Object shiftL(Object exp, int value) { - // TODO Auto-generated method stub + public Object shiftL(Object exp, long value) { throw new RuntimeException("## Error Z3 \n"); } - @Override public Object shiftL(Object exp1, Object exp2) { - // TODO Auto-generated method stub throw new RuntimeException("## Error Z3 \n"); } - @Override - public Object shiftR(int value, Object exp) { - // TODO Auto-generated method stub + public Object shiftR(long value, Object exp) { throw new RuntimeException("## Error Z3 \n"); } - @Override - public Object shiftR(Object exp, int value) { - // TODO Auto-generated method stub + public Object shiftR(Object exp, long value) { throw new RuntimeException("## Error Z3 \n"); } - @Override public Object shiftR(Object exp1, Object exp2) { - // TODO Auto-generated method stub throw new RuntimeException("## Error Z3 \n"); } - @Override - public Object shiftUR(int value, Object exp) { - // TODO Auto-generated method stub + public Object shiftUR(long value, Object exp) { throw new RuntimeException("## Error Z3 \n"); } - @Override - public Object shiftUR(Object exp, int value) { - // TODO Auto-generated method stub + public Object shiftUR(Object exp, long value) { throw new RuntimeException("## Error Z3 \n"); } - @Override public Object shiftUR(Object exp1, Object exp2) { - // TODO Auto-generated method stub throw new RuntimeException("## Error Z3 \n"); } - @Override public Object mixed(Object exp1, Object exp2) { // TODO Auto-generated method stub throw new RuntimeException("## Error Z3 \n"); } - @Override public double getRealValueInf(Object dpvar) { - // TODO Auto-generated method stub - throw new RuntimeException("## Error Z3 \n");//return 0; + try { + Model model = null; + if (Status.SATISFIABLE == solver.check()) { + model = solver.getModel(); + // TODO: clean this up + String strResult = model.eval((Expr)dpvar, true).toString().replaceAll("\\s+",""); + Expr temp = model.eval((Expr)dpvar, false); + if (temp instanceof com.microsoft.z3.RatNum) { + strResult = ((com.microsoft.z3.RatNum)temp).toDecimalString(10); + } + return Double.parseDouble(strResult); + } + else { + assert false; // should not be reachable + return 0; + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3: Exception caught in Z3 JNI: \n" + e); + } } - @Override public double getRealValueSup(Object dpVar) { // TODO Auto-generated method stub throw new RuntimeException("## Error Z3 \n");//return 0; } - @Override public double getRealValue(Object dpVar) { // TODO Auto-generated method stub throw new RuntimeException("## Error Z3 \n");//return 0; } - @Override public void postLogicalOR(Object[] constraint) { // TODO Auto-generated method stub throw new RuntimeException("## Error Z3 \n"); } + // Added by Aymeric to support arrays + @Override + public Object makeArrayVar(String name) { + try { + Sort int_type = ctx.mkIntSort(); + return ctx.mkArrayConst(name, int_type, int_type); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3 : Exception caught in Z3 JNI: " + e); + } + } - @Override - public Object plus(double value, Object exp) { - // TODO Auto-generated method stub - throw new RuntimeException("## Error Z3 \n"); - } + @Override + public Object makeRealArrayVar(String name) { + try { + Sort int_type = ctx.mkIntSort(); + Sort real_type = ctx.mkRealSort(); + return ctx.mkArrayConst(name, int_type, real_type); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3 : Exception caught in Z3 JNI: " + e); + } + } + + @Override + public Object select(Object exp1, Object exp2) { + try { + return ctx.mkSelect((ArrayExpr)exp1, (IntExpr)exp2); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3 : Exception caught in Z3 JNI: " + e); + } + } + @Override + public Object store(Object exp1, Object exp2, Object exp3) { + try { + return ctx.mkStore((ArrayExpr)exp1, (IntExpr)exp2, (IntExpr)exp3); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3 : Exception caught in Z3 JNI: " + e); + } + } - @Override - public Object plus(Object exp, double value) { - // TODO Auto-generated method stub - throw new RuntimeException("## Error Z3 \n"); - } + @Override + public Object realSelect(Object exp1, Object exp2) { + try { + return ctx.mkSelect((ArrayExpr)exp1, (IntExpr)exp2); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3 : Exception caught in Z3 JNI: " + e); + } + } + @Override + public Object realStore(Object exp1, Object exp2, Object exp3) { + try { + return ctx.mkStore((ArrayExpr)exp1, (IntExpr)exp2, (RealExpr)exp3); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3 : Exception caught in Z3 JNI: " + e); + } + } - + @Override + public Object makeIntConst(long value) { + try { + return ctx.mkInt(value); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3 : Exception caught in Z3 JNI: " + e); + } + } + + @Override + public Object makeRealConst(double value) { + try { + return ctx.mkReal("" + value); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("## Error Z3 : Exception caught in Z3 JNI: " + e); + } + } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/SolverTranslator.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/SolverTranslator.java index b725393..eac0084 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/SolverTranslator.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/SolverTranslator.java @@ -38,24 +38,47 @@ public class SolverTranslator { private static Map instanceCache = new HashMap(); - public static Instance createInstance(Constraint constraint) { - Constraint c = constraint; // first constraint - Constraint r = c.getTail(); // rest of constraint - Instance p = null; // parent instance - if (r != null) { - p = instanceCache.get(new ConstraintSequence(r)); - if (p == null) { - p = createInstance(r); -// instanceCache.put(r, p); + public static Instance createInstance(Constraint c) { + + Expression e = null; + + while (c != null) { + Translator translator = new Translator(); + c.accept(translator); + + Expression tmp = translator.getExpression(); + + if (e == null) { + e = tmp; + } else { + e = new Operation(Operation.Operator.AND, e, tmp); } + + c = c.and; } - Translator translator = new Translator(); - c.accept(translator); - Instance i = new Instance(SymbolicInstructionFactory.greenSolver, p, translator.getExpression()); - instanceCache.put(new ConstraintSequence(constraint), i); - return i; + + Instance greenPC = new Instance(SymbolicInstructionFactory.greenSolver, null, e); + return greenPC; } +// public static Instance createInstance(Constraint constraint) { +// Constraint c = constraint; // first constraint +// Constraint r = c.getTail(); // rest of constraint +// Instance p = null; // parent instance +// if (r != null) { +// p = instanceCache.get(new ConstraintSequence(r)); +// if (p == null) { +// p = createInstance(r); +//// instanceCache.put(r, p); +// } +// } +// Translator translator = new Translator(); +// c.accept(translator); +// Instance i = new Instance(SymbolicInstructionFactory.greenSolver, p, translator.getExpression()); +// instanceCache.put(new ConstraintSequence(constraint), i); +// return i; +// } + private final static class ConstraintSequence { private final Constraint sequence; @@ -169,12 +192,13 @@ public void postVisit(BinaryLinearIntegerExpression expression) { @Override public void postVisit(IntegerConstant constant) { - stack.push(new IntConstant(constant.value)); + stack.push(new IntConstant((int)constant.value)); } @Override public void postVisit(SymbolicInteger node) { - stack.push(new IntVariable(node.getName(), node, node._min, node._max)); + assert(node._min>=Integer.MIN_VALUE && node._max<=Integer.MAX_VALUE); + stack.push(new IntVariable(node.getName(), node, (int) node._min, (int) node._max)); } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/TablePrinter.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/TablePrinter.java index c977346..bd0d136 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/TablePrinter.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/solvers/TablePrinter.java @@ -70,15 +70,15 @@ public static void main(String[] args) { System.out.println("=================================="); general.printLatex(); - } catch (IOException _) { + } catch (IOException e) { System.err.println(ERR_MSG); - _.printStackTrace(); + e.printStackTrace(); System.exit(-1); - } catch (ClassNotFoundException _) { + } catch (ClassNotFoundException e) { String msg = "Looks like you changed structure or name of the class " + "contained in the serialiable files after generating the file."; System.err.println(msg); - _.printStackTrace(); + e.printStackTrace(); System.exit(-1); } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/visitors/CollectVariableVisitor.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/visitors/CollectVariableVisitor.java index c0bdb73..c79ffb3 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/visitors/CollectVariableVisitor.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/numeric/visitors/CollectVariableVisitor.java @@ -22,12 +22,14 @@ import java.util.Set; import gov.nasa.jpf.symbc.numeric.ConstraintExpressionVisitor; +import gov.nasa.jpf.symbc.numeric.Expression; import gov.nasa.jpf.symbc.numeric.SymbolicInteger; import gov.nasa.jpf.symbc.numeric.SymbolicReal; +import gov.nasa.jpf.symbc.string.StringSymbolic; public class CollectVariableVisitor extends ConstraintExpressionVisitor { - private Set variables = new HashSet(); + private Set variables = new HashSet(); @Override public void postVisit(SymbolicReal realVariable) { @@ -38,8 +40,13 @@ public void postVisit(SymbolicReal realVariable) { public void postVisit(SymbolicInteger integerVariable) { variables.add(integerVariable); } + + @Override + public void postVisit(StringSymbolic stringVariable) { + variables.add(stringVariable); + } - public Set getVariables() { + public Set getVariables() { return variables; } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/AutomatonExtra.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/AutomatonExtra.java index 8b837fd..72cf005 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/AutomatonExtra.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/AutomatonExtra.java @@ -30,10 +30,13 @@ import dk.brics.automaton.State; import dk.brics.automaton.StatePair; import dk.brics.automaton.Transition; +import gov.nasa.jpf.util.LogManager; +import java.util.logging.Logger; public class AutomatonExtra { - public static boolean logging = false; + //public static boolean logging = false; + static Logger logger = LogManager.getLogger("stringsolver"); /* * Automaton.makeAnyString() produces a language that accepts words @@ -374,7 +377,7 @@ public static Automaton[] splitByCharacter (char c, Automaton a) { else { if (stateWhereSplitOccurs != null && stateWhereSplitOccurs == s) { /* Ignore the rest of this states transitions */ - println("[splitByCharacter] Investigate"); + logger.info("[splitByCharacter] Investigate"); continue; } Transition t1 = new Transition(t.getMin(), t.getMax(), stateMapA1.get(t.getDest())); @@ -408,7 +411,7 @@ public static Automaton insertSingleChar (char c, Automaton a) { for (Transition t: s.getTransitions()) { if (t.getMin() <= c && c <= t.getMax()) { //System.out.println("[Automatan Extra, insertSingleChar] character already inserted"); - println ("[insertSingleChar] character already inserted"); + logger.info ("[insertSingleChar] character already inserted"); return a.clone(); } } @@ -489,7 +492,7 @@ public static Automaton intersection (Automaton a, Automaton b) { } //System.out.println("[AutomatanExtra, intersection] Specail chars in A: " + specialCharsInA); - println ("[intersection] Specail chars in A: " + specialCharsInA); + logger.info ("[intersection] Specail chars in A: " + specialCharsInA); for (State s: b.getStates()) { @@ -505,7 +508,7 @@ public static Automaton intersection (Automaton a, Automaton b) { throw new RuntimeException("[AutomatanExtra, intersection] This was not considered"); } //System.out.println("[AutomatanExtra, intersection] Specail chars in B: " + specialCharsInB); - println ("[intersection] Specail chars in B: " + specialCharsInB); + logger.info ("[intersection] Specail chars in B: " + specialCharsInB); for (Integer i: specialCharsInB) { if (!specialCharsInA.contains(i) && !missingCharsInA.contains(i)) { @@ -514,7 +517,7 @@ public static Automaton intersection (Automaton a, Automaton b) { } //System.out.println("[AutomatanExtra, intersection] Missing chars in A: " + missingCharsInA); - println("[intersection] Missing chars in A: " + missingCharsInA); + logger.info("[intersection] Missing chars in A: " + missingCharsInA); for (Integer i: specialCharsInA) { @@ -524,7 +527,7 @@ public static Automaton intersection (Automaton a, Automaton b) { } //System.out.println("[AutomatanExtra, intersection] Missing chars in B: " + missingCharsInB); - println ("[intersection] Missing chars in B: " + missingCharsInB); + logger.info ("[intersection] Missing chars in B: " + missingCharsInB); /* TODO: Improve performance */ @@ -622,12 +625,6 @@ public static Automaton minus (Automaton a1, Automaton a2) { return AutomatonExtra.intersection(a1, a2.complement().intersection(AutomatonExtra.makeAnyStringFixed())); } - private static void println (String s) { - if (logging) { - System.out.println("[AutomatanExtra] " + s); - } - } - public static Automaton lengthAutomaton (int length) { Automaton result = Automaton.makeEmptyString(); for (int i = 0; i < length; i++) { diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringComparator.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringComparator.java index e4bfb0d..7b7f8d7 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringComparator.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringComparator.java @@ -16,83 +16,85 @@ * limitations under the License. */ -/* Copyright (C) 2005 United States Government as represented by the -Administrator of the National Aeronautics and Space Administration -(NASA). All Rights Reserved. - -Copyright (C) 2009 Fujitsu Laboratories of America, Inc. - -DISCLAIMER OF WARRANTIES AND LIABILITIES; WAIVER AND INDEMNIFICATION - -A. No Warranty: THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY -WARRANTY OF ANY KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, -INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE -WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR FREEDOM FROM -INFRINGEMENT, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL BE ERROR -FREE, OR ANY WARRANTY THAT DOCUMENTATION, IF PROVIDED, WILL CONFORM TO -THE SUBJECT SOFTWARE. NO SUPPORT IS WARRANTED TO BE PROVIDED AS IT IS PROVIDED "AS-IS". - -B. Waiver and Indemnity: RECIPIENT AGREES TO WAIVE ANY AND ALL CLAIMS -AGAINST FUJITSU LABORATORIES OF AMERICA AND ANY OF ITS AFFILIATES, THE -UNITED STATES GOVERNMENT, ITS CONTRACTORS AND SUBCONTRACTORS, AS WELL -AS ANY PRIOR RECIPIENT. IF RECIPIENT'S USE OF THE SUBJECT SOFTWARE -RESULTS IN ANY LIABILITIES, DEMANDS, DAMAGES, EXPENSES OR LOSSES ARISING -FROM SUCH USE, INCLUDING ANY DAMAGES FROM PRODUCTS BASED ON, OR RESULTING -FROM, RECIPIENT'S USE OF THE SUBJECT SOFTWARE, RECIPIENT SHALL INDEMNIFY -AND HOLD HARMLESS FUJITSU LABORATORTIES OF AMERICA AND ANY OF ITS AFFILIATES, -THE UNITED STATES GOVERNMENT, ITS CONTRACTORS AND SUBCONTRACTORS, AS WELL -AS ANY PRIOR RECIPIENT, TO THE EXTENT PERMITTED BY LAW. RECIPIENT'S SOLE -REMEDY FOR ANY SUCH MATTER SHALL BE THE IMMEDIATE, UNILATERAL -TERMINATION OF THIS AGREEMENT. - -*/ - -package gov.nasa.jpf.symbc.string; - - - - public enum StringComparator { - - EQ(" == ") { public StringComparator not() { return NE; }}, - NE(" != ") { public StringComparator not() { return EQ; }}, - EQUALS(" equals ") { public StringComparator not() { return NOTEQUALS; }}, - NOTEQUALS(" notequals ") { public StringComparator not() { return EQUALS; }}, - EQUALSIGNORECASE(" equalsignorecase ") { public StringComparator not() { return NOTEQUALSIGNORECASE; }}, - NOTEQUALSIGNORECASE(" notequalsignorecase ") { public StringComparator not() { return EQUALSIGNORECASE; }}, - STARTSWITH(" startswith ") { public StringComparator not() { return NOTSTARTSWITH; }}, - NOTSTARTSWITH(" notstartswith ") { public StringComparator not() { return STARTSWITH; }}, - ENDSWITH(" endswith ") { public StringComparator not() { return NOTENDSWITH; }}, - NOTENDSWITH(" notendswith ") { public StringComparator not() { return ENDSWITH; }}, - CONTAINS(" contains ") { public StringComparator not() { return NOTCONTAINS; }}, - NOTCONTAINS(" notcontains ") { public StringComparator not() { return CONTAINS; }}, - ISINTEGER(" isinteger ") { public StringComparator not() { return NOTINTEGER; }}, - NOTINTEGER(" notinteger ") { public StringComparator not() { return ISINTEGER; }}, - ISFLOAT(" isfloat ") { public StringComparator not() { return NOTFLOAT; }}, - NOTFLOAT(" notfloat ") { public StringComparator not() { return ISFLOAT; }}, - ISLONG(" islong ") { public StringComparator not() { return NOTLONG; }}, - NOTLONG(" notlong ") { public StringComparator not() { return ISLONG; }}, - ISDOUBLE(" isdouble ") { public StringComparator not() { return NOTDOUBLE; }}, - NOTDOUBLE(" notdouble ") { public StringComparator not() { return ISDOUBLE; }}, - ISBOOLEAN(" isboolean ") { public StringComparator not() { return NOTBOOLEAN; }}, - NOTBOOLEAN(" notboolean ") { public StringComparator not() { return ISBOOLEAN; }}, - EMPTY(" empty ") { public StringComparator not() { return NOTEMPTY; }}, - NOTEMPTY(" notempty ") { public StringComparator not() { return EMPTY; }}, - REGIONMATCHES(" regionmatches ") { public StringComparator not() { return NOREGIONMATCHES; }}, - NOREGIONMATCHES(" noregionmatches ") { public StringComparator not() { return REGIONMATCHES; }}; - - private final String str; - - StringComparator(String str){ - this.str= str; - } - - public abstract StringComparator not(); - - @Override - public String toString() { - return str; - } - } - +/* Copyright (C) 2005 United States Government as represented by the +Administrator of the National Aeronautics and Space Administration +(NASA). All Rights Reserved. + +Copyright (C) 2009 Fujitsu Laboratories of America, Inc. + +DISCLAIMER OF WARRANTIES AND LIABILITIES; WAIVER AND INDEMNIFICATION + +A. No Warranty: THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY +WARRANTY OF ANY KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, +INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE +WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR FREEDOM FROM +INFRINGEMENT, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL BE ERROR +FREE, OR ANY WARRANTY THAT DOCUMENTATION, IF PROVIDED, WILL CONFORM TO +THE SUBJECT SOFTWARE. NO SUPPORT IS WARRANTED TO BE PROVIDED AS IT IS PROVIDED "AS-IS". + +B. Waiver and Indemnity: RECIPIENT AGREES TO WAIVE ANY AND ALL CLAIMS +AGAINST FUJITSU LABORATORIES OF AMERICA AND ANY OF ITS AFFILIATES, THE +UNITED STATES GOVERNMENT, ITS CONTRACTORS AND SUBCONTRACTORS, AS WELL +AS ANY PRIOR RECIPIENT. IF RECIPIENT'S USE OF THE SUBJECT SOFTWARE +RESULTS IN ANY LIABILITIES, DEMANDS, DAMAGES, EXPENSES OR LOSSES ARISING +FROM SUCH USE, INCLUDING ANY DAMAGES FROM PRODUCTS BASED ON, OR RESULTING +FROM, RECIPIENT'S USE OF THE SUBJECT SOFTWARE, RECIPIENT SHALL INDEMNIFY +AND HOLD HARMLESS FUJITSU LABORATORTIES OF AMERICA AND ANY OF ITS AFFILIATES, +THE UNITED STATES GOVERNMENT, ITS CONTRACTORS AND SUBCONTRACTORS, AS WELL +AS ANY PRIOR RECIPIENT, TO THE EXTENT PERMITTED BY LAW. RECIPIENT'S SOLE +REMEDY FOR ANY SUCH MATTER SHALL BE THE IMMEDIATE, UNILATERAL +TERMINATION OF THIS AGREEMENT. + +*/ + +package gov.nasa.jpf.symbc.string; + + + + public enum StringComparator { + + EQ(" == ") { public StringComparator not() { return NE; }}, + NE(" != ") { public StringComparator not() { return EQ; }}, + EQUALS(" equals ") { public StringComparator not() { return NOTEQUALS; }}, + NOTEQUALS(" notequals ") { public StringComparator not() { return EQUALS; }}, + EQUALSIGNORECASE(" equalsignorecase ") { public StringComparator not() { return NOTEQUALSIGNORECASE; }}, + NOTEQUALSIGNORECASE(" notequalsignorecase ") { public StringComparator not() { return EQUALSIGNORECASE; }}, + STARTSWITH(" startswith ") { public StringComparator not() { return NOTSTARTSWITH; }}, + NOTSTARTSWITH(" notstartswith ") { public StringComparator not() { return STARTSWITH; }}, + ENDSWITH(" endswith ") { public StringComparator not() { return NOTENDSWITH; }}, + NOTENDSWITH(" notendswith ") { public StringComparator not() { return ENDSWITH; }}, + CONTAINS(" contains ") { public StringComparator not() { return NOTCONTAINS; }}, + NOTCONTAINS(" notcontains ") { public StringComparator not() { return CONTAINS; }}, + ISINTEGER(" isinteger ") { public StringComparator not() { return NOTINTEGER; }}, + NOTINTEGER(" notinteger ") { public StringComparator not() { return ISINTEGER; }}, + ISFLOAT(" isfloat ") { public StringComparator not() { return NOTFLOAT; }}, + NOTFLOAT(" notfloat ") { public StringComparator not() { return ISFLOAT; }}, + ISLONG(" islong ") { public StringComparator not() { return NOTLONG; }}, + NOTLONG(" notlong ") { public StringComparator not() { return ISLONG; }}, + ISDOUBLE(" isdouble ") { public StringComparator not() { return NOTDOUBLE; }}, + NOTDOUBLE(" notdouble ") { public StringComparator not() { return ISDOUBLE; }}, + ISBOOLEAN(" isboolean ") { public StringComparator not() { return NOTBOOLEAN; }}, + NOTBOOLEAN(" notboolean ") { public StringComparator not() { return ISBOOLEAN; }}, + EMPTY(" empty ") { public StringComparator not() { return NOTEMPTY; }}, + NOTEMPTY(" notempty ") { public StringComparator not() { return EMPTY; }}, + MATCHES(" matches ") { public StringComparator not() { return NOMATCHES; }}, + NOMATCHES(" nomatches ") { public StringComparator not() { return MATCHES; }}, + REGIONMATCHES(" regionmatches ") { public StringComparator not() { return NOREGIONMATCHES; }}, + NOREGIONMATCHES(" noregionmatches ") { public StringComparator not() { return REGIONMATCHES; }}; + + private final String str; + + StringComparator(String str){ + this.str= str; + } + + public abstract StringComparator not(); + + @Override + public String toString() { + return str; + } + } + \ No newline at end of file diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringConstraint.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringConstraint.java index 47a7fae..64de8c0 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringConstraint.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringConstraint.java @@ -50,6 +50,9 @@ package gov.nasa.jpf.symbc.string; +import gov.nasa.jpf.symbc.numeric.ConstraintExpressionVisitor; +import gov.nasa.jpf.symbc.numeric.visitors.CollectVariableVisitor; + import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -167,4 +170,20 @@ public StringExpression getRight () { public StringConstraint and () { return and; } + + public void accept(ConstraintExpressionVisitor visitor) { + visitor.preVisit(this); + left.accept(visitor); + right.accept(visitor); + if (and!=null) and.accept(visitor); + visitor.postVisit(this); + } + + public void accept(CollectVariableVisitor visitor) { + visitor.preVisit(this); + left.accept(visitor); + right.accept(visitor); + if (and!=null) and.accept(visitor); + visitor.postVisit(this); + } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringExpression.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringExpression.java index c93f516..b30528f 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringExpression.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringExpression.java @@ -96,7 +96,8 @@ public IntegerExpression _charAt (IntegerExpression ie) { SymbolicCharAtInteger result = charAt.get(ie.toString()); if (result == null) { //System.out.println ("[StringExpression] [_charAt] could not find: '" + ie.toString() + "' in: " + charAt); - result = new SymbolicCharAtInteger("CharAt(" + ie.toString() + ")_" + lengthcount + "_", 0, MinMax.getVarMaxInt(""), this, ie); + result = new SymbolicCharAtInteger("CharAt(" + ie.toString() + ")_" + lengthcount + "_", 0, Character.MAX_VALUE, this, ie); //Rody: not sure about this +// result = new SymbolicCharAtInteger("CharAt(" + ie.toString() + ")_" + lengthcount + "_", 0, MinMax.getVarMaxInt(""), this, ie); lengthcount++; charAt.put(ie.toString(), result); } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringOperator.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringOperator.java index 054f0bd..2cb47db 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringOperator.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringOperator.java @@ -52,12 +52,12 @@ public enum StringOperator { - CONCAT("concat"), REPLACE("replace"), TRIM("trim"), SUBSTRING("substring"), REPLACEFIRST("replacefirst"), + REPLACEALL("replaceall"), TOLOWERCASE("tolowercase"), TOUPPERCASE("touppercase"), VALUEOF("valueof"); diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringPathCondition.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringPathCondition.java index 12fcd11..a8255b5 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringPathCondition.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringPathCondition.java @@ -49,18 +49,24 @@ */ package gov.nasa.jpf.symbc.string; +import java.util.Collections; +import java.util.Map; +import java.util.Map.Entry; + import gov.nasa.jpf.symbc.numeric.PathCondition; public class StringPathCondition { static boolean flagSolved = false; - + + public String smtlib = ""; + public Map solution = Collections.emptyMap(); public StringConstraint header; int count = 0; - PathCondition npc = null; + private PathCondition npc = null; public StringPathCondition(PathCondition npc) { - this.npc = npc; + this.setNpc(npc); header = null; } @@ -127,28 +133,50 @@ public boolean hasConstraint(StringConstraint c) { return false; } - public boolean solve() {// warning: solve calls simplify - // SymbolicStringConstraintsGeneral solver = new SymbolicStringConstraintsGeneral(); - // solver.solve(this); - StringPathCondition.flagSolved = true; - return true; + public boolean solve() {// warning: solve calls simplify + SymbolicStringConstraintsGeneral solver = new SymbolicStringConstraintsGeneral(); + boolean result = solver.isSatisfiable(this); + StringPathCondition.flagSolved = result; + return result; } public boolean simplify() { SymbolicStringConstraintsGeneral solver = new SymbolicStringConstraintsGeneral(); - boolean result = solver.isSatisfiable(this); + boolean result = solver.isSatisfiable(this); return result; - } public String stringPC() { - return "SPC # = " + count + ((header == null) ? "" : "\n" + header.stringPC()) - + " " + npc.stringPC(); + return "SPC # = " + count + ((header == null) ? "" : "\n" + header.stringPC()) +"\n" + + "NPC "+npc.stringPC(); } public String toString() { - return "SPC # = " + count + ((header == null) ? "" : "\n" + header.toString()) - + " " + npc.toString(); - } - - } + return "SPC # = " + count + ((header == null) ? "" : "\n" + header.toString()) +"\n" + + "NPC "+npc.toString(); + } + + public PathCondition getNpc() { + return npc; + } + + public void setNpc(PathCondition npc) { + this.npc = npc; + } + + public Map getSolution(){ + return this.solution; + } + + + public String printableStringSolution(){ + StringBuilder b = new StringBuilder(); + for (Entry sol : solution.entrySet()) { + b.append(sol.getKey()).append(" : \"").append(sol.getValue()).append("\""); + } + return b.toString(); + } + + + +} diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringSymbolic.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringSymbolic.java index 6b5b4af..4d69828 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringSymbolic.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/StringSymbolic.java @@ -104,7 +104,7 @@ public void getVarsVals(Map varsVals) { varsVals.put(fixName(name), solution); } - private String fixName(String name) { + public String fixName(String name) { if (name.endsWith(SYM_STRING_SUFFIX)) { name = name.substring(0, name.lastIndexOf(SYM_STRING_SUFFIX)); } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/SymbolicCharAtInteger.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/SymbolicCharAtInteger.java index 2d8b39c..d6106db 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/SymbolicCharAtInteger.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/SymbolicCharAtInteger.java @@ -41,4 +41,13 @@ public boolean isConstant () { return constant; } + public StringExpression getExpression(){ + return this.se; + } + + public IntegerExpression getIndex(){ + return this.index; + } + + } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/SymbolicLengthInteger.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/SymbolicLengthInteger.java index ce2309e..d50d0cf 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/SymbolicLengthInteger.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/SymbolicLengthInteger.java @@ -1,20 +1,3 @@ -/* - * Copyright (C) 2014, United States Government, as represented by the - * Administrator of the National Aeronautics and Space Administration. - * All rights reserved. - * - * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ package gov.nasa.jpf.symbc.string; @@ -26,5 +9,9 @@ public SymbolicLengthInteger (String name, int l, int u, StringExpression parent super(name, l, u); this.parent = parent; } + + public StringExpression getExpression(){ + return this.parent; + } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/SymbolicStringConstraintsGeneral.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/SymbolicStringConstraintsGeneral.java index e6f1419..cda887e 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/SymbolicStringConstraintsGeneral.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/SymbolicStringConstraintsGeneral.java @@ -20,12 +20,9 @@ import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Set; import java.util.Timer; -import java.util.TimerTask; - -import javax.management.RuntimeErrorException; +import java.util.logging.Logger; import gov.nasa.jpf.symbc.SymbolicInstructionFactory; import gov.nasa.jpf.symbc.numeric.Comparator; @@ -62,17 +59,16 @@ import gov.nasa.jpf.symbc.string.graph.EdgeSubstring2Equal; import gov.nasa.jpf.symbc.string.graph.EdgeTrimEqual; import gov.nasa.jpf.symbc.string.graph.PreProcessGraph; -import gov.nasa.jpf.symbc.string.graph.PreProcessGraphBackup; import gov.nasa.jpf.symbc.string.graph.StringGraph; import gov.nasa.jpf.symbc.string.graph.Vertex; import gov.nasa.jpf.symbc.string.translate.TranslateToAutomata; import gov.nasa.jpf.symbc.string.translate.TranslateToAutomata2; -import gov.nasa.jpf.symbc.string.translate.TranslateToAutomataSpeedUp; import gov.nasa.jpf.symbc.string.translate.TranslateToCVC; import gov.nasa.jpf.symbc.string.translate.TranslateToCVCInc; import gov.nasa.jpf.symbc.string.translate.TranslateToSAT; import gov.nasa.jpf.symbc.string.translate.TranslateToZ3; import gov.nasa.jpf.symbc.string.translate.TranslateToZ3Inc; +import gov.nasa.jpf.util.LogManager; /** * Main entry point for the symbolic string solver. @@ -94,8 +90,8 @@ public class SymbolicStringConstraintsGeneral { /* Useless from now on */ - public static boolean logging = true; - + static Logger logger = LogManager.getLogger("stringsolver"); + public static int constraintCount = 0; /* When creating constant strings, this is used as unique id */ private static int constantStringCount; @@ -114,6 +110,8 @@ public class SymbolicStringConstraintsGeneral { public static final int DIFF_CHAR = MAX_CHAR - MIN_CHAR; /*Possible sovlers for now */ + public static final String ABC = "ABC"; + public static final String Z3STR2 = "Z3str2"; public static final String AUTOMATA = "Automata"; public static final String SAT = "Sat"; public static final String CVC = "CVC"; @@ -160,13 +158,13 @@ private Vertex createVertex (StringExpression se) { String vertexName = se.getName(); PathCondition.flagSolved = oldValue; Vertex v = new Vertex (vertexName, symbolicIntegerGenerator); - global_spc.npc._addDet(Comparator.EQ, v.getSymbolicLength(), se._length()); + global_spc.getNpc()._addDet(Comparator.EQ, v.getSymbolicLength(), se._length()); return v; } private Vertex createVertex (StringExpression se, int length) { Vertex v = new Vertex (se.getName(), length); - global_spc.npc._addDet(Comparator.EQ, v.getSymbolicLength(), se._length()); + global_spc.getNpc()._addDet(Comparator.EQ, v.getSymbolicLength(), se._length()); return v; } @@ -197,6 +195,8 @@ else if (se instanceof DerivedStringExpression) { Vertex v1,v2,v3; int a1, a2; Edge e; + + switch (temp.op) { case TRIM: @@ -208,6 +208,7 @@ else if (se instanceof DerivedStringExpression) { result = graphBefore; break; case SUBSTRING: + //println("SUBSTRING CASE\n"); // something is symbolic so ... graphBefore = convertToGraph((StringExpression) temp.oprlist[0]); //v1 = createVertex (((StringExpression) temp.oprlist[0])); @@ -217,10 +218,10 @@ else if (se instanceof DerivedStringExpression) { v1 = graphBefore.findVertex(((StringExpression) temp.oprlist[0]).getName()); PathCondition.flagSolved = oldState; if (temp.oprlist[1] instanceof IntegerConstant && (temp.oprlist.length == 2 || temp.oprlist[2] instanceof IntegerConstant)) { - a1 = ((IntegerConstant) temp.oprlist[1]).solution(); + a1 = ((IntegerConstant) temp.oprlist[1]).solutionInt(); a2 = -1; if (temp.oprlist.length == 3) { - a2 = ((IntegerConstant) temp.oprlist[2]).solution(); + a2 = ((IntegerConstant) temp.oprlist[2]).solutionInt(); //a1 > a2 ???? v2 = createVertex (temp, a1 - a2); //println ("[convertToGraph, SUBSTRING] a1 = " + a1 + ", a2 = " + a2); @@ -228,9 +229,9 @@ else if (se instanceof DerivedStringExpression) { } else { v2 = createVertex (temp); - global_spc.npc._addDet(Comparator.EQ, v2.getSymbolicLength(), v1.getSymbolicLength()._minus(a1)); + global_spc.getNpc()._addDet(Comparator.EQ, v2.getSymbolicLength(), v1.getSymbolicLength()._minus(a1)); graphBefore.addEdge(v1, v2, new EdgeSubstring1Equal("EdgeSubstring1Equal_" + v1.getName() + "_" + v2.getName() + "_(" + a1 + ")", a1, v1, v2)); - } + } } else if (temp.oprlist[1] instanceof IntegerExpression && temp.oprlist.length == 2) { //throw new RuntimeException ("Reached"); @@ -238,7 +239,7 @@ else if (temp.oprlist[1] instanceof IntegerExpression && temp.oprlist.length == IntegerExpression ie = (IntegerExpression) temp.oprlist[1]; //throw new RuntimeException (ie.getClass().toString()); processIntegerConstraint(ie, null, null, null); - global_spc.npc._addDet(Comparator.EQ, v2.getSymbolicLength(), v1.getSymbolicLength()._minus(ie)); + global_spc.getNpc()._addDet(Comparator.EQ, v2.getSymbolicLength(), v1.getSymbolicLength()._minus(ie)); graphBefore.addEdge(v1, v2, new EdgeSubstring1Equal("EdgeSubstring1Equal_" + v1.getName() + "_" + v2.getName() + "_(" + ie.toString() + ")", ie, v1, v2)); } @@ -247,8 +248,8 @@ else if (temp.oprlist[1] instanceof IntegerExpression && temp.oprlist.length == if (temp.oprlist[1] instanceof IntegerExpression && temp.oprlist.length == 3 && temp.oprlist[2] instanceof IntegerConstant) { v2 = createVertex (temp); IntegerExpression ie_a2 = (IntegerExpression) temp.oprlist[1]; - a1 = ((IntegerConstant) temp.oprlist[2]).solution(); - global_spc.npc._addDet(Comparator.EQ, v2.getSymbolicLength(), ie_a2._minus(a1)); + a1 = ((IntegerConstant) temp.oprlist[2]).solutionInt(); + global_spc.getNpc()._addDet(Comparator.EQ, v2.getSymbolicLength(), ie_a2._minus(a1)); graphBefore.addEdge(v1, v2, new EdgeSubstring2Equal("EdgeSubstring2Equal_" + v1.getName() + "_" + v2.getName() + "_(" + ie_a2+ "," + a1 +")", a1, ie_a2, v1, v2)); } else { @@ -308,7 +309,7 @@ else if (temp.oprlist[1] instanceof IntegerExpression && temp.oprlist.length == temp2.and = temp3; lolic.addToList((LinearIntegerConstraint)temp1);*/ - global_spc.npc._addDet(Comparator.LE, v1.getSymbolicLength(), 5); + global_spc.getNpc()._addDet(Comparator.LE, v1.getSymbolicLength(), 5); int max = 5; @@ -321,7 +322,7 @@ else if (temp.oprlist[1] instanceof IntegerExpression && temp.oprlist.length == //Don't add anything } else { lolic.addToList(new LinearIntegerConstraint(ie, Comparator.GE, new IntegerConstant ((int) Math.pow(10, i)))); - global_spc.npc._addDet(lolic); + global_spc.getNpc()._addDet(lolic); } @@ -332,19 +333,19 @@ else if (temp.oprlist[1] instanceof IntegerExpression && temp.oprlist.length == } else { lolic.addToList(new LinearIntegerConstraint(ie, Comparator.LE, new IntegerConstant (-1 * ((int) Math.pow(10, i-1))))); } - global_spc.npc._addDet(lolic); + global_spc.getNpc()._addDet(lolic); } for (int i = 2; i <= max; i++) { lolic = new LogicalORLinearIntegerConstraints(); lolic.addToList(new LinearIntegerConstraint(v1.getSymbolicLength(), Comparator.GE, new IntegerConstant (i))); lolic.addToList(new LinearIntegerConstraint(ie, Comparator.LT, new IntegerConstant ((int) Math.pow(10, i-1)))); - global_spc.npc._addDet(lolic); + global_spc.getNpc()._addDet(lolic); lolic = new LogicalORLinearIntegerConstraints(); lolic.addToList(new LinearIntegerConstraint(v1.getSymbolicLength(), Comparator.GE, new IntegerConstant (i))); lolic.addToList(new LinearIntegerConstraint(ie, Comparator.GT, new IntegerConstant (-1 * ((int) Math.pow(10, i-1))))); - global_spc.npc._addDet(lolic); + global_spc.getNpc()._addDet(lolic); } //global_spc.npc._addDet(lolic); @@ -361,17 +362,15 @@ else if (temp.oprlist[1] instanceof IntegerExpression && temp.oprlist.length == } public boolean isSatisfiable(StringPathCondition pc) { + logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); + if (SymbolicInstructionFactory.debugMode) + System.out.println("string analysis: " + pc); + //println ("Path Constraint # " + entered); + //println ("CURRENT PATH CONSTRAINT:\n"); + //println(pc.toString()); boolean result = inner_isSatisfiable(pc); - //println ("PC: " + entered); entered++; - //if (entered == 66) { - - //println ("PC:" + pc.header); - //println ("result: " + result); - //println ("Result: " + entered + " " + result); - /*if (entered == 240) { - throw new RuntimeException("Should have caught it"); - }*/ + logger.info("\n"); return result; } @@ -383,14 +382,17 @@ public boolean isSatisfiable(StringPathCondition pc) { * @return */ private boolean inner_isSatisfiable(StringPathCondition pc) { - //println ("[isSatisfiable] entered"); - String string_dp[] = SymbolicInstructionFactory.string_dp; - /* Set up solver */ if (string_dp[0].equals("automata")) { solver = AUTOMATA; } + else if (string_dp[0].equals("z3str2")) { + solver = Z3STR2; + } + else if (string_dp[0].equals("ABC")) { + solver = ABC; + } else if (string_dp[0].equals("sat")) { solver = SAT; } @@ -413,6 +415,9 @@ else if (string_dp[0].equals("z3_inc")) { return true; } + logger.info("Using solver: " + solver); + + TIMEOUT = SymbolicInstructionFactory.stringTimeout; SymbolicStringConstraintsGeneral.timedOut = false; @@ -427,12 +432,10 @@ else if (string_dp[0].equals("z3_inc")) { cancelTimer(); return temp.isSatisfiable(pc); } - //println ("[isSatisfiable] String PC: " + pc.header); setOfSolution = new HashSet(); StringConstraint sc; if (pc == null) { - //println ("[isSatisfiable] PC is null"); cancelTimer(); return true; } @@ -449,24 +452,25 @@ else if (string_dp[0].equals("z3_inc")) { * and add it to the global_graph */ if (sc != null) { - //println ("Constraints: " + pc.npc.header + "\nDone"); + boolean result = process (sc); sc = sc.and; while (result == true && sc != null) { result = process (sc); sc = sc.and; } - /* check if there was a timeout */ checkTimeOut(); } - //println ("pc.npc: " + pc.npc.header); - + + //println("AFTER PROCESS LOOP:\n"); + //println (global_graph.toDot()); + /* Walk through integer constraints and convert each constraint * to a subgraph and add it to the global_graph */ - Constraint constraint = pc.npc.header; + Constraint constraint = pc.getNpc().header; //println ("[isSatisfiable] Int cons given:" + pc.npc.header); while (constraint != null) { processIntegerConstraint(constraint.getLeft(), constraint.getComparator(), constraint.getRight(), constraint); @@ -477,25 +481,17 @@ else if (string_dp[0].equals("z3_inc")) { checkTimeOut(); } + //First solve any previous integer constriants SymbolicConstraintsGeneral scg = new SymbolicConstraintsGeneral(); - scg.solve(pc.npc); + scg.solve(pc.getNpc()); PathCondition.flagSolved = true; - //println ("Constraints: " + pc.npc.header + "\nDone"); - - //Start solving - //println(global_graph.toDot()); + - /* Preprocess the graph */ - //System.out.println("Number of edges before preprocessing: " + global_graph.getEdges().size()); - //println (pc.npc.toString()); - //println ("++++++++++++++++++"); - boolean resultOfPp = PreProcessGraph.preprocess(global_graph, pc.npc); + boolean resultOfPp = PreProcessGraph.preprocess(global_graph, pc.getNpc()); if (!resultOfPp) { System.out.println("Preprocessor found unsat"); } - //println (pc.npc.toString()); - //println (global_graph.toDot()); if (SymbolicInstructionFactory.preprocesOnly) { System.out.println("Preprocessoring only"); @@ -516,8 +512,6 @@ else if (string_dp[0].equals("z3_inc")) { return false; } - //println ("After preproccess"); - //println(global_graph.toDot()); /* Call the string solver, it will in turn churn away until all * options are exhuasted or a satisfiable solution has turned up */ @@ -525,63 +519,68 @@ else if (string_dp[0].equals("z3_inc")) { try { if (solver.equals(SAT)) { //println ("[isSatisfiable] Using SAT Solver"); - decisionProcedure = TranslateToSAT.isSat(global_graph, pc.npc); + decisionProcedure = TranslateToSAT.isSat(global_graph, pc.getNpc()); + } + if (solver.equals(ABC)) { + logger.info ("[isSatisfiable] Using ABC Solver"); + //decisionProcedure = TranslateToSAT.isSat(global_graph, pc.npc); + decisionProcedure = false; } else if (solver.equals(AUTOMATA)) { //println ("[isSatisfiable] Using Automata's"); TranslateToAutomata.duration = 0; TranslateToAutomata.int_duration = 0; TranslateToAutomata.loops = 0; - decisionProcedure = TranslateToAutomata2.isSat(global_graph, pc.npc); + decisionProcedure = TranslateToAutomata2.isSat(global_graph, pc.getNpc()); timeInvoked++; } else if (solver.equals(CVC)) { //println ("[isSatisfiable] Using Bitvector's"); - decisionProcedure = TranslateToCVC.isSat(global_graph, pc.npc); + decisionProcedure = TranslateToCVC.isSat(global_graph, pc.getNpc()); } else if (solver.equals(CVC_INC)) { //println ("[isSatisfiable] Using Bitvector's"); - decisionProcedure = TranslateToCVCInc.isSat(global_graph, pc.npc); + decisionProcedure = TranslateToCVCInc.isSat(global_graph, pc.getNpc()); } else if (solver.equals(Z3)) { //println ("[isSatisfiable] Using Z3"); - decisionProcedure = TranslateToZ3.isSat(global_graph, pc.npc); + decisionProcedure = TranslateToZ3.isSat(global_graph, pc.getNpc()); } else if (solver.equals(Z3_INC)) { TranslateToZ3Inc.duration = 0; TranslateToZ3Inc.int_duration = 0; TranslateToZ3Inc.loops = 0; - decisionProcedure = TranslateToZ3Inc.isSat(global_graph, pc.npc); + decisionProcedure = TranslateToZ3Inc.isSat(global_graph, pc.getNpc()); string_duration += TranslateToZ3Inc.duration; int_duration += TranslateToZ3Inc.int_duration ; //System.out.println("Loops: " + TranslateToZ3Inc.loops); timeInvoked++; } else if (solver.equals(WRAPPER)) { StringGraph cloneGraph = new StringGraph(global_graph); - PathCondition cloneNpc = pc.npc.make_copy(); + PathCondition cloneNpc = pc.getNpc().make_copy(); boolean pcSolved = PathCondition.flagSolved; //start with z3, and swap to automata if something goes wrong try { - decisionProcedure = TranslateToZ3.isSat(global_graph, pc.npc); + decisionProcedure = TranslateToZ3.isSat(global_graph, pc.getNpc()); } catch (Exception e) { - println("wrapper-z3 throwed exception; " + e.getMessage()); + logger.info("wrapper-z3 throwed exception; " + e.getMessage()); } try { if (decisionProcedure == false) { - println("z3 failed; restoring graph/pc and trying again with automata..."); + logger.warning("z3 failed; restoring graph/pc and trying again with automata..."); global_graph = cloneGraph; - pc.npc = cloneNpc; + pc.setNpc(cloneNpc); PathCondition.flagSolved = pcSolved; TranslateToAutomata.duration = 0; TranslateToAutomata.int_duration = 0; TranslateToAutomata.loops = 0; decisionProcedure = TranslateToAutomata2.isSat( - global_graph, pc.npc); + global_graph, pc.getNpc()); timeInvoked++; } } catch (Exception e) { - println("wrapper-automata throwed exception; " + e.getMessage()); + logger.severe("wrapper-automata throwed exception; " + e.getMessage()); } } else { @@ -740,7 +739,7 @@ public static String getSolution () { private void processIntegerConstraint (Expression e, Comparator comp, Expression other, Constraint origConstraint) { if (PathCondition.flagSolved == false) { SymbolicConstraintsGeneral scg = new SymbolicConstraintsGeneral(); - scg.solve(global_spc.npc); + scg.solve(global_spc.getNpc()); PathCondition.flagSolved = true; } if (e instanceof SymbolicCharAtInteger) { @@ -764,7 +763,7 @@ private void processIntegerConstraint (Expression e, Comparator comp, Expression //Necassery hack //TODO MAB: what is the function of this hack? it makes the preprocessor return UNSAT on some valid constraints! origConstraint.setComparator(Comparator.EQ); - global_spc.npc.flagSolved = false; + global_spc.getNpc().flagSolved = false; } else { Vertex v1 = new Vertex ("CharAt_" + scai.index.solution() + "_" + scai.solution(), String.valueOf((char) scai.solution()), true); @@ -894,7 +893,7 @@ else if (e instanceof SymbolicLengthInteger) { StringGraph parent = convertToGraph(sli.parent); global_graph.mergeIn(parent); Vertex v1 = global_graph.findVertex(sli.parent.getName()); - global_spc.npc._addDet(Comparator.EQ, v1.getSymbolicLength(), sli); + global_spc.getNpc()._addDet(Comparator.EQ, v1.getSymbolicLength(), sli); } /*else { if (e != null) { @@ -911,6 +910,13 @@ private boolean process (StringConstraint sc) { StringGraph leftGraph, rightGraph; StringExpression se_left = sc.left; StringExpression se_right = sc.right; + + //println("\nSCL: " + sc.left); + //println("\nSCR: " + sc.right); + //println("\nSCC: " + sc.comp); + + + Vertex v1, v2; switch (sc.comp) { case EQUALS: @@ -987,7 +993,10 @@ private boolean process (StringConstraint sc) { break; case CONTAINS: leftGraph = convertToGraph (se_left); + //println("LEFT GRAPH: \n" + leftGraph.toDot()); rightGraph = convertToGraph (se_right); + //println("RIGHT GRAPH: \n" + rightGraph.toDot()); + global_graph.mergeIn(leftGraph); global_graph.mergeIn(rightGraph); v1 = global_graph.findVertex(se_left.getName()); @@ -1027,9 +1036,10 @@ public static void cancelTimer () { } } } - - private static void println (String s) { - if (logging) - System.out.println("[SAT-Sexi-JPF] " + s); + + public void solve(StringPathCondition stringPathCondition) { + // TODO Auto-generated method stub + } + } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/SymbolicStringConstraintsGeneralToText.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/SymbolicStringConstraintsGeneralToText.java index dfe600f..2fb192f 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/SymbolicStringConstraintsGeneralToText.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/SymbolicStringConstraintsGeneralToText.java @@ -18,6 +18,7 @@ package gov.nasa.jpf.symbc.string; +// updated by Lucas? import java.util.HashSet; import java.util.List; import java.util.Map; @@ -61,6 +62,8 @@ import gov.nasa.jpf.symbc.string.translate.TranslateToCVC; import gov.nasa.jpf.symbc.string.translate.TranslateToCVCInc; import gov.nasa.jpf.symbc.string.translate.TranslateToSAT; +import gov.nasa.jpf.util.LogManager; +import java.util.logging.Logger; /** * Main entry point for the symbolic string solver. @@ -82,7 +85,7 @@ public class SymbolicStringConstraintsGeneralToText { /* Useless from now on */ - public static boolean logging = true; + static Logger logger = LogManager.getLogger("stringsolver"); /* When creating constant strings, this is used as unique id */ private static int constantStringCount; @@ -119,13 +122,13 @@ public SymbolicStringConstraintsGeneralToText () { private Vertex createVertex (StringExpression se) { Vertex v = new Vertex (se.getName(), symbolicIntegerGenerator); - global_spc.npc._addDet(Comparator.EQ, v.getSymbolicLength(), se._length()); + global_spc.getNpc()._addDet(Comparator.EQ, v.getSymbolicLength(), se._length()); return v; } private Vertex createVertex (StringExpression se, int length) { Vertex v = new Vertex (se.getName(), length); - global_spc.npc._addDet(Comparator.EQ, v.getSymbolicLength(), se._length()); + global_spc.getNpc()._addDet(Comparator.EQ, v.getSymbolicLength(), se._length()); return v; } @@ -171,10 +174,10 @@ else if (se instanceof DerivedStringExpression) { graphBefore = convertToGraph((StringExpression) temp.oprlist[0]); v1 = createVertex (((StringExpression) temp.oprlist[0])); if (temp.oprlist[1] instanceof IntegerConstant && (temp.oprlist.length == 2 || temp.oprlist[2] instanceof IntegerConstant)) { - a1 = ((IntegerConstant) temp.oprlist[1]).solution(); + a1 = ((IntegerConstant) temp.oprlist[1]).solutionInt(); a2 = -1; if (temp.oprlist.length == 3) { - a2 = ((IntegerConstant) temp.oprlist[2]).solution(); + a2 = ((IntegerConstant) temp.oprlist[2]).solutionInt(); //a1 > a2 ???? v2 = createVertex (temp, a1 - a2); //println ("[convertToGraph, SUBSTRING] a1 = " + a1 + ", a2 = " + a2); @@ -182,7 +185,7 @@ else if (se instanceof DerivedStringExpression) { } else { v2 = createVertex (temp); - global_spc.npc._addDet(Comparator.EQ, v2.getSymbolicLength(), v1.getSymbolicLength()._minus(a1)); + global_spc.getNpc()._addDet(Comparator.EQ, v2.getSymbolicLength(), v1.getSymbolicLength()._minus(a1)); graphBefore.addEdge(v1, v2, new EdgeSubstring1Equal("EdgeSubstring1Equal_" + v1.getName() + "_" + v2.getName() + "_(" + a1 + ")", a1, v1, v2)); } } @@ -192,7 +195,7 @@ else if (temp.oprlist[1] instanceof IntegerExpression && temp.oprlist.length == IntegerExpression ie = (IntegerExpression) temp.oprlist[1]; //throw new RuntimeException (ie.getClass().toString()); processIntegerConstraint(ie); - global_spc.npc._addDet(Comparator.EQ, v2.getSymbolicLength(), v1.getSymbolicLength()._minus(ie)); + global_spc.getNpc()._addDet(Comparator.EQ, v2.getSymbolicLength(), v1.getSymbolicLength()._minus(ie)); graphBefore.addEdge(v1, v2, new EdgeSubstring1Equal("EdgeSubstring1Equal_" + v1.getName() + "_" + v2.getName() + "_(" + ie.toString() + ")", ie, v1, v2)); } @@ -201,8 +204,8 @@ else if (temp.oprlist[1] instanceof IntegerExpression && temp.oprlist.length == if (temp.oprlist[1] instanceof IntegerExpression && temp.oprlist.length == 3 && temp.oprlist[2] instanceof IntegerConstant) { v2 = createVertex (temp); IntegerExpression ie_a2 = (IntegerExpression) temp.oprlist[1]; - a1 = ((IntegerConstant) temp.oprlist[2]).solution(); - global_spc.npc._addDet(Comparator.EQ, v2.getSymbolicLength(), ie_a2._minus(a1)); + a1 = ((IntegerConstant) temp.oprlist[2]).solutionInt(); + global_spc.getNpc()._addDet(Comparator.EQ, v2.getSymbolicLength(), ie_a2._minus(a1)); graphBefore.addEdge(v1, v2, new EdgeSubstring2Equal("EdgeSubstring2Equal_" + v1.getName() + "_" + v2.getName() + "_(" + ie_a2+ "," + a1 +")", a1, ie_a2, v1, v2)); } else { @@ -290,7 +293,7 @@ else if (string_dp[0].equals("cvc_inc")) { * to a subgraph and add it to the global_graph */ - Constraint constraint = pc.npc.header; + Constraint constraint = pc.getNpc().header; //println ("[isSatisfiable] Int cons given:" + pc.npc.header); while (constraint != null) { //First solve any previous integer constriants @@ -303,22 +306,22 @@ else if (string_dp[0].equals("cvc_inc")) { //First solve any previous integer constriants SymbolicConstraintsGeneral scg = new SymbolicConstraintsGeneral(); - scg.solve(pc.npc); + scg.solve(pc.getNpc()); PathCondition.flagSolved = true; //Start solving //println(global_graph.toDot()); /* Preprocess the graph */ - boolean resultOfPp = PreProcessGraph.preprocess(global_graph, pc.npc); + boolean resultOfPp = PreProcessGraph.preprocess(global_graph, pc.getNpc()); if (!resultOfPp) { //println ("[isSat] Preprocessor gave Unsat"); return false; } - println(global_graph.toPlainText()); - if (pc.npc.header != null) { - println ("\nvvv vvv vvv vvv\n"); - System.out.println(pc.npc.header); + logger.info(global_graph.toPlainText()); + if (pc.getNpc().header != null) { + logger.info ("\nvvv vvv vvv vvv\n"); + System.out.println(pc.getNpc().header); System.out.println("\n^^^ ^^^ ^^^ ^^^\n"); } return true; @@ -342,7 +345,7 @@ public static String getSolution () { private void processIntegerConstraint (Expression e) { if (PathCondition.flagSolved == false) { SymbolicConstraintsGeneral scg = new SymbolicConstraintsGeneral(); - scg.solve(global_spc.npc); + scg.solve(global_spc.getNpc()); PathCondition.flagSolved = true; } if (e instanceof SymbolicCharAtInteger) { @@ -483,7 +486,7 @@ else if (e instanceof SymbolicLengthInteger) { StringGraph parent = convertToGraph(sli.parent); global_graph.mergeIn(parent); Vertex v1 = global_graph.findVertex(sli.parent.getName()); - global_spc.npc._addDet(Comparator.EQ, v1.getSymbolicLength(), sli); + global_spc.getNpc()._addDet(Comparator.EQ, v1.getSymbolicLength(), sli); } /*else { if (e != null) { @@ -593,8 +596,4 @@ private boolean process (StringConstraint sc) { return true; } - private static void println (String s) { - if (logging) - System.out.println("[SAT-Sexi-JPF] " + s); - } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/SymbolicStringConstraintsHAMPI.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/SymbolicStringConstraintsHAMPI.java index 72bc855..2a668ee 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/SymbolicStringConstraintsHAMPI.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/SymbolicStringConstraintsHAMPI.java @@ -50,6 +50,7 @@ //import gov.nasa.jpf.symbc.numeric.Expression; import gov.nasa.jpf.symbc.numeric.IntegerConstant; +import gov.nasa.jpf.util.LogManager; import java.util.*; @@ -58,6 +59,7 @@ import hampi.constraints.Regexp; import hampi.constraints.Expression; import hampi.Solution; +import java.util.logging.Logger; /* @@ -66,6 +68,7 @@ * Then we need to add this directory to the java.library.path on the command line as in: -Djava.library.path=extensions/symbc/lib */ public class SymbolicStringConstraintsHAMPI { + static Logger logger = LogManager.getLogger("stringsolver"); StringPathCondition pc = null; Hampi hampi; @@ -107,7 +110,7 @@ else if (expr instanceof DerivedStringExpression) { } } else { - System.out.println("Exiting after unhandled type " + expr); + logger.severe("Exiting after unhandled type " + expr); System.exit(0); } return result; @@ -122,12 +125,12 @@ private boolean findSolution(Constraint c1) { while (len < 256) { s = hampi.solve(all,len); if (s.isSatisfiable()) { - System.out.println("Found solution!"); + logger.info("Found solution!"); return true; } len++; } - System.out.println("No solution for " + all.toJavaCode("")); + logger.warning("No solution for " + all.toJavaCode("")); return false; } @@ -142,7 +145,7 @@ private boolean evaluateStringConstraint(StringConstraint c) { left = getStringExpression(c.left); right = getStringExpression(c.right); if (!(c.left instanceof StringConstant) && !(c.right instanceof StringConstant)) { - System.out.println("EQ: One side must be non symbolic for HAMPI to work!"); + logger.severe("EQ: One side must be non symbolic for HAMPI to work!"); System.exit(0); } if ((c.left instanceof StringConstant) && (c.right instanceof StringConstant)) { @@ -172,7 +175,7 @@ else if ((c.right instanceof StringConstant)) { left = getStringExpression(c.left); right = getStringExpression(c.right); if (!(c.left instanceof StringConstant) && !(c.right instanceof StringConstant)) { - System.out.println("NE: One side must be non symbolic for HAMPI to work!"); + logger.severe("NE: One side must be non symbolic for HAMPI to work!"); System.exit(0); } if ((c.left instanceof StringConstant) && (c.right instanceof StringConstant)) { diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/graph/EdgeContains.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/graph/EdgeContains.java index d6942ae..ad781fb 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/graph/EdgeContains.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/graph/EdgeContains.java @@ -30,7 +30,7 @@ public class EdgeContains implements Edge{ public EdgeContains (String name, Vertex source, Vertex end) { this.name = name; this.source = source; - this.dest = dest; + this.dest = end; //Rody: changed RHS from dest to end, seemed like a bug } @Override diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/graph/EdgeSubstring1Equal.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/graph/EdgeSubstring1Equal.java index db37a6b..c80d3d9 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/graph/EdgeSubstring1Equal.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/graph/EdgeSubstring1Equal.java @@ -94,7 +94,7 @@ public int getArgument1 () { return a1; } else { - return ie_a1.solution(); + return (int) ie_a1.solution(); } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/graph/PreProcessGraph.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/graph/PreProcessGraph.java index 66af724..6cc4fba 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/graph/PreProcessGraph.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/graph/PreProcessGraph.java @@ -34,12 +34,14 @@ import gov.nasa.jpf.symbc.string.StringUtility; import gov.nasa.jpf.symbc.string.SymbolicIndexOfInteger; import gov.nasa.jpf.symbc.string.SymbolicStringConstraintsGeneral; +import gov.nasa.jpf.util.LogManager; +import java.util.logging.Logger; /** * This class does the preprocessing of the StringGraph */ public class PreProcessGraph { - private static boolean logging = true; + static Logger logger = LogManager.getLogger("stringsolver"); public static final int MAXIMUM_LENGTH = 30; private static SymbolicConstraintsGeneral scg; @@ -58,7 +60,7 @@ public static boolean preprocess (StringGraph stringGraph, PathCondition pathCon scg = new SymbolicConstraintsGeneral(); - if(!scg.isSatisfiable(pathCondition)) {println("unsat here");}; + if(!scg.isSatisfiable(pathCondition)) {logger.info("unsat here");}; if (!handleEquality(stringGraph, pathCondition)) { //println ("handleEquality returned false"); @@ -2279,32 +2281,32 @@ private static boolean handleBasicIndexOfCharInt (StringGraph g, PathCondition p private static boolean handleBooleanConstraints (StringGraph g, PathCondition pc) { if (!handleBasicBooleanConstraints(g, pc)) { - println ("handleBasicBooleanConstraints returned false"); + logger.info ("handleBasicBooleanConstraints returned false"); return false; } if (!handleStartsWith (g, pc)) { - println ("handleStartsWith returned false"); + logger.info ("handleStartsWith returned false"); return false; } if (!handleEndsWith (g, pc)) { - println ("handleStartsWith returned false"); + logger.info ("handleStartsWith returned false"); return false; } if (!handleContains (g, pc)) { - println ("handleContains returned false"); + logger.info ("handleContains returned false"); return false; } if (!handleStartsWithContains (g, pc)) { - println ("handleStartsWithContains returned false"); + logger.info ("handleStartsWithContains returned false"); return false; } if (!handleEndsWithContains (g, pc)) { - println ("handleEndsWithContains returned false"); + logger.info ("handleEndsWithContains returned false"); return false; } //TODO: Test if (!handleEndsWithCharAt(g, pc)) { - println ("handleEndsWithContains returned false"); + logger.info ("handleEndsWithContains returned false"); return false; } return true; @@ -2343,15 +2345,15 @@ private static boolean handleEndsWithCharAt (StringGraph g, PathCondition pc) { private static boolean handleBasicBooleanConstraints (StringGraph g, PathCondition pc) { if (!handleBasicStartsWith (g, pc)) { - println ("handleBasicStartsWith returned false"); + logger.info ("handleBasicStartsWith returned false"); return false; } if (!handleBasicEndsWith (g, pc)) { - println ("handleBasicEndsWith returned false"); + logger.info ("handleBasicEndsWith returned false"); return false; } if (!handleBasicContains (g, pc)) { - println ("handleBasicContains returned false"); + logger.info ("handleBasicContains returned false"); return false; } return true; @@ -2661,7 +2663,7 @@ else if (e1 instanceof EdgeEndsWith && e2 instanceof EdgeCharAt) { if (!esw.getDest().isConstant()) {continue;} String constantString = esw.getDest().getSolution(); if (eca.index instanceof IntegerConstant) { - int index = eca.index.solution(); + int index = (int) eca.index.solution(); LogicalORLinearIntegerConstraints loic = new LogicalORLinearIntegerConstraints(); loic.addToList(new LinearIntegerConstraint(eca.index, Comparator.LT, eca.getSource().getSymbolicLength()._minus(constantString.length()))); loic.addToList(new LinearIntegerConstraint(eca.value, Comparator.EQ, new IntegerConstant(constantString.charAt(index)))); @@ -2703,7 +2705,7 @@ else if (e1 instanceof EdgeStartsWith && e2 instanceof EdgeCharAt) { if (!esw.getDest().isConstant()) {continue;} String constantString = esw.getDest().getSolution(); if (eca.index instanceof IntegerConstant) { - int index = eca.index.solution(); + int index = (int) eca.index.solution(); if (index < constantString.length()) { pc._addDet(Comparator.EQ, eca.value, new IntegerConstant(constantString.charAt(index))); } @@ -2765,8 +2767,8 @@ private static boolean handleCharAtDependencies (StringGraph g, PathCondition pc EdgeCharAt eca2 = (EdgeCharAt) e2; if (eca1.index instanceof IntegerConstant && eca2.index instanceof IntegerConstant) { - int index1 = ((IntegerConstant) eca1.index).solution(); - int index2 = ((IntegerConstant) eca2.index).solution(); + int index1 = (int) ((IntegerConstant) eca1.index).solution(); + int index2 = (int) ((IntegerConstant) eca2.index).solution(); if (index1 != index2) continue; pc._addDet(Comparator.EQ, eca1.value, eca2.value); } @@ -2942,8 +2944,4 @@ private static boolean sameSource (Edge e1, Edge e2) { return e1.getSource().equals(e2.getSource()); } - private static void println (String msg) { - if (logging) - System.out.println("[PreProcessGraph] " + msg); - } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/graph/PreProcessGraphBackup.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/graph/PreProcessGraphBackup.java index b2953b1..75ca813 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/graph/PreProcessGraphBackup.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/graph/PreProcessGraphBackup.java @@ -32,12 +32,14 @@ import gov.nasa.jpf.symbc.string.StringExpression; import gov.nasa.jpf.symbc.string.StringUtility; import gov.nasa.jpf.symbc.string.SymbolicStringConstraintsGeneral; +import gov.nasa.jpf.util.LogManager; +import java.util.logging.Logger; /** * This class does the preprocessing of the StringGraph */ public class PreProcessGraphBackup { - private static boolean logging = true; + static Logger logger = LogManager.getLogger("stringsolver"); public static final int MAXIMUM_LENGTH = 30; private static SymbolicConstraintsGeneral scg; @@ -219,7 +221,7 @@ else if (e.getSources().get(1).isConstant()) { if (eca.getIndex() instanceof IntegerConstant && eca.getValue() instanceof IntegerConstant && eca.getIndex().solution() < e1.getDest().getSolution().length()) { String startsWithString = e1.getDest().getSolution(); - int charAtIndex = eca.getIndex().solution(); + int charAtIndex = (int) eca.getIndex().solution(); if (startsWithString.charAt(charAtIndex) != charAtIndex) { return false; } @@ -567,8 +569,8 @@ else if (e1 instanceof EdgeIndexOfChar && e2 instanceof EdgeIndexOfChar2) { EdgeIndexOfChar eioc = (EdgeIndexOfChar) e1; EdgeIndexOfChar2 eioc2 = (EdgeIndexOfChar2) e2; if (eioc.getIndex().getExpression() instanceof IntegerConstant && eioc2.getIndex().getExpression() instanceof IntegerConstant) { - int sol1 = eioc.getIndex().getExpression().solution(); - int sol2 = eioc2.getIndex().getExpression().solution(); + int sol1 = (int) eioc.getIndex().getExpression().solution(); + int sol2 = (int) eioc2.getIndex().getExpression().solution(); if (sol1 != sol2) { LogicalORLinearIntegerConstraints loic = new LogicalORLinearIntegerConstraints(); loic.addToList(new LinearIntegerConstraint(eioc.getIndex(), Comparator.EQ, new IntegerConstant(-1))); @@ -1004,8 +1006,4 @@ private static void forceLengthsSame (Vertex v1, Vertex v2, PathCondition pc) { } } - private static void println (String msg) { - if (logging) - System.out.println("[PreProcessGraph] " + msg); - } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/graph/Vertex.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/graph/Vertex.java index f61e140..af02648 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/graph/Vertex.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/graph/Vertex.java @@ -42,7 +42,9 @@ public Vertex (String name, SymbolicIntegerGenerator sig) { this.name = name; this.constant = false; //symbolic_length = new SymbolicInteger(name + ".length_" +count+ "_", 0, MinMax.MAXINT); //Must start with 0, for concat - symbolic_length = sig.create (name, 0, MinMax.getVarMaxInt("")); + long l = MinMax.getVarMaxInt(""); + assert(l>=Integer.MIN_VALUE && l<=Integer.MAX_VALUE); + symbolic_length = sig.create (name, 0, (int) l); this.uniqueNumber = count++; } @@ -79,7 +81,7 @@ public int getLength () { if (constant) { return solution.length(); } - return symbolic_length.solution(); + return (int) symbolic_length.solution(); } public void setSolution (String s) { diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/testing/RandomTest.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/testing/RandomTest.java index 00fcabf..cd5d8e0 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/testing/RandomTest.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/testing/RandomTest.java @@ -18,8 +18,11 @@ package gov.nasa.jpf.symbc.string.testing; +import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; import java.util.List; import java.util.Random; import java.util.Scanner; @@ -131,7 +134,7 @@ public static Profile get3goodSetOfEdges() { return p; } - public static void main (String [] args) throws FileNotFoundException { + public static void main (String [] args) throws NumberFormatException, IOException { setUpJPF(); //Profile p = get3smallSetOfEdges(); @@ -205,9 +208,9 @@ else if (args.length == 1) { } } else { - Scanner scanner = new Scanner(new File(args[1])); - while (scanner.hasNext()) { - String number = scanner.nextLine(); + BufferedReader br = new BufferedReader(new FileReader(args[1])); + String number; + while ((number = br.readLine()) != null) { long seed = Long.parseLong(number); random = new Random(); StringGraph sg = generateRandomStringGraph (p, seed); @@ -225,6 +228,7 @@ else if (args.length == 1) { } System.out.println(",\""+seed+"\","+z3dur.time+","+autodur.time); } + br.close(); } } @@ -445,7 +449,7 @@ private static void handleEdgeSubstring1Equal (StringGraph result) { } /*println (pc.header.toString()); println ("ic: " + ic);*/ - EdgeSubstring1Equal edge = new EdgeSubstring1Equal("EdgeSubstring1Equal_" + getCounter(), ic.solution(), v1, v2); + EdgeSubstring1Equal edge = new EdgeSubstring1Equal("EdgeSubstring1Equal_" + getCounter(), ic.solutionInt(), v1, v2); result.addEdge(v1, v2, edge); } @@ -493,13 +497,13 @@ private static void handleEdgeSubstring2Equal (StringGraph result, int mode) { pc._addDet(Comparator.LE, ie2, v1.getSymbolicLength()); } if (ie1 instanceof IntegerConstant && ie2 instanceof IntegerConstant) { - edge = new EdgeSubstring2Equal("EdgeSubstring1Equal_" + getCounter(), ie1.solution(), ie2.solution(), v1, v2); + edge = new EdgeSubstring2Equal("EdgeSubstring1Equal_" + getCounter(), ie1.solutionInt(), ie2.solutionInt(), v1, v2); } else if (ie1 instanceof IntegerConstant) { - edge = new EdgeSubstring2Equal("EdgeSubstring1Equal_" + getCounter(), ie1.solution(), ie2, v1, v2); + edge = new EdgeSubstring2Equal("EdgeSubstring1Equal_" + getCounter(), ie1.solutionInt(), ie2, v1, v2); } else if (ie2 instanceof IntegerConstant) { - edge = new EdgeSubstring2Equal("EdgeSubstring1Equal_" + getCounter(), ie1, ie2.solution(), v1, v2); + edge = new EdgeSubstring2Equal("EdgeSubstring1Equal_" + getCounter(), ie1, ie2.solutionInt(), v1, v2); } result.addEdge(v1, v2, edge); } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/testing/RandomTest2.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/testing/RandomTest2.java index 522050d..27becb9 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/testing/RandomTest2.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/testing/RandomTest2.java @@ -18,8 +18,11 @@ package gov.nasa.jpf.symbc.string.testing; +import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Random; @@ -138,7 +141,7 @@ public static Profile get3goodSetOfEdges() { return p; } - public static void main (String [] args) throws FileNotFoundException { + public static void main (String [] args) throws NumberFormatException, IOException { Profile p = get3smallSetOfEdges(); //Profile p = get3goodSetOfEdges(); @@ -225,9 +228,9 @@ else if (args.length == 1) { } } else { - Scanner scanner = new Scanner(new File(args[1])); - while (scanner.hasNext()) { - String number = scanner.nextLine(); + BufferedReader br = new BufferedReader(new FileReader(args[1])); + String number; + while ((number = br.readLine()) != null) { long seed = Long.parseLong(number); random = new Random(); generateRandomProblem(p, seed); @@ -244,6 +247,7 @@ else if (args.length == 1) { } System.out.println(",\""+seed+"\","+z3dur.time+","+autodur.time); } + br.close(); } System.exit(0); diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToAutomata.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToAutomata.java index 4569f78..5e39bcc 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToAutomata.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToAutomata.java @@ -63,8 +63,12 @@ import gov.nasa.jpf.symbc.string.graph.EdgeTrimEqual; import gov.nasa.jpf.symbc.string.graph.StringGraph; import gov.nasa.jpf.symbc.string.graph.Vertex; +import gov.nasa.jpf.util.LogManager; +import java.util.logging.Logger; public class TranslateToAutomata { + static Logger logger = LogManager.getLogger("TranslateToAutomata"); + private static Map mapSolved; private static Map mapAutomaton; private static Map mapEdgeCount; @@ -75,8 +79,6 @@ public class TranslateToAutomata { private static Map, Map> memo; private static int concatCount = 128; - private static boolean logging = true; - static SymbolicConstraintsGeneral scg = new SymbolicConstraintsGeneral(); public static long duration = 0; @@ -256,8 +258,8 @@ private static boolean inner_isSat (StringGraph g, PathCondition pc) { //Check if path condition has changed if (PathCondition.flagSolved == false) { loops++; - println ("[isSat] solving path condition: "); - println(global_pc.header.toString()); + logger.info ("[isSat] solving path condition: "); + logger.info(global_pc.header.toString()); long startTime = System.currentTimeMillis(); boolean temp_result = scg.isSatisfiable(global_pc); long temp_dur = System.currentTimeMillis() - startTime; @@ -301,8 +303,8 @@ private static boolean inner_isSat (StringGraph g, PathCondition pc) { if (!handleNotResult) { //println ("returned no"); if (PathCondition.flagSolved == false) { - println ("path condition to be solved"); - println (global_pc.toString()); + logger.info ("path condition to be solved"); + logger.info (global_pc.toString()); loops++; long starttime = System.currentTimeMillis(); boolean int_result = scg.isSatisfiable(global_pc); @@ -387,7 +389,7 @@ else if (e instanceof EdgeIndexOf) { } else if (e instanceof EdgeIndexOf2) { EdgeIndexOf2 eio = (EdgeIndexOf2) e; - if (eio.getIndex().solution() == -1 && eio.getSource().getSolution().indexOf(eio.getDest().getSolution(), eio.getIndex().getMinIndex().solution()) > -1) { + if (eio.getIndex().solution() == -1 && eio.getSource().getSolution().indexOf(eio.getDest().getSolution(), eio.getIndex().getMinIndex().solutionInt()) > -1) { //println ("[EdgeIndexOf2] '" + eio.getSource().getSolution() + "' contains '" + eio.getDest().getSolution() + "' and it should not from " + eio.getIndex().getMinIndex().solution()); if (!eio.getSource().isConstant() && !eio.getDest().isConstant()) { numberOfNots++; @@ -414,7 +416,7 @@ else if (e instanceof EdgeLastIndexOfChar) { } else if (e instanceof EdgeIndexOfChar2) { EdgeIndexOfChar2 eio = (EdgeIndexOfChar2) e; - if (eio.getIndex().solution() == -1 && eio.getSource().getSolution().indexOf(eio.getDest().getSolution(), eio.getIndex().getMinDist().solution()) > -1) { + if (eio.getIndex().solution() == -1 && eio.getSource().getSolution().indexOf(eio.getDest().getSolution(), eio.getIndex().getMinDist().solutionInt()) > -1) { //println ("[EdgeIndexOfChar2] '" + eio.getSource().getSolution() + "' contains '" + eio.getDest().getSolution() + "' after " + eio.getIndex().getMinDist().solution() + " and it should not"); if (!eio.getSource().isConstant() && !eio.getDest().isConstant()) { numberOfNots++; @@ -627,7 +629,7 @@ else if (!e.getDest().isConstant()) { } else if (e instanceof EdgeNotStartsWith) { if (e.getSource().getSolution().startsWith(e.getDest().getSolution())) { - println (e.getSource().getName() + " (" + e.getSource().getSolution() + ") startswith " + e.getDest().getName() + " (" + e.getDest().getSolution() + ") and it shouldn't"); + logger.info (e.getSource().getName() + " (" + e.getSource().getSolution() + ") startswith " + e.getDest().getName() + " (" + e.getDest().getSolution() + ") and it shouldn't"); if (!e.getSource().isConstant() && !e.getDest().isConstant()) { //println ("Here 2"); nonequalityFlipFlop = bitArray[indexBitArray++]; @@ -1046,7 +1048,7 @@ else if (!eio.getDest().isConstant()) { } else if (e instanceof EdgeIndexOf2) { EdgeIndexOf2 eio = (EdgeIndexOf2) e; - if (eio.getIndex().solution() == -1 && eio.getSource().getSolution().indexOf(eio.getDest().getSolution(), eio.getIndex().getMinIndex().solution()) > -1) { + if (eio.getIndex().solution() == -1 && eio.getSource().getSolution().indexOf(eio.getDest().getSolution(), eio.getIndex().getMinIndex().solutionInt()) > -1) { //println ("[EdgeIndexOf2] '" + eio.getSource().getSolution() + "' contains '" + eio.getDest().getSolution() + "' and it should not from " + eio.getIndex().getMinIndex().solution()); if (!eio.getSource().isConstant() && !eio.getDest().isConstant()) { nonequalityFlipFlop = bitArray[indexBitArray++]; @@ -1247,8 +1249,8 @@ else if (!eio.getDest().isConstant()) { } else if (e instanceof EdgeIndexOfChar2) { EdgeIndexOfChar2 eio = (EdgeIndexOfChar2) e; - if (eio.getIndex().solution() == -1 && eio.getSource().getSolution().indexOf(eio.getDest().getSolution(), eio.getIndex().getMinDist().solution()) > -1) { - println ("[EdgeIndexOfChar2] '" + eio.getSource().getSolution() + "' contains '" + eio.getDest().getSolution() + "' after " + eio.getIndex().getMinDist().solution() + " and it should not"); + if (eio.getIndex().solution() == -1 && eio.getSource().getSolution().indexOf(eio.getDest().getSolution(), eio.getIndex().getMinDist().solutionInt()) > -1) { + logger.info ("[EdgeIndexOfChar2] '" + eio.getSource().getSolution() + "' contains '" + eio.getDest().getSolution() + "' after " + eio.getIndex().getMinDist().solution() + " and it should not"); if (!eio.getSource().isConstant() && !eio.getDest().isConstant()) { nonequalityFlipFlop = bitArray[indexBitArray++]; if (nonequalityFlipFlop == false) { @@ -1714,7 +1716,7 @@ else if (!eio.getDest().isConstant()) { } else if (e instanceof EdgeIndexOf2) { EdgeIndexOf2 eio = (EdgeIndexOf2) e; - if (eio.getIndex().solution() == -1 && eio.getSource().getSolution().indexOf(eio.getDest().getSolution(), eio.getIndex().getMinIndex().solution()) > -1) { + if (eio.getIndex().solution() == -1 && eio.getSource().getSolution().indexOf(eio.getDest().getSolution(), eio.getIndex().getMinIndex().solutionInt()) > -1) { //println ("[EdgeIndexOf2] '" + eio.getSource().getSolution() + "' contains '" + eio.getDest().getSolution() + "' and it should not from " + eio.getIndex().getMinIndex().solution()); if (!eio.getSource().isConstant() && !eio.getDest().isConstant()) { if (nonequalityFlipFlop == 0) { @@ -1912,7 +1914,7 @@ else if (!eio.getDest().isConstant()) { } else if (e instanceof EdgeIndexOfChar2) { EdgeIndexOfChar2 eio = (EdgeIndexOfChar2) e; - if (eio.getIndex().solution() == -1 && eio.getSource().getSolution().indexOf(eio.getDest().getSolution(), eio.getIndex().getMinDist().solution()) > -1) { + if (eio.getIndex().solution() == -1 && eio.getSource().getSolution().indexOf(eio.getDest().getSolution(), eio.getIndex().getMinDist().solutionInt()) > -1) { //println ("[EdgeIndexOfChar2] '" + eio.getSource().getSolution() + "' contains '" + eio.getDest().getSolution() + "' after " + eio.getIndex().getMinDist().solution() + " and it should not"); if (!eio.getSource().isConstant() && !eio.getDest().isConstant()) { if (nonequalityFlipFlop == 0) { @@ -2258,7 +2260,7 @@ private static boolean handleEdgeCharAt (EdgeCharAt e) { return false; } else { - temp = AutomatonExtra.lengthAutomaton(e.getIndex().solution()); + temp = AutomatonExtra.lengthAutomaton(e.getIndex().solutionInt()); temp = temp.concatenate(Automaton.makeChar((char) e.getValue().solution()).concatenate(AutomatonExtra.makeAnyStringFixed())); intersection = AutomatonExtra.intersection(a1, temp); if (intersection.isEmpty()) { @@ -2422,7 +2424,7 @@ private static boolean handleEdgeIndexOf (EdgeIndexOf e) { //println (String.format("[handleEdgeIndexOf] a1: '%s'", a1.getShortestExample(true))); Automaton a2 = mapAutomaton.get(e.getDest()); //println (String.format("[handleEdgeIndexOf] a2: '%s'", a2.getShortestExample(true))); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); //First check if it is possible if (index > -1) { Automaton temp = AutomatonExtra.makeAnyStringFixed().concatenate(a2).concatenate(AutomatonExtra.makeAnyStringFixed()); @@ -2560,7 +2562,7 @@ private static boolean handleEdgeLastIndexOf (EdgeLastIndexOf e) { //println ("[handleEdgeIndexOf] entered"); Automaton a1 = mapAutomaton.get(e.getSource()); Automaton a2 = mapAutomaton.get(e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); //First check if it is possible if (index > -1) { Automaton temp = AutomatonExtra.makeAnyStringFixed().concatenate(a2).concatenate(AutomatonExtra.makeAnyStringFixed()); @@ -2649,7 +2651,7 @@ private static boolean handleEdgeIndexOf2 (EdgeIndexOf2 e) { //println ("[handleEdgeIndexOf2] entered: " + e.getName()); Automaton a1 = mapAutomaton.get(e.getSource()); Automaton a2 = mapAutomaton.get(e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); //First check if it is possible if (index > -1) { Automaton temp = AutomatonExtra.makeAnyStringFixed().concatenate(a2).concatenate(AutomatonExtra.makeAnyStringFixed()); @@ -2741,7 +2743,7 @@ private static boolean handleEdgeIndexOfChar (EdgeIndexOfChar e) { //println ("[handleEdgeIndexOfChar] entered"); Automaton a1 = mapAutomaton.get(e.getSource()); //Automaton a2 = mapAutomaton.get(e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); String character = String.valueOf((char) e.getIndex().getExpression().solution()); //First check if it is possible if (index > -1) { @@ -2865,7 +2867,7 @@ private static boolean handleEdgeLastIndexOfChar (EdgeLastIndexOfChar e) { //println ("[handleEdgeLastIndexOfChar] entered"); Automaton a1 = mapAutomaton.get(e.getSource()); //Automaton a2 = mapAutomaton.get(e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); String character = String.valueOf((char) e.getIndex().getExpression().solution()); //First check if it is possible if (index > -1) { @@ -2934,7 +2936,7 @@ private static boolean handleEdgeLastIndexOfChar2 (EdgeLastIndexOfChar2 e) { //println ("[handleEdgeLastIndexOfChar2] entered"); Automaton a1 = mapAutomaton.get(e.getSource()); //Automaton a2 = mapAutomaton.get(e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); String character = String.valueOf((char) e.getIndex().getExpression().solution()); //First check if it is possible if (index > -1) { @@ -2954,7 +2956,7 @@ private static boolean handleEdgeLastIndexOfChar2 (EdgeLastIndexOfChar2 e) { Automaton lastPieceOfString = Automaton.makeCharRange((char) SymbolicStringConstraintsGeneral.MIN_CHAR, (char) SymbolicStringConstraintsGeneral.MAX_CHAR); lastPieceOfString = lastPieceOfString.minus(Automaton.makeChar(character.charAt(0))); lastPieceOfString = AutomatonExtra.star(lastPieceOfString); - lastPieceOfString = lastPieceOfString.concatenate(AutomatonExtra.lengthAutomaton(e.getIndex().getMinDist().solution() - e.getIndex().solution() + 1)); + lastPieceOfString = lastPieceOfString.concatenate(AutomatonExtra.lengthAutomaton(e.getIndex().getMinDist().solutionInt() - e.getIndex().solutionInt() + 1)); //Need to concatenate with any string that does not contain this character. temp = temp.concatenate(Automaton.makeString(character)).concatenate(lastPieceOfString).concatenate(AutomatonExtra.makeAnyStringFixed()); intersection = AutomatonExtra.intersection(a1, temp); @@ -3008,7 +3010,7 @@ private static boolean handleEdgeIndexOfChar2 (EdgeIndexOfChar2 e) { //println ("[handleEdgeIndexOfChar2] entered"); Automaton a1 = mapAutomaton.get(e.getSource()); //Automaton a2 = mapAutomaton.get(e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); String character = String.valueOf((char) e.getIndex().getExpression().solution()); //First check if it is possible if (index > -1) { @@ -3195,7 +3197,7 @@ private static boolean handleEdgeSubstring2Equal (EdgeSubstring2Equal e) { return propResult; } else if (e.getSymbolicArgument2() != null && e.getSymbolicArgument1() == null) { - int arg2 = e.getSymbolicArgument2().solution(); + int arg2 = e.getSymbolicArgument2().solutionInt(); Automaton temp = AutomatonExtra.substring(source, e.getArgument1(), arg2); //println ("[handleEdgeSubstring2Equal] source.getLength() = " + e.getSource().getLength()); //println ("[handleEdgeSubstring2Equal] temp diff = " + (arg2 - e.getArgument1())); @@ -3313,8 +3315,5 @@ private static LogicalORLinearIntegerConstraints elimanateCurrentLengthsConstrai return loic; } - private static void println (String msg) { - if (logging) System.out.println("[TranslateToAutomata] " + msg); - } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToAutomata2.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToAutomata2.java index e4af398..c6c69fc 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToAutomata2.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToAutomata2.java @@ -550,7 +550,7 @@ private static boolean handleEdgeIndexOf (EdgeIndexOf e) { Automaton a1 = mapAutomaton.get(e.getSource()); Automaton a2 = mapAutomaton.get(e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); boolean a1Changed, a2Changed = false; if (index > -1) { @@ -627,7 +627,7 @@ private static boolean handleEdgeIndexOf2 (EdgeIndexOf2 e) { //println ("[handleEdgeIndexOf2] entered: " + e.getName()); Automaton a1 = mapAutomaton.get(e.getSource()); Automaton a2 = mapAutomaton.get(e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); //First check if it is possible if (index > -1) { Automaton temp = AutomatonExtra.makeAnyStringFixed().concatenate(a2).concatenate(AutomatonExtra.makeAnyStringFixed()); @@ -682,7 +682,7 @@ private static boolean handleEdgeIndexOfChar (EdgeIndexOfChar e) { loic.addToList(new LinearIntegerConstraint(e.getIndex().getExpression(), Comparator.NE, new IntegerConstant(e.getIndex().getExpression().solution()))); unsatStack1.add(loic); Automaton a1 = mapAutomaton.get(e.getSource()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); String character = String.valueOf((char) e.getIndex().getExpression().solution()); if (index > -1) { //println ("[handleEdgeIndexOfChar] index > -1"); @@ -760,7 +760,7 @@ private static boolean handleEdgeLastIndexOfChar (EdgeLastIndexOfChar e) { unsatStack1.add(loic); Automaton a1 = mapAutomaton.get(e.getSource()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); String character = String.valueOf((char) e.getIndex().getExpression().solution()); if (index > -1) { Automaton temp = AutomatonExtra.makeAnyStringFixed().concatenate(Automaton.makeString(character)).concatenate(AutomatonExtra.makeAnyStringFixed()); @@ -822,7 +822,7 @@ private static boolean handleEdgeLastIndexOfChar2 (EdgeLastIndexOfChar2 e) { //println ("[handleEdgeLastIndexOfChar2] entered"); Automaton a1 = mapAutomaton.get(e.getSource()); //Automaton a2 = mapAutomaton.get(e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); String character = String.valueOf((char) e.getIndex().getExpression().solution()); //First check if it is possible if (index > -1) { @@ -837,7 +837,7 @@ private static boolean handleEdgeLastIndexOfChar2 (EdgeLastIndexOfChar2 e) { Automaton lastPieceOfString = Automaton.makeCharRange((char) SymbolicStringConstraintsGeneral.MIN_CHAR, (char) SymbolicStringConstraintsGeneral.MAX_CHAR); lastPieceOfString = lastPieceOfString.minus(Automaton.makeChar(character.charAt(0))); lastPieceOfString = AutomatonExtra.star(lastPieceOfString); - lastPieceOfString = lastPieceOfString.concatenate(AutomatonExtra.lengthAutomaton(e.getIndex().getMinDist().solution() - e.getIndex().solution() + 1)); + lastPieceOfString = lastPieceOfString.concatenate(AutomatonExtra.lengthAutomaton(e.getIndex().getMinDist().solutionInt() - e.getIndex().solutionInt() + 1)); //Need to concatenate with any string that does not contain this character. temp = temp.concatenate(Automaton.makeString(character)).concatenate(lastPieceOfString).concatenate(AutomatonExtra.makeAnyStringFixed()); intersection = AutomatonExtra.intersection(a1, temp); @@ -886,7 +886,7 @@ private static boolean handleEdgeIndexOfChar2 (EdgeIndexOfChar2 e) { loic.addToList(new LinearIntegerConstraint(e.getIndex().getMinDist(), Comparator.NE, new IntegerConstant(e.getIndex().getMinDist().solution()))); unsatStack1.add(loic); Automaton a1 = mapAutomaton.get(e.getSource()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); String character = String.valueOf((char) e.getIndex().getExpression().solution()); if (index > -1) { Automaton temp = AutomatonExtra.makeAnyStringFixed().concatenate(Automaton.makeString(character)).concatenate(AutomatonExtra.makeAnyStringFixed()); @@ -897,7 +897,7 @@ private static boolean handleEdgeIndexOfChar2 (EdgeIndexOfChar2 e) { } Automaton exclude = Automaton.makeEmpty(); - for (int i = e.getIndex().getMinDist().solution(); i <= index - e.getDest().getLength(); i++) { + for (int i = e.getIndex().getMinDist().solutionInt(); i <= index - e.getDest().getLength(); i++) { Automaton prefixSpaces = AutomatonExtra.lengthAutomaton(i); Automaton suffixSpaces = AutomatonExtra.lengthAutomaton(index - i - e.getDest().getLength()); Automaton aNew = prefixSpaces.concatenate(Automaton.makeChar(character.charAt(0))).concatenate(suffixSpaces); @@ -965,7 +965,7 @@ private static boolean handleEdgeCharAt (EdgeCharAt e) { return false; } else { - temp = AutomatonExtra.lengthAutomaton(e.getIndex().solution()); + temp = AutomatonExtra.lengthAutomaton(e.getIndex().solutionInt()); temp = temp.concatenate(Automaton.makeChar((char) e.getValue().solution()).concatenate(AutomatonExtra.makeAnyStringFixed())); intersection = AutomatonExtra.intersection(a1, temp); if (intersection.isEmpty()) { @@ -992,7 +992,7 @@ private static boolean handleEdgeNotCharAt (EdgeNotCharAt e) { Automaton a1 = mapAutomaton.get(e.getSource()); Automaton a2 = Automaton.makeChar((char) e.getValue().solution()); - Automaton temp = AutomatonExtra.lengthAutomaton(e.getIndex().solution()); + Automaton temp = AutomatonExtra.lengthAutomaton(e.getIndex().solutionInt()); temp = temp.concatenate(Automaton.makeChar((char) e.getValue().solution()).concatenate(AutomatonExtra.makeAnyStringFixed())); //println ("temp example '" + temp.getShortestExample(true) +"'"); Automaton intersection = a1.minus(temp); @@ -1106,7 +1106,7 @@ else if (e.getSymbolicArgument2() != null && e.getSymbolicArgument1() == null) { loic.addToList(new LinearIntegerConstraint(e.getSymbolicArgument2(), Comparator.NE, new IntegerConstant(e.getSymbolicArgument2().solution()))); unsatStack1.add(loic); - int arg2 = e.getSymbolicArgument2().solution(); + int arg2 = e.getSymbolicArgument2().solutionInt(); Automaton temp = AutomatonExtra.substring(source, e.getArgument1(), arg2); //println ("[handleEdgeSubstring2Equal] source.getLength() = " + e.getSource().getLength()); //println ("[handleEdgeSubstring2Equal] temp diff = " + (arg2 - e.getArgument1())); @@ -1464,7 +1464,7 @@ private static boolean handleNotEdgeIndexOf (EdgeIndexOf e) { unsatStack2.add(new LinearIntegerConstraint(e.getDest().getSymbolicLength(), Comparator.NE, new IntegerConstant(e.getDest().getLength()))); Automaton destination = mapAutomaton.get(e.getDest()); String source = e.getSource().getSolution(); - source = source.substring(0, e.getIndex().solution()); //The part of source before e.getIndex() + source = source.substring(0, e.getIndex().solutionInt()); //The part of source before e.getIndex() for (int i = 0; i <= source.length() - e.getDest().getLength(); i++) { String t = source.substring(i, i + e.getDest().getLength()); @@ -1484,7 +1484,7 @@ private static boolean handleNotEdgeIndexOf (EdgeIndexOf e) { String destination = e.getDest().getSolution(); Automaton temp = AutomatonExtra.makeAnyStringFixed().concatenate(Automaton.makeString(destination)).concatenate(AutomatonExtra.makeAnyStringFixed()); - temp = temp.intersection(AutomatonExtra.lengthAutomaton(e.getIndex().solution())); + temp = temp.intersection(AutomatonExtra.lengthAutomaton(e.getIndex().solutionInt())); temp = temp.concatenate(AutomatonExtra.makeAnyStringFixed()); source = source.minus(temp); @@ -1578,7 +1578,7 @@ private static boolean handleNotEdgeIndexOfChar (EdgeIndexOfChar e) { String destination = String.valueOf((char) e.getIndex().getExpression().solution()); Automaton temp = AutomatonExtra.makeAnyStringFixed().concatenate(Automaton.makeString(destination)).concatenate(AutomatonExtra.makeAnyStringFixed()); - temp = temp.intersection(AutomatonExtra.lengthAutomaton(e.getIndex().solution())); + temp = temp.intersection(AutomatonExtra.lengthAutomaton(e.getIndex().solutionInt())); temp = temp.concatenate(AutomatonExtra.makeAnyStringFixed()); source = source.minus(temp); @@ -1650,7 +1650,7 @@ private static boolean handleNotEdgeLastIndexOfChar (EdgeLastIndexOfChar e) { String source = e.getSource().getSolution(); char destination = (char) e.getIndex().getExpression().solution(); - for (int i = e.getIndex().solution() + 1; i < e.getSource().getLength(); i++) { + for (int i = e.getIndex().solutionInt() + 1; i < e.getSource().getLength(); i++) { char c = source.charAt(i); global_pc._addDet(Comparator.NE, new IntegerConstant(destination), new IntegerConstant(c)); } @@ -1671,7 +1671,7 @@ private static boolean handleNotEdgeLastIndexOfChar (EdgeLastIndexOfChar e) { String destination = String.valueOf((char) e.getIndex().getExpression().solution()); Automaton temp = AutomatonExtra.makeAnyStringFixed().concatenate(Automaton.makeString(destination)).concatenate(AutomatonExtra.makeAnyStringFixed()); - temp = temp.intersection(AutomatonExtra.lengthAutomaton(e.getSource().getLength() - e.getIndex().solution() -1)); + temp = temp.intersection(AutomatonExtra.lengthAutomaton(e.getSource().getLength() - e.getIndex().solutionInt() -1)); temp = AutomatonExtra.makeAnyStringFixed().concatenate(temp); //println ("[handleNotEdgeLastIndexOfChar] e.getSource().getLength(): " + e.getSource().getLength()); //println ("[handleNotEdgeLastIndexOfChar] e.getIndex().solution(): " + e.getIndex().solution()); @@ -1704,7 +1704,7 @@ private static boolean handleNotEdgeIndexOfChar2 (EdgeIndexOfChar2 e) { if (e.getSource().isConstant()) { unsatStack2.add(new LinearIntegerConstraint(e.getDest().getSymbolicLength(), Comparator.NE, new IntegerConstant(e.getDest().getLength()))); - for (int i = e.getIndex().getMinDist().solution(); i < e.getSource().getLength(); i++) { + for (int i = e.getIndex().getMinDist().solutionInt(); i < e.getSource().getLength(); i++) { char c = e.getSource().getSolution().charAt(i); global_pc._addDet(Comparator.NE, new IntegerConstant(c), e.getIndex().getExpression()); } @@ -1723,7 +1723,7 @@ private static boolean handleNotEdgeIndexOfChar2 (EdgeIndexOfChar2 e) { Automaton source = mapAutomaton.get(e.getSource()); String destination = String.valueOf((char) e.getIndex().getExpression().solution()); - Automaton temp = AutomatonExtra.lengthAutomaton(e.getIndex().getMinDist().solution()).concatenate(AutomatonExtra.makeAnyStringFixed().concatenate(Automaton.makeString(destination)).concatenate(AutomatonExtra.makeAnyStringFixed())); + Automaton temp = AutomatonExtra.lengthAutomaton(e.getIndex().getMinDist().solutionInt()).concatenate(AutomatonExtra.makeAnyStringFixed().concatenate(Automaton.makeString(destination)).concatenate(AutomatonExtra.makeAnyStringFixed())); source = source.minus(temp); if (source.isEmpty()) { debug_unsat_reason = "Not handling of edge indexOf == -1, with destination constant, lead to empty source"; @@ -1742,7 +1742,7 @@ private static boolean handleNotEdgeIndexOfChar2 (EdgeIndexOfChar2 e) { String source = e.getSource().getSolution(); char destination = (char) e.getIndex().getExpression().solution(); - for (int i = e.getIndex().getMinDist().solution(); i < e.getIndex().solution(); i++) { + for (int i = e.getIndex().getMinDist().solutionInt(); i < e.getIndex().solution(); i++) { char c = source.charAt(i); global_pc._addDet(Comparator.NE, new IntegerConstant(destination), new IntegerConstant(c)); } @@ -1761,8 +1761,8 @@ private static boolean handleNotEdgeIndexOfChar2 (EdgeIndexOfChar2 e) { Automaton source = mapAutomaton.get(e.getSource()); String destination = String.valueOf((char) e.getIndex().getExpression().solution()); - Automaton temp = AutomatonExtra.lengthAutomaton(e.getIndex().getMinDist().solution()).concatenate(AutomatonExtra.makeAnyStringFixed().concatenate(Automaton.makeString(destination)).concatenate(AutomatonExtra.makeAnyStringFixed())); - temp = temp.intersection(AutomatonExtra.lengthAutomaton(e.getIndex().solution())); + Automaton temp = AutomatonExtra.lengthAutomaton(e.getIndex().getMinDist().solutionInt()).concatenate(AutomatonExtra.makeAnyStringFixed().concatenate(Automaton.makeString(destination)).concatenate(AutomatonExtra.makeAnyStringFixed())); + temp = temp.intersection(AutomatonExtra.lengthAutomaton(e.getIndex().solutionInt())); temp = temp.concatenate(AutomatonExtra.makeAnyStringFixed()); source = source.minus(temp); @@ -1791,7 +1791,7 @@ private static boolean handleNotEdgeLastIndexOfChar2 (EdgeLastIndexOfChar2 e) { if (e.getSource().isConstant()) { unsatStack2.add(new LinearIntegerConstraint(e.getDest().getSymbolicLength(), Comparator.NE, new IntegerConstant(e.getDest().getLength()))); - for (int i = e.getIndex().getMinDist().solution(); i < e.getSource().getLength(); i++) { + for (int i = e.getIndex().getMinDist().solutionInt(); i < e.getSource().getLength(); i++) { char c = e.getSource().getSolution().charAt(i); global_pc._addDet(Comparator.NE, new IntegerConstant(c), e.getIndex().getExpression()); } @@ -1810,7 +1810,7 @@ private static boolean handleNotEdgeLastIndexOfChar2 (EdgeLastIndexOfChar2 e) { Automaton source = mapAutomaton.get(e.getSource()); String destination = String.valueOf((char) e.getIndex().getExpression().solution()); - Automaton temp = AutomatonExtra.lengthAutomaton(e.getIndex().getMinDist().solution()).concatenate(AutomatonExtra.makeAnyStringFixed().concatenate(Automaton.makeString(destination)).concatenate(AutomatonExtra.makeAnyStringFixed())); + Automaton temp = AutomatonExtra.lengthAutomaton(e.getIndex().getMinDist().solutionInt()).concatenate(AutomatonExtra.makeAnyStringFixed().concatenate(Automaton.makeString(destination)).concatenate(AutomatonExtra.makeAnyStringFixed())); source = source.minus(temp); if (source.isEmpty()) { debug_unsat_reason = "Not handling of edge indexOf == -1, with destination constant, lead to empty source"; @@ -1829,7 +1829,7 @@ private static boolean handleNotEdgeLastIndexOfChar2 (EdgeLastIndexOfChar2 e) { String source = e.getSource().getSolution(); char destination = (char) e.getIndex().getExpression().solution(); - for (int i = e.getIndex().getMinDist().solution(); i < e.getSource().getLength(); i++) { + for (int i = e.getIndex().getMinDist().solutionInt(); i < e.getSource().getLength(); i++) { char c = source.charAt(i); global_pc._addDet(Comparator.NE, new IntegerConstant(destination), new IntegerConstant(c)); } @@ -1848,8 +1848,8 @@ private static boolean handleNotEdgeLastIndexOfChar2 (EdgeLastIndexOfChar2 e) { Automaton source = mapAutomaton.get(e.getSource()); String destination = String.valueOf((char) e.getIndex().getExpression().solution()); - Automaton temp = AutomatonExtra.lengthAutomaton(e.getIndex().getMinDist().solution()).concatenate(AutomatonExtra.makeAnyStringFixed().concatenate(Automaton.makeString(destination)).concatenate(AutomatonExtra.makeAnyStringFixed())); - temp = temp.intersection(AutomatonExtra.lengthAutomaton(e.getSource().getLength() - e.getIndex().solution() - 1)); + Automaton temp = AutomatonExtra.lengthAutomaton(e.getIndex().getMinDist().solutionInt()).concatenate(AutomatonExtra.makeAnyStringFixed().concatenate(Automaton.makeString(destination)).concatenate(AutomatonExtra.makeAnyStringFixed())); + temp = temp.intersection(AutomatonExtra.lengthAutomaton(e.getSource().getLength() - e.getIndex().solutionInt() - 1)); temp = AutomatonExtra.makeAnyStringFixed().concatenate(temp); source = source.minus(temp); @@ -1879,7 +1879,7 @@ private static boolean handleNotEdgeIndexOf2 (EdgeIndexOf2 e) { Automaton destination = mapAutomaton.get(e.getDest()); String source = e.getSource().getSolution(); - for (int i = e.getIndex().getMinIndex().solution(); i <= e.getSource().getLength() - e.getDest().getLength(); i++) { + for (int i = e.getIndex().getMinIndex().solutionInt(); i <= e.getSource().getLength() - e.getDest().getLength(); i++) { String t = source.substring(i, i + e.getDest().getLength()); destination = destination.minus(Automaton.makeString(t)); if (destination.isEmpty()) { @@ -1896,7 +1896,7 @@ private static boolean handleNotEdgeIndexOf2 (EdgeIndexOf2 e) { Automaton source = mapAutomaton.get(e.getSource()); String destination = e.getDest().getSolution(); - Automaton temp = AutomatonExtra.lengthAutomaton(e.getIndex().getMinIndex().solution()).concatenate(AutomatonExtra.makeAnyStringFixed()).concatenate(Automaton.makeString(destination)).concatenate(AutomatonExtra.makeAnyStringFixed()); + Automaton temp = AutomatonExtra.lengthAutomaton(e.getIndex().getMinIndex().solutionInt()).concatenate(AutomatonExtra.makeAnyStringFixed()).concatenate(Automaton.makeString(destination)).concatenate(AutomatonExtra.makeAnyStringFixed()); source = source.minus(temp); if (source.isEmpty()) { debug_unsat_reason = "Not handling of edge indexOf == -1, with destination constant, lead to empty source"; @@ -1918,9 +1918,9 @@ private static boolean handleNotEdgeIndexOf2 (EdgeIndexOf2 e) { unsatStack2.add(new LinearIntegerConstraint(e.getDest().getSymbolicLength(), Comparator.NE, new IntegerConstant(e.getDest().getLength()))); Automaton destination = mapAutomaton.get(e.getDest()); String source = e.getSource().getSolution(); - source = source.substring(e.getIndex().getMinIndex().solution(), e.getIndex().solution()); //The part of source before e.getIndex() + source = source.substring(e.getIndex().getMinIndex().solutionInt(), e.getIndex().solutionInt()); //The part of source before e.getIndex() - for (int i = e.getIndex().getMinIndex().solution(); i <= source.length() - e.getDest().getLength(); i++) { + for (int i = e.getIndex().getMinIndex().solutionInt(); i <= source.length() - e.getDest().getLength(); i++) { String t = source.substring(i, i + e.getDest().getLength()); destination = destination.minus(Automaton.makeString(t)); if (destination.isEmpty()) { @@ -1937,8 +1937,8 @@ private static boolean handleNotEdgeIndexOf2 (EdgeIndexOf2 e) { Automaton source = mapAutomaton.get(e.getSource()); String destination = e.getDest().getSolution(); - Automaton temp = AutomatonExtra.lengthAutomaton(e.getIndex().getMinIndex().solution()).concatenate(AutomatonExtra.makeAnyStringFixed().concatenate(Automaton.makeString(destination)).concatenate(AutomatonExtra.makeAnyStringFixed())); - temp = temp.intersection(AutomatonExtra.lengthAutomaton(e.getIndex().solution())); + Automaton temp = AutomatonExtra.lengthAutomaton(e.getIndex().getMinIndex().solutionInt()).concatenate(AutomatonExtra.makeAnyStringFixed().concatenate(Automaton.makeString(destination)).concatenate(AutomatonExtra.makeAnyStringFixed())); + temp = temp.intersection(AutomatonExtra.lengthAutomaton(e.getIndex().solutionInt())); temp = temp.concatenate(AutomatonExtra.makeAnyStringFixed()); source = source.minus(temp); @@ -2183,7 +2183,7 @@ private static void handleEdgeIndexOfVarVar (EdgeIndexOf e, int base) { Automaton source = mapAutomaton.get(e.getSource()); Automaton dest = mapAutomaton.get(e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); //println ("index: " + index); String[] sourceSolutions = new String[base]; String[] destSolutions = new String[base]; @@ -2251,8 +2251,8 @@ private static void handleEdgeIndexOf2VarVar (EdgeIndexOf2 e, int base) { Automaton source = mapAutomaton.get(e.getSource()); Automaton dest = mapAutomaton.get(e.getDest()); - int index = e.getIndex().solution(); - int minIndex = e.getIndex().getMinIndex().solution(); + int index = e.getIndex().solutionInt(); + int minIndex = e.getIndex().getMinIndex().solutionInt(); //println ("index: " + index); String[] sourceSolutions = new String[base]; String[] destSolutions = new String[base]; @@ -2442,7 +2442,7 @@ private static boolean handleEdgeIndexOf2 (EdgeIndexOf2 e, List iterati String source = concreteMap.get(e.getSource()).get(iteration.get(sourceNum)); String dest = concreteMap.get(e.getDest()).get(iteration.get(destNum)); - return source.indexOf(dest, e.getIndex().getMinIndex().solution()) == -1; + return source.indexOf(dest, e.getIndex().getMinIndex().solutionInt()) == -1; } else if (e.getIndex().solution() >= 0) { int sourceNum = mapVertexInteger.get(e.getSource()); int destNum = mapVertexInteger.get(e.getDest()); @@ -2450,7 +2450,7 @@ private static boolean handleEdgeIndexOf2 (EdgeIndexOf2 e, List iterati String source = concreteMap.get(e.getSource()).get(iteration.get(sourceNum)); String dest = concreteMap.get(e.getDest()).get(iteration.get(destNum)); - return source.indexOf(dest, e.getIndex().getMinIndex().solution()) == e.getIndex().solution(); + return source.indexOf(dest, e.getIndex().getMinIndex().solutionInt()) == e.getIndex().solution(); } throw new RuntimeException("This should not be reached"); } @@ -2505,7 +2505,7 @@ private static boolean handleEdgeLastIndexOfChar2 (EdgeLastIndexOfChar2 e, List< String source = concreteMap.get(e.getSource()).get(iteration.get(sourceNum)); String dest = concreteMap.get(e.getDest()).get(iteration.get(destNum)); - return source.lastIndexOf(dest, e.getIndex().getMinDist().solution()) == -1; + return source.lastIndexOf(dest, e.getIndex().getMinDist().solutionInt()) == -1; } else if (e.getIndex().solution() >= 0) { int sourceNum = mapVertexInteger.get(e.getSource()); int destNum = mapVertexInteger.get(e.getDest()); @@ -2513,7 +2513,7 @@ private static boolean handleEdgeLastIndexOfChar2 (EdgeLastIndexOfChar2 e, List< String source = concreteMap.get(e.getSource()).get(iteration.get(sourceNum)); String dest = concreteMap.get(e.getDest()).get(iteration.get(destNum)); - return source.lastIndexOf(dest, e.getIndex().getMinDist().solution()) == e.getIndex().solution(); + return source.lastIndexOf(dest, e.getIndex().getMinDist().solutionInt()) == e.getIndex().solution(); } throw new RuntimeException("This should not be reached"); } @@ -2526,7 +2526,7 @@ private static boolean handleEdgeIndexOfChar2 (EdgeIndexOfChar2 e, List String source = concreteMap.get(e.getSource()).get(iteration.get(sourceNum)); String dest = concreteMap.get(e.getDest()).get(iteration.get(destNum)); - return source.indexOf(dest, e.getIndex().getMinDist().solution()) == -1; + return source.indexOf(dest, e.getIndex().getMinDist().solutionInt()) == -1; } else if (e.getIndex().solution() >= 0) { int sourceNum = mapVertexInteger.get(e.getSource()); int destNum = mapVertexInteger.get(e.getDest()); @@ -2534,7 +2534,7 @@ private static boolean handleEdgeIndexOfChar2 (EdgeIndexOfChar2 e, List String source = concreteMap.get(e.getSource()).get(iteration.get(sourceNum)); String dest = concreteMap.get(e.getDest()).get(iteration.get(destNum)); - return source.indexOf(dest, e.getIndex().getMinDist().solution()) == e.getIndex().solution(); + return source.indexOf(dest, e.getIndex().getMinDist().solutionInt()) == e.getIndex().solution(); } throw new RuntimeException("This should not be reached"); } @@ -2574,7 +2574,4 @@ private static LogicalORLinearIntegerConstraints excludeVertecis(Edge e) { } } - private static void println (String msg) { - System.out.println("[TranslateToAutomata2] " + msg); - } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToAutomataSpeedUp.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToAutomataSpeedUp.java index 0f15782..2347535 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToAutomataSpeedUp.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToAutomataSpeedUp.java @@ -780,7 +780,7 @@ private static boolean handleEdgeCharAt (EdgeCharAt e) { return false; } else { - temp = AutomatonExtra.lengthAutomaton(e.getIndex().solution()); + temp = AutomatonExtra.lengthAutomaton(e.getIndex().solutionInt()); temp = temp.concatenate(Automaton.makeChar((char) e.getValue().solution()).concatenate(AutomatonExtra.makeAnyStringFixed())); intersection = AutomatonExtra.intersection(a1, temp); if (intersection.isEmpty()) { @@ -896,7 +896,7 @@ private static boolean handleEdgeIndexOf (EdgeIndexOf e) { //println ("[handleEdgeIndexOf] entered"); Automaton a1 = mapAutomaton.get(e.getSource()); Automaton a2 = mapAutomaton.get(e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); //First check if it is possible if (index > -1) { Automaton temp = AutomatonExtra.makeAnyStringFixed().concatenate(a2).concatenate(AutomatonExtra.makeAnyStringFixed()); @@ -982,7 +982,7 @@ private static boolean handleEdgeIndexOf2 (EdgeIndexOf2 e) { //println ("[handleEdgeIndexOf] entered"); Automaton a1 = mapAutomaton.get(e.getSource()); Automaton a2 = mapAutomaton.get(e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); //First check if it is possible if (index > -1) { Automaton temp = AutomatonExtra.makeAnyStringFixed().concatenate(a2).concatenate(AutomatonExtra.makeAnyStringFixed()); @@ -1068,7 +1068,7 @@ private static boolean handleEdgeIndexOfChar (EdgeIndexOfChar e) { //println ("[handleEdgeIndexOf] entered"); Automaton a1 = mapAutomaton.get(e.getSource()); //Automaton a2 = mapAutomaton.get(e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); String character = String.valueOf((char) e.getIndex().getExpression().solution()); //First check if it is possible if (index > -1) { @@ -1155,7 +1155,7 @@ private static boolean handleEdgeIndexOfChar2 (EdgeIndexOfChar2 e) { //println ("[handleEdgeIndexOf] entered"); Automaton a1 = mapAutomaton.get(e.getSource()); //Automaton a2 = mapAutomaton.get(e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); String character = String.valueOf((char) e.getIndex().getExpression().solution()); //First check if it is possible if (index > -1) { @@ -1392,8 +1392,5 @@ private static LogicalORLinearIntegerConstraints elimanateCurrentLengthsConstrai return loic; } - private static void println (String msg) { - if (logging) System.out.println("[TranslateToAutomata] " + msg); - } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToCVC.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToCVC.java index 3860ecd..dcbba8c 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToCVC.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToCVC.java @@ -641,8 +641,8 @@ else if (!e.getDest().isConstant()) { public static void handleEdgeCharAt (EdgeCharAt e) { if (!e.getSource().isConstant()) { ExprMut source = getExprMut(e.getSource()); - char c = (char) e.getValue().solution(); - int index = e.getIndex().solution(); + char c = e.getValue().solutionChar(); + int index = e.getIndex().solutionInt(); Expr temp = vc.newBVExtractExpr(source, (e.getSource().getLength() - index) * 8 - 1, (e.getSource().getLength() - index) * 8 - 8); Expr cons = vc.newBVConstExpr(toBits(c)); post (vc.eqExpr(temp, cons)); @@ -650,7 +650,7 @@ public static void handleEdgeCharAt (EdgeCharAt e) { else { String constant = e.getSource().getSolution(); char c = (char) e.getValue().solution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); if (index > -1) { ExprMut temp1 = vc.newBVConstExpr(toBits(constant.charAt(index))); ExprMut temp2 = vc.newBVConstExpr(toBits(c)); @@ -840,7 +840,7 @@ private static void handleEdgeIndexOf2 (EdgeIndexOf2 e) { if (!e.getSource().isConstant() && !e.getDest().isConstant()) { ExprMut source = getExprMut (e.getSource()); ExprMut dest = getExprMut (e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); if (index > -1) { Expr lit = null; for (int i = index; i < index + e.getDest().getLength(); i++) { @@ -866,7 +866,7 @@ else if (e.getSource().getLength() == e.getDest().getLength()) { else if (!e.getSource().isConstant()) { ExprMut source = getExprMut (e.getSource()); String destCons = e.getDest().getSolution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); if (index > -1) { Expr lit = null; for (int i = index; i < index + e.getDest().getLength(); i++) { @@ -893,7 +893,7 @@ else if (!e.getDest().isConstant()) { String sourceCons = e.getSource().getSolution(); ExprMut dest = getExprMut(e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); if (index > -1) { String realSolution = sourceCons.substring(index, index + e.getDest().getLength()); @@ -924,7 +924,7 @@ private static void handleEdgeIndexOf (EdgeIndexOf e) { if (!e.getSource().isConstant() && !e.getDest().isConstant()) { ExprMut source = getExprMut (e.getSource()); ExprMut dest = getExprMut (e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); if (index > -1) { Expr lit = null; for (int i = index; i < index + e.getDest().getLength(); i++) { @@ -950,7 +950,7 @@ else if (e.getSource().getLength() == e.getDest().getLength()) { else if (!e.getSource().isConstant()) { ExprMut source = getExprMut (e.getSource()); String destCons = e.getDest().getSolution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); if (index > -1) { Expr lit = null; for (int i = index; i < index + e.getDest().getLength(); i++) { @@ -977,7 +977,7 @@ else if (!e.getDest().isConstant()) { String sourceCons = e.getSource().getSolution(); ExprMut dest = getExprMut(e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); if (index > -1) { String realSolution = sourceCons.substring(index, index + e.getDest().getLength()); @@ -1007,7 +1007,7 @@ else if (e.getSource().getLength() == e.getDest().getLength()) { private static void handleEdgeIndexOfChar (EdgeIndexOfChar e) { if (!e.getSource().isConstant()) { ExprMut source = getExprMut(e.getSource()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); if (index > -1) { Expr lit = null; @@ -1035,7 +1035,7 @@ private static void handleEdgeIndexOfChar (EdgeIndexOfChar e) { } else { String source = e.getSource().getSolution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); int actualAns = source.indexOf(character); post (vc.eqExpr(vc.ratExpr(actualAns), vc.ratExpr(index))); @@ -1045,7 +1045,7 @@ private static void handleEdgeIndexOfChar (EdgeIndexOfChar e) { private static void handleEdgeLastIndexOfChar (EdgeLastIndexOfChar e) { if (!e.getSource().isConstant()) { ExprMut source = getExprMut(e.getSource()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); if (index > -1) { Expr lit = null; @@ -1073,7 +1073,7 @@ private static void handleEdgeLastIndexOfChar (EdgeLastIndexOfChar e) { } else { String source = e.getSource().getSolution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); int actualAns = source.indexOf(character); post (vc.eqExpr(vc.ratExpr(actualAns), vc.ratExpr(index))); @@ -1083,7 +1083,7 @@ private static void handleEdgeLastIndexOfChar (EdgeLastIndexOfChar e) { private static void handleEdgeLastIndexOfChar2 (EdgeLastIndexOfChar2 e) { if (!e.getSource().isConstant()) { ExprMut source = getExprMut(e.getSource()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); if (index > -1) { Expr lit = null; @@ -1112,9 +1112,9 @@ private static void handleEdgeLastIndexOfChar2 (EdgeLastIndexOfChar2 e) { } else { String source = e.getSource().getSolution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); - int actualAns = source.lastIndexOf(character, e.getIndex().getMinDist().solution()); + int actualAns = source.lastIndexOf(character, e.getIndex().getMinDist().solutionInt()); post (vc.eqExpr(vc.ratExpr(actualAns), vc.ratExpr(index))); } } @@ -1122,14 +1122,14 @@ private static void handleEdgeLastIndexOfChar2 (EdgeLastIndexOfChar2 e) { private static void handleEdgeIndexOfChar2 (EdgeIndexOfChar2 e) { if (!e.getSource().isConstant()) { ExprMut source = getExprMut(e.getSource()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); if (index > -1) { //println ("[handleEdgeIndexOfChar2] branch 1"); Expr lit = null; /* no other occurences of the character may come before */ //println ("[handleEdgeIndexOfChar2] e.getIndex().getMinDist().solution() = " + e.getIndex().getMinDist().solution()); - int i = e.getIndex().getMinDist().solution(); + int i = e.getIndex().getMinDist().solutionInt(); if (e.getIndex().getMinDist().solution() < 0) { i = 0; } @@ -1155,9 +1155,9 @@ private static void handleEdgeIndexOfChar2 (EdgeIndexOfChar2 e) { } else { String source = e.getSource().getSolution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); - int actualAns = source.indexOf(character, e.getIndex().getMinDist().solution()); + int actualAns = source.indexOf(character, e.getIndex().getMinDist().solutionInt()); post (vc.eqExpr(vc.ratExpr(actualAns), vc.ratExpr(index))); } } @@ -1236,7 +1236,7 @@ else if (e.getSymbolicArgument1() == null && e.getSymbolicArgument2() != null) { ExprMut source = getExprMut(e.getSource()); ExprMut dest = getExprMut(e.getDest()); int arg1 = e.getArgument1(); - int arg2 = e.getSymbolicArgument2().solution(); + int arg2 = e.getSymbolicArgument2().solutionInt(); Expr lit = null; for (int i = 0; i < arg2 - arg1; i++) { Expr sourceTemp = vc.newBVExtractExpr(source, (e.getSource().getLength() - (i + arg1)) * 8 - 1, (e.getSource().getLength() - (i + arg1)) * 8 - 8); @@ -1249,7 +1249,7 @@ else if (!e.getSource().isConstant()) { ExprMut source = getExprMut(e.getSource()); String destCons = e.getDest().getSolution(); int arg1 = e.getArgument1(); - int arg2 = e.getSymbolicArgument2().solution(); + int arg2 = e.getSymbolicArgument2().solutionInt(); if (arg2 - arg1 != destCons.length()) { //TODO: Can definitly improve here //global_pc._addDet(Comparator.EQ, e.getSymbolicArgument2(), destCons.length() + arg1); @@ -1342,8 +1342,4 @@ private static ExprMut getExprMut (Vertex v){ return result; } - private static void println (String msg) { - System.out.println("[TranslateToCVC] " + msg); - } - } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToCVCInc.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToCVCInc.java index 0163d8d..e137784 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToCVCInc.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToCVCInc.java @@ -609,8 +609,8 @@ private static boolean handleEdgeCharAt (EdgeCharAt e) { boolean result = true; if (!e.getSource().isConstant()) { ExprMut source = getExprMut(e.getSource()); - char c = (char) e.getValue().solution(); - int index = e.getIndex().solution(); + char c = (char) e.getValue().solutionInt(); + int index = e.getIndex().solutionInt(); //println ("[handleEdgeCharAt] " + c + " " + index); Expr temp = vc.newBVExtractExpr(source, (e.getSource().getLength() - index) * 8 - 1, (e.getSource().getLength() - index) * 8 - 8); Expr cons = vc.newBVConstExpr(toBits(c)); @@ -619,8 +619,8 @@ private static boolean handleEdgeCharAt (EdgeCharAt e) { } else { String constant = e.getSource().getSolution(); - char c = (char) e.getValue().solution(); - int index = e.getIndex().solution(); + char c = (char) e.getValue().solutionInt(); + int index = e.getIndex().solutionInt(); if (index > -1) { ExprMut temp1 = vc.newBVConstExpr(toBits(constant.charAt(index))); ExprMut temp2 = vc.newBVConstExpr(toBits(c)); @@ -642,7 +642,7 @@ private static boolean handleEdgeCharAt (EdgeCharAt e) { //println ("[handleEdgeCharAt] returning false"); //LinearOrIntegerConstraints loic = elimanateCurrentLengthsConstraints(); //println ("[handleEdgeCharAt] e.getSource().getLength(): " + e.getSource().getLength()); - //println ("[handleEdgeCharAt] index: " + e.getIndex().solution()); + //println ("[handleEdgeCharAt] index: " + e.getIndex().solutionInt()); LogicalORLinearIntegerConstraints loic = new LogicalORLinearIntegerConstraints(); loic.addToList(new LinearIntegerConstraint(e.getIndex(), Comparator.NE, new IntegerConstant(e.getIndex().solution()))); loic.addToList(new LinearIntegerConstraint(e.getValue(), Comparator.NE, new IntegerConstant(e.getValue().solution()))); @@ -853,7 +853,7 @@ private static boolean handleEdgeIndexOf2 (EdgeIndexOf2 e) { if (!e.getSource().isConstant() && !e.getDest().isConstant()) { ExprMut source = getExprMut (e.getSource()); ExprMut dest = getExprMut (e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); if (index > -1) { Expr lit = null; for (int i = index; i < index + e.getDest().getLength(); i++) { @@ -873,15 +873,15 @@ else if (e.getSource().getLength() == e.getDest().getLength()) { result = post (vc.notExpr(equal(e))); } else { - //println ("[handleEdgeIndexOf2] posting: " + vc.notExpr(contains(e, e.getIndex().getMinIndex().solution()))); - result = post (vc.notExpr(contains(e, e.getIndex().getMinIndex().solution()))); + //println ("[handleEdgeIndexOf2] posting: " + vc.notExpr(contains(e, e.getIndex().getMinIndex().solutionInt()))); + result = post (vc.notExpr(contains(e, e.getIndex().getMinIndex().solutionInt()))); } } } else if (!e.getSource().isConstant()) { ExprMut source = getExprMut (e.getSource()); String destCons = e.getDest().getSolution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); if (index > -1) { Expr lit = null; for (int i = index; i < index + e.getDest().getLength(); i++) { @@ -901,8 +901,8 @@ else if (e.getSource().getLength() == e.getDest().getLength()) { result = post (vc.notExpr(equal(e))); } else { - //println ("[handleEdgeIndexof2] posting: " + vc.notExpr(contains(e, e.getIndex().getMinIndex().solution()))); - result = post (vc.notExpr(contains(e, e.getIndex().getMinIndex().solution()))); + //println ("[handleEdgeIndexof2] posting: " + vc.notExpr(contains(e, e.getIndex().getMinIndex().solutionInt()))); + result = post (vc.notExpr(contains(e, e.getIndex().getMinIndex().solutionInt()))); } } } @@ -910,7 +910,7 @@ else if (!e.getDest().isConstant()) { String sourceCons = e.getSource().getSolution(); ExprMut dest = getExprMut(e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); if (index > -1) { String realSolution = sourceCons.substring(index, index + e.getDest().getLength()); @@ -932,8 +932,8 @@ else if (e.getSource().getLength() == e.getDest().getLength()) { result = post (vc.notExpr(equal(e))); } else { - //println ("[handleEdgeIndexOf2] posting: " + vc.notExpr(contains(e, e.getIndex().getMinIndex().solution()))); - result = post (vc.notExpr(contains(e, e.getIndex().getMinIndex().solution()))); + //println ("[handleEdgeIndexOf2] posting: " + vc.notExpr(contains(e, e.getIndex().getMinIndex().solutionInt()))); + result = post (vc.notExpr(contains(e, e.getIndex().getMinIndex().solutionInt()))); } } } @@ -952,7 +952,7 @@ private static boolean handleEdgeIndexOf (EdgeIndexOf e) { //println ("[handleEdgeIndexOf] branch 1"); ExprMut source = getExprMut (e.getSource()); ExprMut dest = getExprMut (e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); if (index > -1) { Expr lit = null; for (int i = index; i < index + e.getDest().getLength(); i++) { @@ -982,7 +982,7 @@ else if (!e.getSource().isConstant()) { //println ("[handleEdgeIndexOf] branch 2"); ExprMut source = getExprMut (e.getSource()); String destCons = e.getDest().getSolution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); if (index > -1) { //println ("[handleEdgeIndexOf] branch 2.1"); Expr lit = null; @@ -1018,7 +1018,7 @@ else if (!e.getDest().isConstant()) { String sourceCons = e.getSource().getSolution(); ExprMut dest = getExprMut(e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); if (index > -1) { String realSolution = sourceCons.substring(index, index + e.getDest().getLength()); @@ -1062,8 +1062,8 @@ private static boolean handleEdgeIndexOfChar (EdgeIndexOfChar e) { boolean result = true; if (!e.getSource().isConstant()) { ExprMut source = getExprMut(e.getSource()); - int index = e.getIndex().solution(); - char character = (char) e.getIndex().getExpression().solution(); + int index = e.getIndex().solutionInt(); + char character = (char) e.getIndex().getExpression().solutionInt(); if (index > -1) { Expr lit = null; /* no other occurences of the character may come before */ @@ -1094,8 +1094,8 @@ private static boolean handleEdgeIndexOfChar (EdgeIndexOfChar e) { } else { String source = e.getSource().getSolution(); - int index = e.getIndex().solution(); - char character = (char) e.getIndex().getExpression().solution(); + int index = e.getIndex().solutionInt(); + char character = (char) e.getIndex().getExpression().solutionInt(); int actualAns = source.indexOf(character); result = post (vc.eqExpr(vc.ratExpr(actualAns), vc.ratExpr(index))); } @@ -1112,15 +1112,15 @@ private static boolean handleEdgeIndexOfChar2 (EdgeIndexOfChar2 e) { boolean result = true; if (!e.getSource().isConstant()) { ExprMut source = getExprMut(e.getSource()); - int index = e.getIndex().solution(); - char character = (char) e.getIndex().getExpression().solution(); + int index = e.getIndex().solutionInt(); + char character = (char) e.getIndex().getExpression().solutionInt(); if (index > -1) { //println ("[handleEdgeIndexOfChar2] branch 1"); Expr lit = null; /* no other occurences of the character may come before */ - //println ("[handleEdgeIndexOfChar2] e.getIndex().getMinDist().solution() = " + e.getIndex().getMinDist().solution()); - int i = e.getIndex().getMinDist().solution(); - if (e.getIndex().getMinDist().solution() < 0) { + //println ("[handleEdgeIndexOfChar2] e.getIndex().getMinDist().solutionInt() = " + e.getIndex().getMinDist().solutionInt()); + int i = e.getIndex().getMinDist().solutionInt(); + if (e.getIndex().getMinDist().solutionInt() < 0) { i = 0; } //println ("[handleEdgeIndexOfChar2] min dist: " + i); @@ -1137,7 +1137,7 @@ private static boolean handleEdgeIndexOfChar2 (EdgeIndexOfChar2 e) { } else { Expr lit = null; - int i = e.getIndex().getMinDist().solution(); + int i = e.getIndex().getMinDist().solutionInt(); if (i < 0) i = 0; for (; i < e.getSource().getLength(); i++) { Expr sourceTemp = vc.newBVExtractExpr(source, (e.getSource().getLength() - i) * 8 - 1, (e.getSource().getLength() - i) * 8 - 8); @@ -1149,9 +1149,9 @@ private static boolean handleEdgeIndexOfChar2 (EdgeIndexOfChar2 e) { } else { String source = e.getSource().getSolution(); - int index = e.getIndex().solution(); - char character = (char) e.getIndex().getExpression().solution(); - int actualAns = source.indexOf(character, e.getIndex().getMinDist().solution()); + int index = e.getIndex().solutionInt(); + char character = (char) e.getIndex().getExpression().solutionInt(); + int actualAns = source.indexOf(character, e.getIndex().getMinDist().solutionInt()); result = post (vc.eqExpr(vc.ratExpr(actualAns), vc.ratExpr(index))); } if (result == false) { @@ -1213,8 +1213,8 @@ private static boolean handleEdgeLastIndexOfChar (EdgeLastIndexOfChar e) { boolean result = true; if (!e.getSource().isConstant()) { ExprMut source = getExprMut(e.getSource()); - int index = e.getIndex().solution(); - char character = (char) e.getIndex().getExpression().solution(); + int index = e.getIndex().solutionInt(); + char character = (char) e.getIndex().getExpression().solutionInt(); if (index > -1) { Expr lit = null; /* no other occurences of the character may come after */ @@ -1241,8 +1241,8 @@ private static boolean handleEdgeLastIndexOfChar (EdgeLastIndexOfChar e) { } else { String source = e.getSource().getSolution(); - int index = e.getIndex().solution(); - char character = (char) e.getIndex().getExpression().solution(); + int index = e.getIndex().solutionInt(); + char character = (char) e.getIndex().getExpression().solutionInt(); int actualAns = source.indexOf(character); result = post (vc.eqExpr(vc.ratExpr(actualAns), vc.ratExpr(index))); } @@ -1258,12 +1258,12 @@ private static boolean handleEdgeLastIndexOfChar2 (EdgeLastIndexOfChar2 e) { boolean result = true; if (!e.getSource().isConstant()) { ExprMut source = getExprMut(e.getSource()); - int index = e.getIndex().solution(); - char character = (char) e.getIndex().getExpression().solution(); + int index = e.getIndex().solutionInt(); + char character = (char) e.getIndex().getExpression().solutionInt(); if (index > -1) { Expr lit = null; /* no other occurences of the character may come after up till second argument*/ - for (int i = index+1; i < e.getIndex().getMinDist().solution(); i++) { + for (int i = index+1; i < e.getIndex().getMinDist().solutionInt(); i++) { Expr sourceTemp = vc.newBVExtractExpr(source, (e.getSource().getLength() - i) * 8 - 1, (e.getSource().getLength() - i) * 8 - 8); Expr constant = vc.newBVConstExpr(toBits(character)); lit = and (lit, vc.notExpr(vc.eqExpr(sourceTemp, constant))); @@ -1277,7 +1277,7 @@ private static boolean handleEdgeLastIndexOfChar2 (EdgeLastIndexOfChar2 e) { else { Expr lit = null; //Can not feature uptil the second argument - for (int i = 0; i < e.getIndex().getMinDist().solution(); i++) { + for (int i = 0; i < e.getIndex().getMinDist().solutionInt(); i++) { Expr sourceTemp = vc.newBVExtractExpr(source, (e.getSource().getLength() - i) * 8 - 1, (e.getSource().getLength() - i) * 8 - 8); Expr constant = vc.newBVConstExpr(toBits(character)); lit = and (lit, vc.notExpr(vc.eqExpr(sourceTemp, constant))); @@ -1287,15 +1287,15 @@ private static boolean handleEdgeLastIndexOfChar2 (EdgeLastIndexOfChar2 e) { } else { String source = e.getSource().getSolution(); - int index = e.getIndex().solution(); - char character = (char) e.getIndex().getExpression().solution(); - int actualAns = source.lastIndexOf(character, e.getIndex().getMinDist().solution()); + int index = e.getIndex().solutionInt(); + char character = (char) e.getIndex().getExpression().solutionInt(); + int actualAns = source.lastIndexOf(character, e.getIndex().getMinDist().solutionInt()); result = (index == actualAns); } if (result == false) { LogicalORLinearIntegerConstraints loic = elimanateCurrentLengthsConstraints(); loic.addToList(new LinearIntegerConstraint(e.getIndex(), Comparator.NE, new IntegerConstant(e.getIndex().solution()))); - loic.addToList(new LinearIntegerConstraint(e.getIndex().getMinDist(), Comparator.NE, new IntegerConstant(e.getIndex().getMinDist().solution()))); + loic.addToList(new LinearIntegerConstraint(e.getIndex().getMinDist(), Comparator.NE, new IntegerConstant(e.getIndex().getMinDist().solutionInt()))); global_pc._addDet(loic); } return result; @@ -1344,7 +1344,7 @@ else if (e.getSymbolicArgument1() == null && e.getSymbolicArgument2() != null) { ExprMut source = getExprMut(e.getSource()); ExprMut dest = getExprMut(e.getDest()); int arg1 = e.getArgument1(); - int arg2 = e.getSymbolicArgument2().solution(); + int arg2 = e.getSymbolicArgument2().solutionInt(); Expr lit = null; for (int i = 0; i < arg2 - arg1; i++) { Expr sourceTemp = vc.newBVExtractExpr(source, (e.getSource().getLength() - (i + arg1)) * 8 - 1, (e.getSource().getLength() - (i + arg1)) * 8 - 8); @@ -1357,7 +1357,7 @@ else if (!e.getSource().isConstant()) { ExprMut source = getExprMut(e.getSource()); String destCons = e.getDest().getSolution(); int arg1 = e.getArgument1(); - int arg2 = e.getSymbolicArgument2().solution(); + int arg2 = e.getSymbolicArgument2().solutionInt(); if (arg2 - arg1 != destCons.length()) { //TODO: Can definitly improve here LogicalORLinearIntegerConstraints loic = elimanateCurrentLengthsConstraints(); @@ -1478,9 +1478,6 @@ private static ExprMut getExprMut (Vertex v){ return result; } - private static void println (String msg) { - System.out.println("[TranslateToCVCInc] " + msg); - } private static LogicalORLinearIntegerConstraints elimanateCurrentLengthsConstraints() { LogicalORLinearIntegerConstraints loic = new LogicalORLinearIntegerConstraints(); diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToSAT.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToSAT.java index 99eef4f..37eb10a 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToSAT.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToSAT.java @@ -400,8 +400,8 @@ private static boolean handleEdgeCharAt (EdgeCharAt e) throws ContradictionExcep //Constant cases should be handeld by the preprocessor if (!e.getSource().isConstant()) { int vector1 = retrieveInt(e.getSource()); - int index = e.getIndex().solution(); - int character = e.getValue().solution() - SymbolicStringConstraintsGeneral.MIN_CHAR; + int index = e.getIndex().solutionInt(); + int character = e.getValue().solutionInt() - SymbolicStringConstraintsGeneral.MIN_CHAR; int clause[] = new int [1]; clause[0] = vector1 + index * SymbolicStringConstraintsGeneral.DIFF_CHAR + character; //printClause(clause); @@ -411,7 +411,7 @@ private static boolean handleEdgeCharAt (EdgeCharAt e) throws ContradictionExcep else { //throw new RuntimeException ("Unexpected"); String constantString = e.getSource().getSolution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); //int character = e.getValue().solution() - SymbolicStringConstraintsSAT.MIN_CHAR; if (constantString.charAt(index) != (char) e.getValue().solution()) { return false; @@ -1347,7 +1347,7 @@ private static void handleEdgeIndexof (EdgeIndexOf e) throws ContradictionExcept int vectorLengthOfSource = lengthOfSource * SymbolicStringConstraintsGeneral.DIFF_CHAR; int vectorLengthOfDest = lengthOfDest * SymbolicStringConstraintsGeneral.DIFF_CHAR; - int pos = e.getIndex().solution(); + int pos = e.getIndex().solutionInt(); if (pos > -1) { int vectorPos = pos * SymbolicStringConstraintsGeneral.DIFF_CHAR; //println ("[handleEdgeIndexOf] start..."); @@ -1373,7 +1373,7 @@ else if (!e.getSource().isConstant()) { int vector1 = retrieveInt(e.getSource()); int length = e.getSource().getLength(); String constant = e.getDest().getSolution(); - int position = e.getIndex().solution(); + int position = e.getIndex().solutionInt(); if (position >= 0) { //The string should be found at position int clause[] = new int [1]; @@ -1408,7 +1408,7 @@ else if (!e.getDest().isConstant()) { int vector2 = retrieveInt(e.getDest()); String constantSource = e.getSource().getSolution(); //println ("[handleEdgeIndexof] constantSource: " + constantSource); - int pos = e.getIndex().solution(); + int pos = e.getIndex().solutionInt(); if (pos != -1) { //println ("[handleEdgeIndexOf] pos = " + pos); List clauses = new ArrayList(); diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToZ3.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToZ3.java index 8325b7e..b6a77e5 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToZ3.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToZ3.java @@ -18,6 +18,16 @@ package gov.nasa.jpf.symbc.string.translate; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.logging.Logger; + +import cvc3.Expr; +import cvc3.FlagsMut; import gov.nasa.jpf.symbc.numeric.Comparator; import gov.nasa.jpf.symbc.numeric.IntegerConstant; import gov.nasa.jpf.symbc.numeric.IntegerExpression; @@ -25,8 +35,6 @@ import gov.nasa.jpf.symbc.numeric.LogicalORLinearIntegerConstraints; import gov.nasa.jpf.symbc.numeric.PathCondition; import gov.nasa.jpf.symbc.numeric.SymbolicConstraintsGeneral; -import gov.nasa.jpf.symbc.numeric.SymbolicInteger; -import gov.nasa.jpf.symbc.string.StringUtility; import gov.nasa.jpf.symbc.string.SymbolicStringConstraintsGeneral; import gov.nasa.jpf.symbc.string.graph.Edge; import gov.nasa.jpf.symbc.string.graph.EdgeChar; @@ -53,78 +61,59 @@ import gov.nasa.jpf.symbc.string.graph.EdgeTrimEqual; import gov.nasa.jpf.symbc.string.graph.StringGraph; import gov.nasa.jpf.symbc.string.graph.Vertex; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import javax.management.RuntimeErrorException; - -import org.sat4j.core.VecInt; -import org.sat4j.minisat.SolverFactory; -import org.sat4j.specs.ContradictionException; -import org.sat4j.specs.IProblem; -import org.sat4j.specs.ISolver; -import org.sat4j.specs.TimeoutException; - -import cvc3.Expr; -import cvc3.ExprMut; -import cvc3.FlagsMut; -import cvc3.QueryResult; -import cvc3.SatResult; -import cvc3.TypeMut; -import cvc3.ValidityChecker; +import gov.nasa.jpf.util.LogManager; public class TranslateToZ3 { - + static Logger logger = LogManager.getLogger("TranslateToZ3"); + protected static BVExpr expr; - protected static FlagsMut flags = null; + protected static FlagsMut flags = null; /* This number can be calculated beforehand */ private static final int MAXVAR = 100000; /* Size of string */ private static final int MAX_SIZE_OF_STRINGS = 100; - + private static Map map; private static int vectorOffset; - + private static int varIndex; - - //public static int totalTiming = 0; - + + // public static int totalTiming = 0; + private static boolean printClauses = true; - private static boolean logging = true; - + private static SymbolicConstraintsGeneral scg; - + private static PathCondition global_pc; - + private static Z3Interface z3Interface; - - private static final int MAX_ITERATIONS = 100; //number of symbolic string expansions to try - private static int remainingIterations = MAX_ITERATIONS; //quick fix to prevent stack overflows - - //most sign, first letter - public static boolean isSat (StringGraph g, PathCondition pc) { + + private static final int MAX_ITERATIONS = 100; // number of symbolic string + // expansions to try + private static int remainingIterations = MAX_ITERATIONS; // quick fix to + // prevent stack + // overflows + + // most sign, first letter + public static boolean isSat(StringGraph g, PathCondition pc) { remainingIterations--; - if(remainingIterations < 0) { + if (remainingIterations < 0) { remainingIterations = MAX_ITERATIONS; -// println("no more iterations remains"); + // println("no more iterations remains"); return false; } - -// System.out.println("#STRING-Z3 solving new graph:" + g); + + // System.out.println("#STRING-Z3 solving new graph:" + g); /* check if there was a timeout */ SymbolicStringConstraintsGeneral.checkTimeOut(); - //println ("[isSat] graph after preprocessing: " + g.toDot()); + // println ("[isSat] graph after preprocessing: " + g.toDot()); global_pc = pc; - if (scg == null) scg = new SymbolicConstraintsGeneral(); + if (scg == null) + scg = new SymbolicConstraintsGeneral(); expr = null; - //println ("[isSat] Bitvector: PC passed on: " + pc.header); + // println ("[isSat] Bitvector: PC passed on: " + pc.header); map = new HashMap(); - + if (z3Interface == null) { try { z3Interface = new Z3Interface(); @@ -132,208 +121,194 @@ public static boolean isSat (StringGraph g, PathCondition pc) { throw new RuntimeException("Could not load up z3\nMake sure the Z3 binary is in lib directory"); } } - - - //println ("[isSat] Walking through the edges"); - for (Edge e: g.getEdges()) { + + // println ("[isSat] Walking through the edges"); + for (Edge e : g.getEdges()) { if (e instanceof EdgeStartsWith) { - handleEdgeStartsWith ((EdgeStartsWith) e); - } - else if (e instanceof EdgeNotStartsWith) { + handleEdgeStartsWith((EdgeStartsWith) e); + } else if (e instanceof EdgeNotStartsWith) { handleEdgeNotStartsWith((EdgeNotStartsWith) e); - } - else if (e instanceof EdgeEqual) { - handleEdgeEqual ((EdgeEqual) e); - } - else if (e instanceof EdgeNotEqual) { + } else if (e instanceof EdgeEqual) { + handleEdgeEqual((EdgeEqual) e); + } else if (e instanceof EdgeNotEqual) { handleEdgeNotEqual((EdgeNotEqual) e); - } - else if (e instanceof EdgeTrimEqual) { + } else if (e instanceof EdgeTrimEqual) { handleEdgeTrim((EdgeTrimEqual) e); - } - else if (e instanceof EdgeCharAt) { + } else if (e instanceof EdgeCharAt) { handleEdgeCharAt((EdgeCharAt) e); - } - else if (e instanceof EdgeNotCharAt) { + } else if (e instanceof EdgeNotCharAt) { handleEdgeNotCharAt((EdgeNotCharAt) e); - } - else if (e instanceof EdgeConcat) { + } else if (e instanceof EdgeConcat) { handleEdgeConcat((EdgeConcat) e); - } - else if (e instanceof EdgeContains) { + } else if (e instanceof EdgeContains) { handleEdgeContains((EdgeContains) e); - } - else if (e instanceof EdgeEndsWith) { + } else if (e instanceof EdgeEndsWith) { handleEdgeEndsWith((EdgeEndsWith) e); - } - else if (e instanceof EdgeIndexOf) { + } else if (e instanceof EdgeIndexOf) { handleEdgeIndexOf((EdgeIndexOf) e); - } - else if (e instanceof EdgeIndexOfChar) { + } else if (e instanceof EdgeIndexOfChar) { handleEdgeIndexOfChar((EdgeIndexOfChar) e); - } - else if (e instanceof EdgeLastIndexOfChar) { + } else if (e instanceof EdgeLastIndexOfChar) { handleEdgeLastIndexOfChar((EdgeLastIndexOfChar) e); - } - else if (e instanceof EdgeLastIndexOfChar2) { + } else if (e instanceof EdgeLastIndexOfChar2) { handleEdgeLastIndexOfChar2((EdgeLastIndexOfChar2) e); - } - else if (e instanceof EdgeIndexOf2) { - //println ("[isSat] EdgeIndexOf2"); + } else if (e instanceof EdgeIndexOf2) { + // println ("[isSat] EdgeIndexOf2"); handleEdgeIndexOf2((EdgeIndexOf2) e); - } - else if (e instanceof EdgeIndexOfChar2) { - //println ("[isSat] EdgeIndexOfChar2"); + } else if (e instanceof EdgeIndexOfChar2) { + // println ("[isSat] EdgeIndexOfChar2"); handleEdgeIndexOfChar2((EdgeIndexOfChar2) e); - } - else if (e instanceof EdgeNotContains) { + } else if (e instanceof EdgeNotContains) { handleEdgeNotContains((EdgeNotContains) e); - } - else if (e instanceof EdgeNotEndsWith) { + } else if (e instanceof EdgeNotEndsWith) { handleEdgeNotEndsWith((EdgeNotEndsWith) e); - } - else if (e instanceof EdgeSubstring1Equal) { + } else if (e instanceof EdgeSubstring1Equal) { handleEdgeSubstring1Equal((EdgeSubstring1Equal) e); - } - else if (e instanceof EdgeSubstring2Equal) { + } else if (e instanceof EdgeSubstring2Equal) { handleEdgeSubstring2Equal((EdgeSubstring2Equal) e); - } - else if (e instanceof EdgeReplaceCharChar) { + } else if (e instanceof EdgeReplaceCharChar) { handleEdgeReplaceCharChar((EdgeReplaceCharChar) e); - } - else { + } else { throw new RuntimeException("Edge not supported: " + e.getClass().toString()); } - if(expr != null) { - //println ("[isSat] expr: " + expr.toString()); + if (expr != null) { + // println ("[isSat] expr: " + expr.toString()); } } - //println ("[isSat] Done walking through the edges"); - /* TODO: Remove*/ - if (expr == null) return true; - //println(expr.toString()); - //vc.loadFile(fileName); - //vc.push(); - //long timing = System.currentTimeMillis(); - - - //return true; - //SatResult result = vc.checkUnsat(expr); + // println ("[isSat] Done walking through the edges"); + /* TODO: Remove */ + if (expr == null) + return true; + // println(expr.toString()); + // vc.loadFile(fileName); + // vc.push(); + // long timing = System.currentTimeMillis(); + + // return true; + // SatResult result = vc.checkUnsat(expr); try { - //println ("[isSat] Starting up Z3..."); + // println ("[isSat] Starting up Z3..."); z3Interface = new Z3Interface(); - //println ("[isSat] started, sending message..."); + // println ("[isSat] started, sending message..."); z3Interface.sendMessage(getSMTLibMsg()); - //println ("[isSat] Done"); + // println ("[isSat] Done"); } catch (IOException ex) { throw new RuntimeException("Could not send z3 message: " + ex.getMessage()); } - //System.out.println("Solution: " + z3Interface.getAns()); - //totalTiming += System.currentTimeMillis() - timing; + // System.out.println("Solution: " + z3Interface.getAns()); + // totalTiming += System.currentTimeMillis() - timing; if (z3Interface.sat == false) { - //println ("[isSat] Current solutions is unsat, extending lengts"); - LogicalORLinearIntegerConstraints loic = new LogicalORLinearIntegerConstraints(); - for (Vertex v: g.getVertices()) { - if (!v.getName().startsWith("CHAR")) - loic.addToList(new LinearIntegerConstraint(v.getSymbolicLength(), Comparator.NE, new IntegerConstant(v.getSymbolicLength().solution()))); - } - for (Edge e: g.getEdges()) { - if (e instanceof EdgeChar) { - EdgeChar eca = (EdgeChar) e; - loic.addToList(new LinearIntegerConstraint(eca.getIndex(), Comparator.NE, new IntegerConstant(eca.getIndex().solution()))); - loic.addToList(new LinearIntegerConstraint(eca.getValue(), Comparator.NE, new IntegerConstant(eca.getValue().solution()))); - } - else if (e instanceof EdgeIndexOf) { - EdgeIndexOf eio = (EdgeIndexOf) e; - loic.addToList(new LinearIntegerConstraint(eio.getIndex(), Comparator.NE, new IntegerConstant(eio.getIndex().solution()))); - } - else if (e instanceof EdgeIndexOfChar) { - EdgeIndexOfChar eio = (EdgeIndexOfChar) e; - loic.addToList(new LinearIntegerConstraint(eio.getIndex(), Comparator.NE, new IntegerConstant(eio.getIndex().solution()))); + // println ("[isSat] Current solutions is unsat, extending lengts"); + LogicalORLinearIntegerConstraints loic = new LogicalORLinearIntegerConstraints(); + for (Vertex v : g.getVertices()) { + if (!v.getName().startsWith("CHAR")) + loic.addToList(new LinearIntegerConstraint(v.getSymbolicLength(), Comparator.NE, + new IntegerConstant(v.getSymbolicLength().solution()))); + } + for (Edge e : g.getEdges()) { + if (e instanceof EdgeChar) { + EdgeChar eca = (EdgeChar) e; + loic.addToList(new LinearIntegerConstraint(eca.getIndex(), Comparator.NE, + new IntegerConstant(eca.getIndex().solution()))); + loic.addToList(new LinearIntegerConstraint(eca.getValue(), Comparator.NE, + new IntegerConstant(eca.getValue().solution()))); + } else if (e instanceof EdgeIndexOf) { + EdgeIndexOf eio = (EdgeIndexOf) e; + loic.addToList(new LinearIntegerConstraint(eio.getIndex(), Comparator.NE, + new IntegerConstant(eio.getIndex().solution()))); + } else if (e instanceof EdgeIndexOfChar) { + EdgeIndexOfChar eio = (EdgeIndexOfChar) e; + loic.addToList(new LinearIntegerConstraint(eio.getIndex(), Comparator.NE, + new IntegerConstant(eio.getIndex().solution()))); IntegerExpression charSought = eio.getIndex().getExpression(); - loic.addToList(new LinearIntegerConstraint(charSought, Comparator.NE, new IntegerConstant(charSought.solution()))); - } - else if (e instanceof EdgeLastIndexOfChar) { - EdgeLastIndexOfChar eio = (EdgeLastIndexOfChar) e; - loic.addToList(new LinearIntegerConstraint(eio.getIndex(), Comparator.NE, new IntegerConstant(eio.getIndex().solution()))); - } - else if (e instanceof EdgeLastIndexOfChar2) { - EdgeLastIndexOfChar2 eio = (EdgeLastIndexOfChar2) e; - loic.addToList(new LinearIntegerConstraint(eio.getIndex(), Comparator.NE, new IntegerConstant(eio.getIndex().solution()))); - loic.addToList(new LinearIntegerConstraint(eio.getIndex().getMinDist(), Comparator.NE, new IntegerConstant(eio.getIndex().getMinDist().solution()))); - } - else if (e instanceof EdgeIndexOf2) { - EdgeIndexOf2 eio = (EdgeIndexOf2) e; - loic.addToList(new LinearIntegerConstraint(eio.getIndex(), Comparator.NE, new IntegerConstant(eio.getIndex().solution()))); - loic.addToList(new LinearIntegerConstraint(eio.getIndex().getMinIndex(), Comparator.NE, new IntegerConstant(eio.getIndex().getMinIndex().solution()))); - } - else if (e instanceof EdgeIndexOfChar2) { - EdgeIndexOfChar2 eio = (EdgeIndexOfChar2) e; - loic.addToList(new LinearIntegerConstraint(eio.getIndex(), Comparator.NE, new IntegerConstant(eio.getIndex().solution()))); - loic.addToList(new LinearIntegerConstraint(eio.getIndex().getMinDist(), Comparator.NE, new IntegerConstant(eio.getIndex().getMinDist().solution()))); - } - else if (e instanceof EdgeSubstring1Equal) { - EdgeSubstring1Equal es1e = (EdgeSubstring1Equal) e; - if (es1e.getArgument1Symbolic() != null) { - loic.addToList(new LinearIntegerConstraint(es1e.getArgument1Symbolic(), Comparator.NE, new IntegerConstant(es1e.getArgument1Symbolic().solution()))); - } - } - else if (e instanceof EdgeSubstring2Equal) { - EdgeSubstring2Equal es2e = (EdgeSubstring2Equal) e; - if (es2e.getSymbolicArgument1() != null) { - loic.addToList(new LinearIntegerConstraint(es2e.getSymbolicArgument1(), Comparator.NE, new IntegerConstant(es2e.getSymbolicArgument1().solution()))); - } - if (es2e.getSymbolicArgument2() != null) { - loic.addToList(new LinearIntegerConstraint(es2e.getSymbolicArgument2(), Comparator.NE, new IntegerConstant(es2e.getSymbolicArgument2().solution()))); - } - } - } - //println ("[isSat] loic: " + loic); - pc._addDet(loic); - //println ("[isSat] firing up integer constraint solver"); - if (scg.isSatisfiable(pc)) { - //println ("[isSat] integer constriant solver found it to be sat, solving..."); + loic.addToList(new LinearIntegerConstraint(charSought, Comparator.NE, + new IntegerConstant(charSought.solution()))); + } else if (e instanceof EdgeLastIndexOfChar) { + EdgeLastIndexOfChar eio = (EdgeLastIndexOfChar) e; + loic.addToList(new LinearIntegerConstraint(eio.getIndex(), Comparator.NE, + new IntegerConstant(eio.getIndex().solution()))); + } else if (e instanceof EdgeLastIndexOfChar2) { + EdgeLastIndexOfChar2 eio = (EdgeLastIndexOfChar2) e; + loic.addToList(new LinearIntegerConstraint(eio.getIndex(), Comparator.NE, + new IntegerConstant(eio.getIndex().solution()))); + loic.addToList(new LinearIntegerConstraint(eio.getIndex().getMinDist(), Comparator.NE, + new IntegerConstant(eio.getIndex().getMinDist().solution()))); + } else if (e instanceof EdgeIndexOf2) { + EdgeIndexOf2 eio = (EdgeIndexOf2) e; + loic.addToList(new LinearIntegerConstraint(eio.getIndex(), Comparator.NE, + new IntegerConstant(eio.getIndex().solution()))); + loic.addToList(new LinearIntegerConstraint(eio.getIndex().getMinIndex(), Comparator.NE, + new IntegerConstant(eio.getIndex().getMinIndex().solution()))); + } else if (e instanceof EdgeIndexOfChar2) { + EdgeIndexOfChar2 eio = (EdgeIndexOfChar2) e; + loic.addToList(new LinearIntegerConstraint(eio.getIndex(), Comparator.NE, + new IntegerConstant(eio.getIndex().solution()))); + loic.addToList(new LinearIntegerConstraint(eio.getIndex().getMinDist(), Comparator.NE, + new IntegerConstant(eio.getIndex().getMinDist().solution()))); + } else if (e instanceof EdgeSubstring1Equal) { + EdgeSubstring1Equal es1e = (EdgeSubstring1Equal) e; + if (es1e.getArgument1Symbolic() != null) { + loic.addToList(new LinearIntegerConstraint(es1e.getArgument1Symbolic(), Comparator.NE, + new IntegerConstant(es1e.getArgument1Symbolic().solution()))); + } + } else if (e instanceof EdgeSubstring2Equal) { + EdgeSubstring2Equal es2e = (EdgeSubstring2Equal) e; + if (es2e.getSymbolicArgument1() != null) { + loic.addToList(new LinearIntegerConstraint(es2e.getSymbolicArgument1(), Comparator.NE, + new IntegerConstant(es2e.getSymbolicArgument1().solution()))); + } + if (es2e.getSymbolicArgument2() != null) { + loic.addToList(new LinearIntegerConstraint(es2e.getSymbolicArgument2(), Comparator.NE, + new IntegerConstant(es2e.getSymbolicArgument2().solution()))); + } + } + } + // println ("[isSat] loic: " + loic); + pc._addDet(loic); + // println ("[isSat] firing up integer constraint solver"); + if (scg.isSatisfiable(pc)) { + // println ("[isSat] integer constriant solver found it to be + // sat, solving..."); scg.solve(pc); pc.flagSolved = true; - //println ("[isSat] solved PC: " + pc.header); - - return isSat (g, pc); //TODO: Prevent infinite looping - } - else { - //println ("[isSat] With the added constraint, could not be solved"); - + // println ("[isSat] solved PC: " + pc.header); + + return isSat(g, pc); // TODO: Prevent infinite looping + } else { + // println ("[isSat] With the added constraint, could not be + // solved"); + return false; } - } - else if (z3Interface.sat) { - Map ans = z3Interface.getAns(); - //println(model.toString()); - - for (Entry entry: ans.entrySet()) { - int reverseMapKey = Integer.parseInt(entry.getKey().substring(3)); - String vertexName = BVVar.reverseMap.get(reverseMapKey); - String rawData = entry.getValue(); - rawData = fromRawData(rawData); - ////println (vertexName + " = " + rawData); - Vertex v = g.findVertex(vertexName); - if(!v.isConstant()) { - v.setSolution(rawData); - } - } - // System.out.//println("Satisfiable (Invalid)\n"); - return true; - }else{ - return false; - } - - //return true; + } else if (z3Interface.sat) { + Map ans = z3Interface.getAns(); + // println(model.toString()); + + for (Entry entry : ans.entrySet()) { + int reverseMapKey = Integer.parseInt(entry.getKey().substring(3)); + String vertexName = BVVar.reverseMap.get(reverseMapKey); + String rawData = entry.getValue(); + rawData = fromRawData(rawData); + //// println (vertexName + " = " + rawData); + Vertex v = g.findVertex(vertexName); + if (!v.isConstant()) { + v.setSolution(rawData); + } + } + // System.out.//println("Satisfiable (Invalid)\n"); + return true; + } else { + return false; + } + + // return true; } - private static String fromRawData (String data) { - StringBuilder result = new StringBuilder (); + private static String fromRawData(String data) { + StringBuilder result = new StringBuilder(); StringBuilder word = new StringBuilder(); int count = 0; - //Skip "0bin" + // Skip "0bin" for (int i = 0; i < data.length(); i++) { if (count == 8) { result.append((char) Integer.parseInt(word.toString(), 2)); @@ -346,134 +321,123 @@ private static String fromRawData (String data) { result.append((char) Integer.parseInt(word.toString(), 2)); return result.toString(); } - - private static BVExpr startsWith (Edge e) { + + private static BVExpr startsWith(Edge e) { if (!e.getSource().isConstant() && !e.getDest().isConstant()) { - //println ("startsWith Branch 1"); - BVExpr source = getBVExpr (e.getSource()); - BVExpr dest = getBVExpr (e.getDest()); - - BVExpr temp = new BVExtract (source, e.getSource().getLength() * 8 - 1, (e.getSource().getLength() - e.getDest().getLength() + 1) * 8 - 8); + // println ("startsWith Branch 1"); + BVExpr source = getBVExpr(e.getSource()); + BVExpr dest = getBVExpr(e.getDest()); + + BVExpr temp = new BVExtract(source, e.getSource().getLength() * 8 - 1, + (e.getSource().getLength() - e.getDest().getLength() + 1) * 8 - 8); return (new BVEq(temp, dest)); - - } - else if (!e.getSource().isConstant()) { - //println ("startsWith Branch 2 " + e); + + } else if (!e.getSource().isConstant()) { + // println ("startsWith Branch 2 " + e); BVExpr source = getBVExpr(e.getSource()); String constant = e.getDest().getSolution(); - //println ("[startsWith] constant: " + constant); + // println ("[startsWith] constant: " + constant); BVExpr lit = null; for (int i = 0; i < constant.length(); i++) { - BVExpr temp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, (e.getSource().getLength() - i) * 8 - 8); + BVExpr temp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, + (e.getSource().getLength() - i) * 8 - 8); char character = constant.charAt(i); if (lit == null) { lit = new BVEq(temp, new BVConst(character)); - } - else { + } else { lit = new BVAnd(lit, new BVEq(temp, new BVConst(character))); } } - //println ("[startsWith] returning: " + lit); + // println ("[startsWith] returning: " + lit); return (lit); - } - else if (!e.getDest().isConstant()) { - //println ("startsWith Branch 3 " + e); + } else if (!e.getDest().isConstant()) { + // println ("startsWith Branch 3 " + e); BVExpr dest = getBVExpr(e.getDest()); String constant = e.getSource().getSolution(); BVExpr lit = null; for (int i = 0; i < e.getDest().getLength(); i++) { - BVExpr temp = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, (e.getDest().getLength() - i) * 8 - 8); + BVExpr temp = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, + (e.getDest().getLength() - i) * 8 - 8); char character = constant.charAt(i); - lit = and(lit, new BVEq (temp, new BVConst(character))); - } - /*for (int j = 0; j < constant.length(); j++) { - BVExpr lit = null; - for (int i = 0; i <= j; i++) { - BVExpr temp = new BVExtract(dest, (e.getSource().getLength() - i) * 8 - 1, (e.getSource().getLength() - i) * 8 - 8); - char character = constant.charAt(i); - if (lit == null) { - lit = new BVEq (temp, new BVConst(character)); - } - else { - lit = new BVAnd (lit, new BVEq (temp, new BVConst(character))); - } - } - if (listOfLit == null) { - listOfLit = lit; - } - else { - listOfLit = new BVOr (listOfLit, lit); - } - }*/ + lit = and(lit, new BVEq(temp, new BVConst(character))); + } + /* + * for (int j = 0; j < constant.length(); j++) { BVExpr lit = null; + * for (int i = 0; i <= j; i++) { BVExpr temp = new BVExtract(dest, + * (e.getSource().getLength() - i) * 8 - 1, + * (e.getSource().getLength() - i) * 8 - 8); char character = + * constant.charAt(i); if (lit == null) { lit = new BVEq (temp, new + * BVConst(character)); } else { lit = new BVAnd (lit, new BVEq + * (temp, new BVConst(character))); } } if (listOfLit == null) { + * listOfLit = lit; } else { listOfLit = new BVOr (listOfLit, lit); + * } } + */ return (lit); - } - else { + } else { String sourceConstant = e.getSource().getSolution(); String destConstant = e.getDest().getSolution(); - //println ("[startsWith] sourceConstant: " + sourceConstant); - //println ("[startsWith] destConstant: " + destConstant); - + // println ("[startsWith] sourceConstant: " + sourceConstant); + // println ("[startsWith] destConstant: " + destConstant); + if (sourceConstant.startsWith(destConstant)) { - return new BVTrue (); - } - else { + return new BVTrue(); + } else { return new BVFalse(); } } - //println ("[startsWith] returning null: " + e.toString()); - //return null; + // println ("[startsWith] returning null: " + e.toString()); + // return null; } - - private static void handleEdgeStartsWith (EdgeStartsWith e) { - post (startsWith(e)); + + private static void handleEdgeStartsWith(EdgeStartsWith e) { + post(startsWith(e)); } - - private static void handleEdgeNotStartsWith (EdgeNotStartsWith e) { - if (e.getSource().getLength() < e.getDest().getLength()) return; - post (new BVNot(startsWith(e))); + + private static void handleEdgeNotStartsWith(EdgeNotStartsWith e) { + if (e.getSource().getLength() < e.getDest().getLength()) + return; + post(new BVNot(startsWith(e))); } - - private static void handleEdgeReplaceCharChar (EdgeReplaceCharChar e) { - BVExpr source = getBVExpr (e.getSource()); - BVExpr dest = getBVExpr (e.getDest()); - + + private static void handleEdgeReplaceCharChar(EdgeReplaceCharChar e) { + BVExpr source = getBVExpr(e.getSource()); + BVExpr dest = getBVExpr(e.getDest()); + BVExpr setOflit = null; BVExpr lit; - //println ("[handleEdgeReplaceCharChar] e.getSource().getLength(): " + e.getSource().getLength()); - //if s[i] == toReplace then d[i] == replacedChar otherwise s[i] == d[i] + // println ("[handleEdgeReplaceCharChar] e.getSource().getLength(): " + + // e.getSource().getLength()); + // if s[i] == toReplace then d[i] == replacedChar otherwise s[i] == d[i] for (int i = 1; i <= e.getSource().getLength(); i++) { BVExpr extSrc = new BVExtract(source, i * 8 - 1, i * 8 - 8); BVExpr extDst = new BVExtract(dest, i * 8 - 1, i * 8 - 8); - lit = new BVITE( - new BVEq(extSrc, new BVConst(e.getC1())), - new BVEq(extDst, new BVConst(e.getC2())), - new BVEq(extSrc,extDst)); - setOflit = and (setOflit, lit); + lit = new BVITE(new BVEq(extSrc, new BVConst(e.getC1())), new BVEq(extDst, new BVConst(e.getC2())), + new BVEq(extSrc, extDst)); + setOflit = and(setOflit, lit); } - //println ("[handleEdgeReplaceCharChar] setOflit: " + setOflit); - post (setOflit); - + // println ("[handleEdgeReplaceCharChar] setOflit: " + setOflit); + post(setOflit); + setOflit = null; for (int i = 1; i <= e.getSource().getLength(); i++) { lit = new BVNot(new BVEq(new BVExtract(dest, i * 8 - 1, i * 8 - 8), new BVConst(e.getC1()))); - setOflit = and (setOflit, lit); + setOflit = and(setOflit, lit); } - post (setOflit); + post(setOflit); } - - private static BVExpr endsWith (Edge e) { - //println ("endsWith entered"); + + private static BVExpr endsWith(Edge e) { + // println ("endsWith entered"); if (!e.getSource().isConstant() && !e.getDest().isConstant()) { - //println ("endsWith branch 1"); - BVExpr source = getBVExpr (e.getSource()); - BVExpr dest = getBVExpr (e.getDest()); - + // println ("endsWith branch 1"); + BVExpr source = getBVExpr(e.getSource()); + BVExpr dest = getBVExpr(e.getDest()); + BVExpr temp = new BVExtract(source, e.getDest().getLength() * 8 - 1, 0); return (new BVEq(temp, dest)); - - } - else if (!e.getSource().isConstant()) { - //println ("endsWith branch 2"); + + } else if (!e.getSource().isConstant()) { + // println ("endsWith branch 2"); BVExpr source = getBVExpr(e.getSource()); String constant = e.getDest().getSolution(); BVExpr lit = null; @@ -482,74 +446,64 @@ else if (!e.getSource().isConstant()) { char character = constant.charAt(i); if (lit == null) { lit = new BVEq(temp, new BVConst(character)); - } - else { + } else { lit = new BVAnd(lit, new BVEq(temp, new BVConst(character))); } } return (lit); - } - else if (!e.getDest().isConstant()) { - //println ("endsWith branch 3"); + } else if (!e.getDest().isConstant()) { + // println ("endsWith branch 3"); BVExpr dest = getBVExpr(e.getDest()); String constant = e.getSource().getSolution(); BVExpr lit = null; for (int i = 0; i < e.getDest().getLength(); i++) { - BVExpr temp = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, (e.getDest().getLength() - i) * 8 - 8); + BVExpr temp = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, + (e.getDest().getLength() - i) * 8 - 8); char character = constant.charAt(i + (constant.length() - e.getDest().getLength())); - lit = and (lit, new BVEq (temp, new BVConst (character))); - } - /*for (int j = 0; j < constant.length(); j++) { - BVExpr lit = null; - for (int i = constant.length() - 1; i >= constant.length() - j - 1; i--) { - BVExpr temp = new BVExtract(dest, (constant.length() - i) * 8 - 1, (constant.length() - i) * 8 - 8); - char character = constant.charAt(i); - if (lit == null) { - lit = new BVEq(temp, new BVConst(character)); - } - else { - lit = new BVAnd(lit, new BVEq(temp, new BVConst(character))); - } - - } - if (listOfLit == null) { - listOfLit = lit; - } - else { - listOfLit = new BVOr(listOfLit, lit); - } - }*/ + lit = and(lit, new BVEq(temp, new BVConst(character))); + } + /* + * for (int j = 0; j < constant.length(); j++) { BVExpr lit = null; + * for (int i = constant.length() - 1; i >= constant.length() - j - + * 1; i--) { BVExpr temp = new BVExtract(dest, (constant.length() - + * i) * 8 - 1, (constant.length() - i) * 8 - 8); char character = + * constant.charAt(i); if (lit == null) { lit = new BVEq(temp, new + * BVConst(character)); } else { lit = new BVAnd(lit, new BVEq(temp, + * new BVConst(character))); } + * + * } if (listOfLit == null) { listOfLit = lit; } else { listOfLit = + * new BVOr(listOfLit, lit); } } + */ return (lit); } else { String constant1 = e.getSource().getSolution(); String constant2 = e.getDest().getSolution(); if (constant1.endsWith(constant2)) { return new BVTrue(); - } - else { + } else { return new BVFalse(); } } - //println ("endsWith no branch"); - //return null; + // println ("endsWith no branch"); + // return null; } - - private static void handleEdgeEndsWith (EdgeEndsWith e) { - //println ("handleEdgeEndsWith " + e); - post (endsWith(e)); + + private static void handleEdgeEndsWith(EdgeEndsWith e) { + // println ("handleEdgeEndsWith " + e); + post(endsWith(e)); } - - private static void handleEdgeNotEndsWith (EdgeNotEndsWith e) { - //println ("handleEdgeNotEndsWith"); + + private static void handleEdgeNotEndsWith(EdgeNotEndsWith e) { + // println ("handleEdgeNotEndsWith"); if (e.getDest().getLength() > e.getSource().getLength()) { return; } - post (new BVNot(endsWith(e))); + post(new BVNot(endsWith(e))); } - - private static BVExpr equal (Edge e) { - //println ("[equal] e: " + e.toString()); + + private static BVExpr equal(Edge e) { + // println ("[equal] e: " + e.toString()); if (e.getSource().getLength() != e.getDest().getLength()) { return new BVFalse(); } @@ -557,28 +511,26 @@ private static BVExpr equal (Edge e) { BVExpr source = getBVExpr(e.getSource()); BVExpr dest = getBVExpr(e.getDest()); return new BVEq(source, dest); - } - else if (!e.getSource().isConstant()) { + } else if (!e.getSource().isConstant()) { BVExpr source = getBVExpr(e.getSource()); String constant = e.getDest().getSolution(); BVExpr lit = null; for (int i = 0; i < constant.length(); i++) { char c = constant.charAt(i); - BVExpr temp = new BVExtract(source, (constant.length() -i) * 8 - 1, (constant.length() -i) * 8 - 8); + BVExpr temp = new BVExtract(source, (constant.length() - i) * 8 - 1, (constant.length() - i) * 8 - 8); BVExpr cons = new BVConst(c); - lit = and (lit, new BVEq (temp, cons)); + lit = and(lit, new BVEq(temp, cons)); } return lit; - } - else if (!e.getDest().isConstant()) { + } else if (!e.getDest().isConstant()) { BVExpr dest = getBVExpr(e.getDest()); String constant = e.getSource().getSolution(); BVExpr lit = null; for (int i = 0; i < constant.length(); i++) { char c = constant.charAt(i); - BVExpr temp = new BVExtract (dest, (constant.length() -i) * 8 - 1, (constant.length() -i) * 8 - 8); + BVExpr temp = new BVExtract(dest, (constant.length() - i) * 8 - 1, (constant.length() - i) * 8 - 8); BVExpr cons = new BVConst(c); - lit = and (lit, new BVEq (temp, cons)); + lit = and(lit, new BVEq(temp, cons)); } return lit; @@ -591,104 +543,104 @@ else if (!e.getDest().isConstant()) { return new BVFalse(); } } - //return null; + // return null; } - - - private static void handleEdgeNotEqual (EdgeNotEqual e) { + + private static void handleEdgeNotEqual(EdgeNotEqual e) { if (e.getSource().getLength() != e.getDest().getLength()) { return; } - post (new BVNot(equal(e))); + post(new BVNot(equal(e))); } - - private static void handleEdgeEqual (EdgeEqual e) { - //println ("[handleEdgeEqual] entered: " + e.toString()); - post (equal(e)); + + private static void handleEdgeEqual(EdgeEqual e) { + // println ("[handleEdgeEqual] entered: " + e.toString()); + post(equal(e)); } - - private static void handleEdgeTrim (EdgeTrimEqual e) { - println ("[handleEdgeTrim] entered handleEdgeTrim " + e); + + private static void handleEdgeTrim(EdgeTrimEqual e) { + logger.info("[handleEdgeTrim] entered handleEdgeTrim " + e); if (e.getSource().getLength() == e.getDest().getLength()) { - println ("[handleEdgeTrim] 1. posting: " + equal(e)); - post (equal(e)); + logger.info("[handleEdgeTrim] 1. posting: " + equal(e)); + post(equal(e)); return; } - + if (!e.getSource().isConstant() && !e.getDest().isConstant()) { - //println ("[handleEdgeTrim] branch 1"); + // println ("[handleEdgeTrim] branch 1"); BVExpr source = getBVExpr(e.getSource()); BVExpr dest = getBVExpr(e.getDest()); - + int diff = e.getSource().getLength() - e.getDest().getLength() + 1; - + BVExpr listOflit = null; for (int i = 0; i < diff; i++) { BVExpr lit = null; BVExpr sourceTemp, destTemp; for (int j = 0; j < i; j++) { - sourceTemp = new BVExtract(source, (e.getSource().getLength() - j) * 8 - 1, (e.getSource().getLength() - j) * 8 - 8); - lit = and(lit, new BVEq (sourceTemp, new BVConst (' '))); + sourceTemp = new BVExtract(source, (e.getSource().getLength() - j) * 8 - 1, + (e.getSource().getLength() - j) * 8 - 8); + lit = and(lit, new BVEq(sourceTemp, new BVConst(' '))); } - sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, (e.getSource().getLength() - i - e.getDest().getLength()) * 8 - 1 + 1); - //destTemp = new BVExtract(dest, (e.getDest().getLength() - (j - i)) * 8 - 1, (e.getDest().getLength() - (j - i)) * 8 - 8); - //println ("[handleEdgeTrim] 2. lit before: " + lit); - lit = and (lit, new BVEq(sourceTemp, dest)); - //println ("[handleEdgeTrim] 2. lit so far: " + lit); + sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, + (e.getSource().getLength() - i - e.getDest().getLength()) * 8 - 1 + 1); + // destTemp = new BVExtract(dest, (e.getDest().getLength() - (j + // - i)) * 8 - 1, (e.getDest().getLength() - (j - i)) * 8 - 8); + // println ("[handleEdgeTrim] 2. lit before: " + lit); + lit = and(lit, new BVEq(sourceTemp, dest)); + // println ("[handleEdgeTrim] 2. lit so far: " + lit); for (int j = i + e.getDest().getLength(); j < e.getSource().getLength(); j++) { - sourceTemp = new BVExtract(source, (e.getSource().getLength() - j) * 8 - 1, (e.getSource().getLength() - j) * 8 - 8); + sourceTemp = new BVExtract(source, (e.getSource().getLength() - j) * 8 - 1, + (e.getSource().getLength() - j) * 8 - 8); lit = and(lit, new BVEq(sourceTemp, new BVConst(' '))); } - listOflit = or (listOflit, lit); + listOflit = or(listOflit, lit); } - //println ("[handleEdgeTrim] 2. posting: " + listOflit); - post (listOflit); - - } - else if (!e.getSource().isConstant()) { - //println ("[handleEdgeTrim] branch 2"); + // println ("[handleEdgeTrim] 2. posting: " + listOflit); + post(listOflit); + + } else if (!e.getSource().isConstant()) { + // println ("[handleEdgeTrim] branch 2"); BVExpr source = getBVExpr(e.getSource()); String constant = e.getDest().getSolution(); int diff = e.getSource().getLength() - e.getDest().getLength() + 1; String allPossiblAnswers[] = new String[diff]; for (int i = 0; i < diff; i++) { - StringBuilder sb = new StringBuilder (); + StringBuilder sb = new StringBuilder(); for (int j = 0; j < i; j++) { - sb.append (" "); + sb.append(" "); } - sb.append (constant); + sb.append(constant); for (int j = i + constant.length(); j < e.getSource().getLength(); j++) { - sb.append (" "); + sb.append(" "); } allPossiblAnswers[i] = sb.toString(); } BVExpr listOfLit = null; - for (String s: allPossiblAnswers) { - //println ("[handleEdgeTrim] possible answer: '" + s + "'"); + for (String s : allPossiblAnswers) { + // println ("[handleEdgeTrim] possible answer: '" + s + "'"); BVExpr lit = null; for (int i = 0; i < s.length(); i++) { - BVExpr temp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, (e.getSource().getLength() - i) * 8 - 8); + BVExpr temp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, + (e.getSource().getLength() - i) * 8 - 8); BVExpr bvconst = new BVConst(s.charAt(i)); - BVExpr toplace = new BVEq (temp, bvconst); + BVExpr toplace = new BVEq(temp, bvconst); if (lit == null) { lit = toplace; - } - else { - lit = new BVAnd (lit, toplace); + } else { + lit = new BVAnd(lit, toplace); } } if (listOfLit == null) { listOfLit = lit; - } - else { + } else { listOfLit = new BVOr(listOfLit, lit); } } - //println ("[handleEdgeTrim] 3. posting: " + listOfLit); - post (listOfLit); - } - else if (!e.getDest().isConstant()) { - //println ("[handleEdgeTrim] branch 3"); + // println ("[handleEdgeTrim] 3. posting: " + listOfLit); + post(listOfLit); + } else if (!e.getDest().isConstant()) { + // println ("[handleEdgeTrim] branch 3"); BVExpr dest = getBVExpr(e.getDest()); String constant = e.getSource().getSolution().trim(); if (e.getDest().getLength() != constant.length()) { @@ -696,46 +648,46 @@ else if (!e.getDest().isConstant()) { } BVExpr lit = null; for (int i = 0; i < constant.length(); i++) { - BVExpr temp = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, (e.getDest().getLength() - i) * 8 - 8); - lit = and (lit, new BVEq(temp, new BVConst(constant.charAt(i)))); + BVExpr temp = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, + (e.getDest().getLength() - i) * 8 - 8); + lit = and(lit, new BVEq(temp, new BVConst(constant.charAt(i)))); } - //println ("[handleEdgeTrim] 4. posting: " + lit); - post (lit); + // println ("[handleEdgeTrim] 4. posting: " + lit); + post(lit); } } - - public static void handleEdgeCharAt (EdgeCharAt e) { + + public static void handleEdgeCharAt(EdgeCharAt e) { if (!e.getSource().isConstant()) { BVExpr eqExpr = prepareEqSymbolicSrc(e); - post (eqExpr); - } - else { + post(eqExpr); + } else { List exps = prepareEqConstantSrc(e); for (BVExpr exp : exps) { post(exp); } } } - + private static void handleEdgeNotCharAt(EdgeNotCharAt e) { if (!e.getSource().isConstant()) { BVExpr eqExpr = prepareEqSymbolicSrc(e); - post (new BVNot(eqExpr)); - + post(new BVNot(eqExpr)); + } else { List exps = prepareEqConstantSrc(e); - - if(exps.size() == 1) { + + if (exps.size() == 1) { BVExpr exp = exps.get(0); post(new BVNot(exp)); - - } else { //apply De Morgan' law + + } else { // apply De Morgan' law BVExpr first = ((BVNot) exps.get(0)).expr; BVExpr second = ((BVNot) exps.get(1)).expr; - + BVOr orExpr = new BVOr(first, second); for (int i = 2; i < exps.size(); i++) { - BVExpr exp = ((BVNot) exps.get(i)).expr; + BVExpr exp = ((BVNot) exps.get(i)).expr; orExpr = new BVOr(exp, orExpr); } post(new BVNot(orExpr)); @@ -745,143 +697,154 @@ private static void handleEdgeNotCharAt(EdgeNotCharAt e) { private static List prepareEqConstantSrc(EdgeChar e) { List exprs = new ArrayList(); - + String constant = e.getSource().getSolution(); - char c = (char) e.getValue().solution(); - int index = e.getIndex().solution(); - if (index > -1) { //char c is present at the string + char c = e.getValue().solutionChar(); + int index = e.getIndex().solutionInt(); + if (index > -1) { // char c is present at the string BVExpr temp1 = new BVConst(constant.charAt(index)); BVExpr temp2 = new BVConst(c); exprs.add(new BVEq(temp1, temp2)); - } - else { //char c is not present at the string + } else { // char c is not present at the string for (int i = 0; i < constant.length(); i++) { BVExpr temp1 = new BVConst(constant.charAt(i)); BVExpr temp2 = new BVConst(c); exprs.add((new BVNot(new BVEq(temp1, temp2)))); } } - + return exprs; } private static BVExpr prepareEqSymbolicSrc(EdgeChar e) { BVExpr source = getBVExpr(e.getSource()); char c = (char) e.getValue().solution(); - int index = e.getIndex().solution(); - BVExpr temp = new BVExtract(source, (e.getSource().getLength() - index) * 8 - 1, (e.getSource().getLength() - index) * 8 - 8); + int index = e.getIndex().solutionInt(); + BVExpr temp = new BVExtract(source, (e.getSource().getLength() - index) * 8 - 1, + (e.getSource().getLength() - index) * 8 - 8); BVExpr cons = new BVConst(c); BVExpr eqExpr = new BVEq(temp, cons); return eqExpr; } - - private static void handleEdgeConcat (EdgeConcat e) { + + private static void handleEdgeConcat(EdgeConcat e) { if (e.getDest().isConstant()) { - //println ("[handleEdgeConcat] dest is constant"); + // println ("[handleEdgeConcat] dest is constant"); if (!e.getSources().get(0).isConstant() && !e.getSources().get(1).isConstant()) { - + String constant = e.getDest().getSolution(); BVExpr source1 = getBVExpr(e.getSources().get(0)); BVExpr source2 = getBVExpr(e.getSources().get(1)); BVExpr lit = null; for (int i = 0; i < e.getSources().get(0).getLength(); i++) { - BVExpr temp = new BVExtract(source1, (e.getSources().get(0).getLength() - i) * 8 - 1, (e.getSources().get(0).getLength() - i) * 8 - 8); + BVExpr temp = new BVExtract(source1, (e.getSources().get(0).getLength() - i) * 8 - 1, + (e.getSources().get(0).getLength() - i) * 8 - 8); BVExpr cons = new BVConst(constant.charAt(i)); - lit = and (lit, new BVEq(temp, cons)); + lit = and(lit, new BVEq(temp, cons)); } for (int i = 0; i < e.getSources().get(1).getLength(); i++) { - BVExpr temp = new BVExtract(source2, (e.getSources().get(1).getLength() - i) * 8 - 1, (e.getSources().get(1).getLength() - i) * 8 - 8); + BVExpr temp = new BVExtract(source2, (e.getSources().get(1).getLength() - i) * 8 - 1, + (e.getSources().get(1).getLength() - i) * 8 - 8); BVExpr cons = new BVConst(constant.charAt(i + e.getSources().get(0).getLength())); - lit = and (lit, new BVEq(temp, cons)); + lit = and(lit, new BVEq(temp, cons)); } post(lit); - } - else if (!e.getSources().get(0).isConstant()) { + } else if (!e.getSources().get(0).isConstant()) { String destConstant = e.getDest().getSolution(); String source2Constant = e.getSources().get(1).getSolution(); BVExpr source1 = getBVExpr(e.getSources().get(0)); - if (!destConstant.endsWith(source2Constant)) throw new RuntimeException("This should not happen"); + if (!destConstant.endsWith(source2Constant)) + throw new RuntimeException("This should not happen"); BVExpr lit = null; for (int i = 0; i < e.getSources().get(0).getLength(); i++) { - BVExpr temp = new BVExtract(source1, (e.getSources().get(0).getLength() - i) * 8 - 1, (e.getSources().get(0).getLength() - i) * 8 - 8); + BVExpr temp = new BVExtract(source1, (e.getSources().get(0).getLength() - i) * 8 - 1, + (e.getSources().get(0).getLength() - i) * 8 - 8); BVExpr cons = new BVConst(destConstant.charAt(i)); - lit = and (lit, new BVEq(temp, cons)); + lit = and(lit, new BVEq(temp, cons)); } - post (lit); - } - else if (!e.getSources().get(1).isConstant()) { + post(lit); + } else if (!e.getSources().get(1).isConstant()) { String destConstant = e.getDest().getSolution(); String source1Constant = e.getSources().get(0).getSolution(); BVExpr source2 = getBVExpr(e.getSources().get(1)); - if (!destConstant.startsWith(source1Constant)) throw new RuntimeException("This should not happen"); + if (!destConstant.startsWith(source1Constant)) + throw new RuntimeException("This should not happen"); BVExpr lit = null; for (int i = e.getSources().get(0).getLength(); i < e.getDest().getLength(); i++) { - BVExpr temp = new BVExtract(source2, (e.getDest().getLength() - i) * 8 - 1, (e.getDest().getLength() - i) * 8 - 8); + BVExpr temp = new BVExtract(source2, (e.getDest().getLength() - i) * 8 - 1, + (e.getDest().getLength() - i) * 8 - 8); BVExpr cons = new BVConst(destConstant.charAt(i)); - lit = and (lit, new BVEq(temp, cons)); + lit = and(lit, new BVEq(temp, cons)); } - post (lit); + post(lit); } - - } - else { - //println ("[handleEdgeConcat] dest is NOT constant"); - //e.getDest().isConstant() == false + + } else { + // println ("[handleEdgeConcat] dest is NOT constant"); + // e.getDest().isConstant() == false if (!e.getSources().get(0).isConstant() && !e.getSources().get(1).isConstant()) { - //println ("[handleEdgeConcat] both sources is NOT constant"); + // println ("[handleEdgeConcat] both sources is NOT constant"); BVExpr source1 = getBVExpr(e.getSources().get(0)); BVExpr source2 = getBVExpr(e.getSources().get(1)); BVExpr dest = getBVExpr(e.getDest()); BVExpr lit = null; - BVExpr temp = new BVExtract(dest, (e.getDest().getLength()) * 8 - 1, (e.getDest().getLength() - e.getSources().get(0).getLength() + 1) * 8 - 8); - lit = and (lit, new BVEq(temp, source1)); - //println ("[handleEdgeConcat] " + e.getDest().getLength() + " - " + e.getSources().get(0).getLength()); + BVExpr temp = new BVExtract(dest, (e.getDest().getLength()) * 8 - 1, + (e.getDest().getLength() - e.getSources().get(0).getLength() + 1) * 8 - 8); + lit = and(lit, new BVEq(temp, source1)); + // println ("[handleEdgeConcat] " + e.getDest().getLength() + " + // - " + e.getSources().get(0).getLength()); temp = new BVExtract(dest, (e.getDest().getLength() - e.getSources().get(0).getLength()) * 8 - 1, 0); - lit = and (lit, new BVEq(temp, source2)); + lit = and(lit, new BVEq(temp, source2)); post(lit); - } - else if (!e.getSources().get(0).isConstant()) { + } else if (!e.getSources().get(0).isConstant()) { BVExpr source1 = getBVExpr(e.getSources().get(0)); String source2Cons = e.getSources().get(1).getSolution(); BVExpr dest = getBVExpr(e.getDest()); BVExpr lit = null; for (int i = 0; i < e.getSources().get(0).getLength(); i++) { - BVExpr destTemp = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, (e.getDest().getLength() - i) * 8 - 8); - BVExpr sourceTemp = new BVExtract(source1, (e.getSources().get(0).getLength() - i) * 8 - 1, (e.getSources().get(0).getLength() - i) * 8 - 8); - lit = and (lit, new BVEq(destTemp, sourceTemp)); + BVExpr destTemp = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, + (e.getDest().getLength() - i) * 8 - 8); + BVExpr sourceTemp = new BVExtract(source1, (e.getSources().get(0).getLength() - i) * 8 - 1, + (e.getSources().get(0).getLength() - i) * 8 - 8); + lit = and(lit, new BVEq(destTemp, sourceTemp)); } for (int i = 0; i < source2Cons.length(); i++) { char character = source2Cons.charAt(i); - BVExpr temp = new BVExtract(dest, (e.getDest().getLength() - e.getSources().get(0).getLength() - i) * 8 - 1, (e.getDest().getLength() - e.getSources().get(0).getLength() - i) * 8 - 8); + BVExpr temp = new BVExtract(dest, + (e.getDest().getLength() - e.getSources().get(0).getLength() - i) * 8 - 1, + (e.getDest().getLength() - e.getSources().get(0).getLength() - i) * 8 - 8); BVExpr cons = new BVConst(character); - lit = and (lit, new BVEq(temp, cons)); + lit = and(lit, new BVEq(temp, cons)); } - post (lit); - } - else if (!e.getSources().get(1).isConstant()) { + post(lit); + } else if (!e.getSources().get(1).isConstant()) { String source1Cons = e.getSources().get(0).getSolution(); BVExpr source2 = getBVExpr(e.getSources().get(1)); BVExpr dest = getBVExpr(e.getDest()); BVExpr lit = null; for (int i = 0; i < source1Cons.length(); i++) { char character = source1Cons.charAt(i); - BVExpr temp = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, (e.getDest().getLength() - i) * 8 - 8); + BVExpr temp = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, + (e.getDest().getLength() - i) * 8 - 8); BVExpr cons = new BVConst(character); - lit = and (lit, new BVEq(temp, cons)); + lit = and(lit, new BVEq(temp, cons)); } for (int i = 0; i < e.getSources().get(1).getLength(); i++) { - BVExpr destTemp = new BVExtract(dest, (e.getDest().getLength() - e.getSources().get(0).getLength() - i) * 8 - 1, (e.getDest().getLength() - e.getSources().get(0).getLength() - i) * 8 - 8); - BVExpr source2Temp = new BVExtract(source2, (e.getSources().get(1).getLength() - i) * 8 - 1, (e.getSources().get(1).getLength() - i) * 8 - 8); - lit = and (lit, new BVEq(destTemp, source2Temp)); + BVExpr destTemp = new BVExtract(dest, + (e.getDest().getLength() - e.getSources().get(0).getLength() - i) * 8 - 1, + (e.getDest().getLength() - e.getSources().get(0).getLength() - i) * 8 - 8); + BVExpr source2Temp = new BVExtract(source2, (e.getSources().get(1).getLength() - i) * 8 - 1, + (e.getSources().get(1).getLength() - i) * 8 - 8); + lit = and(lit, new BVEq(destTemp, source2Temp)); } - post (lit); + post(lit); } } } - - private static BVExpr contains (Edge e) { + + private static BVExpr contains(Edge e) { if (!e.getSource().isConstant() && !e.getDest().isConstant()) { - //println ("contains branch 1"); + // println ("contains branch 1"); BVExpr source = getBVExpr(e.getSource()); BVExpr dest = getBVExpr(e.getDest()); int diff = e.getSource().getLength() - e.getDest().getLength(); @@ -889,470 +852,474 @@ private static BVExpr contains (Edge e) { for (int i = 0; i <= diff; i++) { BVExpr lit = null; for (int j = i; j < i + e.getDest().getLength(); j++) { - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - j) * 8 - 1, (e.getSource().getLength() - j) * 8 - 8); - BVExpr destTemp = new BVExtract(dest, (e.getDest().getLength() - (j - i)) * 8 - 1, (e.getDest().getLength() - (j - i)) * 8 - 8); - lit = and (lit, new BVEq(sourceTemp, destTemp)); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - j) * 8 - 1, + (e.getSource().getLength() - j) * 8 - 8); + BVExpr destTemp = new BVExtract(dest, (e.getDest().getLength() - (j - i)) * 8 - 1, + (e.getDest().getLength() - (j - i)) * 8 - 8); + lit = and(lit, new BVEq(sourceTemp, destTemp)); } - listOfLit = or (listOfLit, lit); + listOfLit = or(listOfLit, lit); } return (listOfLit); - } - else if (!e.getSource().isConstant()) { - //println ("contains branch 2"); - //println ("[contains] source not constant"); + } else if (!e.getSource().isConstant()) { + // println ("contains branch 2"); + // println ("[contains] source not constant"); BVExpr source = getBVExpr(e.getSource()); String destCons = e.getDest().getSolution(); int diff = e.getSource().getLength() - destCons.length(); - //println ("[contains] diff: " + diff); + // println ("[contains] diff: " + diff); BVExpr listOfLit = null; for (int i = 0; i <= diff; i++) { BVExpr lit = null; for (int j = i; j < i + destCons.length(); j++) { - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - j) * 8 - 1, (e.getSource().getLength() - j) * 8 - 8); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - j) * 8 - 1, + (e.getSource().getLength() - j) * 8 - 8); BVExpr cons = new BVConst(destCons.charAt(j - i)); - lit = and (lit, new BVEq(sourceTemp, cons)); + lit = and(lit, new BVEq(sourceTemp, cons)); } - listOfLit = or (listOfLit, lit); + listOfLit = or(listOfLit, lit); } return (listOfLit); - } - else if (!e.getDest().isConstant()) { - //println ("contains branch 3"); + } else if (!e.getDest().isConstant()) { + // println ("contains branch 3"); BVExpr dest = getBVExpr(e.getDest()); String sourceCons = e.getSource().getSolution(); - String[] possibleSolutions = new String [e.getSource().getLength() - e.getDest().getLength() + 1]; + String[] possibleSolutions = new String[e.getSource().getLength() - e.getDest().getLength() + 1]; for (int i = 0; i <= e.getSource().getLength() - e.getDest().getLength(); i++) { - possibleSolutions[i] = sourceCons.substring(i, i+e.getDest().getLength()); + possibleSolutions[i] = sourceCons.substring(i, i + e.getDest().getLength()); } BVExpr listOfLit = null; - for (String s: possibleSolutions) { + for (String s : possibleSolutions) { BVExpr lit = null; for (int i = 0; i < s.length(); i++) { - BVExpr temp = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, (e.getDest().getLength() - i) * 8 - 8); + BVExpr temp = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, + (e.getDest().getLength() - i) * 8 - 8); BVExpr cons = new BVConst(sourceCons.charAt(i)); - lit = and (lit, new BVEq(temp, cons)); + lit = and(lit, new BVEq(temp, cons)); } - listOfLit = or (listOfLit, lit); + listOfLit = or(listOfLit, lit); } return (listOfLit); - } - else { + } else { String constant1 = e.getSource().getSolution(); String constant2 = e.getDest().getSolution(); if (constant1.contains(constant2)) { return new BVTrue(); - } - else { + } else { return new BVFalse(); } } - //println ("contains no branch"); - //return null; + // println ("contains no branch"); + // return null; } - - private static void handleEdgeContains (EdgeContains e) { + + private static void handleEdgeContains(EdgeContains e) { if (e.getSource().getLength() == e.getDest().getLength()) { - //println ("[handleEdgeContains] handing over to equals"); - post (equal(e)); + // println ("[handleEdgeContains] handing over to equals"); + post(equal(e)); return; } - post (contains(e)); + post(contains(e)); } - - private static void handleEdgeIndexOf2 (EdgeIndexOf2 e) { + + private static void handleEdgeIndexOf2(EdgeIndexOf2 e) { if (!e.getSource().isConstant() && !e.getDest().isConstant()) { - BVExpr source = getBVExpr (e.getSource()); - BVExpr dest = getBVExpr (e.getDest()); - int index = e.getIndex().solution(); + BVExpr source = getBVExpr(e.getSource()); + BVExpr dest = getBVExpr(e.getDest()); + int index = e.getIndex().solutionInt(); if (index > -1) { BVExpr lit = null; for (int i = index; i < index + e.getDest().getLength(); i++) { - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, (e.getSource().getLength() - i) * 8 - 8); - BVExpr destTemp = new BVExtract(dest, (e.getDest().getLength() - (i - index)) * 8 - 1, (e.getDest().getLength() - (i - index)) * 8 - 8); - lit = and (lit, new BVEq(sourceTemp, destTemp)); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, + (e.getSource().getLength() - i) * 8 - 8); + BVExpr destTemp = new BVExtract(dest, (e.getDest().getLength() - (i - index)) * 8 - 1, + (e.getDest().getLength() - (i - index)) * 8 - 8); + lit = and(lit, new BVEq(sourceTemp, destTemp)); } - post (lit); - } - else { + post(lit); + } else { if (e.getSource().getLength() < e.getDest().getLength()) { return; - } - else if (e.getSource().getLength() == e.getDest().getLength()) { - post (new BVNot(equal(e))); + } else if (e.getSource().getLength() == e.getDest().getLength()) { + post(new BVNot(equal(e))); return; - } - else { - post (new BVNot(contains(e))); //TODO: fix this, it should take into account the minimal distance + } else { + post(new BVNot(contains(e))); // TODO: fix this, it should + // take into account the + // minimal distance } } - } - else if (!e.getSource().isConstant()) { - BVExpr source = getBVExpr (e.getSource()); + } else if (!e.getSource().isConstant()) { + BVExpr source = getBVExpr(e.getSource()); String destCons = e.getDest().getSolution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); if (index > -1) { BVExpr lit = null; for (int i = index; i < index + e.getDest().getLength(); i++) { - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, (e.getSource().getLength() - i) * 8 - 8); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, + (e.getSource().getLength() - i) * 8 - 8); BVExpr cons = new BVConst(destCons.charAt(i - index)); - lit = and (lit, new BVEq(sourceTemp, cons)); + lit = and(lit, new BVEq(sourceTemp, cons)); } - post (lit); - } - else { + post(lit); + } else { if (e.getSource().getLength() < e.getDest().getLength()) { return; - } - else if (e.getSource().getLength() == e.getDest().getLength()) { - post (new BVNot(equal(e))); + } else if (e.getSource().getLength() == e.getDest().getLength()) { + post(new BVNot(equal(e))); return; - } - else { - post (new BVNot(contains(e))); + } else { + post(new BVNot(contains(e))); } } - } - else if (!e.getDest().isConstant()) { + } else if (!e.getDest().isConstant()) { String sourceCons = e.getSource().getSolution(); - + BVExpr dest = getBVExpr(e.getDest()); - int index = e.getIndex().solution(); - + int index = e.getIndex().solutionInt(); + if (index > -1) { String realSolution = sourceCons.substring(index, index + e.getDest().getLength()); BVExpr lit = null; for (int i = 0; i < realSolution.length(); i++) { - BVExpr destExpr = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, (e.getDest().getLength() - i) * 8 - 8); + BVExpr destExpr = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, + (e.getDest().getLength() - i) * 8 - 8); BVExpr cons = new BVConst(realSolution.charAt(i)); - lit = and (lit, new BVEq(destExpr, cons)); + lit = and(lit, new BVEq(destExpr, cons)); } - post (lit); - } - else { + post(lit); + } else { if (e.getSource().getLength() < e.getDest().getLength()) { return; - } - else if (e.getSource().getLength() == e.getDest().getLength()) { - post (new BVNot(equal(e))); + } else if (e.getSource().getLength() == e.getDest().getLength()) { + post(new BVNot(equal(e))); return; - } - else { - post (new BVNot(contains(e))); + } else { + post(new BVNot(contains(e))); } } } } - - private static void handleEdgeIndexOf (EdgeIndexOf e) { - //println ("[handleEdgeIndexOf]"); + + private static void handleEdgeIndexOf(EdgeIndexOf e) { + // println ("[handleEdgeIndexOf]"); if (!e.getSource().isConstant() && !e.getDest().isConstant()) { - //println ("branch 1"); - BVExpr source = getBVExpr (e.getSource()); - BVExpr dest = getBVExpr (e.getDest()); - int index = e.getIndex().solution(); + // println ("branch 1"); + BVExpr source = getBVExpr(e.getSource()); + BVExpr dest = getBVExpr(e.getDest()); + int index = e.getIndex().solutionInt(); if (index > -1) { - //println ("branch 1.1, index: " + index); + // println ("branch 1.1, index: " + index); BVExpr totalLit = null; - //println ("e.getDest().getLength(): " + e.getDest().getLength()); + // println ("e.getDest().getLength(): " + + // e.getDest().getLength()); for (int i = 0; i <= index - e.getDest().getLength(); i++) { BVExpr lit = null; for (int j = 0; j < e.getDest().getLength(); j++) { int totalOffset = i + j; - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - totalOffset) * 8 - 1, (e.getSource().getLength() - totalOffset) * 8 - 8); - BVExpr destTemp = new BVExtract(dest, (e.getDest().getLength() - j) * 8 - 1, (e.getDest().getLength() - j) * 8 - 8); - lit = and (lit, new BVEq(sourceTemp, destTemp)); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - totalOffset) * 8 - 1, + (e.getSource().getLength() - totalOffset) * 8 - 8); + BVExpr destTemp = new BVExtract(dest, (e.getDest().getLength() - j) * 8 - 1, + (e.getDest().getLength() - j) * 8 - 8); + lit = and(lit, new BVEq(sourceTemp, destTemp)); } - totalLit = and (totalLit, new BVNot(lit)); + totalLit = and(totalLit, new BVNot(lit)); } - //println ("totalLit: " + totalLit); + // println ("totalLit: " + totalLit); for (int i = index; i < index + e.getDest().getLength(); i++) { - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, (e.getSource().getLength() - i) * 8 - 8); - BVExpr destTemp = new BVExtract(dest, (e.getDest().getLength() - (i - index)) * 8 - 1, (e.getDest().getLength() - (i - index)) * 8 - 8); - totalLit = and (totalLit, new BVEq(sourceTemp, destTemp)); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, + (e.getSource().getLength() - i) * 8 - 8); + BVExpr destTemp = new BVExtract(dest, (e.getDest().getLength() - (i - index)) * 8 - 1, + (e.getDest().getLength() - (i - index)) * 8 - 8); + totalLit = and(totalLit, new BVEq(sourceTemp, destTemp)); } - post (totalLit); - } - else { + post(totalLit); + } else { if (e.getSource().getLength() < e.getDest().getLength()) { return; - } - else if (e.getSource().getLength() == e.getDest().getLength()) { - post (new BVNot(equal(e))); + } else if (e.getSource().getLength() == e.getDest().getLength()) { + post(new BVNot(equal(e))); return; - } - else { - post (new BVNot(contains(e))); + } else { + post(new BVNot(contains(e))); } } - } - else if (!e.getSource().isConstant()) { - //println ("branch 2"); - BVExpr source = getBVExpr (e.getSource()); + } else if (!e.getSource().isConstant()) { + // println ("branch 2"); + BVExpr source = getBVExpr(e.getSource()); String destCons = e.getDest().getSolution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); if (index > -1) { - //println ("branch 2.1"); + // println ("branch 2.1"); BVExpr totalLit = null; - //Characters before should not be equal - for (int i = 0; i <= index - destCons.length(); i++) { //TODO: Double check + // Characters before should not be equal + for (int i = 0; i <= index - destCons.length(); i++) { // TODO: + // Double + // check BVExpr lit = null; for (int j = 0; j < destCons.length(); j++) { int entireOff = i + j; - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - entireOff) * 8 - 1, (e.getSource().getLength() - entireOff) * 8 - 8); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - entireOff) * 8 - 1, + (e.getSource().getLength() - entireOff) * 8 - 8); BVExpr cons = new BVConst(destCons.charAt(j)); - lit = and (lit, new BVEq (sourceTemp, cons)); + lit = and(lit, new BVEq(sourceTemp, cons)); } totalLit = and(totalLit, new BVNot(lit)); } for (int i = index; i < index + e.getDest().getLength(); i++) { - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, (e.getSource().getLength() - i) * 8 - 8); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, + (e.getSource().getLength() - i) * 8 - 8); BVExpr cons = new BVConst(destCons.charAt(i - index)); - totalLit = and (totalLit, new BVEq(sourceTemp, cons)); + totalLit = and(totalLit, new BVEq(sourceTemp, cons)); } - post (totalLit); - } - else { - //println ("branch 2.2"); + post(totalLit); + } else { + // println ("branch 2.2"); if (e.getSource().getLength() < e.getDest().getLength()) { return; - } - else if (e.getSource().getLength() == e.getDest().getLength()) { - post (new BVNot(equal(e))); + } else if (e.getSource().getLength() == e.getDest().getLength()) { + post(new BVNot(equal(e))); return; - } - else { - post (new BVNot(contains(e))); + } else { + post(new BVNot(contains(e))); } } - } - else if (!e.getDest().isConstant()) { - //println ("branch 3"); + } else if (!e.getDest().isConstant()) { + // println ("branch 3"); String sourceCons = e.getSource().getSolution(); - + BVExpr dest = getBVExpr(e.getDest()); - int index = e.getIndex().solution(); - + int index = e.getIndex().solutionInt(); + if (index > -1) { String realSolution = sourceCons.substring(index, index + e.getDest().getLength()); BVExpr lit = null; for (int i = 0; i < realSolution.length(); i++) { - BVExpr destExpr = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, (e.getDest().getLength() - i) * 8 - 8); + BVExpr destExpr = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, + (e.getDest().getLength() - i) * 8 - 8); BVExpr cons = new BVConst(realSolution.charAt(i)); - lit = and (lit, new BVEq(destExpr, cons)); + lit = and(lit, new BVEq(destExpr, cons)); } - post (lit); - } - else { + post(lit); + } else { if (e.getSource().getLength() < e.getDest().getLength()) { return; - } - else if (e.getSource().getLength() == e.getDest().getLength()) { - post (new BVNot(equal(e))); + } else if (e.getSource().getLength() == e.getDest().getLength()) { + post(new BVNot(equal(e))); return; - } - else { - post (new BVNot(contains(e))); + } else { + post(new BVNot(contains(e))); } } } } - - private static void handleEdgeIndexOfChar (EdgeIndexOfChar e) { + + private static void handleEdgeIndexOfChar(EdgeIndexOfChar e) { if (!e.getSource().isConstant()) { BVExpr source = getBVExpr(e.getSource()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); if (index > -1) { BVExpr lit = null; /* no other occurences of the character may come before */ for (int i = 0; i < index; i++) { - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, (e.getSource().getLength() - i) * 8 - 8); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, + (e.getSource().getLength() - i) * 8 - 8); BVExpr constant = new BVConst(character); - lit = and (lit, new BVNot(new BVEq(sourceTemp, constant))); + lit = and(lit, new BVNot(new BVEq(sourceTemp, constant))); } - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - index) * 8 - 1, (e.getSource().getLength() - index) * 8 - 8); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - index) * 8 - 1, + (e.getSource().getLength() - index) * 8 - 8); BVExpr constant = new BVConst(character); - lit = and (lit, new BVEq(sourceTemp, constant)); - post (lit); - //println ("[handleEdgeIndexOfChar] lit: " + lit.toString()); - } - else { + lit = and(lit, new BVEq(sourceTemp, constant)); + post(lit); + // println ("[handleEdgeIndexOfChar] lit: " + lit.toString()); + } else { BVExpr lit = null; for (int i = 0; i < e.getSource().getLength(); i++) { - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, (e.getSource().getLength() - i) * 8 - 8); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, + (e.getSource().getLength() - i) * 8 - 8); BVExpr constant = new BVConst(character); - lit = and (lit, new BVNot(new BVEq(sourceTemp, constant))); + lit = and(lit, new BVNot(new BVEq(sourceTemp, constant))); } - post (lit); + post(lit); } - } - else { + } else { String source = e.getSource().getSolution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); int actualAns = source.indexOf(character); - post (new BVEq(new BVConst(actualAns), new BVConst(index))); + post(new BVEq(new BVConst(actualAns), new BVConst(index))); } } - - private static void handleEdgeLastIndexOfChar (EdgeLastIndexOfChar e) { + + private static void handleEdgeLastIndexOfChar(EdgeLastIndexOfChar e) { if (!e.getSource().isConstant()) { BVExpr source = getBVExpr(e.getSource()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); if (index > -1) { BVExpr lit = null; /* no other occurences of the character may come after */ - for (int i = index+1; i < e.getSource().getLength(); i++) { - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, (e.getSource().getLength() - i) * 8 - 8); + for (int i = index + 1; i < e.getSource().getLength(); i++) { + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, + (e.getSource().getLength() - i) * 8 - 8); BVExpr constant = new BVConst(character); - lit = and (lit, new BVNot(new BVEq(sourceTemp, constant))); + lit = and(lit, new BVNot(new BVEq(sourceTemp, constant))); } - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - index) * 8 - 1, (e.getSource().getLength() - index) * 8 - 8); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - index) * 8 - 1, + (e.getSource().getLength() - index) * 8 - 8); BVExpr constant = new BVConst(character); - lit = and (lit, new BVEq(sourceTemp, constant)); - post (lit); - //println ("[handleEdgeIndexOfChar] lit: " + lit.toString()); - } - else { + lit = and(lit, new BVEq(sourceTemp, constant)); + post(lit); + // println ("[handleEdgeIndexOfChar] lit: " + lit.toString()); + } else { BVExpr lit = null; for (int i = 0; i < e.getSource().getLength(); i++) { - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, (e.getSource().getLength() - i) * 8 - 8); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, + (e.getSource().getLength() - i) * 8 - 8); BVExpr constant = new BVConst(character); - lit = and (lit, new BVNot(new BVEq(sourceTemp, constant))); + lit = and(lit, new BVNot(new BVEq(sourceTemp, constant))); } - post (lit); + post(lit); } - } - else { + } else { String source = e.getSource().getSolution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); int actualAns = source.indexOf(character); - post (new BVEq(new BVConst(actualAns), new BVConst(index))); + post(new BVEq(new BVConst(actualAns), new BVConst(index))); } } - - private static void handleEdgeLastIndexOfChar2 (EdgeLastIndexOfChar2 e) { + + private static void handleEdgeLastIndexOfChar2(EdgeLastIndexOfChar2 e) { if (!e.getSource().isConstant()) { BVExpr source = getBVExpr(e.getSource()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); if (index > -1) { BVExpr lit = null; - /* no other occurences of the character may come after up till second argument*/ - for (int i = index+1; i < e.getIndex().getMinDist().solution(); i++) { - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, (e.getSource().getLength() - i) * 8 - 8); + /* + * no other occurences of the character may come after up till + * second argument + */ + for (int i = index + 1; i < e.getIndex().getMinDist().solution(); i++) { + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, + (e.getSource().getLength() - i) * 8 - 8); BVExpr constant = new BVConst(character); - lit = and (lit, new BVNot(new BVEq(sourceTemp, constant))); + lit = and(lit, new BVNot(new BVEq(sourceTemp, constant))); } - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - index) * 8 - 1, (e.getSource().getLength() - index) * 8 - 8); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - index) * 8 - 1, + (e.getSource().getLength() - index) * 8 - 8); BVExpr constant = new BVConst(character); - lit = and (lit, new BVEq(sourceTemp, constant)); - post (lit); - //println ("[handleEdgeIndexOfChar] lit: " + lit.toString()); - } - else { + lit = and(lit, new BVEq(sourceTemp, constant)); + post(lit); + // println ("[handleEdgeIndexOfChar] lit: " + lit.toString()); + } else { BVExpr lit = null; - //Can not feature uptil the second argument + // Can not feature uptil the second argument for (int i = 0; i < e.getIndex().getMinDist().solution(); i++) { - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, (e.getSource().getLength() - i) * 8 - 8); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, + (e.getSource().getLength() - i) * 8 - 8); BVExpr constant = new BVConst(character); - lit = and (lit, new BVNot(new BVEq(sourceTemp, constant))); + lit = and(lit, new BVNot(new BVEq(sourceTemp, constant))); } - post (lit); + post(lit); } - } - else { + } else { String source = e.getSource().getSolution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); - int actualAns = source.lastIndexOf(character, e.getIndex().getMinDist().solution()); - post (new BVEq(new BVConst(actualAns), new BVConst(index))); + int actualAns = source.lastIndexOf(character, e.getIndex().getMinDist().solutionInt()); + post(new BVEq(new BVConst(actualAns), new BVConst(index))); } } - - private static void handleEdgeIndexOfChar2 (EdgeIndexOfChar2 e) { + + private static void handleEdgeIndexOfChar2(EdgeIndexOfChar2 e) { if (!e.getSource().isConstant()) { BVExpr source = getBVExpr(e.getSource()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); if (index > -1) { - //println ("[handleEdgeIndexOfChar2] branch 1"); + // println ("[handleEdgeIndexOfChar2] branch 1"); BVExpr lit = null; /* no other occurences of the character may come before */ - //println ("[handleEdgeIndexOfChar2] e.getIndex().getMinDist().solution() = " + e.getIndex().getMinDist().solution()); - int i = e.getIndex().getMinDist().solution(); + // println ("[handleEdgeIndexOfChar2] + // e.getIndex().getMinDist().solution() = " + + // e.getIndex().getMinDist().solution()); + int i = e.getIndex().getMinDist().solutionInt(); if (e.getIndex().getMinDist().solution() < 0) { i = 0; } for (; i < index; i++) { - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, (e.getSource().getLength() - i) * 8 - 8); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, + (e.getSource().getLength() - i) * 8 - 8); BVExpr constant = new BVConst(character); - lit = and (lit, new BVNot(new BVEq(sourceTemp, constant))); + lit = and(lit, new BVNot(new BVEq(sourceTemp, constant))); } - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - index) * 8 - 1, (e.getSource().getLength() - index) * 8 - 8); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - index) * 8 - 1, + (e.getSource().getLength() - index) * 8 - 8); BVExpr constant = new BVConst(character); - lit = and (lit, new BVEq(sourceTemp, constant)); - post (lit); - } - else { + lit = and(lit, new BVEq(sourceTemp, constant)); + post(lit); + } else { BVExpr lit = null; for (int i = 0; i < e.getSource().getLength(); i++) { - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, (e.getSource().getLength() - i) * 8 - 8); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, + (e.getSource().getLength() - i) * 8 - 8); BVExpr constant = new BVConst(character); - lit = and (lit, new BVNot(new BVEq(sourceTemp, constant))); + lit = and(lit, new BVNot(new BVEq(sourceTemp, constant))); } - post (lit); + post(lit); } - } - else { + } else { String source = e.getSource().getSolution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); - int actualAns = source.indexOf(character, e.getIndex().getMinDist().solution()); - post (new BVEq(new BVConst(actualAns), new BVConst(index))); + int actualAns = source.indexOf(character, e.getIndex().getMinDist().solutionInt()); + post(new BVEq(new BVConst(actualAns), new BVConst(index))); } } - - private static void handleEdgeNotContains (EdgeNotContains e) { + + private static void handleEdgeNotContains(EdgeNotContains e) { if (e.getSource().getLength() < e.getDest().getLength()) { return; } - post (new BVNot(contains(e))); + post(new BVNot(contains(e))); } - - private static void handleEdgeSubstring1Equal (EdgeSubstring1Equal e) { + + private static void handleEdgeSubstring1Equal(EdgeSubstring1Equal e) { if (!e.getSource().isConstant() && !e.getDest().isConstant()) { BVExpr source = getBVExpr(e.getSource()); BVExpr dest = getBVExpr(e.getDest()); int arg1 = e.getArgument1(); BVExpr lit = null; for (int i = 0; i < e.getDest().getLength(); i++) { - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - (i + arg1)) * 8 - 1, (e.getSource().getLength() - (i + arg1)) * 8 - 8); - BVExpr destTemp = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, (e.getDest().getLength() - i) * 8 - 8); - lit = and (lit, new BVEq(sourceTemp, destTemp)); - } - post (lit); - } - else if (!e.getSource().isConstant()) { + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - (i + arg1)) * 8 - 1, + (e.getSource().getLength() - (i + arg1)) * 8 - 8); + BVExpr destTemp = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, + (e.getDest().getLength() - i) * 8 - 8); + lit = and(lit, new BVEq(sourceTemp, destTemp)); + } + post(lit); + } else if (!e.getSource().isConstant()) { BVExpr source = getBVExpr(e.getSource()); String destCons = e.getDest().getSolution(); int arg1 = e.getArgument1(); BVExpr lit = null; for (int i = 0; i < e.getDest().getLength(); i++) { - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - (i + arg1)) * 8 - 1, (e.getSource().getLength() - (i + arg1)) * 8 - 8); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - (i + arg1)) * 8 - 1, + (e.getSource().getLength() - (i + arg1)) * 8 - 8); BVExpr destTemp = new BVConst(destCons.charAt(i)); - lit = and (lit, new BVEq(sourceTemp, destTemp)); + lit = and(lit, new BVEq(sourceTemp, destTemp)); } - post (lit); - } - else { + post(lit); + } else { throw new RuntimeException("Preprocessor should handle this"); } } - - private static void handleEdgeSubstring2Equal (EdgeSubstring2Equal e) { + + private static void handleEdgeSubstring2Equal(EdgeSubstring2Equal e) { if (!e.hasSymbolicArgs()) { if (!e.getSource().isConstant() && !e.getDest().isConstant()) { BVExpr source = getBVExpr(e.getSource()); @@ -1361,100 +1328,99 @@ private static void handleEdgeSubstring2Equal (EdgeSubstring2Equal e) { int arg2 = e.getArgument2(); BVExpr lit = null; for (int i = 0; i < arg2 - arg1; i++) { - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - (i + arg1)) * 8 - 1, (e.getSource().getLength() - (i + arg1)) * 8 - 8); - BVExpr destTemp = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, (e.getDest().getLength() - i) * 8 - 8); - lit = and (lit, new BVEq(sourceTemp, destTemp)); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - (i + arg1)) * 8 - 1, + (e.getSource().getLength() - (i + arg1)) * 8 - 8); + BVExpr destTemp = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, + (e.getDest().getLength() - i) * 8 - 8); + lit = and(lit, new BVEq(sourceTemp, destTemp)); } - post (lit); - } - else if (!e.getSource().isConstant()) { + post(lit); + } else if (!e.getSource().isConstant()) { BVExpr source = getBVExpr(e.getSource()); String destCons = e.getDest().getSolution(); int arg1 = e.getArgument1(); int arg2 = e.getArgument2(); BVExpr lit = null; for (int i = 0; i < arg2 - arg1; i++) { - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - (i + arg1)) * 8 - 1, (e.getSource().getLength() - (i + arg1)) * 8 - 8); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - (i + arg1)) * 8 - 1, + (e.getSource().getLength() - (i + arg1)) * 8 - 8); BVExpr destTemp = new BVConst(destCons.charAt(i)); - lit = and (lit, new BVEq(sourceTemp, destTemp)); + lit = and(lit, new BVEq(sourceTemp, destTemp)); } - post (lit); - } - else { + post(lit); + } else { throw new RuntimeException("Preprocessor should handle this"); } - } - else if (e.getSymbolicArgument1() == null && e.getSymbolicArgument2() != null) { + } else if (e.getSymbolicArgument1() == null && e.getSymbolicArgument2() != null) { if (!e.getSource().isConstant() && !e.getDest().isConstant()) { BVExpr source = getBVExpr(e.getSource()); BVExpr dest = getBVExpr(e.getDest()); int arg1 = e.getArgument1(); - int arg2 = e.getSymbolicArgument2().solution(); + int arg2 = e.getSymbolicArgument2().solutionInt(); BVExpr lit = null; for (int i = 0; i < arg2 - arg1; i++) { - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - (i + arg1)) * 8 - 1, (e.getSource().getLength() - (i + arg1)) * 8 - 8); - BVExpr destTemp = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, (e.getDest().getLength() - i) * 8 - 8); - lit = and (lit, new BVEq(sourceTemp, destTemp)); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - (i + arg1)) * 8 - 1, + (e.getSource().getLength() - (i + arg1)) * 8 - 8); + BVExpr destTemp = new BVExtract(dest, (e.getDest().getLength() - i) * 8 - 1, + (e.getDest().getLength() - i) * 8 - 8); + lit = and(lit, new BVEq(sourceTemp, destTemp)); } - post (lit); - } - else if (!e.getSource().isConstant()) { + post(lit); + } else if (!e.getSource().isConstant()) { BVExpr source = getBVExpr(e.getSource()); String destCons = e.getDest().getSolution(); int arg1 = e.getArgument1(); - int arg2 = e.getSymbolicArgument2().solution(); + int arg2 = e.getSymbolicArgument2().solutionInt(); if (arg2 - arg1 != destCons.length()) { - //TODO: Can definitly improve here - //global_pc._addDet(Comparator.EQ, e.getSymbolicArgument2(), destCons.length() + arg1); + // TODO: Can definitly improve here + // global_pc._addDet(Comparator.EQ, + // e.getSymbolicArgument2(), destCons.length() + arg1); post(new BVFalse()); return; - //throw new RuntimeException((arg2 - arg1) + " is not equal to '" + destCons + "' length of " + destCons.length()); + // throw new RuntimeException((arg2 - arg1) + " is not equal + // to '" + destCons + "' length of " + destCons.length()); } BVExpr lit = null; for (int i = 0; i < arg2 - arg1; i++) { - BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - (i + arg1)) * 8 - 1, (e.getSource().getLength() - (i + arg1)) * 8 - 8); + BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - (i + arg1)) * 8 - 1, + (e.getSource().getLength() - (i + arg1)) * 8 - 8); BVExpr destTemp = new BVConst(destCons.charAt(i)); - lit = and (lit, new BVEq(sourceTemp, destTemp)); + lit = and(lit, new BVEq(sourceTemp, destTemp)); } - post (lit); - } - else { + post(lit); + } else { throw new RuntimeException("Preprocessor should handle this"); } - } - else { - throw new RuntimeException ("not supported, yet"); + } else { + throw new RuntimeException("not supported, yet"); } } - - private static BVExpr and (BVExpr orig, BVExpr newE) { + + private static BVExpr and(BVExpr orig, BVExpr newE) { if (orig == null) { return newE; - } - else { + } else { return new BVAnd(orig, newE); } } - - private static BVExpr or (BVExpr orig, BVExpr newE) { + + private static BVExpr or(BVExpr orig, BVExpr newE) { if (orig == null) { return newE; - } - else { + } else { return new BVOr(orig, newE); } } - - private static void post (BVExpr e) { + + private static void post(BVExpr e) { if (expr == null) { expr = e; - } - else { + } else { expr = new BVAnd(e, expr); - } + } } - - private static boolean[] toBits (char c) { + + private static boolean[] toBits(char c) { boolean[] result = new boolean[8]; int num = (int) c; int i = result.length - 1; @@ -1463,21 +1429,24 @@ private static boolean[] toBits (char c) { int temp = num / div; num = num - div * temp; div = div / 2; - if (temp == 1) result[i] = true; + if (temp == 1) + result[i] = true; i--; } return result; - } - - private static BVExpr getBVExpr (Vertex v){ + } + + private static BVExpr getBVExpr(Vertex v) { BVExpr result = map.get(v); if (result == null) { - //8 is easier - //result = vc.varExpr("a", vc.arrayType(vc.intType(), vc.intType())); + // 8 is easier + // result = vc.varExpr("a", vc.arrayType(vc.intType(), + // vc.intType())); result = new BVVar(v.getName(), 8 * v.getLength()); - //println ("[BVExpr] " + v.getName() + " length: " + (8 * v.getLength())); + // println ("[BVExpr] " + v.getName() + " length: " + (8 * + // v.getLength())); map.put(v, result); - //Apply character constraints to each character + // Apply character constraints to each character BVExpr lit = null; for (int i = 0; i < v.getLength(); i++) { BVExpr temp = new BVExtract(result, i * 8 + 7, i * 8); @@ -1485,82 +1454,72 @@ private static BVExpr getBVExpr (Vertex v){ BVExpr cons2 = new BVNot(new BVLT(temp, new BVConst(SymbolicStringConstraintsGeneral.MIN_CHAR))); if (lit == null) { lit = new BVAnd(cons1, cons2); - } - else { + } else { lit = new BVAnd(lit, new BVAnd(cons1, cons2)); } - if(v.isConstant()) { - //the strings are stored in reverse in the bitvector + if (v.isConstant()) { + // the strings are stored in reverse in the bitvector String vertexString = v.getSolution(); int charIndex = (vertexString.length() - 1) - i; char currentChar = vertexString.charAt(charIndex); BVEq consEq = new BVEq(temp, new BVConst(currentChar)); lit = new BVAnd(lit, consEq); } - } - post (lit); + } + post(lit); } return result; } - - private static String getSMTLibString (Expr em) { + + private static String getSMTLibString(Expr em) { StringBuilder sb = new StringBuilder(); - - preOrderTraversal (em, sb); - + + preOrderTraversal(em, sb); + return sb.toString(); } - - private static void preOrderTraversal (Expr em, StringBuilder string) { - + + private static void preOrderTraversal(Expr em, StringBuilder string) { + if (em.isAnd()) { - string.append ("and"); - } - else if (em.isOr()) { - string.append ("or"); - } - else if (em.isNot()) { - string.append ("not"); - } - else if (em.isEq()) { - string.append ("="); - } - else if (em.isBvExtract()) { - string.append ("BV Extract"); + string.append("and"); + } else if (em.isOr()) { + string.append("or"); + } else if (em.isNot()) { + string.append("not"); + } else if (em.isEq()) { + string.append("="); + } else if (em.isBvExtract()) { + string.append("BV Extract"); return; + } else { + string.append("|" + em.getKind() + "|"); } - else { - string.append ("|" + em.getKind() + "|"); - } - string.append (" "); - - string.append ("("); - for (Object e: em.getChildren()) { + string.append(" "); + + string.append("("); + for (Object e : em.getChildren()) { preOrderTraversal((Expr) e, string); } - string.append (")"); + string.append(")"); } - - private static String getSMTLibMsg () { - StringBuilder sb = new StringBuilder (); - - for (Entry e: map.entrySet()) { + + private static String getSMTLibMsg() { + StringBuilder sb = new StringBuilder(); + + for (Entry e : map.entrySet()) { BVVar var = (BVVar) e.getValue(); sb.append(var.toSMTLibDec()); - sb.append ("\n"); + sb.append("\n"); } - - sb.append ("(assert "); - sb.append (expr.toSMTLib()); - sb.append (")\n"); - - sb.append ("(check-sat)\n(get-info model)\n"); - + + sb.append("(assert "); + sb.append(expr.toSMTLib()); + sb.append(")\n"); + + sb.append("(check-sat)\n(get-info model)\n"); + return sb.toString(); } - - private static void println (String msg) { - System.out.println("[TranslateToZ3] " + msg); - } } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToZ3Inc.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToZ3Inc.java index 3be3a46..c26ef70 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToZ3Inc.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/TranslateToZ3Inc.java @@ -758,7 +758,7 @@ private static boolean handleEdgeCharAt (EdgeCharAt e) { if (!e.getSource().isConstant()) { BVExpr source = getBVExpr(e.getSource()); char c = (char) e.getValue().solution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); //println ("[handleEdgeCharAt] " + c + " " + index); BVExpr temp = new BVExtract(source, (e.getSource().getLength() - index) * 8 - 1, (e.getSource().getLength() - index) * 8 - 8); BVExpr cons = new BVConst (c); @@ -767,8 +767,8 @@ private static boolean handleEdgeCharAt (EdgeCharAt e) { } else { String constant = e.getSource().getSolution(); - char c = (char) e.getValue().solution(); - int index = e.getIndex().solution(); + char c = e.getValue().solutionChar(); + int index = e.getIndex().solutionInt(); if (index > -1) { BVExpr temp1 = new BVConst (constant.charAt(index)); BVExpr temp2 = new BVConst (c); @@ -831,7 +831,7 @@ private static boolean handleEdgeNotCharAt (EdgeNotCharAt e) { if (!e.getSource().isConstant()) { BVExpr source = getBVExpr(e.getSource()); char c = (char) e.getValue().solution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); //println ("[handleEdgeCharAt] " + c + " " + index); BVExpr temp = new BVExtract(source, (e.getSource().getLength() - index) * 8 - 1, (e.getSource().getLength() - index) * 8 - 8); BVExpr cons = new BVConst (c); @@ -840,8 +840,8 @@ private static boolean handleEdgeNotCharAt (EdgeNotCharAt e) { } else { String constant = e.getSource().getSolution(); - char c = (char) e.getValue().solution(); - int index = e.getIndex().solution(); + char c = e.getValue().solutionChar(); + int index = e.getIndex().solutionInt(); if (index > -1) { BVExpr temp1 = new BVConst (constant.charAt(index)); BVExpr temp2 = new BVConst (c); @@ -1013,7 +1013,7 @@ private static BVExpr contains (Edge e) { } private static BVExpr contains (Edge e, IntegerExpression IEstartIndex) { - int startIndex = IEstartIndex.solution(); + int startIndex = IEstartIndex.solutionInt(); if (startIndex < 0) startIndex = 0; if (!e.getSource().isConstant() && !e.getDest().isConstant()) { //println ("contains branch 1"); @@ -1115,11 +1115,11 @@ private static boolean handleEdgeIndexOf2 (EdgeIndexOf2 e) { //println ("branch 1"); BVExpr source = getBVExpr (e.getSource()); BVExpr dest = getBVExpr (e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); if (index > -1) { BVExpr totalLit = null; - for (int i = e.getIndex().getMinIndex().solution(); i <= index - e.getDest().getLength(); i++) { + for (int i = e.getIndex().getMinIndex().solutionInt(); i <= index - e.getDest().getLength(); i++) { BVExpr lit = null; for (int j = 0; j < e.getDest().getLength(); j++) { int totalOffset = i + j; @@ -1156,7 +1156,7 @@ else if (!e.getSource().isConstant()) { //println ("branch 2"); BVExpr source = getBVExpr (e.getSource()); String destCons = e.getDest().getSolution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); if (index > -1) { BVExpr lit = null; for (int i = index; i < index + e.getDest().getLength(); i++) { @@ -1187,7 +1187,7 @@ else if (!e.getDest().isConstant()) { String sourceCons = e.getSource().getSolution(); BVExpr dest = getBVExpr(e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); if (index > -1) { String realSolution = sourceCons.substring(index, index + e.getDest().getLength()); @@ -1238,7 +1238,7 @@ private static boolean handleEdgeIndexOf (EdgeIndexOf e) { //println ("[handleEdgeIndexOf] branch 1"); BVExpr source = getBVExpr (e.getSource()); BVExpr dest = getBVExpr (e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); if (index > -1) { /*BVExpr lit = null; @@ -1289,7 +1289,7 @@ else if (!e.getSource().isConstant()) { //println ("[handleEdgeIndexOf] branch 2"); BVExpr source = getBVExpr (e.getSource()); String destCons = e.getDest().getSolution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); if (index > -1) { //println ("[handleEdgeIndexOf] branch 2.1"); BVExpr totalLit = null; @@ -1337,7 +1337,7 @@ else if (!e.getDest().isConstant()) { String sourceCons = e.getSource().getSolution(); BVExpr dest = getBVExpr(e.getDest()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); if (index > -1) { String realSolution = sourceCons.substring(index, index + e.getDest().getLength()); @@ -1395,7 +1395,7 @@ private static boolean handleEdgeIndexOfChar (EdgeIndexOfChar e) { boolean result = true; if (!e.getSource().isConstant()) { BVExpr source = getBVExpr(e.getSource()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); if (index > -1) { //println ("index > -1: " + index); @@ -1430,7 +1430,7 @@ private static boolean handleEdgeIndexOfChar (EdgeIndexOfChar e) { } else { String source = e.getSource().getSolution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); int actualAns = source.indexOf(character); //result = post (new BVEq(new BVConst(actualAns), new BVConst(index))); @@ -1459,7 +1459,7 @@ private static boolean handleEdgeIndexOfChar2 (EdgeIndexOfChar2 e) { if (!e.getSource().isConstant()) { //println ("[handleEdgeIndexOfChar2] branch 1"); BVExpr source = getBVExpr(e.getSource()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); if (index > -1) { //println ("[handleEdgeIndexOfChar2] branch 1.1, index="+index); @@ -1467,7 +1467,7 @@ private static boolean handleEdgeIndexOfChar2 (EdgeIndexOfChar2 e) { BVExpr lit = null; /* no other occurences of the character may come before */ //println ("[handleEdgeIndexOfChar2] e.getIndex().getMinDist().solution() = " + e.getIndex().getMinDist().solution()); - int i = e.getIndex().getMinDist().solution(); + int i = e.getIndex().getMinDist().solutionInt(); //println ("[handleEdgeIndexOfChar2] e.getIndex().getMinDist().solution() = " + e.getIndex().getMinDist().solution()); if (e.getIndex().getMinDist().solution() < 0) { i = 0; @@ -1487,7 +1487,7 @@ private static boolean handleEdgeIndexOfChar2 (EdgeIndexOfChar2 e) { else { //println ("[handleEdgeIndexOfChar2] branch 1.2"); BVExpr lit = null; - int i = e.getIndex().getMinDist().solution(); + int i = e.getIndex().getMinDist().solutionInt(); if (i < 0) i = 0; for (; i < e.getSource().getLength(); i++) { BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - i) * 8 - 1, (e.getSource().getLength() - i) * 8 - 8); @@ -1500,9 +1500,9 @@ private static boolean handleEdgeIndexOfChar2 (EdgeIndexOfChar2 e) { else { //println ("[handleEdgeIndexOfChar2] branch 2"); String source = e.getSource().getSolution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); - int actualAns = source.indexOf(character, e.getIndex().getMinDist().solution()); + int actualAns = source.indexOf(character, e.getIndex().getMinDist().solutionInt()); if (index == actualAns) { result = post (new BVTrue()); } @@ -1598,7 +1598,7 @@ private static boolean handleEdgeLastIndexOfChar (EdgeLastIndexOfChar e) { boolean result = true; if (!e.getSource().isConstant()) { BVExpr source = getBVExpr(e.getSource()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); if (index > -1) { BVExpr lit = null; @@ -1626,7 +1626,7 @@ private static boolean handleEdgeLastIndexOfChar (EdgeLastIndexOfChar e) { } else { String source = e.getSource().getSolution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); int actualAns = source.indexOf(character); result = post (new BVEq(new BVConst(actualAns), new BVConst(index))); @@ -1648,7 +1648,7 @@ private static boolean handleEdgeLastIndexOfChar2 (EdgeLastIndexOfChar2 e) { boolean result = true; if (!e.getSource().isConstant()) { BVExpr source = getBVExpr(e.getSource()); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); if (index > -1) { BVExpr lit = null; @@ -1680,9 +1680,9 @@ private static boolean handleEdgeLastIndexOfChar2 (EdgeLastIndexOfChar2 e) { } else { String source = e.getSource().getSolution(); - int index = e.getIndex().solution(); + int index = e.getIndex().solutionInt(); char character = (char) e.getIndex().getExpression().solution(); - int actualAns = source.lastIndexOf(character, e.getIndex().getMinDist().solution()); + int actualAns = source.lastIndexOf(character, e.getIndex().getMinDist().solutionInt()); result = (index == actualAns); } LogicalORLinearIntegerConstraints loic = new LogicalORLinearIntegerConstraints(); @@ -1748,7 +1748,7 @@ else if (e.getSymbolicArgument1() == null && e.getSymbolicArgument2() != null) { BVExpr source = getBVExpr(e.getSource()); BVExpr dest = getBVExpr(e.getDest()); int arg1 = e.getArgument1(); - int arg2 = e.getSymbolicArgument2().solution(); + int arg2 = e.getSymbolicArgument2().solutionInt(); BVExpr lit = null; for (int i = 0; i < arg2 - arg1; i++) { BVExpr sourceTemp = new BVExtract(source, (e.getSource().getLength() - (i + arg1)) * 8 - 1, (e.getSource().getLength() - (i + arg1)) * 8 - 8); @@ -1761,7 +1761,7 @@ else if (!e.getSource().isConstant()) { BVExpr source = getBVExpr(e.getSource()); String destCons = e.getDest().getSolution(); int arg1 = e.getArgument1(); - int arg2 = e.getSymbolicArgument2().solution(); + int arg2 = e.getSymbolicArgument2().solutionInt(); if (arg2 - arg1 != destCons.length()) { //TODO: Can definitly improve here //LogicalORLinearIntegerConstraints loic = elimanateCurrentLengthsConstraints(); @@ -1784,7 +1784,7 @@ else if (!e.getSource().isConstant()) { } else { //Assume both constants - if (!e.getSource().getSolution().substring(e.getArgument1(),e.getSymbolicArgument2().solution()).equals((e.getDest().getSolution()))) { + if (!e.getSource().getSolution().substring(e.getArgument1(),e.getSymbolicArgument2().solutionInt()).equals((e.getDest().getSolution()))) { //global_pc._addDet(Comparator.NE, e.getSymbolicArgument2(), e.getSymbolicArgument2().solution()); LogicalORLinearIntegerConstraints loic = new LogicalORLinearIntegerConstraints(); loic.addToList(new LinearIntegerConstraint(e.getSource().getSymbolicLength(), Comparator.NE, new IntegerConstant(e.getSource().getLength()))); diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/Z3Interface.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/Z3Interface.java index 66c978e..9e65987 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/Z3Interface.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/string/translate/Z3Interface.java @@ -20,6 +20,8 @@ +import gov.nasa.jpf.util.LogManager; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; @@ -28,10 +30,12 @@ import java.math.BigInteger; import java.util.HashMap; import java.util.Map; +import java.util.logging.Logger; public class Z3Interface { - + static Logger logger = LogManager.getLogger("Z3Interface"); + Process process; OutputStream stdin; InputStream stdout; @@ -99,7 +103,7 @@ public void sendMessage218 (String msg) throws IOException{ if (line.contains("ERROR")) { String oldline = line; line = brCleanUp.readLine(); - System.out.println(msg); + logger.warning(msg); throw new RuntimeException("Z3 encountered an error in its input: " + oldline + "\n" + line); } else if (line.startsWith("((\"model\" \"") && sat) { @@ -134,7 +138,7 @@ public void sendMessage219 (String msg) throws IOException{ if (line.contains("ERROR")) { String oldline = line; line = brCleanUp.readLine(); - System.out.println(msg); + logger.warning(msg); throw new RuntimeException("Z3 encountered an error in its input: " + oldline + "\n" + line); } else if (line.startsWith("((\"model\" \"") && sat) { @@ -163,10 +167,7 @@ public void sendIncMessage (String msg) throws IOException{ //println ("Exiting..."); } - public void println (String msg) { - System.out.println("[Z3Interface] " + msg); - } - + public void sendIncMessage218 (String msg) throws IOException{ sat = false; stdin.write((msg + "\n(check-sat)\n(get-info model)").getBytes()); @@ -188,7 +189,7 @@ else if (line.equals("unsat")) { if (line.contains("ERROR") || line.contains("error")) { String oldline = line; line = brCleanUp.readLine(); - System.out.println(msg); + logger.severe(msg); throw new RuntimeException("Z3 encuntered an error in its input: " + oldline + "\n" + line); } else if (line.startsWith("((\"model\" \"") && sat) { @@ -229,7 +230,7 @@ else if (line.equals("unsat")) { if (line.contains("ERROR") || line.contains("error")) { String oldline = line; line = brCleanUp.readLine(); - System.out.println(msg); + logger.severe(msg); throw new RuntimeException("Z3 encountered an error in its input: " + oldline + "\n" + line); } else if (line.startsWith("((\"model\" \"") && sat) { diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/tree/ATreeListener.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/tree/ATreeListener.java index 6cf2711..483f364 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/tree/ATreeListener.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/tree/ATreeListener.java @@ -46,7 +46,7 @@ public abstract class ATreeListener extends PropertyListenerAdapter { protected Instruction executed; private final static String FILTER = "symbolic.tree.filter"; - protected final Filter nodePredicate; + protected Filter nodePredicate; public ATreeListener(Config conf, JPF jpf) { this.symbolicMethodStarted = false; @@ -80,7 +80,7 @@ protected boolean isRelevantState(VM vm, ThreadInfo thread) { @Override public void executeInstruction(VM vm, ThreadInfo currentThread, Instruction instructionToExecute) { if(isRelevantState(vm, currentThread)) { - if(nodePredicate.apply(executed, instructionToExecute)) { + if(nodePredicate.apply(executed, instructionToExecute, vm, currentThread)) { T node = this.nodeFactory.constructNode(prev, instructionToExecute, vm); this.prev = node; } diff --git a/jpf-symbc/src/main/gov/nasa/jpf/symbc/tree/Filter.java b/jpf-symbc/src/main/gov/nasa/jpf/symbc/tree/Filter.java index d883538..96ac9a7 100644 --- a/jpf-symbc/src/main/gov/nasa/jpf/symbc/tree/Filter.java +++ b/jpf-symbc/src/main/gov/nasa/jpf/symbc/tree/Filter.java @@ -17,8 +17,12 @@ */ package gov.nasa.jpf.symbc.tree; +import gov.nasa.jpf.jvm.bytecode.DIRECTCALLRETURN; import gov.nasa.jpf.jvm.bytecode.IfInstruction; +import gov.nasa.jpf.symbc.numeric.PCChoiceGenerator; import gov.nasa.jpf.vm.Instruction; +import gov.nasa.jpf.vm.ThreadInfo; +import gov.nasa.jpf.vm.VM; import gov.nasa.jpf.vm.bytecode.InvokeInstruction; import gov.nasa.jpf.vm.bytecode.ReturnInstruction; @@ -31,14 +35,24 @@ public interface Filter { // symbolic.tree.filter public static class AllInstrFilter implements Filter { @Override - public boolean apply(Instruction executedInstruction, Instruction instrToBeExecuted) { + public boolean apply(Instruction executedInstruction, Instruction instrToBeExecuted, VM vm, ThreadInfo currentThread) { return true; } } + public static class SymbolicDecisionFilter implements Filter { + @Override + public boolean apply(Instruction executedInstruction, Instruction instrToBeExecuted, VM vm, ThreadInfo currentThread) { + PCChoiceGenerator pc = vm.getLastChoiceGeneratorOfType(PCChoiceGenerator.class); + if(pc != null) + return (pc.getInsn() == executedInstruction); + return false; + } + } + public static class ConstInstrFilter implements Filter { @Override - public boolean apply(Instruction executedInstruction, Instruction instrToBeExecuted) { + public boolean apply(Instruction executedInstruction, Instruction instrToBeExecuted, VM vm, ThreadInfo currentThread) { return (instrToBeExecuted instanceof IfInstruction || instrToBeExecuted instanceof ReturnInstruction); } @@ -46,11 +60,11 @@ public boolean apply(Instruction executedInstruction, Instruction instrToBeExecu public static class InvokeInstrFilter implements Filter { @Override - public boolean apply(Instruction executedInstruction, Instruction instrToBeExecuted) { + public boolean apply(Instruction executedInstruction, Instruction instrToBeExecuted, VM vm, ThreadInfo currentThread) { return instrToBeExecuted instanceof InvokeInstruction; } } - public boolean apply(Instruction executedInstruction, Instruction instrToBeExecuted); + public boolean apply(Instruction executedInstruction, Instruction instrToBeExecuted, VM vm, ThreadInfo currentThread); } diff --git a/jpf-symbc/src/tests/gov/nasa/jpf/symbc/strings/TestSymString.java b/jpf-symbc/src/tests/gov/nasa/jpf/symbc/strings/TestSymString.java index c1f825d..74b81fd 100644 --- a/jpf-symbc/src/tests/gov/nasa/jpf/symbc/strings/TestSymString.java +++ b/jpf-symbc/src/tests/gov/nasa/jpf/symbc/strings/TestSymString.java @@ -2578,7 +2578,7 @@ public void Test31_1 () { //System.out.printf("var1: '%s'\n", var1.solution()); assertTrue(solver + " failed", result); assertTrue(var1.solution().startsWith("aa")); - assertTrue(var1.solution().charAt(si.solution()) == 'a'); + assertTrue(var1.solution().charAt(si.solutionInt()) == 'a'); } } @@ -2604,7 +2604,7 @@ public void Test31_2 () { //System.out.printf("var1: '%s'\n", var1.solution()); assertTrue(solver + " failed", result); assertTrue(!var1.solution().startsWith("aa")); - assertTrue(var1.solution().charAt(si.solution()) == 'a'); + assertTrue(var1.solution().charAt(si.solutionInt()) == 'a'); } } @@ -2632,7 +2632,7 @@ public void Test31_3 () { System.out.printf("var1: '%s'\n", var1.solution()); assertTrue(solver + " failed", result); assertTrue(var1.solution().startsWith("aa")); - assertTrue(var1.solution().charAt(si.solution()) != 'a'); + assertTrue(var1.solution().charAt(si.solutionInt()) != 'a'); } } @@ -2658,7 +2658,7 @@ public void Test31_4 () { //System.out.printf("var1: '%s'\n", var1.solution()); assertTrue(solver + " failed", result); assertTrue(!var1.solution().startsWith("aa")); - assertTrue(var1.solution().charAt(si.solution()) != 'a'); + assertTrue(var1.solution().charAt(si.solutionInt()) != 'a'); } } @@ -4245,7 +4245,7 @@ public void Test58_1 () { boolean result = stringCurrentPC.simplify(); assertTrue(solver + " failed", result); assertTrue(var2.solution().startsWith("bol")); - assertTrue(var2.solution().indexOf(var1.solution()) == 2); + assertTrue(var2.solution().indexOf(var1.solutionChar()) == 2); } } @@ -4270,7 +4270,7 @@ public void Test58_2 () { System.out.println(String.format("var2.solution(): '%s'", var2.solution())); assertTrue(solver + " failed", result); assertTrue(!var2.solution().startsWith("bol")); - assertTrue(var2.solution().indexOf(var1.solution()) == 2); + assertTrue(var2.solution().indexOf(var1.solutionInt()) == 2); } } @@ -4293,7 +4293,7 @@ public void Test58_3 () { boolean result = stringCurrentPC.simplify(); assertTrue(solver + " failed", result); assertTrue(var2.solution().startsWith("bol")); - assertTrue(var2.solution().indexOf(var1.solution()) != 2); + assertTrue(var2.solution().indexOf(var1.solutionInt()) != 2); } } @@ -4316,7 +4316,7 @@ public void Test58_4 () { boolean result = stringCurrentPC.simplify(); assertTrue(solver + " failed", result); assertTrue(!var2.solution().startsWith("bol")); - assertTrue(var2.solution().indexOf(var1.solution()) != 2); + assertTrue(var2.solution().indexOf(var1.solutionInt()) != 2); } } @@ -4339,7 +4339,7 @@ public void Test59_1 () { boolean result = stringCurrentPC.simplify(); assertTrue(solver + " failed", result); assertTrue(var2.solution().startsWith("bol")); - assertTrue(var2.solution().indexOf(var1.solution()) == 2); + assertTrue(var2.solution().indexOf(var1.solutionInt()) == 2); } } @@ -4364,7 +4364,7 @@ public void Test59_2 () { System.out.println(String.format("var2.solution(): '%s'", var2.solution())); assertTrue(solver + " failed", result); assertTrue(!var2.solution().startsWith("bol")); - assertTrue(var2.solution().indexOf(var1.solution()) == 2); + assertTrue(var2.solution().indexOf(var1.solutionChar()) == 2); } } @@ -4387,7 +4387,7 @@ public void Test59_3 () { boolean result = stringCurrentPC.simplify(); assertTrue(solver + " failed", result); assertTrue(var2.solution().startsWith("bol")); - assertTrue(var2.solution().indexOf(var1.solution()) != 2); + assertTrue(var2.solution().indexOf(var1.solutionChar()) != 2); } } @@ -4410,7 +4410,7 @@ public void Test59_4 () { boolean result = stringCurrentPC.simplify(); assertTrue(solver + " failed", result); assertTrue(!var2.solution().startsWith("bol")); - assertTrue(var2.solution().indexOf(var1.solution()) != 2); + assertTrue(var2.solution().indexOf(var1.solutionChar()) != 2); } } @@ -4435,7 +4435,7 @@ public void Test60_1 () { boolean result = stringCurrentPC.simplify(); assertTrue(solver + " failed", result); assertTrue(str.solution().lastIndexOf('/') >= 0); - assertTrue(str.solution().substring(ie1.solution() + 1).contains("EasyChair")); + assertTrue(str.solution().substring(ie1.solutionInt() + 1).contains("EasyChair")); assertTrue(str.solution().startsWith("http://")); } }