From 9ed415f819d3f7ce0d116be1c73b2b0060719d1b Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Thu, 11 Sep 2025 17:47:39 +0200 Subject: [PATCH 01/93] Yices: Add yices_has_mcsat to the bindings --- ...rg_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c | 7 +++++++ .../sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java | 5 +++++ .../java_smt/solvers/yices2/Yices2NativeApiTest.java | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/lib/native/source/yices2j/org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c b/lib/native/source/yices2j/org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c index 9663fb4e28..c63236b3e9 100644 --- a/lib/native/source/yices2j/org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c +++ b/lib/native/source/yices2j/org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c @@ -1598,6 +1598,13 @@ DEFINE_FUNC(int, 1is_1thread_1safe) WITHOUT_ARGS CALL0(int, is_thread_safe) INT_RETURN +/* + * Check if yices was compiled with MCSAT support + */ +DEFINE_FUNC(int, 1has_1mcsat) WITHOUT_ARGS +CALL0(int, has_mcsat) +INT_RETURN + /* * The function first checks whether f is satisifiable or unsatisfiable. * diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java index d642fd74e3..f861efcce1 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java @@ -796,6 +796,11 @@ public static String yices_model_to_string(long m) { */ public static native int yices_is_thread_safe(); + /** + * @return int 1 if the Yices2-lib is compiled with MCSAT support and 0 otherwise + */ + public static native int yices_has_mcsat(); + /** The function first checks whether f is satisifiable or unsatisfiable. */ public static native int yices_check_formula(int term, String logic, long model, String delegate); diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java index b5c891c556..24f10dd00b 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java @@ -54,6 +54,7 @@ import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_function_type; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_term_by_name; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_term_name; +import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_has_mcsat; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_idiv; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_iff; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_init; @@ -613,6 +614,11 @@ public void isThreadSafe() { assertThat(yices_is_thread_safe()).isEqualTo(0); } + @Test + public void hasMCSat() { + assertThat(yices_has_mcsat()).isEqualTo(0); + } + @Test public void quantifierTest() { int boundVar = yices_new_variable(yices_int_type()); From 03e64936708ef7bb6a96f78c4e3ad821f3815014 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Thu, 11 Sep 2025 17:49:50 +0200 Subject: [PATCH 02/93] Yices: Use absolute paths in the build script --- lib/native/source/yices2j/compile.sh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/native/source/yices2j/compile.sh b/lib/native/source/yices2j/compile.sh index 58f2c52135..57b5d1daf9 100755 --- a/lib/native/source/yices2j/compile.sh +++ b/lib/native/source/yices2j/compile.sh @@ -34,12 +34,11 @@ cd ${DIR} JNI_HEADERS="$(../get_jni_headers.sh)" -RELATIVE_ROOT_DIR="../../../.." -YICES_SRC_DIR=$RELATIVE_ROOT_DIR/"$1"/src/include -YICES_LIB_DIR=$RELATIVE_ROOT_DIR/"$1"/build/x86_64-pc-linux-gnu-release/lib/ -GMP_HEADER_DIR=$RELATIVE_ROOT_DIR/"$2" +YICES_SRC_DIR="$1"/src/include +YICES_LIB_DIR="$1"/build/x86_64-pc-linux-gnu-release/lib/ +GMP_HEADER_DIR="$2" GMP_LIB_DIR=$GMP_HEADER_DIR/.libs -GPERF_HEADER_DIR=$RELATIVE_ROOT_DIR/"$3" +GPERF_HEADER_DIR="$3" GPERF_LIB_DIR=$GPERF_HEADER_DIR/lib # check requirements From eedb5a758372cd3d33c99e384bc3389de17807a8 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Thu, 11 Sep 2025 17:50:57 +0200 Subject: [PATCH 03/93] Yices: Use the right "version" property when building yices --- build/build-publish-solvers/solver-yices.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build-publish-solvers/solver-yices.xml b/build/build-publish-solvers/solver-yices.xml index 998d7ea78c..3b2b36decf 100644 --- a/build/build-publish-solvers/solver-yices.xml +++ b/build/build-publish-solvers/solver-yices.xml @@ -39,7 +39,7 @@ SPDX-License-Identifier: Apache-2.0 - + From 366369e43dc73c55de83c8a835bd5c05b314f6ce Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Thu, 11 Sep 2025 17:52:51 +0200 Subject: [PATCH 04/93] Yices: Update dependencies for yices --- lib/ivy.xml | 2 +- solvers_ivy_conf/ivy_javasmt_yices2.xml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/ivy.xml b/lib/ivy.xml index 0b37f16cfe..2101882159 100644 --- a/lib/ivy.xml +++ b/lib/ivy.xml @@ -198,7 +198,7 @@ SPDX-License-Identifier: Apache-2.0 - + - + - + - + From 4a54884690bf866f95589e2be0598353ec669aa4 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Thu, 11 Sep 2025 17:52:09 +0200 Subject: [PATCH 05/93] Yices: API updates --- lib/native/source/yices2j/includes/defines.h | 2 +- .../solvers/yices2/Yices2FormulaCreator.java | 2 + .../java_smt/solvers/yices2/Yices2Model.java | 4 +- .../solvers/yices2/Yices2NativeApi.java | 131 +++++++++++------- 4 files changed, 87 insertions(+), 52 deletions(-) diff --git a/lib/native/source/yices2j/includes/defines.h b/lib/native/source/yices2j/includes/defines.h index 7133b275dd..2979826f9e 100644 --- a/lib/native/source/yices2j/includes/defines.h +++ b/lib/native/source/yices2j/includes/defines.h @@ -149,7 +149,7 @@ typedef void jvoid; // for symmetry to jint, jlong etc. if(arg##id < 0) { \ throwException(jenv, "java/lang/IllegalArgumentException", "An yval_id cannot be negative."); \ }\ - if(arg##tag < 0 || arg##tag > 8) { \ + if(arg##tag < 0 || arg##tag > 9) { \ throwException(jenv, "java/lang/IllegalArgumentException", "Yval_tag is negative or not a valid yval_tag."); \ } \ m_arg##num->node_id = arg##id; \ diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java index bd4ddd6621..260fa47f5f 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java @@ -13,6 +13,7 @@ import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_AND; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_APP_TERM; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_ARITH_CONST; +import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_ARITH_FF_CONSTANT; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_ARITH_GE_ATOM; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_ARITH_SUM; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_BIT_TERM; @@ -160,6 +161,7 @@ public class Yices2FormulaCreator extends FormulaCreator getFunctionAssignment(int t, int[] yval) for (int i = 2; i < expandFun.length - 1; i += 2) { int[] expandMap; if (expandFun[i + 1] == YVAL_MAPPING) { - expandMap = yices_val_expand_mapping(model, expandFun[i], arity, expandFun[i + 1]); + expandMap = + yices_val_expand_mapping(model, expandFun[i], arity, tagForValKind(expandFun[i + 1])); } else { throw new IllegalArgumentException("Unexpected YVAL tag " + yval[1]); } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java index f861efcce1..94bf345b92 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java @@ -29,61 +29,62 @@ private Yices2NativeApi() {} public static final int YICES_CONSTRUCTOR_ERROR = -1; public static final int YICES_BOOL_CONST = 0; public static final int YICES_ARITH_CONST = 1; - public static final int YICES_BV_CONST = 2; - public static final int YICES_SCALAR_CONST = 3; // NOT used in JavaSMT - public static final int YICES_VARIABLE = 4; - public static final int YICES_UNINTERPRETED_TERM = 5; - - public static final int YICES_ITE_TERM = 6; // if-then-else - public static final int YICES_APP_TERM = 7; // application of an uninterpreted function - public static final int YICES_UPDATE_TERM = 8; // function update - public static final int YICES_TUPLE_TERM = 9; // tuple constructor - public static final int YICES_EQ_TERM = 10; // equality - public static final int YICES_DISTINCT_TERM = 11; // distinct t_1 ... t_n - public static final int YICES_FORALL_TERM = 12; // quantifier - public static final int YICES_LAMBDA_TERM = 13; // lambda - public static final int YICES_NOT_TERM = 14; // (not t) - public static final int YICES_OR_TERM = 15; // n-ary OR - public static final int YICES_XOR_TERM = 16; // n-ary XOR - - public static final int YICES_BV_ARRAY = 17; // array of boolean terms - public static final int YICES_BV_DIV = 18; // unsigned division - public static final int YICES_BV_REM = 19; // unsigned remainder - public static final int YICES_BV_SDIV = 20; // signed division - public static final int YICES_BV_SREM = 21; // remainder in signed division (rounding to 0) - public static final int YICES_BV_SMOD = 22; // remainder in signed division (rounding to + public static final int YICES_ARITH_FF_CONSTANT = 2; // finite field rational constant + public static final int YICES_BV_CONST = 3; + public static final int YICES_SCALAR_CONST = 4; // NOT used in JavaSMT + public static final int YICES_VARIABLE = 5; + public static final int YICES_UNINTERPRETED_TERM = 6; + + public static final int YICES_ITE_TERM = 7; // if-then-else + public static final int YICES_APP_TERM = 8; // application of an uninterpreted function + public static final int YICES_UPDATE_TERM = 9; // function update + public static final int YICES_TUPLE_TERM = 10; // tuple constructor + public static final int YICES_EQ_TERM = 11; // equality + public static final int YICES_DISTINCT_TERM = 12; // distinct t_1 ... t_n + public static final int YICES_FORALL_TERM = 13; // quantifier + public static final int YICES_LAMBDA_TERM = 14; // lambda + public static final int YICES_NOT_TERM = 15; // (not t) + public static final int YICES_OR_TERM = 16; // n-ary OR + public static final int YICES_XOR_TERM = 17; // n-ary XOR + + public static final int YICES_BV_ARRAY = 18; // array of boolean terms + public static final int YICES_BV_DIV = 19; // unsigned division + public static final int YICES_BV_REM = 20; // unsigned remainder + public static final int YICES_BV_SDIV = 21; // signed division + public static final int YICES_BV_SREM = 22; // remainder in signed division (rounding to 0) + public static final int YICES_BV_SMOD = 23; // remainder in signed division (rounding to // -infinity) - public static final int YICES_BV_SHL = 23; // shift left (padding with 0) - public static final int YICES_BV_LSHR = 24; // logical shift right (padding with 0) - public static final int YICES_BV_ASHR = 25; // arithmetic shift right (padding with sign bit) - public static final int YICES_BV_GE_ATOM = 26; // unsigned comparison: (t1 >= t2) - public static final int YICES_BV_SGE_ATOM = 27; // signed comparison (t1 >= t2) - public static final int YICES_ARITH_GE_ATOM = 28; // atom (t1 >= t2) for arithmetic terms: t2 is + public static final int YICES_BV_SHL = 24; // shift left (padding with 0) + public static final int YICES_BV_LSHR = 25; // logical shift right (padding with 0) + public static final int YICES_BV_ASHR = 26; // arithmetic shift right (padding with sign bit) + public static final int YICES_BV_GE_ATOM = 27; // unsigned comparison: (t1 >= t2) + public static final int YICES_BV_SGE_ATOM = 28; // signed comparison (t1 >= t2) + public static final int YICES_ARITH_GE_ATOM = 29; // atom (t1 >= t2) for arithmetic terms: t2 is // always 0 - public static final int YICES_ARITH_ROOT_ATOM = 29; // atom (0 <= k <= root_count(p)) && (x r + public static final int YICES_ARITH_ROOT_ATOM = 30; // atom (0 <= k <= root_count(p)) && (x r // root(p,k)) for r in <, <=, ==, !=, >, >= - public static final int YICES_ABS = 30; // absolute value - public static final int YICES_CEIL = 31; // ceil - public static final int YICES_FLOOR = 32; // floor - public static final int YICES_RDIV = 33; // real division (as in x/y) - public static final int YICES_IDIV = 34; // integer division - public static final int YICES_IMOD = 35; // modulo - public static final int YICES_IS_INT_ATOM = 36; // integrality test: (is-int t) - public static final int YICES_DIVIDES_ATOM = 37; // divisibility test: (divides t1 t2) + public static final int YICES_ABS = 31; // absolute value + public static final int YICES_CEIL = 32; // ceil + public static final int YICES_FLOOR = 33; // floor + public static final int YICES_RDIV = 34; // real division (as in x/y) + public static final int YICES_IDIV = 35; // integer division + public static final int YICES_IMOD = 36; // modulo + public static final int YICES_IS_INT_ATOM = 37; // integrality test: (is-int t) + public static final int YICES_DIVIDES_ATOM = 38; // divisibility test: (divides t1 t2) // projections - public static final int YICES_SELECT_TERM = 38; // tuple projection - public static final int YICES_BIT_TERM = 39; // bit-select: extract the i-th bit of a bitvector + public static final int YICES_SELECT_TERM = 39; // tuple projection + public static final int YICES_BIT_TERM = 40; // bit-select: extract the i-th bit of a bitvector // sums - public static final int YICES_BV_SUM = 40; // sum of pairs a * t where a is a bitvector constant + public static final int YICES_BV_SUM = 41; // sum of pairs a * t where a is a bitvector constant // (and t is a bitvector term) - public static final int YICES_ARITH_SUM = 41; // sum of pairs a * t where a is a rational (and t + public static final int YICES_ARITH_SUM = 42; // sum of pairs a * t where a is a rational (and t // is an arithmetic term) - - // products - public static final int YICES_POWER_PRODUCT = 42; // power products: (t1^d1 * ... * t_n^d_n) + public static final int YICES_ARITH_FF_SUM = 43; // sum of pairs a * t where a is an finite + // field constant (and t is an finite field arithmetic term) products + public static final int YICES_POWER_PRODUCT = 44; // power products: (t1^d1 * ... * t_n^d_n) // Workaround as Yices misses some useful operators, // MAX_INT avoids collisions with existing constants @@ -97,11 +98,41 @@ private Yices2NativeApi() {} public static final int YVAL_BOOL = 1; public static final int YVAL_RATIONAL = 2; public static final int YVAL_ALGEBRAIC = 3; - public static final int YVAL_BV = 4; - public static final int YVAL_SCALAR = 5; - public static final int YVAL_TUPLE = 6; - public static final int YVAL_FUNCTION = 7; - public static final int YVAL_MAPPING = 8; + public static final int YVAL_FINITEFIELD = 4; + public static final int YVAL_BV = 5; + public static final int YVAL_SCALAR = 6; + public static final int YVAL_TUPLE = 7; + public static final int YVAL_FUNCTION = 8; + public static final int YVAL_MAPPING = 9; + + public static int tagForValKind(int valKind) { + switch (valKind) { + case 0: + return YVAL_UNKNOWN; // UNKNOWN_VALUE + case 1: + return YVAL_BOOL; // BOOLEAN_VALUE + case 2: + return YVAL_RATIONAL; // RATIONAL_VALUE + case 3: + return YVAL_FINITEFIELD; // FINITEFIELD_VALUE + case 4: + return YVAL_ALGEBRAIC; // ALGEBRAIC_VALUE + case 5: + return YVAL_BV; // BITVECTOR_VALUE + case 6: + return YVAL_TUPLE; // TUPPLE_VALUE + case 7: + return YVAL_SCALAR; // UNINTERPRETED_VALUE + case 8: + return YVAL_FUNCTION; // FUNCTION_VALUE + case 9: + return YVAL_MAPPING; // MAP_VALUE + case 10: + return YVAL_FUNCTION; // UPDATE_VALUE + default: + throw new IllegalArgumentException("Unknown valKind: " + valKind); + } + } /* * Yices initialization and exit From b685751e43ebabd2234557dcdbddd525f402338d Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Thu, 11 Sep 2025 17:55:40 +0200 Subject: [PATCH 06/93] Yices: Use yices_get_term_name to get the name of a function Otherwise Yices may put SMTLIB quotes around the name --- .../sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java index 260fa47f5f..75e3124075 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java @@ -402,7 +402,7 @@ private R visitFunctionApplication( case YICES_APP_TERM: functionKind = FunctionDeclarationKind.UF; functionArgs = getArgs(pF); - functionName = yices_term_to_string(functionArgs.get(0)); + functionName = yices_get_term_name(functionArgs.get(0)); functionDeclaration = functionArgs.get(0); functionArgs.remove(0); break; From c56fc2a62707f0e3e80052b4f01bec521c2bf3ea Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Thu, 11 Sep 2025 17:57:56 +0200 Subject: [PATCH 07/93] Yices: Enable tests that require parallel solver instances When compiled with --thread-safety Yices should be reentrant --- .../java_smt/solvers/yices2/Yices2NativeApiTest.java | 4 ++-- src/org/sosy_lab/java_smt/test/SolverConcurrencyTest.java | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java index 24f10dd00b..33761613df 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java @@ -610,8 +610,8 @@ public void bvMul() { @Test public void isThreadSafe() { - // TODO: this explains why our concurrency tests fail ;D FIX! - assertThat(yices_is_thread_safe()).isEqualTo(0); + // Check that we compiled with --thread-safety to make it reentrant + assertThat(yices_is_thread_safe()).isEqualTo(1); } @Test diff --git a/src/org/sosy_lab/java_smt/test/SolverConcurrencyTest.java b/src/org/sosy_lab/java_smt/test/SolverConcurrencyTest.java index 3b3029a7d1..f380fa18ec 100644 --- a/src/org/sosy_lab/java_smt/test/SolverConcurrencyTest.java +++ b/src/org/sosy_lab/java_smt/test/SolverConcurrencyTest.java @@ -146,14 +146,14 @@ private void requireIntegers() { assume() .withMessage("Solver does not support integers") .that(solver) - .isNoneOf(Solvers.BOOLECTOR, Solvers.YICES2, Solvers.BITWUZLA); + .isNoneOf(Solvers.BOOLECTOR, Solvers.BITWUZLA); } private void requireBitvectors() { assume() .withMessage("Solver does not support bitvectors") .that(solver) - .isNoneOf(Solvers.SMTINTERPOL, Solvers.YICES2, Solvers.OPENSMT); + .isNoneOf(Solvers.SMTINTERPOL, Solvers.OPENSMT); } private void requireOptimization() { @@ -298,7 +298,7 @@ public void testFormulaTranslationWithConcurrentContexts() assume() .withMessage("Solver does not support translation of formulas") .that(solver) - .isNoneOf(Solvers.CVC4, Solvers.CVC5, Solvers.PRINCESS); + .isNoneOf(Solvers.CVC4, Solvers.CVC5, Solvers.PRINCESS, Solvers.YICES2); ConcurrentLinkedQueue contextAndFormulaList = new ConcurrentLinkedQueue<>(); @@ -535,7 +535,7 @@ public void continuousRunningThreadFormulaTransferTranslateTest() { assume() .withMessage("Solver does not support translation of formulas") .that(solver) - .isNoneOf(Solvers.CVC4, Solvers.CVC5, Solvers.PRINCESS); + .isNoneOf(Solvers.CVC4, Solvers.CVC5, Solvers.YICES2, Solvers.PRINCESS); // This is fine! We might access this more than once at a time, // but that gives only access to the bucket, which is threadsafe. From 376e4bc9c4f3ae71213059781407a09ebcd54762 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Thu, 11 Sep 2025 18:00:13 +0200 Subject: [PATCH 08/93] Yices: Enable VariableNamesTest.testBoolVariableDump() The issue has been fixed in the new version and "(" characters in variable names now get quoted --- src/org/sosy_lab/java_smt/test/VariableNamesTest.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/org/sosy_lab/java_smt/test/VariableNamesTest.java b/src/org/sosy_lab/java_smt/test/VariableNamesTest.java index 2f61eb09cd..459dd503bf 100644 --- a/src/org/sosy_lab/java_smt/test/VariableNamesTest.java +++ b/src/org/sosy_lab/java_smt/test/VariableNamesTest.java @@ -537,12 +537,6 @@ public Void visitAtom(BooleanFormula pAtom, FunctionDeclaration @Test public void testBoolVariableDump() { - // FIXME: Broken on yices2 - // Yices does not quote symbols when dumping a formula, f.ex for the variable "(" we get - // (declare-fun |(| () Bool) - // (assert () - // which is not a valid SMTLIB script. - assume().that(solverToUse()).isNotEqualTo(Solvers.YICES2); for (String name : getAllNames()) { BooleanFormula var = createVariableWith(bmgr::makeVariable, name); if (var != null) { From 2a6c45739e38c8eeb31b464f5b03883f7bc556a0 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Thu, 11 Sep 2025 18:00:45 +0200 Subject: [PATCH 09/93] Yices: Disable tests that are too slow --- .../test/BitvectorFormulaManagerTest.java | 5 +++++ .../java_smt/test/ProverEnvironmentTest.java | 16 ++++++++++++++++ .../test/SolverFormulaWithAssumptionsTest.java | 5 +++++ 3 files changed, 26 insertions(+) diff --git a/src/org/sosy_lab/java_smt/test/BitvectorFormulaManagerTest.java b/src/org/sosy_lab/java_smt/test/BitvectorFormulaManagerTest.java index e70e051ada..02cb8a269b 100644 --- a/src/org/sosy_lab/java_smt/test/BitvectorFormulaManagerTest.java +++ b/src/org/sosy_lab/java_smt/test/BitvectorFormulaManagerTest.java @@ -121,6 +121,11 @@ public void bvTooSmallNum() { @Test public void bvModelValue32bit() throws SolverException, InterruptedException { + assume() + .withMessage("Yices2 is too slow in this test") + .that(solver) + .isNotEqualTo(Solvers.YICES2); + BitvectorFormula var = bvmgr.makeVariable(32, "var"); Map values = new LinkedHashMap<>(); diff --git a/src/org/sosy_lab/java_smt/test/ProverEnvironmentTest.java b/src/org/sosy_lab/java_smt/test/ProverEnvironmentTest.java index 861d441372..903659f5fa 100644 --- a/src/org/sosy_lab/java_smt/test/ProverEnvironmentTest.java +++ b/src/org/sosy_lab/java_smt/test/ProverEnvironmentTest.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.Optional; import org.junit.Test; +import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Model; @@ -35,6 +36,11 @@ public class ProverEnvironmentTest extends SolverBasedTest0.ParameterizedSolverB @Test public void assumptionsTest() throws SolverException, InterruptedException { + assume() + .withMessage("Yices2 is too slow in this test") + .that(solver) + .isNotEqualTo(Solvers.YICES2); + BooleanFormula b = bmgr.makeVariable("b"); BooleanFormula c = bmgr.makeVariable("c"); @@ -54,6 +60,11 @@ public void assumptionsWithModelTest() throws SolverException, InterruptedExcept .withMessage("MathSAT can't construct models for SAT check with assumptions") .that(solver) .isNotEqualTo(MATHSAT5); + assume() + .withMessage("Yices2 is too slow in this test") + .that(solver) + .isNotEqualTo(Solvers.YICES2); + BooleanFormula b = bmgr.makeVariable("b"); BooleanFormula c = bmgr.makeVariable("c"); @@ -154,6 +165,11 @@ public void unsatCoreWithAssumptionsTest() throws SolverException, InterruptedEx @Test public void testSatWithUnsatUnsatCoreOptions() throws InterruptedException, SolverException { requireUnsatCore(); + assume() + .withMessage("Yices2 is too slow in this test") + .that(solver) + .isNotEqualTo(Solvers.YICES2); + try (ProverEnvironment prover = context.newProverEnvironment(GENERATE_UNSAT_CORE)) { checkSimpleQuery(prover); } diff --git a/src/org/sosy_lab/java_smt/test/SolverFormulaWithAssumptionsTest.java b/src/org/sosy_lab/java_smt/test/SolverFormulaWithAssumptionsTest.java index 2bef74b3ef..5eb1edcb47 100644 --- a/src/org/sosy_lab/java_smt/test/SolverFormulaWithAssumptionsTest.java +++ b/src/org/sosy_lab/java_smt/test/SolverFormulaWithAssumptionsTest.java @@ -184,6 +184,11 @@ public void assumptionsTest1() throws SolverException, InterruptedException { (check-sat-assumptions (A)) */ + assume() + .withMessage("Yices2 is too slow in this test") + .that(solver) + .isNotEqualTo(Solvers.YICES2); + BooleanFormula a = bmgr.makeVariable("a"); try (ProverEnvironment pe = context.newProverEnvironment()) { pe.push(); From 61445a9ed813cdb272c12b9db8ee1c4942ad2a2c Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Thu, 11 Sep 2025 18:31:41 +0200 Subject: [PATCH 10/93] YIces: Fix handling of solver errors --- .../solvers/yices2/Yices2NativeApi.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java index 94bf345b92..167442bb22 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java @@ -10,6 +10,7 @@ import java.util.function.Supplier; import org.sosy_lab.common.ShutdownNotifier; +import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.basicimpl.ShutdownHook; @SuppressWarnings({"unused", "checkstyle:methodname", "checkstyle:parametername"}) @@ -688,7 +689,7 @@ public static native int yices_check_context_with_assumptions( * @param params Set to 0 for default search parameters. */ public static boolean yices_check_sat(long ctx, long params, ShutdownNotifier shutdownNotifier) - throws IllegalStateException, InterruptedException { + throws IllegalStateException, InterruptedException, SolverException { return satCheckWithShutdownNotifier( () -> yices_check_context(ctx, params), ctx, shutdownNotifier); } @@ -698,7 +699,7 @@ public static boolean yices_check_sat(long ctx, long params, ShutdownNotifier sh */ public static boolean yices_check_sat_with_assumptions( long ctx, long params, int size, int[] assumptions, ShutdownNotifier shutdownNotifier) - throws InterruptedException { + throws InterruptedException, SolverException { return satCheckWithShutdownNotifier( () -> yices_check_context_with_assumptions(ctx, params, size, assumptions), ctx, @@ -708,7 +709,7 @@ public static boolean yices_check_sat_with_assumptions( @SuppressWarnings("try") private static boolean satCheckWithShutdownNotifier( Supplier satCheck, long pCtx, ShutdownNotifier shutdownNotifier) - throws InterruptedException { + throws InterruptedException, SolverException { int result; try (ShutdownHook hook = new ShutdownHook(shutdownNotifier, () -> yices_stop_search(pCtx))) { shutdownNotifier.shutdownIfNecessary(); @@ -718,16 +719,18 @@ private static boolean satCheckWithShutdownNotifier( return check_result(result); } - private static boolean check_result(int result) { + private static boolean check_result(int result) throws InterruptedException, SolverException { switch (result) { case YICES_STATUS_SAT: return true; case YICES_STATUS_UNSAT: return false; + case YICES_STATUS_INTERRUPTED: + throw new InterruptedException(); + case YICES_STATUS_ERROR: + throw new SolverException("SAT check returned \"unknown\""); default: - // TODO Further ERROR CLARIFICATION - String code = (result == YICES_STATUS_UNKNOWN) ? "\"unknown\"" : result + ""; - throw new IllegalStateException("Yices check returned:" + code); + throw new SolverException("Internal solver exception"); } } From 732b0f1b7b54f106aa9696e6138cf4e0559624e8 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Mon, 2 Feb 2026 14:06:35 +0100 Subject: [PATCH 11/93] Add missing import --- .../sosy_lab/java_smt/test/SolverFormulaWithAssumptionsTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/org/sosy_lab/java_smt/test/SolverFormulaWithAssumptionsTest.java b/src/org/sosy_lab/java_smt/test/SolverFormulaWithAssumptionsTest.java index 61c67c8898..afd33723fe 100644 --- a/src/org/sosy_lab/java_smt/test/SolverFormulaWithAssumptionsTest.java +++ b/src/org/sosy_lab/java_smt/test/SolverFormulaWithAssumptionsTest.java @@ -19,6 +19,7 @@ import java.util.List; import org.junit.Test; import org.sosy_lab.common.configuration.InvalidConfigurationException; +import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.InterpolatingProverEnvironment; import org.sosy_lab.java_smt.api.NumeralFormula.IntegerFormula; From c26f145dcc366c6a73b6f7de045d1008ecca313d Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Mon, 2 Feb 2026 14:40:12 +0100 Subject: [PATCH 12/93] Yices2: Use install paths in the compilation script --- lib/native/source/yices2j/compile.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/native/source/yices2j/compile.sh b/lib/native/source/yices2j/compile.sh index 57b5d1daf9..976318dbbc 100755 --- a/lib/native/source/yices2j/compile.sh +++ b/lib/native/source/yices2j/compile.sh @@ -34,10 +34,10 @@ cd ${DIR} JNI_HEADERS="$(../get_jni_headers.sh)" -YICES_SRC_DIR="$1"/src/include -YICES_LIB_DIR="$1"/build/x86_64-pc-linux-gnu-release/lib/ -GMP_HEADER_DIR="$2" -GMP_LIB_DIR=$GMP_HEADER_DIR/.libs +YICES_SRC_DIR="$1"/include +YICES_LIB_DIR="$1"/lib +GMP_HEADER_DIR="$2"/include +GMP_LIB_DIR="$2"/lib GPERF_HEADER_DIR="$3" GPERF_LIB_DIR=$GPERF_HEADER_DIR/lib From 0ee98150ea64b87745107fb32cc25dd3c7b9dd75 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Mon, 2 Feb 2026 14:41:59 +0100 Subject: [PATCH 13/93] Yices2: Update build instructions --- doc/Developers-How-to-Release-into-Ivy.md | 33 ++++++++++++++++++----- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/doc/Developers-How-to-Release-into-Ivy.md b/doc/Developers-How-to-Release-into-Ivy.md index c462daff9a..e40eccf017 100644 --- a/doc/Developers-How-to-Release-into-Ivy.md +++ b/doc/Developers-How-to-Release-into-Ivy.md @@ -339,19 +339,34 @@ ant publish-optimathsat \ ### Publishing Yices2 Yices2 consists of two components: the solver binary and the Java components in JavaSMT. -The Java components were splitt from the rest of JavaSMT because of the GPL. +The Java components were split from the rest of JavaSMT because of the GPL. #### Publishing the solver binary for Yices2 -Prepare gperf and gmp (required for our own static binary): +We recommend using one of our Ubuntu docker images for building Yices2 as the container already +contains one of the dependencies (`gmp`) in a precompiled version. The following instructions will +still work without the image, however, some of the paths may have to be adjusted, and `gmp` +needs to be downloaded and compiled (with `PIC` support) separately + +Prepare `gperf` (a dependency of Yices2, and not inluded in the docker image): ```bash -wget http://ftp.gnu.org/pub/gnu/gperf/gperf-3.1.tar.gz && tar -zxvf gperf-3.1.tar.gz && cd gperf-3.1 && ./configure --enable-cxx --with-pic --disable-shared --enable-fat && make -wget https://gmplib.org/download/gmp/gmp-6.2.0.tar.xz && tar -xvf gmp-6.2.0.tar.xz && cd gmp-6.2.0 && ./configure --enable-cxx --with-pic --disable-shared --enable-fat && make +wget http://ftp.gnu.org/pub/gnu/gperf/gperf-3.3.tar.gz +tar -zxvf gperf-3.3.tar.gz +cd gperf-3.3 +./configure --enable-cxx --with-pic --disable-shared --enable-fat +make -j ``` Download and build Yices2 from source: ```bash -git clone git@github.com:SRI-CSL/yices2.git && cd yices2 && autoconf && ./configure --with-pic-gmp=../gmp-6.2.0/.libs/libgmp.a && make +git clone git@github.com:SRI-CSL/yices2.git +cd yices2 +autoconf +export LDFLAGS=-L/dependencies/gmp-6.3.0/install/x64-linux/lib +export CFLAGS=-I/dependencies/gmp-6.3.0/install/x64-linux/include +./configure --enable-thread-safety --prefix=/workspace/yices2/install +make -j +make install ``` Get the version of Yices2: @@ -359,9 +374,13 @@ Get the version of Yices2: git describe --tags ``` -Publish the solver binary from within JavaSMT (adjust all paths to your system!): +Publish the solver binary from within JavaSMT: ```bash -ant publish-yices2 -Dyices2.path=../solvers/yices2 -Dgmp.path=../solvers/gmp-6.2.0 -Dgperf.path=../solvers/gperf-3.1 -Dyices2.version=2.6.2-89-g0f77dc4b +ant publish-yices2 \ + -Dyices2.path=/workspace/yices2/install \ + -Dgmp.path=/dependencies/gmp-6.3.0/install/x64-linux \ + -Dgperf.path=/workspace/gperf-3.3 \ + -Dyices2.version=2.7.0-g85cf17e4 ``` Afterward, you need to update the version number in `solvers_ivy_conf/ivy_javasmt_yices2.xml` and publish new Java components for Yices2. From 1385e77fb7e507b8df2c2d7b2d3f09acee1f3c83 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Mon, 2 Mar 2026 15:45:45 +0100 Subject: [PATCH 14/93] Yices: Remove 32bit build option --- lib/native/source/yices2j/compile.sh | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/lib/native/source/yices2j/compile.sh b/lib/native/source/yices2j/compile.sh index 976318dbbc..73aa5b5da0 100755 --- a/lib/native/source/yices2j/compile.sh +++ b/lib/native/source/yices2j/compile.sh @@ -75,19 +75,12 @@ echo "Linking libraries together into one file..." # This will link together the file produced above, the Yices library, the GMP library and the standard libraries. # Everything except the standard libraries is included statically. # The result is a single shared library containing all necessary components. -if [ `uname -m` = "x86_64" ]; then - gcc -Wall -g -o $OUT_FILE -shared -Wl,-soname,libyices2j.so \ +gcc -Wall -g -o $OUT_FILE -shared -Wl,-soname,libyices2j.so \ -L. -L$YICES_LIB_DIR -L$GMP_LIB_DIR -L$GPERF_LIB_DIR \ -I$GMP_HEADER_DIR -I$GPERF_HEADER_DIR $OBJ_FILES -Wl,-Bstatic \ -lyices -lgmpxx -lgmp -lgp -static-libstdc++ -lstdc++ \ -Wl,-Bdynamic -lc -lm -Wl,--version-script=libyices2j.version -else - # TODO compiling for/on a 32bit system was not done for quite a long time. We should drop it. - gcc -Wall -g -o ${OUT_FILE} -shared -Wl,-soname,libyices2j.so \ - -L${YICES_LIB_DIR} -L${GMP_LIB_DIR} -L${GPERF_LIB_DIR} \ - -I${GMP_HEADER_DIR} -I${GPERF_HEADER_DIR} ${OBJ_FILES} \ - -Wl,-Bstatic -lyices -lgmpxx -lgmp -Wl,-Bdynamic -lc -lm -lstdc++ -fi + if [ $? -ne 0 ]; then echo "There was a problem during compilation of \"org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c\"" From 11267ec6049c903c1a435d70f19b68bd934c131d Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Mon, 2 Mar 2026 15:49:25 +0100 Subject: [PATCH 15/93] Yices: Update build script for MCSAT --- build/build-publish-solvers/solver-yices.xml | 13 +++++---- lib/native/source/yices2j/compile.sh | 29 ++++++++++++-------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/build/build-publish-solvers/solver-yices.xml b/build/build-publish-solvers/solver-yices.xml index 3b2b36decf..d3b27f89a4 100644 --- a/build/build-publish-solvers/solver-yices.xml +++ b/build/build-publish-solvers/solver-yices.xml @@ -20,11 +20,14 @@ SPDX-License-Identifier: Apache-2.0 - - - - - + + + + + + + + diff --git a/lib/native/source/yices2j/compile.sh b/lib/native/source/yices2j/compile.sh index 73aa5b5da0..f697ccd769 100755 --- a/lib/native/source/yices2j/compile.sh +++ b/lib/native/source/yices2j/compile.sh @@ -34,12 +34,14 @@ cd ${DIR} JNI_HEADERS="$(../get_jni_headers.sh)" -YICES_SRC_DIR="$1"/include +YICES_HEADER_DIR="$1"/include YICES_LIB_DIR="$1"/lib + GMP_HEADER_DIR="$2"/include GMP_LIB_DIR="$2"/lib -GPERF_HEADER_DIR="$3" -GPERF_LIB_DIR=$GPERF_HEADER_DIR/lib + +POLY_LIB_DIR="$3"/lib +CUDD_LIB_DIR="$4"/lib # check requirements if [ ! -f "$YICES_LIB_DIR/libyices.a" ]; then @@ -52,10 +54,15 @@ if [ ! -f "$GMP_LIB_DIR/libgmp.a" ]; then echo "Can not find $GMP_LIB_DIR/libgmp.a" exit 1 fi -if [ ! -f "$GPERF_LIB_DIR/libgp.a" ]; then - echo "You need to specify the GPERF directory on the command line!" - echo "Can not find $GPERF_LIB_DIR/libgp.a" - exit 1 +if [ ! -f "$POLY_LIB_DIR/libpoly.a" ]; then + echo "You need to specify the Libpoly directory on the command line!" + echo "Can not find $POLY_LIB_DIR/libpoly.a" + exit 1 +fi +if [ ! -f "$CUDD_LIB_DIR/libcudd.a" ]; then + echo "You need to specify the CUDD directory on the command line!" + echo "Can not find $CUDD_LIB_DIR/libcudd.a" + exit 1 fi SRC_FILES="org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c" @@ -67,7 +74,7 @@ echo "Compiling the C wrapper code and creating the \"$OUT_FILE\" library..." # This will compile the JNI wrapper part, given the JNI and the Yices header files gcc -g -std=gnu99 -Wall -Wextra -Wpedantic -Wno-return-type -Wno-unused-parameter \ - $JNI_HEADERS -I$YICES_SRC_DIR -I$GMP_HEADER_DIR -I$GPERF_HEADER_DIR $SRC_FILES -fPIC -c + $JNI_HEADERS -I$YICES_HEADER_DIR -I$GMP_HEADER_DIR $SRC_FILES -fPIC -c echo "Compilation Done" echo "Linking libraries together into one file..." @@ -76,9 +83,9 @@ echo "Linking libraries together into one file..." # Everything except the standard libraries is included statically. # The result is a single shared library containing all necessary components. gcc -Wall -g -o $OUT_FILE -shared -Wl,-soname,libyices2j.so \ - -L. -L$YICES_LIB_DIR -L$GMP_LIB_DIR -L$GPERF_LIB_DIR \ - -I$GMP_HEADER_DIR -I$GPERF_HEADER_DIR $OBJ_FILES -Wl,-Bstatic \ - -lyices -lgmpxx -lgmp -lgp -static-libstdc++ -lstdc++ \ + -L$YICES_LIB_DIR -L$GMP_LIB_DIR -L$POLY_LIB_DIR -L$CUDD_LIB_DIR \ + -I$GMP_HEADER_DIR $OBJ_FILES -Wl,-Bstatic \ + -lyices -lcudd -lpoly -lgmpxx -lgmp -static-libstdc++ -lstdc++ \ -Wl,-Bdynamic -lc -lm -Wl,--version-script=libyices2j.version From dfaedbcab54b49a89fb789f8e9261545e1d401b4 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Mon, 2 Mar 2026 16:29:01 +0100 Subject: [PATCH 16/93] Yices: Update build instructions --- doc/Developers-How-to-Release-into-Ivy.md | 63 ++++++++++++++++------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/doc/Developers-How-to-Release-into-Ivy.md b/doc/Developers-How-to-Release-into-Ivy.md index e40eccf017..f3d6178796 100644 --- a/doc/Developers-How-to-Release-into-Ivy.md +++ b/doc/Developers-How-to-Release-into-Ivy.md @@ -348,39 +348,64 @@ contains one of the dependencies (`gmp`) in a precompiled version. The following still work without the image, however, some of the paths may have to be adjusted, and `gmp` needs to be downloaded and compiled (with `PIC` support) separately -Prepare `gperf` (a dependency of Yices2, and not inluded in the docker image): -```bash -wget http://ftp.gnu.org/pub/gnu/gperf/gperf-3.3.tar.gz -tar -zxvf gperf-3.3.tar.gz -cd gperf-3.3 -./configure --enable-cxx --with-pic --disable-shared --enable-fat +#### MCSAT build + +First we need to fetch and build two dependencies: + +- libpoly: + +```shell +git clone https://github.com/SRI-CSL/libpoly.git +cd libpoly +cmake .. -DCMAKE_BUILD_TYPE="Release" \ + -DCMAKE_INSTALL_PREFIX=/workspace/libpoly/install \ + -DGMP_INCLUDE_DIR=/dependencies/gmp-6.3.0/install/x64-linux/include \ + -DGMP_LIBRARY=/dependencies/gmp-6.3.0/install/x64-linux/lib/libgmp.a make -j +make install ``` -Download and build Yices2 from source: -```bash -git clone git@github.com:SRI-CSL/yices2.git -cd yices2 -autoconf -export LDFLAGS=-L/dependencies/gmp-6.3.0/install/x64-linux/lib -export CFLAGS=-I/dependencies/gmp-6.3.0/install/x64-linux/include -./configure --enable-thread-safety --prefix=/workspace/yices2/install +- cudd + +```shell +git clone https://github.com/ivmai/cudd.git +cd cudd +export CFLAGS=-fPIC +./configure --prefix=/workspace/cudd/install + +# Then patch `autoconf`, `automake`, etc in the Makefile make -j make install ``` -Get the version of Yices2: +#### Yices + +Then we can build the actual solver: + +```shell +LDFLAGS="-L/dependencies/gmp-6.3.0/install/x64-linux/lib -L/workspace/libpoly/install/lib -L/workspace/cudd/install/lib" \ +CFLAGS="-I/dependencies/gmp-6.3.0/install/x64-linux/include -I/workspace/libpoly/install/include -I/workspace/cudd/install/include" \ +./configure --enable-mcsat --prefix=/workspace/yices2/install +make -j +make install +``` + +#### JavaSMT solver binary + +First, get the version of Yices2: ```bash git describe --tags ``` -Publish the solver binary from within JavaSMT: -```bash +Then publish the solver binary from within JavaSMT: + +```shell ant publish-yices2 \ -Dyices2.path=/workspace/yices2/install \ -Dgmp.path=/dependencies/gmp-6.3.0/install/x64-linux \ - -Dgperf.path=/workspace/gperf-3.3 \ - -Dyices2.version=2.7.0-g85cf17e4 + -Dlibpoly.path=/workspace/libpoly/install \ + -Dcudd.path=/workspace/cudd/install \ + -Dyices2.version=${VERSION} ``` Afterward, you need to update the version number in `solvers_ivy_conf/ivy_javasmt_yices2.xml` and publish new Java components for Yices2. From 8a35eb6509e1e265720b0040820547c7dfc58eab Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Mon, 2 Mar 2026 17:11:46 +0100 Subject: [PATCH 17/93] Yices: Update tests --- .../java_smt/solvers/yices2/Yices2NativeApiTest.java | 7 ++++--- .../java_smt/test/BitvectorFormulaManagerTest.java | 5 ----- src/org/sosy_lab/java_smt/test/SolverConcurrencyTest.java | 4 ++++ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java index 33761613df..70803c71e3 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java @@ -610,13 +610,14 @@ public void bvMul() { @Test public void isThreadSafe() { - // Check that we compiled with --thread-safety to make it reentrant - assertThat(yices_is_thread_safe()).isEqualTo(1); + // We did not compile with --thread-safety as the option can't be combined with mcsat support + assertThat(yices_is_thread_safe()).isEqualTo(0); } @Test public void hasMCSat() { - assertThat(yices_has_mcsat()).isEqualTo(0); + // Checkt that we compiled wiht --enable-mcsat + assertThat(yices_has_mcsat()).isEqualTo(1); } @Test diff --git a/src/org/sosy_lab/java_smt/test/BitvectorFormulaManagerTest.java b/src/org/sosy_lab/java_smt/test/BitvectorFormulaManagerTest.java index 478b2cd994..60dcabfd9e 100644 --- a/src/org/sosy_lab/java_smt/test/BitvectorFormulaManagerTest.java +++ b/src/org/sosy_lab/java_smt/test/BitvectorFormulaManagerTest.java @@ -121,11 +121,6 @@ public void bvTooSmallNum() { @Test public void bvModelValue32bit() throws SolverException, InterruptedException { - assume() - .withMessage("Yices2 is too slow in this test") - .that(solver) - .isNotEqualTo(Solvers.YICES2); - BitvectorFormula var = bvmgr.makeVariable(32, "var"); Map values = new LinkedHashMap<>(); diff --git a/src/org/sosy_lab/java_smt/test/SolverConcurrencyTest.java b/src/org/sosy_lab/java_smt/test/SolverConcurrencyTest.java index 1d0f7f86bf..7d14b51663 100644 --- a/src/org/sosy_lab/java_smt/test/SolverConcurrencyTest.java +++ b/src/org/sosy_lab/java_smt/test/SolverConcurrencyTest.java @@ -124,6 +124,10 @@ public void checkThatSolverIsAvailable() throws InvalidConfigurationException { .that(solver) .isNotEqualTo(Solvers.MATHSAT5); } + assume() + .withMessage("Yices2 with MCSAT support is not reentrant") + .that(solver) + .isNotEqualTo(Solvers.YICES2); } private void requireConcurrentMultipleStackSupport() { From f0812393152678dcd05692a084676049bdf789c3 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Tue, 3 Mar 2026 16:38:33 +0100 Subject: [PATCH 18/93] Yices: Use MCSAT in JavaSMT --- .../yices2/Yices2IntegerFormulaManager.java | 10 +--------- .../solvers/yices2/Yices2NativeApiTest.java | 19 ++++++++++++------- .../yices2/Yices2NumeralFormulaManager.java | 6 +----- .../yices2/Yices2RationalFormulaManager.java | 6 +----- .../solvers/yices2/Yices2TheoremProver.java | 4 ++-- .../test/BitvectorFormulaManagerTest.java | 3 +++ src/org/sosy_lab/java_smt/test/ModelTest.java | 1 + .../test/NonLinearArithmeticTest.java | 3 +-- .../java_smt/test/SolverTheoriesTest.java | 11 ----------- 9 files changed, 22 insertions(+), 41 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2IntegerFormulaManager.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2IntegerFormulaManager.java index 0d0049dd6d..d5410cd12e 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2IntegerFormulaManager.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2IntegerFormulaManager.java @@ -42,20 +42,12 @@ protected Integer makeNumberImpl(BigDecimal pNumber) { @Override public Integer divide(Integer pParam1, Integer pParam2) { - if (isNumeral(pParam2)) { - return yices_idiv(pParam1, pParam2); - } else { - return super.divide(pParam1, pParam2); - } + return yices_idiv(pParam1, pParam2); } @Override public Integer modulo(Integer pParam1, Integer pParam2) { - if (isNumeral(pParam2)) { return yices_imod(pParam1, pParam2); - } else { - return super.modulo(pParam1, pParam2); - } } @Override diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java index 70803c71e3..be92b099ce 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java @@ -123,15 +123,20 @@ public static void loadYices() { private long env; + private long newContext(boolean mcsat) { + var cfg = yices_new_config(); + yices_set_config(cfg, "solver-type", mcsat ? "mcsat" : "dpllt"); + yices_set_config(cfg, "mode", "interactive"); + var context = yices_new_context(cfg); + yices_context_disable_option(context, "var-elim"); + yices_free_config(cfg); + return context; + } + @Before public void createEnvironment() { yices_init(); - long cfg = yices_new_config(); - yices_set_config(cfg, "solver-type", "dpllt"); - yices_set_config(cfg, "mode", "push-pop"); - env = yices_new_context(cfg); - yices_context_disable_option(env, "var-elim"); - yices_free_config(cfg); + env = newContext(false); } @After @@ -616,7 +621,7 @@ public void isThreadSafe() { @Test public void hasMCSat() { - // Checkt that we compiled wiht --enable-mcsat + // Check that we compiled with --enable-mcsat assertThat(yices_has_mcsat()).isEqualTo(1); } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NumeralFormulaManager.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NumeralFormulaManager.java index 48d8bb4d75..cca73ecbfa 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NumeralFormulaManager.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NumeralFormulaManager.java @@ -91,11 +91,7 @@ public Integer subtract(Integer pParam1, Integer pParam2) { @Override public Integer multiply(Integer pParam1, Integer pParam2) { - if (isNumeral(pParam1) || isNumeral(pParam2)) { - return yices_mul(pParam1, pParam2); - } else { - return super.multiply(pParam1, pParam2); - } + return yices_mul(pParam1, pParam2); } @Override diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2RationalFormulaManager.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2RationalFormulaManager.java index 8f3791a8f6..eb62dfd2cc 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2RationalFormulaManager.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2RationalFormulaManager.java @@ -41,10 +41,6 @@ protected Integer makeNumberImpl(BigDecimal pNumber) { @Override public Integer divide(Integer pParam1, Integer pParam2) { - if (isNumeral(pParam2)) { - return yices_division(pParam1, pParam2); - } else { - return super.divide(pParam1, pParam2); - } + return yices_division(pParam1, pParam2); } } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java index 9d4ee2aaf8..61a367ff2d 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java @@ -75,8 +75,8 @@ protected Yices2TheoremProver( super(pOptions, pBmgr, pShutdownNotifier); this.creator = creator; curCfg = yices_new_config(); - yices_set_config(curCfg, "solver-type", "dpllt"); - yices_set_config(curCfg, "mode", "push-pop"); + yices_set_config(curCfg, "solver-type", "mcsat"); + yices_set_config(curCfg, "mode", "interactive"); curEnv = yices_new_context(curCfg); } diff --git a/src/org/sosy_lab/java_smt/test/BitvectorFormulaManagerTest.java b/src/org/sosy_lab/java_smt/test/BitvectorFormulaManagerTest.java index 60dcabfd9e..5f90f5c4b1 100644 --- a/src/org/sosy_lab/java_smt/test/BitvectorFormulaManagerTest.java +++ b/src/org/sosy_lab/java_smt/test/BitvectorFormulaManagerTest.java @@ -466,6 +466,9 @@ public void bvRotateByConstant() throws SolverException, InterruptedException { public void bvRotateByBV() throws SolverException, InterruptedException { int[] bitsizes; switch (solverToUse()) { + case YICES2: + bitsizes = new int[] {2, 3, 4, 8}; + break; case PRINCESS: bitsizes = new int[] {2, 3}; // Princess is too slow for larger bitvectors break; diff --git a/src/org/sosy_lab/java_smt/test/ModelTest.java b/src/org/sosy_lab/java_smt/test/ModelTest.java index ea6a34b39f..b46ea29c15 100644 --- a/src/org/sosy_lab/java_smt/test/ModelTest.java +++ b/src/org/sosy_lab/java_smt/test/ModelTest.java @@ -2613,6 +2613,7 @@ public void testArray1BvBV() { requireArrays(); requireBitvectors(); + assume().that(solver).isNotEqualTo(Solvers.YICES2); // FIXME Segfaults assume().that(solver).isNotEqualTo(Solvers.BOOLECTOR); // Doesn't support multiple indices var bitvectorType = FormulaType.getBitvectorTypeWithSize(8); diff --git a/src/org/sosy_lab/java_smt/test/NonLinearArithmeticTest.java b/src/org/sosy_lab/java_smt/test/NonLinearArithmeticTest.java index e5650b8ba0..6755e78abb 100644 --- a/src/org/sosy_lab/java_smt/test/NonLinearArithmeticTest.java +++ b/src/org/sosy_lab/java_smt/test/NonLinearArithmeticTest.java @@ -45,7 +45,6 @@ public class NonLinearArithmeticTest extends SolverBas Solvers.MATHSAT5, Solvers.BOOLECTOR, Solvers.CVC4, - Solvers.YICES2, Solvers.OPENSMT); @Parameters(name = "{0} {1} {2}") @@ -204,7 +203,7 @@ public void testDivisionByZero() throws SolverException, InterruptedException { assume() .withMessage("Solver %s does not support division by zero", solverToUse()) .that(solverToUse()) - .isNoneOf(Solvers.YICES2, Solvers.OPENSMT); + .isNotEqualTo(Solvers.OPENSMT); T a = nmgr.makeVariable("a"); T b = nmgr.makeVariable("b"); diff --git a/src/org/sosy_lab/java_smt/test/SolverTheoriesTest.java b/src/org/sosy_lab/java_smt/test/SolverTheoriesTest.java index fdd6dff6e2..0faaca0846 100644 --- a/src/org/sosy_lab/java_smt/test/SolverTheoriesTest.java +++ b/src/org/sosy_lab/java_smt/test/SolverTheoriesTest.java @@ -283,11 +283,6 @@ public void intTest3_DivModLinear_zeroDenominator() throws SolverException, Inte // SMTLIB allows any value for division-by-zero. switch (solverToUse()) { - case YICES2: - assertThrows( - IllegalArgumentException.class, - () -> assertThatFormula(buildDivision(num10, num0, num10)).isSatisfiable()); - break; case OPENSMT: // INFO: OpenSMT does not allow division by zero assertThrows( UnsupportedOperationException.class, @@ -308,11 +303,6 @@ public void intTest3_DivModLinear_zeroDenominator() throws SolverException, Inte } switch (solverToUse()) { - case YICES2: - assertThrows( - IllegalArgumentException.class, - () -> assertThatFormula(buildModulo(num10, num0, num10)).isSatisfiable()); - break; case OPENSMT: // INFO: OpenSMT does not allow division by zero assertThrows(UnsupportedOperationException.class, () -> buildModulo(num10, num0, num10)); break; @@ -354,7 +344,6 @@ public void intTest3_DivModNonLinear() throws SolverException, InterruptedExcept switch (solverToUse()) { case OPENSMT: // INFO: OpenSmt does not allow nonlinear terms case SMTINTERPOL: - case YICES2: assertThrows(UnsupportedOperationException.class, () -> buildDivision(a, b, num5)); assertThrows(UnsupportedOperationException.class, () -> buildModulo(a, b, num0)); break; From 54cad9f34dfb7781d5664484064fd0a4b8b395b3 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Tue, 3 Mar 2026 17:52:11 +0100 Subject: [PATCH 19/93] Yices: Add interpolation to JNI bindings --- ...java_1smt_solvers_yices2_Yices2NativeApi.c | 25 +++++++++++++++++++ .../solvers/yices2/Yices2NativeApi.java | 7 ++++++ .../solvers/yices2/Yices2NativeApiTest.java | 22 ++++++++++++++-- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/lib/native/source/yices2j/org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c b/lib/native/source/yices2j/org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c index c63236b3e9..60c31766e1 100644 --- a/lib/native/source/yices2j/org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c +++ b/lib/native/source/yices2j/org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c @@ -1662,3 +1662,28 @@ TERM_ARG(2) TERM_VECTOR_ARG(3) CALL3(int, model_term_support) TERM_VECTOR_ARG_RETURN(3) +y +__attribute__((visibility("default"))) jjterm Java_org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi_yices_1interpolate(JNIEnv *jenv, jclass jcls, jlong jarg1, jlong jarg2) { + jint jresult = 0; + context_t *arg1 = 0; + context_t *arg2 = 0; + term_t result; + + (void)jenv; + (void)jcls; + arg1 = *(context_t **)&jarg1; + arg2 = *(context_t **)&jarg2; + + interpolation_context_t context = {arg1, arg2, 0, 0}; + smt_status_t c = yices_check_context_with_interpolation(&context, 0, 0); + if (c == YICES_STATUS_SAT) { + throwException(jenv, "java/lang/RuntimeException", "Problem is SAT"); + } + if (c == YICES_STATUS_ERROR) { + throwEx ception(jenv, "java/lang/RuntimeException", "Error during interpolation"); + } + + result = context.interpolant; + jresult = (jint)result; + return jresult; +} diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java index ec33261900..76ff3a3c23 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java @@ -860,4 +860,11 @@ public static native int yices_check_formulas( * @return term_vector (NOT int with error code) that is supported. Empty if error! */ public static native int[] yices_model_term_support(long model, int term); + + /** + * Calculate an interpolant. + * + *

Requires MCSAT, and expects the contexts to be unsatisfiable + */ + public static native int yices_interpolate(long ctxA, long ctxB); } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java index be92b099ce..d948d3a261 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java @@ -43,7 +43,6 @@ import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvsum_component; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvxor2; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_check_context; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_context_disable_option; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_eq; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_exists; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_exit; @@ -61,6 +60,7 @@ import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_int32; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_int64; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_int_type; +import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_interpolate; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_is_thread_safe; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_mul; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_new_config; @@ -127,8 +127,8 @@ private long newContext(boolean mcsat) { var cfg = yices_new_config(); yices_set_config(cfg, "solver-type", mcsat ? "mcsat" : "dpllt"); yices_set_config(cfg, "mode", "interactive"); + yices_set_config(cfg, "model-interpolation", "true"); var context = yices_new_context(cfg); - yices_context_disable_option(context, "var-elim"); yices_free_config(cfg); return context; } @@ -639,6 +639,24 @@ public void quantifierTest() { assertThat(yices_term_constructor(yices_term_child(exists, 0))).isEqualTo(YICES_FORALL_TERM); } + @Test + public void booleanInterpolationTest() { + var boolType = yices_bool_type(); + var a = yices_named_variable(boolType, "a"); + + var ctxA = newContext(true); + var ctxB = newContext(true); + + yices_assert_formula(ctxA, a); + yices_assert_formula(ctxB, yices_not(a)); + var itp = yices_interpolate(ctxA, ctxB); + + assertThat(itp).isEqualTo(a); + + yices_free_context(ctxB); + yices_free_context(ctxA); + } + /** * Only to be used for tests in this class. Old implementation used for creating/retrieving named * variables. Superseded by {@link Yices2FormulaCreator#createNamedVariable} for reasons outlined From 5ea582cfa07493b91c2c4b2bc708f0b1a3135220 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Tue, 3 Mar 2026 18:36:55 +0100 Subject: [PATCH 20/93] Fix editing mistake --- .../org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/native/source/yices2j/org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c b/lib/native/source/yices2j/org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c index 60c31766e1..f8ad3f5ee5 100644 --- a/lib/native/source/yices2j/org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c +++ b/lib/native/source/yices2j/org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c @@ -1662,7 +1662,7 @@ TERM_ARG(2) TERM_VECTOR_ARG(3) CALL3(int, model_term_support) TERM_VECTOR_ARG_RETURN(3) -y + __attribute__((visibility("default"))) jjterm Java_org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi_yices_1interpolate(JNIEnv *jenv, jclass jcls, jlong jarg1, jlong jarg2) { jint jresult = 0; context_t *arg1 = 0; @@ -1680,7 +1680,7 @@ __attribute__((visibility("default"))) jjterm Java_org_sosy_1lab_java_1smt_solve throwException(jenv, "java/lang/RuntimeException", "Problem is SAT"); } if (c == YICES_STATUS_ERROR) { - throwEx ception(jenv, "java/lang/RuntimeException", "Error during interpolation"); + throwException(jenv, "java/lang/RuntimeException", "Error during interpolation"); } result = context.interpolant; From 4c00ba0cf1176704c492e4fc2459068a10ed180d Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Tue, 3 Mar 2026 19:13:55 +0100 Subject: [PATCH 21/93] Yices: Recompile with both thread safety and MCSAT support Despite what the website says, both options appear to be compatible. However, there are some issues, possibly linked to unsat core, where Yices fails to terminate --- .../java_smt/solvers/yices2/Yices2NativeApiTest.java | 4 ++-- .../java_smt/test/BitvectorFormulaManagerTest.java | 5 +++++ .../java_smt/test/BooleanFormulaSubjectTest.java | 7 +++++++ .../java_smt/test/ProverEnvironmentSubjectTest.java | 7 +++++++ .../sosy_lab/java_smt/test/ProverEnvironmentTest.java | 11 +++++++++++ .../sosy_lab/java_smt/test/SolverConcurrencyTest.java | 4 ---- .../test/SolverFormulaWithAssumptionsTest.java | 6 ++++++ src/org/sosy_lab/java_smt/test/UnsatCoreTest.java | 9 +++++++++ 8 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java index d948d3a261..1302f29488 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java @@ -615,8 +615,8 @@ public void bvMul() { @Test public void isThreadSafe() { - // We did not compile with --thread-safety as the option can't be combined with mcsat support - assertThat(yices_is_thread_safe()).isEqualTo(0); + // Check that we compiled with --thread-safety to make it reentrant + assertThat(yices_is_thread_safe()).isEqualTo(1); } @Test diff --git a/src/org/sosy_lab/java_smt/test/BitvectorFormulaManagerTest.java b/src/org/sosy_lab/java_smt/test/BitvectorFormulaManagerTest.java index 5f90f5c4b1..10889f385b 100644 --- a/src/org/sosy_lab/java_smt/test/BitvectorFormulaManagerTest.java +++ b/src/org/sosy_lab/java_smt/test/BitvectorFormulaManagerTest.java @@ -121,6 +121,11 @@ public void bvTooSmallNum() { @Test public void bvModelValue32bit() throws SolverException, InterruptedException { + assume() + .withMessage("Yices2 hangs in this test") + .that(solverToUse()) + .isNotEqualTo(Solvers.YICES2); + BitvectorFormula var = bvmgr.makeVariable(32, "var"); Map values = new LinkedHashMap<>(); diff --git a/src/org/sosy_lab/java_smt/test/BooleanFormulaSubjectTest.java b/src/org/sosy_lab/java_smt/test/BooleanFormulaSubjectTest.java index 93a067acdc..9a256a20e0 100644 --- a/src/org/sosy_lab/java_smt/test/BooleanFormulaSubjectTest.java +++ b/src/org/sosy_lab/java_smt/test/BooleanFormulaSubjectTest.java @@ -9,6 +9,7 @@ package org.sosy_lab.java_smt.test; import static com.google.common.truth.ExpectFailure.assertThat; +import static com.google.common.truth.TruthJUnit.assume; import static org.sosy_lab.java_smt.test.BooleanFormulaSubject.booleanFormulasOf; import com.google.common.base.Throwables; @@ -17,6 +18,7 @@ import com.google.common.truth.SimpleSubjectBuilder; import org.junit.Before; import org.junit.Test; +import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.SolverException; @@ -65,6 +67,11 @@ public void testIsSatisfiableYes() throws SolverException, InterruptedException @Test public void testIsSatisfiableNo() { requireUnsatCore(); + assume() + .withMessage("Yices2 hangs in this test") + .that(solverToUse()) + .isNotEqualTo(Solvers.YICES2); + AssertionError failure = expectFailure(whenTesting -> whenTesting.that(contradiction).isSatisfiable()); assertThat(failure).factValue("which has unsat core").isNotEmpty(); diff --git a/src/org/sosy_lab/java_smt/test/ProverEnvironmentSubjectTest.java b/src/org/sosy_lab/java_smt/test/ProverEnvironmentSubjectTest.java index 743ea4b7d4..72d9a95ed1 100644 --- a/src/org/sosy_lab/java_smt/test/ProverEnvironmentSubjectTest.java +++ b/src/org/sosy_lab/java_smt/test/ProverEnvironmentSubjectTest.java @@ -9,6 +9,7 @@ package org.sosy_lab.java_smt.test; import static com.google.common.truth.ExpectFailure.assertThat; +import static com.google.common.truth.TruthJUnit.assume; import static org.sosy_lab.java_smt.test.ProverEnvironmentSubject.proverEnvironments; import com.google.common.base.Throwables; @@ -17,6 +18,7 @@ import com.google.common.truth.SimpleSubjectBuilder; import org.junit.Before; import org.junit.Test; +import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.ProverEnvironment; @@ -53,6 +55,11 @@ public void testIsSatisfiableYes() throws SolverException, InterruptedException @Test public void testIsSatisfiableNo() throws InterruptedException { requireUnsatCore(); + assume() + .withMessage("Yices2 hangs in this test") + .that(solverToUse()) + .isNotEqualTo(Solvers.YICES2); + try (ProverEnvironment env = context.newProverEnvironment( ProverOptions.GENERATE_MODELS, ProverOptions.GENERATE_UNSAT_CORE)) { diff --git a/src/org/sosy_lab/java_smt/test/ProverEnvironmentTest.java b/src/org/sosy_lab/java_smt/test/ProverEnvironmentTest.java index b62deba03b..acee532ddf 100644 --- a/src/org/sosy_lab/java_smt/test/ProverEnvironmentTest.java +++ b/src/org/sosy_lab/java_smt/test/ProverEnvironmentTest.java @@ -10,6 +10,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.TruthJUnit.assume; import static org.junit.Assert.assertThrows; import static org.sosy_lab.java_smt.api.SolverContext.ProverOptions.GENERATE_UNSAT_CORE; import static org.sosy_lab.java_smt.api.SolverContext.ProverOptions.GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS; @@ -18,7 +19,9 @@ import com.google.common.collect.ImmutableList; import java.util.List; import java.util.Optional; +import org.junit.Before; import org.junit.Test; +import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Formula; @@ -29,6 +32,14 @@ public class ProverEnvironmentTest extends SolverBasedTest0.ParameterizedSolverBasedTest0 { + @Before + public void init() { + assume() + .withMessage("Yices2 hangs in this test") + .that(solverToUse()) + .isNotEqualTo(Solvers.YICES2); + } + @Test public void assumptionsTest() throws SolverException, InterruptedException { BooleanFormula b = bmgr.makeVariable("b"); diff --git a/src/org/sosy_lab/java_smt/test/SolverConcurrencyTest.java b/src/org/sosy_lab/java_smt/test/SolverConcurrencyTest.java index 7d14b51663..1d0f7f86bf 100644 --- a/src/org/sosy_lab/java_smt/test/SolverConcurrencyTest.java +++ b/src/org/sosy_lab/java_smt/test/SolverConcurrencyTest.java @@ -124,10 +124,6 @@ public void checkThatSolverIsAvailable() throws InvalidConfigurationException { .that(solver) .isNotEqualTo(Solvers.MATHSAT5); } - assume() - .withMessage("Yices2 with MCSAT support is not reentrant") - .that(solver) - .isNotEqualTo(Solvers.YICES2); } private void requireConcurrentMultipleStackSupport() { diff --git a/src/org/sosy_lab/java_smt/test/SolverFormulaWithAssumptionsTest.java b/src/org/sosy_lab/java_smt/test/SolverFormulaWithAssumptionsTest.java index 4877aec0be..9a174bae8f 100644 --- a/src/org/sosy_lab/java_smt/test/SolverFormulaWithAssumptionsTest.java +++ b/src/org/sosy_lab/java_smt/test/SolverFormulaWithAssumptionsTest.java @@ -17,6 +17,7 @@ import java.util.ArrayList; import java.util.List; import org.junit.Test; +import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Formula; import org.sosy_lab.java_smt.api.InterpolatingProverEnvironment; @@ -157,6 +158,11 @@ public void assumptionsTest() throws SolverException, InterruptedException { @Test @SuppressWarnings("CheckReturnValue") public void assumptionsTest1() throws SolverException, InterruptedException { + assume() + .withMessage("Yices2 hangs in this test") + .that(solverToUse()) + .isNotEqualTo(Solvers.YICES2); + /* (declare-fun A () Bool) (push 1) diff --git a/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java b/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java index a2af7cd4d2..579af74456 100644 --- a/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java +++ b/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java @@ -15,6 +15,7 @@ import static org.junit.Assert.assertThrows; import com.google.common.collect.ImmutableSet; +import org.junit.Before; import org.junit.Test; import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; @@ -22,6 +23,14 @@ public class UnsatCoreTest extends SolverBasedTest0.ParameterizedSolverBasedTest0 { + @Before + public void init() { + assume() + .withMessage("Yices2 hangs in this test") + .that(solverToUse()) + .isNotEqualTo(Solvers.YICES2); + } + // Tests that unsat cores can not be requested after changes to the stack have been made after // UNSAT has been established. @Test From 0a7422d65ea18a763c17d074e880525dbebcc7be Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Tue, 3 Mar 2026 19:20:24 +0100 Subject: [PATCH 22/93] CI --- .../solvers/yices2/Yices2IntegerFormulaManager.java | 2 +- src/org/sosy_lab/java_smt/test/NonLinearArithmeticTest.java | 6 +----- src/org/sosy_lab/java_smt/test/VariableNamesTest.java | 2 -- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2IntegerFormulaManager.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2IntegerFormulaManager.java index d5410cd12e..07e799eb17 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2IntegerFormulaManager.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2IntegerFormulaManager.java @@ -47,7 +47,7 @@ public Integer divide(Integer pParam1, Integer pParam2) { @Override public Integer modulo(Integer pParam1, Integer pParam2) { - return yices_imod(pParam1, pParam2); + return yices_imod(pParam1, pParam2); } @Override diff --git a/src/org/sosy_lab/java_smt/test/NonLinearArithmeticTest.java b/src/org/sosy_lab/java_smt/test/NonLinearArithmeticTest.java index 6755e78abb..d19c634d5e 100644 --- a/src/org/sosy_lab/java_smt/test/NonLinearArithmeticTest.java +++ b/src/org/sosy_lab/java_smt/test/NonLinearArithmeticTest.java @@ -41,11 +41,7 @@ public class NonLinearArithmeticTest extends SolverBas // INFO: OpenSmt does not suport nonlinear arithmetic static final ImmutableSet SOLVER_WITHOUT_NONLINEAR_ARITHMETIC = ImmutableSet.of( - Solvers.SMTINTERPOL, - Solvers.MATHSAT5, - Solvers.BOOLECTOR, - Solvers.CVC4, - Solvers.OPENSMT); + Solvers.SMTINTERPOL, Solvers.MATHSAT5, Solvers.BOOLECTOR, Solvers.CVC4, Solvers.OPENSMT); @Parameters(name = "{0} {1} {2}") public static Iterable getAllSolversAndTheories() { diff --git a/src/org/sosy_lab/java_smt/test/VariableNamesTest.java b/src/org/sosy_lab/java_smt/test/VariableNamesTest.java index 89ee4ec22d..6d1f718fcb 100644 --- a/src/org/sosy_lab/java_smt/test/VariableNamesTest.java +++ b/src/org/sosy_lab/java_smt/test/VariableNamesTest.java @@ -9,7 +9,6 @@ package org.sosy_lab.java_smt.test; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.TruthJUnit.assume; import static org.junit.Assert.assertThrows; import static org.sosy_lab.java_smt.api.FormulaType.BooleanType; import static org.sosy_lab.java_smt.api.FormulaType.IntegerType; @@ -23,7 +22,6 @@ import java.util.function.BiFunction; import java.util.function.Function; import org.junit.Test; -import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.FloatingPointFormula; import org.sosy_lab.java_smt.api.Formula; From 79f9999e3c13d0b1633e73f12abd23f79ad064f2 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Tue, 3 Mar 2026 20:12:37 +0100 Subject: [PATCH 23/93] Yices: Disable array tests --- src/org/sosy_lab/java_smt/test/ModelTest.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/org/sosy_lab/java_smt/test/ModelTest.java b/src/org/sosy_lab/java_smt/test/ModelTest.java index b46ea29c15..c3183e2760 100644 --- a/src/org/sosy_lab/java_smt/test/ModelTest.java +++ b/src/org/sosy_lab/java_smt/test/ModelTest.java @@ -1252,7 +1252,7 @@ public void testGetArrays3IntegerNoParsing() throws SolverException, Interrupted requireArrays(); requireArrayModel(); - assume().that(solver).isNotEqualTo(Solvers.YICES2); // FIXME Broken in JavaSMT + assume().withMessage("Not supported with MCSAT").that(solver).isNotEqualTo(Solvers.YICES2); // (= (select (select (select arr 5) 3) 1) x) // (= x 123)" @@ -1838,6 +1838,8 @@ public void testArrayWithManyValues() throws SolverException, InterruptedExcepti requireArrays(); requireArrayModel(); + assume().withMessage("Not supported with MCSAT").that(solver).isNotEqualTo(Solvers.YICES2); + // Let's store N values into an array and check that each one is in the model. // The example array formula is: for x in [1...N]: arr = store(arr, i_x, x) // as SMTLIB: arr = store(store(store(... store(array, 0, 0), 1, 1), ... , N-1, N-1) @@ -2683,6 +2685,7 @@ public void testArrayStore1BvBvBv() { assume().that(solver).isNotEqualTo(Solvers.BOOLECTOR); // Doesn't support multiple indices assume().that(solver).isNotEqualTo(Solvers.CVC4); // FIXME Broken in JavaSMT + assume().withMessage("Not supported with MCSAT").that(solver).isNotEqualTo(Solvers.YICES2); var scalarType = FormulaType.getBitvectorTypeWithSize(8); @@ -2806,7 +2809,7 @@ public void testArray1IntInt() { requireArrayModel(); requireIntegers(); - assume().that(solver).isNotEqualTo(Solvers.YICES2); // FIXME Broken in JavaSMT + assume().withMessage("Not supported with MCSAT").that(solver).isNotEqualTo(Solvers.YICES2); var array = amgr.makeArray("array", IntegerType, FormulaType.getArrayType(IntegerType, IntegerType)); @@ -2823,6 +2826,8 @@ public void testArray1IntInt() { @Test public void testArrayStore1IntIntInt() { + assume().withMessage("Not supported with MCSAT").that(solver).isNotEqualTo(Solvers.YICES2); + // Test for 3d integer arrays with exactly one element // array = (Store (const ...) idxA (Store (const ..) idxB (Store (const ...) idx C val)) requireArrays(); @@ -2865,7 +2870,7 @@ public void testArray2IntInt() { requireArrayModel(); requireIntegers(); - assume().that(solver).isNotEqualTo(Solvers.YICES2); // FIXME Broken in JavaSMT + assume().withMessage("Not supported with MCSAT").that(solver).isNotEqualTo(Solvers.YICES2); var array = amgr.makeArray("array", IntegerType, FormulaType.getArrayType(IntegerType, IntegerType)); From 2d9bcb88dc4e749597371090fa88ba2cd907a5a7 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Tue, 3 Mar 2026 20:11:39 +0100 Subject: [PATCH 24/93] Yices: Rename Yices2TheoremProver to Yices2AbstractProver --- .../{Yices2TheoremProver.java => Yices2AbstractProver.java} | 4 ++-- src/org/sosy_lab/java_smt/solvers/yices2/Yices2Model.java | 4 ++-- .../sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) rename src/org/sosy_lab/java_smt/solvers/yices2/{Yices2TheoremProver.java => Yices2AbstractProver.java} (98%) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java similarity index 98% rename from src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java rename to src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java index 61a367ff2d..f87e8b37c5 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2TheoremProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java @@ -55,7 +55,7 @@ * incremental solving, but is more complex to implement. Let's keep this idea is future work for * optimization. */ -class Yices2TheoremProver extends AbstractProverWithAllSat implements ProverEnvironment { +class Yices2AbstractProver extends AbstractProverWithAllSat implements ProverEnvironment { private static final int DEFAULT_PARAMS = 0; // use default setting in the solver @@ -67,7 +67,7 @@ class Yices2TheoremProver extends AbstractProverWithAllSat implements Prov // Therefore, we need to keep track of all added constraints beyond that stack-level. private int stackSizeToUnsat = Integer.MAX_VALUE; - protected Yices2TheoremProver( + protected Yices2AbstractProver( Yices2FormulaCreator creator, Set pOptions, BooleanFormulaManager pBmgr, diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Model.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Model.java index 9a0df9cc43..baf4a7b12e 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Model.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Model.java @@ -61,10 +61,10 @@ public class Yices2Model extends AbstractModel { private final long model; - private final Yices2TheoremProver prover; + private final Yices2AbstractProver prover; private final Yices2FormulaCreator formulaCreator; - Yices2Model(long model, Yices2TheoremProver prover, Yices2FormulaCreator pCreator) { + Yices2Model(long model, Yices2AbstractProver prover, Yices2FormulaCreator pCreator) { super(prover, pCreator); this.model = model; this.prover = prover; diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java index 71e03d5674..33111475a2 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java @@ -113,7 +113,7 @@ public synchronized void close() { @Override protected ProverEnvironment newProverEnvironment0(Set pOptions) { - return new Yices2TheoremProver(creator, pOptions, bfmgr, shutdownManager); + return new Yices2AbstractProver(creator, pOptions, bfmgr, shutdownManager); } @Override From 0b329877749126c0e4df362134ddc5f0c779ceab Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Tue, 3 Mar 2026 21:26:24 +0100 Subject: [PATCH 25/93] Yices: Split off new Yices2Prover class --- .../solvers/yices2/Yices2AbstractProver.java | 33 +++++++++++------ .../java_smt/solvers/yices2/Yices2Model.java | 4 +-- .../java_smt/solvers/yices2/Yices2Prover.java | 36 +++++++++++++++++++ .../solvers/yices2/Yices2SolverContext.java | 2 +- 4 files changed, 61 insertions(+), 14 deletions(-) create mode 100644 src/org/sosy_lab/java_smt/solvers/yices2/Yices2Prover.java diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java index f87e8b37c5..af1400d3c6 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java @@ -25,18 +25,23 @@ import com.google.common.base.Preconditions; import com.google.common.primitives.Ints; +import com.google.errorprone.annotations.CanIgnoreReturnValue; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; +import java.util.Deque; import java.util.List; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; -import org.checkerframework.checker.nullness.qual.Nullable; import org.sosy_lab.common.ShutdownNotifier; +import org.sosy_lab.common.UniqueIdGenerator; +import org.sosy_lab.common.collect.PathCopyingPersistentTreeMap; +import org.sosy_lab.common.collect.PersistentMap; +import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.BooleanFormulaManager; import org.sosy_lab.java_smt.api.Model; -import org.sosy_lab.java_smt.api.ProverEnvironment; import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.basicimpl.AbstractProverWithAllSat; @@ -55,7 +60,8 @@ * incremental solving, but is more complex to implement. Let's keep this idea is future work for * optimization. */ -class Yices2AbstractProver extends AbstractProverWithAllSat implements ProverEnvironment { +abstract class Yices2AbstractProver extends AbstractProverWithAllSat + implements BasicProverEnvironment { private static final int DEFAULT_PARAMS = 0; // use default setting in the solver @@ -67,6 +73,10 @@ class Yices2AbstractProver extends AbstractProverWithAllSat implements Pro // Therefore, we need to keep track of all added constraints beyond that stack-level. private int stackSizeToUnsat = Integer.MAX_VALUE; + private static final UniqueIdGenerator ID_GENERATOR = new UniqueIdGenerator(); + + protected final Deque> stack = new ArrayDeque<>(); + protected Yices2AbstractProver( Yices2FormulaCreator creator, Set pOptions, @@ -78,6 +88,8 @@ protected Yices2AbstractProver( yices_set_config(curCfg, "solver-type", "mcsat"); yices_set_config(curCfg, "mode", "interactive"); curEnv = yices_new_context(curCfg); + + stack.push(PathCopyingPersistentTreeMap.of()); } boolean isClosed() { @@ -98,14 +110,13 @@ protected void popImpl() { } } - @Override - protected @Nullable Void addConstraintImpl(BooleanFormula pConstraint) - throws InterruptedException { - if (!generateUnsatCores) { // unsat core does not work with incremental mode - int constraint = creator.extractInfo(pConstraint); - yices_assert_formula(curEnv, constraint); - } - return null; + @CanIgnoreReturnValue + protected int addConstraint0(BooleanFormula constraint) { + var formula = creator.extractInfo(constraint); + var label = Yices2AbstractProver.ID_GENERATOR.getFreshId(); + yices_assert_formula(curEnv, formula); + stack.push(stack.pop().putAndCopy(label, formula)); + return label; } @Override diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Model.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Model.java index baf4a7b12e..c1a2fb2859 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Model.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Model.java @@ -61,10 +61,10 @@ public class Yices2Model extends AbstractModel { private final long model; - private final Yices2AbstractProver prover; + private final Yices2AbstractProver prover; private final Yices2FormulaCreator formulaCreator; - Yices2Model(long model, Yices2AbstractProver prover, Yices2FormulaCreator pCreator) { + Yices2Model(long model, Yices2AbstractProver prover, Yices2FormulaCreator pCreator) { super(prover, pCreator); this.model = model; this.prover = prover; diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Prover.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Prover.java new file mode 100644 index 0000000000..6477ec3b56 --- /dev/null +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Prover.java @@ -0,0 +1,36 @@ +/* + * This file is part of JavaSMT, + * an API wrapper for a collection of SMT solvers: + * https://github.com/sosy-lab/java-smt + * + * SPDX-FileCopyrightText: 2026 Dirk Beyer + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.sosy_lab.java_smt.solvers.yices2; + +import java.util.Set; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.sosy_lab.common.ShutdownNotifier; +import org.sosy_lab.java_smt.api.BooleanFormula; +import org.sosy_lab.java_smt.api.BooleanFormulaManager; +import org.sosy_lab.java_smt.api.ProverEnvironment; +import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; + +public class Yices2Prover extends Yices2AbstractProver implements ProverEnvironment { + protected Yices2Prover( + Yices2FormulaCreator creator, + Set pOptions, + BooleanFormulaManager pBmgr, + ShutdownNotifier pShutdownNotifier) { + super(creator, pOptions, pBmgr, pShutdownNotifier); + } + + @Override + protected @Nullable Void addConstraintImpl(BooleanFormula constraint) + throws InterruptedException { + addConstraint0(constraint); + return null; + } +} diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java index 33111475a2..38ab8d7f4b 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java @@ -113,7 +113,7 @@ public synchronized void close() { @Override protected ProverEnvironment newProverEnvironment0(Set pOptions) { - return new Yices2AbstractProver(creator, pOptions, bfmgr, shutdownManager); + return new Yices2Prover(creator, pOptions, bfmgr, shutdownManager); } @Override From 259ed366963053e56a4eb9bdd55bfdbbc7bc5c66 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Wed, 4 Mar 2026 08:19:54 +0100 Subject: [PATCH 26/93] Yices: Add interpolation --- .../yices2/Yices2InterpolatingProver.java | 135 ++++++++++++++++++ .../solvers/yices2/Yices2SolverContext.java | 4 +- .../test/InterpolatingProverTest.java | 4 + .../SolverFormulaWithAssumptionsTest.java | 9 ++ 4 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java new file mode 100644 index 0000000000..7489a7b22c --- /dev/null +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java @@ -0,0 +1,135 @@ +/* + * This file is part of JavaSMT, + * an API wrapper for a collection of SMT solvers: + * https://github.com/sosy-lab/java-smt + * + * SPDX-FileCopyrightText: 2026 Dirk Beyer + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.sosy_lab.java_smt.solvers.yices2; + +import static com.google.common.base.Preconditions.checkArgument; +import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_assert_formula; +import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_free_config; +import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_free_context; +import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_interpolate; +import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_new_config; +import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_new_context; +import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_set_config; +import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_true; + +import com.google.common.collect.FluentIterable; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.sosy_lab.common.ShutdownNotifier; +import org.sosy_lab.java_smt.api.BooleanFormula; +import org.sosy_lab.java_smt.api.BooleanFormulaManager; +import org.sosy_lab.java_smt.api.InterpolatingProverEnvironment; +import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; +import org.sosy_lab.java_smt.api.SolverException; + +public class Yices2InterpolatingProver extends Yices2AbstractProver + implements InterpolatingProverEnvironment { + protected Yices2InterpolatingProver( + Yices2FormulaCreator creator, + Set pOptions, + BooleanFormulaManager pBmgr, + ShutdownNotifier pShutdownNotifier) { + super(creator, pOptions, pBmgr, pShutdownNotifier); + } + + @Override + protected @Nullable Integer addConstraintImpl(BooleanFormula constraint) + throws InterruptedException { + return addConstraint0(constraint); + } + + private long newContext(boolean mcsat) { + var cfg = yices_new_config(); + yices_set_config(cfg, "solver-type", mcsat ? "mcsat" : "dpllt"); + yices_set_config(cfg, "mode", "interactive"); + yices_set_config(cfg, "model-interpolation", "true"); + var context = yices_new_context(cfg); + yices_free_config(cfg); + return context; + } + + private void assertAll(long ctx, Collection partition) { + for (var f : partition) { + yices_assert_formula(ctx, f); + } + } + + @Override + public BooleanFormula getInterpolant(Collection formulasOfA) + throws SolverException, InterruptedException { + checkGenerateInterpolants(); + checkArgument( + getAssertedConstraintIds().containsAll(formulasOfA), + "Interpolation can only be done over previously asserted formulas."); + + var setA = ImmutableSet.copyOf(formulasOfA); + var setB = Sets.difference(getAssertedConstraintIds(), setA); + + return creator.encapsulateBoolean( + interpolate( + FluentIterable.from(setA).transform(stack.peek()::get).toSet(), + FluentIterable.from(setB).transform(stack.peek()::get).toSet())); + } + + private int interpolate(Collection setA, Collection setB) { + var ctxA = newContext(true); + var ctxB = newContext(true); + + assertAll(ctxA, setA); + assertAll(ctxB, setB); + try { + return yices_interpolate(ctxA, ctxB); + } finally { + yices_free_context(ctxB); + yices_free_context(ctxA); + } + } + + @Override + public List getSeqInterpolants(List> partitions) + throws SolverException, InterruptedException { + checkGenerateInterpolants(); + checkArgument(!partitions.isEmpty(), "at least one partition should be available."); + final Set assertedConstraintIds = getAssertedConstraintIds(); + checkArgument( + partitions.stream().allMatch(assertedConstraintIds::containsAll), + "interpolation can only be done over previously asserted formulas."); + + final int n = partitions.size(); + final List itps = new ArrayList<>(); + var previousItp = yices_true(); + for (int i = 1; i < n; i++) { + Collection formulasA = + FluentIterable.from(partitions.get(i - 1)) + .transform(stack.peek()::get) + .append(new Integer[] {previousItp}) + .toSet(); + Collection formulasB = + FluentIterable.concat(partitions.subList(i, n)).transform(stack.peek()::get).toSet(); + var itp = interpolate(formulasA, formulasB); + itps.add(creator.encapsulateBoolean(itp)); + previousItp = itp; + } + return itps; + } + + @Override + public List getTreeInterpolants( + List> partitionedFormulas, int[] startOfSubTree) + throws SolverException, InterruptedException { + throw new UnsupportedOperationException(); + } +} diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java index 38ab8d7f4b..39be5937b4 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java @@ -118,8 +118,8 @@ protected ProverEnvironment newProverEnvironment0(Set pOptions) { @Override protected InterpolatingProverEnvironment newProverEnvironmentWithInterpolation0( - Set pSet) { - throw new UnsupportedOperationException("Yices does not support interpolation"); + Set pOptions) { + return new Yices2InterpolatingProver(creator, pOptions, bfmgr, shutdownManager); } @Override diff --git a/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java b/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java index 84a9b24fa7..43db7104da 100644 --- a/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java +++ b/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java @@ -58,6 +58,7 @@ public void simpleInterpolation() throws SolverException, InterruptedExcepti .withMessage("Solver %s runs into timeout on this test", solverToUse()) .that(solverToUse()) .isNotEqualTo(Solvers.CVC5); + assume().that(solver).isNotEqualTo(Solvers.YICES2); try (InterpolatingProverEnvironment prover = newEnvironmentForTest()) { Formula x = makeVariable("x"); @@ -87,6 +88,7 @@ public void simpleInterpolation() throws SolverException, InterruptedExcepti @Test @SuppressWarnings("unchecked") public void emptyInterpolationGroup() throws SolverException, InterruptedException { + assume().that(solver).isNotEqualTo(Solvers.YICES2); try (InterpolatingProverEnvironment prover = newEnvironmentForTest()) { Formula x = makeVariable("x"); Formula y = makeVariable("y"); @@ -1046,6 +1048,7 @@ public void treeInterpolationWithOnePartition() throws SolverException, Inte public void bigSeqInterpolationTest() throws InterruptedException, SolverException { requireBitvectors(); requireInterpolation(); + assume().that(solver).isNotEqualTo(Solvers.YICES2); assume() .withMessage("Solver %s does not support interpolation over bitvectors", solverToUse()) @@ -1204,6 +1207,7 @@ public void testInvalidToken() throws InterruptedException, SolverException p3 = 12350; break; case BITWUZLA: + case YICES2: p3 = -1; break; default: diff --git a/src/org/sosy_lab/java_smt/test/SolverFormulaWithAssumptionsTest.java b/src/org/sosy_lab/java_smt/test/SolverFormulaWithAssumptionsTest.java index 9a174bae8f..97e85d593e 100644 --- a/src/org/sosy_lab/java_smt/test/SolverFormulaWithAssumptionsTest.java +++ b/src/org/sosy_lab/java_smt/test/SolverFormulaWithAssumptionsTest.java @@ -16,6 +16,7 @@ import com.google.common.collect.Lists; import java.util.ArrayList; import java.util.List; +import org.junit.Before; import org.junit.Test; import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.BooleanFormula; @@ -55,6 +56,14 @@ protected InterpolatingProverEnvironment newEnvironmentForTest() return (InterpolatingProverEnvironment) context.newProverEnvironmentWithInterpolation(); } + @Before + public void init() { + assume() + .withMessage("Yices2 hangs in this test") + .that(solverToUse()) + .isNotEqualTo(Solvers.YICES2); + } + @Test @SuppressWarnings("CheckReturnValue") public void basicAssumptionsTest() throws SolverException, InterruptedException { From 3925f17c9154f0a3e41809f478c62e4533fe24dc Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Wed, 4 Mar 2026 09:47:46 +0100 Subject: [PATCH 27/93] Yices: Print error message if interpolation fails --- .../org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/native/source/yices2j/org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c b/lib/native/source/yices2j/org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c index f8ad3f5ee5..e4d808e591 100644 --- a/lib/native/source/yices2j/org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c +++ b/lib/native/source/yices2j/org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c @@ -1677,10 +1677,10 @@ __attribute__((visibility("default"))) jjterm Java_org_sosy_1lab_java_1smt_solve interpolation_context_t context = {arg1, arg2, 0, 0}; smt_status_t c = yices_check_context_with_interpolation(&context, 0, 0); if (c == YICES_STATUS_SAT) { - throwException(jenv, "java/lang/RuntimeException", "Problem is SAT"); + throwException(jenv, "java/lang/IllegalArgumentException", "Could not interpolate, problem is SAT"); } if (c == YICES_STATUS_ERROR) { - throwException(jenv, "java/lang/RuntimeException", "Error during interpolation"); + throwException(jenv, "java/lang/RuntimeException", yices_error_string()); } result = context.interpolant; From d6d1fe9c4a06c857bc68a1ad09281167c8b25dd3 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Wed, 4 Mar 2026 09:59:52 +0100 Subject: [PATCH 28/93] Yices: Remove build files when `ant clean` is run --- build.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.xml b/build.xml index 47fdf4770a..e101a8386c 100644 --- a/build.xml +++ b/build.xml @@ -88,9 +88,11 @@ SPDX-License-Identifier: Apache-2.0 + + From 9ad3504ee50c7f31b76e3b8259083af44886b392 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Wed, 4 Mar 2026 10:30:01 +0100 Subject: [PATCH 29/93] Yices: Change version name to 2.7.0 --- lib/ivy.xml | 2 +- solvers_ivy_conf/ivy_javasmt_yices2.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ivy.xml b/lib/ivy.xml index 4181a28dd6..cf8b2f18d3 100644 --- a/lib/ivy.xml +++ b/lib/ivy.xml @@ -203,7 +203,7 @@ SPDX-License-Identifier: Apache-2.0 - + diff --git a/solvers_ivy_conf/ivy_javasmt_yices2.xml b/solvers_ivy_conf/ivy_javasmt_yices2.xml index 5408b974b4..33c4f5cad0 100644 --- a/solvers_ivy_conf/ivy_javasmt_yices2.xml +++ b/solvers_ivy_conf/ivy_javasmt_yices2.xml @@ -33,7 +33,7 @@ SPDX-License-Identifier: Apache-2.0 - + From 470c9092e6b5d376dba31e404e276f1e388fa4a9 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Wed, 4 Mar 2026 11:04:54 +0100 Subject: [PATCH 30/93] Yices: Simplify interpolation code --- .../solvers/yices2/Yices2InterpolatingProver.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java index 7489a7b22c..2a07bf9c74 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java @@ -11,7 +11,7 @@ package org.sosy_lab.java_smt.solvers.yices2; import static com.google.common.base.Preconditions.checkArgument; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_assert_formula; +import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_assert_formulas; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_free_config; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_free_context; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_interpolate; @@ -23,6 +23,7 @@ import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; +import com.google.common.primitives.Ints; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -61,12 +62,6 @@ private long newContext(boolean mcsat) { return context; } - private void assertAll(long ctx, Collection partition) { - for (var f : partition) { - yices_assert_formula(ctx, f); - } - } - @Override public BooleanFormula getInterpolant(Collection formulasOfA) throws SolverException, InterruptedException { @@ -88,8 +83,9 @@ private int interpolate(Collection setA, Collection setB) { var ctxA = newContext(true); var ctxB = newContext(true); - assertAll(ctxA, setA); - assertAll(ctxB, setB); + yices_assert_formulas(ctxA, setA.size(), Ints.toArray(setA)); + yices_assert_formulas(ctxB, setB.size(), Ints.toArray(setB)); + try { return yices_interpolate(ctxA, ctxB); } finally { From cc6eb5b9bec723716e693127e0bd12239ebfa639 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Wed, 4 Mar 2026 12:41:50 +0100 Subject: [PATCH 31/93] Yices: Add a native test to check the solver version --- .../java_smt/solvers/yices2/Yices2NativeApiTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java index 1302f29488..9a2a7a2078 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java @@ -51,8 +51,11 @@ import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_free_config; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_free_context; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_function_type; +import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_major_version; +import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_patch_level; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_term_by_name; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_term_name; +import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_version; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_has_mcsat; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_idiv; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_iff; @@ -625,6 +628,15 @@ public void hasMCSat() { assertThat(yices_has_mcsat()).isEqualTo(1); } + @Test + public void checkVersion() { + assertThat( + String.format( + "%s.%s.%s", + yices_get_version(), yices_get_major_version(), yices_get_patch_level())) + .isEqualTo("2.7.0"); + } + @Test public void quantifierTest() { int boundVar = yices_new_variable(yices_int_type()); From 594afde86d4fff6b497716abc3048adf31f44ce9 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Wed, 4 Mar 2026 13:10:30 +0100 Subject: [PATCH 32/93] Yices: Skip pushing assertions when planning to calculate an unsat core --- .../solvers/yices2/Yices2AbstractProver.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java index af1400d3c6..b296fa5af4 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java @@ -114,7 +114,11 @@ protected void popImpl() { protected int addConstraint0(BooleanFormula constraint) { var formula = creator.extractInfo(constraint); var label = Yices2AbstractProver.ID_GENERATOR.getFreshId(); - yices_assert_formula(curEnv, formula); + if (!generateUnsatCores) { + // Skip adding the assertion if we plan to use getUnsatCore. We'll later use assumptions + // solving to calculate an unsat core for the assertions + yices_assert_formula(curEnv, formula); + } stack.push(stack.pop().putAndCopy(label, formula)); return label; } @@ -135,7 +139,10 @@ protected void pushImpl() throws InterruptedException { @Override protected boolean isUnsatImpl() throws SolverException, InterruptedException { boolean unsat; - if (generateUnsatCores) { // unsat core does not work with incremental mode + if (generateUnsatCores) { + // Yices only tracks assumptions for unsat core. We keep the stack empty and then treat all + // assertions as assumptions while checking. If the result is 'unsat', we can then + // calculate an unsat core int[] allConstraints = getAllConstraints(); unsat = !yices_check_sat_with_assumptions( @@ -164,7 +171,6 @@ public boolean isUnsatWithAssumptions(Collection pAssumptions) changedSinceLastSatQuery = false; wasLastSatCheckSatisfiable = false; - // TODO handle BooleanFormulaCollection / check for literals final boolean isUnsat = !yices_check_sat_with_assumptions( curEnv, From 57505e1e962599bee7046246ad59df9c18bdc777 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Wed, 4 Mar 2026 13:10:46 +0100 Subject: [PATCH 33/93] Yices: Re-enable unsat core tests --- src/org/sosy_lab/java_smt/test/UnsatCoreTest.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java b/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java index 579af74456..a2af7cd4d2 100644 --- a/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java +++ b/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java @@ -15,7 +15,6 @@ import static org.junit.Assert.assertThrows; import com.google.common.collect.ImmutableSet; -import org.junit.Before; import org.junit.Test; import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; @@ -23,14 +22,6 @@ public class UnsatCoreTest extends SolverBasedTest0.ParameterizedSolverBasedTest0 { - @Before - public void init() { - assume() - .withMessage("Yices2 hangs in this test") - .that(solverToUse()) - .isNotEqualTo(Solvers.YICES2); - } - // Tests that unsat cores can not be requested after changes to the stack have been made after // UNSAT has been established. @Test From 75f8b020981db54a9727c54ea08519efa479a74a Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Wed, 4 Mar 2026 13:18:52 +0100 Subject: [PATCH 34/93] Yices: Use dpllt for unsat core --- .../java_smt/basicimpl/AbstractProver.java | 2 +- .../solvers/yices2/Yices2AbstractProver.java | 22 +++++++++++-------- .../yices2/Yices2InterpolatingProver.java | 14 ------------ .../sosy_lab/java_smt/test/UnsatCoreTest.java | 5 +++++ 4 files changed, 19 insertions(+), 24 deletions(-) diff --git a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java index bf11e2e95c..6e2f6ad070 100644 --- a/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java +++ b/src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java @@ -39,7 +39,7 @@ public abstract class AbstractProver implements BasicProverEnvironment { protected final boolean generateModels; protected final boolean generateAllSat; protected final boolean generateUnsatCores; - private final boolean generateUnsatCoresOverAssumptions; + protected final boolean generateUnsatCoresOverAssumptions; protected final boolean enableSL; // flags for status diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java index b296fa5af4..066df8a5d9 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java @@ -67,7 +67,6 @@ abstract class Yices2AbstractProver extends AbstractProverWithAllSat protected final Yices2FormulaCreator creator; protected final long curEnv; - protected final long curCfg; // Yices does not allow to PUSH when the stack is UNSAT. // Therefore, we need to keep track of all added constraints beyond that stack-level. @@ -78,17 +77,13 @@ abstract class Yices2AbstractProver extends AbstractProverWithAllSat protected final Deque> stack = new ArrayDeque<>(); protected Yices2AbstractProver( - Yices2FormulaCreator creator, + Yices2FormulaCreator pCreator, Set pOptions, BooleanFormulaManager pBmgr, ShutdownNotifier pShutdownNotifier) { super(pOptions, pBmgr, pShutdownNotifier); - this.creator = creator; - curCfg = yices_new_config(); - yices_set_config(curCfg, "solver-type", "mcsat"); - yices_set_config(curCfg, "mode", "interactive"); - curEnv = yices_new_context(curCfg); - + creator = pCreator; + curEnv = newContext(!generateUnsatCores && !generateUnsatCoresOverAssumptions); stack.push(PathCopyingPersistentTreeMap.of()); } @@ -101,6 +96,16 @@ protected boolean hasPersistentModel() { return false; } + long newContext(boolean mcsat) { + var cfg = yices_new_config(); + yices_set_config(cfg, "solver-type", mcsat ? "mcsat" : "dpllt"); + yices_set_config(cfg, "mode", "interactive"); + yices_set_config(cfg, "model-interpolation", "true"); + var context = yices_new_context(cfg); + yices_free_config(cfg); + return context; + } + @Override protected void popImpl() { if (size() < stackSizeToUnsat) { // constraintStack and Yices stack have same level. @@ -235,7 +240,6 @@ public Optional> unsatCoreOverAssumptions( public void close() { if (!closed) { yices_free_context(curEnv); - yices_free_config(curCfg); stackSizeToUnsat = Integer.MAX_VALUE; } super.close(); diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java index 2a07bf9c74..02eeed0535 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java @@ -12,12 +12,8 @@ import static com.google.common.base.Preconditions.checkArgument; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_assert_formulas; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_free_config; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_free_context; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_interpolate; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_new_config; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_new_context; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_set_config; import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_true; import com.google.common.collect.FluentIterable; @@ -52,16 +48,6 @@ protected Yices2InterpolatingProver( return addConstraint0(constraint); } - private long newContext(boolean mcsat) { - var cfg = yices_new_config(); - yices_set_config(cfg, "solver-type", mcsat ? "mcsat" : "dpllt"); - yices_set_config(cfg, "mode", "interactive"); - yices_set_config(cfg, "model-interpolation", "true"); - var context = yices_new_context(cfg); - yices_free_config(cfg); - return context; - } - @Override public BooleanFormula getInterpolant(Collection formulasOfA) throws SolverException, InterruptedException { diff --git a/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java b/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java index a2af7cd4d2..545ea5724b 100644 --- a/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java +++ b/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java @@ -109,6 +109,11 @@ public void unsatCoreOverAssumptionsOnlyLiteralsTest() @Test public void unsatCoreOverAssumptionsThrowsForMissingOptionTest() throws InterruptedException, SolverException { + assume() + .withMessage("Yices need to use dpllt for unsat core if thread safety is enabled") + .that(solver) + .isNotEqualTo(Solvers.YICES2); + requireUnsatCoreOverAssumptions(); try (var prover = context.newProverEnvironment()) { var a = bmgr.makeVariable("a"); From b289de6ac278977398de35f41d8e0bb7428e9234 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Thu, 5 Mar 2026 14:25:09 +0100 Subject: [PATCH 35/93] Yices: Switch back to MCSAT for all provers --- .../java_smt/solvers/yices2/Yices2AbstractProver.java | 2 +- src/org/sosy_lab/java_smt/test/UnsatCoreTest.java | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java index 066df8a5d9..d99aae7049 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java @@ -83,7 +83,7 @@ protected Yices2AbstractProver( ShutdownNotifier pShutdownNotifier) { super(pOptions, pBmgr, pShutdownNotifier); creator = pCreator; - curEnv = newContext(!generateUnsatCores && !generateUnsatCoresOverAssumptions); + curEnv = newContext(true); stack.push(PathCopyingPersistentTreeMap.of()); } diff --git a/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java b/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java index 545ea5724b..a2af7cd4d2 100644 --- a/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java +++ b/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java @@ -109,11 +109,6 @@ public void unsatCoreOverAssumptionsOnlyLiteralsTest() @Test public void unsatCoreOverAssumptionsThrowsForMissingOptionTest() throws InterruptedException, SolverException { - assume() - .withMessage("Yices need to use dpllt for unsat core if thread safety is enabled") - .that(solver) - .isNotEqualTo(Solvers.YICES2); - requireUnsatCoreOverAssumptions(); try (var prover = context.newProverEnvironment()) { var a = bmgr.makeVariable("a"); From 93f1542cbc3f27fd144fe60e11cb5ecd2e2f86db Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Thu, 5 Mar 2026 14:28:47 +0100 Subject: [PATCH 36/93] Yices: Short circuit formula translation if the other context is also Yices Yices has no equivalent to SolverContext and stores all its terms globally. There is no need to move terms from one SolverContext to another, and the original term can simply be used in the new SolverContext --- .../java_smt/solvers/yices2/Yices2FormulaManager.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaManager.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaManager.java index 554c9966b4..a7d9a01b2c 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaManager.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaManager.java @@ -32,7 +32,9 @@ import java.io.IOException; import java.util.Locale; import java.util.Map; +import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Formula; +import org.sosy_lab.java_smt.api.FormulaManager; import org.sosy_lab.java_smt.api.FormulaType; import org.sosy_lab.java_smt.basicimpl.AbstractFormulaManager; @@ -147,6 +149,14 @@ assert getFormulaCreator().getFormulaType(formula) == FormulaType.BooleanType return out.toString(); } + @Override + public BooleanFormula translateFrom(BooleanFormula formula, FormulaManager otherManager) { + if (otherManager instanceof Yices2FormulaManager) { + return formula; + } + return super.translateFrom(formula, otherManager); + } + /** * Quote symbols if required. * From 6633cb1c92d8d0d9c07c732a73915083443b4da3 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Fri, 6 Mar 2026 11:02:08 +0100 Subject: [PATCH 37/93] Yices: Fix assumption tracking --- .../java_smt/solvers/yices2/Yices2AbstractProver.java | 4 +++- .../solvers/yices2/Yices2InterpolatingProver.java | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java index d99aae7049..ace55c0cc3 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java @@ -113,6 +113,7 @@ protected void popImpl() { // Reset stackSizeToUnsat to bring the stack into a pushable state if it was UNSAT before. stackSizeToUnsat = Integer.MAX_VALUE; } + stack.removeLast(); } @CanIgnoreReturnValue @@ -124,7 +125,7 @@ protected int addConstraint0(BooleanFormula constraint) { // solving to calculate an unsat core for the assertions yices_assert_formula(curEnv, formula); } - stack.push(stack.pop().putAndCopy(label, formula)); + stack.addLast(stack.removeLast().putAndCopy(label, formula)); return label; } @@ -139,6 +140,7 @@ protected void pushImpl() throws InterruptedException { // not already set, set it to the current stack-size before pushing. stackSizeToUnsat = size(); } + stack.addLast(stack.getLast()); } @Override diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java index 02eeed0535..349c2e3596 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java @@ -61,8 +61,8 @@ public BooleanFormula getInterpolant(Collection formulasOfA) return creator.encapsulateBoolean( interpolate( - FluentIterable.from(setA).transform(stack.peek()::get).toSet(), - FluentIterable.from(setB).transform(stack.peek()::get).toSet())); + FluentIterable.from(setA).transform(stack.peekLast()::get).toSet(), + FluentIterable.from(setB).transform(stack.peekLast()::get).toSet())); } private int interpolate(Collection setA, Collection setB) { @@ -96,11 +96,11 @@ public List getSeqInterpolants(List formulasA = FluentIterable.from(partitions.get(i - 1)) - .transform(stack.peek()::get) + .transform(stack.peekLast()::get) .append(new Integer[] {previousItp}) .toSet(); Collection formulasB = - FluentIterable.concat(partitions.subList(i, n)).transform(stack.peek()::get).toSet(); + FluentIterable.concat(partitions.subList(i, n)).transform(stack.peekLast()::get).toSet(); var itp = interpolate(formulasA, formulasB); itps.add(creator.encapsulateBoolean(itp)); previousItp = itp; From c68d1e60ef1340b40da8433f198d92afc473489d Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Sat, 7 Mar 2026 23:27:53 +0100 Subject: [PATCH 38/93] Yices: Switch to using the official Java bindings See https://github.com/SRI-CSL/yices2_java_bindings --- .idea/JavaSMT.iml | 11 +- build.xml | 1 - build/build-publish-solvers/solver-yices.xml | 42 +- lib/native/source/yices2j/compile.sh | 111 -- lib/native/source/yices2j/includes/defines.h | 481 ----- lib/native/source/yices2j/libyices2j.version | 12 - ...java_1smt_solvers_yices2_Yices2NativeApi.c | 1689 ----------------- lib/native/x86_64-linux/libyices2j.so | 1 - lib/native/x86_64-linux/libyices2java.so | 1 + solvers_ivy_conf/ivy_yices2.xml | 13 +- .../solvers/yices2/Yices2AbstractProver.java | 98 +- .../yices2/Yices2ArrayFormulaManager.java | 20 +- .../yices2/Yices2BitvectorFormulaManager.java | 98 +- .../yices2/Yices2BooleanFormulaManager.java | 45 +- .../solvers/yices2/Yices2Formula.java | 4 +- .../solvers/yices2/Yices2FormulaCreator.java | 865 +++++---- .../solvers/yices2/Yices2FormulaManager.java | 45 +- .../yices2/Yices2IntegerFormulaManager.java | 8 +- .../yices2/Yices2InterpolatingProver.java | 31 +- .../java_smt/solvers/yices2/Yices2Model.java | 227 +-- .../solvers/yices2/Yices2NativeApi.java | 870 --------- .../solvers/yices2/Yices2NativeApiTest.java | 661 +++---- .../yices2/Yices2NumeralFormulaManager.java | 52 +- .../Yices2QuantifiedFormulaManager.java | 13 +- .../yices2/Yices2RationalFormulaManager.java | 5 +- .../solvers/yices2/Yices2SolverContext.java | 16 +- .../test/InterpolatingProverTest.java | 2 + .../sosy_lab/java_smt/test/UnsatCoreTest.java | 6 + 28 files changed, 1038 insertions(+), 4390 deletions(-) delete mode 100755 lib/native/source/yices2j/compile.sh delete mode 100644 lib/native/source/yices2j/includes/defines.h delete mode 100644 lib/native/source/yices2j/libyices2j.version delete mode 100644 lib/native/source/yices2j/org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c delete mode 120000 lib/native/x86_64-linux/libyices2j.so create mode 120000 lib/native/x86_64-linux/libyices2java.so delete mode 100644 src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java diff --git a/.idea/JavaSMT.iml b/.idea/JavaSMT.iml index 77b8b55e62..cd9d86b1ea 100644 --- a/.idea/JavaSMT.iml +++ b/.idea/JavaSMT.iml @@ -367,6 +367,15 @@ SPDX-License-Identifier: Apache-2.0 + + + + + + + + + - + \ No newline at end of file diff --git a/build.xml b/build.xml index e101a8386c..38288d786a 100644 --- a/build.xml +++ b/build.xml @@ -92,7 +92,6 @@ SPDX-License-Identifier: Apache-2.0 - diff --git a/build/build-publish-solvers/solver-yices.xml b/build/build-publish-solvers/solver-yices.xml index d3b27f89a4..ea5081f88b 100644 --- a/build/build-publish-solvers/solver-yices.xml +++ b/build/build-publish-solvers/solver-yices.xml @@ -12,37 +12,37 @@ SPDX-License-Identifier: Apache-2.0 - - - - - - - - - - - - - - - - + - + + Please specify the Yices2 version with the flag -Dyices2.version=... . - + + - + + + + + + + + + @@ -52,8 +52,6 @@ SPDX-License-Identifier: Apache-2.0 - diff --git a/lib/native/source/yices2j/compile.sh b/lib/native/source/yices2j/compile.sh deleted file mode 100755 index f697ccd769..0000000000 --- a/lib/native/source/yices2j/compile.sh +++ /dev/null @@ -1,111 +0,0 @@ -#!/usr/bin/env bash - -# This file is part of JavaSMT, -# an API wrapper for a collection of SMT solvers: -# https://github.com/sosy-lab/java-smt -# -# SPDX-FileCopyrightText: 2020 Dirk Beyer -# -# SPDX-License-Identifier: Apache-2.0 - -# This script builds libyices2j.so. - -# INFO: Before running this script, you need to do build Yices2. -# See the corresponding section in doc/Developers.md for details. - -# This script searches for all included libraries in the current directory first. -# You can use this to override specific libraries installed on your system. -# You can also use this to force static linking of a specific library, -# if you put only the corresponding .a file in this directory, not the .so file. - -# For example, to statically link against libstdc++, -# compile this library with --with-pic, -# and put the resulting libstdc++.a file in this directory. - -SOURCE="${BASH_SOURCE[0]}" -while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink - DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - SOURCE="$(readlink "$SOURCE")" - [[ ${SOURCE} != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located -done -DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" - -cd ${DIR} - -JNI_HEADERS="$(../get_jni_headers.sh)" - -YICES_HEADER_DIR="$1"/include -YICES_LIB_DIR="$1"/lib - -GMP_HEADER_DIR="$2"/include -GMP_LIB_DIR="$2"/lib - -POLY_LIB_DIR="$3"/lib -CUDD_LIB_DIR="$4"/lib - -# check requirements -if [ ! -f "$YICES_LIB_DIR/libyices.a" ]; then - echo "You need to specify the directory with the downloaded and compiled Yices on the command line!" - echo "Can not find $YICES_LIB_DIR/libyices.a" - exit 1 -fi -if [ ! -f "$GMP_LIB_DIR/libgmp.a" ]; then - echo "You need to specify the GMP directory on the command line!" - echo "Can not find $GMP_LIB_DIR/libgmp.a" - exit 1 -fi -if [ ! -f "$POLY_LIB_DIR/libpoly.a" ]; then - echo "You need to specify the Libpoly directory on the command line!" - echo "Can not find $POLY_LIB_DIR/libpoly.a" - exit 1 -fi -if [ ! -f "$CUDD_LIB_DIR/libcudd.a" ]; then - echo "You need to specify the CUDD directory on the command line!" - echo "Can not find $CUDD_LIB_DIR/libcudd.a" - exit 1 -fi - -SRC_FILES="org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c" -OBJ_FILES="org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.o" - -OUT_FILE="libyices2j.so" - -echo "Compiling the C wrapper code and creating the \"$OUT_FILE\" library..." - -# This will compile the JNI wrapper part, given the JNI and the Yices header files -gcc -g -std=gnu99 -Wall -Wextra -Wpedantic -Wno-return-type -Wno-unused-parameter \ - $JNI_HEADERS -I$YICES_HEADER_DIR -I$GMP_HEADER_DIR $SRC_FILES -fPIC -c - -echo "Compilation Done" -echo "Linking libraries together into one file..." - -# This will link together the file produced above, the Yices library, the GMP library and the standard libraries. -# Everything except the standard libraries is included statically. -# The result is a single shared library containing all necessary components. -gcc -Wall -g -o $OUT_FILE -shared -Wl,-soname,libyices2j.so \ - -L$YICES_LIB_DIR -L$GMP_LIB_DIR -L$POLY_LIB_DIR -L$CUDD_LIB_DIR \ - -I$GMP_HEADER_DIR $OBJ_FILES -Wl,-Bstatic \ - -lyices -lcudd -lpoly -lgmpxx -lgmp -static-libstdc++ -lstdc++ \ - -Wl,-Bdynamic -lc -lm -Wl,--version-script=libyices2j.version - - -if [ $? -ne 0 ]; then - echo "There was a problem during compilation of \"org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c\"" - exit 1 -fi - -echo "Linking Done" -echo "Reducing file size by dropping unused symbols..." - -strip ${OUT_FILE} - -echo "Reduction Done" - -MISSING_SYMBOLS="$(readelf -Ws ${OUT_FILE} | grep NOTYPE | grep GLOBAL | grep UND)" -if [ ! -z "$MISSING_SYMBOLS" ]; then - echo "Warning: There are the following unresolved dependencies in libyices2j.so:" - readelf -Ws ${OUT_FILE} | grep NOTYPE | grep GLOBAL | grep UND - exit 1 -fi - -echo "All Done" diff --git a/lib/native/source/yices2j/includes/defines.h b/lib/native/source/yices2j/includes/defines.h deleted file mode 100644 index 2979826f9e..0000000000 --- a/lib/native/source/yices2j/includes/defines.h +++ /dev/null @@ -1,481 +0,0 @@ -// This file is part of JavaSMT, -// an API wrapper for a collection of SMT solvers: -// https://github.com/sosy-lab/java-smt -// -// SPDX-FileCopyrightText: 2020 Dirk Beyer -// -// SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later - -#include -#include -#include -#include "yices.h" - - -#define CHECK_FOR_NULL(var) \ - if (var == NULL) { \ - return 0; \ - } - -typedef void jvoid; // for symmetry to jint, jlong etc. - -// Macros for defining JNI functions which call Yices -// Use them as follows: -// -// DEFINE_FUNC(java_return_type, escaped_name_without_yices) WITH_X_ARGS(java_arg_types) -// for each arg a definition like TERM_ARG(position) -// CALLX(yices_return_type, function_name_without_yices) -// return definition like TERM_RETURN depending on the return type - - -#define DEFINE_FUNC(jreturn, func_escaped) \ - JNIEXPORT j##jreturn JNICALL Java_org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi_yices_##func_escaped - -#define WITHOUT_ARGS \ - (JNIEnv *jenv, jclass jcls) { - -#define WITH_ONE_ARG(jtype) \ - (JNIEnv *jenv, jclass jcls, j##jtype arg1) { - -#define WITH_TWO_ARGS(jtype1, jtype2) \ - (JNIEnv *jenv, jclass jcls, j##jtype1 arg1, j##jtype2 arg2) { - -#define WITH_THREE_ARGS(jtype1, jtype2, jtype3) \ - (JNIEnv *jenv, jclass jcls, j##jtype1 arg1, j##jtype2 arg2, j##jtype3 arg3) { - -#define WITH_FOUR_ARGS(jtype1, jtype2, jtype3, jtype4) \ - (JNIEnv *jenv, jclass jcls, j##jtype1 arg1, j##jtype2 arg2, j##jtype3 arg3, j##jtype4 arg4) { - -#define WITH_FIVE_ARGS(jtype1, jtype2, jtype3, jtype4, jtype5) \ - (JNIEnv *jenv, jclass jcls, j##jtype1 arg1, j##jtype2 arg2, j##jtype3 arg3, j##jtype4 arg4, j##jtype5 arg5) { - -#define WITH_SIX_ARGS(jtype1, jtype2, jtype3, jtype4, jtype5, jtype6) \ - (JNIEnv *jenv, jclass jcls, j##jtype1 arg1, j##jtype2 arg2, j##jtype3 arg3, j##jtype4 arg4, j##jtype5 arg5, j##jtype6 arg6) { - -#define WITH_SEVEN_ARGS(jtype1, jtype2, jtype3, jtype4, jtype5, jtype6, jtype7) \ - (JNIEnv *jenv, jclass jcls, j##jtype1 arg1, j##jtype2 arg2, j##jtype3 arg3, j##jtype4 arg4, j##jtype5 arg5, j##jtype6 arg6, j##jtype7 arg7) { - -#define SIMPLE_ARG(mtype, num) \ - mtype m_arg##num = arg##num; - -#define UINT32_ARG(num) SIMPLE_ARG(uint32_t, num) - -#define NULL_ARG(mtype, num) \ - mtype *m_arg##num = NULL; - -#define STRING_ARG(num) \ - char * m_arg##num = (char *)(*jenv)->GetStringUTFChars(jenv, arg##num, NULL); \ - if (m_arg##num == NULL) { \ - goto out##num; \ - } - -//may cause memory problems -#define INT_ARRAY_ARG(mtype, num) \ - mtype * m_arg##num = (mtype *)((*jenv)->GetIntArrayElements(jenv, arg##num, NULL)); \ - if (m_arg##num == NULL) { \ - goto out##num; \ - } - -#define EMPTY_INT_ARRAY_ARG(mtype, num) \ - mtype *m_arg##num;\ - size_t sz = (size_t)(arg##num); \ - m_arg##num = (mtype *)malloc(sizeof(mtype) * sz); \ - if (m_arg##num == NULL) { \ - throwException(jenv, "java/lang/OutOfMemoryError", "Cannot allocate native memory for calling Yices"); \ - } \ - -#define EMPTY_YVAL_ARRAY_ARG(num) \ - yval_t *m_arg##num;\ - size_t sz = (size_t)(arg##num); \ - m_arg##num = (yval_t *)malloc(sizeof(yval_t) * sz); \ - if (m_arg##num == NULL) { \ - throwException(jenv, "java/lang/OutOfMemoryError", "Cannot allocate native memory for calling Yices"); \ - } \ - -//may cause memory problems -#define LONG_ARRAY_ARG(mtype, num) \ - mtype * m_arg##num = (mtype *)((*jenv)->GetLongArrayElements(jenv, arg##num, NULL)); \ - if (m_arg##num == NULL) { \ - goto out##num; \ - } - -#define POINTER_ARG(mtype, num) \ - mtype * m_arg##num = (mtype *) arg##num; - -//For ** types -#define POINTER_POINTER_ARG(mtype, num) \ - mtype ** m_arg##num = (mtype **) arg##num; - -#define INT_POINTER_ARG(num) \ - int32_t s_arg##num = 0; \ - int32_t *m_arg##num = &s_arg##num; - -#define LONG_POINTER_ARG(num) \ - int64_t s_arg##num = 0; \ - int64_t *m_arg##num = &s_arg##num; - -#define DOUBLE_POINTER_ARG(num) \ - double s_arg##num = 0; \ - double *m_arg##num = &s_arg##num; - -#define TERM_VECTOR_ARG(num) \ - term_vector_t s_arg##num; \ - term_vector_t *m_arg##num = &s_arg##num; \ - yices_init_term_vector(m_arg##num); \ - -#define TYPE_VECTOR_ARG(num) \ - type_vector_t s_arg##num; \ - type_vector_t *m_arg##num = &s_arg##num; \ - yices_init_type_vector(m_arg##num); \ - -#define YVAL_VECTOR_ARG(num) \ - yval_vector_t s_arg##num; \ - yval_vector_t *m_arg##num = &s_arg##num; \ - yices_init_yval_vector(m_arg##num); \ - -#define EMPTY_YVAL_ARG(num) \ - yval_t s_arg##num; \ - yval_t *m_arg##num = &s_arg##num; \ - -/* - * Builds an yval_t from java input where - * num = Position of the yval_t in the c function call - * id = Position of the Java arg to use as node_id - * tag = Position of the Java arg to use as node_tag -*/ -#define YVAL_ARG(num, id, tag) \ - yval_t s_arg##num; \ - yval_t *m_arg##num = &s_arg##num; \ - if(arg##id < 0) { \ - throwException(jenv, "java/lang/IllegalArgumentException", "An yval_id cannot be negative."); \ - }\ - if(arg##tag < 0 || arg##tag > 9) { \ - throwException(jenv, "java/lang/IllegalArgumentException", "Yval_tag is negative or not a valid yval_tag."); \ - } \ - m_arg##num->node_id = arg##id; \ - m_arg##num->node_tag = arg##tag; \ - -#define MPQ_ARG(num) \ - mpq_t m_arg##num; \ - mpq_init(m_arg##num); \ - -#define CALL0(mreturn, func) mreturn retval = yices_##func(); -#define CALL1(mreturn, func) mreturn retval = yices_##func(m_arg1); -#define CALL2(mreturn, func) mreturn retval = yices_##func(m_arg1, m_arg2); -#define CALL3(mreturn, func) mreturn retval = yices_##func(m_arg1, m_arg2, m_arg3); -#define CALL4(mreturn, func) mreturn retval = yices_##func(m_arg1, m_arg2, m_arg3, m_arg4); -#define CALL5(mreturn, func) mreturn retval = yices_##func(m_arg1, m_arg2, m_arg3, m_arg4, m_arg5); -#define CALL6(mreturn, func) mreturn retval = yices_##func(m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6); -#define CALL7(mreturn, func) mreturn retval = yices_##func(m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7); -#define VOID_CALL0(func) yices_##func(); } -#define VOID_CALL1(func) yices_##func(m_arg1); } -#define VOID_CALL2(func) yices_##func(m_arg1, m_arg2); } -#define VOID_CALL2_WITH_RETURN(func) yices_##func(m_arg1, m_arg2); - -#define FREE_STRING_OPTIONAL_ARG(num) \ - if(arg##num != NULL) {(*jenv)->ReleaseStringUTFChars(jenv, arg##num, m_arg##num); } \ - out##num: - -#define FREE_STRING_ARG(num) \ - (*jenv)->ReleaseStringUTFChars(jenv, arg##num, m_arg##num); \ - out##num: - -#define FREE_INT_ARRAY_ARG(num) \ - (*jenv)->ReleaseIntArrayElements(jenv, arg##num, m_arg##num, 0); \ - out##num: - -#define FREE_LONG_ARRAY_ARG(num) \ - (*jenv)->ReleaseLongArrayElements(jenv, arg##num, m_arg##num, 0); \ - out##num: - -//may cause memory leak through yices_error_string -#define INT_RETURN \ - if (retval <= 0 && yices_error_code() != 0){ \ - const char *msg = yices_error_string(); \ - throwException(jenv, "java/lang/IllegalArgumentException", msg); \ - return -1; \ - } \ - return (jint)retval; \ -} - -#define PLAIN_STRING_RETURN \ - jstring jretval = NULL; \ - if (!(*jenv)->ExceptionCheck(jenv)) { \ - jretval = (*jenv)->NewStringUTF(jenv, retval); \ - } \ - yices_free_string(retval); \ - return jretval; \ -} - -#define STRING_RETURN \ - if (retval == NULL && yices_error_code()!=0) { \ - const char *msg = yices_error_string(); \ - throwException(jenv, "java/lang/IllegalArgumentException", msg); \ - return NULL; \ - } \ - PLAIN_STRING_RETURN - -#define CONST_STRING_RETURN \ - if (retval == NULL && yices_error_code()!=0) { \ - const char *msg = yices_error_string(); \ - throwException(jenv, "java/lang/IllegalArgumentException", msg); \ - return NULL; \ - } \ - jstring jretval = NULL; \ - if (!(*jenv)->ExceptionCheck(jenv)) { \ - jretval = (*jenv)->NewStringUTF(jenv, retval); \ - } \ - return jretval; \ -} - -//may cause memory leak through yices_error_string -#define POINTER_RETURN \ - if(retval == NULL){ \ - const char *msg = yices_error_string(); \ - throwException(jenv, "java/lang/IllegalArgumentException", msg); \ - return 0; \ - } \ - return (long) retval; \ -} - -#define POINTER_ARG_RETURN(num) \ - if(retval == -1 && yices_error_code != 0){ \ - const char *msg = yices_error_string(); \ - throwException(jenv, "java/lang/IllegalArgumentException", msg); \ - return 0; \ - } \ - if(m_arg##num == NULL){ \ - throwException(jenv, "java/lang/IllegalArgumentException", "Pointer to return was NULL"); \ - return 0; \ - } \ - return (long) m_arg##num; \ -} -//may cause memory leak through yices_error_string -#define FROM_INT_POINTER_RETURN(num) \ - if(retval == -1) { \ - const char *msg = yices_error_string(); \ - throwException(jenv, "java/lang/IllegalArgumentException", msg); \ - return -1; \ - } \ - return (jint) *m_arg##num; \ - } - -//may cause memory leak through yices_error_string -#define FROM_LONG_POINTER_RETURN(num) \ - if(retval == -1) { \ - const char *msg = yices_error_string(); \ - throwException(jenv, "java/lang/IllegalArgumentException", msg); \ - return -1; \ - } \ - return (jlong) *m_arg##num; \ - } - -#define FROM_DOUBLE_POINTER_RETURN(num) \ - if(retval == -1) { \ - const char *msg = yices_error_string(); \ - throwException(jenv, "java/lang/IllegalArgumentException", msg); \ - return -1; \ - } \ - return (jdouble) *m_arg##num; \ - } - -#define MPQ_RETURN(num) \ - if(retval == -1) { \ - const char *msg = yices_error_string(); \ - throwException(jenv, "java/lang/IllegalArgumentException", msg); \ - } \ - char * mpqValue = mpq_get_str(NULL, 10, m_arg##num); \ - if(mpqValue == NULL){ \ - throwException(jenv, "java/lang/NullPointerException", "Result of mpq_get_str was NULL."); \ - } \ - jstring jretval = NULL; \ - if (!(*jenv)->ExceptionCheck(jenv)) { \ - jretval = (*jenv)->NewStringUTF(jenv, mpqValue); \ - } \ - mpq_clear(m_arg##num); \ - free(mpqValue); \ - return jretval; \ -} - -#define YVAL_RETURN(num) \ - if(retval == -1) { \ - const char *msg = yices_error_string(); \ - throwException(jenv, "java/lang/IllegalArgumentException", msg); \ - } \ - int yval[2]; \ - yval[0] = s_arg##num.node_id; \ - yval[1] = s_arg##num.node_tag; \ - jintArray jretval; \ - if (!(*jenv)->ExceptionCheck(jenv)) { \ - jretval = (*jenv)->NewIntArray(jenv, 2); \ - if(jretval != NULL){ \ - (*jenv)->SetIntArrayRegion(jenv, jretval, 0, 2, yval); \ - } \ - } \ - return jretval; \ -} - -#define INT_ARRAY_RETURN(num) \ - jintArray jretval = NULL; \ - if(retval == -1){ \ - const char *msg = yices_error_string(); \ - throwException(jenv, "java/lang/IllegalArgumentException", msg); \ - goto out; \ - } \ - if (!(*jenv)->ExceptionCheck(jenv)) { \ - jretval = (*jenv)->NewIntArray(jenv, sz); \ - if(jretval != NULL){ \ - (*jenv)->SetIntArrayRegion(jenv, jretval, 0, sz, m_arg##num); \ - } \ - } \ - out: \ - free(m_arg##num);\ - return jretval; \ -} - -#define TERM_VECTOR_ARG_RETURN(num) \ - jintArray jretval = NULL; \ - if ((*jenv)->ExceptionCheck(jenv)) { \ - goto out; \ - } \ - if(retval == -1){ \ - const char *msg = yices_error_string(); \ - throwException(jenv, "java/lang/IllegalArgumentException", msg); \ - goto out; \ - } \ - size_t sz = s_arg##num.size; \ - jint *jarr = malloc(sizeof(jint) * sz); \ - if (jarr == NULL) { \ - throwException(jenv, "java/lang/OutOfMemoryError", "Cannot allocate native memory for passing return value from Yices"); \ - goto out; \ - } \ - size_t i; \ - term_t * data = s_arg##num.data; \ - for (i = 0; i < sz; ++i) { \ - jarr[i] = (jint)((size_t)data[i]); \ - } \ - jretval = (*jenv)->NewIntArray(jenv, sz); \ - if (jretval != NULL) { \ - (*jenv)->SetIntArrayRegion(jenv, jretval, 0, sz, jarr); \ - } \ - free(jarr); \ - \ - out: \ - yices_delete_term_vector(m_arg##num); \ - return jretval; \ -} - -#define TYPE_VECTOR_ARG_RETURN(num) \ - jintArray jretval = NULL; \ - if ((*jenv)->ExceptionCheck(jenv)) { \ - goto out; \ - } \ - if(retval == -1){ \ - const char *msg = yices_error_string(); \ - throwException(jenv, "java/lang/IllegalArgumentException", msg); \ - return jretval; \ - goto out; \ - } \ - size_t sz = s_arg##num.size; \ - jint *jarr = malloc(sizeof(jint) * sz); \ - if (jarr == NULL) { \ - throwException(jenv, "java/lang/OutOfMemoryError", "Cannot allocate native memory for passing return value from Yices"); \ - goto out; \ - } \ - size_t i; \ - term_t * data = s_arg##num.data; \ - for (i = 0; i < sz; ++i) { \ - jarr[i] = (jint)((size_t)data[i]); \ - } \ - jretval = (*jenv)->NewIntArray(jenv, sz); \ - if (jretval != NULL) { \ - (*jenv)->SetIntArrayRegion(jenv, jretval, 0, sz, jarr); \ - } \ - free(jarr); \ - \ - out: \ - yices_delete_type_vector(m_arg##num); \ - return jretval; \ -} - - -// Define aliases for Yices types -typedef jlong jjctx; -#define CTX_ARG(num) POINTER_ARG(context_t, num) -#define CTX_ARG_VOID(num) POINTER_ARG(context_t, num) -#define CTX_RETURN POINTER_RETURN - -typedef jlong jjconf; -#define CONF_ARG(num) POINTER_ARG(ctx_config_t, num) -#define CONF_ARG_VOID(num) POINTER_ARG(ctx_config_t, num) -#define CONF_RETURN POINTER_RETURN - -typedef jlong jjparam; -#define PARAM_ARG(num) POINTER_ARG(param_t, num) -#define PARAM_ARG_VOID(num) POINTER_ARG(param_t, num) -#define PARAM_RETURN POINTER_RETURN - -typedef jint jjterm; -#define TERM_ARG(num) SIMPLE_ARG(term_t, num) -#define TERM_ARG_VOID(num) SIMPLE_ARG(term_t, num) -#define TERM_RETURN INT_RETURN - -typedef jlong jjmodel; -#define MODEL_ARG(num) POINTER_ARG(model_t, num) -#define MODEL_ARG_VOID(num) POINTER_ARG(model_t, num) -#define MODEL_RETURN POINTER_RETURN -//For things like model_t ** -#define MODEL_ARG_POINTER(num) POINTER_POINTER_ARG(model_t, num) - - -typedef jintArray jjtermArray; -#define TERM_ARRAY_ARG(num) INT_ARRAY_ARG(term_t, num) -#define FREE_TERM_ARRAY_ARG(num) FREE_INT_ARRAY_ARG(num) - -typedef jint jjtype; -#define TYPE_ARG(num) SIMPLE_ARG(type_t, num) -#define TYPE_RETURN INT_RETURN - -typedef jintArray jjtypeArray; -#define TYPE_ARRAY_ARG(num) INT_ARRAY_ARG(type_t, num) -#define FREE_TYPE_ARRAY_ARG(num) FREE_INT_ARRAY_ARG(num) - -typedef jint jjboolean; -#define BOOLEAN_RETURN INT_RETURN - -typedef jlong jjyval; -typedef jint jjnodeid; -typedef jint jjnodetag; - -// Abbreviations for common combinations of return and argument types - -#define get_yices_type(name) \ - DEFINE_FUNC(jtype, 1##name##_1type) WITHOUT_ARGS \ - CALL0(type_t, ##name##_type) \ - TYPE_RETURN - -#define yices_arith(name) \ - DEFINE_FUNC(jterm, 1arith_1##name##_1atom) WITH_ONE_ARG(jterm) \ - TERM_ARG(1) \ - CALL1(term_t, arith_##name##_atom) \ - TERM_RETURN - -#define yices_arith2(name) \ - DEFINE_FUNC(jterm, 1arith_1##name##_1atom) WITH_TWO_ARGS(jterm, jterm) \ - TERM_ARG(1) \ - TERM_ARG(2) \ - CALL2(term_t, arith_##name##_atom) \ - TERM_RETURN - -#define yices_type_is(name) \ - DEFINE_FUNC(jboolean, 1type_1is_1##name) WITH_ONE_ARG(jtype) \ - TYPE_ARG(1) \ - CALL1(type_t, type_is_##name) \ - BOOLEAN_RETURN - -#define yices_term_is(name) \ - DEFINE_FUNC(jboolean, 1term_1is_1##name) WITH_ONE_ARG(jterm) \ - TERM_ARG(1) \ - CALL1(type_t, term_is_##name) \ - BOOLEAN_RETURN - diff --git a/lib/native/source/yices2j/libyices2j.version b/lib/native/source/yices2j/libyices2j.version deleted file mode 100644 index cbd2701b10..0000000000 --- a/lib/native/source/yices2j/libyices2j.version +++ /dev/null @@ -1,12 +0,0 @@ -# This file is part of JavaSMT, -# an API wrapper for a collection of SMT solvers: -# https://github.com/sosy-lab/java-smt -# -# SPDX-FileCopyrightText: 2020 Dirk Beyer -# -# SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later - -YICES2J { - global: Java_*; - local: *; -}; diff --git a/lib/native/source/yices2j/org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c b/lib/native/source/yices2j/org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c deleted file mode 100644 index e4d808e591..0000000000 --- a/lib/native/source/yices2j/org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi.c +++ /dev/null @@ -1,1689 +0,0 @@ -// This file is part of JavaSMT, -// an API wrapper for a collection of SMT solvers: -// https://github.com/sosy-lab/java-smt -// -// Copyright (C) 2007-2020 Dirk Beyer -// SPDX-FileCopyrightText: 2020 Dirk Beyer -// -// SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later - -#include - -#include "includes/defines.h" - -/* - * Copied from the Sun JNI Programmer's Guide and Specification - */ -void throwException(JNIEnv *env, const char *name, const char *msg) { - jclass cls = (*env)->FindClass(env, name); - if (cls != NULL) { - (*env)->ThrowNew(env, cls, msg); - } -} - -/* - * Functions for initializing and freeing Yices internal data structures. - * Call init() before doing anything else to initialize data structures. - * Call exit() after to free allocated memory - */ -DEFINE_FUNC(void, 1init) WITHOUT_ARGS -VOID_CALL0(init) - -DEFINE_FUNC(void, 1exit) WITHOUT_ARGS -VOID_CALL0(exit) - -DEFINE_FUNC(void, 1reset) WITHOUT_ARGS -VOID_CALL0(reset) - -DEFINE_FUNC(void, 1free_1string) WITH_ONE_ARG(long) -POINTER_ARG(char, 1) -VOID_CALL1(free_string) - - -/* - * Create new Yices cnfiguration. - */ -DEFINE_FUNC(jconf, 1new_1config) WITHOUT_ARGS -CALL0(ctx_config_t *, new_config) -CONF_RETURN - -/* - * Delete the specified Yices configuration. - */ -DEFINE_FUNC(void, 1free_1config) WITH_ONE_ARG(jconf) -CONF_ARG_VOID(1) -VOID_CALL1(free_config) - -/* - * Set Yices configuration option. - */ - -DEFINE_FUNC(int, 1set_1config) WITH_THREE_ARGS(jconf, string, string) -CONF_ARG(1) -STRING_ARG(2) -STRING_ARG(3) -CALL3(int, set_config) -FREE_STRING_ARG(2) -FREE_STRING_ARG(3) -INT_RETURN - -DEFINE_FUNC(int, 1default_1config_1for_1logic) WITH_TWO_ARGS(jconf, string) -CONF_ARG(1) -STRING_ARG(2) -CALL2(int, default_config_for_logic) -FREE_STRING_ARG(2) -INT_RETURN - -/* - * Create Yices context with specified configuration. - */ -DEFINE_FUNC(jctx, 1new_1context) WITH_ONE_ARG(jconf) -CONF_ARG(1) -CALL1(context_t *, new_context) -CTX_RETURN - -/* - * Delete specified Yices context. - */ -DEFINE_FUNC(void, 1free_1context) WITH_ONE_ARG(jctx) -CTX_ARG_VOID(1) -VOID_CALL1(free_context) - -/* - *Preprocessing options - */ - -DEFINE_FUNC(int, 1context_1enable_1option) WITH_TWO_ARGS(jctx, string) -CTX_ARG(1) -STRING_ARG(2) -CALL2(int, context_enable_option) -FREE_STRING_ARG(2) -INT_RETURN - -DEFINE_FUNC(int, 1context_1disable_1option) WITH_TWO_ARGS(jctx, string) -CTX_ARG(1) -STRING_ARG(2) -CALL2(int, context_disable_option) -FREE_STRING_ARG(2) -INT_RETURN - -/* - *Search parameters - */ - -DEFINE_FUNC(long, 1new_1param_1record) WITHOUT_ARGS -CALL0(param_t*, new_param_record) -PARAM_RETURN - -DEFINE_FUNC(int, 1set_1param) WITH_THREE_ARGS(jparam, string, string) -PARAM_ARG(1) -STRING_ARG(2) -STRING_ARG(3) -CALL3(int, set_param) -FREE_STRING_ARG(2) -FREE_STRING_ARG(3) -INT_RETURN - -DEFINE_FUNC(void, 1default_1params_1for_1context) WITH_TWO_ARGS(jctx, jparam) -CTX_ARG(1) -PARAM_ARG(2) -VOID_CALL2(default_params_for_context) - -DEFINE_FUNC(void, 1free_1param_1record) WITH_ONE_ARG(jparam) -PARAM_ARG(1) -VOID_CALL1(free_param_record) - -/* - * Yices type constructors - */ - -DEFINE_FUNC(jtype, 1bool_1type) WITHOUT_ARGS -CALL0(type_t, bool_type) -TYPE_RETURN - -DEFINE_FUNC(jtype, 1int_1type) WITHOUT_ARGS -CALL0(type_t, int_type) -TYPE_RETURN - -DEFINE_FUNC(jtype, 1real_1type) WITHOUT_ARGS -CALL0(type_t, real_type) -TYPE_RETURN - -DEFINE_FUNC(jtype, 1bv_1type) WITH_ONE_ARG (int) -UINT32_ARG(1) -CALL1(type_t, bv_type) -TYPE_RETURN - -//scalar type skipped - -// uninterpreted type skipped - -// tuple types skipped - -DEFINE_FUNC(jtype, 1function_1type) WITH_THREE_ARGS(int, jtypeArray, jtype) -UINT32_ARG(1) -TYPE_ARRAY_ARG(2) -TYPE_ARG(3) -CALL3(type_t, function_type) -FREE_TYPE_ARRAY_ARG(2) -TYPE_RETURN - -//redundant function types skipped - -/* - * Yices type tests - */ - -yices_type_is(bool) - -yices_type_is(int) - -yices_type_is(real) - -//check if type is arithmetic (int or real) -yices_type_is(arithmetic) - -yices_type_is(bitvector) - -//tests for previously skipped types skipped - -yices_type_is(function) - -//checks if type1 is subtype of type 2 -DEFINE_FUNC(jboolean, 1type_1test_1subtype) WITH_TWO_ARGS(jtype, jtype) -TYPE_ARG(1) -TYPE_ARG(2) -CALL2(int, test_subtype) -BOOLEAN_RETURN - -//checks if type 1 and type2 are compatible -DEFINE_FUNC(jboolean, 1compatible_1types) WITH_TWO_ARGS(jtype, jtype) -TYPE_ARG(1) -TYPE_ARG(2) -CALL2(int, compatible_types) -BOOLEAN_RETURN - -DEFINE_FUNC(int, 1bvtype_1size) WITH_ONE_ARG(jtype) -TYPE_ARG(1) -CALL1(int, bvtype_size) -INT_RETURN - -//skipping scalar_type_card() - -DEFINE_FUNC(int, 1type_1num_1children) WITH_ONE_ARG(jtype) -TYPE_ARG(1) -CALL1(int, type_num_children) -INT_RETURN - -DEFINE_FUNC(jtype, 1type_1child) WITH_TWO_ARGS(jtype, int) -TYPE_ARG(1) -SIMPLE_ARG(int32_t, 2) -CALL2(type_t, type_child) -TYPE_RETURN - -DEFINE_FUNC(intArray, 1type_1children) WITH_ONE_ARG(jtype) -TYPE_ARG(1) -TYPE_VECTOR_ARG(2) -CALL2(int, type_children) -TYPE_VECTOR_ARG_RETURN(2) - -/* - * Term construction - */ - -DEFINE_FUNC(jterm, 1new_1uninterpreted_1term) WITH_ONE_ARG(jtype) -TYPE_ARG(1) -CALL1(term_t, new_uninterpreted_term) -TERM_RETURN - -DEFINE_FUNC(jterm, 1new_1variable) WITH_ONE_ARG(jtype) -TYPE_ARG(1) -CALL1(term_t, new_variable) -TERM_RETURN - -//ONLY for scalar or uninterprted type which are currently not implemented -DEFINE_FUNC(jterm, 1constant) WITH_TWO_ARGS(jtype, int) -TYPE_ARG(1) -SIMPLE_ARG(int32_t, 2) -CALL2(term_t, constant) -TERM_RETURN - -DEFINE_FUNC(jterm, 1ite) WITH_THREE_ARGS(jterm, jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -TERM_ARG(3) -CALL3(term_t, ite) -TERM_RETURN - -DEFINE_FUNC(jterm, 1eq) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, eq) -TERM_RETURN - -DEFINE_FUNC(jterm, 1neq) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, neq) -TERM_RETURN - -DEFINE_FUNC(jterm, 1distinct) WITH_TWO_ARGS(int, jtermArray) -UINT32_ARG(1) -TERM_ARRAY_ARG(2) -CALL2(term_t, distinct) -FREE_TERM_ARRAY_ARG(2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1application) WITH_THREE_ARGS(jterm, int, jtermArray) -TERM_ARG(1) -UINT32_ARG(2) -TERM_ARRAY_ARG(3) -CALL3(term_t, application) -FREE_TERM_ARRAY_ARG(3) -TERM_RETURN - -//skipping redundant functions - -//skipping tuple fuctions - -DEFINE_FUNC(jterm, 1update) WITH_FOUR_ARGS(jterm, int, jtermArray, jterm) -TERM_ARG(1) -UINT32_ARG(2) -TERM_ARRAY_ARG(3) -TERM_ARG(4) -CALL4(term_t, update) -FREE_TERM_ARRAY_ARG(3) -TERM_RETURN - -//skipping redundant functions - -DEFINE_FUNC(jterm, 1forall) WITH_THREE_ARGS(int, jtermArray, jterm) -UINT32_ARG(1) -TERM_ARRAY_ARG(2) -TERM_ARG(3) -CALL3(term_t, forall) -FREE_TERM_ARRAY_ARG(2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1exists) WITH_THREE_ARGS(int, jtermArray, jterm) -UINT32_ARG(1) -TERM_ARRAY_ARG(2) -TERM_ARG(3) -CALL3(term_t, exists) -FREE_TERM_ARRAY_ARG(2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1lambda) WITH_THREE_ARGS(int, jtermArray, jterm) -UINT32_ARG(1) -TERM_ARRAY_ARG(2) -TERM_ARG(3) -CALL3(term_t, lambda) -FREE_TERM_ARRAY_ARG(2) -TERM_RETURN - -/* - * Boolean terms - */ - -DEFINE_FUNC(jterm, 1true) WITHOUT_ARGS -CALL0(term_t, true) -TERM_RETURN - -DEFINE_FUNC(jterm, 1false) WITHOUT_ARGS -CALL0(term_t, false) -TERM_RETURN - -DEFINE_FUNC(jterm, 1not) WITH_ONE_ARG(jterm) -TERM_ARG(1) -CALL1(term_t, not) -TERM_RETURN - -DEFINE_FUNC(jterm, 1and) WITH_TWO_ARGS(int, jtermArray) -UINT32_ARG(1) -TERM_ARRAY_ARG(2) -CALL2(term_t, and) -FREE_TERM_ARRAY_ARG(2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1and2) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, and2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1and3) WITH_THREE_ARGS(jterm, jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -TERM_ARG(3) -CALL3(term_t, and3) -TERM_RETURN - -DEFINE_FUNC(jterm, 1or) WITH_TWO_ARGS(int, jtermArray) -UINT32_ARG(1) -TERM_ARRAY_ARG(2) -CALL2(term_t, or) -FREE_TERM_ARRAY_ARG(2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1or2) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, or2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1or3) WITH_THREE_ARGS(jterm, jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -TERM_ARG(3) -CALL3(term_t, or3) -TERM_RETURN - -DEFINE_FUNC(jterm, 1xor) WITH_TWO_ARGS(int, jtermArray) -UINT32_ARG(1) -TERM_ARRAY_ARG(2) -CALL2(term_t, xor) -FREE_TERM_ARRAY_ARG(2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1xor2) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, xor2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1xor3) WITH_THREE_ARGS(jterm, jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -TERM_ARG(3) -CALL3(term_t, xor3) -TERM_RETURN - -DEFINE_FUNC(jterm, 1iff) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, iff) -TERM_RETURN - -DEFINE_FUNC(jterm, 1implies) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, implies) -TERM_RETURN - -/* - * ARITHMETIC TERMS - */ - -DEFINE_FUNC(jterm, 1zero) WITHOUT_ARGS -CALL0(term_t, zero) -TERM_RETURN - -DEFINE_FUNC(jterm, 1int32) WITH_ONE_ARG(int) -SIMPLE_ARG(int32_t, 1) -CALL1(term_t, int32) -TERM_RETURN - -DEFINE_FUNC(jterm, 1int64) WITH_ONE_ARG(long) -SIMPLE_ARG(int64_t, 1) -CALL1(term_t, int64) -TERM_RETURN - -DEFINE_FUNC(jterm, 1rational32) WITH_TWO_ARGS(int, int) -SIMPLE_ARG(int32_t, 1) -UINT32_ARG(2) -CALL2(term_t, rational32) -TERM_RETURN - -DEFINE_FUNC(jterm, 1rational64) WITH_TWO_ARGS(long, long) -SIMPLE_ARG(int64_t, 1) -SIMPLE_ARG(uint64_t, 2) -CALL2(term_t, rational64) -TERM_RETURN - -//skipping GMP functions - -DEFINE_FUNC(jterm, 1parse_1rational) WITH_ONE_ARG(string) -STRING_ARG(1) -CALL1(term_t, parse_rational) -FREE_STRING_ARG(1) -TERM_RETURN - -DEFINE_FUNC(jterm, 1parse_1float) WITH_ONE_ARG(string) -STRING_ARG(1) -CALL1(term_t, parse_float) -FREE_STRING_ARG(1) -TERM_RETURN - -DEFINE_FUNC(jterm, 1add) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, add) -TERM_RETURN - -DEFINE_FUNC(jterm, 1sub) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, sub) -TERM_RETURN - -DEFINE_FUNC(jterm, 1neg) WITH_ONE_ARG(jterm) -TERM_ARG(1) -CALL1(term_t, neg) -TERM_RETURN - -DEFINE_FUNC(jterm, 1mul) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, mul) -TERM_RETURN - -DEFINE_FUNC(jterm, 1square) WITH_ONE_ARG(jterm) -TERM_ARG(1) -CALL1(term_t, square) -TERM_RETURN - -DEFINE_FUNC(jterm, 1power) WITH_TWO_ARGS(jterm, int) -TERM_ARG(1) -UINT32_ARG(2) -CALL2(term_t, power) -TERM_RETURN - -DEFINE_FUNC(jterm, 1division) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, division) -TERM_RETURN - -DEFINE_FUNC(jterm, 1sum) WITH_TWO_ARGS(int, jtermArray) -UINT32_ARG(1) -TERM_ARRAY_ARG(2) -CALL2(term_t, sum) -FREE_TERM_ARRAY_ARG(2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1product) WITH_TWO_ARGS(int, jtermArray) -UINT32_ARG(1) -TERM_ARRAY_ARG(2) -CALL2(term_t, product) -FREE_TERM_ARRAY_ARG(2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1poly_1int32) WITH_THREE_ARGS(int, intArray, jtermArray) -UINT32_ARG(1) -INT_ARRAY_ARG(int32_t, 2) -TERM_ARRAY_ARG(3) -CALL3(term_t, poly_int32) -FREE_INT_ARRAY_ARG(2) -FREE_TERM_ARRAY_ARG(3) -TERM_RETURN - -DEFINE_FUNC(jterm, 1poly_1int64) WITH_THREE_ARGS(int, longArray, jtermArray) -UINT32_ARG(1) -LONG_ARRAY_ARG(int64_t, 2) -TERM_ARRAY_ARG(3) -CALL3(term_t, poly_int64) -FREE_LONG_ARRAY_ARG(2) -FREE_TERM_ARRAY_ARG(3) -TERM_RETURN - -//skipping poly_rational32() - -//skipping poly_rational64() - -//skipping gmp functions - -DEFINE_FUNC(jterm, 1abs) WITH_ONE_ARG(jterm) -TERM_ARG(1) -CALL1(term_t, abs) -TERM_RETURN - -DEFINE_FUNC(jterm, 1floor) WITH_ONE_ARG(jterm) -TERM_ARG(1) -CALL1(term_t, floor) -TERM_RETURN - -DEFINE_FUNC(jterm, 1ceil) WITH_ONE_ARG(jterm) -TERM_ARG(1) -CALL1(term_t, ceil) -TERM_RETURN - -DEFINE_FUNC(jterm, 1idiv) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, idiv) -TERM_RETURN - -DEFINE_FUNC(jterm, 1imod) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, imod) -TERM_RETURN - -/* - * Arith operations with two arguments - */ -yices_arith2(eq) -yices_arith2(neq) -yices_arith2(geq) -yices_arith2(leq) -yices_arith2(gt) -yices_arith2(lt) - -/* - * Arith operations with one argument - */ -yices_arith(eq0) -yices_arith(neq0) -yices_arith(geq0) -yices_arith(leq0) -yices_arith(gt0) -yices_arith(lt0) - -DEFINE_FUNC(jterm, 1divides_1atom) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, divides_atom) -TERM_RETURN - -DEFINE_FUNC(jterm, 1is_1int_1atom) WITH_ONE_ARG(jterm) -TERM_ARG(1) -CALL1(term_t, is_int_atom) -TERM_RETURN - -/* - * BITVECTOR TERMS - */ - -DEFINE_FUNC(jterm, 1bvconst_1uint32) WITH_TWO_ARGS(int, int) -UINT32_ARG(1) -UINT32_ARG(2) -CALL2(term_t, bvconst_uint32) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvconst_1uint64) WITH_TWO_ARGS(int, long) -UINT32_ARG(1) -SIMPLE_ARG(uint64_t, 2) -CALL2(term_t, bvconst_uint64) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvconst_1int32) WITH_TWO_ARGS (int, int) -UINT32_ARG(1) -SIMPLE_ARG(int32_t, 2) -CALL2(term_t, bvconst_int32) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvconst_1int64) WITH_TWO_ARGS(int, long) -UINT32_ARG(1) -SIMPLE_ARG(int64_t, 2) -CALL2(term_t, bvconst_int64) -TERM_RETURN - -//GMP FUnctions skipped - -DEFINE_FUNC(jterm, 1bvconst_1zero) WITH_ONE_ARG(int) -UINT32_ARG(1) -CALL1(term_t, bvconst_zero) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvconst_1one) WITH_ONE_ARG(int) -UINT32_ARG(1) -CALL1(term_t, bvconst_one) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvconst_1minus_1one) WITH_ONE_ARG(int) -UINT32_ARG(1) -CALL1(term_t, bvconst_minus_one) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvconst_1from_1array) WITH_TWO_ARGS(int, intArray) -UINT32_ARG(1) -INT_ARRAY_ARG(int32_t, 2) -CALL2(term_t, bvconst_from_array) -FREE_INT_ARRAY_ARG(2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1parse_1bvbin) WITH_ONE_ARG(string) -STRING_ARG(1) -CALL1(term_t, parse_bvbin) -FREE_STRING_ARG(1) -TERM_RETURN - -DEFINE_FUNC(jterm, 1parse_1bvhex) WITH_ONE_ARG(string) -STRING_ARG(1) -CALL1(term_t, parse_bvhex) -FREE_STRING_ARG(1) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvadd) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvadd) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvsub) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvsub) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvneg) WITH_ONE_ARG(jterm) -TERM_ARG(1) -CALL1(term_t, bvneg) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvmul) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvmul) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvsquare) WITH_ONE_ARG(jterm) -TERM_ARG(1) -CALL1(term_t, bvsquare) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvpower) WITH_TWO_ARGS(jterm, int) -TERM_ARG(1) -UINT32_ARG(2) -CALL2(term_t, bvpower) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvsum) WITH_TWO_ARGS(int, jtermArray) -UINT32_ARG(1) -TERM_ARRAY_ARG(2) -CALL2(term_t, bvsum) -FREE_TERM_ARRAY_ARG(2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvproduct) WITH_TWO_ARGS(int, jtermArray) -UINT32_ARG(1) -TERM_ARRAY_ARG(2) -CALL2(term_t, bvproduct) -FREE_TERM_ARRAY_ARG(2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvdiv) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvdiv) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvrem) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvrem) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvsdiv) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvsdiv) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvsrem) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvsrem) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvsmod) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvsmod) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvnot) WITH_ONE_ARG(jterm) -TERM_ARG(1) -CALL1(term_t, bvnot) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvand) WITH_TWO_ARGS(int, jtermArray) -UINT32_ARG(1) -TERM_ARRAY_ARG(2) -CALL2(term_t, bvand) -FREE_TERM_ARRAY_ARG(2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvand2) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvand2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvand3) WITH_THREE_ARGS(jterm, jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -TERM_ARG(3) -CALL3(term_t, bvand3) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvor) WITH_TWO_ARGS(int, jtermArray) -UINT32_ARG(1) -TERM_ARRAY_ARG(2) -CALL2(term_t, bvor) -FREE_TERM_ARRAY_ARG(2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvor2) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvor2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvor3) WITH_THREE_ARGS(jterm, jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -TERM_ARG(3) -CALL3(term_t, bvor3) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvxor) WITH_TWO_ARGS(int, jtermArray) -UINT32_ARG(1) -TERM_ARRAY_ARG(2) -CALL2(term_t, bvxor) -FREE_TERM_ARRAY_ARG(2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvxor2) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvxor2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvxor3) WITH_THREE_ARGS(jterm, jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -TERM_ARG(3) -CALL3(term_t, bvxor3) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvnand) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvnand) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvnor) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvnor) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvxnor) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvxnor) -TERM_RETURN - -DEFINE_FUNC(jterm, 1shift_1left0) WITH_TWO_ARGS(jterm, int) -TERM_ARG(1) -UINT32_ARG(2) -CALL2(term_t, shift_left0) -TERM_RETURN - -DEFINE_FUNC(jterm, 1shift_1left1) WITH_TWO_ARGS(jterm, int) -TERM_ARG(1) -UINT32_ARG(2) -CALL2(term_t, shift_left1) -TERM_RETURN - -DEFINE_FUNC(jterm, 1shift_1right0) WITH_TWO_ARGS(jterm, int) -TERM_ARG(1) -UINT32_ARG(2) -CALL2(term_t, shift_right0) -TERM_RETURN - -DEFINE_FUNC(jterm, 1shift_1right1) WITH_TWO_ARGS(jterm, int) -TERM_ARG(1) -UINT32_ARG(2) -CALL2(term_t, shift_right1) -TERM_RETURN - -DEFINE_FUNC(jterm, 1ashift_1right) WITH_TWO_ARGS(jterm, int) -TERM_ARG(1) -UINT32_ARG(2) -CALL2(term_t, ashift_right) -TERM_RETURN - -DEFINE_FUNC(jterm, 1rotate_1left) WITH_TWO_ARGS(jterm, int) -TERM_ARG(1) -UINT32_ARG(2) -CALL2(term_t, rotate_left) -TERM_RETURN - -DEFINE_FUNC(jterm, 1rotate_1right) WITH_TWO_ARGS(jterm, int) -TERM_ARG(1) -UINT32_ARG(2) -CALL2(term_t, rotate_right) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvshl) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvshl) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvlshr) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvlshr) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvashr) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvashr) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvextract) WITH_THREE_ARGS(jterm, int, int) -TERM_ARG(1) -UINT32_ARG(2) -UINT32_ARG(3) -CALL3(term_t, bvextract) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bitextract) WITH_TWO_ARGS(jterm, int) -TERM_ARG(1) -UINT32_ARG(2) -CALL2(term_t, bitextract) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvconcat) WITH_TWO_ARGS(int, jtermArray) -UINT32_ARG(1) -TERM_ARRAY_ARG(2) -CALL2(term_t, bvconcat) -FREE_TERM_ARRAY_ARG(2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvconcat2) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvconcat2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvrepeat) WITH_TWO_ARGS(jterm, int) -TERM_ARG(1) -UINT32_ARG(2) -CALL2(term_t, bvrepeat) -TERM_RETURN - -DEFINE_FUNC(jterm, 1sign_1extend) WITH_TWO_ARGS(jterm, int) -TERM_ARG(1) -UINT32_ARG(2) -CALL2(term_t, sign_extend) -TERM_RETURN - -DEFINE_FUNC(jterm, 1zero_1extend) WITH_TWO_ARGS(jterm, int) -TERM_ARG(1) -UINT32_ARG(2) -CALL2(term_t, zero_extend) -TERM_RETURN - -DEFINE_FUNC(jterm, 1redand) WITH_ONE_ARG(jterm) -TERM_ARG(1) -CALL1(term_t, redand) -TERM_RETURN - -DEFINE_FUNC(jterm, 1redor) WITH_ONE_ARG(jterm) -TERM_ARG(1) -CALL1(term_t, redor) -TERM_RETURN - -DEFINE_FUNC(jterm, 1redcomp) WITH_TWO_ARGS(jterm,jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, redcomp) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvarray) WITH_TWO_ARGS(int, jtermArray) -UINT32_ARG(1) -TERM_ARRAY_ARG(2) -CALL2(term_t, bvarray) -FREE_TERM_ARRAY_ARG(2) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bveq_1atom) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bveq_atom) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvneq_1atom) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvneq_atom) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvge_1atom) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvge_atom) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvgt_1atom) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvgt_atom) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvle_1atom) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvle_atom) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvlt_1atom) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvlt_atom) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvsge_1atom) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvsge_atom) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvsgt_1atom) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvsgt_atom) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvsle_1atom) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvsle_atom) -TERM_RETURN - -DEFINE_FUNC(jterm, 1bvslt_1atom) WITH_TWO_ARGS(jterm, jterm) -TERM_ARG(1) -TERM_ARG(2) -CALL2(term_t, bvslt_atom) -TERM_RETURN - -/* - * TERM PROPERTIES - */ - -DEFINE_FUNC(jtype, 1type_1of_1term) WITH_ONE_ARG(jterm) -TERM_ARG(1) -CALL1(type_t, type_of_term) -TYPE_RETURN - -yices_term_is(bool) - -yices_term_is(int) - -yices_term_is(real) - -yices_term_is(arithmetic) - -yices_term_is(bitvector) - -//scalar + tuple skipped - -yices_term_is(function) - -DEFINE_FUNC(int, 1term_1bitsize) WITH_ONE_ARG(jterm) -TERM_ARG(1) -CALL1(int, term_bitsize) -INT_RETURN - -DEFINE_FUNC(jboolean, 1term_1is_1ground) WITH_ONE_ARG(jterm) -TERM_ARG(1) -CALL1(int, term_is_ground) -BOOLEAN_RETURN - -yices_term_is(atomic) - -yices_term_is(composite) - -yices_term_is(projection) - -yices_term_is(sum) - -yices_term_is(bvsum) - -yices_term_is(product) - -DEFINE_FUNC(int, 1term_1constructor) WITH_ONE_ARG(jterm) -TERM_ARG(1) -CALL1(term_constructor_t, term_constructor) -INT_RETURN - -DEFINE_FUNC(int, 1term_1num_1children) WITH_ONE_ARG(jterm) -TERM_ARG(1) -CALL1(int, term_num_children) -INT_RETURN - -DEFINE_FUNC(jterm, 1term_1child) WITH_TWO_ARGS(jterm, int) -TERM_ARG(1) -SIMPLE_ARG(int32_t, 2) -CALL2(term_t, term_child) -TERM_RETURN - -DEFINE_FUNC(int, 1proj_1index) WITH_ONE_ARG(jterm) -TERM_ARG(1) -CALL1(int, proj_index) -INT_RETURN - -DEFINE_FUNC(jterm, 1proj_1arg) WITH_ONE_ARG(jterm) -TERM_ARG(1) -CALL1(term_t, proj_arg) -TERM_RETURN - -DEFINE_FUNC(int, 1bool_1const_1value) WITH_ONE_ARG(jterm) -TERM_ARG(1) -INT_POINTER_ARG(2) -CALL2(int, bool_const_value) -FROM_INT_POINTER_RETURN(2) - -DEFINE_FUNC(intArray, 1bv_1const_1value) WITH_TWO_ARGS(jterm, int) -TERM_ARG(1) -EMPTY_INT_ARRAY_ARG(int32_t, 2) -CALL2(int, bv_const_value) -INT_ARRAY_RETURN(2) - -//scalar_const_value skipped - -DEFINE_FUNC(string, 1rational_1const_1value) WITH_ONE_ARG(jterm) -TERM_ARG(1) -MPQ_ARG(2) -CALL2(int, rational_const_value) -MPQ_RETURN(2) - -//TODO FREE strings/arrays // setObjectiveArray -DEFINE_FUNC(objectArray, 1sum_1component) WITH_TWO_ARGS(jterm, int) -TERM_ARG(1) -SIMPLE_ARG(int32_t, 2) -MPQ_ARG(3) -term_t s_arg4; -term_t *m_arg4 = &s_arg4; -CALL4(int, sum_component) -if (retval == -1) { - const char *msg = yices_error_string(); - throwException(jenv, "java/lang/IllegalArgumentException", msg); -} -char *mpqString = mpq_get_str(NULL, 10, m_arg3); -char term[12]; //should be enough for MAX_INT32 -snprintf(term, 12, "%d", s_arg4); -if ((*jenv)->ExceptionCheck(jenv)) { - goto out; -} -jclass stringClass = (*jenv)->FindClass(jenv,"java/lang/String"); -jobjectArray jretval = NULL; -jretval = (jobjectArray)(*jenv)->NewObjectArray(jenv, 2,stringClass,(*jenv)->NewStringUTF(jenv, "")); -if (jretval != NULL) { - (*jenv)->SetObjectArrayElement(jenv, jretval, 0, (*jenv)->NewStringUTF(jenv, mpqString)); - (*jenv)->SetObjectArrayElement(jenv, jretval, 1, (*jenv)->NewStringUTF(jenv, term)); -} -out: -mpq_clear(m_arg3); -return jretval; -} - -//TODO FREE strings/arrays -DEFINE_FUNC(intArray, 1bvsum_1component) WITH_THREE_ARGS(jterm, int, int) -TERM_ARG(1) -SIMPLE_ARG(int32_t, 2) -arg3++; -EMPTY_INT_ARRAY_ARG(int32_t, 3) -term_t s_arg4; -term_t *m_arg4 = &s_arg4; -CALL4(int, bvsum_component); -jintArray jretval = NULL; -m_arg3[sz-1] = s_arg4; -if (retval == -1) { - const char *msg = yices_error_string(); - throwException(jenv, "java/lang/IllegalArgumentException", msg); -} -if ((*jenv)->ExceptionCheck(jenv)) { - goto out; -} -jretval = (*jenv)->NewIntArray(jenv, sz); -if (jretval != NULL) { - (*jenv)->SetIntArrayRegion(jenv, jretval, 0, sz, m_arg3); -} -out: -free(m_arg3); -return jretval; -} - -//TODO FREE strings/arrays, Potential overflow uint32 -> jint -DEFINE_FUNC(intArray, 1product_1component) WITH_TWO_ARGS(jterm, int) -TERM_ARG(1) -SIMPLE_ARG(int32_t, 2) -term_t s_arg3; -term_t *m_arg3 = &s_arg3; -uint32_t s_arg4 = 0; -uint32_t *m_arg4 = &s_arg4; -CALL4(int, product_component) -jintArray jretval = NULL; -if (retval == -1) { - const char *msg = yices_error_string(); - throwException(jenv, "java/lang/IllegalArgumentException", msg); -} -jint *jarr = malloc(sizeof(jint) * 2); -if (jarr == NULL) { - throwException(jenv, "java/lang/OutOfMemoryError", "Cannot allocate native memory for passing return value from Yices"); - goto out; -} -jarr[0] = s_arg3; -jarr[1] = (jint) *m_arg4; -if ((*jenv)->ExceptionCheck(jenv)) { - goto out; -} -jretval = (*jenv)->NewIntArray(jenv, 2); -if (jretval != NULL) { - (*jenv)->SetIntArrayRegion(jenv, jretval, 0, 2, jarr); -} -free (jarr); -out: -return jretval; -} - -/* - * Assertions and SAT Checking - */ - -DEFINE_FUNC(int, 1context_1status) WITH_ONE_ARG(jctx) -CTX_ARG(1) -CALL1(smt_status_t, context_status) -INT_RETURN - -DEFINE_FUNC(int, 1assert_1formula) WITH_TWO_ARGS(jctx, jterm) -CTX_ARG(1) -TERM_ARG(2) -CALL2(int, assert_formula) -INT_RETURN - -DEFINE_FUNC(int, 1assert_1formulas) WITH_THREE_ARGS(jctx, int, jtermArray) -CTX_ARG(1) -UINT32_ARG(2) -TERM_ARRAY_ARG(3) -CALL3(int, assert_formulas) -FREE_TERM_ARRAY_ARG(3) -INT_RETURN - -DEFINE_FUNC(int, 1check_1context) WITH_TWO_ARGS (jctx, jparam) -CTX_ARG(1) -PARAM_ARG(2) -CALL2(smt_status_t, check_context) -INT_RETURN - -DEFINE_FUNC(void, 1stop_1search) WITH_ONE_ARG(jctx) -CTX_ARG(1) -VOID_CALL1(stop_search) - -DEFINE_FUNC(void, 1reset_1context) WITH_ONE_ARG(jctx) -CTX_ARG(1) -VOID_CALL1(reset_context) - -DEFINE_FUNC(int, 1assert_1blocking_1clause) WITH_ONE_ARG(jctx) -CTX_ARG(1) -CALL1(int, assert_blocking_clause) -INT_RETURN - -DEFINE_FUNC(int, 1push) WITH_ONE_ARG(jctx) -CTX_ARG(1) -CALL1(int, push) -INT_RETURN - -DEFINE_FUNC(int, 1pop) WITH_ONE_ARG(jctx) -CTX_ARG(1) -CALL1(int, pop) -INT_RETURN - -DEFINE_FUNC(int, 1check_1context_1with_1assumptions) WITH_FOUR_ARGS (jctx, jparam, int, jtermArray) -CTX_ARG(1) -PARAM_ARG(2) -UINT32_ARG(3) -TERM_ARRAY_ARG(4) -CALL4(smt_status_t, check_context_with_assumptions) -FREE_TERM_ARRAY_ARG(4) -INT_RETURN - -DEFINE_FUNC(jtermArray, 1get_1unsat_1core) WITH_ONE_ARG(jctx) -CTX_ARG(1) -TERM_VECTOR_ARG(2) -CALL2(int, get_unsat_core) -TERM_VECTOR_ARG_RETURN(2) - -/* - * Model Generation and Exploration - */ - -DEFINE_FUNC(jmodel, 1get_1model) WITH_TWO_ARGS(jctx, int) -CTX_ARG(1) -SIMPLE_ARG(int32_t, 2) -CALL2(model_t *, get_model) -MODEL_RETURN - -DEFINE_FUNC(jmodel, 1model_1from_1map) WITH_THREE_ARGS(int ,jtermArray, jtermArray) -UINT32_ARG(1) -TERM_ARRAY_ARG(2) -TERM_ARRAY_ARG(3) -CALL3(model_t *, model_from_map) -FREE_TERM_ARRAY_ARG(2) -FREE_TERM_ARRAY_ARG(3) -MODEL_RETURN - -//1model_1collect_1defined_1terms - -DEFINE_FUNC(jtermArray, 1def_1terms) WITH_ONE_ARG(jmodel) -MODEL_ARG(1) -TERM_VECTOR_ARG(2) -VOID_CALL2_WITH_RETURN(model_collect_defined_terms) -int retval = 0; //declare retval for TERM_VECTOR_ARG_RETURN -TERM_VECTOR_ARG_RETURN(2) - -//yices_exit includes free_model() -DEFINE_FUNC(void, 1free_1model) WITH_ONE_ARG(jmodel) -MODEL_ARG(1) -VOID_CALL1(free_model) - -/* - * TERM VALUES IN MODEL - */ - -DEFINE_FUNC(int, 1get_1bool_1value) WITH_TWO_ARGS(jmodel, jterm) -MODEL_ARG(1) -TERM_ARG(2) -INT_POINTER_ARG(3) -CALL3(int, get_bool_value) -FROM_INT_POINTER_RETURN(3) - -DEFINE_FUNC(int, 1get_1int32_1value) WITH_TWO_ARGS(jmodel, jterm) -MODEL_ARG(1) -TERM_ARG(2) -INT_POINTER_ARG(3) -CALL3(int, get_bool_value) -FROM_INT_POINTER_RETURN(3) - -DEFINE_FUNC(long, 1get_1int64_1value) WITH_TWO_ARGS(jmodel, jterm) -MODEL_ARG(1) -TERM_ARG(2) -LONG_POINTER_ARG(3) -CALL3(int, get_int64_value) -FROM_LONG_POINTER_RETURN(3) - -// skipping get_rational32 | get_rational_64 - -DEFINE_FUNC(double, 1get_1_double_value) WITH_TWO_ARGS(jmodel, jterm) -MODEL_ARG(1) -TERM_ARG(2) -DOUBLE_POINTER_ARG(3) -CALL3(int, get_double_value) -FROM_DOUBLE_POINTER_RETURN(3) - -//skipping gmp functions - -//skipping get_algebraic_number_value - -DEFINE_FUNC(intArray, 1get_1bv_1value) WITH_THREE_ARGS(jmodel, jterm, int) -MODEL_ARG(1) -TERM_ARG(2) -EMPTY_INT_ARRAY_ARG(int32_t, 3) -CALL3(int, get_bv_value) -INT_ARRAY_RETURN(3) - -//skipping get_scalar_value - -DEFINE_FUNC(int, 1formula_1true_1in_1model) WITH_TWO_ARGS(jmodel, jterm) -MODEL_ARG(1) -TERM_ARG(2) -CALL2(int, formula_true_in_model) -INT_RETURN - -DEFINE_FUNC(int, 1formulas_1true_1in_1model) WITH_THREE_ARGS(jmodel, int, jtermArray) -MODEL_ARG(1) -UINT32_ARG(2) -TERM_ARRAY_ARG(3) -CALL3(int, formulas_true_in_model) -FREE_TERM_ARRAY_ARG(3) -INT_RETURN - -DEFINE_FUNC(intArray, 1get_1value) WITH_TWO_ARGS(jmodel, jterm) -MODEL_ARG(1) -TERM_ARG(2) -EMPTY_YVAL_ARG(3) -CALL3(int, get_value) -YVAL_RETURN(3) - -//skipping val_is_ - -DEFINE_FUNC(int, 1val_1bitsize) WITH_THREE_ARGS(jmodel, jnodeid, jnodetag) -MODEL_ARG(1) -YVAL_ARG(2, 2, 3) -CALL2(int, val_bitsize) -INT_RETURN - -//skipping val_tuple_arity - -DEFINE_FUNC(int, 1val_1function_1arity) WITH_THREE_ARGS(jmodel, jnodeid, jnodetag) -MODEL_ARG(1) -YVAL_ARG(2, 2, 3) -CALL2(int, val_function_arity) -INT_RETURN - -//skipping val_mapping_arity - -DEFINE_FUNC(int, 1val_1get_1bool) WITH_THREE_ARGS(jmodel, jnodeid, jnodetag) -MODEL_ARG(1) -YVAL_ARG(2, 2, 3) -INT_POINTER_ARG(3) -CALL3(int, val_get_bool) -FROM_INT_POINTER_RETURN(3) - -// skipping val_get_(arith type) functions in favor of val_get_mpq - -DEFINE_FUNC(string, 1val_1get_1mpq) WITH_THREE_ARGS(jmodel, jnodeid, jnodetag) -MODEL_ARG(1) -YVAL_ARG(2, 2, 3) -MPQ_ARG(3) -CALL3(int, val_get_mpq) -MPQ_RETURN(3) - -//skipping val_get_algebraic_number - -DEFINE_FUNC(intArray, 1val_1get_1bv) WITH_FOUR_ARGS(jmodel, jnodeid, int, jnodetag) -MODEL_ARG(1) -YVAL_ARG(2, 2, 4) -EMPTY_INT_ARRAY_ARG(int32_t, 3) -CALL3(int, val_get_bv) -INT_ARRAY_RETURN(3) - -//skipping val_get_scalar -//skipping val_expand_tuple - -DEFINE_FUNC(intArray, 1val_1expand_1function) WITH_THREE_ARGS(jmodel, jnodeid, jnodetag) -MODEL_ARG(1) -YVAL_ARG(2,2,3) -EMPTY_YVAL_ARG(3) -YVAL_VECTOR_ARG(4) -CALL4(int, val_expand_function) -jintArray jretval = NULL; -if(retval == -1){ - const char *msg = yices_error_string(); - throwException(jenv, "java/lang/IllegalArgumentException", msg); - goto out; -} -if ((*jenv)->ExceptionCheck(jenv)) { - goto out; -} -size_t sz = s_arg4.size; -sz = (sz+1)*2; -jint *jarr = malloc(sizeof(jint) * sz); -if (jarr == NULL) { - throwException(jenv, "java/lang/OutOfMemoryError", "Cannot allocate native memory for passing return value from Yices"); - goto out; -} -yval_t *data = s_arg4.data; -jarr[0] = m_arg3->node_id; -jarr[1] = m_arg3->node_tag; -size_t i; -for (i = 0; i < s_arg4.size; i++) { - jarr[2+2*i] = data[i].node_id; - jarr[2+2*i+1] = data[i].node_tag; -} -jretval = (*jenv)->NewIntArray(jenv, sz); -if (jretval != NULL) { - (*jenv)->SetIntArrayRegion(jenv, jretval, 0, sz, jarr); -} -free(jarr); -out: -yices_delete_yval_vector(m_arg4); -return jretval; -} -//node_id and nodetag split for retaining argment order for C call -DEFINE_FUNC(intArray, 1val_1expand_1mapping) WITH_FOUR_ARGS(jmodel, jnodeid, int, jnodetag) -MODEL_ARG(1) -YVAL_ARG(2,2,4) -EMPTY_YVAL_ARRAY_ARG(3) -EMPTY_YVAL_ARG(4) -CALL4(int, val_expand_mapping) -jintArray jretval = NULL; -if(retval == -1){ - const char *msg = yices_error_string(); - throwException(jenv, "java/lang/IllegalArgumentException", msg); - goto out; -} -if ((*jenv)->ExceptionCheck(jenv)) { - goto out; -} -size_t returnSize = (sz+1)*2; -jint *jarr = malloc(sizeof(jint) * returnSize); -if (jarr == NULL) { - throwException(jenv, "java/lang/OutOfMemoryError", "Cannot allocate native memory for passing return value from Yices"); - goto out; -} -size_t i; -for (i = 0; i < sz; i++) { - jarr[2*i] = m_arg3[i].node_id; - jarr[2*i+1] = m_arg3[i].node_tag; -} -jarr[2*sz] = m_arg4->node_id; -jarr[2*sz+1] = m_arg4->node_tag; -jretval = (*jenv)->NewIntArray(jenv, returnSize); -if (jretval != NULL) { - (*jenv)->SetIntArrayRegion(jenv, jretval, 0, returnSize, jarr); -} -free(jarr); -out: -free(m_arg3); -return jretval; -} - -DEFINE_FUNC(jterm, 1get_1value_1as_1term) WITH_TWO_ARGS(jmodel, jterm) -MODEL_ARG(1) -TERM_ARG(2) -CALL2(term_t, get_value_as_term) -TERM_RETURN - -//skipping following model functions - -/* - * TERM NAMING, PRINTING, PARSING and SUBSTITUTION - */ - -//skipping type functions - -DEFINE_FUNC(int, 1set_1term_1name) WITH_TWO_ARGS(jterm, string) -TERM_ARG(1) -STRING_ARG(2) -CALL2(int, set_term_name) -FREE_STRING_ARG(2) -INT_RETURN - -DEFINE_FUNC(string, 1get_1term_1name) WITH_ONE_ARG(jterm) -TERM_ARG(1) -CALL1(const char *, get_term_name) -CONST_STRING_RETURN - -DEFINE_FUNC(jterm, 1get_1term_1by_1name) WITH_ONE_ARG(string) -STRING_ARG(1) -CALL1(term_t, get_term_by_name) -FREE_STRING_ARG(1) -TERM_RETURN - -//skipping remove_term_name and clear_term_name - -//skipping parse_type - -DEFINE_FUNC(jterm, 1parse_1term) WITH_ONE_ARG(string) -STRING_ARG(1) -CALL1(term_t, parse_term) -FREE_STRING_ARG(1) -TERM_RETURN - -DEFINE_FUNC(jterm, 1subst_1term) WITH_FOUR_ARGS(int, jtermArray, jtermArray, jterm) -UINT32_ARG(1) -TERM_ARRAY_ARG(2) -TERM_ARRAY_ARG(3) -TERM_ARG(4) -CALL4(term_t, subst_term) -FREE_TERM_ARRAY_ARG(2) -FREE_TERM_ARRAY_ARG(3) -TERM_RETURN - -/* - * Printing - */ - -//Creates String that needs to be freed -DEFINE_FUNC(string, 1term_1to_1string) WITH_FOUR_ARGS(jterm, int, int ,int) -TERM_ARG(1) -UINT32_ARG(2) -UINT32_ARG(3) -UINT32_ARG(4) -CALL4(char *, term_to_string) -STRING_RETURN - -DEFINE_FUNC(string, 1type_1to_1string) WITH_FOUR_ARGS(jtype, int, int ,int) -TYPE_ARG(1) -UINT32_ARG(2) -UINT32_ARG(3) -UINT32_ARG(4) -CALL4(char *, type_to_string) -STRING_RETURN - -DEFINE_FUNC(string, 1model_1to_1string) WITH_FOUR_ARGS(jmodel, int, int ,int) -MODEL_ARG(1) -UINT32_ARG(2) -UINT32_ARG(3) -UINT32_ARG(4) -CALL4(char *, model_to_string) -STRING_RETURN - -/* - * Functions for version checking - */ - -DEFINE_FUNC(int, 1get_1version) WITHOUT_ARGS -return __YICES_VERSION; -} - -DEFINE_FUNC(int, 1get_1major_1version) WITHOUT_ARGS -return __YICES_VERSION_MAJOR; -} - -DEFINE_FUNC(int, 1get_1patch_1level) WITHOUT_ARGS -return __YICES_VERSION_PATCHLEVEL; -} - -/* - * Functions in 2.6.2 that are not part of this wrapper: - * - * We don't use arrays at the moment: - * -yices_model_term_array_support - * - * We dont need bit-blasting results: - * -yices_export_formula_to_dimacs - * -yices_export_formulas_to_dimacs - * - * Model/Term printing is managed via Strings, so we dont need these: - * -yices_pp_model - * -yices_print_term_values - * -yices_pp_term_values - * -yices_pp_term_values_fd - * -yices_pp_model_fd - * -yices_print_term_values_fd - */ - -/* - * Check for thread-safe compiliation - */ -DEFINE_FUNC(int, 1is_1thread_1safe) WITHOUT_ARGS -CALL0(int, is_thread_safe) -INT_RETURN - -/* - * Check if yices was compiled with MCSAT support - */ -DEFINE_FUNC(int, 1has_1mcsat) WITHOUT_ARGS -CALL0(int, has_mcsat) -INT_RETURN - -/* - * The function first checks whether f is satisifiable or unsatisfiable. - * - */ -DEFINE_FUNC(int, 1check_1formula) WITH_FOUR_ARGS(jterm, string, jmodel, string) -TERM_ARG(1) -STRING_ARG(2) -MODEL_ARG_POINTER(3) -STRING_ARG(4) -CALL4(smt_status_t, check_formula) -FREE_STRING_ARG(2) -FREE_STRING_ARG(4) -INT_RETURN - -/* - * This is similar to yices_check_formula except that it checks whether - * the conjunction of f[0] ... f[n-1] is satisfiable. - */ -DEFINE_FUNC(int, 1check_1formulas) WITH_FIVE_ARGS(jtermArray, int, string, jmodel, string) -TERM_ARRAY_ARG(1) -UINT32_ARG(2) -STRING_ARG(3) -MODEL_ARG_POINTER(4) -STRING_ARG(5) -CALL5(smt_status_t, check_formulas) -FREE_TERM_ARRAY_ARG(1) -FREE_STRING_ARG(3) -FREE_STRING_ARG(5) -INT_RETURN - -/* - * Checks if the SAT-Solver entered as String is available - */ -DEFINE_FUNC(int, 1has_1delegate) WITH_ONE_ARG(string) -STRING_ARG(1) -CALL1(int, has_delegate) -FREE_STRING_ARG(1) -INT_RETURN - -/* - * Returns type of a function node. - */ -DEFINE_FUNC(jtype, 1val_1function_1type) WITH_THREE_ARGS(jmodel, jnodeid, jnodetag) -MODEL_ARG(1) -YVAL_ARG(2, 2, 3) -CALL2(type_t, val_function_type) -TYPE_RETURN - -/* - * Returns term_vector instead of error int. - */ -DEFINE_FUNC(jtermArray, 1model_1term_1support) WITH_TWO_ARGS(jmodel, jterm) -MODEL_ARG(1) -TERM_ARG(2) -TERM_VECTOR_ARG(3) -CALL3(int, model_term_support) -TERM_VECTOR_ARG_RETURN(3) - -__attribute__((visibility("default"))) jjterm Java_org_sosy_1lab_java_1smt_solvers_yices2_Yices2NativeApi_yices_1interpolate(JNIEnv *jenv, jclass jcls, jlong jarg1, jlong jarg2) { - jint jresult = 0; - context_t *arg1 = 0; - context_t *arg2 = 0; - term_t result; - - (void)jenv; - (void)jcls; - arg1 = *(context_t **)&jarg1; - arg2 = *(context_t **)&jarg2; - - interpolation_context_t context = {arg1, arg2, 0, 0}; - smt_status_t c = yices_check_context_with_interpolation(&context, 0, 0); - if (c == YICES_STATUS_SAT) { - throwException(jenv, "java/lang/IllegalArgumentException", "Could not interpolate, problem is SAT"); - } - if (c == YICES_STATUS_ERROR) { - throwException(jenv, "java/lang/RuntimeException", yices_error_string()); - } - - result = context.interpolant; - jresult = (jint)result; - return jresult; -} diff --git a/lib/native/x86_64-linux/libyices2j.so b/lib/native/x86_64-linux/libyices2j.so deleted file mode 120000 index 41b6dfcafb..0000000000 --- a/lib/native/x86_64-linux/libyices2j.so +++ /dev/null @@ -1 +0,0 @@ -../../java/runtime-yices2/libyices2j.so \ No newline at end of file diff --git a/lib/native/x86_64-linux/libyices2java.so b/lib/native/x86_64-linux/libyices2java.so new file mode 120000 index 0000000000..06b6b7c1c4 --- /dev/null +++ b/lib/native/x86_64-linux/libyices2java.so @@ -0,0 +1 @@ +../../java/runtime-yices2/x64/libyices2java.so \ No newline at end of file diff --git a/solvers_ivy_conf/ivy_yices2.xml b/solvers_ivy_conf/ivy_yices2.xml index 1201add3b0..c815c11e34 100644 --- a/solvers_ivy_conf/ivy_yices2.xml +++ b/solvers_ivy_conf/ivy_yices2.xml @@ -22,11 +22,20 @@ SPDX-License-Identifier: Apache-2.0 - + + + + + + + + + - + + diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java index ace55c0cc3..44889fe406 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java @@ -8,24 +8,13 @@ package org.sosy_lab.java_smt.solvers.yices2; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_STATUS_UNSAT; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_assert_formula; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_check_sat; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_check_sat_with_assumptions; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_context_status; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_free_config; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_free_context; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_model; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_unsat_core; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_new_config; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_new_context; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_pop; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_push; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_set_config; - import com.google.common.base.Preconditions; import com.google.common.primitives.Ints; import com.google.errorprone.annotations.CanIgnoreReturnValue; +import com.sri.yices.Config; +import com.sri.yices.Context; +import com.sri.yices.Parameters; +import com.sri.yices.Status; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; @@ -33,6 +22,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.function.Supplier; import java.util.stream.Collectors; import org.sosy_lab.common.ShutdownNotifier; import org.sosy_lab.common.UniqueIdGenerator; @@ -46,6 +36,7 @@ import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.basicimpl.AbstractProverWithAllSat; import org.sosy_lab.java_smt.basicimpl.CachingModel; +import org.sosy_lab.java_smt.basicimpl.ShutdownHook; /** * Info about the option {@link ProverOptions#GENERATE_UNSAT_CORE}: Yices provides the unsat core @@ -63,10 +54,10 @@ abstract class Yices2AbstractProver extends AbstractProverWithAllSat implements BasicProverEnvironment { - private static final int DEFAULT_PARAMS = 0; // use default setting in the solver + static final Parameters DEFAULT_PARAMS = new Parameters(); // use default setting in the solver protected final Yices2FormulaCreator creator; - protected final long curEnv; + protected final Context curEnv; // Yices does not allow to PUSH when the stack is UNSAT. // Therefore, we need to keep track of all added constraints beyond that stack-level. @@ -96,20 +87,43 @@ protected boolean hasPersistentModel() { return false; } - long newContext(boolean mcsat) { - var cfg = yices_new_config(); - yices_set_config(cfg, "solver-type", mcsat ? "mcsat" : "dpllt"); - yices_set_config(cfg, "mode", "interactive"); - yices_set_config(cfg, "model-interpolation", "true"); - var context = yices_new_context(cfg); - yices_free_config(cfg); - return context; + Context newContext(boolean mcsat) { + try (var cfg = new Config()) { + cfg.set("solver-type", mcsat ? "mcsat" : "dpllt"); + cfg.set("mode", "interactive"); + cfg.set("model-interpolation", "true"); + return new Context(cfg); + } + } + + @SuppressWarnings("try") + static boolean satCheckWithShutdownNotifier( + Supplier satCheck, Context pCtx, ShutdownNotifier shutdownNotifier) + throws InterruptedException, SolverException { + try (ShutdownHook hook = new ShutdownHook(shutdownNotifier, pCtx::stopSearch)) { + shutdownNotifier.shutdownIfNecessary(); + Status result = satCheck.get(); // the expensive computation + shutdownNotifier.shutdownIfNecessary(); + + switch (result) { + case SAT: + return true; + case UNSAT: + return false; + case INTERRUPTED: + throw new InterruptedException(); + case UNKNOWN: + throw new SolverException("SAT check returned \"unknown\""); + default: + throw new SolverException("Internal solver exception"); + } + } } @Override protected void popImpl() { if (size() < stackSizeToUnsat) { // constraintStack and Yices stack have same level. - yices_pop(curEnv); + curEnv.pop(); // Reset stackSizeToUnsat to bring the stack into a pushable state if it was UNSAT before. stackSizeToUnsat = Integer.MAX_VALUE; } @@ -123,7 +137,7 @@ protected int addConstraint0(BooleanFormula constraint) { if (!generateUnsatCores) { // Skip adding the assertion if we plan to use getUnsatCore. We'll later use assumptions // solving to calculate an unsat core for the assertions - yices_assert_formula(curEnv, formula); + curEnv.assertFormula(formula); } stack.addLast(stack.removeLast().putAndCopy(label, formula)); return label; @@ -131,10 +145,10 @@ protected int addConstraint0(BooleanFormula constraint) { @Override protected void pushImpl() throws InterruptedException { - if (size() < stackSizeToUnsat && yices_context_status(curEnv) != YICES_STATUS_UNSAT) { + if (size() < stackSizeToUnsat && curEnv.getStatus() != Status.UNSAT) { // Ensure that constraintStack and Yices stack are on the same level // and Context is not UNSAT from assertions since last push. - yices_push(curEnv); + curEnv.push(); } else if (stackSizeToUnsat == Integer.MAX_VALUE) { // if previous check fails and stackSizeToUnsat is // not already set, set it to the current stack-size before pushing. @@ -150,12 +164,17 @@ protected boolean isUnsatImpl() throws SolverException, InterruptedException { // Yices only tracks assumptions for unsat core. We keep the stack empty and then treat all // assertions as assumptions while checking. If the result is 'unsat', we can then // calculate an unsat core - int[] allConstraints = getAllConstraints(); unsat = - !yices_check_sat_with_assumptions( - curEnv, DEFAULT_PARAMS, allConstraints.length, allConstraints, shutdownNotifier); + !satCheckWithShutdownNotifier( + () -> curEnv.checkWithAssumptions(DEFAULT_PARAMS, getAllConstraints()), + curEnv, + shutdownNotifier); + } else { - unsat = !yices_check_sat(curEnv, DEFAULT_PARAMS, shutdownNotifier); + unsat = + !satCheckWithShutdownNotifier( + () -> curEnv.check(DEFAULT_PARAMS), curEnv, shutdownNotifier); + if (unsat && stackSizeToUnsat == Integer.MAX_VALUE) { stackSizeToUnsat = size(); // If sat check is UNSAT and stackSizeToUnsat waS not already set, @@ -179,11 +198,9 @@ public boolean isUnsatWithAssumptions(Collection pAssumptions) wasLastSatCheckSatisfiable = false; final boolean isUnsat = - !yices_check_sat_with_assumptions( + !satCheckWithShutdownNotifier( + () -> curEnv.checkWithAssumptions(DEFAULT_PARAMS, uncapsulate(pAssumptions)), curEnv, - DEFAULT_PARAMS, - pAssumptions.size(), - uncapsulate(pAssumptions), shutdownNotifier); if (!isUnsat) { wasLastSatCheckSatisfiable = true; @@ -198,9 +215,10 @@ public Model getModel() throws SolverException { return new CachingModel(getEvaluatorWithoutChecks()); } + @SuppressWarnings("resource") @Override protected Yices2Model getEvaluatorWithoutChecks() { - return new Yices2Model(yices_get_model(curEnv, 1), this, creator); + return new Yices2Model(curEnv.getModel(), this, creator); } private List encapsulate(int[] terms) { @@ -227,7 +245,7 @@ public List getUnsatCore() { } private List getUnsatCore0() { - return encapsulate(yices_get_unsat_core(curEnv)); + return encapsulate(curEnv.getUnsatCore()); } @Override @@ -241,7 +259,7 @@ public Optional> unsatCoreOverAssumptions( @Override public void close() { if (!closed) { - yices_free_context(curEnv); + curEnv.close(); stackSizeToUnsat = Integer.MAX_VALUE; } super.close(); diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2ArrayFormulaManager.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2ArrayFormulaManager.java index 1aa728f6e8..1b1e32ad6a 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2ArrayFormulaManager.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2ArrayFormulaManager.java @@ -10,15 +10,10 @@ package org.sosy_lab.java_smt.solvers.yices2; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_application; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_eq; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_function_type; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_lambda; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_new_variable; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_update; - import com.google.common.collect.HashBasedTable; import com.google.common.collect.Table; +import com.sri.yices.Terms; +import com.sri.yices.Types; import org.sosy_lab.java_smt.api.Formula; import org.sosy_lab.java_smt.api.FormulaType; import org.sosy_lab.java_smt.basicimpl.AbstractArrayFormulaManager; @@ -41,19 +36,18 @@ public Yices2ArrayFormulaManager(Yices2FormulaCreator pCreator) { @Override protected Integer select(Integer pArray, Integer pIndex) { - return yices_application(pArray, 1, new int[] {pIndex}); + return Terms.funApplication(pArray, pIndex); } @Override protected Integer store(Integer pArray, Integer pIndex, Integer pValue) { - return yices_update(pArray, 1, new int[] {pIndex}, pValue); + return Terms.functionUpdate1(pArray, pIndex, pValue); } @Override protected Integer internalMakeArray( String pName, FormulaType pIndexType, FormulaType pElementType) { - var yicesFuncType = - yices_function_type(1, new int[] {toSolverType(pIndexType)}, toSolverType(pElementType)); + var yicesFuncType = Types.functionType(toSolverType(pIndexType), toSolverType(pElementType)); return ((Yices2FormulaCreator) getFormulaCreator()).createNamedVariable(yicesFuncType, pName); } @@ -64,7 +58,7 @@ protected Integer internalMakeArray( var constantArray = constCache.get(arraySort, defaultElement); if (constantArray == null) { constantArray = - yices_lambda(1, new int[] {yices_new_variable(toSolverType(pIndexType))}, defaultElement); + Terms.lambda(new int[] {Terms.newVariable(toSolverType(pIndexType))}, defaultElement); constCache.put(arraySort, defaultElement, constantArray); } return constantArray; @@ -72,6 +66,6 @@ protected Integer internalMakeArray( @Override protected Integer equivalence(Integer pArray1, Integer pArray2) { - return yices_eq(pArray1, pArray2); + return Terms.eq(pArray1, pArray2); } } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2BitvectorFormulaManager.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2BitvectorFormulaManager.java index 3df71f8a8a..17d53f2544 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2BitvectorFormulaManager.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2BitvectorFormulaManager.java @@ -8,41 +8,9 @@ package org.sosy_lab.java_smt.solvers.yices2; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvadd; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvand2; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvashr; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvconcat2; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvdiv; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bveq_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvextract; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvge_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvgt_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvle_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvlshr; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvlt_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvmul; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvneg; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvnot; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvor2; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvrem; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvsdiv; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvsge_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvsgt_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvshl; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvsle_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvslt_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvsmod; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvsrem; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvsub; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvxor2; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_parse_bvbin; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_rotate_left; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_rotate_right; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_sign_extend; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_zero_extend; - import com.google.common.base.Preconditions; import com.google.common.base.Strings; +import com.sri.yices.Terms; import java.math.BigInteger; import org.sosy_lab.java_smt.basicimpl.AbstractBitvectorFormulaManager; @@ -64,7 +32,7 @@ protected Integer makeBitvectorImpl(int pLength, BigInteger pI) { bits = Strings.padStart(bits, pLength, '0'); } Preconditions.checkArgument(bits.length() == pLength, "Bitvector has unexpected size."); - return yices_parse_bvbin(bits); + return Terms.parseBvBin(bits); } @Override @@ -76,106 +44,106 @@ protected Integer toIntegerFormulaImpl(Integer bvFormula, boolean pSigned) { @Override protected Integer negate(Integer pParam1) { - return yices_bvneg(pParam1); + return Terms.bvNeg(pParam1); } @Override protected Integer add(Integer pParam1, Integer pParam2) { - return yices_bvadd(pParam1, pParam2); + return Terms.bvAdd(pParam1, pParam2); } @Override protected Integer subtract(Integer pParam1, Integer pParam2) { - return yices_bvsub(pParam1, pParam2); + return Terms.bvSub(pParam1, pParam2); } @Override protected Integer divide(Integer pParam1, Integer pParam2, boolean pSigned) { if (pSigned) { - return yices_bvsdiv(pParam1, pParam2); + return Terms.bvSDiv(pParam1, pParam2); } else { - return yices_bvdiv(pParam1, pParam2); + return Terms.bvDiv(pParam1, pParam2); } } @Override protected Integer remainder(Integer pParam1, Integer pParam2, boolean pSigned) { if (pSigned) { - return yices_bvsrem(pParam1, pParam2); + return Terms.bvSRem(pParam1, pParam2); } else { - return yices_bvrem(pParam1, pParam2); + return Terms.bvRem(pParam1, pParam2); } } @Override protected Integer smodulo(Integer pParam1, Integer pParam2) { - return yices_bvsmod(pParam1, pParam2); + return Terms.bvSMod(pParam1, pParam2); } @Override protected Integer multiply(Integer pParam1, Integer pParam2) { - return yices_bvmul(pParam1, pParam2); + return Terms.bvMul(pParam1, pParam2); } @Override protected Integer equal(Integer pParam1, Integer pParam2) { - return yices_bveq_atom(pParam1, pParam2); + return Terms.bvEq(pParam1, pParam2); } @Override protected Integer greaterThan(Integer pParam1, Integer pParam2, boolean pSigned) { if (pSigned) { - return yices_bvsgt_atom(pParam1, pParam2); + return Terms.bvSGt(pParam1, pParam2); } else { - return yices_bvgt_atom(pParam1, pParam2); + return Terms.bvGt(pParam1, pParam2); } } @Override protected Integer greaterOrEquals(Integer pParam1, Integer pParam2, boolean pSigned) { if (pSigned) { - return yices_bvsge_atom(pParam1, pParam2); + return Terms.bvSGe(pParam1, pParam2); } else { - return yices_bvge_atom(pParam1, pParam2); + return Terms.bvGe(pParam1, pParam2); } } @Override protected Integer lessThan(Integer pParam1, Integer pParam2, boolean pSigned) { if (pSigned) { - return yices_bvslt_atom(pParam1, pParam2); + return Terms.bvSLt(pParam1, pParam2); } else { - return yices_bvlt_atom(pParam1, pParam2); + return Terms.bvLt(pParam1, pParam2); } } @Override protected Integer lessOrEquals(Integer pParam1, Integer pParam2, boolean pSigned) { if (pSigned) { - return yices_bvsle_atom(pParam1, pParam2); + return Terms.bvSLe(pParam1, pParam2); } else { - return yices_bvle_atom(pParam1, pParam2); + return Terms.bvLe(pParam1, pParam2); } } @Override protected Integer not(Integer pParam1) { - return yices_bvnot(pParam1); + return Terms.bvNot(pParam1); } @Override protected Integer and(Integer pParam1, Integer pParam2) { - return yices_bvand2(pParam1, pParam2); + return Terms.bvAnd(pParam1, pParam2); } @Override protected Integer or(Integer pParam1, Integer pParam2) { - return yices_bvor2(pParam1, pParam2); + return Terms.bvOr(pParam1, pParam2); } @Override protected Integer xor(Integer pParam1, Integer pParam2) { - return yices_bvxor2(pParam1, pParam2); + return Terms.bvXor(pParam1, pParam2); } @Override @@ -187,43 +155,43 @@ protected Integer makeVariableImpl(int pLength, String pVar) { @Override protected Integer shiftRight(Integer pNumber, Integer pToShift, boolean pSigned) { if (pSigned) { - return yices_bvashr(pNumber, pToShift); + return Terms.bvAshr(pNumber, pToShift); } else { - return yices_bvlshr(pNumber, pToShift); + return Terms.bvLshr(pNumber, pToShift); } } @Override protected Integer shiftLeft(Integer pNumber, Integer pToShift) { - return yices_bvshl(pNumber, pToShift); + return Terms.bvShl(pNumber, pToShift); } @Override protected Integer rotateLeftByConstant(Integer pNumber, int toRotate) { - return yices_rotate_left(pNumber, toRotate); + return Terms.bvRotateLeft(pNumber, toRotate); } @Override protected Integer rotateRightByConstant(Integer pNumber, int toRotate) { - return yices_rotate_right(pNumber, toRotate); + return Terms.bvRotateRight(pNumber, toRotate); } @Override protected Integer concat(Integer pNumber, Integer pAppend) { - return yices_bvconcat2(pNumber, pAppend); + return Terms.bvConcat(pNumber, pAppend); } @Override protected Integer extract(Integer pNumber, int pMsb, int pLsb) { - return yices_bvextract(pNumber, pLsb, pMsb); + return Terms.bvExtract(pNumber, pLsb, pMsb); } @Override protected Integer extend(Integer pNumber, int pExtensionBits, boolean pSigned) { if (pSigned) { - return yices_sign_extend(pNumber, pExtensionBits); + return Terms.bvSignExtend(pNumber, pExtensionBits); } else { - return yices_zero_extend(pNumber, pExtensionBits); + return Terms.bvZeroExtend(pNumber, pExtensionBits); } } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2BooleanFormulaManager.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2BooleanFormulaManager.java index 322e061ec3..d9dde30895 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2BooleanFormulaManager.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2BooleanFormulaManager.java @@ -8,16 +8,7 @@ package org.sosy_lab.java_smt.solvers.yices2; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_and2; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_false; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_iff; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_implies; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_ite; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_not; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_or2; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_true; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_xor2; - +import com.sri.yices.Terms; import org.sosy_lab.java_smt.basicimpl.AbstractBooleanFormulaManager; public class Yices2BooleanFormulaManager @@ -36,66 +27,54 @@ protected Integer makeVariableImpl(String pVar) { @Override protected Integer makeBooleanImpl(boolean pValue) { if (pValue) { - return yices_true(); + return Terms.mkTrue(); } else { - return yices_false(); + return Terms.mkFalse(); } } @Override protected Integer not(Integer pParam1) { - return yices_not(pParam1); + return Terms.not(pParam1); } @Override protected Integer and(Integer pParam1, Integer pParam2) { - return yices_and2(pParam1, pParam2); + return Terms.and(pParam1, pParam2); } - // Causes BooleanFormulaManagerTest/testConjunctionCollector to fail. - // @Override - // protected Integer andImpl(Collection pParams) { - // return yices_and(pParams.size(), Ints.toArray(pParams)); - // } - @Override protected Integer or(Integer pParam1, Integer pParam2) { - return yices_or2(pParam1, pParam2); + return Terms.or(pParam1, pParam2); } - // Causes BooleanFormulaManagerTest/testDisjunctionCollector to fail. - // @Override - // protected Integer orImpl(Collection pParams) { - // return yices_or(pParams.size(), Ints.toArray(pParams)); - // } - @Override protected Integer xor(Integer pParam1, Integer pParam2) { - return yices_xor2(pParam1, pParam2); + return Terms.xor(pParam1, pParam2); } @Override protected Integer equivalence(Integer pBits1, Integer pBits2) { - return yices_iff(pBits1, pBits2); + return Terms.iff(pBits1, pBits2); } @Override protected Integer implication(Integer bits1, Integer bits2) { - return yices_implies(bits1, bits2); + return Terms.implies(bits1, bits2); } @Override protected boolean isTrue(Integer pBits) { - return pBits.equals(yices_true()); + return pBits.equals(Terms.mkTrue()); } @Override protected boolean isFalse(Integer pBits) { - return pBits.equals(yices_false()); + return pBits.equals(Terms.mkFalse()); } @Override protected Integer ifThenElse(Integer pCond, Integer pF1, Integer pF2) { - return yices_ite(pCond, pF1, pF2); + return Terms.ifThenElse(pCond, pF1, pF2); } } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Formula.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Formula.java index 6b389686ec..a38db06d38 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Formula.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Formula.java @@ -9,9 +9,9 @@ package org.sosy_lab.java_smt.solvers.yices2; import static com.google.common.base.Preconditions.checkNotNull; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_term_to_string; import com.google.errorprone.annotations.Immutable; +import com.sri.yices.Terms; import org.sosy_lab.java_smt.api.ArrayFormula; import org.sosy_lab.java_smt.api.BitvectorFormula; import org.sosy_lab.java_smt.api.BooleanFormula; @@ -40,7 +40,7 @@ final int getTerm() { @Override public final String toString() { - return yices_term_to_string(yicesTerm); + return Terms.toString(yicesTerm); } @Override diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java index 75492af0af..e339dd7e7d 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java @@ -9,140 +9,20 @@ package org.sosy_lab.java_smt.solvers.yices2; import static com.google.common.base.Preconditions.checkArgument; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_ABS; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_AND; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_APP_TERM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_ARITH_CONST; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_ARITH_FF_CONSTANT; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_ARITH_GE_ATOM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_ARITH_SUM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_ARRAY_SELECT; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_BIT_TERM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_BOOL_CONST; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_BV_ARRAY; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_BV_ASHR; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_BV_CONST; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_BV_DIV; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_BV_GE_ATOM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_BV_LSHR; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_BV_MUL; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_BV_REM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_BV_SDIV; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_BV_SGE_ATOM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_BV_SHL; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_BV_SMOD; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_BV_SREM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_BV_SUM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_CEIL; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_DISTINCT_TERM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_DIVIDES_ATOM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_EQ_TERM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_FLOOR; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_FORALL_TERM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_IDIV; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_IMOD; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_IS_INT_ATOM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_ITE_TERM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_LAMBDA_TERM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_NOT_TERM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_OR_TERM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_POWER_PRODUCT; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_RDIV; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_SELECT_TERM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_UNINTERPRETED_TERM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_UPDATE_TERM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_VARIABLE; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_XOR_TERM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_abs; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_and; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_application; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_arith_geq_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bitextract; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bool_const_value; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bool_type; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bv_const_value; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bv_type; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvarray; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvashr; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvconst_from_array; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvdiv; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvge_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvlshr; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvmul; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvpower; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvproduct; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvrem; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvsdiv; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvsge_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvshl; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvsmod; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvsrem; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvsum; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvsum_component; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvtype_size; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_ceil; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_distinct; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_divides_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_division; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_eq; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_floor; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_function_type; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_term_by_name; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_term_name; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_idiv; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_imod; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_int32; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_int_type; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_is_int_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_ite; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_mul; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_new_uninterpreted_term; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_new_variable; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_not; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_or; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_parse_rational; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_power; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_product; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_product_component; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_proj_arg; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_proj_index; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_rational_const_value; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_real_type; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_set_term_name; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_subst_term; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_sum; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_sum_component; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_term_bitsize; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_term_child; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_term_constructor; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_term_is_int; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_term_num_children; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_term_to_string; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_true; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_child; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_is_bitvector; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_is_bool; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_is_function; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_is_int; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_is_real; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_of_term; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_to_string; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_update; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_xor; - -import com.google.common.base.Joiner; + import com.google.common.base.Preconditions; -import com.google.common.collect.Collections2; +import com.google.common.collect.FluentIterable; import com.google.common.collect.HashBasedTable; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Table; import com.google.common.primitives.Ints; +import com.sri.yices.Constructor; +import com.sri.yices.Terms; +import com.sri.yices.Types; import java.math.BigInteger; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -169,15 +49,6 @@ @SuppressWarnings({"ClassTypeParameterName", "MethodTypeParameterName"}) public class Yices2FormulaCreator extends FormulaCreator { - private static final ImmutableSet CONSTANT_AND_VARIABLE_CONSTRUCTORS = - ImmutableSet.of( - YICES_BOOL_CONST, - YICES_ARITH_CONST, - YICES_ARITH_FF_CONSTANT, - YICES_BV_CONST, - YICES_VARIABLE, - YICES_UNINTERPRETED_TERM); - /** * Maps a name and a free variable or function type to a concrete formula node. We allow only 1 * type per var name, meaning there is only 1 column per row! @@ -193,12 +64,12 @@ public class Yices2FormulaCreator extends FormulaCreator ufSymbols = new HashSet<>(); protected Yices2FormulaCreator() { - super(null, yices_bool_type(), yices_int_type(), yices_real_type(), null, null); + super(null, Types.boolType(), Types.intType(), Types.realType(), null, null); } @Override public Integer getBitvectorType(int pBitwidth) { - return yices_bv_type(pBitwidth); + return Types.bvType(pBitwidth); } @Override @@ -208,7 +79,7 @@ public Integer getFloatingPointType(FloatingPointType pType) { @Override public Integer getArrayType(Integer pIndexType, Integer pElementType) { - return yices_function_type(1, new int[] {pIndexType}, pElementType); + return Types.functionType(pIndexType, pElementType); } @Override @@ -246,7 +117,7 @@ public T encapsulate(FormulaType pType, Integer pTerm) { || pType.equals(getFormulaType(pTerm)) : String.format( "Trying to encapsulate formula %s of type %s as %s", - yices_term_to_string(pTerm), getFormulaType(pTerm), pType); + Terms.toString(pTerm), getFormulaType(pTerm), pType); if (pType.isBooleanType()) { return (T) new Yices2BooleanFormula(pTerm); } else if (pType.isIntegerType()) { @@ -289,10 +160,10 @@ protected ArrayFormula encapsul @Override public FormulaType getFormulaType(T pFormula) { if (pFormula instanceof BitvectorFormula) { - int type = yices_type_of_term(extractInfo(pFormula)); - return (FormulaType) FormulaType.getBitvectorTypeWithSize(yices_bvtype_size(type)); + int type = Terms.typeOf(extractInfo(pFormula)); + return (FormulaType) FormulaType.getBitvectorTypeWithSize(Types.bvSize(type)); } else if (pFormula instanceof ArrayFormula) { - return (FormulaType) convertType(yices_type_of_term(extractInfo(pFormula))); + return (FormulaType) convertType(Terms.typeOf(extractInfo(pFormula))); } else { return super.getFormulaType(pFormula); } @@ -300,26 +171,27 @@ public FormulaType getFormulaType(T pFormula) { @Override public FormulaType getFormulaType(Integer pFormula) { - return convertType(yices_type_of_term(pFormula)); + return convertType(Terms.typeOf(pFormula)); } /** Convert from Yices2 types to JavaSMT FormulaTypes. */ private FormulaType convertType(Integer pType) { - if (yices_type_is_bool(pType)) { + if (Types.isBool(pType)) { return FormulaType.BooleanType; - } else if (yices_type_is_int(pType)) { + } else if (Types.isInt(pType)) { return FormulaType.IntegerType; - } else if (yices_type_is_real(pType)) { + } else if (Types.isReal(pType)) { return FormulaType.RationalType; - } else if (yices_type_is_bitvector(pType)) { - return FormulaType.getBitvectorTypeWithSize(yices_bvtype_size(pType)); - } else if (yices_type_is_function(pType)) { - var domain = yices_type_child(pType, 0); - var range = yices_type_child(pType, 1); + } else if (Types.isBitvector(pType)) { + return FormulaType.getBitvectorTypeWithSize(Types.bvSize(pType)); + } else if (Types.isFunction(pType)) { + var domain = Types.child(pType, 0); + var range = Types.child(pType, 1); return FormulaType.getArrayType(convertType(domain), convertType(range)); + } else { + throw new IllegalArgumentException( + String.format("Unknown formula type '%s'", Types.toString(pType))); } - throw new IllegalArgumentException( - String.format("Unknown formula type '%s'", yices_type_to_string(pType))); } /** Creates a named, free variable. Might retrieve it from the cache if created prior. */ @@ -334,18 +206,19 @@ protected int createNamedVariable(int type, String name) { name, formulaCache.row(name)); - int var = yices_new_uninterpreted_term(type); + int var = Terms.newUninterpretedTerm(type); // Names in Yices2 behave like a stack. The last variable named is retrieved when asking for // a term with a specific name. Since we substitute free vars with bound for quantifiers, // this sometimes mixes them up, hence we track them ourselves. - yices_set_term_name(var, name); + // FIXME Should we even set it then? + Terms.setName(var, name); formulaCache.put(name, type, var); return var; } protected int createBoundVariableFromFreeVariable(int unboundVar) { - int type = yices_type_of_term(unboundVar); - String name = yices_get_term_name(unboundVar); + int type = Terms.typeOf(unboundVar); + String name = Terms.getName(unboundVar); // Search for recently created bound variables and re-use it // (Names work like a stack in Yices2. If we associate a term with a name, we get that term @@ -353,17 +226,17 @@ protected int createBoundVariableFromFreeVariable(int unboundVar) { // them with the same name as the free variable (so that it has the same name). This pushes the // name stack, and we get the bound var when asking yices_get_term_by_name(). We want to // re-use the bound variables here, but never the free ones.) - int termFromName = yices_get_term_by_name(name); + int termFromName = Terms.getByName(name); if (termFromName != -1) { - int termFromNameType = yices_type_of_term(termFromName); + int termFromNameType = Terms.typeOf(termFromName); checkArgument( type == termFromNameType, "Cannot override symbol '%s' with new symbol '%s' of type '%s'", - yices_type_to_string(termFromNameType), + Types.toString(termFromNameType), name, - yices_type_to_string(type)); - int constructor = yices_term_constructor(termFromName); - if (constructor == YICES_VARIABLE) { + Types.toString(type)); + Constructor constructor = Terms.constructor(termFromName); + if (constructor == Constructor.VARIABLE) { // Already a bound var return termFromName; } @@ -371,7 +244,7 @@ protected int createBoundVariableFromFreeVariable(int unboundVar) { // reset term name binding // TODO: add yices_remove_term_name(); - int bound = yices_new_variable(type); + int bound = Terms.newVariable(type); // Names in Yices2 behave like a stack. The last variable named is retrieved when asking for // a term with a specific name. Since we substitute free vars with bound for quantifiers, // this sometimes mixes them up, hence we track them ourselves. @@ -379,38 +252,36 @@ protected int createBoundVariableFromFreeVariable(int unboundVar) { // Meaning that if we remove the new name, the old term gets its name back. // Since we just want to retrieve the same var for the quantifier we are currently building, // this is fine. - yices_set_term_name(bound, name); + Terms.setName(bound, name); return bound; } @SuppressWarnings("deprecation") @Override public R visit(FormulaVisitor pVisitor, Formula pFormula, Integer pF) { - int constructor = yices_term_constructor(pF); + Constructor constructor = Terms.constructor(pF); switch (constructor) { - case YICES_BOOL_CONST: - return pVisitor.visitConstant(pFormula, yices_bool_const_value(pF)); - case YICES_ARITH_CONST: + case BOOL_CONSTANT: + return pVisitor.visitConstant(pFormula, Terms.boolConstValue(pF)); + case ARITH_CONSTANT: return pVisitor.visitConstant(pFormula, convertValue(pF, pF)); - case YICES_BV_CONST: + case BV_CONSTANT: return pVisitor.visitConstant(pFormula, convertValue(pF, pF)); - case YICES_LAMBDA_TERM: + case LAMBDA_TERM: // We use lambda terms as array constants return pVisitor.visitFunction( pFormula, - ImmutableList.of(encapsulateWithTypeOf(yices_term_child(pF, 1))), + ImmutableList.of(encapsulateWithTypeOf(Terms.child(pF, 1))), FunctionDeclarationImpl.of( "const", FunctionDeclarationKind.CONST, - ImmutableList.of(getFormulaType(yices_term_child(pF, 1))), + ImmutableList.of(getFormulaType(Terms.child(pF, 1))), getFormulaType(pF), 0)); - case YICES_UNINTERPRETED_TERM: - return pVisitor.visitFreeVariable(pFormula, yices_get_term_name(pF)); - case YICES_VARIABLE: - return pVisitor.visitBoundVariable(pFormula, 0); - case YICES_FORALL_TERM: + case FORALL_TERM: return visitQuantifier(pVisitor, pFormula, pF, Quantifier.FORALL); + case UNINTERPRETED_TERM: + return pVisitor.visitFreeVariable(pFormula, Terms.getName(pF)); default: return visitFunctionApplication(pVisitor, pFormula, pF, constructor); } @@ -426,15 +297,14 @@ private R visitQuantifier( int[] freeVars = new int[boundVars.length]; for (int i = 0; i < boundVars.length; i++) { // use from cached variable mapping - freeVars[i] = - createNamedVariable(yices_type_of_term(boundVars[i]), yices_get_term_name(boundVars[i])); + freeVars[i] = createNamedVariable(Terms.typeOf(boundVars[i]), Terms.getName(boundVars[i])); } int body = Iterables.getLast(args); if (pQuantifier == Quantifier.EXISTS) { - body = yices_not(body); // EXISTS is an alias for NOT(FORALL(x, NOT(body))) + body = Terms.not(body); // EXISTS is an alias for NOT(FORALL(x, NOT(body))) } - int substBody = yices_subst_term(freeVars.length, boundVars, freeVars, body); + int substBody = Terms.subst(body, boundVars, freeVars); return pVisitor.visitQuantifier( (BooleanFormula) pFormula, @@ -446,154 +316,151 @@ private R visitQuantifier( } private R visitFunctionApplication( - FormulaVisitor pVisitor, Formula pFormula, int pF, final int constructor) { + FormulaVisitor pVisitor, Formula pFormula, int pF, final Constructor constructor) { - // Map built-in constructors in negative int to avoid collision with UFs. - int functionDeclaration = -constructor; - - assert !CONSTANT_AND_VARIABLE_CONSTRUCTORS.contains(constructor) - : String.format( - "Term %s with constructor %d should be handled somewhere else", - yices_term_to_string(pF), constructor); + // throw new UnsupportedOperationException(String.format("Constructor %s", constructor)); + Integer functionDeclaration = null; // filled later, except for some special function applications String functionName = null; List functionArgs = null; + List functionIndex = ImmutableList.of(); // filled directly when handling the function application - final FunctionDeclarationKind functionKind; + FunctionDeclarationKind functionKind; switch (constructor) { - case YICES_ITE_TERM: + case ITE_TERM: functionKind = FunctionDeclarationKind.ITE; break; - case YICES_APP_TERM: - var fun = yices_term_child(pF, 0); + case APP_TERM: + var fun = Terms.child(pF, 0); if (ufSymbols.contains(fun)) { functionKind = FunctionDeclarationKind.UF; - functionArgs = getArgs(pF); - functionName = yices_get_term_name(functionArgs.get(0)); - functionDeclaration = functionArgs.get(0); - functionArgs.remove(0); + var args = getArgs(pF); + var f = args.get(0); + var x = FluentIterable.from(args).skip(1).toList(); + functionName = Terms.getName(f); + functionDeclaration = f; + functionArgs = x; } else { functionKind = FunctionDeclarationKind.SELECT; functionArgs = getArgs(pF); functionName = "select"; - functionDeclaration = -YICES_ARRAY_SELECT; + var f = Terms.newVariable(Terms.typeOf(functionArgs.get(0))); + var x = Terms.newVariable(Terms.typeOf(functionArgs.get(1))); + functionDeclaration = Terms.lambda(new int[] {f, x}, Terms.funApplication(f, x)); } break; - case YICES_UPDATE_TERM: + case UPDATE_TERM: functionKind = FunctionDeclarationKind.STORE; - functionArgs = - ImmutableList.of( - yices_term_child(pF, 0), yices_term_child(pF, 1), yices_term_child(pF, 2)); - functionDeclaration = -YICES_UPDATE_TERM; + functionArgs = getArgs(pF); + var f = Terms.newVariable(Terms.typeOf(functionArgs.get(0))); + var x = Terms.newVariable(Terms.typeOf(functionArgs.get(1))); + var y = Terms.newVariable(Terms.typeOf(functionArgs.get(2))); + functionDeclaration = Terms.lambda(new int[] {f, x, y}, Terms.functionUpdate1(f, x, y)); break; - case YICES_EQ_TERM: - functionKind = FunctionDeclarationKind.EQ; // Covers all equivalences + case EQ_TERM: + functionKind = FunctionDeclarationKind.EQ; break; - case YICES_DISTINCT_TERM: + case DISTINCT_TERM: functionKind = FunctionDeclarationKind.DISTINCT; break; - case YICES_NOT_TERM: + case NOT_TERM: if (isNestedExists(pF)) { int existsTerm = Iterables.getOnlyElement(getArgs(pF)); return visitQuantifier(pVisitor, pFormula, existsTerm, Quantifier.EXISTS); } else if (isNestedConjunction(pF)) { functionKind = FunctionDeclarationKind.AND; functionArgs = getNestedConjunctionArgs(pF); - functionDeclaration = -YICES_AND; } else { functionKind = FunctionDeclarationKind.NOT; } break; - case YICES_OR_TERM: + case OR_TERM: functionKind = FunctionDeclarationKind.OR; break; - case YICES_XOR_TERM: + case XOR_TERM: functionKind = FunctionDeclarationKind.XOR; break; - case YICES_BV_DIV: + case BV_DIV: functionKind = FunctionDeclarationKind.BV_UDIV; break; - case YICES_BV_REM: + case BV_REM: functionKind = FunctionDeclarationKind.BV_UREM; break; - case YICES_BV_SDIV: + case BV_SDIV: functionKind = FunctionDeclarationKind.BV_SDIV; break; - case YICES_BV_SREM: + case BV_SREM: functionKind = FunctionDeclarationKind.BV_SREM; break; - case YICES_BV_SMOD: + case BV_SMOD: functionKind = FunctionDeclarationKind.BV_SMOD; break; - case YICES_BV_SHL: + case BV_SHL: functionKind = FunctionDeclarationKind.BV_SHL; break; - case YICES_BV_LSHR: + case BV_LSHR: functionKind = FunctionDeclarationKind.BV_LSHR; break; - case YICES_BV_ASHR: + case BV_ASHR: functionKind = FunctionDeclarationKind.BV_ASHR; break; - case YICES_BV_GE_ATOM: + case BV_GE_ATOM: functionKind = FunctionDeclarationKind.BV_UGE; break; - case YICES_BV_SGE_ATOM: + case BV_SGE_ATOM: functionKind = FunctionDeclarationKind.BV_SGE; break; - case YICES_ARITH_GE_ATOM: + case ARITH_GE_ATOM: functionKind = FunctionDeclarationKind.GTE; break; - case YICES_FLOOR: + case FLOOR: functionKind = FunctionDeclarationKind.FLOOR; break; - case YICES_RDIV: + case RDIV: functionKind = FunctionDeclarationKind.DIV; break; - case YICES_IDIV: + case IDIV: functionKind = FunctionDeclarationKind.DIV; break; - case YICES_SELECT_TERM: + case SELECT_TERM: functionKind = FunctionDeclarationKind.SELECT; break; - case YICES_BV_SUM: - if (yices_term_num_children(pF) == 1) { + case BV_SUM: + if (Terms.numChildren(pF) == 1) { functionKind = FunctionDeclarationKind.BV_MUL; functionArgs = getMultiplyBvSumArgsFromSum(pF); - functionDeclaration = -YICES_BV_MUL; } else { functionKind = FunctionDeclarationKind.BV_ADD; functionArgs = getBvSumArgs(pF); } break; - case YICES_ARITH_SUM: - if (yices_term_num_children(pF) == 1) { + case ARITH_SUM: + if (Terms.numChildren(pF) == 1) { functionKind = FunctionDeclarationKind.MUL; functionArgs = getMultiplySumArgsFromSum(pF); - functionDeclaration = -YICES_POWER_PRODUCT; } else { functionKind = FunctionDeclarationKind.ADD; functionArgs = getSumArgs(pF); } break; - case YICES_POWER_PRODUCT: - if (yices_type_is_bitvector(yices_type_of_term(pF))) { + case POWER_PRODUCT: + if (Terms.isBitvector(pF)) { functionKind = FunctionDeclarationKind.BV_MUL; functionArgs = getMultiplyArgs(pF, true); - functionDeclaration = -YICES_BV_MUL; // TODO Product of more then 2 bitvectors ? } else { functionKind = FunctionDeclarationKind.MUL; functionArgs = getMultiplyArgs(pF, false); } break; - case YICES_BIT_TERM: + case BIT_TERM: functionKind = FunctionDeclarationKind.BV_EXTRACT; functionArgs = getBitArgs(pF); break; - case YICES_BV_ARRAY: + case BV_ARRAY: functionKind = FunctionDeclarationKind.BV_CONCAT; break; default: @@ -606,6 +473,9 @@ private R visitFunctionApplication( if (functionArgs == null) { functionArgs = getArgs(pF); } + if (functionDeclaration == null) { + functionDeclaration = buildDeclaration(functionKind, functionIndex, functionArgs); + } final ImmutableList> argTypes = ImmutableList.copyOf(toType(functionArgs)); @@ -629,6 +499,251 @@ private R visitFunctionApplication( functionName, functionKind, argTypes, getFormulaType(pF), functionDeclaration)); } + private int buildDeclaration( + FunctionDeclarationKind pKind, List pIndex, List pArgs) { + // FIXME + // var args = Lists.transform(pArgs, p -> Terms.newVariable(Terms.typeOf(p))); + ImmutableList.Builder builder = ImmutableList.builder(); + int c = 0; + for (var arg : pArgs) { + builder.add(Terms.newVariable("var" + c++, Terms.typeOf(arg))); + } + var args = builder.build(); + Integer f = null; + switch (pKind) { + case AND: + f = Terms.and(args); + break; + case NOT: + checkArgument(args.size() == 1); + f = Terms.not(args.get(0)); + break; + case OR: + f = Terms.or(args); + break; + case IFF: + checkArgument(args.size() == 2); + f = Terms.iff(args.get(0), args.get(1)); + break; + case ITE: + checkArgument(args.size() == 3); + f = Terms.ifThenElse(args.get(0), args.get(1), args.get(2)); + break; + case XOR: + f = Terms.xor(args); + break; + case IMPLIES: + checkArgument(args.size() == 2); + f = Terms.implies(args.get(0), args.get(1)); + break; + case DISTINCT: + f = Terms.distinct(args); + break; + case STORE: + checkArgument(args.size() == 3); + f = Terms.functionUpdate1(args.get(0), args.get(1), args.get(2)); + break; + case SELECT: + checkArgument(args.size() == 2); + f = Terms.funApplication(args.get(0), args.get(1)); + break; + case CONST: + checkArgument(args.size() == 1); + f = Terms.lambda(new int[] {}, args.get(0)); + break; + case UMINUS: + checkArgument(args.size() == 1); + f = Terms.neg(args.get(0)); + break; + case SUB: + checkArgument(args.size() == 2); + f = Terms.sub(args.get(0), args.get(1)); + break; + case ADD: + f = Terms.add(args); + break; + case DIV: + checkArgument(args.size() == 2); + f = Terms.div(args.get(0), args.get(1)); + break; + case MUL: + checkArgument(args.size() == 2); + f = Terms.mul(args.get(0), args.get(1)); + break; + case MODULO: + checkArgument(args.size() == 2); + f = Terms.imod(args.get(0), args.get(1)); + break; + case UF: + case VAR: + throw new IllegalArgumentException("Expecting builtin kind"); + case LT: + checkArgument(args.size() == 2); + f = Terms.arithLt(args.get(0), args.get(1)); + break; + case LTE: + checkArgument(args.size() == 2); + f = Terms.arithLeq(args.get(0), args.get(1)); + break; + case GT: + checkArgument(args.size() == 2); + f = Terms.arithGt(args.get(0), args.get(1)); + break; + case GTE: + checkArgument(args.size() == 2); + f = Terms.arithGeq(args.get(0), args.get(1)); + break; + case EQ: + checkArgument(args.size() == 2); + f = Terms.eq(args.get(0), args.get(1)); + break; + case EQ_ZERO: + throw new UnsupportedOperationException("EQ_ZERO not supported"); + case GTE_ZERO: + throw new UnsupportedOperationException("GTE_ZERO not supported"); + case FLOOR: + checkArgument(args.size() == 1); + f = Terms.floor(args.get(0)); + break; + case TO_REAL: + throw new UnsupportedOperationException("TO_REAL not supported"); + case INT_TO_BV: + throw new UnsupportedOperationException("INT_TO_BV not supported"); + case BV_EXTRACT: + checkArgument(args.size() == 1); + f = Terms.bvExtract(args.get(0), pIndex.get(0), pIndex.get(1)); + break; + case BV_CONCAT: + f = Terms.bvConcat(args); + break; + case BV_SIGN_EXTENSION: + checkArgument(args.size() == 1); + f = Terms.bvSignExtend(args.get(0), pIndex.get(0)); + break; + case BV_ZERO_EXTENSION: + checkArgument(args.size() == 1); + f = Terms.bvZeroExtend(args.get(0), pIndex.get(0)); + break; + case BV_NOT: + checkArgument(args.size() == 1); + f = Terms.bvNot(args.get(0)); + break; + case BV_NEG: + checkArgument(args.size() == 1); + f = Terms.bvNeg(args.get(0)); + break; + case BV_OR: + f = Terms.bvOr(args); + break; + case BV_AND: + f = Terms.bvAnd(args); + break; + case BV_XOR: + f = Terms.bvXor(args); + break; + case BV_SUB: + checkArgument(args.size() == 2); + f = Terms.bvSub(args.get(0), args.get(1)); + break; + case BV_ADD: + f = Terms.bvAdd(args); + break; + case BV_SDIV: + checkArgument(args.size() == 2); + f = Terms.bvSDiv(args.get(0), args.get(1)); + break; + case BV_UDIV: + checkArgument(args.size() == 2); + f = Terms.bvDiv(args.get(0), args.get(1)); + break; + case BV_SREM: + checkArgument(args.size() == 2); + f = Terms.bvSRem(args.get(0), args.get(1)); + break; + case BV_UREM: + checkArgument(args.size() == 2); + f = Terms.bvRem(args.get(0), args.get(1)); + break; + case BV_SMOD: + checkArgument(args.size() == 2); + f = Terms.bvSMod(args.get(0), args.get(1)); + break; + case BV_MUL: + checkArgument(args.size() == 2); + f = Terms.bvMul(args.get(0), args.get(1)); + break; + case BV_ULT: + checkArgument(args.size() == 2); + f = Terms.bvLt(args.get(0), args.get(1)); + break; + case BV_SLT: + checkArgument(args.size() == 2); + f = Terms.bvSLt(args.get(0), args.get(1)); + break; + case BV_ULE: + checkArgument(args.size() == 2); + f = Terms.bvLe(args.get(0), args.get(1)); + break; + case BV_SLE: + checkArgument(args.size() == 2); + f = Terms.bvSLe(args.get(0), args.get(1)); + break; + case BV_UGT: + checkArgument(args.size() == 2); + f = Terms.bvGt(args.get(0), args.get(1)); + break; + case BV_SGT: + checkArgument(args.size() == 2); + f = Terms.bvSGt(args.get(0), args.get(1)); + break; + case BV_UGE: + checkArgument(args.size() == 2); + f = Terms.bvGe(args.get(0), args.get(1)); + break; + case BV_SGE: + checkArgument(args.size() == 2); + f = Terms.bvSGe(args.get(0), args.get(1)); + break; + case BV_EQ: + checkArgument(args.size() == 2); + f = Terms.bvEq(args.get(0), args.get(1)); + break; + case BV_SHL: + checkArgument(args.size() == 2); + f = Terms.bvShl(args.get(0), args.get(1)); + break; + case BV_LSHR: + checkArgument(args.size() == 2); + f = Terms.bvLshr(args.get(0), args.get(1)); + break; + case BV_ASHR: + checkArgument(args.size() == 2); + f = Terms.bvAshr(args.get(0), args.get(1)); + break; + case BV_ROTATE_LEFT: + throw new UnsupportedOperationException("BV_ROTATE_LEFT not supported"); + case BV_ROTATE_RIGHT: + throw new UnsupportedOperationException("BV_ROTATE_RIGHT not supported"); + case BV_ROTATE_LEFT_BY_INT: + checkArgument(args.size() == 1); + f = Terms.bvRotateLeft(args.get(0), pIndex.get(0)); + break; + case BV_ROTATE_RIGHT_BY_INT: + checkArgument(args.size() == 1); + f = Terms.bvRotateRight(args.get(0), pIndex.get(0)); + break; + case UBV_TO_INT: + throw new UnsupportedOperationException("UBV_TO_INT not supported"); + case SBV_TO_INT: + throw new UnsupportedOperationException("SBV_TO_INT not supported"); + case OTHER: + throw new UnsupportedOperationException("OTHER not supported"); + default: + throw new UnsupportedOperationException(); + } + return Terms.lambda(args, f); + } + private List> toType(final List args) { return Lists.transform(args, this::getFormulaType); } @@ -640,14 +755,14 @@ private List> toType(final List args) { * of Yices. */ private static boolean isNestedExists(int outerTerm) { - return yices_term_constructor(outerTerm) == YICES_NOT_TERM - && yices_term_constructor(yices_term_child(outerTerm, 0)) == YICES_FORALL_TERM; + return Terms.constructor(outerTerm) == Constructor.NOT_TERM + && Terms.constructor(Terms.child(outerTerm, 0)) == Constructor.FORALL_TERM; } /** Yices transforms AND(x,...) into NOT(OR(NOT(X),NOT(...)). */ private static boolean isNestedConjunction(int outerTerm) { - return yices_term_constructor(outerTerm) == YICES_NOT_TERM - && yices_term_constructor(yices_term_child(outerTerm, 0)) == YICES_OR_TERM; + return Terms.constructor(outerTerm) == Constructor.NOT_TERM + && Terms.constructor(Terms.child(outerTerm, 0)) == Constructor.OR_TERM; } /** @@ -656,35 +771,28 @@ private static boolean isNestedConjunction(int outerTerm) { *

Only call this method for terms that are nested conjunctions! */ private static List getNestedConjunctionArgs(int outerTerm) { - checkArgument(yices_term_constructor(outerTerm) == YICES_NOT_TERM); - int middleTerm = yices_term_child(outerTerm, 0); - checkArgument(yices_term_constructor(middleTerm) == YICES_OR_TERM); + checkArgument(Terms.constructor(outerTerm) == Constructor.NOT_TERM); + int middleTerm = Terms.child(outerTerm, 0); + checkArgument(Terms.constructor(middleTerm) == Constructor.OR_TERM); List result = new ArrayList<>(); for (int child : getArgs(middleTerm)) { - result.add(yices_not(child)); + result.add(Terms.not(child)); } return result; } private static List getArgs(int parent) { - try { - return getArgs0(parent); - } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("problematic term: " + yices_term_to_string(parent), e); + ImmutableList.Builder children = ImmutableList.builder(); + for (int i = 0; i < Terms.numChildren(parent); i++) { + children.add(Terms.child(parent, i)); } - } - - private static List getArgs0(int parent) { - List children = new ArrayList<>(); - for (int i = 0; i < yices_term_num_children(parent); i++) { - children.add(yices_term_child(parent, i)); - } - return children; + return children.build(); } private static List getSumArgs(int parent) { + /* List children = new ArrayList<>(); - for (int i = 0; i < yices_term_num_children(parent); i++) { + for (int i = 0; i < Terms.numChildren(parent); i++) { String[] child = yices_sum_component(parent, i); String coeff = child[0]; int term = Integer.parseInt(child[1]); @@ -696,13 +804,28 @@ private static List getSumArgs(int parent) { } } return children; + */ + throw new UnsupportedOperationException("arith sum not supported"); + } + + /** extract -1 and X from the sum of one element [-1*x]. */ + private static List getMultiplySumArgsFromSum(int parent) { + /* + checkArgument(Terms.numChildren(parent) == 1); + String[] child = yices_sum_component(parent, 0); + int term = Integer.parseInt(child[1]); + checkArgument(term != -1, "unexpected constant coeff without variable"); + int coeffTerm = yices_parse_rational(child[0]); + return ImmutableList.of(coeffTerm, term); + */ + throw new UnsupportedOperationException("arith sum not supported"); } /** extract all entries of a BV sum like "3*x + 2*y + 1". */ private static List getBvSumArgs(int parent) { - List children = new ArrayList<>(); - int bitsize = yices_term_bitsize(parent); - for (int i = 0; i < yices_term_num_children(parent); i++) { + /*List children = new ArrayList<>(); + int bitsize = Terms.bitSize(parent); + for (int i = 0; i < Terms.numChildren(parent); i++) { int[] component = yices_bvsum_component(parent, i, bitsize); assert component.length == bitsize + 1; // the components consist of coefficient (as bits) and variable (if missing: -1) @@ -715,33 +838,29 @@ private static List getBvSumArgs(int parent) { } } return children; + */ + throw new UnsupportedOperationException("bvsum not supported"); } /** extract -1 and X from the sum of one element [-1*x]. */ private static List getMultiplyBvSumArgsFromSum(int parent) { - checkArgument(yices_term_num_children(parent) == 1); - int bitsize = yices_term_bitsize(parent); + /* + checkArgument(Terms.numChildren(parent) == 1); + int bitsize = Terms.bitSize(parent); int[] component = yices_bvsum_component(parent, 0, bitsize); int coeff = yices_bvconst_from_array(bitsize, Arrays.copyOfRange(component, 0, bitsize)); int term = component[component.length - 1]; checkArgument(term != -1, "unexpected constant coeff without variable"); return ImmutableList.of(coeff, term); - } - - /** extract -1 and X from the sum of one element [-1*x]. */ - private static List getMultiplySumArgsFromSum(int parent) { - checkArgument(yices_term_num_children(parent) == 1); - String[] child = yices_sum_component(parent, 0); - int term = Integer.parseInt(child[1]); - checkArgument(term != -1, "unexpected constant coeff without variable"); - int coeffTerm = yices_parse_rational(child[0]); - return ImmutableList.of(coeffTerm, term); + */ + throw new UnsupportedOperationException("bvsum not supported"); } private static List getMultiplyArgs(int parent, boolean isBV) { + /* // TODO Add exponent? List result = new ArrayList<>(); - for (int i = 0; i < yices_term_num_children(parent); i++) { + for (int i = 0; i < Terms.numChildren(parent); i++) { int[] component = yices_product_component(parent, i); if (isBV) { result.add(yices_bvpower(component[0], component[1])); @@ -750,154 +869,34 @@ private static List getMultiplyArgs(int parent, boolean isBV) { } } return result; + */ + throw new UnsupportedOperationException("product not supported"); } /** get "index" and "b" from "(bit index b)". */ private static List getBitArgs(int parent) { - return ImmutableList.of(yices_proj_arg(parent), yices_int32(yices_proj_index(parent))); + return ImmutableList.of(Terms.projArg(parent), Terms.intConst(Terms.projIndex(parent))); } @Override public Integer callFunctionImpl(Integer pDeclaration, List pArgs) { - if (pDeclaration < 0) { // is constant function application from API - switch (-pDeclaration) { - case YICES_ITE_TERM: - checkArgsLength("YICES_ITE_TERM", pArgs, 3); - return yices_ite(pArgs.get(0), pArgs.get(1), pArgs.get(2)); - case YICES_EQ_TERM: - checkArgsLength("YICES_EQ_TERM", pArgs, 2); - return yices_eq(pArgs.get(0), pArgs.get(1)); - case YICES_DISTINCT_TERM: - return yices_distinct(pArgs.size(), Ints.toArray(pArgs)); - case YICES_NOT_TERM: - checkArgsLength("YICES_NOT_TERM", pArgs, 1); - return yices_not(pArgs.get(0)); - case YICES_OR_TERM: - return yices_or(pArgs.size(), Ints.toArray(pArgs)); - case YICES_XOR_TERM: - return yices_xor(pArgs.size(), Ints.toArray(pArgs)); - case YICES_BV_DIV: - checkArgsLength("YICES_BV_DIV", pArgs, 2); - return yices_bvdiv(pArgs.get(0), pArgs.get(1)); - case YICES_BV_REM: - checkArgsLength("YICES_BV_REM", pArgs, 2); - return yices_bvrem(pArgs.get(0), pArgs.get(1)); - case YICES_BV_SDIV: - checkArgsLength("YICES_BV_SDIV", pArgs, 2); - return yices_bvsdiv(pArgs.get(0), pArgs.get(1)); - case YICES_BV_SREM: - checkArgsLength("YICES_BV_SREM", pArgs, 2); - return yices_bvsrem(pArgs.get(0), pArgs.get(1)); - case YICES_BV_SMOD: - checkArgsLength("YICES_BV_SMOD", pArgs, 2); - return yices_bvsmod(pArgs.get(0), pArgs.get(1)); - case YICES_BV_SHL: - checkArgsLength("YICES_BV_SHL", pArgs, 2); - return yices_bvshl(pArgs.get(0), pArgs.get(1)); - case YICES_BV_LSHR: - checkArgsLength("YICES_BV_LSHR", pArgs, 2); - return yices_bvlshr(pArgs.get(0), pArgs.get(1)); - case YICES_BV_ASHR: - checkArgsLength("YICES_BV_ASHR", pArgs, 2); - return yices_bvashr(pArgs.get(0), pArgs.get(1)); - case YICES_BV_GE_ATOM: - checkArgsLength("YICES_BV_GE_ATOM", pArgs, 2); - return yices_bvge_atom(pArgs.get(0), pArgs.get(1)); - case YICES_BV_SGE_ATOM: - checkArgsLength("YICES_BV_SGE_ATOM", pArgs, 2); - return yices_bvsge_atom(pArgs.get(0), pArgs.get(1)); - case YICES_ARITH_GE_ATOM: - checkArgsLength("YICES_ARITH_GE_ATOM", pArgs, 2); - return yices_arith_geq_atom(pArgs.get(0), pArgs.get(1)); - case YICES_ABS: - checkArgsLength("YICES_ABS", pArgs, 1); - return yices_abs(pArgs.get(0)); - case YICES_CEIL: - checkArgsLength("YICES_CEIL", pArgs, 1); - return yices_ceil(pArgs.get(0)); - case YICES_FLOOR: - checkArgsLength("YICES_FLOOR", pArgs, 1); - return yices_floor(pArgs.get(0)); - case YICES_RDIV: - checkArgsLength("YICES_RDIV", pArgs, 2); - return yices_division(pArgs.get(0), pArgs.get(1)); - case YICES_IDIV: - checkArgsLength("YICES_IDIV", pArgs, 2); - return yices_idiv(pArgs.get(0), pArgs.get(1)); - case YICES_IMOD: - checkArgsLength("YICES_IMOD", pArgs, 2); - return yices_imod(pArgs.get(0), pArgs.get(1)); - case YICES_IS_INT_ATOM: - checkArgsLength("YICES_IS_INT_ATOM", pArgs, 1); - return yices_is_int_atom(pArgs.get(0)); - case YICES_DIVIDES_ATOM: - checkArgsLength("YICES_DIVIDES_ATOM", pArgs, 2); - return yices_divides_atom(pArgs.get(0), pArgs.get(1)); - case YICES_BV_SUM: - return yices_bvsum(pArgs.size(), Ints.toArray(pArgs)); - case YICES_ARITH_SUM: - return yices_sum(pArgs.size(), Ints.toArray(pArgs)); - case YICES_POWER_PRODUCT: - return yices_product(pArgs.size(), Ints.toArray(pArgs)); - case YICES_BIT_TERM: - checkArgsLength("YICES_BIT_TERM", pArgs, 2); - return yices_bitextract(pArgs.get(0), toInt(pArgs.get(1))); - case YICES_BV_ARRAY: - return yices_bvarray(pArgs.size(), Ints.toArray(pArgs)); - case YICES_BV_MUL: - return yices_bvproduct(pArgs.size(), Ints.toArray(pArgs)); - case YICES_AND: - return yices_and(pArgs.size(), Ints.toArray(pArgs)); - case YICES_ARRAY_SELECT: - return yices_application(pArgs.get(0), 1, new int[] {pArgs.get(1)}); - case YICES_UPDATE_TERM: - return yices_update(pArgs.get(0), 1, new int[] {pArgs.get(1)}, pArgs.get(2)); - default: - // TODO add more cases - // if something bad happens here, - // in most cases the solution is a fix in the method visitFunctionApplication - throw new IllegalArgumentException( - String.format( - "Unknown function declaration with constructor %d and arguments %s (%s)", - -pDeclaration, - pArgs, - Lists.transform(pArgs, Yices2NativeApi::yices_term_to_string))); - } - } else { // is UF Application - if (pArgs.isEmpty()) { - return pDeclaration; - } else { - int[] argArray = Ints.toArray(pArgs); - int app = yices_application(pDeclaration, argArray.length, argArray); - return app; - } + checkArgument(Types.numChildren(Terms.typeOf(pDeclaration)) == 1 + pArgs.size()); + if (pArgs.isEmpty()) { + return pDeclaration; + } else { + return Terms.funApplication(pDeclaration, Ints.toArray(pArgs)); } } - private int toInt(int termId) { - assert yices_term_is_int(termId); - return Integer.parseInt(yices_rational_const_value(termId)); - } - - private void checkArgsLength(String kind, List pArgs, final int expectedLength) { - checkArgument( - pArgs.size() == expectedLength, - "%s with %s expected arguments was called with unexpected arguments: %s", - kind, - expectedLength, - Collections2.transform(pArgs, Yices2NativeApi::yices_term_to_string)); - } - @Override public Integer declareUFImpl(String pName, Integer pReturnType, List pArgTypes) { - int size = pArgTypes.size(); int[] argTypeArray = Ints.toArray(pArgTypes); final int yicesFuncType; if (pArgTypes.isEmpty()) { // a nullary function is a plain symbol (variable) yicesFuncType = pReturnType; } else { - yicesFuncType = yices_function_type(size, argTypeArray, pReturnType); + yicesFuncType = Types.functionType(argTypeArray, pReturnType); } int uf = createNamedVariable(yicesFuncType, pName); ufSymbols.add(uf); @@ -906,51 +905,75 @@ public Integer declareUFImpl(String pName, Integer pReturnType, List pA @Override protected Integer getBooleanVarDeclarationImpl(Integer pTFormulaInfo) { - return yices_term_constructor(pTFormulaInfo); + return pTFormulaInfo; } private Object parseNumeralValue(Integer pF, FormulaType type) { checkArgument( - yices_term_constructor(pF) == YICES_ARITH_CONST, + Terms.isArithConstant(pF), "Term: '%s' with type '%s' is not an arithmetic constant", - yices_term_to_string(pF), - yices_type_to_string(yices_type_of_term(pF))); + Terms.toString(pF), + Types.toString(Terms.typeOf(pF))); - String value = yices_rational_const_value(pF); if (type.isRationalType()) { - Rational ratValue = Rational.of(value); - return ratValue.isIntegral() ? ratValue.getNum() : ratValue; + var rational = Terms.arithConstValue(pF); + return rational.isInteger() + ? rational.getNumerator() + : Rational.of(rational.getNumerator(), rational.getDenominator()); } else if (type.isIntegerType()) { - return new BigInteger(value); + return Terms.arithConstValue(pF).getNumerator(); } else { throw new IllegalArgumentException("Unexpected type: " + type); } } + /** + * Converts an array of booleans into a BigInteger value. + * + *

Assumes "little endian" encoding + */ + BigInteger bitsToInteger(boolean[] bits) { + var value = BigInteger.ZERO; + for (var p = 0; p < bits.length; p++) { + if (bits[p]) { + value = value.setBit(p); + } + } + return value; + } + + /** + * Converts a BigInteger into an array of booleans. + * + *

Inverse of {@link #bitsToInteger} + */ + boolean[] integerToBits(int bitsize, BigInteger value) { + checkArgument(bitsize >= value.bitLength()); + + var bits = new boolean[bitsize]; + for (int p = 0; p < value.bitLength(); p++) { + bits[p] = value.testBit(p); + } + return bits; + } + private BigInteger parseBitvector(int pF) { checkArgument( - yices_term_constructor(pF) == YICES_BV_CONST, - "Term: '%s' is not a bitvector constant", - yices_term_to_string(pF)); - - int[] littleEndianBV = yices_bv_const_value(pF, yices_term_bitsize(pF)); - checkArgument(littleEndianBV.length != 0, "BV was empty"); - String bigEndianBV = Joiner.on("").join(Lists.reverse(Ints.asList(littleEndianBV))); - return new BigInteger(bigEndianBV, 2); + Terms.isBvConstant(pF), "Term: '%s' is not a bitvector constant", Terms.toString(pF)); + return bitsToInteger(Terms.bvConstValue(pF)); } @Override public Object convertValue(Integer typeKey, Integer pF) { FormulaType type = getFormulaType(typeKey); if (type.isBooleanType()) { - return pF.equals(yices_true()); + return pF.equals(Terms.mkTrue()); } else if (type.isRationalType() || type.isIntegerType()) { return parseNumeralValue(pF, type); } else if (type.isBitvectorType()) { return parseBitvector(pF); } else { - throw new IllegalArgumentException( - "Unexpected type: " + yices_type_to_string(yices_type_of_term(pF))); + throw new IllegalArgumentException("Unexpected type: " + Types.toString(Terms.typeOf(pF))); } } } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaManager.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaManager.java index a7d9a01b2c..b5888acad9 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaManager.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaManager.java @@ -9,26 +9,15 @@ package org.sosy_lab.java_smt.solvers.yices2; import static com.google.common.base.CharMatcher.inRange; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_APP_TERM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvtype_size; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_distinct; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_eq; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_parse_term; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_term_child; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_term_constructor; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_term_to_string; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_true; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_children; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_is_bitvector; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_num_children; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_of_term; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_to_string; import com.google.common.base.CharMatcher; import com.google.common.base.Preconditions; import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.primitives.Ints; +import com.sri.yices.Constructor; +import com.sri.yices.Terms; +import com.sri.yices.Types; import java.io.IOException; import java.util.Locale; import java.util.Map; @@ -77,31 +66,31 @@ static Integer getYicesTerm(Formula pT) { @Override protected Integer equalImpl(Integer pArg1, Integer pArgs) { - return yices_eq(pArg1, pArgs); + return Terms.eq(pArg1, pArgs); } @Override protected Integer distinctImpl(Iterable pArgs) { int[] array = Ints.toArray(ImmutableList.copyOf(pArgs)); if (array.length < 2) { - return yices_true(); + return Terms.mkTrue(); } else { - return yices_distinct(array.length, array); + return Terms.distinct(array); } } @Override protected Integer parseImpl(String pSmtScript) throws IllegalArgumentException { - // TODO Might expect Yices input language instead of smt-lib2 notation - return yices_parse_term(pSmtScript); + // Yices uses its own input language and can't parse smt-lib2 + throw new UnsupportedOperationException(); } /** Helper function to (pretty) print yices2 sorts. */ private String getTypeRepr(int type) { - if (yices_type_is_bitvector(type)) { - return "(_ BitVec " + yices_bvtype_size(type) + ")"; + if (Types.isBitvector(type)) { + return "(_ BitVec " + Types.bvSize(type) + ")"; } - String typeRepr = yices_type_to_string(type); + String typeRepr = Types.toString(type); return typeRepr.substring(0, 1).toUpperCase(Locale.getDefault()) + typeRepr.substring(1); } @@ -116,17 +105,17 @@ assert getFormulaCreator().getFormulaType(formula) == FormulaType.BooleanType for (Map.Entry entry : varsAndUFs.entrySet()) { final int term = ((Yices2Formula) entry.getValue()).getTerm(); final int type; - if (yices_term_constructor(term) == YICES_APP_TERM) { + if (Terms.constructor(term) == Constructor.APP_TERM) { // Is an UF. Correct type is carried by first child. - type = yices_type_of_term(yices_term_child(term, 0)); + type = Terms.typeOf(Terms.child(term, 0)); } else { - type = yices_type_of_term(term); + type = Terms.typeOf(term); } final int[] types; - if (yices_type_num_children(type) == 0) { + if (Types.numChildren(type) == 0) { types = new int[] {type}; } else { - types = yices_type_children(type); // adds children types and then return type + types = Types.children(type); // adds children types and then return type } if (types.length > 0) { out.append("(declare-fun "); @@ -144,7 +133,7 @@ assert getFormulaCreator().getFormulaType(formula) == FormulaType.BooleanType } } // TODO fold formula to avoid exp. overhead - out.append("(assert ").append(yices_term_to_string(formula)).append(")"); + out.append("(assert ").append(Terms.toString(formula)).append(")"); return out.toString(); } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2IntegerFormulaManager.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2IntegerFormulaManager.java index 07e799eb17..b9622dd235 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2IntegerFormulaManager.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2IntegerFormulaManager.java @@ -8,9 +8,7 @@ package org.sosy_lab.java_smt.solvers.yices2; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_idiv; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_imod; - +import com.sri.yices.Terms; import java.math.BigDecimal; import java.math.BigInteger; import org.sosy_lab.java_smt.api.IntegerFormulaManager; @@ -42,12 +40,12 @@ protected Integer makeNumberImpl(BigDecimal pNumber) { @Override public Integer divide(Integer pParam1, Integer pParam2) { - return yices_idiv(pParam1, pParam2); + return Terms.idiv(pParam1, pParam2); } @Override public Integer modulo(Integer pParam1, Integer pParam2) { - return yices_imod(pParam1, pParam2); + return Terms.imod(pParam1, pParam2); } @Override diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java index 349c2e3596..5f9b2cc202 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java @@ -11,15 +11,14 @@ package org.sosy_lab.java_smt.solvers.yices2; import static com.google.common.base.Preconditions.checkArgument; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_assert_formulas; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_free_context; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_interpolate; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_true; import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; import com.google.common.primitives.Ints; +import com.sri.yices.InterpolationContext; +import com.sri.yices.Status; +import com.sri.yices.Terms; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -66,17 +65,21 @@ public BooleanFormula getInterpolant(Collection formulasOfA) } private int interpolate(Collection setA, Collection setB) { - var ctxA = newContext(true); - var ctxB = newContext(true); + try (var ctxA = newContext(true); + var ctxB = newContext(true)) { - yices_assert_formulas(ctxA, setA.size(), Ints.toArray(setA)); - yices_assert_formulas(ctxB, setB.size(), Ints.toArray(setB)); + ctxA.assertFormulas(Ints.toArray(setA)); + ctxB.assertFormulas(Ints.toArray(setB)); + var context = new InterpolationContext(ctxA, ctxB); - try { - return yices_interpolate(ctxA, ctxB); - } finally { - yices_free_context(ctxB); - yices_free_context(ctxA); + // TODO How to abort this? + var status = context.check(DEFAULT_PARAMS, false); + if (status == Status.UNSAT) { + return context.getInterpolant(); + } else { + // TODO + throw new IllegalArgumentException(); + } } } @@ -92,7 +95,7 @@ public List getSeqInterpolants(List itps = new ArrayList<>(); - var previousItp = yices_true(); + var previousItp = Terms.mkTrue(); for (int i = 1; i < n; i++) { Collection formulasA = FluentIterable.from(partitions.get(i - 1)) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Model.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Model.java index c1a2fb2859..58d281bd92 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Model.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Model.java @@ -8,49 +8,14 @@ package org.sosy_lab.java_smt.solvers.yices2; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YVAL_ALGEBRAIC; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YVAL_BOOL; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YVAL_BV; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YVAL_FUNCTION; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YVAL_MAPPING; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YVAL_RATIONAL; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.tagForValKind; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_application; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvtype_size; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_def_terms; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_eq; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_false; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_free_model; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_term_name; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_value; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_value_as_term; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_model_to_string; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_parse_bvbin; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_parse_float; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_parse_rational; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_term_to_string; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_true; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_children; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_is_arithmetic; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_is_bitvector; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_is_bool; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_is_int; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_of_term; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_to_string; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_val_bitsize; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_val_expand_function; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_val_expand_mapping; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_val_function_arity; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_val_get_bool; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_val_get_bv; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_val_get_mpq; - -import com.google.common.base.Joiner; import com.google.common.base.Preconditions; -import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.common.primitives.Ints; +import com.sri.yices.Model; +import com.sri.yices.Terms; +import com.sri.yices.Types; +import com.sri.yices.VectorValue; +import com.sri.yices.YVal; +import com.sri.yices.YicesException; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; @@ -60,11 +25,11 @@ public class Yices2Model extends AbstractModel { - private final long model; + private final Model model; private final Yices2AbstractProver prover; private final Yices2FormulaCreator formulaCreator; - Yices2Model(long model, Yices2AbstractProver prover, Yices2FormulaCreator pCreator) { + Yices2Model(Model model, Yices2AbstractProver prover, Yices2FormulaCreator pCreator) { super(prover, pCreator); this.model = model; this.prover = prover; @@ -74,7 +39,7 @@ public class Yices2Model extends AbstractModel { @Override public void close() { if (!isClosed()) { - yices_free_model(model); + model.close(); } super.close(); } @@ -84,146 +49,124 @@ public ImmutableList asList() { Preconditions.checkState(!isClosed()); Preconditions.checkState(!prover.isClosed(), "cannot use model after prover is closed"); ImmutableList.Builder assignments = ImmutableList.builder(); - int[] termsInModel = yices_def_terms(model); + int[] termsInModel = model.collectDefinedTerms(); for (int term : termsInModel) { - int[] yvalTag = yices_get_value(model, term); - switch (yvalTag[1]) { - case YVAL_BOOL: - case YVAL_RATIONAL: - case YVAL_ALGEBRAIC: - case YVAL_BV: + YVal yval = model.getValue(term); + switch (yval.tag) { + case BOOL: + case RATIONAL: + case ALGEBRAIC: + case BV: assignments.add(getSimpleAssignment(term)); continue; - case YVAL_FUNCTION: // UFs and Arrays - assignments.addAll(getFunctionAssignment(term, yvalTag)); + case FUNCTION: // UFs and Arrays + assignments.addAll(getFunctionAssignment(term, yval)); continue; default: - throw new UnsupportedOperationException("YVAL with unexpected tag: " + yvalTag[1]); + throw new UnsupportedOperationException("YVAL with unexpected tag: " + yval.tag); } } return assignments.build(); } - private ImmutableList getFunctionAssignment(int t, int[] yval) { + private ImmutableList getFunctionAssignment(int f, YVal value) { + int[] types = Types.children(Terms.typeOf(f)); + VectorValue expandFun = model.expandFunction(value); + ImmutableList.Builder assignments = ImmutableList.builder(); - int arity = yices_val_function_arity(model, yval[0], yval[1]); - int[] types = yices_type_children(yices_type_of_term(t)); - int[] argTerms = new int[arity]; - String name = yices_get_term_name(t); - int[] expandFun = yices_val_expand_function(model, yval[0], yval[1]); - for (int i = 2; i < expandFun.length - 1; i += 2) { - int[] expandMap; - if (expandFun[i + 1] == YVAL_MAPPING) { - expandMap = - yices_val_expand_mapping(model, expandFun[i], arity, tagForValKind(expandFun[i + 1])); - } else { - throw new IllegalArgumentException("Unexpected YVAL tag " + yval[1]); - } - List argumentInterpretation = new ArrayList<>(); - for (int j = 0; j < expandMap.length - 2; j += 2) { - Object argValue = valueFromYval(expandMap[j], expandMap[j + 1], types[j / 2]); - argumentInterpretation.add(argValue); - argTerms[j / 2] = valueAsTerm(types[j / 2], argValue); + for (var map : expandFun.vector) { + var x = model.expandMapping(map); + + ImmutableList.Builder builderValues = ImmutableList.builder(); + ImmutableList.Builder builderTerms = ImmutableList.builder(); + + for (int p = 0; p < x.vector.length; p++) { + var v = x.vector[p]; + var t = types[p]; + + var argValue = toValue(v, t); + var argTerm = constantValue(argValue, t); + + builderValues.add(argValue); + builderTerms.add(argTerm); } - Object funValue = - valueFromYval( - expandMap[expandMap.length - 2], - expandMap[expandMap.length - 1], - types[types.length - 1]); - int valueTerm = valueAsTerm(types[types.length - 1], funValue); - int funApp = yices_application(t, arity, argTerms); + + var funValue = toValue(x.value, types[types.length - 1]); + var funTerm = constantValue(funValue, types[types.length - 1]); + + var app = Terms.funApplication(f, builderTerms.build()); + assignments.add( new ValueAssignment( - creator.encapsulateWithTypeOf(funApp), - creator.encapsulateWithTypeOf(valueTerm), - creator.encapsulateBoolean(yices_eq(funApp, valueTerm)), - name, + creator.encapsulateWithTypeOf(app), + creator.encapsulateWithTypeOf(funTerm), + creator.encapsulateBoolean(Terms.eq(app, funTerm)), + Terms.getName(f), funValue, - argumentInterpretation)); + builderValues.build())); } return assignments.build(); } private ValueAssignment getSimpleAssignment(int t) { List argumentInterpretation = new ArrayList<>(); - int valueTerm = yices_get_value_as_term(model, t); + int valueTerm = model.valueAsTerm(t); return new ValueAssignment( creator.encapsulateWithTypeOf(t), creator.encapsulateWithTypeOf(valueTerm), - creator.encapsulateBoolean(yices_eq(t, valueTerm)), - yices_get_term_name(t), + creator.encapsulateBoolean(Terms.eq(t, valueTerm)), + Terms.getName(t), formulaCreator.convertValue(t, valueTerm), argumentInterpretation); } - private Object valueFromYval(int id, int tag, int type) { - if (tag == YVAL_BOOL) { - return yices_val_get_bool(model, id, tag); - } else if (tag == YVAL_RATIONAL) { - String value = yices_val_get_mpq(model, id, tag); - if (yices_type_is_int(type) && !value.contains("/")) { - return new BigInteger(value); - } else { - return Rational.of(value); - } - } else if (tag == YVAL_BV) { - int size = yices_val_bitsize(model, id, tag); - int[] littleEndianBV = yices_val_get_bv(model, id, size, tag); - Preconditions.checkArgument(littleEndianBV.length != 0, "BV was empty"); - String bigEndianBV = Joiner.on("").join(Lists.reverse(Ints.asList(littleEndianBV))); - return new BigInteger(bigEndianBV, 2); - } else { - throw new IllegalArgumentException("Unexpected YVAL tag: " + tag); + /** Convert a Yices value to a Java value. */ + private Object toValue(YVal value, int type) { + switch (value.tag) { + case BOOL: + return model.boolValue(value); + case RATIONAL: + if (Types.isInt(type)) { + return model.bigIntegerValue(value); + } else { + var rational = model.bigRationalValue(value); + return Rational.of(rational.getNumerator(), rational.getDenominator()); + } + case BV: + return formulaCreator.bitsToInteger(model.bvValue(value)); + default: + throw new IllegalArgumentException("Unexpected value type: " + value.tag); } } - private int valueAsTerm(int type, Object value) { - if (yices_type_is_bool(type)) { - if ((boolean) value) { - return yices_true(); - } else { - return yices_false(); - } - } else if (yices_type_is_arithmetic(type)) { - String val = value.toString(); - if (val.contains("/")) { - return yices_parse_rational(val); - } else { - return yices_parse_float(val); - } - } else if (yices_type_is_bitvector(type)) { - BigInteger val = (BigInteger) value; - int bvSize = yices_bvtype_size(type); - String bits = val.toString(2); - assert bits.length() <= bvSize - : "numeral value " + val + " is out of range for size " + bvSize; - if (bits.length() < bvSize) { - bits = Strings.padStart(bits, bvSize, '0'); - } - Preconditions.checkArgument(bits.length() == bvSize, "Bitvector has unexpected size."); - return yices_parse_bvbin(bits); + /** Create a term for a constant value. */ + private int constantValue(Object value, int type) { + if (Types.isBool(type)) { + return Terms.mkBoolConst((Boolean) value); + } else if (Types.isInt(type)) { + return Terms.intConst((BigInteger) value); + } else if (Types.isReal(type)) { + var rational = (Rational) value; + return Terms.rationalConst(rational.getNum(), rational.getDen()); + } else if (Types.isBitvector(type)) { + return Terms.bvConst(formulaCreator.integerToBits(Types.bvSize(type), (BigInteger) value)); } else { - throw new IllegalArgumentException("Unexpected type: " + yices_type_to_string(type)); + throw new IllegalArgumentException("Unexpected type: " + Types.toString(type)); } } @Override protected @Nullable Integer evalImpl(Integer pFormula) { - // TODO Can UF appear here?? // Built in Functions like "add" seem to be OK - Preconditions.checkState(!isClosed()); - // TODO REENABLE after testing - // Preconditions.checkState(!prover.isClosed(), "cannot use model after prover is closed"); - int val = yices_get_value_as_term(model, pFormula); - if (val == -1) { - throw new IllegalArgumentException( - "Could not evaluate Term: " + yices_term_to_string(pFormula)); + try { + return model.valueAsTerm(pFormula); + } catch (YicesException e) { + throw new IllegalArgumentException("Could not evaluate term: " + Terms.toString(pFormula)); } - return val; } @Override public String toString() { - return yices_model_to_string(model); + return model.toString(); } } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java deleted file mode 100644 index 76ff3a3c23..0000000000 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApi.java +++ /dev/null @@ -1,870 +0,0 @@ -// This file is part of JavaSMT, -// an API wrapper for a collection of SMT solvers: -// https://github.com/sosy-lab/java-smt -// -// SPDX-FileCopyrightText: 2020 Dirk Beyer -// -// SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later - -package org.sosy_lab.java_smt.solvers.yices2; - -import java.util.function.Supplier; -import org.sosy_lab.common.ShutdownNotifier; -import org.sosy_lab.java_smt.api.SolverException; -import org.sosy_lab.java_smt.basicimpl.ShutdownHook; - -@SuppressWarnings({"unused", "checkstyle:methodname", "checkstyle:parametername"}) -public final class Yices2NativeApi { - private Yices2NativeApi() {} - - // Yices2 status codes - public static final int YICES_STATUS_IDLE = 0; - public static final int YICES_STATUS_SEARCHING = 1; - public static final int YICES_STATUS_UNKNOWN = 2; - public static final int YICES_STATUS_SAT = 3; - public static final int YICES_STATUS_UNSAT = 4; - public static final int YICES_STATUS_INTERRUPTED = 5; - public static final int YICES_STATUS_ERROR = 6; - - // Yices2 term constructors - public static final int YICES_CONSTRUCTOR_ERROR = -1; - public static final int YICES_BOOL_CONST = 0; - public static final int YICES_ARITH_CONST = 1; - public static final int YICES_ARITH_FF_CONSTANT = 2; // finite field rational constant - public static final int YICES_BV_CONST = 3; - public static final int YICES_SCALAR_CONST = 4; // NOT used in JavaSMT - public static final int YICES_VARIABLE = 5; - public static final int YICES_UNINTERPRETED_TERM = 6; - - public static final int YICES_ITE_TERM = 7; // if-then-else - public static final int YICES_APP_TERM = 8; // application of an uninterpreted function - public static final int YICES_UPDATE_TERM = 9; // function update - public static final int YICES_TUPLE_TERM = 10; // tuple constructor - public static final int YICES_EQ_TERM = 11; // equality - public static final int YICES_DISTINCT_TERM = 12; // distinct t_1 ... t_n - public static final int YICES_FORALL_TERM = 13; // quantifier - public static final int YICES_LAMBDA_TERM = 14; // lambda - public static final int YICES_NOT_TERM = 15; // (not t) - public static final int YICES_OR_TERM = 16; // n-ary OR - public static final int YICES_XOR_TERM = 17; // n-ary XOR - - public static final int YICES_BV_ARRAY = 18; // array of boolean terms - public static final int YICES_BV_DIV = 19; // unsigned division - public static final int YICES_BV_REM = 20; // unsigned remainder - public static final int YICES_BV_SDIV = 21; // signed division - public static final int YICES_BV_SREM = 22; // remainder in signed division (rounding to 0) - public static final int YICES_BV_SMOD = 23; // remainder in signed division (rounding to - // -infinity) - public static final int YICES_BV_SHL = 24; // shift left (padding with 0) - public static final int YICES_BV_LSHR = 25; // logical shift right (padding with 0) - public static final int YICES_BV_ASHR = 26; // arithmetic shift right (padding with sign bit) - public static final int YICES_BV_GE_ATOM = 27; // unsigned comparison: (t1 >= t2) - public static final int YICES_BV_SGE_ATOM = 28; // signed comparison (t1 >= t2) - public static final int YICES_ARITH_GE_ATOM = 29; // atom (t1 >= t2) for arithmetic terms: t2 is - // always 0 - public static final int YICES_ARITH_ROOT_ATOM = 30; // atom (0 <= k <= root_count(p)) && (x r - // root(p,k)) for r in <, <=, ==, !=, >, >= - - public static final int YICES_ABS = 31; // absolute value - public static final int YICES_CEIL = 32; // ceil - public static final int YICES_FLOOR = 33; // floor - public static final int YICES_RDIV = 34; // real division (as in x/y) - public static final int YICES_IDIV = 35; // integer division - public static final int YICES_IMOD = 36; // modulo - public static final int YICES_IS_INT_ATOM = 37; // integrality test: (is-int t) - public static final int YICES_DIVIDES_ATOM = 38; // divisibility test: (divides t1 t2) - - // projections - public static final int YICES_SELECT_TERM = 39; // tuple projection - public static final int YICES_BIT_TERM = 40; // bit-select: extract the i-th bit of a bitvector - - // sums - public static final int YICES_BV_SUM = 41; // sum of pairs a * t where a is a bitvector constant - // (and t is a bitvector term) - public static final int YICES_ARITH_SUM = 42; // sum of pairs a * t where a is a rational (and t - // is an arithmetic term) - public static final int YICES_ARITH_FF_SUM = 43; // sum of pairs a * t where a is an finite - // field constant (and t is an finite field arithmetic term) products - public static final int YICES_POWER_PRODUCT = 44; // power products: (t1^d1 * ... * t_n^d_n) - - // Workaround as Yices misses some useful operators, - // MAX_INT avoids collisions with existing constants - public static final int YICES_AND = Integer.MAX_VALUE - 1; - public static final int YICES_BV_MUL = Integer.MAX_VALUE - 2; - public static final int YICES_ARRAY_SELECT = Integer.MAX_VALUE - 3; - - /* - * Yices model tags - */ - public static final int YVAL_UNKNOWN = 0; - public static final int YVAL_BOOL = 1; - public static final int YVAL_RATIONAL = 2; - public static final int YVAL_ALGEBRAIC = 3; - public static final int YVAL_FINITEFIELD = 4; - public static final int YVAL_BV = 5; - public static final int YVAL_SCALAR = 6; - public static final int YVAL_TUPLE = 7; - public static final int YVAL_FUNCTION = 8; - public static final int YVAL_MAPPING = 9; - - public static int tagForValKind(int valKind) { - switch (valKind) { - case 0: - return YVAL_UNKNOWN; // UNKNOWN_VALUE - case 1: - return YVAL_BOOL; // BOOLEAN_VALUE - case 2: - return YVAL_RATIONAL; // RATIONAL_VALUE - case 3: - return YVAL_FINITEFIELD; // FINITEFIELD_VALUE - case 4: - return YVAL_ALGEBRAIC; // ALGEBRAIC_VALUE - case 5: - return YVAL_BV; // BITVECTOR_VALUE - case 6: - return YVAL_TUPLE; // TUPPLE_VALUE - case 7: - return YVAL_SCALAR; // UNINTERPRETED_VALUE - case 8: - return YVAL_FUNCTION; // FUNCTION_VALUE - case 9: - return YVAL_MAPPING; // MAP_VALUE - case 10: - return YVAL_FUNCTION; // UPDATE_VALUE - default: - throw new IllegalArgumentException("Unknown valKind: " + valKind); - } - } - - /* - * Yices initialization and exit - */ - - /** Initializes Yices data structures. Needs to be called before doing anything else. */ - public static native void yices_init(); - - /** Call at the end to free memory allocated by Yices. */ - public static native void yices_exit(); - - /** - * Perform a full reset of Yices - * - *

This function deletes all the terms and types defined in Yices and resets the symbol tables. - * It also deletes all contexts, models, configuration descriptors, and other records allocated in - * Yices. - */ - public static native void yices_reset(); - - /** - * Frees the specified String. Several API functions build and return a character string that is - * allocated by Yices. To avoid memory leaks, this string must be freed when it is no longer used - * by calling this function. - * - * @param stringPtr The pointer to the String - */ - public static native void free_string(long stringPtr); - - /* - * Yices Version checking for test purposes - */ - - public static native int yices_get_version(); - - public static native int yices_get_major_version(); - - public static native int yices_get_patch_level(); - - /* - * Context/ Environment creation - */ - - public static native long yices_new_config(); - - public static native void yices_free_config(long cfg); - - /** - * Set option to specified value. - * - * @param cfg The configuration to set the option in. - * @param option The option to set. - * @param value The value that the option will be set to. - */ - public static native void yices_set_config(long cfg, String option, String value); - - /** - * Prepares a context configuration for the specified logic. - * - * @param cfg The configuration to be prepared - * @param logic Name of the logic to prepare for or "NULL" - * @return 0 if successful, -1 if an error occurred - */ - public static native int yices_default_config_for_logic(long cfg, String logic); - - public static native long yices_new_context(long cfg); - - public static native void yices_free_context(long ctx); - - public static native void yices_context_enable_option(long ctx, String option); - - public static native void yices_context_disable_option(long ctx, String option); - - /* - * Yices search params - */ - - public static native long yices_new_param_record(); - - public static native int yices_set_param(long record, String name, String value); - - public static native void yices_default_params_for_context(long ctx, long record); - - public static native void yices_free_param_record(long record); - - /* - * Yices type construction - */ - public static native int yices_bool_type(); - - public static native int yices_int_type(); - - public static native int yices_real_type(); - - /** - * Constructs a bitvector type. - * - * @param size is the number of bits. It must be positive and no more than YICES_MAX_BVSIZE - * @return bitvector type - */ - public static native int yices_bv_type(int size); - - /** - * Creates the function type (-> dom[0] … dom[n-1] range). - * - * @param n function arity (i.e., size of array dom) - * @param dom array of domain types - * @param range range type - * @return function type of n-arity - */ - public static native int yices_function_type(int n, int[] dom, int range); - - /* - * Yices type tests - */ - public static native boolean yices_type_is_bool(int t); - - public static native boolean yices_type_is_int(int t); - - public static native boolean yices_type_is_real(int t); - - /** - * Checks if type is arithmetic (i.e., either integer or real). - * - * @param t Type to check - * @return true if arithmetic, false otherwise - */ - public static native boolean yices_type_is_arithmetic(int t); - - public static native boolean yices_type_is_bitvector(int t); - - public static native boolean yices_type_is_function(int t); - - /** - * Tests if the first type is a subtype of the second. - * - * @param t1 The first type - * @param t2 The second type - * @return true if t1 is a subtype of t2, otherwise false - */ - public static native boolean yices_test_subtype(int t1, int t2); - - /** - * Tests if Type1 and Type2 are compatible. - * - * @param t1 The first type - * @param t2 The second type - * @return true if t1 and t2 are compatible, otherwise false - */ - public static native boolean yices_compatible_types(int t1, int t2); - - /** - * Size of bitvector. - * - * @param t Bitvector to get the size of - * @return Number of bits in bitvector or 0 if an error occurred - */ - public static native int yices_bvtype_size(int t); - - public static native int yices_type_num_children(int t); - - public static native int yices_type_child(int t, int index); - - public static native int[] yices_type_children(int t); - - /* - * TERM CONSTRUCTION - */ - - public static native int yices_new_uninterpreted_term(int type); - - public static native int yices_new_variable(int type); - - public static native int yices_constant(int type, int index); - - public static native int yices_ite(int t_if, int t_then, int t_else); - - public static native int yices_eq(int t_1, int t_2); - - public static native int yices_neq(int t_1, int t_2); - - public static native int yices_distinct(int size, int[] terms); - - public static native int yices_application(int t, int size, int[] terms); - - public static native int yices_update(int t1, int size, int[] terms, int t2); - - public static native int yices_forall(int size, int[] terms, int t); - - public static native int yices_exists(int size, int[] terms, int t); - - public static native int yices_lambda(int size, int[] terms, int t); - - /* - * Bool Terms - */ - - public static native int yices_true(); - - public static native int yices_false(); - - public static native int yices_not(int t); - - public static native int yices_and(int n, int[] arg); - - public static native int yices_and2(int t1, int t2); - - public static native int yices_and3(int t1, int t2, int t3); - - public static native int yices_or(int n, int[] arg); - - public static native int yices_or2(int t1, int t2); - - public static native int yices_or3(int t1, int t2, int t3); - - public static native int yices_xor(int n, int[] arg); - - public static native int yices_xor2(int t1, int t2); - - public static native int yices_xor3(int t1, int t2, int t3); - - public static native int yices_iff(int t1, int t2); - - public static native int yices_implies(int t1, int t2); - - /* - * Arithmetic Terms - */ - public static native int yices_zero(); - - public static native int yices_int32(int value); - - public static native int yices_int64(long val); - - public static native int yices_rational32(int num, int den); - - public static native int yices_rational64(long num, long den); - - public static native int yices_parse_rational(String val); - - public static native int yices_parse_float(String val); - - public static native int yices_add(int t1, int t2); - - public static native int yices_sub(int t1, int t2); - - public static native int yices_neg(int t); - - public static native int yices_mul(int t1, int t2); - - public static native int yices_square(int t); - - public static native int yices_power(int t, int power); - - public static native int yices_division(int t1, int t2); - - public static native int yices_sum(int size, int[] terms); - - public static native int yices_product(int size, int[] terms); - - public static native int yices_poly_int32(int size, int[] coeff, int[] terms); - - public static native int yices_poly_int64(int size, long[] coeff, int[] terms); - - public static native int yices_abs(int t); - - public static native int yices_floor(int t); - - public static native int yices_ceil(int t); - - public static native int yices_idiv(int t1, int t2); - - public static native int yices_imod(int t1, int t2); - - public static native int yices_arith_eq_atom(int t1, int t2); - - public static native int yices_arith_neq_atom(int t1, int t2); - - public static native int yices_arith_geq_atom(int t1, int t2); - - public static native int yices_arith_leq_atom(int t1, int t2); - - public static native int yices_arith_gt_atom(int t1, int t2); - - public static native int yices_arith_lt_atom(int t1, int t2); - - public static native int yices_arith_eq0_atom(int t); - - public static native int yices_arith_neq0_atom(int t); - - public static native int yices_arith_geq0_atom(int t); - - public static native int yices_arith_leq0_atom(int t); - - public static native int yices_arith_gt0_atom(int t); - - public static native int yices_arith_lt0_atom(int t); - - public static native int yices_divides_atom(int t1, int t2); - - public static native int yices_is_int_atom(int t); - - /* - * Bitvector Terms - */ - public static native int yices_bvconst_uint32(int size, int value); - - public static native int yices_bvcinst_uint64(int size, long value); - - public static native int yices_bvconst_int32(int size, int value); - - public static native int yices_bvconst_int64(int size, long value); - - public static native int yices_bvconst_zero(int size); - - public static native int yices_bvconst_one(int size); - - public static native int yices_bvconst_minus_one(int size); - - /** - * Parses the given Array in little endian order values[0] becomes the least significant bit. - * values[size-1] becomes the most significant bit. - */ - public static native int yices_bvconst_from_array(int size, int[] values); - - public static native int yices_parse_bvbin(String value); - - public static native int yices_parse_bvhex(String value); - - public static native int yices_bvadd(int t1, int t2); - - public static native int yices_bvsub(int t1, int t2); - - public static native int yices_bvneg(int t); - - public static native int yices_bvmul(int t1, int t2); - - public static native int yices_bvsquare(int t); - - public static native int yices_bvpower(int t, int power); - - public static native int yices_bvsum(int size, int[] terms); - - public static native int yices_bvproduct(int size, int[] terms); - - public static native int yices_bvdiv(int t1, int t2); - - public static native int yices_bvrem(int t1, int t2); - - public static native int yices_bvsdiv(int t1, int t2); - - public static native int yices_bvsrem(int t1, int t2); - - public static native int yices_bvsmod(int t1, int t2); - - public static native int yices_bvnot(int t); - - public static native int yices_bvand(int size, int[] terms); - - public static native int yices_bvand2(int t1, int t2); - - public static native int yices_bvand3(int t1, int t2, int t3); - - public static native int yices_bvor(int size, int[] terms); - - public static native int yices_bvor2(int t1, int t2); - - public static native int yices_bvor3(int t1, int t2, int t3); - - public static native int yices_bvxor(int size, int[] terms); - - public static native int yices_bvxor2(int t1, int t2); - - public static native int yices_bvxor3(int t1, int t2, int t3); - - public static native int yices_bvnand(int t1, int t2); - - public static native int yices_bvnor(int t1, int t2); - - public static native int yices_bvxnor(int t1, int t2); - - public static native int yices_shift_left0(int t, int shift); - - public static native int yices_shift_left1(int t, int shift); - - public static native int yices_shift_right0(int t, int shift); - - public static native int yices_shift_right1(int t, int shift); - - public static native int yices_ashift_right(int t, int shift); - - public static native int yices_rotate_left(int t, int shift); - - public static native int yices_rotate_right(int t, int shift); - - public static native int yices_bvshl(int t1, int t2); - - public static native int yices_bvlshr(int t1, int t2); - - public static native int yices_bvashr(int t1, int t2); - - public static native int yices_bvextract(int t, int limit1, int limit2); - - public static native int yices_bitextract(int t, int pos); - - public static native int yices_bvconcat(int size, int[] terms); - - public static native int yices_bvconcat2(int t1, int t2); - - public static native int yices_bvrepeat(int t, int times); - - public static native int yices_sign_extend(int t, int times); - - public static native int yices_zero_extend(int t, int times); - - public static native int yices_redand(int t); - - public static native int yices_redor(int t); - - public static native int yices_redcomp(int t1, int t2); - - public static native int yices_bvarray(int size, int[] terms); - - public static native int yices_bveq_atom(int t1, int t2); - - public static native int yices_bvneq_atom(int t1, int t2); - - public static native int yices_bvge_atom(int t1, int t2); - - public static native int yices_bvgt_atom(int t1, int t2); - - public static native int yices_bvle_atom(int t1, int t2); - - public static native int yices_bvlt_atom(int t1, int t2); - - public static native int yices_bvsge_atom(int t1, int t2); - - public static native int yices_bvsgt_atom(int t1, int t2); - - public static native int yices_bvsle_atom(int t1, int t2); - - public static native int yices_bvslt_atom(int t1, int t2); - - /* - * Term properties - */ - public static native int yices_type_of_term(int t); - - public static native boolean yices_term_is_bool(int t); - - public static native boolean yices_term_is_int(int t); - - public static native boolean yices_term_is_real(int t); - - public static native boolean yices_term_is_arithmetic(int t); - - public static native boolean yices_term_is_bitvector(int t); - - public static native boolean yices_term_is_function(int t); - - public static native int yices_term_bitsize(int t); - - public static native boolean yices_term_is_ground(int t); - - public static native boolean yices_term_is_atomic(int t); - - public static native boolean yices_term_is_composite(int t); - - public static native boolean yices_term_is_projection(int t); - - public static native boolean yices_term_is_sum(int t); - - public static native boolean yices_term_is_bvsum(int t); - - public static native boolean yices_term_is_product(int t); - - public static native int yices_term_constructor(int t); - - public static native int yices_term_num_children(int t); - - public static native int yices_term_child(int t, int index); - - public static native int yices_proj_index(int t); - - public static native int yices_proj_arg(int t); - - public static native boolean yices_bool_const_value(int t); - - // TODO Return bool[] instead of int[]? - /** Returns in little endian order. */ - public static native int[] yices_bv_const_value(int t, int bitsize); - - public static native String yices_rational_const_value(int t); - - /** - * Returns i-th sum component of term t as String-Array [coefficient, term]. If t is in a form - * like 3+x, for i = 0 the returned term will be -1/NULL_TERM. - */ - public static native String[] yices_sum_component(int t, int i); - - /** - * Returns the i-th component of a bvsum. Returned array has length bitsize+1. array[0] to - * array[array.length-2] contain the coefficient, array[array.length-1] the term. If the t is in a - * form like [101]+x, for i = 0, the returned term will be -1/NULL_TERM. - */ - public static native int[] yices_bvsum_component(int t, int i, int bitsize); - - // TODO can return up to UINT32_MAX ? - // Daniel: we cast the uint return of exp to signed int (jint), this is obviously wrong! - /** - * Returns an array of size 2 in the form [term,exp] for the term and exponent at index i and - * checks automatically for errors (original function return) and throws IllegalArgumentException - * for return value -1. Original API: int32_t yices_product_component(term_t t, int32_t i, term_t - * *term, uint32_t *exp) Component of a power product. A product t is of the form t0^d0 × … × - * tn^dn. This function stores the term ti into *term and the exponent di into *exp. The function - * returns -1 if t is not a product or if the index i is too large. It returns 0 otherwise. - */ - public static native int[] yices_product_component(int t, int i); - - /* - * SAT Checking - */ - public static native int yices_context_status(long ctx); - - public static native void yices_assert_formula(long ctx, int f); - - public static native void yices_assert_formulas(long ctx, int size, int[] formulas); - - /** - * @param params Set to 0 for default search parameters. - */ - public static native int yices_check_context(long ctx, long params); - - public static native void yices_stop_search(long ctx); - - public static native void yices_reset_context(long ctx); - - public static native int yices_assert_blocking_clause(long ctx); - - public static native void yices_push(long ctx); - - public static native void yices_pop(long ctx); - - /** - * @param params Set to 0 for default search parameters. - */ - public static native int yices_check_context_with_assumptions( - long ctx, long params, int size, int[] terms); - - public static native int[] yices_get_unsat_core(long ctx); - - /** - * @param params Set to 0 for default search parameters. - */ - public static boolean yices_check_sat(long ctx, long params, ShutdownNotifier shutdownNotifier) - throws IllegalStateException, InterruptedException, SolverException { - return satCheckWithShutdownNotifier( - () -> yices_check_context(ctx, params), ctx, shutdownNotifier); - } - - /** - * @param params Set to 0 for default search parameters. - */ - public static boolean yices_check_sat_with_assumptions( - long ctx, long params, int size, int[] assumptions, ShutdownNotifier shutdownNotifier) - throws InterruptedException, SolverException { - return satCheckWithShutdownNotifier( - () -> yices_check_context_with_assumptions(ctx, params, size, assumptions), - ctx, - shutdownNotifier); - } - - @SuppressWarnings("try") - private static boolean satCheckWithShutdownNotifier( - Supplier satCheck, long pCtx, ShutdownNotifier shutdownNotifier) - throws InterruptedException, SolverException { - int result; - try (ShutdownHook hook = new ShutdownHook(shutdownNotifier, () -> yices_stop_search(pCtx))) { - shutdownNotifier.shutdownIfNecessary(); - result = satCheck.get(); // the expensive computation - } - shutdownNotifier.shutdownIfNecessary(); - return check_result(result); - } - - private static boolean check_result(int result) throws InterruptedException, SolverException { - switch (result) { - case YICES_STATUS_SAT: - return true; - case YICES_STATUS_UNSAT: - return false; - case YICES_STATUS_INTERRUPTED: - throw new InterruptedException(); - case YICES_STATUS_ERROR: - throw new SolverException("SAT check returned \"unknown\""); - default: - throw new SolverException("Internal solver exception"); - } - } - - /* - * Model generation and exploration - */ - - public static native long yices_get_model(long ctx, int keepSubst); - - public static native long yices_model_from_map(int size, int[] var, int[] constant); - - /* - * renamed collect_defined_terms to def_terms as it caused an UnsatisfiedLinkError for some reason - */ - public static native int[] yices_def_terms(long model); // collect_defined_terms(long model); - - public static native void yices_free_model(long model); - - /** get the value of a term as pair [node_id, node_tag]. */ - public static native int[] yices_get_value(long m, int t); - - public static native int yices_val_bitsize(long m, int id, int tag); - - public static native int yices_val_function_arity(long m, int id, int tag); - - public static native boolean yices_val_get_bool(long m, int id, int tag); - - public static native String yices_val_get_mpq(long m, int id, int tag); - - /* - * node_id / node_tag separated to preserve C call order - * Returns in little endian order - */ - public static native int[] yices_val_get_bv(long m, int id, int size, int tag); - - /** - * Returns array of yval_t values built like this: [yval_t.node_id, yval_t.node_tag, - * yval_t.node_id, yval_t.node_tag, ...]. The first pair of values represent the default value, - * the following values should represent mappings, which can be expanded using expand_mapping(). - */ - public static native int[] yices_val_expand_function(long m, int id, int tag); - - /** - * Returns array of yval_t values built like this: [yval_t.node_id, yval_t.node_tag, - * yval_t.node_id, yval_t.node_tag, ...]. The last pair of values represent the function's value, - * the other pairs are values for the function's arguments. node_id / node_tag separated to - * preserve C call order - */ - public static native int[] yices_val_expand_mapping(long m, int id, int arity, int tag); - - /** get the value of a term as (constant) term. */ - public static native int yices_get_value_as_term(long m, int t); - - public static native void yices_set_term_name(int t, String name); - - public static native String yices_get_term_name(int t); - - public static native int yices_get_term_by_name(String name); - - /** - * Use to print a term in a readable format. Result will be truncated if height/width of the - * String are too small. - * - * @param t The term to print - * @param width The width of the resulting String - * @param height The height/lines of resulting String - */ - private static native String yices_term_to_string(int t, int width, int height, int offset); - - private static native String yices_type_to_string(int t, int width, int height, int offset); - - private static native String yices_model_to_string(long m, int width, int height, int offset); - - public static String yices_term_to_string(int t) { - return yices_term_to_string(t, Integer.MAX_VALUE, 1, 0); - } - - public static String yices_type_to_string(int t) { - return yices_type_to_string(t, Integer.MAX_VALUE, 1, 0); - } - - public static String yices_model_to_string(long m) { - return yices_model_to_string(m, Integer.MAX_VALUE, 1, 0); - } - - /** - * Parse a single expression/term in SMTLIB2-based Yices input language. - * - *

Declarations of symbols not are allowed. All symbols must already be known. - */ - public static native int yices_parse_term(String t); - - public static native int yices_subst_term(int size, int[] from, int[] to, int t); - - /** - * @return int 1 if the Yices2-lib is compiled thread-safe and 0 otherwise - */ - public static native int yices_is_thread_safe(); - - /** - * @return int 1 if the Yices2-lib is compiled with MCSAT support and 0 otherwise - */ - public static native int yices_has_mcsat(); - - /** The function first checks whether f is satisifiable or unsatisfiable. */ - public static native int yices_check_formula(int term, String logic, long model, String delegate); - - /** - * This is similar to yices_check_formula except that it checks whether the conjunction of f[0] - * ... f[n-1] is satisfiable. - */ - public static native int yices_check_formulas( - int[] terms, int n, String logic, long model, String delegate); - - /** - * @return int 1 if delegate(SAT-Solver) available for use, 0 otherwise - */ - public static native int yices_has_delegate(String delegate); - - /** - * @return type of a function node - */ - public static native int yices_val_function_type(long model, int id, int tag); - - /** - * @return term_vector (NOT int with error code) that is supported. Empty if error! - */ - public static native int[] yices_model_term_support(long model, int term); - - /** - * Calculate an interpolant. - * - *

Requires MCSAT, and expects the contexts to be unsatisfiable - */ - public static native int yices_interpolate(long ctxA, long ctxB); -} diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java index 9a2a7a2078..aef18ef04f 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java @@ -8,282 +8,192 @@ package org.sosy_lab.java_smt.solvers.yices2; -import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_APP_TERM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_ARITH_CONST; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_ARITH_SUM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_BV_CONST; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_BV_SUM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_EQ_TERM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_FORALL_TERM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_NOT_TERM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_OR_TERM; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_POWER_PRODUCT; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_add; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_and; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_and2; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_application; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_arith_eq_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_arith_gt_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_assert_formula; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bool_const_value; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bool_type; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bv_const_value; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bv_type; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvadd; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvand2; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvconst_int64; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvconst_minus_one; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvconst_one; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bveq_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvmul; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvpower; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvsum_component; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_bvxor2; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_check_context; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_eq; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_exists; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_exit; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_false; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_forall; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_free_config; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_free_context; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_function_type; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_major_version; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_patch_level; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_term_by_name; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_term_name; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_version; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_has_mcsat; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_idiv; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_iff; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_init; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_int32; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_int64; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_int_type; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_interpolate; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_is_thread_safe; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_mul; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_new_config; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_new_context; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_new_uninterpreted_term; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_new_variable; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_not; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_or; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_or2; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_parse_bvbin; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_parse_rational; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_parse_term; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_product_component; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_proj_arg; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_rational32; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_redand; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_set_config; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_set_term_name; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_sign_extend; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_sub; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_sum; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_sum_component; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_term_bitsize; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_term_child; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_term_constructor; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_term_is_bool; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_term_num_children; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_term_to_string; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_true; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_of_term; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_type_to_string; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_zero_extend; - -import com.google.common.base.Joiner; -import com.google.common.collect.Lists; -import com.google.common.primitives.Ints; + +import com.sri.yices.Config; +import com.sri.yices.Constructor; +import com.sri.yices.Context; +import com.sri.yices.InterpolationContext; +import com.sri.yices.Parameters; +import com.sri.yices.Status; +import com.sri.yices.Terms; +import com.sri.yices.Types; +import com.sri.yices.Yices; +import com.sri.yices.YicesException; import java.math.BigInteger; -import java.util.Arrays; import org.junit.After; -import org.junit.AssumptionViolatedException; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.sosy_lab.common.NativeLibraries; import org.sosy_lab.common.rationals.Rational; -@SuppressWarnings("unused") public class Yices2NativeApiTest { - private static final int SAT = 3; - private static final int UNSAT = 4; @BeforeClass public static void loadYices() { - try { - NativeLibraries.loadLibrary("yices2j"); - } catch (UnsatisfiedLinkError e) { - throw new AssumptionViolatedException("Yices2 is not available", e); - } + NativeLibraries.loadLibrary("yices2java"); + Yices.isReady(); } - private long env; + private Context env; - private long newContext(boolean mcsat) { - var cfg = yices_new_config(); - yices_set_config(cfg, "solver-type", mcsat ? "mcsat" : "dpllt"); - yices_set_config(cfg, "mode", "interactive"); - yices_set_config(cfg, "model-interpolation", "true"); - var context = yices_new_context(cfg); - yices_free_config(cfg); - return context; + private Context newContext(boolean mcsat) { + try (var cfg = new Config()) { + cfg.set("solver-type", mcsat ? "mcsat" : "dpllt"); + cfg.set("mode", "interactive"); + cfg.set("model-interpolation", "true"); + return new Context(cfg); + } } @Before public void createEnvironment() { - yices_init(); env = newContext(false); } @After public void freeEnvironment() { - yices_free_context(env); - yices_exit(); + env.close(); } @Test public void simpleUNSAT() { - int termTrue = yices_true(); - int termFalse = yices_false(); - int formula = yices_and2(termTrue, termFalse); - yices_assert_formula(env, formula); - assertThat(yices_check_context(env, 0)).isEqualTo(UNSAT); + int termTrue = Terms.mkTrue(); + int termFalse = Terms.mkFalse(); + int formula = Terms.and(termTrue, termFalse); + env.assertFormula(formula); + assertThat(env.check()).isEqualTo(Status.UNSAT); } @Test public void simpleSAT() { - int termTrue = yices_true(); - int formula = yices_and2(termTrue, termTrue); - yices_assert_formula(env, formula); - assertThat(yices_check_context(env, 0)).isEqualTo(SAT); + int termTrue = Terms.mkTrue(); + int formula = Terms.and(termTrue, termTrue); + env.assertFormula(formula); + assertThat(env.check()).isEqualTo(Status.SAT); } - /* - * 3=SAT 4=UNSAT - */ + // 3=SAT 4=UNSAT @Test public void arrayArgSAT() { - int n = 4; - int termTrue = yices_true(); + int termTrue = Terms.mkTrue(); int[] terms = {termTrue, termTrue, termTrue, termTrue}; - int formula = yices_and(n, terms); - yices_assert_formula(env, formula); - assertThat(yices_check_context(env, 0)).isEqualTo(SAT); + int formula = Terms.and(terms); + env.assertFormula(formula); + assertThat(env.check()).isEqualTo(Status.SAT); } @Test public void arrayArgUNSAT() { - int n = 4; - int termTrue = yices_true(); - int termFalse = yices_false(); + int termTrue = Terms.mkTrue(); + int termFalse = Terms.mkFalse(); int[] terms = {termFalse, termTrue, termTrue, termTrue}; - int formula = yices_and(n, terms); - yices_assert_formula(env, formula); - assertThat(yices_check_context(env, 0)).isEqualTo(UNSAT); + int formula = Terms.and(terms); + env.assertFormula(formula); + assertThat(env.check()).isEqualTo(Status.UNSAT); } @Test public void arithAddSAT() { - int one = yices_int32(1); - int two = yices_int32(2); - int three = yices_int32(3); - int add = yices_add(one, two); - int equal = yices_eq(three, add); - yices_assert_formula(env, equal); - assertThat(yices_check_context(env, 0)).isEqualTo(SAT); + int one = Terms.intConst(1); + int two = Terms.intConst(2); + int three = Terms.intConst(3); + int add = Terms.add(one, two); + int equal = Terms.eq(three, add); + env.assertFormula(equal); + assertThat(env.check()).isEqualTo(Status.SAT); } @Test public void arithAddUNSAT() { - int one = yices_int32(1); - int two = yices_int32(99); - int three = yices_int32(3); - int add = yices_add(one, two); - int equal = yices_eq(three, add); - yices_assert_formula(env, equal); - assertThat(yices_check_context(env, 0)).isEqualTo(UNSAT); + int one = Terms.intConst(1); + int two = Terms.intConst(99); + int three = Terms.intConst(3); + int add = Terms.add(one, two); + int equal = Terms.eq(three, add); + env.assertFormula(equal); + assertThat(env.check()).isEqualTo(Status.UNSAT); } @SuppressWarnings("CheckReturnValue") @Test public void rationalError() { - assertThrows(IllegalArgumentException.class, () -> yices_rational32(1, 0)); + assertThrows(YicesException.class, () -> Terms.rationalConst(1, 0)); } @Test public void negativeRationalError() { // TODO negative unsigned integer causes no error. Need to ensure positive value before - assertThat(yices_rational32(1, -5)).isGreaterThan(0); + assertThat(Terms.rationalConst(1, -5)).isGreaterThan(0); } @SuppressWarnings("CheckReturnValue") @Test public void wrongType() { - int one = yices_int32(1); - assertThrows(IllegalArgumentException.class, () -> yices_term_bitsize(one)); + int one = Terms.intConst(1); + assertThrows(YicesException.class, () -> Terms.bitSize(one)); } @Test public void testRange() { + /* int intmax = yices_int32(Integer.MAX_VALUE); int longmax = yices_int64(Long.MAX_VALUE); int gt = yices_arith_gt_atom(longmax, intmax); - yices_assert_formula(env, gt); - assertThat(yices_check_context(env, 0)).isEqualTo(SAT); + env.assertFormula(gt); + assertThat(env.check()).isEqualTo(SAT); + + */ + throw new AssertionError("yices_int32 not supported"); } @Test public void simpleBitvectorSAT() { - int v1 = yices_parse_bvbin("01010"); - int v2 = yices_parse_bvbin("10101"); - int v3 = yices_bvconst_one(1); - int f1 = yices_bvxor2(v1, v2); - int f2 = yices_redand(f1); - int f3 = yices_bveq_atom(f2, v3); - yices_assert_formula(env, f3); - assertThat(yices_check_context(env, 0)).isEqualTo(SAT); + int v1 = Terms.parseBvBin("01010"); + int v2 = Terms.parseBvBin("10101"); + int v3 = Terms.bvOne(1); + int f1 = Terms.bvXor(v1, v2); + int f2 = Terms.bvRedAnd(f1); + int f3 = Terms.bvEq(f2, v3); + env.assertFormula(f3); + assertThat(env.check()).isEqualTo(Status.SAT); } @Test public void simpleBitvectorUNSAT() { - int v1 = yices_parse_bvbin("01010"); - int v2 = yices_parse_bvbin("10101"); - int v3 = yices_bvconst_one(1); - int f1 = yices_bvand2(v1, v2); - int f2 = yices_redand(f1); - int f3 = yices_bveq_atom(f2, v3); - yices_assert_formula(env, f3); - assertThat(yices_check_context(env, 0)).isEqualTo(UNSAT); + int v1 = Terms.parseBvBin("01010"); + int v2 = Terms.parseBvBin("10101"); + int v3 = Terms.bvOne(1); + int f1 = Terms.bvAnd(v1, v2); + int f2 = Terms.bvRedAnd(f1); + int f3 = Terms.bvEq(f2, v3); + env.assertFormula(f3); + assertThat(env.check()).isEqualTo(Status.UNSAT); } @Test public void boolValueQuery() { - int v1 = yices_true(); - int v2 = yices_false(); - assertThat(yices_bool_const_value(v1)).isTrue(); - assertThat(yices_bool_const_value(v2)).isFalse(); + int v1 = Terms.mkTrue(); + int v2 = Terms.mkFalse(); + assertThat(Terms.boolConstValue(v1)).isTrue(); + assertThat(Terms.boolConstValue(v2)).isFalse(); } @Test public void boolValueTypeMismatch() { - int v1 = yices_int32(45); - assertThrows(IllegalArgumentException.class, () -> yices_bool_const_value(v1)); + int v1 = Terms.intConst(45); + assertThrows(YicesException.class, () -> Terms.boolConstValue(v1)); } @Test public void bitvectorReturn() { - int bv1 = yices_parse_bvbin("111000"); - int[] bvComp = {0, 0, 0, 1, 1, 1}; - int bvsize = yices_term_bitsize(bv1); + int bv1 = Terms.parseBvBin("111000"); + boolean[] bvComp = {false, false, false, true, true, true}; + int bvsize = Terms.bitSize(bv1); assertThat(bvsize).isEqualTo(6); - int[] bvReturn = yices_bv_const_value(bv1, bvsize); + boolean[] bvReturn = Terms.bvConstValue(bv1); assertThat(bvComp).isEqualTo(bvReturn); } @@ -294,11 +204,11 @@ public void rationalValueTest() { int negativeNum = -50; int negativeDen = -30000; BigInteger largeNumber = BigInteger.valueOf(2).pow(10000); - int ratConst = yices_rational32(num, den); - int negativeNumConst = yices_parse_rational(negativeNum + "/" + den); - int negativeDenConst = yices_parse_rational(num + "/" + negativeDen); - int negativeNumDenConst = yices_parse_rational(negativeNum + "/" + negativeDen); - int bigConst = yices_parse_rational(largeNumber.toString()); + int ratConst = Terms.rationalConst(num, den); + int negativeNumConst = Terms.parseRational(negativeNum + "/" + den); + int negativeDenConst = Terms.parseRational(num + "/" + negativeDen); + int negativeNumDenConst = Terms.parseRational(negativeNum + "/" + negativeDen); + int bigConst = Terms.parseRational(largeNumber.toString()); Yices2FormulaCreator creator = new Yices2FormulaCreator(); assertThat(creator.convertValue(ratConst, ratConst)).isEqualTo(Rational.of(num + "/" + den)); assertThat(creator.convertValue(bigConst, bigConst)).isEqualTo(largeNumber); @@ -312,146 +222,148 @@ public void rationalValueTest() { @Test public void bvValueTest() { - int value = 14; - int bv = yices_bvconst_int64(4, value); - if (yices_term_constructor(bv) == YICES_BV_CONST) { - int[] littleEndianBV = yices_bv_const_value(bv, yices_term_bitsize(bv)); - checkArgument(littleEndianBV.length != 0, "BV was empty"); - String bigEndianBV = Joiner.on("").join(Lists.reverse(Ints.asList(littleEndianBV))); - BigInteger big = new BigInteger(bigEndianBV, 2); + long value = 14; + int bv = Terms.bvConst(4, value); + if (Terms.constructor(bv) == Constructor.BV_CONSTANT) { + boolean[] bits = Terms.bvConstValue(bv); + var big = BigInteger.ZERO; + for (var p = 0; p < bits.length; p++) { + if (bits[p]) { + big = big.setBit(p); + } + } assertThat(big).isEqualTo(BigInteger.valueOf(value)); } } @Test public void termNaming() { - int t = yices_parse_bvbin("0100100001100101011011000110110001101111"); + int t = Terms.parseBvBin("0100100001100101011011000110110001101111"); String termName = "Hello"; - yices_set_term_name(t, termName); - assertThat(yices_get_term_name(t)).isEqualTo(termName); + Terms.setName(t, termName); + assertThat(Terms.getName(t)).isEqualTo(termName); } @Test public void satWithVariable() { - int termFalse = yices_false(); - int var = yices_new_uninterpreted_term(yices_bool_type()); - int formula = yices_or2(termFalse, var); - yices_assert_formula(env, formula); - assertThat(yices_check_context(env, 0)).isEqualTo(SAT); + int termFalse = Terms.mkFalse(); + int var = Terms.newUninterpretedTerm(Types.boolType()); + int formula = Terms.or(termFalse, var); + env.assertFormula(formula); + assertThat(env.check()).isEqualTo(Status.SAT); } // Yices converts add(YICES_ARITH_CONST, YICES_ARITH_CONST) to an YICES_ARITH_CONST // Yices converts add(YICES_ARITH_CONST, YICES_UNINTERPRETED_TERM) to YICES_ARITH_SUM @Test public void termConstructorAdd() { - int one = yices_int32(1); - int two = yices_new_uninterpreted_term(yices_int_type()); // yices_int32(2); - int addition = yices_add(one, two); - assertThat(yices_term_constructor(addition)).isEqualTo(YICES_ARITH_SUM); + int one = Terms.intConst(1); + int two = Terms.newUninterpretedTerm(Types.intType()); // Terms.intConst(2); + int addition = Terms.add(one, two); + assertThat(Terms.constructor(addition)).isEqualTo(Constructor.ARITH_SUM); } @Test public void termConstructorAnd() { // and 1 2 is replaced with not (or (not 1) (not 2)) - int termTrue = yices_new_uninterpreted_term(yices_bool_type()); // yices_true(); - yices_set_term_name(termTrue, "termTrue"); - int termTwo = yices_new_uninterpreted_term(yices_bool_type()); - yices_set_term_name(termTwo, "termTwo"); - int and = yices_and2(termTrue, termTwo); + int termTrue = Terms.newUninterpretedTerm(Types.boolType()); // Terms.mkTrue(); + Terms.setName(termTrue, "termTrue"); + int termTwo = Terms.newUninterpretedTerm(Types.boolType()); + Terms.setName(termTwo, "termTwo"); + int and = Terms.and(termTrue, termTwo); - int child = yices_term_child(and, 0); - assertThat(yices_term_constructor(child)).isEqualTo(YICES_OR_TERM); - assertThat(yices_term_num_children(child)).isEqualTo(2); - assertThat(yices_term_to_string(and)).isEqualTo("(and termTrue termTwo)"); - assertThat(yices_term_constructor(and)).isEqualTo(YICES_NOT_TERM); + int child = Terms.child(and, 0); + assertThat(Terms.constructor(child)).isEqualTo(Constructor.OR_TERM); + assertThat(Terms.numChildren(child)).isEqualTo(2); + assertThat(Terms.toString(and)).isEqualTo("(and termTrue termTwo)"); + assertThat(Terms.constructor(and)).isEqualTo(Constructor.NOT_TERM); } @Test public void termConstructorOr() { - int termFalse = yices_new_uninterpreted_term(yices_bool_type()); // yices_false(); - // yices_set_term_name(termFalse, "1"); - int two = yices_new_uninterpreted_term(yices_bool_type()); - // yices_set_term_name(two, "5"); + int termFalse = Terms.newUninterpretedTerm(Types.boolType()); // Terms.mkFalse(); + // Terms.setName(termFalse, "1"); + int two = Terms.newUninterpretedTerm(Types.boolType()); + // Terms.setName(two, "5"); int[] orArray = {termFalse, two, termFalse, termFalse}; - int or = yices_or(4, orArray); - assertThat(yices_term_is_bool(or)).isTrue(); - assertThat(yices_term_constructor(or)).isEqualTo(YICES_OR_TERM); + int or = Terms.or(orArray); + assertThat(Terms.isBool(or)).isTrue(); + assertThat(Terms.constructor(or)).isEqualTo(Constructor.OR_TERM); // Works after changing something? } // Expecting YICES_OR_TERM as constructor but getting YICES_UNINTERPRETED_TERM @Test public void termConstructorNot() { - int termTrue = yices_new_uninterpreted_term(yices_bool_type()); // yices_true(); - yices_set_term_name(termTrue, "termTrue"); - int termTwo = yices_new_uninterpreted_term(yices_bool_type()); - yices_set_term_name(termTwo, "termTwo"); - int not = yices_not(termTrue); - assertThat(yices_term_constructor(not)).isEqualTo(YICES_NOT_TERM); + int termTrue = Terms.newUninterpretedTerm(Types.boolType()); // Terms.mkTrue(); + Terms.setName(termTrue, "termTrue"); + int termTwo = Terms.newUninterpretedTerm(Types.boolType()); + Terms.setName(termTwo, "termTwo"); + int not = Terms.not(termTrue); + assertThat(Terms.constructor(not)).isEqualTo(Constructor.NOT_TERM); } @Test public void modularCongruence() { - int pNumber1 = yices_int32(9); - int pNumber2 = yices_int32(5); - int mod = yices_int32(4); - int subTerm = yices_sub(pNumber1, pNumber2); - int div = yices_idiv(subTerm, mod); - int mul = yices_mul(mod, div); - int eq = yices_arith_eq_atom(subTerm, mul); - assertThat(eq).isEqualTo(yices_true()); + int pNumber1 = Terms.intConst(9); + int pNumber2 = Terms.intConst(5); + int mod = Terms.intConst(4); + int subTerm = Terms.sub(pNumber1, pNumber2); + int div = Terms.idiv(subTerm, mod); + int mul = Terms.mul(mod, div); + int eq = Terms.arithEq(subTerm, mul); + assertThat(eq).isEqualTo(Terms.mkTrue()); } @Test public void orSimplification() { - int termTrue = yices_true(); - int boolType = yices_bool_type(); + int termTrue = Terms.mkTrue(); + int boolType = Types.boolType(); int[] orArray = new int[20]; for (int i = 0; i < (orArray.length - 1); i++) { - orArray[i] = yices_named_variable(boolType, "x" + i); + orArray[i] = Terms.newUninterpretedTerm("x" + i, boolType); } orArray[(orArray.length - 1)] = termTrue; - int or = yices_or(orArray.length, orArray); - assertThat(or).isEqualTo(yices_true()); + int or = Terms.or(orArray); + assertThat(or).isEqualTo(Terms.mkTrue()); } @Test public void andSimplification() { - int termFalse = yices_false(); - int boolType = yices_bool_type(); + int termFalse = Terms.mkFalse(); + int boolType = Types.boolType(); int[] andArray = new int[20]; for (int i = 0; i < (andArray.length - 1); i++) { - andArray[i] = yices_named_variable(boolType, "x" + i); + andArray[i] = Terms.newUninterpretedTerm("x" + i, boolType); } andArray[(andArray.length - 1)] = termFalse; - int and = yices_and(andArray.length, andArray); - assertThat(and).isEqualTo(yices_false()); + int and = Terms.and(andArray); + assertThat(and).isEqualTo(Terms.mkFalse()); } @Test public void iffConstructor() { - int one = yices_new_uninterpreted_term(yices_bool_type()); - int two = yices_new_uninterpreted_term(yices_bool_type()); - int iff = yices_iff(one, two); - assertThat(yices_term_constructor(iff)).isEqualTo(YICES_EQ_TERM); + int one = Terms.newUninterpretedTerm(Types.boolType()); + int two = Terms.newUninterpretedTerm(Types.boolType()); + int iff = Terms.iff(one, two); + assertThat(Terms.constructor(iff)).isEqualTo(Constructor.EQ_TERM); } @Test public void ufConstructor() { - int funType = yices_function_type(1, new int[] {yices_int_type()}, yices_bool_type()); - int uf = yices_named_variable(funType, "uf"); - int[] argArray = new int[] {yices_int32(123)}; - int app = yices_application(uf, argArray.length, argArray); - assertThat(yices_term_constructor(app)).isEqualTo(YICES_APP_TERM); + int funType = Types.functionType(new int[] {Types.intType()}, Types.boolType()); + int uf = Terms.newUninterpretedTerm("uf", funType); + int[] argArray = new int[] {Terms.intConst(123)}; + int app = Terms.funApplication(uf, argArray); + assertThat(Terms.constructor(app)).isEqualTo(Constructor.APP_TERM); } @Test public void uf2Constructor() { - int funType = - yices_function_type(2, new int[] {yices_int_type(), yices_int_type()}, yices_int_type()); - int uf = yices_named_variable(funType, "uf"); - int[] argArray = new int[] {yices_int32(123), yices_int32(456)}; - int app = yices_application(uf, argArray.length, argArray); - assertThat(yices_term_constructor(app)).isEqualTo(YICES_APP_TERM); + int funType = Types.functionType(Types.intType(), Types.intType(), Types.intType()); + int uf = Terms.newUninterpretedTerm("uf", funType); + int[] argArray = new int[] {Terms.intConst(123), Terms.intConst(456)}; + int app = Terms.funApplication(uf, argArray); + assertThat(Terms.constructor(app)).isEqualTo(Constructor.APP_TERM); } @Test @@ -461,70 +373,74 @@ public void parseTerm() { // int xsmallery = yices_parse_term("assert (< x y)"); // int xbigger4 = yices_parse_term("assert (> x 4)"); // int ysmaller7 = yices_parse_term("assert (< y 7)"); - // assertThat(yices_check_context(env, 0), SAT); - int y = yices_int32(5); - yices_set_term_name(y, "y"); - int x = yices_parse_term("(/= y 5)"); - assertThat(yices_term_to_string(x)).isEqualTo("false"); + // assertThat(env.check(), SAT); + int y = Terms.intConst(5); + Terms.setName(y, "y"); + int x = Terms.parse("(/= y 5)"); + assertThat(Terms.toString(x)).isEqualTo("false"); } @Test public void arithSimplification() { - int x = yices_int32(6); - int y = yices_int32(7); - int add = yices_add(x, y); - int mul = yices_mul(x, y); + int x = Terms.intConst(6); + int y = Terms.intConst(7); + int add = Terms.add(x, y); + int mul = Terms.mul(x, y); Yices2FormulaCreator creator = new Yices2FormulaCreator(); assertThat(creator.convertValue(add, add)).isEqualTo(BigInteger.valueOf(13)); - assertThat(yices_term_constructor(add)).isEqualTo(YICES_ARITH_CONST); + assertThat(Terms.constructor(add)).isEqualTo(Constructor.ARITH_CONSTANT); assertThat(creator.convertValue(mul, mul)).isEqualTo(BigInteger.valueOf(42)); - assertThat(yices_term_constructor(mul)).isEqualTo(YICES_ARITH_CONST); + assertThat(Terms.constructor(mul)).isEqualTo(Constructor.ARITH_CONSTANT); } @Test public void sumComponents() { - int three = yices_int32(3); - int rat = yices_parse_rational("3/2"); - int x = yices_named_variable(yices_int_type(), "x"); + /* + int three = Terms.intConst(3); + int rat = Terms.parseRational("3/2"); + int x = Terms.newUninterpretedTerm(Types.intType(), "x"); int[] oneX = {three, x}; int sumOneX = yices_sum(2, oneX); - for (int i = 0; i < yices_term_num_children(sumOneX); i++) { - assertThat(yices_term_to_string(sumOneX)).isNotNull(); + for (int i = 0; i < Terms.numChildren(sumOneX); i++) { + assertThat(Terms.toString(sumOneX)).isNotNull(); assertThat(Arrays.toString(yices_sum_component(sumOneX, i))).isNotNull(); } int[] twoX = {three, x, x}; int sumTwoX = yices_sum(3, twoX); - for (int i = 0; i < yices_term_num_children(sumTwoX); i++) { - assertThat(yices_term_to_string(sumTwoX)).isNotNull(); + for (int i = 0; i < Terms.numChildren(sumTwoX); i++) { + assertThat(Terms.toString(sumTwoX)).isNotNull(); assertThat(Arrays.toString(yices_sum_component(sumTwoX, i))).isNotNull(); } int[] twoThrees = {three, x, three}; int sumTwoThrees = yices_sum(3, twoThrees); - for (int i = 0; i < yices_term_num_children(sumTwoThrees); i++) { - assertThat(yices_term_to_string(sumTwoThrees)).isNotNull(); + for (int i = 0; i < Terms.numChildren(sumTwoThrees); i++) { + assertThat(Terms.toString(sumTwoThrees)).isNotNull(); assertThat(Arrays.toString(yices_sum_component(sumTwoThrees, i))).isNotNull(); } - int xTimesRational = yices_mul(rat, x); + int xTimesRational = Terms.bvMul(rat, x); int[] ratSum = {three, xTimesRational}; int sumRatX = yices_sum(2, ratSum); - for (int i = 0; i < yices_term_num_children(sumRatX); i++) { - assertThat(yices_term_to_string(sumRatX)).isNotNull(); + for (int i = 0; i < Terms.numChildren(sumRatX); i++) { + assertThat(Terms.toString(sumRatX)).isNotNull(); assertThat(Arrays.toString(yices_sum_component(sumRatX, i))).isNotNull(); } + */ + throw new AssertionError("sums not supported"); } @Test public void bvSumComponents() { + /* String bv1StringValue = "00101"; - int bv1 = yices_parse_bvbin(bv1StringValue); - int bv5type = yices_bv_type(5); - int x = yices_named_variable(bv5type, "x"); - int negativeX = yices_bvmul(yices_bvconst_minus_one(5), x); - int add = yices_bvadd(bv1, negativeX); - assertThat(yices_term_num_children(add)).isEqualTo(2); - assertThat(yices_term_to_string(add)).isNotNull(); - - int[] component1 = yices_bvsum_component(add, 0, yices_term_bitsize(add)); + int bv1 = Terms.parseBvBin(bv1StringValue); + int bv5type = Types.bvType(5); + int x = Terms.newUninterpretedTerm(bv5type, "x"); + int negativeX = Terms.bvMul(Terms.bvMinusOne(5), x); + int add = Terms.bvAdd(bv1, negativeX); + assertThat(Terms.numChildren(add)).isEqualTo(2); + assertThat(Terms.toString(add)).isNotNull(); + + int[] component1 = yices_bvsum_component(add, 0, Terms.bitSize(add)); String value1 = Joiner.on("") .join( @@ -538,7 +454,7 @@ public void bvSumComponents() { // Term id is NULL (-1) for i = 0 assertThat(term1).isEqualTo(-1); - int[] component2 = yices_bvsum_component(add, 1, yices_term_bitsize(add)); + int[] component2 = yices_bvsum_component(add, 1, Terms.bitSize(add)); String value2 = Joiner.on("") .join( @@ -551,143 +467,126 @@ public void bvSumComponents() { assertThat(new BigInteger(value2, 2)).isEqualTo(BigInteger.valueOf(31)); // Term id is NULL (-1) for i = 0 assertThat(term2).isEqualTo(x); + */ + throw new AssertionError("sums not supported"); } @SuppressWarnings("CheckReturnValue") - @Test(expected = IllegalArgumentException.class) + @Test public void bvExtensionStructureTest() { int initialSize = 5; int extendBy = 5; - int x = yices_named_variable(yices_bv_type(initialSize), "x"); - int signExtendedX = yices_sign_extend(x, extendBy); - int zeroExtendedX = yices_zero_extend(x, extendBy); - - assertThat(yices_term_to_string(x)).isNotNull(); - assertThat(yices_term_num_children(x)).isEqualTo(0); - assertThat(yices_term_num_children(signExtendedX)).isEqualTo(initialSize + extendBy); - assertThat(yices_term_to_string(signExtendedX)).isNotNull(); - assertThat(yices_term_num_children(zeroExtendedX)).isEqualTo(initialSize + extendBy); - assertThat(yices_term_to_string(zeroExtendedX)).isNotNull(); - - int bvSignExt = yices_proj_arg(yices_term_child(signExtendedX, 0)); - int bvSizeSignExt = yices_term_bitsize(bvSignExt); - int extendedBySignExt = yices_term_num_children(signExtendedX) - bvSizeSignExt; + int x = Terms.newUninterpretedTerm("x", Types.bvType(initialSize)); + int signExtendedX = Terms.bvSignExtend(x, extendBy); + int zeroExtendedX = Terms.bvZeroExtend(x, extendBy); + + assertThat(Terms.toString(x)).isNotNull(); + assertThat(Terms.numChildren(x)).isEqualTo(0); + assertThat(Terms.numChildren(signExtendedX)).isEqualTo(initialSize + extendBy); + assertThat(Terms.toString(signExtendedX)).isNotNull(); + assertThat(Terms.numChildren(zeroExtendedX)).isEqualTo(initialSize + extendBy); + assertThat(Terms.toString(zeroExtendedX)).isNotNull(); + + int bvSignExt = Terms.projArg(Terms.child(signExtendedX, 0)); + int bvSizeSignExt = Terms.bitSize(bvSignExt); + int extendedBySignExt = Terms.numChildren(signExtendedX) - bvSizeSignExt; assertThat(extendedBySignExt).isEqualTo(extendBy); - int bvZeroExt = yices_proj_arg(yices_term_child(zeroExtendedX, 0)); - int bvSizeZeroExt = yices_term_bitsize(bvZeroExt); - int extendedByZeroExt = yices_term_num_children(zeroExtendedX) - bvSizeZeroExt; + int bvZeroExt = Terms.projArg(Terms.child(zeroExtendedX, 0)); + int bvSizeZeroExt = Terms.bitSize(bvZeroExt); + int extendedByZeroExt = Terms.numChildren(zeroExtendedX) - bvSizeZeroExt; assertThat(extendedByZeroExt).isEqualTo(extendBy); - assertThat(yices_term_child(zeroExtendedX, bvSizeZeroExt)).isEqualTo(yices_false()); - assertThat(yices_term_child(signExtendedX, bvSizeSignExt)).isNotEqualTo(yices_false()); + assertThat(Terms.child(zeroExtendedX, bvSizeZeroExt)).isEqualTo(Terms.mkFalse()); + assertThat(Terms.child(signExtendedX, bvSizeSignExt)).isNotEqualTo(Terms.mkFalse()); - yices_proj_arg(yices_term_child(x, 0)); // throws + assertThrows(YicesException.class, () -> Terms.projArg(Terms.child(x, 0))); } @Test public void booleanParse() { - int test = yices_parse_term("false"); - assertThat(yices_false()).isEqualTo(test); - int test2 = yices_parse_term("true"); - assertThat(yices_true()).isEqualTo(test2); + int test = Terms.parse("false"); + assertThat(Terms.mkFalse()).isEqualTo(test); + int test2 = Terms.parse("true"); + assertThat(Terms.mkTrue()).isEqualTo(test2); } @Test public void bvSum() { - int type = yices_bv_type(5); - int bv1 = yices_named_variable(type, "x"); - int bv2 = yices_named_variable(type, "y"); - int add = yices_bvadd(bv1, bv2); - int constructor = yices_term_constructor(add); - assertThat(constructor).isEqualTo(YICES_BV_SUM); + int type = Types.bvType(5); + int bv1 = Terms.newUninterpretedTerm("x", type); + int bv2 = Terms.newUninterpretedTerm("y", type); + int add = Terms.bvAdd(bv1, bv2); + Constructor constructor = Terms.constructor(add); + assertThat(constructor).isEqualTo(Constructor.BV_SUM); } @Test public void bvMul() { - int type = yices_bv_type(5); - int bv2 = yices_named_variable(type, "x"); - int mul = yices_bvmul(bv2, bv2); - assertThat(yices_term_constructor(mul)).isEqualTo(YICES_POWER_PRODUCT); + /* + int type = Types.bvType(5); + int bv2 = Terms.newUninterpretedTerm(type, "x"); + int mul = Terms.bvMul(bv2, bv2); + assertThat(Terms.constructor(mul)).isEqualTo(Constructor.POWER_PRODUCT); // bv2 + bv2 == bv2² int[] component = yices_product_component(mul, 0); assertThat(component[0]).isEqualTo(bv2); assertThat(component[1]).isEqualTo(2); - assertThat(yices_term_constructor(yices_bvpower(component[0], component[1]))).isGreaterThan(0); + assertThat(Terms.constructor(yices_bvpower(component[0], component[1]))).isGreaterThan(0); + */ + throw new AssertionError("products not supported"); } @Test public void isThreadSafe() { - // Check that we compiled with --thread-safety to make it reentrant - assertThat(yices_is_thread_safe()).isEqualTo(1); + // Check that we compiled with --enable-thread-safety to make it reentrant + assertThat(Yices.isThreadSafe()).isTrue(); } @Test public void hasMCSat() { // Check that we compiled with --enable-mcsat - assertThat(yices_has_mcsat()).isEqualTo(1); + assertThat(Yices.hasMcsat()).isTrue(); } @Test public void checkVersion() { - assertThat( - String.format( - "%s.%s.%s", - yices_get_version(), yices_get_major_version(), yices_get_patch_level())) - .isEqualTo("2.7.0"); + assertThat(Yices.version()).isEqualTo("2.7.0"); } @Test public void quantifierTest() { - int boundVar = yices_new_variable(yices_int_type()); - int eleven = yices_int32(11); - int body = yices_eq(eleven, boundVar); + int boundVar = Terms.newVariable(Types.intType()); + int eleven = Terms.intConst(11); + int body = Terms.eq(eleven, boundVar); - int forall = yices_forall(1, new int[] {boundVar}, body); - int exists = yices_exists(1, new int[] {boundVar}, body); + int forall = Terms.forall(new int[] {boundVar}, body); + int exists = Terms.exists(new int[] {boundVar}, body); - assertThat(yices_term_constructor(forall)).isEqualTo(YICES_FORALL_TERM); - assertThat(yices_term_constructor(exists)).isEqualTo(YICES_NOT_TERM); - assertThat(yices_term_constructor(yices_term_child(exists, 0))).isEqualTo(YICES_FORALL_TERM); + assertThat(Terms.constructor(forall)).isEqualTo(Constructor.FORALL_TERM); + assertThat(Terms.constructor(exists)).isEqualTo(Constructor.NOT_TERM); + assertThat(Terms.constructor(Terms.child(exists, 0))).isEqualTo(Constructor.FORALL_TERM); } @Test public void booleanInterpolationTest() { - var boolType = yices_bool_type(); - var a = yices_named_variable(boolType, "a"); - - var ctxA = newContext(true); - var ctxB = newContext(true); - - yices_assert_formula(ctxA, a); - yices_assert_formula(ctxB, yices_not(a)); - var itp = yices_interpolate(ctxA, ctxB); - - assertThat(itp).isEqualTo(a); - - yices_free_context(ctxB); - yices_free_context(ctxA); - } - - /** - * Only to be used for tests in this class. Old implementation used for creating/retrieving named - * variables. Superseded by {@link Yices2FormulaCreator#createNamedVariable} for reasons outlined - * there. - */ - private static int yices_named_variable(int type, String name) { - int termFromName = yices_get_term_by_name(name); - if (termFromName != -1) { - int termFromNameType = yices_type_of_term(termFromName); - checkArgument( - type == termFromNameType, - "Cannot override symbol '%s' with new symbol '%s' of type '%s'", - yices_type_to_string(termFromNameType), - name, - yices_type_to_string(type)); - return termFromName; + var boolType = Types.boolType(); + var a = Terms.newUninterpretedTerm("a", boolType); + + try (var ctxA = newContext(true); + var ctxB = newContext(true)) { + + ctxA.assertFormula(a); + ctxB.assertFormula(Terms.not(a)); + + var context = new InterpolationContext(ctxA, ctxB); + + try (var param = new Parameters()) { + var status = context.check(param, false); + + assertThat(status).isEqualTo(Status.UNSAT); + assertThat(context.getInterpolant()).isEqualTo(a); + } } - int var = yices_new_uninterpreted_term(type); - yices_set_term_name(var, name); - return var; } } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NumeralFormulaManager.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NumeralFormulaManager.java index cca73ecbfa..2d4dfa89a5 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NumeralFormulaManager.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NumeralFormulaManager.java @@ -8,25 +8,9 @@ package org.sosy_lab.java_smt.solvers.yices2; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.YICES_ARITH_CONST; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_add; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_arith_eq_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_arith_geq_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_arith_gt_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_arith_leq_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_arith_lt_atom; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_distinct; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_floor; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_int64; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_mul; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_neg; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_parse_float; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_parse_rational; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_sub; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_term_constructor; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_true; - import com.google.common.primitives.Ints; +import com.sri.yices.Constructor; +import com.sri.yices.Terms; import java.math.BigInteger; import java.util.List; import org.sosy_lab.java_smt.api.NumeralFormula; @@ -45,12 +29,12 @@ protected Yices2NumeralFormulaManager( @Override protected boolean isNumeral(Integer pVal) { - return yices_term_constructor(pVal) == YICES_ARITH_CONST; + return Terms.constructor(pVal) == Constructor.ARITH_CONSTANT; } @Override public Integer makeNumberImpl(long pI) { - return yices_int64(pI); + return Terms.intConst(pI); } @Override @@ -61,9 +45,9 @@ public Integer makeNumberImpl(BigInteger pI) { @Override public Integer makeNumberImpl(String pI) { if (pI.contains("/")) { - return yices_parse_rational(pI); + return Terms.parseRational(pI); } else { - return yices_parse_float(pI); + return Terms.parseFloat(pI); } } @@ -76,60 +60,60 @@ public Integer makeVariableImpl(String pI) { @Override public Integer negate(Integer pParam1) { - return yices_neg(pParam1); + return Terms.neg(pParam1); } @Override public Integer add(Integer pParam1, Integer pParam2) { - return yices_add(pParam1, pParam2); + return Terms.add(pParam1, pParam2); } @Override public Integer subtract(Integer pParam1, Integer pParam2) { - return yices_sub(pParam1, pParam2); + return Terms.sub(pParam1, pParam2); } @Override public Integer multiply(Integer pParam1, Integer pParam2) { - return yices_mul(pParam1, pParam2); + return Terms.mul(pParam1, pParam2); } @Override public Integer equal(Integer pParam1, Integer pParam2) { - return yices_arith_eq_atom(pParam1, pParam2); + return Terms.arithEq(pParam1, pParam2); } @Override public Integer distinctImpl(List pNumbers) { if (pNumbers.size() < 2) { - return yices_true(); + return Terms.mkTrue(); } else { - return yices_distinct(pNumbers.size(), Ints.toArray(pNumbers)); + return Terms.distinct(Ints.toArray(pNumbers)); } } @Override public Integer greaterThan(Integer pParam1, Integer pParam2) { - return yices_arith_gt_atom(pParam1, pParam2); + return Terms.arithGt(pParam1, pParam2); } @Override public Integer greaterOrEquals(Integer pParam1, Integer pParam2) { - return yices_arith_geq_atom(pParam1, pParam2); + return Terms.arithGeq(pParam1, pParam2); } @Override public Integer lessThan(Integer pParam1, Integer pParam2) { - return yices_arith_lt_atom(pParam1, pParam2); + return Terms.arithLt(pParam1, pParam2); } @Override public Integer lessOrEquals(Integer pParam1, Integer pParam2) { - return yices_arith_leq_atom(pParam1, pParam2); + return Terms.arithLeq(pParam1, pParam2); } @Override protected Integer floor(Integer pNumber) { - return yices_floor(pNumber); + return Terms.floor(pNumber); } } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2QuantifiedFormulaManager.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2QuantifiedFormulaManager.java index e842a87e16..9ad84a6a6d 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2QuantifiedFormulaManager.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2QuantifiedFormulaManager.java @@ -9,12 +9,9 @@ package org.sosy_lab.java_smt.solvers.yices2; import static com.google.common.base.Preconditions.checkArgument; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_exists; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_forall; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_subst_term; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_term_to_string; import com.google.common.primitives.Ints; +import com.sri.yices.Terms; import java.util.List; import org.sosy_lab.java_smt.api.SolverException; import org.sosy_lab.java_smt.basicimpl.AbstractQuantifiedFormulaManager; @@ -40,15 +37,15 @@ public Integer mkQuantifier(Quantifier pQ, List pVars, Integer pBody) { !pVars.isEmpty(), "Missing variables for quantifier '%s' and body '%s'.", pQ, - yices_term_to_string(pBody)); + Terms.toString(pBody)); Yices2FormulaCreator creator = (Yices2FormulaCreator) formulaCreator; int[] vars = pVars.stream().mapToInt(creator::createBoundVariableFromFreeVariable).toArray(); - int substBody = yices_subst_term(vars.length, Ints.toArray(pVars), vars, pBody); + int substBody = Terms.subst(pBody, Ints.toArray(pVars), vars); if (pQ == Quantifier.FORALL) { - return yices_forall(vars.length, vars, substBody); + return Terms.forall(vars, substBody); } else { - return yices_exists(vars.length, vars, substBody); + return Terms.exists(vars, substBody); } } } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2RationalFormulaManager.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2RationalFormulaManager.java index eb62dfd2cc..9ac0bc8a4f 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2RationalFormulaManager.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2RationalFormulaManager.java @@ -8,8 +8,7 @@ package org.sosy_lab.java_smt.solvers.yices2; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_division; - +import com.sri.yices.Terms; import java.math.BigDecimal; import org.sosy_lab.java_smt.api.NumeralFormula; import org.sosy_lab.java_smt.api.NumeralFormula.RationalFormula; @@ -41,6 +40,6 @@ protected Integer makeNumberImpl(BigDecimal pNumber) { @Override public Integer divide(Integer pParam1, Integer pParam2) { - return yices_division(pParam1, pParam2); + return Terms.div(pParam1, pParam2); } } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java index 39be5937b4..a0e6c28b17 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java @@ -8,12 +8,7 @@ package org.sosy_lab.java_smt.solvers.yices2; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_exit; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_major_version; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_patch_level; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_get_version; -import static org.sosy_lab.java_smt.solvers.yices2.Yices2NativeApi.yices_init; - +import com.sri.yices.Yices; import java.util.Set; import java.util.function.Consumer; import org.sosy_lab.common.ShutdownNotifier; @@ -51,14 +46,14 @@ public static Yices2SolverContext create( ShutdownNotifier pShutdownManager, Consumer pLoader) { - pLoader.accept("yices2j"); + pLoader.accept("yices2java"); synchronized (Yices2SolverContext.class) { if (numLoadedInstances == 0) { // Avoid loading and initializing twice, // because this would make all existing terms and types unavailable, // which is bad behavior and a potential memory leak. - yices_init(); + Yices.isReady(); } numLoadedInstances++; } @@ -89,8 +84,7 @@ public static Yices2SolverContext create( @Override public String getVersion() { - return String.format( - "Yices %d.%d.%d", yices_get_version(), yices_get_major_version(), yices_get_patch_level()); + return "Yices " + Yices.version(); } @Override @@ -105,7 +99,7 @@ public synchronized void close() { synchronized (Yices2SolverContext.class) { numLoadedInstances--; if (numLoadedInstances == 0) { - yices_exit(); + // TODO Garbage collect? } } } diff --git a/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java b/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java index 43db7104da..cdf09c4d28 100644 --- a/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java +++ b/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java @@ -463,6 +463,8 @@ public void sequentialInterpolationWithFewPartitions() @Test public void sequentialBVInterpolation() throws SolverException, InterruptedException { + assertThat(solver).isNotEqualTo(Solvers.YICES2); // FIXME + requireBitvectors(); InterpolatingProverEnvironment stack = newEnvironmentForTest(); diff --git a/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java b/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java index a2af7cd4d2..38f1a72fe6 100644 --- a/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java +++ b/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java @@ -15,12 +15,18 @@ import static org.junit.Assert.assertThrows; import com.google.common.collect.ImmutableSet; +import org.junit.Before; import org.junit.Test; import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; import org.sosy_lab.java_smt.api.SolverException; public class UnsatCoreTest extends SolverBasedTest0.ParameterizedSolverBasedTest0 { + @Before + public void init() { + // FIXME + assertThat(solver).isNotEqualTo(Solvers.YICES2); + } // Tests that unsat cores can not be requested after changes to the stack have been made after // UNSAT has been established. From 951ddb37eb403af20c29d9ca633232b7936f5dc0 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Sun, 8 Mar 2026 11:11:26 +0100 Subject: [PATCH 39/93] Yices: Update tests for Yices 2.8 --- .../java_smt/test/ArrayFormulaManagerTest.java | 4 ++++ .../test/BitvectorFormulaManagerTest.java | 5 ----- .../java_smt/test/BooleanFormulaSubjectTest.java | 7 ------- .../java_smt/test/InterpolatingProverTest.java | 9 +++------ src/org/sosy_lab/java_smt/test/ModelTest.java | 13 +++++-------- .../test/ProverEnvironmentSubjectTest.java | 7 ------- .../java_smt/test/ProverEnvironmentTest.java | 11 ----------- .../test/SolverFormulaWithAssumptionsTest.java | 15 --------------- src/org/sosy_lab/java_smt/test/UnsatCoreTest.java | 6 ------ 9 files changed, 12 insertions(+), 65 deletions(-) diff --git a/src/org/sosy_lab/java_smt/test/ArrayFormulaManagerTest.java b/src/org/sosy_lab/java_smt/test/ArrayFormulaManagerTest.java index 178d4b73e8..bac5bf45b0 100644 --- a/src/org/sosy_lab/java_smt/test/ArrayFormulaManagerTest.java +++ b/src/org/sosy_lab/java_smt/test/ArrayFormulaManagerTest.java @@ -8,6 +8,7 @@ package org.sosy_lab.java_smt.test; +import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.TruthJUnit.assume; import static org.sosy_lab.java_smt.api.FormulaType.IntegerType; import static org.sosy_lab.java_smt.api.FormulaType.RationalType; @@ -249,6 +250,9 @@ public void testArrayConstBvWithDefault() throws SolverException, InterruptedExc @Test public void testArrayWithManyValues() throws SolverException, InterruptedException { + // FIXME Regression after the bug fix (used to be slow already..) + assertThat(solver).isNotEqualTo(Solvers.YICES2); + requireIntegers(); requireArrays(); diff --git a/src/org/sosy_lab/java_smt/test/BitvectorFormulaManagerTest.java b/src/org/sosy_lab/java_smt/test/BitvectorFormulaManagerTest.java index 10889f385b..5f90f5c4b1 100644 --- a/src/org/sosy_lab/java_smt/test/BitvectorFormulaManagerTest.java +++ b/src/org/sosy_lab/java_smt/test/BitvectorFormulaManagerTest.java @@ -121,11 +121,6 @@ public void bvTooSmallNum() { @Test public void bvModelValue32bit() throws SolverException, InterruptedException { - assume() - .withMessage("Yices2 hangs in this test") - .that(solverToUse()) - .isNotEqualTo(Solvers.YICES2); - BitvectorFormula var = bvmgr.makeVariable(32, "var"); Map values = new LinkedHashMap<>(); diff --git a/src/org/sosy_lab/java_smt/test/BooleanFormulaSubjectTest.java b/src/org/sosy_lab/java_smt/test/BooleanFormulaSubjectTest.java index 9a256a20e0..93a067acdc 100644 --- a/src/org/sosy_lab/java_smt/test/BooleanFormulaSubjectTest.java +++ b/src/org/sosy_lab/java_smt/test/BooleanFormulaSubjectTest.java @@ -9,7 +9,6 @@ package org.sosy_lab.java_smt.test; import static com.google.common.truth.ExpectFailure.assertThat; -import static com.google.common.truth.TruthJUnit.assume; import static org.sosy_lab.java_smt.test.BooleanFormulaSubject.booleanFormulasOf; import com.google.common.base.Throwables; @@ -18,7 +17,6 @@ import com.google.common.truth.SimpleSubjectBuilder; import org.junit.Before; import org.junit.Test; -import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.SolverException; @@ -67,11 +65,6 @@ public void testIsSatisfiableYes() throws SolverException, InterruptedException @Test public void testIsSatisfiableNo() { requireUnsatCore(); - assume() - .withMessage("Yices2 hangs in this test") - .that(solverToUse()) - .isNotEqualTo(Solvers.YICES2); - AssertionError failure = expectFailure(whenTesting -> whenTesting.that(contradiction).isSatisfiable()); assertThat(failure).factValue("which has unsat core").isNotEmpty(); diff --git a/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java b/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java index cdf09c4d28..c78951248b 100644 --- a/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java +++ b/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java @@ -57,8 +57,7 @@ public void simpleInterpolation() throws SolverException, InterruptedExcepti assume() .withMessage("Solver %s runs into timeout on this test", solverToUse()) .that(solverToUse()) - .isNotEqualTo(Solvers.CVC5); - assume().that(solver).isNotEqualTo(Solvers.YICES2); + .isNoneOf(Solvers.CVC5, Solvers.YICES2); try (InterpolatingProverEnvironment prover = newEnvironmentForTest()) { Formula x = makeVariable("x"); @@ -88,7 +87,7 @@ public void simpleInterpolation() throws SolverException, InterruptedExcepti @Test @SuppressWarnings("unchecked") public void emptyInterpolationGroup() throws SolverException, InterruptedException { - assume().that(solver).isNotEqualTo(Solvers.YICES2); + assertThat(solver).isNotEqualTo(Solvers.YICES2); try (InterpolatingProverEnvironment prover = newEnvironmentForTest()) { Formula x = makeVariable("x"); Formula y = makeVariable("y"); @@ -464,7 +463,6 @@ public void sequentialInterpolationWithFewPartitions() @Test public void sequentialBVInterpolation() throws SolverException, InterruptedException { assertThat(solver).isNotEqualTo(Solvers.YICES2); // FIXME - requireBitvectors(); InterpolatingProverEnvironment stack = newEnvironmentForTest(); @@ -1050,7 +1048,6 @@ public void treeInterpolationWithOnePartition() throws SolverException, Inte public void bigSeqInterpolationTest() throws InterruptedException, SolverException { requireBitvectors(); requireInterpolation(); - assume().that(solver).isNotEqualTo(Solvers.YICES2); assume() .withMessage("Solver %s does not support interpolation over bitvectors", solverToUse()) @@ -1059,7 +1056,7 @@ public void bigSeqInterpolationTest() throws InterruptedException, SolverExc assume() .withMessage("Solver %s runs into timeout on this test", solverToUse()) .that(solverToUse()) - .isNotEqualTo(Solvers.CVC5); + .isNoneOf(Solvers.CVC5, Solvers.YICES2); int bvWidth = 32; BitvectorFormula bv0 = bvmgr.makeBitvector(bvWidth, 0); diff --git a/src/org/sosy_lab/java_smt/test/ModelTest.java b/src/org/sosy_lab/java_smt/test/ModelTest.java index c3183e2760..bf4e13184d 100644 --- a/src/org/sosy_lab/java_smt/test/ModelTest.java +++ b/src/org/sosy_lab/java_smt/test/ModelTest.java @@ -1252,7 +1252,7 @@ public void testGetArrays3IntegerNoParsing() throws SolverException, Interrupted requireArrays(); requireArrayModel(); - assume().withMessage("Not supported with MCSAT").that(solver).isNotEqualTo(Solvers.YICES2); + assertThat(solver).isNotEqualTo(Solvers.YICES2); // FIXME // (= (select (select (select arr 5) 3) 1) x) // (= x 123)" @@ -1838,7 +1838,7 @@ public void testArrayWithManyValues() throws SolverException, InterruptedExcepti requireArrays(); requireArrayModel(); - assume().withMessage("Not supported with MCSAT").that(solver).isNotEqualTo(Solvers.YICES2); + assertThat(solver).isNotEqualTo(Solvers.YICES2); // FIXME // Let's store N values into an array and check that each one is in the model. // The example array formula is: for x in [1...N]: arr = store(arr, i_x, x) @@ -2615,7 +2615,7 @@ public void testArray1BvBV() { requireArrays(); requireBitvectors(); - assume().that(solver).isNotEqualTo(Solvers.YICES2); // FIXME Segfaults + assertThat(solver).isNotEqualTo(Solvers.YICES2); // FIXME Segfaults assume().that(solver).isNotEqualTo(Solvers.BOOLECTOR); // Doesn't support multiple indices var bitvectorType = FormulaType.getBitvectorTypeWithSize(8); @@ -2685,7 +2685,6 @@ public void testArrayStore1BvBvBv() { assume().that(solver).isNotEqualTo(Solvers.BOOLECTOR); // Doesn't support multiple indices assume().that(solver).isNotEqualTo(Solvers.CVC4); // FIXME Broken in JavaSMT - assume().withMessage("Not supported with MCSAT").that(solver).isNotEqualTo(Solvers.YICES2); var scalarType = FormulaType.getBitvectorTypeWithSize(8); @@ -2809,7 +2808,7 @@ public void testArray1IntInt() { requireArrayModel(); requireIntegers(); - assume().withMessage("Not supported with MCSAT").that(solver).isNotEqualTo(Solvers.YICES2); + assertThat(solver).isNotEqualTo(Solvers.YICES2); // FIXME var array = amgr.makeArray("array", IntegerType, FormulaType.getArrayType(IntegerType, IntegerType)); @@ -2826,8 +2825,6 @@ public void testArray1IntInt() { @Test public void testArrayStore1IntIntInt() { - assume().withMessage("Not supported with MCSAT").that(solver).isNotEqualTo(Solvers.YICES2); - // Test for 3d integer arrays with exactly one element // array = (Store (const ...) idxA (Store (const ..) idxB (Store (const ...) idx C val)) requireArrays(); @@ -2870,7 +2867,7 @@ public void testArray2IntInt() { requireArrayModel(); requireIntegers(); - assume().withMessage("Not supported with MCSAT").that(solver).isNotEqualTo(Solvers.YICES2); + assertThat(solver).isNotEqualTo(Solvers.YICES2); // FIXME var array = amgr.makeArray("array", IntegerType, FormulaType.getArrayType(IntegerType, IntegerType)); diff --git a/src/org/sosy_lab/java_smt/test/ProverEnvironmentSubjectTest.java b/src/org/sosy_lab/java_smt/test/ProverEnvironmentSubjectTest.java index 72d9a95ed1..743ea4b7d4 100644 --- a/src/org/sosy_lab/java_smt/test/ProverEnvironmentSubjectTest.java +++ b/src/org/sosy_lab/java_smt/test/ProverEnvironmentSubjectTest.java @@ -9,7 +9,6 @@ package org.sosy_lab.java_smt.test; import static com.google.common.truth.ExpectFailure.assertThat; -import static com.google.common.truth.TruthJUnit.assume; import static org.sosy_lab.java_smt.test.ProverEnvironmentSubject.proverEnvironments; import com.google.common.base.Throwables; @@ -18,7 +17,6 @@ import com.google.common.truth.SimpleSubjectBuilder; import org.junit.Before; import org.junit.Test; -import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.ProverEnvironment; @@ -55,11 +53,6 @@ public void testIsSatisfiableYes() throws SolverException, InterruptedException @Test public void testIsSatisfiableNo() throws InterruptedException { requireUnsatCore(); - assume() - .withMessage("Yices2 hangs in this test") - .that(solverToUse()) - .isNotEqualTo(Solvers.YICES2); - try (ProverEnvironment env = context.newProverEnvironment( ProverOptions.GENERATE_MODELS, ProverOptions.GENERATE_UNSAT_CORE)) { diff --git a/src/org/sosy_lab/java_smt/test/ProverEnvironmentTest.java b/src/org/sosy_lab/java_smt/test/ProverEnvironmentTest.java index acee532ddf..b62deba03b 100644 --- a/src/org/sosy_lab/java_smt/test/ProverEnvironmentTest.java +++ b/src/org/sosy_lab/java_smt/test/ProverEnvironmentTest.java @@ -10,7 +10,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.TruthJUnit.assume; import static org.junit.Assert.assertThrows; import static org.sosy_lab.java_smt.api.SolverContext.ProverOptions.GENERATE_UNSAT_CORE; import static org.sosy_lab.java_smt.api.SolverContext.ProverOptions.GENERATE_UNSAT_CORE_OVER_ASSUMPTIONS; @@ -19,9 +18,7 @@ import com.google.common.collect.ImmutableList; import java.util.List; import java.util.Optional; -import org.junit.Before; import org.junit.Test; -import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.BasicProverEnvironment; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Formula; @@ -32,14 +29,6 @@ public class ProverEnvironmentTest extends SolverBasedTest0.ParameterizedSolverBasedTest0 { - @Before - public void init() { - assume() - .withMessage("Yices2 hangs in this test") - .that(solverToUse()) - .isNotEqualTo(Solvers.YICES2); - } - @Test public void assumptionsTest() throws SolverException, InterruptedException { BooleanFormula b = bmgr.makeVariable("b"); diff --git a/src/org/sosy_lab/java_smt/test/SolverFormulaWithAssumptionsTest.java b/src/org/sosy_lab/java_smt/test/SolverFormulaWithAssumptionsTest.java index 97e85d593e..4877aec0be 100644 --- a/src/org/sosy_lab/java_smt/test/SolverFormulaWithAssumptionsTest.java +++ b/src/org/sosy_lab/java_smt/test/SolverFormulaWithAssumptionsTest.java @@ -16,9 +16,7 @@ import com.google.common.collect.Lists; import java.util.ArrayList; import java.util.List; -import org.junit.Before; import org.junit.Test; -import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.BooleanFormula; import org.sosy_lab.java_smt.api.Formula; import org.sosy_lab.java_smt.api.InterpolatingProverEnvironment; @@ -56,14 +54,6 @@ protected InterpolatingProverEnvironment newEnvironmentForTest() return (InterpolatingProverEnvironment) context.newProverEnvironmentWithInterpolation(); } - @Before - public void init() { - assume() - .withMessage("Yices2 hangs in this test") - .that(solverToUse()) - .isNotEqualTo(Solvers.YICES2); - } - @Test @SuppressWarnings("CheckReturnValue") public void basicAssumptionsTest() throws SolverException, InterruptedException { @@ -167,11 +157,6 @@ public void assumptionsTest() throws SolverException, InterruptedException { @Test @SuppressWarnings("CheckReturnValue") public void assumptionsTest1() throws SolverException, InterruptedException { - assume() - .withMessage("Yices2 hangs in this test") - .that(solverToUse()) - .isNotEqualTo(Solvers.YICES2); - /* (declare-fun A () Bool) (push 1) diff --git a/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java b/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java index 38f1a72fe6..a2af7cd4d2 100644 --- a/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java +++ b/src/org/sosy_lab/java_smt/test/UnsatCoreTest.java @@ -15,18 +15,12 @@ import static org.junit.Assert.assertThrows; import com.google.common.collect.ImmutableSet; -import org.junit.Before; import org.junit.Test; import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; import org.sosy_lab.java_smt.api.SolverException; public class UnsatCoreTest extends SolverBasedTest0.ParameterizedSolverBasedTest0 { - @Before - public void init() { - // FIXME - assertThat(solver).isNotEqualTo(Solvers.YICES2); - } // Tests that unsat cores can not be requested after changes to the stack have been made after // UNSAT has been established. From e0b7c00b47eaefc40632a79ae2ef1487f0cc21a0 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Sun, 8 Mar 2026 16:07:34 +0100 Subject: [PATCH 40/93] Yices: Add support for sums and products in the visitor --- .../solvers/yices2/Yices2FormulaCreator.java | 106 +++++++++--------- 1 file changed, 52 insertions(+), 54 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java index e339dd7e7d..9fc323267a 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java @@ -18,7 +18,10 @@ import com.google.common.collect.Lists; import com.google.common.collect.Table; import com.google.common.primitives.Ints; +import com.sri.yices.BigRational; import com.sri.yices.Constructor; +import com.sri.yices.ProductComponent; +import com.sri.yices.SumComponent; import com.sri.yices.Terms; import com.sri.yices.Types; import java.math.BigInteger; @@ -790,87 +793,82 @@ private static List getArgs(int parent) { } private static List getSumArgs(int parent) { - /* - List children = new ArrayList<>(); + // TODO Refactor me + ImmutableList.Builder terms = ImmutableList.builder(); for (int i = 0; i < Terms.numChildren(parent); i++) { - String[] child = yices_sum_component(parent, i); - String coeff = child[0]; - int term = Integer.parseInt(child[1]); - if (term == -1) { // No term just a number - children.add(yices_parse_rational(coeff)); - } else { - int coeffTerm = yices_parse_rational(coeff); - children.add(yices_mul(coeffTerm, term)); - } + SumComponent component = (SumComponent) Terms.projSum(parent, i); + + var factor = + Terms.rationalConst( + component.getFactor().getNumerator(), component.getFactor().getDenominator()); + var term = component.getTerm() == Terms.NULL_TERM ? Terms.one() : component.getTerm(); + + terms.add(Terms.mul(factor, term)); } - return children; - */ - throw new UnsupportedOperationException("arith sum not supported"); + return terms.build(); } /** extract -1 and X from the sum of one element [-1*x]. */ private static List getMultiplySumArgsFromSum(int parent) { - /* + // TODO Refactor me checkArgument(Terms.numChildren(parent) == 1); - String[] child = yices_sum_component(parent, 0); - int term = Integer.parseInt(child[1]); - checkArgument(term != -1, "unexpected constant coeff without variable"); - int coeffTerm = yices_parse_rational(child[0]); - return ImmutableList.of(coeffTerm, term); - */ - throw new UnsupportedOperationException("arith sum not supported"); + + SumComponent component = (SumComponent) Terms.projSum(parent, 0); + var factor = + Terms.rationalConst( + component.getFactor().getNumerator(), component.getFactor().getDenominator()); + checkArgument(component.getTerm() != Terms.NULL_TERM); + + return ImmutableList.of(factor, component.getTerm()); } /** extract all entries of a BV sum like "3*x + 2*y + 1". */ private static List getBvSumArgs(int parent) { - /*List children = new ArrayList<>(); - int bitsize = Terms.bitSize(parent); + // TODO Refactor me + ImmutableList.Builder terms = ImmutableList.builder(); for (int i = 0; i < Terms.numChildren(parent); i++) { - int[] component = yices_bvsum_component(parent, i, bitsize); - assert component.length == bitsize + 1; - // the components consist of coefficient (as bits) and variable (if missing: -1) - int coeff = yices_bvconst_from_array(bitsize, Arrays.copyOfRange(component, 0, bitsize)); - int term = component[component.length - 1]; - if (term == -1) { // No term - children.add(coeff); - } else { - children.add(yices_bvmul(coeff, term)); + SumComponent component = (SumComponent) Terms.projSum(parent, i); + + ImmutableList.Builder builder = ImmutableList.builder(); + for (var bit : component.getFactor()) { + builder.add(bit ? 1 : 0); } + var factor = Terms.bvConst(builder.build()); + var term = component.getTerm() == Terms.NULL_TERM ? Terms.one() : component.getTerm(); + + terms.add(Terms.bvMul(factor, term)); } - return children; - */ - throw new UnsupportedOperationException("bvsum not supported"); + return terms.build(); } /** extract -1 and X from the sum of one element [-1*x]. */ private static List getMultiplyBvSumArgsFromSum(int parent) { - /* + // TODO Refactor me checkArgument(Terms.numChildren(parent) == 1); - int bitsize = Terms.bitSize(parent); - int[] component = yices_bvsum_component(parent, 0, bitsize); - int coeff = yices_bvconst_from_array(bitsize, Arrays.copyOfRange(component, 0, bitsize)); - int term = component[component.length - 1]; - checkArgument(term != -1, "unexpected constant coeff without variable"); - return ImmutableList.of(coeff, term); - */ - throw new UnsupportedOperationException("bvsum not supported"); + SumComponent component = (SumComponent) Terms.projSum(parent, 0); + + ImmutableList.Builder builder = ImmutableList.builder(); + for (var bit : component.getFactor()) { + builder.add(bit ? 1 : 0); + } + var factor = Terms.bvConst(builder.build()); + checkArgument(component.getTerm() != Terms.NULL_TERM); + + return ImmutableList.of(factor, component.getTerm()); } private static List getMultiplyArgs(int parent, boolean isBV) { - /* - // TODO Add exponent? - List result = new ArrayList<>(); + // TODO Refactor me + ImmutableList.Builder builder = ImmutableList.builder(); for (int i = 0; i < Terms.numChildren(parent); i++) { - int[] component = yices_product_component(parent, i); + ProductComponent component = Terms.projProduct(parent, i); if (isBV) { - result.add(yices_bvpower(component[0], component[1])); + builder.add(Terms.bvPower(component.getTerm(), component.getPower())); } else { - result.add(yices_power(component[0], component[1])); // add term, ignore exponent + builder.add(Terms.power(component.getTerm(), component.getPower())); } } - return result; - */ - throw new UnsupportedOperationException("product not supported"); + return builder.build(); } /** get "index" and "b" from "(bit index b)". */ From e89734e246d6d9a1784ca7c29bf9a3b92c815b64 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Sun, 8 Mar 2026 16:43:52 +0100 Subject: [PATCH 41/93] Yices: Fix bv sums --- .../java_smt/solvers/yices2/Yices2FormulaCreator.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java index 9fc323267a..be329894b7 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java @@ -834,7 +834,10 @@ private static List getBvSumArgs(int parent) { builder.add(bit ? 1 : 0); } var factor = Terms.bvConst(builder.build()); - var term = component.getTerm() == Terms.NULL_TERM ? Terms.one() : component.getTerm(); + var term = + component.getTerm() == Terms.NULL_TERM + ? Terms.bvOne(Terms.bitSize(parent)) + : component.getTerm(); terms.add(Terms.bvMul(factor, term)); } From c80f0fd80ae151d4a783534283858dc089a23c1c Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Sun, 8 Mar 2026 16:44:44 +0100 Subject: [PATCH 42/93] Yices: Print error message when function is called with wrong number of arguments --- .../java_smt/solvers/yices2/Yices2FormulaCreator.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java index be329894b7..1ce4f435b9 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java @@ -881,7 +881,11 @@ private static List getBitArgs(int parent) { @Override public Integer callFunctionImpl(Integer pDeclaration, List pArgs) { - checkArgument(Types.numChildren(Terms.typeOf(pDeclaration)) == 1 + pArgs.size()); + checkArgument( + Types.numChildren(Terms.typeOf(pDeclaration)) == 1 + pArgs.size(), + "Expecting %s arguments, but %s were given", + Types.numChildren(Terms.typeOf(pDeclaration)) - 1, + pArgs.size()); if (pArgs.isEmpty()) { return pDeclaration; } else { From f45773803c5276f4a705b64ff9d656553aa0af16 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Sun, 8 Mar 2026 17:18:10 +0100 Subject: [PATCH 43/93] Yices: Suppress `unchecked` warnings --- .../java_smt/solvers/yices2/Yices2FormulaCreator.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java index 1ce4f435b9..795baf4ffc 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java @@ -796,6 +796,7 @@ private static List getSumArgs(int parent) { // TODO Refactor me ImmutableList.Builder terms = ImmutableList.builder(); for (int i = 0; i < Terms.numChildren(parent); i++) { + @SuppressWarnings("unchecked") SumComponent component = (SumComponent) Terms.projSum(parent, i); var factor = @@ -812,7 +813,7 @@ private static List getSumArgs(int parent) { private static List getMultiplySumArgsFromSum(int parent) { // TODO Refactor me checkArgument(Terms.numChildren(parent) == 1); - + @SuppressWarnings("unchecked") SumComponent component = (SumComponent) Terms.projSum(parent, 0); var factor = Terms.rationalConst( @@ -827,6 +828,7 @@ private static List getBvSumArgs(int parent) { // TODO Refactor me ImmutableList.Builder terms = ImmutableList.builder(); for (int i = 0; i < Terms.numChildren(parent); i++) { + @SuppressWarnings("unchecked") SumComponent component = (SumComponent) Terms.projSum(parent, i); ImmutableList.Builder builder = ImmutableList.builder(); @@ -848,6 +850,7 @@ private static List getBvSumArgs(int parent) { private static List getMultiplyBvSumArgsFromSum(int parent) { // TODO Refactor me checkArgument(Terms.numChildren(parent) == 1); + @SuppressWarnings("unchecked") SumComponent component = (SumComponent) Terms.projSum(parent, 0); ImmutableList.Builder builder = ImmutableList.builder(); From a989722c6d62258738244e0dfc3a13629fdf874c Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Mon, 9 Mar 2026 10:52:10 +0100 Subject: [PATCH 44/93] Yices: Use larger print window to make sure formulas are not cut off --- .../sosy_lab/java_smt/solvers/yices2/Yices2FormulaManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaManager.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaManager.java index b5888acad9..28cbe48b21 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaManager.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaManager.java @@ -133,7 +133,7 @@ assert getFormulaCreator().getFormulaType(formula) == FormulaType.BooleanType } } // TODO fold formula to avoid exp. overhead - out.append("(assert ").append(Terms.toString(formula)).append(")"); + out.append("(assert ").append(Terms.toString(formula, 100000, 1)).append(")"); return out.toString(); } From 84ed2abad934ba0e0a80e15cf24d57510825d179 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Mon, 9 Mar 2026 12:12:47 +0100 Subject: [PATCH 45/93] Use a simpler example in `simpleInterpolation` and `emptyInterpolationGroup` test The old example is too complex for several solvers now (cvc5, yices2, opensmt) --- .../test/InterpolatingProverTest.java | 45 +++++++++---------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java b/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java index c78951248b..1f01a3a1ca 100644 --- a/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java +++ b/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java @@ -54,21 +54,31 @@ private InterpolatingProverEnvironment newEnvironmentForTest() { @Test @SuppressWarnings("CheckReturnValue") public void simpleInterpolation() throws SolverException, InterruptedException { + try (InterpolatingProverEnvironment prover = newEnvironmentForTest()) { + var f1 = lessThanNumber(makeVariable("x"), makeNumber(0)); + var f2 = greaterThanNumber(makeVariable("x"), makeNumber(0)); + + prover.push(f1); + T id2 = prover.push(f2); + + assertThatEnvironment(prover).isUnsatisfiable(); + prover.getInterpolant(ImmutableList.of(id2)); + // we actually only check for a successful execution here, the result is irrelevant. + } + } + + @Test + @SuppressWarnings("CheckReturnValue") + public void notSoSimpleInterpolation() throws SolverException, InterruptedException { assume() .withMessage("Solver %s runs into timeout on this test", solverToUse()) .that(solverToUse()) - .isNoneOf(Solvers.CVC5, Solvers.YICES2); + .isNoneOf(Solvers.CVC5, Solvers.YICES2, Solvers.OPENSMT); try (InterpolatingProverEnvironment prover = newEnvironmentForTest()) { Formula x = makeVariable("x"); Formula y = makeVariable("y"); - /* INFO: Due to limitations in OpenSMT we need to use a simpler formular for this solver - * Setting z=x means that the original formula `2x ≠ 1+2z`simplifies to `0 ≠ 1`, - * which is trivially true. - * - * https://github.com/usi-verification-and-security/opensmt/issues/638 - */ - Formula z = solverToUse() == Solvers.OPENSMT ? x : makeVariable("z"); + Formula z = makeVariable("z"); BooleanFormula f1 = mgr.makeEqual(y, multiplyNumber(makeNumber(2), x)); BooleanFormula f2 = @@ -76,32 +86,19 @@ public void simpleInterpolation() throws SolverException, InterruptedExcepti prover.push(f1); T id2 = prover.push(f2); - boolean check = prover.isUnsat(); - assertWithMessage("formulas must be contradicting").that(check).isTrue(); + assertThatEnvironment(prover).isUnsatisfiable(); prover.getInterpolant(ImmutableList.of(id2)); // we actually only check for a successful execution here, the result is irrelevant. } } @Test - @SuppressWarnings("unchecked") public void emptyInterpolationGroup() throws SolverException, InterruptedException { - assertThat(solver).isNotEqualTo(Solvers.YICES2); try (InterpolatingProverEnvironment prover = newEnvironmentForTest()) { - Formula x = makeVariable("x"); - Formula y = makeVariable("y"); - /* INFO: Due to limitations in OpenSMT we need to use a simpler formula for this solver - * Setting z=x means that the original formula `2x ≠ 1+2z`simplifies to `0 ≠ 1`, - * which is trivially true. - * - * https://github.com/usi-verification-and-security/opensmt/issues/638 - */ - Formula z = solverToUse() == Solvers.OPENSMT ? x : makeVariable("z"); + var f1 = lessThanNumber(makeVariable("x"), makeNumber(0)); + var f2 = greaterThanNumber(makeVariable("x"), makeNumber(0)); - BooleanFormula f1 = mgr.makeEqual(y, multiplyNumber(makeNumber(2), x)); - BooleanFormula f2 = - mgr.makeEqual(y, addNumber(makeNumber(1), multiplyNumber(z, makeNumber(2)))); T id1 = prover.push(f1); T id2 = prover.push(f2); assertThat(prover.isUnsat()).isTrue(); From 54bd265333975e0b0a049c96037016ae2fdefac5 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Mon, 9 Mar 2026 13:20:51 +0100 Subject: [PATCH 46/93] Yices: Fix handling of UFs with no arguments --- .../solvers/yices2/Yices2FormulaCreator.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java index 795baf4ffc..53d8074238 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java @@ -884,15 +884,16 @@ private static List getBitArgs(int parent) { @Override public Integer callFunctionImpl(Integer pDeclaration, List pArgs) { - checkArgument( - Types.numChildren(Terms.typeOf(pDeclaration)) == 1 + pArgs.size(), - "Expecting %s arguments, but %s were given", - Types.numChildren(Terms.typeOf(pDeclaration)) - 1, - pArgs.size()); - if (pArgs.isEmpty()) { - return pDeclaration; - } else { + if (Terms.isFunction(pDeclaration)) { + checkArgument( + Types.numChildren(Terms.typeOf(pDeclaration)) == 1 + pArgs.size(), + "Expecting %s arguments, but found %s", + Types.numChildren(Terms.typeOf(pDeclaration)) - 1, + pArgs.size()); return Terms.funApplication(pDeclaration, Ints.toArray(pArgs)); + } else { + checkArgument(pArgs.isEmpty(), "Expecting no arguments, but found %s", pArgs.size()); + return pDeclaration; } } From 8d8ca8e9e091e536174d0d9b2668ba9605a82adc Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Mon, 9 Mar 2026 14:19:56 +0100 Subject: [PATCH 47/93] Yices: Add an option for picking the solver (DPLLT or MCSat) --- .../solvers/yices2/Yices2AbstractProver.java | 5 +++-- .../solvers/yices2/Yices2InterpolatingProver.java | 5 +++-- .../java_smt/solvers/yices2/Yices2Prover.java | 5 +++-- .../java_smt/solvers/yices2/Yices2SolverContext.java | 12 ++++++++++-- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java index 44889fe406..dd3fab625c 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java @@ -71,10 +71,11 @@ protected Yices2AbstractProver( Yices2FormulaCreator pCreator, Set pOptions, BooleanFormulaManager pBmgr, - ShutdownNotifier pShutdownNotifier) { + ShutdownNotifier pShutdownNotifier, + boolean pForceMCSat) { super(pOptions, pBmgr, pShutdownNotifier); creator = pCreator; - curEnv = newContext(true); + curEnv = newContext(pForceMCSat); stack.push(PathCopyingPersistentTreeMap.of()); } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java index 5f9b2cc202..d41ffd5145 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java @@ -37,8 +37,9 @@ protected Yices2InterpolatingProver( Yices2FormulaCreator creator, Set pOptions, BooleanFormulaManager pBmgr, - ShutdownNotifier pShutdownNotifier) { - super(creator, pOptions, pBmgr, pShutdownNotifier); + ShutdownNotifier pShutdownNotifier, + boolean pForceMCSat) { + super(creator, pOptions, pBmgr, pShutdownNotifier, pForceMCSat); } @Override diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Prover.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Prover.java index 6477ec3b56..5747dc618f 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Prover.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Prover.java @@ -23,8 +23,9 @@ protected Yices2Prover( Yices2FormulaCreator creator, Set pOptions, BooleanFormulaManager pBmgr, - ShutdownNotifier pShutdownNotifier) { - super(creator, pOptions, pBmgr, pShutdownNotifier); + ShutdownNotifier pShutdownNotifier, + boolean pForceMCSat) { + super(creator, pOptions, pBmgr, pShutdownNotifier, pForceMCSat); } @Override diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java index a0e6c28b17..f24d82b2f4 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java @@ -12,6 +12,8 @@ import java.util.Set; import java.util.function.Consumer; import org.sosy_lab.common.ShutdownNotifier; +import org.sosy_lab.common.configuration.Option; +import org.sosy_lab.common.configuration.Options; import org.sosy_lab.java_smt.SolverContextFactory.Solvers; import org.sosy_lab.java_smt.api.BooleanFormulaManager; import org.sosy_lab.java_smt.api.FormulaManager; @@ -21,6 +23,7 @@ import org.sosy_lab.java_smt.basicimpl.AbstractNumeralFormulaManager.NonLinearArithmetic; import org.sosy_lab.java_smt.basicimpl.AbstractSolverContext; +@Options(prefix = "solver.yices2") public class Yices2SolverContext extends AbstractSolverContext { private final Yices2FormulaCreator creator; @@ -30,6 +33,11 @@ public class Yices2SolverContext extends AbstractSolverContext { private static int numLoadedInstances = 0; private boolean closed = false; + @Option( + secure = true, + description = "Always use MCSat solver, instead of the normal DPLLT based solver.") + private boolean forceMCSat = true; + public Yices2SolverContext( FormulaManager pFmgr, Yices2FormulaCreator creator, @@ -107,13 +115,13 @@ public synchronized void close() { @Override protected ProverEnvironment newProverEnvironment0(Set pOptions) { - return new Yices2Prover(creator, pOptions, bfmgr, shutdownManager); + return new Yices2Prover(creator, pOptions, bfmgr, shutdownManager, forceMCSat); } @Override protected InterpolatingProverEnvironment newProverEnvironmentWithInterpolation0( Set pOptions) { - return new Yices2InterpolatingProver(creator, pOptions, bfmgr, shutdownManager); + return new Yices2InterpolatingProver(creator, pOptions, bfmgr, shutdownManager, forceMCSat); } @Override From 1270cdbfbcb886367beb73dc1ee862fae1bb903e Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Mon, 9 Mar 2026 16:35:45 +0100 Subject: [PATCH 48/93] Yices: Add a hack to handle bv terms in the visitors Yices rewrites bv terms into boolean operations. We should restore the original term for the visitor to handle this correctly --- .../solvers/yices2/Yices2FormulaCreator.java | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java index 53d8074238..61cf16d531 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java @@ -259,6 +259,16 @@ protected int createBoundVariableFromFreeVariable(int unboundVar) { return bound; } + /** + * Returns the name of a variable or uf term. + * + *

Will return an abstract value name if the term has no name. Yices may introduce unnamed + * terms while rewriting bv operations + */ + private String lookupName(int term) { + return Terms.getName(term) == null ? "@" + term : Terms.getName(term); + } + @SuppressWarnings("deprecation") @Override public R visit(FormulaVisitor pVisitor, Formula pFormula, Integer pF) { @@ -284,7 +294,7 @@ public R visit(FormulaVisitor pVisitor, Formula pFormula, Integer pF) { case FORALL_TERM: return visitQuantifier(pVisitor, pFormula, pF, Quantifier.FORALL); case UNINTERPRETED_TERM: - return pVisitor.visitFreeVariable(pFormula, Terms.getName(pF)); + return pVisitor.visitFreeVariable(pFormula, lookupName(pF)); default: return visitFunctionApplication(pVisitor, pFormula, pF, constructor); } @@ -343,7 +353,7 @@ private R visitFunctionApplication( var args = getArgs(pF); var f = args.get(0); var x = FluentIterable.from(args).skip(1).toList(); - functionName = Terms.getName(f); + functionName = lookupName(f); functionDeclaration = f; functionArgs = x; } else { @@ -460,10 +470,13 @@ private R visitFunctionApplication( } break; case BIT_TERM: + // FIXME Not really "extract" functionKind = FunctionDeclarationKind.BV_EXTRACT; - functionArgs = getBitArgs(pF); + functionIndex = ImmutableList.of(Terms.projIndex(pF)); + functionArgs = ImmutableList.of(Terms.projArg(pF)); break; case BV_ARRAY: + // FIXME Not really "concat" functionKind = FunctionDeclarationKind.BV_CONCAT; break; default: @@ -614,10 +627,14 @@ private int buildDeclaration( throw new UnsupportedOperationException("INT_TO_BV not supported"); case BV_EXTRACT: checkArgument(args.size() == 1); - f = Terms.bvExtract(args.get(0), pIndex.get(0), pIndex.get(1)); + f = Terms.bvExtractBit(args.get(0), pIndex.get(0)); + // FIXME Should be: + // f = Terms.bvExtract(args.get(0), pIndex.get(0), pIndex.get(1)); break; case BV_CONCAT: - f = Terms.bvConcat(args); + f = Terms.bvFromBoolArray(args); + // FIXME Should be: + // f = Terms.bvConcat(args); break; case BV_SIGN_EXTENSION: checkArgument(args.size() == 1); From 3d12d469193234282f48360ca4b297941b09a4ac Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Mon, 9 Mar 2026 23:15:19 +0100 Subject: [PATCH 49/93] Yices: Actually apply solver options --- .../java_smt/SolverContextFactory.java | 2 +- .../solvers/yices2/Yices2AbstractProver.java | 8 ++-- .../yices2/Yices2InterpolatingProver.java | 8 ++-- .../java_smt/solvers/yices2/Yices2Prover.java | 4 +- .../solvers/yices2/Yices2SolverContext.java | 41 +++++++++++++------ 5 files changed, 40 insertions(+), 23 deletions(-) diff --git a/src/org/sosy_lab/java_smt/SolverContextFactory.java b/src/org/sosy_lab/java_smt/SolverContextFactory.java index 636ebddd9c..43d64b5d14 100644 --- a/src/org/sosy_lab/java_smt/SolverContextFactory.java +++ b/src/org/sosy_lab/java_smt/SolverContextFactory.java @@ -308,7 +308,7 @@ private SolverContext generateContext0(Solvers solverToCreate) config, shutdownNotifier, logfile, (int) randomSeed, nonLinearArithmetic); case YICES2: - return Yices2SolverContext.create(nonLinearArithmetic, shutdownNotifier, loader); + return Yices2SolverContext.create(config, nonLinearArithmetic, shutdownNotifier, loader); case BOOLECTOR: return BoolectorSolverContext.create(config, shutdownNotifier, logfile, randomSeed, loader); diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java index dd3fab625c..e54ca73bfb 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java @@ -72,10 +72,10 @@ protected Yices2AbstractProver( Set pOptions, BooleanFormulaManager pBmgr, ShutdownNotifier pShutdownNotifier, - boolean pForceMCSat) { + String pSolverType) { super(pOptions, pBmgr, pShutdownNotifier); creator = pCreator; - curEnv = newContext(pForceMCSat); + curEnv = newContext(pSolverType); stack.push(PathCopyingPersistentTreeMap.of()); } @@ -88,9 +88,9 @@ protected boolean hasPersistentModel() { return false; } - Context newContext(boolean mcsat) { + Context newContext(String solverType) { try (var cfg = new Config()) { - cfg.set("solver-type", mcsat ? "mcsat" : "dpllt"); + cfg.set("solver-type", solverType); cfg.set("mode", "interactive"); cfg.set("model-interpolation", "true"); return new Context(cfg); diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java index d41ffd5145..86f4995e56 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java @@ -38,8 +38,8 @@ protected Yices2InterpolatingProver( Set pOptions, BooleanFormulaManager pBmgr, ShutdownNotifier pShutdownNotifier, - boolean pForceMCSat) { - super(creator, pOptions, pBmgr, pShutdownNotifier, pForceMCSat); + String pSolverType) { + super(creator, pOptions, pBmgr, pShutdownNotifier, pSolverType); } @Override @@ -66,8 +66,8 @@ public BooleanFormula getInterpolant(Collection formulasOfA) } private int interpolate(Collection setA, Collection setB) { - try (var ctxA = newContext(true); - var ctxB = newContext(true)) { + try (var ctxA = newContext("mcsat"); + var ctxB = newContext("mcsat")) { ctxA.assertFormulas(Ints.toArray(setA)); ctxB.assertFormulas(Ints.toArray(setB)); diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Prover.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Prover.java index 5747dc618f..c334d4aed1 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Prover.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Prover.java @@ -24,8 +24,8 @@ protected Yices2Prover( Set pOptions, BooleanFormulaManager pBmgr, ShutdownNotifier pShutdownNotifier, - boolean pForceMCSat) { - super(creator, pOptions, pBmgr, pShutdownNotifier, pForceMCSat); + String pSolverType) { + super(creator, pOptions, pBmgr, pShutdownNotifier, pSolverType); } @Override diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java index f24d82b2f4..1c782b58f5 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java @@ -12,6 +12,8 @@ import java.util.Set; import java.util.function.Consumer; import org.sosy_lab.common.ShutdownNotifier; +import org.sosy_lab.common.configuration.Configuration; +import org.sosy_lab.common.configuration.InvalidConfigurationException; import org.sosy_lab.common.configuration.Option; import org.sosy_lab.common.configuration.Options; import org.sosy_lab.java_smt.SolverContextFactory.Solvers; @@ -23,36 +25,48 @@ import org.sosy_lab.java_smt.basicimpl.AbstractNumeralFormulaManager.NonLinearArithmetic; import org.sosy_lab.java_smt.basicimpl.AbstractSolverContext; -@Options(prefix = "solver.yices2") public class Yices2SolverContext extends AbstractSolverContext { + @Options(prefix = "solver.yices2") + private static class Yices2Parameters { + @Option( + secure = true, + description = "Backend to use for the solver", + values = {"dpllt", "mcsat"}) + String solverType = "mcsat"; + + Yices2Parameters(Configuration config) throws InvalidConfigurationException { + config.inject(this); + } + } + private final Yices2FormulaCreator creator; private final BooleanFormulaManager bfmgr; private final ShutdownNotifier shutdownManager; + private final Yices2Parameters parameters; private static int numLoadedInstances = 0; private boolean closed = false; - @Option( - secure = true, - description = "Always use MCSat solver, instead of the normal DPLLT based solver.") - private boolean forceMCSat = true; - - public Yices2SolverContext( + private Yices2SolverContext( FormulaManager pFmgr, Yices2FormulaCreator creator, BooleanFormulaManager pBfmgr, - ShutdownNotifier pShutdownManager) { + ShutdownNotifier pShutdownManager, + Yices2Parameters pParameters) { super(pFmgr); this.creator = creator; bfmgr = pBfmgr; shutdownManager = pShutdownManager; + parameters = pParameters; } public static Yices2SolverContext create( + Configuration pConfig, NonLinearArithmetic pNonLinearArithmetic, ShutdownNotifier pShutdownManager, - Consumer pLoader) { + Consumer pLoader) + throws InvalidConfigurationException { pLoader.accept("yices2java"); @@ -66,6 +80,8 @@ public static Yices2SolverContext create( numLoadedInstances++; } + Yices2Parameters params = new Yices2Parameters(pConfig); + Yices2FormulaCreator creator = new Yices2FormulaCreator(); Yices2UFManager functionTheory = new Yices2UFManager(creator); Yices2BooleanFormulaManager booleanTheory = new Yices2BooleanFormulaManager(creator); @@ -87,7 +103,7 @@ public static Yices2SolverContext create( bitvectorTheory, quantTheory, arrayTheory); - return new Yices2SolverContext(manager, creator, booleanTheory, pShutdownManager); + return new Yices2SolverContext(manager, creator, booleanTheory, pShutdownManager, params); } @Override @@ -115,13 +131,14 @@ public synchronized void close() { @Override protected ProverEnvironment newProverEnvironment0(Set pOptions) { - return new Yices2Prover(creator, pOptions, bfmgr, shutdownManager, forceMCSat); + return new Yices2Prover(creator, pOptions, bfmgr, shutdownManager, parameters.solverType); } @Override protected InterpolatingProverEnvironment newProverEnvironmentWithInterpolation0( Set pOptions) { - return new Yices2InterpolatingProver(creator, pOptions, bfmgr, shutdownManager, forceMCSat); + return new Yices2InterpolatingProver( + creator, pOptions, bfmgr, shutdownManager, parameters.solverType); } @Override From 3d806099add6e53fb3d12a28869329124d69831b Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Tue, 10 Mar 2026 15:10:06 +0100 Subject: [PATCH 50/93] Yices: Update build instructions --- doc/Developers-How-to-Release-into-Ivy.md | 30 ++++++++++++++--------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/doc/Developers-How-to-Release-into-Ivy.md b/doc/Developers-How-to-Release-into-Ivy.md index f3d6178796..e74fe2215a 100644 --- a/doc/Developers-How-to-Release-into-Ivy.md +++ b/doc/Developers-How-to-Release-into-Ivy.md @@ -341,14 +341,14 @@ ant publish-optimathsat \ Yices2 consists of two components: the solver binary and the Java components in JavaSMT. The Java components were split from the rest of JavaSMT because of the GPL. -#### Publishing the solver binary for Yices2 +#### 1. Publishing the solver binary for Yices2 We recommend using one of our Ubuntu docker images for building Yices2 as the container already contains one of the dependencies (`gmp`) in a precompiled version. The following instructions will still work without the image, however, some of the paths may have to be adjusted, and `gmp` needs to be downloaded and compiled (with `PIC` support) separately -#### MCSAT build +#### a) Dependencies First we need to fetch and build two dependencies: @@ -378,19 +378,30 @@ make -j make install ``` -#### Yices +#### b) Yices Then we can build the actual solver: ```shell +git clone https://github.com/SRI-CSL/yices2.git +cd yices2 LDFLAGS="-L/dependencies/gmp-6.3.0/install/x64-linux/lib -L/workspace/libpoly/install/lib -L/workspace/cudd/install/lib" \ CFLAGS="-I/dependencies/gmp-6.3.0/install/x64-linux/include -I/workspace/libpoly/install/include -I/workspace/cudd/install/include" \ -./configure --enable-mcsat --prefix=/workspace/yices2/install +./configure --enable-mcsat --enable-thread-safety --prefix=/workspace/yices2/install make -j make install ``` -#### JavaSMT solver binary +#### c) Yices Java bindings + +```shell +git clone https://github.com/daniel-raffler/yices2_java_bindings.git +cd yices2_java_bindings +# Patch the Makefile +ant install +``` + +#### d) JavaSMT solver binary First, get the version of Yices2: ```bash @@ -400,17 +411,12 @@ git describe --tags Then publish the solver binary from within JavaSMT: ```shell -ant publish-yices2 \ - -Dyices2.path=/workspace/yices2/install \ - -Dgmp.path=/dependencies/gmp-6.3.0/install/x64-linux \ - -Dlibpoly.path=/workspace/libpoly/install \ - -Dcudd.path=/workspace/cudd/install \ - -Dyices2.version=${VERSION} +ant publish-yices2 -Dyices2_java.path=/workspace/yices2_java_bindings -Dyices2.version=${VERSION} ``` Afterward, you need to update the version number in `solvers_ivy_conf/ivy_javasmt_yices2.xml` and publish new Java components for Yices2. -#### Publish the Java components for Yices2 +#### 2. Publish the Java components for Yices2 Info: There is a small cyclic dependency: JavaSMT itself depends on the Java components of Yices2. From bbf18f3f6649ab7e2725f4c9eb7f7dd92b39b76e Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Wed, 11 Mar 2026 18:04:12 +0100 Subject: [PATCH 51/93] Yices: Add a build script --- build/build-publish-solvers/solver-yices.xml | 130 ++++++++++++++++++- 1 file changed, 125 insertions(+), 5 deletions(-) diff --git a/build/build-publish-solvers/solver-yices.xml b/build/build-publish-solvers/solver-yices.xml index ea5081f88b..5760fa48cd 100644 --- a/build/build-publish-solvers/solver-yices.xml +++ b/build/build-publish-solvers/solver-yices.xml @@ -15,18 +15,138 @@ SPDX-License-Identifier: Apache-2.0 + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - Please specify the Yices2 version with the flag -Dyices2.version=... . - - + + From 6a9b40c0cf911812b2a810127028fcd75e889cff Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Wed, 11 Mar 2026 18:13:34 +0100 Subject: [PATCH 52/93] Yices: Add yices patch --- lib/native/source/yices2/yices2.patch | 48 +++++++++++++++++++ lib/native/source/yices2/yices2.patch.license | 7 +++ 2 files changed, 55 insertions(+) create mode 100644 lib/native/source/yices2/yices2.patch create mode 100644 lib/native/source/yices2/yices2.patch.license diff --git a/lib/native/source/yices2/yices2.patch b/lib/native/source/yices2/yices2.patch new file mode 100644 index 0000000000..9da0ee7621 --- /dev/null +++ b/lib/native/source/yices2/yices2.patch @@ -0,0 +1,48 @@ +Index: src/main/java/com/sri/yices/Makefile +diff --git a/src/main/java/com/sri/yices/Makefile b/src/main/java/com/sri/yices/Makefile +--- a/src/main/java/com/sri/yices/Makefile (revision 2be85e119b6004cc489172568398582268a4f59d) ++++ b/src/main/java/com/sri/yices/Makefile (date 1773243769420) +@@ -56,9 +56,10 @@ + # we ignore versions and soname for now + + # default include directories for jni.h and jni_md.h +-CPPFLAGS := -I $(JAVA_HOME)/include -I $(JAVA_HOME)/include/$(OS) ++CPPFLAGS := -I $(JAVA_HOME)/include -I $(JAVA_HOME)/include/$(OS) -I $(GMP_PATH)/include -I $(YICES_PATH)/include + CXXFLAGS := -g -fPIC +-LIBS := -lyices -lgmp ++LDFLAGS := -L $(YICES_PATH)/lib -L $(CUDD_PATH)/lib -L $(POLY_PATH)/lib -L $(GMP_PATH)/lib ++LIBS := -lyices -lcudd -lpoly -lgmpxx -lgmp + + CXX ?= g++ + +@@ -86,7 +87,7 @@ + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -dynamiclib -o $@ yicesJNI.o $(LIBS) + + libyices2java.so: yicesJNI.o +- $(CXX) $(CFLAGS) $(LDFLAGS) -shared -o $@ yicesJNI.o $(LIBS) ++ $(CXX) $(CFLAGS) $(LDFLAGS) -o $@ yicesJNI.o -shared -Wl,-soname,libyices2java.so -Wl,-Bstatic $(LIBS) -static-libstdc++ -lstdc++ -Wl,-Bdynamic -lc -lm -Wl,--version-script=libyices2java.version + + LIBDIR := $(YICES_JNI) + +Index: src/main/java/com/sri/yices/libyices2java.version +diff --git a/src/main/java/com/sri/yices/libyices2java.version b/src/main/java/com/sri/yices/libyices2java.version +new file mode 100644 +--- /dev/null (date 1773151156723) ++++ b/src/main/java/com/sri/yices/libyices2java.version (date 1773151156723) +@@ -0,0 +1,4 @@ ++YICES2JAVA { ++ global: Java_*; ++ local: *; ++}; +Index: src/main/java/com/sri/yices/Yices.java +diff --git a/src/main/java/com/sri/yices/Yices.java b/src/main/java/com/sri/yices/Yices.java +--- a/src/main/java/com/sri/yices/Yices.java (revision 2be85e119b6004cc489172568398582268a4f59d) ++++ b/src/main/java/com/sri/yices/Yices.java (date 1773078497837) +@@ -13,7 +13,6 @@ + */ + static { + try { +- System.loadLibrary("yices2java"); + init(); + is_ready = true; + } catch (LinkageError e) { diff --git a/lib/native/source/yices2/yices2.patch.license b/lib/native/source/yices2/yices2.patch.license new file mode 100644 index 0000000000..3191e1cf83 --- /dev/null +++ b/lib/native/source/yices2/yices2.patch.license @@ -0,0 +1,7 @@ +// This file is part of JavaSMT, +// an API wrapper for a collection of SMT solvers: +// https://github.com/sosy-lab/java-smt +// +// SPDX-FileCopyrightText: 2026 Dirk Beyer +// +// SPDX-License-Identifier: Apache-2.0 OR MIT From bb4b9d2bc810e8e0d86194754e32f7b4e54f092e Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Thu, 12 Mar 2026 10:07:30 +0100 Subject: [PATCH 53/93] Yices: Remove dead code --- .../java_smt/solvers/yices2/Yices2FormulaCreator.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java index 61cf16d531..69822a6ed1 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java @@ -894,11 +894,6 @@ private static List getMultiplyArgs(int parent, boolean isBV) { return builder.build(); } - /** get "index" and "b" from "(bit index b)". */ - private static List getBitArgs(int parent) { - return ImmutableList.of(Terms.projArg(parent), Terms.intConst(Terms.projIndex(parent))); - } - @Override public Integer callFunctionImpl(Integer pDeclaration, List pArgs) { if (Terms.isFunction(pDeclaration)) { From dd62a9a6a0cd90790a2013b23eba0d4c977e831d Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Thu, 12 Mar 2026 11:08:47 +0100 Subject: [PATCH 54/93] Yices: Turn missing native tests back on --- .../solvers/yices2/Yices2FormulaCreator.java | 5 +- .../java_smt/solvers/yices2/Yices2Model.java | 5 +- .../solvers/yices2/Yices2NativeApiTest.java | 133 +++++++----------- 3 files changed, 58 insertions(+), 85 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java index 69822a6ed1..af976540b1 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java @@ -953,7 +953,8 @@ private Object parseNumeralValue(Integer pF, FormulaType type) { * *

Assumes "little endian" encoding */ - BigInteger bitsToInteger(boolean[] bits) { + static BigInteger bitsToInteger(boolean[] bits) { + // FIXME We're treating the bv as unsigned. Should we return a signed value instead? var value = BigInteger.ZERO; for (var p = 0; p < bits.length; p++) { if (bits[p]) { @@ -968,7 +969,7 @@ BigInteger bitsToInteger(boolean[] bits) { * *

Inverse of {@link #bitsToInteger} */ - boolean[] integerToBits(int bitsize, BigInteger value) { + static boolean[] integerToBits(int bitsize, BigInteger value) { checkArgument(bitsize >= value.bitLength()); var bits = new boolean[bitsize]; diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Model.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Model.java index 58d281bd92..0ae70649b3 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Model.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Model.java @@ -134,7 +134,7 @@ private Object toValue(YVal value, int type) { return Rational.of(rational.getNumerator(), rational.getDenominator()); } case BV: - return formulaCreator.bitsToInteger(model.bvValue(value)); + return Yices2FormulaCreator.bitsToInteger(model.bvValue(value)); default: throw new IllegalArgumentException("Unexpected value type: " + value.tag); } @@ -150,7 +150,8 @@ private int constantValue(Object value, int type) { var rational = (Rational) value; return Terms.rationalConst(rational.getNum(), rational.getDen()); } else if (Types.isBitvector(type)) { - return Terms.bvConst(formulaCreator.integerToBits(Types.bvSize(type), (BigInteger) value)); + return Terms.bvConst( + Yices2FormulaCreator.integerToBits(Types.bvSize(type), (BigInteger) value)); } else { throw new IllegalArgumentException("Unexpected type: " + Types.toString(type)); } diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java index aef18ef04f..f359e1198a 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java @@ -11,12 +11,16 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; +import com.google.common.collect.ImmutableList; +import com.sri.yices.BigRational; import com.sri.yices.Config; import com.sri.yices.Constructor; import com.sri.yices.Context; import com.sri.yices.InterpolationContext; import com.sri.yices.Parameters; +import com.sri.yices.ProductComponent; import com.sri.yices.Status; +import com.sri.yices.SumComponent; import com.sri.yices.Terms; import com.sri.yices.Types; import com.sri.yices.Yices; @@ -138,15 +142,11 @@ public void wrongType() { @Test public void testRange() { - /* - int intmax = yices_int32(Integer.MAX_VALUE); - int longmax = yices_int64(Long.MAX_VALUE); - int gt = yices_arith_gt_atom(longmax, intmax); + int longmax = Terms.intConst(Long.MAX_VALUE); + int verylong = Terms.intConst(BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE)); + int gt = Terms.arithGt(verylong, longmax); env.assertFormula(gt); - assertThat(env.check()).isEqualTo(SAT); - - */ - throw new AssertionError("yices_int32 not supported"); + assertThat(env.check()).isEqualTo(Status.SAT); } @Test @@ -395,80 +395,56 @@ public void arithSimplification() { @Test public void sumComponents() { - /* int three = Terms.intConst(3); - int rat = Terms.parseRational("3/2"); - int x = Terms.newUninterpretedTerm(Types.intType(), "x"); - int[] oneX = {three, x}; - int sumOneX = yices_sum(2, oneX); - for (int i = 0; i < Terms.numChildren(sumOneX); i++) { - assertThat(Terms.toString(sumOneX)).isNotNull(); - assertThat(Arrays.toString(yices_sum_component(sumOneX, i))).isNotNull(); - } - int[] twoX = {three, x, x}; - int sumTwoX = yices_sum(3, twoX); - for (int i = 0; i < Terms.numChildren(sumTwoX); i++) { - assertThat(Terms.toString(sumTwoX)).isNotNull(); - assertThat(Arrays.toString(yices_sum_component(sumTwoX, i))).isNotNull(); - } - int[] twoThrees = {three, x, three}; - int sumTwoThrees = yices_sum(3, twoThrees); - for (int i = 0; i < Terms.numChildren(sumTwoThrees); i++) { - assertThat(Terms.toString(sumTwoThrees)).isNotNull(); - assertThat(Arrays.toString(yices_sum_component(sumTwoThrees, i))).isNotNull(); - } - int xTimesRational = Terms.bvMul(rat, x); - int[] ratSum = {three, xTimesRational}; - int sumRatX = yices_sum(2, ratSum); - for (int i = 0; i < Terms.numChildren(sumRatX); i++) { - assertThat(Terms.toString(sumRatX)).isNotNull(); - assertThat(Arrays.toString(yices_sum_component(sumRatX, i))).isNotNull(); - } - */ - throw new AssertionError("sums not supported"); + int x = Terms.newUninterpretedTerm("x", Types.intType()); + int xTimesRational = Terms.mul(x, Terms.parseRational("3/2")); + + int add = Terms.add(ImmutableList.of(three, xTimesRational)); + + assertThat(Terms.constructor(add)).isEqualTo(Constructor.ARITH_SUM); + assertThat(Terms.numChildren(add)).isEqualTo(2); + + @SuppressWarnings("unchecked") + SumComponent component1 = (SumComponent) Terms.projSum(add, 0); + // Coefficient is 3 + assertThat(component1.getFactor()).isEqualTo(new BigRational("3")); + // Term id is NULL (-1) for i = 0 + assertThat(component1.getTerm()).isEqualTo(-1); + + @SuppressWarnings("unchecked") + SumComponent component2 = (SumComponent) Terms.projSum(add, 1); + // Coefficient is 3/2 + assertThat(component2.getFactor()).isEqualTo(new BigRational("3/2")); + // Term is x for i = 1 + assertThat(component2.getTerm()).isEqualTo(x); } @Test public void bvSumComponents() { - /* String bv1StringValue = "00101"; int bv1 = Terms.parseBvBin(bv1StringValue); - int bv5type = Types.bvType(5); - int x = Terms.newUninterpretedTerm(bv5type, "x"); + int x = Terms.newUninterpretedTerm("x", Types.bvType(5)); int negativeX = Terms.bvMul(Terms.bvMinusOne(5), x); int add = Terms.bvAdd(bv1, negativeX); + + assertThat(Terms.constructor(add)).isEqualTo(Constructor.BV_SUM); assertThat(Terms.numChildren(add)).isEqualTo(2); - assertThat(Terms.toString(add)).isNotNull(); - - int[] component1 = yices_bvsum_component(add, 0, Terms.bitSize(add)); - String value1 = - Joiner.on("") - .join( - Lists.reverse( - Ints.asList(Arrays.copyOfRange(component1, 0, component1.length - 1)))); - int term1 = component1[component1.length - 1]; - // Value of coefficient - assertThat(value1).isEqualTo(bv1StringValue); + + @SuppressWarnings("unchecked") + SumComponent component1 = (SumComponent) Terms.projSum(add, 0); + BigInteger coeff1 = Yices2FormulaCreator.bitsToInteger(component1.getFactor()); // Coefficient as BigInt - assertThat(new BigInteger(value1, 2)).isEqualTo(BigInteger.valueOf(5)); + assertThat(coeff1).isEqualTo(new BigInteger(bv1StringValue, 2)); // Term id is NULL (-1) for i = 0 - assertThat(term1).isEqualTo(-1); - - int[] component2 = yices_bvsum_component(add, 1, Terms.bitSize(add)); - String value2 = - Joiner.on("") - .join( - Lists.reverse( - Ints.asList(Arrays.copyOfRange(component2, 0, component2.length - 1)))); - int term2 = component2[component2.length - 1]; - // Value of coefficient (-1 == 11111) - assertThat(value2).isEqualTo("11111"); + assertThat(component1.getTerm()).isEqualTo(-1); + + @SuppressWarnings("unchecked") + SumComponent component2 = (SumComponent) Terms.projSum(add, 1); + BigInteger coeff2 = Yices2FormulaCreator.bitsToInteger(component2.getFactor()); // Coefficient as BigInt (31 because it has no sign bit, and -1 is max for bv) - assertThat(new BigInteger(value2, 2)).isEqualTo(BigInteger.valueOf(31)); - // Term id is NULL (-1) for i = 0 - assertThat(term2).isEqualTo(x); - */ - throw new AssertionError("sums not supported"); + assertThat(coeff2).isEqualTo(BigInteger.valueOf(31)); + // Term is x for i = 1 + assertThat(component2.getTerm()).isEqualTo(x); } @SuppressWarnings("CheckReturnValue") @@ -480,12 +456,9 @@ public void bvExtensionStructureTest() { int signExtendedX = Terms.bvSignExtend(x, extendBy); int zeroExtendedX = Terms.bvZeroExtend(x, extendBy); - assertThat(Terms.toString(x)).isNotNull(); assertThat(Terms.numChildren(x)).isEqualTo(0); assertThat(Terms.numChildren(signExtendedX)).isEqualTo(initialSize + extendBy); - assertThat(Terms.toString(signExtendedX)).isNotNull(); assertThat(Terms.numChildren(zeroExtendedX)).isEqualTo(initialSize + extendBy); - assertThat(Terms.toString(zeroExtendedX)).isNotNull(); int bvSignExt = Terms.projArg(Terms.child(signExtendedX, 0)); int bvSizeSignExt = Terms.bitSize(bvSignExt); @@ -523,18 +496,16 @@ public void bvSum() { @Test public void bvMul() { - /* int type = Types.bvType(5); - int bv2 = Terms.newUninterpretedTerm(type, "x"); + int bv2 = Terms.newUninterpretedTerm("x", type); int mul = Terms.bvMul(bv2, bv2); assertThat(Terms.constructor(mul)).isEqualTo(Constructor.POWER_PRODUCT); - // bv2 + bv2 == bv2² - int[] component = yices_product_component(mul, 0); - assertThat(component[0]).isEqualTo(bv2); - assertThat(component[1]).isEqualTo(2); - assertThat(Terms.constructor(yices_bvpower(component[0], component[1]))).isGreaterThan(0); - */ - throw new AssertionError("products not supported"); + // bv2 * bv2 == bv2² + ProductComponent component = Terms.projProduct(mul, 0); + assertThat(component.getTerm()).isEqualTo(bv2); + assertThat(component.getPower()).isEqualTo(2); + assertThat(Terms.constructor(Terms.bvPower(component.getTerm(), component.getPower()))) + .isEqualTo(Constructor.POWER_PRODUCT); } @Test From fc78997fb19f4689c1bf328cd1beff517ba71e7c Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Fri, 13 Mar 2026 10:51:10 +0100 Subject: [PATCH 55/93] Yices: Update tests Segfaults have been fixed by https://github.com/SRI-CSL/yices2/pull/614 --- src/org/sosy_lab/java_smt/test/ModelTest.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/org/sosy_lab/java_smt/test/ModelTest.java b/src/org/sosy_lab/java_smt/test/ModelTest.java index bf4e13184d..d9c51fe02f 100644 --- a/src/org/sosy_lab/java_smt/test/ModelTest.java +++ b/src/org/sosy_lab/java_smt/test/ModelTest.java @@ -1252,8 +1252,6 @@ public void testGetArrays3IntegerNoParsing() throws SolverException, Interrupted requireArrays(); requireArrayModel(); - assertThat(solver).isNotEqualTo(Solvers.YICES2); // FIXME - // (= (select (select (select arr 5) 3) 1) x) // (= x 123)" ArrayFormulaType innerType = @@ -1838,8 +1836,6 @@ public void testArrayWithManyValues() throws SolverException, InterruptedExcepti requireArrays(); requireArrayModel(); - assertThat(solver).isNotEqualTo(Solvers.YICES2); // FIXME - // Let's store N values into an array and check that each one is in the model. // The example array formula is: for x in [1...N]: arr = store(arr, i_x, x) // as SMTLIB: arr = store(store(store(... store(array, 0, 0), 1, 1), ... , N-1, N-1) @@ -2615,7 +2611,6 @@ public void testArray1BvBV() { requireArrays(); requireBitvectors(); - assertThat(solver).isNotEqualTo(Solvers.YICES2); // FIXME Segfaults assume().that(solver).isNotEqualTo(Solvers.BOOLECTOR); // Doesn't support multiple indices var bitvectorType = FormulaType.getBitvectorTypeWithSize(8); @@ -2639,7 +2634,6 @@ public void testArray2BvBv() { requireBitvectors(); assume().that(solver).isNotEqualTo(Solvers.BOOLECTOR); // Doesn't support multiple indices - assume().that(solver).isNotEqualTo(Solvers.YICES2); // Yices does not give nested array models // Test for 2d bitvector arrays with formula like: // array[1][7] = 10 and array[3][2] = 5 and array[5][4] = 20 @@ -2685,6 +2679,10 @@ public void testArrayStore1BvBvBv() { assume().that(solver).isNotEqualTo(Solvers.BOOLECTOR); // Doesn't support multiple indices assume().that(solver).isNotEqualTo(Solvers.CVC4); // FIXME Broken in JavaSMT + assume() + .withMessage("Yices does not support constant arrays when mcsat is used") + .that(solver) + .isNotEqualTo(Solvers.YICES2); var scalarType = FormulaType.getBitvectorTypeWithSize(8); @@ -2726,8 +2724,10 @@ public void testArrayStore2BvBvBv() { requireBitvectors(); assume().that(solver).isNotEqualTo(Solvers.BOOLECTOR); // Doesn't support multiple indices - assume().that(solver).isNotEqualTo(Solvers.YICES2); // Yices does not give nested array models - + assume() + .withMessage("Yices does not support constant arrays when mcsat is used") + .that(solver) + .isNotEqualTo(Solvers.YICES2); // FIXME CVC4 array model is sometimes broken in JavaSMT. Unfixable in CVC4, fixed in CVC5. assume().that(solver).isNotEqualTo(Solvers.CVC4); @@ -2808,8 +2808,6 @@ public void testArray1IntInt() { requireArrayModel(); requireIntegers(); - assertThat(solver).isNotEqualTo(Solvers.YICES2); // FIXME - var array = amgr.makeArray("array", IntegerType, FormulaType.getArrayType(IntegerType, IntegerType)); @@ -2832,6 +2830,10 @@ public void testArrayStore1IntIntInt() { requireConstArrays(); assume().that(solver).isNotEqualTo(Solvers.CVC4); // FIXME Broken in JavaSMT + assume() + .withMessage("Yices does not support constant arrays when mcsat is used") + .that(solver) + .isNotEqualTo(Solvers.YICES2); var scalarType = FormulaType.IntegerType; @@ -2867,8 +2869,6 @@ public void testArray2IntInt() { requireArrayModel(); requireIntegers(); - assertThat(solver).isNotEqualTo(Solvers.YICES2); // FIXME - var array = amgr.makeArray("array", IntegerType, FormulaType.getArrayType(IntegerType, IntegerType)); From c984dee73b97a0b190fd371042b5d86975297884 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Fri, 13 Mar 2026 11:05:30 +0100 Subject: [PATCH 56/93] Yices: Update more model tests --- src/org/sosy_lab/java_smt/test/ModelTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/org/sosy_lab/java_smt/test/ModelTest.java b/src/org/sosy_lab/java_smt/test/ModelTest.java index d9c51fe02f..beb0adc814 100644 --- a/src/org/sosy_lab/java_smt/test/ModelTest.java +++ b/src/org/sosy_lab/java_smt/test/ModelTest.java @@ -267,6 +267,10 @@ public void testGetInts() throws SolverException, InterruptedException { @Test public void testGetBvUfs() throws SolverException, InterruptedException { requireBitvectors(); + assume() + .withMessage("Yices uses a default value for the function and returns no mappings") + .that(solver) + .isNotEqualTo(Solvers.YICES2); // Some names are specifically chosen to test the Boolector model // Use 1 instead of 0 or max bv value, as solvers tend to use 0, min or max as default for (String ufName : VARIABLE_NAMES) { @@ -380,6 +384,10 @@ public void testGetUFsWithMultipleAssignments() throws SolverException, Interrup @Test public void testGetUFwithMoreParams() throws Exception { + assume() + .withMessage("Yices uses a default value for the function and returns no mappings") + .that(solver) + .isNotEqualTo(Solvers.YICES2); // Boolector does not support integers if (imgr != null) { IntegerFormula x = From 91c9f424b54ca53993776b8ff0c6e14293b0e7de Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Fri, 13 Mar 2026 11:23:39 +0100 Subject: [PATCH 57/93] Yices: Check shutdown notifier before interpolating, and print a better error message if interpolation fails --- .../solvers/yices2/Yices2InterpolatingProver.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java index 86f4995e56..10f5bef466 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java @@ -65,7 +65,8 @@ public BooleanFormula getInterpolant(Collection formulasOfA) FluentIterable.from(setB).transform(stack.peekLast()::get).toSet())); } - private int interpolate(Collection setA, Collection setB) { + private int interpolate(Collection setA, Collection setB) + throws InterruptedException { try (var ctxA = newContext("mcsat"); var ctxB = newContext("mcsat")) { @@ -74,12 +75,14 @@ private int interpolate(Collection setA, Collection setB) { var context = new InterpolationContext(ctxA, ctxB); // TODO How to abort this? + // For now, let's just check before and after the call: + shutdownNotifier.shutdownIfNecessary(); var status = context.check(DEFAULT_PARAMS, false); + shutdownNotifier.shutdownIfNecessary(); if (status == Status.UNSAT) { return context.getInterpolant(); } else { - // TODO - throw new IllegalArgumentException(); + throw new IllegalArgumentException("Solver state must be unsat"); } } } From e0aa8fb15bf7ca07a6d26b5f1e65a06389251ced Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Fri, 13 Mar 2026 12:00:25 +0100 Subject: [PATCH 58/93] Yices: Turn a model test back on The test still takes several seconds, but no longer seems to hang --- src/org/sosy_lab/java_smt/test/ArrayFormulaManagerTest.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/org/sosy_lab/java_smt/test/ArrayFormulaManagerTest.java b/src/org/sosy_lab/java_smt/test/ArrayFormulaManagerTest.java index bac5bf45b0..5e7b2be9f4 100644 --- a/src/org/sosy_lab/java_smt/test/ArrayFormulaManagerTest.java +++ b/src/org/sosy_lab/java_smt/test/ArrayFormulaManagerTest.java @@ -8,7 +8,6 @@ package org.sosy_lab.java_smt.test; -import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.TruthJUnit.assume; import static org.sosy_lab.java_smt.api.FormulaType.IntegerType; import static org.sosy_lab.java_smt.api.FormulaType.RationalType; @@ -250,9 +249,7 @@ public void testArrayConstBvWithDefault() throws SolverException, InterruptedExc @Test public void testArrayWithManyValues() throws SolverException, InterruptedException { - // FIXME Regression after the bug fix (used to be slow already..) - assertThat(solver).isNotEqualTo(Solvers.YICES2); - + requireIntegers(); requireArrays(); From 68ed6fe36104fb7a198ce6763772134e913c2435 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Fri, 13 Mar 2026 14:26:14 +0100 Subject: [PATCH 59/93] Yices: Update build docs --- doc/Developers-How-to-Release-into-Ivy.md | 114 +++++++++++----------- lib/ivy.xml | 1 - 2 files changed, 56 insertions(+), 59 deletions(-) diff --git a/doc/Developers-How-to-Release-into-Ivy.md b/doc/Developers-How-to-Release-into-Ivy.md index e74fe2215a..8fd0db1ada 100644 --- a/doc/Developers-How-to-Release-into-Ivy.md +++ b/doc/Developers-How-to-Release-into-Ivy.md @@ -343,89 +343,87 @@ The Java components were split from the rest of JavaSMT because of the GPL. #### 1. Publishing the solver binary for Yices2 -We recommend using one of our Ubuntu docker images for building Yices2 as the container already -contains one of the dependencies (`gmp`) in a precompiled version. The following instructions will -still work without the image, however, some of the paths may have to be adjusted, and `gmp` -needs to be downloaded and compiled (with `PIC` support) separately +We expect one of the Ubuntu docker images to be used for building Yices2. While it's possible to +build the backend without the container, our build script relies on a preinstalled +dependency that is already included when using the docker image. Without it, some paths +would have to be changed, and the user would have to provide their own version of the dependency -#### a) Dependencies +#### 1. Build the Yices binaries -First we need to fetch and build two dependencies: +We provide a build script for Yices: +```shell +ant publish-yices2 -Dyices2.version=2.8.0-prerelease +``` -- libpoly: +The script will fetch all dependencies, download and compile Yices, and then build the JNI bindings +that are needed to use the solver from Java -```shell -git clone https://github.com/SRI-CSL/libpoly.git -cd libpoly -cmake .. -DCMAKE_BUILD_TYPE="Release" \ - -DCMAKE_INSTALL_PREFIX=/workspace/libpoly/install \ - -DGMP_INCLUDE_DIR=/dependencies/gmp-6.3.0/install/x64-linux/include \ - -DGMP_LIBRARY=/dependencies/gmp-6.3.0/install/x64-linux/lib/libgmp.a -make -j -make install +#### 2. Build the JavaSMT backend + +In `solvers_ivy_conf/ivy_javasmt_yices2.xml` update the version of the `javasmt-solver-yices2` +dependency: + +```xml + + ``` -- cudd +Then, in `lib/ivy.xml` start looking for the following section: -```shell -git clone https://github.com/ivmai/cudd.git -cd cudd -export CFLAGS=-fPIC -./configure --prefix=/workspace/cudd/install - -# Then patch `autoconf`, `automake`, etc in the Makefile -make -j -make install +```xml + + ``` -#### b) Yices +Remove the dependency and replace it with the line from `ivy_javasmt_yices2.xml`, except that +`conf` has been changed to `runtime-yices2->solver-yices2`: -Then we can build the actual solver: +```xml -```shell -git clone https://github.com/SRI-CSL/yices2.git -cd yices2 -LDFLAGS="-L/dependencies/gmp-6.3.0/install/x64-linux/lib -L/workspace/libpoly/install/lib -L/workspace/cudd/install/lib" \ -CFLAGS="-I/dependencies/gmp-6.3.0/install/x64-linux/include -I/workspace/libpoly/install/include -I/workspace/cudd/install/include" \ -./configure --enable-mcsat --enable-thread-safety --prefix=/workspace/yices2/install -make -j -make install + ``` -#### c) Yices Java bindings +Then run `ant` to build the project + +Now go to the dependency in `ivy.xml` again and change `conf` back to `runtime->solver-yices2`: +```xml + + +``` + +Then publish the GPL components of JavaSMT: ```shell -git clone https://github.com/daniel-raffler/yices2_java_bindings.git -cd yices2_java_bindings -# Patch the Makefile -ant install +ant publish-artifacts-yices2 -Dversion=yices2.8-prerelease ``` -#### d) JavaSMT solver binary +Finally, return the dependency in `ivy.xml` to its original form, but with the version updated: -First, get the version of Yices2: -```bash -git describe --tags -``` +```xml -Then publish the solver binary from within JavaSMT: + +``` +Optionally, you may now publish a new version of JavaSMT: ```shell -ant publish-yices2 -Dyices2_java.path=/workspace/yices2_java_bindings -Dyices2.version=${VERSION} +ant publish -Dversion=yices-prerelease ``` -Afterward, you need to update the version number in `solvers_ivy_conf/ivy_javasmt_yices2.xml` and publish new Java components for Yices2. - -#### 2. Publish the Java components for Yices2 +#### 3. Publish the packages -Info: There is a small cyclic dependency: JavaSMT itself depends on the Java components of Yices2. +Test the new version, then publish it to svn: +```shell +# Publish Yices solver binaries +svn add repository/org.sosy_lab/javasmt-solver-yices2/*-2.8.0-prerelease* repository/org.sosy_lab/javasmt-solver-yices2/*/*-2.8.0-prerelease* +svn ci repository/org.sosy_lab/javasmt-solver-yices2 -m"publish version 2.8.0-prerelease of Yices Solver" -As long as no API was changed and compilation succeeds, simply execute `ant publish-artifacts-yices2`. +# Publish Yices JavaSMT component +svn add repository/org.sosy_lab/javasmt-yices2/*-yices2.8-prerelease* repository/org.sosy_lab/javasmt-yices2/*/*-yices2.8-prerelease* +svn ci repository/org.sosy_lab/javasmt-yices2 -m"publish version yices2.8-prerelease of Yices Solver" -If the API was changed, we need to break the dependency cycle for the publication and revert this later: -edit `lib/ivy.xml` and replace the dependency towards `javasmt-yices2` with the dependency towards `javasmt-solver-yices2` -(the line can be copied from `solvers_ivy_conf/ivy_javasmt_yices2.xml`). -Then run `ant publish-artifacts-yices2`. -We still need to figure out how to avoid the warning about a dirty repository in that case, e.g. by a temporary commit. +# (Optional) Publish JavaSMT +svn add *-yices-prerelease* +svn ci -m"publish version yices-prerelease of JavaSMT Solver Library" +``` [Ivy Repository]: http://www.sosy-lab.org/ivy/org.sosy_lab/ diff --git a/lib/ivy.xml b/lib/ivy.xml index cf8b2f18d3..1163ddff2b 100644 --- a/lib/ivy.xml +++ b/lib/ivy.xml @@ -203,7 +203,6 @@ SPDX-License-Identifier: Apache-2.0 - From 891c1bafd841360ca913cad8a9b8c36e01ea4556 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Fri, 13 Mar 2026 15:48:56 +0100 Subject: [PATCH 60/93] Format --- doc/Developers-How-to-Release-into-Ivy.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/doc/Developers-How-to-Release-into-Ivy.md b/doc/Developers-How-to-Release-into-Ivy.md index 8fd0db1ada..1c25b86899 100644 --- a/doc/Developers-How-to-Release-into-Ivy.md +++ b/doc/Developers-How-to-Release-into-Ivy.md @@ -364,7 +364,6 @@ In `solvers_ivy_conf/ivy_javasmt_yices2.xml` update the version of the `javasmt- dependency: ```xml - ``` @@ -379,7 +378,6 @@ Remove the dependency and replace it with the line from `ivy_javasmt_yices2.xml` `conf` has been changed to `runtime-yices2->solver-yices2`: ```xml - ``` @@ -388,7 +386,6 @@ Then run `ant` to build the project Now go to the dependency in `ivy.xml` again and change `conf` back to `runtime->solver-yices2`: ```xml - ``` @@ -400,7 +397,6 @@ ant publish-artifacts-yices2 -Dversion=yices2.8-prerelease Finally, return the dependency in `ivy.xml` to its original form, but with the version updated: ```xml - ``` From 0c34471e3613fa79cf7aa67c2441ad65c1812616 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Fri, 13 Mar 2026 22:05:03 +0100 Subject: [PATCH 61/93] Clean up --- build.xml | 1 - .../java_smt/solvers/yices2/Yices2FormulaCreator.java | 11 ++--------- .../java_smt/test/ArrayFormulaManagerTest.java | 1 - 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/build.xml b/build.xml index 38288d786a..47fdf4770a 100644 --- a/build.xml +++ b/build.xml @@ -88,7 +88,6 @@ SPDX-License-Identifier: Apache-2.0 - diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java index e5ca0449c5..5f7352ae54 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java @@ -213,7 +213,6 @@ protected int createNamedVariable(int type, String name) { // Names in Yices2 behave like a stack. The last variable named is retrieved when asking for // a term with a specific name. Since we substitute free vars with bound for quantifiers, // this sometimes mixes them up, hence we track them ourselves. - // FIXME Should we even set it then? Terms.setName(var, name); formulaCache.put(name, type, var); return var; @@ -269,7 +268,6 @@ private String lookupName(int term) { return Terms.getName(term) == null ? "@" + term : Terms.getName(term); } - @SuppressWarnings("deprecation") @Override public R visit(FormulaVisitor pVisitor, Formula pFormula, Integer pF) { Constructor constructor = Terms.constructor(pF); @@ -330,12 +328,9 @@ private R visitQuantifier( private R visitFunctionApplication( FormulaVisitor pVisitor, Formula pFormula, int pF, final Constructor constructor) { - - // throw new UnsupportedOperationException(String.format("Constructor %s", constructor)); - Integer functionDeclaration = null; - // filled later, except for some special function applications String functionName = null; + Integer functionDeclaration = null; List functionArgs = null; List functionIndex = ImmutableList.of(); @@ -517,15 +512,13 @@ private R visitFunctionApplication( private int buildDeclaration( FunctionDeclarationKind pKind, List pIndex, List pArgs) { - // FIXME - // var args = Lists.transform(pArgs, p -> Terms.newVariable(Terms.typeOf(p))); ImmutableList.Builder builder = ImmutableList.builder(); int c = 0; for (var arg : pArgs) { builder.add(Terms.newVariable("var" + c++, Terms.typeOf(arg))); } var args = builder.build(); - Integer f = null; + int f; switch (pKind) { case AND: f = Terms.and(args); diff --git a/src/org/sosy_lab/java_smt/test/ArrayFormulaManagerTest.java b/src/org/sosy_lab/java_smt/test/ArrayFormulaManagerTest.java index 5e7b2be9f4..178d4b73e8 100644 --- a/src/org/sosy_lab/java_smt/test/ArrayFormulaManagerTest.java +++ b/src/org/sosy_lab/java_smt/test/ArrayFormulaManagerTest.java @@ -249,7 +249,6 @@ public void testArrayConstBvWithDefault() throws SolverException, InterruptedExc @Test public void testArrayWithManyValues() throws SolverException, InterruptedException { - requireIntegers(); requireArrays(); From a22273f2509746380c6741f6040ac7c78ebc55c0 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Sat, 14 Mar 2026 10:06:44 +0100 Subject: [PATCH 62/93] Yices: Add comments about failing interpolation tests --- .../java_smt/test/InterpolatingProverTest.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java b/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java index f82b24bb48..36c9ef095d 100644 --- a/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java +++ b/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java @@ -176,8 +176,14 @@ public void binaryInterpolationWithConstantFalse() // some interpolant needs to be FALSE, however, it can be at arbitrary position. BooleanFormula expectedInterpolant = bmgr.makeFalse(); - if (solverToUse() == Solvers.Z3_WITH_INTERPOLATION) { - expectedInterpolant = bmgr.makeTrue(); // LegacyZ3 has an issue here. + if (solverToUse() == Solvers.Z3_WITH_INTERPOLATION || solverToUse() == Solvers.YICES2) { + // FIXME This test seems wrong to me. Solvers are not guaranteed to return an inductive + // sequence if getInterpolant is used multiple times. And even if it was an inductive + // sequence, 'false' doesn't have to appear in it: + // formulas F F F + // interplants T T T F + // (getInterpolants would return [T,T] in this case) + expectedInterpolant = bmgr.makeTrue(); } assertThat( ImmutableList.of( @@ -380,7 +386,11 @@ public void sequentialInterpolationIsNotRepeatedIndividualInterpolation() // sequential interpolation should always work as expected checkItpSequence(ImmutableList.of(A, B, C), itpSeq); - checkItpSequence(ImmutableList.of(A, B, C), ImmutableList.of(itp1, itp2)); + if (solver != Solvers.YICES2) { + // FIXME This is not guaranteed to be an inductive sequence, see the documentation of + // getInterpolant + checkItpSequence(ImmutableList.of(A, B, C), ImmutableList.of(itp1, itp2)); + } } @Test From d32868403f7cc4e5e64b13b2e281b12b3b2b8894 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Sat, 14 Mar 2026 12:24:11 +0100 Subject: [PATCH 63/93] Yices: Add support for arrays with multiple indices --- .../solvers/yices2/Yices2FormulaCreator.java | 6 ++ .../java_smt/solvers/yices2/Yices2Model.java | 59 ++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java index 5f7352ae54..dc6c521a95 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java @@ -978,6 +978,12 @@ private BigInteger parseBitvector(int pF) { return bitsToInteger(Terms.bvConstValue(pF)); } + public boolean isArrayVariable(int term) { + checkArgument(Terms.isFunction(term)); + checkArgument(Terms.isUninterpreted(term)); + return !ufSymbols.contains(term); + } + @Override public Object convertValue(Integer typeKey, Integer pF) { FormulaType type = getFormulaType(typeKey); diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Model.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Model.java index cf8d43ef4e..585539649f 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Model.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Model.java @@ -9,6 +9,8 @@ package org.sosy_lab.java_smt.solvers.yices2; import com.google.common.base.Preconditions; +import com.google.common.base.Verify; +import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableList; import com.sri.yices.Model; import com.sri.yices.Terms; @@ -60,7 +62,11 @@ public ImmutableList asList() { assignments.add(getSimpleAssignment(term)); continue; case FUNCTION: // UFs and Arrays - assignments.addAll(getFunctionAssignment(term, yval)); + if (formulaCreator.isArrayVariable(term)) { + assignments.addAll(getArrayAssignment(term, yval)); + } else { + assignments.addAll(getFunctionAssignment(term, yval)); + } continue; default: throw new UnsupportedOperationException("YVAL with unexpected tag: " + yval.tag); @@ -109,6 +115,57 @@ private ImmutableList getFunctionAssignment(int f, YVal value) return assignments.build(); } + private List getArrayAssignment0( + int f, Iterable arguments, Iterable values, int type, YVal value) { + if (Types.isFunction(type)) { + var signature = Types.children(type); + Verify.verify(signature.length == 2); + var leftType = signature[0]; + var rightType = signature[1]; + + ImmutableList.Builder assignments = ImmutableList.builder(); + for (var map : model.expandFunction(value).vector) { + var app = model.expandMapping(map); + Verify.verify(app.vector.length == 1); + + // Build term for the current index + var leftValue = toValue(app.vector[0], leftType); + var leftTerm = constantValue(leftValue, leftType); + + // Add it to the argument list + var newArguments = FluentIterable.concat(arguments, ImmutableList.of(leftTerm)); + var newValue = FluentIterable.concat(values, ImmutableList.of(leftValue)); + + assignments.addAll(getArrayAssignment0(f, newArguments, newValue, rightType, app.value)); + } + return assignments.build(); + + } else { + // Build term for the left side of the assignment + var app = f; + for (var arg : arguments) { + app = Terms.funApplication(app, arg); + } + + // Build term for the value + var rightValue = toValue(value, type); + var rightTerm = constantValue(rightValue, type); + + return ImmutableList.of( + new ValueAssignment( + creator.encapsulateWithTypeOf(app), + creator.encapsulateWithTypeOf(rightTerm), + creator.encapsulateBoolean(Terms.eq(app, rightTerm)), + Terms.getName(f), + rightValue, + ImmutableList.copyOf(values))); + } + } + + private List getArrayAssignment(int f, YVal value) { + return getArrayAssignment0(f, ImmutableList.of(), ImmutableList.of(), Terms.typeOf(f), value); + } + private ValueAssignment getSimpleAssignment(int t) { List argumentInterpretation = new ArrayList<>(); int valueTerm = model.valueAsTerm(t); From bf748bcd28d8434d545babcd3d56684e25cb61a5 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Sat, 14 Mar 2026 12:47:37 +0100 Subject: [PATCH 64/93] Yices: Set `hasPersistentModel` to true --- .../sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java index 0ae2d5b089..16fbb08797 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java @@ -85,7 +85,7 @@ boolean isClosed() { @Override protected boolean hasPersistentModel() { - return false; + return true; } Context newContext(String solverType) { From c6b1d55f1eb78e525084404cb384b3a4e9aa3a7e Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Sat, 14 Mar 2026 13:41:34 +0100 Subject: [PATCH 65/93] Yices: Make new classes package private --- .../java_smt/solvers/yices2/Yices2InterpolatingProver.java | 4 ++-- src/org/sosy_lab/java_smt/solvers/yices2/Yices2Prover.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java index 10f5bef466..e760f7d21c 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java @@ -31,9 +31,9 @@ import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; import org.sosy_lab.java_smt.api.SolverException; -public class Yices2InterpolatingProver extends Yices2AbstractProver +class Yices2InterpolatingProver extends Yices2AbstractProver implements InterpolatingProverEnvironment { - protected Yices2InterpolatingProver( + Yices2InterpolatingProver( Yices2FormulaCreator creator, Set pOptions, BooleanFormulaManager pBmgr, diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Prover.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Prover.java index c334d4aed1..6c5b976f4d 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Prover.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2Prover.java @@ -18,8 +18,8 @@ import org.sosy_lab.java_smt.api.ProverEnvironment; import org.sosy_lab.java_smt.api.SolverContext.ProverOptions; -public class Yices2Prover extends Yices2AbstractProver implements ProverEnvironment { - protected Yices2Prover( +class Yices2Prover extends Yices2AbstractProver implements ProverEnvironment { + Yices2Prover( Yices2FormulaCreator creator, Set pOptions, BooleanFormulaManager pBmgr, From 56d653d95466ce8994faa7f5a9d3314bb0fdb839 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Sat, 14 Mar 2026 13:50:40 +0100 Subject: [PATCH 66/93] Yices: Use assumption solving wrapper This fixes some corner cases where interpolation isn't available after isUnsatWithAssumptions --- .../sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java index d825b69cde..e2b93fd94f 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java @@ -149,6 +149,6 @@ protected OptimizationProverEnvironment newOptimizationProverEnvironment0( @Override protected boolean supportsAssumptionSolving() { - return true; + return false; } } From 937e03412ceee01a184badb483653d9d161530e4 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Sat, 14 Mar 2026 13:58:58 +0100 Subject: [PATCH 67/93] Yices: Fix issue in getModel when GENERATE_UNSAT_CORE has been set --- .../solvers/yices2/Yices2AbstractProver.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java index 16fbb08797..2e2bb27998 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java @@ -219,7 +219,18 @@ public Model getModel() throws SolverException { @SuppressWarnings("resource") @Override protected Yices2Model getEvaluatorWithoutChecks() { - return new Yices2Model(curEnv.getModel(), this, creator); + if (generateUnsatCores) { + // We didn't push the assertions when we were planning to use getUnsatCore. Because of that + // the SAT check now needs to be repeated to get a model + curEnv.push(); + curEnv.assertFormulas(getAllConstraints()); + curEnv.check(); + var model = curEnv.getModel(); + curEnv.pop(); + return new Yices2Model(model, this, creator); + } else { + return new Yices2Model(curEnv.getModel(), this, creator); + } } private List encapsulate(int[] terms) { From 147ce7c0997bda14d466a41a40cb6c84555e2a9b Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Sat, 14 Mar 2026 14:00:09 +0100 Subject: [PATCH 68/93] Yices: Inline a method --- .../java_smt/solvers/yices2/Yices2AbstractProver.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java index 2e2bb27998..8ba373359e 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2AbstractProver.java @@ -253,10 +253,6 @@ private int[] uncapsulate(Collection terms) { @Override public List getUnsatCore() { checkGenerateUnsatCores(); - return getUnsatCore0(); - } - - private List getUnsatCore0() { return encapsulate(curEnv.getUnsatCore()); } @@ -265,7 +261,7 @@ public Optional> unsatCoreOverAssumptions( Collection pAssumptions) throws SolverException, InterruptedException { checkGenerateUnsatCoresOverAssumptions(); boolean sat = !isUnsatWithAssumptions(pAssumptions); - return sat ? Optional.empty() : Optional.of(getUnsatCore0()); + return sat ? Optional.empty() : Optional.of(encapsulate(curEnv.getUnsatCore())); } @Override From 70a1502ae5446c53ab0a5549696bd31c20b8f1a7 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Sat, 14 Mar 2026 14:13:34 +0100 Subject: [PATCH 69/93] Yices: Add missing newline --- .idea/JavaSMT.iml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.idea/JavaSMT.iml b/.idea/JavaSMT.iml index cd9d86b1ea..7d221c56c9 100644 --- a/.idea/JavaSMT.iml +++ b/.idea/JavaSMT.iml @@ -582,4 +582,4 @@ SPDX-License-Identifier: Apache-2.0 - \ No newline at end of file + From c1b220400c6ba3f722aa29802e4262ac0ed270f4 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Sat, 14 Mar 2026 14:15:52 +0100 Subject: [PATCH 70/93] Yices: Turn the final interpolation test back on The test will hang when using the Intelij runner, but work fine when using `ant tests` --- src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java b/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java index 36c9ef095d..d93d92eae3 100644 --- a/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java +++ b/src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java @@ -468,7 +468,6 @@ public void sequentialInterpolationWithFewPartitions() @Test public void sequentialBVInterpolation() throws SolverException, InterruptedException { - assertThat(solver).isNotEqualTo(Solvers.YICES2); // FIXME requireBitvectors(); InterpolatingProverEnvironment stack = newEnvironmentForTest(); From 46f8cae0a7f2f848b70cad4f784c202e35a09edc Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Sat, 14 Mar 2026 19:18:36 +0100 Subject: [PATCH 71/93] Yices: Use property to skip loading the Yices library --- lib/native/source/yices2/yices2.patch | 12 ------------ .../java_smt/solvers/yices2/Yices2SolverContext.java | 1 + 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/lib/native/source/yices2/yices2.patch b/lib/native/source/yices2/yices2.patch index 9da0ee7621..d4479edca6 100644 --- a/lib/native/source/yices2/yices2.patch +++ b/lib/native/source/yices2/yices2.patch @@ -34,15 +34,3 @@ new file mode 100644 + global: Java_*; + local: *; +}; -Index: src/main/java/com/sri/yices/Yices.java -diff --git a/src/main/java/com/sri/yices/Yices.java b/src/main/java/com/sri/yices/Yices.java ---- a/src/main/java/com/sri/yices/Yices.java (revision 2be85e119b6004cc489172568398582268a4f59d) -+++ b/src/main/java/com/sri/yices/Yices.java (date 1773078497837) -@@ -13,7 +13,6 @@ - */ - static { - try { -- System.loadLibrary("yices2java"); - init(); - is_ready = true; - } catch (LinkageError e) { diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java index e2b93fd94f..ab98cef279 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2SolverContext.java @@ -75,6 +75,7 @@ public static Yices2SolverContext create( // Avoid loading and initializing twice, // because this would make all existing terms and types unavailable, // which is bad behavior and a potential memory leak. + System.setProperty("yices.skipAutoloader", "true"); Yices.isReady(); } numLoadedInstances++; From fd3f4bdc0551b1d44fc2f92dac3696fb405d4e47 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Sun, 15 Mar 2026 10:18:22 +0100 Subject: [PATCH 72/93] Yices: Add ant targets to clean the build --- build/build-publish-solvers/solver-yices.xml | 22 +++++++++++++-- doc/Developers-How-to-Release-into-Ivy.md | 29 ++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/build/build-publish-solvers/solver-yices.xml b/build/build-publish-solvers/solver-yices.xml index 5760fa48cd..86a2a804e3 100644 --- a/build/build-publish-solvers/solver-yices.xml +++ b/build/build-publish-solvers/solver-yices.xml @@ -72,7 +72,6 @@ SPDX-License-Identifier: Apache-2.0 - @@ -115,6 +114,12 @@ SPDX-License-Identifier: Apache-2.0 + + + + + + @@ -122,9 +127,16 @@ SPDX-License-Identifier: Apache-2.0 - + + + + + + + + @@ -137,6 +149,12 @@ SPDX-License-Identifier: Apache-2.0 + + + + + + diff --git a/doc/Developers-How-to-Release-into-Ivy.md b/doc/Developers-How-to-Release-into-Ivy.md index 1c25b86899..a71a448e09 100644 --- a/doc/Developers-How-to-Release-into-Ivy.md +++ b/doc/Developers-How-to-Release-into-Ivy.md @@ -358,6 +358,35 @@ ant publish-yices2 -Dyices2.version=2.8.0-prerelease The script will fetch all dependencies, download and compile Yices, and then build the JNI bindings that are needed to use the solver from Java +We provide additional `ant` targets for a more fine-grained build: + +* `ant build-yices2-java` will build all binaries, but not publish them +* `ant clean-yices2-java` will undo the last build step and delete the JNI bindings +* `ant clean-yices2` will undo the last two build step and delete the Yices binaries and the JNI + bindings + +Changes can then be made to the downloaded source in `downloads` before publishing the binaries +with `ant publish-yices2`. For instance, we could switch to a different branch for Yices: + +``` shell +ant build-yices2-java +ant clean-yices2 +cd downloads/yices2 +git checkout my-branch +cd ../.. +ant publish-yices2 -Dyices2.version=2.8.0-prerelease +``` + +It's also possible to only download the dependencies: + +* `ant download-cudd` +* `ant download-poly` +* `ant download-yices2` +* `ant download-yices2-java` + +Changes can then be made to the downloaded source before publishing. Compared to the first +method, this avoids the needless initial build + #### 2. Build the JavaSMT backend In `solvers_ivy_conf/ivy_javasmt_yices2.xml` update the version of the `javasmt-solver-yices2` From 3635aa50205c21193c580c1a2f1161ca09508ca9 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Sun, 15 Mar 2026 11:57:55 +0100 Subject: [PATCH 73/93] Yices: Use generic methods to handle sum and product terms --- .../solvers/yices2/Yices2FormulaCreator.java | 150 ++++++++++-------- 1 file changed, 82 insertions(+), 68 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java index dc6c521a95..e0a82eb3a5 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java @@ -439,29 +439,29 @@ private R visitFunctionApplication( case BV_SUM: if (Terms.numChildren(pF) == 1) { functionKind = FunctionDeclarationKind.BV_MUL; - functionArgs = getMultiplyBvSumArgsFromSum(pF); + functionArgs = getOnlySumTerm(pF); } else { functionKind = FunctionDeclarationKind.BV_ADD; - functionArgs = getBvSumArgs(pF); + functionArgs = getSumTerms(pF); } break; case ARITH_SUM: if (Terms.numChildren(pF) == 1) { functionKind = FunctionDeclarationKind.MUL; - functionArgs = getMultiplySumArgsFromSum(pF); + functionArgs = getOnlySumTerm(pF); } else { functionKind = FunctionDeclarationKind.ADD; - functionArgs = getSumArgs(pF); + functionArgs = getSumTerms(pF); } break; case POWER_PRODUCT: if (Terms.isBitvector(pF)) { functionKind = FunctionDeclarationKind.BV_MUL; - functionArgs = getMultiplyArgs(pF, true); + functionArgs = getProductFactors(pF); // TODO Product of more then 2 bitvectors ? } else { functionKind = FunctionDeclarationKind.MUL; - functionArgs = getMultiplyArgs(pF, false); + functionArgs = getProductFactors(pF); } break; case BIT_TERM: @@ -488,7 +488,8 @@ private R visitFunctionApplication( functionDeclaration = buildDeclaration(functionKind, functionIndex, functionArgs); } - final ImmutableList> argTypes = ImmutableList.copyOf(toType(functionArgs)); + final ImmutableList> argTypes = + ImmutableList.copyOf(Lists.transform(functionArgs, this::getFormulaType)); Preconditions.checkState( functionArgs.size() == argTypes.size(), @@ -757,10 +758,6 @@ private int buildDeclaration( return Terms.lambda(args, f); } - private List> toType(final List args) { - return Lists.transform(args, this::getFormulaType); - } - /** * Yices transforms EXISTS(x, body) into NOT(FORALL(x, NOT(body))). See * getArgs(int parent) { return children.build(); } - private static List getSumArgs(int parent) { - // TODO Refactor me - ImmutableList.Builder terms = ImmutableList.builder(); - for (int i = 0; i < Terms.numChildren(parent); i++) { - @SuppressWarnings("unchecked") - SumComponent component = (SumComponent) Terms.projSum(parent, i); - - var factor = - Terms.rationalConst( - component.getFactor().getNumerator(), component.getFactor().getDenominator()); - var term = component.getTerm() == Terms.NULL_TERM ? Terms.one() : component.getTerm(); + /** 1 for the given theory. */ + private static int mkOne(int type) { + if (Types.isArithmetic(type)) { + return Terms.one(); + } else if (Types.isBitvector(type)) { + return Terms.bvOne(Types.bvSize(type)); + } else { + throw new IllegalArgumentException(); + } + } - terms.add(Terms.mul(factor, term)); + /** Convert value to constant term. */ + private static int toConstant(Object value) { + if (value instanceof BigRational) { + var rational = (BigRational) value; + if (rational.isInteger()) { + return Terms.intConst(rational.getNumerator()); + } else { + return Terms.rationalConst(rational); + } + } else if (value instanceof boolean[]) { + var array = (boolean[]) value; + ImmutableList.Builder builder = ImmutableList.builder(); + for (var bit : array) { + builder.add(bit ? 1 : 0); + } + return Terms.bvConst(builder.build()); + } else { + throw new IllegalArgumentException(); } - return terms.build(); } - /** extract -1 and X from the sum of one element [-1*x]. */ - private static List getMultiplySumArgsFromSum(int parent) { - // TODO Refactor me - checkArgument(Terms.numChildren(parent) == 1); - @SuppressWarnings("unchecked") - SumComponent component = (SumComponent) Terms.projSum(parent, 0); - var factor = - Terms.rationalConst( - component.getFactor().getNumerator(), component.getFactor().getDenominator()); - checkArgument(component.getTerm() != Terms.NULL_TERM); + /** Multiply two arithmetic or bv terms. */ + private static int mkMultiply(int a, int b) { + if (Terms.isArithmetic(a) && Terms.isArithmetic(b)) { + return Terms.mul(a, b); + } else if (Terms.isBitvector(a) && Terms.isBitvector(b)) { + return Terms.bvMul(a, b); + } else { + throw new IllegalArgumentException(); + } + } - return ImmutableList.of(factor, component.getTerm()); + /* Power of a bv or an arithmetic term. */ + private static int mkPower(int term, int exponent) { + if (Terms.isArithmetic(term)) { + return Terms.power(term, exponent); + } else if (Terms.isBitvector(term)) { + return Terms.bvPower(term, exponent); + } else { + throw new IllegalArgumentException(); + } } - /** extract all entries of a BV sum like "3*x + 2*y + 1". */ - private static List getBvSumArgs(int parent) { - // TODO Refactor me + /** + * Returns a list of terms for a sum. + * + *

Splits a sum a*t1 + b*t2 + ... into a list of terms a*t1, + * b*t2, ... + */ + private static List getSumTerms(int parent) { ImmutableList.Builder terms = ImmutableList.builder(); for (int i = 0; i < Terms.numChildren(parent); i++) { - @SuppressWarnings("unchecked") - SumComponent component = (SumComponent) Terms.projSum(parent, i); - - ImmutableList.Builder builder = ImmutableList.builder(); - for (var bit : component.getFactor()) { - builder.add(bit ? 1 : 0); - } - var factor = Terms.bvConst(builder.build()); + SumComponent component = Terms.projSum(parent, i); + var factor = toConstant(component.getFactor()); var term = component.getTerm() == Terms.NULL_TERM - ? Terms.bvOne(Terms.bitSize(parent)) + ? mkOne(Terms.typeOf(parent)) : component.getTerm(); - terms.add(Terms.bvMul(factor, term)); + terms.add(mkMultiply(factor, term)); } return terms.build(); } - /** extract -1 and X from the sum of one element [-1*x]. */ - private static List getMultiplyBvSumArgsFromSum(int parent) { - // TODO Refactor me + /** + * Returns coefficient and term for a sum with only a single term. + * + *

Splits the sum term Σ a*t into a and t + */ + private static List getOnlySumTerm(int parent) { checkArgument(Terms.numChildren(parent) == 1); - @SuppressWarnings("unchecked") - SumComponent component = (SumComponent) Terms.projSum(parent, 0); - - ImmutableList.Builder builder = ImmutableList.builder(); - for (var bit : component.getFactor()) { - builder.add(bit ? 1 : 0); - } - var factor = Terms.bvConst(builder.build()); + SumComponent component = Terms.projSum(parent, 0); checkArgument(component.getTerm() != Terms.NULL_TERM); - - return ImmutableList.of(factor, component.getTerm()); + return ImmutableList.of(toConstant(component.getFactor()), component.getTerm()); } - private static List getMultiplyArgs(int parent, boolean isBV) { - // TODO Refactor me + /** + * Returns a list of factors for a product term. + * + *

Splits a product a^m * b^n * ... into a list of monomials a^m, + * b^n, ... + */ + private static List getProductFactors(int parent) { ImmutableList.Builder builder = ImmutableList.builder(); for (int i = 0; i < Terms.numChildren(parent); i++) { ProductComponent component = Terms.projProduct(parent, i); - if (isBV) { - builder.add(Terms.bvPower(component.getTerm(), component.getPower())); - } else { - builder.add(Terms.power(component.getTerm(), component.getPower())); - } + builder.add(mkPower(component.getTerm(), component.getPower())); } return builder.build(); } From 764ee9ec07f0f6866327d5b7441f6e144f2058b1 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Tue, 17 Mar 2026 09:11:35 +0100 Subject: [PATCH 74/93] Yices: Add Windows binaries --- build/build-publish-solvers/solver-yices.xml | 149 ++++++++++++++---- lib/native/source/yices2/jni.patch | 91 +++++++++++ ...yices2.patch.license => jni.patch.license} | 0 lib/native/source/yices2/yices.patch | 35 ++++ lib/native/source/yices2/yices.patch.license | 7 + lib/native/source/yices2/yices2.patch | 36 ----- solvers_ivy_conf/ivy_yices2.xml | 5 +- 7 files changed, 257 insertions(+), 66 deletions(-) create mode 100644 lib/native/source/yices2/jni.patch rename lib/native/source/yices2/{yices2.patch.license => jni.patch.license} (100%) create mode 100644 lib/native/source/yices2/yices.patch create mode 100644 lib/native/source/yices2/yices.patch.license delete mode 100644 lib/native/source/yices2/yices2.patch diff --git a/build/build-publish-solvers/solver-yices.xml b/build/build-publish-solvers/solver-yices.xml index 86a2a804e3..0a16c242bc 100644 --- a/build/build-publish-solvers/solver-yices.xml +++ b/build/build-publish-solvers/solver-yices.xml @@ -41,12 +41,12 @@ SPDX-License-Identifier: Apache-2.0 + + + - - - @@ -62,14 +62,32 @@ SPDX-License-Identifier: Apache-2.0 + - + + + + + + + + + + + + + + + + + + @@ -79,17 +97,37 @@ SPDX-License-Identifier: Apache-2.0 + + - + + + + + + + + + + + + + + + + + + + @@ -99,13 +137,19 @@ SPDX-License-Identifier: Apache-2.0 + + + + + + - - + + - + @@ -113,12 +157,47 @@ SPDX-License-Identifier: Apache-2.0 - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -127,33 +206,44 @@ SPDX-License-Identifier: Apache-2.0 - - - - - - - + - - + - - + + + + - - - + + + + + + + + + + + + + + + - + - + + + + + - - + + + diff --git a/lib/native/source/yices2/jni.patch b/lib/native/source/yices2/jni.patch new file mode 100644 index 0000000000..6e1338ac6c --- /dev/null +++ b/lib/native/source/yices2/jni.patch @@ -0,0 +1,91 @@ +Index: build.xml +diff --git a/build.xml b/build.xml +--- a/build.xml (revision 25b03e1858b3ef006bca2532b87510613d8af55f) ++++ b/build.xml (date 1773730694637) +@@ -224,7 +224,6 @@ + +- + + + +Index: src/main/java/com/sri/yices/Makefile +diff --git a/src/main/java/com/sri/yices/Makefile b/src/main/java/com/sri/yices/Makefile +--- a/src/main/java/com/sri/yices/Makefile (revision 25b03e1858b3ef006bca2532b87510613d8af55f) ++++ b/src/main/java/com/sri/yices/Makefile (date 1773727210451) +@@ -31,7 +31,9 @@ + ifeq ($(OS),darwin) + EXTENSION=dylib + else +-ifeq ($(OS),) ++ifeq ($(OS),win32) ++ EXTENSION=dll ++else ifeq ($(OS),) + $(error "Please set $$OS") + else + $(error "Unkown OS: $(OS)") +@@ -48,7 +50,11 @@ + endif + + # name of the library +-libyices2java := libyices2java.$(EXTENSION) ++ifeq ($(OS),win32) ++ libyices2java := yices2java.$(EXTENSION) ++else ++ libyices2java := libyices2java.$(EXTENSION) ++endif + + # install name for darwin + libyices2java_install_name := $(YICES_JNI)/libyices2java.dylib +@@ -56,9 +62,11 @@ + # we ignore versions and soname for now + + # default include directories for jni.h and jni_md.h +-CPPFLAGS := -I $(JAVA_HOME)/include -I $(JAVA_HOME)/include/$(OS) +-CXXFLAGS := -g -fPIC +-LIBS := -lyices -lgmp ++CPPFLAGS := -I $(JNI_PATH) -I $(JNI_PATH)/$(OS) -I $(GMP_PATH)/include -I $(YICES_PATH)/include ++CXXFLAGS := -O3 -fPIC $(CXXFLAGS) ++ ++LDFLAGS := -L $(YICES_PATH)/lib -L $(CUDD_PATH)/lib -L $(POLY_PATH)/lib -L $(GMP_PATH)/lib ++LIBS := -lyices -lcudd -lpoly -lgmpxx -lgmp + + CXX ?= g++ + +@@ -86,7 +94,10 @@ + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -dynamiclib -o $@ yicesJNI.o $(LIBS) + + libyices2java.so: yicesJNI.o +- $(CXX) $(CFLAGS) $(LDFLAGS) -shared -o $@ yicesJNI.o $(LIBS) ++ $(CXX) $(CFLAGS) $(LDFLAGS) -o $@ yicesJNI.o -shared -Wl,-soname,$(libyices2java) -Wl,-Bstatic $(LIBS) -static-libstdc++ -lstdc++ -Wl,-Bdynamic -lc -lm -Wl,--version-script=libyices2java.version ++ ++yices2java.dll: yicesJNI.o ++ $(CXX) $(CFLAGS) $(LDFLAGS) -o $@ yicesJNI.o -shared -Wl,-soname,$(libyices2java) -Wl,-Bstatic,--whole-archive -lpthread -Wl,-Bstatic,--no-whole-archive $(LIBS) -static-libgcc -static-libstdc++ -lstdc++ -Wl,-Bdynamic -lm -Wl,--version-script=libyices2java.version + + LIBDIR := $(YICES_JNI) + +@@ -99,7 +110,10 @@ + install-darwin: + cp $(libyices2java) $(LIBDIR) + ++install-win32: ++ cp $(libyices2java) $(LIBDIR) ++ + clean: +- rm -f *.o *.so *.dylib com_sri_yices_Yices.h *.class ++ rm -f *.o *.so *.dylib *.dll com_sri_yices_Yices.h *.class + +-.PHONY: all clean install install-linux install-darwin ++.PHONY: all clean install install-linux install-darwin install-win32 + +Index: src/main/java/com/sri/yices/libyices2java.version +diff --git a/src/main/java/com/sri/yices/libyices2java.version b/src/main/java/com/sri/yices/libyices2java.version +new file mode 100644 +--- /dev/null (date 1773662010549) ++++ b/src/main/java/com/sri/yices/libyices2java.version (date 1773662010549) +@@ -0,0 +1,4 @@ ++YICES2JAVA { ++ global: Java_*; ++ local: *; ++}; diff --git a/lib/native/source/yices2/yices2.patch.license b/lib/native/source/yices2/jni.patch.license similarity index 100% rename from lib/native/source/yices2/yices2.patch.license rename to lib/native/source/yices2/jni.patch.license diff --git a/lib/native/source/yices2/yices.patch b/lib/native/source/yices2/yices.patch new file mode 100644 index 0000000000..3b2667205c --- /dev/null +++ b/lib/native/source/yices2/yices.patch @@ -0,0 +1,35 @@ +Index: configure.ac +diff --git a/configure.ac b/configure.ac +--- a/configure.ac (revision dc5687ca5964ff44ded1628923b5a878f7a78d59) ++++ b/configure.ac (date 1773697157769) +@@ -174,7 +174,7 @@ + AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[__thread int test;]], + [[]])], +-has_tls=yes,has_tls=no,has_tls=no) ++has_tls=yes,has_tls=no,has_tls=yes) + AC_MSG_RESULT([$has_tls]) + # + # restore CPPFLAGS and LIBS +@@ -660,7 +660,7 @@ + lp_variable_db_detach(var_db); + ]]) + +-],run_ok=yes,run_ok=no,run_ok=no) ++],run_ok=yes,run_ok=no,run_ok=yes) + AC_MSG_RESULT([$run_ok]) + # + # restore CPPFLAGS and LIBS +Index: Makefile +diff --git a/Makefile b/Makefile +--- a/Makefile (revision dc5687ca5964ff44ded1628923b5a878f7a78d59) ++++ b/Makefile (date 1773662227754) +@@ -145,7 +145,7 @@ + newarch=$(subst x86_64,i686,$(ARCH)) + else + ifeq ($(OPTION),mingw32) +- newarch=i686-w64-mingw32 ++ newarch=x86_64-w64-mingw32 + POSIXOS=mingw + endif + endif diff --git a/lib/native/source/yices2/yices.patch.license b/lib/native/source/yices2/yices.patch.license new file mode 100644 index 0000000000..3191e1cf83 --- /dev/null +++ b/lib/native/source/yices2/yices.patch.license @@ -0,0 +1,7 @@ +// This file is part of JavaSMT, +// an API wrapper for a collection of SMT solvers: +// https://github.com/sosy-lab/java-smt +// +// SPDX-FileCopyrightText: 2026 Dirk Beyer +// +// SPDX-License-Identifier: Apache-2.0 OR MIT diff --git a/lib/native/source/yices2/yices2.patch b/lib/native/source/yices2/yices2.patch deleted file mode 100644 index d4479edca6..0000000000 --- a/lib/native/source/yices2/yices2.patch +++ /dev/null @@ -1,36 +0,0 @@ -Index: src/main/java/com/sri/yices/Makefile -diff --git a/src/main/java/com/sri/yices/Makefile b/src/main/java/com/sri/yices/Makefile ---- a/src/main/java/com/sri/yices/Makefile (revision 2be85e119b6004cc489172568398582268a4f59d) -+++ b/src/main/java/com/sri/yices/Makefile (date 1773243769420) -@@ -56,9 +56,10 @@ - # we ignore versions and soname for now - - # default include directories for jni.h and jni_md.h --CPPFLAGS := -I $(JAVA_HOME)/include -I $(JAVA_HOME)/include/$(OS) -+CPPFLAGS := -I $(JAVA_HOME)/include -I $(JAVA_HOME)/include/$(OS) -I $(GMP_PATH)/include -I $(YICES_PATH)/include - CXXFLAGS := -g -fPIC --LIBS := -lyices -lgmp -+LDFLAGS := -L $(YICES_PATH)/lib -L $(CUDD_PATH)/lib -L $(POLY_PATH)/lib -L $(GMP_PATH)/lib -+LIBS := -lyices -lcudd -lpoly -lgmpxx -lgmp - - CXX ?= g++ - -@@ -86,7 +87,7 @@ - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -dynamiclib -o $@ yicesJNI.o $(LIBS) - - libyices2java.so: yicesJNI.o -- $(CXX) $(CFLAGS) $(LDFLAGS) -shared -o $@ yicesJNI.o $(LIBS) -+ $(CXX) $(CFLAGS) $(LDFLAGS) -o $@ yicesJNI.o -shared -Wl,-soname,libyices2java.so -Wl,-Bstatic $(LIBS) -static-libstdc++ -lstdc++ -Wl,-Bdynamic -lc -lm -Wl,--version-script=libyices2java.version - - LIBDIR := $(YICES_JNI) - -Index: src/main/java/com/sri/yices/libyices2java.version -diff --git a/src/main/java/com/sri/yices/libyices2java.version b/src/main/java/com/sri/yices/libyices2java.version -new file mode 100644 ---- /dev/null (date 1773151156723) -+++ b/src/main/java/com/sri/yices/libyices2java.version (date 1773151156723) -@@ -0,0 +1,4 @@ -+YICES2JAVA { -+ global: Java_*; -+ local: *; -+}; diff --git a/solvers_ivy_conf/ivy_yices2.xml b/solvers_ivy_conf/ivy_yices2.xml index c815c11e34..3840f1581b 100644 --- a/solvers_ivy_conf/ivy_yices2.xml +++ b/solvers_ivy_conf/ivy_yices2.xml @@ -26,15 +26,18 @@ SPDX-License-Identifier: Apache-2.0 - + + + + From d34d8d8b0ddda179835f83cf38f0f1e7fee697ba Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Tue, 17 Mar 2026 14:01:05 +0100 Subject: [PATCH 75/93] Yices: Only use 8 threads for the mingw build to avoid OOM crashes --- build/build-publish-solvers/solver-yices.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build-publish-solvers/solver-yices.xml b/build/build-publish-solvers/solver-yices.xml index 0a16c242bc..55bdf88f0b 100644 --- a/build/build-publish-solvers/solver-yices.xml +++ b/build/build-publish-solvers/solver-yices.xml @@ -171,7 +171,7 @@ SPDX-License-Identifier: Apache-2.0 - + From a9c9dfcce7b33a038f385633bc3a1d447989e58d Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Tue, 17 Mar 2026 21:29:17 +0100 Subject: [PATCH 76/93] Yices: Update feature table --- README.md | 54 +++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 5d4ecbf951..fe5483d51f 100644 --- a/README.md +++ b/README.md @@ -61,20 +61,20 @@ Only a few SMT solvers provide support for theories like Arrays, Floating Point, JavaSMT supports several SMT solvers (see [Getting Started](doc/Getting-started.md) for installation): -| SMT Solver | Linux x64 | Linux arm64 | Windows x64 | Windows arm64 | MacOS x64 | MacOS arm64 | Description | -| --- |:---:|:---:|:---:|:---:|:---:|:---:|:--- | -| [Bitwuzla](https://bitwuzla.github.io/) | :heavy_check_mark:² | :heavy_check_mark:² | :heavy_check_mark: | | | | a fast solver for bitvector logic | -| [Boolector](https://boolector.github.io/) | :heavy_check_mark: | | | | | | a fast solver for bitvector logic, misses formula introspection, deprecated | -| [CVC4](https://cvc4.github.io/) | :heavy_check_mark: | | | | | | | -| [CVC5](https://cvc5.github.io/) | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | -| [MathSAT5](http://mathsat.fbk.eu/) | :heavy_check_mark:³ | :heavy_check_mark:³ | :heavy_check_mark: | | [maybe](https://github.com/sosy-lab/java-smt/pull/430)⁴ | | | -| [OpenSMT](https://verify.inf.usi.ch/opensmt) | :heavy_check_mark:² | :heavy_check_mark:² | | | | | | -| [OptiMathSAT](http://optimathsat.disi.unitn.it/) | :heavy_check_mark: | | | | | | based on MathSAT5, with support for optimization queries | -| [Princess](http://www.philipp.ruemmer.org/princess.shtml) | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | Java-based SMT solver | -| [SMTInterpol](https://ultimate.informatik.uni-freiburg.de/smtinterpol/) | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | Java-based SMT solver | -| [Yices2](https://yices.csl.sri.com/) | :heavy_check_mark: | | [maybe](https://github.com/sosy-lab/java-smt/pull/215) | | [maybe](https://github.com/sosy-lab/java-smt/pull/400)⁴ | | | -| [Z3](https://github.com/Z3Prover/z3) | :heavy_check_mark:³ | :heavy_check_mark:³ | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | mature and well-known solver | -| [Z3_WITH_INTERPOLATION](https://github.com/Z3Prover/z3) | :heavy_check_mark: | :heavy_check_mark: | | | | | an older version of Z3 that still provides interpolation support | +| SMT Solver | Linux x64 | Linux arm64 | Windows x64 | Windows arm64 | MacOS x64 | MacOS arm64 | Description | +|-------------------------------------------------------------------------|:-------------------:|:-------------------:|:------------------:|:------------------:|:-------------------------------------------------------:|:------------------:|:----------------------------------------------------------------------------| +| [Bitwuzla](https://bitwuzla.github.io/) | :heavy_check_mark:² | :heavy_check_mark:² | :heavy_check_mark: | | | | a fast solver for bitvector logic | +| [Boolector](https://boolector.github.io/) | :heavy_check_mark: | | | | | | a fast solver for bitvector logic, misses formula introspection, deprecated | +| [CVC4](https://cvc4.github.io/) | :heavy_check_mark: | | | | | | | +| [CVC5](https://cvc5.github.io/) | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | | +| [MathSAT5](http://mathsat.fbk.eu/) | :heavy_check_mark:³ | :heavy_check_mark:³ | :heavy_check_mark: | | [maybe](https://github.com/sosy-lab/java-smt/pull/430)⁴ | | | +| [OpenSMT](https://verify.inf.usi.ch/opensmt) | :heavy_check_mark:² | :heavy_check_mark:² | | | | | | +| [OptiMathSAT](http://optimathsat.disi.unitn.it/) | :heavy_check_mark: | | | | | | based on MathSAT5, with support for optimization queries | +| [Princess](http://www.philipp.ruemmer.org/princess.shtml) | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | Java-based SMT solver | +| [SMTInterpol](https://ultimate.informatik.uni-freiburg.de/smtinterpol/) | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | Java-based SMT solver | +| [Yices2](https://yices.csl.sri.com/) | :heavy_check_mark: | | :heavy_check_mark: | | [maybe](https://github.com/sosy-lab/java-smt/pull/400)⁴ | | | +| [Z3](https://github.com/Z3Prover/z3) | :heavy_check_mark:³ | :heavy_check_mark:³ | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | mature and well-known solver | +| [Z3_WITH_INTERPOLATION](https://github.com/Z3Prover/z3) | :heavy_check_mark: | :heavy_check_mark: | | | | | an older version of Z3 that still provides interpolation support | We support a reasonable list of operating systems and versions. - Our main target is Linux (mainly Ubuntu or comparable Linux distributions). @@ -114,19 +114,19 @@ If something specific is missing, please [look for or file an issue](https://git #### Multithreading Support -| SMT Solver | Concurrent context usage⁵ | Concurrent prover usage⁶ | -| --- |:---:|:---:| -| [Bitwuzla](https://bitwuzla.github.io/) | :heavy_check_mark: | | -| [Boolector](https://boolector.github.io/) | :heavy_check_mark: | | -| [CVC4](https://cvc4.github.io/) | :heavy_check_mark: | :heavy_check_mark: | -| [CVC5](https://cvc4.github.io/) | :question: | | -| [MathSAT5](http://mathsat.fbk.eu/) | :heavy_check_mark: | | -| [OpenSMT](https://verify.inf.usi.ch/opensmt) | :question: | | -| [OptiMathSAT](http://optimathsat.disi.unitn.it/) | :heavy_check_mark: | | -| [Princess](http://www.philipp.ruemmer.org/princess.shtml) | :heavy_check_mark: | | -| [SMTInterpol](https://ultimate.informatik.uni-freiburg.de/smtinterpol/) | :heavy_check_mark: | | -| [Yices2](https://yices.csl.sri.com/) | | | -| [Z3](https://github.com/Z3Prover/z3) | :heavy_check_mark: | | +| SMT Solver | Concurrent context usage⁵ | Concurrent prover usage⁶ | +|-------------------------------------------------------------------------|:-------------------------:|:------------------------:| +| [Bitwuzla](https://bitwuzla.github.io/) | :heavy_check_mark: | | +| [Boolector](https://boolector.github.io/) | :heavy_check_mark: | | +| [CVC4](https://cvc4.github.io/) | :heavy_check_mark: | :heavy_check_mark: | +| [CVC5](https://cvc4.github.io/) | :heavy_check_mark: | | +| [MathSAT5](http://mathsat.fbk.eu/) | :heavy_check_mark: | | +| [OpenSMT](https://verify.inf.usi.ch/opensmt) | :heavy_check_mark: | | +| [OptiMathSAT](http://optimathsat.disi.unitn.it/) | :heavy_check_mark: | | +| [Princess](http://www.philipp.ruemmer.org/princess.shtml) | :heavy_check_mark: | | +| [SMTInterpol](https://ultimate.informatik.uni-freiburg.de/smtinterpol/) | :heavy_check_mark: | | +| [Yices2](https://yices.csl.sri.com/) | :heavy_check_mark: | | +| [Z3](https://github.com/Z3Prover/z3) | :heavy_check_mark: | | Interruption using a [ShutdownNotifier][] may be used to interrupt a solver from any thread. Formulas are translatable in between contexts/provers/threads using _FormulaManager.translateFrom()_. From 9907e249fb1bb060dd54968747a9e3c59cc74b6c Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Wed, 18 Mar 2026 10:04:46 +0100 Subject: [PATCH 77/93] Yices: Disable autoloader in native tests --- .../sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java index f359e1198a..6fc3892353 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java @@ -37,6 +37,7 @@ public class Yices2NativeApiTest { @BeforeClass public static void loadYices() { + System.setProperty("yices.skipAutoloader", "true"); NativeLibraries.loadLibrary("yices2java"); Yices.isReady(); } From 40beee327716604f27e168a220bba9c5f965b38e Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Wed, 18 Mar 2026 12:11:16 +0100 Subject: [PATCH 78/93] Yices: Enable Windows tests --- src/org/sosy_lab/java_smt/test/SolverContextFactoryTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/test/SolverContextFactoryTest.java b/src/org/sosy_lab/java_smt/test/SolverContextFactoryTest.java index 29972b7c19..b81cebe3e3 100644 --- a/src/org/sosy_lab/java_smt/test/SolverContextFactoryTest.java +++ b/src/org/sosy_lab/java_smt/test/SolverContextFactoryTest.java @@ -118,7 +118,7 @@ private boolean isSupportedOperatingSystemAndArchitecture() { case BOOLECTOR: case CVC4: case YICES2: - return IS_LINUX && !IS_ARCH_ARM64; + return IS_LINUX && !IS_ARCH_ARM64 || IS_WINDOWS; case CVC5: return (IS_LINUX && isSufficientVersionOfLibcxx("cvc5jni")) || IS_WINDOWS || IS_MAC; case OPENSMT: From 67ad89c5276ff7872ea7eae16f62a0dd33e742dd Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Wed, 18 Mar 2026 12:12:02 +0100 Subject: [PATCH 79/93] Yices: Enable division by zero tests --- src/org/sosy_lab/java_smt/test/NumeralFormulaManagerTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/org/sosy_lab/java_smt/test/NumeralFormulaManagerTest.java b/src/org/sosy_lab/java_smt/test/NumeralFormulaManagerTest.java index d3160b4372..1a1db5933b 100644 --- a/src/org/sosy_lab/java_smt/test/NumeralFormulaManagerTest.java +++ b/src/org/sosy_lab/java_smt/test/NumeralFormulaManagerTest.java @@ -31,7 +31,7 @@ public class NumeralFormulaManagerTest extends SolverBasedTest0.ParameterizedSol @Test public void divZeroTest() throws SolverException, InterruptedException { requireIntegers(); - assume().that(solver).isNoneOf(Solvers.OPENSMT, Solvers.YICES2); // No division by zero + assume().that(solver).isNotEqualTo(Solvers.OPENSMT); // No division by zero IntegerFormula zero = imgr.makeNumber(0); IntegerFormula three = imgr.makeNumber(3); @@ -67,7 +67,7 @@ public void divZeroTest() throws SolverException, InterruptedException { @Test public void modZeroTest() throws SolverException, InterruptedException { requireIntegers(); - assume().that(solver).isNoneOf(Solvers.OPENSMT, Solvers.YICES2); // No division by zero + assume().that(solver).isNotEqualTo(Solvers.OPENSMT); // No division by zero IntegerFormula zero = imgr.makeNumber(0); IntegerFormula three = imgr.makeNumber(3); From 4340a3e358c71e6df299582652929b2cd2e63fc0 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Wed, 18 Mar 2026 19:03:30 +0100 Subject: [PATCH 80/93] CI --- src/org/sosy_lab/java_smt/test/SolverContextFactoryTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/test/SolverContextFactoryTest.java b/src/org/sosy_lab/java_smt/test/SolverContextFactoryTest.java index b81cebe3e3..e61bad0615 100644 --- a/src/org/sosy_lab/java_smt/test/SolverContextFactoryTest.java +++ b/src/org/sosy_lab/java_smt/test/SolverContextFactoryTest.java @@ -118,7 +118,7 @@ private boolean isSupportedOperatingSystemAndArchitecture() { case BOOLECTOR: case CVC4: case YICES2: - return IS_LINUX && !IS_ARCH_ARM64 || IS_WINDOWS; + return (IS_LINUX && !IS_ARCH_ARM64) || IS_WINDOWS; case CVC5: return (IS_LINUX && isSufficientVersionOfLibcxx("cvc5jni")) || IS_WINDOWS || IS_MAC; case OPENSMT: From d61d6fa1946cc5b722a549f96184d454b5a14718 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Wed, 18 Mar 2026 19:08:12 +0100 Subject: [PATCH 81/93] Yices: Fix an error message --- .../java_smt/solvers/yices2/Yices2FormulaCreator.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java index e0a82eb3a5..c50ae92215 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java @@ -207,7 +207,9 @@ protected int createNamedVariable(int type, String name) { !formulaCache.containsRow(name), "Symbol '%s' already used for a variable of type '%s'", name, - formulaCache.row(name)); + formulaCache.containsRow(name) + ? Types.toString(formulaCache.row(name).keySet().iterator().next()) + : ""); int var = Terms.newUninterpretedTerm(type); // Names in Yices2 behave like a stack. The last variable named is retrieved when asking for From 47c6b82cdca2f0ede7386be085041ba93e115166 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Wed, 18 Mar 2026 19:10:20 +0100 Subject: [PATCH 82/93] Yices: Add support for modulo in the visitor --- .../java_smt/solvers/yices2/Yices2FormulaCreator.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java index c50ae92215..bf6147d8a4 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java @@ -435,6 +435,9 @@ private R visitFunctionApplication( case IDIV: functionKind = FunctionDeclarationKind.DIV; break; + case IMOD: + functionKind = FunctionDeclarationKind.MODULO; + break; case SELECT_TERM: functionKind = FunctionDeclarationKind.SELECT; break; @@ -477,7 +480,7 @@ private R visitFunctionApplication( functionKind = FunctionDeclarationKind.BV_CONCAT; break; default: - functionKind = FunctionDeclarationKind.OTHER; + throw new UnsupportedOperationException(constructor.toString()); } if (functionName == null) { From c87aa50213387ed65c246fa9c1c34c19c688d284 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Wed, 18 Mar 2026 20:41:04 +0100 Subject: [PATCH 83/93] Yices: Fix products in the visitor --- .../solvers/yices2/Yices2FormulaCreator.java | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java index bf6147d8a4..4c5552c432 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java @@ -847,17 +847,6 @@ private static int mkMultiply(int a, int b) { } } - /* Power of a bv or an arithmetic term. */ - private static int mkPower(int term, int exponent) { - if (Terms.isArithmetic(term)) { - return Terms.power(term, exponent); - } else if (Terms.isBitvector(term)) { - return Terms.bvPower(term, exponent); - } else { - throw new IllegalArgumentException(); - } - } - /** * Returns a list of terms for a sum. * @@ -894,14 +883,16 @@ private static List getOnlySumTerm(int parent) { /** * Returns a list of factors for a product term. * - *

Splits a product a^m * b^n * ... into a list of monomials a^m, - * b^n, ... + *

Splits a product a^m * b^n * ... into a list of individual factors a + * * ... * b * ... */ private static List getProductFactors(int parent) { ImmutableList.Builder builder = ImmutableList.builder(); for (int i = 0; i < Terms.numChildren(parent); i++) { ProductComponent component = Terms.projProduct(parent, i); - builder.add(mkPower(component.getTerm(), component.getPower())); + for (int k = 0; k < component.getPower(); k++) { + builder.add(component.getTerm()); + } } return builder.build(); } From f0a20388af81a1f251df44ee3f3338896b70aa5a Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Wed, 18 Mar 2026 20:42:15 +0100 Subject: [PATCH 84/93] Yices: Fix products/sums with more than 2 terms --- .../solvers/yices2/Yices2FormulaCreator.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java index 4c5552c432..78de1aaa6f 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java @@ -447,7 +447,12 @@ private R visitFunctionApplication( functionArgs = getOnlySumTerm(pF); } else { functionKind = FunctionDeclarationKind.BV_ADD; - functionArgs = getSumTerms(pF); + var terms = getSumTerms(pF); + var right = + terms.size() > 2 + ? Terms.bvAdd(FluentIterable.from(terms).skip(1).toList()) + : terms.get(1); + functionArgs = ImmutableList.of(terms.get(0), right); } break; case ARITH_SUM: @@ -462,8 +467,12 @@ private R visitFunctionApplication( case POWER_PRODUCT: if (Terms.isBitvector(pF)) { functionKind = FunctionDeclarationKind.BV_MUL; - functionArgs = getProductFactors(pF); - // TODO Product of more then 2 bitvectors ? + var factors = getProductFactors(pF); + var right = factors.get(1); + for (var p = 2; p < factors.size(); p++) { + right = Terms.bvMul(right, factors.get(p)); + } + functionArgs = ImmutableList.of(factors.get(0), right); } else { functionKind = FunctionDeclarationKind.MUL; functionArgs = getProductFactors(pF); @@ -582,8 +591,7 @@ private int buildDeclaration( f = Terms.div(args.get(0), args.get(1)); break; case MUL: - checkArgument(args.size() == 2); - f = Terms.mul(args.get(0), args.get(1)); + f = Terms.mul(args); break; case MODULO: checkArgument(args.size() == 2); From 18956369db3a4c554a7f96e34e42efaaad93a358 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Wed, 18 Mar 2026 21:02:52 +0100 Subject: [PATCH 85/93] Yices: Rewrite "bit" and "bool-to-bv" terms in the visitor --- .../solvers/yices2/Yices2FormulaCreator.java | 53 ++++++++++++++----- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java index 78de1aaa6f..5b7fbe3c44 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java @@ -479,14 +479,45 @@ private R visitFunctionApplication( } break; case BIT_TERM: - // FIXME Not really "extract" - functionKind = FunctionDeclarationKind.BV_EXTRACT; - functionIndex = ImmutableList.of(Terms.projIndex(pF)); - functionArgs = ImmutableList.of(Terms.projArg(pF)); + // Yices rewrites most "bitwise" operations on bitvectors, f.ex bvand(a,b) becomes + // (bool-to-bv (and (bit a k) (bit b k)) (and (bit a k-1) (bit b k-1)) ...) + // Here (bit a k) returns the k-th bit of the bitvector as a boolean, and bool-to-bv is + // used to (re)construct the bitvector from a vector of boolean terms + // Since "bit" and "bool-to-bv" are not supported by the visitor, we have to undo the + // transformation here + + // Rewrite (bit x n) to (= (extract x n n) #b1). Yices will then further simplify to + // (= (bool-to-bv (bit x n)) #b1) + // We visit the outer "=" and handle the rest in the arguments + functionKind = FunctionDeclarationKind.EQ; + functionArgs = + ImmutableList.of( + Terms.bvExtract(Terms.projArg(pF), Terms.projIndex(pF), Terms.projIndex(pF)), + Terms.bvConst(1, 1)); break; case BV_ARRAY: - // FIXME Not really "concat" - functionKind = FunctionDeclarationKind.BV_CONCAT; + if (Terms.numChildren(pF) == 1) { + if (Terms.constructor(Terms.child(pF, 0)) == Constructor.BIT_TERM) { + // Rewrite (bool-to-bv (bit x n)) to (extract x n n) + functionKind = FunctionDeclarationKind.BV_EXTRACT; + functionIndex = + ImmutableList.of( + Terms.projIndex(Terms.child(pF, 0)), Terms.projIndex(Terms.child(pF, 0))); + functionArgs = ImmutableList.of(Terms.projArg(Terms.child(pF, 0))); + } else { + // Rewrite (bool-to-bv _) to (ite _ #1 #0) + functionKind = FunctionDeclarationKind.ITE; + functionArgs = + ImmutableList.of(Terms.child(pF, 0), Terms.bvConst(1, 1), Terms.bvConst(1, 0)); + } + } else { + // Rewrite (bool-to-bv a b ...) to (concat ... (ite b #1 #0) (ite a #1 #0)) + functionKind = FunctionDeclarationKind.BV_CONCAT; + functionArgs = + FluentIterable.from(Lists.reverse(getArgs(pF))) + .transform(p -> Terms.ifThenElse(p, Terms.bvConst(1, 1), Terms.bvConst(1, 0))) + .toList(); + } break; default: throw new UnsupportedOperationException(constructor.toString()); @@ -633,15 +664,11 @@ private int buildDeclaration( case INT_TO_BV: throw new UnsupportedOperationException("INT_TO_BV not supported"); case BV_EXTRACT: - checkArgument(args.size() == 1); - f = Terms.bvExtractBit(args.get(0), pIndex.get(0)); - // FIXME Should be: - // f = Terms.bvExtract(args.get(0), pIndex.get(0), pIndex.get(1)); + checkArgument(args.size() == 1 && pIndex.size() == 2); + f = Terms.bvExtract(args.get(0), pIndex.get(0), pIndex.get(1)); break; case BV_CONCAT: - f = Terms.bvFromBoolArray(args); - // FIXME Should be: - // f = Terms.bvConcat(args); + f = Terms.bvConcat(args); break; case BV_SIGN_EXTENSION: checkArgument(args.size() == 1); From 511800d58b85a1905cd8741a2416eb0a8c8adef3 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Wed, 18 Mar 2026 21:36:32 +0100 Subject: [PATCH 86/93] Yices: Don't rewrite and/or terms with more than 2 arguments --- .../solvers/yices2/Yices2BooleanFormulaManager.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2BooleanFormulaManager.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2BooleanFormulaManager.java index 7291baf35f..ea44280146 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2BooleanFormulaManager.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2BooleanFormulaManager.java @@ -8,7 +8,9 @@ package org.sosy_lab.java_smt.solvers.yices2; +import com.google.common.collect.ImmutableList; import com.sri.yices.Terms; +import java.util.Collection; import org.sosy_lab.java_smt.basicimpl.AbstractBooleanFormulaManager; class Yices2BooleanFormulaManager @@ -43,11 +45,21 @@ protected Integer and(Integer pParam1, Integer pParam2) { return Terms.and(pParam1, pParam2); } + @Override + protected Integer andImpl(Collection pParams) { + return Terms.and(ImmutableList.copyOf(pParams)); + } + @Override protected Integer or(Integer pParam1, Integer pParam2) { return Terms.or(pParam1, pParam2); } + @Override + protected Integer orImpl(Collection pParams) { + return Terms.or(ImmutableList.copyOf(pParams)); + } + @Override protected Integer xor(Integer pParam1, Integer pParam2) { return Terms.xor(pParam1, pParam2); From 946beae21e92967d49f28b951e8f123302626e94 Mon Sep 17 00:00:00 2001 From: Daniel Raffler Date: Thu, 19 Mar 2026 09:37:06 +0100 Subject: [PATCH 87/93] Yices: Update maven script --- build/build-maven-publish.xml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/build/build-maven-publish.xml b/build/build-maven-publish.xml index 73b23d0eb3..2e33b35b6f 100644 --- a/build/build-maven-publish.xml +++ b/build/build-maven-publish.xml @@ -266,10 +266,13 @@ SPDX-License-Identifier: Apache-2.0 - + + - + + + From 5b057618b104e61ae51e232d3d151d7ecccf450b Mon Sep 17 00:00:00 2001 From: Karlheinz Friedberger Date: Mon, 23 Mar 2026 20:20:31 +0100 Subject: [PATCH 88/93] Yices2: fix unit test for Boolector and CVC4 (Linux only). --- src/org/sosy_lab/java_smt/test/SolverContextFactoryTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/org/sosy_lab/java_smt/test/SolverContextFactoryTest.java b/src/org/sosy_lab/java_smt/test/SolverContextFactoryTest.java index e61bad0615..3387c19b51 100644 --- a/src/org/sosy_lab/java_smt/test/SolverContextFactoryTest.java +++ b/src/org/sosy_lab/java_smt/test/SolverContextFactoryTest.java @@ -117,8 +117,9 @@ private boolean isSupportedOperatingSystemAndArchitecture() { return true; case BOOLECTOR: case CVC4: + return IS_LINUX && !IS_ARCH_ARM64; case YICES2: - return (IS_LINUX && !IS_ARCH_ARM64) || IS_WINDOWS; + return (IS_LINUX && !IS_ARCH_ARM64) || (IS_WINDOWS && !IS_ARCH_ARM64); case CVC5: return (IS_LINUX && isSufficientVersionOfLibcxx("cvc5jni")) || IS_WINDOWS || IS_MAC; case OPENSMT: From 04134287c57d116958bfcbe9dc845ed7ec0091fd Mon Sep 17 00:00:00 2001 From: Karlheinz Friedberger Date: Mon, 23 Mar 2026 21:17:52 +0100 Subject: [PATCH 89/93] Yices2: update build-scripts and documentation --- lib/native/x86_64-windows/README.md | 10 ++++++--- solvers_ivy_conf/ivy_javasmt_yices2.xml | 27 +++++++++++++++++++------ 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/lib/native/x86_64-windows/README.md b/lib/native/x86_64-windows/README.md index ed0a3560f5..94befdd835 100644 --- a/lib/native/x86_64-windows/README.md +++ b/lib/native/x86_64-windows/README.md @@ -3,7 +3,7 @@ This file is part of JavaSMT, an API wrapper for a collection of SMT solvers: https://github.com/sosy-lab/java-smt -SPDX-FileCopyrightText: 2025 Dirk Beyer +SPDX-FileCopyrightText: 2026 Dirk Beyer SPDX-License-Identifier: Apache-2.0 --> @@ -40,9 +40,11 @@ For Bitwuzla: - `mklink libbitwuzlaj.dll ..\..\java\runtime-bitwuzla\x64\libbitwuzlaj.dll` For CVC5: - - `mlink libcvc5jni.dll ..\..\java\runtime-cvc5\x64\libcvcjni.so` +For Yices2: +- `mlink yices2java.dll ..\..\java\runtime-yices2\x64\yices2java.so` + ### With a direct copy of the library: An alternative simple solution (without the need of administrator rights) is to copy over @@ -62,9 +64,11 @@ For Bitwuzla: - `copy ..\..\java\runtime-bitwuzla\x64\libbitwuzlaj.dll libbitwuzlaj.dll` For CVC5: - - `copy ..\..\java\runtime-cvc5\x64\libcvc5jni.dll libcvc5jni.dll` +For Yices2: +- `copy ..\..\java\runtime-yices2\x64\yices2java.dll yices2java.dll` + Or simply use a wildcard: - `copy ..\..\java\runtime-*\*dll .\` - `copy ..\..\java\runtime-*\x64\*dll .\` diff --git a/solvers_ivy_conf/ivy_javasmt_yices2.xml b/solvers_ivy_conf/ivy_javasmt_yices2.xml index 33c4f5cad0..6e68fe524f 100644 --- a/solvers_ivy_conf/ivy_javasmt_yices2.xml +++ b/solvers_ivy_conf/ivy_javasmt_yices2.xml @@ -5,7 +5,7 @@ This file is part of JavaSMT, an API wrapper for a collection of SMT solvers: https://github.com/sosy-lab/java-smt -SPDX-FileCopyrightText: 2020 Dirk Beyer +SPDX-FileCopyrightText: 2026 Dirk Beyer SPDX-License-Identifier: Apache-2.0 --> @@ -23,7 +23,18 @@ SPDX-License-Identifier: Apache-2.0 - + + + + + + + + + + + + @@ -33,19 +44,23 @@ SPDX-License-Identifier: Apache-2.0 - + - + - + - + From 44b2ed327171faec69cf627fdece09f525927d8c Mon Sep 17 00:00:00 2001 From: Karlheinz Friedberger Date: Mon, 23 Mar 2026 22:12:33 +0100 Subject: [PATCH 90/93] Yices2: update JavaSMT bindings for Yices2 to v6.0.0-141-g04134287c --- lib/ivy.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ivy.xml b/lib/ivy.xml index 80d9b80b4e..0f01709801 100644 --- a/lib/ivy.xml +++ b/lib/ivy.xml @@ -202,7 +202,7 @@ SPDX-License-Identifier: Apache-2.0 - + From b0254e379b0e9e2c5ace0c4df7762274ea04f0ee Mon Sep 17 00:00:00 2001 From: Karlheinz Friedberger Date: Mon, 23 Mar 2026 22:36:56 +0100 Subject: [PATCH 91/93] Yices2: apply Refaster findings. --- .../java_smt/solvers/yices2/Yices2FormulaCreator.java | 8 +++++--- .../solvers/yices2/Yices2InterpolatingProver.java | 5 +++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java index 5b7fbe3c44..cead1976d0 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2FormulaCreator.java @@ -9,6 +9,7 @@ package org.sosy_lab.java_smt.solvers.yices2; import static com.google.common.base.Preconditions.checkArgument; +import static org.sosy_lab.common.collect.Collections3.transformedImmutableListCopy; import com.google.common.base.Preconditions; import com.google.common.collect.FluentIterable; @@ -514,9 +515,10 @@ private R visitFunctionApplication( // Rewrite (bool-to-bv a b ...) to (concat ... (ite b #1 #0) (ite a #1 #0)) functionKind = FunctionDeclarationKind.BV_CONCAT; functionArgs = - FluentIterable.from(Lists.reverse(getArgs(pF))) - .transform(p -> Terms.ifThenElse(p, Terms.bvConst(1, 1), Terms.bvConst(1, 0))) - .toList(); + transformedImmutableListCopy( + getArgs(pF), + p -> Terms.ifThenElse(p, Terms.bvConst(1, 1), Terms.bvConst(1, 0))) + .reverse(); } break; default: diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java index e760f7d21c..749f3a5ccd 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2InterpolatingProver.java @@ -11,6 +11,7 @@ package org.sosy_lab.java_smt.solvers.yices2; import static com.google.common.base.Preconditions.checkArgument; +import static org.sosy_lab.common.collect.Collections3.transformedImmutableSetCopy; import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableSet; @@ -61,8 +62,8 @@ public BooleanFormula getInterpolant(Collection formulasOfA) return creator.encapsulateBoolean( interpolate( - FluentIterable.from(setA).transform(stack.peekLast()::get).toSet(), - FluentIterable.from(setB).transform(stack.peekLast()::get).toSet())); + transformedImmutableSetCopy(setA, stack.peekLast()::get), + transformedImmutableSetCopy(setB, stack.peekLast()::get))); } private int interpolate(Collection setA, Collection setB) From 09af75ab1ec01cc679a4e353cfeb287ad8ad7343 Mon Sep 17 00:00:00 2001 From: Karlheinz Friedberger Date: Mon, 23 Mar 2026 22:37:40 +0100 Subject: [PATCH 92/93] Yices2: ignore certain architectures or older systems in tests. --- .../java_smt/solvers/yices2/Yices2NativeApiTest.java | 11 ++++++++--- .../java_smt/test/SolverContextFactoryTest.java | 5 ++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java index 6fc3892353..a36890a170 100644 --- a/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java +++ b/src/org/sosy_lab/java_smt/solvers/yices2/Yices2NativeApiTest.java @@ -27,6 +27,7 @@ import com.sri.yices.YicesException; import java.math.BigInteger; import org.junit.After; +import org.junit.AssumptionViolatedException; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -37,9 +38,13 @@ public class Yices2NativeApiTest { @BeforeClass public static void loadYices() { - System.setProperty("yices.skipAutoloader", "true"); - NativeLibraries.loadLibrary("yices2java"); - Yices.isReady(); + try { + System.setProperty("yices.skipAutoloader", "true"); + NativeLibraries.loadLibrary("yices2java"); + Yices.isReady(); + } catch (UnsatisfiedLinkError e) { + throw new AssumptionViolatedException("Yices2 is not available", e); + } } private Context env; diff --git a/src/org/sosy_lab/java_smt/test/SolverContextFactoryTest.java b/src/org/sosy_lab/java_smt/test/SolverContextFactoryTest.java index 3387c19b51..2b14bba982 100644 --- a/src/org/sosy_lab/java_smt/test/SolverContextFactoryTest.java +++ b/src/org/sosy_lab/java_smt/test/SolverContextFactoryTest.java @@ -119,7 +119,8 @@ private boolean isSupportedOperatingSystemAndArchitecture() { case CVC4: return IS_LINUX && !IS_ARCH_ARM64; case YICES2: - return (IS_LINUX && !IS_ARCH_ARM64) || (IS_WINDOWS && !IS_ARCH_ARM64); + return (IS_LINUX && !IS_ARCH_ARM64 && isSufficientVersionOfLibcxx("yices2java")) + || (IS_WINDOWS && !IS_ARCH_ARM64); case CVC5: return (IS_LINUX && isSufficientVersionOfLibcxx("cvc5jni")) || IS_WINDOWS || IS_MAC; case OPENSMT: @@ -168,6 +169,8 @@ private String[] getRequiredLibcxx(String library) { return new String[] {"GLIBC_2.33", "GLIBC_2.38"}; case "cvc5jni": return new String[] {"GLIBC_2.32"}; + case "yices2java": + return new String[] {"GLIBC_2.34"}; default: return new String[] {}; } From 661c824b1be0ef55edab05bb326a41fc80ae114c Mon Sep 17 00:00:00 2001 From: Karlheinz Friedberger Date: Mon, 23 Mar 2026 23:57:03 +0100 Subject: [PATCH 93/93] Yices2: fix AppVeyor CI config. --- .appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.appveyor.yml b/.appveyor.yml index 797eb36576..5261bca7c0 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -45,6 +45,7 @@ build_script: Copy-Item -Path "lib\java\runtime-mathsat\x64\*.dll" -Destination "lib\native\x86_64-windows\" -Force Copy-Item -Path "lib\java\runtime-bitwuzla\x64\*.dll" -Destination "lib\native\x86_64-windows\" -Force Copy-Item -Path "lib\java\runtime-cvc5\x64\*.dll" -Destination "lib\native\x86_64-windows\" -Force + Copy-Item -Path "lib\java\runtime-yices2\x64\*.dll" -Destination "lib\native\x86_64-windows\" -Force test_script: - ant unit-tests