diff --git a/.gitignore b/.gitignore index 505601597..3d6e631f1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ *~ *.pyc +# .hpp files are automatically generated +*.hpp .z3-trace # OCaml generated files *.a @@ -7,6 +9,9 @@ *.cmi *.cmxa ocamlz3 +# Java generated files +*.class +*.jar # Emacs temp files \#*\# # Directories with generated code and documentation @@ -31,12 +36,15 @@ ncscope.out # Commonly used directories for code bld_dbg/* bld_rel/* +bld_dbg_x64/* +bld_rel_x64/* # Auto generated files. config.log config.status configure install_tactic.cpp mem_initializer.cpp +gparams_register_modules.cpp scripts/config-debug.mk scripts/config-release.mk src/api/api_commands.cpp @@ -49,5 +57,6 @@ src/api/python/z3consts.py src/api/python/z3core.py src/ast/pattern/database.h src/util/version.h -src/api/java/Z3Native.c -src/api/java/Z3Native.java \ No newline at end of file +src/api/java/Native.cpp +src/api/java/Native.java +src/api/java/enumerations/*.java diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 55e873997..4c74b41a5 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -14,6 +14,12 @@ Version 4.3.2 - Removed 'autoconf' dependency. We do not need to execute 'autoconf' and './configure' anymore to build Z3. +- Fixed incorrect result returned by Z3_solver_get_num_scopes. (Thanks to Herman Venter). This bug was introduced in Z3 4.3.0 + +- Java bindings. To enable them, we must use the option `--java` when executing the `mk_make.py` script. Example: `python scripts/mk_make.py --java` + +- Fixed crash when parsing incorrect formulas. The crash was introduced when support for "arithmetic coercions" was added in Z3 4.3.0. + Version 4.3.1 ============= diff --git a/examples/c++/example.cpp b/examples/c++/example.cpp index 180117a96..ab6e67ab9 100644 --- a/examples/c++/example.cpp +++ b/examples/c++/example.cpp @@ -143,7 +143,7 @@ void prove_example2() { void nonlinear_example1() { std::cout << "nonlinear example 1\n"; config cfg; - cfg.set(":auto-config", true); + cfg.set("auto_config", true); context c(cfg); expr x = c.real_const("x"); @@ -158,12 +158,13 @@ void nonlinear_example1() { std::cout << s.check() << "\n"; model m = s.get_model(); std::cout << m << "\n"; - c.set(":pp-decimal", true); // set decimal notation + set_param("pp.decimal", true); // set decimal notation std::cout << "model in decimal notation\n"; std::cout << m << "\n"; - c.set(":pp-decimal-precision", 50); // increase number of decimal places to 50. + set_param("pp.decimal-precision", 50); // increase number of decimal places to 50. std::cout << "model using 50 decimal places\n"; std::cout << m << "\n"; + set_param("pp.decimal", false); // disable decimal notation } /** @@ -352,7 +353,7 @@ void quantifier_example() { // making sure model based quantifier instantiation is enabled. params p(c); - p.set(":mbqi", true); + p.set("mbqi", true); s.set(p); s.add(forall(x, y, f(x, y) >= 0)); @@ -468,7 +469,7 @@ void unsat_core_example3() { // enabling unsat core tracking params p(c); - p.set(":unsat-core", true); + p.set("unsat_core", true); s.set(p); // The following assertion will not be tracked. @@ -585,7 +586,7 @@ void tactic_example4() { std::cout << "tactic example 4\n"; context c; params p(c); - p.set(":mul2concat", true); + p.set("mul2concat", true); tactic t = with(tactic(c, "simplify"), p) & tactic(c, "solve-eqs") & @@ -628,8 +629,8 @@ void tactic_example6() { std::cout << "tactic example 6\n"; context c; params p(c); - p.set(":arith-lhs", true); - p.set(":som", true); // sum-of-monomials normal form + p.set("arith_lhs", true); + p.set("som", true); // sum-of-monomials normal form solver s = (with(tactic(c, "simplify"), p) & tactic(c, "normalize-bounds") & diff --git a/examples/c/test_capi.c b/examples/c/test_capi.c index 70cdc2852..27bf6de2c 100644 --- a/examples/c/test_capi.c +++ b/examples/c/test_capi.c @@ -70,7 +70,7 @@ Z3_context mk_context_custom(Z3_config cfg, Z3_error_handler err) { Z3_context ctx; - Z3_set_param_value(cfg, "MODEL", "true"); + Z3_set_param_value(cfg, "model", "true"); ctx = Z3_mk_context(cfg); Z3_set_error_handler(ctx, err); @@ -105,7 +105,7 @@ Z3_context mk_context() Z3_context mk_proof_context() { Z3_config cfg = Z3_mk_config(); Z3_context ctx; - Z3_set_param_value(cfg, "PROOF_MODE", "2"); + Z3_set_param_value(cfg, "proof", "true"); ctx = mk_context_custom(cfg, throw_z3_error); Z3_del_config(cfg); return ctx; @@ -1038,12 +1038,12 @@ void quantifier_example1() /* If quantified formulas are asserted in a logical context, then Z3 may return L_UNDEF. In this case, the model produced by Z3 should be viewed as a potential/candidate model. */ - Z3_set_param_value(cfg, "MODEL", "true"); + /* The current model finder for quantified formulas cannot handle injectivity. So, we are limiting the number of iterations to avoid a long "wait". */ - Z3_set_param_value(cfg, "MBQI_MAX_ITERATIONS", "10"); + Z3_global_param_set("smt.mbqi.max_iterations", "10"); ctx = mk_context_custom(cfg, error_handler); Z3_del_config(cfg); @@ -1087,8 +1087,9 @@ void quantifier_example1() if (Z3_get_search_failure(ctx) != Z3_QUANTIFIERS) { exitf("unexpected result"); } - Z3_del_context(ctx); + /* reset global parameters set by this function */ + Z3_global_param_reset_all(); } /** @@ -1646,7 +1647,7 @@ void parser_example3() cfg = Z3_mk_config(); /* See quantifer_example1 */ - Z3_set_param_value(cfg, "MODEL", "true"); + Z3_set_param_value(cfg, "model", "true"); ctx = mk_context_custom(cfg, error_handler); Z3_del_config(cfg); @@ -2249,57 +2250,6 @@ void unsat_core_and_proof_example() { Z3_del_context(ctx); } -/** - \brief Extract classes of implied equalities. - - This example illustrates the use of #Z3_get_implied_equalities. -*/ -void get_implied_equalities_example() { - Z3_config cfg = Z3_mk_config(); - Z3_context ctx; - - printf("\nget_implied_equalities example\n"); - LOG_MSG("get_implied_equalities example"); - - Z3_set_param_value(cfg, "ARITH_PROCESS_ALL_EQS", "true"); - Z3_set_param_value(cfg, "ARITH_EQ_BOUNDS", "true"); - ctx = Z3_mk_context(cfg); - Z3_del_config(cfg); - { - Z3_sort int_ty = Z3_mk_int_sort(ctx); - Z3_ast a = mk_int_var(ctx,"a"); - Z3_ast b = mk_int_var(ctx,"b"); - Z3_ast c = mk_int_var(ctx,"c"); - Z3_ast d = mk_int_var(ctx,"d"); - Z3_func_decl f = Z3_mk_func_decl(ctx, Z3_mk_string_symbol(ctx,"f"), 1, &int_ty, int_ty); - Z3_ast fa = Z3_mk_app(ctx, f, 1, &a); - Z3_ast fb = Z3_mk_app(ctx, f, 1, &b); - Z3_ast fc = Z3_mk_app(ctx, f, 1, &c); - unsigned const num_terms = 7; - unsigned i; - Z3_ast terms[7] = { a, b, c, d, fa, fb, fc }; - unsigned class_ids[7] = { 0, 0, 0, 0, 0, 0, 0 }; - - Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, a, b)); - Z3_assert_cnstr(ctx, Z3_mk_eq(ctx, b, c)); - Z3_assert_cnstr(ctx, Z3_mk_le(ctx, fc, b)); - Z3_assert_cnstr(ctx, Z3_mk_le(ctx, b, fa)); - - Z3_get_implied_equalities(ctx, num_terms, terms, class_ids); - for (i = 0; i < num_terms; ++i) { - printf("Class %s |-> %d\n", Z3_ast_to_string(ctx, terms[i]), class_ids[i]); - } - printf("asserting f(a) <= b\n"); - Z3_assert_cnstr(ctx, Z3_mk_le(ctx, fa, b)); - Z3_get_implied_equalities(ctx, num_terms, terms, class_ids); - for (i = 0; i < num_terms; ++i) { - printf("Class %s |-> %d\n", Z3_ast_to_string(ctx, terms[i]), class_ids[i]); - } - } - /* delete logical context */ - Z3_del_context(ctx); -} - #define MAX_RETRACTABLE_ASSERTIONS 1024 /** @@ -2504,7 +2454,7 @@ void reference_counter_example() { LOG_MSG("reference_counter_example"); cfg = Z3_mk_config(); - Z3_set_param_value(cfg, "MODEL", "true"); + Z3_set_param_value(cfg, "model", "true"); // Create a Z3 context where the user is reponsible for managing // Z3_ast reference counters. ctx = Z3_mk_context_rc(cfg); @@ -2685,7 +2635,6 @@ int main() { binary_tree_example(); enum_example(); unsat_core_and_proof_example(); - get_implied_equalities_example(); incremental_example1(); reference_counter_example(); smt2parser_example(); diff --git a/examples/dotnet/Program.cs b/examples/dotnet/Program.cs index db3cd30b2..2085de296 100644 --- a/examples/dotnet/Program.cs +++ b/examples/dotnet/Program.cs @@ -248,10 +248,13 @@ namespace test_mapi return res; } - static void Prove(Context ctx, BoolExpr f, params BoolExpr[] assumptions) + static void Prove(Context ctx, BoolExpr f, bool useMBQI = false, params BoolExpr[] assumptions) { Console.WriteLine("Proving: " + f); Solver s = ctx.MkSolver(); + Params p = ctx.MkParams(); + p.Add("mbqi", useMBQI); + s.Parameters = p; foreach (BoolExpr a in assumptions) s.Assert(a); s.Assert(ctx.MkNot(f)); @@ -270,10 +273,13 @@ namespace test_mapi } } - static void Disprove(Context ctx, BoolExpr f, params BoolExpr[] assumptions) + static void Disprove(Context ctx, BoolExpr f, bool useMBQI = false, params BoolExpr[] assumptions) { Console.WriteLine("Disproving: " + f); Solver s = ctx.MkSolver(); + Params p = ctx.MkParams(); + p.Add("mbqi", useMBQI); + s.Parameters = p; foreach (BoolExpr a in assumptions) s.Assert(a); s.Assert(ctx.MkNot(f)); @@ -298,7 +304,7 @@ namespace test_mapi ArithExpr xr = (ArithExpr)ctx.MkConst(ctx.MkSymbol("x"), ctx.MkRealSort()); ArithExpr yr = (ArithExpr)ctx.MkConst(ctx.MkSymbol("y"), ctx.MkRealSort()); - Goal g4 = ctx.MkGoal(true, false, true); + Goal g4 = ctx.MkGoal(true); g4.Assert(ctx.MkGt(xr, ctx.MkReal(10, 1))); g4.Assert(ctx.MkEq(yr, ctx.MkAdd(xr, ctx.MkReal(1, 1)))); g4.Assert(ctx.MkGt(yr, ctx.MkReal(1, 1))); @@ -330,7 +336,7 @@ namespace test_mapi { Console.WriteLine("ArrayExample1"); - Goal g = ctx.MkGoal(true, false, false); + Goal g = ctx.MkGoal(true); ArraySort asort = ctx.MkArraySort(ctx.IntSort, ctx.MkBitVecSort(32)); ArrayExpr aex = (ArrayExpr)ctx.MkConst(ctx.MkSymbol("MyArray"), asort); Expr sel = ctx.MkSelect(aex, ctx.MkInt(0)); @@ -640,95 +646,76 @@ namespace test_mapi /// Prove that f(x, y) = f(w, v) implies y = v when /// f is injective in the second argument. /// - public static void QuantifierExample3() + public static void QuantifierExample3(Context ctx) { Console.WriteLine("QuantifierExample3"); - - Dictionary cfg = new Dictionary() { - { "MBQI", "false" }, - { "PROOF_MODE", "2" }, - { "AUTO_CONFIG", "false" } - }; - /* If quantified formulas are asserted in a logical context, then the model produced by Z3 should be viewed as a potential model. */ - using (Context ctx = new Context(cfg)) - { - /* declare function f */ - Sort I = ctx.IntSort; - FuncDecl f = ctx.MkFuncDecl("f", new Sort[] { I, I }, I); + /* declare function f */ + Sort I = ctx.IntSort; + FuncDecl f = ctx.MkFuncDecl("f", new Sort[] { I, I }, I); - /* f is injective in the second argument. */ - BoolExpr inj = InjAxiom(ctx, f, 1); + /* f is injective in the second argument. */ + BoolExpr inj = InjAxiom(ctx, f, 1); - /* create x, y, v, w, fxy, fwv */ - Expr x = ctx.MkIntConst("x"); - Expr y = ctx.MkIntConst("y"); - Expr v = ctx.MkIntConst("v"); - Expr w = ctx.MkIntConst("w"); - Expr fxy = ctx.MkApp(f, x, y); - Expr fwv = ctx.MkApp(f, w, v); + /* create x, y, v, w, fxy, fwv */ + Expr x = ctx.MkIntConst("x"); + Expr y = ctx.MkIntConst("y"); + Expr v = ctx.MkIntConst("v"); + Expr w = ctx.MkIntConst("w"); + Expr fxy = ctx.MkApp(f, x, y); + Expr fwv = ctx.MkApp(f, w, v); - /* f(x, y) = f(w, v) */ - BoolExpr p1 = ctx.MkEq(fxy, fwv); + /* f(x, y) = f(w, v) */ + BoolExpr p1 = ctx.MkEq(fxy, fwv); - /* prove f(x, y) = f(w, v) implies y = v */ - BoolExpr p2 = ctx.MkEq(y, v); - Prove(ctx, p2, inj, p1); + /* prove f(x, y) = f(w, v) implies y = v */ + BoolExpr p2 = ctx.MkEq(y, v); + Prove(ctx, p2, false, inj, p1); - /* disprove f(x, y) = f(w, v) implies x = w */ - BoolExpr p3 = ctx.MkEq(x, w); - Disprove(ctx, p3, inj, p1); - } + /* disprove f(x, y) = f(w, v) implies x = w */ + BoolExpr p3 = ctx.MkEq(x, w); + Disprove(ctx, p3, false, inj, p1); } /// /// Prove that f(x, y) = f(w, v) implies y = v when /// f is injective in the second argument. /// - public static void QuantifierExample4() + public static void QuantifierExample4(Context ctx) { Console.WriteLine("QuantifierExample4"); - Dictionary cfg = new Dictionary() { - { "MBQI", "false" }, - { "PROOF_MODE", "2" }, - { "AUTO_CONFIG","false" }}; - - /* If quantified formulas are asserted in a logical context, then the model produced by Z3 should be viewed as a potential model. */ - using (Context ctx = new Context(cfg)) - { - /* declare function f */ - Sort I = ctx.IntSort; - FuncDecl f = ctx.MkFuncDecl("f", new Sort[] { I, I }, I); + /* declare function f */ + Sort I = ctx.IntSort; + FuncDecl f = ctx.MkFuncDecl("f", new Sort[] { I, I }, I); - /* f is injective in the second argument. */ - BoolExpr inj = InjAxiomAbs(ctx, f, 1); + /* f is injective in the second argument. */ + BoolExpr inj = InjAxiomAbs(ctx, f, 1); - /* create x, y, v, w, fxy, fwv */ - Expr x = ctx.MkIntConst("x"); - Expr y = ctx.MkIntConst("y"); - Expr v = ctx.MkIntConst("v"); - Expr w = ctx.MkIntConst("w"); - Expr fxy = ctx.MkApp(f, x, y); - Expr fwv = ctx.MkApp(f, w, v); + /* create x, y, v, w, fxy, fwv */ + Expr x = ctx.MkIntConst("x"); + Expr y = ctx.MkIntConst("y"); + Expr v = ctx.MkIntConst("v"); + Expr w = ctx.MkIntConst("w"); + Expr fxy = ctx.MkApp(f, x, y); + Expr fwv = ctx.MkApp(f, w, v); - /* f(x, y) = f(w, v) */ - BoolExpr p1 = ctx.MkEq(fxy, fwv); + /* f(x, y) = f(w, v) */ + BoolExpr p1 = ctx.MkEq(fxy, fwv); - /* prove f(x, y) = f(w, v) implies y = v */ - BoolExpr p2 = ctx.MkEq(y, v); - Prove(ctx, p2, inj, p1); + /* prove f(x, y) = f(w, v) implies y = v */ + BoolExpr p2 = ctx.MkEq(y, v); + Prove(ctx, p2, false, inj, p1); - /* disprove f(x, y) = f(w, v) implies x = w */ - BoolExpr p3 = ctx.MkEq(x, w); - Disprove(ctx, p3, inj, p1); - } + /* disprove f(x, y) = f(w, v) implies x = w */ + BoolExpr p3 = ctx.MkEq(x, w); + Disprove(ctx, p3, false, inj, p1); } /// @@ -756,7 +743,7 @@ namespace test_mapi BoolExpr trivial_eq = ctx.MkEq(fapp, fapp); BoolExpr nontrivial_eq = ctx.MkEq(fapp, fapp2); - Goal g = ctx.MkGoal(true, false, true); + Goal g = ctx.MkGoal(true); g.Assert(trivial_eq); g.Assert(nontrivial_eq); Console.WriteLine("Goal: " + g); @@ -784,18 +771,18 @@ namespace test_mapi throw new TestFailedException(); - Goal g2 = ctx.MkGoal(true, true, false); + Goal g2 = ctx.MkGoal(true, true); ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g2); if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedSat) throw new TestFailedException(); - g2 = ctx.MkGoal(true, true, false); + g2 = ctx.MkGoal(true, true); g2.Assert(ctx.MkFalse()); ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g2); if (ar.NumSubgoals != 1 || !ar.Subgoals[0].IsDecidedUnsat) throw new TestFailedException(); - Goal g3 = ctx.MkGoal(true, true, false); + Goal g3 = ctx.MkGoal(true, true); Expr xc = ctx.MkConst(ctx.MkSymbol("x"), ctx.IntSort); Expr yc = ctx.MkConst(ctx.MkSymbol("y"), ctx.IntSort); g3.Assert(ctx.MkEq(xc, ctx.MkNumeral(1, ctx.IntSort))); @@ -839,7 +826,7 @@ namespace test_mapi // Error handling test. try { - Expr plus_ri = ctx.MkAdd(ctx.MkInt(1), ctx.MkReal(2)); + IntExpr i = ctx.MkInt("1/2"); throw new TestFailedException(); // unreachable } catch (Z3Exception) @@ -1063,7 +1050,7 @@ namespace test_mapi // Or perhaps a tactic for QF_BV - Goal g = ctx.MkGoal(true, false, true); + Goal g = ctx.MkGoal(true); g.Assert(eq); Tactic t = ctx.MkTactic("qfbv"); @@ -1086,7 +1073,7 @@ namespace test_mapi Expr y = ctx.MkConst("y", bvs); BoolExpr q = ctx.MkEq(x, y); - Goal g = ctx.MkGoal(true, false, true); + Goal g = ctx.MkGoal(true); g.Assert(q); Tactic t1 = ctx.MkTactic("qfbv"); @@ -1128,7 +1115,7 @@ namespace test_mapi /// public static void FindModelExample2(Context ctx) { - Console.WriteLine("find_model_example2"); + Console.WriteLine("FindModelExample2"); IntExpr x = ctx.MkIntConst("x"); IntExpr y = ctx.MkIntConst("y"); @@ -1250,13 +1237,13 @@ namespace test_mapi /* prove z < 0 */ BoolExpr f = ctx.MkLt(z, zero); Console.WriteLine("prove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < 0"); - Prove(ctx, f, c1, c2, c3); + Prove(ctx, f, false, c1, c2, c3); /* disprove z < -1 */ IntExpr minus_one = ctx.MkInt(-1); f = ctx.MkLt(z, minus_one); Console.WriteLine("disprove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < -1"); - Disprove(ctx, f, c1, c2, c3); + Disprove(ctx, f, false, c1, c2, c3); } /// @@ -1448,7 +1435,7 @@ namespace test_mapi BoolExpr thm = ctx.SMTLIBFormulas[0]; Console.WriteLine("formula: {0}", thm); - Prove(ctx, thm, ca); + Prove(ctx, thm, false, ca); } /// @@ -1979,45 +1966,40 @@ namespace test_mapi /// /// Extract unsatisfiable core example /// - public static void UnsatCoreAndProofExample() + public static void UnsatCoreAndProofExample(Context ctx) { Console.WriteLine("UnsatCoreAndProofExample"); - Dictionary cfg = new Dictionary() { { "PROOF_MODE", "2" } }; + Solver solver = ctx.MkSolver(); - using (Context ctx = new Context(cfg)) + BoolExpr pa = ctx.MkBoolConst("PredA"); + BoolExpr pb = ctx.MkBoolConst("PredB"); + BoolExpr pc = ctx.MkBoolConst("PredC"); + BoolExpr pd = ctx.MkBoolConst("PredD"); + BoolExpr p1 = ctx.MkBoolConst("P1"); + BoolExpr p2 = ctx.MkBoolConst("P2"); + BoolExpr p3 = ctx.MkBoolConst("P3"); + BoolExpr p4 = ctx.MkBoolConst("P4"); + BoolExpr[] assumptions = new BoolExpr[] { ctx.MkNot(p1), ctx.MkNot(p2), ctx.MkNot(p3), ctx.MkNot(p4) }; + BoolExpr f1 = ctx.MkAnd(new BoolExpr[] { pa, pb, pc }); + BoolExpr f2 = ctx.MkAnd(new BoolExpr[] { pa, ctx.MkNot(pb), pc }); + BoolExpr f3 = ctx.MkOr(ctx.MkNot(pa), ctx.MkNot(pc)); + BoolExpr f4 = pd; + + solver.Assert(ctx.MkOr(f1, p1)); + solver.Assert(ctx.MkOr(f2, p2)); + solver.Assert(ctx.MkOr(f3, p3)); + solver.Assert(ctx.MkOr(f4, p4)); + Status result = solver.Check(assumptions); + + if (result == Status.UNSATISFIABLE) { - Solver solver = ctx.MkSolver(); - - BoolExpr pa = ctx.MkBoolConst("PredA"); - BoolExpr pb = ctx.MkBoolConst("PredB"); - BoolExpr pc = ctx.MkBoolConst("PredC"); - BoolExpr pd = ctx.MkBoolConst("PredD"); - BoolExpr p1 = ctx.MkBoolConst("P1"); - BoolExpr p2 = ctx.MkBoolConst("P2"); - BoolExpr p3 = ctx.MkBoolConst("P3"); - BoolExpr p4 = ctx.MkBoolConst("P4"); - BoolExpr[] assumptions = new BoolExpr[] { ctx.MkNot(p1), ctx.MkNot(p2), ctx.MkNot(p3), ctx.MkNot(p4) }; - BoolExpr f1 = ctx.MkAnd(new BoolExpr[] { pa, pb, pc }); - BoolExpr f2 = ctx.MkAnd(new BoolExpr[] { pa, ctx.MkNot(pb), pc }); - BoolExpr f3 = ctx.MkOr(ctx.MkNot(pa), ctx.MkNot(pc)); - BoolExpr f4 = pd; - - solver.Assert(ctx.MkOr(f1, p1)); - solver.Assert(ctx.MkOr(f2, p2)); - solver.Assert(ctx.MkOr(f3, p3)); - solver.Assert(ctx.MkOr(f4, p4)); - Status result = solver.Check(assumptions); - - if (result == Status.UNSATISFIABLE) + Console.WriteLine("unsat"); + Console.WriteLine("proof: {0}", solver.Proof); + Console.WriteLine("core: "); + foreach (Expr c in solver.UnsatCore) { - Console.WriteLine("unsat"); - Console.WriteLine("proof: {0}", solver.Proof); - Console.WriteLine("core: "); - foreach (Expr c in solver.UnsatCore) - { - Console.WriteLine("{0}", c); - } + Console.WriteLine("{0}", c); } } } @@ -2054,9 +2036,8 @@ namespace test_mapi SimpleExample(); - using (Context ctx = new Context(new Dictionary() - { { "MODEL", "true"}, - { "PROOF_MODE", "2"} })) + // These examples need model generation turned on. + using (Context ctx = new Context(new Dictionary() { { "model", "true" } })) { BasicTests(ctx); CastingTest(ctx); @@ -2067,25 +2048,16 @@ namespace test_mapi ParOrExample(ctx); FindModelExample1(ctx); FindModelExample2(ctx); - ProveExample1(ctx); - ProveExample2(ctx); PushPopExample1(ctx); ArrayExample1(ctx); - ArrayExample2(ctx); ArrayExample3(ctx); - TupleExample(ctx); BitvectorExample1(ctx); BitvectorExample2(ctx); ParserExample1(ctx); ParserExample2(ctx); - ParserExample3(ctx); ParserExample4(ctx); ParserExample5(ctx); ITEExample(ctx); - EnumExample(ctx); - ListExample(ctx); - TreeExample(ctx); - ForestExample(ctx); EvalExample1(ctx); EvalExample2(ctx); FindSmallModelExample(ctx); @@ -2093,9 +2065,29 @@ namespace test_mapi FiniteDomainExample(ctx); } - QuantifierExample3(); - QuantifierExample4(); - UnsatCoreAndProofExample(); + // These examples need proof generation turned on. + using (Context ctx = new Context(new Dictionary() { { "proof", "true" } })) + { + ProveExample1(ctx); + ProveExample2(ctx); + ArrayExample2(ctx); + TupleExample(ctx); + ParserExample3(ctx); + EnumExample(ctx); + ListExample(ctx); + TreeExample(ctx); + ForestExample(ctx); + UnsatCoreAndProofExample(ctx); + } + + // These examples need proof generation turned on and auto-config set to false. + using (Context ctx = new Context(new Dictionary() + { {"proof", "true" }, + {"auto-config", "false" } })) + { + QuantifierExample3(ctx); + QuantifierExample4(ctx); + } Log.Close(); if (Log.isOpen()) diff --git a/examples/java/JavaExample.java b/examples/java/JavaExample.java new file mode 100644 index 000000000..b3cb939ac --- /dev/null +++ b/examples/java/JavaExample.java @@ -0,0 +1,2274 @@ +/*++ + Copyright (c) 2012 Microsoft Corporation + +Module Name: + + Program.java + +Abstract: + + Z3 Java API: Example program + +Author: + + Christoph Wintersteiger (cwinter) 2012-11-27 + +Notes: + +--*/ + +import java.util.*; + +import com.microsoft.z3.*; + +class JavaExample +{ + @SuppressWarnings("serial") + class TestFailedException extends Exception + { + public TestFailedException() + { + super("Check FAILED"); + } + }; + + // / Create axiom: function f is injective in the i-th argument. + + // / + // / The following axiom is produced: + // / + // / forall (x_0, ..., x_n) finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i + // / + // / Where, finvis a fresh function declaration. + + public BoolExpr InjAxiom(Context ctx, FuncDecl f, int i) throws Z3Exception + { + Sort[] domain = f.Domain(); + int sz = f.DomainSize(); + + if (i >= sz) + { + System.out.println("failed to create inj axiom"); + return null; + } + + /* declare the i-th inverse of f: finv */ + Sort finv_domain = f.Range(); + Sort finv_range = domain[i]; + FuncDecl finv = ctx.MkFuncDecl("f_fresh", finv_domain, finv_range); + + /* allocate temporary arrays */ + Expr[] xs = new Expr[sz]; + Symbol[] names = new Symbol[sz]; + Sort[] types = new Sort[sz]; + + /* fill types, names and xs */ + + for (int j = 0; j < sz; j++) + { + types[j] = domain[j]; + names[j] = ctx.MkSymbol("x_" + Integer.toString(j)); + xs[j] = ctx.MkBound(j, types[j]); + } + Expr x_i = xs[i]; + + /* create f(x_0, ..., x_i, ..., x_{n-1}) */ + Expr fxs = f.Apply(xs); + + /* create f_inv(f(x_0, ..., x_i, ..., x_{n-1})) */ + Expr finv_fxs = finv.Apply(fxs); + + /* create finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i */ + Expr eq = ctx.MkEq(finv_fxs, x_i); + + /* use f(x_0, ..., x_i, ..., x_{n-1}) as the pattern for the quantifier */ + Pattern p = ctx.MkPattern(new Expr[] { fxs }); + + /* create & assert quantifier */ + BoolExpr q = ctx.MkForall(types, /* types of quantified variables */ + names, /* names of quantified variables */ + eq, 1, new Pattern[] { p } /* patterns */, null, null, null); + + return q; + } + + // / Create axiom: function f is injective in the i-th argument. + + // / + // / The following axiom is produced: + // / + // / forall (x_0, ..., x_n) finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i + // / + // / Where, finvis a fresh function declaration. + + public BoolExpr InjAxiomAbs(Context ctx, FuncDecl f, int i) + throws Z3Exception + { + Sort[] domain = f.Domain(); + int sz = f.DomainSize(); + + if (i >= sz) + { + System.out.println("failed to create inj axiom"); + return null; + } + + /* declare the i-th inverse of f: finv */ + Sort finv_domain = f.Range(); + Sort finv_range = domain[i]; + FuncDecl finv = ctx.MkFuncDecl("f_fresh", finv_domain, finv_range); + + /* allocate temporary arrays */ + Expr[] xs = new Expr[sz]; + + /* fill types, names and xs */ + for (int j = 0; j < sz; j++) + { + xs[j] = ctx.MkConst("x_" + Integer.toString(j), domain[j]); + } + Expr x_i = xs[i]; + + /* create f(x_0, ..., x_i, ..., x_{n-1}) */ + Expr fxs = f.Apply(xs); + + /* create f_inv(f(x_0, ..., x_i, ..., x_{n-1})) */ + Expr finv_fxs = finv.Apply(fxs); + + /* create finv(f(x_0, ..., x_i, ..., x_{n-1})) = x_i */ + Expr eq = ctx.MkEq(finv_fxs, x_i); + + /* use f(x_0, ..., x_i, ..., x_{n-1}) as the pattern for the quantifier */ + Pattern p = ctx.MkPattern(new Expr[] { fxs }); + + /* create & assert quantifier */ + BoolExpr q = ctx.MkForall(xs, /* types of quantified variables */ + eq, /* names of quantified variables */ + 1, new Pattern[] { p } /* patterns */, null, null, null); + + return q; + } + + // / Assert the axiom: function f is commutative. + + // / + // / This example uses the SMT-LIB parser to simplify the axiom + // construction. + // / + private BoolExpr CommAxiom(Context ctx, FuncDecl f) throws Exception + { + Sort t = f.Range(); + Sort[] dom = f.Domain(); + + if (dom.length != 2 || !t.equals(dom[0]) || !t.equals(dom[1])) + { + System.out.println(Integer.toString(dom.length) + " " + + dom[0].toString() + " " + dom[1].toString() + " " + + t.toString()); + throw new Exception( + "function must be binary, and argument types must be equal to return type"); + } + + String bench = "(benchmark comm :formula (forall (x " + t.Name() + + ") (y " + t.Name() + ") (= (" + f.Name() + " x y) (" + + f.Name() + " y x))))"; + ctx.ParseSMTLIBString(bench, new Symbol[] { t.Name() }, + new Sort[] { t }, new Symbol[] { f.Name() }, + new FuncDecl[] { f }); + return ctx.SMTLIBFormulas()[0]; + } + + // / "Hello world" example: create a Z3 logical context, and delete it. + + public void SimpleExample() throws Z3Exception + { + System.out.println("SimpleExample"); + Log.Append("SimpleExample"); + + { + Context ctx = new Context(); + /* do something with the context */ + + /* be kind to dispose manually and not wait for the GC. */ + ctx.Dispose(); + } + } + + Model Check(Context ctx, BoolExpr f, Status sat) throws Z3Exception, + TestFailedException + { + Solver s = ctx.MkSolver(); + s.Assert(f); + if (s.Check() != sat) + throw new TestFailedException(); + if (sat == Status.SATISFIABLE) + return s.Model(); + else + return null; + } + + void SolveTactical(Context ctx, Tactic t, Goal g, Status sat) + throws Z3Exception, TestFailedException + { + Solver s = ctx.MkSolver(t); + System.out.println("\nTactical solver: " + s); + + for (BoolExpr a : g.Formulas()) + s.Assert(a); + System.out.println("Solver: " + s); + + if (s.Check() != sat) + throw new TestFailedException(); + } + + ApplyResult ApplyTactic(Context ctx, Tactic t, Goal g) throws Z3Exception + { + System.out.println("\nGoal: " + g); + + ApplyResult res = t.Apply(g); + System.out.println("Application result: " + res); + + Status q = Status.UNKNOWN; + for (Goal sg : res.Subgoals()) + if (sg.IsDecidedSat()) + q = Status.SATISFIABLE; + else if (sg.IsDecidedUnsat()) + q = Status.UNSATISFIABLE; + + switch (q) + { + case UNKNOWN: + System.out.println("Tactic result: Undecided"); + break; + case SATISFIABLE: + System.out.println("Tactic result: SAT"); + break; + case UNSATISFIABLE: + System.out.println("Tactic result: UNSAT"); + break; + } + + return res; + } + + void Prove(Context ctx, BoolExpr f, boolean useMBQI) throws Z3Exception, + TestFailedException + { + BoolExpr[] assumptions = new BoolExpr[0]; + Prove(ctx, f, useMBQI, assumptions); + } + + void Prove(Context ctx, BoolExpr f, boolean useMBQI, BoolExpr assumption) + throws Z3Exception, TestFailedException + { + BoolExpr[] assumptions = { assumption }; + Prove(ctx, f, useMBQI, assumptions); + } + + void Prove(Context ctx, BoolExpr f, boolean useMBQI, BoolExpr[] assumptions) + throws Z3Exception, TestFailedException + { + System.out.println("Proving: " + f); + Solver s = ctx.MkSolver(); + Params p = ctx.MkParams(); + p.Add("mbqi", useMBQI); + s.setParameters(p); + for (BoolExpr a : assumptions) + s.Assert(a); + s.Assert(ctx.MkNot(f)); + Status q = s.Check(); + + switch (q) + { + case UNKNOWN: + System.out.println("Unknown because: " + s.ReasonUnknown()); + break; + case SATISFIABLE: + throw new TestFailedException(); + case UNSATISFIABLE: + System.out.println("OK, proof: " + s.Proof()); + break; + } + } + + void Disprove(Context ctx, BoolExpr f, boolean useMBQI) throws Z3Exception, + TestFailedException + { + BoolExpr[] a = {}; + Disprove(ctx, f, useMBQI, a); + } + + void Disprove(Context ctx, BoolExpr f, boolean useMBQI, BoolExpr assumption) + throws Z3Exception, TestFailedException + { + BoolExpr[] a = { assumption }; + Disprove(ctx, f, useMBQI, a); + } + + void Disprove(Context ctx, BoolExpr f, boolean useMBQI, + BoolExpr[] assumptions) throws Z3Exception, TestFailedException + { + System.out.println("Disproving: " + f); + Solver s = ctx.MkSolver(); + Params p = ctx.MkParams(); + p.Add("mbqi", useMBQI); + s.setParameters(p); + for (BoolExpr a : assumptions) + s.Assert(a); + s.Assert(ctx.MkNot(f)); + Status q = s.Check(); + + switch (q) + { + case UNKNOWN: + System.out.println("Unknown because: " + s.ReasonUnknown()); + break; + case SATISFIABLE: + System.out.println("OK, model: " + s.Model()); + break; + case UNSATISFIABLE: + throw new TestFailedException(); + } + } + + void ModelConverterTest(Context ctx) throws Z3Exception, + TestFailedException + { + System.out.println("ModelConverterTest"); + + ArithExpr xr = (ArithExpr) ctx.MkConst(ctx.MkSymbol("x"), + ctx.MkRealSort()); + ArithExpr yr = (ArithExpr) ctx.MkConst(ctx.MkSymbol("y"), + ctx.MkRealSort()); + Goal g4 = ctx.MkGoal(true, false, false); + g4.Assert(ctx.MkGt(xr, ctx.MkReal(10, 1))); + g4.Assert(ctx.MkEq(yr, + ctx.MkAdd(new ArithExpr[] { xr, ctx.MkReal(1, 1) }))); + g4.Assert(ctx.MkGt(yr, ctx.MkReal(1, 1))); + + ApplyResult ar = ApplyTactic(ctx, ctx.MkTactic("simplify"), g4); + if (ar.NumSubgoals() == 1 + && (ar.Subgoals()[0].IsDecidedSat() || ar.Subgoals()[0] + .IsDecidedUnsat())) + throw new TestFailedException(); + + ar = ApplyTactic(ctx, ctx.AndThen(ctx.MkTactic("simplify"), + ctx.MkTactic("solve-eqs"), null), g4); + if (ar.NumSubgoals() == 1 + && (ar.Subgoals()[0].IsDecidedSat() || ar.Subgoals()[0] + .IsDecidedUnsat())) + throw new TestFailedException(); + + Solver s = ctx.MkSolver(); + for (BoolExpr e : ar.Subgoals()[0].Formulas()) + s.Assert(e); + Status q = s.Check(); + System.out.println("Solver says: " + q); + System.out.println("Model: \n" + s.Model()); + System.out.println("Converted Model: \n" + + ar.ConvertModel(0, s.Model())); + if (q != Status.SATISFIABLE) + throw new TestFailedException(); + } + + // / A simple array example. + + void ArrayExample1(Context ctx) throws Z3Exception, TestFailedException + { + System.out.println("ArrayExample1"); + Log.Append("ArrayExample1"); + + Goal g = ctx.MkGoal(true, false, false); + ArraySort asort = ctx.MkArraySort(ctx.IntSort(), ctx.MkBitVecSort(32)); + ArrayExpr aex = (ArrayExpr) ctx.MkConst(ctx.MkSymbol("MyArray"), asort); + Expr sel = ctx.MkSelect(aex, ctx.MkInt(0)); + g.Assert(ctx.MkEq(sel, ctx.MkBV(42, 32))); + Symbol xs = ctx.MkSymbol("x"); + IntExpr xc = (IntExpr) ctx.MkConst(xs, ctx.IntSort()); + + Symbol fname = ctx.MkSymbol("f"); + Sort[] domain = { ctx.IntSort() }; + FuncDecl fd = ctx.MkFuncDecl(fname, domain, ctx.IntSort()); + Expr[] fargs = { ctx.MkConst(xs, ctx.IntSort()) }; + IntExpr fapp = (IntExpr) ctx.MkApp(fd, fargs); + + g.Assert(ctx.MkEq(ctx.MkAdd(new ArithExpr[] { xc, fapp }), + ctx.MkInt(123))); + + Solver s = ctx.MkSolver(); + for (BoolExpr a : g.Formulas()) + s.Assert(a); + System.out.println("Solver: " + s); + + Status q = s.Check(); + System.out.println("Status: " + q); + + if (q != Status.SATISFIABLE) + throw new TestFailedException(); + + System.out.println("Model = " + s.Model()); + + System.out.println("Interpretation of MyArray:\n" + + s.Model().FuncInterp(aex.FuncDecl())); + System.out + .println("Interpretation of x:\n" + s.Model().ConstInterp(xc)); + System.out.println("Interpretation of f:\n" + s.Model().FuncInterp(fd)); + System.out.println("Interpretation of MyArray as Term:\n" + + s.Model().FuncInterp(aex.FuncDecl())); + } + + // / Prove store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 + // = i3 or select(a1, i3) = select(a2, i3)). + + // / This example demonstrates how to use the array + // theory. + public void ArrayExample2(Context ctx) throws Z3Exception, + TestFailedException + { + System.out.println("ArrayExample2"); + Log.Append("ArrayExample2"); + + Sort int_type = ctx.IntSort(); + Sort array_type = ctx.MkArraySort(int_type, int_type); + + ArrayExpr a1 = (ArrayExpr) ctx.MkConst("a1", array_type); + ArrayExpr a2 = ctx.MkArrayConst("a2", int_type, int_type); + Expr i1 = ctx.MkConst("i1", int_type); + Expr i2 = ctx.MkConst("i2", int_type); + Expr i3 = ctx.MkConst("i3", int_type); + Expr v1 = ctx.MkConst("v1", int_type); + Expr v2 = ctx.MkConst("v2", int_type); + + Expr st1 = ctx.MkStore(a1, i1, v1); + Expr st2 = ctx.MkStore(a2, i2, v2); + + Expr sel1 = ctx.MkSelect(a1, i3); + Expr sel2 = ctx.MkSelect(a2, i3); + + /* create antecedent */ + BoolExpr antecedent = ctx.MkEq(st1, st2); + + /* + * create consequent: i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, + * i3) + */ + BoolExpr consequent = ctx.MkOr(new BoolExpr[] { ctx.MkEq(i1, i3), + ctx.MkEq(i2, i3), ctx.MkEq(sel1, sel2) }); + + /* + * prove store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = + * i3 or select(a1, i3) = select(a2, i3)) + */ + BoolExpr thm = ctx.MkImplies(antecedent, consequent); + System.out + .println("prove: store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3))"); + System.out.println(thm); + Prove(ctx, thm, false); + } + + // / Show that distinct(a_0, ... , a_n) is + // / unsatisfiable when a_i's are arrays from boolean to + // / boolean and n > 4. + + // / This example also shows how to use the distinct + // construct. + public void ArrayExample3(Context ctx) throws Z3Exception, + TestFailedException + { + System.out.println("ArrayExample3"); + Log.Append("ArrayExample2"); + + for (int n = 2; n <= 5; n++) + { + System.out.println("n = " + Integer.toString(n)); + + Sort bool_type = ctx.MkBoolSort(); + Sort array_type = ctx.MkArraySort(bool_type, bool_type); + Expr[] a = new Expr[n]; + + /* create arrays */ + for (int i = 0; i < n; i++) + { + a[i] = ctx.MkConst("array_" + Integer.toString(i), array_type); + } + + /* assert distinct(a[0], ..., a[n]) */ + BoolExpr d = ctx.MkDistinct(a); + System.out.println(d); + + /* context is satisfiable if n < 5 */ + Model model = Check(ctx, d, n < 5 ? Status.SATISFIABLE + : Status.UNSATISFIABLE); + if (n < 5) + { + for (int i = 0; i < n; i++) + { + System.out.println(a[i].toString() + " = " + + model.Evaluate(a[i], false)); + } + } + } + } + + // / Sudoku solving example. + + void SudokuExample(Context ctx) throws Z3Exception, TestFailedException + { + System.out.println("SudokuExample"); + Log.Append("SudokuExample"); + + // 9x9 matrix of integer variables + IntExpr[][] X = new IntExpr[9][]; + for (int i = 0; i < 9; i++) + { + X[i] = new IntExpr[9]; + for (int j = 0; j < 9; j++) + X[i][j] = (IntExpr) ctx.MkConst( + ctx.MkSymbol("x_" + (i + 1) + "_" + (j + 1)), + ctx.IntSort()); + } + + // each cell contains a value in {1, ..., 9} + BoolExpr[][] cells_c = new BoolExpr[9][]; + for (int i = 0; i < 9; i++) + { + cells_c[i] = new BoolExpr[9]; + for (int j = 0; j < 9; j++) + cells_c[i][j] = ctx.MkAnd(new BoolExpr[] { + ctx.MkLe(ctx.MkInt(1), X[i][j]), + ctx.MkLe(X[i][j], ctx.MkInt(9)) }); + } + + // each row contains a digit at most once + BoolExpr[] rows_c = new BoolExpr[9]; + for (int i = 0; i < 9; i++) + rows_c[i] = ctx.MkDistinct(X[i]); + + // each column contains a digit at most once + BoolExpr[] cols_c = new BoolExpr[9]; + for (int j = 0; j < 9; j++) + cols_c[j] = ctx.MkDistinct(X[j]); + + // each 3x3 square contains a digit at most once + BoolExpr[][] sq_c = new BoolExpr[3][]; + for (int i0 = 0; i0 < 3; i0++) + { + sq_c[i0] = new BoolExpr[3]; + for (int j0 = 0; j0 < 3; j0++) + { + IntExpr[] square = new IntExpr[9]; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + square[3 * i + j] = X[3 * i0 + i][3 * j0 + j]; + sq_c[i0][j0] = ctx.MkDistinct(square); + } + } + + BoolExpr sudoku_c = ctx.MkTrue(); + for (BoolExpr[] t : cells_c) + sudoku_c = ctx.MkAnd(new BoolExpr[] { ctx.MkAnd(t), sudoku_c }); + sudoku_c = ctx.MkAnd(new BoolExpr[] { ctx.MkAnd(rows_c), sudoku_c }); + sudoku_c = ctx.MkAnd(new BoolExpr[] { ctx.MkAnd(cols_c), sudoku_c }); + for (BoolExpr[] t : sq_c) + sudoku_c = ctx.MkAnd(new BoolExpr[] { ctx.MkAnd(t), sudoku_c }); + + // sudoku instance, we use '0' for empty cells + int[][] instance = { { 0, 0, 0, 0, 9, 4, 0, 3, 0 }, + { 0, 0, 0, 5, 1, 0, 0, 0, 7 }, { 0, 8, 9, 0, 0, 0, 0, 4, 0 }, + { 0, 0, 0, 0, 0, 0, 2, 0, 8 }, { 0, 6, 0, 2, 0, 1, 0, 5, 0 }, + { 1, 0, 2, 0, 0, 0, 0, 0, 0 }, { 0, 7, 0, 0, 0, 0, 5, 2, 0 }, + { 9, 0, 0, 0, 6, 5, 0, 0, 0 }, { 0, 4, 0, 9, 7, 0, 0, 0, 0 } }; + + BoolExpr instance_c = ctx.MkTrue(); + for (int i = 0; i < 9; i++) + for (int j = 0; j < 9; j++) + instance_c = ctx + .MkAnd(new BoolExpr[] { + instance_c, + (BoolExpr) ctx.MkITE( + ctx.MkEq(ctx.MkInt(instance[i][j]), + ctx.MkInt(0)), + ctx.MkTrue(), + ctx.MkEq(X[i][j], + ctx.MkInt(instance[i][j]))) }); + + Solver s = ctx.MkSolver(); + s.Assert(sudoku_c); + s.Assert(instance_c); + + if (s.Check() == Status.SATISFIABLE) + { + Model m = s.Model(); + Expr[][] R = new Expr[9][9]; + for (int i = 0; i < 9; i++) + for (int j = 0; j < 9; j++) + R[i][j] = m.Evaluate(X[i][j], false); + System.out.println("Sudoku solution:"); + for (int i = 0; i < 9; i++) + { + for (int j = 0; j < 9; j++) + System.out.print(" " + R[i][j]); + System.out.println(); + } + } else + { + System.out.println("Failed to solve sudoku"); + throw new TestFailedException(); + } + } + + // / A basic example of how to use quantifiers. + + void QuantifierExample1(Context ctx) throws Z3Exception + { + System.out.println("QuantifierExample"); + Log.Append("QuantifierExample"); + + Sort[] types = new Sort[3]; + IntExpr[] xs = new IntExpr[3]; + Symbol[] names = new Symbol[3]; + IntExpr[] vars = new IntExpr[3]; + + for (int j = 0; j < 3; j++) + { + types[j] = ctx.IntSort(); + names[j] = ctx.MkSymbol("x_" + Integer.toString(j)); + xs[j] = (IntExpr) ctx.MkConst(names[j], types[j]); + vars[j] = (IntExpr) ctx.MkBound(2 - j, types[j]); // <-- vars + // reversed! + } + + Expr body_vars = ctx + .MkAnd(new BoolExpr[] { + ctx.MkEq( + ctx.MkAdd(new ArithExpr[] { vars[0], + ctx.MkInt(1) }), ctx.MkInt(2)), + ctx.MkEq( + ctx.MkAdd(new ArithExpr[] { vars[1], + ctx.MkInt(2) }), + ctx.MkAdd(new ArithExpr[] { vars[2], + ctx.MkInt(3) })) }); + + Expr body_const = ctx.MkAnd(new BoolExpr[] { + ctx.MkEq(ctx.MkAdd(new ArithExpr[] { xs[0], ctx.MkInt(1) }), + ctx.MkInt(2)), + ctx.MkEq(ctx.MkAdd(new ArithExpr[] { xs[1], ctx.MkInt(2) }), + ctx.MkAdd(new ArithExpr[] { xs[2], ctx.MkInt(3) })) }); + + Expr x = ctx.MkForall(types, names, body_vars, 1, null, null, + ctx.MkSymbol("Q1"), ctx.MkSymbol("skid1")); + System.out.println("Quantifier X: " + x.toString()); + + Expr y = ctx.MkForall(xs, body_const, 1, null, null, + ctx.MkSymbol("Q2"), ctx.MkSymbol("skid2")); + System.out.println("Quantifier Y: " + y.toString()); + } + + void QuantifierExample2(Context ctx) throws Z3Exception + { + + System.out.println("QuantifierExample2"); + Log.Append("QuantifierExample2"); + + Expr q1, q2; + FuncDecl f = ctx.MkFuncDecl("f", ctx.IntSort(), ctx.IntSort()); + FuncDecl g = ctx.MkFuncDecl("g", ctx.IntSort(), ctx.IntSort()); + + // Quantifier with Exprs as the bound variables. + { + Expr x = ctx.MkConst("x", ctx.IntSort()); + Expr y = ctx.MkConst("y", ctx.IntSort()); + Expr f_x = ctx.MkApp(f, new Expr[] { x }); + Expr f_y = ctx.MkApp(f, new Expr[] { y }); + Expr g_y = ctx.MkApp(g, new Expr[] { y }); + Pattern[] pats = new Pattern[] { ctx.MkPattern(new Expr[] { f_x, + g_y }) }; + Expr[] no_pats = new Expr[] { f_y }; + Expr[] bound = new Expr[] { x, y }; + Expr body = ctx.MkAnd(new BoolExpr[] { ctx.MkEq(f_x, f_y), + ctx.MkEq(f_y, g_y) }); + + q1 = ctx.MkForall(bound, body, 1, null, no_pats, ctx.MkSymbol("q"), + ctx.MkSymbol("sk")); + + System.out.println(q1); + } + + // Quantifier with de-Brujin indices. + { + Expr x = ctx.MkBound(1, ctx.IntSort()); + Expr y = ctx.MkBound(0, ctx.IntSort()); + Expr f_x = ctx.MkApp(f, new Expr[] { x }); + Expr f_y = ctx.MkApp(f, new Expr[] { y }); + Expr g_y = ctx.MkApp(g, new Expr[] { y }); + Pattern[] pats = new Pattern[] { ctx.MkPattern(new Expr[] { f_x, + g_y }) }; + Expr[] no_pats = new Expr[] { f_y }; + Symbol[] names = new Symbol[] { ctx.MkSymbol("x"), + ctx.MkSymbol("y") }; + Sort[] sorts = new Sort[] { ctx.IntSort(), ctx.IntSort() }; + Expr body = ctx.MkAnd(new BoolExpr[] { ctx.MkEq(f_x, f_y), + ctx.MkEq(f_y, g_y) }); + + q2 = ctx.MkForall(sorts, names, body, 1, null, // pats, + no_pats, ctx.MkSymbol("q"), ctx.MkSymbol("sk")); + System.out.println(q2); + } + + System.out.println(q1.equals(q2)); + } + + // / Prove that f(x, y) = f(w, v) implies y = v when + // / f is injective in the second argument. + + public void QuantifierExample3(Context ctx) throws Z3Exception, + TestFailedException + { + System.out.println("QuantifierExample3"); + Log.Append("QuantifierExample3"); + + /* + * If quantified formulas are asserted in a logical context, then the + * model produced by Z3 should be viewed as a potential model. + */ + + /* declare function f */ + Sort I = ctx.IntSort(); + FuncDecl f = ctx.MkFuncDecl("f", new Sort[] { I, I }, I); + + /* f is injective in the second argument. */ + BoolExpr inj = InjAxiom(ctx, f, 1); + + /* create x, y, v, w, fxy, fwv */ + Expr x = ctx.MkIntConst("x"); + Expr y = ctx.MkIntConst("y"); + Expr v = ctx.MkIntConst("v"); + Expr w = ctx.MkIntConst("w"); + Expr fxy = ctx.MkApp(f, new Expr[] { x, y }); + Expr fwv = ctx.MkApp(f, new Expr[] { w, v }); + + /* f(x, y) = f(w, v) */ + BoolExpr p1 = ctx.MkEq(fxy, fwv); + + /* prove f(x, y) = f(w, v) implies y = v */ + BoolExpr p2 = ctx.MkEq(y, v); + Prove(ctx, p2, false, new BoolExpr[] { inj, p1 }); + + /* disprove f(x, y) = f(w, v) implies x = w */ + BoolExpr p3 = ctx.MkEq(x, w); + Disprove(ctx, p3, false, new BoolExpr[] { inj, p1 }); + } + + // / Prove that f(x, y) = f(w, v) implies y = v when + // / f is injective in the second argument. + + public void QuantifierExample4(Context ctx) throws Z3Exception, TestFailedException + { + System.out.println("QuantifierExample4"); + Log.Append("QuantifierExample4"); + + /* + * If quantified formulas are asserted in a logical context, then the + * model produced by Z3 should be viewed as a potential model. + */ + + /* declare function f */ + Sort I = ctx.IntSort(); + FuncDecl f = ctx.MkFuncDecl("f", new Sort[] { I, I }, I); + + /* f is injective in the second argument. */ + BoolExpr inj = InjAxiomAbs(ctx, f, 1); + + /* create x, y, v, w, fxy, fwv */ + Expr x = ctx.MkIntConst("x"); + Expr y = ctx.MkIntConst("y"); + Expr v = ctx.MkIntConst("v"); + Expr w = ctx.MkIntConst("w"); + Expr fxy = ctx.MkApp(f, new Expr[] { x, y }); + Expr fwv = ctx.MkApp(f, new Expr[] { w, v }); + + /* f(x, y) = f(w, v) */ + BoolExpr p1 = ctx.MkEq(fxy, fwv); + + /* prove f(x, y) = f(w, v) implies y = v */ + BoolExpr p2 = ctx.MkEq(y, v); + Prove(ctx, p2, false, new BoolExpr[] { inj, p1 }); + + /* disprove f(x, y) = f(w, v) implies x = w */ + BoolExpr p3 = ctx.MkEq(x, w); + Disprove(ctx, p3, false, new BoolExpr[] { inj, p1 }); + } + + // / Some basic tests. + + void BasicTests(Context ctx) throws Z3Exception, TestFailedException + { + System.out.println("BasicTests"); + + Symbol fname = ctx.MkSymbol("f"); + Symbol x = ctx.MkSymbol("x"); + Symbol y = ctx.MkSymbol("y"); + + Sort bs = ctx.MkBoolSort(); + + Sort[] domain = { bs, bs }; + FuncDecl f = ctx.MkFuncDecl(fname, domain, bs); + Expr fapp = ctx.MkApp(f, + new Expr[] { ctx.MkConst(x, bs), ctx.MkConst(y, bs) }); + + Expr[] fargs2 = { ctx.MkFreshConst("cp", bs) }; + Sort[] domain2 = { bs }; + Expr fapp2 = ctx.MkApp(ctx.MkFreshFuncDecl("fp", domain2, bs), fargs2); + + BoolExpr trivial_eq = ctx.MkEq(fapp, fapp); + BoolExpr nontrivial_eq = ctx.MkEq(fapp, fapp2); + + Goal g = ctx.MkGoal(true, false, false); + g.Assert(trivial_eq); + g.Assert(nontrivial_eq); + System.out.println("Goal: " + g); + + Solver solver = ctx.MkSolver(); + + for (BoolExpr a : g.Formulas()) + solver.Assert(a); + + if (solver.Check() != Status.SATISFIABLE) + throw new TestFailedException(); + + ApplyResult ar = ApplyTactic(ctx, ctx.MkTactic("simplify"), g); + if (ar.NumSubgoals() == 1 + && (ar.Subgoals()[0].IsDecidedSat() || ar.Subgoals()[0] + .IsDecidedUnsat())) + throw new TestFailedException(); + + ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g); + if (ar.NumSubgoals() != 1 || !ar.Subgoals()[0].IsDecidedSat()) + throw new TestFailedException(); + + g.Assert(ctx.MkEq(ctx.MkNumeral(1, ctx.MkBitVecSort(32)), + ctx.MkNumeral(2, ctx.MkBitVecSort(32)))); + ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g); + if (ar.NumSubgoals() != 1 || !ar.Subgoals()[0].IsDecidedUnsat()) + throw new TestFailedException(); + + Goal g2 = ctx.MkGoal(true, true, false); + ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g2); + if (ar.NumSubgoals() != 1 || !ar.Subgoals()[0].IsDecidedSat()) + throw new TestFailedException(); + + g2 = ctx.MkGoal(true, true, false); + g2.Assert(ctx.MkFalse()); + ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g2); + if (ar.NumSubgoals() != 1 || !ar.Subgoals()[0].IsDecidedUnsat()) + throw new TestFailedException(); + + Goal g3 = ctx.MkGoal(true, true, false); + Expr xc = ctx.MkConst(ctx.MkSymbol("x"), ctx.IntSort()); + Expr yc = ctx.MkConst(ctx.MkSymbol("y"), ctx.IntSort()); + g3.Assert(ctx.MkEq(xc, ctx.MkNumeral(1, ctx.IntSort()))); + g3.Assert(ctx.MkEq(yc, ctx.MkNumeral(2, ctx.IntSort()))); + BoolExpr constr = ctx.MkEq(xc, yc); + g3.Assert(constr); + ar = ApplyTactic(ctx, ctx.MkTactic("smt"), g3); + if (ar.NumSubgoals() != 1 || !ar.Subgoals()[0].IsDecidedUnsat()) + throw new TestFailedException(); + + ModelConverterTest(ctx); + + // Real num/den test. + RatNum rn = ctx.MkReal(42, 43); + Expr inum = rn.Numerator(); + Expr iden = rn.Denominator(); + System.out.println("Numerator: " + inum + " Denominator: " + iden); + if (!inum.toString().equals("42") || !iden.toString().equals("43")) + throw new TestFailedException(); + + if (!rn.ToDecimalString(3).toString().equals("0.976?")) + throw new TestFailedException(); + + BigIntCheck(ctx, ctx.MkReal("-1231231232/234234333")); + BigIntCheck(ctx, ctx.MkReal("-123123234234234234231232/234234333")); + BigIntCheck(ctx, ctx.MkReal("-234234333")); + BigIntCheck(ctx, ctx.MkReal("234234333/2")); + + String bn = "1234567890987654321"; + + if (!ctx.MkInt(bn).BigInteger().toString().equals(bn)) + throw new TestFailedException(); + + if (!ctx.MkBV(bn, 128).BigInteger().toString().equals(bn)) + throw new TestFailedException(); + + if (ctx.MkBV(bn, 32).BigInteger().toString().equals(bn)) + throw new TestFailedException(); + + // Error handling test. + try + { + IntExpr i = ctx.MkInt("1/2"); + throw new TestFailedException(); // unreachable + } catch (Z3Exception e) + { + } + } + + // / Some basic expression casting tests. + + void CastingTest(Context ctx) throws Z3Exception, TestFailedException + { + System.out.println("CastingTest"); + + Sort[] domain = { ctx.BoolSort(), ctx.BoolSort() }; + FuncDecl f = ctx.MkFuncDecl("f", domain, ctx.BoolSort()); + + AST upcast = ctx.MkFuncDecl(ctx.MkSymbol("q"), domain, ctx.BoolSort()); + + try + { + FuncDecl downcast = (FuncDecl) f; // OK + } catch (ClassCastException e) + { + throw new TestFailedException(); + } + + try + { + Expr uc = (Expr) upcast; + throw new TestFailedException(); // should not be reachable! + } catch (ClassCastException e) + { + } + + Symbol s = ctx.MkSymbol(42); + IntSymbol si = (s.getClass() == IntSymbol.class) ? (IntSymbol) s : null; + if (si == null) + throw new TestFailedException(); + try + { + IntSymbol si2 = (IntSymbol) s; + } catch (ClassCastException e) + { + throw new TestFailedException(); + } + + s = ctx.MkSymbol("abc"); + StringSymbol ss = (s.getClass() == StringSymbol.class) ? (StringSymbol) s + : null; + if (ss == null) + throw new TestFailedException(); + try + { + StringSymbol ss2 = (StringSymbol) s; + } catch (ClassCastException e) + { + throw new TestFailedException(); + } + try + { + IntSymbol si2 = (IntSymbol) s; + throw new TestFailedException(); // unreachable + } catch (Exception e) + { + } + + Sort srt = ctx.MkBitVecSort(32); + BitVecSort bvs = null; + try + { + bvs = (BitVecSort) srt; + } catch (ClassCastException e) + { + throw new TestFailedException(); + } + + if (bvs.Size() != 32) + throw new TestFailedException(); + + Expr q = ctx.MkAdd(new ArithExpr[] { ctx.MkInt(1), ctx.MkInt(2) }); + Expr q2 = q.Args()[1]; + Sort qs = q2.Sort(); + if (qs.getClass() != IntSort.class) + throw new TestFailedException(); + try + { + IntSort isrt = (IntSort) qs; + } catch (ClassCastException e) + { + throw new TestFailedException(); + } + + AST a = ctx.MkInt(42); + + try + { + Expr.class.cast(a); + } catch (ClassCastException e) + { + throw new TestFailedException(); + } + + try + { + ArithExpr.class.cast(a); + } catch (ClassCastException e) + { + throw new TestFailedException(); + } + + try + { + IntExpr.class.cast(a); + } catch (ClassCastException e) + { + throw new TestFailedException(); + } + + try + { + IntNum.class.cast(a); + } catch (ClassCastException e) + { + throw new TestFailedException(); + } + + Expr[][] earr = new Expr[2][]; + earr[0] = new Expr[2]; + earr[1] = new Expr[2]; + earr[0][0] = ctx.MkTrue(); + earr[0][1] = ctx.MkTrue(); + earr[1][0] = ctx.MkFalse(); + earr[1][1] = ctx.MkFalse(); + for (Expr[] ea : earr) + for (Expr e : ea) + { + try + { + Expr ns = ctx.MkNot((BoolExpr) e); + BoolExpr ens = (BoolExpr) ns; + } catch (ClassCastException ex) + { + throw new TestFailedException(); + } + } + } + + // / Shows how to read an SMT1 file. + + void SMT1FileTest(String filename) throws Z3Exception + { + System.out.print("SMT File test "); + + { + HashMap cfg = new HashMap(); + Context ctx = new Context(cfg); + ctx.ParseSMTLIBFile(filename, null, null, null, null); + + BoolExpr a = ctx.MkAnd(ctx.SMTLIBFormulas()); + System.out.println("read formula: " + a); + } + } + + // / Shows how to read an SMT2 file. + + void SMT2FileTest(String filename) throws Z3Exception + { + Date before = new Date(); + + System.out.println("SMT2 File test "); + System.gc(); + + { + HashMap cfg = new HashMap(); + cfg.put("model", "true"); + Context ctx = new Context(cfg); + Expr a = ctx.ParseSMTLIB2File(filename, null, null, null, null); + + long t_diff = ((new Date()).getTime() - before.getTime()) / 1000; + + System.out.println("SMT2 file read time: " + t_diff + " sec"); + + // Iterate over the formula. + + LinkedList q = new LinkedList(); + q.add(a); + int cnt = 0; + while (q.size() > 0) + { + AST cur = (AST) q.removeFirst(); + cnt++; + + if (cur.getClass() == Expr.class) + if (!(cur.IsVar())) + for (Expr c : ((Expr) cur).Args()) + q.add(c); + } + System.out.println(cnt + " ASTs"); + } + + long t_diff = ((new Date()).getTime() - before.getTime()) / 1000; + System.out.println("SMT2 file test took " + t_diff + " sec"); + } + + // / Shows how to use Solver(logic) + + // / + void LogicExample(Context ctx) throws Z3Exception, TestFailedException + { + System.out.println("LogicTest"); + Log.Append("LogicTest"); + + Context.ToggleWarningMessages(true); + + BitVecSort bvs = ctx.MkBitVecSort(32); + Expr x = ctx.MkConst("x", bvs); + Expr y = ctx.MkConst("y", bvs); + BoolExpr eq = ctx.MkEq(x, y); + + // Use a solver for QF_BV + Solver s = ctx.MkSolver("QF_BV"); + s.Assert(eq); + Status res = s.Check(); + System.out.println("solver result: " + res); + + // Or perhaps a tactic for QF_BV + Goal g = ctx.MkGoal(true, false, false); + g.Assert(eq); + + Tactic t = ctx.MkTactic("qfbv"); + ApplyResult ar = t.Apply(g); + System.out.println("tactic result: " + ar); + + if (ar.NumSubgoals() != 1 || !ar.Subgoals()[0].IsDecidedSat()) + throw new TestFailedException(); + } + + // / Demonstrates how to use the ParOr tactic. + + void ParOrExample(Context ctx) throws Z3Exception, TestFailedException + { + System.out.println("ParOrExample"); + Log.Append("ParOrExample"); + + BitVecSort bvs = ctx.MkBitVecSort(32); + Expr x = ctx.MkConst("x", bvs); + Expr y = ctx.MkConst("y", bvs); + BoolExpr q = ctx.MkEq(x, y); + + Goal g = ctx.MkGoal(true, false, false); + g.Assert(q); + + Tactic t1 = ctx.MkTactic("qfbv"); + Tactic t2 = ctx.MkTactic("qfbv"); + Tactic p = ctx.ParOr(new Tactic[] { t1, t2 }); + + ApplyResult ar = p.Apply(g); + + if (ar.NumSubgoals() != 1 || !ar.Subgoals()[0].IsDecidedSat()) + throw new TestFailedException(); + } + + void BigIntCheck(Context ctx, RatNum r) throws Z3Exception + { + System.out.println("Num: " + r.BigIntNumerator()); + System.out.println("Den: " + r.BigIntDenominator()); + } + + // / Find a model for x xor y. + + public void FindModelExample1(Context ctx) throws Z3Exception, + TestFailedException + { + System.out.println("FindModelExample1"); + Log.Append("FindModelExample1"); + + BoolExpr x = ctx.MkBoolConst("x"); + BoolExpr y = ctx.MkBoolConst("y"); + BoolExpr x_xor_y = ctx.MkXor(x, y); + + Model model = Check(ctx, x_xor_y, Status.SATISFIABLE); + System.out.println("x = " + model.Evaluate(x, false) + ", y = " + + model.Evaluate(y, false)); + } + + // / Find a model for x < y + 1, x > 2. + // / Then, assert not(x = y), and find another model. + + public void FindModelExample2(Context ctx) throws Z3Exception, + TestFailedException + { + System.out.println("FindModelExample2"); + Log.Append("FindModelExample2"); + + IntExpr x = ctx.MkIntConst("x"); + IntExpr y = ctx.MkIntConst("y"); + IntExpr one = ctx.MkInt(1); + IntExpr two = ctx.MkInt(2); + + ArithExpr y_plus_one = ctx.MkAdd(new ArithExpr[] { y, one }); + + BoolExpr c1 = ctx.MkLt(x, y_plus_one); + BoolExpr c2 = ctx.MkGt(x, two); + + BoolExpr q = ctx.MkAnd(new BoolExpr[] { c1, c2 }); + + System.out.println("model for: x < y + 1, x > 2"); + Model model = Check(ctx, q, Status.SATISFIABLE); + System.out.println("x = " + model.Evaluate(x, false) + ", y =" + + model.Evaluate(y, false)); + + /* assert not(x = y) */ + BoolExpr x_eq_y = ctx.MkEq(x, y); + BoolExpr c3 = ctx.MkNot(x_eq_y); + + q = ctx.MkAnd(new BoolExpr[] { q, c3 }); + + System.out.println("model for: x < y + 1, x > 2, not(x = y)"); + model = Check(ctx, q, Status.SATISFIABLE); + System.out.println("x = " + model.Evaluate(x, false) + ", y = " + + model.Evaluate(y, false)); + } + + // / Prove x = y implies g(x) = g(y), and + // / disprove x = y implies g(g(x)) = g(y). + + // / This function demonstrates how to create uninterpreted + // / types and functions. + public void ProveExample1(Context ctx) throws Z3Exception, + TestFailedException + { + System.out.println("ProveExample1"); + Log.Append("ProveExample1"); + + /* create uninterpreted type. */ + Sort U = ctx.MkUninterpretedSort(ctx.MkSymbol("U")); + + /* declare function g */ + FuncDecl g = ctx.MkFuncDecl("g", U, U); + + /* create x and y */ + Expr x = ctx.MkConst("x", U); + Expr y = ctx.MkConst("y", U); + /* create g(x), g(y) */ + Expr gx = g.Apply(x); + Expr gy = g.Apply(y); + + /* assert x = y */ + BoolExpr eq = ctx.MkEq(x, y); + + /* prove g(x) = g(y) */ + BoolExpr f = ctx.MkEq(gx, gy); + System.out.println("prove: x = y implies g(x) = g(y)"); + Prove(ctx, ctx.MkImplies(eq, f), false); + + /* create g(g(x)) */ + Expr ggx = g.Apply(gx); + + /* disprove g(g(x)) = g(y) */ + f = ctx.MkEq(ggx, gy); + System.out.println("disprove: x = y implies g(g(x)) = g(y)"); + Disprove(ctx, ctx.MkImplies(eq, f), false); + + /* Print the model using the custom model printer */ + Model m = Check(ctx, ctx.MkNot(f), Status.SATISFIABLE); + System.out.println(m); + } + + // / Prove not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < 0 + // . + // / Then, show that z < -1 is not implied. + + // / This example demonstrates how to combine uninterpreted + // functions + // / and arithmetic. + public void ProveExample2(Context ctx) throws Z3Exception, + TestFailedException + { + System.out.println("ProveExample2"); + Log.Append("ProveExample2"); + + /* declare function g */ + Sort I = ctx.IntSort(); + + FuncDecl g = ctx.MkFuncDecl("g", I, I); + + /* create x, y, and z */ + IntExpr x = ctx.MkIntConst("x"); + IntExpr y = ctx.MkIntConst("y"); + IntExpr z = ctx.MkIntConst("z"); + + /* create gx, gy, gz */ + Expr gx = ctx.MkApp(g, x); + Expr gy = ctx.MkApp(g, y); + Expr gz = ctx.MkApp(g, z); + + /* create zero */ + IntExpr zero = ctx.MkInt(0); + + /* assert not(g(g(x) - g(y)) = g(z)) */ + ArithExpr gx_gy = ctx.MkSub(new ArithExpr[] { (IntExpr) gx, + (IntExpr) gy }); + Expr ggx_gy = ctx.MkApp(g, gx_gy); + BoolExpr eq = ctx.MkEq(ggx_gy, gz); + BoolExpr c1 = ctx.MkNot(eq); + + /* assert x + z <= y */ + ArithExpr x_plus_z = ctx.MkAdd(new ArithExpr[] { x, z }); + BoolExpr c2 = ctx.MkLe(x_plus_z, y); + + /* assert y <= x */ + BoolExpr c3 = ctx.MkLe(y, x); + + /* prove z < 0 */ + BoolExpr f = ctx.MkLt(z, zero); + System.out + .println("prove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < 0"); + Prove(ctx, f, false, new BoolExpr[] { c1, c2, c3 }); + + /* disprove z < -1 */ + IntExpr minus_one = ctx.MkInt(-1); + f = ctx.MkLt(z, minus_one); + System.out + .println("disprove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < -1"); + Disprove(ctx, f, false, new BoolExpr[] { c1, c2, c3 }); + } + + // / Show how push & pop can be used to create "backtracking" points. + + // / This example also demonstrates how big numbers can be + // / created in ctx. + public void PushPopExample1(Context ctx) throws Z3Exception, + TestFailedException + { + System.out.println("PushPopExample1"); + Log.Append("PushPopExample1"); + + /* create a big number */ + IntSort int_type = ctx.IntSort(); + IntExpr big_number = ctx + .MkInt("1000000000000000000000000000000000000000000000000000000"); + + /* create number 3 */ + IntExpr three = (IntExpr) ctx.MkNumeral("3", int_type); + + /* create x */ + IntExpr x = ctx.MkIntConst("x"); + + Solver solver = ctx.MkSolver(); + + /* assert x >= "big number" */ + BoolExpr c1 = ctx.MkGe(x, big_number); + System.out.println("assert: x >= 'big number'"); + solver.Assert(c1); + + /* create a backtracking point */ + System.out.println("push"); + solver.Push(); + + /* assert x <= 3 */ + BoolExpr c2 = ctx.MkLe(x, three); + System.out.println("assert: x <= 3"); + solver.Assert(c2); + + /* context is inconsistent at this point */ + if (solver.Check() != Status.UNSATISFIABLE) + throw new TestFailedException(); + + /* + * backtrack: the constraint x <= 3 will be removed, since it was + * asserted after the last ctx.Push. + */ + System.out.println("pop"); + solver.Pop(1); + + /* the context is consistent again. */ + if (solver.Check() != Status.SATISFIABLE) + throw new TestFailedException(); + + /* new constraints can be asserted... */ + + /* create y */ + IntExpr y = ctx.MkIntConst("y"); + + /* assert y > x */ + BoolExpr c3 = ctx.MkGt(y, x); + System.out.println("assert: y > x"); + solver.Assert(c3); + + /* the context is still consistent. */ + if (solver.Check() != Status.SATISFIABLE) + throw new TestFailedException(); + } + + // / Tuples. + + // / Check that the projection of a tuple + // / returns the corresponding element. + public void TupleExample(Context ctx) throws Z3Exception, + TestFailedException + { + System.out.println("TupleExample"); + Log.Append("TupleExample"); + + Sort int_type = ctx.IntSort(); + TupleSort tuple = ctx.MkTupleSort(ctx.MkSymbol("mk_tuple"), // name of + // tuple + // constructor + new Symbol[] { ctx.MkSymbol("first"), ctx.MkSymbol("second") }, // names + // of + // projection + // operators + new Sort[] { int_type, int_type } // types of projection + // operators + ); + FuncDecl first = tuple.FieldDecls()[0]; // declarations are for + // projections + FuncDecl second = tuple.FieldDecls()[1]; + Expr x = ctx.MkConst("x", int_type); + Expr y = ctx.MkConst("y", int_type); + Expr n1 = tuple.MkDecl().Apply(new Expr[] { x, y }); + Expr n2 = first.Apply(n1); + BoolExpr n3 = ctx.MkEq(x, n2); + System.out.println("Tuple example: " + n3); + Prove(ctx, n3, false); + } + + // / Simple bit-vector example. + + // / + // / This example disproves that x - 10 <= 0 IFF x <= 10 for (32-bit) + // machine integers + // / + public void BitvectorExample1(Context ctx) throws Z3Exception, + TestFailedException + { + System.out.println("BitvectorExample1"); + Log.Append("BitvectorExample1"); + + Sort bv_type = ctx.MkBitVecSort(32); + BitVecExpr x = (BitVecExpr) ctx.MkConst("x", bv_type); + BitVecNum zero = (BitVecNum) ctx.MkNumeral("0", bv_type); + BitVecNum ten = ctx.MkBV(10, 32); + BitVecExpr x_minus_ten = ctx.MkBVSub(x, ten); + /* bvsle is signed less than or equal to */ + BoolExpr c1 = ctx.MkBVSLE(x, ten); + BoolExpr c2 = ctx.MkBVSLE(x_minus_ten, zero); + BoolExpr thm = ctx.MkIff(c1, c2); + System.out + .println("disprove: x - 10 <= 0 IFF x <= 10 for (32-bit) machine integers"); + Disprove(ctx, thm, false); + } + + // / Find x and y such that: x ^ y - 103 == x * y + + public void BitvectorExample2(Context ctx) throws Z3Exception, + TestFailedException + { + System.out.println("BitvectorExample2"); + Log.Append("BitvectorExample2"); + + /* construct x ^ y - 103 == x * y */ + Sort bv_type = ctx.MkBitVecSort(32); + BitVecExpr x = ctx.MkBVConst("x", 32); + BitVecExpr y = ctx.MkBVConst("y", 32); + BitVecExpr x_xor_y = ctx.MkBVXOR(x, y); + BitVecExpr c103 = (BitVecNum) ctx.MkNumeral("103", bv_type); + BitVecExpr lhs = ctx.MkBVSub(x_xor_y, c103); + BitVecExpr rhs = ctx.MkBVMul(x, y); + BoolExpr ctr = ctx.MkEq(lhs, rhs); + + System.out + .println("find values of x and y, such that x ^ y - 103 == x * y"); + + /* find a model (i.e., values for x an y that satisfy the constraint */ + Model m = Check(ctx, ctr, Status.SATISFIABLE); + System.out.println(m); + } + + // / Demonstrates how to use the SMTLIB parser. + + public void ParserExample1(Context ctx) throws Z3Exception, + TestFailedException + { + System.out.println("ParserExample1"); + Log.Append("ParserExample1"); + + ctx.ParseSMTLIBString( + "(benchmark tst :extrafuns ((x Int) (y Int)) :formula (> x y) :formula (> x 0))", + null, null, null, null); + for (BoolExpr f : ctx.SMTLIBFormulas()) + System.out.println("formula " + f); + + Model m = Check(ctx, ctx.MkAnd(ctx.SMTLIBFormulas()), + Status.SATISFIABLE); + } + + // / Demonstrates how to initialize the parser symbol table. + + public void ParserExample2(Context ctx) throws Z3Exception, + TestFailedException + { + System.out.println("ParserExample2"); + Log.Append("ParserExample2"); + + Symbol[] declNames = { ctx.MkSymbol("a"), ctx.MkSymbol("b") }; + FuncDecl a = ctx.MkConstDecl(declNames[0], ctx.MkIntSort()); + FuncDecl b = ctx.MkConstDecl(declNames[1], ctx.MkIntSort()); + FuncDecl[] decls = new FuncDecl[] { a, b }; + + ctx.ParseSMTLIBString("(benchmark tst :formula (> a b))", null, null, + declNames, decls); + BoolExpr f = ctx.SMTLIBFormulas()[0]; + System.out.println("formula: " + f); + Check(ctx, f, Status.SATISFIABLE); + } + + // / Demonstrates how to initialize the parser symbol table. + + public void ParserExample3(Context ctx) throws Exception + { + System.out.println("ParserExample3"); + Log.Append("ParserExample3"); + + /* declare function g */ + Sort I = ctx.MkIntSort(); + FuncDecl g = ctx.MkFuncDecl("g", new Sort[] { I, I }, I); + + BoolExpr ca = CommAxiom(ctx, g); + + ctx.ParseSMTLIBString( + "(benchmark tst :formula (forall (x Int) (y Int) (implies (= x y) (= (gg x 0) (gg 0 y)))))", + null, null, new Symbol[] { ctx.MkSymbol("gg") }, + new FuncDecl[] { g }); + + BoolExpr thm = ctx.SMTLIBFormulas()[0]; + System.out.println("formula: " + thm); + Prove(ctx, thm, false, ca); + } + + // / Display the declarations, assumptions and formulas in a SMT-LIB string. + + public void ParserExample4(Context ctx) throws Z3Exception + { + System.out.println("ParserExample4"); + Log.Append("ParserExample4"); + + ctx.ParseSMTLIBString( + "(benchmark tst :extrafuns ((x Int) (y Int)) :assumption (= x 20) :formula (> x y) :formula (> x 0))", + null, null, null, null); + for (FuncDecl decl : ctx.SMTLIBDecls()) + { + System.out.println("Declaration: " + decl); + } + for (BoolExpr f : ctx.SMTLIBAssumptions()) + { + System.out.println("Assumption: " + f); + } + for (BoolExpr f : ctx.SMTLIBFormulas()) + { + System.out.println("Formula: " + f); + } + } + + // / Demonstrates how to handle parser errors using Z3 error handling + // support. + + // / + public void ParserExample5(Context ctx) + { + System.out.println("ParserExample5"); + + try + { + ctx.ParseSMTLIBString( + /* + * the following string has a parsing error: missing + * parenthesis + */ + "(benchmark tst :extrafuns ((x Int (y Int)) :formula (> x y) :formula (> x 0))", + null, null, null, null); + } catch (Z3Exception e) + { + System.out.println("Z3 error: " + e); + } + } + + // / Create an ite-Expr (if-then-else Exprs). + + public void ITEExample(Context ctx) throws Z3Exception + { + System.out.println("ITEExample"); + Log.Append("ITEExample"); + + BoolExpr f = ctx.MkFalse(); + Expr one = ctx.MkInt(1); + Expr zero = ctx.MkInt(0); + Expr ite = ctx.MkITE(f, one, zero); + + System.out.println("Expr: " + ite); + } + + // / Create an enumeration data type. + + public void EnumExample(Context ctx) throws Z3Exception, + TestFailedException + { + System.out.println("EnumExample"); + Log.Append("EnumExample"); + + Symbol name = ctx.MkSymbol("fruit"); + + EnumSort fruit = ctx.MkEnumSort(name, + new Symbol[] { ctx.MkSymbol("apple"), ctx.MkSymbol("banana"), + ctx.MkSymbol("orange") }); + + System.out.println((fruit.Consts()[0])); + System.out.println((fruit.Consts()[1])); + System.out.println((fruit.Consts()[2])); + + System.out.println((fruit.TesterDecls()[0])); + System.out.println((fruit.TesterDecls()[1])); + System.out.println((fruit.TesterDecls()[2])); + + Expr apple = fruit.Consts()[0]; + Expr banana = fruit.Consts()[1]; + Expr orange = fruit.Consts()[2]; + + /* Apples are different from oranges */ + Prove(ctx, ctx.MkNot(ctx.MkEq(apple, orange)), false); + + /* Apples pass the apple test */ + Prove(ctx, (BoolExpr) ctx.MkApp(fruit.TesterDecls()[0], apple), false); + + /* Oranges fail the apple test */ + Disprove(ctx, (BoolExpr) ctx.MkApp(fruit.TesterDecls()[0], orange), + false); + Prove(ctx, (BoolExpr) ctx.MkNot((BoolExpr) ctx.MkApp( + fruit.TesterDecls()[0], orange)), false); + + Expr fruity = ctx.MkConst("fruity", fruit); + + /* If something is fruity, then it is an apple, banana, or orange */ + + Prove(ctx, + ctx.MkOr(new BoolExpr[] { ctx.MkEq(fruity, apple), + ctx.MkEq(fruity, banana), ctx.MkEq(fruity, orange) }), + false); + } + + // / Create a list datatype. + + public void ListExample(Context ctx) throws Z3Exception, + TestFailedException + { + System.out.println("ListExample"); + Log.Append("ListExample"); + + Sort int_ty; + ListSort int_list; + Expr nil, l1, l2, x, y, u, v; + BoolExpr fml, fml1; + + int_ty = ctx.MkIntSort(); + + int_list = ctx.MkListSort(ctx.MkSymbol("int_list"), int_ty); + + nil = ctx.MkConst(int_list.NilDecl()); + l1 = ctx.MkApp(int_list.ConsDecl(), new Expr[] { ctx.MkInt(1), nil }); + l2 = ctx.MkApp(int_list.ConsDecl(), new Expr[] { ctx.MkInt(2), nil }); + + /* nil != cons(1, nil) */ + Prove(ctx, ctx.MkNot(ctx.MkEq(nil, l1)), false); + + /* cons(2,nil) != cons(1, nil) */ + Prove(ctx, ctx.MkNot(ctx.MkEq(l1, l2)), false); + + /* cons(x,nil) = cons(y, nil) => x = y */ + x = ctx.MkConst("x", int_ty); + y = ctx.MkConst("y", int_ty); + l1 = ctx.MkApp(int_list.ConsDecl(), new Expr[] { x, nil }); + l2 = ctx.MkApp(int_list.ConsDecl(), new Expr[] { y, nil }); + Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(x, y)), false); + + /* cons(x,u) = cons(x, v) => u = v */ + u = ctx.MkConst("u", int_list); + v = ctx.MkConst("v", int_list); + l1 = ctx.MkApp(int_list.ConsDecl(), new Expr[] { x, u }); + l2 = ctx.MkApp(int_list.ConsDecl(), new Expr[] { y, v }); + Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(u, v)), false); + Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(x, y)), false); + + /* is_nil(u) or is_cons(u) */ + Prove(ctx, + ctx.MkOr(new BoolExpr[] { + (BoolExpr) ctx.MkApp(int_list.IsNilDecl(), + new Expr[] { u }), + (BoolExpr) ctx.MkApp(int_list.IsConsDecl(), + new Expr[] { u }) }), false); + + /* occurs check u != cons(x,u) */ + Prove(ctx, ctx.MkNot(ctx.MkEq(u, l1)), false); + + /* destructors: is_cons(u) => u = cons(head(u),tail(u)) */ + fml1 = ctx.MkEq(u, ctx.MkApp(int_list.ConsDecl(), + new Expr[] { ctx.MkApp(int_list.HeadDecl(), new Expr[] { u }), + ctx.MkApp(int_list.TailDecl(), new Expr[] { u }) })); + fml = ctx.MkImplies( + (BoolExpr) ctx.MkApp(int_list.IsConsDecl(), new Expr[] { u }), + fml1); + System.out.println("Formula " + fml); + + Prove(ctx, fml, false); + + Disprove(ctx, fml1, false); + } + + // / Create a binary tree datatype. + + public void TreeExample(Context ctx) throws Z3Exception, + TestFailedException + { + System.out.println("TreeExample"); + Log.Append("TreeExample"); + + Sort cell; + FuncDecl nil_decl, is_nil_decl, cons_decl, is_cons_decl, car_decl, cdr_decl; + Expr nil, l1, l2, x, y, u, v; + BoolExpr fml, fml1; + String[] head_tail = new String[] { "car", "cdr" }; + Sort[] sorts = new Sort[] { null, null }; + int[] sort_refs = new int[] { 0, 0 }; + Constructor nil_con, cons_con; + + nil_con = ctx.MkConstructor("nil", "is_nil", null, null, null); + cons_con = ctx.MkConstructor("cons", "is_cons", head_tail, sorts, + sort_refs); + Constructor[] constructors = new Constructor[] { nil_con, cons_con }; + + cell = ctx.MkDatatypeSort("cell", constructors); + + nil_decl = nil_con.ConstructorDecl(); + is_nil_decl = nil_con.TesterDecl(); + cons_decl = cons_con.ConstructorDecl(); + is_cons_decl = cons_con.TesterDecl(); + FuncDecl[] cons_accessors = cons_con.AccessorDecls(); + car_decl = cons_accessors[0]; + cdr_decl = cons_accessors[1]; + + nil = ctx.MkConst(nil_decl); + l1 = ctx.MkApp(cons_decl, new Expr[] { nil, nil }); + l2 = ctx.MkApp(cons_decl, new Expr[] { l1, nil }); + + /* nil != cons(nil, nil) */ + Prove(ctx, ctx.MkNot(ctx.MkEq(nil, l1)), false); + + /* cons(x,u) = cons(x, v) => u = v */ + u = ctx.MkConst("u", cell); + v = ctx.MkConst("v", cell); + x = ctx.MkConst("x", cell); + y = ctx.MkConst("y", cell); + l1 = ctx.MkApp(cons_decl, new Expr[] { x, u }); + l2 = ctx.MkApp(cons_decl, new Expr[] { y, v }); + Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(u, v)), false); + Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(x, y)), false); + + /* is_nil(u) or is_cons(u) */ + Prove(ctx, + ctx.MkOr(new BoolExpr[] { + (BoolExpr) ctx.MkApp(is_nil_decl, new Expr[] { u }), + (BoolExpr) ctx.MkApp(is_cons_decl, new Expr[] { u }) }), + false); + + /* occurs check u != cons(x,u) */ + Prove(ctx, ctx.MkNot(ctx.MkEq(u, l1)), false); + + /* destructors: is_cons(u) => u = cons(car(u),cdr(u)) */ + fml1 = ctx.MkEq( + u, + ctx.MkApp( + cons_decl, + new Expr[] { ctx.MkApp(car_decl, u), + ctx.MkApp(cdr_decl, u) })); + fml = ctx.MkImplies((BoolExpr) ctx.MkApp(is_cons_decl, u), fml1); + System.out.println("Formula " + fml); + Prove(ctx, fml, false); + + Disprove(ctx, fml1, false); + } + + // / Create a forest of trees. + + // / + // / forest ::= nil | cons(tree, forest) + // / tree ::= nil | cons(forest, forest) + // / + public void ForestExample(Context ctx) throws Z3Exception, + TestFailedException + { + System.out.println("ForestExample"); + Log.Append("ForestExample"); + + Sort tree, forest; + FuncDecl nil1_decl, is_nil1_decl, cons1_decl, is_cons1_decl, car1_decl, cdr1_decl; + FuncDecl nil2_decl, is_nil2_decl, cons2_decl, is_cons2_decl, car2_decl, cdr2_decl; + Expr nil1, nil2, t1, t2, t3, t4, f1, f2, f3, l1, l2, x, y, u, v; + + // + // Declare the names of the accessors for cons. + // Then declare the sorts of the accessors. + // For this example, all sorts refer to the new types 'forest' and + // 'tree' + // being declared, so we pass in null for both sorts1 and sorts2. + // On the other hand, the sort_refs arrays contain the indices of the + // two new sorts being declared. The first element in sort1_refs + // points to 'tree', which has index 1, the second element in sort1_refs + // array + // points to 'forest', which has index 0. + // + Symbol[] head_tail1 = new Symbol[] { ctx.MkSymbol("head"), + ctx.MkSymbol("tail") }; + Sort[] sorts1 = new Sort[] { null, null }; + int[] sort1_refs = new int[] { 1, 0 }; // the first item points to a + // tree, the second to a forest + + Symbol[] head_tail2 = new Symbol[] { ctx.MkSymbol("car"), + ctx.MkSymbol("cdr") }; + Sort[] sorts2 = new Sort[] { null, null }; + int[] sort2_refs = new int[] { 0, 0 }; // both items point to the forest + // datatype. + Constructor nil1_con, cons1_con, nil2_con, cons2_con; + Constructor[] constructors1 = new Constructor[2], constructors2 = new Constructor[2]; + Symbol[] sort_names = { ctx.MkSymbol("forest"), ctx.MkSymbol("tree") }; + + /* build a forest */ + nil1_con = ctx.MkConstructor(ctx.MkSymbol("nil"), + ctx.MkSymbol("is_nil"), null, null, null); + cons1_con = ctx.MkConstructor(ctx.MkSymbol("cons1"), + ctx.MkSymbol("is_cons1"), head_tail1, sorts1, sort1_refs); + constructors1[0] = nil1_con; + constructors1[1] = cons1_con; + + /* build a tree */ + nil2_con = ctx.MkConstructor(ctx.MkSymbol("nil2"), + ctx.MkSymbol("is_nil2"), null, null, null); + cons2_con = ctx.MkConstructor(ctx.MkSymbol("cons2"), + ctx.MkSymbol("is_cons2"), head_tail2, sorts2, sort2_refs); + constructors2[0] = nil2_con; + constructors2[1] = cons2_con; + + Constructor[][] clists = new Constructor[][] { constructors1, + constructors2 }; + + Sort[] sorts = ctx.MkDatatypeSorts(sort_names, clists); + forest = sorts[0]; + tree = sorts[1]; + + // + // Now that the datatype has been created. + // Query the constructors for the constructor + // functions, testers, and field accessors. + // + nil1_decl = nil1_con.ConstructorDecl(); + is_nil1_decl = nil1_con.TesterDecl(); + cons1_decl = cons1_con.ConstructorDecl(); + is_cons1_decl = cons1_con.TesterDecl(); + FuncDecl[] cons1_accessors = cons1_con.AccessorDecls(); + car1_decl = cons1_accessors[0]; + cdr1_decl = cons1_accessors[1]; + + nil2_decl = nil2_con.ConstructorDecl(); + is_nil2_decl = nil2_con.TesterDecl(); + cons2_decl = cons2_con.ConstructorDecl(); + is_cons2_decl = cons2_con.TesterDecl(); + FuncDecl[] cons2_accessors = cons2_con.AccessorDecls(); + car2_decl = cons2_accessors[0]; + cdr2_decl = cons2_accessors[1]; + + nil1 = ctx.MkConst(nil1_decl); + nil2 = ctx.MkConst(nil2_decl); + f1 = ctx.MkApp(cons1_decl, new Expr[] { nil2, nil1 }); + t1 = ctx.MkApp(cons2_decl, new Expr[] { nil1, nil1 }); + t2 = ctx.MkApp(cons2_decl, new Expr[] { f1, nil1 }); + t3 = ctx.MkApp(cons2_decl, new Expr[] { f1, f1 }); + t4 = ctx.MkApp(cons2_decl, new Expr[] { nil1, f1 }); + f2 = ctx.MkApp(cons1_decl, new Expr[] { t1, nil1 }); + f3 = ctx.MkApp(cons1_decl, new Expr[] { t1, f1 }); + + /* nil != cons(nil,nil) */ + Prove(ctx, ctx.MkNot(ctx.MkEq(nil1, f1)), false); + Prove(ctx, ctx.MkNot(ctx.MkEq(nil2, t1)), false); + + /* cons(x,u) = cons(x, v) => u = v */ + u = ctx.MkConst("u", forest); + v = ctx.MkConst("v", forest); + x = ctx.MkConst("x", tree); + y = ctx.MkConst("y", tree); + l1 = ctx.MkApp(cons1_decl, new Expr[] { x, u }); + l2 = ctx.MkApp(cons1_decl, new Expr[] { y, v }); + Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(u, v)), false); + Prove(ctx, ctx.MkImplies(ctx.MkEq(l1, l2), ctx.MkEq(x, y)), false); + + /* is_nil(u) or is_cons(u) */ + Prove(ctx, ctx.MkOr(new BoolExpr[] { + (BoolExpr) ctx.MkApp(is_nil1_decl, new Expr[] { u }), + (BoolExpr) ctx.MkApp(is_cons1_decl, new Expr[] { u }) }), false); + + /* occurs check u != cons(x,u) */ + Prove(ctx, ctx.MkNot(ctx.MkEq(u, l1)), false); + } + + // / Demonstrate how to use #Eval. + + public void EvalExample1(Context ctx) throws Z3Exception + { + System.out.println("EvalExample1"); + Log.Append("EvalExample1"); + + IntExpr x = ctx.MkIntConst("x"); + IntExpr y = ctx.MkIntConst("y"); + IntExpr two = ctx.MkInt(2); + + Solver solver = ctx.MkSolver(); + + /* assert x < y */ + solver.Assert(ctx.MkLt(x, y)); + + /* assert x > 2 */ + solver.Assert(ctx.MkGt(x, two)); + + /* find model for the constraints above */ + Model model = null; + if (Status.SATISFIABLE == solver.Check()) + { + model = solver.Model(); + System.out.println(model); + System.out.println("\nevaluating x+y"); + Expr v = model.Evaluate(ctx.MkAdd(new ArithExpr[] { x, y }), false); + if (v != null) + { + System.out.println("result = " + (v)); + } else + { + System.out.println("Failed to evaluate: x+y"); + } + } else + { + System.out.println("BUG, the constraints are satisfiable."); + } + } + + // / Demonstrate how to use #Eval on tuples. + + public void EvalExample2(Context ctx) throws Z3Exception + { + System.out.println("EvalExample2"); + Log.Append("EvalExample2"); + + Sort int_type = ctx.IntSort(); + TupleSort tuple = ctx.MkTupleSort(ctx.MkSymbol("mk_tuple"), // name of + // tuple + // constructor + new Symbol[] { ctx.MkSymbol("first"), ctx.MkSymbol("second") }, // names + // of + // projection + // operators + new Sort[] { int_type, int_type } // types of projection + // operators + ); + FuncDecl first = tuple.FieldDecls()[0]; // declarations are for + // projections + FuncDecl second = tuple.FieldDecls()[1]; + Expr tup1 = ctx.MkConst("t1", tuple); + Expr tup2 = ctx.MkConst("t2", tuple); + + Solver solver = ctx.MkSolver(); + + /* assert tup1 != tup2 */ + solver.Assert(ctx.MkNot(ctx.MkEq(tup1, tup2))); + /* assert first tup1 = first tup2 */ + solver.Assert(ctx.MkEq(ctx.MkApp(first, tup1), ctx.MkApp(first, tup2))); + + /* find model for the constraints above */ + Model model = null; + if (Status.SATISFIABLE == solver.Check()) + { + model = solver.Model(); + System.out.println(model); + System.out.println("evaluating tup1 " + + (model.Evaluate(tup1, false))); + System.out.println("evaluating tup2 " + + (model.Evaluate(tup2, false))); + System.out.println("evaluating second(tup2) " + + (model.Evaluate(ctx.MkApp(second, tup2), false))); + } else + { + System.out.println("BUG, the constraints are satisfiable."); + } + } + + // / Demonstrate how to use Pushand Popto + // / control the size of models. + + // / Note: this test is specialized to 32-bit bitvectors. + public void CheckSmall(Context ctx, Solver solver, BitVecExpr[] to_minimize) + throws Z3Exception + { + int num_Exprs = to_minimize.length; + int[] upper = new int[num_Exprs]; + int[] lower = new int[num_Exprs]; + for (int i = 0; i < upper.length; ++i) + { + upper[i] = Integer.MAX_VALUE; + lower[i] = 0; + } + boolean some_work = true; + int last_index = -1; + int last_upper = 0; + while (some_work) + { + solver.Push(); + + boolean check_is_sat = true; + while (check_is_sat && some_work) + { + // Assert all feasible bounds. + for (int i = 0; i < num_Exprs; ++i) + { + solver.Assert(ctx.MkBVULE(to_minimize[i], + ctx.MkBV(upper[i], 32))); + } + + check_is_sat = Status.SATISFIABLE == solver.Check(); + if (!check_is_sat) + { + if (last_index != -1) + { + lower[last_index] = last_upper + 1; + } + break; + } + System.out.println(solver.Model()); + + // narrow the bounds based on the current model. + for (int i = 0; i < num_Exprs; ++i) + { + Expr v = solver.Model().Evaluate(to_minimize[i], false); + int ui = ((BitVecNum) v).Int(); + if (ui < upper[i]) + { + upper[i] = (int) ui; + } + System.out.println(i + " " + lower[i] + " " + upper[i]); + } + + // find a new bound to add + some_work = false; + last_index = 0; + for (int i = 0; i < num_Exprs; ++i) + { + if (lower[i] < upper[i]) + { + last_upper = (upper[i] + lower[i]) / 2; + last_index = i; + solver.Assert(ctx.MkBVULE(to_minimize[i], + ctx.MkBV(last_upper, 32))); + some_work = true; + break; + } + } + } + solver.Pop(); + } + } + + // / Reduced-size model generation example. + + public void FindSmallModelExample(Context ctx) throws Z3Exception + { + System.out.println("FindSmallModelExample"); + Log.Append("FindSmallModelExample"); + + BitVecExpr x = ctx.MkBVConst("x", 32); + BitVecExpr y = ctx.MkBVConst("y", 32); + BitVecExpr z = ctx.MkBVConst("z", 32); + + Solver solver = ctx.MkSolver(); + + solver.Assert(ctx.MkBVULE(x, ctx.MkBVAdd(y, z))); + CheckSmall(ctx, solver, new BitVecExpr[] { x, y, z }); + } + + // / Simplifier example. + + public void SimplifierExample(Context ctx) throws Z3Exception + { + System.out.println("SimplifierExample"); + Log.Append("SimplifierExample"); + + IntExpr x = ctx.MkIntConst("x"); + IntExpr y = ctx.MkIntConst("y"); + IntExpr z = ctx.MkIntConst("z"); + IntExpr u = ctx.MkIntConst("u"); + + Expr t1 = ctx.MkAdd(new ArithExpr[] { + x, + ctx.MkSub(new ArithExpr[] { y, + ctx.MkAdd(new ArithExpr[] { x, z }) }) }); + Expr t2 = t1.Simplify(); + System.out.println((t1) + " -> " + (t2)); + } + + // / Extract unsatisfiable core example + + public void UnsatCoreAndProofExample(Context ctx) throws Z3Exception + { + System.out.println("UnsatCoreAndProofExample"); + Log.Append("UnsatCoreAndProofExample"); + + Solver solver = ctx.MkSolver(); + + BoolExpr pa = ctx.MkBoolConst("PredA"); + BoolExpr pb = ctx.MkBoolConst("PredB"); + BoolExpr pc = ctx.MkBoolConst("PredC"); + BoolExpr pd = ctx.MkBoolConst("PredD"); + BoolExpr p1 = ctx.MkBoolConst("P1"); + BoolExpr p2 = ctx.MkBoolConst("P2"); + BoolExpr p3 = ctx.MkBoolConst("P3"); + BoolExpr p4 = ctx.MkBoolConst("P4"); + BoolExpr[] assumptions = new BoolExpr[] { ctx.MkNot(p1), ctx.MkNot(p2), + ctx.MkNot(p3), ctx.MkNot(p4) }; + BoolExpr f1 = ctx.MkAnd(new BoolExpr[] { pa, pb, pc }); + BoolExpr f2 = ctx.MkAnd(new BoolExpr[] { pa, ctx.MkNot(pb), pc }); + BoolExpr f3 = ctx.MkOr(new BoolExpr[] { ctx.MkNot(pa), ctx.MkNot(pc) }); + BoolExpr f4 = pd; + + solver.Assert(ctx.MkOr(new BoolExpr[] { f1, p1 })); + solver.Assert(ctx.MkOr(new BoolExpr[] { f2, p2 })); + solver.Assert(ctx.MkOr(new BoolExpr[] { f3, p3 })); + solver.Assert(ctx.MkOr(new BoolExpr[] { f4, p4 })); + Status result = solver.Check(assumptions); + + if (result == Status.UNSATISFIABLE) + { + System.out.println("unsat"); + System.out.println("proof: " + solver.Proof()); + System.out.println("core: "); + for (Expr c : solver.UnsatCore()) + { + System.out.println(c); + } + } + } + + public void FiniteDomainExample(Context ctx) throws Z3Exception + { + System.out.println("FiniteDomainExample"); + Log.Append("FiniteDomainExample"); + + FiniteDomainSort s = ctx.MkFiniteDomainSort("S", 10); + FiniteDomainSort t = ctx.MkFiniteDomainSort("T", 10); + Expr s1 = ctx.MkNumeral(1, s); + Expr t1 = ctx.MkNumeral(1, t); + System.out.println(s); + System.out.println(t); + System.out.println(s1); + System.out.println(ctx.MkNumeral(2, s)); + System.out.println(t1); + // But you cannot mix numerals of different sorts + // even if the size of their domains are the same: + // System.out.println(ctx.MkEq(s1, t1)); + } + + public static void main(String[] args) + { + JavaExample p = new JavaExample(); + try + { + Context.ToggleWarningMessages(true); + Log.Open("test.log"); + + System.out.print("Z3 Major Version: "); + System.out.println(Version.Major()); + System.out.print("Z3 Full Version: "); + System.out.println(Version.getString()); + + p.SimpleExample(); + + { // These examples need model generation turned on. + HashMap cfg = new HashMap(); + cfg.put("model", "true"); + Context ctx = new Context(cfg); + p.BasicTests(ctx); + p.CastingTest(ctx); + p.SudokuExample(ctx); + p.QuantifierExample1(ctx); + p.QuantifierExample2(ctx); + p.LogicExample(ctx); + p.ParOrExample(ctx); + p.FindModelExample1(ctx); + p.FindModelExample2(ctx); + p.PushPopExample1(ctx); + p.ArrayExample1(ctx); + p.ArrayExample3(ctx); + p.BitvectorExample1(ctx); + p.BitvectorExample2(ctx); + p.ParserExample1(ctx); + p.ParserExample2(ctx); + p.ParserExample4(ctx); + p.ParserExample5(ctx); + p.ITEExample(ctx); + p.EvalExample1(ctx); + p.EvalExample2(ctx); + p.FindSmallModelExample(ctx); + p.SimplifierExample(ctx); + p.FiniteDomainExample(ctx); + } + + { // These examples need proof generation turned on. + HashMap cfg = new HashMap(); + cfg.put("proof", "true"); + Context ctx = new Context(cfg); + p.ProveExample1(ctx); + p.ProveExample2(ctx); + p.ArrayExample2(ctx); + p.TupleExample(ctx); + p.ParserExample3(ctx); + p.EnumExample(ctx); + p.ListExample(ctx); + p.TreeExample(ctx); + p.ForestExample(ctx); + p.UnsatCoreAndProofExample(ctx); + } + + { // These examples need proof generation turned on and auto-config + // set to false. + HashMap cfg = new HashMap(); + cfg.put("proof", "true"); + cfg.put("auto-config", "false"); + Context ctx = new Context(cfg); + p.QuantifierExample3(ctx); + p.QuantifierExample4(ctx); + } + + Log.Close(); + if (Log.isOpen()) + System.out.println("Log is still open!"); + } catch (Z3Exception ex) + { + System.out.println("Z3 Managed Exception: " + ex.getMessage()); + System.out.println("Stack trace: "); + ex.printStackTrace(System.out); + } catch (TestFailedException ex) + { + System.out.println("TEST CASE FAILED: " + ex.getMessage()); + System.out.println("Stack trace: "); + ex.printStackTrace(System.out); + } catch (Exception ex) + { + System.out.println("Unknown Exception: " + ex.getMessage()); + System.out.println("Stack trace: "); + ex.printStackTrace(System.out); + } + } +} diff --git a/examples/java/README b/examples/java/README new file mode 100644 index 000000000..fa1f20a63 --- /dev/null +++ b/examples/java/README @@ -0,0 +1,15 @@ +### This is work-in-progress and does not work yet. + +Small example using the Z3 Java bindings. +To build the example execute + make examples +in the build directory. + +It will create JavaExample.class in the build directory, +which can be run on Windows via + java -cp com.microsoft.z3.jar;. JavaExample + +On Linux and FreeBSD, we must use + LD_LIBRARY_PATH=. java -cp com.microsoft.z3.jar:. JavaExample + + \ No newline at end of file diff --git a/scripts/mk_project.py b/scripts/mk_project.py index 862a0915b..707d067e2 100644 --- a/scripts/mk_project.py +++ b/scripts/mk_project.py @@ -18,34 +18,32 @@ def init_project_def(): add_lib('subpaving', ['interval'], 'math/subpaving') add_lib('ast', ['util', 'polynomial']) add_lib('rewriter', ['ast', 'polynomial'], 'ast/rewriter') + add_lib('normal_forms', ['rewriter'], 'ast/normal_forms') add_lib('model', ['rewriter']) add_lib('tactic', ['ast', 'model']) add_lib('substitution', ['ast'], 'ast/substitution') add_lib('parser_util', ['ast'], 'parsers/util') add_lib('grobner', ['ast'], 'math/grobner') add_lib('euclid', ['util'], 'math/euclid') - # Front-end-params module still contain a lot of parameters for smt solver component. - # This should be fixed - add_lib('front_end_params', ['ast']) - # Simplifier module will be deleted in the future. - # It has been replaced with rewriter module. - add_lib('simplifier', ['rewriter', 'front_end_params'], 'ast/simplifier') - add_lib('normal_forms', ['rewriter', 'front_end_params'], 'ast/normal_forms') add_lib('core_tactics', ['tactic', 'normal_forms'], 'tactic/core') add_lib('sat_tactic', ['tactic', 'sat'], 'sat/tactic') add_lib('arith_tactics', ['core_tactics', 'sat'], 'tactic/arith') add_lib('nlsat_tactic', ['nlsat', 'sat_tactic', 'arith_tactics'], 'nlsat/tactic') add_lib('subpaving_tactic', ['core_tactics', 'subpaving'], 'math/subpaving/tactic') add_lib('aig_tactic', ['tactic'], 'tactic/aig') - add_lib('solver', ['model', 'tactic', 'front_end_params']) + add_lib('solver', ['model', 'tactic']) add_lib('cmd_context', ['solver', 'rewriter']) add_lib('extra_cmds', ['cmd_context', 'subpaving_tactic', 'arith_tactics'], 'cmd_context/extra_cmds') add_lib('smt2parser', ['cmd_context', 'parser_util'], 'parsers/smt2') + add_lib('proof_checker', ['rewriter'], 'ast/proof_checker') + # Simplifier module will be deleted in the future. + # It has been replaced with rewriter module. + add_lib('simplifier', ['rewriter'], 'ast/simplifier') + add_lib('macros', ['simplifier'], 'ast/macros') add_lib('pattern', ['normal_forms', 'smt2parser', 'simplifier'], 'ast/pattern') - add_lib('macros', ['simplifier', 'front_end_params'], 'ast/macros') - add_lib('proof_checker', ['rewriter', 'front_end_params'], 'ast/proof_checker') - add_lib('bit_blaster', ['rewriter', 'simplifier', 'front_end_params'], 'ast/rewriter/bit_blaster') - add_lib('proto_model', ['model', 'simplifier', 'front_end_params'], 'smt/proto_model') + add_lib('bit_blaster', ['rewriter', 'simplifier'], 'ast/rewriter/bit_blaster') + add_lib('smt_params', ['ast', 'simplifier', 'pattern', 'bit_blaster'], 'smt/params') + add_lib('proto_model', ['model', 'simplifier', 'smt_params'], 'smt/proto_model') add_lib('smt', ['bit_blaster', 'macros', 'normal_forms', 'cmd_context', 'proto_model', 'substitution', 'grobner', 'euclid', 'proof_checker', 'pattern', 'parser_util']) add_lib('user_plugin', ['smt'], 'smt/user_plugin') @@ -71,7 +69,7 @@ def init_project_def(): static=build_static_lib(), export_files=API_files) add_dot_net_dll('dotnet', ['api_dll'], 'api/dotnet', dll_name='Microsoft.Z3', assembly_info_dir='Properties') - add_java_dll('java', ['api_dll'], 'api/java', dll_name='libz3java', package_name="com.Microsoft.Z3") + add_java_dll('java', ['api_dll'], 'api/java', dll_name='libz3java', package_name="com.microsoft.z3", manifest_file='manifest') add_hlib('cpp', 'api/c++', includes2install=['z3++.h']) set_z3py_dir('api/python') # Examples @@ -79,6 +77,7 @@ def init_project_def(): add_c_example('c_example', 'c') add_c_example('maxsat') add_dotnet_example('dotnet_example', 'dotnet') + add_java_example('java_example', 'java') add_z3py_example('py_example', 'python') return API_files diff --git a/scripts/mk_util.py b/scripts/mk_util.py index b69171a24..98fae665a 100644 --- a/scripts/mk_util.py +++ b/scripts/mk_util.py @@ -56,6 +56,8 @@ JAVA_COMPONENT='java' CPP_COMPONENT='cpp' ##################### IS_WINDOWS=False +IS_LINUX=False +IS_OSX=False VERBOSE=True DEBUG_MODE=False SHOW_CPPS = True @@ -75,7 +77,13 @@ PREFIX='/usr' GMP=False def is_windows(): - return IS_WINDOWS + return IS_WINDOWS + +def is_linux(): + return IS_LINUX + +def is_osx(): + return IS_OSX def unix_path2dos(path): return string.join(path.split('/'), '\\') @@ -317,6 +325,11 @@ if os.name == 'nt': SHOW_CPPS=False # Enable .Net bindings by default on windows DOTNET_ENABLED=True +elif os.name == 'posix': + if os.uname()[0] == 'Darwin': + IS_OSX=True + elif os.uname()[0] == 'Linux': + IS_LINUX=True def display_help(exit_code): print "mk_make.py: Z3 Makefile generator\n" @@ -484,6 +497,32 @@ def is_verbose(): def is_java_enabled(): return JAVA_ENABLED +def is_compiler(given, expected): + """ + Return True if the 'given' compiler is the expected one. + >>> is_compiler('g++', 'g++') + True + >>> is_compiler('/home/g++', 'g++') + True + >>> is_compiler(os.path.join('home', 'g++'), 'g++') + True + >>> is_compiler('clang++', 'g++') + False + >>> is_compiler(os.path.join('home', 'clang++'), 'clang++') + True + """ + if given == expected: + return True + if len(expected) < len(given): + return given[len(given) - len(expected) - 1] == os.sep and given[len(given) - len(expected):] == expected + return False + +def is_CXX_gpp(): + return is_compiler(CXX, 'g++') + +def is_CXX_clangpp(): + return is_compiler(CXX, 'clang++') + def get_cpp_files(path): return filter(lambda f: f.endswith('.cpp'), os.listdir(path)) @@ -493,6 +532,9 @@ def get_c_files(path): def get_cs_files(path): return filter(lambda f: f.endswith('.cs'), os.listdir(path)) +def get_java_files(path): + return filter(lambda f: f.endswith('.java'), os.listdir(path)) + def find_all_deps(name, deps): new_deps = [] for dep in deps: @@ -922,29 +964,48 @@ class DotNetDLLComponent(Component): class JavaDLLComponent(Component): - def __init__(self, name, dll_name, package_name, path, deps): + def __init__(self, name, dll_name, package_name, manifest_file, path, deps): Component.__init__(self, name, path, deps) if dll_name == None: dll_name = name self.dll_name = dll_name self.package_name = package_name + self.manifest_file = manifest_file def mk_makefile(self, out): if is_java_enabled(): - dllfile = '%s$(SO_EXT)' % self.dll_name - out.write('%s: %s/Z3Native.java %s$(SO_EXT)\n' % (dllfile, self.to_src_dir, get_component('api_dll').dll_name)) - if IS_WINDOWS: - out.write('\tcd %s && %s Z3Native.java\n' % (unix_path2dos(self.to_src_dir), JAVAC)) - out.write('\tmove %s\\*.class .\n' % unix_path2dos(self.to_src_dir)) - out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)Z3Native$(OBJ_EXT) -I"%s/include" -I"%s/include/win32" -I%s %s/Z3Native.c\n' % (JAVA_HOME, JAVA_HOME, get_component('api').to_src_dir, self.to_src_dir)) - out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) Z3Native$(OBJ_EXT) libz3.lib\n' % dllfile) + mk_dir(BUILD_DIR+'/api/java/classes') + dllfile = '%s$(SO_EXT)' % self.dll_name + out.write('libz3java$(SO_EXT): libz3$(SO_EXT) %s/Native.cpp\n' % self.to_src_dir) + t = '\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)api/java/Native$(OBJ_EXT) -I"%s/include" -I"%s/include/PLATFORM" -I%s %s/Native.cpp\n' % (JAVA_HOME, JAVA_HOME, get_component('api').to_src_dir, self.to_src_dir) + if IS_OSX: + t = t.replace('PLATFORM', 'darwin') + elif IS_LINUX: + t = t.replace('PLATFORM', 'linux') else: - out.write('\tcd %s; %s Z3Native.java\n' % (self.to_src_dir, JAVAC)) - out.write('\tmv %s/*.class .\n' % self.to_src_dir) - out.write('\t$(CXX) $(CXXFLAGS) $(CXX_OUT_FLAG)Z3Native$(OBJ_EXT) -I"%s/include" -I%s %s/Z3Native.c\n' % (JAVA_HOME, get_component('api').to_src_dir, self.to_src_dir)) - out.write('\t$(SLINK) $(SLINK_OUT_FLAG)%s $(SLINK_FLAGS) -L. Z3Native$(OBJ_EXT) -lz3\n' % dllfile) - out.write('%s: %s\n\n' % (self.name, dllfile)) - # TODO: Compile and package all the .class files. + t = t.replace('PLATFORM', 'win32') + out.write(t) + if IS_WINDOWS: # On Windows, CL creates a .lib file to link against. + out.write('\t$(SLINK) $(SLINK_OUT_FLAG)libz3java$(SO_EXT) $(SLINK_FLAGS) api/java/Native$(OBJ_EXT) libz3$(LIB_EXT)\n') + else: + out.write('\t$(SLINK) $(SLINK_OUT_FLAG)libz3java$(SO_EXT) $(SLINK_FLAGS) api/java/Native$(OBJ_EXT) libz3$(SO_EXT)\n') + out.write('%s.jar: libz3java$(SO_EXT) ' % self.package_name) + deps = '' + for jfile in get_java_files(self.src_dir): + deps += ('%s/%s ' % (self.to_src_dir, jfile)) + for jfile in get_java_files((self.src_dir + "/enumerations")): + deps += ('%s/enumerations/%s ' % (self.to_src_dir, jfile)) + if IS_WINDOWS: deps = deps.replace('/', '\\') + out.write(deps) + out.write('\n') + t = ('\t%s %s/enumerations/*.java -d api/java/classes\n' % (JAVAC, self.to_src_dir)) + if IS_WINDOWS: t = t.replace('/','\\') + out.write(t) + t = ('\t%s -cp api/java/classes %s/*.java -d api/java/classes\n' % (JAVAC, self.to_src_dir)) + if IS_WINDOWS: t = t.replace('/','\\') + out.write(t) + out.write('\tjar cfm %s.jar %s/manifest -C api/java/classes .\n' % (self.package_name, self.to_src_dir)) + out.write('java: %s.jar\n\n' % self.package_name) def main_component(self): return is_java_enabled() @@ -1015,7 +1076,7 @@ class DotNetExampleComponent(ExampleComponent): if DOTNET_ENABLED: dll_name = get_component(DOTNET_COMPONENT).dll_name dll = '%s.dll' % dll_name - exefile = '%s.exe' % self.name + exefile = '%s$(EXE_EXT)' % self.name out.write('%s: %s' % (exefile, dll)) for csfile in get_cs_files(self.ex_dir): out.write(' ') @@ -1034,6 +1095,30 @@ class DotNetExampleComponent(ExampleComponent): out.write('\n') out.write('_ex_%s: %s\n\n' % (self.name, exefile)) +class JavaExampleComponent(ExampleComponent): + def __init__(self, name, path): + ExampleComponent.__init__(self, name, path) + + def is_example(self): + return JAVA_ENABLED + + def mk_makefile(self, out): + if JAVA_ENABLED: + pkg = get_component(JAVA_COMPONENT).package_name + '.jar' + out.write('_ex_%s: %s' % (self.name, pkg)) + deps = '' + for jfile in get_java_files(self.ex_dir): + out.write(' %s/%s' % (self.to_ex_dir, jfile)) + if IS_WINDOWS: + deps = deps.replace('/', '\\') + out.write('%s\n' % deps) + out.write('\t%s -cp %s ' % (JAVAC, pkg)) + win_ex_dir = self.to_ex_dir + for javafile in get_java_files(self.ex_dir): + out.write(' ') + out.write('%s/%s' % (win_ex_dir, javafile)) + out.write(' -d .\n\n') + class PythonExampleComponent(ExampleComponent): def __init__(self, name, path): ExampleComponent.__init__(self, name, path) @@ -1083,8 +1168,8 @@ def add_dot_net_dll(name, deps=[], path=None, dll_name=None, assembly_info_dir=N c = DotNetDLLComponent(name, dll_name, path, deps, assembly_info_dir) reg_component(name, c) -def add_java_dll(name, deps=[], path=None, dll_name=None, package_name=None): - c = JavaDLLComponent(name, dll_name, package_name, path, deps) +def add_java_dll(name, deps=[], path=None, dll_name=None, package_name=None, manifest_file=None): + c = JavaDLLComponent(name, dll_name, package_name, manifest_file, path, deps) reg_component(name, c) def add_cpp_example(name, path=None): @@ -1099,6 +1184,10 @@ def add_dotnet_example(name, path=None): c = DotNetExampleComponent(name, path) reg_component(name, c) +def add_java_example(name, path=None): + c = JavaExampleComponent(name, path) + reg_component(name, c) + def add_z3py_example(name, path=None): c = PythonExampleComponent(name, path) reg_component(name, c) @@ -1179,7 +1268,7 @@ def mk_config(): else: CPPFLAGS = '%s -D_MP_INTERNAL' % CPPFLAGS CXXFLAGS = '%s -c' % CXXFLAGS - if CXX == 'g++': + if is_CXX_gpp(): CXXFLAGS = '%s -fopenmp -mfpmath=sse' % CXXFLAGS LDFLAGS = '%s -fopenmp' % LDFLAGS SLIBEXTRAFLAGS = '-fopenmp' @@ -1193,7 +1282,7 @@ def mk_config(): SLIBFLAGS = '-dynamiclib' elif sysname == 'Linux': CXXFLAGS = '%s -fno-strict-aliasing -D_LINUX_' % CXXFLAGS - if CXX == 'clang++': + if is_CXX_clangpp(): CXXFLAGS = '%s -Wno-unknown-pragmas -Wno-overloaded-virtual -Wno-unused-value' % CXXFLAGS SO_EXT = '.so' LDFLAGS = '%s -lrt' % LDFLAGS @@ -1331,9 +1420,113 @@ def mk_makefile(): # Generate automatically generated source code def mk_auto_src(): if not ONLY_MAKEFILES: + exec_pyg_scripts() mk_pat_db() mk_all_install_tactic_cpps() mk_all_mem_initializer_cpps() + mk_all_gparams_register_modules() + +UINT = 0 +BOOL = 1 +DOUBLE = 2 +STRING = 3 +SYMBOL = 4 +UINT_MAX = 4294967295 +CURR_PYG = None + +def get_curr_pyg(): + return CURR_PYG + +TYPE2CPK = { UINT : 'CPK_UINT', BOOL : 'CPK_BOOL', DOUBLE : 'CPK_DOUBLE', STRING : 'CPK_STRING', SYMBOL : 'CPK_SYMBOL' } +TYPE2CTYPE = { UINT : 'unsigned', BOOL : 'bool', DOUBLE : 'double', STRING : 'char const *', SYMBOL : 'symbol' } +TYPE2GETTER = { UINT : 'get_uint', BOOL : 'get_bool', DOUBLE : 'get_double', STRING : 'get_str', SYMBOL : 'get_sym' } + +def pyg_default(p): + if p[1] == BOOL: + if p[2]: + return "true" + else: + return "false" + return p[2] + +def pyg_default_as_c_literal(p): + if p[1] == BOOL: + if p[2]: + return "true" + else: + return "false" + elif p[1] == STRING: + return '"%s"' % p[2] + elif p[1] == SYMBOL: + return 'symbol("%s")' % p[2] + return p[2] + +def to_c_method(s): + return s.replace('.', '_') + +def def_module_params(module_name, export, params, class_name=None, description=None): + pyg = get_curr_pyg() + dirname = os.path.split(get_curr_pyg())[0] + if class_name == None: + class_name = '%s_params' % module_name + hpp = os.path.join(dirname, '%s.hpp' % class_name) + out = open(hpp, 'w') + out.write('// Automatically generated file\n') + out.write('#include"params.h"\n') + if export: + out.write('#include"gparams.h"\n') + out.write('struct %s {\n' % class_name) + out.write(' params_ref const & p;\n') + if export: + out.write(' params_ref g;\n') + out.write(' %s(params_ref const & _p = params_ref()):\n' % class_name) + out.write(' p(_p)') + if export: + out.write(', g(gparams::get_module("%s"))' % module_name) + out.write(' {}\n') + out.write(' static void collect_param_descrs(param_descrs & d) {\n') + for param in params: + out.write(' d.insert("%s", %s, "%s", "%s");\n' % (param[0], TYPE2CPK[param[1]], param[3], pyg_default(param))) + out.write(' }\n') + if export: + out.write(' /*\n') + out.write(" REG_MODULE_PARAMS('%s', '%s::collect_param_descrs')\n" % (module_name, class_name)) + if description != None: + out.write(" REG_MODULE_DESCRIPTION('%s', '%s')\n" % (module_name, description)) + out.write(' */\n') + # Generated accessors + for param in params: + if export: + out.write(' %s %s() const { return p.%s("%s", g, %s); }\n' % + (TYPE2CTYPE[param[1]], to_c_method(param[0]), TYPE2GETTER[param[1]], param[0], pyg_default_as_c_literal(param))) + else: + out.write(' %s %s() const { return p.%s("%s", %s); }\n' % + (TYPE2CTYPE[param[1]], to_c_method(param[0]), TYPE2GETTER[param[1]], param[0], pyg_default_as_c_literal(param))) + out.write('};\n') + if is_verbose(): + print "Generated '%s'" % hpp + +def max_memory_param(): + return ('max_memory', UINT, UINT_MAX, 'maximum amount of memory in megabytes') + +def max_steps_param(): + return ('max_steps', UINT, UINT_MAX, 'maximum number of steps') + +PYG_GLOBALS = { 'UINT' : UINT, 'BOOL' : BOOL, 'DOUBLE' : DOUBLE, 'STRING' : STRING, 'SYMBOL' : SYMBOL, + 'UINT_MAX' : UINT_MAX, + 'max_memory_param' : max_memory_param, + 'max_steps_param' : max_steps_param, + 'def_module_params' : def_module_params } + +# Execute python auxiliary scripts that generate extra code for Z3. +def exec_pyg_scripts(): + global CURR_PYG + for root, dirs, files in os.walk('src'): + for f in files: + if f.endswith('.pyg'): + script = os.path.join(root, f) + CURR_PYG = script + execfile(script, PYG_GLOBALS) # TODO: delete after src/ast/pattern/expr_pattern_match # database.smt ==> database.h @@ -1458,7 +1651,7 @@ def mk_install_tactic_cpp(cnames, path): probe_pat = re.compile('[ \t]*ADD_PROBE\(.*\)') for cname in cnames: c = get_component(cname) - h_files = filter(lambda f: f.endswith('.h'), os.listdir(c.src_dir)) + h_files = filter(lambda f: f.endswith('.h') or f.endswith('.hpp'), os.listdir(c.src_dir)) for h_file in h_files: added_include = False fin = open("%s/%s" % (c.src_dir, h_file), 'r') @@ -1510,18 +1703,20 @@ def mk_all_install_tactic_cpps(): # This file implements the procedures # void mem_initialize() # void mem_finalize() -# This procedures are invoked by the Z3 memory_manager +# These procedures are invoked by the Z3 memory_manager def mk_mem_initializer_cpp(cnames, path): initializer_cmds = [] finalizer_cmds = [] fullname = '%s/mem_initializer.cpp' % path fout = open(fullname, 'w') fout.write('// Automatically generated file.\n') - initializer_pat = re.compile('[ \t]*ADD_INITIALIZER\(\'([^\']*)\'\)') - finalizer_pat = re.compile('[ \t]*ADD_FINALIZER\(\'([^\']*)\'\)') + initializer_pat = re.compile('[ \t]*ADD_INITIALIZER\(\'([^\']*)\'\)') + # ADD_INITIALIZER with priority + initializer_prio_pat = re.compile('[ \t]*ADD_INITIALIZER\(\'([^\']*)\',[ \t]*(-?[0-9]*)\)') + finalizer_pat = re.compile('[ \t]*ADD_FINALIZER\(\'([^\']*)\'\)') for cname in cnames: c = get_component(cname) - h_files = filter(lambda f: f.endswith('.h'), os.listdir(c.src_dir)) + h_files = filter(lambda f: f.endswith('.h') or f.endswith('.hpp'), os.listdir(c.src_dir)) for h_file in h_files: added_include = False fin = open("%s/%s" % (c.src_dir, h_file), 'r') @@ -1531,15 +1726,22 @@ def mk_mem_initializer_cpp(cnames, path): if not added_include: added_include = True fout.write('#include"%s"\n' % h_file) - initializer_cmds.append(m.group(1)) + initializer_cmds.append((m.group(1), 0)) + m = initializer_prio_pat.match(line) + if m: + if not added_include: + added_include = True + fout.write('#include"%s"\n' % h_file) + initializer_cmds.append((m.group(1), int(m.group(2)))) m = finalizer_pat.match(line) if m: if not added_include: added_include = True fout.write('#include"%s"\n' % h_file) finalizer_cmds.append(m.group(1)) + initializer_cmds.sort(key=lambda tup: tup[1]) fout.write('void mem_initialize() {\n') - for cmd in initializer_cmds: + for (cmd, prio) in initializer_cmds: fout.write(cmd) fout.write('\n') fout.write('}\n') @@ -1560,6 +1762,63 @@ def mk_all_mem_initializer_cpps(): cnames.append(c.name) mk_mem_initializer_cpp(cnames, c.src_dir) +# Generate an mem_initializer.cpp at path. +# This file implements the procedure +# void gparams_register_modules() +# This procedure is invoked by gparams::init() +def mk_gparams_register_modules(cnames, path): + cmds = [] + mod_cmds = [] + mod_descrs = [] + fullname = '%s/gparams_register_modules.cpp' % path + fout = open(fullname, 'w') + fout.write('// Automatically generated file.\n') + fout.write('#include"gparams.h"\n') + reg_pat = re.compile('[ \t]*REG_PARAMS\(\'([^\']*)\'\)') + reg_mod_pat = re.compile('[ \t]*REG_MODULE_PARAMS\(\'([^\']*)\', *\'([^\']*)\'\)') + reg_mod_descr_pat = re.compile('[ \t]*REG_MODULE_DESCRIPTION\(\'([^\']*)\', *\'([^\']*)\'\)') + for cname in cnames: + c = get_component(cname) + h_files = filter(lambda f: f.endswith('.h') or f.endswith('.hpp'), os.listdir(c.src_dir)) + for h_file in h_files: + added_include = False + fin = open("%s/%s" % (c.src_dir, h_file), 'r') + for line in fin: + m = reg_pat.match(line) + if m: + if not added_include: + added_include = True + fout.write('#include"%s"\n' % h_file) + cmds.append((m.group(1))) + m = reg_mod_pat.match(line) + if m: + if not added_include: + added_include = True + fout.write('#include"%s"\n' % h_file) + mod_cmds.append((m.group(1), m.group(2))) + m = reg_mod_descr_pat.match(line) + if m: + mod_descrs.append((m.group(1), m.group(2))) + fout.write('void gparams_register_modules() {\n') + for code in cmds: + fout.write('{ param_descrs d; %s(d); gparams::register_global(d); }\n' % code) + for (mod, code) in mod_cmds: + fout.write('{ param_descrs * d = alloc(param_descrs); %s(*d); gparams::register_module("%s", d); }\n' % (code, mod)) + for (mod, descr) in mod_descrs: + fout.write('gparams::register_module_descr("%s", "%s");\n' % (mod, descr)) + fout.write('}\n') + if VERBOSE: + print "Generated '%s'" % fullname + +def mk_all_gparams_register_modules(): + if not ONLY_MAKEFILES: + for c in get_components(): + if c.require_mem_initializer(): + cnames = [] + cnames.extend(c.deps) + cnames.append(c.name) + mk_gparams_register_modules(cnames, c.src_dir) + # Generate a .def based on the files at c.export_files slot. def mk_def_file(c): pat1 = re.compile(".*Z3_API.*") @@ -1796,7 +2055,7 @@ def mk_z3consts_java(api_files): java = get_component(JAVA_COMPONENT) DeprecatedEnums = [ 'Z3_search_failure' ] - gendir = java.src_dir + "/" + java.package_name.replace(".", "/") + "/Enumerations" + gendir = java.src_dir + "/enumerations" if not os.path.exists(gendir): os.mkdir(gendir) @@ -1847,15 +2106,32 @@ def mk_z3consts_java(api_files): if name not in DeprecatedEnums: efile = open('%s/%s.java' % (gendir, name), 'w') efile.write('/**\n * Automatically generated file\n **/\n\n') - efile.write('package %s;\n\n' % java.package_name); + efile.write('package %s.enumerations;\n\n' % java.package_name); efile.write('/**\n') efile.write(' * %s\n' % name) efile.write(' **/\n') efile.write('public enum %s {\n' % name) efile.write + first = True for k, i in decls.iteritems(): - efile.write('%s (%s),\n' % (k, i)) + if first: + first = False + else: + efile.write(',\n') + efile.write(' %s (%s)' % (k, i)) + efile.write(";\n") + efile.write('\n private final int intValue;\n\n') + efile.write(' %s(int v) {\n' % name) + efile.write(' this.intValue = v;\n') + efile.write(' }\n\n') + efile.write(' public static final %s fromInt(int v) {\n' % name) + efile.write(' for (%s k: values()) \n' % name) + efile.write(' if (k.intValue == v) return k;\n') + efile.write(' return values()[0];\n') + efile.write(' }\n\n') + efile.write(' public final int toInt() { return this.intValue; }\n') + # efile.write(';\n %s(int v) {}\n' % name) efile.write('}\n\n') efile.close() mode = SEARCHING @@ -1965,3 +2241,8 @@ def mk_win_dist(build_path, dist_path): for pyc in filter(lambda f: f.endswith('.pyc'), os.listdir(build_path)): shutil.copy('%s/%s' % (build_path, pyc), '%s/bin/%s' % (dist_path, pyc)) + + +if __name__ == '__main__': + import doctest + doctest.testmod() diff --git a/scripts/update_api.py b/scripts/update_api.py index 7e1439375..d7dbb7bcf 100644 --- a/scripts/update_api.py +++ b/scripts/update_api.py @@ -252,11 +252,11 @@ def param2java(p): k = param_kind(p) if k == OUT: if param_type(p) == INT or param_type(p) == UINT: - return "Integer" + return "IntPtr" elif param_type(p) == INT64 or param_type(p) == UINT64 or param_type(p) >= FIRST_OBJ_ID: - return "Long" + return "LongPtr" elif param_type(p) == STRING: - return "String" + return "StringPtr" else: print "ERROR: unreachable code" assert(False) @@ -468,54 +468,35 @@ def java_method_name(name): i = i + 1 return result -# Return the Java method name used to retrieve the elements of the given parameter -def java_get_array_elements(p): - if param_type(p) == INT or param_type(p) == UINT: - return 'GetIntArrayElements' - else: - return 'GetLongArrayElements' -# Return the Java method name used to release the elements of the given parameter -def java_release_array_elements(p): - if param_type(p) == INT or param_type(p) == UINT: - return 'ReleaseIntArrayElements' - else: - return 'ReleaseLongArrayElements' # Return the type of the java array elements def java_array_element_type(p): if param_type(p) == INT or param_type(p) == UINT: return 'jint' else: return 'jlong' -def java_set_array_region(p): - if param_type(p) == INT or param_type(p) == UINT: - return 'SetIntArrayRegion' - else: - return 'SetLongArrayRegion' def mk_java(): if not is_java_enabled(): return java_dir = get_component('java').src_dir - try: - os.mkdir('%s/com/Microsoft/Z3/' % java_dir) - except: - pass # OK if it exists already. - java_nativef = '%s/com/Microsoft/Z3/Native.java' % java_dir - java_wrapperf = '%s/com/Microsoft/Z3/Native.c' % java_dir + java_nativef = '%s/Native.java' % java_dir + java_wrapperf = '%s/Native.cpp' % java_dir java_native = open(java_nativef, 'w') java_native.write('// Automatically generated file\n') - java_native.write('package com.Microsoft.Z3;\n') + java_native.write('package %s;\n' % get_component('java').package_name) + java_native.write('import %s.enumerations.*;\n' % get_component('java').package_name) java_native.write('public final class Native {\n') java_native.write(' public static class IntPtr { public int value; }\n') java_native.write(' public static class LongPtr { public long value; }\n') java_native.write(' public static class StringPtr { public String value; }\n') - - if is_windows(): - java_native.write(' static { System.loadLibrary("%s"); }\n' % get_component('java')) + java_native.write(' public static native void setInternalErrorHandler(long ctx);\n\n') + if IS_WINDOWS: + java_native.write(' static { System.loadLibrary("%s"); }\n' % get_component('java').dll_name) else: java_native.write(' static { System.loadLibrary("%s"); }\n' % get_component('java').dll_name[3:]) # We need 3: to extract the prexi 'lib' form the dll_name + java_native.write('\n') for name, result, params in _dotnet_decls: - java_native.write(' public static native %s %s(' % (type2java(result), java_method_name(name))) + java_native.write(' protected static native %s INTERNAL%s(' % (type2java(result), java_method_name(name))) first = True i = 0; for param in params: @@ -526,22 +507,108 @@ def mk_java(): java_native.write('%s a%d' % (param2java(param), i)) i = i + 1 java_native.write(');\n') - java_native.write(' public static void main(String[] args) {\n') - java_native.write(' IntPtr major = new IntPtr(), minor = new IntPtr(), build = new IntPtr(), revision = new IntPtr();\n') - java_native.write(' getVersion(major, minor, build, revision);\n') - java_native.write(' System.out.format("Z3 (for Java) %d.%d.%d%n", major.value, minor.value, build.value);\n') - java_native.write(' }\n') - java_native.write('}\n'); + java_native.write('\n\n') + # Exception wrappers + for name, result, params in _dotnet_decls: + java_native.write(' public static %s %s(' % (type2java(result), java_method_name(name))) + first = True + i = 0; + for param in params: + if first: + first = False + else: + java_native.write(', ') + java_native.write('%s a%d' % (param2java(param), i)) + i = i + 1 + java_native.write(')') + if len(params) > 0 and param_type(params[0]) == CONTEXT: + java_native.write(' throws Z3Exception') + java_native.write('\n') + java_native.write(' {\n') + java_native.write(' ') + if result != VOID: + java_native.write('%s res = ' % type2java(result)) + java_native.write('INTERNAL%s(' % (java_method_name(name))) + first = True + i = 0; + for param in params: + if first: + first = False + else: + java_native.write(', ') + java_native.write('a%d' % i) + i = i + 1 + java_native.write(');\n') + if len(params) > 0 and param_type(params[0]) == CONTEXT: + java_native.write(' Z3_error_code err = Z3_error_code.fromInt(INTERNALgetErrorCode(a0));\n') + java_native.write(' if (err != Z3_error_code.Z3_OK)\n') + java_native.write(' throw new Z3Exception(INTERNALgetErrorMsgEx(a0, err.toInt()));\n') + if result != VOID: + java_native.write(' return res;\n') + java_native.write(' }\n\n') + java_native.write('}\n') java_wrapper = open(java_wrapperf, 'w') + pkg_str = get_component('java').package_name.replace('.', '_') java_wrapper.write('// Automatically generated file\n') java_wrapper.write('#include\n') java_wrapper.write('#include\n') java_wrapper.write('#include"z3.h"\n') java_wrapper.write('#ifdef __cplusplus\n') java_wrapper.write('extern "C" {\n') - java_wrapper.write('#endif\n') + java_wrapper.write('#endif\n\n') + java_wrapper.write('#if defined(_M_X64) || defined(_AMD64_)\n\n') + java_wrapper.write('#define GETLONGAELEMS(T,OLD,NEW) \\\n') + java_wrapper.write(' T * NEW = (OLD == 0) ? 0 : (T*) jenv->GetLongArrayElements(OLD, NULL);\n') + java_wrapper.write('#define RELEASELONGAELEMS(OLD,NEW) \\\n') + java_wrapper.write(' if (OLD != 0) jenv->ReleaseLongArrayElements(OLD, (jlong *) NEW, JNI_ABORT); \n\n') + java_wrapper.write('#define GETLONGAREGION(T,OLD,Z,SZ,NEW) \\\n') + java_wrapper.write(' jenv->GetLongArrayRegion(OLD,Z,(jsize)SZ,(jlong*)NEW); \n') + java_wrapper.write('#define SETLONGAREGION(OLD,Z,SZ,NEW) \\\n') + java_wrapper.write(' jenv->SetLongArrayRegion(OLD,Z,(jsize)SZ,(jlong*)NEW) \n\n') + java_wrapper.write('#else\n\n') + java_wrapper.write('#define GETLONGAELEMS(T,OLD,NEW) \\\n') + java_wrapper.write(' T * NEW = 0; { \\\n') + java_wrapper.write(' jlong * temp = (OLD == 0) ? 0 : jenv->GetLongArrayElements(OLD, NULL); \\\n') + java_wrapper.write(' unsigned int size = (OLD == 0) ? 0 :jenv->GetArrayLength(OLD); \\\n') + java_wrapper.write(' if (OLD != 0) { \\\n') + java_wrapper.write(' NEW = (T*) (new int[size]); \\\n') + java_wrapper.write(' for (unsigned i=0; i < size; i++) \\\n') + java_wrapper.write(' NEW[i] = reinterpret_cast(temp[i]); \\\n') + java_wrapper.write(' jenv->ReleaseLongArrayElements(OLD, temp, JNI_ABORT); \\\n') + java_wrapper.write(' } \\\n') + java_wrapper.write(' } \n\n') + java_wrapper.write('#define RELEASELONGAELEMS(OLD,NEW) \\\n') + java_wrapper.write(' delete [] NEW; \n\n') + java_wrapper.write('#define GETLONGAREGION(T,OLD,Z,SZ,NEW) \\\n') + java_wrapper.write(' { \\\n') + java_wrapper.write(' jlong * temp = new jlong[SZ]; \\\n') + java_wrapper.write(' jenv->GetLongArrayRegion(OLD,Z,(jsize)SZ,(jlong*)temp); \\\n') + java_wrapper.write(' for (int i = 0; i < (SZ); i++) \\\n') + java_wrapper.write(' NEW[i] = reinterpret_cast(temp[i]); \\\n') + java_wrapper.write(' delete [] temp; \\\n') + java_wrapper.write(' }\n\n') + java_wrapper.write('#define SETLONGAREGION(OLD,Z,SZ,NEW) \\\n') + java_wrapper.write(' { \\\n') + java_wrapper.write(' jlong * temp = new jlong[SZ]; \\\n') + java_wrapper.write(' for (int i = 0; i < (SZ); i++) \\\n') + java_wrapper.write(' temp[i] = reinterpret_cast(NEW[i]); \\\n') + java_wrapper.write(' jenv->SetLongArrayRegion(OLD,Z,(jsize)SZ,temp); \\\n') + java_wrapper.write(' delete [] temp; \\\n') + java_wrapper.write(' }\n\n') + java_wrapper.write('#endif\n\n') + java_wrapper.write('void Z3JavaErrorHandler(Z3_context c, Z3_error_code e)\n') + java_wrapper.write('{\n') + java_wrapper.write(' // Internal do-nothing error handler. This is required to avoid that Z3 calls exit()\n') + java_wrapper.write(' // upon errors, but the actual error handling is done by throwing exceptions in the\n') + java_wrapper.write(' // wrappers below.\n') + java_wrapper.write('}\n\n') + java_wrapper.write('JNIEXPORT void JNICALL Java_%s_Native_setInternalErrorHandler(JNIEnv * jenv, jclass cls, jlong a0)\n' % pkg_str) + java_wrapper.write('{\n') + java_wrapper.write(' Z3_set_error_handler((Z3_context)a0, Z3JavaErrorHandler);\n') + java_wrapper.write('}\n\n') + java_wrapper.write('') for name, result, params in _dotnet_decls: - java_wrapper.write('JNIEXPORT %s JNICALL Java_Z3Native_%s(JNIEnv * jenv, jclass cls' % (type2javaw(result), java_method_name(name))) + java_wrapper.write('JNIEXPORT %s JNICALL Java_%s_Native_INTERNAL%s(JNIEnv * jenv, jclass cls' % (type2javaw(result), pkg_str, java_method_name(name))) i = 0; for param in params: java_wrapper.write(', ') @@ -555,17 +622,20 @@ def mk_java(): if k == OUT or k == INOUT: java_wrapper.write(' %s _a%s;\n' % (type2str(param_type(param)), i)) elif k == IN_ARRAY or k == INOUT_ARRAY: - java_wrapper.write(' %s * _a%s = (%s *) jenv->%s(a%s, NULL);\n' % (type2str(param_type(param)), - i, - type2str(param_type(param)), - java_get_array_elements(param), - i)) + if param_type(param) == INT or param_type(param) == UINT: + java_wrapper.write(' %s * _a%s = (%s*) jenv->GetIntArrayElements(a%s, NULL);\n' % (type2str(param_type(param)), i, type2str(param_type(param)), i)) + else: + java_wrapper.write(' GETLONGAELEMS(%s, a%s, _a%s);\n' % (type2str(param_type(param)), i, i)) elif k == OUT_ARRAY: java_wrapper.write(' %s * _a%s = (%s *) malloc(((unsigned)a%s) * sizeof(%s));\n' % (type2str(param_type(param)), i, type2str(param_type(param)), param_array_capacity_pos(param), type2str(param_type(param)))) + if param_type(param) == INT or param_type(param) == UINT: + java_wrapper.write(' jenv->GetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i)) + else: + java_wrapper.write(' GETLONGAREGION(%s, a%s, 0, a%s, _a%s);\n' % (type2str(param_type(param)), i, param_array_capacity_pos(param), i)) elif k == IN and param_type(param) == STRING: java_wrapper.write(' Z3_string _a%s = (Z3_string) jenv->GetStringUTFChars(a%s, NULL);\n' % (i, i)) i = i + 1 @@ -597,17 +667,17 @@ def mk_java(): for param in params: k = param_kind(param) if k == OUT_ARRAY: - java_wrapper.write(' jenv->%s(a%s, 0, (jsize)a%s, (%s *) _a%s);\n' % (java_set_array_region(param), - i, - param_array_capacity_pos(param), - java_array_element_type(param), - i)) + if param_type(param) == INT or param_type(param) == UINT: + java_wrapper.write(' jenv->SetIntArrayRegion(a%s, 0, (jsize)a%s, (jint*)_a%s);\n' % (i, param_array_capacity_pos(param), i)) + else: + java_wrapper.write(' SETLONGAREGION(a%s, 0, a%s, _a%s);\n' % (i, param_array_capacity_pos(param), i)) java_wrapper.write(' free(_a%s);\n' % i) elif k == IN_ARRAY or k == OUT_ARRAY: - java_wrapper.write(' jenv->%s(a%s, (%s *) _a%s, JNI_ABORT);\n' % (java_release_array_elements(param), - i, - java_array_element_type(param), - i)) + if param_type(param) == INT or param_type(param) == UINT: + java_wrapper.write(' jenv->ReleaseIntArrayElements(a%s, (jint*)_a%s, JNI_ABORT);\n' % (i, i)) + else: + java_wrapper.write(' RELEASELONGAELEMS(a%s, _a%s);\n' % (i, i)) + elif k == OUT or k == INOUT: if param_type(param) == INT or param_type(param) == UINT: java_wrapper.write(' {\n') @@ -626,7 +696,7 @@ def mk_java(): if result == STRING: java_wrapper.write(' return jenv->NewStringUTF(result);\n') elif result != VOID: - java_wrapper.write(' return (%s) result;\n' % type2javaw(result)) + java_wrapper.write(' return (%s) result;\n' % type2javaw(result)) java_wrapper.write('}\n') java_wrapper.write('#ifdef __cplusplus\n') java_wrapper.write('}\n') diff --git a/src/api/api_ast.cpp b/src/api/api_ast.cpp index aeddf63c3..c604927fd 100644 --- a/src/api/api_ast.cpp +++ b/src/api/api_ast.cpp @@ -36,6 +36,7 @@ Revision History: #include"scoped_ctrl_c.h" #include"cancel_eh.h" #include"scoped_timer.h" +#include"pp_params.hpp" extern "C" { @@ -674,8 +675,8 @@ extern "C" { ast_manager & m = mk_c(c)->m(); expr * a = to_expr(_a); params_ref p = to_param_ref(_p); - unsigned timeout = p.get_uint(":timeout", UINT_MAX); - bool use_ctrl_c = p.get_bool(":ctrl-c", false); + unsigned timeout = p.get_uint("timeout", mk_c(c)->get_timeout()); + bool use_ctrl_c = p.get_bool("ctrl_c", false); th_rewriter m_rw(m, p); expr_ref result(m); cancel_eh eh(m_rw); @@ -833,7 +834,8 @@ extern "C" { break; case Z3_PRINT_SMTLIB_COMPLIANT: { ast_smt_pp pp(mk_c(c)->m()); - pp.set_simplify_implies(get_pp_default_params().m_pp_simplify_implies); + pp_params params; + pp.set_simplify_implies(params.simplify_implies()); ast* a1 = to_ast(a); pp.set_logic(mk_c(c)->fparams().m_smtlib_logic.c_str()); if (!is_expr(a1)) { @@ -886,7 +888,8 @@ extern "C" { pp.set_logic(logic); pp.set_status(status); pp.add_attributes(attributes); - pp.set_simplify_implies(get_pp_default_params().m_pp_simplify_implies); + pp_params params; + pp.set_simplify_implies(params.simplify_implies()); for (unsigned i = 0; i < num_assumptions; ++i) { pp.add_assumption(to_expr(assumptions[i])); } diff --git a/src/api/api_config_params.cpp b/src/api/api_config_params.cpp index 07e043726..aaaabb7b2 100644 --- a/src/api/api_config_params.cpp +++ b/src/api/api_config_params.cpp @@ -17,106 +17,99 @@ Revision History: --*/ #include"z3.h" #include"api_context.h" -#include"api_config_params.h" #include"pp.h" #include"api_log_macros.h" #include"api_util.h" +#include"cmd_context.h" #include"symbol.h" - -namespace api { - - config_params::config_params(): - m_ini(false /* do not abort on errors */) { - register_verbosity_level(m_ini); - register_warning(m_ini); - m_params.register_params(m_ini); - register_pp_params(m_ini); - } - - config_params::config_params(front_end_params const & p):m_params(p) { - register_verbosity_level(m_ini); - register_warning(m_ini); - register_pp_params(m_ini); - } - -}; - -extern std::string smt_keyword2opt_name(symbol const & opt); +#include"gparams.h" +#include"env_params.h" +#include"context_params.h" extern "C" { + void Z3_API Z3_global_param_set(Z3_string param_id, Z3_string param_value) { + memory::initialize(UINT_MAX); + LOG_Z3_global_param_set(param_id, param_value); + try { + gparams::set(param_id, param_value); + env_params::updt_params(); + } + catch (z3_exception & ex) { + // The error handler is only available for contexts + // Just throw a warning. + std::ostringstream buffer; + buffer << "Error setting " << param_id << ", " << ex.msg(); + warning_msg(buffer.str().c_str()); + } + } + + void Z3_API Z3_global_param_reset_all() { + memory::initialize(UINT_MAX); + LOG_Z3_global_param_reset_all(); + gparams::reset(); + env_params::updt_params(); + } + + std::string g_Z3_global_param_get_buffer; + + Z3_bool_opt Z3_API Z3_global_param_get(Z3_string param_id, Z3_string_ptr param_value) { + memory::initialize(UINT_MAX); + LOG_Z3_global_param_get(param_id, param_value); + *param_value = 0; + try { + g_Z3_global_param_get_buffer = gparams::get_value(param_id); + *param_value = g_Z3_global_param_get_buffer.c_str(); + return Z3_TRUE; + } + catch (z3_exception & ex) { + // The error handler is only available for contexts + // Just throw a warning. + std::ostringstream buffer; + buffer << "Error setting " << param_id << ": " << ex.msg(); + warning_msg(buffer.str().c_str()); + return Z3_FALSE; + } + } + Z3_config Z3_API Z3_mk_config() { + memory::initialize(UINT_MAX); LOG_Z3_mk_config(); - memory::initialize(0); - Z3_config r = reinterpret_cast(alloc(api::config_params)); + Z3_config r = reinterpret_cast(alloc(context_params)); RETURN_Z3(r); } void Z3_API Z3_del_config(Z3_config c) { LOG_Z3_del_config(c); - dealloc((reinterpret_cast(c))); + dealloc((reinterpret_cast(c))); } void Z3_API Z3_set_param_value(Z3_config c, char const * param_id, char const * param_value) { - try { - LOG_Z3_set_param_value(c, param_id, param_value); - api::config_params* p = reinterpret_cast(c); - if (param_id != 0 && param_id[0] == ':') { - // Allow SMT2 style paramater names such as :model, :relevancy, etc - std::string new_param_id = smt_keyword2opt_name(symbol(param_id)); - p->m_ini.set_param_value(new_param_id.c_str(), param_value); - } - else { - p->m_ini.set_param_value(param_id, param_value); - } + LOG_Z3_set_param_value(c, param_id, param_value); + try { + context_params * p = reinterpret_cast(c); + p->set(param_id, param_value); } - catch (set_get_param_exception & ex) { - // The error handler was not set yet. + catch (z3_exception & ex) { + // The error handler is only available for contexts // Just throw a warning. std::ostringstream buffer; - buffer << "Error setting " << param_id << ", " << ex.get_msg(); + buffer << "Error setting " << param_id << ": " << ex.msg(); warning_msg(buffer.str().c_str()); } } void Z3_API Z3_update_param_value(Z3_context c, Z3_string param_id, Z3_string param_value) { + Z3_TRY; LOG_Z3_update_param_value(c, param_id, param_value); RESET_ERROR_CODE(); - ini_params ini; - mk_c(c)->fparams().register_params(ini); - register_pp_params(ini); - register_verbosity_level(ini); - register_warning(ini); - if (mk_c(c)->has_solver()) { - ini.freeze(); - } - if (param_id != 0 && param_id[0] == ':') { - // Allow SMT2 style paramater names such as :model, :relevancy, etc - std::string new_param_id = smt_keyword2opt_name(symbol(param_id)); - ini.set_param_value(new_param_id.c_str(), param_value); - } - else { - ini.set_param_value(param_id, param_value); - } - memory::set_high_watermark(static_cast(mk_c(c)->fparams().m_memory_high_watermark)*1024*1024); - memory::set_max_size(static_cast(mk_c(c)->fparams().m_memory_max_size)*1024*1024); + mk_c(c)->params().set(param_id, param_value); + Z3_CATCH; } Z3_bool Z3_API Z3_get_param_value(Z3_context c, Z3_string param_id, Z3_string* param_value) { LOG_Z3_get_param_value(c, param_id, param_value); - ini_params ini; - mk_c(c)->fparams().register_params(ini); - register_verbosity_level(ini); - register_pp_params(ini); - register_warning(ini); - std::string param_value_s; - if (!ini.get_param_value(param_id, param_value_s)) { - if (param_value) *param_value = 0; - return false; - } - if (param_value) { - *param_value = mk_c(c)->mk_external_string(param_value_s); - } - return true; + // TODO + return Z3_FALSE; } }; diff --git a/src/api/api_config_params.h b/src/api/api_config_params.h deleted file mode 100644 index 22e713c50..000000000 --- a/src/api/api_config_params.h +++ /dev/null @@ -1,36 +0,0 @@ -/*++ -Copyright (c) 2012 Microsoft Corporation - -Module Name: - - api_config_params.h - -Abstract: - Configuration parameters - -Author: - - Leonardo de Moura (leonardo) 2012-02-29. - -Revision History: - ---*/ -#ifndef _API_CONFIG_PARAMS_H_ -#define _API_CONFIG_PARAMS_H_ - -#include"ini_file.h" -#include"front_end_params.h" - -namespace api { - - class config_params { - public: - ini_params m_ini; - front_end_params m_params; - config_params(); - config_params(front_end_params const & p); - }; - -}; - -#endif diff --git a/src/api/api_context.cpp b/src/api/api_context.cpp index ba8d2ae64..69b7ea999 100644 --- a/src/api/api_context.cpp +++ b/src/api/api_context.cpp @@ -18,7 +18,6 @@ Revision History: --*/ #include"api_context.h" -#include"api_config_params.h" #include"smtparser.h" #include"version.h" #include"ast_pp.h" @@ -54,14 +53,6 @@ namespace api { return static_cast(f); } - context::param_ini::param_ini(front_end_params & p) : m_params(p) { - p.open_trace_file(); - } - - context::param_ini::~param_ini() { - m_params.close_trace_file(); - } - context::add_plugins::add_plugins(ast_manager & m) { reg_decl_plugins(m); } @@ -88,11 +79,10 @@ namespace api { } } - context::context(config_params * p, bool user_ref_count): - m_params(p ? p->m_params : front_end_params()), - m_param_ini(m_params), + context::context(context_params * p, bool user_ref_count): + m_params(p != 0 ? *p : context_params()), m_user_ref_count(user_ref_count), - m_manager(m_params.m_proof_mode, m_params.m_trace_stream), + m_manager(m_params.m_proof ? PGM_FINE : PGM_DISABLED, m_params.m_trace ? m_params.m_trace_file_name.c_str() : 0), m_plugins(m_manager), m_arith_util(m_manager), m_bv_util(m_manager), @@ -115,8 +105,6 @@ namespace api { // // Configuration parameter settings. // - memory::set_high_watermark(static_cast(m_params.m_memory_high_watermark)*1024*1024); - memory::set_max_size(static_cast(m_params.m_memory_max_size)*1024*1024); if (m_params.m_debug_ref_count) { m_manager.debug_ref_count(); } @@ -335,7 +323,8 @@ namespace api { smt::kernel & context::get_smt_kernel() { if (!m_solver) { - m_solver = alloc(smt::kernel, m_manager, m_params); + m_fparams.updt_params(m_params); + m_solver = alloc(smt::kernel, m_manager, m_fparams); } return *m_solver; } @@ -420,15 +409,15 @@ extern "C" { Z3_context Z3_API Z3_mk_context(Z3_config c) { LOG_Z3_mk_context(c); - memory::initialize(0); - Z3_context r = reinterpret_cast(alloc(api::context, reinterpret_cast(c), false)); + memory::initialize(UINT_MAX); + Z3_context r = reinterpret_cast(alloc(api::context, reinterpret_cast(c), false)); RETURN_Z3(r); } Z3_context Z3_API Z3_mk_context_rc(Z3_config c) { LOG_Z3_mk_context_rc(c); - memory::initialize(0); - Z3_context r = reinterpret_cast(alloc(api::context, reinterpret_cast(c), true)); + memory::initialize(UINT_MAX); + Z3_context r = reinterpret_cast(alloc(api::context, reinterpret_cast(c), true)); RETURN_Z3(r); } @@ -574,11 +563,4 @@ ast_manager & Z3_API Z3_get_manager(__in Z3_context c) { return mk_c(c)->m(); } -front_end_params& Z3_API Z3_get_parameters(__in Z3_context c) { - return mk_c(c)->fparams(); -} -Z3_context Z3_mk_context_from_params(front_end_params const& p) { - api::config_params cp(p); - return reinterpret_cast(alloc(api::context, &cp)); -} diff --git a/src/api/api_context.h b/src/api/api_context.h index 3da506b54..a126f0790 100644 --- a/src/api/api_context.h +++ b/src/api/api_context.h @@ -28,32 +28,22 @@ Revision History: #include"datatype_decl_plugin.h" #include"dl_decl_plugin.h" #include"smt_kernel.h" -#include"front_end_params.h" +#include"smt_params.h" #include"event_handler.h" #include"tactic_manager.h" +#include"context_params.h" namespace smtlib { class parser; }; namespace api { - class config_params; - Z3_search_failure mk_Z3_search_failure(smt::failure f); class context : public tactic_manager { - class param_ini { - front_end_params & m_params; - public: - param_ini(front_end_params & p); - ~param_ini(); - }; - struct add_plugins { add_plugins(ast_manager & m); }; - - front_end_params m_params; - param_ini m_param_ini; + context_params m_params; bool m_user_ref_count; //!< if true, the user is responsible for managing referenc counters. ast_manager m_manager; add_plugins m_plugins; @@ -62,8 +52,11 @@ namespace api { bv_util m_bv_util; datalog::dl_decl_util m_datalog_util; + // Support for old solver API + smt_params m_fparams; smt::kernel * m_solver; // General purpose solver for backward compatibility - + // ------------------------------- + ast_ref_vector m_last_result; //!< used when m_user_ref_count == true ast_ref_vector m_ast_trail; //!< used when m_user_ref_count == false unsigned_vector m_ast_lim; @@ -103,11 +96,16 @@ namespace api { // // ------------------------ - context(config_params * p, bool user_ref_count = false); + context(context_params * p, bool user_ref_count = false); ~context(); - - front_end_params & fparams() { return m_params; } ast_manager & m() { return m_manager; } + + context_params & params() { return m_params; } + bool produce_proofs() const { return m_manager.proofs_enabled(); } + bool produce_models() const { return m_params.m_model; } + bool produce_unsat_cores() const { return m_params.m_unsat_core; } + bool use_auto_config() const { return m_params.m_auto_config; } + unsigned get_timeout() const { return m_params.m_timeout; } arith_util & autil() { return m_arith_util; } bv_util & bvutil() { return m_bv_util; } datalog::dl_decl_util & datalog_util() { return m_datalog_util; } @@ -168,12 +166,13 @@ namespace api { static void out_of_memory_handler(void * _ctx); void check_sorts(ast * n); + // ------------------------ // // Solver interface for backward compatibility // // ------------------------ - + smt_params & fparams() { return m_fparams; } bool has_solver() const { return m_solver != 0; } smt::kernel & get_smt_kernel(); void assert_cnstr(expr * a); diff --git a/src/api/api_datalog.cpp b/src/api/api_datalog.cpp index 0200a4405..28fe3ed33 100644 --- a/src/api/api_datalog.cpp +++ b/src/api/api_datalog.cpp @@ -32,7 +32,7 @@ Revision History: namespace api { - fixedpoint_context::fixedpoint_context(ast_manager& m, front_end_params& p) : + fixedpoint_context::fixedpoint_context(ast_manager& m, smt_params& p) : m_state(0), m_reduce_app(0), m_reduce_assign(0), @@ -48,7 +48,7 @@ namespace api { if (!m.has_plugin(name)) { m.register_plugin(name, alloc(datalog::dl_decl_plugin)); } - datalog::relation_manager& r = m_context.get_rmanager(); + datalog::relation_manager& r = m_context.get_rel_context().get_rmanager(); r.register_plugin(alloc(datalog::external_relation_plugin, *this, r)); } @@ -265,7 +265,7 @@ extern "C" { RESET_ERROR_CODE(); lbool r = l_undef; cancel_eh eh(*to_fixedpoint_ref(d)); - unsigned timeout = to_fixedpoint(d)->m_params.get_uint(":timeout", UINT_MAX); + unsigned timeout = to_fixedpoint(d)->m_params.get_uint("timeout", mk_c(c)->get_timeout()); api::context::set_interruptable(*(mk_c(c)), eh); { scoped_timer timer(timeout, &eh); @@ -289,13 +289,13 @@ extern "C" { LOG_Z3_fixedpoint_query_relations(c, d, num_relations, relations); RESET_ERROR_CODE(); lbool r = l_undef; - unsigned timeout = to_fixedpoint(d)->m_params.get_uint(":timeout", UINT_MAX); + unsigned timeout = to_fixedpoint(d)->m_params.get_uint("timeout", mk_c(c)->get_timeout()); cancel_eh eh(*to_fixedpoint_ref(d)); api::context::set_interruptable(*(mk_c(c)), eh); { scoped_timer timer(timeout, &eh); try { - r = to_fixedpoint_ref(d)->ctx().dl_query(num_relations, to_func_decls(relations)); + r = to_fixedpoint_ref(d)->ctx().rel_query(num_relations, to_func_decls(relations)); } catch (z3_exception& ex) { mk_c(c)->handle_exception(ex); @@ -344,7 +344,7 @@ extern "C" { std::istream& s) { ast_manager& m = mk_c(c)->m(); dl_collected_cmds coll(m); - cmd_context ctx(&mk_c(c)->fparams(), false, &m); + cmd_context ctx(false, &m); install_dl_collect_cmds(coll, ctx); ctx.set_ignore_check(true); if (!parse_smt2_commands(ctx, s)) { diff --git a/src/api/api_datalog.h b/src/api/api_datalog.h index 97bedfc9b..1dc0a9cbd 100644 --- a/src/api/api_datalog.h +++ b/src/api/api_datalog.h @@ -21,7 +21,7 @@ Revision History: #include"z3.h" #include"ast.h" -#include"front_end_params.h" +#include"smt_params.h" #include"dl_external_relation.h" #include"dl_decl_plugin.h" #include"smt_kernel.h" @@ -40,7 +40,7 @@ namespace api { datalog::context m_context; ast_ref_vector m_trail; public: - fixedpoint_context(ast_manager& m, front_end_params& p); + fixedpoint_context(ast_manager& m, smt_params& p); virtual ~fixedpoint_context() {} family_id get_family_id() const { return const_cast(m_context).get_decl_util().get_family_id(); } void set_state(void* state); diff --git a/src/api/api_model.cpp b/src/api/api_model.cpp index a6ada4ae6..f26ffeeba 100644 --- a/src/api/api_model.cpp +++ b/src/api/api_model.cpp @@ -25,6 +25,7 @@ Revision History: #include"model.h" #include"model_v2_pp.h" #include"model_smt2_pp.h" +#include"model_params.hpp" extern "C" { @@ -200,7 +201,7 @@ extern "C" { LOG_Z3_get_as_array_func_decl(c, a); RESET_ERROR_CODE(); if (is_expr(to_ast(a)) && is_app_of(to_expr(a), mk_c(c)->get_array_fid(), OP_AS_ARRAY)) { - return of_func_decl(to_func_decl(to_app(a)->get_decl()->get_parameter(0).get_ast())); + RETURN_Z3(of_func_decl(to_func_decl(to_app(a)->get_decl()->get_parameter(0).get_ast()))); } else { SET_ERROR_CODE(Z3_INVALID_ARG); @@ -488,7 +489,8 @@ extern "C" { Z3_model m, Z3_ast t, Z3_ast * v) { - return Z3_model_eval(c, m, t, mk_c(c)->fparams().m_model_completion, v); + model_params p; + return Z3_model_eval(c, m, t, p.completion(), v); } Z3_bool Z3_API Z3_eval_func_decl(Z3_context c, @@ -660,7 +662,8 @@ extern "C" { result.resize(result.size()-1); } else { - model_v2_pp(buffer, *(to_model_ref(m)), mk_c(c)->fparams().m_model_partial); + model_params p; + model_v2_pp(buffer, *(to_model_ref(m)), p.partial()); result = buffer.str(); } return mk_c(c)->mk_external_string(result); diff --git a/src/api/api_params.cpp b/src/api/api_params.cpp index 74899bc44..19634af32 100644 --- a/src/api/api_params.cpp +++ b/src/api/api_params.cpp @@ -66,7 +66,7 @@ extern "C" { Z3_TRY; LOG_Z3_params_set_bool(c, p, k, v); RESET_ERROR_CODE(); - to_params(p)->m_params.set_bool(to_symbol(k), v != 0); + to_params(p)->m_params.set_bool(norm_param_name(to_symbol(k)).c_str(), v != 0); Z3_CATCH; } @@ -77,7 +77,7 @@ extern "C" { Z3_TRY; LOG_Z3_params_set_uint(c, p, k, v); RESET_ERROR_CODE(); - to_params(p)->m_params.set_uint(to_symbol(k), v); + to_params(p)->m_params.set_uint(norm_param_name(to_symbol(k)).c_str(), v); Z3_CATCH; } @@ -88,7 +88,7 @@ extern "C" { Z3_TRY; LOG_Z3_params_set_double(c, p, k, v); RESET_ERROR_CODE(); - to_params(p)->m_params.set_double(to_symbol(k), v); + to_params(p)->m_params.set_double(norm_param_name(to_symbol(k)).c_str(), v); Z3_CATCH; } @@ -99,7 +99,7 @@ extern "C" { Z3_TRY; LOG_Z3_params_set_symbol(c, p, k, v); RESET_ERROR_CODE(); - to_params(p)->m_params.set_sym(to_symbol(k), to_symbol(v)); + to_params(p)->m_params.set_sym(norm_param_name(to_symbol(k)).c_str(), to_symbol(v)); Z3_CATCH; } diff --git a/src/api/api_parsers.cpp b/src/api/api_parsers.cpp index b6d18096f..69ca1fc81 100644 --- a/src/api/api_parsers.cpp +++ b/src/api/api_parsers.cpp @@ -296,7 +296,7 @@ extern "C" { Z3_symbol const decl_names[], Z3_func_decl const decls[]) { Z3_TRY; - cmd_context ctx(&mk_c(c)->fparams(), false, &(mk_c(c)->m())); + cmd_context ctx(false, &(mk_c(c)->m())); ctx.set_ignore_check(true); if (exec) { ctx.set_solver(alloc(z3_context_solver, *mk_c(c))); @@ -362,7 +362,7 @@ extern "C" { Z3_symbol decl_names[], Z3_func_decl decls[]) { Z3_TRY; - cmd_context ctx(&mk_c(c)->fparams(), false, &(mk_c(c)->m())); + cmd_context ctx(false, &(mk_c(c)->m())); std::string s(str); std::istringstream is(s); // No logging for this one, since it private. diff --git a/src/api/api_solver.cpp b/src/api/api_solver.cpp index 790ca8f59..67d083704 100644 --- a/src/api/api_solver.cpp +++ b/src/api/api_solver.cpp @@ -36,11 +36,17 @@ extern "C" { static void init_solver_core(Z3_context c, Z3_solver _s) { ast_manager & m = mk_c(c)->m(); Z3_solver_ref * s = to_solver(_s); - s->m_solver->set_produce_proofs(m.proofs_enabled()); - s->m_solver->set_produce_unsat_cores(s->m_params.get_bool(":unsat-core", false)); - s->m_solver->set_produce_models(s->m_params.get_bool(":model", true)); - s->m_solver->set_front_end_params(mk_c(c)->fparams()); - s->m_solver->updt_params(s->m_params); + s->m_solver->set_produce_proofs(mk_c(c)->produce_proofs()); + s->m_solver->set_produce_unsat_cores(s->m_params.get_bool("unsat_core", mk_c(c)->produce_unsat_cores())); + s->m_solver->set_produce_models(s->m_params.get_bool("model", mk_c(c)->produce_models())); + if (!mk_c(c)->use_auto_config()) { + params_ref p = s->m_params; + p.set_bool("auto_config", false); + s->m_solver->updt_params(p); + } + else { + s->m_solver->updt_params(s->m_params); + } s->m_solver->init(m, s->m_logic); s->m_initialized = true; } @@ -127,8 +133,8 @@ extern "C" { LOG_Z3_solver_set_params(c, s, p); RESET_ERROR_CODE(); if (to_solver(s)->m_initialized) { - bool old_model = to_solver(s)->m_params.get_bool(":model", true); - bool new_model = to_param_ref(p).get_bool(":model", true); + bool old_model = to_solver(s)->m_params.get_bool("model", true); + bool new_model = to_param_ref(p).get_bool("model", true); if (old_model != new_model) to_solver_ref(s)->set_produce_models(new_model); to_solver_ref(s)->updt_params(to_param_ref(p)); @@ -238,8 +244,8 @@ extern "C" { } } expr * const * _assumptions = to_exprs(assumptions); - unsigned timeout = to_solver(s)->m_params.get_uint(":timeout", UINT_MAX); - bool use_ctrl_c = to_solver(s)->m_params.get_bool(":ctrl-c", false); + unsigned timeout = to_solver(s)->m_params.get_uint("timeout", mk_c(c)->get_timeout()); + bool use_ctrl_c = to_solver(s)->m_params.get_bool("ctrl_c", false); cancel_eh eh(*to_solver_ref(s)); api::context::set_interruptable(*(mk_c(c)), eh); lbool result; diff --git a/src/api/api_tactic.cpp b/src/api/api_tactic.cpp index ff55923a4..5bce218e6 100644 --- a/src/api/api_tactic.cpp +++ b/src/api/api_tactic.cpp @@ -404,8 +404,8 @@ extern "C" { Z3_apply_result_ref * ref = alloc(Z3_apply_result_ref, mk_c(c)->m()); mk_c(c)->save_object(ref); - unsigned timeout = p.get_uint(":timeout", UINT_MAX); - bool use_ctrl_c = p.get_bool(":ctrl-c", false); + unsigned timeout = p.get_uint("timeout", UINT_MAX); + bool use_ctrl_c = p.get_bool("ctrl_c", false); cancel_eh eh(*to_tactic_ref(t)); to_tactic_ref(t)->updt_params(p); diff --git a/src/api/c++/z3++.h b/src/api/c++/z3++.h index 7fc36575a..fca009cea 100644 --- a/src/api/c++/z3++.h +++ b/src/api/c++/z3++.h @@ -64,6 +64,11 @@ namespace z3 { class apply_result; class fixedpoint; + inline void set_param(char const * param, char const * value) { Z3_global_param_set(param, value); } + inline void set_param(char const * param, bool value) { Z3_global_param_set(param, value ? "true" : "false"); } + inline void set_param(char const * param, int value) { std::ostringstream oss; oss << value; Z3_global_param_set(param, oss.str().c_str()); } + inline void reset_params() { Z3_global_param_reset_all(); } + /** \brief Exception used to sign API usage errors. */ diff --git a/src/api/dotnet/BitVecSort.cs b/src/api/dotnet/BitVecSort.cs index 55ef4ae49..d865159f4 100644 --- a/src/api/dotnet/BitVecSort.cs +++ b/src/api/dotnet/BitVecSort.cs @@ -37,7 +37,6 @@ namespace Microsoft.Z3 #region Internal internal BitVecSort(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } - internal BitVecSort(Context ctx, uint size) : base(ctx, Native.Z3_mk_bv_sort(ctx.nCtx, size)) { Contract.Requires(ctx != null); } #endregion }; } diff --git a/src/api/dotnet/Context.cs b/src/api/dotnet/Context.cs index 2aea1586c..aee60c43f 100644 --- a/src/api/dotnet/Context.cs +++ b/src/api/dotnet/Context.cs @@ -113,7 +113,6 @@ namespace Microsoft.Z3 get { Contract.Ensures(Contract.Result() != null); - if (m_boolSort == null) m_boolSort = new BoolSort(this); return m_boolSort; } } @@ -134,7 +133,14 @@ namespace Microsoft.Z3 /// /// Retrieves the Real sort of the context. /// - public RealSort RealSort { get { Contract.Ensures(Contract.Result() != null); if (m_realSort == null) m_realSort = new RealSort(this); return m_realSort; } } + public RealSort RealSort + { + get + { + Contract.Ensures(Contract.Result() != null); + if (m_realSort == null) m_realSort = new RealSort(this); return m_realSort; + } + } /// /// Create a new Boolean sort. @@ -193,7 +199,7 @@ namespace Microsoft.Z3 { Contract.Ensures(Contract.Result() != null); - return new BitVecSort(this, size); + return new BitVecSort(this, Native.Z3_mk_bv_sort(nCtx, size)); } /// @@ -388,7 +394,7 @@ namespace Microsoft.Z3 IntPtr[] n_constr = new IntPtr[n]; for (uint i = 0; i < n; i++) { - var constructor = c[i]; + Constructor[] constructor = c[i]; Contract.Assume(Contract.ForAll(constructor, arr => arr != null), "Clousot does not support yet quantified formula on multidimensional arrays"); CheckContextMatch(constructor); cla[i] = new ConstructorList(this, constructor); @@ -3651,6 +3657,7 @@ namespace Microsoft.Z3 Goal_DRQ.Clear(this); Model_DRQ.Clear(this); Params_DRQ.Clear(this); + ParamDescrs_DRQ.Clear(this); Probe_DRQ.Clear(this); Solver_DRQ.Clear(this); Statistics_DRQ.Clear(this); diff --git a/src/api/dotnet/Expr.cs b/src/api/dotnet/Expr.cs index 22a506c71..9f5c04f0b 100644 --- a/src/api/dotnet/Expr.cs +++ b/src/api/dotnet/Expr.cs @@ -433,7 +433,8 @@ namespace Microsoft.Z3 get { return (Native.Z3_is_app(Context.nCtx, NativeObject) != 0 && - (Z3_sort_kind)Native.Z3_get_sort_kind(Context.nCtx, Native.Z3_get_sort(Context.nCtx, NativeObject)) == Z3_sort_kind.Z3_ARRAY_SORT); + (Z3_sort_kind)Native.Z3_get_sort_kind(Context.nCtx, Native.Z3_get_sort(Context.nCtx, NativeObject)) + == Z3_sort_kind.Z3_ARRAY_SORT); } } @@ -1308,7 +1309,8 @@ namespace Microsoft.Z3 get { return (Native.Z3_is_app(Context.nCtx, NativeObject) != 0 && - (Z3_sort_kind)Native.Z3_get_sort_kind(Context.nCtx, Native.Z3_get_sort(Context.nCtx, NativeObject)) == Z3_sort_kind.Z3_RELATION_SORT); + Native.Z3_get_sort_kind(Context.nCtx, Native.Z3_get_sort(Context.nCtx, NativeObject)) + == (uint)Z3_sort_kind.Z3_RELATION_SORT); } } @@ -1429,7 +1431,7 @@ namespace Microsoft.Z3 get { return (Native.Z3_is_app(Context.nCtx, NativeObject) != 0 && - (Z3_sort_kind)Native.Z3_get_sort_kind(Context.nCtx, Native.Z3_get_sort(Context.nCtx, NativeObject)) == Z3_sort_kind.Z3_FINITE_DOMAIN_SORT); + Native.Z3_get_sort_kind(Context.nCtx, Native.Z3_get_sort(Context.nCtx, NativeObject)) == (uint)Z3_sort_kind.Z3_FINITE_DOMAIN_SORT); } } @@ -1489,8 +1491,8 @@ namespace Microsoft.Z3 internal override void CheckNativeObject(IntPtr obj) { if (Native.Z3_is_app(Context.nCtx, obj) == 0 && - (Z3_ast_kind)Native.Z3_get_ast_kind(Context.nCtx, obj) != Z3_ast_kind.Z3_VAR_AST && - (Z3_ast_kind)Native.Z3_get_ast_kind(Context.nCtx, obj) != Z3_ast_kind.Z3_QUANTIFIER_AST) + Native.Z3_get_ast_kind(Context.nCtx, obj) != (uint)Z3_ast_kind.Z3_VAR_AST && + Native.Z3_get_ast_kind(Context.nCtx, obj) != (uint)Z3_ast_kind.Z3_QUANTIFIER_AST) throw new Z3Exception("Underlying object is not a term"); base.CheckNativeObject(obj); } @@ -1530,7 +1532,7 @@ namespace Microsoft.Z3 { case Z3_sort_kind.Z3_INT_SORT: return new IntNum(ctx, obj); case Z3_sort_kind.Z3_REAL_SORT: return new RatNum(ctx, obj); - case Z3_sort_kind.Z3_BV_SORT: return new BitVecNum(ctx, obj); + case Z3_sort_kind.Z3_BV_SORT: return new BitVecNum(ctx, obj); } } @@ -1541,7 +1543,7 @@ namespace Microsoft.Z3 case Z3_sort_kind.Z3_REAL_SORT: return new RealExpr(ctx, obj); case Z3_sort_kind.Z3_BV_SORT: return new BitVecExpr(ctx, obj); case Z3_sort_kind.Z3_ARRAY_SORT: return new ArrayExpr(ctx, obj); - case Z3_sort_kind.Z3_DATATYPE_SORT: return new DatatypeExpr(ctx, obj); + case Z3_sort_kind.Z3_DATATYPE_SORT: return new DatatypeExpr(ctx, obj); } return new Expr(ctx, obj); diff --git a/src/api/dotnet/FuncDecl.cs b/src/api/dotnet/FuncDecl.cs index 37929e88f..15b6a59db 100644 --- a/src/api/dotnet/FuncDecl.cs +++ b/src/api/dotnet/FuncDecl.cs @@ -110,7 +110,7 @@ namespace Microsoft.Z3 { Contract.Ensures(Contract.Result() != null); - var n = DomainSize; + uint n = DomainSize; Sort[] res = new Sort[n]; for (uint i = 0; i < n; i++) diff --git a/src/api/dotnet/Goal.cs b/src/api/dotnet/Goal.cs index 6a0b253bb..e648ac80c 100644 --- a/src/api/dotnet/Goal.cs +++ b/src/api/dotnet/Goal.cs @@ -184,10 +184,10 @@ namespace Microsoft.Z3 { Tactic t = Context.MkTactic("simplify"); ApplyResult res = t.Apply(this, p); - + if (res.NumSubgoals == 0) - return Context.MkGoal(); - else + throw new Z3Exception("No subgoals"); + else return res.Subgoals[0]; } diff --git a/src/api/dotnet/IDecRefQueue.cs b/src/api/dotnet/IDecRefQueue.cs index e6276c4f4..d741a8f05 100644 --- a/src/api/dotnet/IDecRefQueue.cs +++ b/src/api/dotnet/IDecRefQueue.cs @@ -24,7 +24,7 @@ using System.Threading; using System.Diagnostics.Contracts; namespace Microsoft.Z3 -{ +{ [ContractClass(typeof(DecRefQueueContracts))] internal abstract class IDecRefQueue { @@ -35,7 +35,7 @@ namespace Microsoft.Z3 { Contract.Invariant(this.m_queue != null); } - + #endregion readonly internal protected Object m_lock = new Object(); diff --git a/src/api/dotnet/Microsoft.Z3.csproj b/src/api/dotnet/Microsoft.Z3.csproj index 762b83b28..a1bb868eb 100644 --- a/src/api/dotnet/Microsoft.Z3.csproj +++ b/src/api/dotnet/Microsoft.Z3.csproj @@ -252,6 +252,71 @@ ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules true + + true + bin\x86\Debug\ + DEBUG;TRACE + true + full + x86 + ..\Debug\Microsoft.Z3.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + + + bin\x86\Release\ + true + ..\external\Microsoft.Z3.xml + true + pdbonly + x86 + ..\external\Microsoft.Z3.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + + + bin\x86\external\ + true + ..\external\Microsoft.Z3.xml + true + pdbonly + x86 + bin\Release\Microsoft.Z3.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + + + bin\x86\Release_delaysign\ + DELAYSIGN + true + ..\Release_delaysign\Microsoft.Z3.xml + true + pdbonly + x86 + ..\release\Microsoft.Z3.dll.CodeAnalysisLog.xml + true + GlobalSuppressions.cs + prompt + MinimumRecommendedRules.ruleset + ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets + true + ;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules + true + diff --git a/src/api/dotnet/Model.cs b/src/api/dotnet/Model.cs index 5529677dd..5c0bc24f8 100644 --- a/src/api/dotnet/Model.cs +++ b/src/api/dotnet/Model.cs @@ -165,8 +165,8 @@ namespace Microsoft.Z3 { Contract.Ensures(Contract.Result() != null); - var nFuncs = NumFuncs; - var nConsts = NumConsts; + uint nFuncs = NumFuncs; + uint nConsts = NumConsts; uint n = nFuncs + nConsts; FuncDecl[] res = new FuncDecl[n]; for (uint i = 0; i < nConsts; i++) diff --git a/src/api/dotnet/Quantifier.cs b/src/api/dotnet/Quantifier.cs index c6754e570..f59d0bda2 100644 --- a/src/api/dotnet/Quantifier.cs +++ b/src/api/dotnet/Quantifier.cs @@ -181,8 +181,6 @@ namespace Microsoft.Z3 if (sorts.Length != names.Length) throw new Z3Exception("Number of sorts does not match number of names"); - IntPtr[] _patterns = AST.ArrayToNative(patterns); - if (noPatterns == null && quantifierID == null && skolemID == null) { NativeObject = Native.Z3_mk_quantifier(ctx.nCtx, (isForall) ? 1 : 0, weight, diff --git a/src/api/java/AST.java b/src/api/java/AST.java new file mode 100644 index 000000000..b7d048a1e --- /dev/null +++ b/src/api/java/AST.java @@ -0,0 +1,245 @@ +/** + * This file was automatically generated from AST.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +import com.microsoft.z3.enumerations.*; + +/** + * The abstract syntax tree (AST) class. + **/ +public class AST extends Z3Object +{ + /** + * Comparison operator. An AST An + * AST + * + * @return True if and are from + * the same context and represent the same sort; false otherwise. + **/ + /* Overloaded operators are not translated. */ + + /** + * Comparison operator. An AST An + * AST + * + * @return True if and are not + * from the same context or represent different sorts; false + * otherwise. + **/ + /* Overloaded operators are not translated. */ + + /** + * Object comparison. + **/ + public boolean equals(Object o) + { + AST casted = null; + + try + { + casted = AST.class.cast(o); + } catch (ClassCastException e) + { + return false; + } + + return this.NativeObject() == casted.NativeObject(); + } + + /** + * Object Comparison. Another AST + * + * @return Negative if the object should be sorted before , positive if after else zero. + **/ + public int compareTo(Object other) throws Z3Exception + { + if (other == null) + return 1; + + AST oAST = null; + try + { + oAST = AST.class.cast(other); + } catch (ClassCastException e) + { + return 1; + } + + if (Id() < oAST.Id()) + return -1; + else if (Id() > oAST.Id()) + return +1; + else + return 0; + } + + /** + * The AST's hash code. + * + * @return A hash code + **/ + public int GetHashCode() throws Z3Exception + { + return (int) Native.getAstHash(Context().nCtx(), NativeObject()); + } + + /** + * A unique identifier for the AST (unique among all ASTs). + **/ + public int Id() throws Z3Exception + { + return Native.getAstId(Context().nCtx(), NativeObject()); + } + + /** + * Translates (copies) the AST to the Context . A context + * + * @return A copy of the AST which is associated with + **/ + public AST Translate(Context ctx) throws Z3Exception + { + + if (Context() == ctx) + return this; + else + return new AST(ctx, Native.translate(Context().nCtx(), + NativeObject(), ctx.nCtx())); + } + + /** + * The kind of the AST. + **/ + public Z3_ast_kind ASTKind() throws Z3Exception + { + return Z3_ast_kind.fromInt(Native.getAstKind(Context().nCtx(), + NativeObject())); + } + + /** + * Indicates whether the AST is an Expr + **/ + public boolean IsExpr() throws Z3Exception + { + switch (ASTKind()) + { + case Z3_APP_AST: + case Z3_NUMERAL_AST: + case Z3_QUANTIFIER_AST: + case Z3_VAR_AST: + return true; + default: + return false; + } + } + + /** + * Indicates whether the AST is a BoundVariable + **/ + public boolean IsVar() throws Z3Exception + { + return this.ASTKind() == Z3_ast_kind.Z3_VAR_AST; + } + + /** + * Indicates whether the AST is a Quantifier + **/ + public boolean IsQuantifier() throws Z3Exception + { + return this.ASTKind() == Z3_ast_kind.Z3_QUANTIFIER_AST; + } + + /** + * Indicates whether the AST is a Sort + **/ + public boolean IsSort() throws Z3Exception + { + return this.ASTKind() == Z3_ast_kind.Z3_SORT_AST; + } + + /** + * Indicates whether the AST is a FunctionDeclaration + **/ + public boolean IsFuncDecl() throws Z3Exception + { + return this.ASTKind() == Z3_ast_kind.Z3_FUNC_DECL_AST; + } + + /** + * A string representation of the AST. + **/ + public String toString() + { + try + { + return Native.astToString(Context().nCtx(), NativeObject()); + } catch (Z3Exception e) + { + return "Z3Exception: " + e.getMessage(); + } + } + + /** + * A string representation of the AST in s-expression notation. + **/ + public String SExpr() throws Z3Exception + { + return Native.astToString(Context().nCtx(), NativeObject()); + } + + AST(Context ctx) + { + super(ctx); + } + + AST(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + void IncRef(long o) throws Z3Exception + { + // Console.WriteLine("AST IncRef()"); + if (Context() == null) + throw new Z3Exception("inc() called on null context"); + if (o == 0) + throw new Z3Exception("inc() called on null AST"); + Context().AST_DRQ().IncAndClear(Context(), o); + super.IncRef(o); + } + + void DecRef(long o) throws Z3Exception + { + // Console.WriteLine("AST DecRef()"); + if (Context() == null) + throw new Z3Exception("dec() called on null context"); + if (o == 0) + throw new Z3Exception("dec() called on null AST"); + Context().AST_DRQ().Add(o); + super.DecRef(o); + } + + static AST Create(Context ctx, long obj) throws Z3Exception + { + switch (Z3_ast_kind.fromInt(Native.getAstKind(ctx.nCtx(), obj))) + { + case Z3_FUNC_DECL_AST: + return new FuncDecl(ctx, obj); + case Z3_QUANTIFIER_AST: + return new Quantifier(ctx, obj); + case Z3_SORT_AST: + return Sort.Create(ctx, obj); + case Z3_APP_AST: + case Z3_NUMERAL_AST: + case Z3_VAR_AST: + return Expr.Create(ctx, obj); + default: + throw new Z3Exception("Unknown AST kind"); + } + } +} diff --git a/src/api/java/ASTDecRefQueue.java b/src/api/java/ASTDecRefQueue.java new file mode 100644 index 000000000..f66c54006 --- /dev/null +++ b/src/api/java/ASTDecRefQueue.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2012 Microsoft Corporation + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +public class ASTDecRefQueue extends IDecRefQueue +{ + public void IncRef(Context ctx, long obj) + { + try + { + Native.incRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } + + public void DecRef(Context ctx, long obj) + { + try + { + Native.decRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } +}; diff --git a/src/api/java/ASTMap.java b/src/api/java/ASTMap.java new file mode 100644 index 000000000..c40c4c6b8 --- /dev/null +++ b/src/api/java/ASTMap.java @@ -0,0 +1,124 @@ +/** + * This file was automatically generated from ASTMap.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Map from AST to AST + **/ +class ASTMap extends Z3Object +{ + /** + * Checks whether the map contains the key . An AST + * + * @return True if is a key in the map, false + * otherwise. + **/ + public boolean Contains(AST k) throws Z3Exception + { + + return Native.astMapContains(Context().nCtx(), NativeObject(), + k.NativeObject()); + } + + /** + * Finds the value associated with the key . + * This function signs an error when is not a key in + * the map. An AST + * + * @throws Z3Exception + **/ + public AST Find(AST k) throws Z3Exception + { + return new AST(Context(), Native.astMapFind(Context().nCtx(), + NativeObject(), k.NativeObject())); + } + + /** + * Stores or replaces a new key/value pair in the map. The + * key AST The value AST + **/ + public void Insert(AST k, AST v) throws Z3Exception + { + + Native.astMapInsert(Context().nCtx(), NativeObject(), k.NativeObject(), + v.NativeObject()); + } + + /** + * Erases the key from the map. An + * AST + **/ + public void Erase(AST k) throws Z3Exception + { + + Native.astMapErase(Context().nCtx(), NativeObject(), k.NativeObject()); + } + + /** + * Removes all keys from the map. + **/ + public void Reset() throws Z3Exception + { + Native.astMapReset(Context().nCtx(), NativeObject()); + } + + /** + * The size of the map + **/ + public int Size() throws Z3Exception + { + return Native.astMapSize(Context().nCtx(), NativeObject()); + } + + /** + * The keys stored in the map. + * + * @throws Z3Exception + **/ + public ASTVector Keys() throws Z3Exception + { + return new ASTVector(Context(), Native.astMapKeys(Context().nCtx(), + NativeObject())); + } + + /** + * Retrieves a string representation of the map. + **/ + public String toString() + { + try + { + return Native.astMapToString(Context().nCtx(), NativeObject()); + } catch (Z3Exception e) + { + return "Z3Exception: " + e.getMessage(); + } + } + + ASTMap(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + ASTMap(Context ctx) throws Z3Exception + { + super(ctx, Native.mkAstMap(ctx.nCtx())); + } + + void IncRef(long o) throws Z3Exception + { + Context().ASTMap_DRQ().IncAndClear(Context(), o); + super.IncRef(o); + } + + void DecRef(long o) throws Z3Exception + { + Context().ASTMap_DRQ().Add(o); + super.DecRef(o); + } +} diff --git a/src/api/java/ASTVector.java b/src/api/java/ASTVector.java new file mode 100644 index 000000000..0e9cf1ae7 --- /dev/null +++ b/src/api/java/ASTVector.java @@ -0,0 +1,109 @@ +/** + * This file was automatically generated from ASTVector.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Vectors of ASTs. + **/ +class ASTVector extends Z3Object +{ + /** + * The size of the vector + **/ + public int Size() throws Z3Exception + { + return Native.astVectorSize(Context().nCtx(), NativeObject()); + } + + /** + * Retrieves the i-th object in the vector. May throw an + * IndexOutOfBoundsException when is out of + * range. Index + * + * @return An AST + * @throws Z3Exception + **/ + public AST get(int i) throws Z3Exception + { + return new AST(Context(), Native.astVectorGet(Context().nCtx(), + NativeObject(), i)); + } + + public void set(int i, AST value) throws Z3Exception + { + + Native.astVectorSet(Context().nCtx(), NativeObject(), i, + value.NativeObject()); + } + + /** + * Resize the vector to . The new size of the vector. + **/ + public void Resize(int newSize) throws Z3Exception + { + Native.astVectorResize(Context().nCtx(), NativeObject(), newSize); + } + + /** + * Add the AST to the back of the vector. The size is + * increased by 1. An AST + **/ + public void Push(AST a) throws Z3Exception + { + Native.astVectorPush(Context().nCtx(), NativeObject(), a.NativeObject()); + } + + /** + * Translates all ASTs in the vector to . A context + * + * @return A new ASTVector + * @throws Z3Exception + **/ + public ASTVector Translate(Context ctx) throws Z3Exception + { + return new ASTVector(Context(), Native.astVectorTranslate(Context() + .nCtx(), NativeObject(), ctx.nCtx())); + } + + /** + * Retrieves a string representation of the vector. + **/ + public String toString() + { + try + { + return Native.astVectorToString(Context().nCtx(), NativeObject()); + } catch (Z3Exception e) + { + return "Z3Exception: " + e.getMessage(); + } + } + + ASTVector(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + ASTVector(Context ctx) throws Z3Exception + { + super(ctx, Native.mkAstVector(ctx.nCtx())); + } + + void IncRef(long o) throws Z3Exception + { + Context().ASTVector_DRQ().IncAndClear(Context(), o); + super.IncRef(o); + } + + void DecRef(long o) throws Z3Exception + { + Context().ASTVector_DRQ().Add(o); + super.DecRef(o); + } +} diff --git a/src/api/java/AlgebraicNum.java b/src/api/java/AlgebraicNum.java new file mode 100644 index 000000000..9aee64e65 --- /dev/null +++ b/src/api/java/AlgebraicNum.java @@ -0,0 +1,59 @@ +/** + * This file was automatically generated from AlgebraicNum.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Algebraic numbers + **/ +public class AlgebraicNum extends ArithExpr +{ + /** + * Return a upper bound for a given real algebraic number. The interval + * isolating the number is smaller than 1/10^. + * the + * precision of the result + * + * @return A numeral Expr of sort Real + **/ + public RatNum ToUpper(int precision) throws Z3Exception + { + + return new RatNum(Context(), Native.getAlgebraicNumberUpper(Context() + .nCtx(), NativeObject(), precision)); + } + + /** + * Return a lower bound for the given real algebraic number. The interval + * isolating the number is smaller than 1/10^. + * + * + * @return A numeral Expr of sort Real + **/ + public RatNum ToLower(int precision) throws Z3Exception + { + + return new RatNum(Context(), Native.getAlgebraicNumberLower(Context() + .nCtx(), NativeObject(), precision)); + } + + /** + * Returns a string representation in decimal notation. The result + * has at most decimal places. + **/ + public String ToDecimal(int precision) throws Z3Exception + { + + return Native.getNumeralDecimalString(Context().nCtx(), NativeObject(), + precision); + } + + AlgebraicNum(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + + } +} diff --git a/src/api/java/ApplyResult.java b/src/api/java/ApplyResult.java new file mode 100644 index 000000000..31267b536 --- /dev/null +++ b/src/api/java/ApplyResult.java @@ -0,0 +1,82 @@ +/** + * This file was automatically generated from ApplyResult.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * ApplyResult objects represent the result of an application of a tactic to a + * goal. It contains the subgoals that were produced. + **/ +public class ApplyResult extends Z3Object +{ + /** + * The number of Subgoals. + **/ + public int NumSubgoals() throws Z3Exception + { + return Native.applyResultGetNumSubgoals(Context().nCtx(), + NativeObject()); + } + + /** + * Retrieves the subgoals from the ApplyResult. + * + * @throws Z3Exception + **/ + public Goal[] Subgoals() throws Z3Exception + { + int n = NumSubgoals(); + Goal[] res = new Goal[n]; + for (int i = 0; i < n; i++) + res[i] = new Goal(Context(), Native.applyResultGetSubgoal(Context() + .nCtx(), NativeObject(), i)); + return res; + } + + /** + * Convert a model for the subgoal into a model for the + * original goal g, that the ApplyResult was obtained from. + * + * @return A model for g + * @throws Z3Exception + **/ + public Model ConvertModel(int i, Model m) throws Z3Exception + { + return new Model(Context(), Native.applyResultConvertModel(Context() + .nCtx(), NativeObject(), i, m.NativeObject())); + } + + /** + * A string representation of the ApplyResult. + **/ + public String toString() + { + try + { + return Native.applyResultToString(Context().nCtx(), NativeObject()); + } catch (Z3Exception e) + { + return "Z3Exception: " + e.getMessage(); + } + } + + ApplyResult(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + void IncRef(long o) throws Z3Exception + { + Context().ApplyResult_DRQ().IncAndClear(Context(), o); + super.IncRef(o); + } + + void DecRef(long o) throws Z3Exception + { + Context().ApplyResult_DRQ().Add(o); + super.DecRef(o); + } +} diff --git a/src/api/java/ApplyResultDecRefQueue.java b/src/api/java/ApplyResultDecRefQueue.java new file mode 100644 index 000000000..c459e85aa --- /dev/null +++ b/src/api/java/ApplyResultDecRefQueue.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2012 Microsoft Corporation + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +class ApplyResultDecRefQueue extends IDecRefQueue +{ + public void IncRef(Context ctx, long obj) + { + try + { + Native.applyResultIncRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } + + public void DecRef(Context ctx, long obj) + { + try + { + Native.applyResultDecRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } +}; diff --git a/src/api/java/ArithExpr.java b/src/api/java/ArithExpr.java new file mode 100644 index 000000000..c429f2322 --- /dev/null +++ b/src/api/java/ArithExpr.java @@ -0,0 +1,26 @@ +/** + * This file was automatically generated from ArithExpr.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + * **/ + +package com.microsoft.z3; + +/** + * Arithmetic expressions (int/real) + **/ +public class ArithExpr extends Expr +{ + /** + * Constructor for ArithExpr + **/ + protected ArithExpr(Context ctx) + { + super(ctx); + } + + ArithExpr(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } +} diff --git a/src/api/java/ArithSort.java b/src/api/java/ArithSort.java new file mode 100644 index 000000000..5e1780539 --- /dev/null +++ b/src/api/java/ArithSort.java @@ -0,0 +1,18 @@ +/** + * This file was automatically generated from ArithSort.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * An arithmetic sort, i.e., Int or Real. + **/ +public class ArithSort extends Sort +{ + ArithSort(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } +}; diff --git a/src/api/java/ArrayExpr.java b/src/api/java/ArrayExpr.java new file mode 100644 index 000000000..b3bbb8d75 --- /dev/null +++ b/src/api/java/ArrayExpr.java @@ -0,0 +1,27 @@ +/** + * This file was automatically generated from ArrayExpr.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + + +/** + * Array expressions + **/ +public class ArrayExpr extends Expr +{ + /** + * Constructor for ArrayExpr + **/ + protected ArrayExpr(Context ctx) + { + super(ctx); + } + + ArrayExpr(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } +} diff --git a/src/api/java/ArraySort.java b/src/api/java/ArraySort.java new file mode 100644 index 000000000..cd126443c --- /dev/null +++ b/src/api/java/ArraySort.java @@ -0,0 +1,44 @@ +/** + * This file was automatically generated from ArraySort.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Array sorts. + **/ +public class ArraySort extends Sort +{ + /** + * The domain of the array sort. + * @throws Z3Exception + **/ + public Sort Domain() throws Z3Exception + { + return Sort.Create(Context(), + Native.getArraySortDomain(Context().nCtx(), NativeObject())); + } + + /** + * The range of the array sort. + * @throws Z3Exception + **/ + public Sort Range() throws Z3Exception + { + return Sort.Create(Context(), + Native.getArraySortRange(Context().nCtx(), NativeObject())); + } + + ArraySort(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + ArraySort(Context ctx, Sort domain, Sort range) throws Z3Exception + { + super(ctx, Native.mkArraySort(ctx.nCtx(), domain.NativeObject(), + range.NativeObject())); + } +}; diff --git a/src/api/java/AstMapDecRefQueue.java b/src/api/java/AstMapDecRefQueue.java new file mode 100644 index 000000000..d59074cdb --- /dev/null +++ b/src/api/java/AstMapDecRefQueue.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2012 Microsoft Corporation + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +class ASTMapDecRefQueue extends IDecRefQueue +{ + public void IncRef(Context ctx, long obj) + { + try + { + Native.astMapIncRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } + + public void DecRef(Context ctx, long obj) + { + try + { + Native.astMapDecRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } +}; diff --git a/src/api/java/AstVectorDecRefQueue.java b/src/api/java/AstVectorDecRefQueue.java new file mode 100644 index 000000000..d4b508a54 --- /dev/null +++ b/src/api/java/AstVectorDecRefQueue.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2012 Microsoft Corporation + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +class ASTVectorDecRefQueue extends IDecRefQueue +{ + public void IncRef(Context ctx, long obj) + { + try + { + Native.astVectorIncRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } + + public void DecRef(Context ctx, long obj) + { + try + { + Native.astVectorDecRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } +}; diff --git a/src/api/java/BitVecExpr.java b/src/api/java/BitVecExpr.java new file mode 100644 index 000000000..fb0f4d72a --- /dev/null +++ b/src/api/java/BitVecExpr.java @@ -0,0 +1,36 @@ +/** + * This file was automatically generated from BitVecExpr.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Bit-vector expressions + **/ +public class BitVecExpr extends Expr +{ + + /** + * The size of the sort of a bit-vector term. + * @throws Z3Exception + **/ + public int SortSize() throws Z3Exception + { + return ((BitVecSort) Sort()).Size(); + } + + /** + * Constructor for BitVecExpr + **/ + protected BitVecExpr(Context ctx) + { + super(ctx); + } + + BitVecExpr(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } +} diff --git a/src/api/java/BitVecNum.java b/src/api/java/BitVecNum.java new file mode 100644 index 000000000..3560d5efa --- /dev/null +++ b/src/api/java/BitVecNum.java @@ -0,0 +1,68 @@ +/** + * This file was automatically generated from BitVecNum.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +import java.math.BigInteger; + +/** + * Bit-vector numerals + **/ +public class BitVecNum extends BitVecExpr +{ + /** + * Retrieve the int value. + * + * @throws Z3Exception + **/ + public int Int() throws Z3Exception + { + Native.IntPtr res = new Native.IntPtr(); + if (Native.getNumeralInt(Context().nCtx(), NativeObject(), res) ^ true) + throw new Z3Exception("Numeral is not an int"); + return res.value; + } + + /** + * Retrieve the 64-bit int value. + * + * @throws Z3Exception + **/ + public long Long() throws Z3Exception + { + Native.LongPtr res = new Native.LongPtr(); + if (Native.getNumeralInt64(Context().nCtx(), NativeObject(), res) ^ true) + throw new Z3Exception("Numeral is not an int64"); + return res.value; + } + + /** + * Retrieve the BigInteger value. + **/ + public BigInteger BigInteger() + { + return new BigInteger(this.toString()); + } + + /** + * Returns a string representation of the numeral. + **/ + public String toString() + { + try + { + return Native.getNumeralString(Context().nCtx(), NativeObject()); + } catch (Z3Exception e) + { + return "Z3Exception: " + e.getMessage(); + } + } + + BitVecNum(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } +} diff --git a/src/api/java/BitVecSort.java b/src/api/java/BitVecSort.java new file mode 100644 index 000000000..58781302e --- /dev/null +++ b/src/api/java/BitVecSort.java @@ -0,0 +1,25 @@ +/** + * This file was automatically generated from BitVecSort.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ +package com.microsoft.z3; + +/** + * Bit-vector sorts. + **/ +public class BitVecSort extends Sort +{ + /** + * The size of the bit-vector sort. + **/ + public int Size() throws Z3Exception + { + return Native.getBvSortSize(Context().nCtx(), NativeObject()); + } + + BitVecSort(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } +}; diff --git a/src/api/java/BoolExpr.java b/src/api/java/BoolExpr.java new file mode 100644 index 000000000..40786f76d --- /dev/null +++ b/src/api/java/BoolExpr.java @@ -0,0 +1,30 @@ +/** + * This file was automatically generated from BoolExpr.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Boolean expressions + **/ +public class BoolExpr extends Expr +{ + /** + * Constructor for BoolExpr + **/ + protected BoolExpr(Context ctx) + { + super(ctx); + } + + /** + * Constructor for BoolExpr + * @throws Z3Exception + **/ + BoolExpr(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } +} diff --git a/src/api/java/BoolSort.java b/src/api/java/BoolSort.java new file mode 100644 index 000000000..03711289a --- /dev/null +++ b/src/api/java/BoolSort.java @@ -0,0 +1,16 @@ +/** + * This file was automatically generated from BoolSort.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * A Boolean sort. + **/ +public class BoolSort extends Sort +{ + BoolSort(Context ctx, long obj) throws Z3Exception { super(ctx, obj); { }} + BoolSort(Context ctx) throws Z3Exception { super(ctx, Native.mkBoolSort(ctx.nCtx())); { }} +}; diff --git a/src/api/java/Constructor.java b/src/api/java/Constructor.java new file mode 100644 index 000000000..e267998a0 --- /dev/null +++ b/src/api/java/Constructor.java @@ -0,0 +1,107 @@ +/** + * This file was automatically generated from Constructor.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Constructors are used for datatype sorts. + **/ +public class Constructor extends Z3Object +{ + /** + * The number of fields of the constructor. + * @throws Z3Exception + **/ + public int NumFields() throws Z3Exception + { + init(); + return n; + } + + /** + * The function declaration of the constructor. + * @throws Z3Exception + **/ + public FuncDecl ConstructorDecl() throws Z3Exception + { + init(); + return m_constructorDecl; + } + + /** + * The function declaration of the tester. + * @throws Z3Exception + **/ + public FuncDecl TesterDecl() throws Z3Exception + { + init(); + return m_testerDecl; + } + + /** + * The function declarations of the accessors + * @throws Z3Exception + **/ + public FuncDecl[] AccessorDecls() throws Z3Exception + { + init(); + return m_accessorDecls; + } + + /** + * Destructor. + **/ + protected void finalize() throws Z3Exception + { + Native.delConstructor(Context().nCtx(), NativeObject()); + } + + private int n = 0; + private FuncDecl m_testerDecl = null; + private FuncDecl m_constructorDecl = null; + private FuncDecl[] m_accessorDecls = null; + + Constructor(Context ctx, Symbol name, Symbol recognizer, + Symbol[] fieldNames, Sort[] sorts, int[] sortRefs) + throws Z3Exception + { + super(ctx); + + n = AST.ArrayLength(fieldNames); + + if (n != AST.ArrayLength(sorts)) + throw new Z3Exception( + "Number of field names does not match number of sorts"); + if (sortRefs != null && sortRefs.length != n) + throw new Z3Exception( + "Number of field names does not match number of sort refs"); + + if (sortRefs == null) + sortRefs = new int[n]; + + setNativeObject(Native.mkConstructor(ctx.nCtx(), name.NativeObject(), + recognizer.NativeObject(), n, Symbol.ArrayToNative(fieldNames), + Sort.ArrayToNative(sorts), sortRefs)); + + } + + private void init() throws Z3Exception + { + if (m_testerDecl != null) + return; + Native.LongPtr constructor = new Native.LongPtr(); + Native.LongPtr tester = new Native.LongPtr(); + long[] accessors = new long[n]; + Native.queryConstructor(Context().nCtx(), NativeObject(), n, + constructor, tester, accessors); + m_constructorDecl = new FuncDecl(Context(), constructor.value); + m_testerDecl = new FuncDecl(Context(), tester.value); + m_accessorDecls = new FuncDecl[n]; + for (int i = 0; i < n; i++) + m_accessorDecls[i] = new FuncDecl(Context(), accessors[i]); + } + +} diff --git a/src/api/java/ConstructorList.java b/src/api/java/ConstructorList.java new file mode 100644 index 000000000..87b6bd4fd --- /dev/null +++ b/src/api/java/ConstructorList.java @@ -0,0 +1,35 @@ +/** + * This file was automatically generated from ConstructorList.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Lists of constructors + **/ +public class ConstructorList extends Z3Object +{ + /** + * Destructor. + **/ + protected void finalize() throws Z3Exception + { + Native.delConstructorList(Context().nCtx(), NativeObject()); + } + + ConstructorList(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + ConstructorList(Context ctx, Constructor[] constructors) throws Z3Exception + { + super(ctx); + + setNativeObject(Native.mkConstructorList(Context().nCtx(), + (int) constructors.length, + Constructor.ArrayToNative(constructors))); + } +} diff --git a/src/api/java/Context.java b/src/api/java/Context.java new file mode 100644 index 000000000..d6076b5ee --- /dev/null +++ b/src/api/java/Context.java @@ -0,0 +1,3102 @@ +/** + * This file was automatically generated from Context.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +import java.util.*; +import com.microsoft.z3.enumerations.*; + +/** + * The main interaction with Z3 happens via the Context. + **/ +public class Context extends IDisposable +{ + /** + * Constructor. + **/ + public Context() throws Z3Exception + { + super(); + m_ctx = Native.mkContextRc(0); + InitContext(); + } + + /** + * Constructor. + **/ + public Context(Map settings) throws Z3Exception + { + super(); + long cfg = Native.mkConfig(); + for (Map.Entry kv : settings.entrySet()) + Native.setParamValue(cfg, kv.getKey(), kv.getValue()); + m_ctx = Native.mkContextRc(cfg); + Native.delConfig(cfg); + InitContext(); + } + + private Context(long ctx, long refCount) + { + super(); + this.m_ctx = ctx; + this.m_refCount = refCount; + } + + /** + * Creates a new symbol using an integer. Not all integers can be + * passed to this function. The legal range of unsigned integers is 0 to + * 2^30-1. + **/ + public IntSymbol MkSymbol(int i) throws Z3Exception + { + return new IntSymbol(this, i); + } + + /** + * Create a symbol using a string. + **/ + public StringSymbol MkSymbol(String name) throws Z3Exception + { + return new StringSymbol(this, name); + } + + /** + * Create an array of symbols. + **/ + Symbol[] MkSymbols(String[] names) throws Z3Exception + { + if (names == null) + return null; + Symbol[] result = new Symbol[names.length]; + for (int i = 0; i < names.length; ++i) + result[i] = MkSymbol(names[i]); + return result; + } + + private BoolSort m_boolSort = null; + private IntSort m_intSort = null; + private RealSort m_realSort = null; + + /** + * Retrieves the Boolean sort of the context. + **/ + public BoolSort BoolSort() throws Z3Exception + { + if (m_boolSort == null) + m_boolSort = new BoolSort(this); + return m_boolSort; + } + + /** + * Retrieves the Integer sort of the context. + **/ + public IntSort IntSort() throws Z3Exception + { + if (m_intSort == null) + m_intSort = new IntSort(this); + return m_intSort; + } + + /** + * Retrieves the Real sort of the context. + **/ + public RealSort RealSort() throws Z3Exception + { + if (m_realSort == null) + m_realSort = new RealSort(this); + return m_realSort; + } + + /** + * Create a new Boolean sort. + **/ + public BoolSort MkBoolSort() throws Z3Exception + { + + return new BoolSort(this); + } + + /** + * Create a new uninterpreted sort. + **/ + public UninterpretedSort MkUninterpretedSort(Symbol s) throws Z3Exception + { + + CheckContextMatch(s); + return new UninterpretedSort(this, s); + } + + /** + * Create a new uninterpreted sort. + **/ + public UninterpretedSort MkUninterpretedSort(String str) throws Z3Exception + { + + return MkUninterpretedSort(MkSymbol(str)); + } + + /** + * Create a new integer sort. + **/ + public IntSort MkIntSort() throws Z3Exception + { + + return new IntSort(this); + } + + /** + * Create a real sort. + **/ + public RealSort MkRealSort() throws Z3Exception + { + + return new RealSort(this); + } + + /** + * Create a new bit-vector sort. + **/ + public BitVecSort MkBitVecSort(int size) throws Z3Exception + { + + return new BitVecSort(this, Native.mkBvSort(nCtx(), size)); + } + + /** + * Create a new array sort. + **/ + public ArraySort MkArraySort(Sort domain, Sort range) throws Z3Exception + { + + CheckContextMatch(domain); + CheckContextMatch(range); + return new ArraySort(this, domain, range); + } + + /** + * Create a new tuple sort. + **/ + public TupleSort MkTupleSort(Symbol name, Symbol[] fieldNames, + Sort[] fieldSorts) throws Z3Exception + { + + CheckContextMatch(name); + CheckContextMatch(fieldNames); + CheckContextMatch(fieldSorts); + return new TupleSort(this, name, (int) fieldNames.length, fieldNames, + fieldSorts); + } + + /** + * Create a new enumeration sort. + **/ + public EnumSort MkEnumSort(Symbol name, Symbol[] enumNames) + throws Z3Exception + { + + CheckContextMatch(name); + CheckContextMatch(enumNames); + return new EnumSort(this, name, enumNames); + } + + /** + * Create a new enumeration sort. + **/ + public EnumSort MkEnumSort(String name, String[] enumNames) + throws Z3Exception + { + + return new EnumSort(this, MkSymbol(name), MkSymbols(enumNames)); + } + + /** + * Create a new list sort. + **/ + public ListSort MkListSort(Symbol name, Sort elemSort) throws Z3Exception + { + + CheckContextMatch(name); + CheckContextMatch(elemSort); + return new ListSort(this, name, elemSort); + } + + /** + * Create a new list sort. + **/ + public ListSort MkListSort(String name, Sort elemSort) throws Z3Exception + { + + CheckContextMatch(elemSort); + return new ListSort(this, MkSymbol(name), elemSort); + } + + /** + * Create a new finite domain sort. + **/ + public FiniteDomainSort MkFiniteDomainSort(Symbol name, long size) + throws Z3Exception + { + + CheckContextMatch(name); + return new FiniteDomainSort(this, name, size); + } + + /** + * Create a new finite domain sort. + **/ + public FiniteDomainSort MkFiniteDomainSort(String name, long size) + throws Z3Exception + { + + return new FiniteDomainSort(this, MkSymbol(name), size); + } + + /** + * Create a datatype constructor. constructor + * name name of recognizer + * function. names of the constructor + * fields. field sorts, 0 if the field sort + * refers to a recursive sort. reference to + * datatype sort that is an argument to the constructor; if the + * corresponding sort reference is 0, then the value in sort_refs should be + * an index referring to one of the recursive datatypes that is + * declared. + **/ + public Constructor MkConstructor(Symbol name, Symbol recognizer, + Symbol[] fieldNames, Sort[] sorts, int[] sortRefs) + throws Z3Exception + { + + return new Constructor(this, name, recognizer, fieldNames, sorts, + sortRefs); + } + + /** + * Create a datatype constructor. + * + * @return + **/ + public Constructor MkConstructor(String name, String recognizer, + String[] fieldNames, Sort[] sorts, int[] sortRefs) + throws Z3Exception + { + + return new Constructor(this, MkSymbol(name), MkSymbol(recognizer), + MkSymbols(fieldNames), sorts, sortRefs); + } + + /** + * Create a new datatype sort. + **/ + public DatatypeSort MkDatatypeSort(Symbol name, Constructor[] constructors) + throws Z3Exception + { + + CheckContextMatch(name); + CheckContextMatch(constructors); + return new DatatypeSort(this, name, constructors); + } + + /** + * Create a new datatype sort. + **/ + public DatatypeSort MkDatatypeSort(String name, Constructor[] constructors) + throws Z3Exception + { + + CheckContextMatch(constructors); + return new DatatypeSort(this, MkSymbol(name), constructors); + } + + /** + * Create mutually recursive datatypes. names of + * datatype sorts list of constructors, one list per + * sort. + **/ + public DatatypeSort[] MkDatatypeSorts(Symbol[] names, Constructor[][] c) + throws Z3Exception + { + + CheckContextMatch(names); + int n = (int) names.length; + ConstructorList[] cla = new ConstructorList[n]; + long[] n_constr = new long[n]; + for (int i = 0; i < n; i++) + { + Constructor[] constructor = c[i]; + + CheckContextMatch(constructor); + cla[i] = new ConstructorList(this, constructor); + n_constr[i] = cla[i].NativeObject(); + } + long[] n_res = new long[n]; + Native.mkDatatypes(nCtx(), n, Symbol.ArrayToNative(names), n_res, + n_constr); + DatatypeSort[] res = new DatatypeSort[n]; + for (int i = 0; i < n; i++) + res[i] = new DatatypeSort(this, n_res[i]); + return res; + } + + /** + * Create mutually recursive data-types. + * + * @return + **/ + public DatatypeSort[] MkDatatypeSorts(String[] names, Constructor[][] c) + throws Z3Exception + { + + return MkDatatypeSorts(MkSymbols(names), c); + } + + /** + * Creates a new function declaration. + **/ + public FuncDecl MkFuncDecl(Symbol name, Sort[] domain, Sort range) + throws Z3Exception + { + + CheckContextMatch(name); + CheckContextMatch(domain); + CheckContextMatch(range); + return new FuncDecl(this, name, domain, range); + } + + /** + * Creates a new function declaration. + **/ + public FuncDecl MkFuncDecl(Symbol name, Sort domain, Sort range) + throws Z3Exception + { + + CheckContextMatch(name); + CheckContextMatch(domain); + CheckContextMatch(range); + Sort[] q = new Sort[] { domain }; + return new FuncDecl(this, name, q, range); + } + + /** + * Creates a new function declaration. + **/ + public FuncDecl MkFuncDecl(String name, Sort[] domain, Sort range) + throws Z3Exception + { + + CheckContextMatch(domain); + CheckContextMatch(range); + return new FuncDecl(this, MkSymbol(name), domain, range); + } + + /** + * Creates a new function declaration. + **/ + public FuncDecl MkFuncDecl(String name, Sort domain, Sort range) + throws Z3Exception + { + + CheckContextMatch(domain); + CheckContextMatch(range); + Sort[] q = new Sort[] { domain }; + return new FuncDecl(this, MkSymbol(name), q, range); + } + + /** + * Creates a fresh function declaration with a name prefixed with . + **/ + public FuncDecl MkFreshFuncDecl(String prefix, Sort[] domain, Sort range) + throws Z3Exception + { + + CheckContextMatch(domain); + CheckContextMatch(range); + return new FuncDecl(this, prefix, domain, range); + } + + /** + * Creates a new constant function declaration. + **/ + public FuncDecl MkConstDecl(Symbol name, Sort range) throws Z3Exception + { + + CheckContextMatch(name); + CheckContextMatch(range); + return new FuncDecl(this, name, null, range); + } + + /** + * Creates a new constant function declaration. + **/ + public FuncDecl MkConstDecl(String name, Sort range) throws Z3Exception + { + + CheckContextMatch(range); + return new FuncDecl(this, MkSymbol(name), null, range); + } + + /** + * Creates a fresh constant function declaration with a name prefixed with + * . + * + **/ + public FuncDecl MkFreshConstDecl(String prefix, Sort range) + throws Z3Exception + { + + CheckContextMatch(range); + return new FuncDecl(this, prefix, null, range); + } + + /** + * Creates a new bound variable. The de-Bruijn index of + * the variable The sort of the variable + **/ + public Expr MkBound(int index, Sort ty) throws Z3Exception + { + return Expr.Create(this, + Native.mkBound(nCtx(), index, ty.NativeObject())); + } + + /** + * Create a quantifier pattern. + **/ + public Pattern MkPattern(Expr[] terms) throws Z3Exception + { + if (terms.length == 0) + throw new Z3Exception("Cannot create a pattern from zero terms"); + + long[] termsNative = AST.ArrayToNative(terms); + return new Pattern(this, Native.mkPattern(nCtx(), (int) terms.length, + termsNative)); + } + + /** + * Creates a new Constant of sort and named + * . + **/ + public Expr MkConst(Symbol name, Sort range) throws Z3Exception + { + + CheckContextMatch(name); + CheckContextMatch(range); + + return Expr.Create( + this, + Native.mkConst(nCtx(), name.NativeObject(), + range.NativeObject())); + } + + /** + * Creates a new Constant of sort and named + * . + **/ + public Expr MkConst(String name, Sort range) throws Z3Exception + { + + return MkConst(MkSymbol(name), range); + } + + /** + * Creates a fresh Constant of sort and a name + * prefixed with . + **/ + public Expr MkFreshConst(String prefix, Sort range) throws Z3Exception + { + + CheckContextMatch(range); + return Expr.Create(this, + Native.mkFreshConst(nCtx(), prefix, range.NativeObject())); + } + + /** + * Creates a fresh constant from the FuncDecl . A decl of a 0-arity function + **/ + public Expr MkConst(FuncDecl f) throws Z3Exception + { + + return MkApp(f, (Expr[]) null); + } + + /** + * Create a Boolean constant. + **/ + public BoolExpr MkBoolConst(Symbol name) throws Z3Exception + { + + return (BoolExpr) MkConst(name, BoolSort()); + } + + /** + * Create a Boolean constant. + **/ + public BoolExpr MkBoolConst(String name) throws Z3Exception + { + + return (BoolExpr) MkConst(MkSymbol(name), BoolSort()); + } + + /** + * Creates an integer constant. + **/ + public IntExpr MkIntConst(Symbol name) throws Z3Exception + { + + return (IntExpr) MkConst(name, IntSort()); + } + + /** + * Creates an integer constant. + **/ + public IntExpr MkIntConst(String name) throws Z3Exception + { + + return (IntExpr) MkConst(name, IntSort()); + } + + /** + * Creates a real constant. + **/ + public RealExpr MkRealConst(Symbol name) throws Z3Exception + { + + return (RealExpr) MkConst(name, RealSort()); + } + + /** + * Creates a real constant. + **/ + public RealExpr MkRealConst(String name) throws Z3Exception + { + + return (RealExpr) MkConst(name, RealSort()); + } + + /** + * Creates a bit-vector constant. + **/ + public BitVecExpr MkBVConst(Symbol name, int size) throws Z3Exception + { + + return (BitVecExpr) MkConst(name, MkBitVecSort(size)); + } + + /** + * Creates a bit-vector constant. + **/ + public BitVecExpr MkBVConst(String name, int size) throws Z3Exception + { + + return (BitVecExpr) MkConst(name, MkBitVecSort(size)); + } + + /** + * Create a new function application. + **/ + public Expr MkApp(FuncDecl f, Expr arg) throws Z3Exception + { + CheckContextMatch(f); + CheckContextMatch(arg); + Expr[] args = { arg }; + return Expr.Create(this, f, args); + } + + /** + * Create a new function application. + **/ + public Expr MkApp(FuncDecl f, Expr[] args) throws Z3Exception + { + + CheckContextMatch(f); + CheckContextMatch(args); + return Expr.Create(this, f, args); + } + + /** + * The true Term. + **/ + public BoolExpr MkTrue() throws Z3Exception + { + return new BoolExpr(this, Native.mkTrue(nCtx())); + } + + /** + * The false Term. + **/ + public BoolExpr MkFalse() throws Z3Exception + { + return new BoolExpr(this, Native.mkFalse(nCtx())); + } + + /** + * Creates a Boolean value. + **/ + public BoolExpr MkBool(boolean value) throws Z3Exception + { + return value ? MkTrue() : MkFalse(); + } + + /** + * Creates the equality = . + **/ + public BoolExpr MkEq(Expr x, Expr y) throws Z3Exception + { + CheckContextMatch(x); + CheckContextMatch(y); + return new BoolExpr(this, Native.mkEq(nCtx(), x.NativeObject(), + y.NativeObject())); + } + + /** + * Creates a distinct term. + **/ + public BoolExpr MkDistinct(Expr[] args) throws Z3Exception + { + CheckContextMatch(args); + return new BoolExpr(this, Native.mkDistinct(nCtx(), (int) args.length, + AST.ArrayToNative(args))); + } + + /** + * Mk an expression representing not(a). + **/ + public BoolExpr MkNot(BoolExpr a) throws Z3Exception + { + + CheckContextMatch(a); + return new BoolExpr(this, Native.mkNot(nCtx(), a.NativeObject())); + } + + /** + * Create an expression representing an if-then-else: + * ite(t1, t2, t3). An expression with Boolean + * sort An expression An + * expression with the same sort as + **/ + public Expr MkITE(BoolExpr t1, Expr t2, Expr t3) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + CheckContextMatch(t3); + return Expr.Create( + this, + Native.mkIte(nCtx(), t1.NativeObject(), t2.NativeObject(), + t3.NativeObject())); + } + + /** + * Create an expression representing t1 iff t2. + **/ + public BoolExpr MkIff(BoolExpr t1, BoolExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.mkIff(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Create an expression representing t1 -> t2. + **/ + public BoolExpr MkImplies(BoolExpr t1, BoolExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.mkImplies(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Create an expression representing t1 xor t2. + **/ + public BoolExpr MkXor(BoolExpr t1, BoolExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.mkXor(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Create an expression representing t[0] and t[1] and .... + **/ + public BoolExpr MkAnd(BoolExpr[] t) throws Z3Exception + { + + CheckContextMatch(t); + return new BoolExpr(this, Native.mkAnd(nCtx(), (int) t.length, + AST.ArrayToNative(t))); + } + + /** + * Create an expression representing t[0] or t[1] or .... + **/ + public BoolExpr MkOr(BoolExpr[] t) throws Z3Exception + { + + CheckContextMatch(t); + return new BoolExpr(this, Native.mkOr(nCtx(), (int) t.length, + AST.ArrayToNative(t))); + } + + /** + * Create an expression representing t[0] + t[1] + .... + **/ + public ArithExpr MkAdd(ArithExpr[] t) throws Z3Exception + { + + CheckContextMatch(t); + return (ArithExpr) Expr.Create(this, + Native.mkAdd(nCtx(), (int) t.length, AST.ArrayToNative(t))); + } + + /** + * Create an expression representing t[0] * t[1] * .... + **/ + public ArithExpr MkMul(ArithExpr[] t) throws Z3Exception + { + + CheckContextMatch(t); + return (ArithExpr) Expr.Create(this, + Native.mkMul(nCtx(), (int) t.length, AST.ArrayToNative(t))); + } + + /** + * Create an expression representing t[0] - t[1] - .... + **/ + public ArithExpr MkSub(ArithExpr[] t) throws Z3Exception + { + + CheckContextMatch(t); + return (ArithExpr) Expr.Create(this, + Native.mkSub(nCtx(), (int) t.length, AST.ArrayToNative(t))); + } + + /** + * Create an expression representing -t. + **/ + public ArithExpr MkUnaryMinus(ArithExpr t) throws Z3Exception + { + + CheckContextMatch(t); + return (ArithExpr) Expr.Create(this, + Native.mkUnaryMinus(nCtx(), t.NativeObject())); + } + + /** + * Create an expression representing t1 / t2. + **/ + public ArithExpr MkDiv(ArithExpr t1, ArithExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return (ArithExpr) Expr.Create(this, + Native.mkDiv(nCtx(), t1.NativeObject(), t2.NativeObject())); + } + + /** + * Create an expression representing t1 mod t2. The + * arguments must have int type. + **/ + public IntExpr MkMod(IntExpr t1, IntExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new IntExpr(this, Native.mkMod(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Create an expression representing t1 rem t2. The + * arguments must have int type. + **/ + public IntExpr MkRem(IntExpr t1, IntExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new IntExpr(this, Native.mkRem(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Create an expression representing t1 ^ t2. + **/ + public ArithExpr MkPower(ArithExpr t1, ArithExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return (ArithExpr) Expr.Create(this, + Native.mkPower(nCtx(), t1.NativeObject(), t2.NativeObject())); + } + + /** + * Create an expression representing t1 < t2 + **/ + public BoolExpr MkLt(ArithExpr t1, ArithExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.mkLt(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Create an expression representing t1 <= t2 + **/ + public BoolExpr MkLe(ArithExpr t1, ArithExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.mkLe(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Create an expression representing t1 > t2 + **/ + public BoolExpr MkGt(ArithExpr t1, ArithExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.mkGt(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Create an expression representing t1 >= t2 + **/ + public BoolExpr MkGe(ArithExpr t1, ArithExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.mkGe(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Coerce an integer to a real. There is also a converse operation + * exposed. It follows the semantics prescribed by the SMT-LIB standard. + * + * You can take the floor of a real by creating an auxiliary integer Term + * k and and asserting + * MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. The argument + * must be of integer sort. + **/ + public RealExpr MkInt2Real(IntExpr t) throws Z3Exception + { + + CheckContextMatch(t); + return new RealExpr(this, Native.mkInt2real(nCtx(), t.NativeObject())); + } + + /** + * Coerce a real to an integer. The semantics of this function + * follows the SMT-LIB standard for the function to_int. The argument must + * be of real sort. + **/ + public IntExpr MkReal2Int(RealExpr t) throws Z3Exception + { + + CheckContextMatch(t); + return new IntExpr(this, Native.mkReal2int(nCtx(), t.NativeObject())); + } + + /** + * Creates an expression that checks whether a real number is an integer. + **/ + public BoolExpr MkIsInteger(RealExpr t) throws Z3Exception + { + + CheckContextMatch(t); + return new BoolExpr(this, Native.mkIsInt(nCtx(), t.NativeObject())); + } + + /** + * Bitwise negation. The argument must have a bit-vector + * sort. + **/ + public BitVecExpr MkBVNot(BitVecExpr t) throws Z3Exception + { + + CheckContextMatch(t); + return new BitVecExpr(this, Native.mkBvnot(nCtx(), t.NativeObject())); + } + + /** + * Take conjunction of bits in a vector, return vector of length 1. + * The argument must have a bit-vector sort. + **/ + public BitVecExpr MkBVRedAND(BitVecExpr t) throws Z3Exception + { + + CheckContextMatch(t); + return new BitVecExpr(this, Native.mkBvredand(nCtx(), t.NativeObject())); + } + + /** + * Take disjunction of bits in a vector, return vector of length 1. + * The argument must have a bit-vector sort. + **/ + public BitVecExpr MkBVRedOR(BitVecExpr t) throws Z3Exception + { + + CheckContextMatch(t); + return new BitVecExpr(this, Native.mkBvredor(nCtx(), t.NativeObject())); + } + + /** + * Bitwise conjunction. The arguments must have a bit-vector + * sort. + **/ + public BitVecExpr MkBVAND(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.mkBvand(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Bitwise disjunction. The arguments must have a bit-vector + * sort. + **/ + public BitVecExpr MkBVOR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.mkBvor(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Bitwise XOR. The arguments must have a bit-vector + * sort. + **/ + public BitVecExpr MkBVXOR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.mkBvxor(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Bitwise NAND. The arguments must have a bit-vector + * sort. + **/ + public BitVecExpr MkBVNAND(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.mkBvnand(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Bitwise NOR. The arguments must have a bit-vector + * sort. + **/ + public BitVecExpr MkBVNOR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.mkBvnor(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Bitwise XNOR. The arguments must have a bit-vector + * sort. + **/ + public BitVecExpr MkBVXNOR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.mkBvxnor(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Standard two's complement unary minus. The arguments must have a + * bit-vector sort. + **/ + public BitVecExpr MkBVNeg(BitVecExpr t) throws Z3Exception + { + + CheckContextMatch(t); + return new BitVecExpr(this, Native.mkBvneg(nCtx(), t.NativeObject())); + } + + /** + * Two's complement addition. The arguments must have the same + * bit-vector sort. + **/ + public BitVecExpr MkBVAdd(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.mkBvadd(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Two's complement subtraction. The arguments must have the same + * bit-vector sort. + **/ + public BitVecExpr MkBVSub(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.mkBvsub(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Two's complement multiplication. The arguments must have the + * same bit-vector sort. + **/ + public BitVecExpr MkBVMul(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.mkBvmul(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Unsigned division. It is defined as the floor of + * t1/t2 if \c t2 is different from zero. If t2 is + * zero, then the result is undefined. The arguments must have the same + * bit-vector sort. + **/ + public BitVecExpr MkBVUDiv(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.mkBvudiv(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Signed division. It is defined in the following way: + * + * - The \c floor of t1/t2 if \c t2 is different from zero, and + * t1*t2 >= 0. + * + * - The \c ceiling of t1/t2 if \c t2 is different from zero, + * and t1*t2 < 0. + * + * If t2 is zero, then the result is undefined. The arguments + * must have the same bit-vector sort. + **/ + public BitVecExpr MkBVSDiv(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.mkBvsdiv(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Unsigned remainder. It is defined as + * t1 - (t1 /u t2) * t2, where /u represents + * unsigned division. If t2 is zero, then the result is + * undefined. The arguments must have the same bit-vector sort. + **/ + public BitVecExpr MkBVURem(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.mkBvurem(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Signed remainder. It is defined as + * t1 - (t1 /s t2) * t2, where /s represents + * signed division. The most significant bit (sign) of the result is equal + * to the most significant bit of \c t1. + * + * If t2 is zero, then the result is undefined. The arguments + * must have the same bit-vector sort. + **/ + public BitVecExpr MkBVSRem(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.mkBvsrem(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Two's complement signed remainder (sign follows divisor). If + * t2 is zero, then the result is undefined. The arguments must + * have the same bit-vector sort. + **/ + public BitVecExpr MkBVSMod(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.mkBvsmod(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Unsigned less-than The arguments must have the same bit-vector + * sort. + **/ + public BoolExpr MkBVULT(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.mkBvult(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Two's complement signed less-than The arguments must have the + * same bit-vector sort. + **/ + public BoolExpr MkBVSLT(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.mkBvslt(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Unsigned less-than or equal to. The arguments must have the + * same bit-vector sort. + **/ + public BoolExpr MkBVULE(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.mkBvule(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Two's complement signed less-than or equal to. The arguments + * must have the same bit-vector sort. + **/ + public BoolExpr MkBVSLE(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.mkBvsle(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Unsigned greater than or equal to. The arguments must have the + * same bit-vector sort. + **/ + public BoolExpr MkBVUGE(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.mkBvuge(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Two's complement signed greater than or equal to. The arguments + * must have the same bit-vector sort. + **/ + public BoolExpr MkBVSGE(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.mkBvsge(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Unsigned greater-than. The arguments must have the same + * bit-vector sort. + **/ + public BoolExpr MkBVUGT(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.mkBvugt(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Two's complement signed greater-than. The arguments must have + * the same bit-vector sort. + **/ + public BoolExpr MkBVSGT(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.mkBvsgt(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Bit-vector concatenation. The arguments must have a bit-vector + * sort. + * + * @return The result is a bit-vector of size n1+n2, where + * n1 (n2) is the size of t1 + * (t2). + * + **/ + public BitVecExpr MkConcat(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.mkConcat(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Bit-vector extraction. Extract the bits + * down to from a bitvector of size m to + * yield a new bitvector of size n, where + * n = high - low + 1. The argument must + * have a bit-vector sort. + **/ + public BitVecExpr MkExtract(int high, int low, BitVecExpr t) + throws Z3Exception + { + + CheckContextMatch(t); + return new BitVecExpr(this, Native.mkExtract(nCtx(), high, low, + t.NativeObject())); + } + + /** + * Bit-vector sign extension. Sign-extends the given bit-vector to + * the (signed) equivalent bitvector of size m+i, where \c m is + * the size of the given bit-vector. The argument must + * have a bit-vector sort. + **/ + public BitVecExpr MkSignExt(int i, BitVecExpr t) throws Z3Exception + { + + CheckContextMatch(t); + return new BitVecExpr(this, Native.mkSignExt(nCtx(), i, + t.NativeObject())); + } + + /** + * Bit-vector zero extension. Extend the given bit-vector with + * zeros to the (unsigned) equivalent bitvector of size m+i, + * where \c m is the size of the given bit-vector. The argument must have a bit-vector sort. + **/ + public BitVecExpr MkZeroExt(int i, BitVecExpr t) throws Z3Exception + { + + CheckContextMatch(t); + return new BitVecExpr(this, Native.mkZeroExt(nCtx(), i, + t.NativeObject())); + } + + /** + * Bit-vector repetition. The argument must + * have a bit-vector sort. + **/ + public BitVecExpr MkRepeat(int i, BitVecExpr t) throws Z3Exception + { + + CheckContextMatch(t); + return new BitVecExpr(this, + Native.mkRepeat(nCtx(), i, t.NativeObject())); + } + + /** + * Shift left. It is equivalent to multiplication by + * 2^x where \c x is the value of . + * + * NB. The semantics of shift operations varies between environments. This + * definition does not necessarily capture directly the semantics of the + * programming language or assembly architecture you are modeling. + * + * The arguments must have a bit-vector sort. + **/ + public BitVecExpr MkBVSHL(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.mkBvshl(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Logical shift right It is equivalent to unsigned division by + * 2^x where \c x is the value of . + * + * NB. The semantics of shift operations varies between environments. This + * definition does not necessarily capture directly the semantics of the + * programming language or assembly architecture you are modeling. + * + * The arguments must have a bit-vector sort. + **/ + public BitVecExpr MkBVLSHR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.mkBvlshr(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Arithmetic shift right It is like logical shift right except + * that the most significant bits of the result always copy the most + * significant bit of the second argument. + * + * NB. The semantics of shift operations varies between environments. This + * definition does not necessarily capture directly the semantics of the + * programming language or assembly architecture you are modeling. + * + * The arguments must have a bit-vector sort. + **/ + public BitVecExpr MkBVASHR(BitVecExpr t1, BitVecExpr t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.mkBvashr(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Rotate Left. Rotate bits of \c t to the left \c i times. The + * argument must have a bit-vector sort. + **/ + public BitVecExpr MkBVRotateLeft(int i, BitVecExpr t) throws Z3Exception + { + + CheckContextMatch(t); + return new BitVecExpr(this, Native.mkRotateLeft(nCtx(), i, + t.NativeObject())); + } + + /** + * Rotate Right. Rotate bits of \c t to the right \c i times. The + * argument must have a bit-vector sort. + **/ + public BitVecExpr MkBVRotateRight(int i, BitVecExpr t) throws Z3Exception + { + + CheckContextMatch(t); + return new BitVecExpr(this, Native.mkRotateRight(nCtx(), i, + t.NativeObject())); + } + + /** + * Rotate Left. Rotate bits of to the left + * times. The arguments must have the same bit-vector + * sort. + **/ + public BitVecExpr MkBVRotateLeft(BitVecExpr t1, BitVecExpr t2) + throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.mkExtRotateLeft(nCtx(), + t1.NativeObject(), t2.NativeObject())); + } + + /** + * Rotate Right. Rotate bits of to the + * right times. The arguments must have the same + * bit-vector sort. + **/ + public BitVecExpr MkBVRotateRight(BitVecExpr t1, BitVecExpr t2) + throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BitVecExpr(this, Native.mkExtRotateRight(nCtx(), + t1.NativeObject(), t2.NativeObject())); + } + + /** + * Create an bit bit-vector from the integer argument + * . NB. This function is essentially treated + * as uninterpreted. So you cannot expect Z3 to precisely reflect the + * semantics of this function when solving constraints with this function. + * + * The argument must be of integer sort. + **/ + public BitVecExpr MkInt2BV(int n, IntExpr t) throws Z3Exception + { + + CheckContextMatch(t); + return new BitVecExpr(this, + Native.mkInt2bv(nCtx(), n, t.NativeObject())); + } + + /** + * Create an integer from the bit-vector argument . + * If \c is_signed is false, then the bit-vector \c t1 is treated + * as unsigned. So the result is non-negative and in the range + * [0..2^N-1], where N are the number of bits in . If \c is_signed is true, \c t1 is treated as a signed + * bit-vector. + * + * NB. This function is essentially treated as uninterpreted. So you cannot + * expect Z3 to precisely reflect the semantics of this function when + * solving constraints with this function. + * + * The argument must be of bit-vector sort. + **/ + public IntExpr MkBV2Int(BitVecExpr t, boolean signed) throws Z3Exception + { + + CheckContextMatch(t); + return new IntExpr(this, Native.mkBv2int(nCtx(), t.NativeObject(), + (signed) ? true : false)); + } + + /** + * Create a predicate that checks that the bit-wise addition does not + * overflow. The arguments must be of bit-vector sort. + **/ + public BoolExpr MkBVAddNoOverflow(BitVecExpr t1, BitVecExpr t2, + boolean isSigned) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, + Native.mkBvaddNoOverflow(nCtx(), t1.NativeObject(), + t2.NativeObject(), (isSigned) ? true : false)); + } + + /** + * Create a predicate that checks that the bit-wise addition does not + * underflow. The arguments must be of bit-vector sort. + **/ + public BoolExpr MkBVAddNoUnderflow(BitVecExpr t1, BitVecExpr t2) + throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.mkBvaddNoUnderflow(nCtx(), + t1.NativeObject(), t2.NativeObject())); + } + + /** + * Create a predicate that checks that the bit-wise subtraction does not + * overflow. The arguments must be of bit-vector sort. + **/ + public BoolExpr MkBVSubNoOverflow(BitVecExpr t1, BitVecExpr t2) + throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.mkBvsubNoOverflow(nCtx(), + t1.NativeObject(), t2.NativeObject())); + } + + /** + * Create a predicate that checks that the bit-wise subtraction does not + * underflow. The arguments must be of bit-vector sort. + **/ + public BoolExpr MkBVSubNoUnderflow(BitVecExpr t1, BitVecExpr t2, + boolean isSigned) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, + Native.mkBvsubNoUnderflow(nCtx(), t1.NativeObject(), + t2.NativeObject(), (isSigned) ? true : false)); + } + + /** + * Create a predicate that checks that the bit-wise signed division does not + * overflow. The arguments must be of bit-vector sort. + **/ + public BoolExpr MkBVSDivNoOverflow(BitVecExpr t1, BitVecExpr t2) + throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.mkBvsdivNoOverflow(nCtx(), + t1.NativeObject(), t2.NativeObject())); + } + + /** + * Create a predicate that checks that the bit-wise negation does not + * overflow. The arguments must be of bit-vector sort. + **/ + public BoolExpr MkBVNegNoOverflow(BitVecExpr t) throws Z3Exception + { + + CheckContextMatch(t); + return new BoolExpr(this, Native.mkBvnegNoOverflow(nCtx(), + t.NativeObject())); + } + + /** + * Create a predicate that checks that the bit-wise multiplication does not + * overflow. The arguments must be of bit-vector sort. + **/ + public BoolExpr MkBVMulNoOverflow(BitVecExpr t1, BitVecExpr t2, + boolean isSigned) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, + Native.mkBvmulNoOverflow(nCtx(), t1.NativeObject(), + t2.NativeObject(), (isSigned) ? true : false)); + } + + /** + * Create a predicate that checks that the bit-wise multiplication does not + * underflow. The arguments must be of bit-vector sort. + **/ + public BoolExpr MkBVMulNoUnderflow(BitVecExpr t1, BitVecExpr t2) + throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new BoolExpr(this, Native.mkBvmulNoUnderflow(nCtx(), + t1.NativeObject(), t2.NativeObject())); + } + + /** + * Create an array constant. + **/ + public ArrayExpr MkArrayConst(Symbol name, Sort domain, Sort range) + throws Z3Exception + { + + return (ArrayExpr) MkConst(name, MkArraySort(domain, range)); + } + + /** + * Create an array constant. + **/ + public ArrayExpr MkArrayConst(String name, Sort domain, Sort range) + throws Z3Exception + { + + return (ArrayExpr) MkConst(MkSymbol(name), MkArraySort(domain, range)); + } + + /** + * Array read. The argument a is the array and + * i is the index of the array that gets read. + * + * The node a must have an array sort + * [domain -> range], and i must have the sort + * domain. The sort of the result is range. + * + **/ + public Expr MkSelect(ArrayExpr a, Expr i) throws Z3Exception + { + + CheckContextMatch(a); + CheckContextMatch(i); + return Expr.Create(this, + Native.mkSelect(nCtx(), a.NativeObject(), i.NativeObject())); + } + + /** + * Array update. The node a must have an array sort + * [domain -> range], i must have sort + * domain, v must have sort range. The sort of the + * result is [domain -> range]. The semantics of this function + * is given by the theory of arrays described in the SMT-LIB standard. See + * http://smtlib.org for more details. The result of this function is an + * array that is equal to a (with respect to + * select) on all indices except for i, where it + * maps to v (and the select of a + * with respect to i may be a different value). + **/ + public ArrayExpr MkStore(ArrayExpr a, Expr i, Expr v) throws Z3Exception + { + + CheckContextMatch(a); + CheckContextMatch(i); + CheckContextMatch(v); + return new ArrayExpr(this, Native.mkStore(nCtx(), a.NativeObject(), + i.NativeObject(), v.NativeObject())); + } + + /** + * Create a constant array. The resulting term is an array, such + * that a selecton an arbitrary index produces the value + * v. + * + **/ + public ArrayExpr MkConstArray(Sort domain, Expr v) throws Z3Exception + { + + CheckContextMatch(domain); + CheckContextMatch(v); + return new ArrayExpr(this, Native.mkConstArray(nCtx(), + domain.NativeObject(), v.NativeObject())); + } + + /** + * Maps f on the argument arrays. Eeach element of + * args must be of an array sort + * [domain_i -> range_i]. The function declaration + * f must have type range_1 .. range_n -> range. + * v must have sort range. The sort of the result is + * [domain_i -> range]. + **/ + public ArrayExpr MkMap(FuncDecl f, ArrayExpr[] args) throws Z3Exception + { + + CheckContextMatch(f); + CheckContextMatch(args); + return (ArrayExpr) Expr.Create(this, Native.mkMap(nCtx(), + f.NativeObject(), AST.ArrayLength(args), + AST.ArrayToNative(args))); + } + + /** + * Access the array default value. Produces the default range + * value, for arrays that can be represented as finite maps with a default + * range value. + **/ + public Expr MkTermArray(ArrayExpr array) throws Z3Exception + { + + CheckContextMatch(array); + return Expr.Create(this, + Native.mkArrayDefault(nCtx(), array.NativeObject())); + } + + /** + * Create a set type. + **/ + public SetSort MkSetSort(Sort ty) throws Z3Exception + { + + CheckContextMatch(ty); + return new SetSort(this, ty); + } + + /** + * Create an empty set. + **/ + public Expr MkEmptySet(Sort domain) throws Z3Exception + { + + CheckContextMatch(domain); + return Expr.Create(this, + Native.mkEmptySet(nCtx(), domain.NativeObject())); + } + + /** + * Create the full set. + **/ + public Expr MkFullSet(Sort domain) throws Z3Exception + { + + CheckContextMatch(domain); + return Expr.Create(this, + Native.mkFullSet(nCtx(), domain.NativeObject())); + } + + /** + * Add an element to the set. + **/ + public Expr MkSetAdd(Expr set, Expr element) throws Z3Exception + { + + CheckContextMatch(set); + CheckContextMatch(element); + return Expr.Create( + this, + Native.mkSetAdd(nCtx(), set.NativeObject(), + element.NativeObject())); + } + + /** + * Remove an element from a set. + **/ + public Expr MkSetDel(Expr set, Expr element) throws Z3Exception + { + + CheckContextMatch(set); + CheckContextMatch(element); + return Expr.Create( + this, + Native.mkSetDel(nCtx(), set.NativeObject(), + element.NativeObject())); + } + + /** + * Take the union of a list of sets. + **/ + public Expr MkSetUnion(Expr[] args) throws Z3Exception + { + + CheckContextMatch(args); + return Expr.Create( + this, + Native.mkSetUnion(nCtx(), (int) args.length, + AST.ArrayToNative(args))); + } + + /** + * Take the intersection of a list of sets. + **/ + public Expr MkSetIntersection(Expr[] args) throws Z3Exception + { + + CheckContextMatch(args); + return Expr.Create( + this, + Native.mkSetIntersect(nCtx(), (int) args.length, + AST.ArrayToNative(args))); + } + + /** + * Take the difference between two sets. + **/ + public Expr MkSetDifference(Expr arg1, Expr arg2) throws Z3Exception + { + + CheckContextMatch(arg1); + CheckContextMatch(arg2); + return Expr.Create( + this, + Native.mkSetDifference(nCtx(), arg1.NativeObject(), + arg2.NativeObject())); + } + + /** + * Take the complement of a set. + **/ + public Expr MkSetComplement(Expr arg) throws Z3Exception + { + + CheckContextMatch(arg); + return Expr.Create(this, + Native.mkSetComplement(nCtx(), arg.NativeObject())); + } + + /** + * Check for set membership. + **/ + public Expr MkSetMembership(Expr elem, Expr set) throws Z3Exception + { + + CheckContextMatch(elem); + CheckContextMatch(set); + return Expr.Create( + this, + Native.mkSetMember(nCtx(), elem.NativeObject(), + set.NativeObject())); + } + + /** + * Check for subsetness of sets. + **/ + public Expr MkSetSubset(Expr arg1, Expr arg2) throws Z3Exception + { + + CheckContextMatch(arg1); + CheckContextMatch(arg2); + return Expr.Create( + this, + Native.mkSetSubset(nCtx(), arg1.NativeObject(), + arg2.NativeObject())); + } + + /** + * Create a Term of a given sort. A string representing the + * Term value in decimal notation. If the given sort is a real, then the + * Term can be a rational, that is, a string of the form + * [num]* / [num]*. The sort of the + * numeral. In the current implementation, the given sort can be an int, + * real, or bit-vectors of arbitrary size. + * + * @return A Term with value and sort + **/ + public Expr MkNumeral(String v, Sort ty) throws Z3Exception + { + + CheckContextMatch(ty); + return Expr + .Create(this, Native.mkNumeral(nCtx(), v, ty.NativeObject())); + } + + /** + * Create a Term of a given sort. This function can be use to create + * numerals that fit in a machine integer. It is slightly faster than + * MakeNumeral since it is not necessary to parse a string. + * Value of the numeral Sort of the + * numeral + * + * @return A Term with value and type + **/ + public Expr MkNumeral(int v, Sort ty) throws Z3Exception + { + + CheckContextMatch(ty); + return Expr.Create(this, Native.mkInt(nCtx(), v, ty.NativeObject())); + } + + /** + * Create a Term of a given sort. This function can be use to create + * numerals that fit in a machine integer. It is slightly faster than + * MakeNumeral since it is not necessary to parse a string. + * Value of the numeral Sort of the + * numeral + * + * @return A Term with value and type + **/ + public Expr MkNumeral(long v, Sort ty) throws Z3Exception + { + + CheckContextMatch(ty); + return Expr.Create(this, Native.mkInt64(nCtx(), v, ty.NativeObject())); + } + + /** + * Create a real from a fraction. numerator of + * rational. denominator of rational. + * + * @return A Term with value / + * and sort Real + **/ + public RatNum MkReal(int num, int den) throws Z3Exception + { + if (den == 0) + throw new Z3Exception("Denominator is zero"); + + return new RatNum(this, Native.mkReal(nCtx(), num, den)); + } + + /** + * Create a real numeral. A string representing the Term + * value in decimal notation. + * + * @return A Term with value and sort Real + **/ + public RatNum MkReal(String v) throws Z3Exception + { + + return new RatNum(this, Native.mkNumeral(nCtx(), v, RealSort() + .NativeObject())); + } + + /** + * Create a real numeral. value of the numeral. + * + * @return A Term with value and sort Real + **/ + public RatNum MkReal(int v) throws Z3Exception + { + + return new RatNum(this, Native.mkInt(nCtx(), v, RealSort() + .NativeObject())); + } + + /** + * Create a real numeral. value of the numeral. + * + * @return A Term with value and sort Real + **/ + public RatNum MkReal(long v) throws Z3Exception + { + + return new RatNum(this, Native.mkInt64(nCtx(), v, RealSort() + .NativeObject())); + } + + /** + * Create an integer numeral. A string representing the Term + * value in decimal notation. + **/ + public IntNum MkInt(String v) throws Z3Exception + { + + return new IntNum(this, Native.mkNumeral(nCtx(), v, IntSort() + .NativeObject())); + } + + /** + * Create an integer numeral. value of the numeral. + * + * @return A Term with value and sort Integer + **/ + public IntNum MkInt(int v) throws Z3Exception + { + + return new IntNum(this, Native.mkInt(nCtx(), v, IntSort() + .NativeObject())); + } + + /** + * Create an integer numeral. value of the numeral. + * + * @return A Term with value and sort Integer + **/ + public IntNum MkInt(long v) throws Z3Exception + { + + return new IntNum(this, Native.mkInt64(nCtx(), v, IntSort() + .NativeObject())); + } + + /** + * Create a bit-vector numeral. A string representing the + * value in decimal notation. the size of the + * bit-vector + **/ + public BitVecNum MkBV(String v, int size) throws Z3Exception + { + + return (BitVecNum) MkNumeral(v, MkBitVecSort(size)); + } + + /** + * Create a bit-vector numeral. value of the + * numeral. the size of the bit-vector + **/ + public BitVecNum MkBV(int v, int size) throws Z3Exception + { + + return (BitVecNum) MkNumeral(v, MkBitVecSort(size)); + } + + /** + * Create a bit-vector numeral. value of the + * numeral. * the size of the bit-vector + **/ + public BitVecNum MkBV(long v, int size) throws Z3Exception + { + + return (BitVecNum) MkNumeral(v, MkBitVecSort(size)); + } + + /** + * Create a universal Quantifier. Creates a forall formula, where + * is the weight, is + * an array of patterns, is an array with the sorts + * of the bound variables, is an array with the + * 'names' of the bound variables, and is the body + * of the quantifier. Quantifiers are associated with weights indicating the + * importance of using the quantifier during instantiation. + * the sorts of the bound variables. names of the bound variables the + * body of the quantifier. quantifiers are + * associated with weights indicating the importance of using the quantifier + * during instantiation. By default, pass the weight 0. array containing the patterns created using + * MkPattern. array containing + * the anti-patterns created using MkPattern. optional symbol to track quantifier. optional symbol to track skolem constants. + **/ + public Quantifier MkForall(Sort[] sorts, Symbol[] names, Expr body, + int weight, Pattern[] patterns, Expr[] noPatterns, + Symbol quantifierID, Symbol skolemID) throws Z3Exception + { + + return new Quantifier(this, true, sorts, names, body, weight, patterns, + noPatterns, quantifierID, skolemID); + } + + /** + * Create a universal Quantifier. + **/ + public Quantifier MkForall(Expr[] boundConstants, Expr body, int weight, + Pattern[] patterns, Expr[] noPatterns, Symbol quantifierID, + Symbol skolemID) throws Z3Exception + { + + return new Quantifier(this, true, boundConstants, body, weight, + patterns, noPatterns, quantifierID, skolemID); + } + + /** + * Create an existential Quantifier. + **/ + public Quantifier MkExists(Sort[] sorts, Symbol[] names, Expr body, + int weight, Pattern[] patterns, Expr[] noPatterns, + Symbol quantifierID, Symbol skolemID) throws Z3Exception + { + + return new Quantifier(this, false, sorts, names, body, weight, + patterns, noPatterns, quantifierID, skolemID); + } + + /** + * Create an existential Quantifier. + **/ + public Quantifier MkExists(Expr[] boundConstants, Expr body, int weight, + Pattern[] patterns, Expr[] noPatterns, Symbol quantifierID, + Symbol skolemID) throws Z3Exception + { + + return new Quantifier(this, false, boundConstants, body, weight, + patterns, noPatterns, quantifierID, skolemID); + } + + /** + * Create a Quantifier. + **/ + public Quantifier MkQuantifier(boolean universal, Sort[] sorts, + Symbol[] names, Expr body, int weight, Pattern[] patterns, + Expr[] noPatterns, Symbol quantifierID, Symbol skolemID) + throws Z3Exception + { + + if (universal) + return MkForall(sorts, names, body, weight, patterns, noPatterns, + quantifierID, skolemID); + else + return MkExists(sorts, names, body, weight, patterns, noPatterns, + quantifierID, skolemID); + } + + /** + * Create a Quantifier. + **/ + public Quantifier MkQuantifier(boolean universal, Expr[] boundConstants, + Expr body, int weight, Pattern[] patterns, Expr[] noPatterns, + Symbol quantifierID, Symbol skolemID) throws Z3Exception + { + + if (universal) + return MkForall(boundConstants, body, weight, patterns, noPatterns, + quantifierID, skolemID); + else + return MkExists(boundConstants, body, weight, patterns, noPatterns, + quantifierID, skolemID); + } + + /** + * Selects the format used for pretty-printing expressions. The + * default mode for pretty printing expressions is to produce SMT-LIB style + * output where common subexpressions are printed at each occurrence. The + * mode is called Z3_PRINT_SMTLIB_FULL. To print shared common + * subexpressions only once, use the Z3_PRINT_LOW_LEVEL mode. To print in + * way that conforms to SMT-LIB standards and uses let expressions to share + * common sub-expressions use Z3_PRINT_SMTLIB_COMPLIANT. + **/ + public void setPrintMode(Z3_ast_print_mode value) throws Z3Exception + { + Native.setAstPrintMode(nCtx(), value.toInt()); + } + + /** + * Convert a benchmark into an SMT-LIB formatted string. Name of the benchmark. The argument is optional. + * The benchmark logic. The status string (sat, unsat, or unknown) Other attributes, such as source, difficulty or + * category. Auxiliary + * assumptions. Formula to be checked for + * consistency in conjunction with assumptions. + * + * @return A string representation of the benchmark. + **/ + public String BenchmarkToSMTString(String name, String logic, + String status, String attributes, BoolExpr[] assumptions, + BoolExpr formula) throws Z3Exception + { + + return Native.benchmarkToSmtlibString(nCtx(), name, logic, status, + attributes, (int) assumptions.length, + AST.ArrayToNative(assumptions), formula.NativeObject()); + } + + /** + * Parse the given string using the SMT-LIB parser. The symbol + * table of the parser can be initialized using the given sorts and + * declarations. The symbols in the arrays and + * don't need to match the names of the sorts + * and declarations in the arrays and . This is a useful feature since we can use arbitrary names + * to reference sorts and declarations. + **/ + public void ParseSMTLIBString(String str, Symbol[] sortNames, Sort[] sorts, + Symbol[] declNames, FuncDecl[] decls) throws Z3Exception + { + int csn = Symbol.ArrayLength(sortNames); + int cs = Sort.ArrayLength(sorts); + int cdn = Symbol.ArrayLength(declNames); + int cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + Native.parseSmtlibString(nCtx(), str, AST.ArrayLength(sorts), + Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), + AST.ArrayToNative(decls)); + } + + /** + * Parse the given file using the SMT-LIB parser. + **/ + public void ParseSMTLIBFile(String fileName, Symbol[] sortNames, + Sort[] sorts, Symbol[] declNames, FuncDecl[] decls) + throws Z3Exception + { + int csn = Symbol.ArrayLength(sortNames); + int cs = Sort.ArrayLength(sorts); + int cdn = Symbol.ArrayLength(declNames); + int cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + Native.parseSmtlibFile(nCtx(), fileName, AST.ArrayLength(sorts), + Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), + AST.ArrayToNative(decls)); + } + + /** + * The number of SMTLIB formulas parsed by the last call to + * ParseSMTLIBString or ParseSMTLIBFile. + **/ + public int NumSMTLIBFormulas() throws Z3Exception + { + return Native.getSmtlibNumFormulas(nCtx()); + } + + /** + * The formulas parsed by the last call to ParseSMTLIBString or + * ParseSMTLIBFile. + **/ + public BoolExpr[] SMTLIBFormulas() throws Z3Exception + { + + int n = NumSMTLIBFormulas(); + BoolExpr[] res = new BoolExpr[n]; + for (int i = 0; i < n; i++) + res[i] = (BoolExpr) Expr.Create(this, + Native.getSmtlibFormula(nCtx(), i)); + return res; + } + + /** + * The number of SMTLIB assumptions parsed by the last call to + * ParseSMTLIBString or ParseSMTLIBFile. + **/ + public int NumSMTLIBAssumptions() throws Z3Exception + { + return Native.getSmtlibNumAssumptions(nCtx()); + } + + /** + * The assumptions parsed by the last call to ParseSMTLIBString + * or ParseSMTLIBFile. + **/ + public BoolExpr[] SMTLIBAssumptions() throws Z3Exception + { + + int n = NumSMTLIBAssumptions(); + BoolExpr[] res = new BoolExpr[n]; + for (int i = 0; i < n; i++) + res[i] = (BoolExpr) Expr.Create(this, + Native.getSmtlibAssumption(nCtx(), i)); + return res; + } + + /** + * The number of SMTLIB declarations parsed by the last call to + * ParseSMTLIBString or ParseSMTLIBFile. + **/ + public int NumSMTLIBDecls() throws Z3Exception + { + return Native.getSmtlibNumDecls(nCtx()); + } + + /** + * The declarations parsed by the last call to + * ParseSMTLIBString or ParseSMTLIBFile. + **/ + public FuncDecl[] SMTLIBDecls() throws Z3Exception + { + + int n = NumSMTLIBDecls(); + FuncDecl[] res = new FuncDecl[n]; + for (int i = 0; i < n; i++) + res[i] = new FuncDecl(this, Native.getSmtlibDecl(nCtx(), i)); + return res; + } + + /** + * The number of SMTLIB sorts parsed by the last call to + * ParseSMTLIBString or ParseSMTLIBFile. + **/ + public int NumSMTLIBSorts() throws Z3Exception + { + return Native.getSmtlibNumSorts(nCtx()); + } + + /** + * The declarations parsed by the last call to + * ParseSMTLIBString or ParseSMTLIBFile. + **/ + public Sort[] SMTLIBSorts() throws Z3Exception + { + + int n = NumSMTLIBSorts(); + Sort[] res = new Sort[n]; + for (int i = 0; i < n; i++) + res[i] = Sort.Create(this, Native.getSmtlibSort(nCtx(), i)); + return res; + } + + /** + * Parse the given string using the SMT-LIB2 parser. + * + * @return A conjunction of assertions in the scope (up to push/pop) at the + * end of the string. + **/ + public BoolExpr ParseSMTLIB2String(String str, Symbol[] sortNames, + Sort[] sorts, Symbol[] declNames, FuncDecl[] decls) + throws Z3Exception + { + + int csn = Symbol.ArrayLength(sortNames); + int cs = Sort.ArrayLength(sorts); + int cdn = Symbol.ArrayLength(declNames); + int cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + return (BoolExpr) Expr.Create(this, Native.parseSmtlib2String(nCtx(), + str, AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), + AST.ArrayToNative(sorts), AST.ArrayLength(decls), + Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls))); + } + + /** + * Parse the given file using the SMT-LIB2 parser. + **/ + public BoolExpr ParseSMTLIB2File(String fileName, Symbol[] sortNames, + Sort[] sorts, Symbol[] declNames, FuncDecl[] decls) + throws Z3Exception + { + + int csn = Symbol.ArrayLength(sortNames); + int cs = Sort.ArrayLength(sorts); + int cdn = Symbol.ArrayLength(declNames); + int cd = AST.ArrayLength(decls); + if (csn != cs || cdn != cd) + throw new Z3Exception("Argument size mismatch"); + return (BoolExpr) Expr.Create(this, Native.parseSmtlib2File(nCtx(), + fileName, AST.ArrayLength(sorts), + Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), + AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), + AST.ArrayToNative(decls))); + } + + /** + * Creates a new Goal. Note that the Context must have been + * created with proof generation support if is set + * to true here. Indicates whether model + * generation should be enabled. Indicates + * whether unsat core generation should be enabled. Indicates whether proof generation should be + * enabled. + **/ + public Goal MkGoal(boolean models, boolean unsatCores, boolean proofs) + throws Z3Exception + { + + return new Goal(this, models, unsatCores, proofs); + } + + /** + * Creates a new ParameterSet. + **/ + public Params MkParams() throws Z3Exception + { + + return new Params(this); + } + + /** + * The number of supported tactics. + **/ + public int NumTactics() throws Z3Exception + { + return Native.getNumTactics(nCtx()); + } + + /** + * The names of all supported tactics. + **/ + public String[] TacticNames() throws Z3Exception + { + + int n = NumTactics(); + String[] res = new String[n]; + for (int i = 0; i < n; i++) + res[i] = Native.getTacticName(nCtx(), i); + return res; + } + + /** + * Returns a string containing a description of the tactic with the given + * name. + **/ + public String TacticDescription(String name) throws Z3Exception + { + + return Native.tacticGetDescr(nCtx(), name); + } + + /** + * Creates a new Tactic. + **/ + public Tactic MkTactic(String name) throws Z3Exception + { + + return new Tactic(this, name); + } + + /** + * Create a tactic that applies to a Goal and then + * to every subgoal produced by . + **/ + public Tactic AndThen(Tactic t1, Tactic t2, Tactic[] ts) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + CheckContextMatch(ts); + + long last = 0; + if (ts != null && ts.length > 0) + { + last = ts[ts.length - 1].NativeObject(); + for (int i = ts.length - 2; i >= 0; i--) + last = Native.tacticAndThen(nCtx(), ts[i].NativeObject(), last); + } + if (last != 0) + { + last = Native.tacticAndThen(nCtx(), t2.NativeObject(), last); + return new Tactic(this, Native.tacticAndThen(nCtx(), + t1.NativeObject(), last)); + } else + return new Tactic(this, Native.tacticAndThen(nCtx(), + t1.NativeObject(), t2.NativeObject())); + } + + /** + * Create a tactic that applies to a Goal and then + * to every subgoal produced by . + * Shorthand for AndThen. + **/ + public Tactic Then(Tactic t1, Tactic t2, Tactic[] ts) throws Z3Exception + { + + return AndThen(t1, t2, ts); + } + + /** + * Create a tactic that first applies to a Goal and if + * it fails then returns the result of applied to the + * Goal. + **/ + public Tactic OrElse(Tactic t1, Tactic t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new Tactic(this, Native.tacticOrElse(nCtx(), t1.NativeObject(), + t2.NativeObject())); + } + + /** + * Create a tactic that applies to a goal for milliseconds. If does not + * terminate within milliseconds, then it fails. + * + **/ + public Tactic TryFor(Tactic t, int ms) throws Z3Exception + { + + CheckContextMatch(t); + return new Tactic(this, Native.tacticTryFor(nCtx(), t.NativeObject(), + ms)); + } + + /** + * Create a tactic that applies to a given goal if the + * probe evaluates to true. If evaluates to false, then the new tactic behaves like the + * skip tactic. + **/ + public Tactic When(Probe p, Tactic t) throws Z3Exception + { + + CheckContextMatch(t); + CheckContextMatch(p); + return new Tactic(this, Native.tacticWhen(nCtx(), p.NativeObject(), + t.NativeObject())); + } + + /** + * Create a tactic that applies to a given goal if the + * probe evaluates to true and + * otherwise. + **/ + public Tactic Cond(Probe p, Tactic t1, Tactic t2) throws Z3Exception + { + + CheckContextMatch(p); + CheckContextMatch(t1); + CheckContextMatch(t2); + return new Tactic(this, Native.tacticCond(nCtx(), p.NativeObject(), + t1.NativeObject(), t2.NativeObject())); + } + + /** + * Create a tactic that keeps applying until the goal + * is not modified anymore or the maximum number of iterations is reached. + **/ + public Tactic Repeat(Tactic t, int max) throws Z3Exception + { + + CheckContextMatch(t); + return new Tactic(this, Native.tacticRepeat(nCtx(), t.NativeObject(), + max)); + } + + /** + * Create a tactic that just returns the given goal. + **/ + public Tactic Skip() throws Z3Exception + { + + return new Tactic(this, Native.tacticSkip(nCtx())); + } + + /** + * Create a tactic always fails. + **/ + public Tactic Fail() throws Z3Exception + { + + return new Tactic(this, Native.tacticFail(nCtx())); + } + + /** + * Create a tactic that fails if the probe evaluates to + * false. + **/ + public Tactic FailIf(Probe p) throws Z3Exception + { + + CheckContextMatch(p); + return new Tactic(this, Native.tacticFailIf(nCtx(), p.NativeObject())); + } + + /** + * Create a tactic that fails if the goal is not triviall satisfiable (i.e., + * empty) or trivially unsatisfiable (i.e., contains `false'). + **/ + public Tactic FailIfNotDecided() throws Z3Exception + { + + return new Tactic(this, Native.tacticFailIfNotDecided(nCtx())); + } + + /** + * Create a tactic that applies using the given set of + * parameters . + **/ + public Tactic UsingParams(Tactic t, Params p) throws Z3Exception + { + + CheckContextMatch(t); + CheckContextMatch(p); + return new Tactic(this, Native.tacticUsingParams(nCtx(), + t.NativeObject(), p.NativeObject())); + } + + /** + * Create a tactic that applies using the given set of + * parameters . Alias for + * UsingParams + **/ + public Tactic With(Tactic t, Params p) throws Z3Exception + { + + return UsingParams(t, p); + } + + /** + * Create a tactic that applies the given tactics in parallel. + **/ + public Tactic ParOr(Tactic[] t) throws Z3Exception + { + + CheckContextMatch(t); + return new Tactic(this, Native.tacticParOr(nCtx(), + Tactic.ArrayLength(t), Tactic.ArrayToNative(t))); + } + + /** + * Create a tactic that applies to a given goal and + * then to every subgoal produced by . The subgoals are processed in parallel. + **/ + public Tactic ParAndThen(Tactic t1, Tactic t2) throws Z3Exception + { + + CheckContextMatch(t1); + CheckContextMatch(t2); + return new Tactic(this, Native.tacticParAndThen(nCtx(), + t1.NativeObject(), t2.NativeObject())); + } + + /** + * Interrupt the execution of a Z3 procedure. This procedure can be + * used to interrupt: solvers, simplifiers and tactics. + **/ + public void Interrupt() throws Z3Exception + { + Native.interrupt(nCtx()); + } + + /** + * The number of supported Probes. + **/ + public int NumProbes() throws Z3Exception + { + return Native.getNumProbes(nCtx()); + } + + /** + * The names of all supported Probes. + **/ + public String[] ProbeNames() throws Z3Exception + { + + int n = NumProbes(); + String[] res = new String[n]; + for (int i = 0; i < n; i++) + res[i] = Native.getProbeName(nCtx(), i); + return res; + } + + /** + * Returns a string containing a description of the probe with the given + * name. + **/ + public String ProbeDescription(String name) throws Z3Exception + { + + return Native.probeGetDescr(nCtx(), name); + } + + /** + * Creates a new Probe. + **/ + public Probe MkProbe(String name) throws Z3Exception + { + + return new Probe(this, name); + } + + /** + * Create a probe that always evaluates to . + **/ + public Probe Const(double val) throws Z3Exception + { + + return new Probe(this, Native.probeConst(nCtx(), val)); + } + + /** + * Create a probe that evaluates to "true" when the value returned by + * is less than the value returned by + **/ + public Probe Lt(Probe p1, Probe p2) throws Z3Exception + { + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Native.probeLt(nCtx(), p1.NativeObject(), + p2.NativeObject())); + } + + /** + * Create a probe that evaluates to "true" when the value returned by + * is greater than the value returned by + **/ + public Probe Gt(Probe p1, Probe p2) throws Z3Exception + { + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Native.probeGt(nCtx(), p1.NativeObject(), + p2.NativeObject())); + } + + /** + * Create a probe that evaluates to "true" when the value returned by + * is less than or equal the value returned by + * + **/ + public Probe Le(Probe p1, Probe p2) throws Z3Exception + { + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Native.probeLe(nCtx(), p1.NativeObject(), + p2.NativeObject())); + } + + /** + * Create a probe that evaluates to "true" when the value returned by + * is greater than or equal the value returned by + * + **/ + public Probe Ge(Probe p1, Probe p2) throws Z3Exception + { + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Native.probeGe(nCtx(), p1.NativeObject(), + p2.NativeObject())); + } + + /** + * Create a probe that evaluates to "true" when the value returned by + * is equal to the value returned by + **/ + public Probe Eq(Probe p1, Probe p2) throws Z3Exception + { + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Native.probeEq(nCtx(), p1.NativeObject(), + p2.NativeObject())); + } + + /** + * Create a probe that evaluates to "true" when the value and evaluate to "true". + **/ + public Probe And(Probe p1, Probe p2) throws Z3Exception + { + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Native.probeAnd(nCtx(), p1.NativeObject(), + p2.NativeObject())); + } + + /** + * Create a probe that evaluates to "true" when the value or evaluate to "true". + **/ + public Probe Or(Probe p1, Probe p2) throws Z3Exception + { + + CheckContextMatch(p1); + CheckContextMatch(p2); + return new Probe(this, Native.probeOr(nCtx(), p1.NativeObject(), + p2.NativeObject())); + } + + /** + * Create a probe that evaluates to "true" when the value does not evaluate to "true". + **/ + public Probe Not(Probe p) throws Z3Exception + { + + CheckContextMatch(p); + return new Probe(this, Native.probeNot(nCtx(), p.NativeObject())); + } + + /** + * Creates a new (incremental) solver. This solver also uses a set + * of builtin tactics for handling the first check-sat command, and + * check-sat commands that take more than a given number of milliseconds to + * be solved. + **/ + public Solver MkSolver() throws Z3Exception + { + return MkSolver((Symbol) null); + } + + /** + * Creates a new (incremental) solver. This solver also uses a set + * of builtin tactics for handling the first check-sat command, and + * check-sat commands that take more than a given number of milliseconds to + * be solved. + **/ + public Solver MkSolver(Symbol logic) throws Z3Exception + { + + if (logic == null) + return new Solver(this, Native.mkSolver(nCtx())); + else + return new Solver(this, Native.mkSolverForLogic(nCtx(), + logic.NativeObject())); + } + + /** + * Creates a new (incremental) solver. + **/ + public Solver MkSolver(String logic) throws Z3Exception + { + + return MkSolver(MkSymbol(logic)); + } + + /** + * Creates a new (incremental) solver. + **/ + public Solver MkSimpleSolver() throws Z3Exception + { + + return new Solver(this, Native.mkSimpleSolver(nCtx())); + } + + /** + * Creates a solver that is implemented using the given tactic. + * The solver supports the commands Push and Pop, + * but it will always solve each check from scratch. + **/ + public Solver MkSolver(Tactic t) throws Z3Exception + { + + return new Solver(this, Native.mkSolverFromTactic(nCtx(), + t.NativeObject())); + } + + /** + * Create a Fixedpoint context. + **/ + public Fixedpoint MkFixedpoint() throws Z3Exception + { + + return new Fixedpoint(this); + } + + /** + * Wraps an AST. This function is used for transitions between + * native and managed objects. Note that + * must be a native object obtained from Z3 (e.g., through ) and that it must have a correct reference count (see + * e.g., . The native pointer to + * wrap. + **/ + public AST WrapAST(long nativeObject) throws Z3Exception + { + + return AST.Create(this, nativeObject); + } + + /** + * Unwraps an AST. This function is used for transitions between + * native and managed objects. It returns the native pointer to the AST. + * Note that AST objects are reference counted and unwrapping an AST + * disables automatic reference counting, i.e., all references to the IntPtr + * that is returned must be handled externally and through native calls (see + * e.g., ). The AST to unwrap. + **/ + public long UnwrapAST(AST a) + { + return a.NativeObject(); + } + + /** + * Return a string describing all available parameters to + * Expr.Simplify. + **/ + public String SimplifyHelp() throws Z3Exception + { + + return Native.simplifyGetHelp(nCtx()); + } + + /** + * Retrieves parameter descriptions for simplifier. + **/ + public ParamDescrs SimplifyParameterDescriptions() throws Z3Exception + { + return new ParamDescrs(this, Native.simplifyGetParamDescrs(nCtx())); + } + + /** + * Enable/disable printing of warning messages to the console. Note + * that this function is static and effects the behaviour of all contexts + * globally. + **/ + public static void ToggleWarningMessages(boolean enabled) + throws Z3Exception + { + Native.toggleWarningMessages((enabled) ? true : false); + } + + /** + * Update a mutable configuration parameter. The list of all + * configuration parameters can be obtained using the Z3 executable: + * z3.exe -ini? Only a few configuration parameters are mutable + * once the context is created. An exception is thrown when trying to modify + * an immutable parameter. + **/ + public void UpdateParamValue(String id, String value) throws Z3Exception + { + Native.updateParamValue(nCtx(), id, value); + } + + /** + * Get a configuration parameter. Returns null if the parameter + * value does not exist. + **/ + public String GetParamValue(String id) throws Z3Exception + { + Native.StringPtr res = new Native.StringPtr(); + boolean r = Native.getParamValue(nCtx(), id, res); + if (!r) + return null; + else + return res.value; + } + + long m_ctx = 0; + + long nCtx() + { + return m_ctx; + } + + void InitContext() throws Z3Exception + { + setPrintMode(Z3_ast_print_mode.Z3_PRINT_SMTLIB2_COMPLIANT); + Native.setInternalErrorHandler(nCtx()); + } + + void CheckContextMatch(Z3Object other) throws Z3Exception + { + if (this != other.Context()) + throw new Z3Exception("Context mismatch"); + } + + void CheckContextMatch(Z3Object[] arr) throws Z3Exception + { + if (arr != null) + for (Z3Object a : arr) + CheckContextMatch(a); + } + + private ASTDecRefQueue m_AST_DRQ = new ASTDecRefQueue(); + private ASTMapDecRefQueue m_ASTMap_DRQ = new ASTMapDecRefQueue(); + private ASTVectorDecRefQueue m_ASTVector_DRQ = new ASTVectorDecRefQueue(); + private ApplyResultDecRefQueue m_ApplyResult_DRQ = new ApplyResultDecRefQueue(); + private FuncInterpEntryDecRefQueue m_FuncEntry_DRQ = new FuncInterpEntryDecRefQueue(); + private FuncInterpDecRefQueue m_FuncInterp_DRQ = new FuncInterpDecRefQueue(); + private GoalDecRefQueue m_Goal_DRQ = new GoalDecRefQueue(); + private ModelDecRefQueue m_Model_DRQ = new ModelDecRefQueue(); + private ParamsDecRefQueue m_Params_DRQ = new ParamsDecRefQueue(); + private ParamDescrsDecRefQueue m_ParamDescrs_DRQ = new ParamDescrsDecRefQueue(); + private ProbeDecRefQueue m_Probe_DRQ = new ProbeDecRefQueue(); + private SolverDecRefQueue m_Solver_DRQ = new SolverDecRefQueue(); + private StatisticsDecRefQueue m_Statistics_DRQ = new StatisticsDecRefQueue(); + private TacticDecRefQueue m_Tactic_DRQ = new TacticDecRefQueue(); + private FixedpointDecRefQueue m_Fixedpoint_DRQ = new FixedpointDecRefQueue(); + + ASTDecRefQueue AST_DRQ() + { + return m_AST_DRQ; + } + + ASTMapDecRefQueue ASTMap_DRQ() + { + return m_ASTMap_DRQ; + } + + ASTVectorDecRefQueue ASTVector_DRQ() + { + return m_ASTVector_DRQ; + } + + ApplyResultDecRefQueue ApplyResult_DRQ() + { + return m_ApplyResult_DRQ; + } + + FuncInterpEntryDecRefQueue FuncEntry_DRQ() + { + return m_FuncEntry_DRQ; + } + + FuncInterpDecRefQueue FuncInterp_DRQ() + { + return m_FuncInterp_DRQ; + } + + GoalDecRefQueue Goal_DRQ() + { + return m_Goal_DRQ; + } + + ModelDecRefQueue Model_DRQ() + { + return m_Model_DRQ; + } + + ParamsDecRefQueue Params_DRQ() + { + return m_Params_DRQ; + } + + ParamDescrsDecRefQueue ParamDescrs_DRQ() + { + return m_ParamDescrs_DRQ; + } + + ProbeDecRefQueue Probe_DRQ() + { + return m_Probe_DRQ; + } + + SolverDecRefQueue Solver_DRQ() + { + return m_Solver_DRQ; + } + + StatisticsDecRefQueue Statistics_DRQ() + { + return m_Statistics_DRQ; + } + + TacticDecRefQueue Tactic_DRQ() + { + return m_Tactic_DRQ; + } + + FixedpointDecRefQueue Fixedpoint_DRQ() + { + return m_Fixedpoint_DRQ; + } + + protected long m_refCount = 0; + + /** + * Finalizer. + **/ + protected void finalize() + { + Dispose(); + + if (m_refCount == 0) + { + try + { + Native.delContext(m_ctx); + } catch (Z3Exception e) + { + // OK. + } + m_ctx = 0; + } else + /* re-queue the finalizer */ + /* BUG: DRQ's need to be taken over too! */ + new Context(m_ctx, m_refCount); + } + + /** + * Disposes of the context. + **/ + public void Dispose() + { + m_AST_DRQ.Clear(this); + m_ASTMap_DRQ.Clear(this); + m_ASTVector_DRQ.Clear(this); + m_ApplyResult_DRQ.Clear(this); + m_FuncEntry_DRQ.Clear(this); + m_FuncInterp_DRQ.Clear(this); + m_Goal_DRQ.Clear(this); + m_Model_DRQ.Clear(this); + m_Params_DRQ.Clear(this); + m_Probe_DRQ.Clear(this); + m_Solver_DRQ.Clear(this); + m_Statistics_DRQ.Clear(this); + m_Tactic_DRQ.Clear(this); + m_Fixedpoint_DRQ.Clear(this); + + m_boolSort = null; + m_intSort = null; + m_realSort = null; + } +} diff --git a/src/api/java/DatatypeExpr.java b/src/api/java/DatatypeExpr.java new file mode 100644 index 000000000..63cb02f80 --- /dev/null +++ b/src/api/java/DatatypeExpr.java @@ -0,0 +1,26 @@ +/** + * This file was automatically generated from DatatypeExpr.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Datatype expressions + **/ +public class DatatypeExpr extends Expr +{ + /** + * Constructor for DatatypeExpr + **/ + protected DatatypeExpr(Context ctx) + { + super(ctx); + } + + DatatypeExpr(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } +} diff --git a/src/api/java/DatatypeSort.java b/src/api/java/DatatypeSort.java new file mode 100644 index 000000000..7e6d002aa --- /dev/null +++ b/src/api/java/DatatypeSort.java @@ -0,0 +1,91 @@ +/** + * This file was automatically generated from DatatypeSort.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Datatype sorts. + **/ +public class DatatypeSort extends Sort +{ + /** + * The number of constructors of the datatype sort. + **/ + public int NumConstructors() throws Z3Exception + { + return Native.getDatatypeSortNumConstructors(Context().nCtx(), + NativeObject()); + } + + /** + * The constructors. + * + * @throws Z3Exception + **/ + public FuncDecl[] Constructors() throws Z3Exception + { + int n = NumConstructors(); + FuncDecl[] res = new FuncDecl[n]; + for (int i = 0; i < n; i++) + res[i] = new FuncDecl(Context(), Native.getDatatypeSortConstructor( + Context().nCtx(), NativeObject(), i)); + return res; + } + + /** + * The recognizers. + * + * @throws Z3Exception + **/ + public FuncDecl[] Recognizers() throws Z3Exception + { + int n = NumConstructors(); + FuncDecl[] res = new FuncDecl[n]; + for (int i = 0; i < n; i++) + res[i] = new FuncDecl(Context(), Native.getDatatypeSortRecognizer( + Context().nCtx(), NativeObject(), i)); + return res; + } + + /** + * The constructor accessors. + * + * @throws Z3Exception + **/ + public FuncDecl[][] Accessors() throws Z3Exception + { + + int n = NumConstructors(); + FuncDecl[][] res = new FuncDecl[n][]; + for (int i = 0; i < n; i++) + { + FuncDecl fd = new FuncDecl(Context(), + Native.getDatatypeSortConstructor(Context().nCtx(), + NativeObject(), i)); + int ds = fd.DomainSize(); + FuncDecl[] tmp = new FuncDecl[ds]; + for (int j = 0; j < ds; j++) + tmp[j] = new FuncDecl(Context(), + Native.getDatatypeSortConstructorAccessor(Context() + .nCtx(), NativeObject(), i, j)); + res[i] = tmp; + } + return res; + } + + DatatypeSort(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + DatatypeSort(Context ctx, Symbol name, Constructor[] constructors) + throws Z3Exception + { + super(ctx, Native.mkDatatype(ctx.nCtx(), name.NativeObject(), + (int) constructors.length, ArrayToNative(constructors))); + + } +}; diff --git a/src/api/java/EnumSort.java b/src/api/java/EnumSort.java new file mode 100644 index 000000000..10f0f9764 --- /dev/null +++ b/src/api/java/EnumSort.java @@ -0,0 +1,61 @@ +/** + * This file was automatically generated from EnumSort.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Enumeration sorts. + **/ +public class EnumSort extends Sort +{ + /** + * The function declarations of the constants in the enumeration. + **/ + public FuncDecl[] ConstDecls() + { + return _constdecls; + } + + /** + * The constants in the enumeration. + **/ + public Expr[] Consts() + { + return _consts; + } + + /** + * The test predicates for the constants in the enumeration. + **/ + public FuncDecl[] TesterDecls() + { + return _testerdecls; + } + + private FuncDecl[] _constdecls = null, _testerdecls = null; + private Expr[] _consts = null; + + EnumSort(Context ctx, Symbol name, Symbol[] enumNames) throws Z3Exception + { + super(ctx); + + int n = enumNames.length; + long[] n_constdecls = new long[n]; + long[] n_testers = new long[n]; + setNativeObject(Native.mkEnumerationSort(ctx.nCtx(), + name.NativeObject(), (int) n, Symbol.ArrayToNative(enumNames), + n_constdecls, n_testers)); + _constdecls = new FuncDecl[n]; + for (int i = 0; i < n; i++) + _constdecls[i] = new FuncDecl(ctx, n_constdecls[i]); + _testerdecls = new FuncDecl[n]; + for (int i = 0; i < n; i++) + _testerdecls[i] = new FuncDecl(ctx, n_testers[i]); + _consts = new Expr[n]; + for (int i = 0; i < n; i++) + _consts[i] = ctx.MkApp(_constdecls[i], (Expr[])null); + } +}; diff --git a/src/api/java/Expr.java b/src/api/java/Expr.java new file mode 100644 index 000000000..a67d94e7e --- /dev/null +++ b/src/api/java/Expr.java @@ -0,0 +1,1812 @@ +/** + * This file was automatically generated from Expr.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +import com.microsoft.z3.enumerations.*; + +/* using System; */ + +/** + * Expressions are terms. + **/ +public class Expr extends AST +{ + /** + * Returns a simplified version of the expression + **/ + public Expr Simplify() throws Z3Exception + { + return Simplify(null); + } + + /** + * Returns a simplified version of the expression + * A set of + * parameters to configure the simplifier + * + **/ + public Expr Simplify(Params p) throws Z3Exception + { + + if (p == null) + return Expr.Create(Context(), + Native.simplify(Context().nCtx(), NativeObject())); + else + return Expr.Create( + Context(), + Native.simplifyEx(Context().nCtx(), NativeObject(), + p.NativeObject())); + } + + /** + * The function declaration of the function that is applied in this + * expression. + **/ + public FuncDecl FuncDecl() throws Z3Exception + { + + return new FuncDecl(Context(), Native.getAppDecl(Context().nCtx(), + NativeObject())); + } + + /** + * Indicates whether the expression is the true or false expression or + * something else (Z3_L_UNDEF). + **/ + public Z3_lbool BoolValue() throws Z3Exception + { + return Z3_lbool.fromInt(Native.getBoolValue(Context().nCtx(), + NativeObject())); + } + + /** + * The number of arguments of the expression. + **/ + public int NumArgs() throws Z3Exception + { + return Native.getAppNumArgs(Context().nCtx(), NativeObject()); + } + + /** + * The arguments of the expression. + **/ + public Expr[] Args() throws Z3Exception + { + + int n = NumArgs(); + Expr[] res = new Expr[n]; + for (int i = 0; i < n; i++) + res[i] = Expr.Create(Context(), + Native.getAppArg(Context().nCtx(), NativeObject(), i)); + return res; + } + + /** + * Update the arguments of the expression using the arguments The number of new arguments should coincide with the + * current number of arguments. + **/ + public void Update(Expr[] args) throws Z3Exception + { + + Context().CheckContextMatch(args); + if (args.length != NumArgs()) + throw new Z3Exception("Number of arguments does not match"); + setNativeObject(Native.updateTerm(Context().nCtx(), NativeObject(), + (int) args.length, Expr.ArrayToNative(args))); + } + + /** + * Substitute every occurrence of from[i] in the expression + * with to[i], for i smaller than + * num_exprs. The result is the new expression. The + * arrays from and to must have size + * num_exprs. For every i smaller than + * num_exprs, we must have that sort of from[i] + * must be equal to sort of to[i]. + **/ + public Expr Substitute(Expr[] from, Expr[] to) throws Z3Exception + { + + Context().CheckContextMatch(from); + Context().CheckContextMatch(to); + if (from.length != to.length) + throw new Z3Exception("Argument sizes do not match"); + return Expr.Create(Context(), Native.substitute(Context().nCtx(), + NativeObject(), (int) from.length, Expr.ArrayToNative(from), + Expr.ArrayToNative(to))); + } + + /** + * Substitute every occurrence of from in the expression with + * to. + **/ + public Expr Substitute(Expr from, Expr to) throws Z3Exception + { + + return Substitute(new Expr[] { from }, new Expr[] { to }); + } + + /** + * Substitute the free variables in the expression with the expressions in + * For every i smaller than + * num_exprs, the variable with de-Bruijn index i + * is replaced with term to[i]. + **/ + public Expr SubstituteVars(Expr[] to) throws Z3Exception + { + + Context().CheckContextMatch(to); + return Expr.Create(Context(), Native.substituteVars(Context().nCtx(), + NativeObject(), (int) to.length, Expr.ArrayToNative(to))); + } + + /** + * Translates (copies) the term to the Context . + * A context + * + * @return A copy of the term which is associated with + **/ + public Expr Translate(Context ctx) throws Z3Exception + { + + if (Context() == ctx) + return this; + else + return Expr.Create( + ctx, + Native.translate(Context().nCtx(), NativeObject(), + ctx.nCtx())); + } + + /** + * Returns a string representation of the expression. + **/ + public String toString() + { + return super.toString(); + } + + /** + * Indicates whether the term is a numeral + **/ + public boolean IsNumeral() throws Z3Exception + { + return Native.isNumeralAst(Context().nCtx(), NativeObject()); + } + + /** + * Indicates whether the term is well-sorted. + * + * @return True if the term is well-sorted, false otherwise. + **/ + public boolean IsWellSorted() throws Z3Exception + { + return Native.isWellSorted(Context().nCtx(), NativeObject()); + } + + /** + * The Sort of the term. + **/ + public Sort Sort() throws Z3Exception + { + return Sort.Create(Context(), + Native.getSort(Context().nCtx(), NativeObject())); + } + + /** + * Indicates whether the term represents a constant. + **/ + public boolean IsConst() throws Z3Exception + { + return IsExpr() && NumArgs() == 0 && FuncDecl().DomainSize() == 0; + } + + /** + * Indicates whether the term is an integer numeral. + **/ + public boolean IsIntNum() throws Z3Exception + { + return IsNumeral() && IsInt(); + } + + /** + * Indicates whether the term is a real numeral. + **/ + public boolean IsRatNum() throws Z3Exception + { + return IsNumeral() && IsReal(); + } + + /** + * Indicates whether the term is an algebraic number + **/ + public boolean IsAlgebraicNumber() throws Z3Exception + { + return Native.isAlgebraicNumber(Context().nCtx(), NativeObject()); + } + + /** + * Indicates whether the term has Boolean sort. + **/ + public boolean IsBool() throws Z3Exception + { + return (IsExpr() && Native.isEqSort(Context().nCtx(), + Native.mkBoolSort(Context().nCtx()), + Native.getSort(Context().nCtx(), NativeObject()))); + } + + /** + * Indicates whether the term is the constant true. + **/ + public boolean IsTrue() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_TRUE; + } + + /** + * Indicates whether the term is the constant false. + **/ + public boolean IsFalse() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_FALSE; + } + + /** + * Indicates whether the term is an equality predicate. + **/ + public boolean IsEq() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_EQ; + } + + /** + * Indicates whether the term is an n-ary distinct predicate (every argument + * is mutually distinct). + **/ + public boolean IsDistinct() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_DISTINCT; + } + + /** + * Indicates whether the term is a ternary if-then-else term + **/ + public boolean IsITE() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_ITE; + } + + /** + * Indicates whether the term is an n-ary conjunction + **/ + public boolean IsAnd() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_AND; + } + + /** + * Indicates whether the term is an n-ary disjunction + **/ + public boolean IsOr() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_OR; + } + + /** + * Indicates whether the term is an if-and-only-if (Boolean equivalence, + * binary) + **/ + public boolean IsIff() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_IFF; + } + + /** + * Indicates whether the term is an exclusive or + **/ + public boolean IsXor() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_XOR; + } + + /** + * Indicates whether the term is a negation + **/ + public boolean IsNot() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_NOT; + } + + /** + * Indicates whether the term is an implication + **/ + public boolean IsImplies() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_IMPLIES; + } + + /** + * Indicates whether the term is of integer sort. + **/ + public boolean IsInt() throws Z3Exception + { + return (Native.isNumeralAst(Context().nCtx(), NativeObject()) && Native + .getSortKind(Context().nCtx(), + Native.getSort(Context().nCtx(), NativeObject())) == Z3_sort_kind.Z3_INT_SORT + .toInt()); + } + + /** + * Indicates whether the term is of sort real. + **/ + public boolean IsReal() throws Z3Exception + { + return Native.getSortKind(Context().nCtx(), + Native.getSort(Context().nCtx(), NativeObject())) == Z3_sort_kind.Z3_REAL_SORT + .toInt(); + } + + /** + * Indicates whether the term is an arithmetic numeral. + **/ + public boolean IsArithmeticNumeral() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_ANUM; + } + + /** + * Indicates whether the term is a less-than-or-equal + **/ + public boolean IsLE() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_LE; + } + + /** + * Indicates whether the term is a greater-than-or-equal + **/ + public boolean IsGE() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_GE; + } + + /** + * Indicates whether the term is a less-than + **/ + public boolean IsLT() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_LT; + } + + /** + * Indicates whether the term is a greater-than + **/ + public boolean IsGT() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_GT; + } + + /** + * Indicates whether the term is addition (binary) + **/ + public boolean IsAdd() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_ADD; + } + + /** + * Indicates whether the term is subtraction (binary) + **/ + public boolean IsSub() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SUB; + } + + /** + * Indicates whether the term is a unary minus + **/ + public boolean IsUMinus() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_UMINUS; + } + + /** + * Indicates whether the term is multiplication (binary) + **/ + public boolean IsMul() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_MUL; + } + + /** + * Indicates whether the term is division (binary) + **/ + public boolean IsDiv() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_DIV; + } + + /** + * Indicates whether the term is integer division (binary) + **/ + public boolean IsIDiv() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_IDIV; + } + + /** + * Indicates whether the term is remainder (binary) + **/ + public boolean IsRemainder() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_REM; + } + + /** + * Indicates whether the term is modulus (binary) + **/ + public boolean IsModulus() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_MOD; + } + + /** + * Indicates whether the term is a coercion of integer to real (unary) + **/ + public boolean IsIntToReal() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_TO_REAL; + } + + /** + * Indicates whether the term is a coercion of real to integer (unary) + **/ + public boolean IsRealToInt() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_TO_INT; + } + + /** + * Indicates whether the term is a check that tests whether a real is + * integral (unary) + **/ + public boolean IsRealIsInt() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_IS_INT; + } + + /** + * Indicates whether the term is of an array sort. + **/ + public boolean IsArray() throws Z3Exception + { + return (Native.isApp(Context().nCtx(), NativeObject()) && Z3_sort_kind + .fromInt(Native.getSortKind(Context().nCtx(), + Native.getSort(Context().nCtx(), NativeObject()))) == Z3_sort_kind.Z3_ARRAY_SORT); + } + + /** + * Indicates whether the term is an array store. It satisfies + * select(store(a,i,v),j) = if i = j then v else select(a,j). Array store + * takes at least 3 arguments. + **/ + public boolean IsStore() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_STORE; + } + + /** + * Indicates whether the term is an array select. + **/ + public boolean IsSelect() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SELECT; + } + + /** + * Indicates whether the term is a constant array. For example, + * select(const(v),i) = v holds for every v and i. The function is + * unary. + **/ + public boolean IsConstantArray() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_CONST_ARRAY; + } + + /** + * Indicates whether the term is a default array. For example + * default(const(v)) = v. The function is unary. + **/ + public boolean IsDefaultArray() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_ARRAY_DEFAULT; + } + + /** + * Indicates whether the term is an array map. It satisfies + * map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. + **/ + public boolean IsArrayMap() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_ARRAY_MAP; + } + + /** + * Indicates whether the term is an as-array term. An as-array term + * is n array value that behaves as the function graph of the function + * passed as parameter. + **/ + public boolean IsAsArray() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_AS_ARRAY; + } + + /** + * Indicates whether the term is set union + **/ + public boolean IsSetUnion() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SET_UNION; + } + + /** + * Indicates whether the term is set intersection + **/ + public boolean IsSetIntersect() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SET_INTERSECT; + } + + /** + * Indicates whether the term is set difference + **/ + public boolean IsSetDifference() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SET_DIFFERENCE; + } + + /** + * Indicates whether the term is set complement + **/ + public boolean IsSetComplement() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SET_COMPLEMENT; + } + + /** + * Indicates whether the term is set subset + **/ + public boolean IsSetSubset() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SET_SUBSET; + } + + /** + * Indicates whether the terms is of bit-vector sort. + **/ + public boolean IsBV() throws Z3Exception + { + return Native.getSortKind(Context().nCtx(), + Native.getSort(Context().nCtx(), NativeObject())) == Z3_sort_kind.Z3_BV_SORT + .toInt(); + } + + /** + * Indicates whether the term is a bit-vector numeral + **/ + public boolean IsBVNumeral() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BNUM; + } + + /** + * Indicates whether the term is a one-bit bit-vector with value one + **/ + public boolean IsBVBitOne() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BIT1; + } + + /** + * Indicates whether the term is a one-bit bit-vector with value zero + **/ + public boolean IsBVBitZero() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BIT0; + } + + /** + * Indicates whether the term is a bit-vector unary minus + **/ + public boolean IsBVUMinus() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BNEG; + } + + /** + * Indicates whether the term is a bit-vector addition (binary) + **/ + public boolean IsBVAdd() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BADD; + } + + /** + * Indicates whether the term is a bit-vector subtraction (binary) + **/ + public boolean IsBVSub() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BSUB; + } + + /** + * Indicates whether the term is a bit-vector multiplication (binary) + **/ + public boolean IsBVMul() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BMUL; + } + + /** + * Indicates whether the term is a bit-vector signed division (binary) + **/ + public boolean IsBVSDiv() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BSDIV; + } + + /** + * Indicates whether the term is a bit-vector unsigned division (binary) + **/ + public boolean IsBVUDiv() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BUDIV; + } + + /** + * Indicates whether the term is a bit-vector signed remainder (binary) + **/ + public boolean IsBVSRem() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BSREM; + } + + /** + * Indicates whether the term is a bit-vector unsigned remainder (binary) + **/ + public boolean IsBVURem() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BUREM; + } + + /** + * Indicates whether the term is a bit-vector signed modulus + **/ + public boolean IsBVSMod() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BSMOD; + } + + /** + * Indicates whether the term is a bit-vector signed division by zero + **/ + boolean IsBVSDiv0() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BSDIV0; + } + + /** + * Indicates whether the term is a bit-vector unsigned division by zero + **/ + boolean IsBVUDiv0() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BUDIV0; + } + + /** + * Indicates whether the term is a bit-vector signed remainder by zero + **/ + boolean IsBVSRem0() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BSREM0; + } + + /** + * Indicates whether the term is a bit-vector unsigned remainder by zero + **/ + boolean IsBVURem0() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BUREM0; + } + + /** + * Indicates whether the term is a bit-vector signed modulus by zero + **/ + boolean IsBVSMod0() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BSMOD0; + } + + /** + * Indicates whether the term is an unsigned bit-vector less-than-or-equal + **/ + public boolean IsBVULE() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_ULEQ; + } + + /** + * Indicates whether the term is a signed bit-vector less-than-or-equal + **/ + public boolean IsBVSLE() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SLEQ; + } + + /** + * Indicates whether the term is an unsigned bit-vector + * greater-than-or-equal + **/ + public boolean IsBVUGE() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_UGEQ; + } + + /** + * Indicates whether the term is a signed bit-vector greater-than-or-equal + **/ + public boolean IsBVSGE() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SGEQ; + } + + /** + * Indicates whether the term is an unsigned bit-vector less-than + **/ + public boolean IsBVULT() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_ULT; + } + + /** + * Indicates whether the term is a signed bit-vector less-than + **/ + public boolean IsBVSLT() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SLT; + } + + /** + * Indicates whether the term is an unsigned bit-vector greater-than + **/ + public boolean IsBVUGT() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_UGT; + } + + /** + * Indicates whether the term is a signed bit-vector greater-than + **/ + public boolean IsBVSGT() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SGT; + } + + /** + * Indicates whether the term is a bit-wise AND + **/ + public boolean IsBVAND() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BAND; + } + + /** + * Indicates whether the term is a bit-wise OR + **/ + public boolean IsBVOR() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BOR; + } + + /** + * Indicates whether the term is a bit-wise NOT + **/ + public boolean IsBVNOT() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BNOT; + } + + /** + * Indicates whether the term is a bit-wise XOR + **/ + public boolean IsBVXOR() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BXOR; + } + + /** + * Indicates whether the term is a bit-wise NAND + **/ + public boolean IsBVNAND() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BNAND; + } + + /** + * Indicates whether the term is a bit-wise NOR + **/ + public boolean IsBVNOR() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BNOR; + } + + /** + * Indicates whether the term is a bit-wise XNOR + **/ + public boolean IsBVXNOR() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BXNOR; + } + + /** + * Indicates whether the term is a bit-vector concatenation (binary) + **/ + public boolean IsBVConcat() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_CONCAT; + } + + /** + * Indicates whether the term is a bit-vector sign extension + **/ + public boolean IsBVSignExtension() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_SIGN_EXT; + } + + /** + * Indicates whether the term is a bit-vector zero extension + **/ + public boolean IsBVZeroExtension() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_ZERO_EXT; + } + + /** + * Indicates whether the term is a bit-vector extraction + **/ + public boolean IsBVExtract() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_EXTRACT; + } + + /** + * Indicates whether the term is a bit-vector repetition + **/ + public boolean IsBVRepeat() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_REPEAT; + } + + /** + * Indicates whether the term is a bit-vector reduce OR + **/ + public boolean IsBVReduceOR() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BREDOR; + } + + /** + * Indicates whether the term is a bit-vector reduce AND + **/ + public boolean IsBVReduceAND() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BREDAND; + } + + /** + * Indicates whether the term is a bit-vector comparison + **/ + public boolean IsBVComp() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BCOMP; + } + + /** + * Indicates whether the term is a bit-vector shift left + **/ + public boolean IsBVShiftLeft() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BSHL; + } + + /** + * Indicates whether the term is a bit-vector logical shift right + **/ + public boolean IsBVShiftRightLogical() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BLSHR; + } + + /** + * Indicates whether the term is a bit-vector arithmetic shift left + **/ + public boolean IsBVShiftRightArithmetic() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BASHR; + } + + /** + * Indicates whether the term is a bit-vector rotate left + **/ + public boolean IsBVRotateLeft() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_ROTATE_LEFT; + } + + /** + * Indicates whether the term is a bit-vector rotate right + **/ + public boolean IsBVRotateRight() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_ROTATE_RIGHT; + } + + /** + * Indicates whether the term is a bit-vector rotate left (extended) + * Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator + * instead of a parametric one. + **/ + public boolean IsBVRotateLeftExtended() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_EXT_ROTATE_LEFT; + } + + /** + * Indicates whether the term is a bit-vector rotate right (extended) + * Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator + * instead of a parametric one. + **/ + public boolean IsBVRotateRightExtended() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_EXT_ROTATE_RIGHT; + } + + /** + * Indicates whether the term is a coercion from integer to bit-vector + * This function is not supported by the decision procedures. Only + * the most rudimentary simplification rules are applied to this + * function. + **/ + public boolean IsIntToBV() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_INT2BV; + } + + /** + * Indicates whether the term is a coercion from bit-vector to integer + * This function is not supported by the decision procedures. Only + * the most rudimentary simplification rules are applied to this + * function. + **/ + public boolean IsBVToInt() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_BV2INT; + } + + /** + * Indicates whether the term is a bit-vector carry Compute the + * carry bit in a full-adder. The meaning is given by the equivalence (carry + * l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) + **/ + public boolean IsBVCarry() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_CARRY; + } + + /** + * Indicates whether the term is a bit-vector ternary XOR The + * meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor + * l1 l2) l3) + **/ + public boolean IsBVXOR3() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_XOR3; + } + + /** + * Indicates whether the term is a label (used by the Boogie Verification + * condition generator). The label has two parameters, a string and + * a Boolean polarity. It takes one argument, a formula. + **/ + public boolean IsLabel() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_LABEL; + } + + /** + * Indicates whether the term is a label literal (used by the Boogie + * Verification condition generator). A label literal has a set of + * string parameters. It takes no arguments. + **/ + public boolean IsLabelLit() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_LABEL_LIT; + } + + /** + * Indicates whether the term is a binary equivalence modulo namings. + * This binary predicate is used in proof terms. It captures + * equisatisfiability and equivalence modulo renamings. + **/ + public boolean IsOEQ() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_OEQ; + } + + /** + * Indicates whether the term is a Proof for the expression 'true'. + **/ + public boolean IsProofTrue() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_TRUE; + } + + /** + * Indicates whether the term is a proof for a fact asserted by the user. + **/ + public boolean IsProofAsserted() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_ASSERTED; + } + + /** + * Indicates whether the term is a proof for a fact (tagged as goal) + * asserted by the user. + **/ + public boolean IsProofGoal() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_GOAL; + } + + /** + * Indicates whether the term is proof via modus ponens Given a + * proof for p and a proof for (implies p q), produces a proof for q. T1: p + * T2: (implies p q) [mp T1 T2]: q The second antecedents may also be a + * proof for (iff p q). + **/ + public boolean IsProofModusPonens() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_MODUS_PONENS; + } + + /** + * Indicates whether the term is a proof for (R t t), where R is a reflexive + * relation. This proof object has no antecedents. The only + * reflexive relations that are used are equivalence modulo namings, + * equality and equivalence. That is, R is either '~', '=' or + * 'iff'. + **/ + public boolean IsProofReflexivity() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_REFLEXIVITY; + } + + /** + * Indicates whether the term is proof by symmetricity of a relation + * Given an symmetric relation R and a proof for (R t s), produces + * a proof for (R s t). T1: (R t s) [symmetry T1]: (R s t) T1 is the + * antecedent of this proof object. + **/ + public boolean IsProofSymmetry() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_SYMMETRY; + } + + /** + * Indicates whether the term is a proof by transitivity of a relation + * Given a transitive relation R, and proofs for (R t s) and (R s + * u), produces a proof for (R t u). T1: (R t s) T2: (R s u) [trans T1 T2]: + * (R t u) + **/ + public boolean IsProofTransitivity() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_TRANSITIVITY; + } + + /** + * Indicates whether the term is a proof by condensed transitivity of a + * relation Condensed transitivity proof. This proof object is + * only used if the parameter PROOF_MODE is 1. It combines several symmetry + * and transitivity proofs. Example: T1: (R a b) T2: (R c b) T3: (R c d) + * [trans* T1 T2 T3]: (R a d) R must be a symmetric and transitive relation. + * + * Assuming that this proof object is a proof for (R s t), then a proof + * checker must check if it is possible to prove (R s t) using the + * antecedents, symmetry and transitivity. That is, if there is a path from + * s to t, if we view every antecedent (R a b) as an edge between a and b. + * + **/ + public boolean IsProofTransitivityStar() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_TRANSITIVITY_STAR; + } + + /** + * Indicates whether the term is a monotonicity proof object. T1: + * (R t_1 s_1) ... Tn: (R t_n s_n) [monotonicity T1 ... Tn]: (R (f t_1 ... + * t_n) (f s_1 ... s_n)) Remark: if t_i == s_i, then the antecedent Ti is + * suppressed. That is, reflexivity proofs are supressed to save space. + * + **/ + public boolean IsProofMonotonicity() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_MONOTONICITY; + } + + /** + * Indicates whether the term is a quant-intro proof Given a proof + * for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). T1: + * (~ p q) [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) + **/ + public boolean IsProofQuantIntro() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_QUANT_INTRO; + } + + /** + * Indicates whether the term is a distributivity proof object. + * Given that f (= or) distributes over g (= and), produces a proof for (= + * (f a (g c d)) (g (f a c) (f a d))) If f and g are associative, this proof + * also justifies the following equality: (= (f (g a b) (g c d)) (g (f a c) + * (f a d) (f b c) (f b d))) where each f and g can have arbitrary number of + * arguments. + * + * This proof object has no antecedents. Remark. This rule is used by the + * CNF conversion pass and instantiated by f = or, and g = and. + **/ + public boolean IsProofDistributivity() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_DISTRIBUTIVITY; + } + + /** + * Indicates whether the term is a proof by elimination of AND + * Given a proof for (and l_1 ... l_n), produces a proof for l_i T1: (and + * l_1 ... l_n) [and-elim T1]: l_i + **/ + public boolean IsProofAndElimination() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_AND_ELIM; + } + + /** + * Indicates whether the term is a proof by eliminiation of not-or + * Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). + * T1: (not (or l_1 ... l_n)) [not-or-elim T1]: (not l_i) + **/ + public boolean IsProofOrElimination() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_NOT_OR_ELIM; + } + + /** + * Indicates whether the term is a proof by rewriting A proof for + * a local rewriting step (= t s). The head function symbol of t is + * interpreted. + * + * This proof object has no antecedents. The conclusion of a rewrite rule is + * either an equality (= t s), an equivalence (iff t s), or + * equi-satisfiability (~ t s). Remark: if f is bool, then = is iff. + * + * Examples: (= (+ x 0) x) (= (+ x 1 2) (+ 3 x)) (iff (or x false) x) + * + **/ + public boolean IsProofRewrite() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_REWRITE; + } + + /** + * Indicates whether the term is a proof by rewriting A proof for + * rewriting an expression t into an expression s. This proof object is used + * if the parameter PROOF_MODE is 1. This proof object can have n + * antecedents. The antecedents are proofs for equalities used as + * substitution rules. The object is also used in a few cases if the + * parameter PROOF_MODE is 2. The cases are: - When applying contextual + * simplification (CONTEXT_SIMPLIFIER=true) - When converting bit-vectors to + * Booleans (BIT2BOOL=true) - When pulling ite expression up + * (PULL_CHEAP_ITE_TREES=true) + **/ + public boolean IsProofRewriteStar() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_REWRITE_STAR; + } + + /** + * Indicates whether the term is a proof for pulling quantifiers out. + * A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) + * r))). This proof object has no antecedents. + **/ + public boolean IsProofPullQuant() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_PULL_QUANT; + } + + /** + * Indicates whether the term is a proof for pulling quantifiers out. + * A proof for (iff P Q) where Q is in prenex normal form. This + * proof object is only used if the parameter PROOF_MODE is 1. This proof + * object has no antecedents + **/ + public boolean IsProofPullQuantStar() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_PULL_QUANT_STAR; + } + + /** + * Indicates whether the term is a proof for pushing quantifiers in. + * A proof for: (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] + * ... p_n[x_1 ... x_m])) (and (forall (x_1 ... x_m) p_1[x_1 ... x_m]) ... + * (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) This proof object has no + * antecedents + **/ + public boolean IsProofPushQuant() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_PUSH_QUANT; + } + + /** + * Indicates whether the term is a proof for elimination of unused + * variables. A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) + * p[x_1 ... x_n]) (forall (x_1 ... x_n) p[x_1 ... x_n])) + * + * It is used to justify the elimination of unused variables. This proof + * object has no antecedents. + **/ + public boolean IsProofElimUnusedVars() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_ELIM_UNUSED_VARS; + } + + /** + * Indicates whether the term is a proof for destructive equality resolution + * A proof for destructive equality resolution: (iff (forall (x) + * (or (not (= x t)) P[x])) P[t]) if x does not occur in t. + * + * This proof object has no antecedents. + * + * Several variables can be eliminated simultaneously. + **/ + public boolean IsProofDER() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_DER; + } + + /** + * Indicates whether the term is a proof for quantifier instantiation + * A proof of (or (not (forall (x) (P x))) (P a)) + **/ + public boolean IsProofQuantInst() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_QUANT_INST; + } + + /** + * Indicates whether the term is a hypthesis marker. Mark a + * hypothesis in a natural deduction style proof. + **/ + public boolean IsProofHypothesis() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_HYPOTHESIS; + } + + /** + * Indicates whether the term is a proof by lemma T1: false [lemma + * T1]: (or (not l_1) ... (not l_n)) + * + * This proof object has one antecedent: a hypothetical proof for false. It + * converts the proof in a proof for (or (not l_1) ... (not l_n)), when T1 + * contains the hypotheses: l_1, ..., l_n. + **/ + public boolean IsProofLemma() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_LEMMA; + } + + /** + * Indicates whether the term is a proof by unit resolution T1: + * (or l_1 ... l_n l_1' ... l_m') T2: (not l_1) ... T(n+1): (not l_n) + * [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') + **/ + public boolean IsProofUnitResolution() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_UNIT_RESOLUTION; + } + + /** + * Indicates whether the term is a proof by iff-true T1: p + * [iff-true T1]: (iff p true) + **/ + public boolean IsProofIFFTrue() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_IFF_TRUE; + } + + /** + * Indicates whether the term is a proof by iff-false T1: (not p) + * [iff-false T1]: (iff p false) + **/ + public boolean IsProofIFFFalse() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_IFF_FALSE; + } + + /** + * Indicates whether the term is a proof by commutativity [comm]: + * (= (f a b) (f b a)) + * + * f is a commutative operator. + * + * This proof object has no antecedents. Remark: if f is bool, then = is + * iff. + **/ + public boolean IsProofCommutativity() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_COMMUTATIVITY; + } + + /** + * Indicates whether the term is a proof for Tseitin-like axioms + * Proof object used to justify Tseitin's like axioms: + * + * (or (not (and p q)) p) (or (not (and p q)) q) (or (not (and p q r)) p) + * (or (not (and p q r)) q) (or (not (and p q r)) r) ... (or (and p q) (not + * p) (not q)) (or (not (or p q)) p q) (or (or p q) (not p)) (or (or p q) + * (not q)) (or (not (iff p q)) (not p) q) (or (not (iff p q)) p (not q)) + * (or (iff p q) (not p) (not q)) (or (iff p q) p q) (or (not (ite a b c)) + * (not a) b) (or (not (ite a b c)) a c) (or (ite a b c) (not a) (not b)) + * (or (ite a b c) a (not c)) (or (not (not a)) (not a)) (or (not a) a) + * + * This proof object has no antecedents. Note: all axioms are propositional + * tautologies. Note also that 'and' and 'or' can take multiple arguments. + * You can recover the propositional tautologies by unfolding the Boolean + * connectives in the axioms a small bounded number of steps (=3). + * + **/ + public boolean IsProofDefAxiom() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_DEF_AXIOM; + } + + /** + * Indicates whether the term is a proof for introduction of a name + * Introduces a name for a formula/term. Suppose e is an + * expression with free variables x, and def-intro introduces the name n(x). + * The possible cases are: + * + * When e is of Boolean type: [def-intro]: (and (or n (not e)) (or (not n) + * e)) + * + * or: [def-intro]: (or (not n) e) when e only occurs positively. + * + * When e is of the form (ite cond th el): [def-intro]: (and (or (not cond) + * (= n th)) (or cond (= n el))) + * + * Otherwise: [def-intro]: (= n e) + **/ + public boolean IsProofDefIntro() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_DEF_INTRO; + } + + /** + * Indicates whether the term is a proof for application of a definition + * [apply-def T1]: F ~ n F is 'equivalent' to n, given that T1 is + * a proof that n is a name for F. + **/ + public boolean IsProofApplyDef() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_APPLY_DEF; + } + + /** + * Indicates whether the term is a proof iff-oeq T1: (iff p q) + * [iff~ T1]: (~ p q) + **/ + public boolean IsProofIFFOEQ() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_IFF_OEQ; + } + + /** + * Indicates whether the term is a proof for a positive NNF step + * Proof for a (positive) NNF step. Example: + * + * T1: (not s_1) ~ r_1 T2: (not s_2) ~ r_2 T3: s_1 ~ r_1' T4: s_2 ~ r_2' + * [nnf-pos T1 T2 T3 T4]: (~ (iff s_1 s_2) (and (or r_1 r_2') (or r_1' + * r_2))) + * + * The negation normal form steps NNF_POS and NNF_NEG are used in the + * following cases: (a) When creating the NNF of a positive force + * quantifier. The quantifier is retained (unless the bound variables are + * eliminated). Example T1: q ~ q_new [nnf-pos T1]: (~ (forall (x T) q) + * (forall (x T) q_new)) + * + * (b) When recursively creating NNF over Boolean formulas, where the + * top-level connective is changed during NNF conversion. The relevant + * Boolean connectives for NNF_POS are 'implies', 'iff', 'xor', 'ite'. + * NNF_NEG furthermore handles the case where negation is pushed over + * Boolean connectives 'and' and 'or'. + **/ + public boolean IsProofNNFPos() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_NNF_POS; + } + + /** + * Indicates whether the term is a proof for a negative NNF step + * Proof for a (negative) NNF step. Examples: + * + * T1: (not s_1) ~ r_1 ... Tn: (not s_n) ~ r_n [nnf-neg T1 ... Tn]: (not + * (and s_1 ... s_n)) ~ (or r_1 ... r_n) and T1: (not s_1) ~ r_1 ... Tn: + * (not s_n) ~ r_n [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 + * ... r_n) and T1: (not s_1) ~ r_1 T2: (not s_2) ~ r_2 T3: s_1 ~ r_1' T4: + * s_2 ~ r_2' [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) (and (or r_1 + * r_2) (or r_1' r_2'))) + **/ + public boolean IsProofNNFNeg() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_NNF_NEG; + } + + /** + * Indicates whether the term is a proof for (~ P Q) here Q is in negation + * normal form. A proof for (~ P Q) where Q is in negation normal + * form. + * + * This proof object is only used if the parameter PROOF_MODE is 1. + * + * This proof object may have n antecedents. Each antecedent is a + * PR_DEF_INTRO. + **/ + public boolean IsProofNNFStar() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_NNF_STAR; + } + + /** + * Indicates whether the term is a proof for (~ P Q) where Q is in + * conjunctive normal form. A proof for (~ P Q) where Q is in + * conjunctive normal form. This proof object is only used if the parameter + * PROOF_MODE is 1. This proof object may have n antecedents. Each + * antecedent is a PR_DEF_INTRO. + **/ + public boolean IsProofCNFStar() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_CNF_STAR; + } + + /** + * Indicates whether the term is a proof for a Skolemization step + * Proof for: + * + * [sk]: (~ (not (forall x (p x y))) (not (p (sk y) y))) [sk]: (~ (exists x + * (p x y)) (p (sk y) y)) + * + * This proof object has no antecedents. + **/ + public boolean IsProofSkolemize() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_SKOLEMIZE; + } + + /** + * Indicates whether the term is a proof by modus ponens for + * equi-satisfiability. Modus ponens style rule for + * equi-satisfiability. T1: p T2: (~ p q) [mp~ T1 T2]: q + **/ + public boolean IsProofModusPonensOEQ() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_MODUS_PONENS_OEQ; + } + + /** + * Indicates whether the term is a proof for theory lemma Generic + * proof for theory lemmas. + * + * The theory lemma function comes with one or more parameters. The first + * parameter indicates the name of the theory. For the theory of arithmetic, + * additional parameters provide hints for checking the theory lemma. The + * hints for arithmetic are: - farkas - followed by rational coefficients. + * Multiply the coefficients to the inequalities in the lemma, add the + * (negated) inequalities and obtain a contradiction. - triangle-eq - + * Indicates a lemma related to the equivalence: (iff (= t1 t2) (and (<= + * t1 t2) (<= t2 t1))) - gcd-test - Indicates an integer linear + * arithmetic lemma that uses a gcd test. + **/ + public boolean IsProofTheoryLemma() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_PR_TH_LEMMA; + } + + /** + * Indicates whether the term is of an array sort. + **/ + public boolean IsRelation() throws Z3Exception + { + return (Native.isApp(Context().nCtx(), NativeObject()) && Native + .getSortKind(Context().nCtx(), + Native.getSort(Context().nCtx(), NativeObject())) == Z3_sort_kind.Z3_RELATION_SORT + .toInt()); + } + + /** + * Indicates whether the term is an relation store Insert a record + * into a relation. The function takes n+1 arguments, where the + * first argument is the relation and the remaining n elements + * correspond to the n columns of the relation. + **/ + public boolean IsRelationStore() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_STORE; + } + + /** + * Indicates whether the term is an empty relation + **/ + public boolean IsEmptyRelation() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_EMPTY; + } + + /** + * Indicates whether the term is a test for the emptiness of a relation + **/ + public boolean IsIsEmptyRelation() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_IS_EMPTY; + } + + /** + * Indicates whether the term is a relational join + **/ + public boolean IsRelationalJoin() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_JOIN; + } + + /** + * Indicates whether the term is the union or convex hull of two relations. + * The function takes two arguments. + **/ + public boolean IsRelationUnion() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_UNION; + } + + /** + * Indicates whether the term is the widening of two relations The + * function takes two arguments. + **/ + public boolean IsRelationWiden() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_WIDEN; + } + + /** + * Indicates whether the term is a projection of columns (provided as + * numbers in the parameters). The function takes one + * argument. + **/ + public boolean IsRelationProject() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_PROJECT; + } + + /** + * Indicates whether the term is a relation filter Filter + * (restrict) a relation with respect to a predicate. The first argument is + * a relation. The second argument is a predicate with free de-Brujin + * indices corresponding to the columns of the relation. So the first column + * in the relation has index 0. + **/ + public boolean IsRelationFilter() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_FILTER; + } + + /** + * Indicates whether the term is an intersection of a relation with the + * negation of another. Intersect the first relation with respect + * to negation of the second relation (the function takes two arguments). + * Logically, the specification can be described by a function + * + * target = filter_by_negation(pos, neg, columns) + * + * where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, + * such that target are elements in x in pos, such that there is no y in neg + * that agrees with x on the columns c1, d1, .., cN, dN. + **/ + public boolean IsRelationNegationFilter() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_NEGATION_FILTER; + } + + /** + * Indicates whether the term is the renaming of a column in a relation + * The function takes one argument. The parameters contain the + * renaming as a cycle. + **/ + public boolean IsRelationRename() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_RENAME; + } + + /** + * Indicates whether the term is the complement of a relation + **/ + public boolean IsRelationComplement() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_COMPLEMENT; + } + + /** + * Indicates whether the term is a relational select Check if a + * record is an element of the relation. The function takes n+1 + * arguments, where the first argument is a relation, and the remaining + * n arguments correspond to a record. + **/ + public boolean IsRelationSelect() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_SELECT; + } + + /** + * Indicates whether the term is a relational clone (copy) Create + * a fresh copy (clone) of a relation. The function is logically the + * identity, but in the context of a register machine allows for terms of + * kind to perform destructive updates to + * the first argument. + **/ + public boolean IsRelationClone() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_RA_CLONE; + } + + /** + * Indicates whether the term is of an array sort. + **/ + public boolean IsFiniteDomain() throws Z3Exception + { + return (Native.isApp(Context().nCtx(), NativeObject()) && Native + .getSortKind(Context().nCtx(), + Native.getSort(Context().nCtx(), NativeObject())) == Z3_sort_kind.Z3_FINITE_DOMAIN_SORT + .toInt()); + } + + /** + * Indicates whether the term is a less than predicate over a finite domain. + **/ + public boolean IsFiniteDomainLT() throws Z3Exception + { + return FuncDecl().DeclKind() == Z3_decl_kind.Z3_OP_FD_LT; + } + + /** + * The de-Burijn index of a bound variable. Bound variables are + * indexed by de-Bruijn indices. It is perhaps easiest to explain the + * meaning of de-Bruijn indices by indicating the compilation process from + * non-de-Bruijn formulas to de-Bruijn format. + * abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) + * abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) + * abs1(x, x, n) = b_n + * abs1(y, x, n) = y + * abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) + * abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) + * The last line is significant: the index of a bound variable is + * different depending on the scope in which it appears. The deeper x + * appears, the higher is its index. + **/ + public int Index() throws Z3Exception + { + if (!IsVar()) + throw new Z3Exception("Term is not a bound variable."); + + return Native.getIndexValue(Context().nCtx(), NativeObject()); + } + + /** + * Constructor for Expr + **/ + protected Expr(Context ctx) + { + super(ctx); + { + } + } + + /** + * Constructor for Expr + **/ + protected Expr(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + { + } + } + + void CheckNativeObject(long obj) throws Z3Exception + { + if (Native.isApp(Context().nCtx(), obj) + ^ true + && Native.getAstKind(Context().nCtx(), obj) != Z3_ast_kind.Z3_VAR_AST + .toInt() + && Native.getAstKind(Context().nCtx(), obj) != Z3_ast_kind.Z3_QUANTIFIER_AST + .toInt()) + throw new Z3Exception("Underlying object is not a term"); + super.CheckNativeObject(obj); + } + + static Expr Create(Context ctx, FuncDecl f, Expr[] arguments) + throws Z3Exception + { + + long obj = Native.mkApp(ctx.nCtx(), f.NativeObject(), + AST.ArrayLength(arguments), AST.ArrayToNative(arguments)); + return Create(ctx, obj); + } + + static Expr Create(Context ctx, long obj) throws Z3Exception + { + + Z3_ast_kind k = Z3_ast_kind.fromInt(Native.getAstKind(ctx.nCtx(), obj)); + if (k == Z3_ast_kind.Z3_QUANTIFIER_AST) + return new Quantifier(ctx, obj); + long s = Native.getSort(ctx.nCtx(), obj); + Z3_sort_kind sk = Z3_sort_kind + .fromInt(Native.getSortKind(ctx.nCtx(), s)); + + if (Native.isAlgebraicNumber(ctx.nCtx(), obj)) // is this a numeral ast? + return new AlgebraicNum(ctx, obj); + + if (Native.isNumeralAst(ctx.nCtx(), obj)) + { + switch (sk) + { + case Z3_INT_SORT: + return new IntNum(ctx, obj); + case Z3_REAL_SORT: + return new RatNum(ctx, obj); + case Z3_BV_SORT: + return new BitVecNum(ctx, obj); + default: ; + } + } + + switch (sk) + { + case Z3_BOOL_SORT: + return new BoolExpr(ctx, obj); + case Z3_INT_SORT: + return new IntExpr(ctx, obj); + case Z3_REAL_SORT: + return new RealExpr(ctx, obj); + case Z3_BV_SORT: + return new BitVecExpr(ctx, obj); + case Z3_ARRAY_SORT: + return new ArrayExpr(ctx, obj); + case Z3_DATATYPE_SORT: + return new DatatypeExpr(ctx, obj); + default: ; + } + + return new Expr(ctx, obj); + } +} diff --git a/src/api/java/FiniteDomainSort.java b/src/api/java/FiniteDomainSort.java new file mode 100644 index 000000000..8c39320ad --- /dev/null +++ b/src/api/java/FiniteDomainSort.java @@ -0,0 +1,34 @@ +/** + * This file was automatically generated from FiniteDomainSort.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Finite domain sorts. + **/ +public class FiniteDomainSort extends Sort +{ + /** + * The size of the finite domain sort. + **/ + public long Size() throws Z3Exception + { + Native.LongPtr res = new Native.LongPtr(); + Native.getFiniteDomainSortSize(Context().nCtx(), NativeObject(), res); + return res.value; + } + + FiniteDomainSort(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + FiniteDomainSort(Context ctx, Symbol name, long size) throws Z3Exception + { + super(ctx, Native.mkFiniteDomainSort(ctx.nCtx(), name.NativeObject(), + size)); + } +} diff --git a/src/api/java/Fixedpoint.java b/src/api/java/Fixedpoint.java new file mode 100644 index 000000000..375cb7b97 --- /dev/null +++ b/src/api/java/Fixedpoint.java @@ -0,0 +1,333 @@ +/** + * This file was automatically generated from Fixedpoint.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +import com.microsoft.z3.enumerations.*; + +/** + * Object for managing fixedpoints + **/ +public class Fixedpoint extends Z3Object +{ + + /** + * A string that describes all available fixedpoint solver parameters. + **/ + public String Help() throws Z3Exception + { + return Native.fixedpointGetHelp(Context().nCtx(), NativeObject()); + } + + /** + * Sets the fixedpoint solver parameters. + * + * @throws Z3Exception + **/ + public void setParameters(Params value) throws Z3Exception + { + + Context().CheckContextMatch(value); + Native.fixedpointSetParams(Context().nCtx(), NativeObject(), + value.NativeObject()); + } + + /** + * Retrieves parameter descriptions for Fixedpoint solver. + * + * @throws Z3Exception + **/ + public ParamDescrs ParameterDescriptions() throws Z3Exception + { + return new ParamDescrs(Context(), Native.fixedpointGetParamDescrs( + Context().nCtx(), NativeObject())); + } + + /** + * Assert a constraint (or multiple) into the fixedpoint solver. + * + * @throws Z3Exception + **/ + public void Assert(BoolExpr[] constraints) throws Z3Exception + { + Context().CheckContextMatch(constraints); + for (BoolExpr a : constraints) + { + Native.fixedpointAssert(Context().nCtx(), NativeObject(), + a.NativeObject()); + } + } + + /** + * Register predicate as recursive relation. + * + * @throws Z3Exception + **/ + public void RegisterRelation(FuncDecl f) throws Z3Exception + { + + Context().CheckContextMatch(f); + Native.fixedpointRegisterRelation(Context().nCtx(), NativeObject(), + f.NativeObject()); + } + + /** + * Add rule into the fixedpoint solver. + * + * @throws Z3Exception + **/ + public void AddRule(BoolExpr rule, Symbol name) throws Z3Exception + { + + Context().CheckContextMatch(rule); + Native.fixedpointAddRule(Context().nCtx(), NativeObject(), + rule.NativeObject(), AST.GetNativeObject(name)); + } + + /** + * Add table fact to the fixedpoint solver. + * + * @throws Z3Exception + **/ + public void AddFact(FuncDecl pred, int[] args) throws Z3Exception + { + + Context().CheckContextMatch(pred); + Native.fixedpointAddFact(Context().nCtx(), NativeObject(), + pred.NativeObject(), (int) args.length, args); + } + + /** + * Query the fixedpoint solver. A query is a conjunction of constraints. The + * constraints may include the recursively defined relations. The query is + * satisfiable if there is an instance of the query variables and a + * derivation for it. The query is unsatisfiable if there are no derivations + * satisfying the query variables. + * + * @throws Z3Exception + **/ + public Status Query(BoolExpr query) throws Z3Exception + { + + Context().CheckContextMatch(query); + Z3_lbool r = Z3_lbool.fromInt(Native.fixedpointQuery(Context().nCtx(), + NativeObject(), query.NativeObject())); + switch (r) + { + case Z3_L_TRUE: + return Status.SATISFIABLE; + case Z3_L_FALSE: + return Status.UNSATISFIABLE; + default: + return Status.UNKNOWN; + } + } + + /** + * Query the fixedpoint solver. A query is an array of relations. The query + * is satisfiable if there is an instance of some relation that is + * non-empty. The query is unsatisfiable if there are no derivations + * satisfying any of the relations. + * + * @throws Z3Exception + **/ + public Status Query(FuncDecl[] relations) throws Z3Exception + { + + Context().CheckContextMatch(relations); + Z3_lbool r = Z3_lbool.fromInt(Native.fixedpointQueryRelations(Context() + .nCtx(), NativeObject(), AST.ArrayLength(relations), AST + .ArrayToNative(relations))); + switch (r) + { + case Z3_L_TRUE: + return Status.SATISFIABLE; + case Z3_L_FALSE: + return Status.UNSATISFIABLE; + default: + return Status.UNKNOWN; + } + } + + /** + * Creates a backtracking point. + **/ + public void Push() throws Z3Exception + { + Native.fixedpointPush(Context().nCtx(), NativeObject()); + } + + /** + * Backtrack one backtracking point. Note that an exception is + * thrown if Pop is called without a corresponding Push + * + **/ + public void Pop() throws Z3Exception + { + Native.fixedpointPop(Context().nCtx(), NativeObject()); + } + + /** + * Update named rule into in the fixedpoint solver. + * + * @throws Z3Exception + **/ + public void UpdateRule(BoolExpr rule, Symbol name) throws Z3Exception + { + + Context().CheckContextMatch(rule); + Native.fixedpointUpdateRule(Context().nCtx(), NativeObject(), + rule.NativeObject(), AST.GetNativeObject(name)); + } + + /** + * Retrieve satisfying instance or instances of solver, or definitions for + * the recursive predicates that show unsatisfiability. + * + * @throws Z3Exception + **/ + public Expr GetAnswer() throws Z3Exception + { + long ans = Native.fixedpointGetAnswer(Context().nCtx(), NativeObject()); + return (ans == 0) ? null : Expr.Create(Context(), ans); + } + + /** + * Retrieve explanation why fixedpoint engine returned status Unknown. + **/ + public String GetReasonUnknown() throws Z3Exception + { + + return Native.fixedpointGetReasonUnknown(Context().nCtx(), + NativeObject()); + } + + /** + * Retrieve the number of levels explored for a given predicate. + **/ + public int GetNumLevels(FuncDecl predicate) throws Z3Exception + { + return Native.fixedpointGetNumLevels(Context().nCtx(), NativeObject(), + predicate.NativeObject()); + } + + /** + * Retrieve the cover of a predicate. + * + * @throws Z3Exception + **/ + public Expr GetCoverDelta(int level, FuncDecl predicate) throws Z3Exception + { + long res = Native.fixedpointGetCoverDelta(Context().nCtx(), + NativeObject(), level, predicate.NativeObject()); + return (res == 0) ? null : Expr.Create(Context(), res); + } + + /** + * Add property about the predicate. The property is added + * at level. + **/ + public void AddCover(int level, FuncDecl predicate, Expr property) + throws Z3Exception + { + Native.fixedpointAddCover(Context().nCtx(), NativeObject(), level, + predicate.NativeObject(), property.NativeObject()); + } + + /** + * Retrieve internal string representation of fixedpoint object. + **/ + public String toString() + { + try + { + return Native.fixedpointToString(Context().nCtx(), NativeObject(), + 0, null); + } catch (Z3Exception e) + { + return "Z3Exception: " + e.getMessage(); + } + } + + /** + * Instrument the Datalog engine on which table representation to use for + * recursive predicate. + **/ + public void SetPredicateRepresentation(FuncDecl f, Symbol[] kinds) throws Z3Exception + { + + Native.fixedpointSetPredicateRepresentation(Context().nCtx(), + NativeObject(), f.NativeObject(), AST.ArrayLength(kinds), + Symbol.ArrayToNative(kinds)); + + } + + /** + * Convert benchmark given as set of axioms, rules and queries to a string. + **/ + public String toString(BoolExpr[] queries) throws Z3Exception + { + + return Native.fixedpointToString(Context().nCtx(), NativeObject(), + AST.ArrayLength(queries), AST.ArrayToNative(queries)); + } + + /** + * Retrieve set of rules added to fixedpoint context. + * + * @throws Z3Exception + **/ + public BoolExpr[] Rules() throws Z3Exception + { + + ASTVector v = new ASTVector(Context(), Native.fixedpointGetRules( + Context().nCtx(), NativeObject())); + int n = v.Size(); + BoolExpr[] res = new BoolExpr[n]; + for (int i = 0; i < n; i++) + res[i] = new BoolExpr(Context(), v.get(i).NativeObject()); + return res; + } + + /** + * Retrieve set of assertions added to fixedpoint context. + * + * @throws Z3Exception + **/ + public BoolExpr[] Assertions() throws Z3Exception + { + + ASTVector v = new ASTVector(Context(), Native.fixedpointGetAssertions( + Context().nCtx(), NativeObject())); + int n = v.Size(); + BoolExpr[] res = new BoolExpr[n]; + for (int i = 0; i < n; i++) + res[i] = new BoolExpr(Context(), v.get(i).NativeObject()); + return res; + } + + Fixedpoint(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + Fixedpoint(Context ctx) throws Z3Exception + { + super(ctx, Native.mkFixedpoint(ctx.nCtx())); + } + + void IncRef(long o) throws Z3Exception + { + Context().Fixedpoint_DRQ().IncAndClear(Context(), o); + super.IncRef(o); + } + + void DecRef(long o) throws Z3Exception + { + Context().Fixedpoint_DRQ().Add(o); + super.DecRef(o); + } +} diff --git a/src/api/java/FixedpointDecRefQueue.java b/src/api/java/FixedpointDecRefQueue.java new file mode 100644 index 000000000..677691db8 --- /dev/null +++ b/src/api/java/FixedpointDecRefQueue.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2012 Microsoft Corporation + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +class FixedpointDecRefQueue extends IDecRefQueue +{ + public void IncRef(Context ctx, long obj) + { + try + { + Native.fixedpointIncRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } + + public void DecRef(Context ctx, long obj) + { + try + { + Native.fixedpointDecRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } +}; diff --git a/src/api/java/FuncDecl.java b/src/api/java/FuncDecl.java new file mode 100644 index 000000000..a2bf28c5d --- /dev/null +++ b/src/api/java/FuncDecl.java @@ -0,0 +1,397 @@ +/** + * This file was automatically generated from FuncDecl.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +import com.microsoft.z3.enumerations.*; + +/** + * Function declarations. + **/ +public class FuncDecl extends AST +{ + /** + * Comparison operator. + * + * @return True if and share the + * same context and are equal, false otherwise. + **/ + /* Overloaded operators are not translated. */ + + /** + * Comparison operator. + * + * @return True if and do not + * share the same context or are not equal, false otherwise. + **/ + /* Overloaded operators are not translated. */ + + /** + * Object comparison. + **/ + public boolean Equals(Object o) + { + FuncDecl casted = (FuncDecl) o; + if (casted == null) + return false; + return this == casted; + } + + /** + * A hash code. + **/ + public int GetHashCode() throws Z3Exception + { + return super.GetHashCode(); + } + + /** + * A string representations of the function declaration. + **/ + public String toString() + { + try + { + return Native.funcDeclToString(Context().nCtx(), NativeObject()); + } catch (Z3Exception e) + { + return "Z3Exception: " + e.getMessage(); + } + } + + /** + * Returns a unique identifier for the function declaration. + **/ + public int Id() throws Z3Exception + { + return Native.getFuncDeclId(Context().nCtx(), NativeObject()); + } + + /** + * The arity of the function declaration + **/ + public int Arity() throws Z3Exception + { + return Native.getArity(Context().nCtx(), NativeObject()); + } + + /** + * The size of the domain of the function declaration + **/ + public int DomainSize() throws Z3Exception + { + return Native.getDomainSize(Context().nCtx(), NativeObject()); + } + + /** + * The domain of the function declaration + **/ + public Sort[] Domain() throws Z3Exception + { + + int n = DomainSize(); + + Sort[] res = new Sort[n]; + for (int i = 0; i < n; i++) + res[i] = Sort.Create(Context(), + Native.getDomain(Context().nCtx(), NativeObject(), i)); + return res; + } + + /** + * The range of the function declaration + **/ + public Sort Range() throws Z3Exception + { + + return Sort.Create(Context(), + Native.getRange(Context().nCtx(), NativeObject())); + } + + /** + * The kind of the function declaration. + **/ + public Z3_decl_kind DeclKind() throws Z3Exception + { + return Z3_decl_kind.fromInt(Native.getDeclKind(Context().nCtx(), + NativeObject())); + } + + /** + * The name of the function declaration + **/ + public Symbol Name() throws Z3Exception + { + + return Symbol.Create(Context(), + Native.getDeclName(Context().nCtx(), NativeObject())); + } + + /** + * The number of parameters of the function declaration + **/ + public int NumParameters() throws Z3Exception + { + return Native.getDeclNumParameters(Context().nCtx(), NativeObject()); + } + + /** + * The parameters of the function declaration + **/ + public Parameter[] Parameters() throws Z3Exception + { + + int num = NumParameters(); + Parameter[] res = new Parameter[num]; + for (int i = 0; i < num; i++) + { + Z3_parameter_kind k = Z3_parameter_kind.fromInt(Native + .getDeclParameterKind(Context().nCtx(), NativeObject(), i)); + switch (k) + { + case Z3_PARAMETER_INT: + res[i] = new Parameter(k, Native.getDeclIntParameter(Context() + .nCtx(), NativeObject(), i)); + break; + case Z3_PARAMETER_DOUBLE: + res[i] = new Parameter(k, Native.getDeclDoubleParameter( + Context().nCtx(), NativeObject(), i)); + break; + case Z3_PARAMETER_SYMBOL: + res[i] = new Parameter(k, Symbol.Create(Context(), Native + .getDeclSymbolParameter(Context().nCtx(), + NativeObject(), i))); + break; + case Z3_PARAMETER_SORT: + res[i] = new Parameter(k, Sort.Create(Context(), Native + .getDeclSortParameter(Context().nCtx(), NativeObject(), + i))); + break; + case Z3_PARAMETER_AST: + res[i] = new Parameter(k, new AST(Context(), + Native.getDeclAstParameter(Context().nCtx(), + NativeObject(), i))); + break; + case Z3_PARAMETER_FUNC_DECL: + res[i] = new Parameter(k, new FuncDecl(Context(), + Native.getDeclFuncDeclParameter(Context().nCtx(), + NativeObject(), i))); + break; + case Z3_PARAMETER_RATIONAL: + res[i] = new Parameter(k, Native.getDeclRationalParameter( + Context().nCtx(), NativeObject(), i)); + break; + default: + throw new Z3Exception( + "Unknown function declaration parameter kind encountered"); + } + } + return res; + } + + /** + * Function declarations can have Parameters associated with them. + **/ + public class Parameter + { + private Z3_parameter_kind kind; + private int i; + private double d; + private Symbol sym; + private Sort srt; + private AST ast; + private FuncDecl fd; + private String r; + + /** + * The int value of the parameter. + **/ + public int Int() throws Z3Exception + { + if (ParameterKind() != Z3_parameter_kind.Z3_PARAMETER_INT) + throw new Z3Exception("parameter is not an int"); + return i; + } + + /** + * The double value of the parameter. + **/ + public double Double() throws Z3Exception + { + if (ParameterKind() != Z3_parameter_kind.Z3_PARAMETER_DOUBLE) + throw new Z3Exception("parameter is not a double "); + return d; + } + + /** + * The Symbol value of the parameter. + **/ + public Symbol Symbol() throws Z3Exception + { + if (ParameterKind() != Z3_parameter_kind.Z3_PARAMETER_SYMBOL) + throw new Z3Exception("parameter is not a Symbol"); + return sym; + } + + /** + * The Sort value of the parameter. + **/ + public Sort Sort() throws Z3Exception + { + if (ParameterKind() != Z3_parameter_kind.Z3_PARAMETER_SORT) + throw new Z3Exception("parameter is not a Sort"); + return srt; + } + + /** + * The AST value of the parameter. + **/ + public AST AST() throws Z3Exception + { + if (ParameterKind() != Z3_parameter_kind.Z3_PARAMETER_AST) + throw new Z3Exception("parameter is not an AST"); + return ast; + } + + /** + * The FunctionDeclaration value of the parameter. + **/ + public FuncDecl FuncDecl() throws Z3Exception + { + if (ParameterKind() != Z3_parameter_kind.Z3_PARAMETER_FUNC_DECL) + throw new Z3Exception("parameter is not a function declaration"); + return fd; + } + + /** + * The rational string value of the parameter. + **/ + public String Rational() throws Z3Exception + { + if (ParameterKind() != Z3_parameter_kind.Z3_PARAMETER_RATIONAL) + throw new Z3Exception("parameter is not a rational String"); + return r; + } + + /** + * The kind of the parameter. + **/ + public Z3_parameter_kind ParameterKind() throws Z3Exception + { + return kind; + } + + Parameter(Z3_parameter_kind k, int i) + { + this.kind = k; + this.i = i; + } + + Parameter(Z3_parameter_kind k, double d) + { + this.kind = k; + this.d = d; + } + + Parameter(Z3_parameter_kind k, Symbol s) + { + this.kind = k; + this.sym = s; + } + + Parameter(Z3_parameter_kind k, Sort s) + { + this.kind = k; + this.srt = s; + } + + Parameter(Z3_parameter_kind k, AST a) + { + this.kind = k; + this.ast = a; + } + + Parameter(Z3_parameter_kind k, FuncDecl fd) + { + this.kind = k; + this.fd = fd; + } + + Parameter(Z3_parameter_kind k, String r) + { + this.kind = k; + this.r = r; + } + } + + FuncDecl(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + + } + + FuncDecl(Context ctx, Symbol name, Sort[] domain, Sort range) + throws Z3Exception + { + super(ctx, Native.mkFuncDecl(ctx.nCtx(), name.NativeObject(), + AST.ArrayLength(domain), AST.ArrayToNative(domain), + range.NativeObject())); + + } + + FuncDecl(Context ctx, String prefix, Sort[] domain, Sort range) + throws Z3Exception + { + super(ctx, Native.mkFreshFuncDecl(ctx.nCtx(), prefix, + AST.ArrayLength(domain), AST.ArrayToNative(domain), + range.NativeObject())); + + } + + void CheckNativeObject(long obj) throws Z3Exception + { + if (Native.getAstKind(Context().nCtx(), obj) != Z3_ast_kind.Z3_FUNC_DECL_AST + .toInt()) + throw new Z3Exception( + "Underlying object is not a function declaration"); + super.CheckNativeObject(obj); + } + + /** + * Create expression that applies function to arguments. + * + * @return + **/ + /* operator this[] not translated */ + + /** + * Create expression that applies function to arguments. + * + * @return + **/ + public Expr Apply(Expr[] args) throws Z3Exception + { + Context().CheckContextMatch(args); + return Expr.Create(Context(), this, args); + } + + /** + * Create expression that applies function to one argument. + * + * @return + **/ + public Expr Apply(Expr arg) throws Z3Exception + { + Context().CheckContextMatch(arg); + Expr[] a = { arg }; + return Expr.Create(Context(), this, a); + } + +} diff --git a/src/api/java/FuncInterp.java b/src/api/java/FuncInterp.java new file mode 100644 index 000000000..261f433e7 --- /dev/null +++ b/src/api/java/FuncInterp.java @@ -0,0 +1,185 @@ +/** + * This file was automatically generated from FuncInterp.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * A function interpretation is represented as a finite map and an 'else' value. + * Each entry in the finite map represents the value of a function given a set + * of arguments. + **/ +public class FuncInterp extends Z3Object +{ + /** + * An Entry object represents an element in the finite map used to encode a + * function interpretation. + **/ + public class Entry extends Z3Object + { + /** + * Return the (symbolic) value of this entry. + * + * @throws Z3Exception + **/ + public Expr Value() throws Z3Exception + { + return Expr.Create(Context(), + Native.funcEntryGetValue(Context().nCtx(), NativeObject())); + } + + /** + * The number of arguments of the entry. + **/ + public int NumArgs() throws Z3Exception + { + return Native.funcEntryGetNumArgs(Context().nCtx(), NativeObject()); + } + + /** + * The arguments of the function entry. + * + * @throws Z3Exception + **/ + public Expr[] Args() throws Z3Exception + { + int n = NumArgs(); + Expr[] res = new Expr[n]; + for (int i = 0; i < n; i++) + res[i] = Expr.Create(Context(), Native.funcEntryGetArg( + Context().nCtx(), NativeObject(), i)); + return res; + } + + /** + * A string representation of the function entry. + **/ + public String toString() + { + try + { + int n = NumArgs(); + String res = "["; + Expr[] args = Args(); + for (int i = 0; i < n; i++) + res += args[i] + ", "; + return res + Value() + "]"; + } catch (Z3Exception e) + { + return new String("Z3Exception: " + e.getMessage()); + } + } + + Entry(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + void IncRef(long o) throws Z3Exception + { + Context().FuncEntry_DRQ().IncAndClear(Context(), o); + super.IncRef(o); + } + + void DecRef(long o) throws Z3Exception + { + Context().FuncEntry_DRQ().Add(o); + super.DecRef(o); + } + }; + + /** + * The number of entries in the function interpretation. + **/ + public int NumEntries() throws Z3Exception + { + return Native.funcInterpGetNumEntries(Context().nCtx(), NativeObject()); + } + + /** + * The entries in the function interpretation + * + * @throws Z3Exception + **/ + public Entry[] Entries() throws Z3Exception + { + int n = NumEntries(); + Entry[] res = new Entry[n]; + for (int i = 0; i < n; i++) + res[i] = new Entry(Context(), Native.funcInterpGetEntry(Context() + .nCtx(), NativeObject(), i)); + return res; + } + + /** + * The (symbolic) `else' value of the function interpretation. + * + * @throws Z3Exception + **/ + public Expr Else() throws Z3Exception + { + return Expr.Create(Context(), + Native.funcInterpGetElse(Context().nCtx(), NativeObject())); + } + + /** + * The arity of the function interpretation + **/ + public int Arity() throws Z3Exception + { + return Native.funcInterpGetArity(Context().nCtx(), NativeObject()); + } + + /** + * A string representation of the function interpretation. + **/ + public String toString() + { + try + { + String res = ""; + res += "["; + for (Entry e : Entries()) + { + int n = e.NumArgs(); + if (n > 1) + res += "["; + Expr[] args = e.Args(); + for (int i = 0; i < n; i++) + { + if (i != 0) + res += ", "; + res += args[i]; + } + if (n > 1) + res += "]"; + res += " -> " + e.Value() + ", "; + } + res += "else -> " + Else(); + res += "]"; + return res; + } catch (Z3Exception e) + { + return new String("Z3Exception: " + e.getMessage()); + } + } + + FuncInterp(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + void IncRef(long o) throws Z3Exception + { + Context().FuncInterp_DRQ().IncAndClear(Context(), o); + super.IncRef(o); + } + + void DecRef(long o) throws Z3Exception + { + Context().FuncInterp_DRQ().Add(o); + super.DecRef(o); + } +} diff --git a/src/api/java/FuncInterpDecRefQueue.java b/src/api/java/FuncInterpDecRefQueue.java new file mode 100644 index 000000000..d1b662cb2 --- /dev/null +++ b/src/api/java/FuncInterpDecRefQueue.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2012 Microsoft Corporation + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +class FuncInterpDecRefQueue extends IDecRefQueue +{ + public void IncRef(Context ctx, long obj) + { + try + { + Native.funcInterpIncRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } + + public void DecRef(Context ctx, long obj) + { + try + { + Native.funcInterpDecRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } +}; diff --git a/src/api/java/FuncInterpEntryDecRefQueue.java b/src/api/java/FuncInterpEntryDecRefQueue.java new file mode 100644 index 000000000..df2702020 --- /dev/null +++ b/src/api/java/FuncInterpEntryDecRefQueue.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2012 Microsoft Corporation + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +class FuncInterpEntryDecRefQueue extends IDecRefQueue +{ + public void IncRef(Context ctx, long obj) + { + try + { + Native.funcEntryIncRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } + + public void DecRef(Context ctx, long obj) + { + try + { + Native.funcEntryDecRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } +}; diff --git a/src/api/java/Goal.java b/src/api/java/Goal.java new file mode 100644 index 000000000..61ac96d30 --- /dev/null +++ b/src/api/java/Goal.java @@ -0,0 +1,231 @@ +/** + * This file was automatically generated from Goal.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +import com.microsoft.z3.enumerations.*; + +/** + * A goal (aka problem). A goal is essentially a set of formulas, that can be + * solved and/or transformed using tactics and solvers. + **/ +public class Goal extends Z3Object +{ + /** + * The precision of the goal. Goals can be transformed using over + * and under approximations. An under approximation is applied when the + * objective is to find a model for a given goal. An over approximation is + * applied when the objective is to find a proof for a given goal. + * + **/ + public Z3_goal_prec Precision() throws Z3Exception + { + return Z3_goal_prec.fromInt(Native.goalPrecision(Context().nCtx(), + NativeObject())); + } + + /** + * Indicates whether the goal is precise. + **/ + public boolean IsPrecise() throws Z3Exception + { + return Precision() == Z3_goal_prec.Z3_GOAL_PRECISE; + } + + /** + * Indicates whether the goal is an under-approximation. + **/ + public boolean IsUnderApproximation() throws Z3Exception + { + return Precision() == Z3_goal_prec.Z3_GOAL_UNDER; + } + + /** + * Indicates whether the goal is an over-approximation. + **/ + public boolean IsOverApproximation() throws Z3Exception + { + return Precision() == Z3_goal_prec.Z3_GOAL_OVER; + } + + /** + * Indicates whether the goal is garbage (i.e., the product of over- and + * under-approximations). + **/ + public boolean IsGarbage() throws Z3Exception + { + return Precision() == Z3_goal_prec.Z3_GOAL_UNDER_OVER; + } + + /** + * Adds the to the given goal. + * + * @throws Z3Exception + **/ + public void Assert(BoolExpr[] constraints) throws Z3Exception + { + Context().CheckContextMatch(constraints); + for (BoolExpr c : constraints) + { + Native.goalAssert(Context().nCtx(), NativeObject(), + c.NativeObject()); + } + } + + /** + * Adds a to the given goal. + * + * @throws Z3Exception + **/ + public void Assert(BoolExpr constraint) throws Z3Exception + { + Context().CheckContextMatch(constraint); + Native.goalAssert(Context().nCtx(), NativeObject(), + constraint.NativeObject()); + } + + /** + * Indicates whether the goal contains `false'. + **/ + public boolean Inconsistent() throws Z3Exception + { + return Native.goalInconsistent(Context().nCtx(), NativeObject()); + } + + /** + * The depth of the goal. This tracks how many transformations + * were applied to it. + **/ + public int Depth() throws Z3Exception + { + return Native.goalDepth(Context().nCtx(), NativeObject()); + } + + /** + * Erases all formulas from the given goal. + **/ + public void Reset() throws Z3Exception + { + Native.goalReset(Context().nCtx(), NativeObject()); + } + + /** + * The number of formulas in the goal. + **/ + public int Size() throws Z3Exception + { + return Native.goalSize(Context().nCtx(), NativeObject()); + } + + /** + * The formulas in the goal. + * + * @throws Z3Exception + **/ + public BoolExpr[] Formulas() throws Z3Exception + { + int n = Size(); + BoolExpr[] res = new BoolExpr[n]; + for (int i = 0; i < n; i++) + res[i] = new BoolExpr(Context(), Native.goalFormula(Context() + .nCtx(), NativeObject(), i)); + return res; + } + + /** + * The number of formulas, subformulas and terms in the goal. + **/ + public int NumExprs() throws Z3Exception + { + return Native.goalNumExprs(Context().nCtx(), NativeObject()); + } + + /** + * Indicates whether the goal is empty, and it is precise or the product of + * an under approximation. + **/ + public boolean IsDecidedSat() throws Z3Exception + { + return Native.goalIsDecidedSat(Context().nCtx(), NativeObject()); + } + + /** + * Indicates whether the goal contains `false', and it is precise or the + * product of an over approximation. + **/ + public boolean IsDecidedUnsat() throws Z3Exception + { + return Native.goalIsDecidedUnsat(Context().nCtx(), NativeObject()); + } + + /** + * Translates (copies) the Goal to the target Context . + * + * @throws Z3Exception + **/ + public Goal Translate(Context ctx) throws Z3Exception + { + return new Goal(ctx, Native.goalTranslate(Context().nCtx(), + NativeObject(), ctx.nCtx())); + } + + /** + * Simplifies the goal. Essentially invokes the `simplify' tactic + * on the goal. + **/ + public Goal Simplify(Params p) throws Z3Exception + { + Tactic t = Context().MkTactic("simplify"); + ApplyResult res = t.Apply(this, p); + + if (res.NumSubgoals() == 0) + throw new Z3Exception("No subgoals"); + else + return res.Subgoals()[0]; + } + + /** + * Goal to string conversion. + * + * @return A string representation of the Goal. + **/ + public String toString() + { + try + { + return Native.goalToString(Context().nCtx(), NativeObject()); + } catch (Z3Exception e) + { + return "Z3Exception: " + e.getMessage(); + } + } + + Goal(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + Goal(Context ctx, boolean models, boolean unsatCores, boolean proofs) + throws Z3Exception + { + super(ctx, Native.mkGoal(ctx.nCtx(), (models) ? true : false, + (unsatCores) ? true : false, (proofs) ? true : false)); + } + + void IncRef(long o) throws Z3Exception + { + Context().Goal_DRQ().IncAndClear(Context(), o); + super.IncRef(o); + } + + void DecRef(long o) throws Z3Exception + { + Context().Goal_DRQ().Add(o); + super.DecRef(o); + } + +} diff --git a/src/api/java/GoalDecRefQueue.java b/src/api/java/GoalDecRefQueue.java new file mode 100644 index 000000000..7dd52285f --- /dev/null +++ b/src/api/java/GoalDecRefQueue.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2012 Microsoft Corporation + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +class GoalDecRefQueue extends IDecRefQueue +{ + public void IncRef(Context ctx, long obj) + { + try + { + Native.goalIncRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } + + public void DecRef(Context ctx, long obj) + { + try + { + Native.goalDecRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } +}; diff --git a/src/api/java/IDecRefQueue.java b/src/api/java/IDecRefQueue.java new file mode 100644 index 000000000..e4eec7f4f --- /dev/null +++ b/src/api/java/IDecRefQueue.java @@ -0,0 +1,48 @@ +/** + * This file was automatically generated from IDecRefQueue.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +import java.util.*; + +abstract class IDecRefQueue +{ + protected Object m_lock = new Object(); + protected LinkedList m_queue = new LinkedList(); + final int m_move_limit = 1024; + + public abstract void IncRef(Context ctx, long obj); + + public abstract void DecRef(Context ctx, long obj); + + public void IncAndClear(Context ctx, long o) + { + IncRef(ctx, o); + if (m_queue.size() >= m_move_limit) + Clear(ctx); + } + + public void Add(long o) + { + if (o == 0) + return; + + synchronized (m_lock) + { + m_queue.add(o); + } + } + + public void Clear(Context ctx) + { + synchronized (m_lock) + { + for (Long o : m_queue) + DecRef(ctx, o); + m_queue.clear(); + } + } +} diff --git a/src/api/java/com/Microsoft/Z3/IDisposable.java b/src/api/java/IDisposable.java similarity index 76% rename from src/api/java/com/Microsoft/Z3/IDisposable.java rename to src/api/java/IDisposable.java index 03885d1e7..02bbb0ad5 100644 --- a/src/api/java/com/Microsoft/Z3/IDisposable.java +++ b/src/api/java/IDisposable.java @@ -17,9 +17,11 @@ Notes: --*/ -package com.Microsoft.Z3; +package com.microsoft.z3; public class IDisposable { - public void Dispose() {} + public void Dispose() throws Z3Exception + { + } } diff --git a/src/api/java/IntExpr.java b/src/api/java/IntExpr.java new file mode 100644 index 000000000..78cc15f90 --- /dev/null +++ b/src/api/java/IntExpr.java @@ -0,0 +1,26 @@ +/** + * This file was automatically generated from IntExpr.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Int expressions + **/ +public class IntExpr extends ArithExpr +{ + /** + * Constructor for IntExpr + **/ + protected IntExpr(Context ctx) throws Z3Exception + { + super(ctx); + } + + IntExpr(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } +} diff --git a/src/api/java/IntNum.java b/src/api/java/IntNum.java new file mode 100644 index 000000000..1397616c6 --- /dev/null +++ b/src/api/java/IntNum.java @@ -0,0 +1,65 @@ +/** + * This file was automatically generated from IntNum.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +import java.math.BigInteger; + +/** + * Integer Numerals + **/ +public class IntNum extends IntExpr +{ + + IntNum(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + /** + * Retrieve the int value. + **/ + public int Int() throws Z3Exception + { + Native.IntPtr res = new Native.IntPtr(); + if (Native.getNumeralInt(Context().nCtx(), NativeObject(), res) ^ true) + throw new Z3Exception("Numeral is not an int"); + return res.value; + } + + /** + * Retrieve the 64-bit int value. + **/ + public long Int64() throws Z3Exception + { + Native.LongPtr res = new Native.LongPtr(); + if (Native.getNumeralInt64(Context().nCtx(), NativeObject(), res) ^ true) + throw new Z3Exception("Numeral is not an int64"); + return res.value; + } + + /** + * Retrieve the BigInteger value. + **/ + public BigInteger BigInteger() throws Z3Exception + { + return new BigInteger(this.toString()); + } + + /** + * Returns a string representation of the numeral. + **/ + public String toString() + { + try + { + return Native.getNumeralString(Context().nCtx(), NativeObject()); + } catch (Z3Exception e) + { + return "Z3Exception: " + e.getMessage(); + } + } +} diff --git a/src/api/java/IntSort.java b/src/api/java/IntSort.java new file mode 100644 index 000000000..44e48ccd1 --- /dev/null +++ b/src/api/java/IntSort.java @@ -0,0 +1,23 @@ +/** + * This file was automatically generated from IntSort.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * An Integer sort + **/ +public class IntSort extends ArithSort +{ + IntSort(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + IntSort(Context ctx) throws Z3Exception + { + super(ctx, Native.mkIntSort(ctx.nCtx())); + } +} diff --git a/src/api/java/IntSymbol.java b/src/api/java/IntSymbol.java new file mode 100644 index 000000000..3dbdfaf73 --- /dev/null +++ b/src/api/java/IntSymbol.java @@ -0,0 +1,44 @@ +/** + * This file was automatically generated from IntSymbol.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +import com.microsoft.z3.enumerations.*; + +/** + * Numbered symbols + **/ +public class IntSymbol extends Symbol +{ + /** + * The int value of the symbol. Throws an exception if the symbol + * is not of int kind. + **/ + public int Int() throws Z3Exception + { + if (!IsIntSymbol()) + throw new Z3Exception("Int requested from non-Int symbol"); + return Native.getSymbolInt(Context().nCtx(), NativeObject()); + } + + IntSymbol(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + IntSymbol(Context ctx, int i) throws Z3Exception + { + super(ctx, Native.mkIntSymbol(ctx.nCtx(), i)); + } + + void CheckNativeObject(long obj) throws Z3Exception + { + if (Native.getSymbolKind(Context().nCtx(), obj) != Z3_symbol_kind.Z3_INT_SYMBOL + .toInt()) + throw new Z3Exception("Symbol is not of integer kind"); + super.CheckNativeObject(obj); + } +} diff --git a/src/api/java/ListSort.java b/src/api/java/ListSort.java new file mode 100644 index 000000000..98292b6ae --- /dev/null +++ b/src/api/java/ListSort.java @@ -0,0 +1,101 @@ +/** + * This file was automatically generated from ListSort.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * List sorts. + **/ +public class ListSort extends Sort +{ + /** + * The declaration of the nil function of this list sort. + **/ + public FuncDecl NilDecl() + { + + return nilDecl; + } + + /** + * The empty list. + **/ + public Expr Nil() + { + + return nilConst; + } + + /** + * The declaration of the isNil function of this list sort. + **/ + public FuncDecl IsNilDecl() + { + + return isNilDecl; + } + + /** + * The declaration of the cons function of this list sort. + **/ + public FuncDecl ConsDecl() + { + + return consDecl; + } + + /** + * The declaration of the isCons function of this list sort. + * + **/ + public FuncDecl IsConsDecl() + { + + return isConsDecl; + } + + /** + * The declaration of the head function of this list sort. + **/ + public FuncDecl HeadDecl() + { + + return headDecl; + } + + /** + * The declaration of the tail function of this list sort. + **/ + public FuncDecl TailDecl() + { + + return tailDecl; + } + + private FuncDecl nilDecl, isNilDecl, consDecl, isConsDecl, headDecl, + tailDecl; + private Expr nilConst; + + ListSort(Context ctx, Symbol name, Sort elemSort) throws Z3Exception + { + super(ctx); + + Native.LongPtr inil = new Native.LongPtr(), iisnil = new Native.LongPtr(); + Native.LongPtr icons = new Native.LongPtr(), iiscons = new Native.LongPtr(); + Native.LongPtr ihead = new Native.LongPtr(), itail = new Native.LongPtr(); + + setNativeObject(Native.mkListSort(ctx.nCtx(), name.NativeObject(), + elemSort.NativeObject(), inil, iisnil, icons, iiscons, ihead, + itail)); + nilDecl = new FuncDecl(ctx, inil.value); + isNilDecl = new FuncDecl(ctx, iisnil.value); + consDecl = new FuncDecl(ctx, icons.value); + isConsDecl = new FuncDecl(ctx, iiscons.value); + headDecl = new FuncDecl(ctx, ihead.value); + tailDecl = new FuncDecl(ctx, itail.value); + nilConst = ctx.MkConst(nilDecl); + } +}; diff --git a/src/api/java/Log.java b/src/api/java/Log.java new file mode 100644 index 000000000..cd62f82ac --- /dev/null +++ b/src/api/java/Log.java @@ -0,0 +1,60 @@ +/** + * This file was automatically generated from Log.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Interaction logging for Z3. Note that this is a global, static log + * and if multiple Context objects are created, it logs the interaction with all + * of them. + **/ +public final class Log +{ + private static boolean m_is_open = false; + + /** + * Open an interaction log file. the name of the file + * to open + * + * @return True if opening the log file succeeds, false otherwise. + **/ + public static boolean Open(String filename) + { + m_is_open = true; + return Native.openLog(filename) == 1; + } + + /** + * Closes the interaction log. + **/ + public static void Close() + { + m_is_open = false; + Native.closeLog(); + } + + /** + * Appends the user-provided string to the interaction + * log. + * @throws Z3Exception + **/ + public static void Append(String s) throws Z3Exception + { + if (!m_is_open) + throw new Z3Exception("Log cannot be closed."); + Native.appendLog(s); + } + + /** + * Checks whether the interaction log is opened. + * + * @return True if the interaction log is open, false otherwise. + **/ + public static boolean isOpen() + { + return m_is_open; + } +} diff --git a/src/api/java/Model.java b/src/api/java/Model.java new file mode 100644 index 000000000..e38c260c4 --- /dev/null +++ b/src/api/java/Model.java @@ -0,0 +1,302 @@ +/** + * This file was automatically generated from Model.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +import com.microsoft.z3.enumerations.*; + +/** + * A Model contains interpretations (assignments) of constants and functions. + **/ +public class Model extends Z3Object +{ + /** + * Retrieves the interpretation (the assignment) of in + * the model. A Constant + * + * @return An expression if the constant has an interpretation in the model, + * null otherwise. + * @throws Z3Exception + **/ + public Expr ConstInterp(Expr a) throws Z3Exception + { + Context().CheckContextMatch(a); + return ConstInterp(a.FuncDecl()); + } + + /** + * Retrieves the interpretation (the assignment) of in + * the model. A function declaration of zero arity + * + * @return An expression if the function has an interpretation in the model, + * null otherwise. + * @throws Z3Exception + **/ + public Expr ConstInterp(FuncDecl f) throws Z3Exception + { + Context().CheckContextMatch(f); + if (f.Arity() != 0 + || Native.getSortKind(Context().nCtx(), + Native.getRange(Context().nCtx(), f.NativeObject())) == Z3_sort_kind.Z3_ARRAY_SORT + .toInt()) + throw new Z3Exception( + "Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp."); + + long n = Native.modelGetConstInterp(Context().nCtx(), NativeObject(), + f.NativeObject()); + if (n == 0) + return null; + else + return Expr.Create(Context(), n); + } + + /** + * Retrieves the interpretation (the assignment) of a non-constant in the model. A function declaration of + * non-zero arity + * + * @return A FunctionInterpretation if the function has an interpretation in + * the model, null otherwise. + * @throws Z3Exception + **/ + public FuncInterp FuncInterp(FuncDecl f) throws Z3Exception + { + Context().CheckContextMatch(f); + + Z3_sort_kind sk = Z3_sort_kind.fromInt(Native.getSortKind(Context() + .nCtx(), Native.getRange(Context().nCtx(), f.NativeObject()))); + + if (f.Arity() == 0) + { + long n = Native.modelGetConstInterp(Context().nCtx(), + NativeObject(), f.NativeObject()); + + if (sk == Z3_sort_kind.Z3_ARRAY_SORT) + { + if (n == 0) + return null; + else + { + if (Native.isAsArray(Context().nCtx(), n) ^ true) + throw new Z3Exception( + "Argument was not an array constant"); + long fd = Native.getAsArrayFuncDecl(Context().nCtx(), n); + return FuncInterp(new FuncDecl(Context(), fd)); + } + } else + { + throw new Z3Exception( + "Constant functions do not have a function interpretation; use ConstInterp"); + } + } else + { + long n = Native.modelGetFuncInterp(Context().nCtx(), + NativeObject(), f.NativeObject()); + if (n == 0) + return null; + else + return new FuncInterp(Context(), n); + } + } + + /** + * The number of constants that have an interpretation in the model. + **/ + public int NumConsts() throws Z3Exception + { + return Native.modelGetNumConsts(Context().nCtx(), NativeObject()); + } + + /** + * The function declarations of the constants in the model. + * + * @throws Z3Exception + **/ + public FuncDecl[] ConstDecls() throws Z3Exception + { + int n = NumConsts(); + FuncDecl[] res = new FuncDecl[n]; + for (int i = 0; i < n; i++) + res[i] = new FuncDecl(Context(), Native.modelGetConstDecl(Context() + .nCtx(), NativeObject(), i)); + return res; + } + + /** + * The number of function interpretations in the model. + **/ + public int NumFuncs() throws Z3Exception + { + return Native.modelGetNumFuncs(Context().nCtx(), NativeObject()); + } + + /** + * The function declarations of the function interpretations in the model. + * + * @throws Z3Exception + **/ + public FuncDecl[] FuncDecls() throws Z3Exception + { + int n = NumFuncs(); + FuncDecl[] res = new FuncDecl[n]; + for (int i = 0; i < n; i++) + res[i] = new FuncDecl(Context(), Native.modelGetFuncDecl(Context() + .nCtx(), NativeObject(), i)); + return res; + } + + /** + * All symbols that have an interpretation in the model. + * + * @throws Z3Exception + **/ + public FuncDecl[] Decls() throws Z3Exception + { + int nFuncs = NumFuncs(); + int nConsts = NumConsts(); + int n = nFuncs + nConsts; + FuncDecl[] res = new FuncDecl[n]; + for (int i = 0; i < nConsts; i++) + res[i] = new FuncDecl(Context(), Native.modelGetConstDecl(Context() + .nCtx(), NativeObject(), i)); + for (int i = 0; i < nFuncs; i++) + res[nConsts + i] = new FuncDecl(Context(), Native.modelGetFuncDecl( + Context().nCtx(), NativeObject(), i)); + return res; + } + + /** + * A ModelEvaluationFailedException is thrown when an expression cannot be + * evaluated by the model. + **/ + @SuppressWarnings("serial") + public class ModelEvaluationFailedException extends Z3Exception + { + /** + * An exception that is thrown when model evaluation fails. + **/ + public ModelEvaluationFailedException() + { + super(); + } + } + + /** + * Evaluates the expression in the current model. + * This function may fail if contains + * quantifiers, is partial (MODEL_PARTIAL enabled), or if is not well-sorted. In this case a + * ModelEvaluationFailedException is thrown. An expression When this flag + * is enabled, a model value will be assigned to any constant or function + * that does not have an interpretation in the model. + * + * @return The evaluation of in the model. + * @throws Z3Exception + **/ + public Expr Eval(Expr t, boolean completion) throws Z3Exception + { + Native.LongPtr v = new Native.LongPtr(); + if (Native.modelEval(Context().nCtx(), NativeObject(), + t.NativeObject(), (completion) ? true : false, v) ^ true) + throw new ModelEvaluationFailedException(); + else + return Expr.Create(Context(), v.value); + } + + /** + * Alias for Eval. + * + * @throws Z3Exception + **/ + public Expr Evaluate(Expr t, boolean completion) throws Z3Exception + { + return Eval(t, completion); + } + + /** + * The number of uninterpreted sorts that the model has an interpretation + * for. + **/ + public int NumSorts() throws Z3Exception + { + return Native.modelGetNumSorts(Context().nCtx(), NativeObject()); + } + + /** + * The uninterpreted sorts that the model has an interpretation for. + * Z3 also provides an intepretation for uninterpreted sorts used + * in a formula. The interpretation for a sort is a finite set of distinct + * values. We say this finite set is the "universe" of the sort. + * + * + * @throws Z3Exception + **/ + public Sort[] Sorts() throws Z3Exception + { + + int n = NumSorts(); + Sort[] res = new Sort[n]; + for (int i = 0; i < n; i++) + res[i] = Sort.Create(Context(), + Native.modelGetSort(Context().nCtx(), NativeObject(), i)); + return res; + } + + /** + * The finite set of distinct values that represent the interpretation for + * sort . An + * uninterpreted sort + * + * @return An array of expressions, where each is an element of the universe + * of + * @throws Z3Exception + **/ + public Expr[] SortUniverse(Sort s) throws Z3Exception + { + + ASTVector nUniv = new ASTVector(Context(), Native.modelGetSortUniverse( + Context().nCtx(), NativeObject(), s.NativeObject())); + int n = nUniv.Size(); + Expr[] res = new Expr[n]; + for (int i = 0; i < n; i++) + res[i] = Expr.Create(Context(), nUniv.get(i).NativeObject()); + return res; + } + + /** + * Conversion of models to strings. + * + * @return A string representation of the model. + **/ + public String toString() + { + try + { + return Native.modelToString(Context().nCtx(), NativeObject()); + } catch (Z3Exception e) + { + return "Z3Exception: " + e.getMessage(); + } + } + + Model(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + void IncRef(long o) throws Z3Exception + { + Context().Model_DRQ().IncAndClear(Context(), o); + super.IncRef(o); + } + + void DecRef(long o) throws Z3Exception + { + Context().Model_DRQ().Add(o); + super.DecRef(o); + } +} diff --git a/src/api/java/ModelDecRefQueue.java b/src/api/java/ModelDecRefQueue.java new file mode 100644 index 000000000..71fb939cf --- /dev/null +++ b/src/api/java/ModelDecRefQueue.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2012 Microsoft Corporation + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +class ModelDecRefQueue extends IDecRefQueue +{ + public void IncRef(Context ctx, long obj) + { + try + { + Native.modelIncRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } + + public void DecRef(Context ctx, long obj) + { + try + { + Native.modelDecRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } +}; diff --git a/src/api/java/ParamDescrs.java b/src/api/java/ParamDescrs.java new file mode 100644 index 000000000..09b70f5c7 --- /dev/null +++ b/src/api/java/ParamDescrs.java @@ -0,0 +1,91 @@ +/** + * This file was automatically generated from ParamDescrs.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +import com.microsoft.z3.enumerations.*; + +/** + * A ParamDescrs describes a set of parameters. + **/ +public class ParamDescrs extends Z3Object +{ + /** + * validate a set of parameters. + **/ + public void Validate(Params p) throws Z3Exception + { + + Native.paramsValidate(Context().nCtx(), p.NativeObject(), + NativeObject()); + } + + /** + * Retrieve kind of parameter. + **/ + public Z3_param_kind GetKind(Symbol name) throws Z3Exception + { + + return Z3_param_kind.fromInt(Native.paramDescrsGetKind( + Context().nCtx(), NativeObject(), name.NativeObject())); + } + + /** + * Retrieve all names of parameters. + * + * @throws Z3Exception + **/ + public Symbol[] Names() throws Z3Exception + { + int sz = Native.paramDescrsSize(Context().nCtx(), NativeObject()); + Symbol[] names = new Symbol[sz]; + for (int i = 0; i < sz; ++i) + { + names[i] = Symbol.Create(Context(), Native.paramDescrsGetName( + Context().nCtx(), NativeObject(), i)); + } + return names; + } + + /** + * The size of the ParamDescrs. + **/ + public int Size() throws Z3Exception + { + return Native.paramDescrsSize(Context().nCtx(), NativeObject()); + } + + /** + * Retrieves a string representation of the ParamDescrs. + **/ + public String toString() + { + try + { + return Native.paramDescrsToString(Context().nCtx(), NativeObject()); + } catch (Z3Exception e) + { + return "Z3Exception: " + e.getMessage(); + } + } + + ParamDescrs(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + void IncRef(long o) throws Z3Exception + { + Context().ParamDescrs_DRQ().IncAndClear(Context(), o); + super.IncRef(o); + } + + void DecRef(long o) throws Z3Exception + { + Context().ParamDescrs_DRQ().Add(o); + super.DecRef(o); + } +} diff --git a/src/api/java/ParamDescrsDecRefQueue.java b/src/api/java/ParamDescrsDecRefQueue.java new file mode 100644 index 000000000..75e2a2c7e --- /dev/null +++ b/src/api/java/ParamDescrsDecRefQueue.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2012 Microsoft Corporation + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +class ParamDescrsDecRefQueue extends IDecRefQueue +{ + public void IncRef(Context ctx, long obj) + { + try + { + Native.paramDescrsIncRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } + + public void DecRef(Context ctx, long obj) + { + try + { + Native.paramDescrsDecRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } +}; diff --git a/src/api/java/Params.java b/src/api/java/Params.java new file mode 100644 index 000000000..c954c50e5 --- /dev/null +++ b/src/api/java/Params.java @@ -0,0 +1,108 @@ +/** + * This file was automatically generated from Params.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * A ParameterSet represents a configuration in the form of Symbol/value pairs. + **/ +public class Params extends Z3Object +{ + /** + * Adds a parameter setting. + **/ + public void Add(Symbol name, boolean value) throws Z3Exception + { + Native.paramsSetBool(Context().nCtx(), NativeObject(), + name.NativeObject(), (value) ? true : false); + } + + /** + * Adds a parameter setting. + **/ + public void Add(Symbol name, double value) throws Z3Exception + { + Native.paramsSetDouble(Context().nCtx(), NativeObject(), + name.NativeObject(), value); + } + + /** + * Adds a parameter setting. + **/ + public void Add(Symbol name, Symbol value) throws Z3Exception + { + + Native.paramsSetSymbol(Context().nCtx(), NativeObject(), + name.NativeObject(), value.NativeObject()); + } + + /** + * Adds a parameter setting. + **/ + public void Add(String name, boolean value) throws Z3Exception + { + Native.paramsSetBool(Context().nCtx(), NativeObject(), + Context().MkSymbol(name).NativeObject(), value); + } + + /** + * Adds a parameter setting. + **/ + public void Add(String name, int value) throws Z3Exception + { + Native.paramsSetUint(Context().nCtx(), NativeObject(), Context() + .MkSymbol(name).NativeObject(), value); + } + + /** + * Adds a parameter setting. + **/ + public void Add(String name, double value) throws Z3Exception + { + Native.paramsSetDouble(Context().nCtx(), NativeObject(), Context() + .MkSymbol(name).NativeObject(), value); + } + + /** + * Adds a parameter setting. + **/ + public void Add(String name, Symbol value) throws Z3Exception + { + Native.paramsSetSymbol(Context().nCtx(), NativeObject(), Context() + .MkSymbol(name).NativeObject(), value.NativeObject()); + } + + /** + * A string representation of the parameter set. + **/ + public String toString() + { + try + { + return Native.paramsToString(Context().nCtx(), NativeObject()); + } catch (Z3Exception e) + { + return "Z3Exception: " + e.getMessage(); + } + } + + Params(Context ctx) throws Z3Exception + { + super(ctx, Native.mkParams(ctx.nCtx())); + } + + void IncRef(long o) throws Z3Exception + { + Context().Params_DRQ().IncAndClear(Context(), o); + super.IncRef(o); + } + + void DecRef(long o) throws Z3Exception + { + Context().Params_DRQ().Add(o); + super.DecRef(o); + } +} diff --git a/src/api/java/ParamsDecRefQueue.java b/src/api/java/ParamsDecRefQueue.java new file mode 100644 index 000000000..7c3ccbee8 --- /dev/null +++ b/src/api/java/ParamsDecRefQueue.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2012 Microsoft Corporation + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +class ParamsDecRefQueue extends IDecRefQueue +{ + public void IncRef(Context ctx, long obj) + { + try + { + Native.paramsIncRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } + + public void DecRef(Context ctx, long obj) + { + try + { + Native.paramsDecRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } +}; diff --git a/src/api/java/Pattern.java b/src/api/java/Pattern.java new file mode 100644 index 000000000..ed36ad0e7 --- /dev/null +++ b/src/api/java/Pattern.java @@ -0,0 +1,57 @@ +/** + * This file was automatically generated from Pattern.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Patterns comprise a list of terms. The list should be non-empty. If the list + * comprises of more than one term, it is also called a multi-pattern. + **/ +public class Pattern extends AST +{ + /** + * The number of terms in the pattern. + **/ + public int NumTerms() throws Z3Exception + { + return Native.getPatternNumTerms(Context().nCtx(), NativeObject()); + } + + /** + * The terms in the pattern. + * + * @throws Z3Exception + **/ + public Expr[] Terms() throws Z3Exception + { + + int n = NumTerms(); + Expr[] res = new Expr[n]; + for (int i = 0; i < n; i++) + res[i] = Expr.Create(Context(), + Native.getPattern(Context().nCtx(), NativeObject(), i)); + return res; + } + + /** + * A string representation of the pattern. + **/ + public String toString() + { + try + { + return Native.patternToString(Context().nCtx(), NativeObject()); + } catch (Z3Exception e) + { + return "Z3Exception: " + e.getMessage(); + } + } + + Pattern(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } +} diff --git a/src/api/java/Probe.java b/src/api/java/Probe.java new file mode 100644 index 000000000..80ac55b70 --- /dev/null +++ b/src/api/java/Probe.java @@ -0,0 +1,63 @@ +/** + * This file was automatically generated from Probe.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Probes are used to inspect a goal (aka problem) and collect information that + * may be used to decide which solver and/or preprocessing step will be used. + * The complete list of probes may be obtained using the procedures + * Context.NumProbes and Context.ProbeNames. It may + * also be obtained using the command (help-tactics) in the SMT 2.0 + * front-end. + **/ +public class Probe extends Z3Object +{ + /** + * Execute the probe over the goal. + * + * @return A probe always produce a double value. "Boolean" probes return + * 0.0 for false, and a value different from 0.0 for true. + * @throws Z3Exception + **/ + public double Apply(Goal g) throws Z3Exception + { + Context().CheckContextMatch(g); + return Native.probeApply(Context().nCtx(), NativeObject(), + g.NativeObject()); + } + + /** + * Apply the probe to a goal. + * @throws Z3Exception + **/ + public double get(Goal g) throws Z3Exception + { + return Apply(g); + } + + Probe(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + Probe(Context ctx, String name) throws Z3Exception + { + super(ctx, Native.mkProbe(ctx.nCtx(), name)); + } + + void IncRef(long o) throws Z3Exception + { + Context().Probe_DRQ().IncAndClear(Context(), o); + super.IncRef(o); + } + + void DecRef(long o) throws Z3Exception + { + Context().Probe_DRQ().Add(o); + super.DecRef(o); + } +} diff --git a/src/api/java/ProbeDecRefQueue.java b/src/api/java/ProbeDecRefQueue.java new file mode 100644 index 000000000..b368702df --- /dev/null +++ b/src/api/java/ProbeDecRefQueue.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2012 Microsoft Corporation + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +class ProbeDecRefQueue extends IDecRefQueue +{ + public void IncRef(Context ctx, long obj) + { + try + { + Native.probeIncRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } + + public void DecRef(Context ctx, long obj) + { + try + { + Native.probeDecRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } +}; diff --git a/src/api/java/Quantifier.java b/src/api/java/Quantifier.java new file mode 100644 index 000000000..6ee7e4412 --- /dev/null +++ b/src/api/java/Quantifier.java @@ -0,0 +1,214 @@ +/** + * This file was automatically generated from Quantifier.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +import com.microsoft.z3.enumerations.*; + +/** + * Quantifier expressions. + **/ +public class Quantifier extends BoolExpr +{ + /** + * Indicates whether the quantifier is universal. + **/ + public boolean IsUniversal() throws Z3Exception + { + return Native.isQuantifierForall(Context().nCtx(), NativeObject()); + } + + /** + * Indicates whether the quantifier is existential. + **/ + public boolean IsExistential() throws Z3Exception + { + return !IsUniversal(); + } + + /** + * The weight of the quantifier. + **/ + public int Weight() throws Z3Exception + { + return Native.getQuantifierWeight(Context().nCtx(), NativeObject()); + } + + /** + * The number of patterns. + **/ + public int NumPatterns() throws Z3Exception + { + return Native + .getQuantifierNumPatterns(Context().nCtx(), NativeObject()); + } + + /** + * The patterns. + * + * @throws Z3Exception + **/ + public Pattern[] Patterns() throws Z3Exception + { + int n = NumPatterns(); + Pattern[] res = new Pattern[n]; + for (int i = 0; i < n; i++) + res[i] = new Pattern(Context(), Native.getQuantifierPatternAst( + Context().nCtx(), NativeObject(), i)); + return res; + } + + /** + * The number of no-patterns. + **/ + public int NumNoPatterns() throws Z3Exception + { + return Native.getQuantifierNumNoPatterns(Context().nCtx(), + NativeObject()); + } + + /** + * The no-patterns. + * + * @throws Z3Exception + **/ + public Pattern[] NoPatterns() throws Z3Exception + { + int n = NumNoPatterns(); + Pattern[] res = new Pattern[n]; + for (int i = 0; i < n; i++) + res[i] = new Pattern(Context(), Native.getQuantifierNoPatternAst( + Context().nCtx(), NativeObject(), i)); + return res; + } + + /** + * The number of bound variables. + **/ + public int NumBound() throws Z3Exception + { + return Native.getQuantifierNumBound(Context().nCtx(), NativeObject()); + } + + /** + * The symbols for the bound variables. + * + * @throws Z3Exception + **/ + public Symbol[] BoundVariableNames() throws Z3Exception + { + int n = NumBound(); + Symbol[] res = new Symbol[n]; + for (int i = 0; i < n; i++) + res[i] = Symbol.Create(Context(), Native.getQuantifierBoundName( + Context().nCtx(), NativeObject(), i)); + return res; + } + + /** + * The sorts of the bound variables. + * + * @throws Z3Exception + **/ + public Sort[] BoundVariableSorts() throws Z3Exception + { + int n = NumBound(); + Sort[] res = new Sort[n]; + for (int i = 0; i < n; i++) + res[i] = Sort.Create(Context(), Native.getQuantifierBoundSort( + Context().nCtx(), NativeObject(), i)); + return res; + } + + /** + * The body of the quantifier. + * + * @throws Z3Exception + **/ + public BoolExpr Body() throws Z3Exception + { + return new BoolExpr(Context(), Native.getQuantifierBody(Context() + .nCtx(), NativeObject())); + } + + Quantifier(Context ctx, boolean isForall, Sort[] sorts, Symbol[] names, + Expr body, int weight, Pattern[] patterns, Expr[] noPatterns, + Symbol quantifierID, Symbol skolemID) throws Z3Exception + { + super(ctx); + + Context().CheckContextMatch(patterns); + Context().CheckContextMatch(noPatterns); + Context().CheckContextMatch(sorts); + Context().CheckContextMatch(names); + Context().CheckContextMatch(body); + + if (sorts.length != names.length) + throw new Z3Exception( + "Number of sorts does not match number of names"); + + if (noPatterns == null && quantifierID == null && skolemID == null) + { + setNativeObject(Native.mkQuantifier(ctx.nCtx(), (isForall) ? true + : false, weight, AST.ArrayLength(patterns), AST + .ArrayToNative(patterns), AST.ArrayLength(sorts), AST + .ArrayToNative(sorts), Symbol.ArrayToNative(names), body + .NativeObject())); + } else + { + setNativeObject(Native.mkQuantifierEx(ctx.nCtx(), + (isForall) ? true : false, weight, AST.GetNativeObject(quantifierID), + AST.GetNativeObject(skolemID), + AST.ArrayLength(patterns), AST.ArrayToNative(patterns), + AST.ArrayLength(noPatterns), AST.ArrayToNative(noPatterns), + AST.ArrayLength(sorts), AST.ArrayToNative(sorts), + Symbol.ArrayToNative(names), + body.NativeObject())); + } + } + + Quantifier(Context ctx, boolean isForall, Expr[] bound, Expr body, + int weight, Pattern[] patterns, Expr[] noPatterns, + Symbol quantifierID, Symbol skolemID) throws Z3Exception + { + super(ctx); + + Context().CheckContextMatch(noPatterns); + Context().CheckContextMatch(patterns); + // Context().CheckContextMatch(bound); + Context().CheckContextMatch(body); + + if (noPatterns == null && quantifierID == null && skolemID == null) + { + setNativeObject(Native.mkQuantifierConst(ctx.nCtx(), + (isForall) ? true : false, weight, AST.ArrayLength(bound), + AST.ArrayToNative(bound), AST.ArrayLength(patterns), + AST.ArrayToNative(patterns), body.NativeObject())); + } else + { + setNativeObject(Native.mkQuantifierConstEx(ctx.nCtx(), + (isForall) ? true : false, weight, + AST.GetNativeObject(quantifierID), + AST.GetNativeObject(skolemID), AST.ArrayLength(bound), + AST.ArrayToNative(bound), AST.ArrayLength(patterns), + AST.ArrayToNative(patterns), AST.ArrayLength(noPatterns), + AST.ArrayToNative(noPatterns), body.NativeObject())); + } + } + + Quantifier(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + void CheckNativeObject(long obj) throws Z3Exception + { + if (Native.getAstKind(Context().nCtx(), obj) != Z3_ast_kind.Z3_QUANTIFIER_AST + .toInt()) + throw new Z3Exception("Underlying object is not a quantifier"); + super.CheckNativeObject(obj); + } +} diff --git a/src/api/java/RatNum.java b/src/api/java/RatNum.java new file mode 100644 index 000000000..bdc57fbdb --- /dev/null +++ b/src/api/java/RatNum.java @@ -0,0 +1,80 @@ +/** + * This file was automatically generated from RatNum.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +import java.math.BigInteger; + +/** + * Rational Numerals + **/ +public class RatNum extends RealExpr +{ + /** + * The numerator of a rational numeral. + **/ + public IntNum Numerator() throws Z3Exception + { + return new IntNum(Context(), Native.getNumerator(Context().nCtx(), + NativeObject())); + } + + /** + * The denominator of a rational numeral. + **/ + public IntNum Denominator() throws Z3Exception + { + return new IntNum(Context(), Native.getDenominator(Context().nCtx(), + NativeObject())); + } + + /** + * Converts the numerator of the rational to a BigInteger + **/ + public BigInteger BigIntNumerator() throws Z3Exception + { + IntNum n = Numerator(); + return new BigInteger(n.toString()); + } + + /** + * Converts the denominator of the rational to a BigInteger + **/ + public BigInteger BigIntDenominator() throws Z3Exception + { + IntNum n = Denominator(); + return new BigInteger(n.toString()); + } + + /** + * Returns a string representation in decimal notation. The result + * has at most decimal places. + **/ + public String ToDecimalString(int precision) throws Z3Exception + { + return Native.getNumeralDecimalString(Context().nCtx(), NativeObject(), + precision); + } + + /** + * Returns a string representation of the numeral. + **/ + public String toString() + { + try + { + return Native.getNumeralString(Context().nCtx(), NativeObject()); + } catch (Z3Exception e) + { + return "Z3Exception: " + e.getMessage(); + } + } + + RatNum(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } +} diff --git a/src/api/java/RealExpr.java b/src/api/java/RealExpr.java new file mode 100644 index 000000000..20d603d9a --- /dev/null +++ b/src/api/java/RealExpr.java @@ -0,0 +1,26 @@ +/** + * This file was automatically generated from RealExpr.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Real expressions + **/ +public class RealExpr extends ArithExpr +{ + /** + * Constructor for RealExpr + **/ + protected RealExpr(Context ctx) + { + super(ctx); + } + + RealExpr(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } +} diff --git a/src/api/java/RealSort.java b/src/api/java/RealSort.java new file mode 100644 index 000000000..ce7295ead --- /dev/null +++ b/src/api/java/RealSort.java @@ -0,0 +1,23 @@ +/** + * This file was automatically generated from RealSort.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * A real sort + **/ +public class RealSort extends ArithSort +{ + RealSort(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + RealSort(Context ctx) throws Z3Exception + { + super(ctx, Native.mkRealSort(ctx.nCtx())); + } +} diff --git a/src/api/java/RelationSort.java b/src/api/java/RelationSort.java new file mode 100644 index 000000000..820228e82 --- /dev/null +++ b/src/api/java/RelationSort.java @@ -0,0 +1,46 @@ +/** + * This file was automatically generated from RelationSort.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Relation sorts. + **/ +public class RelationSort extends Sort +{ + /** + * The arity of the relation sort. + **/ + public int Arity() throws Z3Exception + { + return Native.getRelationArity(Context().nCtx(), NativeObject()); + } + + /** + * The sorts of the columns of the relation sort. + * @throws Z3Exception + **/ + public Sort[] ColumnSorts() throws Z3Exception + { + + if (m_columnSorts != null) + return m_columnSorts; + + int n = Arity(); + Sort[] res = new Sort[n]; + for (int i = 0; i < n; i++) + res[i] = Sort.Create(Context(), Native.getRelationColumn(Context() + .nCtx(), NativeObject(), i)); + return res; + } + + private Sort[] m_columnSorts = null; + + RelationSort(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } +} diff --git a/src/api/java/SetSort.java b/src/api/java/SetSort.java new file mode 100644 index 000000000..ffeebfd3d --- /dev/null +++ b/src/api/java/SetSort.java @@ -0,0 +1,23 @@ +/** + * This file was automatically generated from SetSort.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Set sorts. + **/ +public class SetSort extends Sort +{ + SetSort(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + SetSort(Context ctx, Sort ty) throws Z3Exception + { + super(ctx, Native.mkSetSort(ctx.nCtx(), ty.NativeObject())); + } +} diff --git a/src/api/java/Solver.java b/src/api/java/Solver.java new file mode 100644 index 000000000..278427d49 --- /dev/null +++ b/src/api/java/Solver.java @@ -0,0 +1,286 @@ +/** + * This file was automatically generated from Solver.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +import com.microsoft.z3.enumerations.*; + +/** + * Solvers. + **/ +public class Solver extends Z3Object +{ + /** + * A string that describes all available solver parameters. + **/ + public String Help() throws Z3Exception + { + return Native.solverGetHelp(Context().nCtx(), NativeObject()); + } + + /** + * Sets the solver parameters. + * + * @throws Z3Exception + **/ + public void setParameters(Params value) throws Z3Exception + { + Context().CheckContextMatch(value); + Native.solverSetParams(Context().nCtx(), NativeObject(), + value.NativeObject()); + } + + /** + * Retrieves parameter descriptions for solver. + * + * @throws Z3Exception + **/ + public ParamDescrs ParameterDescriptions() throws Z3Exception + { + return new ParamDescrs(Context(), Native.solverGetParamDescrs(Context() + .nCtx(), NativeObject())); + } + + /** + * The current number of backtracking points (scopes). + * + **/ + public int NumScopes() throws Z3Exception + { + return Native.solverGetNumScopes(Context().nCtx(), NativeObject()); + } + + /** + * Creates a backtracking point. + **/ + public void Push() throws Z3Exception + { + Native.solverPush(Context().nCtx(), NativeObject()); + } + + /** + * Backtracks one backtracking point. . + **/ + public void Pop() throws Z3Exception + { + Pop(1); + } + + /** + * Backtracks backtracking points. Note that + * an exception is thrown if is not smaller than + * NumScopes + **/ + public void Pop(int n) throws Z3Exception + { + Native.solverPop(Context().nCtx(), NativeObject(), n); + } + + /** + * Resets the Solver. This removes all assertions from the + * solver. + **/ + public void Reset() throws Z3Exception + { + Native.solverReset(Context().nCtx(), NativeObject()); + } + + /** + * Assert a multiple constraints into the solver. + * + * @throws Z3Exception + **/ + public void Assert(BoolExpr[] constraints) throws Z3Exception + { + Context().CheckContextMatch(constraints); + for (BoolExpr a : constraints) + { + Native.solverAssert(Context().nCtx(), NativeObject(), + a.NativeObject()); + } + } + + /** + * Assert one constraint into the solver. + * + * @throws Z3Exception + **/ + public void Assert(BoolExpr constraint) throws Z3Exception + { + Context().CheckContextMatch(constraint); + Native.solverAssert(Context().nCtx(), NativeObject(), + constraint.NativeObject()); + } + + /** + * The number of assertions in the solver. + * + * @throws Z3Exception + **/ + public int NumAssertions() throws Z3Exception + { + ASTVector ass = new ASTVector(Context(), Native.solverGetAssertions( + Context().nCtx(), NativeObject())); + return ass.Size(); + } + + /** + * The set of asserted formulas. + * + * @throws Z3Exception + **/ + public BoolExpr[] Assertions() throws Z3Exception + { + ASTVector ass = new ASTVector(Context(), Native.solverGetAssertions( + Context().nCtx(), NativeObject())); + int n = ass.Size(); + BoolExpr[] res = new BoolExpr[n]; + for (int i = 0; i < n; i++) + res[i] = new BoolExpr(Context(), ass.get(i).NativeObject()); + return res; + } + + /** + * Checks whether the assertions in the solver are consistent or not. + * + **/ + public Status Check(Expr[] assumptions) throws Z3Exception + { + Z3_lbool r; + if (assumptions == null) + r = Z3_lbool.fromInt(Native.solverCheck(Context().nCtx(), + NativeObject())); + else + r = Z3_lbool.fromInt(Native.solverCheckAssumptions( + Context().nCtx(), NativeObject(), (int) assumptions.length, + AST.ArrayToNative(assumptions))); + switch (r) + { + case Z3_L_TRUE: + return Status.SATISFIABLE; + case Z3_L_FALSE: + return Status.UNSATISFIABLE; + default: + return Status.UNKNOWN; + } + } + + /** + * Checks whether the assertions in the solver are consistent or not. + * + **/ + public Status Check() throws Z3Exception + { + return Check(null); + } + + /** + * The model of the last Check. The result is + * null if Check was not invoked before, if its + * results was not SATISFIABLE, or if model production is not + * enabled. + * + * @throws Z3Exception + **/ + public Model Model() throws Z3Exception + { + long x = Native.solverGetModel(Context().nCtx(), NativeObject()); + if (x == 0) + return null; + else + return new Model(Context(), x); + } + + /** + * The proof of the last Check. The result is + * null if Check was not invoked before, if its + * results was not UNSATISFIABLE, or if proof production is + * disabled. + * + * @throws Z3Exception + **/ + public Expr Proof() throws Z3Exception + { + long x = Native.solverGetProof(Context().nCtx(), NativeObject()); + if (x == 0) + return null; + else + return Expr.Create(Context(), x); + } + + /** + * The unsat core of the last Check. The unsat core + * is a subset of Assertions The result is empty if + * Check was not invoked before, if its results was not + * UNSATISFIABLE, or if core production is disabled. + * + * @throws Z3Exception + **/ + public Expr[] UnsatCore() throws Z3Exception + { + + ASTVector core = new ASTVector(Context(), Native.solverGetUnsatCore( + Context().nCtx(), NativeObject())); + int n = core.Size(); + Expr[] res = new Expr[n]; + for (int i = 0; i < n; i++) + res[i] = Expr.Create(Context(), core.get(i).NativeObject()); + return res; + } + + /** + * A brief justification of why the last call to Check returned + * UNKNOWN. + **/ + public String ReasonUnknown() throws Z3Exception + { + return Native.solverGetReasonUnknown(Context().nCtx(), NativeObject()); + } + + /** + * Solver statistics. + * + * @throws Z3Exception + **/ + public Statistics Statistics() throws Z3Exception + { + return new Statistics(Context(), Native.solverGetStatistics(Context() + .nCtx(), NativeObject())); + } + + /** + * A string representation of the solver. + **/ + public String toString() + { + try + { + return Native.solverToString(Context().nCtx(), NativeObject()); + } catch (Z3Exception e) + { + return "Z3Exception: " + e.getMessage(); + } + } + + Solver(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + void IncRef(long o) throws Z3Exception + { + Context().Solver_DRQ().IncAndClear(Context(), o); + super.IncRef(o); + } + + void DecRef(long o) throws Z3Exception + { + Context().Solver_DRQ().Add(o); + super.DecRef(o); + } +} diff --git a/src/api/java/SolverDecRefQueue.java b/src/api/java/SolverDecRefQueue.java new file mode 100644 index 000000000..2696f6ecc --- /dev/null +++ b/src/api/java/SolverDecRefQueue.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2012 Microsoft Corporation + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +class SolverDecRefQueue extends IDecRefQueue +{ + public void IncRef(Context ctx, long obj) + { + try + { + Native.solverIncRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } + + public void DecRef(Context ctx, long obj) + { + try + { + Native.solverDecRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } +}; diff --git a/src/api/java/Sort.java b/src/api/java/Sort.java new file mode 100644 index 000000000..fcf6b117a --- /dev/null +++ b/src/api/java/Sort.java @@ -0,0 +1,154 @@ +/** + * This file was automatically generated from Sort.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +import com.microsoft.z3.enumerations.*; + +/** + * The Sort class implements type information for ASTs. + **/ +public class Sort extends AST +{ + /** + * Comparison operator. A Sort A + * Sort + * + * @return True if and are from + * the same context and represent the same sort; false otherwise. + **/ + /* Overloaded operators are not translated. */ + + /** + * Comparison operator. A Sort A + * Sort + * + * @return True if and are not + * from the same context or represent different sorts; false + * otherwise. + **/ + /* Overloaded operators are not translated. */ + + /** + * Equality operator for objects of type Sort. + * + * @return + **/ + public boolean equals(Object o) + { + Sort casted = null; + + try { + casted = Sort.class.cast(o); + } catch (ClassCastException e) { + return false; + } + + return this.NativeObject() == casted.NativeObject(); + } + + /** + * Hash code generation for Sorts + * + * @return A hash code + **/ + public int GetHashCode() throws Z3Exception + { + return super.GetHashCode(); + } + + /** + * Returns a unique identifier for the sort. + **/ + public int Id() throws Z3Exception + { + return Native.getSortId(Context().nCtx(), NativeObject()); + } + + /** + * The kind of the sort. + **/ + public Z3_sort_kind SortKind() throws Z3Exception + { + return Z3_sort_kind.fromInt(Native.getSortKind(Context().nCtx(), + NativeObject())); + } + + /** + * The name of the sort + **/ + public Symbol Name() throws Z3Exception + { + return Symbol.Create(Context(), + Native.getSortName(Context().nCtx(), NativeObject())); + } + + /** + * A string representation of the sort. + **/ + public String toString() + { + try + { + return Native.sortToString(Context().nCtx(), NativeObject()); + } catch (Z3Exception e) + { + return "Z3Exception: " + e.getMessage(); + } + } + + /** + * Sort constructor + **/ + protected Sort(Context ctx) throws Z3Exception + { + super(ctx); + { + } + } + + Sort(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + { + } + } + + void CheckNativeObject(long obj) throws Z3Exception + { + if (Native.getAstKind(Context().nCtx(), obj) != Z3_ast_kind.Z3_SORT_AST + .toInt()) + throw new Z3Exception("Underlying object is not a sort"); + super.CheckNativeObject(obj); + } + + static Sort Create(Context ctx, long obj) throws Z3Exception + { + switch (Z3_sort_kind.fromInt(Native.getSortKind(ctx.nCtx(), obj))) + { + case Z3_ARRAY_SORT: + return new ArraySort(ctx, obj); + case Z3_BOOL_SORT: + return new BoolSort(ctx, obj); + case Z3_BV_SORT: + return new BitVecSort(ctx, obj); + case Z3_DATATYPE_SORT: + return new DatatypeSort(ctx, obj); + case Z3_INT_SORT: + return new IntSort(ctx, obj); + case Z3_REAL_SORT: + return new RealSort(ctx, obj); + case Z3_UNINTERPRETED_SORT: + return new UninterpretedSort(ctx, obj); + case Z3_FINITE_DOMAIN_SORT: + return new FiniteDomainSort(ctx, obj); + case Z3_RELATION_SORT: + return new RelationSort(ctx, obj); + default: + throw new Z3Exception("Unknown sort kind"); + } + } +} diff --git a/src/api/java/Statistics.java b/src/api/java/Statistics.java new file mode 100644 index 000000000..3f6e31f96 --- /dev/null +++ b/src/api/java/Statistics.java @@ -0,0 +1,199 @@ +/** + * This file was automatically generated from Statistics.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Objects of this class track statistical information about solvers. + **/ +public class Statistics extends Z3Object +{ + /** + * Statistical data is organized into pairs of [Key, Entry], where every + * Entry is either a DoubleEntry or a UIntEntry + **/ + public class Entry + { + /** + * The key of the entry. + **/ + public String Key; + + /** + * The uint-value of the entry. + **/ + public int UIntValue() + { + return m_int; + } + + /** + * The double-value of the entry. + **/ + public double DoubleValue() + { + return m_double; + } + + /** + * True if the entry is uint-valued. + **/ + public boolean IsUInt() + { + return m_is_int; + } + + /** + * True if the entry is double-valued. + **/ + public boolean IsDouble() + { + return m_is_double; + } + + /** + * The string representation of the the entry's value. + * + * @throws Z3Exception + **/ + public String Value() throws Z3Exception + { + if (IsUInt()) + return Integer.toString(m_int); + else if (IsDouble()) + return Double.toString(m_double); + else + throw new Z3Exception("Unknown statistical entry type"); + } + + /** + * The string representation of the Entry. + **/ + public String toString() + { + try + { + return Key + ": " + Value(); + } catch (Z3Exception e) + { + return new String("Z3Exception: " + e.getMessage()); + } + } + + private boolean m_is_int = false; + private boolean m_is_double = false; + private int m_int = 0; + private double m_double = 0.0; + + Entry(String k, int v) + { + Key = k; + m_is_int = true; + m_int = v; + } + + Entry(String k, double v) + { + Key = k; + m_is_double = true; + m_double = v; + } + } + + /** + * A string representation of the statistical data. + **/ + public String toString() + { + try + { + return Native.statsToString(Context().nCtx(), NativeObject()); + } catch (Z3Exception e) + { + return "Z3Exception: " + e.getMessage(); + } + } + + /** + * The number of statistical data. + **/ + public int Size() throws Z3Exception + { + return Native.statsSize(Context().nCtx(), NativeObject()); + } + + /** + * The data entries. + * + * @throws Z3Exception + **/ + public Entry[] Entries() throws Z3Exception + { + + int n = Size(); + Entry[] res = new Entry[n]; + for (int i = 0; i < n; i++) + { + Entry e; + String k = Native.statsGetKey(Context().nCtx(), NativeObject(), i); + if (Native.statsIsUint(Context().nCtx(), NativeObject(), i)) + e = new Entry(k, Native.statsGetUintValue(Context().nCtx(), + NativeObject(), i)); + else if (Native.statsIsDouble(Context().nCtx(), NativeObject(), i)) + e = new Entry(k, Native.statsGetDoubleValue(Context().nCtx(), + NativeObject(), i)); + else + throw new Z3Exception("Unknown data entry value"); + res[i] = e; + } + return res; + } + + /** + * The statistical counters. + **/ + public String[] Keys() throws Z3Exception + { + int n = Size(); + String[] res = new String[n]; + for (int i = 0; i < n; i++) + res[i] = Native.statsGetKey(Context().nCtx(), NativeObject(), i); + return res; + } + + /** + * The value of a particular statistical counter. Returns null if + * the key is unknown. + * + * @throws Z3Exception + **/ + public Entry get(String key) throws Z3Exception + { + int n = Size(); + Entry[] es = Entries(); + for (int i = 0; i < n; i++) + if (es[i].Key == key) + return es[i]; + return null; + } + + Statistics(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + void IncRef(long o) throws Z3Exception + { + Context().Statistics_DRQ().IncAndClear(Context(), o); + super.IncRef(o); + } + + void DecRef(long o) throws Z3Exception + { + Context().Statistics_DRQ().Add(o); + super.DecRef(o); + } +} diff --git a/src/api/java/StatisticsDecRefQueue.java b/src/api/java/StatisticsDecRefQueue.java new file mode 100644 index 000000000..907cf8760 --- /dev/null +++ b/src/api/java/StatisticsDecRefQueue.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2012 Microsoft Corporation + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +class StatisticsDecRefQueue extends IDecRefQueue +{ + public void IncRef(Context ctx, long obj) + { + try + { + Native.statsIncRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } + + public void DecRef(Context ctx, long obj) + { + try + { + Native.statsDecRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } +}; diff --git a/src/api/java/Status.java b/src/api/java/Status.java new file mode 100644 index 000000000..117618426 --- /dev/null +++ b/src/api/java/Status.java @@ -0,0 +1,42 @@ +/** + * This file was automatically generated from Status.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Status values. + **/ +public enum Status +{ + // / Used to signify an unsatisfiable status. + UNSATISFIABLE(1), + + // / Used to signify an unknown status. + UNKNOWN(0), + + // / Used to signify a satisfiable status. + SATISFIABLE(1); + + private final int intValue; + + Status(int v) + { + this.intValue = v; + } + + public static final Status fromInt(int v) + { + for (Status k : values()) + if (k.intValue == v) + return k; + return values()[0]; + } + + public final int toInt() + { + return this.intValue; + } +} diff --git a/src/api/java/StringSymbol.java b/src/api/java/StringSymbol.java new file mode 100644 index 000000000..81ada78a4 --- /dev/null +++ b/src/api/java/StringSymbol.java @@ -0,0 +1,43 @@ +/** + * This file was automatically generated from StringSymbol.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +import com.microsoft.z3.enumerations.*; + +/** + * Named symbols + **/ +public class StringSymbol extends Symbol +{ + /** + * The string value of the symbol. Throws an exception if the + * symbol is not of string kind. + **/ + public String String() throws Z3Exception + { + return Native.getSymbolString(Context().nCtx(), NativeObject()); + } + + StringSymbol(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + StringSymbol(Context ctx, String s) throws Z3Exception + { + super(ctx, Native.mkStringSymbol(ctx.nCtx(), s)); + } + + void CheckNativeObject(long obj) throws Z3Exception + { + if (Native.getSymbolKind(Context().nCtx(), obj) != Z3_symbol_kind.Z3_STRING_SYMBOL + .toInt()) + throw new Z3Exception("Symbol is not of String kind"); + + super.CheckNativeObject(obj); + } +} diff --git a/src/api/java/Symbol.java b/src/api/java/Symbol.java new file mode 100644 index 000000000..cd987adf2 --- /dev/null +++ b/src/api/java/Symbol.java @@ -0,0 +1,81 @@ +/** + * This file was automatically generated from Symbol.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +import com.microsoft.z3.enumerations.*; + +/** + * Symbols are used to name several term and type constructors. + **/ +public class Symbol extends Z3Object +{ + /** + * The kind of the symbol (int or string) + **/ + protected Z3_symbol_kind Kind() throws Z3Exception + { + return Z3_symbol_kind.fromInt(Native.getSymbolKind(Context().nCtx(), + NativeObject())); + } + + /** + * Indicates whether the symbol is of Int kind + **/ + public boolean IsIntSymbol() throws Z3Exception + { + return Kind() == Z3_symbol_kind.Z3_INT_SYMBOL; + } + + /** + * Indicates whether the symbol is of string kind. + **/ + public boolean IsStringSymbol() throws Z3Exception + { + return Kind() == Z3_symbol_kind.Z3_STRING_SYMBOL; + } + + /** + * A string representation of the symbol. + **/ + public String toString() + { + try + { + if (IsIntSymbol()) + return Integer.toString(((IntSymbol) this).Int()); + else if (IsStringSymbol()) + return ((StringSymbol) this).String(); + else + return new String( + "Z3Exception: Unknown symbol kind encountered."); + } catch (Z3Exception ex) + { + return new String("Z3Exception: " + ex.getMessage()); + } + } + + /** + * Symbol constructor + **/ + protected Symbol(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + static Symbol Create(Context ctx, long obj) throws Z3Exception + { + switch (Z3_symbol_kind.fromInt(Native.getSymbolKind(ctx.nCtx(), obj))) + { + case Z3_INT_SYMBOL: + return new IntSymbol(ctx, obj); + case Z3_STRING_SYMBOL: + return new StringSymbol(ctx, obj); + default: + throw new Z3Exception("Unknown symbol kind encountered"); + } + } +} diff --git a/src/api/java/Tactic.java b/src/api/java/Tactic.java new file mode 100644 index 000000000..124db0ef2 --- /dev/null +++ b/src/api/java/Tactic.java @@ -0,0 +1,107 @@ +/** + * This file was automatically generated from Tactic.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Tactics are the basic building block for creating custom solvers for specific + * problem domains. The complete list of tactics may be obtained using + * Context.NumTactics and Context.TacticNames. It may + * also be obtained using the command (help-tactics) in the SMT 2.0 + * front-end. + **/ +public class Tactic extends Z3Object +{ + /** + * A string containing a description of parameters accepted by the tactic. + **/ + public String Help() throws Z3Exception + { + return Native.tacticGetHelp(Context().nCtx(), NativeObject()); + } + + /** + * Retrieves parameter descriptions for Tactics. + * @throws Z3Exception + **/ + public ParamDescrs ParameterDescriptions() throws Z3Exception + { + return new ParamDescrs(Context(), Native.tacticGetParamDescrs(Context() + .nCtx(), NativeObject())); + } + + /** + * Execute the tactic over the goal. + * @throws Z3Exception + **/ + public ApplyResult Apply(Goal g) throws Z3Exception + { + return Apply(g, null); + } + + /** + * Execute the tactic over the goal. + * @throws Z3Exception + **/ + public ApplyResult Apply(Goal g, Params p) throws Z3Exception + { + + Context().CheckContextMatch(g); + if (p == null) + return new ApplyResult(Context(), Native.tacticApply(Context() + .nCtx(), NativeObject(), g.NativeObject())); + else + { + Context().CheckContextMatch(p); + return new ApplyResult(Context(), + Native.tacticApplyEx(Context().nCtx(), NativeObject(), + g.NativeObject(), p.NativeObject())); + } + } + + /** + * Apply the tactic to a goal. + * @throws Z3Exception + **/ + public ApplyResult get(Goal g) throws Z3Exception + { + + return Apply(g, null); + } + + /** + * Creates a solver that is implemented using the given tactic. + * @throws Z3Exception + **/ + public Solver Solver() throws Z3Exception + { + + return Context().MkSolver(this); + } + + Tactic(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + Tactic(Context ctx, String name) throws Z3Exception + { + super(ctx, Native.mkTactic(ctx.nCtx(), name)); + } + + void IncRef(long o) throws Z3Exception + { + Context().Tactic_DRQ().IncAndClear(Context(), o); + super.IncRef(o); + } + + void DecRef(long o) throws Z3Exception + { + Context().Tactic_DRQ().Add(o); + super.DecRef(o); + } +} diff --git a/src/api/java/TacticDecRefQueue.java b/src/api/java/TacticDecRefQueue.java new file mode 100644 index 000000000..c2ea2c079 --- /dev/null +++ b/src/api/java/TacticDecRefQueue.java @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2012 Microsoft Corporation + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +class TacticDecRefQueue extends IDecRefQueue +{ + public void IncRef(Context ctx, long obj) + { + try + { + Native.tacticIncRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } + + public void DecRef(Context ctx, long obj) + { + try + { + Native.tacticDecRef(ctx.nCtx(), obj); + } catch (Z3Exception e) + { + // OK. + } + } +}; diff --git a/src/api/java/TupleSort.java b/src/api/java/TupleSort.java new file mode 100644 index 000000000..3eb28b88e --- /dev/null +++ b/src/api/java/TupleSort.java @@ -0,0 +1,58 @@ +/** + * This file was automatically generated from TupleSort.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Tuple sorts. + **/ +public class TupleSort extends Sort +{ + /** + * The constructor function of the tuple. + * @throws Z3Exception + **/ + public FuncDecl MkDecl() throws Z3Exception + { + + return new FuncDecl(Context(), Native.getTupleSortMkDecl(Context() + .nCtx(), NativeObject())); + } + + /** + * The number of fields in the tuple. + **/ + public int NumFields() throws Z3Exception + { + return Native.getTupleSortNumFields(Context().nCtx(), NativeObject()); + } + + /** + * The field declarations. + * @throws Z3Exception + **/ + public FuncDecl[] FieldDecls() throws Z3Exception + { + + int n = NumFields(); + FuncDecl[] res = new FuncDecl[n]; + for (int i = 0; i < n; i++) + res[i] = new FuncDecl(Context(), Native.getTupleSortFieldDecl( + Context().nCtx(), NativeObject(), i)); + return res; + } + + TupleSort(Context ctx, Symbol name, int numFields, Symbol[] fieldNames, + Sort[] fieldSorts) throws Z3Exception + { + super(ctx); + + Native.LongPtr t = new Native.LongPtr(); + setNativeObject(Native.mkTupleSort(ctx.nCtx(), name.NativeObject(), + numFields, Symbol.ArrayToNative(fieldNames), + AST.ArrayToNative(fieldSorts), t, new long[numFields])); + } +}; diff --git a/src/api/java/UninterpretedSort.java b/src/api/java/UninterpretedSort.java new file mode 100644 index 000000000..bc062cb50 --- /dev/null +++ b/src/api/java/UninterpretedSort.java @@ -0,0 +1,23 @@ +/** + * This file was automatically generated from UninterpretedSort.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Uninterpreted Sorts + **/ +public class UninterpretedSort extends Sort +{ + UninterpretedSort(Context ctx, long obj) throws Z3Exception + { + super(ctx, obj); + } + + UninterpretedSort(Context ctx, Symbol s) throws Z3Exception + { + super(ctx, Native.mkUninterpretedSort(ctx.nCtx(), s.NativeObject())); + } +} diff --git a/src/api/java/Version.java b/src/api/java/Version.java new file mode 100644 index 000000000..af5da39de --- /dev/null +++ b/src/api/java/Version.java @@ -0,0 +1,64 @@ +/** + * This file was automatically generated from Version.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Version information. Note that this class is static. + **/ +public class Version +{ + /** + * The major version + **/ + public static int Major() + { + Native.IntPtr major = new Native.IntPtr(), minor = new Native.IntPtr(), build = new Native.IntPtr(), revision = new Native.IntPtr(); + Native.getVersion(major, minor, build, revision); + return major.value; + } + + /** + * The minor version + **/ + public static int Minor() + { + Native.IntPtr major = new Native.IntPtr(), minor = new Native.IntPtr(), build = new Native.IntPtr(), revision = new Native.IntPtr(); + Native.getVersion(major, minor, build, revision); + return minor.value; + } + + /** + * The build version + **/ + public static int Build() + { + Native.IntPtr major = new Native.IntPtr(), minor = new Native.IntPtr(), build = new Native.IntPtr(), revision = new Native.IntPtr(); + Native.getVersion(major, minor, build, revision); + return build.value; + } + + /** + * The revision + **/ + public static int Revision() + { + Native.IntPtr major = new Native.IntPtr(), minor = new Native.IntPtr(), build = new Native.IntPtr(), revision = new Native.IntPtr(); + Native.getVersion(major, minor, build, revision); + return revision.value; + } + + /** + * A string representation of the version information. + **/ + public static String getString() + { + Native.IntPtr major = new Native.IntPtr(), minor = new Native.IntPtr(), build = new Native.IntPtr(), revision = new Native.IntPtr(); + Native.getVersion(major, minor, build, revision); + return Integer.toString(major.value) + "." + Integer.toString(minor.value) + "." + + Integer.toString(build.value) + "." + Integer.toString(revision.value); + } +} diff --git a/src/api/java/Z3Exception.java b/src/api/java/Z3Exception.java new file mode 100644 index 000000000..ae7046c90 --- /dev/null +++ b/src/api/java/Z3Exception.java @@ -0,0 +1,40 @@ +/** + * This file was automatically generated from Z3Exception.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +import java.lang.Exception; + +/** + * The exception base class for error reporting from Z3 + **/ +@SuppressWarnings("serial") +public class Z3Exception extends Exception +{ + /** + * Constructor. + **/ + public Z3Exception() + { + super(); + } + + /** + * Constructor. + **/ + public Z3Exception(String message) + { + super(message); + } + + /** + * Constructor. + **/ + public Z3Exception(String message, Exception inner) + { + super(message, inner); + } +} diff --git a/src/api/java/Z3Object.java b/src/api/java/Z3Object.java new file mode 100644 index 000000000..8aeb03ddf --- /dev/null +++ b/src/api/java/Z3Object.java @@ -0,0 +1,115 @@ +/** + * This file was automatically generated from Z3Object.cs + * w/ further modifications by: + * @author Christoph M. Wintersteiger (cwinter) + **/ + +package com.microsoft.z3; + +/** + * Internal base class for interfacing with native Z3 objects. Should not be + * used externally. + **/ +public class Z3Object extends IDisposable +{ + /** + * Finalizer. + **/ + protected void finalize() throws Z3Exception + { + Dispose(); + } + + /** + * Disposes of the underlying native Z3 object. + **/ + public void Dispose() throws Z3Exception + { + if (m_n_obj != 0) + { + DecRef(m_n_obj); + m_n_obj = 0; + } + + if (m_ctx != null) + { + m_ctx.m_refCount--; + m_ctx = null; + } + } + + private Context m_ctx = null; + private long m_n_obj = 0; + + Z3Object(Context ctx) + { + ctx.m_refCount++; + m_ctx = ctx; + } + + Z3Object(Context ctx, long obj) throws Z3Exception + { + ctx.m_refCount++; + m_ctx = ctx; + IncRef(obj); + m_n_obj = obj; + } + + void IncRef(long o) throws Z3Exception + { + } + + void DecRef(long o) throws Z3Exception + { + } + + void CheckNativeObject(long obj) throws Z3Exception + { + } + + long NativeObject() + { + return m_n_obj; + } + + void setNativeObject(long value) throws Z3Exception + { + if (value != 0) + { + CheckNativeObject(value); + IncRef(value); + } + if (m_n_obj != 0) + { + DecRef(m_n_obj); + } + m_n_obj = value; + } + + static long GetNativeObject(Z3Object s) + { + if (s == null) + return 0; + return s.NativeObject(); + } + + Context Context() + { + return m_ctx; + } + + static long[] ArrayToNative(Z3Object[] a) + { + if (a == null) + return null; + long[] an = new long[a.length]; + for (int i = 0; i < a.length; i++) + an[i] = (a[i] == null) ? 0 : a[i].NativeObject(); + return an; + } + + static int ArrayLength(Z3Object[] a) + { + return (a == null) ? 0 : a.length; + } +} diff --git a/src/api/java/com/Microsoft/Z3/AST.java b/src/api/java/com/Microsoft/Z3/AST.java deleted file mode 100644 index ad4c9d94a..000000000 --- a/src/api/java/com/Microsoft/Z3/AST.java +++ /dev/null @@ -1,209 +0,0 @@ -/** - * This file was automatically generated from AST.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ -/* using System.Collections; */ -/* using System.Collections.Generic; */ - - /** - * The abstract syntax tree (AST) class. - **/ - public class AST extends Z3Object - { - /** - * Comparison operator. - * An AST - * An AST - * @return True if and are from the same context - * and represent the same sort; false otherwise. - **/ - /* Overloaded operators are not translated. */ - - /** - * Comparison operator. - * An AST - * An AST - * @return True if and are not from the same context - * or represent different sorts; false otherwise. - **/ - /* Overloaded operators are not translated. */ - - /** - * Object comparison. - **/ - public boolean Equals(object o) - { - AST casted = (AST) o; - if (casted == null) return false; - return this == casted; - } - - /** - * Object Comparison. - * Another AST - * @return Negative if the object should be sorted before , positive if after else zero. - **/ - public int CompareTo(object other) - { - if (other == null) return 1; - AST oAST = (AST) other; - if (oAST == null) - return 1; - else - { - if (Id < oAST.Id) - return -1; - else if (Id > oAST.Id) - return +1; - else - return 0; - } - } - - /** - * The AST's hash code. - * @return A hash code - **/ - public int GetHashCode() - { - return (int)Native.getAstHash(Context.nCtx, NativeObject); - } - - /** - * A unique identifier for the AST (unique among all ASTs). - **/ - public long Id() { return Native.getAstId(Context.nCtx, NativeObject); } - - /** - * Translates (copies) the AST to the Context . - * A context - * @return A copy of the AST which is associated with - **/ - public AST Translate(Context ctx) - { - - - - if (ReferenceEquals(Context, ctx)) - return this; - else - return new AST(ctx, Native.translate(Context.nCtx, NativeObject, ctx.nCtx)); - } - - /** - * The kind of the AST. - **/ - public Z3_ast_kind ASTKind() { return (Z3_ast_kind)Native.getAstKind(Context.nCtx, NativeObject); } - - /** - * Indicates whether the AST is an Expr - **/ - public boolean IsExpr() - { - switch (ASTKind) - { - case Z3_ast_kind.Z3_APP_AST: - case Z3_ast_kind.Z3_NUMERAL_AST: - case Z3_ast_kind.Z3_QUANTIFIER_AST: - case Z3_ast_kind.Z3_VAR_AST: return true; - default: return false; - } - } - - /** - * Indicates whether the AST is a BoundVariable - **/ - public boolean IsVar() { return this.ASTKind == Z3_ast_kind.Z3_VAR_AST; } - - /** - * Indicates whether the AST is a Quantifier - **/ - public boolean IsQuantifier() { return this.ASTKind == Z3_ast_kind.Z3_QUANTIFIER_AST; } - - /** - * Indicates whether the AST is a Sort - **/ - public boolean IsSort() { return this.ASTKind == Z3_ast_kind.Z3_SORT_AST; } - - /** - * Indicates whether the AST is a FunctionDeclaration - **/ - public boolean IsFuncDecl() { return this.ASTKind == Z3_ast_kind.Z3_FUNC_DECL_AST; } - - /** - * A string representation of the AST. - **/ - public String toString() - { - return Native.asttoString(Context.nCtx, NativeObject); - } - - /** - * A string representation of the AST in s-expression notation. - **/ - public String SExpr() - { - - - return Native.asttoString(Context.nCtx, NativeObject); - } - - AST(Context ctx) { super(ctx); } - AST(Context ctx, IntPtr obj) { super(ctx, obj); } - - class DecRefQueue extends Z3.DecRefQueue - { - public void IncRef(Context ctx, IntPtr obj) - { - Native.incRef(ctx.nCtx, obj); - } - - public void DecRef(Context ctx, IntPtr obj) - { - Native.decRef(ctx.nCtx, obj); - } - }; - - void IncRef(IntPtr o) - { - // Console.WriteLine("AST IncRef()"); - if (Context == null) - throw new Z3Exception("inc() called on null context"); - if (o == IntPtr.Zero) - throw new Z3Exception("inc() called on null AST"); - Context.AST_DRQ.IncAndClear(Context, o); - super.IncRef(o); - } - - void DecRef(IntPtr o) - { - // Console.WriteLine("AST DecRef()"); - if (Context == null) - throw new Z3Exception("dec() called on null context"); - if (o == IntPtr.Zero) - throw new Z3Exception("dec() called on null AST"); - Context.AST_DRQ.Add(o); - super.DecRef(o); - } - - static AST Create(Context ctx, IntPtr obj) - { - - - - switch ((Z3_ast_kind)Native.getAstKind(ctx.nCtx, obj)) - { - case Z3_ast_kind.Z3_FUNC_DECL_AST: return new FuncDecl(ctx, obj); - case Z3_ast_kind.Z3_QUANTIFIER_AST: return new Quantifier(ctx, obj); - case Z3_ast_kind.Z3_SORT_AST: return Sort.Create(ctx, obj); - case Z3_ast_kind.Z3_APP_AST: - case Z3_ast_kind.Z3_NUMERAL_AST: - case Z3_ast_kind.Z3_VAR_AST: return Expr.Create(ctx, obj); - default: - throw new Z3Exception("Unknown AST kind"); - } - } - } diff --git a/src/api/java/com/Microsoft/Z3/ASTMap.java b/src/api/java/com/Microsoft/Z3/ASTMap.java deleted file mode 100644 index 7b95861b4..000000000 --- a/src/api/java/com/Microsoft/Z3/ASTMap.java +++ /dev/null @@ -1,127 +0,0 @@ -/** - * This file was automatically generated from ASTMap.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * Map from AST to AST - **/ - class ASTMap extends Z3Object - { - /** - * Checks whether the map contains the key . - * An AST - * @return True if is a key in the map, false otherwise. - **/ - public boolean Contains(AST k) - { - - - return Native.astMapContains(Context.nCtx, NativeObject, k.NativeObject) != 0; - } - - /** - * Finds the value associated with the key . - * - * This function signs an error when is not a key in the map. - * - * An AST - **/ - public AST Find(AST k) - { - - - - return new AST(Context, Native.astMapFind(Context.nCtx, NativeObject, k.NativeObject)); - } - - /** - * Stores or replaces a new key/value pair in the map. - * The key AST - * The value AST - **/ - public void Insert(AST k, AST v) - { - - - - Native.astMapInsert(Context.nCtx, NativeObject, k.NativeObject, v.NativeObject); - } - - /** - * Erases the key from the map. - * An AST - **/ - public void Erase(AST k) - { - - - Native.astMapErase(Context.nCtx, NativeObject, k.NativeObject); - } - - /** - * Removes all keys from the map. - **/ - public void Reset() - { - Native.astMapReset(Context.nCtx, NativeObject); - } - - /** - * The size of the map - **/ - public long Size() { return Native.astMapSize(Context.nCtx, NativeObject); } - - /** - * The keys stored in the map. - **/ - public ASTVector Keys() - { - return new ASTVector(Context, Native.astMapKeys(Context.nCtx, NativeObject)); - } - - /** - * Retrieves a string representation of the map. - **/ - public String toString() - { - return Native.astMaptoString(Context.nCtx, NativeObject); - } - - ASTMap(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - ASTMap(Context ctx) - { super(ctx, Native.mkAstMap(ctx.nCtx)); - - } - - class DecRefQueue extends Z3.DecRefQueue - { - public void IncRef(Context ctx, IntPtr obj) - { - Native.astMapIncRef(ctx.nCtx, obj); - } - - public void DecRef(Context ctx, IntPtr obj) - { - Native.astMapDecRef(ctx.nCtx, obj); - } - }; - - void IncRef(IntPtr o) - { - Context.ASTMap_DRQ.IncAndClear(Context, o); - super.IncRef(o); - } - - void DecRef(IntPtr o) - { - Context.ASTMap_DRQ.Add(o); - super.DecRef(o); - } - } diff --git a/src/api/java/com/Microsoft/Z3/ASTVector.java b/src/api/java/com/Microsoft/Z3/ASTVector.java deleted file mode 100644 index 0ae2ff20a..000000000 --- a/src/api/java/com/Microsoft/Z3/ASTVector.java +++ /dev/null @@ -1,107 +0,0 @@ -/** - * This file was automatically generated from ASTVector.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * Vectors of ASTs. - **/ - class ASTVector extends Z3Object - { - /** - * The size of the vector - **/ - public long Size() { return Native.astVectorSize(Context.nCtx, NativeObject); } - - /** - * Retrieves the i-th object in the vector. - * May throw an IndexOutOfBoundsException when is out of range. - * Index - * @return An AST - **/ - public AST get(long i) - { - - - return new AST(Context, Native.astVectorGet(Context.nCtx, NativeObject, i)); - } - public void set(long i, AST value) - { - - - Native.astVectorSet(Context.nCtx, NativeObject, i, value.NativeObject); - } - - /** - * Resize the vector to . - * The new size of the vector. - **/ - public void Resize(long newSize) - { - Native.astVectorResize(Context.nCtx, NativeObject, newSize); - } - - /** - * Add the AST to the back of the vector. The size - * is increased by 1. - * An AST - **/ - public void Push(AST a) - { - - - Native.astVectorPush(Context.nCtx, NativeObject, a.NativeObject); - } - - /** - * Translates all ASTs in the vector to . - * A context - * @return A new ASTVector - **/ - public ASTVector Translate(Context ctx) - { - - - - return new ASTVector(Context, Native.astVectorTranslate(Context.nCtx, NativeObject, ctx.nCtx)); - } - - /** - * Retrieves a string representation of the vector. - **/ - public String toString() - { - return Native.astVectortoString(Context.nCtx, NativeObject); - } - - ASTVector(Context ctx, IntPtr obj) { super(ctx, obj); } - ASTVector(Context ctx) { super(ctx, Native.mkAstVector(ctx.nCtx)); } - - class DecRefQueue extends Z3.DecRefQueue - { - public void IncRef(Context ctx, IntPtr obj) - { - Native.astVectorIncRef(ctx.nCtx, obj); - } - - public void DecRef(Context ctx, IntPtr obj) - { - Native.astVectorDecRef(ctx.nCtx, obj); - } - }; - - void IncRef(IntPtr o) - { - Context.ASTVector_DRQ.IncAndClear(Context, o); - super.IncRef(o); - } - - void DecRef(IntPtr o) - { - Context.ASTVector_DRQ.Add(o); - super.DecRef(o); - } - } diff --git a/src/api/java/com/Microsoft/Z3/ApplyResult.java b/src/api/java/com/Microsoft/Z3/ApplyResult.java deleted file mode 100644 index 9bd613930..000000000 --- a/src/api/java/com/Microsoft/Z3/ApplyResult.java +++ /dev/null @@ -1,84 +0,0 @@ -/** - * This file was automatically generated from ApplyResult.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * ApplyResult objects represent the result of an application of a - * tactic to a goal. It contains the subgoals that were produced. - **/ - public class ApplyResult extends Z3Object - { - /** - * The number of Subgoals. - **/ - public long NumSubgoals() { return Native.applyResultGetNumSubgoals(Context.nCtx, NativeObject); } - - /** - * Retrieves the subgoals from the ApplyResult. - **/ - public Goal[] Subgoals() - { - - - - long n = NumSubgoals; - Goal[] res = new Goal[n]; - for (long i = 0; i < n; i++) - res[i] = new Goal(Context, Native.applyResultGetSubgoal(Context.nCtx, NativeObject, i)); - return res; - } - - /** - * Convert a model for the subgoal into a model for the original - * goal g, that the ApplyResult was obtained from. - * @return A model for g - **/ - public Model ConvertModel(long i, Model m) - { - - - - return new Model(Context, Native.applyResultConvertModel(Context.nCtx, NativeObject, i, m.NativeObject)); - } - - /** - * A string representation of the ApplyResult. - **/ - public String toString() - { - return Native.applyResulttoString(Context.nCtx, NativeObject); - } - - ApplyResult(Context ctx, IntPtr obj) { super(ctx, obj); - - } - - class DecRefQueue extends Z3.DecRefQueue - { - public void IncRef(Context ctx, IntPtr obj) - { - Native.applyResultIncRef(ctx.nCtx, obj); - } - - public void DecRef(Context ctx, IntPtr obj) - { - Native.applyResultDecRef(ctx.nCtx, obj); - } - }; - - void IncRef(IntPtr o) - { - Context.ApplyResult_DRQ.IncAndClear(Context, o); - super.IncRef(o); - } - - void DecRef(IntPtr o) - { - Context.ApplyResult_DRQ.Add(o); - super.DecRef(o); - } - } diff --git a/src/api/java/com/Microsoft/Z3/Constructor.java b/src/api/java/com/Microsoft/Z3/Constructor.java deleted file mode 100644 index 7c9b2a85c..000000000 --- a/src/api/java/com/Microsoft/Z3/Constructor.java +++ /dev/null @@ -1,143 +0,0 @@ -/** - * This file was automatically generated from Constructor.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * Constructors are used for datatype sorts. - **/ - public class Constructor extends Z3Object - { - /** - * The number of fields of the constructor. - **/ - public long NumFields() - { - init(); - return n; - } - - /** - * The function declaration of the constructor. - **/ - public FuncDecl ConstructorDecl() - { - - init(); - return m_constructorDecl; - } - - /** - * The function declaration of the tester. - **/ - public FuncDecl TesterDecl() - { - - init(); - return m_testerDecl; - } - - /** - * The function declarations of the accessors - **/ - public FuncDecl[] AccessorDecls() - { - - init(); - return m_accessorDecls; - } - - /** - * Destructor. - **/ - protected void finalize() - { - Native.delConstructor(Context.nCtx, NativeObject); - } - - - private void ObjectInvariant() - { - - - } - - - private long n = 0; - private FuncDecl m_testerDecl = null; - private FuncDecl m_constructorDecl = null; - private FuncDecl[] m_accessorDecls = null; - - Constructor(Context ctx, Symbol name, Symbol recognizer, Symbol[] fieldNames, - Sort[] sorts, long[] sortRefs) - { super(ctx); - - - - - n = AST.ArrayLength(fieldNames); - - if (n != AST.ArrayLength(sorts)) - throw new Z3Exception("Number of field names does not match number of sorts"); - if (sortRefs != null && sortRefs.Length != n) - throw new Z3Exception("Number of field names does not match number of sort refs"); - - if (sortRefs == null) sortRefs = new long[n]; - - NativeObject = Native.mkConstructor(ctx.nCtx, name.NativeObject, recognizer.NativeObject, - n, - Symbol.ArrayToNative(fieldNames), - Sort.ArrayToNative(sorts), - sortRefs); - - } - - private void init() - { - - - - - if (m_testerDecl != null) return; - IntPtr constructor = IntPtr.Zero; - IntPtr tester = IntPtr.Zero; - IntPtr[] accessors = new IntPtr[n]; - Native.queryConstructor(Context.nCtx, NativeObject, n, constructor, tester, accessors); - m_constructorDecl = new FuncDecl(Context, constructor); - m_testerDecl = new FuncDecl(Context, tester); - m_accessorDecls = new FuncDecl[n]; - for (long i = 0; i < n; i++) - m_accessorDecls[i] = new FuncDecl(Context, accessors[i]); - } - - } - - /** - * Lists of constructors - **/ - public class ConstructorList extends Z3Object - { - /** - * Destructor. - **/ - protected void finalize() - { - Native.delConstructorList(Context.nCtx, NativeObject); - } - - ConstructorList(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - - ConstructorList(Context ctx, Constructor[] constructors) - { super(ctx); - - - - NativeObject = Native.mkConstructorList(Context.nCtx, (long)constructors.Length, Constructor.ArrayToNative(constructors)); - } - } diff --git a/src/api/java/com/Microsoft/Z3/Context.java b/src/api/java/com/Microsoft/Z3/Context.java deleted file mode 100644 index c18fb7414..000000000 --- a/src/api/java/com/Microsoft/Z3/Context.java +++ /dev/null @@ -1,3543 +0,0 @@ -/** - * This file was automatically generated from Context.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ -/* using System.Collections.Generic; */ -/* using System.Runtime.InteropServices; */ - - /** - * The main interaction with Z3 happens via the Context. - **/ - public class Context extends IDisposable - { - /** - * Constructor. - **/ - public Context() - { super(); - m_ctx = Native.mkContextRc(IntPtr.Zero); - InitContext(); - } - - /** - * Constructor. - **/ - public Context(Dictionary settings) - { super(); - - - IntPtr cfg = Native.mkConfig(); - for (KeyValuePair.Iterator kv = settings.iterator(); kv.hasNext(); ) - Native.setParamValue(cfg, kv.Key, kv.Value); - m_ctx = Native.mkContextRc(cfg); - Native.delConfig(cfg); - InitContext(); - } - - /** - * Creates a new symbol using an integer. - * - * Not all integers can be passed to this function. - * The legal range of unsigned integers is 0 to 2^30-1. - * - **/ - public IntSymbol MkSymbol(int i) - { - - - return new IntSymbol(this, i); - } - - /** - * Create a symbol using a string. - **/ - public StringSymbol MkSymbol(String name) - { - - - return new StringSymbol(this, name); - } - - /** - * Create an array of symbols. - **/ - Symbol[] MkSymbols(String[] names) - { - - - - - - if (names == null) return null; - Symbol[] result = new Symbol[names.Length]; - for (int i = 0; i < names.Length; ++i) result[i] = MkSymbol(names[i]); - return result; - } - - private BoolSort m_booleanSort = null; - private IntSort m_intSort = null; - private RealSort m_realSort = null; - - /** - * Retrieves the Boolean sort of the context. - **/ - public BoolSort BoolSort() - { - - - if (m_booleanSort == null) m_booleanSort = new BoolSort(this); return m_booleanSort; - } - - /** - * Retrieves the Integer sort of the context. - **/ - public IntSort IntSort() - { - - if (m_intSort == null) m_intSort = new IntSort(this); return m_intSort; - } - - - /** - * Retrieves the Real sort of the context. - **/ - public RealSort RealSort () { return m_realSort; } - - /** - * Create a new Boolean sort. - **/ - public BoolSort MkBoolSort() - { - - return new BoolSort(this); - } - - /** - * Create a new uninterpreted sort. - **/ - public UninterpretedSort MkUninterpretedSort(Symbol s) - { - - - - CheckContextMatch(s); - return new UninterpretedSort(this, s); - } - - /** - * Create a new uninterpreted sort. - **/ - public UninterpretedSort MkUninterpretedSort(String str) - { - - - return MkUninterpretedSort(MkSymbol(str)); - } - - /** - * Create a new integer sort. - **/ - public IntSort MkIntSort() - { - - - return new IntSort(this); - } - - /** - * Create a real sort. - **/ - public RealSort MkRealSort() - { - - return new RealSort(this); - } - - /** - * Create a new bit-vector sort. - **/ - public BitVecSort MkBitVecSort(long size) - { - - - return new BitVecSort(this, size); - } - - /** - * Create a new array sort. - **/ - public ArraySort MkArraySort(Sort domain, Sort range) - { - - - - - CheckContextMatch(domain); - CheckContextMatch(range); - return new ArraySort(this, domain, range); - } - - /** - * Create a new tuple sort. - **/ - public TupleSort MkTupleSort(Symbol name, Symbol[] fieldNames, Sort[] fieldSorts) - { - - - - - - - CheckContextMatch(name); - CheckContextMatch(fieldNames); - CheckContextMatch(fieldSorts); - return new TupleSort(this, name, (long)fieldNames.Length, fieldNames, fieldSorts); - } - - /** - * Create a new enumeration sort. - **/ - public EnumSort MkEnumSort(Symbol name, Symbol[] enumNames) - { - - - - - - - CheckContextMatch(name); - CheckContextMatch(enumNames); - return new EnumSort(this, name, enumNames); - } - - /** - * Create a new enumeration sort. - **/ - public EnumSort MkEnumSort(String name, String[] enumNames) - { - - - - return new EnumSort(this, MkSymbol(name), MkSymbols(enumNames)); - } - - /** - * Create a new list sort. - **/ - public ListSort MkListSort(Symbol name, Sort elemSort) - { - - - - - CheckContextMatch(name); - CheckContextMatch(elemSort); - return new ListSort(this, name, elemSort); - } - - /** - * Create a new list sort. - **/ - public ListSort MkListSort(String name, Sort elemSort) - { - - - - CheckContextMatch(elemSort); - return new ListSort(this, MkSymbol(name), elemSort); - } - - /** - * Create a new finite domain sort. - **/ - public FiniteDomainSort MkFiniteDomainSort(Symbol name, ulong size) - { - - - - CheckContextMatch(name); - return new FiniteDomainSort(this, name, size); - } - - /** - * Create a new finite domain sort. - **/ - public FiniteDomainSort MkFiniteDomainSort(String name, ulong size) - { - - - return new FiniteDomainSort(this, MkSymbol(name), size); - } - - - /** - * Create a datatype constructor. - * constructor name - * name of recognizer function. - * names of the constructor fields. - * field sorts, 0 if the field sort refers to a recursive sort. - * reference to datatype sort that is an argument to the constructor; - * if the corresponding sort reference is 0, then the value in sort_refs should be an index - * referring to one of the recursive datatypes that is declared. - **/ - public Constructor MkConstructor(Symbol name, Symbol recognizer, Symbol[] fieldNames, Sort[] sorts, long[] sortRefs) - { - - - - - return new Constructor(this, name, recognizer, fieldNames, sorts, sortRefs); - } - - /** - * Create a datatype constructor. - * - * - * - * - * - * @return - **/ - public Constructor MkConstructor(String name, String recognizer, String[] fieldNames, Sort[] sorts, long[] sortRefs) - { - - - return new Constructor(this, MkSymbol(name), MkSymbol(recognizer), MkSymbols(fieldNames), sorts, sortRefs); - } - - /** - * Create a new datatype sort. - **/ - public DatatypeSort MkDatatypeSort(Symbol name, Constructor[] constructors) - { - - - - - - - CheckContextMatch(name); - CheckContextMatch(constructors); - return new DatatypeSort(this, name, constructors); - } - - /** - * Create a new datatype sort. - **/ - public DatatypeSort MkDatatypeSort(String name, Constructor[] constructors) - { - - - - - CheckContextMatch(constructors); - return new DatatypeSort(this, MkSymbol(name), constructors); - } - - /** - * Create mutually recursive datatypes. - * names of datatype sorts - * list of constructors, one list per sort. - **/ - public DatatypeSort[] MkDatatypeSorts(Symbol[] names, Constructor[][] c) - { - - - - - - - - CheckContextMatch(names); - long n = (long)names.Length; - ConstructorList[] cla = new ConstructorList[n]; - IntPtr[] n_constr = new IntPtr[n]; - for (long i = 0; i < n; i++) - { - var constructor = c[i]; - - CheckContextMatch(constructor); - cla[i] = new ConstructorList(this, constructor); - n_constr[i] = cla[i].NativeObject; - } - IntPtr[] n_res = new IntPtr[n]; - Native.mkDatatypes(nCtx, n, Symbol.ArrayToNative(names), n_res, n_constr); - DatatypeSort[] res = new DatatypeSort[n]; - for (long i = 0; i < n; i++) - res[i] = new DatatypeSort(this, n_res[i]); - return res; - } - - /** - * Create mutually recursive data-types. - * - * - * @return - **/ - public DatatypeSort[] MkDatatypeSorts(String[] names, Constructor[][] c) - { - - - - - - - - return MkDatatypeSorts(MkSymbols(names), c); - } - - - /** - * Creates a new function declaration. - **/ - public FuncDecl MkFuncDecl(Symbol name, Sort[] domain, Sort range) - { - - - - - - CheckContextMatch(name); - CheckContextMatch(domain); - CheckContextMatch(range); - return new FuncDecl(this, name, domain, range); - } - - /** - * Creates a new function declaration. - **/ - public FuncDecl MkFuncDecl(Symbol name, Sort domain, Sort range) - { - - - - - - CheckContextMatch(name); - CheckContextMatch(domain); - CheckContextMatch(range); - Sort[] q = new Sort[] { domain }; - return new FuncDecl(this, name, q, range); - } - - /** - * Creates a new function declaration. - **/ - public FuncDecl MkFuncDecl(String name, Sort[] domain, Sort range) - { - - - - - CheckContextMatch(domain); - CheckContextMatch(range); - return new FuncDecl(this, MkSymbol(name), domain, range); - } - - /** - * Creates a new function declaration. - **/ - public FuncDecl MkFuncDecl(String name, Sort domain, Sort range) - { - - - - - CheckContextMatch(domain); - CheckContextMatch(range); - Sort[] q = new Sort[] { domain }; - return new FuncDecl(this, MkSymbol(name), q, range); - } - - /** - * Creates a fresh function declaration with a name prefixed with . - * - * - **/ - public FuncDecl MkFreshFuncDecl(String prefix, Sort[] domain, Sort range) - { - - - - - CheckContextMatch(domain); - CheckContextMatch(range); - return new FuncDecl(this, prefix, domain, range); - } - - /** - * Creates a new constant function declaration. - **/ - public FuncDecl MkConstDecl(Symbol name, Sort range) - { - - - - - CheckContextMatch(name); - CheckContextMatch(range); - return new FuncDecl(this, name, null, range); - } - - /** - * Creates a new constant function declaration. - **/ - public FuncDecl MkConstDecl(String name, Sort range) - { - - - - CheckContextMatch(range); - return new FuncDecl(this, MkSymbol(name), null, range); - } - - /** - * Creates a fresh constant function declaration with a name prefixed with . - * - * - **/ - public FuncDecl MkFreshConstDecl(String prefix, Sort range) - { - - - - CheckContextMatch(range); - return new FuncDecl(this, prefix, null, range); - } - - /** - * Creates a new bound variable. - * The de-Bruijn index of the variable - * The sort of the variable - **/ - public Expr MkBound(long index, Sort ty) - { - - - - return Expr.Create(this, Native.mkBound(nCtx, index, ty.NativeObject)); - } - - /** - * Create a quantifier pattern. - **/ - public Pattern MkPattern(Expr[] terms) - { - - if (terms.Length == 0) - throw new Z3Exception("Cannot create a pattern from zero terms"); - - - - - - IntPtr[] termsNative = AST.ArrayToNative(terms); - return new Pattern(this, Native.mkPattern(nCtx, (long)terms.Length, termsNative)); - } - - /** - * Creates a new Constant of sort and named . - **/ - public Expr MkConst(Symbol name, Sort range) - { - - - - - CheckContextMatch(name); - CheckContextMatch(range); - - return Expr.Create(this, Native.mkConst(nCtx, name.NativeObject, range.NativeObject)); - } - - /** - * Creates a new Constant of sort and named . - **/ - public Expr MkConst(String name, Sort range) - { - - - - return MkConst(MkSymbol(name), range); - } - - /** - * Creates a fresh Constant of sort and a - * name prefixed with . - **/ - public Expr MkFreshConst(String prefix, Sort range) - { - - - - CheckContextMatch(range); - return Expr.Create(this, Native.mkFreshConst(nCtx, prefix, range.NativeObject)); - } - - /** - * Creates a fresh constant from the FuncDecl . - * A decl of a 0-arity function - **/ - public Expr MkConst(FuncDecl f) - { - - - - return MkApp(f); - } - - /** - * Create a Boolean constant. - **/ - public BoolExpr MkBoolConst(Symbol name) - { - - - - return (BoolExpr)MkConst(name, BoolSort); - } - - /** - * Create a Boolean constant. - **/ - public BoolExpr MkBoolConst(String name) - { - - - return (BoolExpr)MkConst(MkSymbol(name), BoolSort); - } - - /** - * Creates an integer constant. - **/ - public IntExpr MkIntConst(Symbol name) - { - - - - return (IntExpr)MkConst(name, IntSort); - } - - /** - * Creates an integer constant. - **/ - public IntExpr MkIntConst(String name) - { - - - - return (IntExpr)MkConst(name, IntSort); - } - - /** - * Creates a real constant. - **/ - public RealExpr MkRealConst(Symbol name) - { - - - - return (RealExpr)MkConst(name, RealSort); - } - - /** - * Creates a real constant. - **/ - public RealExpr MkRealConst(String name) - { - - - return (RealExpr)MkConst(name, RealSort); - } - - /** - * Creates a bit-vector constant. - **/ - public BitVecExpr MkBVConst(Symbol name, long size) - { - - - - return (BitVecExpr)MkConst(name, MkBitVecSort(size)); - } - - /** - * Creates a bit-vector constant. - **/ - public BitVecExpr MkBVConst(String name, long size) - { - - - return (BitVecExpr)MkConst(name, MkBitVecSort(size)); - } - - /** - * Create a new function application. - **/ - public Expr MkApp(FuncDecl f, Expr[] args) - { - - - - - CheckContextMatch(f); - CheckContextMatch(args); - return Expr.Create(this, f, args); - } - - /** - * The true Term. - **/ - public BoolExpr MkTrue() - { - - - return new BoolExpr(this, Native.mkTrue(nCtx)); - } - - /** - * The false Term. - **/ - public BoolExpr MkFalse() - { - - - return new BoolExpr(this, Native.mkFalse(nCtx)); - } - - /** - * Creates a Boolean value. - **/ - public BoolExpr MkBool(boolean value) - { - - - return value ? MkTrue() : MkFalse(); - } - - /** - * Creates the equality = . - **/ - public BoolExpr MkEq(Expr x, Expr y) - { - - - - - CheckContextMatch(x); - CheckContextMatch(y); - return new BoolExpr(this, Native.mkEq(nCtx, x.NativeObject, y.NativeObject)); - } - - /** - * Creates a distinct term. - **/ - public BoolExpr MkDistinct(Expr[] args) - { - - - - - - CheckContextMatch(args); - return new BoolExpr(this, Native.mkDistinct(nCtx, (long)args.Length, AST.ArrayToNative(args))); - } - - /** - * Mk an expression representing not(a). - **/ - public BoolExpr MkNot(BoolExpr a) - { - - - - CheckContextMatch(a); - return new BoolExpr(this, Native.mkNot(nCtx, a.NativeObject)); - } - - /** - * Create an expression representing an if-then-else: ite(t1, t2, t3). - * An expression with Boolean sort - * An expression - * An expression with the same sort as - **/ - public Expr MkITE(BoolExpr t1, Expr t2, Expr t3) - { - - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - CheckContextMatch(t3); - return Expr.Create(this, Native.mkIte(nCtx, t1.NativeObject, t2.NativeObject, t3.NativeObject)); - } - - /** - * Create an expression representing t1 iff t2. - **/ - public BoolExpr MkIff(BoolExpr t1, BoolExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkIff(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Create an expression representing t1 -> t2. - **/ - public BoolExpr MkImplies(BoolExpr t1, BoolExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkImplies(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Create an expression representing t1 xor t2. - **/ - public BoolExpr MkXor(BoolExpr t1, BoolExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkXor(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Create an expression representing t[0] and t[1] and .... - **/ - public BoolExpr MkAnd(BoolExpr[] t) - { - - - - - CheckContextMatch(t); - return new BoolExpr(this, Native.mkAnd(nCtx, (long)t.Length, AST.ArrayToNative(t))); - } - - /** - * Create an expression representing t[0] or t[1] or .... - **/ - public BoolExpr MkOr(BoolExpr[] t) - { - - - - - CheckContextMatch(t); - return new BoolExpr(this, Native.mkOr(nCtx, (long)t.Length, AST.ArrayToNative(t))); - } - - /** - * Create an expression representing t[0] + t[1] + .... - **/ - public ArithExpr MkAdd(ArithExpr[] t) - { - - - - - CheckContextMatch(t); - return (ArithExpr)Expr.Create(this, Native.mkAdd(nCtx, (long)t.Length, AST.ArrayToNative(t))); - } - - /** - * Create an expression representing t[0] * t[1] * .... - **/ - public ArithExpr MkMul(ArithExpr[] t) - { - - - - - CheckContextMatch(t); - return (ArithExpr)Expr.Create(this, Native.mkMul(nCtx, (long)t.Length, AST.ArrayToNative(t))); - } - - /** - * Create an expression representing t[0] - t[1] - .... - **/ - public ArithExpr MkSub(ArithExpr[] t) - { - - - - - CheckContextMatch(t); - return (ArithExpr)Expr.Create(this, Native.mkSub(nCtx, (long)t.Length, AST.ArrayToNative(t))); - } - - /** - * Create an expression representing -t. - **/ - public ArithExpr MkUnaryMinus(ArithExpr t) - { - - - - CheckContextMatch(t); - return (ArithExpr)Expr.Create(this, Native.mkUnaryMinus(nCtx, t.NativeObject)); - } - - /** - * Create an expression representing t1 / t2. - **/ - public ArithExpr MkDiv(ArithExpr t1, ArithExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return (ArithExpr)Expr.Create(this, Native.mkDiv(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Create an expression representing t1 mod t2. - * The arguments must have int type. - **/ - public IntExpr MkMod(IntExpr t1, IntExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new IntExpr(this, Native.mkMod(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Create an expression representing t1 rem t2. - * The arguments must have int type. - **/ - public IntExpr MkRem(IntExpr t1, IntExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new IntExpr(this, Native.mkRem(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Create an expression representing t1 ^ t2. - **/ - public ArithExpr MkPower(ArithExpr t1, ArithExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return (ArithExpr)Expr.Create(this, Native.mkPower(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Create an expression representing t1 < t2 - **/ - public BoolExpr MkLt(ArithExpr t1, ArithExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkLt(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Create an expression representing t1 <= t2 - **/ - public BoolExpr MkLe(ArithExpr t1, ArithExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkLe(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Create an expression representing t1 > t2 - **/ - public BoolExpr MkGt(ArithExpr t1, ArithExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkGt(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Create an expression representing t1 >= t2 - **/ - public BoolExpr MkGe(ArithExpr t1, ArithExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkGe(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Coerce an integer to a real. - * - * There is also a converse operation exposed. It follows the semantics prescribed by the SMT-LIB standard. - * - * You can take the floor of a real by creating an auxiliary integer Term k and - * and asserting MakeInt2Real(k) <= t1 < MkInt2Real(k)+1. - * The argument must be of integer sort. - * - **/ - public RealExpr MkInt2Real(IntExpr t) - { - - - - CheckContextMatch(t); - return new RealExpr(this, Native.mkInt2real(nCtx, t.NativeObject)); - } - - /** - * Coerce a real to an integer. - * - * The semantics of this function follows the SMT-LIB standard for the function to_int. - * The argument must be of real sort. - * - **/ - public IntExpr MkReal2Int(RealExpr t) - { - - - - CheckContextMatch(t); - return new IntExpr(this, Native.mkReal2int(nCtx, t.NativeObject)); - } - - /** - * Creates an expression that checks whether a real number is an integer. - **/ - public BoolExpr MkIsInteger(RealExpr t) - { - - - - CheckContextMatch(t); - return new BoolExpr(this, Native.mkIsInt(nCtx, t.NativeObject)); - } - - /** - * Bitwise negation. - * The argument must have a bit-vector sort. - **/ - public BitVecExpr MkBVNot(BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Native.mkBvnot(nCtx, t.NativeObject)); - } - - /** - * Take conjunction of bits in a vector, return vector of length 1. - * The argument must have a bit-vector sort. - **/ - public BitVecExpr MkBVRedAND(BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Native.mkBvredand(nCtx, t.NativeObject)); - } - - /** - * Take disjunction of bits in a vector, return vector of length 1. - * The argument must have a bit-vector sort. - **/ - public BitVecExpr MkBVRedOR(BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Native.mkBvredor(nCtx, t.NativeObject)); - } - - /** - * Bitwise conjunction. - * The arguments must have a bit-vector sort. - **/ - public BitVecExpr MkBVAND(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvand(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Bitwise disjunction. - * The arguments must have a bit-vector sort. - **/ - public BitVecExpr MkBVOR(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvor(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Bitwise XOR. - * The arguments must have a bit-vector sort. - **/ - public BitVecExpr MkBVXOR(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvxor(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Bitwise NAND. - * The arguments must have a bit-vector sort. - **/ - public BitVecExpr MkBVNAND(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvnand(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Bitwise NOR. - * The arguments must have a bit-vector sort. - **/ - public BitVecExpr MkBVNOR(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvnor(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Bitwise XNOR. - * The arguments must have a bit-vector sort. - **/ - public BitVecExpr MkBVXNOR(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvxnor(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Standard two's complement unary minus. - * The arguments must have a bit-vector sort. - **/ - public BitVecExpr MkBVNeg(BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Native.mkBvneg(nCtx, t.NativeObject)); - } - - /** - * Two's complement addition. - * The arguments must have the same bit-vector sort. - **/ - public BitVecExpr MkBVAdd(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvadd(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Two's complement subtraction. - * The arguments must have the same bit-vector sort. - **/ - public BitVecExpr MkBVSub(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvsub(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Two's complement multiplication. - * The arguments must have the same bit-vector sort. - **/ - public BitVecExpr MkBVMul(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvmul(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Unsigned division. - * - * It is defined as the floor of t1/t2 if \c t2 is - * different from zero. If t2 is zero, then the result - * is undefined. - * The arguments must have the same bit-vector sort. - * - **/ - public BitVecExpr MkBVUDiv(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvudiv(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Signed division. - * - * It is defined in the following way: - * - * - The \c floor of t1/t2 if \c t2 is different from zero, and t1*t2 >= 0. - * - * - The \c ceiling of t1/t2 if \c t2 is different from zero, and t1*t2 < 0. - * - * If t2 is zero, then the result is undefined. - * The arguments must have the same bit-vector sort. - * - **/ - public BitVecExpr MkBVSDiv(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvsdiv(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Unsigned remainder. - * - * It is defined as t1 - (t1 /u t2) * t2, where /u represents unsigned division. - * If t2 is zero, then the result is undefined. - * The arguments must have the same bit-vector sort. - * - **/ - public BitVecExpr MkBVURem(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvurem(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Signed remainder. - * - * It is defined as t1 - (t1 /s t2) * t2, where /s represents signed division. - * The most significant bit (sign) of the result is equal to the most significant bit of \c t1. - * - * If t2 is zero, then the result is undefined. - * The arguments must have the same bit-vector sort. - * - **/ - public BitVecExpr MkBVSRem(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvsrem(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Two's complement signed remainder (sign follows divisor). - * - * If t2 is zero, then the result is undefined. - * The arguments must have the same bit-vector sort. - * - **/ - public BitVecExpr MkBVSMod(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvsmod(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Unsigned less-than - * - * The arguments must have the same bit-vector sort. - * - **/ - public BoolExpr MkBVULT(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvult(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Two's complement signed less-than - * - * The arguments must have the same bit-vector sort. - * - **/ - public BoolExpr MkBVSLT(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvslt(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Unsigned less-than or equal to. - * - * The arguments must have the same bit-vector sort. - * - **/ - public BoolExpr MkBVULE(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvule(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Two's complement signed less-than or equal to. - * - * The arguments must have the same bit-vector sort. - * - **/ - public BoolExpr MkBVSLE(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvsle(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Unsigned greater than or equal to. - * - * The arguments must have the same bit-vector sort. - * - **/ - public BoolExpr MkBVUGE(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvuge(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Two's complement signed greater than or equal to. - * - * The arguments must have the same bit-vector sort. - * - **/ - public BoolExpr MkBVSGE(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvsge(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Unsigned greater-than. - * - * The arguments must have the same bit-vector sort. - * - **/ - public BoolExpr MkBVUGT(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvugt(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Two's complement signed greater-than. - * - * The arguments must have the same bit-vector sort. - * - **/ - public BoolExpr MkBVSGT(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvsgt(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Bit-vector concatenation. - * - * The arguments must have a bit-vector sort. - * - * @return - * The result is a bit-vector of size n1+n2, where n1 (n2) - * is the size of t1 (t2). - * - **/ - public BitVecExpr MkConcat(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkConcat(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Bit-vector extraction. - * - * Extract the bits down to from a bitvector of - * size m to yield a new bitvector of size n, where - * n = high - low + 1. - * The argument must have a bit-vector sort. - * - **/ - public BitVecExpr MkExtract(long high, long low, BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Native.mkExtract(nCtx, high, low, t.NativeObject)); - } - - /** - * Bit-vector sign extension. - * - * Sign-extends the given bit-vector to the (signed) equivalent bitvector of - * size m+i, where \c m is the size of the given bit-vector. - * The argument must have a bit-vector sort. - * - **/ - public BitVecExpr MkSignExt(long i, BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Native.mkSignExt(nCtx, i, t.NativeObject)); - } - - /** - * Bit-vector zero extension. - * - * Extend the given bit-vector with zeros to the (unsigned) equivalent - * bitvector of size m+i, where \c m is the size of the - * given bit-vector. - * The argument must have a bit-vector sort. - * - **/ - public BitVecExpr MkZeroExt(long i, BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Native.mkZeroExt(nCtx, i, t.NativeObject)); - } - - /** - * Bit-vector repetition. - * - * The argument must have a bit-vector sort. - * - **/ - public BitVecExpr MkRepeat(long i, BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Native.mkRepeat(nCtx, i, t.NativeObject)); - } - - /** - * Shift left. - * - * It is equivalent to multiplication by 2^x where \c x is the value of . - * - * NB. The semantics of shift operations varies between environments. This - * definition does not necessarily capture directly the semantics of the - * programming language or assembly architecture you are modeling. - * - * The arguments must have a bit-vector sort. - * - **/ - public BitVecExpr MkBVSHL(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvshl(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Logical shift right - * - * It is equivalent to unsigned division by 2^x where \c x is the value of . - * - * NB. The semantics of shift operations varies between environments. This - * definition does not necessarily capture directly the semantics of the - * programming language or assembly architecture you are modeling. - * - * The arguments must have a bit-vector sort. - * - **/ - public BitVecExpr MkBVLSHR(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvlshr(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Arithmetic shift right - * - * It is like logical shift right except that the most significant - * bits of the result always copy the most significant bit of the - * second argument. - * - * NB. The semantics of shift operations varies between environments. This - * definition does not necessarily capture directly the semantics of the - * programming language or assembly architecture you are modeling. - * - * The arguments must have a bit-vector sort. - * - **/ - public BitVecExpr MkBVASHR(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkBvashr(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Rotate Left. - * - * Rotate bits of \c t to the left \c i times. - * The argument must have a bit-vector sort. - * - **/ - public BitVecExpr MkBVRotateLeft(long i, BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Native.mkRotateLeft(nCtx, i, t.NativeObject)); - } - - /** - * Rotate Right. - * - * Rotate bits of \c t to the right \c i times. - * The argument must have a bit-vector sort. - * - **/ - public BitVecExpr MkBVRotateRight(long i, BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Native.mkRotateRight(nCtx, i, t.NativeObject)); - } - - /** - * Rotate Left. - * - * Rotate bits of to the left times. - * The arguments must have the same bit-vector sort. - * - **/ - public BitVecExpr MkBVRotateLeft(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkExtRotateLeft(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Rotate Right. - * - * Rotate bits of to the right times. - * The arguments must have the same bit-vector sort. - * - **/ - public BitVecExpr MkBVRotateRight(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BitVecExpr(this, Native.mkExtRotateRight(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Create an bit bit-vector from the integer argument . - * - * NB. This function is essentially treated as uninterpreted. - * So you cannot expect Z3 to precisely reflect the semantics of this function - * when solving constraints with this function. - * - * The argument must be of integer sort. - * - **/ - public BitVecExpr MkInt2BV(long n, IntExpr t) - { - - - - CheckContextMatch(t); - return new BitVecExpr(this, Native.mkInt2bv(nCtx, n, t.NativeObject)); - } - - /** - * Create an integer from the bit-vector argument . - * - * If \c is_signed is false, then the bit-vector \c t1 is treated as unsigned. - * So the result is non-negative and in the range [0..2^N-1], where - * N are the number of bits in . - * If \c is_signed is true, \c t1 is treated as a signed bit-vector. - * - * NB. This function is essentially treated as uninterpreted. - * So you cannot expect Z3 to precisely reflect the semantics of this function - * when solving constraints with this function. - * - * The argument must be of bit-vector sort. - * - **/ - public IntExpr MkBV2Int(BitVecExpr t, boolean signed) - { - - - - CheckContextMatch(t); - return new IntExpr(this, Native.mkBv2int(nCtx, t.NativeObject, (signed) ? 1 : 0)); - } - - /** - * Create a predicate that checks that the bit-wise addition does not overflow. - * - * The arguments must be of bit-vector sort. - * - **/ - public BoolExpr MkBVAddNoOverflow(BitVecExpr t1, BitVecExpr t2, boolean isSigned) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvaddNoOverflow(nCtx, t1.NativeObject, t2.NativeObject, (isSigned) ? 1 : 0)); - } - - /** - * Create a predicate that checks that the bit-wise addition does not underflow. - * - * The arguments must be of bit-vector sort. - * - **/ - public BoolExpr MkBVAddNoUnderflow(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvaddNoUnderflow(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Create a predicate that checks that the bit-wise subtraction does not overflow. - * - * The arguments must be of bit-vector sort. - * - **/ - public BoolExpr MkBVSubNoOverflow(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvsubNoOverflow(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Create a predicate that checks that the bit-wise subtraction does not underflow. - * - * The arguments must be of bit-vector sort. - * - **/ - public BoolExpr MkBVSubNoUnderflow(BitVecExpr t1, BitVecExpr t2, boolean isSigned) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvsubNoUnderflow(nCtx, t1.NativeObject, t2.NativeObject, (isSigned) ? 1 : 0)); - } - - /** - * Create a predicate that checks that the bit-wise signed division does not overflow. - * - * The arguments must be of bit-vector sort. - * - **/ - public BoolExpr MkBVSDivNoOverflow(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvsdivNoOverflow(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Create a predicate that checks that the bit-wise negation does not overflow. - * - * The arguments must be of bit-vector sort. - * - **/ - public BoolExpr MkBVNegNoOverflow(BitVecExpr t) - { - - - - CheckContextMatch(t); - return new BoolExpr(this, Native.mkBvnegNoOverflow(nCtx, t.NativeObject)); - } - - /** - * Create a predicate that checks that the bit-wise multiplication does not overflow. - * - * The arguments must be of bit-vector sort. - * - **/ - public BoolExpr MkBVMulNoOverflow(BitVecExpr t1, BitVecExpr t2, boolean isSigned) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvmulNoOverflow(nCtx, t1.NativeObject, t2.NativeObject, (isSigned) ? 1 : 0)); - } - - /** - * Create a predicate that checks that the bit-wise multiplication does not underflow. - * - * The arguments must be of bit-vector sort. - * - **/ - public BoolExpr MkBVMulNoUnderflow(BitVecExpr t1, BitVecExpr t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new BoolExpr(this, Native.mkBvmulNoUnderflow(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Create an array constant. - **/ - public ArrayExpr MkArrayConst(Symbol name, Sort domain, Sort range) - { - - - - - - return (ArrayExpr)MkConst(name, MkArraySort(domain, range)); - } - - /** - * Create an array constant. - **/ - public ArrayExpr MkArrayConst(String name, Sort domain, Sort range) - { - - - - - return (ArrayExpr)MkConst(MkSymbol(name), MkArraySort(domain, range)); - } - - /** - * Array read. - * - * The argument a is the array and i is the index - * of the array that gets read. - * - * The node a must have an array sort [domain -> range], - * and i must have the sort domain. - * The sort of the result is range. - * - * - * - **/ - public Expr MkSelect(ArrayExpr a, Expr i) - { - - - - - CheckContextMatch(a); - CheckContextMatch(i); - return Expr.Create(this, Native.mkSelect(nCtx, a.NativeObject, i.NativeObject)); - } - - /** - * Array update. - * - * The node a must have an array sort [domain -> range], - * i must have sort domain, - * v must have sort range. The sort of the result is [domain -> range]. - * The semantics of this function is given by the theory of arrays described in the SMT-LIB - * standard. See http://smtlib.org for more details. - * The result of this function is an array that is equal to a - * (with respect to select) - * on all indices except for i, where it maps to v - * (and the select of a with - * respect to i may be a different value). - * - * - * - **/ - public ArrayExpr MkStore(ArrayExpr a, Expr i, Expr v) - { - - - - - - CheckContextMatch(a); - CheckContextMatch(i); - CheckContextMatch(v); - return new ArrayExpr(this, Native.mkStore(nCtx, a.NativeObject, i.NativeObject, v.NativeObject)); - } - - /** - * Create a constant array. - * - * The resulting term is an array, such that a selecton an arbitrary index - * produces the value v. - * - * - * - **/ - public ArrayExpr MkConstArray(Sort domain, Expr v) - { - - - - - CheckContextMatch(domain); - CheckContextMatch(v); - return new ArrayExpr(this, Native.mkConstArray(nCtx, domain.NativeObject, v.NativeObject)); - } - - /** - * Maps f on the argument arrays. - * - * Eeach element of args must be of an array sort [domain_i -> range_i]. - * The function declaration f must have type range_1 .. range_n -> range. - * v must have sort range. The sort of the result is [domain_i -> range]. - * - * - * - * - **/ - public ArrayExpr MkMap(FuncDecl f, ArrayExpr[] args) - { - - - - - CheckContextMatch(f); - CheckContextMatch(args); - return (ArrayExpr)Expr.Create(this, Native.mkMap(nCtx, f.NativeObject, AST.ArrayLength(args), AST.ArrayToNative(args))); - } - - /** - * Access the array default value. - * - * Produces the default range value, for arrays that can be represented as - * finite maps with a default range value. - * - **/ - public Expr MkTermArray(ArrayExpr array) - { - - - - CheckContextMatch(array); - return Expr.Create(this, Native.mkArrayDefault(nCtx, array.NativeObject)); - } - - /** - * Create a set type. - **/ - public SetSort MkSetSort(Sort ty) - { - - - - CheckContextMatch(ty); - return new SetSort(this, ty); - } - - /** - * Create an empty set. - **/ - public Expr MkEmptySet(Sort domain) - { - - - - CheckContextMatch(domain); - return Expr.Create(this, Native.mkEmptySet(nCtx, domain.NativeObject)); - } - - /** - * Create the full set. - **/ - public Expr MkFullSet(Sort domain) - { - - - - CheckContextMatch(domain); - return Expr.Create(this, Native.mkFullSet(nCtx, domain.NativeObject)); - } - - /** - * Add an element to the set. - **/ - public Expr MkSetAdd(Expr set, Expr element) - { - - - - - CheckContextMatch(set); - CheckContextMatch(element); - return Expr.Create(this, Native.mkSetAdd(nCtx, set.NativeObject, element.NativeObject)); - } - - - /** - * Remove an element from a set. - **/ - public Expr MkSetDel(Expr set, Expr element) - { - - - - - CheckContextMatch(set); - CheckContextMatch(element); - return Expr.Create(this, Native.mkSetDel(nCtx, set.NativeObject, element.NativeObject)); - } - - /** - * Take the union of a list of sets. - **/ - public Expr MkSetUnion(Expr[] args) - { - - - - CheckContextMatch(args); - return Expr.Create(this, Native.mkSetUnion(nCtx, (long)args.Length, AST.ArrayToNative(args))); - } - - /** - * Take the intersection of a list of sets. - **/ - public Expr MkSetIntersection(Expr[] args) - { - - - - - CheckContextMatch(args); - return Expr.Create(this, Native.mkSetIntersect(nCtx, (long)args.Length, AST.ArrayToNative(args))); - } - - /** - * Take the difference between two sets. - **/ - public Expr MkSetDifference(Expr arg1, Expr arg2) - { - - - - - CheckContextMatch(arg1); - CheckContextMatch(arg2); - return Expr.Create(this, Native.mkSetDifference(nCtx, arg1.NativeObject, arg2.NativeObject)); - } - - /** - * Take the complement of a set. - **/ - public Expr MkSetComplement(Expr arg) - { - - - - CheckContextMatch(arg); - return Expr.Create(this, Native.mkSetComplement(nCtx, arg.NativeObject)); - } - - /** - * Check for set membership. - **/ - public Expr MkSetMembership(Expr elem, Expr set) - { - - - - - CheckContextMatch(elem); - CheckContextMatch(set); - return Expr.Create(this, Native.mkSetMember(nCtx, elem.NativeObject, set.NativeObject)); - } - - /** - * Check for subsetness of sets. - **/ - public Expr MkSetSubset(Expr arg1, Expr arg2) - { - - - - - CheckContextMatch(arg1); - CheckContextMatch(arg2); - return Expr.Create(this, Native.mkSetSubset(nCtx, arg1.NativeObject, arg2.NativeObject)); - } - - - /** - * Create a Term of a given sort. - * A string representing the Term value in decimal notation. If the given sort is a real, then the Term can be a rational, that is, a string of the form [num]* / [num]*. - * The sort of the numeral. In the current implementation, the given sort can be an int, real, or bit-vectors of arbitrary size. - * @return A Term with value and sort - **/ - public Expr MkNumeral(String v, Sort ty) - { - - - - CheckContextMatch(ty); - return Expr.Create(this, Native.mkNumeral(nCtx, v, ty.NativeObject)); - } - - /** - * Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. - * It is slightly faster than MakeNumeral since it is not necessary to parse a string. - * Value of the numeral - * Sort of the numeral - * @return A Term with value and type - **/ - public Expr MkNumeral(int v, Sort ty) - { - - - - CheckContextMatch(ty); - return Expr.Create(this, Native.mkInt(nCtx, v, ty.NativeObject)); - } - - /** - * Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. - * It is slightly faster than MakeNumeral since it is not necessary to parse a string. - * Value of the numeral - * Sort of the numeral - * @return A Term with value and type - **/ - public Expr MkNumeral(long v, Sort ty) - { - - - - CheckContextMatch(ty); - return Expr.Create(this, Native.mkUnsignedInt(nCtx, v, ty.NativeObject)); - } - - /** - * Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. - * It is slightly faster than MakeNumeral since it is not necessary to parse a string. - * Value of the numeral - * Sort of the numeral - * @return A Term with value and type - **/ - public Expr MkNumeral(long v, Sort ty) - { - - - - CheckContextMatch(ty); - return Expr.Create(this, Native.mkInt64(nCtx, v, ty.NativeObject)); - } - - /** - * Create a Term of a given sort. This function can be use to create numerals that fit in a machine integer. - * It is slightly faster than MakeNumeral since it is not necessary to parse a string. - * Value of the numeral - * Sort of the numeral - * @return A Term with value and type - **/ - public Expr MkNumeral(ulong v, Sort ty) - { - - - - CheckContextMatch(ty); - return Expr.Create(this, Native.mkUnsignedInt64(nCtx, v, ty.NativeObject)); - } - - /** - * Create a real from a fraction. - * numerator of rational. - * denominator of rational. - * @return A Term with value / and sort Real - * - **/ - public RatNum MkReal(int num, int den) - { - if (den == 0) - throw new Z3Exception("Denominator is zero"); - - - - - return new RatNum(this, Native.mkReal(nCtx, num, den)); - } - - /** - * Create a real numeral. - * A string representing the Term value in decimal notation. - * @return A Term with value and sort Real - **/ - public RatNum MkReal(String v) - { - - - return new RatNum(this, Native.mkNumeral(nCtx, v, RealSort.NativeObject)); - } - - /** - * Create a real numeral. - * value of the numeral. - * @return A Term with value and sort Real - **/ - public RatNum MkReal(int v) - { - - - return new RatNum(this, Native.mkInt(nCtx, v, RealSort.NativeObject)); - } - - /** - * Create a real numeral. - * value of the numeral. - * @return A Term with value and sort Real - **/ - public RatNum MkReal(long v) - { - - - return new RatNum(this, Native.mkUnsignedInt(nCtx, v, RealSort.NativeObject)); - } - - /** - * Create a real numeral. - * value of the numeral. - * @return A Term with value and sort Real - **/ - public RatNum MkReal(long v) - { - - - return new RatNum(this, Native.mkInt64(nCtx, v, RealSort.NativeObject)); - } - - /** - * Create a real numeral. - * value of the numeral. - * @return A Term with value and sort Real - **/ - public RatNum MkReal(ulong v) - { - - - return new RatNum(this, Native.mkUnsignedInt64(nCtx, v, RealSort.NativeObject)); - } - - /** - * Create an integer numeral. - * A string representing the Term value in decimal notation. - **/ - public IntNum MkInt(String v) - { - - - return new IntNum(this, Native.mkNumeral(nCtx, v, IntSort.NativeObject)); - } - - /** - * Create an integer numeral. - * value of the numeral. - * @return A Term with value and sort Integer - **/ - public IntNum MkInt(int v) - { - - - return new IntNum(this, Native.mkInt(nCtx, v, IntSort.NativeObject)); - } - - /** - * Create an integer numeral. - * value of the numeral. - * @return A Term with value and sort Integer - **/ - public IntNum MkInt(long v) - { - - - return new IntNum(this, Native.mkUnsignedInt(nCtx, v, IntSort.NativeObject)); - } - - /** - * Create an integer numeral. - * value of the numeral. - * @return A Term with value and sort Integer - **/ - public IntNum MkInt(long v) - { - - - return new IntNum(this, Native.mkInt64(nCtx, v, IntSort.NativeObject)); - } - - /** - * Create an integer numeral. - * value of the numeral. - * @return A Term with value and sort Integer - **/ - public IntNum MkInt(ulong v) - { - - - return new IntNum(this, Native.mkUnsignedInt64(nCtx, v, IntSort.NativeObject)); - } - - /** - * Create a bit-vector numeral. - * A string representing the value in decimal notation. - * the size of the bit-vector - **/ - public BitVecNum MkBV(String v, long size) - { - - - return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); - } - - /** - * Create a bit-vector numeral. - * value of the numeral. - * the size of the bit-vector - **/ - public BitVecNum MkBV(int v, long size) - { - - - return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); - } - - /** - * Create a bit-vector numeral. - * value of the numeral. - * the size of the bit-vector - **/ - public BitVecNum MkBV(long v, long size) - { - - - return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); - } - - /** - * Create a bit-vector numeral. - * value of the numeral. - * * the size of the bit-vector - **/ - public BitVecNum MkBV(long v, long size) - { - - - return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); - } - - /** - * Create a bit-vector numeral. - * value of the numeral. - * the size of the bit-vector - **/ - public BitVecNum MkBV(ulong v, long size) - { - - - return (BitVecNum)MkNumeral(v, MkBitVecSort(size)); - } - - - /** - * Create a universal Quantifier. - * - * Creates a forall formula, where is the weight, - * is an array of patterns, is an array - * with the sorts of the bound variables, is an array with the - * 'names' of the bound variables, and is the body of the - * quantifier. Quantifiers are associated with weights indicating - * the importance of using the quantifier during instantiation. - * - * the sorts of the bound variables. - * names of the bound variables - * the body of the quantifier. - * quantifiers are associated with weights indicating the importance of using the quantifier during instantiation. By default, pass the weight 0. - * array containing the patterns created using MkPattern. - * array containing the anti-patterns created using MkPattern. - * optional symbol to track quantifier. - * optional symbol to track skolem constants. - **/ - public Quantifier MkForall(Sort[] sorts, Symbol[] names, Expr body, long weight, Pattern[] patterns, Expr[] noPatterns, Symbol quantifierID, Symbol skolemID) - { - - - - - - - - - - - - return new Quantifier(this, true, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); - } - - - /** - * Create a universal Quantifier. - **/ - public Quantifier MkForall(Expr[] boundConstants, Expr body, long weight, Pattern[] patterns, Expr[] noPatterns, Symbol quantifierID, Symbol skolemID) - { - - - - - - - - return new Quantifier(this, true, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - } - - /** - * Create an existential Quantifier. - * - **/ - public Quantifier MkExists(Sort[] sorts, Symbol[] names, Expr body, long weight, Pattern[] patterns, Expr[] noPatterns, Symbol quantifierID, Symbol skolemID) - { - - - - - - - - - - - return new Quantifier(this, false, sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); - } - - /** - * Create an existential Quantifier. - **/ - public Quantifier MkExists(Expr[] boundConstants, Expr body, long weight, Pattern[] patterns, Expr[] noPatterns, Symbol quantifierID, Symbol skolemID) - { - - - - - - - return new Quantifier(this, false, boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - } - - - /** - * Create a Quantifier. - **/ - public Quantifier MkQuantifier(boolean universal, Sort[] sorts, Symbol[] names, Expr body, long weight, Pattern[] patterns, Expr[] noPatterns, Symbol quantifierID, Symbol skolemID) - { - - - - - - - - - - - - if (universal) - return MkForall(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); - else - return MkExists(sorts, names, body, weight, patterns, noPatterns, quantifierID, skolemID); - } - - - /** - * Create a Quantifier. - **/ - public Quantifier MkQuantifier(boolean universal, Expr[] boundConstants, Expr body, long weight, Pattern[] patterns, Expr[] noPatterns, Symbol quantifierID, Symbol skolemID) - { - - - - - - - - if (universal) - return MkForall(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - else - return MkExists(boundConstants, body, weight, patterns, noPatterns, quantifierID, skolemID); - } - - - - /** - * Selects the format used for pretty-printing expressions. - * - * The default mode for pretty printing expressions is to produce - * SMT-LIB style output where common subexpressions are printed - * at each occurrence. The mode is called Z3_PRINT_SMTLIB_FULL. - * To print shared common subexpressions only once, - * use the Z3_PRINT_LOW_LEVEL mode. - * To print in way that conforms to SMT-LIB standards and uses let - * expressions to share common sub-expressions use Z3_PRINT_SMTLIB_COMPLIANT. - * - * - * - * - * - **/ - public void setPrintMode(Z3_ast_print_mode value) { Native.setAstPrintMode(nCtx, (long)value); } - - /** - * Convert a benchmark into an SMT-LIB formatted string. - * Name of the benchmark. The argument is optional. - * The benchmark logic. - * The status string (sat, unsat, or unknown) - * Other attributes, such as source, difficulty or category. - * Auxiliary assumptions. - * Formula to be checked for consistency in conjunction with assumptions. - * @return A string representation of the benchmark. - **/ - public String BenchmarkToSMTString(String name, String logic, String status, String attributes, - BoolExpr[] assumptions, BoolExpr formula) - { - - - - - return Native.benchmarkToSmtlibString(nCtx, name, logic, status, attributes, - (long)assumptions.Length, AST.ArrayToNative(assumptions), - formula.NativeObject); - } - - /** - * Parse the given string using the SMT-LIB parser. - * - * The symbol table of the parser can be initialized using the given sorts and declarations. - * The symbols in the arrays and - * don't need to match the names of the sorts and declarations in the arrays - * and . This is a useful feature since we can use arbitrary names to - * reference sorts and declarations. - * - **/ - public void ParseSMTLIBString(String str, Symbol[] sortNames, Sort[] sorts, Symbol[] declNames, FuncDecl[] decls) - { - long csn = Symbol.ArrayLength(sortNames); - long cs = Sort.ArrayLength(sorts); - long cdn = Symbol.ArrayLength(declNames); - long cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - Native.parseSmtlibString(nCtx, str, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)); - } - - /** - * Parse the given file using the SMT-LIB parser. - * - **/ - public void ParseSMTLIBFile(String fileName, Symbol[] sortNames, Sort[] sorts, Symbol[] declNames, FuncDecl[] decls) - { - long csn = Symbol.ArrayLength(sortNames); - long cs = Sort.ArrayLength(sorts); - long cdn = Symbol.ArrayLength(declNames); - long cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - Native.parseSmtlibFile(nCtx, fileName, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls)); - } - - /** - * The number of SMTLIB formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - **/ - public long NumSMTLIBFormulas () { return Native.getSmtlibNumFormulas(nCtx); } - - /** - * The formulas parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - **/ - public BoolExpr[] SMTLIBFormulas() - { - - - long n = NumSMTLIBFormulas; - BoolExpr[] res = new BoolExpr[n]; - for (long i = 0; i < n; i++) - res[i] = (BoolExpr)Expr.Create(this, Native.getSmtlibFormula(nCtx, i)); - return res; - } - - /** - * The number of SMTLIB assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - **/ - public long NumSMTLIBAssumptions () { return Native.getSmtlibNumAssumptions(nCtx); } - - /** - * The assumptions parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - **/ - public BoolExpr[] SMTLIBAssumptions() - { - - - long n = NumSMTLIBAssumptions; - BoolExpr[] res = new BoolExpr[n]; - for (long i = 0; i < n; i++) - res[i] = (BoolExpr)Expr.Create(this, Native.getSmtlibAssumption(nCtx, i)); - return res; - } - - /** - * The number of SMTLIB declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - **/ - public long NumSMTLIBDecls () { return Native.getSmtlibNumDecls(nCtx); } - - /** - * The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - **/ - public FuncDecl[] SMTLIBDecls() - { - - - long n = NumSMTLIBDecls; - FuncDecl[] res = new FuncDecl[n]; - for (long i = 0; i < n; i++) - res[i] = new FuncDecl(this, Native.getSmtlibDecl(nCtx, i)); - return res; - } - - /** - * The number of SMTLIB sorts parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - **/ - public long NumSMTLIBSorts () { return Native.getSmtlibNumSorts(nCtx); } - - /** - * The declarations parsed by the last call to ParseSMTLIBString or ParseSMTLIBFile. - **/ - public Sort[] SMTLIBSorts() - { - - - long n = NumSMTLIBSorts; - Sort[] res = new Sort[n]; - for (long i = 0; i < n; i++) - res[i] = Sort.Create(this, Native.getSmtlibSort(nCtx, i)); - return res; - } - - /** - * Parse the given string using the SMT-LIB2 parser. - * - * @return A conjunction of assertions in the scope (up to push/pop) at the end of the string. - **/ - public BoolExpr ParseSMTLIB2String(String str, Symbol[] sortNames, Sort[] sorts, Symbol[] declNames, FuncDecl[] decls) - { - - - long csn = Symbol.ArrayLength(sortNames); - long cs = Sort.ArrayLength(sorts); - long cdn = Symbol.ArrayLength(declNames); - long cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - return (BoolExpr)Expr.Create(this, Native.parseSmtlib2String(nCtx, str, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls))); - } - - /** - * Parse the given file using the SMT-LIB2 parser. - * - **/ - public BoolExpr ParseSMTLIB2File(String fileName, Symbol[] sortNames, Sort[] sorts, Symbol[] declNames, FuncDecl[] decls) - { - - - long csn = Symbol.ArrayLength(sortNames); - long cs = Sort.ArrayLength(sorts); - long cdn = Symbol.ArrayLength(declNames); - long cd = AST.ArrayLength(decls); - if (csn != cs || cdn != cd) - throw new Z3Exception("Argument size mismatch"); - return (BoolExpr)Expr.Create(this, Native.parseSmtlib2File(nCtx, fileName, - AST.ArrayLength(sorts), Symbol.ArrayToNative(sortNames), AST.ArrayToNative(sorts), - AST.ArrayLength(decls), Symbol.ArrayToNative(declNames), AST.ArrayToNative(decls))); - } - - /** - * Creates a new Goal. - * - * Note that the Context must have been created with proof generation support if - * is set to true here. - * - * Indicates whether model generation should be enabled. - * Indicates whether unsat core generation should be enabled. - * Indicates whether proof generation should be enabled. - **/ - public Goal MkGoal(boolean models, boolean unsatCores, boolean proofs) - { - - - return new Goal(this, models, unsatCores, proofs); - } - - /** - * Creates a new ParameterSet. - **/ - public Params MkParams() - { - - - return new Params(this); - } - - /** - * The number of supported tactics. - **/ - public long NumTactics() { return Native.getNumTactics(nCtx); } - - /** - * The names of all supported tactics. - **/ - public String[] TacticNames() - { - - - long n = NumTactics; - String[] res = new String[n]; - for (long i = 0; i < n; i++) - res[i] = Native.getTacticName(nCtx, i); - return res; - } - - /** - * Returns a string containing a description of the tactic with the given name. - **/ - public String TacticDescription(String name) - { - - - return Native.tacticGetDescr(nCtx, name); - } - - /** - * Creates a new Tactic. - **/ - public Tactic MkTactic(String name) - { - - - return new Tactic(this, name); - } - - /** - * Create a tactic that applies to a Goal and - * then to every subgoal produced by . - **/ - public Tactic AndThen(Tactic t1, Tactic t2, Tactic[] ts) - { - - - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - CheckContextMatch(ts); - - IntPtr last = IntPtr.Zero; - if (ts != null && ts.Length > 0) - { - last = ts[ts.Length - 1].NativeObject; - for (int i = ts.Length - 2; i >= 0; i--) - last = Native.tacticAndThen(nCtx, ts[i].NativeObject, last); - } - if (last != IntPtr.Zero) - { - last = Native.tacticAndThen(nCtx, t2.NativeObject, last); - return new Tactic(this, Native.tacticAndThen(nCtx, t1.NativeObject, last)); - } - else - return new Tactic(this, Native.tacticAndThen(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Create a tactic that applies to a Goal and - * then to every subgoal produced by . - * - * Shorthand for AndThen. - * - **/ - public Tactic Then(Tactic t1, Tactic t2, Tactic[] ts) - { - - - - - - return AndThen(t1, t2, ts); - } - - /** - * Create a tactic that first applies to a Goal and - * if it fails then returns the result of applied to the Goal. - **/ - public Tactic OrElse(Tactic t1, Tactic t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new Tactic(this, Native.tacticOrElse(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Create a tactic that applies to a goal for milliseconds. - * - * If does not terminate within milliseconds, then it fails. - * - **/ - public Tactic TryFor(Tactic t, long ms) - { - - - - CheckContextMatch(t); - return new Tactic(this, Native.tacticTryFor(nCtx, t.NativeObject, ms)); - } - - /** - * Create a tactic that applies to a given goal if the probe - * evaluates to true. - * - * If evaluates to false, then the new tactic behaves like the skip tactic. - * - **/ - public Tactic When(Probe p, Tactic t) - { - - - - - CheckContextMatch(t); - CheckContextMatch(p); - return new Tactic(this, Native.tacticWhen(nCtx, p.NativeObject, t.NativeObject)); - } - - /** - * Create a tactic that applies to a given goal if the probe - * evaluates to true and otherwise. - **/ - public Tactic Cond(Probe p, Tactic t1, Tactic t2) - { - - - - - - CheckContextMatch(p); - CheckContextMatch(t1); - CheckContextMatch(t2); - return new Tactic(this, Native.tacticCond(nCtx, p.NativeObject, t1.NativeObject, t2.NativeObject)); - } - - /** - * Create a tactic that keeps applying until the goal is not - * modified anymore or the maximum number of iterations is reached. - **/ - public Tactic Repeat(Tactic t, long max) - { - - - - CheckContextMatch(t); - return new Tactic(this, Native.tacticRepeat(nCtx, t.NativeObject, max)); - } - - /** - * Create a tactic that just returns the given goal. - **/ - public Tactic Skip() - { - - - return new Tactic(this, Native.tacticSkip(nCtx)); - } - - /** - * Create a tactic always fails. - **/ - public Tactic Fail() - { - - - return new Tactic(this, Native.tacticFail(nCtx)); - } - - /** - * Create a tactic that fails if the probe evaluates to false. - **/ - public Tactic FailIf(Probe p) - { - - - - CheckContextMatch(p); - return new Tactic(this, Native.tacticFailIf(nCtx, p.NativeObject)); - } - - /** - * Create a tactic that fails if the goal is not triviall satisfiable (i.e., empty) - * or trivially unsatisfiable (i.e., contains `false'). - **/ - public Tactic FailIfNotDecided() - { - - - return new Tactic(this, Native.tacticFailIfNotDecided(nCtx)); - } - - /** - * Create a tactic that applies using the given set of parameters . - **/ - public Tactic UsingParams(Tactic t, Params p) - { - - - - - CheckContextMatch(t); - CheckContextMatch(p); - return new Tactic(this, Native.tacticUsingParams(nCtx, t.NativeObject, p.NativeObject)); - } - - /** - * Create a tactic that applies using the given set of parameters . - * Alias for UsingParams - **/ - public Tactic With(Tactic t, Params p) - { - - - - - return UsingParams(t, p); - } - - /** - * Create a tactic that applies the given tactics in parallel. - **/ - public Tactic ParOr(Tactic[] t) - { - - - - CheckContextMatch(t); - return new Tactic(this, Native.tacticParOr(nCtx, Tactic.ArrayLength(t), Tactic.ArrayToNative(t))); - } - - /** - * Create a tactic that applies to a given goal and then - * to every subgoal produced by . The subgoals are processed in parallel. - **/ - public Tactic ParAndThen(Tactic t1, Tactic t2) - { - - - - - CheckContextMatch(t1); - CheckContextMatch(t2); - return new Tactic(this, Native.tacticParAndThen(nCtx, t1.NativeObject, t2.NativeObject)); - } - - /** - * Interrupt the execution of a Z3 procedure. - * This procedure can be used to interrupt: solvers, simplifiers and tactics. - **/ - public void Interrupt() - { - Native.interrupt(nCtx); - } - - /** - * The number of supported Probes. - **/ - public long NumProbes() { return Native.getNumProbes(nCtx); } - - /** - * The names of all supported Probes. - **/ - public String[] ProbeNames() - { - - - long n = NumProbes; - String[] res = new String[n]; - for (long i = 0; i < n; i++) - res[i] = Native.getProbeName(nCtx, i); - return res; - } - - /** - * Returns a string containing a description of the probe with the given name. - **/ - public String ProbeDescription(String name) - { - - - return Native.probeGetDescr(nCtx, name); - } - - /** - * Creates a new Probe. - **/ - public Probe MkProbe(String name) - { - - - return new Probe(this, name); - } - - /** - * Create a probe that always evaluates to . - **/ - public Probe Const(double val) - { - - - return new Probe(this, Native.probeConst(nCtx, val)); - } - - /** - * Create a probe that evaluates to "true" when the value returned by - * is less than the value returned by - **/ - public Probe Lt(Probe p1, Probe p2) - { - - - - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Native.probeLt(nCtx, p1.NativeObject, p2.NativeObject)); - } - - /** - * Create a probe that evaluates to "true" when the value returned by - * is greater than the value returned by - **/ - public Probe Gt(Probe p1, Probe p2) - { - - - - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Native.probeGt(nCtx, p1.NativeObject, p2.NativeObject)); - } - - /** - * Create a probe that evaluates to "true" when the value returned by - * is less than or equal the value returned by - **/ - public Probe Le(Probe p1, Probe p2) - { - - - - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Native.probeLe(nCtx, p1.NativeObject, p2.NativeObject)); - } - - /** - * Create a probe that evaluates to "true" when the value returned by - * is greater than or equal the value returned by - **/ - public Probe Ge(Probe p1, Probe p2) - { - - - - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Native.probeGe(nCtx, p1.NativeObject, p2.NativeObject)); - } - - /** - * Create a probe that evaluates to "true" when the value returned by - * is equal to the value returned by - **/ - public Probe Eq(Probe p1, Probe p2) - { - - - - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Native.probeEq(nCtx, p1.NativeObject, p2.NativeObject)); - } - - /** - * Create a probe that evaluates to "true" when the value - * and evaluate to "true". - **/ - public Probe And(Probe p1, Probe p2) - { - - - - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Native.probeAnd(nCtx, p1.NativeObject, p2.NativeObject)); - } - - /** - * Create a probe that evaluates to "true" when the value - * or evaluate to "true". - **/ - public Probe Or(Probe p1, Probe p2) - { - - - - - CheckContextMatch(p1); - CheckContextMatch(p2); - return new Probe(this, Native.probeOr(nCtx, p1.NativeObject, p2.NativeObject)); - } - - /** - * Create a probe that evaluates to "true" when the value - * does not evaluate to "true". - **/ - public Probe Not(Probe p) - { - - - - CheckContextMatch(p); - return new Probe(this, Native.probeNot(nCtx, p.NativeObject)); - } - - /** - * Creates a new (incremental) solver. - * - * This solver also uses a set of builtin tactics for handling the first - * check-sat command, and check-sat commands that take more than a given - * number of milliseconds to be solved. - * - **/ - public Solver MkSolver(Symbol logic) - { - - - if (logic == null) - return new Solver(this, Native.mkSolver(nCtx)); - else - return new Solver(this, Native.mkSolverForLogic(nCtx, logic.NativeObject)); - } - - /** - * Creates a new (incremental) solver. - * - **/ - public Solver MkSolver(String logic) - { - - - return MkSolver(MkSymbol(logic)); - } - - /** - * Creates a new (incremental) solver. - **/ - public Solver MkSimpleSolver() - { - - - return new Solver(this, Native.mkSimpleSolver(nCtx)); - } - - /** - * Creates a solver that is implemented using the given tactic. - * - * The solver supports the commands Push and Pop, but it - * will always solve each check from scratch. - * - **/ - public Solver MkSolver(Tactic t) - { - - - - return new Solver(this, Native.mkSolverFromTactic(nCtx, t.NativeObject)); - } - - /** - * Create a Fixedpoint context. - **/ - public Fixedpoint MkFixedpoint() - { - - - return new Fixedpoint(this); - } - - - /** - * Wraps an AST. - * This function is used for transitions between native and - * managed objects. Note that must be a - * native object obtained from Z3 (e.g., through ) - * and that it must have a correct reference count (see e.g., - * . - * - * The native pointer to wrap. - **/ - public AST WrapAST(IntPtr nativeObject) - { - - return AST.Create(this, nativeObject); - } - - /** - * Unwraps an AST. - * This function is used for transitions between native and - * managed objects. It returns the native pointer to the AST. Note that - * AST objects are reference counted and unwrapping an AST disables automatic - * reference counting, i.e., all references to the IntPtr that is returned - * must be handled externally and through native calls (see e.g., - * ). - * - * The AST to unwrap. - **/ - public IntPtr UnwrapAST(AST a) - { - return a.NativeObject; - } - - /** - * Return a string describing all available parameters to Expr.Simplify. - **/ - public String SimplifyHelp() - { - - - return Native.simplifyGetHelp(nCtx); - } - - /** - * Retrieves parameter descriptions for simplifier. - **/ - public ParamDescrs SimplifyParameterDescriptions() { return new ParamDescrs(this, Native.simplifyGetParamDescrs(nCtx)); } - - /** - * Enable/disable printing of warning messages to the console. - * Note that this function is static and effects the behaviour of - * all contexts globally. - **/ - public static void ToggleWarningMessages(boolean enabled) - { - Native.toggleWarningMessages((enabled) ? 1 : 0); - } - - ///// - ///// A delegate which is executed when an error is raised. - ///// - ///// - ///// Note that it is possible for memory leaks to occur if error handlers - ///// throw exceptions. - ///// - //public delegate void ErrorHandler(Context ctx, Z3_error_code errorCode, String errorString); - - ///// - ///// The OnError event. - ///// - //public event ErrorHandler OnError = null; - - /** - * Update a mutable configuration parameter. - * - * The list of all configuration parameters can be obtained using the Z3 executable: - * z3.exe -ini? - * Only a few configuration parameters are mutable once the context is created. - * An exception is thrown when trying to modify an immutable parameter. - * - * - **/ - public void UpdateParamValue(String id, String value) - { - Native.updateParamValue(nCtx, id, value); - } - - /** - * Get a configuration parameter. - * - * Returns null if the parameter value does not exist. - * - * - **/ - public String GetParamValue(String id) - { - Native.IntPtr res = new Native.IntPtr(); - int r = Native.getParamValue(nCtx, id, res); - if (r == (int)Z3_lboolean.Z3_L_FALSE) - return null; - else - return Marshal.PtrtoStringAnsi(res); - } - - - IntPtr m_ctx = IntPtr.Zero; - Native.errorHandler mNErrHandler = null; - IntPtr nCtx () { return m_ctx; } - - void NativeErrorHandler(IntPtr ctx, Z3_error_code errorCode) - { - // Do-nothing error handler. The wrappers in Z3.Native will throw exceptions upon errors. - } - - void InitContext() - { - PrintMode = Z3_ast_print_mode.Z3_PRINT_SMTLIB2_COMPLIANT; - m_n_err_handler = new Native.errorHandler(NativeErrorHandler); // keep reference so it doesn't get collected. - Native.setErrorHandler(m_ctx, m_n_err_handler); - GC.SuppressFinalize(this); - } - - void CheckContextMatch(Z3Object other) - { - - - if (!ReferenceEquals(this, other.Context)) - throw new Z3Exception("Context mismatch"); - } - - void CheckContextMatch(Z3Object[] arr) - { - - - if (arr != null) - { - for (Z3Object.Iterator a = arr.iterator(); a.hasNext(); ) - { - // It was an assume, now we added the precondition, and we made it into an assert - CheckContextMatch(a); - } - } - } - - private void ObjectInvariant() - { - - - - - - - - - - - - - - - - } - - private AST.DecRefQueue m_AST_DRQ = new AST.DecRefQueue(); - private ASTMap.DecRefQueue m_ASTMap_DRQ = new ASTMap.DecRefQueue(); - private ASTVector.DecRefQueue m_ASTVector_DRQ = new ASTVector.DecRefQueue(); - private ApplyResult.DecRefQueue m_ApplyResult_DRQ = new ApplyResult.DecRefQueue(); - private FuncInterp.Entry.DecRefQueue m_FuncEntry_DRQ = new FuncInterp.Entry.DecRefQueue(); - private FuncInterp.DecRefQueue m_FuncInterp_DRQ = new FuncInterp.DecRefQueue(); - private Goal.DecRefQueue m_Goal_DRQ = new Goal.DecRefQueue(); - private Model.DecRefQueue m_Model_DRQ = new Model.DecRefQueue(); - private Params.DecRefQueue m_Params_DRQ = new Params.DecRefQueue(); - private ParamDescrs.DecRefQueue m_ParamDescrs_DRQ = new ParamDescrs.DecRefQueue(); - private Probe.DecRefQueue m_Probe_DRQ = new Probe.DecRefQueue(); - private Solver.DecRefQueue m_Solver_DRQ = new Solver.DecRefQueue(); - private Statistics.DecRefQueue m_Statistics_DRQ = new Statistics.DecRefQueue(); - private Tactic.DecRefQueue m_Tactic_DRQ = new Tactic.DecRefQueue(); - private Fixedpoint.DecRefQueue m_Fixedpoint_DRQ = new Fixedpoint.DecRefQueue(); - - AST.DecRefQueue AST_DRQ () { return m_AST_DRQ; } - ASTMap.DecRefQueue ASTMap_DRQ () { return m_ASTMap_DRQ; } - ASTVector.DecRefQueue ASTVector_DRQ () { return m_ASTVector_DRQ; } - ApplyResult.DecRefQueue ApplyResult_DRQ () { return m_ApplyResult_DRQ; } - FuncInterp.Entry.DecRefQueue FuncEntry_DRQ () { return m_FuncEntry_DRQ; } - FuncInterp.DecRefQueue FuncInterp_DRQ () { return m_FuncInterp_DRQ; } - Goal.DecRefQueue Goal_DRQ () { return m_Goal_DRQ; } - Model.DecRefQueue Model_DRQ () { return m_Model_DRQ; } - Params.DecRefQueue Params_DRQ () { return m_Params_DRQ; } - ParamDescrs.DecRefQueue ParamDescrs_DRQ () { return m_ParamDescrs_DRQ; } - Probe.DecRefQueue Probe_DRQ () { return m_Probe_DRQ; } - Solver.DecRefQueue Solver_DRQ () { return m_Solver_DRQ; } - Statistics.DecRefQueue Statistics_DRQ () { return m_Statistics_DRQ; } - Tactic.DecRefQueue Tactic_DRQ () { return m_Tactic_DRQ; } - Fixedpoint.DecRefQueue Fixedpoint_DRQ () { return m_Fixedpoint_DRQ; } - - - long refCount = 0; - - /** - * Finalizer. - **/ - protected void finalize() - { - // Console.WriteLine("Context Finalizer from " + System.Threading.Thread.CurrentThread.ManagedThreadId); - Dispose(); - - if (refCount == 0) - { - m_n_err_handler = null; - Native.delContext(m_ctx); - m_ctx = IntPtr.Zero; - } - else - GC.ReRegisterForFinalize(this); - } - - /** - * Disposes of the context. - **/ - public void Dispose() - { - // Console.WriteLine("Context Dispose from " + System.Threading.Thread.CurrentThread.ManagedThreadId); - AST_DRQ.Clear(this); - ASTMap_DRQ.Clear(this); - ASTVector_DRQ.Clear(this); - ApplyResult_DRQ.Clear(this); - FuncEntry_DRQ.Clear(this); - FuncInterp_DRQ.Clear(this); - Goal_DRQ.Clear(this); - Model_DRQ.Clear(this); - Params_DRQ.Clear(this); - Probe_DRQ.Clear(this); - Solver_DRQ.Clear(this); - Statistics_DRQ.Clear(this); - Tactic_DRQ.Clear(this); - Fixedpoint_DRQ.Clear(this); - - m_booleanSort = null; - m_intSort = null; - m_realSort = null; - } - } diff --git a/src/api/java/com/Microsoft/Z3/DecRefQUeue.java b/src/api/java/com/Microsoft/Z3/DecRefQUeue.java deleted file mode 100644 index 279887a7c..000000000 --- a/src/api/java/com/Microsoft/Z3/DecRefQUeue.java +++ /dev/null @@ -1,70 +0,0 @@ -/** - * This file was automatically generated from DecRefQUeue.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ -/* using System.Collections; */ -/* using System.Collections.Generic; */ -/* using System.Threading; */ - - abstract class DecRefQueue - { - - private void ObjectInvariant() - { - - } - - - protected Object m_lock = new Object(); - protected List m_queue = new List(); - final long m_move_limit = 1024; - - public abstract void IncRef(Context ctx, IntPtr obj); - public abstract void DecRef(Context ctx, IntPtr obj); - - public void IncAndClear(Context ctx, IntPtr o) - { - - - IncRef(ctx, o); - if (m_queue.Count >= m_move_limit) Clear(ctx); - } - - public void Add(IntPtr o) - { - if (o == IntPtr.Zero) return; - - synchronized (m_lock) - { - m_queue.Add(o); - } - } - - public void Clear(Context ctx) - { - - - synchronized (m_lock) - { - for (IntPtr.Iterator o = m_queue.iterator(); o.hasNext(); ) - DecRef(ctx, o); - m_queue.Clear(); - } - } - } - - abstract class DecRefQueueContracts extends DecRefQueue - { - public void IncRef(Context ctx, IntPtr obj) - { - - } - - public void DecRef(Context ctx, IntPtr obj) - { - - } - } diff --git a/src/api/java/com/Microsoft/Z3/Enumerations/Z3_ast_kind.java b/src/api/java/com/Microsoft/Z3/Enumerations/Z3_ast_kind.java deleted file mode 100644 index 2ba3f58ab..000000000 --- a/src/api/java/com/Microsoft/Z3/Enumerations/Z3_ast_kind.java +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Automatically generated file - **/ - -package com.Microsoft.Z3; - -/** - * Z3_ast_kind - **/ -public enum Z3_ast_kind { -Z3_VAR_AST (2), -Z3_SORT_AST (4), -Z3_QUANTIFIER_AST (3), -Z3_UNKNOWN_AST (1000), -Z3_FUNC_DECL_AST (5), -Z3_NUMERAL_AST (0), -Z3_APP_AST (1), -} - diff --git a/src/api/java/com/Microsoft/Z3/Enumerations/Z3_ast_print_mode.java b/src/api/java/com/Microsoft/Z3/Enumerations/Z3_ast_print_mode.java deleted file mode 100644 index 4aa4a2716..000000000 --- a/src/api/java/com/Microsoft/Z3/Enumerations/Z3_ast_print_mode.java +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Automatically generated file - **/ - -package com.Microsoft.Z3; - -/** - * Z3_ast_print_mode - **/ -public enum Z3_ast_print_mode { -Z3_PRINT_SMTLIB2_COMPLIANT (3), -Z3_PRINT_SMTLIB_COMPLIANT (2), -Z3_PRINT_SMTLIB_FULL (0), -Z3_PRINT_LOW_LEVEL (1), -} - diff --git a/src/api/java/com/Microsoft/Z3/Enumerations/Z3_decl_kind.java b/src/api/java/com/Microsoft/Z3/Enumerations/Z3_decl_kind.java deleted file mode 100644 index 3b0b01715..000000000 --- a/src/api/java/com/Microsoft/Z3/Enumerations/Z3_decl_kind.java +++ /dev/null @@ -1,164 +0,0 @@ -/** - * Automatically generated file - **/ - -package com.Microsoft.Z3; - -/** - * Z3_decl_kind - **/ -public enum Z3_decl_kind { -Z3_OP_LABEL (1792), -Z3_OP_PR_REWRITE (1294), -Z3_OP_UNINTERPRETED (2051), -Z3_OP_SUB (519), -Z3_OP_ZERO_EXT (1058), -Z3_OP_ADD (518), -Z3_OP_IS_INT (528), -Z3_OP_BREDOR (1061), -Z3_OP_BNOT (1051), -Z3_OP_BNOR (1054), -Z3_OP_PR_CNF_STAR (1315), -Z3_OP_RA_JOIN (1539), -Z3_OP_LE (514), -Z3_OP_SET_UNION (773), -Z3_OP_PR_UNDEF (1280), -Z3_OP_BREDAND (1062), -Z3_OP_LT (516), -Z3_OP_RA_UNION (1540), -Z3_OP_BADD (1028), -Z3_OP_BUREM0 (1039), -Z3_OP_OEQ (267), -Z3_OP_PR_MODUS_PONENS (1284), -Z3_OP_RA_CLONE (1548), -Z3_OP_REPEAT (1060), -Z3_OP_RA_NEGATION_FILTER (1544), -Z3_OP_BSMOD0 (1040), -Z3_OP_BLSHR (1065), -Z3_OP_BASHR (1066), -Z3_OP_PR_UNIT_RESOLUTION (1304), -Z3_OP_ROTATE_RIGHT (1068), -Z3_OP_ARRAY_DEFAULT (772), -Z3_OP_PR_PULL_QUANT (1296), -Z3_OP_PR_APPLY_DEF (1310), -Z3_OP_PR_REWRITE_STAR (1295), -Z3_OP_IDIV (523), -Z3_OP_PR_GOAL (1283), -Z3_OP_PR_IFF_TRUE (1305), -Z3_OP_LABEL_LIT (1793), -Z3_OP_BOR (1050), -Z3_OP_PR_SYMMETRY (1286), -Z3_OP_TRUE (256), -Z3_OP_SET_COMPLEMENT (776), -Z3_OP_CONCAT (1056), -Z3_OP_PR_NOT_OR_ELIM (1293), -Z3_OP_IFF (263), -Z3_OP_BSHL (1064), -Z3_OP_PR_TRANSITIVITY (1287), -Z3_OP_SGT (1048), -Z3_OP_RA_WIDEN (1541), -Z3_OP_PR_DEF_INTRO (1309), -Z3_OP_NOT (265), -Z3_OP_PR_QUANT_INTRO (1290), -Z3_OP_UGT (1047), -Z3_OP_DT_RECOGNISER (2049), -Z3_OP_SET_INTERSECT (774), -Z3_OP_BSREM (1033), -Z3_OP_RA_STORE (1536), -Z3_OP_SLT (1046), -Z3_OP_ROTATE_LEFT (1067), -Z3_OP_PR_NNF_NEG (1313), -Z3_OP_PR_REFLEXIVITY (1285), -Z3_OP_ULEQ (1041), -Z3_OP_BIT1 (1025), -Z3_OP_BIT0 (1026), -Z3_OP_EQ (258), -Z3_OP_BMUL (1030), -Z3_OP_ARRAY_MAP (771), -Z3_OP_STORE (768), -Z3_OP_PR_HYPOTHESIS (1302), -Z3_OP_RA_RENAME (1545), -Z3_OP_AND (261), -Z3_OP_TO_REAL (526), -Z3_OP_PR_NNF_POS (1312), -Z3_OP_PR_AND_ELIM (1292), -Z3_OP_MOD (525), -Z3_OP_BUDIV0 (1037), -Z3_OP_PR_TRUE (1281), -Z3_OP_BNAND (1053), -Z3_OP_PR_ELIM_UNUSED_VARS (1299), -Z3_OP_RA_FILTER (1543), -Z3_OP_FD_LT (1549), -Z3_OP_RA_EMPTY (1537), -Z3_OP_DIV (522), -Z3_OP_ANUM (512), -Z3_OP_MUL (521), -Z3_OP_UGEQ (1043), -Z3_OP_BSREM0 (1038), -Z3_OP_PR_TH_LEMMA (1318), -Z3_OP_BXOR (1052), -Z3_OP_DISTINCT (259), -Z3_OP_PR_IFF_FALSE (1306), -Z3_OP_BV2INT (1072), -Z3_OP_EXT_ROTATE_LEFT (1069), -Z3_OP_PR_PULL_QUANT_STAR (1297), -Z3_OP_BSUB (1029), -Z3_OP_PR_ASSERTED (1282), -Z3_OP_BXNOR (1055), -Z3_OP_EXTRACT (1059), -Z3_OP_PR_DER (1300), -Z3_OP_DT_CONSTRUCTOR (2048), -Z3_OP_GT (517), -Z3_OP_BUREM (1034), -Z3_OP_IMPLIES (266), -Z3_OP_SLEQ (1042), -Z3_OP_GE (515), -Z3_OP_BAND (1049), -Z3_OP_ITE (260), -Z3_OP_AS_ARRAY (778), -Z3_OP_RA_SELECT (1547), -Z3_OP_CONST_ARRAY (770), -Z3_OP_BSDIV (1031), -Z3_OP_OR (262), -Z3_OP_PR_HYPER_RESOLVE (1319), -Z3_OP_AGNUM (513), -Z3_OP_PR_PUSH_QUANT (1298), -Z3_OP_BSMOD (1035), -Z3_OP_PR_IFF_OEQ (1311), -Z3_OP_PR_LEMMA (1303), -Z3_OP_SET_SUBSET (777), -Z3_OP_SELECT (769), -Z3_OP_RA_PROJECT (1542), -Z3_OP_BNEG (1027), -Z3_OP_UMINUS (520), -Z3_OP_REM (524), -Z3_OP_TO_INT (527), -Z3_OP_PR_QUANT_INST (1301), -Z3_OP_SGEQ (1044), -Z3_OP_POWER (529), -Z3_OP_XOR3 (1074), -Z3_OP_RA_IS_EMPTY (1538), -Z3_OP_CARRY (1073), -Z3_OP_DT_ACCESSOR (2050), -Z3_OP_PR_TRANSITIVITY_STAR (1288), -Z3_OP_PR_NNF_STAR (1314), -Z3_OP_PR_COMMUTATIVITY (1307), -Z3_OP_ULT (1045), -Z3_OP_BSDIV0 (1036), -Z3_OP_SET_DIFFERENCE (775), -Z3_OP_INT2BV (1071), -Z3_OP_XOR (264), -Z3_OP_PR_MODUS_PONENS_OEQ (1317), -Z3_OP_BNUM (1024), -Z3_OP_BUDIV (1032), -Z3_OP_PR_MONOTONICITY (1289), -Z3_OP_PR_DEF_AXIOM (1308), -Z3_OP_FALSE (257), -Z3_OP_EXT_ROTATE_RIGHT (1070), -Z3_OP_PR_DISTRIBUTIVITY (1291), -Z3_OP_SIGN_EXT (1057), -Z3_OP_PR_SKOLEMIZE (1316), -Z3_OP_BCOMP (1063), -Z3_OP_RA_COMPLEMENT (1546), -} - diff --git a/src/api/java/com/Microsoft/Z3/Enumerations/Z3_error_code.java b/src/api/java/com/Microsoft/Z3/Enumerations/Z3_error_code.java deleted file mode 100644 index ef5fa6f2c..000000000 --- a/src/api/java/com/Microsoft/Z3/Enumerations/Z3_error_code.java +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Automatically generated file - **/ - -package com.Microsoft.Z3; - -/** - * Z3_error_code - **/ -public enum Z3_error_code { -Z3_INVALID_PATTERN (6), -Z3_MEMOUT_FAIL (7), -Z3_NO_PARSER (5), -Z3_OK (0), -Z3_INVALID_ARG (3), -Z3_EXCEPTION (12), -Z3_IOB (2), -Z3_INTERNAL_FATAL (9), -Z3_INVALID_USAGE (10), -Z3_FILE_ACCESS_ERROR (8), -Z3_SORT_ERROR (1), -Z3_PARSER_ERROR (4), -Z3_DEC_REF_ERROR (11), -} - diff --git a/src/api/java/com/Microsoft/Z3/Enumerations/Z3_goal_prec.java b/src/api/java/com/Microsoft/Z3/Enumerations/Z3_goal_prec.java deleted file mode 100644 index 38e2fdf96..000000000 --- a/src/api/java/com/Microsoft/Z3/Enumerations/Z3_goal_prec.java +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Automatically generated file - **/ - -package com.Microsoft.Z3; - -/** - * Z3_goal_prec - **/ -public enum Z3_goal_prec { -Z3_GOAL_UNDER (1), -Z3_GOAL_PRECISE (0), -Z3_GOAL_UNDER_OVER (3), -Z3_GOAL_OVER (2), -} - diff --git a/src/api/java/com/Microsoft/Z3/Enumerations/Z3_lbool.java b/src/api/java/com/Microsoft/Z3/Enumerations/Z3_lbool.java deleted file mode 100644 index 63ee2e227..000000000 --- a/src/api/java/com/Microsoft/Z3/Enumerations/Z3_lbool.java +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Automatically generated file - **/ - -package com.Microsoft.Z3; - -/** - * Z3_lbool - **/ -public enum Z3_lbool { -Z3_L_TRUE (1), -Z3_L_UNDEF (0), -Z3_L_FALSE (-1), -} - diff --git a/src/api/java/com/Microsoft/Z3/Enumerations/Z3_param_kind.java b/src/api/java/com/Microsoft/Z3/Enumerations/Z3_param_kind.java deleted file mode 100644 index e3d8c0e77..000000000 --- a/src/api/java/com/Microsoft/Z3/Enumerations/Z3_param_kind.java +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Automatically generated file - **/ - -package com.Microsoft.Z3; - -/** - * Z3_param_kind - **/ -public enum Z3_param_kind { -Z3_PK_BOOL (1), -Z3_PK_SYMBOL (3), -Z3_PK_OTHER (5), -Z3_PK_INVALID (6), -Z3_PK_UINT (0), -Z3_PK_STRING (4), -Z3_PK_DOUBLE (2), -} - diff --git a/src/api/java/com/Microsoft/Z3/Enumerations/Z3_parameter_kind.java b/src/api/java/com/Microsoft/Z3/Enumerations/Z3_parameter_kind.java deleted file mode 100644 index 0de56c3cd..000000000 --- a/src/api/java/com/Microsoft/Z3/Enumerations/Z3_parameter_kind.java +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Automatically generated file - **/ - -package com.Microsoft.Z3; - -/** - * Z3_parameter_kind - **/ -public enum Z3_parameter_kind { -Z3_PARAMETER_FUNC_DECL (6), -Z3_PARAMETER_DOUBLE (1), -Z3_PARAMETER_SYMBOL (3), -Z3_PARAMETER_INT (0), -Z3_PARAMETER_AST (5), -Z3_PARAMETER_SORT (4), -Z3_PARAMETER_RATIONAL (2), -} - diff --git a/src/api/java/com/Microsoft/Z3/Enumerations/Z3_sort_kind.java b/src/api/java/com/Microsoft/Z3/Enumerations/Z3_sort_kind.java deleted file mode 100644 index 59a69b4c0..000000000 --- a/src/api/java/com/Microsoft/Z3/Enumerations/Z3_sort_kind.java +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Automatically generated file - **/ - -package com.Microsoft.Z3; - -/** - * Z3_sort_kind - **/ -public enum Z3_sort_kind { -Z3_BV_SORT (4), -Z3_FINITE_DOMAIN_SORT (8), -Z3_ARRAY_SORT (5), -Z3_UNKNOWN_SORT (1000), -Z3_RELATION_SORT (7), -Z3_REAL_SORT (3), -Z3_INT_SORT (2), -Z3_UNINTERPRETED_SORT (0), -Z3_BOOL_SORT (1), -Z3_DATATYPE_SORT (6), -} - diff --git a/src/api/java/com/Microsoft/Z3/Enumerations/Z3_symbol_kind.java b/src/api/java/com/Microsoft/Z3/Enumerations/Z3_symbol_kind.java deleted file mode 100644 index efe5804eb..000000000 --- a/src/api/java/com/Microsoft/Z3/Enumerations/Z3_symbol_kind.java +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Automatically generated file - **/ - -package com.Microsoft.Z3; - -/** - * Z3_symbol_kind - **/ -public enum Z3_symbol_kind { -Z3_INT_SYMBOL (0), -Z3_STRING_SYMBOL (1), -} - diff --git a/src/api/java/com/Microsoft/Z3/Expr.java b/src/api/java/com/Microsoft/Z3/Expr.java deleted file mode 100644 index 760fe813d..000000000 --- a/src/api/java/com/Microsoft/Z3/Expr.java +++ /dev/null @@ -1,1554 +0,0 @@ -/** - * This file was automatically generated from Expr.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * Expressions are terms. - **/ - public class Expr extends AST - { - /** - * Returns a simplified version of the expression. - * A set of parameters to configure the simplifier - * - **/ - public Expr Simplify(Params p) - { - - - if (p == null) - return Expr.Create(Context, Native.simplify(Context.nCtx, NativeObject)); - else - return Expr.Create(Context, Native.simplifyEx(Context.nCtx, NativeObject, p.NativeObject)); - } - - /** - * The function declaration of the function that is applied in this expression. - **/ - public FuncDecl FuncDecl() - { - - return new FuncDecl(Context, Native.getAppDecl(Context.nCtx, NativeObject)); - } - - /** - * Indicates whether the expression is the true or false expression - * or something else (Z3_L_UNDEF). - **/ - public Z3_lboolean BoolValue() { return (Z3_lboolean)Native.getBooleanValue(Context.nCtx, NativeObject); } - - /** - * The number of arguments of the expression. - **/ - public long NumArgs() { return Native.getAppNumArgs(Context.nCtx, NativeObject); } - - /** - * The arguments of the expression. - **/ - public Expr[] Args() - { - - - long n = NumArgs; - Expr[] res = new Expr[n]; - for (long i = 0; i < n; i++) - res[i] = Expr.Create(Context, Native.getAppArg(Context.nCtx, NativeObject, i)); - return res; - } - - /** - * Update the arguments of the expression using the arguments - * The number of new arguments should coincide with the current number of arguments. - **/ - public void Update(Expr[] args) - { - - - - Context.CheckContextMatch(args); - if (args.Length != NumArgs) - throw new Z3Exception("Number of arguments does not match"); - NativeObject = Native.updateTerm(Context.nCtx, NativeObject, (long)args.Length, Expr.ArrayToNative(args)); - } - - /** - * Substitute every occurrence of from[i] in the expression with to[i], for i smaller than num_exprs. - * - * The result is the new expression. The arrays from and to must have size num_exprs. - * For every i smaller than num_exprs, we must have that - * sort of from[i] must be equal to sort of to[i]. - * - **/ - public Expr Substitute(Expr[] from, Expr[] to) - { - - - - - - - Context.CheckContextMatch(from); - Context.CheckContextMatch(to); - if (from.Length != to.Length) - throw new Z3Exception("Argument sizes do not match"); - return Expr.Create(Context, Native.substitute(Context.nCtx, NativeObject, (long)from.Length, Expr.ArrayToNative(from), Expr.ArrayToNative(to))); - } - - /** - * Substitute every occurrence of from in the expression with to. - * - **/ - public Expr Substitute(Expr from, Expr to) - { - - - - - return Substitute(new Expr[] { from }, new Expr[] { to }); - } - - /** - * Substitute the free variables in the expression with the expressions in - * - * For every i smaller than num_exprs, the variable with de-Bruijn index i is replaced with term to[i]. - * - **/ - public Expr SubstituteVars(Expr[] to) - { - - - - - Context.CheckContextMatch(to); - return Expr.Create(Context, Native.substituteVars(Context.nCtx, NativeObject, (long)to.Length, Expr.ArrayToNative(to))); - } - - /** - * Translates (copies) the term to the Context . - * A context - * @return A copy of the term which is associated with - **/ - public Expr Translate(Context ctx) - { - - - - if (ReferenceEquals(Context, ctx)) - return this; - else - return Expr.Create(ctx, Native.translate(Context.nCtx, NativeObject, ctx.nCtx)); - } - - /** - * Returns a string representation of the expression. - **/ - public String toString() - { - return super.toString(); - } - - /** - * Indicates whether the term is a numeral - **/ - public boolean IsNumeral() { return Native.isNumeralAst(Context.nCtx, NativeObject) != 0; } - - /** - * Indicates whether the term is well-sorted. - * @return True if the term is well-sorted, false otherwise. - **/ - public boolean IsWellSorted() { return Native.isWellSorted(Context.nCtx, NativeObject) != 0; } - - /** - * The Sort of the term. - **/ - public Sort Sort() - { - - return Sort.Create(Context, Native.getSort(Context.nCtx, NativeObject)); - } - - /** - * Indicates whether the term represents a constant. - **/ - public boolean IsConst() { return IsExpr && NumArgs == 0 && FuncDecl.DomainSize == 0; } - - /** - * Indicates whether the term is an integer numeral. - **/ - public boolean IsIntNum() { return IsNumeral && IsInt; } - - /** - * Indicates whether the term is a real numeral. - **/ - public boolean IsRatNum() { return IsNumeral && IsReal; } - - /** - * Indicates whether the term is an algebraic number - **/ - public boolean IsAlgebraicNumber() { return Native.isAlgebraicNumber(Context.nCtx, NativeObject) != 0; } - - - /** - * Indicates whether the term has Boolean sort. - **/ - public boolean IsBool() - { - return (IsExpr && - Native.isEqSort(Context.nCtx, - Native.mkBooleanSort(Context.nCtx), - Native.getSort(Context.nCtx, NativeObject)) != 0); - } - - /** - * Indicates whether the term is the constant true. - **/ - public boolean IsTrue() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_TRUE; } - - /** - * Indicates whether the term is the constant false. - **/ - public boolean IsFalse() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FALSE; } - - /** - * Indicates whether the term is an equality predicate. - **/ - public boolean IsEq() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_EQ; } - - /** - * Indicates whether the term is an n-ary distinct predicate (every argument is mutually distinct). - **/ - public boolean IsDistinct() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_DISTINCT; } - - /** - * Indicates whether the term is a ternary if-then-else term - **/ - public boolean IsITE() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ITE; } - - /** - * Indicates whether the term is an n-ary conjunction - **/ - public boolean IsAnd() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_AND; } - - /** - * Indicates whether the term is an n-ary disjunction - **/ - public boolean IsOr() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_OR; } - - /** - * Indicates whether the term is an if-and-only-if (Boolean equivalence, binary) - **/ - public boolean IsIff() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_IFF; } - - /** - * Indicates whether the term is an exclusive or - **/ - public boolean IsXor() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_XOR; } - - /** - * Indicates whether the term is a negation - **/ - public boolean IsNot() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_NOT; } - - /** - * Indicates whether the term is an implication - **/ - public boolean IsImplies() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_IMPLIES; } - - /** - * Indicates whether the term is of integer sort. - **/ - public boolean IsInt() - { - return (Native.isNumeralAst(Context.nCtx, NativeObject) != 0 && - Native.getSortKind(Context.nCtx, Native.getSort(Context.nCtx, NativeObject)) == (long)Z3_sort_kind.Z3_INT_SORT); - } - - /** - * Indicates whether the term is of sort real. - **/ - public boolean IsReal() { return Native.getSortKind(Context.nCtx, Native.getSort(Context.nCtx, NativeObject)) == (long)Z3_sort_kind.Z3_REAL_SORT; } - - /** - * Indicates whether the term is an arithmetic numeral. - **/ - public boolean IsArithmeticNumeral() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ANUM; } - - /** - * Indicates whether the term is a less-than-or-equal - **/ - public boolean IsLE() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_LE; } - - /** - * Indicates whether the term is a greater-than-or-equal - **/ - public boolean IsGE() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_GE; } - - /** - * Indicates whether the term is a less-than - **/ - public boolean IsLT() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_LT; } - - /** - * Indicates whether the term is a greater-than - **/ - public boolean IsGT() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_GT; } - - /** - * Indicates whether the term is addition (binary) - **/ - public boolean IsAdd() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ADD; } - - /** - * Indicates whether the term is subtraction (binary) - **/ - public boolean IsSub() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SUB; } - - /** - * Indicates whether the term is a unary minus - **/ - public boolean IsUMinus() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_UMINUS; } - - /** - * Indicates whether the term is multiplication (binary) - **/ - public boolean IsMul() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_MUL; } - - /** - * Indicates whether the term is division (binary) - **/ - public boolean IsDiv() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_DIV; } - - /** - * Indicates whether the term is integer division (binary) - **/ - public boolean IsIDiv() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_IDIV; } - - /** - * Indicates whether the term is remainder (binary) - **/ - public boolean IsRemainder() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_REM; } - - /** - * Indicates whether the term is modulus (binary) - **/ - public boolean IsModulus() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_MOD; } - - /** - * Indicates whether the term is a coercion of integer to real (unary) - **/ - public boolean IsIntToReal() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_TO_REAL; } - - /** - * Indicates whether the term is a coercion of real to integer (unary) - **/ - public boolean IsRealToInt() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_TO_INT; } - - /** - * Indicates whether the term is a check that tests whether a real is integral (unary) - **/ - public boolean IsRealIsInt() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_IS_INT; } - - /** - * Indicates whether the term is of an array sort. - **/ - public boolean IsArray() - { - return (Native.isApp(Context.nCtx, NativeObject) != 0 && - (Z3_sort_kind)Native.getSortKind(Context.nCtx, Native.getSort(Context.nCtx, NativeObject)) == Z3_sort_kind.Z3_ARRAY_SORT); - } - - /** - * Indicates whether the term is an array store. - * It satisfies select(store(a,i,v),j) = if i = j then v else select(a,j). - * Array store takes at least 3 arguments. - **/ - public boolean IsStore() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_STORE; } - - /** - * Indicates whether the term is an array select. - **/ - public boolean IsSelect() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SELECT; } - - /** - * Indicates whether the term is a constant array. - * For example, select(const(v),i) = v holds for every v and i. The function is unary. - **/ - public boolean IsConstantArray() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_CONST_ARRAY; } - - /** - * Indicates whether the term is a default array. - * For example default(const(v)) = v. The function is unary. - **/ - public boolean IsDefaultArray() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ARRAY_DEFAULT; } - - /** - * Indicates whether the term is an array map. - * It satisfies map[f](a1,..,a_n)[i] = f(a1[i],...,a_n[i]) for every i. - **/ - public boolean IsArrayMap() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ARRAY_MAP; } - - /** - * Indicates whether the term is an as-array term. - * An as-array term is n array value that behaves as the function graph of the - * function passed as parameter. - **/ - public boolean IsAsArray() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_AS_ARRAY; } - - /** - * Indicates whether the term is set union - **/ - public boolean IsSetUnion() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SET_UNION; } - - /** - * Indicates whether the term is set intersection - **/ - public boolean IsSetIntersect() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SET_INTERSECT; } - - /** - * Indicates whether the term is set difference - **/ - public boolean IsSetDifference() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SET_DIFFERENCE; } - - /** - * Indicates whether the term is set complement - **/ - public boolean IsSetComplement() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SET_COMPLEMENT; } - - /** - * Indicates whether the term is set subset - **/ - public boolean IsSetSubset() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SET_SUBSET; } - - /** - * Indicates whether the terms is of bit-vector sort. - **/ - public boolean IsBV() { return Native.getSortKind(Context.nCtx, Native.getSort(Context.nCtx, NativeObject)) == (long)Z3_sort_kind.Z3_BV_SORT; } - - /** - * Indicates whether the term is a bit-vector numeral - **/ - public boolean IsBVNumeral() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BNUM; } - - /** - * Indicates whether the term is a one-bit bit-vector with value one - **/ - public boolean IsBVBitOne() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BIT1; } - - /** - * Indicates whether the term is a one-bit bit-vector with value zero - **/ - public boolean IsBVBitZero() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BIT0; } - - /** - * Indicates whether the term is a bit-vector unary minus - **/ - public boolean IsBVUMinus() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BNEG; } - - /** - * Indicates whether the term is a bit-vector addition (binary) - **/ - public boolean IsBVAdd() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BADD; } - - /** - * Indicates whether the term is a bit-vector subtraction (binary) - **/ - public boolean IsBVSub() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSUB; } - - /** - * Indicates whether the term is a bit-vector multiplication (binary) - **/ - public boolean IsBVMul() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BMUL; } - - /** - * Indicates whether the term is a bit-vector signed division (binary) - **/ - public boolean IsBVSDiv() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSDIV; } - - /** - * Indicates whether the term is a bit-vector unsigned division (binary) - **/ - public boolean IsBVUDiv() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BUDIV; } - - /** - * Indicates whether the term is a bit-vector signed remainder (binary) - **/ - public boolean IsBVSRem() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSREM; } - - /** - * Indicates whether the term is a bit-vector unsigned remainder (binary) - **/ - public boolean IsBVURem() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BUREM; } - - /** - * Indicates whether the term is a bit-vector signed modulus - **/ - public boolean IsBVSMod() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSMOD; } - - /** - * Indicates whether the term is a bit-vector signed division by zero - **/ - boolean IsBVSDiv0 () { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSDIV0; } - - /** - * Indicates whether the term is a bit-vector unsigned division by zero - **/ - boolean IsBVUDiv0 () { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BUDIV0; } - - /** - * Indicates whether the term is a bit-vector signed remainder by zero - **/ - boolean IsBVSRem0 () { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSREM0; } - - /** - * Indicates whether the term is a bit-vector unsigned remainder by zero - **/ - boolean IsBVURem0 () { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BUREM0; } - - /** - * Indicates whether the term is a bit-vector signed modulus by zero - **/ - boolean IsBVSMod0 () { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSMOD0; } - - /** - * Indicates whether the term is an unsigned bit-vector less-than-or-equal - **/ - public boolean IsBVULE() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ULEQ; } - - /** - * Indicates whether the term is a signed bit-vector less-than-or-equal - **/ - public boolean IsBVSLE() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SLEQ; } - - /** - * Indicates whether the term is an unsigned bit-vector greater-than-or-equal - **/ - public boolean IsBVUGE() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_UGEQ; } - - /** - * Indicates whether the term is a signed bit-vector greater-than-or-equal - **/ - public boolean IsBVSGE() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SGEQ; } - - /** - * Indicates whether the term is an unsigned bit-vector less-than - **/ - public boolean IsBVULT() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ULT; } - - /** - * Indicates whether the term is a signed bit-vector less-than - **/ - public boolean IsBVSLT() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SLT; } - - /** - * Indicates whether the term is an unsigned bit-vector greater-than - **/ - public boolean IsBVUGT() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_UGT; } - - /** - * Indicates whether the term is a signed bit-vector greater-than - **/ - public boolean IsBVSGT() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SGT; } - - /** - * Indicates whether the term is a bit-wise AND - **/ - public boolean IsBVAND() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BAND; } - - /** - * Indicates whether the term is a bit-wise OR - **/ - public boolean IsBVOR() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BOR; } - - /** - * Indicates whether the term is a bit-wise NOT - **/ - public boolean IsBVNOT() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BNOT; } - - /** - * Indicates whether the term is a bit-wise XOR - **/ - public boolean IsBVXOR() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BXOR; } - - /** - * Indicates whether the term is a bit-wise NAND - **/ - public boolean IsBVNAND() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BNAND; } - - /** - * Indicates whether the term is a bit-wise NOR - **/ - public boolean IsBVNOR() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BNOR; } - - /** - * Indicates whether the term is a bit-wise XNOR - **/ - public boolean IsBVXNOR() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BXNOR; } - - /** - * Indicates whether the term is a bit-vector concatenation (binary) - **/ - public boolean IsBVConcat() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_CONCAT; } - - /** - * Indicates whether the term is a bit-vector sign extension - **/ - public boolean IsBVSignExtension() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_SIGN_EXT; } - - /** - * Indicates whether the term is a bit-vector zero extension - **/ - public boolean IsBVZeroExtension() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ZERO_EXT; } - - /** - * Indicates whether the term is a bit-vector extraction - **/ - public boolean IsBVExtract() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_EXTRACT; } - - /** - * Indicates whether the term is a bit-vector repetition - **/ - public boolean IsBVRepeat() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_REPEAT; } - - /** - * Indicates whether the term is a bit-vector reduce OR - **/ - public boolean IsBVReduceOR() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BREDOR; } - - /** - * Indicates whether the term is a bit-vector reduce AND - **/ - public boolean IsBVReduceAND() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BREDAND; } - - /** - * Indicates whether the term is a bit-vector comparison - **/ - public boolean IsBVComp() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BCOMP; } - - /** - * Indicates whether the term is a bit-vector shift left - **/ - public boolean IsBVShiftLeft() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BSHL; } - - /** - * Indicates whether the term is a bit-vector logical shift right - **/ - public boolean IsBVShiftRightLogical() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BLSHR; } - - /** - * Indicates whether the term is a bit-vector arithmetic shift left - **/ - public boolean IsBVShiftRightArithmetic() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BASHR; } - - /** - * Indicates whether the term is a bit-vector rotate left - **/ - public boolean IsBVRotateLeft() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ROTATE_LEFT; } - - /** - * Indicates whether the term is a bit-vector rotate right - **/ - public boolean IsBVRotateRight() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_ROTATE_RIGHT; } - - /** - * Indicates whether the term is a bit-vector rotate left (extended) - * Similar to Z3_OP_ROTATE_LEFT, but it is a binary operator instead of a parametric one. - **/ - public boolean IsBVRotateLeftExtended() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_EXT_ROTATE_LEFT; } - - /** - * Indicates whether the term is a bit-vector rotate right (extended) - * Similar to Z3_OP_ROTATE_RIGHT, but it is a binary operator instead of a parametric one. - **/ - public boolean IsBVRotateRightExtended() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_EXT_ROTATE_RIGHT; } - - /** - * Indicates whether the term is a coercion from integer to bit-vector - * This function is not supported by the decision procedures. Only the most - * rudimentary simplification rules are applied to this function. - **/ - public boolean IsIntToBV() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_INT2BV; } - - /** - * Indicates whether the term is a coercion from bit-vector to integer - * This function is not supported by the decision procedures. Only the most - * rudimentary simplification rules are applied to this function. - **/ - public boolean IsBVToInt() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_BV2INT; } - - /** - * Indicates whether the term is a bit-vector carry - * Compute the carry bit in a full-adder. The meaning is given by the - * equivalence (carry l1 l2 l3) <=> (or (and l1 l2) (and l1 l3) (and l2 l3))) - **/ - public boolean IsBVCarry() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_CARRY; } - - /** - * Indicates whether the term is a bit-vector ternary XOR - * The meaning is given by the equivalence (xor3 l1 l2 l3) <=> (xor (xor l1 l2) l3) - **/ - public boolean IsBVXOR3() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_XOR3; } - - - /** - * Indicates whether the term is a label (used by the Boogie Verification condition generator). - * The label has two parameters, a string and a Boolean polarity. It takes one argument, a formula. - **/ - public boolean IsLabel() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_LABEL; } - - /** - * Indicates whether the term is a label literal (used by the Boogie Verification condition generator). - * A label literal has a set of string parameters. It takes no arguments. - **/ - public boolean IsLabelLit() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_LABEL_LIT; } - - /** - * Indicates whether the term is a binary equivalence modulo namings. - * This binary predicate is used in proof terms. - * It captures equisatisfiability and equivalence modulo renamings. - **/ - public boolean IsOEQ() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_OEQ; } - - /** - * Indicates whether the term is a Proof for the expression 'true'. - **/ - public boolean IsProofTrue() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_TRUE; } - - /** - * Indicates whether the term is a proof for a fact asserted by the user. - **/ - public boolean IsProofAsserted() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_ASSERTED; } - - /** - * Indicates whether the term is a proof for a fact (tagged as goal) asserted by the user. - **/ - public boolean IsProofGoal() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_GOAL; } - - /** - * Indicates whether the term is proof via modus ponens - * - * Given a proof for p and a proof for (implies p q), produces a proof for q. - * T1: p - * T2: (implies p q) - * [mp T1 T2]: q - * The second antecedents may also be a proof for (iff p q). - **/ - public boolean IsProofModusPonens() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_MODUS_PONENS; } - - /** - * Indicates whether the term is a proof for (R t t), where R is a reflexive relation. - * This proof object has no antecedents. - * The only reflexive relations that are used are - * equivalence modulo namings, equality and equivalence. - * That is, R is either '~', '=' or 'iff'. - **/ - public boolean IsProofReflexivity() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_REFLEXIVITY; } - - /** - * Indicates whether the term is proof by symmetricity of a relation - * - * Given an symmetric relation R and a proof for (R t s), produces a proof for (R s t). - * T1: (R t s) - * [symmetry T1]: (R s t) - * T1 is the antecedent of this proof object. - * - **/ - public boolean IsProofSymmetry() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_SYMMETRY; } - - /** - * Indicates whether the term is a proof by transitivity of a relation - * - * Given a transitive relation R, and proofs for (R t s) and (R s u), produces a proof - * for (R t u). - * T1: (R t s) - * T2: (R s u) - * [trans T1 T2]: (R t u) - * - **/ - public boolean IsProofTransitivity() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_TRANSITIVITY; } - - /** - * Indicates whether the term is a proof by condensed transitivity of a relation - * - * Condensed transitivity proof. This proof object is only used if the parameter PROOF_MODE is 1. - * It combines several symmetry and transitivity proofs. - * Example: - * T1: (R a b) - * T2: (R c b) - * T3: (R c d) - * [trans* T1 T2 T3]: (R a d) - * R must be a symmetric and transitive relation. - * - * Assuming that this proof object is a proof for (R s t), then - * a proof checker must check if it is possible to prove (R s t) - * using the antecedents, symmetry and transitivity. That is, - * if there is a path from s to t, if we view every - * antecedent (R a b) as an edge between a and b. - * - **/ - public boolean IsProofTransitivityStar() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_TRANSITIVITY_STAR; } - - - /** - * Indicates whether the term is a monotonicity proof object. - * - * T1: (R t_1 s_1) - * ... - * Tn: (R t_n s_n) - * [monotonicity T1 ... Tn]: (R (f t_1 ... t_n) (f s_1 ... s_n)) - * Remark: if t_i == s_i, then the antecedent Ti is suppressed. - * That is, reflexivity proofs are supressed to save space. - * - **/ - public boolean IsProofMonotonicity() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_MONOTONICITY; } - - /** - * Indicates whether the term is a quant-intro proof - * - * Given a proof for (~ p q), produces a proof for (~ (forall (x) p) (forall (x) q)). - * T1: (~ p q) - * [quant-intro T1]: (~ (forall (x) p) (forall (x) q)) - * - **/ - public boolean IsProofQuantIntro() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_QUANT_INTRO; } - - /** - * Indicates whether the term is a distributivity proof object. - * - * Given that f (= or) distributes over g (= and), produces a proof for - * (= (f a (g c d)) - * (g (f a c) (f a d))) - * If f and g are associative, this proof also justifies the following equality: - * (= (f (g a b) (g c d)) - * (g (f a c) (f a d) (f b c) (f b d))) - * where each f and g can have arbitrary number of arguments. - * - * This proof object has no antecedents. - * Remark. This rule is used by the CNF conversion pass and - * instantiated by f = or, and g = and. - * - **/ - public boolean IsProofDistributivity() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_DISTRIBUTIVITY; } - - /** - * Indicates whether the term is a proof by elimination of AND - * - * Given a proof for (and l_1 ... l_n), produces a proof for l_i - * T1: (and l_1 ... l_n) - * [and-elim T1]: l_i - * - **/ - public boolean IsProofAndElimination() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_AND_ELIM; } - - /** - * Indicates whether the term is a proof by eliminiation of not-or - * - * Given a proof for (not (or l_1 ... l_n)), produces a proof for (not l_i). - * T1: (not (or l_1 ... l_n)) - * [not-or-elim T1]: (not l_i) - * - **/ - public boolean IsProofOrElimination() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_NOT_OR_ELIM; } - - /** - * Indicates whether the term is a proof by rewriting - * - * A proof for a local rewriting step (= t s). - * The head function symbol of t is interpreted. - * - * This proof object has no antecedents. - * The conclusion of a rewrite rule is either an equality (= t s), - * an equivalence (iff t s), or equi-satisfiability (~ t s). - * Remark: if f is bool, then = is iff. - * - * Examples: - * (= (+ x 0) x) - * (= (+ x 1 2) (+ 3 x)) - * (iff (or x false) x) - * - **/ - public boolean IsProofRewrite() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_REWRITE; } - - /** - * Indicates whether the term is a proof by rewriting - * - * A proof for rewriting an expression t into an expression s. - * This proof object is used if the parameter PROOF_MODE is 1. - * This proof object can have n antecedents. - * The antecedents are proofs for equalities used as substitution rules. - * The object is also used in a few cases if the parameter PROOF_MODE is 2. - * The cases are: - * - When applying contextual simplification (CONTEXT_SIMPLIFIER=true) - * - When converting bit-vectors to Booleans (BIT2BOOL=true) - * - When pulling ite expression up (PULL_CHEAP_ITE_TREES=true) - * - **/ - public boolean IsProofRewriteStar() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_REWRITE_STAR; } - - /** - * Indicates whether the term is a proof for pulling quantifiers out. - * - * A proof for (iff (f (forall (x) q(x)) r) (forall (x) (f (q x) r))). This proof object has no antecedents. - * - **/ - public boolean IsProofPullQuant() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_PULL_QUANT; } - - /** - * Indicates whether the term is a proof for pulling quantifiers out. - * - * A proof for (iff P Q) where Q is in prenex normal form. - * This proof object is only used if the parameter PROOF_MODE is 1. - * This proof object has no antecedents - * - **/ - public boolean IsProofPullQuantStar() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_PULL_QUANT_STAR; } - - /** - * Indicates whether the term is a proof for pushing quantifiers in. - * - * A proof for: - * (iff (forall (x_1 ... x_m) (and p_1[x_1 ... x_m] ... p_n[x_1 ... x_m])) - * (and (forall (x_1 ... x_m) p_1[x_1 ... x_m]) - * ... - * (forall (x_1 ... x_m) p_n[x_1 ... x_m]))) - * This proof object has no antecedents - * - **/ - public boolean IsProofPushQuant() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_PUSH_QUANT; } - - /** - * Indicates whether the term is a proof for elimination of unused variables. - * - * A proof for (iff (forall (x_1 ... x_n y_1 ... y_m) p[x_1 ... x_n]) - * (forall (x_1 ... x_n) p[x_1 ... x_n])) - * - * It is used to justify the elimination of unused variables. - * This proof object has no antecedents. - * - **/ - public boolean IsProofElimUnusedVars() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_ELIM_UNUSED_VARS; } - - /** - * Indicates whether the term is a proof for destructive equality resolution - * - * A proof for destructive equality resolution: - * (iff (forall (x) (or (not (= x t)) P[x])) P[t]) - * if x does not occur in t. - * - * This proof object has no antecedents. - * - * Several variables can be eliminated simultaneously. - * - **/ - public boolean IsProofDER() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_DER; } - - /** - * Indicates whether the term is a proof for quantifier instantiation - * - * A proof of (or (not (forall (x) (P x))) (P a)) - * - **/ - public boolean IsProofQuantInst() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_QUANT_INST; } - - /** - * Indicates whether the term is a hypthesis marker. - * Mark a hypothesis in a natural deduction style proof. - **/ - public boolean IsProofHypothesis() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_HYPOTHESIS; } - - /** - * Indicates whether the term is a proof by lemma - * - * T1: false - * [lemma T1]: (or (not l_1) ... (not l_n)) - * - * This proof object has one antecedent: a hypothetical proof for false. - * It converts the proof in a proof for (or (not l_1) ... (not l_n)), - * when T1 contains the hypotheses: l_1, ..., l_n. - * - **/ - public boolean IsProofLemma() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_LEMMA; } - - /** - * Indicates whether the term is a proof by unit resolution - * - * T1: (or l_1 ... l_n l_1' ... l_m') - * T2: (not l_1) - * ... - * T(n+1): (not l_n) - * [unit-resolution T1 ... T(n+1)]: (or l_1' ... l_m') - * - **/ - public boolean IsProofUnitResolution() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_UNIT_RESOLUTION; } - - /** - * Indicates whether the term is a proof by iff-true - * - * T1: p - * [iff-true T1]: (iff p true) - * - **/ - public boolean IsProofIFFTrue() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_IFF_TRUE; } - - /** - * Indicates whether the term is a proof by iff-false - * - * T1: (not p) - * [iff-false T1]: (iff p false) - * - **/ - public boolean IsProofIFFFalse() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_IFF_FALSE; } - - /** - * Indicates whether the term is a proof by commutativity - * - * [comm]: (= (f a b) (f b a)) - * - * f is a commutative operator. - * - * This proof object has no antecedents. - * Remark: if f is bool, then = is iff. - * - **/ - public boolean IsProofCommutativity() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_COMMUTATIVITY; } - - /** - * Indicates whether the term is a proof for Tseitin-like axioms - * - * Proof object used to justify Tseitin's like axioms: - * - * (or (not (and p q)) p) - * (or (not (and p q)) q) - * (or (not (and p q r)) p) - * (or (not (and p q r)) q) - * (or (not (and p q r)) r) - * ... - * (or (and p q) (not p) (not q)) - * (or (not (or p q)) p q) - * (or (or p q) (not p)) - * (or (or p q) (not q)) - * (or (not (iff p q)) (not p) q) - * (or (not (iff p q)) p (not q)) - * (or (iff p q) (not p) (not q)) - * (or (iff p q) p q) - * (or (not (ite a b c)) (not a) b) - * (or (not (ite a b c)) a c) - * (or (ite a b c) (not a) (not b)) - * (or (ite a b c) a (not c)) - * (or (not (not a)) (not a)) - * (or (not a) a) - * - * This proof object has no antecedents. - * Note: all axioms are propositional tautologies. - * Note also that 'and' and 'or' can take multiple arguments. - * You can recover the propositional tautologies by - * unfolding the Boolean connectives in the axioms a small - * bounded number of steps (=3). - * - **/ - public boolean IsProofDefAxiom() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_DEF_AXIOM; } - - /** - * Indicates whether the term is a proof for introduction of a name - * - * Introduces a name for a formula/term. - * Suppose e is an expression with free variables x, and def-intro - * introduces the name n(x). The possible cases are: - * - * When e is of Boolean type: - * [def-intro]: (and (or n (not e)) (or (not n) e)) - * - * or: - * [def-intro]: (or (not n) e) - * when e only occurs positively. - * - * When e is of the form (ite cond th el): - * [def-intro]: (and (or (not cond) (= n th)) (or cond (= n el))) - * - * Otherwise: - * [def-intro]: (= n e) - * - **/ - public boolean IsProofDefIntro() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_DEF_INTRO; } - - /** - * Indicates whether the term is a proof for application of a definition - * - * [apply-def T1]: F ~ n - * F is 'equivalent' to n, given that T1 is a proof that - * n is a name for F. - * - **/ - public boolean IsProofApplyDef() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_APPLY_DEF; } - - /** - * Indicates whether the term is a proof iff-oeq - * - * T1: (iff p q) - * [iff~ T1]: (~ p q) - * - **/ - public boolean IsProofIFFOEQ() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_IFF_OEQ; } - - /** - * Indicates whether the term is a proof for a positive NNF step - * - * Proof for a (positive) NNF step. Example: - * - * T1: (not s_1) ~ r_1 - * T2: (not s_2) ~ r_2 - * T3: s_1 ~ r_1' - * T4: s_2 ~ r_2' - * [nnf-pos T1 T2 T3 T4]: (~ (iff s_1 s_2) - * (and (or r_1 r_2') (or r_1' r_2))) - * - * The negation normal form steps NNF_POS and NNF_NEG are used in the following cases: - * (a) When creating the NNF of a positive force quantifier. - * The quantifier is retained (unless the bound variables are eliminated). - * Example - * T1: q ~ q_new - * [nnf-pos T1]: (~ (forall (x T) q) (forall (x T) q_new)) - * - * (b) When recursively creating NNF over Boolean formulas, where the top-level - * connective is changed during NNF conversion. The relevant Boolean connectives - * for NNF_POS are 'implies', 'iff', 'xor', 'ite'. - * NNF_NEG furthermore handles the case where negation is pushed - * over Boolean connectives 'and' and 'or'. - * - **/ - public boolean IsProofNNFPos() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_NNF_POS; } - - /** - * Indicates whether the term is a proof for a negative NNF step - * - * Proof for a (negative) NNF step. Examples: - * - * T1: (not s_1) ~ r_1 - * ... - * Tn: (not s_n) ~ r_n - * [nnf-neg T1 ... Tn]: (not (and s_1 ... s_n)) ~ (or r_1 ... r_n) - * and - * T1: (not s_1) ~ r_1 - * ... - * Tn: (not s_n) ~ r_n - * [nnf-neg T1 ... Tn]: (not (or s_1 ... s_n)) ~ (and r_1 ... r_n) - * and - * T1: (not s_1) ~ r_1 - * T2: (not s_2) ~ r_2 - * T3: s_1 ~ r_1' - * T4: s_2 ~ r_2' - * [nnf-neg T1 T2 T3 T4]: (~ (not (iff s_1 s_2)) - * (and (or r_1 r_2) (or r_1' r_2'))) - * - **/ - public boolean IsProofNNFNeg() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_NNF_NEG; } - - /** - * Indicates whether the term is a proof for (~ P Q) here Q is in negation normal form. - * - * A proof for (~ P Q) where Q is in negation normal form. - * - * This proof object is only used if the parameter PROOF_MODE is 1. - * - * This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. - * - **/ - public boolean IsProofNNFStar() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_NNF_STAR; } - - /** - * Indicates whether the term is a proof for (~ P Q) where Q is in conjunctive normal form. - * - * A proof for (~ P Q) where Q is in conjunctive normal form. - * This proof object is only used if the parameter PROOF_MODE is 1. - * This proof object may have n antecedents. Each antecedent is a PR_DEF_INTRO. - * - **/ - public boolean IsProofCNFStar() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_CNF_STAR; } - - /** - * Indicates whether the term is a proof for a Skolemization step - * - * Proof for: - * - * [sk]: (~ (not (forall x (p x y))) (not (p (sk y) y))) - * [sk]: (~ (exists x (p x y)) (p (sk y) y)) - * - * This proof object has no antecedents. - * - **/ - public boolean IsProofSkolemize() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_SKOLEMIZE; } - - /** - * Indicates whether the term is a proof by modus ponens for equi-satisfiability. - * - * Modus ponens style rule for equi-satisfiability. - * T1: p - * T2: (~ p q) - * [mp~ T1 T2]: q - * - **/ - public boolean IsProofModusPonensOEQ() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_MODUS_PONENS_OEQ; } - - /** - * Indicates whether the term is a proof for theory lemma - * - * Generic proof for theory lemmas. - * - * The theory lemma function comes with one or more parameters. - * The first parameter indicates the name of the theory. - * For the theory of arithmetic, additional parameters provide hints for - * checking the theory lemma. - * The hints for arithmetic are: - * - farkas - followed by rational coefficients. Multiply the coefficients to the - * inequalities in the lemma, add the (negated) inequalities and obtain a contradiction. - * - triangle-eq - Indicates a lemma related to the equivalence: - * (iff (= t1 t2) (and (<= t1 t2) (<= t2 t1))) - * - gcd-test - Indicates an integer linear arithmetic lemma that uses a gcd test. - * - **/ - public boolean IsProofTheoryLemma() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PR_TH_LEMMA; } - - /** - * Indicates whether the term is of an array sort. - **/ - public boolean IsRelation() - { - return (Native.isApp(Context.nCtx, NativeObject) != 0 && - (Z3_sort_kind)Native.getSortKind(Context.nCtx, Native.getSort(Context.nCtx, NativeObject)) == Z3_sort_kind.Z3_RELATION_SORT); - } - - /** - * Indicates whether the term is an relation store - * - * Insert a record into a relation. - * The function takes n+1 arguments, where the first argument is the relation and the remaining n elements - * correspond to the n columns of the relation. - * - **/ - public boolean IsRelationStore() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_STORE; } - - /** - * Indicates whether the term is an empty relation - **/ - public boolean IsEmptyRelation() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_EMPTY; } - - /** - * Indicates whether the term is a test for the emptiness of a relation - **/ - public boolean IsIsEmptyRelation() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_IS_EMPTY; } - - /** - * Indicates whether the term is a relational join - **/ - public boolean IsRelationalJoin() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_JOIN; } - - /** - * Indicates whether the term is the union or convex hull of two relations. - * The function takes two arguments. - **/ - public boolean IsRelationUnion() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_UNION; } - - /** - * Indicates whether the term is the widening of two relations - * The function takes two arguments. - **/ - public boolean IsRelationWiden() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_WIDEN; } - - /** - * Indicates whether the term is a projection of columns (provided as numbers in the parameters). - * The function takes one argument. - **/ - public boolean IsRelationProject() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_PROJECT; } - - /** - * Indicates whether the term is a relation filter - * - * Filter (restrict) a relation with respect to a predicate. - * The first argument is a relation. - * The second argument is a predicate with free de-Brujin indices - * corresponding to the columns of the relation. - * So the first column in the relation has index 0. - * - **/ - public boolean IsRelationFilter() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_FILTER; } - - /** - * Indicates whether the term is an intersection of a relation with the negation of another. - * - * Intersect the first relation with respect to negation - * of the second relation (the function takes two arguments). - * Logically, the specification can be described by a function - * - * target = filter_by_negation(pos, neg, columns) - * - * where columns are pairs c1, d1, .., cN, dN of columns from pos and neg, such that - * target are elements in x in pos, such that there is no y in neg that agrees with - * x on the columns c1, d1, .., cN, dN. - * - **/ - public boolean IsRelationNegationFilter() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_NEGATION_FILTER; } - - /** - * Indicates whether the term is the renaming of a column in a relation - * - * The function takes one argument. - * The parameters contain the renaming as a cycle. - * - **/ - public boolean IsRelationRename() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_RENAME; } - - /** - * Indicates whether the term is the complement of a relation - **/ - public boolean IsRelationComplement() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_COMPLEMENT; } - - /** - * Indicates whether the term is a relational select - * - * Check if a record is an element of the relation. - * The function takes n+1 arguments, where the first argument is a relation, - * and the remaining n arguments correspond to a record. - * - **/ - public boolean IsRelationSelect() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_SELECT; } - - /** - * Indicates whether the term is a relational clone (copy) - * - * Create a fresh copy (clone) of a relation. - * The function is logically the identity, but - * in the context of a register machine allows - * for terms of kind - * to perform destructive updates to the first argument. - * - **/ - public boolean IsRelationClone() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_RA_CLONE; } - - /** - * Indicates whether the term is of an array sort. - **/ - public boolean IsFiniteDomain() - { - return (Native.isApp(Context.nCtx, NativeObject) != 0 && - (Z3_sort_kind)Native.getSortKind(Context.nCtx, Native.getSort(Context.nCtx, NativeObject)) == Z3_sort_kind.Z3_FINITE_DOMAIN_SORT); - } - - /** - * Indicates whether the term is a less than predicate over a finite domain. - **/ - public boolean IsFiniteDomainLT() { return FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_FD_LT; } - - /** - * The de-Burijn index of a bound variable. - * - * Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain - * the meaning of de-Bruijn indices by indicating the compilation process from - * non-de-Bruijn formulas to de-Bruijn format. - * - * abs(forall (x1) phi) = forall (x1) abs1(phi, x1, 0) - * abs(forall (x1, x2) phi) = abs(forall (x1) abs(forall (x2) phi)) - * abs1(x, x, n) = b_n - * abs1(y, x, n) = y - * abs1(f(t1,...,tn), x, n) = f(abs1(t1,x,n), ..., abs1(tn,x,n)) - * abs1(forall (x1) phi, x, n) = forall (x1) (abs1(phi, x, n+1)) - * - * The last line is significant: the index of a bound variable is different depending - * on the scope in which it appears. The deeper x appears, the higher is its - * index. - * - **/ - public long Index() - { - if (!IsVar) - throw new Z3Exception("Term is not a bound variable."); - - - - return Native.getIndexValue(Context.nCtx, NativeObject); - } - - /** - * Constructor for Expr - **/ - protected Expr(Context ctx) { super(ctx); } - /** - * Constructor for Expr - **/ - protected Expr(Context ctx, IntPtr obj) { super(ctx, obj); } - - void CheckNativeObject(IntPtr obj) - { - if (Native.isApp(Context.nCtx, obj) == 0 && - (Z3_ast_kind)Native.getAstKind(Context.nCtx, obj) != Z3_ast_kind.Z3_VAR_AST && - (Z3_ast_kind)Native.getAstKind(Context.nCtx, obj) != Z3_ast_kind.Z3_QUANTIFIER_AST) - throw new Z3Exception("Underlying object is not a term"); - super.CheckNativeObject(obj); - } - - static Expr Create(Context ctx, FuncDecl f, Expr[] arguments) - { - - - - - IntPtr obj = Native.mkApp(ctx.nCtx, f.NativeObject, - AST.ArrayLength(arguments), - AST.ArrayToNative(arguments)); - return Create(ctx, obj); - } - - static Expr Create(Context ctx, IntPtr obj) - { - - - - Z3_ast_kind k = (Z3_ast_kind)Native.getAstKind(ctx.nCtx, obj); - if (k == Z3_ast_kind.Z3_QUANTIFIER_AST) - return new Quantifier(ctx, obj); - IntPtr s = Native.getSort(ctx.nCtx, obj); - Z3_sort_kind sk = (Z3_sort_kind)Native.getSortKind(ctx.nCtx, s); - - if (Native.isAlgebraicNumber(ctx.nCtx, obj) != 0) // is this a numeral ast? - return new AlgebraicNum(ctx, obj); - - if (Native.isNumeralAst(ctx.nCtx, obj) != 0) - { - switch (sk) - { - case Z3_sort_kind.Z3_INT_SORT: return new IntNum(ctx, obj); - case Z3_sort_kind.Z3_REAL_SORT: return new RatNum(ctx, obj); - case Z3_sort_kind.Z3_BV_SORT: return new BitVecNum(ctx, obj); - } - } - - switch (sk) - { - case Z3_sort_kind.Z3_BOOL_SORT: return new BoolExpr(ctx, obj); - case Z3_sort_kind.Z3_INT_SORT: return new IntExpr(ctx, obj); - case Z3_sort_kind.Z3_REAL_SORT: return new RealExpr(ctx, obj); - case Z3_sort_kind.Z3_BV_SORT: return new BitVecExpr(ctx, obj); - case Z3_sort_kind.Z3_ARRAY_SORT: return new ArrayExpr(ctx, obj); - case Z3_sort_kind.Z3_DATATYPE_SORT: return new DatatypeExpr(ctx, obj); - } - - return new Expr(ctx, obj); - } - } - - /** - * Boolean expressions - **/ - public class BoolExpr extends Expr - { - /** Constructor for BoolExpr - **/ - protected BoolExpr(Context ctx) { super(ctx); } - /** Constructor for BoolExpr - **/ - BoolExpr(Context ctx, IntPtr obj) { super(ctx, obj); } - } - - /** - * Arithmetic expressions (int/real) - **/ - public class ArithExpr extends Expr - { - /** Constructor for ArithExpr - **/ - protected ArithExpr(Context ctx) - { super(ctx); - - } - ArithExpr(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - } - - /** - * Int expressions - **/ - public class IntExpr extends ArithExpr - { - /** Constructor for IntExpr - **/ - protected IntExpr(Context ctx) - { super(ctx); - - } - IntExpr(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - } - - /** - * Real expressions - **/ - public class RealExpr extends ArithExpr - { - /** Constructor for RealExpr - **/ - protected RealExpr(Context ctx) - { super(ctx); - - } - RealExpr(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - } - - /** - * Bit-vector expressions - **/ - public class BitVecExpr extends Expr - { - - /** - * The size of the sort of a bit-vector term. - **/ - public long SortSize() { return ((BitVecSort)Sort).Size; } - - /** Constructor for BitVecExpr - **/ - protected BitVecExpr(Context ctx) { super(ctx); } - BitVecExpr(Context ctx, IntPtr obj) { super(ctx, obj); } - } - - /** - * Array expressions - **/ - public class ArrayExpr extends Expr - { - /** Constructor for ArrayExpr - **/ - protected ArrayExpr(Context ctx) - { super(ctx); - - } - ArrayExpr(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - } - - /** - * Datatype expressions - **/ - public class DatatypeExpr extends Expr - { - /** Constructor for DatatypeExpr - **/ - protected DatatypeExpr(Context ctx) - { super(ctx); - - } - DatatypeExpr(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - } diff --git a/src/api/java/com/Microsoft/Z3/Fixedpoint.java b/src/api/java/com/Microsoft/Z3/Fixedpoint.java deleted file mode 100644 index 77ce576ac..000000000 --- a/src/api/java/com/Microsoft/Z3/Fixedpoint.java +++ /dev/null @@ -1,302 +0,0 @@ -/** - * This file was automatically generated from Fixedpoint.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * Object for managing fixedpoints - **/ - public class Fixedpoint extends Z3Object - { - - /** - * A string that describes all available fixedpoint solver parameters. - **/ - public String Help() - { - - return Native.fixedpointGetHelp(Context.nCtx, NativeObject); - } - - /** - * Sets the fixedpoint solver parameters. - **/ - public void setParameters(Params value) - { - - Context.CheckContextMatch(value); - Native.fixedpointSetParams(Context.nCtx, NativeObject, value.NativeObject); - } - - /** - * Retrieves parameter descriptions for Fixedpoint solver. - **/ - public ParamDescrs ParameterDescriptions() { return new ParamDescrs(Context, Native.fixedpointGetParamDescrs(Context.nCtx, NativeObject)); } - - - /** - * Assert a constraint (or multiple) into the fixedpoint solver. - **/ - public void Assert(BoolExpr[] constraints) - { - - - - Context.CheckContextMatch(constraints); - for (BoolExpr.Iterator a = constraints.iterator(); a.hasNext(); ) - { - Native.fixedpointAssert(Context.nCtx, NativeObject, a.NativeObject); - } - } - - /** - * Register predicate as recursive relation. - **/ - public void RegisterRelation(FuncDecl f) - { - - - Context.CheckContextMatch(f); - Native.fixedpointRegisterRelation(Context.nCtx, NativeObject, f.NativeObject); - } - - /** - * Add rule into the fixedpoint solver. - **/ - public void AddRule(BoolExpr rule, Symbol name) - { - - - Context.CheckContextMatch(rule); - Native.fixedpointAddRule(Context.nCtx, NativeObject, rule.NativeObject, AST.GetNativeObject(name)); - } - - /** - * Add table fact to the fixedpoint solver. - **/ - public void AddFact(FuncDecl pred, long[] args) - { - - - - Context.CheckContextMatch(pred); - Native.fixedpointAddFact(Context.nCtx, NativeObject, pred.NativeObject, (long)args.Length, args); - } - - /** - * Query the fixedpoint solver. - * A query is a conjunction of constraints. The constraints may include the recursively defined relations. - * The query is satisfiable if there is an instance of the query variables and a derivation for it. - * The query is unsatisfiable if there are no derivations satisfying the query variables. - **/ - public Status Query(BoolExpr query) - { - - - Context.CheckContextMatch(query); - Z3_lboolean r = (Z3_lboolean)Native.fixedpointQuery(Context.nCtx, NativeObject, query.NativeObject); - switch (r) - { - case Z3_lboolean.Z3_L_TRUE: return Status.SATISFIABLE; - case Z3_lboolean.Z3_L_FALSE: return Status.UNSATISFIABLE; - default: return Status.UNKNOWN; - } - } - - /** - * Query the fixedpoint solver. - * A query is an array of relations. - * The query is satisfiable if there is an instance of some relation that is non-empty. - * The query is unsatisfiable if there are no derivations satisfying any of the relations. - **/ - public Status Query(FuncDecl[] relations) - { - - - - Context.CheckContextMatch(relations); - Z3_lboolean r = (Z3_lboolean)Native.fixedpointQueryRelations(Context.nCtx, NativeObject, - AST.ArrayLength(relations), AST.ArrayToNative(relations)); - switch (r) - { - case Z3_lboolean.Z3_L_TRUE: return Status.SATISFIABLE; - case Z3_lboolean.Z3_L_FALSE: return Status.UNSATISFIABLE; - default: return Status.UNKNOWN; - } - } - - /** - * Creates a backtracking point. - * - **/ - public void Push() - { - Native.fixedpointPush(Context.nCtx, NativeObject); - } - - /** - * Backtrack one backtracking point. - * Note that an exception is thrown if Pop is called without a corresponding Push - * - **/ - public void Pop() - { - Native.fixedpointPop(Context.nCtx, NativeObject); - } - - - /** - * Update named rule into in the fixedpoint solver. - **/ - public void UpdateRule(BoolExpr rule, Symbol name) - { - - - Context.CheckContextMatch(rule); - Native.fixedpointUpdateRule(Context.nCtx, NativeObject, rule.NativeObject, AST.GetNativeObject(name)); - } - - /** - * Retrieve satisfying instance or instances of solver, - * or definitions for the recursive predicates that show unsatisfiability. - **/ - public Expr GetAnswer() - { - IntPtr ans = Native.fixedpointGetAnswer(Context.nCtx, NativeObject); - return (ans == IntPtr.Zero) ? null : Expr.Create(Context, ans); - } - - /** - * Retrieve explanation why fixedpoint engine returned status Unknown. - **/ - public String GetReasonUnknown() - { - - - return Native.fixedpointGetReasonUnknown(Context.nCtx, NativeObject); - } - - /** - * Retrieve the number of levels explored for a given predicate. - **/ - public long GetNumLevels(FuncDecl predicate) - { - return Native.fixedpointGetNumLevels(Context.nCtx, NativeObject, predicate.NativeObject); - } - - /** - * Retrieve the cover of a predicate. - **/ - public Expr GetCoverDelta(int level, FuncDecl predicate) - { - IntPtr res = Native.fixedpointGetCoverDelta(Context.nCtx, NativeObject, level, predicate.NativeObject); - return (res == IntPtr.Zero) ? null : Expr.Create(Context, res); - } - - /** - * Add property about the predicate. - * The property is added at level. - **/ - public void AddCover(int level, FuncDecl predicate, Expr property) - { - Native.fixedpointAddCover(Context.nCtx, NativeObject, level, predicate.NativeObject, property.NativeObject); - } - - /** - * Retrieve internal string representation of fixedpoint object. - **/ - public String toString() - { - return Native.fixedpointtoString(Context.nCtx, NativeObject, 0, null); - } - - /** - * Instrument the Datalog engine on which table representation to use for recursive predicate. - **/ - public void SetPredicateRepresentation(FuncDecl f, Symbol[] kinds) - { - - - Native.fixedpointSetPredicateRepresentation(Context.nCtx, NativeObject, - f.NativeObject, AST.ArrayLength(kinds), Symbol.ArrayToNative(kinds)); - - } - - /** - * Convert benchmark given as set of axioms, rules and queries to a string. - **/ - public String toString(BoolExpr[] queries) - { - - return Native.fixedpointtoString(Context.nCtx, NativeObject, - AST.ArrayLength(queries), AST.ArrayToNative(queries)); - } - - /** - * Retrieve set of rules added to fixedpoint context. - **/ - public BoolExpr[] Rules() - { - - - ASTVector v = new ASTVector(Context, Native.fixedpointGetRules(Context.nCtx, NativeObject)); - long n = v.Size; - BoolExpr[] res = new BoolExpr[n]; - for (long i = 0; i < n; i++) - res[i] = new BoolExpr(Context, v[i].NativeObject); - return res; - } - - /** - * Retrieve set of assertions added to fixedpoint context. - **/ - public BoolExpr[] Assertions() - { - - - ASTVector v = new ASTVector(Context, Native.fixedpointGetAssertions(Context.nCtx, NativeObject)); - long n = v.Size; - BoolExpr[] res = new BoolExpr[n]; - for (long i = 0; i < n; i++) - res[i] = new BoolExpr(Context, v[i].NativeObject); - return res; - } - - - Fixedpoint(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - Fixedpoint(Context ctx) - { super(ctx, Native.mkFixedpoint(ctx.nCtx)); - - } - - class DecRefQueue extends Z3.DecRefQueue - { - public void IncRef(Context ctx, IntPtr obj) - { - Native.fixedpointIncRef(ctx.nCtx, obj); - } - - public void DecRef(Context ctx, IntPtr obj) - { - Native.fixedpointDecRef(ctx.nCtx, obj); - } - }; - - void IncRef(IntPtr o) - { - Context.Fixedpoint_DRQ.IncAndClear(Context, o); - super.IncRef(o); - } - - void DecRef(IntPtr o) - { - Context.Fixedpoint_DRQ.Add(o); - super.DecRef(o); - } - } diff --git a/src/api/java/com/Microsoft/Z3/FuncDecl.java b/src/api/java/com/Microsoft/Z3/FuncDecl.java deleted file mode 100644 index ddedcf4ee..000000000 --- a/src/api/java/com/Microsoft/Z3/FuncDecl.java +++ /dev/null @@ -1,292 +0,0 @@ -/** - * This file was automatically generated from FuncDecl.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * Function declarations. - **/ - public class FuncDecl extends AST - { - /** - * Comparison operator. - * @return True if and share the same context and are equal, false otherwise. - **/ - /* Overloaded operators are not translated. */ - - /** - * Comparison operator. - * @return True if and do not share the same context or are not equal, false otherwise. - **/ - /* Overloaded operators are not translated. */ - - /** - * Object comparison. - **/ - public boolean Equals(object o) - { - FuncDecl casted = (FuncDecl) o; - if (casted == null) return false; - return this == casted; - } - - /** - * A hash code. - **/ - public int GetHashCode() - { - return super.GetHashCode(); - } - - /** - * A string representations of the function declaration. - **/ - public String toString() - { - return Native.funcDecltoString(Context.nCtx, NativeObject); - } - - /** - * Returns a unique identifier for the function declaration. - **/ - public long Id() { return Native.getFuncDeclId(Context.nCtx, NativeObject); } - - /** - * The arity of the function declaration - **/ - public long Arity() { return Native.getArity(Context.nCtx, NativeObject); } - - /** - * The size of the domain of the function declaration - * - **/ - public long DomainSize() { return Native.getDomainSize(Context.nCtx, NativeObject); } - - /** - * The domain of the function declaration - **/ - public Sort[] Domain() - { - - - var n = DomainSize; - - Sort[] res = new Sort[n]; - for (long i = 0; i < n; i++) - res[i] = Sort.Create(Context, Native.getDomain(Context.nCtx, NativeObject, i)); - return res; - } - - /** - * The range of the function declaration - **/ - public Sort Range() - { - - return Sort.Create(Context, Native.getRange(Context.nCtx, NativeObject)); - } - - /** - * The kind of the function declaration. - **/ - public Z3_decl_kind DeclKind() { return (Z3_decl_kind)Native.getDeclKind(Context.nCtx, NativeObject); } - - /** - * The name of the function declaration - **/ - public Symbol Name() - { - - return Symbol.Create(Context, Native.getDeclName(Context.nCtx, NativeObject)); - } - - /** - * The number of parameters of the function declaration - **/ - public long NumParameters() { return Native.getDeclNumParameters(Context.nCtx, NativeObject); } - - /** - * The parameters of the function declaration - **/ - public Parameter[] Parameters() - { - - - long num = NumParameters; - Parameter[] res = new Parameter[num]; - for (long i = 0; i < num; i++) - { - Z3_parameter_kind k = (Z3_parameter_kind)Native.getDeclParameterKind(Context.nCtx, NativeObject, i); - switch (k) - { - case Z3_parameter_kind.Z3_PARAMETER_INT: - res[i] = new Parameter(k, Native.getDeclIntParameter(Context.nCtx, NativeObject, i)); - break; - case Z3_parameter_kind.Z3_PARAMETER_DOUBLE: - res[i] = new Parameter(k, Native.getDeclDoubleParameter(Context.nCtx, NativeObject, i)); - break; - case Z3_parameter_kind.Z3_PARAMETER_SYMBOL: - res[i] = new Parameter(k, Symbol.Create(Context, Native.getDeclSymbolParameter(Context.nCtx, NativeObject, i))); - break; - case Z3_parameter_kind.Z3_PARAMETER_SORT: - res[i] = new Parameter(k, Sort.Create(Context, Native.getDeclSortParameter(Context.nCtx, NativeObject, i))); - break; - case Z3_parameter_kind.Z3_PARAMETER_AST: - res[i] = new Parameter(k, new AST(Context, Native.getDeclAstParameter(Context.nCtx, NativeObject, i))); - break; - case Z3_parameter_kind.Z3_PARAMETER_FUNC_DECL: - res[i] = new Parameter(k, new FuncDecl(Context, Native.getDeclFuncDeclParameter(Context.nCtx, NativeObject, i))); - break; - case Z3_parameter_kind.Z3_PARAMETER_RATIONAL: - res[i] = new Parameter(k, Native.getDeclRationalParameter(Context.nCtx, NativeObject, i)); - break; - default: - throw new Z3Exception("Unknown function declaration parameter kind encountered"); - } - return res; - } - } - - /** - * Function declarations can have Parameters associated with them. - **/ - public class Parameter - { - private Z3_parameter_kind kind; - private int i; - private double d; - private Symbol sym; - private Sort srt; - private AST ast; - private FuncDecl fd; - private String r; - - /**The int value of the parameter. - **/ - public int Int () { if (ParameterKind != Z3_parameter_kind.Z3_PARAMETER_INT) throw new Z3Exception("parameter is not an int"); return i; } - /**The double value of the parameter. - **/ - public double Double () { if (ParameterKind != Z3_parameter_kind.Z3_PARAMETER_DOUBLE) throw new Z3Exception("parameter is not a double "); return d; } - /**The Symbol value of the parameter. - **/ - public Symbol Symbol () { if (ParameterKind != Z3_parameter_kind.Z3_PARAMETER_SYMBOL) throw new Z3Exception("parameter is not a Symbol"); return sym; } - /**The Sort value of the parameter. - **/ - public Sort Sort () { if (ParameterKind != Z3_parameter_kind.Z3_PARAMETER_SORT) throw new Z3Exception("parameter is not a Sort"); return srt; } - /**The AST value of the parameter. - **/ - public AST AST () { if (ParameterKind != Z3_parameter_kind.Z3_PARAMETER_AST) throw new Z3Exception("parameter is not an AST"); return ast; } - /**The FunctionDeclaration value of the parameter. - **/ - public FuncDecl FuncDecl () { if (ParameterKind != Z3_parameter_kind.Z3_PARAMETER_FUNC_DECL) throw new Z3Exception("parameter is not a function declaration"); return fd; } - /**The rational string value of the parameter. - **/ - public String Rational () { if (ParameterKind != Z3_parameter_kind.Z3_PARAMETER_RATIONAL) throw new Z3Exception("parameter is not a rational String"); return r; } - - /** - * The kind of the parameter. - **/ - public Z3_parameter_kind ParameterKind() { return kind; } - - Parameter(Z3_parameter_kind k, int i) - { - this.kind = k; - this.i = i; - } - Parameter(Z3_parameter_kind k, double d) - { - this.kind = k; - this.d = d; - } - - Parameter(Z3_parameter_kind k, Symbol s) - { - this.kind = k; - this.sym = s; - } - - Parameter(Z3_parameter_kind k, Sort s) - { - this.kind = k; - this.srt = s; - } - - Parameter(Z3_parameter_kind k, AST a) - { - this.kind = k; - this.ast = a; - } - - Parameter(Z3_parameter_kind k, FuncDecl fd) - { - this.kind = k; - this.fd = fd; - } - - Parameter(Z3_parameter_kind k, String r) - { - this.kind = k; - this.r = r; - } - } - - FuncDecl(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - - FuncDecl(Context ctx, Symbol name, Sort[] domain, Sort range) - : base(ctx, Native.mkFuncDecl(ctx.nCtx, name.NativeObject, - AST.ArrayLength(domain), AST.ArrayToNative(domain), - range.NativeObject)) - - - - } - - FuncDecl(Context ctx, String prefix, Sort[] domain, Sort range) - : base(ctx, Native.mkFreshFuncDecl(ctx.nCtx, prefix, - AST.ArrayLength(domain), AST.ArrayToNative(domain), - range.NativeObject)) - - - } - - void CheckNativeObject(IntPtr obj) - { - if (Native.getAstKind(Context.nCtx, obj) != (long)Z3_ast_kind.Z3_FUNC_DECL_AST) - throw new Z3Exception("Underlying object is not a function declaration"); - super.CheckNativeObject(obj); - } - - /** - * Create expression that applies function to arguments. - * - * @return - **/ - public Expr this[params() lic Expr this[params Expr[] args - { - public Expr this[params() - { - - - return Apply(args); - } - - /** - * Create expression that applies function to arguments. - * - * @return - **/ - public Expr Apply(Expr[] args) - { - - - Context.CheckContextMatch(args); - return Expr.Create(Context, this, args); - } - - } diff --git a/src/api/java/com/Microsoft/Z3/FuncInterp.java b/src/api/java/com/Microsoft/Z3/FuncInterp.java deleted file mode 100644 index 6aeb33759..000000000 --- a/src/api/java/com/Microsoft/Z3/FuncInterp.java +++ /dev/null @@ -1,179 +0,0 @@ -/** - * This file was automatically generated from FuncInterp.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * A function interpretation is represented as a finite map and an 'else' value. - * Each entry in the finite map represents the value of a function given a set of arguments. - **/ - public class FuncInterp extends Z3Object - { - /** - * An Entry object represents an element in the finite map used to encode - * a function interpretation. - **/ - public class Entry extends Z3Object - { - /** - * Return the (symbolic) value of this entry. - **/ - public Expr Value() { - - return Expr.Create(Context, Native.funcEntryGetValue(Context.nCtx, NativeObject)); } - } - - /** - * The number of arguments of the entry. - **/ - public long NumArgs() { return Native.funcEntryGetNumArgs(Context.nCtx, NativeObject); } - - /** - * The arguments of the function entry. - **/ - public Expr[] Args() - { - - - - long n = NumArgs; - Expr[] res = new Expr[n]; - for (long i = 0; i < n; i++) - res[i] = Expr.Create(Context, Native.funcEntryGetArg(Context.nCtx, NativeObject, i)); - return res; - } - - /** - * A string representation of the function entry. - **/ - public String toString() - { - long n = NumArgs; - String res = "["; - Expr[] args = Args; - for (long i = 0; i < n; i++) - res += args[i] + ", "; - return res + Value + "]"; - } - - Entry(Context ctx, IntPtr obj) { super(ctx, obj); } - - class DecRefQueue extends Z3.DecRefQueue - { - public void IncRef(Context ctx, IntPtr obj) - { - Native.funcEntryIncRef(ctx.nCtx, obj); - } - - public void DecRef(Context ctx, IntPtr obj) - { - Native.funcEntryDecRef(ctx.nCtx, obj); - } - }; - - void IncRef(IntPtr o) - { - Context.FuncEntry_DRQ.IncAndClear(Context, o); - super.IncRef(o); - } - - void DecRef(IntPtr o) - { - Context.FuncEntry_DRQ.Add(o); - super.DecRef(o); - } - }; - - /** - * The number of entries in the function interpretation. - **/ - public long NumEntries() { return Native.funcInterpGetNumEntries(Context.nCtx, NativeObject); } - - /** - * The entries in the function interpretation - **/ - public Entry[] Entries() - { - - Contract.Ensures(Contract.ForAll(0, Contract.Result().Length, - j => Contract.Result()[j] != null)); - - long n = NumEntries; - Entry[] res = new Entry[n]; - for (long i = 0; i < n; i++) - res[i] = new Entry(Context, Native.funcInterpGetEntry(Context.nCtx, NativeObject, i)); - return res; - } - - /** - * The (symbolic) `else' value of the function interpretation. - **/ - public Expr Else() { - - - return Expr.Create(Context, Native.funcInterpGetElse(Context.nCtx, NativeObject)); } - } - - /** - * The arity of the function interpretation - **/ - public long Arity() { return Native.funcInterpGetArity(Context.nCtx, NativeObject); } - - /** - * A string representation of the function interpretation. - **/ - public String toString() - { - String res = ""; - res += "["; - for (Entry.Iterator e = Entries.iterator(); e.hasNext(); ) - { - long n = e.NumArgs; - if (n > 1) res += "["; - Expr[] args = e.Args; - for (long i = 0; i < n; i++) - { - if (i != 0) res += ", "; - res += args[i]; - } - if (n > 1) res += "]"; - res += " -> " + e.Value + ", "; - } - res += "else -> " + Else; - res += "]"; - return res; - } - - FuncInterp(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - - class DecRefQueue extends Z3.DecRefQueue - { - public void IncRef(Context ctx, IntPtr obj) - { - Native.funcInterpIncRef(ctx.nCtx, obj); - } - - public void DecRef(Context ctx, IntPtr obj) - { - Native.funcInterpDecRef(ctx.nCtx, obj); - } - }; - - void IncRef(IntPtr o) - { - Context.FuncInterp_DRQ.IncAndClear(Context, o); - super.IncRef(o); - } - - void DecRef(IntPtr o) - { - Context.FuncInterp_DRQ.Add(o); - super.DecRef(o); - } - } diff --git a/src/api/java/com/Microsoft/Z3/Goal.java b/src/api/java/com/Microsoft/Z3/Goal.java deleted file mode 100644 index 171b81d47..000000000 --- a/src/api/java/com/Microsoft/Z3/Goal.java +++ /dev/null @@ -1,182 +0,0 @@ -/** - * This file was automatically generated from Goal.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * A goal (aka problem). A goal is essentially a set - * of formulas, that can be solved and/or transformed using - * tactics and solvers. - **/ - public class Goal extends Z3Object - { - /** - * The precision of the goal. - * - * Goals can be transformed using over and under approximations. - * An under approximation is applied when the objective is to find a model for a given goal. - * An over approximation is applied when the objective is to find a proof for a given goal. - * - **/ - public Z3_goal_prec Precision() { return (Z3_goal_prec)Native.goalPrecision(Context.nCtx, NativeObject); } - - /** - * Indicates whether the goal is precise. - **/ - public boolean IsPrecise() { return Precision == Z3_goal_prec.Z3_GOAL_PRECISE; } - /** - * Indicates whether the goal is an under-approximation. - **/ - public boolean IsUnderApproximation() { return Precision == Z3_goal_prec.Z3_GOAL_UNDER; } - - /** - * Indicates whether the goal is an over-approximation. - **/ - public boolean IsOverApproximation() { return Precision == Z3_goal_prec.Z3_GOAL_OVER; } - - /** - * Indicates whether the goal is garbage (i.e., the product of over- and under-approximations). - **/ - public boolean IsGarbage() { return Precision == Z3_goal_prec.Z3_GOAL_UNDER_OVER; } - - /** - * Adds the to the given goal. - **/ - public void Assert(BoolExpr[] constraints) - { - - - - Context.CheckContextMatch(constraints); - for (BoolExpr.Iterator c = constraints.iterator(); c.hasNext(); ) - { - // It was an assume, now made an assert just to be sure we do not regress - Native.goalAssert(Context.nCtx, NativeObject, c.NativeObject); - } - } - - /** - * Indicates whether the goal contains `false'. - **/ - public boolean Inconsistent() { return Native.goalInconsistent(Context.nCtx, NativeObject) != 0; } - - /** - * The depth of the goal. - * - * This tracks how many transformations were applied to it. - * - **/ - public long Depth() { return Native.goalDepth(Context.nCtx, NativeObject); } - - /** - * Erases all formulas from the given goal. - **/ - public void Reset() - { - Native.goalReset(Context.nCtx, NativeObject); - } - - /** - * The number of formulas in the goal. - **/ - public long Size() { return Native.goalSize(Context.nCtx, NativeObject); } - - /** - * The formulas in the goal. - **/ - public BoolExpr[] Formulas() - { - - - long n = Size; - BoolExpr[] res = new BoolExpr[n]; - for (long i = 0; i < n; i++) - res[i] = new BoolExpr(Context, Native.goalFormula(Context.nCtx, NativeObject, i)); - return res; - } - - /** - * The number of formulas, subformulas and terms in the goal. - **/ - public long NumExprs() { return Native.goalNumExprs(Context.nCtx, NativeObject); } - - /** - * Indicates whether the goal is empty, and it is precise or the product of an under approximation. - **/ - public boolean IsDecidedSat() { return Native.goalIsDecidedSat(Context.nCtx, NativeObject) != 0; } - - /** - * Indicates whether the goal contains `false', and it is precise or the product of an over approximation. - **/ - public boolean IsDecidedUnsat() { return Native.goalIsDecidedUnsat(Context.nCtx, NativeObject) != 0; } - - /** - * Translates (copies) the Goal to the target Context . - **/ - public Goal Translate(Context ctx) - { - - - return new Goal(ctx, Native.goalTranslate(Context.nCtx, NativeObject, ctx.nCtx)); - } - - /** - * Simplifies the goal. - * Essentially invokes the `simplify' tactic on the goal. - **/ - public Goal Simplify(Params p) - { - Tactic t = Context.MkTactic("simplify"); - ApplyResult res = t.Apply(this, p); - - if (res.NumSubgoals == 0) - return Context.MkGoal(); - else - return res.Subgoals[0]; - } - - /** - * Goal to string conversion. - * @return A string representation of the Goal. - **/ - public String toString() - { - return Native.goaltoString(Context.nCtx, NativeObject); - } - - Goal(Context ctx, IntPtr obj) { super(ctx, obj); } - - Goal(Context ctx, boolean models, boolean unsatCores, boolean proofs) - { super(ctx, Native.mkGoal(ctx.nCtx, (models); ? 1 : 0, (unsatCores) ? 1 : 0, (proofs) ? 1 : 0)) - - } - - class DecRefQueue extends Z3.DecRefQueue - { - public void IncRef(Context ctx, IntPtr obj) - { - Native.goalIncRef(ctx.nCtx, obj); - } - - public void DecRef(Context ctx, IntPtr obj) - { - Native.goalDecRef(ctx.nCtx, obj); - } - }; - - void IncRef(IntPtr o) - { - Context.Goal_DRQ.IncAndClear(Context, o); - super.IncRef(o); - } - - void DecRef(IntPtr o) - { - Context.Goal_DRQ.Add(o); - super.DecRef(o); - } - - } diff --git a/src/api/java/com/Microsoft/Z3/Log.java b/src/api/java/com/Microsoft/Z3/Log.java deleted file mode 100644 index 35ac0e022..000000000 --- a/src/api/java/com/Microsoft/Z3/Log.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * This file was automatically generated from Log.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * Interaction logging for Z3. - * - * Note that this is a global, static log and if multiple Context - * objects are created, it logs the interaction with all of them. - * - **/ - public final class Log - { - private boolean m_is_open = false; - - /** - * Open an interaction log file. - * the name of the file to open - * @return True if opening the log file succeeds, false otherwise. - **/ - public boolean Open(String filename) - { - m_is_open = true; - return Native.openLog(filename) == 1; - } - - /** - * Closes the interaction log. - **/ - public void Close() - { - m_is_open = false; - Native.closeLog(); - } - - /** - * Appends the user-provided string to the interaction log. - **/ - public void Append(String s) - { - - - if (!m_is_open) - throw new Z3Exception("Log cannot be closed."); - Native.appendLog(s); - } - - /** - * Checks whether the interaction log is opened. - * @return True if the interaction log is open, false otherwise. - **/ - public boolean isOpen() - { - return m_is_open; - } - } diff --git a/src/api/java/com/Microsoft/Z3/Model.java b/src/api/java/com/Microsoft/Z3/Model.java deleted file mode 100644 index edd774f56..000000000 --- a/src/api/java/com/Microsoft/Z3/Model.java +++ /dev/null @@ -1,279 +0,0 @@ -/** - * This file was automatically generated from Model.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * A Model contains interpretations (assignments) of constants and functions. - **/ - public class Model extends Z3Object - { - /** - * Retrieves the interpretation (the assignment) of in the model. - * A Constant - * @return An expression if the constant has an interpretation in the model, null otherwise. - **/ - public Expr ConstInterp(Expr a) - { - - - Context.CheckContextMatch(a); - return ConstInterp(a.FuncDecl); - } - - /** - * Retrieves the interpretation (the assignment) of in the model. - * A function declaration of zero arity - * @return An expression if the function has an interpretation in the model, null otherwise. - **/ - public Expr ConstInterp(FuncDecl f) - { - - - Context.CheckContextMatch(f); - if (f.Arity != 0 || - Native.getSortKind(Context.nCtx, Native.getRange(Context.nCtx, f.NativeObject)) == (long)Z3_sort_kind.Z3_ARRAY_SORT) - throw new Z3Exception("Non-zero arity functions and arrays have FunctionInterpretations as a model. Use FuncInterp."); - - IntPtr n = Native.modelGetConstInterp(Context.nCtx, NativeObject, f.NativeObject); - if (n == IntPtr.Zero) - return null; - else - return Expr.Create(Context, n); - } - - /** - * Retrieves the interpretation (the assignment) of a non-constant in the model. - * A function declaration of non-zero arity - * @return A FunctionInterpretation if the function has an interpretation in the model, null otherwise. - **/ - public FuncInterp FuncInterp(FuncDecl f) - { - - - Context.CheckContextMatch(f); - - Z3_sort_kind sk = (Z3_sort_kind)Native.getSortKind(Context.nCtx, Native.getRange(Context.nCtx, f.NativeObject)); - - if (f.Arity == 0) - { - IntPtr n = Native.modelGetConstInterp(Context.nCtx, NativeObject, f.NativeObject); - - if (sk == Z3_sort_kind.Z3_ARRAY_SORT) - { - if (n == IntPtr.Zero) - return null; - else - { - if (Native.isAsArray(Context.nCtx, n) == 0) - throw new Z3Exception("Argument was not an array constant"); - IntPtr fd = Native.getAsArrayFuncDecl(Context.nCtx, n); - return FuncInterp(new FuncDecl(Context, fd)); - } - } - else - { - throw new Z3Exception("Constant functions do not have a function interpretation; use ConstInterp"); - } - } - else - { - IntPtr n = Native.modelGetFuncInterp(Context.nCtx, NativeObject, f.NativeObject); - if (n == IntPtr.Zero) - return null; - else - return new FuncInterp(Context, n); - } - } - - /** - * The number of constants that have an interpretation in the model. - **/ - public long NumConsts() { return Native.modelGetNumConsts(Context.nCtx, NativeObject); } - - /** - * The function declarations of the constants in the model. - **/ - public FuncDecl[] ConstDecls() - { - - - long n = NumConsts; - FuncDecl[] res = new FuncDecl[n]; - for (long i = 0; i < n; i++) - res[i] = new FuncDecl(Context, Native.modelGetConstDecl(Context.nCtx, NativeObject, i)); - return res; - } - - /** - * The number of function interpretations in the model. - **/ - public long NumFuncs() { return Native.modelGetNumFuncs(Context.nCtx, NativeObject); } - - /** - * The function declarations of the function interpretations in the model. - **/ - public FuncDecl[] FuncDecls() - { - - - long n = NumFuncs; - FuncDecl[] res = new FuncDecl[n]; - for (long i = 0; i < n; i++) - res[i] = new FuncDecl(Context, Native.modelGetFuncDecl(Context.nCtx, NativeObject, i)); - return res; - } - - /** - * All symbols that have an interpretation in the model. - **/ - public FuncDecl[] Decls() - { - - - var nFuncs = NumFuncs; - var nConsts = NumConsts; - long n = nFuncs + nConsts; - FuncDecl[] res = new FuncDecl[n]; - for (long i = 0; i < nConsts; i++) - res[i] = new FuncDecl(Context, Native.modelGetConstDecl(Context.nCtx, NativeObject, i)); - for (long i = 0; i < nFuncs; i++) - res[nConsts + i] = new FuncDecl(Context, Native.modelGetFuncDecl(Context.nCtx, NativeObject, i)); - return res; - } - - /** - * A ModelEvaluationFailedException is thrown when an expression cannot be evaluated by the model. - **/ - public class ModelEvaluationFailedException extends Z3Exception - { - /** - * An exception that is thrown when model evaluation fails. - **/ - public ModelEvaluationFailedException() { super(); } - } - - /** - * Evaluates the expression in the current model. - * - * This function may fail if contains quantifiers, - * is partial (MODEL_PARTIAL enabled), or if is not well-sorted. - * In this case a ModelEvaluationFailedException is thrown. - * - * An expression - * - * When this flag is enabled, a model value will be assigned to any constant - * or function that does not have an interpretation in the model. - * - * @return The evaluation of in the model. - **/ - public Expr Eval(Expr t, boolean completion) - { - - - - IntPtr v = IntPtr.Zero; - if (Native.modelEval(Context.nCtx, NativeObject, t.NativeObject, (completion) ? 1 : 0, v) == 0) - throw new ModelEvaluationFailedException(); - else - return Expr.Create(Context, v); - } - - /** - * Alias for Eval. - **/ - public Expr Evaluate(Expr t, boolean completion) - { - - - - return Eval(t, completion); - } - - /** - * The number of uninterpreted sorts that the model has an interpretation for. - **/ - public long NumSorts () { return Native.modelGetNumSorts(Context.nCtx, NativeObject); } - - /** - * The uninterpreted sorts that the model has an interpretation for. - * - * Z3 also provides an intepretation for uninterpreted sorts used in a formula. - * The interpretation for a sort is a finite set of distinct values. We say this finite set is - * the "universe" of the sort. - * - * - * - **/ - public Sort[] Sorts() - { - - - long n = NumSorts; - Sort[] res = new Sort[n]; - for (long i = 0; i < n; i++) - res[i] = Sort.Create(Context, Native.modelGetSort(Context.nCtx, NativeObject, i)); - return res; - } - - /** - * The finite set of distinct values that represent the interpretation for sort . - * - * An uninterpreted sort - * @return An array of expressions, where each is an element of the universe of - **/ - public Expr[] SortUniverse(Sort s) - { - - - - ASTVector nUniv = new ASTVector(Context, Native.modelGetSortUniverse(Context.nCtx, NativeObject, s.NativeObject)); - long n = nUniv.Size; - Expr[] res = new Expr[n]; - for (long i = 0; i < n; i++) - res[i] = Expr.Create(Context, nUniv[i].NativeObject); - return res; - } - - /** - * Conversion of models to strings. - * @return A string representation of the model. - **/ - public String toString() - { - return Native.modeltoString(Context.nCtx, NativeObject); - } - - Model(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - - class DecRefQueue extends Z3.DecRefQueue - { - public void IncRef(Context ctx, IntPtr obj) - { - Native.modelIncRef(ctx.nCtx, obj); - } - - public void DecRef(Context ctx, IntPtr obj) - { - Native.modelDecRef(ctx.nCtx, obj); - } - }; - - void IncRef(IntPtr o) - { - Context.Model_DRQ.IncAndClear(Context, o); - super.IncRef(o); - } - - void DecRef(IntPtr o) - { - Context.Model_DRQ.Add(o); - super.DecRef(o); - } - } diff --git a/src/api/java/com/Microsoft/Z3/Native.c b/src/api/java/com/Microsoft/Z3/Native.c deleted file mode 100644 index 653e32bc5..000000000 --- a/src/api/java/com/Microsoft/Z3/Native.c +++ /dev/null @@ -1,2259 +0,0 @@ -// Automatically generated file -#include -#include -#include"z3.h" -#ifdef __cplusplus -extern "C" { -#endif -JNIEXPORT jlong JNICALL Java_Z3Native_mkConfig(JNIEnv * jenv, jclass cls) { - Z3_config result = Z3_mk_config(); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_delConfig(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_del_config((Z3_config)a0); -} -JNIEXPORT void JNICALL Java_Z3Native_setParamValue(JNIEnv * jenv, jclass cls, jlong a0, jstring a1, jstring a2) { - Z3_string _a1 = (Z3_string) jenv->GetStringUTFChars(a1, NULL); - Z3_string _a2 = (Z3_string) jenv->GetStringUTFChars(a2, NULL); - Z3_set_param_value((Z3_config)a0, _a1, _a2); -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkContext(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_context result = Z3_mk_context((Z3_config)a0); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkContextRc(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_context result = Z3_mk_context_rc((Z3_config)a0); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_delContext(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_del_context((Z3_context)a0); -} -JNIEXPORT void JNICALL Java_Z3Native_incRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_inc_ref((Z3_context)a0, (Z3_ast)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_decRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_dec_ref((Z3_context)a0, (Z3_ast)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_updateParamValue(JNIEnv * jenv, jclass cls, jlong a0, jstring a1, jstring a2) { - Z3_string _a1 = (Z3_string) jenv->GetStringUTFChars(a1, NULL); - Z3_string _a2 = (Z3_string) jenv->GetStringUTFChars(a2, NULL); - Z3_update_param_value((Z3_context)a0, _a1, _a2); -} -JNIEXPORT jboolean JNICALL Java_Z3Native_getParamValue(JNIEnv * jenv, jclass cls, jlong a0, jstring a1, jobject a2) { - Z3_string _a1 = (Z3_string) jenv->GetStringUTFChars(a1, NULL); - Z3_string _a2; - Z3_bool result = Z3_get_param_value((Z3_context)a0, _a1, &_a2); - { - jclass mc = jenv->GetObjectClass(a2); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a2, fid, (jlong) _a2); - } - return (jboolean) result; -} -JNIEXPORT void JNICALL Java_Z3Native_interrupt(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_interrupt((Z3_context)a0); -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkParams(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_params result = Z3_mk_params((Z3_context)a0); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_paramsIncRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_params_inc_ref((Z3_context)a0, (Z3_params)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_paramsDecRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_params_dec_ref((Z3_context)a0, (Z3_params)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_paramsSetBool(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jboolean a3) { - Z3_params_set_bool((Z3_context)a0, (Z3_params)a1, (Z3_symbol)a2, (Z3_bool)a3); -} -JNIEXPORT void JNICALL Java_Z3Native_paramsSetUint(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jint a3) { - Z3_params_set_uint((Z3_context)a0, (Z3_params)a1, (Z3_symbol)a2, (unsigned)a3); -} -JNIEXPORT void JNICALL Java_Z3Native_paramsSetDouble(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jdouble a3) { - Z3_params_set_double((Z3_context)a0, (Z3_params)a1, (Z3_symbol)a2, (double)a3); -} -JNIEXPORT void JNICALL Java_Z3Native_paramsSetSymbol(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jlong a3) { - Z3_params_set_symbol((Z3_context)a0, (Z3_params)a1, (Z3_symbol)a2, (Z3_symbol)a3); -} -JNIEXPORT jstring JNICALL Java_Z3Native_paramsToString(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_string result = Z3_params_to_string((Z3_context)a0, (Z3_params)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT void JNICALL Java_Z3Native_paramsValidate(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_params_validate((Z3_context)a0, (Z3_params)a1, (Z3_param_descrs)a2); -} -JNIEXPORT void JNICALL Java_Z3Native_paramDescrsIncRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_param_descrs_inc_ref((Z3_context)a0, (Z3_param_descrs)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_paramDescrsDecRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_param_descrs_dec_ref((Z3_context)a0, (Z3_param_descrs)a1); -} -JNIEXPORT jint JNICALL Java_Z3Native_paramDescrsGetKind(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - unsigned result = Z3_param_descrs_get_kind((Z3_context)a0, (Z3_param_descrs)a1, (Z3_symbol)a2); - return (jint) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_paramDescrsSize(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_param_descrs_size((Z3_context)a0, (Z3_param_descrs)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_paramDescrsGetName(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_symbol result = Z3_param_descrs_get_name((Z3_context)a0, (Z3_param_descrs)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jstring JNICALL Java_Z3Native_paramDescrsToString(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_string result = Z3_param_descrs_to_string((Z3_context)a0, (Z3_param_descrs)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkIntSymbol(JNIEnv * jenv, jclass cls, jlong a0, jint a1) { - Z3_symbol result = Z3_mk_int_symbol((Z3_context)a0, (int)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkStringSymbol(JNIEnv * jenv, jclass cls, jlong a0, jstring a1) { - Z3_string _a1 = (Z3_string) jenv->GetStringUTFChars(a1, NULL); - Z3_symbol result = Z3_mk_string_symbol((Z3_context)a0, _a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkUninterpretedSort(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_sort result = Z3_mk_uninterpreted_sort((Z3_context)a0, (Z3_symbol)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBoolSort(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_sort result = Z3_mk_bool_sort((Z3_context)a0); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkIntSort(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_sort result = Z3_mk_int_sort((Z3_context)a0); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkRealSort(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_sort result = Z3_mk_real_sort((Z3_context)a0); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvSort(JNIEnv * jenv, jclass cls, jlong a0, jint a1) { - Z3_sort result = Z3_mk_bv_sort((Z3_context)a0, (unsigned)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkFiniteDomainSort(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_sort result = Z3_mk_finite_domain_sort((Z3_context)a0, (Z3_symbol)a1, (__uint64)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkArraySort(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_sort result = Z3_mk_array_sort((Z3_context)a0, (Z3_sort)a1, (Z3_sort)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkTupleSort(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jlongArray a3, jlongArray a4, jobject a5, jlongArray a6) { - Z3_symbol * _a3 = (Z3_symbol *) jenv->GetLongArrayElements(a3, NULL); - Z3_sort * _a4 = (Z3_sort *) jenv->GetLongArrayElements(a4, NULL); - Z3_func_decl _a5; - Z3_func_decl * _a6 = (Z3_func_decl *) malloc(((unsigned)a2) * sizeof(Z3_func_decl)); - Z3_sort result = Z3_mk_tuple_sort((Z3_context)a0, (Z3_symbol)a1, (unsigned)a2, _a3, _a4, &_a5, _a6); - jenv->ReleaseLongArrayElements(a3, (jlong *) _a3, JNI_ABORT); - jenv->ReleaseLongArrayElements(a4, (jlong *) _a4, JNI_ABORT); - { - jclass mc = jenv->GetObjectClass(a5); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a5, fid, (jlong) _a5); - } - jenv->SetLongArrayRegion(a6, 0, (jsize)a2, (jlong *) _a6); - free(_a6); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkEnumerationSort(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jlongArray a3, jlongArray a4, jlongArray a5) { - Z3_symbol * _a3 = (Z3_symbol *) jenv->GetLongArrayElements(a3, NULL); - Z3_func_decl * _a4 = (Z3_func_decl *) malloc(((unsigned)a2) * sizeof(Z3_func_decl)); - Z3_func_decl * _a5 = (Z3_func_decl *) malloc(((unsigned)a2) * sizeof(Z3_func_decl)); - Z3_sort result = Z3_mk_enumeration_sort((Z3_context)a0, (Z3_symbol)a1, (unsigned)a2, _a3, _a4, _a5); - jenv->ReleaseLongArrayElements(a3, (jlong *) _a3, JNI_ABORT); - jenv->SetLongArrayRegion(a4, 0, (jsize)a2, (jlong *) _a4); - free(_a4); - jenv->SetLongArrayRegion(a5, 0, (jsize)a2, (jlong *) _a5); - free(_a5); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkListSort(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jobject a3, jobject a4, jobject a5, jobject a6, jobject a7, jobject a8) { - Z3_func_decl _a3; - Z3_func_decl _a4; - Z3_func_decl _a5; - Z3_func_decl _a6; - Z3_func_decl _a7; - Z3_func_decl _a8; - Z3_sort result = Z3_mk_list_sort((Z3_context)a0, (Z3_symbol)a1, (Z3_sort)a2, &_a3, &_a4, &_a5, &_a6, &_a7, &_a8); - { - jclass mc = jenv->GetObjectClass(a3); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a3, fid, (jlong) _a3); - } - { - jclass mc = jenv->GetObjectClass(a4); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a4, fid, (jlong) _a4); - } - { - jclass mc = jenv->GetObjectClass(a5); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a5, fid, (jlong) _a5); - } - { - jclass mc = jenv->GetObjectClass(a6); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a6, fid, (jlong) _a6); - } - { - jclass mc = jenv->GetObjectClass(a7); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a7, fid, (jlong) _a7); - } - { - jclass mc = jenv->GetObjectClass(a8); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a8, fid, (jlong) _a8); - } - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkConstructor(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jint a3, jlongArray a4, jlongArray a5, jintArray a6) { - Z3_symbol * _a4 = (Z3_symbol *) jenv->GetLongArrayElements(a4, NULL); - Z3_sort * _a5 = (Z3_sort *) jenv->GetLongArrayElements(a5, NULL); - unsigned * _a6 = (unsigned *) jenv->GetIntArrayElements(a6, NULL); - Z3_constructor result = Z3_mk_constructor((Z3_context)a0, (Z3_symbol)a1, (Z3_symbol)a2, (unsigned)a3, _a4, _a5, _a6); - jenv->ReleaseLongArrayElements(a4, (jlong *) _a4, JNI_ABORT); - jenv->ReleaseLongArrayElements(a5, (jlong *) _a5, JNI_ABORT); - jenv->ReleaseIntArrayElements(a6, (jint *) _a6, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_delConstructor(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_del_constructor((Z3_context)a0, (Z3_constructor)a1); -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkDatatype(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jlongArray a3) { - Z3_constructor * _a3 = (Z3_constructor *) jenv->GetLongArrayElements(a3, NULL); - Z3_sort result = Z3_mk_datatype((Z3_context)a0, (Z3_symbol)a1, (unsigned)a2, _a3); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkConstructorList(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlongArray a2) { - Z3_constructor * _a2 = (Z3_constructor *) jenv->GetLongArrayElements(a2, NULL); - Z3_constructor_list result = Z3_mk_constructor_list((Z3_context)a0, (unsigned)a1, _a2); - jenv->ReleaseLongArrayElements(a2, (jlong *) _a2, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_delConstructorList(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_del_constructor_list((Z3_context)a0, (Z3_constructor_list)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_mkDatatypes(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlongArray a2, jlongArray a3, jlongArray a4) { - Z3_symbol * _a2 = (Z3_symbol *) jenv->GetLongArrayElements(a2, NULL); - Z3_sort * _a3 = (Z3_sort *) malloc(((unsigned)a1) * sizeof(Z3_sort)); - Z3_constructor_list * _a4 = (Z3_constructor_list *) jenv->GetLongArrayElements(a4, NULL); - Z3_mk_datatypes((Z3_context)a0, (unsigned)a1, _a2, _a3, _a4); - jenv->ReleaseLongArrayElements(a2, (jlong *) _a2, JNI_ABORT); - jenv->SetLongArrayRegion(a3, 0, (jsize)a1, (jlong *) _a3); - free(_a3); -} -JNIEXPORT void JNICALL Java_Z3Native_queryConstructor(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jobject a3, jobject a4, jlongArray a5) { - Z3_func_decl _a3; - Z3_func_decl _a4; - Z3_func_decl * _a5 = (Z3_func_decl *) malloc(((unsigned)a2) * sizeof(Z3_func_decl)); - Z3_query_constructor((Z3_context)a0, (Z3_constructor)a1, (unsigned)a2, &_a3, &_a4, _a5); - { - jclass mc = jenv->GetObjectClass(a3); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a3, fid, (jlong) _a3); - } - { - jclass mc = jenv->GetObjectClass(a4); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a4, fid, (jlong) _a4); - } - jenv->SetLongArrayRegion(a5, 0, (jsize)a2, (jlong *) _a5); - free(_a5); -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkFuncDecl(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jlongArray a3, jlong a4) { - Z3_sort * _a3 = (Z3_sort *) jenv->GetLongArrayElements(a3, NULL); - Z3_func_decl result = Z3_mk_func_decl((Z3_context)a0, (Z3_symbol)a1, (unsigned)a2, _a3, (Z3_sort)a4); - jenv->ReleaseLongArrayElements(a3, (jlong *) _a3, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkApp(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jlongArray a3) { - Z3_ast * _a3 = (Z3_ast *) jenv->GetLongArrayElements(a3, NULL); - Z3_ast result = Z3_mk_app((Z3_context)a0, (Z3_func_decl)a1, (unsigned)a2, _a3); - jenv->ReleaseLongArrayElements(a3, (jlong *) _a3, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkConst(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_const((Z3_context)a0, (Z3_symbol)a1, (Z3_sort)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkFreshFuncDecl(JNIEnv * jenv, jclass cls, jlong a0, jstring a1, jint a2, jlongArray a3, jlong a4) { - Z3_string _a1 = (Z3_string) jenv->GetStringUTFChars(a1, NULL); - Z3_sort * _a3 = (Z3_sort *) jenv->GetLongArrayElements(a3, NULL); - Z3_func_decl result = Z3_mk_fresh_func_decl((Z3_context)a0, _a1, (unsigned)a2, _a3, (Z3_sort)a4); - jenv->ReleaseLongArrayElements(a3, (jlong *) _a3, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkFreshConst(JNIEnv * jenv, jclass cls, jlong a0, jstring a1, jlong a2) { - Z3_string _a1 = (Z3_string) jenv->GetStringUTFChars(a1, NULL); - Z3_ast result = Z3_mk_fresh_const((Z3_context)a0, _a1, (Z3_sort)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkTrue(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_ast result = Z3_mk_true((Z3_context)a0); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkFalse(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_ast result = Z3_mk_false((Z3_context)a0); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkEq(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_eq((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkDistinct(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlongArray a2) { - Z3_ast * _a2 = (Z3_ast *) jenv->GetLongArrayElements(a2, NULL); - Z3_ast result = Z3_mk_distinct((Z3_context)a0, (unsigned)a1, _a2); - jenv->ReleaseLongArrayElements(a2, (jlong *) _a2, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkNot(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_mk_not((Z3_context)a0, (Z3_ast)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkIte(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jlong a3) { - Z3_ast result = Z3_mk_ite((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2, (Z3_ast)a3); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkIff(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_iff((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkImplies(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_implies((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkXor(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_xor((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkAnd(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlongArray a2) { - Z3_ast * _a2 = (Z3_ast *) jenv->GetLongArrayElements(a2, NULL); - Z3_ast result = Z3_mk_and((Z3_context)a0, (unsigned)a1, _a2); - jenv->ReleaseLongArrayElements(a2, (jlong *) _a2, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkOr(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlongArray a2) { - Z3_ast * _a2 = (Z3_ast *) jenv->GetLongArrayElements(a2, NULL); - Z3_ast result = Z3_mk_or((Z3_context)a0, (unsigned)a1, _a2); - jenv->ReleaseLongArrayElements(a2, (jlong *) _a2, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkAdd(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlongArray a2) { - Z3_ast * _a2 = (Z3_ast *) jenv->GetLongArrayElements(a2, NULL); - Z3_ast result = Z3_mk_add((Z3_context)a0, (unsigned)a1, _a2); - jenv->ReleaseLongArrayElements(a2, (jlong *) _a2, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkMul(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlongArray a2) { - Z3_ast * _a2 = (Z3_ast *) jenv->GetLongArrayElements(a2, NULL); - Z3_ast result = Z3_mk_mul((Z3_context)a0, (unsigned)a1, _a2); - jenv->ReleaseLongArrayElements(a2, (jlong *) _a2, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkSub(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlongArray a2) { - Z3_ast * _a2 = (Z3_ast *) jenv->GetLongArrayElements(a2, NULL); - Z3_ast result = Z3_mk_sub((Z3_context)a0, (unsigned)a1, _a2); - jenv->ReleaseLongArrayElements(a2, (jlong *) _a2, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkUnaryMinus(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_mk_unary_minus((Z3_context)a0, (Z3_ast)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkDiv(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_div((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkMod(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_mod((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkRem(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_rem((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkPower(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_power((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkLt(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_lt((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkLe(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_le((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkGt(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_gt((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkGe(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_ge((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkInt2real(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_mk_int2real((Z3_context)a0, (Z3_ast)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkReal2int(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_mk_real2int((Z3_context)a0, (Z3_ast)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkIsInt(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_mk_is_int((Z3_context)a0, (Z3_ast)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvnot(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_mk_bvnot((Z3_context)a0, (Z3_ast)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvredand(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_mk_bvredand((Z3_context)a0, (Z3_ast)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvredor(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_mk_bvredor((Z3_context)a0, (Z3_ast)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvand(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvand((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvor(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvor((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvxor(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvxor((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvnand(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvnand((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvnor(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvnor((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvxnor(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvxnor((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvneg(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_mk_bvneg((Z3_context)a0, (Z3_ast)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvadd(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvadd((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvsub(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvsub((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvmul(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvmul((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvudiv(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvudiv((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvsdiv(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvsdiv((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvurem(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvurem((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvsrem(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvsrem((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvsmod(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvsmod((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvult(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvult((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvslt(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvslt((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvule(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvule((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvsle(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvsle((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvuge(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvuge((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvsge(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvsge((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvugt(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvugt((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvsgt(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvsgt((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkConcat(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_concat((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkExtract(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jint a2, jlong a3) { - Z3_ast result = Z3_mk_extract((Z3_context)a0, (unsigned)a1, (unsigned)a2, (Z3_ast)a3); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkSignExt(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlong a2) { - Z3_ast result = Z3_mk_sign_ext((Z3_context)a0, (unsigned)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkZeroExt(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlong a2) { - Z3_ast result = Z3_mk_zero_ext((Z3_context)a0, (unsigned)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkRepeat(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlong a2) { - Z3_ast result = Z3_mk_repeat((Z3_context)a0, (unsigned)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvshl(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvshl((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvlshr(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvlshr((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvashr(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvashr((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkRotateLeft(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlong a2) { - Z3_ast result = Z3_mk_rotate_left((Z3_context)a0, (unsigned)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkRotateRight(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlong a2) { - Z3_ast result = Z3_mk_rotate_right((Z3_context)a0, (unsigned)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkExtRotateLeft(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_ext_rotate_left((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkExtRotateRight(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_ext_rotate_right((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkInt2bv(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlong a2) { - Z3_ast result = Z3_mk_int2bv((Z3_context)a0, (unsigned)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBv2int(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jboolean a2) { - Z3_ast result = Z3_mk_bv2int((Z3_context)a0, (Z3_ast)a1, (Z3_bool)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvaddNoOverflow(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jboolean a3) { - Z3_ast result = Z3_mk_bvadd_no_overflow((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2, (Z3_bool)a3); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvaddNoUnderflow(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvadd_no_underflow((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvsubNoOverflow(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvsub_no_overflow((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvsubNoUnderflow(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jboolean a3) { - Z3_ast result = Z3_mk_bvsub_no_underflow((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2, (Z3_bool)a3); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvsdivNoOverflow(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvsdiv_no_overflow((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvnegNoOverflow(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_mk_bvneg_no_overflow((Z3_context)a0, (Z3_ast)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvmulNoOverflow(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jboolean a3) { - Z3_ast result = Z3_mk_bvmul_no_overflow((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2, (Z3_bool)a3); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBvmulNoUnderflow(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_bvmul_no_underflow((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkSelect(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_select((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkStore(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jlong a3) { - Z3_ast result = Z3_mk_store((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2, (Z3_ast)a3); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkConstArray(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_const_array((Z3_context)a0, (Z3_sort)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkMap(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jlongArray a3) { - Z3_ast * _a3 = (Z3_ast *) jenv->GetLongArrayElements(a3, NULL); - Z3_ast result = Z3_mk_map((Z3_context)a0, (Z3_func_decl)a1, (unsigned)a2, _a3); - jenv->ReleaseLongArrayElements(a3, (jlong *) _a3, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkArrayDefault(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_mk_array_default((Z3_context)a0, (Z3_ast)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkSetSort(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_sort result = Z3_mk_set_sort((Z3_context)a0, (Z3_sort)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkEmptySet(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_mk_empty_set((Z3_context)a0, (Z3_sort)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkFullSet(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_mk_full_set((Z3_context)a0, (Z3_sort)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkSetAdd(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_set_add((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkSetDel(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_set_del((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkSetUnion(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlongArray a2) { - Z3_ast * _a2 = (Z3_ast *) jenv->GetLongArrayElements(a2, NULL); - Z3_ast result = Z3_mk_set_union((Z3_context)a0, (unsigned)a1, _a2); - jenv->ReleaseLongArrayElements(a2, (jlong *) _a2, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkSetIntersect(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlongArray a2) { - Z3_ast * _a2 = (Z3_ast *) jenv->GetLongArrayElements(a2, NULL); - Z3_ast result = Z3_mk_set_intersect((Z3_context)a0, (unsigned)a1, _a2); - jenv->ReleaseLongArrayElements(a2, (jlong *) _a2, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkSetDifference(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_set_difference((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkSetComplement(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_mk_set_complement((Z3_context)a0, (Z3_ast)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkSetMember(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_set_member((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkSetSubset(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_set_subset((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkNumeral(JNIEnv * jenv, jclass cls, jlong a0, jstring a1, jlong a2) { - Z3_string _a1 = (Z3_string) jenv->GetStringUTFChars(a1, NULL); - Z3_ast result = Z3_mk_numeral((Z3_context)a0, _a1, (Z3_sort)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkReal(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jint a2) { - Z3_ast result = Z3_mk_real((Z3_context)a0, (int)a1, (int)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkInt(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlong a2) { - Z3_ast result = Z3_mk_int((Z3_context)a0, (int)a1, (Z3_sort)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkUnsignedInt(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlong a2) { - Z3_ast result = Z3_mk_unsigned_int((Z3_context)a0, (unsigned)a1, (Z3_sort)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkInt64(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_int64((Z3_context)a0, (__int64)a1, (Z3_sort)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkUnsignedInt64(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_mk_unsigned_int64((Z3_context)a0, (__uint64)a1, (Z3_sort)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkPattern(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlongArray a2) { - Z3_ast * _a2 = (Z3_ast *) jenv->GetLongArrayElements(a2, NULL); - Z3_pattern result = Z3_mk_pattern((Z3_context)a0, (unsigned)a1, _a2); - jenv->ReleaseLongArrayElements(a2, (jlong *) _a2, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkBound(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlong a2) { - Z3_ast result = Z3_mk_bound((Z3_context)a0, (unsigned)a1, (Z3_sort)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkForall(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jint a2, jlongArray a3, jint a4, jlongArray a5, jlongArray a6, jlong a7) { - Z3_pattern * _a3 = (Z3_pattern *) jenv->GetLongArrayElements(a3, NULL); - Z3_sort * _a5 = (Z3_sort *) jenv->GetLongArrayElements(a5, NULL); - Z3_symbol * _a6 = (Z3_symbol *) jenv->GetLongArrayElements(a6, NULL); - Z3_ast result = Z3_mk_forall((Z3_context)a0, (unsigned)a1, (unsigned)a2, _a3, (unsigned)a4, _a5, _a6, (Z3_ast)a7); - jenv->ReleaseLongArrayElements(a3, (jlong *) _a3, JNI_ABORT); - jenv->ReleaseLongArrayElements(a5, (jlong *) _a5, JNI_ABORT); - jenv->ReleaseLongArrayElements(a6, (jlong *) _a6, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkExists(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jint a2, jlongArray a3, jint a4, jlongArray a5, jlongArray a6, jlong a7) { - Z3_pattern * _a3 = (Z3_pattern *) jenv->GetLongArrayElements(a3, NULL); - Z3_sort * _a5 = (Z3_sort *) jenv->GetLongArrayElements(a5, NULL); - Z3_symbol * _a6 = (Z3_symbol *) jenv->GetLongArrayElements(a6, NULL); - Z3_ast result = Z3_mk_exists((Z3_context)a0, (unsigned)a1, (unsigned)a2, _a3, (unsigned)a4, _a5, _a6, (Z3_ast)a7); - jenv->ReleaseLongArrayElements(a3, (jlong *) _a3, JNI_ABORT); - jenv->ReleaseLongArrayElements(a5, (jlong *) _a5, JNI_ABORT); - jenv->ReleaseLongArrayElements(a6, (jlong *) _a6, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkQuantifier(JNIEnv * jenv, jclass cls, jlong a0, jboolean a1, jint a2, jint a3, jlongArray a4, jint a5, jlongArray a6, jlongArray a7, jlong a8) { - Z3_pattern * _a4 = (Z3_pattern *) jenv->GetLongArrayElements(a4, NULL); - Z3_sort * _a6 = (Z3_sort *) jenv->GetLongArrayElements(a6, NULL); - Z3_symbol * _a7 = (Z3_symbol *) jenv->GetLongArrayElements(a7, NULL); - Z3_ast result = Z3_mk_quantifier((Z3_context)a0, (Z3_bool)a1, (unsigned)a2, (unsigned)a3, _a4, (unsigned)a5, _a6, _a7, (Z3_ast)a8); - jenv->ReleaseLongArrayElements(a4, (jlong *) _a4, JNI_ABORT); - jenv->ReleaseLongArrayElements(a6, (jlong *) _a6, JNI_ABORT); - jenv->ReleaseLongArrayElements(a7, (jlong *) _a7, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkQuantifierEx(JNIEnv * jenv, jclass cls, jlong a0, jboolean a1, jint a2, jlong a3, jlong a4, jint a5, jlongArray a6, jint a7, jlongArray a8, jint a9, jlongArray a10, jlongArray a11, jlong a12) { - Z3_pattern * _a6 = (Z3_pattern *) jenv->GetLongArrayElements(a6, NULL); - Z3_ast * _a8 = (Z3_ast *) jenv->GetLongArrayElements(a8, NULL); - Z3_sort * _a10 = (Z3_sort *) jenv->GetLongArrayElements(a10, NULL); - Z3_symbol * _a11 = (Z3_symbol *) jenv->GetLongArrayElements(a11, NULL); - Z3_ast result = Z3_mk_quantifier_ex((Z3_context)a0, (Z3_bool)a1, (unsigned)a2, (Z3_symbol)a3, (Z3_symbol)a4, (unsigned)a5, _a6, (unsigned)a7, _a8, (unsigned)a9, _a10, _a11, (Z3_ast)a12); - jenv->ReleaseLongArrayElements(a6, (jlong *) _a6, JNI_ABORT); - jenv->ReleaseLongArrayElements(a8, (jlong *) _a8, JNI_ABORT); - jenv->ReleaseLongArrayElements(a10, (jlong *) _a10, JNI_ABORT); - jenv->ReleaseLongArrayElements(a11, (jlong *) _a11, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkForallConst(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jint a2, jlongArray a3, jint a4, jlongArray a5, jlong a6) { - Z3_app * _a3 = (Z3_app *) jenv->GetLongArrayElements(a3, NULL); - Z3_pattern * _a5 = (Z3_pattern *) jenv->GetLongArrayElements(a5, NULL); - Z3_ast result = Z3_mk_forall_const((Z3_context)a0, (unsigned)a1, (unsigned)a2, _a3, (unsigned)a4, _a5, (Z3_ast)a6); - jenv->ReleaseLongArrayElements(a3, (jlong *) _a3, JNI_ABORT); - jenv->ReleaseLongArrayElements(a5, (jlong *) _a5, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkExistsConst(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jint a2, jlongArray a3, jint a4, jlongArray a5, jlong a6) { - Z3_app * _a3 = (Z3_app *) jenv->GetLongArrayElements(a3, NULL); - Z3_pattern * _a5 = (Z3_pattern *) jenv->GetLongArrayElements(a5, NULL); - Z3_ast result = Z3_mk_exists_const((Z3_context)a0, (unsigned)a1, (unsigned)a2, _a3, (unsigned)a4, _a5, (Z3_ast)a6); - jenv->ReleaseLongArrayElements(a3, (jlong *) _a3, JNI_ABORT); - jenv->ReleaseLongArrayElements(a5, (jlong *) _a5, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkQuantifierConst(JNIEnv * jenv, jclass cls, jlong a0, jboolean a1, jint a2, jint a3, jlongArray a4, jint a5, jlongArray a6, jlong a7) { - Z3_app * _a4 = (Z3_app *) jenv->GetLongArrayElements(a4, NULL); - Z3_pattern * _a6 = (Z3_pattern *) jenv->GetLongArrayElements(a6, NULL); - Z3_ast result = Z3_mk_quantifier_const((Z3_context)a0, (Z3_bool)a1, (unsigned)a2, (unsigned)a3, _a4, (unsigned)a5, _a6, (Z3_ast)a7); - jenv->ReleaseLongArrayElements(a4, (jlong *) _a4, JNI_ABORT); - jenv->ReleaseLongArrayElements(a6, (jlong *) _a6, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkQuantifierConstEx(JNIEnv * jenv, jclass cls, jlong a0, jboolean a1, jint a2, jlong a3, jlong a4, jint a5, jlongArray a6, jint a7, jlongArray a8, jint a9, jlongArray a10, jlong a11) { - Z3_app * _a6 = (Z3_app *) jenv->GetLongArrayElements(a6, NULL); - Z3_pattern * _a8 = (Z3_pattern *) jenv->GetLongArrayElements(a8, NULL); - Z3_ast * _a10 = (Z3_ast *) jenv->GetLongArrayElements(a10, NULL); - Z3_ast result = Z3_mk_quantifier_const_ex((Z3_context)a0, (Z3_bool)a1, (unsigned)a2, (Z3_symbol)a3, (Z3_symbol)a4, (unsigned)a5, _a6, (unsigned)a7, _a8, (unsigned)a9, _a10, (Z3_ast)a11); - jenv->ReleaseLongArrayElements(a6, (jlong *) _a6, JNI_ABORT); - jenv->ReleaseLongArrayElements(a8, (jlong *) _a8, JNI_ABORT); - jenv->ReleaseLongArrayElements(a10, (jlong *) _a10, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getSymbolKind(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_symbol_kind((Z3_context)a0, (Z3_symbol)a1); - return (jint) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getSymbolInt(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - int result = Z3_get_symbol_int((Z3_context)a0, (Z3_symbol)a1); - return (jint) result; -} -JNIEXPORT jstring JNICALL Java_Z3Native_getSymbolString(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_string result = Z3_get_symbol_string((Z3_context)a0, (Z3_symbol)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT jlong JNICALL Java_Z3Native_getSortName(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_symbol result = Z3_get_sort_name((Z3_context)a0, (Z3_sort)a1); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getSortId(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_sort_id((Z3_context)a0, (Z3_sort)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_sortToAst(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_sort_to_ast((Z3_context)a0, (Z3_sort)a1); - return (jlong) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_isEqSort(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_bool result = Z3_is_eq_sort((Z3_context)a0, (Z3_sort)a1, (Z3_sort)a2); - return (jboolean) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getSortKind(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_sort_kind((Z3_context)a0, (Z3_sort)a1); - return (jint) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getBvSortSize(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_bv_sort_size((Z3_context)a0, (Z3_sort)a1); - return (jint) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_getFiniteDomainSortSize(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jobject a2) { - __uint64 _a2; - Z3_bool result = Z3_get_finite_domain_sort_size((Z3_context)a0, (Z3_sort)a1, &_a2); - { - jclass mc = jenv->GetObjectClass(a2); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a2, fid, (jlong) _a2); - } - return (jboolean) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getArraySortDomain(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_sort result = Z3_get_array_sort_domain((Z3_context)a0, (Z3_sort)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getArraySortRange(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_sort result = Z3_get_array_sort_range((Z3_context)a0, (Z3_sort)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getTupleSortMkDecl(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_func_decl result = Z3_get_tuple_sort_mk_decl((Z3_context)a0, (Z3_sort)a1); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getTupleSortNumFields(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_tuple_sort_num_fields((Z3_context)a0, (Z3_sort)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getTupleSortFieldDecl(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_func_decl result = Z3_get_tuple_sort_field_decl((Z3_context)a0, (Z3_sort)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getDatatypeSortNumConstructors(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_datatype_sort_num_constructors((Z3_context)a0, (Z3_sort)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getDatatypeSortConstructor(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_func_decl result = Z3_get_datatype_sort_constructor((Z3_context)a0, (Z3_sort)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getDatatypeSortRecognizer(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_func_decl result = Z3_get_datatype_sort_recognizer((Z3_context)a0, (Z3_sort)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getDatatypeSortConstructorAccessor(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jint a3) { - Z3_func_decl result = Z3_get_datatype_sort_constructor_accessor((Z3_context)a0, (Z3_sort)a1, (unsigned)a2, (unsigned)a3); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getRelationArity(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_relation_arity((Z3_context)a0, (Z3_sort)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getRelationColumn(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_sort result = Z3_get_relation_column((Z3_context)a0, (Z3_sort)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_funcDeclToAst(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_func_decl_to_ast((Z3_context)a0, (Z3_func_decl)a1); - return (jlong) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_isEqFuncDecl(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_bool result = Z3_is_eq_func_decl((Z3_context)a0, (Z3_func_decl)a1, (Z3_func_decl)a2); - return (jboolean) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getFuncDeclId(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_func_decl_id((Z3_context)a0, (Z3_func_decl)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getDeclName(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_symbol result = Z3_get_decl_name((Z3_context)a0, (Z3_func_decl)a1); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getDeclKind(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_decl_kind((Z3_context)a0, (Z3_func_decl)a1); - return (jint) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getDomainSize(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_domain_size((Z3_context)a0, (Z3_func_decl)a1); - return (jint) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getArity(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_arity((Z3_context)a0, (Z3_func_decl)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getDomain(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_sort result = Z3_get_domain((Z3_context)a0, (Z3_func_decl)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getRange(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_sort result = Z3_get_range((Z3_context)a0, (Z3_func_decl)a1); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getDeclNumParameters(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_decl_num_parameters((Z3_context)a0, (Z3_func_decl)a1); - return (jint) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getDeclParameterKind(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - unsigned result = Z3_get_decl_parameter_kind((Z3_context)a0, (Z3_func_decl)a1, (unsigned)a2); - return (jint) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getDeclIntParameter(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - int result = Z3_get_decl_int_parameter((Z3_context)a0, (Z3_func_decl)a1, (unsigned)a2); - return (jint) result; -} -JNIEXPORT jdouble JNICALL Java_Z3Native_getDeclDoubleParameter(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - double result = Z3_get_decl_double_parameter((Z3_context)a0, (Z3_func_decl)a1, (unsigned)a2); - return (jdouble) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getDeclSymbolParameter(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_symbol result = Z3_get_decl_symbol_parameter((Z3_context)a0, (Z3_func_decl)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getDeclSortParameter(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_sort result = Z3_get_decl_sort_parameter((Z3_context)a0, (Z3_func_decl)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getDeclAstParameter(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_ast result = Z3_get_decl_ast_parameter((Z3_context)a0, (Z3_func_decl)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getDeclFuncDeclParameter(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_func_decl result = Z3_get_decl_func_decl_parameter((Z3_context)a0, (Z3_func_decl)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jstring JNICALL Java_Z3Native_getDeclRationalParameter(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_string result = Z3_get_decl_rational_parameter((Z3_context)a0, (Z3_func_decl)a1, (unsigned)a2); - return jenv->NewStringUTF(result); -} -JNIEXPORT jlong JNICALL Java_Z3Native_appToAst(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_app_to_ast((Z3_context)a0, (Z3_app)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getAppDecl(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_func_decl result = Z3_get_app_decl((Z3_context)a0, (Z3_app)a1); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getAppNumArgs(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_app_num_args((Z3_context)a0, (Z3_app)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getAppArg(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_ast result = Z3_get_app_arg((Z3_context)a0, (Z3_app)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_isEqAst(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_bool result = Z3_is_eq_ast((Z3_context)a0, (Z3_ast)a1, (Z3_ast)a2); - return (jboolean) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getAstId(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_ast_id((Z3_context)a0, (Z3_ast)a1); - return (jint) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getAstHash(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_ast_hash((Z3_context)a0, (Z3_ast)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getSort(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_sort result = Z3_get_sort((Z3_context)a0, (Z3_ast)a1); - return (jlong) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_isWellSorted(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_bool result = Z3_is_well_sorted((Z3_context)a0, (Z3_ast)a1); - return (jboolean) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getBoolValue(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_bool_value((Z3_context)a0, (Z3_ast)a1); - return (jint) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getAstKind(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_ast_kind((Z3_context)a0, (Z3_ast)a1); - return (jint) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_isApp(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_bool result = Z3_is_app((Z3_context)a0, (Z3_ast)a1); - return (jboolean) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_isNumeralAst(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_bool result = Z3_is_numeral_ast((Z3_context)a0, (Z3_ast)a1); - return (jboolean) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_isAlgebraicNumber(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_bool result = Z3_is_algebraic_number((Z3_context)a0, (Z3_ast)a1); - return (jboolean) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_toApp(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_app result = Z3_to_app((Z3_context)a0, (Z3_ast)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_toFuncDecl(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_func_decl result = Z3_to_func_decl((Z3_context)a0, (Z3_ast)a1); - return (jlong) result; -} -JNIEXPORT jstring JNICALL Java_Z3Native_getNumeralString(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_string result = Z3_get_numeral_string((Z3_context)a0, (Z3_ast)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT jstring JNICALL Java_Z3Native_getNumeralDecimalString(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_string result = Z3_get_numeral_decimal_string((Z3_context)a0, (Z3_ast)a1, (unsigned)a2); - return jenv->NewStringUTF(result); -} -JNIEXPORT jlong JNICALL Java_Z3Native_getNumerator(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_get_numerator((Z3_context)a0, (Z3_ast)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getDenominator(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_get_denominator((Z3_context)a0, (Z3_ast)a1); - return (jlong) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_getNumeralSmall(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jobject a2, jobject a3) { - __int64 _a2; - __int64 _a3; - Z3_bool result = Z3_get_numeral_small((Z3_context)a0, (Z3_ast)a1, &_a2, &_a3); - { - jclass mc = jenv->GetObjectClass(a2); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a2, fid, (jlong) _a2); - } - { - jclass mc = jenv->GetObjectClass(a3); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a3, fid, (jlong) _a3); - } - return (jboolean) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_getNumeralInt(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jobject a2) { - int _a2; - Z3_bool result = Z3_get_numeral_int((Z3_context)a0, (Z3_ast)a1, &_a2); - { - jclass mc = jenv->GetObjectClass(a2); - jfieldID fid = jenv->GetFieldID(mc, "value", "I"); - jenv->SetIntField(a2, fid, (jint) _a2); - } - return (jboolean) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_getNumeralUint(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jobject a2) { - unsigned _a2; - Z3_bool result = Z3_get_numeral_uint((Z3_context)a0, (Z3_ast)a1, &_a2); - { - jclass mc = jenv->GetObjectClass(a2); - jfieldID fid = jenv->GetFieldID(mc, "value", "I"); - jenv->SetIntField(a2, fid, (jint) _a2); - } - return (jboolean) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_getNumeralUint64(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jobject a2) { - __uint64 _a2; - Z3_bool result = Z3_get_numeral_uint64((Z3_context)a0, (Z3_ast)a1, &_a2); - { - jclass mc = jenv->GetObjectClass(a2); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a2, fid, (jlong) _a2); - } - return (jboolean) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_getNumeralInt64(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jobject a2) { - __int64 _a2; - Z3_bool result = Z3_get_numeral_int64((Z3_context)a0, (Z3_ast)a1, &_a2); - { - jclass mc = jenv->GetObjectClass(a2); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a2, fid, (jlong) _a2); - } - return (jboolean) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_getNumeralRationalInt64(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jobject a2, jobject a3) { - __int64 _a2; - __int64 _a3; - Z3_bool result = Z3_get_numeral_rational_int64((Z3_context)a0, (Z3_ast)a1, &_a2, &_a3); - { - jclass mc = jenv->GetObjectClass(a2); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a2, fid, (jlong) _a2); - } - { - jclass mc = jenv->GetObjectClass(a3); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a3, fid, (jlong) _a3); - } - return (jboolean) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getAlgebraicNumberLower(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_ast result = Z3_get_algebraic_number_lower((Z3_context)a0, (Z3_ast)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getAlgebraicNumberUpper(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_ast result = Z3_get_algebraic_number_upper((Z3_context)a0, (Z3_ast)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_patternToAst(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_pattern_to_ast((Z3_context)a0, (Z3_pattern)a1); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getPatternNumTerms(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_pattern_num_terms((Z3_context)a0, (Z3_pattern)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getPattern(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_ast result = Z3_get_pattern((Z3_context)a0, (Z3_pattern)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getIndexValue(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_index_value((Z3_context)a0, (Z3_ast)a1); - return (jint) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_isQuantifierForall(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_bool result = Z3_is_quantifier_forall((Z3_context)a0, (Z3_ast)a1); - return (jboolean) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getQuantifierWeight(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_quantifier_weight((Z3_context)a0, (Z3_ast)a1); - return (jint) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getQuantifierNumPatterns(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_quantifier_num_patterns((Z3_context)a0, (Z3_ast)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getQuantifierPatternAst(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_pattern result = Z3_get_quantifier_pattern_ast((Z3_context)a0, (Z3_ast)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getQuantifierNumNoPatterns(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_quantifier_num_no_patterns((Z3_context)a0, (Z3_ast)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getQuantifierNoPatternAst(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_ast result = Z3_get_quantifier_no_pattern_ast((Z3_context)a0, (Z3_ast)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getQuantifierNumBound(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_quantifier_num_bound((Z3_context)a0, (Z3_ast)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getQuantifierBoundName(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_symbol result = Z3_get_quantifier_bound_name((Z3_context)a0, (Z3_ast)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getQuantifierBoundSort(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_sort result = Z3_get_quantifier_bound_sort((Z3_context)a0, (Z3_ast)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getQuantifierBody(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_get_quantifier_body((Z3_context)a0, (Z3_ast)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_simplify(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_simplify((Z3_context)a0, (Z3_ast)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_simplifyEx(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_simplify_ex((Z3_context)a0, (Z3_ast)a1, (Z3_params)a2); - return (jlong) result; -} -JNIEXPORT jstring JNICALL Java_Z3Native_simplifyGetHelp(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_string result = Z3_simplify_get_help((Z3_context)a0); - return jenv->NewStringUTF(result); -} -JNIEXPORT jlong JNICALL Java_Z3Native_simplifyGetParamDescrs(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_param_descrs result = Z3_simplify_get_param_descrs((Z3_context)a0); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_updateTerm(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jlongArray a3) { - Z3_ast * _a3 = (Z3_ast *) jenv->GetLongArrayElements(a3, NULL); - Z3_ast result = Z3_update_term((Z3_context)a0, (Z3_ast)a1, (unsigned)a2, _a3); - jenv->ReleaseLongArrayElements(a3, (jlong *) _a3, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_substitute(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jlongArray a3, jlongArray a4) { - Z3_ast * _a3 = (Z3_ast *) jenv->GetLongArrayElements(a3, NULL); - Z3_ast * _a4 = (Z3_ast *) jenv->GetLongArrayElements(a4, NULL); - Z3_ast result = Z3_substitute((Z3_context)a0, (Z3_ast)a1, (unsigned)a2, _a3, _a4); - jenv->ReleaseLongArrayElements(a3, (jlong *) _a3, JNI_ABORT); - jenv->ReleaseLongArrayElements(a4, (jlong *) _a4, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_substituteVars(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jlongArray a3) { - Z3_ast * _a3 = (Z3_ast *) jenv->GetLongArrayElements(a3, NULL); - Z3_ast result = Z3_substitute_vars((Z3_context)a0, (Z3_ast)a1, (unsigned)a2, _a3); - jenv->ReleaseLongArrayElements(a3, (jlong *) _a3, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_translate(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_translate((Z3_context)a0, (Z3_ast)a1, (Z3_context)a2); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_modelIncRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_model_inc_ref((Z3_context)a0, (Z3_model)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_modelDecRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_model_dec_ref((Z3_context)a0, (Z3_model)a1); -} -JNIEXPORT jboolean JNICALL Java_Z3Native_modelEval(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jboolean a3, jobject a4) { - Z3_ast _a4; - Z3_bool result = Z3_model_eval((Z3_context)a0, (Z3_model)a1, (Z3_ast)a2, (Z3_bool)a3, &_a4); - { - jclass mc = jenv->GetObjectClass(a4); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a4, fid, (jlong) _a4); - } - return (jboolean) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_modelGetConstInterp(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_model_get_const_interp((Z3_context)a0, (Z3_model)a1, (Z3_func_decl)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_modelGetFuncInterp(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_func_interp result = Z3_model_get_func_interp((Z3_context)a0, (Z3_model)a1, (Z3_func_decl)a2); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_modelGetNumConsts(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_model_get_num_consts((Z3_context)a0, (Z3_model)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_modelGetConstDecl(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_func_decl result = Z3_model_get_const_decl((Z3_context)a0, (Z3_model)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_modelGetNumFuncs(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_model_get_num_funcs((Z3_context)a0, (Z3_model)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_modelGetFuncDecl(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_func_decl result = Z3_model_get_func_decl((Z3_context)a0, (Z3_model)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_modelGetNumSorts(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_model_get_num_sorts((Z3_context)a0, (Z3_model)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_modelGetSort(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_sort result = Z3_model_get_sort((Z3_context)a0, (Z3_model)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_modelGetSortUniverse(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast_vector result = Z3_model_get_sort_universe((Z3_context)a0, (Z3_model)a1, (Z3_sort)a2); - return (jlong) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_isAsArray(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_bool result = Z3_is_as_array((Z3_context)a0, (Z3_ast)a1); - return (jboolean) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getAsArrayFuncDecl(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_func_decl result = Z3_get_as_array_func_decl((Z3_context)a0, (Z3_ast)a1); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_funcInterpIncRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_func_interp_inc_ref((Z3_context)a0, (Z3_func_interp)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_funcInterpDecRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_func_interp_dec_ref((Z3_context)a0, (Z3_func_interp)a1); -} -JNIEXPORT jint JNICALL Java_Z3Native_funcInterpGetNumEntries(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_func_interp_get_num_entries((Z3_context)a0, (Z3_func_interp)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_funcInterpGetEntry(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_func_entry result = Z3_func_interp_get_entry((Z3_context)a0, (Z3_func_interp)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_funcInterpGetElse(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_func_interp_get_else((Z3_context)a0, (Z3_func_interp)a1); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_funcInterpGetArity(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_func_interp_get_arity((Z3_context)a0, (Z3_func_interp)a1); - return (jint) result; -} -JNIEXPORT void JNICALL Java_Z3Native_funcEntryIncRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_func_entry_inc_ref((Z3_context)a0, (Z3_func_entry)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_funcEntryDecRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_func_entry_dec_ref((Z3_context)a0, (Z3_func_entry)a1); -} -JNIEXPORT jlong JNICALL Java_Z3Native_funcEntryGetValue(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_func_entry_get_value((Z3_context)a0, (Z3_func_entry)a1); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_funcEntryGetNumArgs(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_func_entry_get_num_args((Z3_context)a0, (Z3_func_entry)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_funcEntryGetArg(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_ast result = Z3_func_entry_get_arg((Z3_context)a0, (Z3_func_entry)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_openLog(JNIEnv * jenv, jclass cls, jstring a0) { - Z3_string _a0 = (Z3_string) jenv->GetStringUTFChars(a0, NULL); - int result = Z3_open_log(_a0); - return (jint) result; -} -JNIEXPORT void JNICALL Java_Z3Native_appendLog(JNIEnv * jenv, jclass cls, jstring a0) { - Z3_string _a0 = (Z3_string) jenv->GetStringUTFChars(a0, NULL); - Z3_append_log(_a0); -} -JNIEXPORT void JNICALL Java_Z3Native_closeLog(JNIEnv * jenv, jclass cls) { - Z3_close_log(); -} -JNIEXPORT void JNICALL Java_Z3Native_toggleWarningMessages(JNIEnv * jenv, jclass cls, jboolean a0) { - Z3_toggle_warning_messages((Z3_bool)a0); -} -JNIEXPORT void JNICALL Java_Z3Native_setAstPrintMode(JNIEnv * jenv, jclass cls, jlong a0, jint a1) { - Z3_set_ast_print_mode((Z3_context)a0, (Z3_ast_print_mode)a1); -} -JNIEXPORT jstring JNICALL Java_Z3Native_astToString(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_string result = Z3_ast_to_string((Z3_context)a0, (Z3_ast)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT jstring JNICALL Java_Z3Native_patternToString(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_string result = Z3_pattern_to_string((Z3_context)a0, (Z3_pattern)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT jstring JNICALL Java_Z3Native_sortToString(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_string result = Z3_sort_to_string((Z3_context)a0, (Z3_sort)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT jstring JNICALL Java_Z3Native_funcDeclToString(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_string result = Z3_func_decl_to_string((Z3_context)a0, (Z3_func_decl)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT jstring JNICALL Java_Z3Native_modelToString(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_string result = Z3_model_to_string((Z3_context)a0, (Z3_model)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT jstring JNICALL Java_Z3Native_benchmarkToSmtlibString(JNIEnv * jenv, jclass cls, jlong a0, jstring a1, jstring a2, jstring a3, jstring a4, jint a5, jlongArray a6, jlong a7) { - Z3_string _a1 = (Z3_string) jenv->GetStringUTFChars(a1, NULL); - Z3_string _a2 = (Z3_string) jenv->GetStringUTFChars(a2, NULL); - Z3_string _a3 = (Z3_string) jenv->GetStringUTFChars(a3, NULL); - Z3_string _a4 = (Z3_string) jenv->GetStringUTFChars(a4, NULL); - Z3_ast * _a6 = (Z3_ast *) jenv->GetLongArrayElements(a6, NULL); - Z3_string result = Z3_benchmark_to_smtlib_string((Z3_context)a0, _a1, _a2, _a3, _a4, (unsigned)a5, _a6, (Z3_ast)a7); - jenv->ReleaseLongArrayElements(a6, (jlong *) _a6, JNI_ABORT); - return jenv->NewStringUTF(result); -} -JNIEXPORT jlong JNICALL Java_Z3Native_parseSmtlib2String(JNIEnv * jenv, jclass cls, jlong a0, jstring a1, jint a2, jlongArray a3, jlongArray a4, jint a5, jlongArray a6, jlongArray a7) { - Z3_string _a1 = (Z3_string) jenv->GetStringUTFChars(a1, NULL); - Z3_symbol * _a3 = (Z3_symbol *) jenv->GetLongArrayElements(a3, NULL); - Z3_sort * _a4 = (Z3_sort *) jenv->GetLongArrayElements(a4, NULL); - Z3_symbol * _a6 = (Z3_symbol *) jenv->GetLongArrayElements(a6, NULL); - Z3_func_decl * _a7 = (Z3_func_decl *) jenv->GetLongArrayElements(a7, NULL); - Z3_ast result = Z3_parse_smtlib2_string((Z3_context)a0, _a1, (unsigned)a2, _a3, _a4, (unsigned)a5, _a6, _a7); - jenv->ReleaseLongArrayElements(a3, (jlong *) _a3, JNI_ABORT); - jenv->ReleaseLongArrayElements(a4, (jlong *) _a4, JNI_ABORT); - jenv->ReleaseLongArrayElements(a6, (jlong *) _a6, JNI_ABORT); - jenv->ReleaseLongArrayElements(a7, (jlong *) _a7, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_parseSmtlib2File(JNIEnv * jenv, jclass cls, jlong a0, jstring a1, jint a2, jlongArray a3, jlongArray a4, jint a5, jlongArray a6, jlongArray a7) { - Z3_string _a1 = (Z3_string) jenv->GetStringUTFChars(a1, NULL); - Z3_symbol * _a3 = (Z3_symbol *) jenv->GetLongArrayElements(a3, NULL); - Z3_sort * _a4 = (Z3_sort *) jenv->GetLongArrayElements(a4, NULL); - Z3_symbol * _a6 = (Z3_symbol *) jenv->GetLongArrayElements(a6, NULL); - Z3_func_decl * _a7 = (Z3_func_decl *) jenv->GetLongArrayElements(a7, NULL); - Z3_ast result = Z3_parse_smtlib2_file((Z3_context)a0, _a1, (unsigned)a2, _a3, _a4, (unsigned)a5, _a6, _a7); - jenv->ReleaseLongArrayElements(a3, (jlong *) _a3, JNI_ABORT); - jenv->ReleaseLongArrayElements(a4, (jlong *) _a4, JNI_ABORT); - jenv->ReleaseLongArrayElements(a6, (jlong *) _a6, JNI_ABORT); - jenv->ReleaseLongArrayElements(a7, (jlong *) _a7, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_parseSmtlibString(JNIEnv * jenv, jclass cls, jlong a0, jstring a1, jint a2, jlongArray a3, jlongArray a4, jint a5, jlongArray a6, jlongArray a7) { - Z3_string _a1 = (Z3_string) jenv->GetStringUTFChars(a1, NULL); - Z3_symbol * _a3 = (Z3_symbol *) jenv->GetLongArrayElements(a3, NULL); - Z3_sort * _a4 = (Z3_sort *) jenv->GetLongArrayElements(a4, NULL); - Z3_symbol * _a6 = (Z3_symbol *) jenv->GetLongArrayElements(a6, NULL); - Z3_func_decl * _a7 = (Z3_func_decl *) jenv->GetLongArrayElements(a7, NULL); - Z3_parse_smtlib_string((Z3_context)a0, _a1, (unsigned)a2, _a3, _a4, (unsigned)a5, _a6, _a7); - jenv->ReleaseLongArrayElements(a3, (jlong *) _a3, JNI_ABORT); - jenv->ReleaseLongArrayElements(a4, (jlong *) _a4, JNI_ABORT); - jenv->ReleaseLongArrayElements(a6, (jlong *) _a6, JNI_ABORT); - jenv->ReleaseLongArrayElements(a7, (jlong *) _a7, JNI_ABORT); -} -JNIEXPORT void JNICALL Java_Z3Native_parseSmtlibFile(JNIEnv * jenv, jclass cls, jlong a0, jstring a1, jint a2, jlongArray a3, jlongArray a4, jint a5, jlongArray a6, jlongArray a7) { - Z3_string _a1 = (Z3_string) jenv->GetStringUTFChars(a1, NULL); - Z3_symbol * _a3 = (Z3_symbol *) jenv->GetLongArrayElements(a3, NULL); - Z3_sort * _a4 = (Z3_sort *) jenv->GetLongArrayElements(a4, NULL); - Z3_symbol * _a6 = (Z3_symbol *) jenv->GetLongArrayElements(a6, NULL); - Z3_func_decl * _a7 = (Z3_func_decl *) jenv->GetLongArrayElements(a7, NULL); - Z3_parse_smtlib_file((Z3_context)a0, _a1, (unsigned)a2, _a3, _a4, (unsigned)a5, _a6, _a7); - jenv->ReleaseLongArrayElements(a3, (jlong *) _a3, JNI_ABORT); - jenv->ReleaseLongArrayElements(a4, (jlong *) _a4, JNI_ABORT); - jenv->ReleaseLongArrayElements(a6, (jlong *) _a6, JNI_ABORT); - jenv->ReleaseLongArrayElements(a7, (jlong *) _a7, JNI_ABORT); -} -JNIEXPORT jint JNICALL Java_Z3Native_getSmtlibNumFormulas(JNIEnv * jenv, jclass cls, jlong a0) { - unsigned result = Z3_get_smtlib_num_formulas((Z3_context)a0); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getSmtlibFormula(JNIEnv * jenv, jclass cls, jlong a0, jint a1) { - Z3_ast result = Z3_get_smtlib_formula((Z3_context)a0, (unsigned)a1); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getSmtlibNumAssumptions(JNIEnv * jenv, jclass cls, jlong a0) { - unsigned result = Z3_get_smtlib_num_assumptions((Z3_context)a0); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getSmtlibAssumption(JNIEnv * jenv, jclass cls, jlong a0, jint a1) { - Z3_ast result = Z3_get_smtlib_assumption((Z3_context)a0, (unsigned)a1); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getSmtlibNumDecls(JNIEnv * jenv, jclass cls, jlong a0) { - unsigned result = Z3_get_smtlib_num_decls((Z3_context)a0); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getSmtlibDecl(JNIEnv * jenv, jclass cls, jlong a0, jint a1) { - Z3_func_decl result = Z3_get_smtlib_decl((Z3_context)a0, (unsigned)a1); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getSmtlibNumSorts(JNIEnv * jenv, jclass cls, jlong a0) { - unsigned result = Z3_get_smtlib_num_sorts((Z3_context)a0); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getSmtlibSort(JNIEnv * jenv, jclass cls, jlong a0, jint a1) { - Z3_sort result = Z3_get_smtlib_sort((Z3_context)a0, (unsigned)a1); - return (jlong) result; -} -JNIEXPORT jstring JNICALL Java_Z3Native_getSmtlibError(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_string result = Z3_get_smtlib_error((Z3_context)a0); - return jenv->NewStringUTF(result); -} -JNIEXPORT jint JNICALL Java_Z3Native_getErrorCode(JNIEnv * jenv, jclass cls, jlong a0) { - unsigned result = Z3_get_error_code((Z3_context)a0); - return (jint) result; -} -JNIEXPORT void JNICALL Java_Z3Native_setError(JNIEnv * jenv, jclass cls, jlong a0, jint a1) { - Z3_set_error((Z3_context)a0, (Z3_error_code)a1); -} -JNIEXPORT jstring JNICALL Java_Z3Native_getErrorMsg(JNIEnv * jenv, jclass cls, jint a0) { - Z3_string result = Z3_get_error_msg((Z3_error_code)a0); - return jenv->NewStringUTF(result); -} -JNIEXPORT jstring JNICALL Java_Z3Native_getErrorMsgEx(JNIEnv * jenv, jclass cls, jlong a0, jint a1) { - Z3_string result = Z3_get_error_msg_ex((Z3_context)a0, (Z3_error_code)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT void JNICALL Java_Z3Native_getVersion(JNIEnv * jenv, jclass cls, jobject a0, jobject a1, jobject a2, jobject a3) { - unsigned _a0; - unsigned _a1; - unsigned _a2; - unsigned _a3; - Z3_get_version(&_a0, &_a1, &_a2, &_a3); - { - jclass mc = jenv->GetObjectClass(a0); - jfieldID fid = jenv->GetFieldID(mc, "value", "I"); - jenv->SetIntField(a0, fid, (jint) _a0); - } - { - jclass mc = jenv->GetObjectClass(a1); - jfieldID fid = jenv->GetFieldID(mc, "value", "I"); - jenv->SetIntField(a1, fid, (jint) _a1); - } - { - jclass mc = jenv->GetObjectClass(a2); - jfieldID fid = jenv->GetFieldID(mc, "value", "I"); - jenv->SetIntField(a2, fid, (jint) _a2); - } - { - jclass mc = jenv->GetObjectClass(a3); - jfieldID fid = jenv->GetFieldID(mc, "value", "I"); - jenv->SetIntField(a3, fid, (jint) _a3); - } -} -JNIEXPORT void JNICALL Java_Z3Native_enableTrace(JNIEnv * jenv, jclass cls, jstring a0) { - Z3_string _a0 = (Z3_string) jenv->GetStringUTFChars(a0, NULL); - Z3_enable_trace(_a0); -} -JNIEXPORT void JNICALL Java_Z3Native_disableTrace(JNIEnv * jenv, jclass cls, jstring a0) { - Z3_string _a0 = (Z3_string) jenv->GetStringUTFChars(a0, NULL); - Z3_disable_trace(_a0); -} -JNIEXPORT void JNICALL Java_Z3Native_resetMemory(JNIEnv * jenv, jclass cls) { - Z3_reset_memory(); -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkFixedpoint(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_fixedpoint result = Z3_mk_fixedpoint((Z3_context)a0); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_fixedpointIncRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_fixedpoint_inc_ref((Z3_context)a0, (Z3_fixedpoint)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_fixedpointDecRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_fixedpoint_dec_ref((Z3_context)a0, (Z3_fixedpoint)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_fixedpointAddRule(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jlong a3) { - Z3_fixedpoint_add_rule((Z3_context)a0, (Z3_fixedpoint)a1, (Z3_ast)a2, (Z3_symbol)a3); -} -JNIEXPORT void JNICALL Java_Z3Native_fixedpointAddFact(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jint a3, jintArray a4) { - unsigned * _a4 = (unsigned *) jenv->GetIntArrayElements(a4, NULL); - Z3_fixedpoint_add_fact((Z3_context)a0, (Z3_fixedpoint)a1, (Z3_func_decl)a2, (unsigned)a3, _a4); - jenv->ReleaseIntArrayElements(a4, (jint *) _a4, JNI_ABORT); -} -JNIEXPORT void JNICALL Java_Z3Native_fixedpointAssert(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_fixedpoint_assert((Z3_context)a0, (Z3_fixedpoint)a1, (Z3_ast)a2); -} -JNIEXPORT jint JNICALL Java_Z3Native_fixedpointQuery(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - int result = Z3_fixedpoint_query((Z3_context)a0, (Z3_fixedpoint)a1, (Z3_ast)a2); - return (jint) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_fixedpointQueryRelations(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jlongArray a3) { - Z3_func_decl * _a3 = (Z3_func_decl *) jenv->GetLongArrayElements(a3, NULL); - int result = Z3_fixedpoint_query_relations((Z3_context)a0, (Z3_fixedpoint)a1, (unsigned)a2, _a3); - jenv->ReleaseLongArrayElements(a3, (jlong *) _a3, JNI_ABORT); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_fixedpointGetAnswer(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_fixedpoint_get_answer((Z3_context)a0, (Z3_fixedpoint)a1); - return (jlong) result; -} -JNIEXPORT jstring JNICALL Java_Z3Native_fixedpointGetReasonUnknown(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_string result = Z3_fixedpoint_get_reason_unknown((Z3_context)a0, (Z3_fixedpoint)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT void JNICALL Java_Z3Native_fixedpointUpdateRule(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jlong a3) { - Z3_fixedpoint_update_rule((Z3_context)a0, (Z3_fixedpoint)a1, (Z3_ast)a2, (Z3_symbol)a3); -} -JNIEXPORT jint JNICALL Java_Z3Native_fixedpointGetNumLevels(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - unsigned result = Z3_fixedpoint_get_num_levels((Z3_context)a0, (Z3_fixedpoint)a1, (Z3_func_decl)a2); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_fixedpointGetCoverDelta(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jlong a3) { - Z3_ast result = Z3_fixedpoint_get_cover_delta((Z3_context)a0, (Z3_fixedpoint)a1, (int)a2, (Z3_func_decl)a3); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_fixedpointAddCover(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jlong a3, jlong a4) { - Z3_fixedpoint_add_cover((Z3_context)a0, (Z3_fixedpoint)a1, (int)a2, (Z3_func_decl)a3, (Z3_ast)a4); -} -JNIEXPORT jlong JNICALL Java_Z3Native_fixedpointGetStatistics(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_stats result = Z3_fixedpoint_get_statistics((Z3_context)a0, (Z3_fixedpoint)a1); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_fixedpointRegisterRelation(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_fixedpoint_register_relation((Z3_context)a0, (Z3_fixedpoint)a1, (Z3_func_decl)a2); -} -JNIEXPORT void JNICALL Java_Z3Native_fixedpointSetPredicateRepresentation(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jint a3, jlongArray a4) { - Z3_symbol * _a4 = (Z3_symbol *) jenv->GetLongArrayElements(a4, NULL); - Z3_fixedpoint_set_predicate_representation((Z3_context)a0, (Z3_fixedpoint)a1, (Z3_func_decl)a2, (unsigned)a3, _a4); - jenv->ReleaseLongArrayElements(a4, (jlong *) _a4, JNI_ABORT); -} -JNIEXPORT jlong JNICALL Java_Z3Native_fixedpointGetRules(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast_vector result = Z3_fixedpoint_get_rules((Z3_context)a0, (Z3_fixedpoint)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_fixedpointGetAssertions(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast_vector result = Z3_fixedpoint_get_assertions((Z3_context)a0, (Z3_fixedpoint)a1); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_fixedpointSetParams(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_fixedpoint_set_params((Z3_context)a0, (Z3_fixedpoint)a1, (Z3_params)a2); -} -JNIEXPORT jstring JNICALL Java_Z3Native_fixedpointGetHelp(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_string result = Z3_fixedpoint_get_help((Z3_context)a0, (Z3_fixedpoint)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT jlong JNICALL Java_Z3Native_fixedpointGetParamDescrs(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_param_descrs result = Z3_fixedpoint_get_param_descrs((Z3_context)a0, (Z3_fixedpoint)a1); - return (jlong) result; -} -JNIEXPORT jstring JNICALL Java_Z3Native_fixedpointToString(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jlongArray a3) { - Z3_ast * _a3 = (Z3_ast *) jenv->GetLongArrayElements(a3, NULL); - Z3_string result = Z3_fixedpoint_to_string((Z3_context)a0, (Z3_fixedpoint)a1, (unsigned)a2, _a3); - jenv->ReleaseLongArrayElements(a3, (jlong *) _a3, JNI_ABORT); - return jenv->NewStringUTF(result); -} -JNIEXPORT jlong JNICALL Java_Z3Native_fixedpointFromString(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jstring a2) { - Z3_string _a2 = (Z3_string) jenv->GetStringUTFChars(a2, NULL); - Z3_ast_vector result = Z3_fixedpoint_from_string((Z3_context)a0, (Z3_fixedpoint)a1, _a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_fixedpointFromFile(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jstring a2) { - Z3_string _a2 = (Z3_string) jenv->GetStringUTFChars(a2, NULL); - Z3_ast_vector result = Z3_fixedpoint_from_file((Z3_context)a0, (Z3_fixedpoint)a1, _a2); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_fixedpointPush(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_fixedpoint_push((Z3_context)a0, (Z3_fixedpoint)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_fixedpointPop(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_fixedpoint_pop((Z3_context)a0, (Z3_fixedpoint)a1); -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkAstVector(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_ast_vector result = Z3_mk_ast_vector((Z3_context)a0); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_astVectorIncRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast_vector_inc_ref((Z3_context)a0, (Z3_ast_vector)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_astVectorDecRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast_vector_dec_ref((Z3_context)a0, (Z3_ast_vector)a1); -} -JNIEXPORT jint JNICALL Java_Z3Native_astVectorSize(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_ast_vector_size((Z3_context)a0, (Z3_ast_vector)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_astVectorGet(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_ast result = Z3_ast_vector_get((Z3_context)a0, (Z3_ast_vector)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_astVectorSet(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jlong a3) { - Z3_ast_vector_set((Z3_context)a0, (Z3_ast_vector)a1, (unsigned)a2, (Z3_ast)a3); -} -JNIEXPORT void JNICALL Java_Z3Native_astVectorResize(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_ast_vector_resize((Z3_context)a0, (Z3_ast_vector)a1, (unsigned)a2); -} -JNIEXPORT void JNICALL Java_Z3Native_astVectorPush(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast_vector_push((Z3_context)a0, (Z3_ast_vector)a1, (Z3_ast)a2); -} -JNIEXPORT jlong JNICALL Java_Z3Native_astVectorTranslate(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast_vector result = Z3_ast_vector_translate((Z3_context)a0, (Z3_ast_vector)a1, (Z3_context)a2); - return (jlong) result; -} -JNIEXPORT jstring JNICALL Java_Z3Native_astVectorToString(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_string result = Z3_ast_vector_to_string((Z3_context)a0, (Z3_ast_vector)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkAstMap(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_ast_map result = Z3_mk_ast_map((Z3_context)a0); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_astMapIncRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast_map_inc_ref((Z3_context)a0, (Z3_ast_map)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_astMapDecRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast_map_dec_ref((Z3_context)a0, (Z3_ast_map)a1); -} -JNIEXPORT jboolean JNICALL Java_Z3Native_astMapContains(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_bool result = Z3_ast_map_contains((Z3_context)a0, (Z3_ast_map)a1, (Z3_ast)a2); - return (jboolean) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_astMapFind(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast result = Z3_ast_map_find((Z3_context)a0, (Z3_ast_map)a1, (Z3_ast)a2); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_astMapInsert(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jlong a3) { - Z3_ast_map_insert((Z3_context)a0, (Z3_ast_map)a1, (Z3_ast)a2, (Z3_ast)a3); -} -JNIEXPORT void JNICALL Java_Z3Native_astMapErase(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_ast_map_erase((Z3_context)a0, (Z3_ast_map)a1, (Z3_ast)a2); -} -JNIEXPORT void JNICALL Java_Z3Native_astMapReset(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast_map_reset((Z3_context)a0, (Z3_ast_map)a1); -} -JNIEXPORT jint JNICALL Java_Z3Native_astMapSize(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_ast_map_size((Z3_context)a0, (Z3_ast_map)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_astMapKeys(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast_vector result = Z3_ast_map_keys((Z3_context)a0, (Z3_ast_map)a1); - return (jlong) result; -} -JNIEXPORT jstring JNICALL Java_Z3Native_astMapToString(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_string result = Z3_ast_map_to_string((Z3_context)a0, (Z3_ast_map)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkGoal(JNIEnv * jenv, jclass cls, jlong a0, jboolean a1, jboolean a2, jboolean a3) { - Z3_goal result = Z3_mk_goal((Z3_context)a0, (Z3_bool)a1, (Z3_bool)a2, (Z3_bool)a3); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_goalIncRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_goal_inc_ref((Z3_context)a0, (Z3_goal)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_goalDecRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_goal_dec_ref((Z3_context)a0, (Z3_goal)a1); -} -JNIEXPORT jint JNICALL Java_Z3Native_goalPrecision(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_goal_precision((Z3_context)a0, (Z3_goal)a1); - return (jint) result; -} -JNIEXPORT void JNICALL Java_Z3Native_goalAssert(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_goal_assert((Z3_context)a0, (Z3_goal)a1, (Z3_ast)a2); -} -JNIEXPORT jboolean JNICALL Java_Z3Native_goalInconsistent(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_bool result = Z3_goal_inconsistent((Z3_context)a0, (Z3_goal)a1); - return (jboolean) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_goalDepth(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_goal_depth((Z3_context)a0, (Z3_goal)a1); - return (jint) result; -} -JNIEXPORT void JNICALL Java_Z3Native_goalReset(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_goal_reset((Z3_context)a0, (Z3_goal)a1); -} -JNIEXPORT jint JNICALL Java_Z3Native_goalSize(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_goal_size((Z3_context)a0, (Z3_goal)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_goalFormula(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_ast result = Z3_goal_formula((Z3_context)a0, (Z3_goal)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_goalNumExprs(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_goal_num_exprs((Z3_context)a0, (Z3_goal)a1); - return (jint) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_goalIsDecidedSat(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_bool result = Z3_goal_is_decided_sat((Z3_context)a0, (Z3_goal)a1); - return (jboolean) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_goalIsDecidedUnsat(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_bool result = Z3_goal_is_decided_unsat((Z3_context)a0, (Z3_goal)a1); - return (jboolean) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_goalTranslate(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_goal result = Z3_goal_translate((Z3_context)a0, (Z3_goal)a1, (Z3_context)a2); - return (jlong) result; -} -JNIEXPORT jstring JNICALL Java_Z3Native_goalToString(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_string result = Z3_goal_to_string((Z3_context)a0, (Z3_goal)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkTactic(JNIEnv * jenv, jclass cls, jlong a0, jstring a1) { - Z3_string _a1 = (Z3_string) jenv->GetStringUTFChars(a1, NULL); - Z3_tactic result = Z3_mk_tactic((Z3_context)a0, _a1); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_tacticIncRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_tactic_inc_ref((Z3_context)a0, (Z3_tactic)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_tacticDecRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_tactic_dec_ref((Z3_context)a0, (Z3_tactic)a1); -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkProbe(JNIEnv * jenv, jclass cls, jlong a0, jstring a1) { - Z3_string _a1 = (Z3_string) jenv->GetStringUTFChars(a1, NULL); - Z3_probe result = Z3_mk_probe((Z3_context)a0, _a1); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_probeIncRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_probe_inc_ref((Z3_context)a0, (Z3_probe)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_probeDecRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_probe_dec_ref((Z3_context)a0, (Z3_probe)a1); -} -JNIEXPORT jlong JNICALL Java_Z3Native_tacticAndThen(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_tactic result = Z3_tactic_and_then((Z3_context)a0, (Z3_tactic)a1, (Z3_tactic)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_tacticOrElse(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_tactic result = Z3_tactic_or_else((Z3_context)a0, (Z3_tactic)a1, (Z3_tactic)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_tacticParOr(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlongArray a2) { - Z3_tactic * _a2 = (Z3_tactic *) jenv->GetLongArrayElements(a2, NULL); - Z3_tactic result = Z3_tactic_par_or((Z3_context)a0, (unsigned)a1, _a2); - jenv->ReleaseLongArrayElements(a2, (jlong *) _a2, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_tacticParAndThen(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_tactic result = Z3_tactic_par_and_then((Z3_context)a0, (Z3_tactic)a1, (Z3_tactic)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_tacticTryFor(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_tactic result = Z3_tactic_try_for((Z3_context)a0, (Z3_tactic)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_tacticWhen(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_tactic result = Z3_tactic_when((Z3_context)a0, (Z3_probe)a1, (Z3_tactic)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_tacticCond(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jlong a3) { - Z3_tactic result = Z3_tactic_cond((Z3_context)a0, (Z3_probe)a1, (Z3_tactic)a2, (Z3_tactic)a3); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_tacticRepeat(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_tactic result = Z3_tactic_repeat((Z3_context)a0, (Z3_tactic)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_tacticSkip(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_tactic result = Z3_tactic_skip((Z3_context)a0); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_tacticFail(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_tactic result = Z3_tactic_fail((Z3_context)a0); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_tacticFailIf(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_tactic result = Z3_tactic_fail_if((Z3_context)a0, (Z3_probe)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_tacticFailIfNotDecided(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_tactic result = Z3_tactic_fail_if_not_decided((Z3_context)a0); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_tacticUsingParams(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_tactic result = Z3_tactic_using_params((Z3_context)a0, (Z3_tactic)a1, (Z3_params)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_probeConst(JNIEnv * jenv, jclass cls, jlong a0, jdouble a1) { - Z3_probe result = Z3_probe_const((Z3_context)a0, (double)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_probeLt(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_probe result = Z3_probe_lt((Z3_context)a0, (Z3_probe)a1, (Z3_probe)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_probeGt(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_probe result = Z3_probe_gt((Z3_context)a0, (Z3_probe)a1, (Z3_probe)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_probeLe(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_probe result = Z3_probe_le((Z3_context)a0, (Z3_probe)a1, (Z3_probe)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_probeGe(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_probe result = Z3_probe_ge((Z3_context)a0, (Z3_probe)a1, (Z3_probe)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_probeEq(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_probe result = Z3_probe_eq((Z3_context)a0, (Z3_probe)a1, (Z3_probe)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_probeAnd(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_probe result = Z3_probe_and((Z3_context)a0, (Z3_probe)a1, (Z3_probe)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_probeOr(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_probe result = Z3_probe_or((Z3_context)a0, (Z3_probe)a1, (Z3_probe)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_probeNot(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_probe result = Z3_probe_not((Z3_context)a0, (Z3_probe)a1); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getNumTactics(JNIEnv * jenv, jclass cls, jlong a0) { - unsigned result = Z3_get_num_tactics((Z3_context)a0); - return (jint) result; -} -JNIEXPORT jstring JNICALL Java_Z3Native_getTacticName(JNIEnv * jenv, jclass cls, jlong a0, jint a1) { - Z3_string result = Z3_get_tactic_name((Z3_context)a0, (unsigned)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT jint JNICALL Java_Z3Native_getNumProbes(JNIEnv * jenv, jclass cls, jlong a0) { - unsigned result = Z3_get_num_probes((Z3_context)a0); - return (jint) result; -} -JNIEXPORT jstring JNICALL Java_Z3Native_getProbeName(JNIEnv * jenv, jclass cls, jlong a0, jint a1) { - Z3_string result = Z3_get_probe_name((Z3_context)a0, (unsigned)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT jstring JNICALL Java_Z3Native_tacticGetHelp(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_string result = Z3_tactic_get_help((Z3_context)a0, (Z3_tactic)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT jlong JNICALL Java_Z3Native_tacticGetParamDescrs(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_param_descrs result = Z3_tactic_get_param_descrs((Z3_context)a0, (Z3_tactic)a1); - return (jlong) result; -} -JNIEXPORT jstring JNICALL Java_Z3Native_tacticGetDescr(JNIEnv * jenv, jclass cls, jlong a0, jstring a1) { - Z3_string _a1 = (Z3_string) jenv->GetStringUTFChars(a1, NULL); - Z3_string result = Z3_tactic_get_descr((Z3_context)a0, _a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT jstring JNICALL Java_Z3Native_probeGetDescr(JNIEnv * jenv, jclass cls, jlong a0, jstring a1) { - Z3_string _a1 = (Z3_string) jenv->GetStringUTFChars(a1, NULL); - Z3_string result = Z3_probe_get_descr((Z3_context)a0, _a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT jdouble JNICALL Java_Z3Native_probeApply(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - double result = Z3_probe_apply((Z3_context)a0, (Z3_probe)a1, (Z3_goal)a2); - return (jdouble) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_tacticApply(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_apply_result result = Z3_tactic_apply((Z3_context)a0, (Z3_tactic)a1, (Z3_goal)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_tacticApplyEx(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jlong a3) { - Z3_apply_result result = Z3_tactic_apply_ex((Z3_context)a0, (Z3_tactic)a1, (Z3_goal)a2, (Z3_params)a3); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_applyResultIncRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_apply_result_inc_ref((Z3_context)a0, (Z3_apply_result)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_applyResultDecRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_apply_result_dec_ref((Z3_context)a0, (Z3_apply_result)a1); -} -JNIEXPORT jstring JNICALL Java_Z3Native_applyResultToString(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_string result = Z3_apply_result_to_string((Z3_context)a0, (Z3_apply_result)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT jint JNICALL Java_Z3Native_applyResultGetNumSubgoals(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_apply_result_get_num_subgoals((Z3_context)a0, (Z3_apply_result)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_applyResultGetSubgoal(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_goal result = Z3_apply_result_get_subgoal((Z3_context)a0, (Z3_apply_result)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_applyResultConvertModel(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jlong a3) { - Z3_model result = Z3_apply_result_convert_model((Z3_context)a0, (Z3_apply_result)a1, (unsigned)a2, (Z3_model)a3); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkSolver(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_solver result = Z3_mk_solver((Z3_context)a0); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkSimpleSolver(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_solver result = Z3_mk_simple_solver((Z3_context)a0); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkSolverForLogic(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_solver result = Z3_mk_solver_for_logic((Z3_context)a0, (Z3_symbol)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkSolverFromTactic(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_solver result = Z3_mk_solver_from_tactic((Z3_context)a0, (Z3_tactic)a1); - return (jlong) result; -} -JNIEXPORT jstring JNICALL Java_Z3Native_solverGetHelp(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_string result = Z3_solver_get_help((Z3_context)a0, (Z3_solver)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT jlong JNICALL Java_Z3Native_solverGetParamDescrs(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_param_descrs result = Z3_solver_get_param_descrs((Z3_context)a0, (Z3_solver)a1); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_solverSetParams(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_solver_set_params((Z3_context)a0, (Z3_solver)a1, (Z3_params)a2); -} -JNIEXPORT void JNICALL Java_Z3Native_solverIncRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_solver_inc_ref((Z3_context)a0, (Z3_solver)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_solverDecRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_solver_dec_ref((Z3_context)a0, (Z3_solver)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_solverPush(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_solver_push((Z3_context)a0, (Z3_solver)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_solverPop(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_solver_pop((Z3_context)a0, (Z3_solver)a1, (unsigned)a2); -} -JNIEXPORT void JNICALL Java_Z3Native_solverReset(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_solver_reset((Z3_context)a0, (Z3_solver)a1); -} -JNIEXPORT jint JNICALL Java_Z3Native_solverGetNumScopes(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_solver_get_num_scopes((Z3_context)a0, (Z3_solver)a1); - return (jint) result; -} -JNIEXPORT void JNICALL Java_Z3Native_solverAssert(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2) { - Z3_solver_assert((Z3_context)a0, (Z3_solver)a1, (Z3_ast)a2); -} -JNIEXPORT void JNICALL Java_Z3Native_solverAssertAndTrack(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jlong a3) { - Z3_solver_assert_and_track((Z3_context)a0, (Z3_solver)a1, (Z3_ast)a2, (Z3_ast)a3); -} -JNIEXPORT jlong JNICALL Java_Z3Native_solverGetAssertions(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast_vector result = Z3_solver_get_assertions((Z3_context)a0, (Z3_solver)a1); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_solverCheck(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - int result = Z3_solver_check((Z3_context)a0, (Z3_solver)a1); - return (jint) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_solverCheckAssumptions(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jlongArray a3) { - Z3_ast * _a3 = (Z3_ast *) jenv->GetLongArrayElements(a3, NULL); - int result = Z3_solver_check_assumptions((Z3_context)a0, (Z3_solver)a1, (unsigned)a2, _a3); - jenv->ReleaseLongArrayElements(a3, (jlong *) _a3, JNI_ABORT); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_solverGetModel(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_model result = Z3_solver_get_model((Z3_context)a0, (Z3_solver)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_solverGetProof(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast result = Z3_solver_get_proof((Z3_context)a0, (Z3_solver)a1); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_solverGetUnsatCore(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_ast_vector result = Z3_solver_get_unsat_core((Z3_context)a0, (Z3_solver)a1); - return (jlong) result; -} -JNIEXPORT jstring JNICALL Java_Z3Native_solverGetReasonUnknown(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_string result = Z3_solver_get_reason_unknown((Z3_context)a0, (Z3_solver)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT jlong JNICALL Java_Z3Native_solverGetStatistics(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_stats result = Z3_solver_get_statistics((Z3_context)a0, (Z3_solver)a1); - return (jlong) result; -} -JNIEXPORT jstring JNICALL Java_Z3Native_solverToString(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_string result = Z3_solver_to_string((Z3_context)a0, (Z3_solver)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT jstring JNICALL Java_Z3Native_statsToString(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_string result = Z3_stats_to_string((Z3_context)a0, (Z3_stats)a1); - return jenv->NewStringUTF(result); -} -JNIEXPORT void JNICALL Java_Z3Native_statsIncRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_stats_inc_ref((Z3_context)a0, (Z3_stats)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_statsDecRef(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_stats_dec_ref((Z3_context)a0, (Z3_stats)a1); -} -JNIEXPORT jint JNICALL Java_Z3Native_statsSize(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_stats_size((Z3_context)a0, (Z3_stats)a1); - return (jint) result; -} -JNIEXPORT jstring JNICALL Java_Z3Native_statsGetKey(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_string result = Z3_stats_get_key((Z3_context)a0, (Z3_stats)a1, (unsigned)a2); - return jenv->NewStringUTF(result); -} -JNIEXPORT jboolean JNICALL Java_Z3Native_statsIsUint(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_bool result = Z3_stats_is_uint((Z3_context)a0, (Z3_stats)a1, (unsigned)a2); - return (jboolean) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_statsIsDouble(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_bool result = Z3_stats_is_double((Z3_context)a0, (Z3_stats)a1, (unsigned)a2); - return (jboolean) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_statsGetUintValue(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - unsigned result = Z3_stats_get_uint_value((Z3_context)a0, (Z3_stats)a1, (unsigned)a2); - return (jint) result; -} -JNIEXPORT jdouble JNICALL Java_Z3Native_statsGetDoubleValue(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - double result = Z3_stats_get_double_value((Z3_context)a0, (Z3_stats)a1, (unsigned)a2); - return (jdouble) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkInjectiveFunction(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jlongArray a3, jlong a4) { - Z3_sort * _a3 = (Z3_sort *) jenv->GetLongArrayElements(a3, NULL); - Z3_func_decl result = Z3_mk_injective_function((Z3_context)a0, (Z3_symbol)a1, (unsigned)a2, _a3, (Z3_sort)a4); - jenv->ReleaseLongArrayElements(a3, (jlong *) _a3, JNI_ABORT); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_setLogic(JNIEnv * jenv, jclass cls, jlong a0, jstring a1) { - Z3_string _a1 = (Z3_string) jenv->GetStringUTFChars(a1, NULL); - Z3_set_logic((Z3_context)a0, _a1); -} -JNIEXPORT void JNICALL Java_Z3Native_push(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_push((Z3_context)a0); -} -JNIEXPORT void JNICALL Java_Z3Native_pop(JNIEnv * jenv, jclass cls, jlong a0, jint a1) { - Z3_pop((Z3_context)a0, (unsigned)a1); -} -JNIEXPORT jint JNICALL Java_Z3Native_getNumScopes(JNIEnv * jenv, jclass cls, jlong a0) { - unsigned result = Z3_get_num_scopes((Z3_context)a0); - return (jint) result; -} -JNIEXPORT void JNICALL Java_Z3Native_persistAst(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_persist_ast((Z3_context)a0, (Z3_ast)a1, (unsigned)a2); -} -JNIEXPORT void JNICALL Java_Z3Native_assertCnstr(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_assert_cnstr((Z3_context)a0, (Z3_ast)a1); -} -JNIEXPORT jint JNICALL Java_Z3Native_checkAndGetModel(JNIEnv * jenv, jclass cls, jlong a0, jobject a1) { - Z3_model _a1; - int result = Z3_check_and_get_model((Z3_context)a0, &_a1); - { - jclass mc = jenv->GetObjectClass(a1); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a1, fid, (jlong) _a1); - } - return (jint) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_check(JNIEnv * jenv, jclass cls, jlong a0) { - int result = Z3_check((Z3_context)a0); - return (jint) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_checkAssumptions(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlongArray a2, jobject a3, jobject a4, jobject a5, jlongArray a6) { - Z3_ast * _a2 = (Z3_ast *) jenv->GetLongArrayElements(a2, NULL); - Z3_model _a3; - Z3_ast _a4; - unsigned _a5; - Z3_ast * _a6 = (Z3_ast *) malloc(((unsigned)a1) * sizeof(Z3_ast)); - int result = Z3_check_assumptions((Z3_context)a0, (unsigned)a1, _a2, &_a3, &_a4, &_a5, _a6); - jenv->ReleaseLongArrayElements(a2, (jlong *) _a2, JNI_ABORT); - { - jclass mc = jenv->GetObjectClass(a3); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a3, fid, (jlong) _a3); - } - { - jclass mc = jenv->GetObjectClass(a4); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a4, fid, (jlong) _a4); - } - { - jclass mc = jenv->GetObjectClass(a5); - jfieldID fid = jenv->GetFieldID(mc, "value", "I"); - jenv->SetIntField(a5, fid, (jint) _a5); - } - jenv->SetLongArrayRegion(a6, 0, (jsize)a1, (jlong *) _a6); - free(_a6); - return (jint) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getImpliedEqualities(JNIEnv * jenv, jclass cls, jlong a0, jint a1, jlongArray a2, jintArray a3) { - Z3_ast * _a2 = (Z3_ast *) jenv->GetLongArrayElements(a2, NULL); - unsigned * _a3 = (unsigned *) malloc(((unsigned)a1) * sizeof(unsigned)); - unsigned result = Z3_get_implied_equalities((Z3_context)a0, (unsigned)a1, _a2, _a3); - jenv->ReleaseLongArrayElements(a2, (jlong *) _a2, JNI_ABORT); - jenv->SetIntArrayRegion(a3, 0, (jsize)a1, (jint *) _a3); - free(_a3); - return (jint) result; -} -JNIEXPORT void JNICALL Java_Z3Native_delModel(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_del_model((Z3_context)a0, (Z3_model)a1); -} -JNIEXPORT void JNICALL Java_Z3Native_softCheckCancel(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_soft_check_cancel((Z3_context)a0); -} -JNIEXPORT jint JNICALL Java_Z3Native_getSearchFailure(JNIEnv * jenv, jclass cls, jlong a0) { - unsigned result = Z3_get_search_failure((Z3_context)a0); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_mkLabel(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jboolean a2, jlong a3) { - Z3_ast result = Z3_mk_label((Z3_context)a0, (Z3_symbol)a1, (Z3_bool)a2, (Z3_ast)a3); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getRelevantLabels(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_literals result = Z3_get_relevant_labels((Z3_context)a0); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getRelevantLiterals(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_literals result = Z3_get_relevant_literals((Z3_context)a0); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getGuessedLiterals(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_literals result = Z3_get_guessed_literals((Z3_context)a0); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_delLiterals(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_del_literals((Z3_context)a0, (Z3_literals)a1); -} -JNIEXPORT jint JNICALL Java_Z3Native_getNumLiterals(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_num_literals((Z3_context)a0, (Z3_literals)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getLabelSymbol(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_symbol result = Z3_get_label_symbol((Z3_context)a0, (Z3_literals)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getLiteral(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_ast result = Z3_get_literal((Z3_context)a0, (Z3_literals)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT void JNICALL Java_Z3Native_disableLiteral(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_disable_literal((Z3_context)a0, (Z3_literals)a1, (unsigned)a2); -} -JNIEXPORT void JNICALL Java_Z3Native_blockLiterals(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - Z3_block_literals((Z3_context)a0, (Z3_literals)a1); -} -JNIEXPORT jint JNICALL Java_Z3Native_getModelNumConstants(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_model_num_constants((Z3_context)a0, (Z3_model)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getModelConstant(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_func_decl result = Z3_get_model_constant((Z3_context)a0, (Z3_model)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getModelNumFuncs(JNIEnv * jenv, jclass cls, jlong a0, jlong a1) { - unsigned result = Z3_get_model_num_funcs((Z3_context)a0, (Z3_model)a1); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getModelFuncDecl(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_func_decl result = Z3_get_model_func_decl((Z3_context)a0, (Z3_model)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_evalFuncDecl(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jobject a3) { - Z3_ast _a3; - Z3_bool result = Z3_eval_func_decl((Z3_context)a0, (Z3_model)a1, (Z3_func_decl)a2, &_a3); - { - jclass mc = jenv->GetObjectClass(a3); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a3, fid, (jlong) _a3); - } - return (jboolean) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_isArrayValue(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jobject a3) { - unsigned _a3; - Z3_bool result = Z3_is_array_value((Z3_context)a0, (Z3_model)a1, (Z3_ast)a2, &_a3); - { - jclass mc = jenv->GetObjectClass(a3); - jfieldID fid = jenv->GetFieldID(mc, "value", "I"); - jenv->SetIntField(a3, fid, (jint) _a3); - } - return (jboolean) result; -} -JNIEXPORT void JNICALL Java_Z3Native_getArrayValue(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jint a3, jlongArray a4, jlongArray a5, jobject a6) { - Z3_ast * _a4 = (Z3_ast *) malloc(((unsigned)a3) * sizeof(Z3_ast)); - Z3_ast * _a5 = (Z3_ast *) malloc(((unsigned)a3) * sizeof(Z3_ast)); - Z3_ast _a6; - Z3_get_array_value((Z3_context)a0, (Z3_model)a1, (Z3_ast)a2, (unsigned)a3, _a4, _a5, &_a6); - jenv->SetLongArrayRegion(a4, 0, (jsize)a3, (jlong *) _a4); - free(_a4); - jenv->SetLongArrayRegion(a5, 0, (jsize)a3, (jlong *) _a5); - free(_a5); - { - jclass mc = jenv->GetObjectClass(a6); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a6, fid, (jlong) _a6); - } -} -JNIEXPORT jlong JNICALL Java_Z3Native_getModelFuncElse(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - Z3_ast result = Z3_get_model_func_else((Z3_context)a0, (Z3_model)a1, (unsigned)a2); - return (jlong) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getModelFuncNumEntries(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2) { - unsigned result = Z3_get_model_func_num_entries((Z3_context)a0, (Z3_model)a1, (unsigned)a2); - return (jint) result; -} -JNIEXPORT jint JNICALL Java_Z3Native_getModelFuncEntryNumArgs(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jint a3) { - unsigned result = Z3_get_model_func_entry_num_args((Z3_context)a0, (Z3_model)a1, (unsigned)a2, (unsigned)a3); - return (jint) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getModelFuncEntryArg(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jint a3, jint a4) { - Z3_ast result = Z3_get_model_func_entry_arg((Z3_context)a0, (Z3_model)a1, (unsigned)a2, (unsigned)a3, (unsigned)a4); - return (jlong) result; -} -JNIEXPORT jlong JNICALL Java_Z3Native_getModelFuncEntryValue(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jint a2, jint a3) { - Z3_ast result = Z3_get_model_func_entry_value((Z3_context)a0, (Z3_model)a1, (unsigned)a2, (unsigned)a3); - return (jlong) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_eval(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jobject a3) { - Z3_ast _a3; - Z3_bool result = Z3_eval((Z3_context)a0, (Z3_model)a1, (Z3_ast)a2, &_a3); - { - jclass mc = jenv->GetObjectClass(a3); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a3, fid, (jlong) _a3); - } - return (jboolean) result; -} -JNIEXPORT jboolean JNICALL Java_Z3Native_evalDecl(JNIEnv * jenv, jclass cls, jlong a0, jlong a1, jlong a2, jint a3, jlongArray a4, jobject a5) { - Z3_ast * _a4 = (Z3_ast *) jenv->GetLongArrayElements(a4, NULL); - Z3_ast _a5; - Z3_bool result = Z3_eval_decl((Z3_context)a0, (Z3_model)a1, (Z3_func_decl)a2, (unsigned)a3, _a4, &_a5); - jenv->ReleaseLongArrayElements(a4, (jlong *) _a4, JNI_ABORT); - { - jclass mc = jenv->GetObjectClass(a5); - jfieldID fid = jenv->GetFieldID(mc, "value", "J"); - jenv->SetLongField(a5, fid, (jlong) _a5); - } - return (jboolean) result; -} -JNIEXPORT jstring JNICALL Java_Z3Native_contextToString(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_string result = Z3_context_to_string((Z3_context)a0); - return jenv->NewStringUTF(result); -} -JNIEXPORT jstring JNICALL Java_Z3Native_statisticsToString(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_string result = Z3_statistics_to_string((Z3_context)a0); - return jenv->NewStringUTF(result); -} -JNIEXPORT jlong JNICALL Java_Z3Native_getContextAssignment(JNIEnv * jenv, jclass cls, jlong a0) { - Z3_ast result = Z3_get_context_assignment((Z3_context)a0); - return (jlong) result; -} -#ifdef __cplusplus -} -#endif diff --git a/src/api/java/com/Microsoft/Z3/Native.class b/src/api/java/com/Microsoft/Z3/Native.class deleted file mode 100644 index 04e71cfb4..000000000 Binary files a/src/api/java/com/Microsoft/Z3/Native.class and /dev/null differ diff --git a/src/api/java/com/Microsoft/Z3/Native.java b/src/api/java/com/Microsoft/Z3/Native.java deleted file mode 100644 index 31ca6f4bc..000000000 --- a/src/api/java/com/Microsoft/Z3/Native.java +++ /dev/null @@ -1,497 +0,0 @@ -// Automatically generated file -package com.Microsoft.Z3; -public final class Native { - public static class IntPtr { public int value; } - public static class LongPtr { public long value; } - public static class StringPtr { public String value; } - static { System.loadLibrary(""); } - public static native long mkConfig(); - public static native void delConfig(long a0); - public static native void setParamValue(long a0, String a1, String a2); - public static native long mkContext(long a0); - public static native long mkContextRc(long a0); - public static native void delContext(long a0); - public static native void incRef(long a0, long a1); - public static native void decRef(long a0, long a1); - public static native void updateParamValue(long a0, String a1, String a2); - public static native boolean getParamValue(long a0, String a1, String a2); - public static native void interrupt(long a0); - public static native long mkParams(long a0); - public static native void paramsIncRef(long a0, long a1); - public static native void paramsDecRef(long a0, long a1); - public static native void paramsSetBool(long a0, long a1, long a2, boolean a3); - public static native void paramsSetUint(long a0, long a1, long a2, int a3); - public static native void paramsSetDouble(long a0, long a1, long a2, double a3); - public static native void paramsSetSymbol(long a0, long a1, long a2, long a3); - public static native String paramsToString(long a0, long a1); - public static native void paramsValidate(long a0, long a1, long a2); - public static native void paramDescrsIncRef(long a0, long a1); - public static native void paramDescrsDecRef(long a0, long a1); - public static native int paramDescrsGetKind(long a0, long a1, long a2); - public static native int paramDescrsSize(long a0, long a1); - public static native long paramDescrsGetName(long a0, long a1, int a2); - public static native String paramDescrsToString(long a0, long a1); - public static native long mkIntSymbol(long a0, int a1); - public static native long mkStringSymbol(long a0, String a1); - public static native long mkUninterpretedSort(long a0, long a1); - public static native long mkBoolSort(long a0); - public static native long mkIntSort(long a0); - public static native long mkRealSort(long a0); - public static native long mkBvSort(long a0, int a1); - public static native long mkFiniteDomainSort(long a0, long a1, long a2); - public static native long mkArraySort(long a0, long a1, long a2); - public static native long mkTupleSort(long a0, long a1, int a2, long[] a3, long[] a4, Long a5, long[] a6); - public static native long mkEnumerationSort(long a0, long a1, int a2, long[] a3, long[] a4, long[] a5); - public static native long mkListSort(long a0, long a1, long a2, Long a3, Long a4, Long a5, Long a6, Long a7, Long a8); - public static native long mkConstructor(long a0, long a1, long a2, int a3, long[] a4, long[] a5, int[] a6); - public static native void delConstructor(long a0, long a1); - public static native long mkDatatype(long a0, long a1, int a2, long[] a3); - public static native long mkConstructorList(long a0, int a1, long[] a2); - public static native void delConstructorList(long a0, long a1); - public static native void mkDatatypes(long a0, int a1, long[] a2, long[] a3, long[] a4); - public static native void queryConstructor(long a0, long a1, int a2, Long a3, Long a4, long[] a5); - public static native long mkFuncDecl(long a0, long a1, int a2, long[] a3, long a4); - public static native long mkApp(long a0, long a1, int a2, long[] a3); - public static native long mkConst(long a0, long a1, long a2); - public static native long mkFreshFuncDecl(long a0, String a1, int a2, long[] a3, long a4); - public static native long mkFreshConst(long a0, String a1, long a2); - public static native long mkTrue(long a0); - public static native long mkFalse(long a0); - public static native long mkEq(long a0, long a1, long a2); - public static native long mkDistinct(long a0, int a1, long[] a2); - public static native long mkNot(long a0, long a1); - public static native long mkIte(long a0, long a1, long a2, long a3); - public static native long mkIff(long a0, long a1, long a2); - public static native long mkImplies(long a0, long a1, long a2); - public static native long mkXor(long a0, long a1, long a2); - public static native long mkAnd(long a0, int a1, long[] a2); - public static native long mkOr(long a0, int a1, long[] a2); - public static native long mkAdd(long a0, int a1, long[] a2); - public static native long mkMul(long a0, int a1, long[] a2); - public static native long mkSub(long a0, int a1, long[] a2); - public static native long mkUnaryMinus(long a0, long a1); - public static native long mkDiv(long a0, long a1, long a2); - public static native long mkMod(long a0, long a1, long a2); - public static native long mkRem(long a0, long a1, long a2); - public static native long mkPower(long a0, long a1, long a2); - public static native long mkLt(long a0, long a1, long a2); - public static native long mkLe(long a0, long a1, long a2); - public static native long mkGt(long a0, long a1, long a2); - public static native long mkGe(long a0, long a1, long a2); - public static native long mkInt2real(long a0, long a1); - public static native long mkReal2int(long a0, long a1); - public static native long mkIsInt(long a0, long a1); - public static native long mkBvnot(long a0, long a1); - public static native long mkBvredand(long a0, long a1); - public static native long mkBvredor(long a0, long a1); - public static native long mkBvand(long a0, long a1, long a2); - public static native long mkBvor(long a0, long a1, long a2); - public static native long mkBvxor(long a0, long a1, long a2); - public static native long mkBvnand(long a0, long a1, long a2); - public static native long mkBvnor(long a0, long a1, long a2); - public static native long mkBvxnor(long a0, long a1, long a2); - public static native long mkBvneg(long a0, long a1); - public static native long mkBvadd(long a0, long a1, long a2); - public static native long mkBvsub(long a0, long a1, long a2); - public static native long mkBvmul(long a0, long a1, long a2); - public static native long mkBvudiv(long a0, long a1, long a2); - public static native long mkBvsdiv(long a0, long a1, long a2); - public static native long mkBvurem(long a0, long a1, long a2); - public static native long mkBvsrem(long a0, long a1, long a2); - public static native long mkBvsmod(long a0, long a1, long a2); - public static native long mkBvult(long a0, long a1, long a2); - public static native long mkBvslt(long a0, long a1, long a2); - public static native long mkBvule(long a0, long a1, long a2); - public static native long mkBvsle(long a0, long a1, long a2); - public static native long mkBvuge(long a0, long a1, long a2); - public static native long mkBvsge(long a0, long a1, long a2); - public static native long mkBvugt(long a0, long a1, long a2); - public static native long mkBvsgt(long a0, long a1, long a2); - public static native long mkConcat(long a0, long a1, long a2); - public static native long mkExtract(long a0, int a1, int a2, long a3); - public static native long mkSignExt(long a0, int a1, long a2); - public static native long mkZeroExt(long a0, int a1, long a2); - public static native long mkRepeat(long a0, int a1, long a2); - public static native long mkBvshl(long a0, long a1, long a2); - public static native long mkBvlshr(long a0, long a1, long a2); - public static native long mkBvashr(long a0, long a1, long a2); - public static native long mkRotateLeft(long a0, int a1, long a2); - public static native long mkRotateRight(long a0, int a1, long a2); - public static native long mkExtRotateLeft(long a0, long a1, long a2); - public static native long mkExtRotateRight(long a0, long a1, long a2); - public static native long mkInt2bv(long a0, int a1, long a2); - public static native long mkBv2int(long a0, long a1, boolean a2); - public static native long mkBvaddNoOverflow(long a0, long a1, long a2, boolean a3); - public static native long mkBvaddNoUnderflow(long a0, long a1, long a2); - public static native long mkBvsubNoOverflow(long a0, long a1, long a2); - public static native long mkBvsubNoUnderflow(long a0, long a1, long a2, boolean a3); - public static native long mkBvsdivNoOverflow(long a0, long a1, long a2); - public static native long mkBvnegNoOverflow(long a0, long a1); - public static native long mkBvmulNoOverflow(long a0, long a1, long a2, boolean a3); - public static native long mkBvmulNoUnderflow(long a0, long a1, long a2); - public static native long mkSelect(long a0, long a1, long a2); - public static native long mkStore(long a0, long a1, long a2, long a3); - public static native long mkConstArray(long a0, long a1, long a2); - public static native long mkMap(long a0, long a1, int a2, long[] a3); - public static native long mkArrayDefault(long a0, long a1); - public static native long mkSetSort(long a0, long a1); - public static native long mkEmptySet(long a0, long a1); - public static native long mkFullSet(long a0, long a1); - public static native long mkSetAdd(long a0, long a1, long a2); - public static native long mkSetDel(long a0, long a1, long a2); - public static native long mkSetUnion(long a0, int a1, long[] a2); - public static native long mkSetIntersect(long a0, int a1, long[] a2); - public static native long mkSetDifference(long a0, long a1, long a2); - public static native long mkSetComplement(long a0, long a1); - public static native long mkSetMember(long a0, long a1, long a2); - public static native long mkSetSubset(long a0, long a1, long a2); - public static native long mkNumeral(long a0, String a1, long a2); - public static native long mkReal(long a0, int a1, int a2); - public static native long mkInt(long a0, int a1, long a2); - public static native long mkUnsignedInt(long a0, int a1, long a2); - public static native long mkInt64(long a0, long a1, long a2); - public static native long mkUnsignedInt64(long a0, long a1, long a2); - public static native long mkPattern(long a0, int a1, long[] a2); - public static native long mkBound(long a0, int a1, long a2); - public static native long mkForall(long a0, int a1, int a2, long[] a3, int a4, long[] a5, long[] a6, long a7); - public static native long mkExists(long a0, int a1, int a2, long[] a3, int a4, long[] a5, long[] a6, long a7); - public static native long mkQuantifier(long a0, boolean a1, int a2, int a3, long[] a4, int a5, long[] a6, long[] a7, long a8); - public static native long mkQuantifierEx(long a0, boolean a1, int a2, long a3, long a4, int a5, long[] a6, int a7, long[] a8, int a9, long[] a10, long[] a11, long a12); - public static native long mkForallConst(long a0, int a1, int a2, long[] a3, int a4, long[] a5, long a6); - public static native long mkExistsConst(long a0, int a1, int a2, long[] a3, int a4, long[] a5, long a6); - public static native long mkQuantifierConst(long a0, boolean a1, int a2, int a3, long[] a4, int a5, long[] a6, long a7); - public static native long mkQuantifierConstEx(long a0, boolean a1, int a2, long a3, long a4, int a5, long[] a6, int a7, long[] a8, int a9, long[] a10, long a11); - public static native int getSymbolKind(long a0, long a1); - public static native int getSymbolInt(long a0, long a1); - public static native String getSymbolString(long a0, long a1); - public static native long getSortName(long a0, long a1); - public static native int getSortId(long a0, long a1); - public static native long sortToAst(long a0, long a1); - public static native boolean isEqSort(long a0, long a1, long a2); - public static native int getSortKind(long a0, long a1); - public static native int getBvSortSize(long a0, long a1); - public static native boolean getFiniteDomainSortSize(long a0, long a1, Long a2); - public static native long getArraySortDomain(long a0, long a1); - public static native long getArraySortRange(long a0, long a1); - public static native long getTupleSortMkDecl(long a0, long a1); - public static native int getTupleSortNumFields(long a0, long a1); - public static native long getTupleSortFieldDecl(long a0, long a1, int a2); - public static native int getDatatypeSortNumConstructors(long a0, long a1); - public static native long getDatatypeSortConstructor(long a0, long a1, int a2); - public static native long getDatatypeSortRecognizer(long a0, long a1, int a2); - public static native long getDatatypeSortConstructorAccessor(long a0, long a1, int a2, int a3); - public static native int getRelationArity(long a0, long a1); - public static native long getRelationColumn(long a0, long a1, int a2); - public static native long funcDeclToAst(long a0, long a1); - public static native boolean isEqFuncDecl(long a0, long a1, long a2); - public static native int getFuncDeclId(long a0, long a1); - public static native long getDeclName(long a0, long a1); - public static native int getDeclKind(long a0, long a1); - public static native int getDomainSize(long a0, long a1); - public static native int getArity(long a0, long a1); - public static native long getDomain(long a0, long a1, int a2); - public static native long getRange(long a0, long a1); - public static native int getDeclNumParameters(long a0, long a1); - public static native int getDeclParameterKind(long a0, long a1, int a2); - public static native int getDeclIntParameter(long a0, long a1, int a2); - public static native double getDeclDoubleParameter(long a0, long a1, int a2); - public static native long getDeclSymbolParameter(long a0, long a1, int a2); - public static native long getDeclSortParameter(long a0, long a1, int a2); - public static native long getDeclAstParameter(long a0, long a1, int a2); - public static native long getDeclFuncDeclParameter(long a0, long a1, int a2); - public static native String getDeclRationalParameter(long a0, long a1, int a2); - public static native long appToAst(long a0, long a1); - public static native long getAppDecl(long a0, long a1); - public static native int getAppNumArgs(long a0, long a1); - public static native long getAppArg(long a0, long a1, int a2); - public static native boolean isEqAst(long a0, long a1, long a2); - public static native int getAstId(long a0, long a1); - public static native int getAstHash(long a0, long a1); - public static native long getSort(long a0, long a1); - public static native boolean isWellSorted(long a0, long a1); - public static native int getBoolValue(long a0, long a1); - public static native int getAstKind(long a0, long a1); - public static native boolean isApp(long a0, long a1); - public static native boolean isNumeralAst(long a0, long a1); - public static native boolean isAlgebraicNumber(long a0, long a1); - public static native long toApp(long a0, long a1); - public static native long toFuncDecl(long a0, long a1); - public static native String getNumeralString(long a0, long a1); - public static native String getNumeralDecimalString(long a0, long a1, int a2); - public static native long getNumerator(long a0, long a1); - public static native long getDenominator(long a0, long a1); - public static native boolean getNumeralSmall(long a0, long a1, Long a2, Long a3); - public static native boolean getNumeralInt(long a0, long a1, Integer a2); - public static native boolean getNumeralUint(long a0, long a1, Integer a2); - public static native boolean getNumeralUint64(long a0, long a1, Long a2); - public static native boolean getNumeralInt64(long a0, long a1, Long a2); - public static native boolean getNumeralRationalInt64(long a0, long a1, Long a2, Long a3); - public static native long getAlgebraicNumberLower(long a0, long a1, int a2); - public static native long getAlgebraicNumberUpper(long a0, long a1, int a2); - public static native long patternToAst(long a0, long a1); - public static native int getPatternNumTerms(long a0, long a1); - public static native long getPattern(long a0, long a1, int a2); - public static native int getIndexValue(long a0, long a1); - public static native boolean isQuantifierForall(long a0, long a1); - public static native int getQuantifierWeight(long a0, long a1); - public static native int getQuantifierNumPatterns(long a0, long a1); - public static native long getQuantifierPatternAst(long a0, long a1, int a2); - public static native int getQuantifierNumNoPatterns(long a0, long a1); - public static native long getQuantifierNoPatternAst(long a0, long a1, int a2); - public static native int getQuantifierNumBound(long a0, long a1); - public static native long getQuantifierBoundName(long a0, long a1, int a2); - public static native long getQuantifierBoundSort(long a0, long a1, int a2); - public static native long getQuantifierBody(long a0, long a1); - public static native long simplify(long a0, long a1); - public static native long simplifyEx(long a0, long a1, long a2); - public static native String simplifyGetHelp(long a0); - public static native long simplifyGetParamDescrs(long a0); - public static native long updateTerm(long a0, long a1, int a2, long[] a3); - public static native long substitute(long a0, long a1, int a2, long[] a3, long[] a4); - public static native long substituteVars(long a0, long a1, int a2, long[] a3); - public static native long translate(long a0, long a1, long a2); - public static native void modelIncRef(long a0, long a1); - public static native void modelDecRef(long a0, long a1); - public static native boolean modelEval(long a0, long a1, long a2, boolean a3, Long a4); - public static native long modelGetConstInterp(long a0, long a1, long a2); - public static native long modelGetFuncInterp(long a0, long a1, long a2); - public static native int modelGetNumConsts(long a0, long a1); - public static native long modelGetConstDecl(long a0, long a1, int a2); - public static native int modelGetNumFuncs(long a0, long a1); - public static native long modelGetFuncDecl(long a0, long a1, int a2); - public static native int modelGetNumSorts(long a0, long a1); - public static native long modelGetSort(long a0, long a1, int a2); - public static native long modelGetSortUniverse(long a0, long a1, long a2); - public static native boolean isAsArray(long a0, long a1); - public static native long getAsArrayFuncDecl(long a0, long a1); - public static native void funcInterpIncRef(long a0, long a1); - public static native void funcInterpDecRef(long a0, long a1); - public static native int funcInterpGetNumEntries(long a0, long a1); - public static native long funcInterpGetEntry(long a0, long a1, int a2); - public static native long funcInterpGetElse(long a0, long a1); - public static native int funcInterpGetArity(long a0, long a1); - public static native void funcEntryIncRef(long a0, long a1); - public static native void funcEntryDecRef(long a0, long a1); - public static native long funcEntryGetValue(long a0, long a1); - public static native int funcEntryGetNumArgs(long a0, long a1); - public static native long funcEntryGetArg(long a0, long a1, int a2); - public static native int openLog(String a0); - public static native void appendLog(String a0); - public static native void closeLog(); - public static native void toggleWarningMessages(boolean a0); - public static native void setAstPrintMode(long a0, int a1); - public static native String astToString(long a0, long a1); - public static native String patternToString(long a0, long a1); - public static native String sortToString(long a0, long a1); - public static native String funcDeclToString(long a0, long a1); - public static native String modelToString(long a0, long a1); - public static native String benchmarkToSmtlibString(long a0, String a1, String a2, String a3, String a4, int a5, long[] a6, long a7); - public static native long parseSmtlib2String(long a0, String a1, int a2, long[] a3, long[] a4, int a5, long[] a6, long[] a7); - public static native long parseSmtlib2File(long a0, String a1, int a2, long[] a3, long[] a4, int a5, long[] a6, long[] a7); - public static native void parseSmtlibString(long a0, String a1, int a2, long[] a3, long[] a4, int a5, long[] a6, long[] a7); - public static native void parseSmtlibFile(long a0, String a1, int a2, long[] a3, long[] a4, int a5, long[] a6, long[] a7); - public static native int getSmtlibNumFormulas(long a0); - public static native long getSmtlibFormula(long a0, int a1); - public static native int getSmtlibNumAssumptions(long a0); - public static native long getSmtlibAssumption(long a0, int a1); - public static native int getSmtlibNumDecls(long a0); - public static native long getSmtlibDecl(long a0, int a1); - public static native int getSmtlibNumSorts(long a0); - public static native long getSmtlibSort(long a0, int a1); - public static native String getSmtlibError(long a0); - public static native int getErrorCode(long a0); - public static native void setError(long a0, int a1); - public static native String getErrorMsg(int a0); - public static native String getErrorMsgEx(long a0, int a1); - public static native void getVersion(Integer a0, Integer a1, Integer a2, Integer a3); - public static native void enableTrace(String a0); - public static native void disableTrace(String a0); - public static native void resetMemory(); - public static native long mkFixedpoint(long a0); - public static native void fixedpointIncRef(long a0, long a1); - public static native void fixedpointDecRef(long a0, long a1); - public static native void fixedpointAddRule(long a0, long a1, long a2, long a3); - public static native void fixedpointAddFact(long a0, long a1, long a2, int a3, int[] a4); - public static native void fixedpointAssert(long a0, long a1, long a2); - public static native int fixedpointQuery(long a0, long a1, long a2); - public static native int fixedpointQueryRelations(long a0, long a1, int a2, long[] a3); - public static native long fixedpointGetAnswer(long a0, long a1); - public static native String fixedpointGetReasonUnknown(long a0, long a1); - public static native void fixedpointUpdateRule(long a0, long a1, long a2, long a3); - public static native int fixedpointGetNumLevels(long a0, long a1, long a2); - public static native long fixedpointGetCoverDelta(long a0, long a1, int a2, long a3); - public static native void fixedpointAddCover(long a0, long a1, int a2, long a3, long a4); - public static native long fixedpointGetStatistics(long a0, long a1); - public static native void fixedpointRegisterRelation(long a0, long a1, long a2); - public static native void fixedpointSetPredicateRepresentation(long a0, long a1, long a2, int a3, long[] a4); - public static native long fixedpointGetRules(long a0, long a1); - public static native long fixedpointGetAssertions(long a0, long a1); - public static native void fixedpointSetParams(long a0, long a1, long a2); - public static native String fixedpointGetHelp(long a0, long a1); - public static native long fixedpointGetParamDescrs(long a0, long a1); - public static native String fixedpointToString(long a0, long a1, int a2, long[] a3); - public static native long fixedpointFromString(long a0, long a1, String a2); - public static native long fixedpointFromFile(long a0, long a1, String a2); - public static native void fixedpointPush(long a0, long a1); - public static native void fixedpointPop(long a0, long a1); - public static native long mkAstVector(long a0); - public static native void astVectorIncRef(long a0, long a1); - public static native void astVectorDecRef(long a0, long a1); - public static native int astVectorSize(long a0, long a1); - public static native long astVectorGet(long a0, long a1, int a2); - public static native void astVectorSet(long a0, long a1, int a2, long a3); - public static native void astVectorResize(long a0, long a1, int a2); - public static native void astVectorPush(long a0, long a1, long a2); - public static native long astVectorTranslate(long a0, long a1, long a2); - public static native String astVectorToString(long a0, long a1); - public static native long mkAstMap(long a0); - public static native void astMapIncRef(long a0, long a1); - public static native void astMapDecRef(long a0, long a1); - public static native boolean astMapContains(long a0, long a1, long a2); - public static native long astMapFind(long a0, long a1, long a2); - public static native void astMapInsert(long a0, long a1, long a2, long a3); - public static native void astMapErase(long a0, long a1, long a2); - public static native void astMapReset(long a0, long a1); - public static native int astMapSize(long a0, long a1); - public static native long astMapKeys(long a0, long a1); - public static native String astMapToString(long a0, long a1); - public static native long mkGoal(long a0, boolean a1, boolean a2, boolean a3); - public static native void goalIncRef(long a0, long a1); - public static native void goalDecRef(long a0, long a1); - public static native int goalPrecision(long a0, long a1); - public static native void goalAssert(long a0, long a1, long a2); - public static native boolean goalInconsistent(long a0, long a1); - public static native int goalDepth(long a0, long a1); - public static native void goalReset(long a0, long a1); - public static native int goalSize(long a0, long a1); - public static native long goalFormula(long a0, long a1, int a2); - public static native int goalNumExprs(long a0, long a1); - public static native boolean goalIsDecidedSat(long a0, long a1); - public static native boolean goalIsDecidedUnsat(long a0, long a1); - public static native long goalTranslate(long a0, long a1, long a2); - public static native String goalToString(long a0, long a1); - public static native long mkTactic(long a0, String a1); - public static native void tacticIncRef(long a0, long a1); - public static native void tacticDecRef(long a0, long a1); - public static native long mkProbe(long a0, String a1); - public static native void probeIncRef(long a0, long a1); - public static native void probeDecRef(long a0, long a1); - public static native long tacticAndThen(long a0, long a1, long a2); - public static native long tacticOrElse(long a0, long a1, long a2); - public static native long tacticParOr(long a0, int a1, long[] a2); - public static native long tacticParAndThen(long a0, long a1, long a2); - public static native long tacticTryFor(long a0, long a1, int a2); - public static native long tacticWhen(long a0, long a1, long a2); - public static native long tacticCond(long a0, long a1, long a2, long a3); - public static native long tacticRepeat(long a0, long a1, int a2); - public static native long tacticSkip(long a0); - public static native long tacticFail(long a0); - public static native long tacticFailIf(long a0, long a1); - public static native long tacticFailIfNotDecided(long a0); - public static native long tacticUsingParams(long a0, long a1, long a2); - public static native long probeConst(long a0, double a1); - public static native long probeLt(long a0, long a1, long a2); - public static native long probeGt(long a0, long a1, long a2); - public static native long probeLe(long a0, long a1, long a2); - public static native long probeGe(long a0, long a1, long a2); - public static native long probeEq(long a0, long a1, long a2); - public static native long probeAnd(long a0, long a1, long a2); - public static native long probeOr(long a0, long a1, long a2); - public static native long probeNot(long a0, long a1); - public static native int getNumTactics(long a0); - public static native String getTacticName(long a0, int a1); - public static native int getNumProbes(long a0); - public static native String getProbeName(long a0, int a1); - public static native String tacticGetHelp(long a0, long a1); - public static native long tacticGetParamDescrs(long a0, long a1); - public static native String tacticGetDescr(long a0, String a1); - public static native String probeGetDescr(long a0, String a1); - public static native double probeApply(long a0, long a1, long a2); - public static native long tacticApply(long a0, long a1, long a2); - public static native long tacticApplyEx(long a0, long a1, long a2, long a3); - public static native void applyResultIncRef(long a0, long a1); - public static native void applyResultDecRef(long a0, long a1); - public static native String applyResultToString(long a0, long a1); - public static native int applyResultGetNumSubgoals(long a0, long a1); - public static native long applyResultGetSubgoal(long a0, long a1, int a2); - public static native long applyResultConvertModel(long a0, long a1, int a2, long a3); - public static native long mkSolver(long a0); - public static native long mkSimpleSolver(long a0); - public static native long mkSolverForLogic(long a0, long a1); - public static native long mkSolverFromTactic(long a0, long a1); - public static native String solverGetHelp(long a0, long a1); - public static native long solverGetParamDescrs(long a0, long a1); - public static native void solverSetParams(long a0, long a1, long a2); - public static native void solverIncRef(long a0, long a1); - public static native void solverDecRef(long a0, long a1); - public static native void solverPush(long a0, long a1); - public static native void solverPop(long a0, long a1, int a2); - public static native void solverReset(long a0, long a1); - public static native int solverGetNumScopes(long a0, long a1); - public static native void solverAssert(long a0, long a1, long a2); - public static native void solverAssertAndTrack(long a0, long a1, long a2, long a3); - public static native long solverGetAssertions(long a0, long a1); - public static native int solverCheck(long a0, long a1); - public static native int solverCheckAssumptions(long a0, long a1, int a2, long[] a3); - public static native long solverGetModel(long a0, long a1); - public static native long solverGetProof(long a0, long a1); - public static native long solverGetUnsatCore(long a0, long a1); - public static native String solverGetReasonUnknown(long a0, long a1); - public static native long solverGetStatistics(long a0, long a1); - public static native String solverToString(long a0, long a1); - public static native String statsToString(long a0, long a1); - public static native void statsIncRef(long a0, long a1); - public static native void statsDecRef(long a0, long a1); - public static native int statsSize(long a0, long a1); - public static native String statsGetKey(long a0, long a1, int a2); - public static native boolean statsIsUint(long a0, long a1, int a2); - public static native boolean statsIsDouble(long a0, long a1, int a2); - public static native int statsGetUintValue(long a0, long a1, int a2); - public static native double statsGetDoubleValue(long a0, long a1, int a2); - public static native long mkInjectiveFunction(long a0, long a1, int a2, long[] a3, long a4); - public static native void setLogic(long a0, String a1); - public static native void push(long a0); - public static native void pop(long a0, int a1); - public static native int getNumScopes(long a0); - public static native void persistAst(long a0, long a1, int a2); - public static native void assertCnstr(long a0, long a1); - public static native int checkAndGetModel(long a0, Long a1); - public static native int check(long a0); - public static native int checkAssumptions(long a0, int a1, long[] a2, Long a3, Long a4, Integer a5, long[] a6); - public static native int getImpliedEqualities(long a0, int a1, long[] a2, int[] a3); - public static native void delModel(long a0, long a1); - public static native void softCheckCancel(long a0); - public static native int getSearchFailure(long a0); - public static native long mkLabel(long a0, long a1, boolean a2, long a3); - public static native long getRelevantLabels(long a0); - public static native long getRelevantLiterals(long a0); - public static native long getGuessedLiterals(long a0); - public static native void delLiterals(long a0, long a1); - public static native int getNumLiterals(long a0, long a1); - public static native long getLabelSymbol(long a0, long a1, int a2); - public static native long getLiteral(long a0, long a1, int a2); - public static native void disableLiteral(long a0, long a1, int a2); - public static native void blockLiterals(long a0, long a1); - public static native int getModelNumConstants(long a0, long a1); - public static native long getModelConstant(long a0, long a1, int a2); - public static native int getModelNumFuncs(long a0, long a1); - public static native long getModelFuncDecl(long a0, long a1, int a2); - public static native boolean evalFuncDecl(long a0, long a1, long a2, Long a3); - public static native boolean isArrayValue(long a0, long a1, long a2, Integer a3); - public static native void getArrayValue(long a0, long a1, long a2, int a3, long[] a4, long[] a5, Long a6); - public static native long getModelFuncElse(long a0, long a1, int a2); - public static native int getModelFuncNumEntries(long a0, long a1, int a2); - public static native int getModelFuncEntryNumArgs(long a0, long a1, int a2, int a3); - public static native long getModelFuncEntryArg(long a0, long a1, int a2, int a3, int a4); - public static native long getModelFuncEntryValue(long a0, long a1, int a2, int a3); - public static native boolean eval(long a0, long a1, long a2, Long a3); - public static native boolean evalDecl(long a0, long a1, long a2, int a3, long[] a4, Long a5); - public static native String contextToString(long a0); - public static native String statisticsToString(long a0); - public static native long getContextAssignment(long a0); - public static void main(String[] args) { - IntPtr major = new IntPtr(), minor = new IntPtr(), build = new IntPtr(), revision = new IntPtr(); - getVersion(major, minor, build, revision); - System.out.format("Z3 (for Java) %d.%d.%d%n", major.value, minor.value, build.value); - } -} diff --git a/src/api/java/com/Microsoft/Z3/Numeral.java b/src/api/java/com/Microsoft/Z3/Numeral.java deleted file mode 100644 index d0ed20dc9..000000000 --- a/src/api/java/com/Microsoft/Z3/Numeral.java +++ /dev/null @@ -1,264 +0,0 @@ -/** - * This file was automatically generated from Numeral.cs - **/ - -package com.Microsoft.Z3; -/* using System; */ - -/* using System.Numerics; */ - - /** - * Integer Numerals - **/ - public class IntNum extends IntExpr - { - - IntNum(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - - - /** - * Retrieve the 64-bit unsigned integer value. - **/ - public UInt64 UInt64() - { - UInt64 res = 0; - if (Native.getNumeralLong64(Context.nCtx, NativeObject, res) == 0) - throw new Z3Exception("Numeral is not a 64 bit unsigned"); - return res; - } - - /** - * Retrieve the int value. - **/ - public int Int() - { - int res = 0; - if (Native.getNumeralInt(Context.nCtx, NativeObject, res) == 0) - throw new Z3Exception("Numeral is not an int"); - return res; - } - - /** - * Retrieve the 64-bit int value. - **/ - public Int64 Int64() - { - Int64 res = 0; - if (Native.getNumeralInt64(Context.nCtx, NativeObject, res) == 0) - throw new Z3Exception("Numeral is not an int64"); - return res; - } - - /** - * Retrieve the int value. - **/ - public long UInt() - { - long res = 0; - if (Native.getNumeralLong(Context.nCtx, NativeObject, res) == 0) - throw new Z3Exception("Numeral is not a long"); - return res; - } - - /** - * Retrieve the BigInteger value. - **/ - public BigInteger BigInteger() - { - return BigInteger.Parse(this.toString()); - } - - /** - * Returns a string representation of the numeral. - **/ - public String toString() - { - return Native.getNumeralString(Context.nCtx, NativeObject); - } - } - - /** - * Rational Numerals - **/ - public class RatNum extends RealExpr - { - /** - * The numerator of a rational numeral. - **/ - public IntNum Numerator() { - - - return new IntNum(Context, Native.getNumerator(Context.nCtx, NativeObject)); } - } - - /** - * The denominator of a rational numeral. - **/ - public IntNum Denominator() { - - - return new IntNum(Context, Native.getDenominator(Context.nCtx, NativeObject)); } - } - - /** - * Converts the numerator of the rational to a BigInteger - **/ - public BigInteger BigIntNumerator() - { - IntNum n = Numerator; - return BigInteger.Parse(n.toString()); - } - - /** - * Converts the denominator of the rational to a BigInteger - **/ - public BigInteger BigIntDenominator() - { - IntNum n = Denominator; - return BigInteger.Parse(n.toString()); - } - - /** - * Returns a string representation in decimal notation. - * The result has at most decimal places. - **/ - public String ToDecimalString(long precision) - { - return Native.getNumeralDecimalString(Context.nCtx, NativeObject, precision); - } - - /** - * Returns a string representation of the numeral. - **/ - public String toString() - { - return Native.getNumeralString(Context.nCtx, NativeObject); - } - - RatNum(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - } - - - /** - * Bit-vector numerals - **/ - public class BitVecNum extends BitVecExpr - { - /** - * Retrieve the 64-bit unsigned integer value. - **/ - public UInt64 UInt64() - { - UInt64 res = 0; - if (Native.getNumeralLong64(Context.nCtx, NativeObject, res) == 0) - throw new Z3Exception("Numeral is not a 64 bit unsigned"); - return res; - } - - /** - * Retrieve the int value. - **/ - public int Int() - { - int res = 0; - if (Native.getNumeralInt(Context.nCtx, NativeObject, res) == 0) - throw new Z3Exception("Numeral is not an int"); - return res; - } - - /** - * Retrieve the 64-bit int value. - **/ - public Int64 Int64() - { - Int64 res = 0; - if (Native.getNumeralInt64(Context.nCtx, NativeObject, res) == 0) - throw new Z3Exception("Numeral is not an int64"); - return res; - } - - /** - * Retrieve the int value. - **/ - public long UInt() - { - long res = 0; - if (Native.getNumeralLong(Context.nCtx, NativeObject, res) == 0) - throw new Z3Exception("Numeral is not a long"); - return res; - } - - /** - * Retrieve the BigInteger value. - **/ - public BigInteger BigInteger() - { - return BigInteger.Parse(this.toString()); - } - - /** - * Returns a string representation of the numeral. - **/ - public String toString() - { - return Native.getNumeralString(Context.nCtx, NativeObject); - } - - BitVecNum(Context ctx, IntPtr obj) { super(ctx, obj); } - } - - /** - * Algebraic numbers - **/ - public class AlgebraicNum extends ArithExpr - { - /** - * Return a upper bound for a given real algebraic number. - * The interval isolating the number is smaller than 1/10^. - * - * the precision of the result - * @return A numeral Expr of sort Real - **/ - public RatNum ToUpper(long precision) - { - - - return new RatNum(Context, Native.getAlgebraicNumberUpper(Context.nCtx, NativeObject, precision)); - } - - /** - * Return a lower bound for the given real algebraic number. - * The interval isolating the number is smaller than 1/10^. - * - * - * @return A numeral Expr of sort Real - **/ - public RatNum ToLower(long precision) - { - - - return new RatNum(Context, Native.getAlgebraicNumberLower(Context.nCtx, NativeObject, precision)); - } - - /** - * Returns a string representation in decimal notation. - * The result has at most decimal places. - **/ - public String ToDecimal(long precision) - { - - - return Native.getNumeralDecimalString(Context.nCtx, NativeObject, precision); - } - - AlgebraicNum(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - } diff --git a/src/api/java/com/Microsoft/Z3/ParamDescrs.java b/src/api/java/com/Microsoft/Z3/ParamDescrs.java deleted file mode 100644 index abade80b2..000000000 --- a/src/api/java/com/Microsoft/Z3/ParamDescrs.java +++ /dev/null @@ -1,87 +0,0 @@ -/** - * This file was automatically generated from ParamDescrs.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * A ParamDescrs describes a set of parameters. - **/ - public class ParamDescrs extends Z3Object - { - /** - * validate a set of parameters. - **/ - public void Validate(Params p) - { - - Native.paramsValidate(Context.nCtx, p.NativeObject, NativeObject); - } - - /** - * Retrieve kind of parameter. - **/ - public Z3_param_kind GetKind(Symbol name) - { - - return (Z3_param_kind)Native.paramDescrsGetKind(Context.nCtx, NativeObject, name.NativeObject); - } - - /** - * Retrieve all names of parameters. - **/ - public Symbol[] Names() - { - long sz = Native.paramDescrsSize(Context.nCtx, NativeObject); - Symbol[] names = new Symbol[sz]; - for (long i = 0; i < sz; ++i) { - names[i] = Symbol.Create(Context, Native.paramDescrsGetName(Context.nCtx, NativeObject, i)); - } - return names; - } - - /** - * The size of the ParamDescrs. - **/ - public long Size() { return Native.paramDescrsSize(Context.nCtx, NativeObject); } - - /** - * Retrieves a string representation of the ParamDescrs. - **/ - public String toString() - { - return Native.paramDescrstoString(Context.nCtx, NativeObject); - } - - ParamDescrs(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - - class DecRefQueue extends Z3.DecRefQueue - { - public void IncRef(Context ctx, IntPtr obj) - { - Native.paramDescrsIncRef(ctx.nCtx, obj); - } - - public void DecRef(Context ctx, IntPtr obj) - { - Native.paramDescrsDecRef(ctx.nCtx, obj); - } - }; - - void IncRef(IntPtr o) - { - Context.ParamDescrs_DRQ.IncAndClear(Context, o); - super.IncRef(o); - } - - void DecRef(IntPtr o) - { - Context.ParamDescrs_DRQ.Add(o); - super.DecRef(o); - } - } diff --git a/src/api/java/com/Microsoft/Z3/Params.java b/src/api/java/com/Microsoft/Z3/Params.java deleted file mode 100644 index 040b6d67d..000000000 --- a/src/api/java/com/Microsoft/Z3/Params.java +++ /dev/null @@ -1,126 +0,0 @@ -/** - * This file was automatically generated from Params.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * A ParameterSet represents a configuration in the form of Symbol/value pairs. - **/ - public class Params extends Z3Object - { - /** - * Adds a parameter setting. - **/ - public void Add(Symbol name, boolean value) - { - - - Native.paramsSetBoolean(Context.nCtx, NativeObject, name.NativeObject, (value) ? 1 : 0); - } - - /** - * Adds a parameter setting. - **/ - public void Add(Symbol name, long value) - { - - - Native.paramsSetLong(Context.nCtx, NativeObject, name.NativeObject, value); - } - - /** - * Adds a parameter setting. - **/ - public void Add(Symbol name, double value) - { - - - Native.paramsSetDouble(Context.nCtx, NativeObject, name.NativeObject, value); - } - - /** - * Adds a parameter setting. - **/ - public void Add(Symbol name, Symbol value) - { - - - - Native.paramsSetSymbol(Context.nCtx, NativeObject, name.NativeObject, value.NativeObject); - } - - /** - * Adds a parameter setting. - **/ - public void Add(String name, boolean value) - { - Native.paramsSetBoolean(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, (value) ? 1 : 0); - } - - /** - * Adds a parameter setting. - **/ - public void Add(String name, long value) - { - Native.paramsSetLong(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, value); - } - - /** - * Adds a parameter setting. - **/ - public void Add(String name, double value) - { - Native.paramsSetDouble(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, value); - } - - /** - * Adds a parameter setting. - **/ - public void Add(String name, Symbol value) - { - - - Native.paramsSetSymbol(Context.nCtx, NativeObject, Context.MkSymbol(name).NativeObject, value.NativeObject); - } - - /** - * A string representation of the parameter set. - **/ - public String toString() - { - return Native.paramstoString(Context.nCtx, NativeObject); - } - - Params(Context ctx) - { super(ctx, Native.mkParams(ctx.nCtx)); - - } - - class DecRefQueue extends Z3.DecRefQueue - { - public void IncRef(Context ctx, IntPtr obj) - { - Native.paramsIncRef(ctx.nCtx, obj); - } - - public void DecRef(Context ctx, IntPtr obj) - { - Native.paramsDecRef(ctx.nCtx, obj); - } - }; - - void IncRef(IntPtr o) - { - Context.Params_DRQ.IncAndClear(Context, o); - super.IncRef(o); - } - - void DecRef(IntPtr o) - { - Context.Params_DRQ.Add(o); - super.DecRef(o); - } - } diff --git a/src/api/java/com/Microsoft/Z3/Pattern.java b/src/api/java/com/Microsoft/Z3/Pattern.java deleted file mode 100644 index edc772dcf..000000000 --- a/src/api/java/com/Microsoft/Z3/Pattern.java +++ /dev/null @@ -1,48 +0,0 @@ -/** - * This file was automatically generated from Pattern.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ -/* using System.Runtime.InteropServices; */ - - /** - * Patterns comprise a list of terms. The list should be - * non-empty. If the list comprises of more than one term, it is - * also called a multi-pattern. - **/ - public class Pattern extends AST - { - /** - * The number of terms in the pattern. - **/ - public long NumTerms() { return Native.getPatternNumTerms(Context.nCtx, NativeObject); } - - /** - * The terms in the pattern. - **/ - public Expr[] Terms() - { - - - long n = NumTerms; - Expr[] res = new Expr[n]; - for (long i = 0; i < n; i++) - res[i] = Expr.Create(Context, Native.getPattern(Context.nCtx, NativeObject, i)); - return res; - } - - /** - * A string representation of the pattern. - **/ - public String toString() - { - return Native.patterntoString(Context.nCtx, NativeObject); - } - - Pattern(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - } diff --git a/src/api/java/com/Microsoft/Z3/Probe.java b/src/api/java/com/Microsoft/Z3/Probe.java deleted file mode 100644 index 36f949966..000000000 --- a/src/api/java/com/Microsoft/Z3/Probe.java +++ /dev/null @@ -1,72 +0,0 @@ -/** - * This file was automatically generated from Probe.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ -/* using System.Runtime.InteropServices; */ - - /** - * Probes are used to inspect a goal (aka problem) and collect information that may be used to decide - * which solver and/or preprocessing step will be used. - * The complete list of probes may be obtained using the procedures Context.NumProbes - * and Context.ProbeNames. - * It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. - **/ - public class Probe extends Z3Object - { - /** - * Execute the probe over the goal. - * @return A probe always produce a double value. - * "Boolean" probes return 0.0 for false, and a value different from 0.0 for true. - **/ - public double Apply(Goal g) - { - - - Context.CheckContextMatch(g); - return Native.probeApply(Context.nCtx, NativeObject, g.NativeObject); - } - - /** - * Apply the probe to a goal. - **/ - public double this[Goal() - - - return Apply(g); } } - - Probe(Context ctx, IntPtr obj) - { super(ctx, obj); - - Probe(Context ctx, String name) - { super(ctx, Native.mkProbe(ctx.nCtx, name)); - - } - - class DecRefQueue extends Z3.DecRefQueue - { - public void IncRef(Context ctx, IntPtr obj) - { - Native.probeIncRef(ctx.nCtx, obj); - } - - public void DecRef(Context ctx, IntPtr obj) - { - Native.probeDecRef(ctx.nCtx, obj); - } - }; - - void IncRef(IntPtr o) - { - Context.Probe_DRQ.IncAndClear(Context, o); - super.IncRef(o); - } - - void DecRef(IntPtr o) - { - Context.Probe_DRQ.Add(o); - super.DecRef(o); - } - } diff --git a/src/api/java/com/Microsoft/Z3/Quantifier.java b/src/api/java/com/Microsoft/Z3/Quantifier.java deleted file mode 100644 index 6c7c91be7..000000000 --- a/src/api/java/com/Microsoft/Z3/Quantifier.java +++ /dev/null @@ -1,198 +0,0 @@ -/** - * This file was automatically generated from Quantifier.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * Quantifier expressions. - **/ - public class Quantifier extends BoolExpr - { - /** - * Indicates whether the quantifier is universal. - **/ - public boolean IsUniversal() { return Native.isQuantifierForall(Context.nCtx, NativeObject) != 0; } - - /** - * Indicates whether the quantifier is existential. - **/ - public boolean IsExistential() { return !IsUniversal; } - - /** - * The weight of the quantifier. - **/ - public long Weight() { return Native.getQuantifierWeight(Context.nCtx, NativeObject); } - - /** - * The number of patterns. - **/ - public long NumPatterns() { return Native.getQuantifierNumPatterns(Context.nCtx, NativeObject); } - - /** - * The patterns. - **/ - public Pattern[] Patterns() - { - - - long n = NumPatterns; - Pattern[] res = new Pattern[n]; - for (long i = 0; i < n; i++) - res[i] = new Pattern(Context, Native.getQuantifierPatternAst(Context.nCtx, NativeObject, i)); - return res; - } - - /** - * The number of no-patterns. - **/ - public long NumNoPatterns() { return Native.getQuantifierNumNoPatterns(Context.nCtx, NativeObject); } - - /** - * The no-patterns. - **/ - public Pattern[] NoPatterns() - { - - - long n = NumNoPatterns; - Pattern[] res = new Pattern[n]; - for (long i = 0; i < n; i++) - res[i] = new Pattern(Context, Native.getQuantifierNoPatternAst(Context.nCtx, NativeObject, i)); - return res; - } - - /** - * The number of bound variables. - **/ - public long NumBound() { return Native.getQuantifierNumBound(Context.nCtx, NativeObject); } - - /** - * The symbols for the bound variables. - **/ - public Symbol[] BoundVariableNames() - { - - - long n = NumBound; - Symbol[] res = new Symbol[n]; - for (long i = 0; i < n; i++) - res[i] = Symbol.Create(Context, Native.getQuantifierBoundName(Context.nCtx, NativeObject, i)); - return res; - } - - /** - * The sorts of the bound variables. - **/ - public Sort[] BoundVariableSorts() - { - - - long n = NumBound; - Sort[] res = new Sort[n]; - for (long i = 0; i < n; i++) - res[i] = Sort.Create(Context, Native.getQuantifierBoundSort(Context.nCtx, NativeObject, i)); - return res; - } - - /** - * The body of the quantifier. - **/ - public BoolExpr Body() { - - - return new BoolExpr(Context, Native.getQuantifierBody(Context.nCtx, NativeObject)); } - } - - Quantifier(Context ctx, boolean isForall, Sort[] sorts, Symbol[] names, Expr body, - long weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, - Symbol quantifierID = null, Symbol skolemID = null - ) - { super(ctx); - - - - - - - - - - - Context.CheckContextMatch(patterns); - Context.CheckContextMatch(noPatterns); - Context.CheckContextMatch(sorts); - Context.CheckContextMatch(names); - Context.CheckContextMatch(body); - - if (sorts.Length != names.Length) - throw new Z3Exception("Number of sorts does not match number of names"); - - IntPtr[] _patterns = AST.ArrayToNative(patterns); - - if (noPatterns == null && quantifierID == null && skolemID == null) - { - NativeObject = Native.mkQuantifier(ctx.nCtx, (isForall) ? 1 : 0, weight, - AST.ArrayLength(patterns), AST.ArrayToNative(patterns), - AST.ArrayLength(sorts), AST.ArrayToNative(sorts), - Symbol.ArrayToNative(names), - body.NativeObject); - else - { - NativeObject = Native.mkQuantifierEx(ctx.nCtx, (isForall) ? 1 : 0, weight, - AST.GetNativeObject(quantifierID), AST.GetNativeObject(skolemID), - AST.ArrayLength(patterns), AST.ArrayToNative(patterns), - AST.ArrayLength(noPatterns), AST.ArrayToNative(noPatterns), - AST.ArrayLength(sorts), AST.ArrayToNative(sorts), - Symbol.ArrayToNative(names), - body.NativeObject); - } - } - - Quantifier(Context ctx, boolean isForall, Expr[] bound, Expr body, - long weight = 1, Pattern[] patterns = null, Expr[] noPatterns = null, - Symbol quantifierID = null, Symbol skolemID = null - ) - { super(ctx); - - - - - - - - Context.CheckContextMatch(noPatterns); - Context.CheckContextMatch(patterns); - //Context.CheckContextMatch(bound); - Context.CheckContextMatch(body); - - if (noPatterns == null && quantifierID == null && skolemID == null) - { - NativeObject = Native.mkQuantifierConst(ctx.nCtx, (isForall) ? 1 : 0, weight, - AST.ArrayLength(bound), AST.ArrayToNative(bound), - AST.ArrayLength(patterns), AST.ArrayToNative(patterns), - body.NativeObject); - } - else - { - NativeObject = Native.mkQuantifierConstEx(ctx.nCtx, (isForall) ? 1 : 0, weight, - AST.GetNativeObject(quantifierID), AST.GetNativeObject(skolemID), - AST.ArrayLength(bound), AST.ArrayToNative(bound), - AST.ArrayLength(patterns), AST.ArrayToNative(patterns), - AST.ArrayLength(noPatterns), AST.ArrayToNative(noPatterns), - body.NativeObject); - } - } - - - Quantifier(Context ctx, IntPtr obj) { super(ctx, obj); } - - void CheckNativeObject(IntPtr obj) - { - if ((Z3_ast_kind)Native.getAstKind(Context.nCtx, obj) != Z3_ast_kind.Z3_QUANTIFIER_AST) - throw new Z3Exception("Underlying object is not a quantifier"); - super.CheckNativeObject(obj); - } - } diff --git a/src/api/java/com/Microsoft/Z3/Solver.java b/src/api/java/com/Microsoft/Z3/Solver.java deleted file mode 100644 index 787e115ab..000000000 --- a/src/api/java/com/Microsoft/Z3/Solver.java +++ /dev/null @@ -1,247 +0,0 @@ -/** - * This file was automatically generated from Solver.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * Solvers. - **/ - public class Solver extends Z3Object - { - /** - * A string that describes all available solver parameters. - **/ - public String Help() - { - - - return Native.solverGetHelp(Context.nCtx, NativeObject); - } - - /** - * Sets the solver parameters. - **/ - public void setParameters(Params value) - { - - - Context.CheckContextMatch(value); - Native.solverSetParams(Context.nCtx, NativeObject, value.NativeObject); - } - - /** - * Retrieves parameter descriptions for solver. - **/ - public ParamDescrs ParameterDescriptions() { return new ParamDescrs(Context, Native.solverGetParamDescrs(Context.nCtx, NativeObject)); } - - - /** - * The current number of backtracking points (scopes). - * - * - **/ - public long NumScopes() { return Native.solverGetNumScopes(Context.nCtx, NativeObject); } - - /** - * Creates a backtracking point. - * - **/ - public void Push() - { - Native.solverPush(Context.nCtx, NativeObject); - } - - /** - * Backtracks backtracking points. - * Note that an exception is thrown if is not smaller than NumScopes - * - **/ - public void Pop(long n) - { - Native.solverPop(Context.nCtx, NativeObject, n); - } - - /** - * Resets the Solver. - * This removes all assertions from the solver. - **/ - public void Reset() - { - Native.solverReset(Context.nCtx, NativeObject); - } - - /** - * Assert a constraint (or multiple) into the solver. - **/ - public void Assert(BoolExpr[] constraints) - { - - - - Context.CheckContextMatch(constraints); - for (BoolExpr.Iterator a = constraints.iterator(); a.hasNext(); ) - { - Native.solverAssert(Context.nCtx, NativeObject, a.NativeObject); - } - } - - /** - * The number of assertions in the solver. - **/ - public long NumAssertions() - { - ASTVector ass = new ASTVector(Context, Native.solverGetAssertions(Context.nCtx, NativeObject)); - return ass.Size; - } - - /** - * The set of asserted formulas. - **/ - public BoolExpr[] Assertions() - { - - - ASTVector ass = new ASTVector(Context, Native.solverGetAssertions(Context.nCtx, NativeObject)); - long n = ass.Size; - BoolExpr[] res = new BoolExpr[n]; - for (long i = 0; i < n; i++) - res[i] = new BoolExpr(Context, ass[i].NativeObject); - return res; - } - - /** - * Checks whether the assertions in the solver are consistent or not. - * - * - * - * - * - **/ - public Status Check(Expr[] assumptions) - { - Z3_lboolean r; - if (assumptions == null) - r = (Z3_lboolean)Native.solverCheck(Context.nCtx, NativeObject); - else - r = (Z3_lboolean)Native.solverCheckAssumptions(Context.nCtx, NativeObject, (long)assumptions.Length, AST.ArrayToNative(assumptions)); - switch (r) - { - case Z3_lboolean.Z3_L_TRUE: return Status.SATISFIABLE; - case Z3_lboolean.Z3_L_FALSE: return Status.UNSATISFIABLE; - default: return Status.UNKNOWN; - } - } - - /** - * The model of the last Check. - * - * The result is null if Check was not invoked before, - * if its results was not SATISFIABLE, or if model production is not enabled. - * - **/ - public Model Model() - { - IntPtr x = Native.solverGetModel(Context.nCtx, NativeObject); - if (x == IntPtr.Zero) - return null; - else - return new Model(Context, x); - } - - /** - * The proof of the last Check. - * - * The result is null if Check was not invoked before, - * if its results was not UNSATISFIABLE, or if proof production is disabled. - * - **/ - public Expr Proof() - { - IntPtr x = Native.solverGetProof(Context.nCtx, NativeObject); - if (x == IntPtr.Zero) - return null; - else - return Expr.Create(Context, x); - } - - /** - * The unsat core of the last Check. - * - * The unsat core is a subset of Assertions - * The result is empty if Check was not invoked before, - * if its results was not UNSATISFIABLE, or if core production is disabled. - * - **/ - public Expr[] UnsatCore() - { - - - ASTVector core = new ASTVector(Context, Native.solverGetUnsatCore(Context.nCtx, NativeObject)); - long n = core.Size; - Expr[] res = new Expr[n]; - for (long i = 0; i < n; i++) - res[i] = Expr.Create(Context, core[i].NativeObject); - return res; - } - - /** - * A brief justification of why the last call to Check returned UNKNOWN. - **/ - public String ReasonUnknown() - { - - - return Native.solverGetReasonUnknown(Context.nCtx, NativeObject); - } - - /** - * Solver statistics. - **/ - public Statistics Statistics() - { - - - return new Statistics(Context, Native.solverGetStatistics(Context.nCtx, NativeObject)); - } - - /** - * A string representation of the solver. - **/ - public String toString() - { - return Native.solvertoString(Context.nCtx, NativeObject); - } - - Solver(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - - class DecRefQueue extends Z3.DecRefQueue - { - public void IncRef(Context ctx, IntPtr obj) - { - Native.solverIncRef(ctx.nCtx, obj); - } - - public void DecRef(Context ctx, IntPtr obj) - { - Native.solverDecRef(ctx.nCtx, obj); - } - }; - - void IncRef(IntPtr o) - { - Context.Solver_DRQ.IncAndClear(Context, o); - super.IncRef(o); - } - - void DecRef(IntPtr o) - { - Context.Solver_DRQ.Add(o); - super.DecRef(o); - } - } diff --git a/src/api/java/com/Microsoft/Z3/Sort.java b/src/api/java/com/Microsoft/Z3/Sort.java deleted file mode 100644 index 8e4735389..000000000 --- a/src/api/java/com/Microsoft/Z3/Sort.java +++ /dev/null @@ -1,583 +0,0 @@ -/** - * This file was automatically generated from Sort.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * The Sort class implements type information for ASTs. - **/ - public class Sort extends AST - { - /** - * Comparison operator. - * A Sort - * A Sort - * @return True if and are from the same context - * and represent the same sort; false otherwise. - **/ - /* Overloaded operators are not translated. */ - - /** - * Comparison operator. - * A Sort - * A Sort - * @return True if and are not from the same context - * or represent different sorts; false otherwise. - **/ - /* Overloaded operators are not translated. */ - - /** - * Equality operator for objects of type Sort. - * - * @return - **/ - public boolean Equals(object o) - { - Sort casted = o as Sort; - if (casted == null) return false; - return this == casted; - } - - /** - * Hash code generation for Sorts - * @return A hash code - **/ - public int GetHashCode() - { - return super.GetHashCode(); - } - - /** - * Returns a unique identifier for the sort. - **/ - public long Id() { return Native.getSortId(Context.nCtx, NativeObject); } - - /** - * The kind of the sort. - **/ - public Z3_sort_kind SortKind() { return (Z3_sort_kind)Native.getSortKind(Context.nCtx, NativeObject); } - - /** - * The name of the sort - **/ - public Symbol Name() { - - return Symbol.Create(Context, Native.getSortName(Context.nCtx, NativeObject)); } - } - - /** - * A string representation of the sort. - **/ - public String toString() - { - return Native.sorttoString(Context.nCtx, NativeObject); - - /** - * Sort constructor - **/ - protected Sort(Context ctx) { super(ctx); } - Sort(Context ctx, IntPtr obj) { super(ctx, obj); } - - void CheckNativeObject(IntPtr obj) - { - if (Native.getAstKind(Context.nCtx, obj) != (long)Z3_ast_kind.Z3_SORT_AST) - throw new Z3Exception("Underlying object is not a sort"); - super.CheckNativeObject(obj); - } - - static Sort Create(Context ctx, IntPtr obj) - { - - - - switch ((Z3_sort_kind)Native.getSortKind(ctx.nCtx, obj)) - { - case Z3_sort_kind.Z3_ARRAY_SORT: return new ArraySort(ctx, obj); - case Z3_sort_kind.Z3_BOOL_SORT: return new BoolSort(ctx, obj); - case Z3_sort_kind.Z3_BV_SORT: return new BitVecSort(ctx, obj); - case Z3_sort_kind.Z3_DATATYPE_SORT: return new DatatypeSort(ctx, obj); - case Z3_sort_kind.Z3_INT_SORT: return new IntSort(ctx, obj); - case Z3_sort_kind.Z3_REAL_SORT: return new RealSort(ctx, obj); - case Z3_sort_kind.Z3_UNINTERPRETED_SORT: return new UninterpretedSort(ctx, obj); - case Z3_sort_kind.Z3_FINITE_DOMAIN_SORT: return new FiniteDomainSort(ctx, obj); - case Z3_sort_kind.Z3_RELATION_SORT: return new RelationSort(ctx, obj); - default: - throw new Z3Exception("Unknown sort kind"); - } - } - } - - /** - * A Boolean sort. - **/ - public class BoolSort extends Sort - { - BoolSort(Context ctx, IntPtr obj) { super(ctx, obj); } - BoolSort(Context ctx) { super(ctx, Native.mkBooleanSort(ctx.nCtx)); } - }; - - /** - * An arithmetic sort, i.e., Int or Real. - **/ - public class ArithSort extends Sort - { - ArithSort(Context ctx, IntPtr obj) { super(ctx, obj); } - }; - - /** - * An Integer sort - **/ - public class IntSort extends ArithSort - { - IntSort(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - IntSort(Context ctx) - { super(ctx, Native.mkIntSort(ctx.nCtx)); - - } - } - - /** - * A real sort - **/ - public class RealSort extends ArithSort - { - RealSort(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - RealSort(Context ctx) - { super(ctx, Native.mkRealSort(ctx.nCtx)); - - } - } - - /** - * Bit-vector sorts. - **/ - public class BitVecSort extends Sort - { - /** - * The size of the bit-vector sort. - **/ - public long Size() { return Native.getBvSortSize(Context.nCtx, NativeObject); } - - BitVecSort(Context ctx, IntPtr obj) { super(ctx, obj); } - BitVecSort(Context ctx, long size) { super(ctx, Native.mkBvSort(ctx.nCtx, size)); } - }; - - /** - * Array sorts. - **/ - public class ArraySort extends Sort - { - /** - * The domain of the array sort. - **/ - public Sort Domain() { - - - return Sort.Create(Context, Native.getArraySortDomain(Context.nCtx, NativeObject)); } - } - - /** - * The range of the array sort. - **/ - public Sort Range() { - - - return Sort.Create(Context, Native.getArraySortRange(Context.nCtx, NativeObject)); } - } - - ArraySort(Context ctx, IntPtr obj) { super(ctx, obj); } - ArraySort(Context ctx, Sort domain, Sort range) - { super(ctx, Native.mkArraySort(ctx.nCtx, domain.NativeObject, range.NativeObject)); - - - - }; - - /** - * Datatype sorts. - **/ - public class DatatypeSort extends Sort - { - /** - * The number of constructors of the datatype sort. - **/ - public long NumConstructors() { return Native.getDatatypeSortNumConstructors(Context.nCtx, NativeObject); } - - /** - * The constructors. - **/ - public FuncDecl[] Constructors() - { - - - long n = NumConstructors; - FuncDecl[] res = new FuncDecl[n]; - for (long i = 0; i < n; i++) - res[i] = new FuncDecl(Context, Native.getDatatypeSortConstructor(Context.nCtx, NativeObject, i)); - return res; - } - - /** - * The recognizers. - **/ - public FuncDecl[] Recognizers() - { - - - long n = NumConstructors; - FuncDecl[] res = new FuncDecl[n]; - for (long i = 0; i < n; i++) - res[i] = new FuncDecl(Context, Native.getDatatypeSortRecognizer(Context.nCtx, NativeObject, i)); - return res; - } - - /** - * The constructor accessors. - **/ - public FuncDecl[][] Accessors() - { - - - long n = NumConstructors; - FuncDecl[][] res = new FuncDecl[n][]; - for (long i = 0; i < n; i++) - { - FuncDecl fd = new FuncDecl(Context, Native.getDatatypeSortConstructor(Context.nCtx, NativeObject, i)); - long ds = fd.DomainSize; - FuncDecl[] tmp = new FuncDecl[ds]; - for (long j = 0; j < ds; j++) - tmp[j] = new FuncDecl(Context, Native.getDatatypeSortConstructorAccessor(Context.nCtx, NativeObject, i, j)); - res[i] = tmp; - } - return res; - } - - DatatypeSort(Context ctx, IntPtr obj) { super(ctx, obj); } - - DatatypeSort(Context ctx, Symbol name, Constructor[] constructors) - { super(ctx, Native.mkDatatype(ctx.nCtx, name.NativeObject, (long)constructors.Length, ArrayToNative(constructors))); - - - - } - }; - - /** - * Uninterpreted Sorts - **/ - public class UninterpretedSort extends Sort - { - UninterpretedSort(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - UninterpretedSort(Context ctx, Symbol s) - { super(ctx, Native.mkUninterpretedSort(ctx.nCtx, s.NativeObject)); - - - } - } - - /** - * Tuple sorts. - **/ - public class TupleSort extends Sort - { - /** - * The constructor function of the tuple. - **/ - public FuncDecl MkDecl() { - - - return new FuncDecl(Context, Native.getTupleSortMkDecl(Context.nCtx, NativeObject)); } - } - - /** - * The number of fields in the tuple. - **/ - public long NumFields() { return Native.getTupleSortNumFields(Context.nCtx, NativeObject); } - - /** - * The field declarations. - **/ - public FuncDecl[] FieldDecls() - { - - - long n = NumFields; - FuncDecl[] res = new FuncDecl[n]; - for (long i = 0; i < n; i++) - res[i] = new FuncDecl(Context, Native.getTupleSortFieldDecl(Context.nCtx, NativeObject, i)); - return res; - } - - TupleSort(Context ctx, Symbol name, long numFields, Symbol[] fieldNames, Sort[] fieldSorts) - { super(ctx); - - - - IntPtr t = IntPtr.Zero; - NativeObject = Native.mkTupleSort(ctx.nCtx, name.NativeObject, numFields, - Symbol.ArrayToNative(fieldNames), AST.ArrayToNative(fieldSorts), - t, new IntPtr[numFields]); - } - }; - - /** - * Enumeration sorts. - **/ - public class EnumSort extends Sort - { - /** - * The function declarations of the constants in the enumeration. - **/ - public FuncDecl[] ConstDecls() { - - - return _constdecls; } - } - - /** - * The constants in the enumeration. - **/ - public Expr[] Consts() { - - - return _consts; } - } - - /** - * The test predicates for the constants in the enumeration. - **/ - public FuncDecl[] TesterDecls() { - - - return _testerdecls; - } - - - private void ObjectInvariant() - { - - - - } - - - - private FuncDecl[] _constdecls = null, _testerdecls = null; - private Expr[] _consts = null; - - EnumSort(Context ctx, Symbol name, Symbol[] enumNames) - { super(ctx); - - - - - int n = enumNames.Length; - IntPtr[] n_constdecls = new IntPtr[n]; - IntPtr[] n_testers = new IntPtr[n]; - NativeObject = Native.mkEnumerationSort(ctx.nCtx, name.NativeObject, (long)n, - Symbol.ArrayToNative(enumNames), n_constdecls, n_testers); - _constdecls = new FuncDecl[n]; - for (long i = 0; i < n; i++) - _constdecls[i] = new FuncDecl(ctx, n_constdecls[i]); - _testerdecls = new FuncDecl[n]; - for (long i = 0; i < n; i++) - _testerdecls[i] = new FuncDecl(ctx, n_testers[i]); - _consts = new Expr[n]; - for (long i = 0; i < n; i++) - _consts[i] = ctx.MkApp(_constdecls[i]); - } - }; - - /** - * List sorts. - **/ - public class ListSort extends Sort - { - /** - * The declaration of the nil function of this list sort. - **/ - public FuncDecl NilDecl() - - return nilDecl; } } - - /** - * The empty list. - **/ - public Expr Nil() - { - - return nilConst; - } - - /** - * The declaration of the isNil function of this list sort. - **/ - public FuncDecl IsNilDecl() - { - - return isNilDecl; - } - - /** - * The declaration of the cons function of this list sort. - **/ - public FuncDecl ConsDecl() - { - - return consDecl; - } - - /** - * The declaration of the isCons function of this list sort. - * - **/ - public FuncDecl IsConsDecl() - { - - return isConsDecl; - } - - /** - * The declaration of the head function of this list sort. - **/ - public FuncDecl HeadDecl() - { - - return headDecl; - } - - /** - * The declaration of the tail function of this list sort. - **/ - public FuncDecl TailDecl() - { - - return tailDecl; - } - - - private void ObjectInvariant() - { - - - - - - - - } - - - - private FuncDecl nilDecl, isNilDecl, consDecl, isConsDecl, headDecl, tailDecl; - private Expr nilConst; - - ListSort(Context ctx, Symbol name, Sort elemSort) - { super(ctx); - - - - - IntPtr inil = IntPtr.Zero, - iisnil = IntPtr.Zero, - icons = IntPtr.Zero, - iiscons = IntPtr.Zero, - ihead = IntPtr.Zero, - itail = IntPtr.Zero; - - NativeObject = Native.mkListSort(ctx.nCtx, name.NativeObject, elemSort.NativeObject, - inil, iisnil, icons, iiscons, ihead, itail); - nilDecl = new FuncDecl(ctx, inil); - isNilDecl = new FuncDecl(ctx, iisnil); - consDecl = new FuncDecl(ctx, icons); - isConsDecl = new FuncDecl(ctx, iiscons); - headDecl = new FuncDecl(ctx, ihead); - tailDecl = new FuncDecl(ctx, itail); - nilConst = ctx.MkConst(nilDecl); - } - }; - - /** - * Relation sorts. - **/ - public class RelationSort extends Sort - { - /** - * The arity of the relation sort. - **/ - public long Arity() { return Native.getRelationArity(Context.nCtx, NativeObject); } - - /** - * The sorts of the columns of the relation sort. - **/ - public Sort[] ColumnSorts() - { - - - if (m_columnSorts != null) - return m_columnSorts; - - long n = Arity; - Sort[] res = new Sort[n]; - for (long i = 0; i < n; i++) - res[i] = Sort.Create(Context, Native.getRelationColumn(Context.nCtx, NativeObject, i)); - return res; - } - - private Sort[] m_columnSorts = null; - - RelationSort(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - } - - /** - * Finite domain sorts. - **/ - public class FiniteDomainSort extends Sort - { - /** - * The size of the finite domain sort. - **/ - public ulong Size() { ulong res = 0; Native.getFiniteDomainSortSize(Context.nCtx, NativeObject, ref res); return res; } - - FiniteDomainSort(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - FiniteDomainSort(Context ctx, Symbol name, ulong size) - { super(ctx, Native.mkFiniteDomainSort(ctx.nCtx, name.NativeObject, size)); - - - - } - } - - /** - * Set sorts. - **/ - public class SetSort extends Sort - { - SetSort(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - SetSort(Context ctx, Sort ty) - { super(ctx, Native.mkSetSort(ctx.nCtx, ty.NativeObject)); - - - } - } diff --git a/src/api/java/com/Microsoft/Z3/Statistics.java b/src/api/java/com/Microsoft/Z3/Statistics.java deleted file mode 100644 index d9aac9d67..000000000 --- a/src/api/java/com/Microsoft/Z3/Statistics.java +++ /dev/null @@ -1,167 +0,0 @@ -/** - * This file was automatically generated from Statistics.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * Objects of this class track statistical information about solvers. - **/ - public class Statistics extends Z3Object - { - /** - * Statistical data is organized into pairs of [Key, Entry], where every - * Entry is either a DoubleEntry or a UIntEntry - **/ - public class Entry - { - /** - * The key of the entry. - **/ - /** - * The uint-value of the entry. - **/ - public long UIntValue() { return m_long; } - /** - * The double-value of the entry. - **/ - public double DoubleValue() { return m_double; } - /** - * True if the entry is uint-valued. - **/ - public boolean IsUInt() { return m_is_long; } - /** - * True if the entry is double-valued. - **/ - public boolean IsDouble() { return m_is_double; } - - /** - * The string representation of the the entry's value. - **/ - public String Value() - { - - - if (IsUInt) - return m_long.toString(); - else if (IsDouble) - return m_double.toString(); - else - throw new Z3Exception("Unknown statistical entry type"); - } - - /** - * The string representation of the Entry. - **/ - public String toString() - { - return Key + ": " + Value; - } - - private boolean m_is_long = false; - private boolean m_is_double = false; - private long m_long = 0; - private double m_double = 0.0; - Entry(String k, long v) { Key = k; m_is_long = true; m_long = v; } - Entry(String k, double v) { Key = k; m_is_double = true; m_double = v; } - } - - /** - * A string representation of the statistical data. - **/ - public String toString() - { - return Native.statstoString(Context.nCtx, NativeObject); - } - - /** - * The number of statistical data. - **/ - public long Size() { return Native.statsSize(Context.nCtx, NativeObject); } - - /** - * The data entries. - **/ - public Entry[] Entries() - { - - - - - long n = Size; - Entry[] res = new Entry[n]; - for (long i = 0; i < n; i++) - { - Entry e; - String k = Native.statsGetKey(Context.nCtx, NativeObject, i); - if (Native.statsIsLong(Context.nCtx, NativeObject, i) != 0) - e = new Entry(k, Native.statsGetLongValue(Context.nCtx, NativeObject, i)); - else if (Native.statsIsDouble(Context.nCtx, NativeObject, i) != 0) - e = new Entry(k, Native.statsGetDoubleValue(Context.nCtx, NativeObject, i)); - else - throw new Z3Exception("Unknown data entry value"); - res[i] = e; - } - return res; - } - - /** - * The statistical counters. - **/ - public String[] Keys() - { - - - long n = Size; - String[] res = new String[n]; - for (long i = 0; i < n; i++) - res[i] = Native.statsGetKey(Context.nCtx, NativeObject, i); - return res; - } - - /** - * The value of a particular statistical counter. - * Returns null if the key is unknown. - **/ - public Entry get(String key) - { - long n = Size; - Entry[] es = Entries; - for (long i = 0; i < n; i++) - if (es[i].Key == key) - return es[i]; - return null; - } - - Statistics(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - - class DecRefQueue extends Z3.DecRefQueue - { - public void IncRef(Context ctx, IntPtr obj) - { - Native.statsIncRef(ctx.nCtx, obj); - } - - public void DecRef(Context ctx, IntPtr obj) - { - Native.statsDecRef(ctx.nCtx, obj); - } - }; - - void IncRef(IntPtr o) - { - Context.Statistics_DRQ.IncAndClear(Context, o); - super.IncRef(o); - } - - void DecRef(IntPtr o) - { - Context.Statistics_DRQ.Add(o); - super.DecRef(o); - } - } diff --git a/src/api/java/com/Microsoft/Z3/Status.java b/src/api/java/com/Microsoft/Z3/Status.java deleted file mode 100644 index 86c902285..000000000 --- a/src/api/java/com/Microsoft/Z3/Status.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * This file was automatically generated from Status.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * Status values. - **/ - /** - * Used to signify an unsatisfiable status. - **/ - UNSATISFIABLE = -1, - - /** - * Used to signify an unknown status. - **/ - UNKNOWN = 0, - - /** - * Used to signify a satisfiable status. - **/ - SATISFIABLE = 1 - diff --git a/src/api/java/com/Microsoft/Z3/Symbol.java b/src/api/java/com/Microsoft/Z3/Symbol.java deleted file mode 100644 index 972999e66..000000000 --- a/src/api/java/com/Microsoft/Z3/Symbol.java +++ /dev/null @@ -1,140 +0,0 @@ -/** - * This file was automatically generated from Symbol.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ -/* using System.Runtime.InteropServices; */ - - /** - * Symbols are used to name several term and type constructors. - **/ - public class Symbol extends Z3Object - { - /** - * The kind of the symbol (int or string) - **/ - protected Z3_symbol_kind Kind - { - get { return (Z3_symbol_kind)Native.getSymbolKind(Context.nCtx, NativeObject); } - } - - /** - * Indicates whether the symbol is of Int kind - **/ - public boolean IsIntSymbol() - { - return Kind == Z3_symbol_kind.Z3_INT_SYMBOL; - } - - /** - * Indicates whether the symbol is of string kind. - **/ - public boolean IsStringSymbol() - { - return Kind == Z3_symbol_kind.Z3_STRING_SYMBOL; - } - - /** - * A string representation of the symbol. - **/ - public String toString() - { - if (IsIntSymbol()) - return ((IntSymbol)this).Int.toString(); - else if (IsStringSymbol()) - return ((StringSymbol)this).String; - else - throw new Z3Exception("Unknown symbol kind encountered"); - } - - /** - * Symbol constructor - **/ - protected Symbol(Context ctx, IntPtr obj) { super(ctx, obj); - - } - - static Symbol Create(Context ctx, IntPtr obj) - { - - - - switch ((Z3_symbol_kind)Native.getSymbolKind(ctx.nCtx, obj)) - { - case Z3_symbol_kind.Z3_INT_SYMBOL: return new IntSymbol(ctx, obj); - case Z3_symbol_kind.Z3_STRING_SYMBOL: return new StringSymbol(ctx, obj); - default: - throw new Z3Exception("Unknown symbol kind encountered"); - } - } - } - - /** - * Numbered symbols - **/ - public class IntSymbol extends Symbol - { - /** - * The int value of the symbol. - * Throws an exception if the symbol is not of int kind. - **/ - public int Int() - { - if (!IsIntSymbol()) - throw new Z3Exception("Int requested from non-Int symbol"); - return Native.getSymbolInt(Context.nCtx, NativeObject); - } - - IntSymbol(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - IntSymbol(Context ctx, int i) - { super(ctx, Native.mkIntSymbol(ctx.nCtx, i)); - - } - - void CheckNativeObject(IntPtr obj) - { - if ((Z3_symbol_kind)Native.getSymbolKind(Context.nCtx, obj) != Z3_symbol_kind.Z3_INT_SYMBOL) - throw new Z3Exception("Symbol is not of integer kind"); - super.CheckNativeObject(obj); - } - } - - /** - * Named symbols - **/ - public class StringSymbol extends Symbol - { - /** - * The string value of the symbol. - * Throws an exception if the symbol is not of string kind. - **/ - public String String() - { - - - if (!IsStringSymbol()) - throw new Z3Exception("String requested from non-String symbol"); - return Native.getSymbolString(Context.nCtx, NativeObject); - } - - StringSymbol(Context ctx, IntPtr obj) { super(ctx, obj); - - } - - StringSymbol(Context ctx, String s) { super(ctx, Native.mkStringSymbol(ctx.nCtx, s)); - - } - - void CheckNativeObject(IntPtr obj) - { - if ((Z3_symbol_kind)Native.getSymbolKind(Context.nCtx, obj) != Z3_symbol_kind.Z3_STRING_SYMBOL) - throw new Z3Exception("Symbol is not of String kind"); - - super.CheckNativeObject(obj); - } - } diff --git a/src/api/java/com/Microsoft/Z3/Tactic.java b/src/api/java/com/Microsoft/Z3/Tactic.java deleted file mode 100644 index ae74c3a6b..000000000 --- a/src/api/java/com/Microsoft/Z3/Tactic.java +++ /dev/null @@ -1,107 +0,0 @@ -/** - * This file was automatically generated from Tactic.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * Tactics are the basic building block for creating custom solvers for specific problem domains. - * The complete list of tactics may be obtained using Context.NumTactics - * and Context.TacticNames. - * It may also be obtained using the command (help-tactics) in the SMT 2.0 front-end. - **/ - public class Tactic extends Z3Object - { - /** - * A string containing a description of parameters accepted by the tactic. - **/ - public String Help() - { - - - return Native.tacticGetHelp(Context.nCtx, NativeObject); - } - - - /** - * Retrieves parameter descriptions for Tactics. - **/ - public ParamDescrs ParameterDescriptions() { return new ParamDescrs(Context, Native.tacticGetParamDescrs(Context.nCtx, NativeObject)); } - - - /** - * Execute the tactic over the goal. - **/ - public ApplyResult Apply(Goal g, Params p) - { - - - - Context.CheckContextMatch(g); - if (p == null) - return new ApplyResult(Context, Native.tacticApply(Context.nCtx, NativeObject, g.NativeObject)); - else - { - Context.CheckContextMatch(p); - return new ApplyResult(Context, Native.tacticApplyEx(Context.nCtx, NativeObject, g.NativeObject, p.NativeObject)); - } - } - - /** - * Apply the tactic to a goal. - **/ - public ApplyResult get(Goal g) - { - - - - return Apply(g); - } - - /** - * Creates a solver that is implemented using the given tactic. - * - **/ - public Solver Solver() - { - - - return Context.MkSolver(this); - } - - Tactic(Context ctx, IntPtr obj) - { super(ctx, obj); - - } - Tactic(Context ctx, String name) - { super(ctx, Native.mkTactic(ctx.nCtx, name)); - - } - - class DecRefQueue extends Z3.DecRefQueue - { - public void IncRef(Context ctx, IntPtr obj) - { - Native.tacticIncRef(ctx.nCtx, obj); - } - - public void DecRef(Context ctx, IntPtr obj) - { - Native.tacticDecRef(ctx.nCtx, obj); - } - }; - - void IncRef(IntPtr o) - { - Context.Tactic_DRQ.IncAndClear(Context, o); - super.IncRef(o); - } - - void DecRef(IntPtr o) - { - Context.Tactic_DRQ.Add(o); - super.DecRef(o); - } - } diff --git a/src/api/java/com/Microsoft/Z3/Version.class b/src/api/java/com/Microsoft/Z3/Version.class deleted file mode 100644 index 472674ff6..000000000 Binary files a/src/api/java/com/Microsoft/Z3/Version.class and /dev/null differ diff --git a/src/api/java/com/Microsoft/Z3/Version.java b/src/api/java/com/Microsoft/Z3/Version.java deleted file mode 100644 index 8038f02d5..000000000 --- a/src/api/java/com/Microsoft/Z3/Version.java +++ /dev/null @@ -1,68 +0,0 @@ -/** - * This file was automatically generated from Version.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * Version information. - * Note that this class is static. - **/ - public final class Version - { - Version() { } - - /** - * The major version - **/ - public long Major() - { - long major = 0, minor = 0, build = 0, revision = 0; - Native.getVersion(major, minor, build, revision); - return major; - } - - /** - * The minor version - **/ - public long Minor() - { - long major = 0, minor = 0, build = 0, revision = 0; - Native.getVersion(major, minor, build, revision); - return minor; - } - - /** - * The build version - **/ - public long Build() - { - long major = 0, minor = 0, build = 0, revision = 0; - Native.getVersion(major, minor, build, revision); - return build; - } - - /** - * The revision - **/ - public long Revision() - { - long major = 0, minor = 0, build = 0, revision = 0; - Native.getVersion(major, minor, build, revision); - return revision; - } - - /** - * A string representation of the version information. - **/ - public String toString() - { - - - long major = 0, minor = 0, build = 0, revision = 0; - Native.getVersion(major, minor, build, revision); - return major.toString() + "." + minor.toString() + "." + build.toString() + "." + revision.toString(); - } - } diff --git a/src/api/java/com/Microsoft/Z3/Z3Exception.java b/src/api/java/com/Microsoft/Z3/Z3Exception.java deleted file mode 100644 index 0e05add87..000000000 --- a/src/api/java/com/Microsoft/Z3/Z3Exception.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * This file was automatically generated from Z3Exception.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * The exception base class for error reporting from Z3 - **/ - public class Z3Exception extends Exception - { - /** - * Constructor. - **/ - public Z3Exception() { super(); } - - /** - * Constructor. - **/ - public Z3Exception(String message) { super(message); } - - /** - * Constructor. - **/ - public Z3Exception(String message, System.Exception inner) { super(message, inner); } - } diff --git a/src/api/java/com/Microsoft/Z3/Z3Object.java b/src/api/java/com/Microsoft/Z3/Z3Object.java deleted file mode 100644 index ca4258980..000000000 --- a/src/api/java/com/Microsoft/Z3/Z3Object.java +++ /dev/null @@ -1,120 +0,0 @@ -/** - * This file was automatically generated from Z3Object.cs - **/ - -package com.Microsoft.Z3; - -/* using System; */ - - /** - * Internal base class for interfacing with native Z3 objects. - * Should not be used externally. - **/ - public class Z3Object extends IDisposable - { - /** - * Finalizer. - **/ - protected void finalize() - { - Dispose(); - } - - /** - * Disposes of the underlying native Z3 object. - **/ - public void Dispose() - { - if (m_n_obj != IntPtr.Zero) - { - DecRef(m_n_obj); - m_n_obj = IntPtr.Zero; - } - - if (m_ctx != null) - { - m_ctx.refCount--; - if (m_ctx.refCount == 0) - GC.ReRegisterForFinalize(m_ctx); - m_ctx = null; - } - - GC.SuppressFinalize(this); - } - - - private void ObjectInvariant() - { - - } - - - private Context m_ctx = null; - private IntPtr m_n_obj = IntPtr.Zero; - - Z3Object(Context ctx) - { - - - ctx.refCount++; - m_ctx = ctx; - } - - Z3Object(Context ctx, IntPtr obj) - { - - - ctx.refCount++; - m_ctx = ctx; - IncRef(obj); - m_n_obj = obj; - } - - void IncRef(IntPtr o) { } - void DecRef(IntPtr o) { } - - void CheckNativeObject(IntPtr obj) { } - - IntPtr NativeObject - { - get { return m_n_obj; } - set - { - if (value != IntPtr.Zero) { CheckNativeObject(value); IncRef(value); } - if (m_n_obj != IntPtr.Zero) { DecRef(m_n_obj); } - m_n_obj = value; - } - } - - static IntPtr GetNativeObject(Z3Object s) - { - if (s == null) return new IntPtr(); - return s.NativeObject; - } - - Context Context - { - get - { - - return m_ctx; - } - } - - static IntPtr[] ArrayToNative(Z3Object[] a) - { - - - - if (a == null) return null; - IntPtr[] an = new IntPtr[a.Length]; - for (long i = 0; i < a.Length; i++) - if (a[i] != null) an[i] = a[i].NativeObject; - return an; - } - - static long ArrayLength(Z3Object[] a) - { - return (a == null)?0:(long)a.Length; - } - } diff --git a/src/api/java/manifest b/src/api/java/manifest new file mode 100644 index 000000000..b54445cf2 --- /dev/null +++ b/src/api/java/manifest @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 +Created-By: 4.3.0 (Microsoft Research LTD.) diff --git a/src/api/java/mk_java.py b/src/api/java/mk_java.py index a2cc51274..87f3e274a 100644 --- a/src/api/java/mk_java.py +++ b/src/api/java/mk_java.py @@ -1,24 +1,46 @@ -############################################ +###################################################### # Copyright (c) 2012 Microsoft Corporation # # Auxiliary scripts for generating Java bindings # from the managed API. # # Author: Christoph M. Wintersteiger (cwinter) -############################################ +###################################################### + + +### +# DO NOT USE THIS SCRIPT! +# This script creates a rough draft of a Java API from +# the managed API, but does not automated the process. +### CS="../dotnet/" EXT=".cs" EXCLUDE=["Enumerations.cs", "Native.cs", "AssemblyInfo.cs"] OUTDIR="com/Microsoft/Z3/" +ENUMS_FILE = "Enumerations.cs" import os import fileinput import string import re +EXCLUDE_METHODS = [ [ "Context.cs", "public Expr MkNumeral(ulong" ], + [ "Context.cs", "public Expr MkNumeral(uint" ], + [ "Context.cs", "public RatNum MkReal(ulong" ], + [ "Context.cs", "public RatNum MkReal(uint" ], + [ "Context.cs", "public IntNum MkInt(ulong" ], + [ "Context.cs", "public IntNum MkInt(uint" ], + [ "Context.cs", "public BitVecNum MkBV(ulong" ], + [ "Context.cs", "public BitVecNum MkBV(uint" ], + ] + +ENUMS = [] + def mk_java_bindings(): - print "Generating Java bindings (from C# bindings in " + CS + ")." + print "Generating Java bindings (from C# bindings in " + CS + ")..." + print "Finding enumerations in " + ENUMS_FILE + "..." + find_enums(ENUMS_FILE) for root, dirs, files in os.walk(CS): for fn in files: if not fn in EXCLUDE and fn.endswith(EXT): @@ -29,9 +51,17 @@ def subst_getters(s, getters): s = s.replace(g, g + "()") def type_replace(s): - s = s.replace("bool", "boolean") - s = s.replace("uint", "long") + s = s.replace(" bool", " boolean") + s = s.replace("(bool", "(boolean") + s = s.replace("uint", "int") + s = s.replace("ulong", "long") s = s.replace("string", "String") + s = s.replace("IntPtr", "long") + s = s.replace("Dictionary<", "Map<") + s = s.replace("UInt64", "long") + s = s.replace("Int64", "long") + s = s.replace("List", "LinkedList") + s = s.replace("System.Exception", "Exception") return s def rename_native(s): @@ -47,6 +77,55 @@ def rename_native(s): s = c0 + c1 + c2 return s +def find_enums(fn): + for line in fileinput.input(os.path.join(CS, fn)): + s = string.rstrip(string.lstrip(line)) + if s.startswith("public enum"): + ENUMS.append(s.split(" ")[2]) + + +def enum_replace(line): + for e in ENUMS: + if line.find("case") != -1: + line = line.replace(e + ".", "") + elif line.find("== (int)") != -1 or line.find("!= (int)") != -1: + line = re.sub("\(int\)" + e + "\.(?P[A-Z0-9_]*)", e + ".\g.toInt()", line) + elif line.find("==") != -1 or line.find("!=") != -1: + line = re.sub(e + "\.(?P[A-Z0-9_]*)", e + ".\g", line) + else: + # line = re.sub("\(\(" + e + "\)(?P.*\(.*)\)", "(" + e + ".values()[\g])", line) + line = re.sub("\(" + e + "\)(?P.*\(.*\))", e + ".fromInt(\g)", line) + return line + +def replace_generals(a): + a = re.sub(" NativeObject", " NativeObject()", a) + a = re.sub("\.NativeObject", ".NativeObject()", a) + a = re.sub("(?P[\.\(])Id", "\gId()", a) + a = a.replace("(Context ==", "(Context() ==") + a = a.replace("(Context,", "(Context(),") + a = a.replace("Context.", "Context().") + a = a.replace(".nCtx", ".nCtx()") + a = a.replace("(nCtx", "(nCtx()") + a = re.sub("Context\(\).(?P[^_]*)_DRQ", "Context().\g_DRQ()", a) + a = re.sub("ASTKind", "ASTKind()", a) + a = re.sub("IsExpr(?P[ ;])", "IsExpr()\g", a) + a = re.sub("IsNumeral(?P[ ;])", "IsNumeral()\g", a) + a = re.sub("IsInt(?P[ ;])", "IsInt()\g", a) + a = re.sub("IsReal(?P[ ;])", "IsReal()\g", a) + a = re.sub("IsVar(?P[ ;\)])", "IsVar()\g", a) + a = re.sub("FuncDecl.DeclKind", "FuncDecl().DeclKind()", a) + a = re.sub("FuncDecl.DomainSize", "FuncDecl().DomainSize()", a) + a = re.sub("(?P[=&]) Num(?P[a-zA-Z]*)", "\g Num\g()", a) + a = re.sub("= Denominator", "= Denominator()", a) + a = re.sub(", BoolSort(?P[\)\.])", ", BoolSort()\g", a) + a = re.sub(", RealSort(?P[\)\.])", ", RealSort()\g", a) + a = re.sub(", IntSort(?P[\)\.])", ", IntSort()\g", a) + a = a.replace("? 1 : 0", "? true : false") + if a.find("Native.") != -1 and a.find("!= 0") != -1: + a = a.replace("!= 0", "") + if a.find("Native.") != -1 and a.find("== 0") != -1: + a = a.replace("== 0", "^ true") + return a def translate(filename): tgtfn = OUTDIR + filename.replace(EXT, ".java") @@ -65,6 +144,10 @@ def translate(filename): in_bracket_op = 0 in_getter_get = 0 in_getter_set = 0 + had_ulong_res = 0 + in_enum = 0 + missing_foreach_brace = 0 + foreach_opened_brace = 0 for line in fileinput.input(os.path.join(CS, filename)): s = string.rstrip(string.lstrip(line)) if in_javadoc: @@ -87,6 +170,13 @@ def translate(filename): tgt.write(t + " **/\n") in_javadoc = 0 + # for i in range(0, len(EXCLUDE_METHODS)): + # if filename == EXCLUDE_METHODS[i][0] and s.startswith(EXCLUDE_METHODS[i][1]): + # tgt.write(t + "/* Not translated because it would translate to a function with clashing types. */\n") + # in_unsupported = 1 + # break + + if in_unsupported: if s == "}": in_unsupported = 0 @@ -98,8 +188,11 @@ def translate(filename): in_header = 0 tgt.write(" * This file was automatically generated from " + filename + " \n") tgt.write(" **/\n") - tgt.write("\npackage com.Microsoft.Z3;\n") - + tgt.write("\npackage com.Microsoft.Z3;\n\n") + tgt.write("import java.math.BigInteger;\n") + tgt.write("import java.util.*;\n") + tgt.write("import java.lang.Exception;\n") + tgt.write("import com.Microsoft.Z3.Enumerations.*;\n") elif in_header == 1: # tgt.write(" * " + line.replace(filename, tgtfn)) pass @@ -113,10 +206,21 @@ def translate(filename): for i in range(0, line.find(s)+1): t += " " tgt.write(t + "/* Overloaded operators are not translated. */\n") - in_unsupported = 1; + in_unsupported = 1 + elif s.startswith("public enum"): + tgt.write(line.replace("enum", "class")) + in_enum = 1 + elif in_enum == 1: + if s == "}": + tgt.write(line) + in_enum = 0 + else: + line = re.sub("(?P.*)\W*=\W*(?P[^\n,])", "public static final int \g = \g;", line) + tgt.write(line.replace(",","")) elif s.startswith("public class") or s.startswith("internal class") or s.startswith("internal abstract class"): a = line.replace(":", "extends").replace("internal ", "") a = a.replace(", IComparable", "") + a = type_replace(a) tgt.write(a) in_class = 1 in_static_class = 0 @@ -129,10 +233,13 @@ def translate(filename): in_javadoc = 1 elif skip_brace and s == "{": skip_brace = 0 - elif s.find("public") != -1 and s.find("class") == -1 and s.find("event") == -1 and s.find("(") == -1: + elif ((s.find("public") != -1 or s.find("protected") != -1) and s.find("class") == -1 and s.find("event") == -1 and s.find("(") == -1) or s.startswith("internal virtual IntPtr NativeObject") or s.startswith("internal Context Context"): if (s.startswith("new")): s = s[3:] + s = s.replace("internal virtual", "") + s = s.replace("internal", "") tokens = s.split(" ") + # print "TOKENS: " + str(len(tokens)) if len(tokens) == 3: in_getter = tokens[2] in_getter_type = type_replace((tokens[0] + " " + tokens[1])) @@ -140,6 +247,7 @@ def translate(filename): in_getter_type = in_getter_type.replace("static", "") lastindent = line.find(s) skip_brace = 1 + getters.append(in_getter) elif len(tokens) == 4: if tokens[2].startswith("this["): in_bracket_op = 1 @@ -152,21 +260,36 @@ def translate(filename): if in_static_class: in_getter_type = in_getter_type.replace("static", "") lastindent = line.find(s) - skip_brace = 1 + skip_brace = 1 + getters.append(in_getter) else: in_getter = tokens[2] in_getter_type = type_replace(tokens[0] + " " + tokens[1]) - if in_static_class: - in_getter_type = in_getter_type.replace("static", "") - rest = s[s.find("get ") + 4:-1] - subst_getters(rest, getters) - rest = type_replace(rest) - rest = rename_native(rest) - t = "" - for i in range(0, lastindent): - t += " " - tgt.write(t + in_getter_type + " " + in_getter + "() " + rest + "\n") - getters.append(in_getter) + if tokens[2].startswith("this["): + lastindent = line.find(s) + t = "" + for i in range(0, lastindent): t += " " + tgt.write(t + "/* operator this[] not translated */\n ") + in_unsupported = 1 + else: + if in_static_class: + in_getter_type = in_getter_type.replace("static", "") + rest = s[s.find("get ") + 4:-1] + subst_getters(rest, getters) + rest = type_replace(rest) + rest = rename_native(rest) + rest = replace_generals(rest) + rest = enum_replace(rest) + t = "" + for i in range(0, lastindent): + t += " " + tgt.write(t + in_getter_type + " " + in_getter + "() " + rest + "\n") + if rest.find("}") == -1: + in_getter_get = 1 + else: + getters.append(in_getter) + in_getter = "" + in_getter_type = "" print "ACC: " + s + " --> " + in_getter elif s.find("{ get {") != -1: line = type_replace(line) @@ -177,6 +300,8 @@ def translate(filename): rest = re.sub("Contract.\w+\([\s\S]*\);", "", rest) subst_getters(rest, getters) rest = rename_native(rest) + rest = replace_generals(rest) + rest = enum_replace(rest) if in_bracket_op: tgt.write(d + rest) else: @@ -185,12 +310,14 @@ def translate(filename): elif in_getter != "" and s.startswith("get"): t = "" for i in range(0, lastindent): - t += " " + t += " " if len(s) > 3: rest = s[3:] else: rest = "" subst_getters(rest, getters) rest = type_replace(rest) rest = rename_native(rest) + rest = replace_generals(rest) + rest = enum_replace(rest) if in_bracket_op: tgt.write(t + in_getter_type + " " + in_getter + " " + rest + "\n") else: @@ -207,6 +334,8 @@ def translate(filename): rest = rest.replace("(Integer)value", "Integer(value)") rest = type_replace(rest) rest = rename_native(rest) + rest = replace_generals(rest) + rest = enum_replace(rest) ac_acc = in_getter_type[:in_getter_type.find(' ')] ac_type = in_getter_type[in_getter_type.find(' ')+1:] if in_bracket_op: @@ -216,13 +345,13 @@ def translate(filename): tgt.write(t + ac_acc + " void set" + in_getter + "(" + ac_type + " value) " + rest + "\n") if rest.find("}") == -1: in_getter_set = 1 - elif in_getter != "" and in_getter_get and s == "}": + elif in_getter != "" and in_getter_get == 1 and s == "}": tgt.write(line) in_getter_get = 0 - elif in_getter != "" and in_getter_set and s == "}": + elif in_getter != "" and in_getter_set == 1 and s == "}": tgt.write(line) in_getter_set = 0 - elif in_getter != "" and not in_getter_get and not in_getter_set and s == "}": + elif in_getter != "" and in_getter_get == 0 and in_getter_set == 0 and s == "}": in_getter = "" in_getter_type == "" in_bracket_op = 0 @@ -232,48 +361,103 @@ def translate(filename): line = re.sub("(?P\w+)(?P[,;])", "\g\g", line) tgt.write(line); elif (not in_class and (s.startswith("{") or s.startswith("}"))) or s.startswith("[") or s.startswith("#"): - # print "Skipping: " + s; + # tgt.write("// Skipping: " + s) pass elif line == "}\n": pass else: # indent = line.find(s) + # tgt.write("// LINE: " + line) if line.find(": base") != -1: - line = re.sub(": base\((?P

[\w,.\(\) ]*)\)", "{ super(\g

);", line) - if line.find("; {") != -1: - line = line.replace("; {", ";") + line = re.sub(": base\((?P

[^\{]*)\)", "{ super(\g

);", line) + line = line[4:] + obraces = line.count("{") + cbraces = line.count("}") + mbraces = obraces - cbraces + # tgt.write("// obraces = " + str(obraces) + "\n") + if obraces == 1: + skip_brace = 1 else: - skip_brace = 1 - if s.startswith("public"): + for i in range(0, mbraces): + line = line.replace("\n", "}\n") + if (s.find("public") != -1 or s.find("protected") != -1 or s.find("internal") != -1) and s.find("(") != -1: line = re.sub(" = [\w.]+(?P[,;\)])", "\g", line) a = type_replace(line) + a = enum_replace(a) a = re.sub("(?P[\(, ])params ", "\g", a) a = a.replace("base.", "super.") a = re.sub("Contract.\w+\([\s\S]*\);", "", a) a = rename_native(a) a = re.sub("~\w+\(\)", "protected void finalize()", a) + + if missing_foreach_brace == 1: + # a = a.replace("\n", " // checked " + str(foreach_opened_brace) + "\n") + if foreach_opened_brace == 0 and a.find("{") != -1: + foreach_opened_brace = 1 + elif foreach_opened_brace == 0 and a.find("}") == -1: + a = a.replace("\n", "}}\n") + foreach_opened_brace = 0 + missing_foreach_brace = 0 + elif foreach_opened_brace == 1 and a.find("}") != -1: + a = a.replace("\n", "}}\n") + foreach_opened_brace = 0 + missing_foreach_brace = 0 + +# if a.find("foreach") != -1: +# missing_foreach_brace = 1 +# a = re.sub("foreach\s*\((?P[\w <>,]+)\s+(?P\w+)\s+in\s+(?P\w+)\)", + # "{ Iterator fe_i = \g.iterator(); while (fe_i.hasNext()) { \g \g = (long)fe_i.next(); ", +# a) a = re.sub("foreach\s*\((?P[\w <>,]+)\s+(?P\w+)\s+in\s+(?P\w+)\)", - "for (\g.Iterator \g = \g.iterator(); \g.hasNext(); )", a) + "for (\g \g: \g)", + a) + if a.find("long o: m_queue") != -1: + a = a.replace("long", "Long") a = a.replace("readonly ", "") a = a.replace("const ", "final ") - a = a.replace("ToString", "toString") + a = a.replace("String ToString", "String toString") + a = a.replace(".ToString", ".toString") a = a.replace("internal ", "") a = a.replace("new static", "static") a = a.replace("new public", "public") a = a.replace("override ", "") a = a.replace("virtual ", "") a = a.replace("o as AST", "(AST) o") + a = a.replace("o as Sort", "(Sort) o") a = a.replace("other as AST", "(AST) other") a = a.replace("o as FuncDecl", "(FuncDecl) o") + a = a.replace("IntPtr obj", "long obj") + a = a.replace("IntPtr o", "long o") + a = a.replace("new long()", "0") + a = a.replace("long.Zero", "0") + a = a.replace("object o", "Object o") + a = a.replace("object other", "Object other") a = a.replace("IntPtr res = IntPtr.Zero;", "Native.IntPtr res = new Native.IntPtr();") a = a.replace("out res", "res") + a = a.replace("GC.ReRegisterForFinalize(m_ctx);", "") + a = a.replace("GC.SuppressFinalize(this);", "") + a = a.replace(".Length", ".length") + a = a.replace("m_queue.Count", "m_queue.size()") + a = a.replace("m_queue.Add", "m_queue.add") + a = a.replace("m_queue.Clear", "m_queue.clear") + a = a.replace("for (long ", "for (int ") + a = a.replace("ReferenceEquals(Context, ctx)", "Context() == ctx") + a = a.replace("BigInteger.Parse", "new BigInteger") + if had_ulong_res == 0 and a.find("ulong res = 0") != -1: + a = a.replace("ulong res = 0;", "LongPtr res = new LongPtr();") + elif had_ulong_res == 1: + a = a.replace("ref res)", "res)") + if a.find("return res;") != -1: + a = a.replace("return res;", "return res.value;") + had_ulong_res = 0 a = a.replace("lock (", "synchronized (") if in_static_class: a = a.replace("static", "") a = re.sub("ref (?P\w+)", "\g", a) subst_getters(a, getters) + a = re.sub("NativeObject = (?P.*);", "setNativeObject(\g);", a) + a = replace_generals(a) tgt.write(a) - tgt.close() mk_java_bindings() diff --git a/src/api/ml/Makefile b/src/api/ml/Makefile new file mode 100644 index 000000000..55f89fe1c --- /dev/null +++ b/src/api/ml/Makefile @@ -0,0 +1,14 @@ +# to set ARGS, invoke as e.g.: $ make ARGS='-DUNSAFE_ERRORS -DLEAK_CONTEXTS' +ARGS= + + +default: z3.ml z3.mli z3_stubs.c + + +%.ml %.mli %_stubs.c: ../%_api.h %.0.idl x3.ml x3V3.ml x3V3.mli \ + error_handling.idl mlx_get_app_args.idl mlx_get_array_sort.idl mlx_get_datatype_sort.idl mlx_get_domains.idl mlx_get_error_msg.idl mlx_get_pattern_terms.idl mlx_get_tuple_sort.idl mlx_mk_context_x.idl mlx_mk_datatypes.idl mlx_mk_numeral.idl mlx_mk_sort.idl mlx_mk_symbol.idl mlx_model.idl mlx_numeral_refine.idl mlx_parse_smtlib.idl mlx_sort_refine.idl mlx_statistics.idl mlx_symbol_refine.idl mlx_term_refine.idl \ + generate_mlapi.sh add_error_checking.V3.sed add_error_checking.sed preprocess.sed postprocess.sed reverse.sed + ./generate_mlapi.sh $(ARGS) + +clean: + rm -f z3.ml z3.mli z3_stubs.c diff --git a/src/api/ml/Makefile.build b/src/api/ml/Makefile.build new file mode 100644 index 000000000..27c798bbf --- /dev/null +++ b/src/api/ml/Makefile.build @@ -0,0 +1,69 @@ +# Makefile to compile OCaml interface to Z3 +# +# Parameters: ARGS and DEPS environment variables +# ARGS is passed through to the Makefile that generates the OCaml interface +# DEPS is a sequence of files that are deleted when the OCaml interface changes + +SRC_ML=../../../src/api/ml +ifeq (${OS}, Windows_NT) +# the BLD_ML path ends up stored in z3.cm{,x}a, so it must be in windows format +BLD_ML=$(shell cygpath -m $(CURDIR)) +CFLAGS=-ccopt -wd4090 -ccopt -I$(SRC_ML)/.. +XCDBG=-g $(CFLAGS) +XCOPT=-ccopt -Ox -ccopt -Oy- $(CFLAGS) +# ole32 is needed by camlidl (COM support) +XLIB=-cclib ole32.lib +AR=lib /nologo /LIBPATH:../../build ../../z3.lib /out: +O=obj +A=lib +else +BLD_ML=$(CURDIR) +CFLAGS=-ccopt -Wno-discard-qual -ccopt -Wno-unused-variable -ccopt -I$(SRC_ML)/.. +XCDBG=-g -ccopt -g $(CFLAGS) +XCOPT=-ccopt -O3 -ccopt -fomit-frame-pointer $(CFLAGS) +XLIB= +AR=ar rcs # note trailing space is significant +O=o +A=a +endif + + +all: z3.cma z3.cmxa ocamlz3 + + +# keep these files to avoid repeatedly rebuilding them +.PRECIOUS: $(SRC_ML)/z3.ml $(SRC_ML)/z3.mli $(SRC_ML)/z3_stubs.c z3.ml z3.mli z3_stubs.c z3_theory_stubs.c + +# regenerate OCaml API if needed +$(SRC_ML)/%.mli $(SRC_ML)/%.ml $(SRC_ML)/%_stubs.c: $(SRC_ML)/Makefile + make -C $(SRC_ML) z3.mli z3.ml z3_stubs.c + +# copy OCaml API from src to build directories +%.mli %.ml %_stubs.c %_theory_stubs.c: $(SRC_ML)/%.mli $(SRC_ML)/%.ml $(SRC_ML)/%_stubs.c Makefile + cp $(SRC_ML)/z3.mli $(SRC_ML)/z3.ml $(SRC_ML)/z3_stubs.c $(SRC_ML)/z3_theory_stubs.c . + +# OCaml library module for native code clients +%.cmxa %.cmi lib%stubs.a %.a: %.mli %.ml %_stubs.c %_theory_stubs.c Makefile + rm -f $(DEPS) + ocamlopt.opt -c $(XCOPT) z3.mli z3.ml z3_stubs.c z3_theory_stubs.c + $(AR)libz3stubs.$(A) z3.$(O) z3_stubs.$(O) z3_theory_stubs.$(O) + ocamlopt.opt -a -cclib -L$(BLD_ML)/../.. $(XLIB) -cclib -lcamlidl -cclib -lz3 -cclib -lz3stubs z3.cmx -o z3.cmxa + rm -f z3_theory_stubs.$(O) z3_stubs.$(O) z3.$(O) z3.cmx + +# OCaml library module for byte code clients +%.cma %.cmi lib%stubs_dbg.a: %.mli %.ml %_stubs.c %_theory_stubs.c Makefile + rm -f $(DEPS) + ocamlc.opt -c $(XCDBG) z3.mli z3.ml z3_stubs.c z3_theory_stubs.c + $(AR)libz3stubs_dbg.$(A) z3_stubs.$(O) z3_theory_stubs.$(O) + ocamlc.opt -custom -a $(CXDBG) -cclib -L$(BLD_ML)/../.. $(XLIB) -cclib -lcamlidl -cclib -lz3 -cclib -lz3stubs_dbg z3.cmo -o z3.cma + rm -f z3_theory_stubs.$(O) z3_stubs.$(O) z3.cmo + + +# OCaml custom toplevel system pre-linked with Z3 +ocamlz3: z3.cma Makefile + ocamlmktop -o ocamlz3 z3.cma -cclib -L. + + +clean: Makefile + make -C $(SRC_ML) clean + rm -rf Makefile libz3stubs.$(A) libz3stubs_dbg.$(A) ocamlz3 ocamlz3.dSYM z3.$(O) z3.$(A) z3.cma z3.cmi z3.cmo z3.cmx z3.cmxa z3.ml z3.mli z3_stubs.$(O) z3_stubs.c z3_theory_stubs.$(O) z3_theory_stubs.c diff --git a/src/api/ml/add_error_checking.V3.sed b/src/api/ml/add_error_checking.V3.sed index 170ca2d6b..7df291520 100644 --- a/src/api/ml/add_error_checking.V3.sed +++ b/src/api/ml/add_error_checking.V3.sed @@ -1,2 +1,2 @@ # Customize error handling for contexts created in ML: -s/Z3_API Z3_mk_context\(_rc\|\)(\(.*\))/Z3_API Z3_mk_context\1(\2) quote(dealloc,\"Z3_set_error_handler(_res, caml_z3_error_handler);\")/g +s/Z3_API Z3_mk_context(\(.*\))/Z3_API Z3_mk_context(\1) quote(dealloc,\"Z3_set_error_handler(_res, (void*)caml_z3_error_handler);\")/g diff --git a/src/api/ml/add_error_checking.sed b/src/api/ml/add_error_checking.sed index ede3275e1..71c06b9e4 100644 --- a/src/api/ml/add_error_checking.sed +++ b/src/api/ml/add_error_checking.sed @@ -3,14 +3,19 @@ # Add error checking epilogue for all Z3_API functions that accept two Z3_contexts :begincc -# add epilogue for two Z3_context parameters -s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\|\))\(;\|\)[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5\6) quote(dealloc,\"check_error_code(\3);\")\7/g - -# if a match was found, done with all Z3_contexts and Z3_theorys +# add epilogue for two Z3_context parameters and if a match was found, done with all Z3_contexts and Z3_theorys so jump to endt +s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\));[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5\6) quote(dealloc,\"check_error_code(\3);\");/g +t endt +s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\));[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5) quote(dealloc,\"check_error_code(\3);\");/g +t endt +s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\))[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5\6) quote(dealloc,\"check_error_code(\3);\")/g +t endt +s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\))[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5) quote(dealloc,\"check_error_code(\3);\")/g t endt # if complete prototype, done with two Z3_contexts -/Z3_API .*(.*)\(;\|\)[ ]*$/b endcc +/Z3_API .*(.*);[ ]*$/b endcc +/Z3_API .*(.*)[ ]*$/b endcc # if incomplete prototype /Z3_API .*(.*/{ @@ -18,10 +23,14 @@ t endt # read another line N - # add epilogue for two Z3_context parameters - s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\|\))\(;\|\)[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5\6) quote(dealloc,\"check_error_code(\3); check_error_code(\5);\")\7/g - - # if a match was found, done with all Z3_contexts and Z3_theorys + # add epilogue for two Z3_context parameters and if a match was found, done with all Z3_contexts and Z3_theorys so jump to endt + s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\));[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5\6) quote(dealloc,\"check_error_code(\3); check_error_code(\5);\");/g + t endt + s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\));[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5) quote(dealloc,\"check_error_code(\3); check_error_code(\5);\");/g + t endt + s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\))[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5\6) quote(dealloc,\"check_error_code(\3); check_error_code(\5);\")/g + t endt + s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\))[ ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5) quote(dealloc,\"check_error_code(\3); check_error_code(\5);\")/g t endt # else keep looking for two Z3_contexts @@ -31,14 +40,19 @@ t endt # Add error checking epilogue for all Z3_API functions that accept one Z3_context :beginc -# add epilogue for one Z3_context parameter -s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\|\))\(;\|\)[ ]*$/Z3_API \1(\2Z3_context \3\4) quote(dealloc,\"check_error_code(\3);\")\5/g - -# if a match was found, done with all Z3_contexts and Z3_theorys +# add epilogue for one Z3_context parameter and if a match was found, done with all Z3_contexts and Z3_theorys so jump to endt +s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\));[ ]*$/Z3_API \1(\2Z3_context \3\4) quote(dealloc,\"check_error_code(\3);\");/g +t endt +s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\));[ ]*$/Z3_API \1(\2Z3_context \3) quote(dealloc,\"check_error_code(\3);\");/g +t endt +s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\)[ ]*$/Z3_API \1(\2Z3_context \3\4) quote(dealloc,\"check_error_code(\3);\")/g +t endt +s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\))[ ]*$/Z3_API \1(\2Z3_context \3) quote(dealloc,\"check_error_code(\3);\")/g t endt # if complete prototype, done with all Z3_contexts -/Z3_API .*(.*)\(;\|\)[ ]*$/b endc +/Z3_API .*(.*);[ ]*$/b endc +/Z3_API .*(.*)[ ]*$/b endc # if incomplete prototype /Z3_API .*(.*/{ @@ -46,10 +60,14 @@ t endt # read another line N - # add epilogue for one Z3_context parameter - s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\|\))\(;\|\)[ ]*$/Z3_API \1(\2Z3_context \3\4) quote(dealloc,\"check_error_code(\3);\")\5/g - - # if a match was found, done with all Z3_contexts and Z3_theorys + # add epilogue for one Z3_context parameter and if a match was found, done with all Z3_contexts and Z3_theorys so jump to endt + s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\));[ ]*$/Z3_API \1(\2Z3_context \3\4) quote(dealloc,\"check_error_code(\3);\");/g + t endt + s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\));[ ]*$/Z3_API \1(\2Z3_context \3) quote(dealloc,\"check_error_code(\3);\");/g + t endt + s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\))[ ]*$/Z3_API \1(\2Z3_context \3\4) quote(dealloc,\"check_error_code(\3);\")/g + t endt + s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\))[ ]*$/Z3_API \1(\2Z3_context \3) quote(dealloc,\"check_error_code(\3);\")/g t endt # else keep looking for one Z3_context @@ -60,24 +78,33 @@ t endt # Add error checking epilogue for all Z3_API functions that accept a Z3_theory :begint -# add epilogue for one Z3_theory parameter -s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\)\([^a-zA-Z].*\|\))\(;\|\)[ ]*$/Z3_API \1(\2Z3_theory \3\4) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\")\5/g - -# if a match was found, done with all Z3_contexts and Z3_theorys +# add epilogue for one Z3_theory parameter and if a match was found, done with all Z3_contexts and Z3_theorys so jump to endt +s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\)\([^a-zA-Z].*\));[ ]*$/Z3_API \1(\2Z3_theory \3\4) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\");/g +t endt +s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\));[ ]*$/Z3_API \1(\2Z3_theory \3) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\");/g +t endt +s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\)\([^a-zA-Z].*\))[ ]*$/Z3_API \1(\2Z3_theory \3\4) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\")/g +t endt +s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\))[ ]*$/Z3_API \1(\2Z3_theory \3) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\")/g t endt # if complete prototype, done with all Z3_theorys -/Z3_API .*(.*)\(;\|\)[ ]*$/b endt +/Z3_API .*(.*);[ ]*$/b endt +/Z3_API .*(.*)[ ]*$/b endt /Z3_API .*(.*/{ # read another line N - # add epilogue for one Z3_theory parameter - s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\)\([^a-zA-Z].*\|\))\(;\|\)[ ]*$/Z3_API \1(\2Z3_theory \3\4) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\")\5/g - - # if a match was found, done with all Z3_theorys + # add epilogue for one Z3_theory parameter and if a match was found, done with all Z3_contexts and Z3_theorys so jump to endt + s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\)\([^a-zA-Z].*\));[ ]*$/Z3_API \1(\2Z3_theory \3\4) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\");/g + t endt + s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\));[ ]*$/Z3_API \1(\2Z3_theory \3) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\");/g + t endt + s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\)\([^a-zA-Z].*\))[ ]*$/Z3_API \1(\2Z3_theory \3\4) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\")/g + t endt + s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\))[ ]*$/Z3_API \1(\2Z3_theory \3) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\")/g t endt # else keep looking for one Z3_theory diff --git a/src/api/ml/error_handling.idl b/src/api/ml/error_handling.idl index cc49a91e4..5a2ec9915 100644 --- a/src/api/ml/error_handling.idl +++ b/src/api/ml/error_handling.idl @@ -53,6 +53,12 @@ Author: #endif +// The V3 API uses a single handler irregardless of UNSAFE_ERRORS +quote(c," +/* All contexts share the same handler */ +static value caml_z3_error_handler = 0; +"); + #ifdef SAFE_ERRORS quote(mlmli," @@ -64,7 +70,7 @@ quote(mlmli," exception Error of context * error_code "); quote(ml," -/* Register dynamically-generated exception tag for use from C */ +(* Register dynamically-generated exception tag for use from C *) let _ = Callback.register_exception \"Z3.Error\" (Error (Obj.magic None, OK)) "); @@ -108,7 +114,7 @@ quote(mlmli," exception Error of context * error_code "); quote(ml," -/* Register dynamically-generated exception tag for use from C */ +(* Register dynamically-generated exception tag for use from C *) let _ = Callback.register_exception \"Z3.Error\" (Error (Obj.magic None, OK)) "); @@ -116,9 +122,6 @@ quote(c," /* Error checking routine that does nothing */ void check_error_code(Z3_context c) {} -/* All contexts share the same handler */ -static value caml_error_handler = 0; - static void error_handler_static (Z3_context c, Z3_error_code e) { static struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; @@ -126,8 +129,8 @@ static void error_handler_static (Z3_context c, Z3_error_code e) value ctx_err[2]; ctx_err[0] = c2ml_Z3_context(&c); ctx_err[1] = camlidl_c2ml_z3_Z3_error_code(&e, &_ctxs); - if (caml_error_handler) { - caml_callback2(caml_error_handler, ctx_err[0], ctx_err[1]); + if (caml_z3_error_handler) { + caml_callback2(caml_z3_error_handler, ctx_err[0], ctx_err[1]); } else { /* if no handler set, raise OCaml Error exception */ exn_tag = caml_named_value(\"Z3.Error\"); @@ -141,7 +144,7 @@ static void error_handler_static (Z3_context c, Z3_error_code e) void ml2c_Z3_error_handler (value ml_handler, void* c_handler) { - caml_error_handler = ml_handler; + caml_z3_error_handler = ml_handler; c_handler = (void*)error_handler_static; } diff --git a/src/api/ml/generate_mlapi.sh b/src/api/ml/generate_mlapi.sh new file mode 100755 index 000000000..dd8692833 --- /dev/null +++ b/src/api/ml/generate_mlapi.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +# Script to generate the Z3 OCaml API +# +# Assumes that environment variables are set to provide access to the following commands: camlidl, gcc, grep, sed +# +# This script uses 'gcc -E' as the C preprocessor, other C preprocessors may work but have not been tested. +# +# Invoke with "-DUNSAFE_ERRORS" to build version that does not support recoverable errors, but avoids some error-checking overhead. +# Invoke with "-DLEAK_CONTEXTS" to build version that leaks Z3_context objects, but avoids some garbage-collection overhead. + + +# add calls to error checking routine +# convert from doxygen to ocamldoc markup and other syntactic munging +# ../z3_api.h -> z3V3_api.idl +sed -f add_error_checking.V3.sed -f preprocess.sed ../z3_api.h > z3V3_api.idl + +# z3.idl (z3V3_api.idl x3V3.mli x3V3.ml) -> z3V3_stubs.c, z3V3.mli, z3V3.ml +gcc -E -w -P -CC -xc -DCAMLIDL -DMLAPIV3 $@ z3.0.idl > z3V3.idl +camlidl -nocpp z3V3.idl + +# reverse.sed to reverse order of substitution of enums to avoid matching prefixes such as enum_1 of enum_10 +grep "^and z3_[a-zA-Z0-9_]* = [a-z][a-zA-Z0-9_]*$" z3V3.mli | sed -e "s|and z3_\([a-zA-Z0-9_]*\) = \([a-zA-Z0-9_]*\)|s/\2/\1/g|g" -f reverse.sed > /tmp/renameV3.sed +grep "^and z3_[a-zA-Z0-9_]* = [a-z][a-zA-Z0-9_ ]* option$" z3V3.mli | sed -e "s|and \(z3_[a-zA-Z0-9_]*\) = \([a-zA-Z0-9_ ]*\)|s/\1/\2/g|g" >> /tmp/renameV3.sed + +# rename.sed to substitute out type equations for enums and options, then postprocess +cp -f z3V3.mli z3V3.ml /tmp +sed -f /tmp/renameV3.sed -f postprocess.sed /tmp/z3V3.mli > z3V3.mli +sed -f /tmp/renameV3.sed -f postprocess.sed /tmp/z3V3.ml > z3V3.ml + +# ../z3_api.h -> z3_api.idl +sed -f add_error_checking.sed -f preprocess.sed ../z3_api.h > z3_api.idl + +# z3.idl (z3_api.idl x3.ml) -> z3_stubs.c, z3.mli, z3.ml +gcc -E -w -P -CC -xc -I. -DCAMLIDL $@ z3.0.idl > z3.idl +camlidl -nocpp z3.idl + +# reverse.sed to reverse order of substitution of enums to avoid matching prefixes such as enum_1 of enum_10 +grep "^and z3_[a-zA-Z0-9_]* = [a-z][a-zA-Z0-9_]*$" z3.mli | sed -e "s|and z3_\([a-zA-Z0-9_]*\) = \([a-zA-Z0-9_]*\)|s/\2/\1/g|g" -f reverse.sed > /tmp/rename.sed +grep "^and z3_[a-zA-Z0-9_]* = [a-z][a-zA-Z0-9_ ]* option$" z3.mli | sed -e "s|and \(z3_[a-zA-Z0-9_]*\) = \([a-zA-Z0-9_ ]*\)|s/\1/\2/g|g" >> /tmp/rename.sed + +# rename.sed to substitute out type equations for enums and options, then postprocess +cp z3.mli z3.ml /tmp +sed -f /tmp/rename.sed -f postprocess.sed /tmp/z3.mli > z3.mli +sed -f /tmp/rename.sed -f postprocess.sed /tmp/z3.ml > z3.ml + + +# append Z3.V3 module onto Z3 module +cat z3V3.mli >> z3.mli +cat z3V3.ml >> z3.ml +sed "1,22d" z3V3_stubs.c >> z3_stubs.c + +rm -f z3V3_api.idl z3V3.idl z3V3.ml z3V3.mli z3V3_stubs.c z3_api.idl z3.idl diff --git a/src/api/ml/postprocess.sed b/src/api/ml/postprocess.sed new file mode 100644 index 000000000..f25f70cb7 --- /dev/null +++ b/src/api/ml/postprocess.sed @@ -0,0 +1,8 @@ +# remove 'z3_' and 'Z3_' prefixes on names + +s/{\!Z3\./{\!/g +s/\([^_]\)[zZ]3_/\1/g + +# remove cyclic definitions introduced by substituting type equations + +s/^and \([a-z][a-zA-Z_ ]*\) = \1$//g diff --git a/src/api/ml/build.sed b/src/api/ml/preprocess.sed similarity index 92% rename from src/api/ml/build.sed rename to src/api/ml/preprocess.sed index e4434a5a1..c7d1fc804 100644 --- a/src/api/ml/build.sed +++ b/src/api/ml/preprocess.sed @@ -1,7 +1,7 @@ # attempt to clean up the mess with 'unsigned' -s/__in unsigned __/__in __/g -s/__out unsigned __/__out __/g -s/__out_opt unsigned __/__out_opt __/g +s/ unsigned/ unsigned int/g +s/unsigned int long/unsigned long/g +s/unsigned int __/unsigned __/g # '@name ' -> 'Section: ' @@ -43,7 +43,7 @@ s/\\ / /g s/\\c \([^ .,:]*\)/[\1]/g # '#Z3_' -> 'Z3.' -s/#Z3_\([^ \n\.\t,)]*\)/{!Z3.\1}/g +s/#Z3_\([^ \.,) ]*\)/{!Z3.\1}/g # '/*@}*/' -> '' s/\/\*@{\*\///g diff --git a/src/api/ml/reverse.sed b/src/api/ml/reverse.sed new file mode 100644 index 000000000..31ac563d2 --- /dev/null +++ b/src/api/ml/reverse.sed @@ -0,0 +1,3 @@ +# output lines of input in reverse order + +1!G;h;$!d diff --git a/src/api/ml/z3.idl b/src/api/ml/z3.0.idl similarity index 97% rename from src/api/ml/z3.idl rename to src/api/ml/z3.0.idl index 2450e387d..3773a28e3 100644 --- a/src/api/ml/z3.idl +++ b/src/api/ml/z3.0.idl @@ -91,16 +91,6 @@ quote(c,"#define xstr(s) str(s)"); quote(c,"#define str(s) #s"); -// CamlIDL (1.05) has a bug where it does not accept [unsigned] as a type, -// only as a specifier, so unsigned is defined to be unsigned int. -#define unsigned unsigned int - - -// Suppress "warning C4090: 'function' : different 'const' qualifiers" as -// CamlIDL does not seem to get this right. -quote(c,"#pragma warning(disable:4090)"); - - #ifndef MLAPIV3 #define DEFINE_TYPE(T) typedef [abstract] void* T diff --git a/src/api/ml/z3.mli b/src/api/ml/z3.mli index 9f58ba06a..905716035 100644 --- a/src/api/ml/z3.mli +++ b/src/api/ml/z3.mli @@ -4886,7 +4886,8 @@ external fixedpoint_add_rule : context -> fixedpoint -> ast -> symbol -> unit of sorts in the domain of [r]. Each sort in the domain should be an integral (bit-vector, Boolean or or finite domain sort). - The call has the same effect as adding a rule where is applied to the arguments. + The call has the same effect as adding a rule where + is applied to the arguments. def_API('fixedpoint_add_fact', VOID, (_in(CONTEXT), _in(FIXEDPOINT), _in(FUNC_DECL), _in(UINT), _in_array(3, UINT))) *) diff --git a/src/api/python/z3.py b/src/api/python/z3.py index a71db82c5..6517de221 100644 --- a/src/api/python/z3.py +++ b/src/api/python/z3.py @@ -23,8 +23,11 @@ Small example: >>> s.add(y == x + 1) >>> s.check() sat ->>> s.model() -[y = 2, x = 1] +>>> m = s.model() +>>> m[x] +1 +>>> m[y] +2 Z3 exceptions: @@ -169,28 +172,6 @@ class Context: """ Z3_interrupt(self.ref()) - def set(self, *args, **kws): - """Set global configuration options. - - Z3 command line options can be set using this method. - The option names can be specified in different ways: - - >>> ctx = Context() - >>> ctx.set('WELL_SORTED_CHECK', True) - >>> ctx.set(':well-sorted-check', True) - >>> ctx.set(well_sorted_check=True) - """ - if __debug__: - _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.") - for key, value in kws.iteritems(): - Z3_update_param_value(self.ctx, str(key).upper(), _to_param_value(value)) - prev = None - for a in args: - if prev == None: - prev = a - else: - Z3_update_param_value(self.ctx, str(prev), _to_param_value(a)) - prev = None # Global Z3 context _main_ctx = None @@ -220,16 +201,48 @@ def _get_ctx(ctx): else: return ctx -def set_option(*args, **kws): - """Update parameters of the global context `main_ctx()`, and global configuration options of Z3Py. See `Context.set()`. - - >>> set_option(precision=10) +def set_param(*args, **kws): + """Set Z3 global (or module) parameters. + + >>> set_param(precision=10) """ + if __debug__: + _z3_assert(len(args) % 2 == 0, "Argument list must have an even number of elements.") new_kws = {} for k, v in kws.iteritems(): if not set_pp_option(k, v): new_kws[k] = v - main_ctx().set(*args, **new_kws) + for key, value in new_kws.iteritems(): + Z3_global_param_set(str(key).upper(), _to_param_value(value)) + prev = None + for a in args: + if prev == None: + prev = a + else: + Z3_global_param_set(str(prev), _to_param_value(a)) + prev = None + +def reset_params(): + """Reset all global (or module) parameters. + """ + Z3_global_param_reset_all() + +def set_option(*args, **kws): + """Alias for 'set_param' for backward compatibility. + """ + return set_param(*args, **kws) + +def get_param(name): + """Return the value of a Z3 global (or module) parameter + + >>> get_param('nlsat.reorder') + 'true' + """ + ptr = (ctypes.c_char_p * 1)() + if Z3_global_param_get(str(name), ptr): + r = str(ptr[0]) + return r + raise Z3Exception("failed to retrieve value for '%s'" % name) ######################################### # @@ -632,10 +645,10 @@ class FuncDeclRef(AstRef): >>> f(x, x) f(x, ToReal(x)) """ - args = _get_args(args) + args = _get_args(args) num = len(args) if __debug__: - _z3_assert(num == self.arity(), "Incorrect number of arguments") + _z3_assert(num == self.arity(), "Incorrect number of arguments to %s" % self) _args = (Ast * num)() saved = [] for i in range(num): @@ -1718,10 +1731,11 @@ def Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]): >>> q = Exists([x, y], f(x, y) >= x, skid="foo") >>> q Exists([x, y], f(x, y) >= x) - >>> Tactic('nnf')(q) - [[f(x!foo!1, y!foo!0) >= x!foo!1]] - >>> Tactic('nnf')(q).as_expr() - f(x!foo!3, y!foo!2) >= x!foo!3 + >>> is_quantifier(q) + True + >>> r = Tactic('nnf')(q).as_expr() + >>> is_quantifier(r) + False """ return _mk_quantifier(False, vs, body, weight, qid, skid, patterns, no_patterns) @@ -1735,7 +1749,7 @@ class ArithSortRef(SortRef): """Real and Integer sorts.""" def is_real(self): - """Return `True` if `self` is the integer sort. + """Return `True` if `self` is of the sort Real. >>> x = Real('x') >>> x.is_real() @@ -1749,7 +1763,7 @@ class ArithSortRef(SortRef): return self.kind() == Z3_REAL_SORT def is_int(self): - """Return `True` if `self` is the real sort. + """Return `True` if `self` is of the sort Integer. >>> x = Int('x') >>> x.is_int() @@ -4384,8 +4398,8 @@ def args2params(arguments, keywords, ctx=None): """Convert python arguments into a Z3_params object. A ':' is added to the keywords, and '_' is replaced with '-' - >>> args2params([':model', True, ':relevancy', 2], {'elim_and' : True}) - (params :model 1 :relevancy 2 :elim-and 1) + >>> args2params(['model', True, 'relevancy', 2], {'elim_and' : True}) + (params model 1 relevancy 2 elim_and 1) """ if __debug__: _z3_assert(len(arguments) % 2 == 0, "Argument list must have an even number of elements.") @@ -4398,7 +4412,6 @@ def args2params(arguments, keywords, ctx=None): r.set(prev, a) prev = None for k, v in keywords.iteritems(): - k = ':' + k.replace('_', '-') r.set(k, v) return r @@ -5774,8 +5787,15 @@ class Solver(Z3PPObject): >>> s.assert_and_track(x < 0, p3) >>> print s.check() unsat - >>> print s.unsat_core() - [p3, p1] + >>> c = s.unsat_core() + >>> len(c) + 2 + >>> Bool('p1') in c + True + >>> Bool('p2') in c + False + >>> p3 in c + True """ if isinstance(p, str): p = Bool(p, self.ctx) @@ -6972,9 +6992,9 @@ def solve(*args, **keywords): configure it using the options in `keywords`, adds the constraints in `args`, and invokes check. - >>> a, b = Ints('a b') - >>> solve(a + b == 3, Or(a == 0, a == 1), a != 0) - [b = 2, a = 1] + >>> a = Int('a') + >>> solve(a > 0, a < 2) + [a = 1] """ s = Solver() s.set(**keywords) diff --git a/src/api/z3_api.h b/src/api/z3_api.h index 9570af43b..49d59e125 100644 --- a/src/api/z3_api.h +++ b/src/api/z3_api.h @@ -1233,25 +1233,99 @@ extern "C" { #endif // CAMLIDL #ifdef CorML3 + /** + @name Configuration + */ + + /*@{*/ + /** + \brief Set a global (or module) parameter. + This setting is shared by all Z3 contexts. + + When a Z3 module is initialized it will use the value of these parameters + when Z3_params objects are not provided. + + The name of parameter can be composed of characters [a-z][A-Z], digits [0-9], '-' and '_'. + The character '.' is a delimiter (more later). + + The parameter names are case-insensitive. The character '-' should be viewed as an "alias" for '_'. + Thus, the following parameter names are considered equivalent: "pp.decimal-precision" and "PP.DECIMAL_PRECISION". + + This function can be used to set parameters for a specific Z3 module. + This can be done by using .. + For example: + Z3_global_param_set('pp.decimal', 'true') + will set the parameter "decimal" in the module "pp" to true. + + def_API('Z3_global_param_set', VOID, (_in(STRING), _in(STRING))) + */ + void Z3_API Z3_global_param_set(__in Z3_string param_id, __in Z3_string param_value); + + + /** + \brief Restore the value of all global (and module) parameters. + This command will not affect already created objects (such as tactics and solvers). + + \sa Z3_global_param_set + + def_API('Z3_global_param_reset_all', VOID, ()) + */ + void Z3_API Z3_global_param_reset_all(); + + /** + \brief Get a global (or module) parameter. + + Returns \mlonly \c None \endmlonly \conly \c Z3_FALSE + if the parameter value does not exist. + + \sa Z3_global_param_set + + The caller must invoke #Z3_global_param_del_value to delete the value returned at \c param_value. + + \remark This function cannot be invoked simultaneously from different threads without synchronization. + The result string stored in param_value is stored in shared location. + + def_API('Z3_global_param_get', BOOL, (_in(STRING), _out(STRING))) + */ + Z3_bool_opt Z3_API Z3_global_param_get(__in Z3_string param_id, __out_opt Z3_string_ptr param_value); + + /*@}*/ + /** @name Create configuration */ /*@{*/ /** - \brief Create a configuration. + \brief Create a configuration object for the Z3 context object. Configurations are created in order to assign parameters prior to creating - contexts for Z3 interaction. For example, if the users wishes to use model + contexts for Z3 interaction. For example, if the users wishes to use proof generation, then call: - \ccode{Z3_set_param_value(cfg\, "MODEL"\, "true")} + \ccode{Z3_set_param_value(cfg\, "proof"\, "true")} \mlonly \remark Consider using {!mk_context_x} instead of using explicit configuration objects. The function {!mk_context_x} receives an array of string pairs. This array represents the configuration options. \endmlonly + \remark In previous versions of Z3, the \c Z3_config was used to store + global and module configurations. Now, we should use \c Z3_global_param_set. + + The following parameters can be set: + + - proof (Boolean) Enable proof generation + - debug_ref_count (Boolean) Enable debug support for Z3_ast reference counting + - trace (Boolean) Tracing support for VCC + - trace_file_name (String) Trace out file for VCC traces + - timeout (unsigned) default timeout (in milliseconds) used for solvers + - well_sorted_check type checker + - auto_config use heuristics to automatically select solver and configure it + - model model generation for solvers, this parameter can be overwritten when creating a solver + - model_validate validate models produced by solvers + - unsat_core unsat-core generation for solvers, this parameter can be overwritten when creating a solver + \sa Z3_set_param_value \sa Z3_del_config @@ -1271,18 +1345,14 @@ extern "C" { /** \brief Set a configuration parameter. - The list of all configuration parameters can be obtained using the Z3 executable: - - \verbatim - z3.exe -ini? - \endverbatim + The following parameters can be set for \sa Z3_mk_config def_API('Z3_set_param_value', VOID, (_in(CONFIG), _in(STRING), _in(STRING))) */ void Z3_API Z3_set_param_value(__in Z3_config c, __in Z3_string param_id, __in Z3_string param_value); - + /*@}*/ #endif @@ -1367,33 +1437,18 @@ extern "C" { #endif /** - \brief Update a mutable configuration parameter. + \brief Set a value of a context parameter. - The list of all configuration parameters can be obtained using the Z3 executable: - - \verbatim - z3.exe -ini? - \endverbatim - - Only a few configuration parameters are mutable once the context is created. - The error handler is invoked when trying to modify an immutable parameter. - - \conly \sa Z3_set_param_value - \mlonly \sa Z3_mk_context \endmlonly + \sa Z3_global_param_set def_API('Z3_update_param_value', VOID, (_in(CONTEXT), _in(STRING), _in(STRING))) */ void Z3_API Z3_update_param_value(__in Z3_context c, __in Z3_string param_id, __in Z3_string param_value); /** - \brief Get a configuration parameter. + \brief Return the value of a context parameter. - Returns \mlonly \c None \endmlonly \conly \c Z3_FALSE - if the parameter value does not exist. - - \conly \sa Z3_mk_config - \conly \sa Z3_set_param_value - \mlonly \sa Z3_mk_context \endmlonly + \sa Z3_global_param_get def_API('Z3_get_param_value', BOOL, (_in(CONTEXT), _in(STRING), _out(STRING))) */ @@ -1663,7 +1718,7 @@ extern "C" { use the APIs for creating numerals and pass a numeric constant together with the sort returned by this call. - \sa Z3_get_finite_domain_sort_size. + \sa Z3_get_finite_domain_sort_size def_API('Z3_mk_finite_domain_sort', SORT, (_in(CONTEXT), _in(SYMBOL), _in(UINT64))) */ diff --git a/src/api/z3_replayer.cpp b/src/api/z3_replayer.cpp index b41ef876c..079516145 100644 --- a/src/api/z3_replayer.cpp +++ b/src/api/z3_replayer.cpp @@ -232,8 +232,11 @@ struct z3_replayer::imp { } void read_ptr() { - if (!(('0' <= curr() && curr() <= '9') || ('A' <= curr() && curr() <= 'F') || ('a' <= curr() && curr() <= 'f'))) + if (!(('0' <= curr() && curr() <= '9') || ('A' <= curr() && curr() <= 'F') || ('a' <= curr() && curr() <= 'f'))) { + TRACE("invalid_ptr", tout << "curr: " << curr() << "\n";); throw z3_replayer_exception("invalid ptr"); + } + unsigned pos = 0; m_ptr = 0; while (true) { char c = curr(); @@ -246,10 +249,13 @@ struct z3_replayer::imp { else if ('A' <= c && c <= 'F') { m_ptr = m_ptr * 16 + 10 + (c - 'A'); } + else if (pos == 1 && (c == 'x' || c == 'X')) { + // support for 0x.... notation + } else { return; } - next(); + next(); pos++; } } diff --git a/src/ast/array_decl_plugin.h b/src/ast/array_decl_plugin.h index bd1e123e3..68c473560 100644 --- a/src/ast/array_decl_plugin.h +++ b/src/ast/array_decl_plugin.h @@ -144,7 +144,21 @@ public: bool is_map(expr* n) const { return is_app_of(n, m_fid, OP_ARRAY_MAP); } bool is_as_array(expr * n) const { return is_app_of(n, m_fid, OP_AS_ARRAY); } bool is_as_array_tree(expr * n); + bool is_select(func_decl* f) const { return is_decl_of(f, m_fid, OP_SELECT); } + bool is_store(func_decl* f) const { return is_decl_of(f, m_fid, OP_STORE); } + bool is_const(func_decl* f) const { return is_decl_of(f, m_fid, OP_CONST_ARRAY); } + bool is_map(func_decl* f) const { return is_decl_of(f, m_fid, OP_ARRAY_MAP); } + bool is_as_array(func_decl* f) const { return is_decl_of(f, m_fid, OP_AS_ARRAY); } func_decl * get_as_array_func_decl(app * n) const { SASSERT(is_as_array(n)); return to_func_decl(n->get_decl()->get_parameter(0).get_ast()); } + + app * mk_store(unsigned num_args, expr * const * args) { + return m_manager.mk_app(m_fid, OP_STORE, 0, 0, num_args, args); + } + + app * mk_select(unsigned num_args, expr * const * args) { + return m_manager.mk_app(m_fid, OP_SELECT, 0, 0, num_args, args); + } + app * mk_map(func_decl * f, unsigned num_args, expr * const * args) { parameter p(f); return m_manager.mk_app(m_fid, OP_ARRAY_MAP, 1, &p, num_args, args); diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 3c98dca33..ae82dcadf 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -1196,13 +1196,36 @@ decl_plugin * user_sort_plugin::mk_fresh() { // // ----------------------------------- -ast_manager::ast_manager(proof_gen_mode m, std::ostream *trace_stream, bool is_format_manager): +ast_manager::ast_manager(proof_gen_mode m, char const * trace_file, bool is_format_manager): m_alloc("ast_manager"), m_expr_array_manager(*this, m_alloc), m_expr_dependency_manager(*this, m_alloc), m_expr_dependency_array_manager(*this, m_alloc), m_proof_mode(m), - m_trace_stream(trace_stream) { + m_trace_stream(0), + m_trace_stream_owner(false) { + + if (trace_file) { + m_trace_stream = alloc(std::fstream, trace_file, std::ios_base::out); + m_trace_stream_owner = true; + } + + if (!is_format_manager) + m_format_manager = alloc(ast_manager, PGM_DISABLED, m_trace_stream, true); + else + m_format_manager = 0; + init(); +} + +ast_manager::ast_manager(proof_gen_mode m, std::fstream * trace_stream, bool is_format_manager): + m_alloc("ast_manager"), + m_expr_array_manager(*this, m_alloc), + m_expr_dependency_manager(*this, m_alloc), + m_expr_dependency_array_manager(*this, m_alloc), + m_proof_mode(m), + m_trace_stream(trace_stream), + m_trace_stream_owner(false) { + if (!is_format_manager) m_format_manager = alloc(ast_manager, PGM_DISABLED, trace_stream, true); else @@ -1216,9 +1239,10 @@ ast_manager::ast_manager(ast_manager const & src, bool disable_proofs): m_expr_dependency_manager(*this, m_alloc), m_expr_dependency_array_manager(*this, m_alloc), m_proof_mode(disable_proofs ? PGM_DISABLED : src.m_proof_mode), - m_trace_stream(src.m_trace_stream) { + m_trace_stream(src.m_trace_stream), + m_trace_stream_owner(false) { SASSERT(!src.is_format_manager()); - m_format_manager = 0; + m_format_manager = alloc(ast_manager, PGM_DISABLED, m_trace_stream, true); init(); copy_families_plugins(src); } @@ -1256,6 +1280,7 @@ void ast_manager::init() { ast_manager::~ast_manager() { SASSERT(is_format_manager() || !m_family_manager.has_family(symbol("format"))); + dec_ref(m_bool_sort); dec_ref(m_proof_sort); dec_ref(m_true); @@ -1294,6 +1319,13 @@ ast_manager::~ast_manager() { #endif if (m_format_manager != 0) dealloc(m_format_manager); + if (m_trace_stream_owner) { + std::fstream & tmp = * m_trace_stream; + tmp << "[eof]\n"; + tmp.close(); + dealloc(m_trace_stream); + m_trace_stream = 0; + } } void ast_manager::compact_memory() { @@ -1873,8 +1905,8 @@ app * ast_manager::mk_app_core(func_decl * decl, unsigned num_args, expr * const new_node = new (mem) app(decl, num_args, args); r = register_node(new_node); } -#ifndef SMTCOMP - if (m_trace_stream != NULL && r == new_node) { + + if (m_trace_stream && r == new_node) { *m_trace_stream << "[mk-app] #" << r->get_id() << " "; if (r->get_num_args() == 0 && r->get_decl()->get_name() == "int") { ast_ll_pp(*m_trace_stream, *this, r); @@ -1887,7 +1919,7 @@ app * ast_manager::mk_app_core(func_decl * decl, unsigned num_args, expr * const *m_trace_stream << "\n"; } } -#endif + return r; } @@ -2064,8 +2096,7 @@ quantifier * ast_manager::mk_quantifier(bool forall, unsigned num_decls, sort * num_no_patterns, no_patterns); quantifier * r = register_node(new_node); -#ifndef SMTCOMP - if (m_trace_stream != NULL && r == new_node) { + if (m_trace_stream && r == new_node) { *m_trace_stream << "[mk-quant] #" << r->get_id() << " " << qid; for (unsigned i = 0; i < num_patterns; ++i) { *m_trace_stream << " #" << patterns[i]->get_id(); @@ -2073,7 +2104,7 @@ quantifier * ast_manager::mk_quantifier(bool forall, unsigned num_decls, sort * *m_trace_stream << " #" << body->get_id() << "\n"; } -#endif + return r; } @@ -2637,12 +2668,13 @@ proof * ast_manager::mk_unit_resolution(unsigned num_proofs, proof * const * pro ptr_buffer args; args.append(num_proofs, (expr**) proofs); expr * fact; - expr const * f1 = get_fact(proofs[0]); - expr const * f2 = get_fact(proofs[1]); + expr * f1 = get_fact(proofs[0]); + expr * f2 = get_fact(proofs[1]); if (num_proofs == 2 && is_complement(f1, f2)) { fact = mk_false(); } else { + CTRACE("mk_unit_resolution_bug", !is_or(f1), tout << mk_pp(f1, *this) << " " << mk_pp(f2, *this) << "\n";); SASSERT(is_or(f1)); ptr_buffer new_lits; app const * cls = to_app(f1); diff --git a/src/ast/ast.h b/src/ast/ast.h index 8453598f2..2a0872721 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -1350,7 +1350,8 @@ protected: unsigned m_fresh_id; bool m_debug_ref_count; u_map m_debug_free_indices; - std::ostream* m_trace_stream; + std::fstream* m_trace_stream; + bool m_trace_stream_owner; #ifdef Z3DEBUG bool slow_not_contains(ast const * n); #endif @@ -1361,10 +1362,14 @@ protected: bool coercion_needed(func_decl * decl, unsigned num_args, expr * const * args); public: - ast_manager(proof_gen_mode = PGM_DISABLED, std::ostream * trace_stream = NULL, bool is_format_manager = false); + ast_manager(proof_gen_mode = PGM_DISABLED, char const * trace_file = 0, bool is_format_manager = false); + ast_manager(proof_gen_mode, std::fstream * trace_stream, bool is_format_manager = false); ast_manager(ast_manager const & src, bool disable_proofs = false); ~ast_manager(); + bool has_trace_stream() const { return m_trace_stream != 0; } + std::ostream & trace_stream() { SASSERT(has_trace_stream()); return *m_trace_stream; } + void enable_int_real_coercions(bool f) { m_int_real_coercions = f; } bool int_real_coercions() const { return m_int_real_coercions; } diff --git a/src/ast/ast_pp.h b/src/ast/ast_pp.h index d99fb7670..7e7bdfc4e 100644 --- a/src/ast/ast_pp.h +++ b/src/ast/ast_pp.h @@ -24,7 +24,7 @@ Revision History: #include"ast_smt2_pp.h" struct mk_pp : public mk_ismt2_pp { - mk_pp(ast * t, ast_manager & m, pp_params const & p, unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0): + mk_pp(ast * t, ast_manager & m, params_ref const & p, unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0): mk_ismt2_pp(t, m, p, indent, num_vars, var_prefix) { } mk_pp(ast * t, ast_manager & m, unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0): diff --git a/src/ast/ast_printer.cpp b/src/ast/ast_printer.cpp index 33ddcb709..8d6ed91f7 100644 --- a/src/ast/ast_printer.cpp +++ b/src/ast/ast_printer.cpp @@ -33,14 +33,14 @@ public: virtual void display(std::ostream & out, func_decl * f, unsigned indent = 0) const { out << f->get_name(); } - virtual void pp(sort * s, format_ns::format_ref & r) const { mk_smt2_format(s, env(), get_pp_default_params(), r); } - virtual void pp(func_decl * f, format_ns::format_ref & r) const { mk_smt2_format(f, env(), get_pp_default_params(), r); } + virtual void pp(sort * s, format_ns::format_ref & r) const { mk_smt2_format(s, env(), params_ref(), r); } + virtual void pp(func_decl * f, format_ns::format_ref & r) const { mk_smt2_format(f, env(), params_ref(), r); } virtual void pp(expr * n, format_ns::format_ref & r) const { sbuffer buf; - mk_smt2_format(n, env(), get_pp_default_params(), 0, 0, r, buf); + mk_smt2_format(n, env(), params_ref(), 0, 0, r, buf); } virtual void pp(expr * n, unsigned num_vars, char const * var_prefix, format_ns::format_ref & r, sbuffer & var_names) const { - mk_smt2_format(n, env(), get_pp_default_params(), num_vars, var_prefix, r, var_names); + mk_smt2_format(n, env(), params_ref(), num_vars, var_prefix, r, var_names); } virtual void display(std::ostream & out, expr * n, unsigned indent, unsigned num_vars, char const * var_prefix, sbuffer & var_names) const { NOT_IMPLEMENTED_YET(); diff --git a/src/ast/ast_smt2_pp.cpp b/src/ast/ast_smt2_pp.cpp index dcc7a1a0d..afe301ddf 100644 --- a/src/ast/ast_smt2_pp.cpp +++ b/src/ast/ast_smt2_pp.cpp @@ -24,6 +24,7 @@ Revision History: #include"ast_ll_pp.h" #include"ast_pp.h" #include"algebraic_numbers.h" +#include"pp_params.hpp" using namespace format_ns; #define ALIAS_PREFIX "a" @@ -376,7 +377,6 @@ typedef app_ref_vector format_ref_vector; class smt2_printer { ast_manager & m_manager; - pp_params const & m_params; smt2_pp_environment & m_env; shared_occs m_soccs; @@ -421,6 +421,16 @@ class smt2_printer { string_buffer<> m_next_name_buffer; + // Config + bool m_pp_decimal; + unsigned m_pp_decimal_precision; + bool m_pp_bv_lits; + bool m_pp_bv_neg; + unsigned m_pp_max_depth; + unsigned m_pp_min_alias_size; + bool m_pp_flat_assoc; + + symbol next_name(char const * prefix, unsigned & idx) { while (true) { m_next_name_buffer.reset(); @@ -508,10 +518,10 @@ class smt2_printer { void pp_const(app * c) { format * f; if (m_env.get_autil().is_numeral(c) || m_env.get_autil().is_irrational_algebraic_numeral(c)) { - f = m_env.pp_arith_literal(c, m_params.m_pp_decimal, m_params.m_pp_decimal_precision); + f = m_env.pp_arith_literal(c, m_pp_decimal, m_pp_decimal_precision); } else if (m_env.get_bvutil().is_numeral(c)) { - f = m_env.pp_bv_literal(c, m_params.m_pp_bv_lits, m_params.m_pp_bv_neg); + f = m_env.pp_bv_literal(c, m_pp_bv_lits, m_pp_bv_neg); } else if (m_env.get_futil().is_value(c)) { f = m_env.pp_float_literal(c); @@ -584,8 +594,8 @@ class smt2_printer { m_format_stack.shrink(fr.m_spos); m_info_stack.shrink(fr.m_spos); if (fr.m_use_alias && m_root != t && - ((f_info.m_depth >= m_params.m_pp_max_depth) || - ((f_info.m_weight >= m_params.m_pp_min_alias_size || is_quantifier(t)) && m_soccs.is_shared(t)))) { + ((f_info.m_depth >= m_pp_max_depth) || + ((f_info.m_weight >= m_pp_min_alias_size || is_quantifier(t)) && m_soccs.is_shared(t)))) { symbol a = next_alias(); TRACE("smt2_pp", tout << "a: " << a << " depth: " << f_info.m_depth << ", weight: " << f_info.m_weight << ", lvl: " << f_info.m_lvl << " t: #" << t->get_id() << "\n" << mk_ll_pp(t, m()) @@ -602,7 +612,7 @@ class smt2_printer { } bool flat_assoc(app * t, frame const & fr) { - if (!m_params.m_pp_flat_assoc) + if (!m_pp_flat_assoc) return false; func_decl * f = t->get_decl(); if (f->is_associative() && m_frame_stack.size() >= 2 && !m_soccs.is_shared(t)) { @@ -943,9 +953,8 @@ class smt2_printer { } public: - smt2_printer(smt2_pp_environment & env, pp_params const & params): + smt2_printer(smt2_pp_environment & env, params_ref const & params): m_manager(env.get_manager()), - m_params(params), m_env(env), m_soccs(m_manager), m_root(0), @@ -953,6 +962,15 @@ public: m_next_alias_idx(1), m_format_stack(fm()) { init_expr2alias_stack(); + + pp_params p(params); + m_pp_decimal = p.decimal(); + m_pp_decimal_precision = p.decimal_precision(); + m_pp_bv_lits = p.bv_literals(); + m_pp_bv_neg = p.bv_neg(); + m_pp_max_depth = p.max_depth(); + m_pp_min_alias_size = p.min_alias_size(); + m_pp_flat_assoc = p.flat_assoc(); } ~smt2_printer() { @@ -1003,24 +1021,24 @@ public: }; -void mk_smt2_format(expr * n, smt2_pp_environment & env, pp_params const & p, +void mk_smt2_format(expr * n, smt2_pp_environment & env, params_ref const & p, unsigned num_vars, char const * var_prefix, format_ref & r, sbuffer & var_names) { smt2_printer pr(env, p); pr(n, num_vars, var_prefix, r, var_names); } -void mk_smt2_format(sort * s, smt2_pp_environment & env, pp_params const & p, format_ref & r) { +void mk_smt2_format(sort * s, smt2_pp_environment & env, params_ref const & p, format_ref & r) { smt2_printer pr(env, p); pr(s, r); } -void mk_smt2_format(func_decl * f, smt2_pp_environment & env, pp_params const & p, format_ref & r) { +void mk_smt2_format(func_decl * f, smt2_pp_environment & env, params_ref const & p, format_ref & r) { smt2_printer pr(env, p); pr(f, r); } -std::ostream & ast_smt2_pp(std::ostream & out, expr * n, smt2_pp_environment & env, pp_params const & p, unsigned indent, +std::ostream & ast_smt2_pp(std::ostream & out, expr * n, smt2_pp_environment & env, params_ref const & p, unsigned indent, unsigned num_vars, char const * var_prefix) { ast_manager & m = env.get_manager(); format_ref r(fm(m)); @@ -1032,7 +1050,7 @@ std::ostream & ast_smt2_pp(std::ostream & out, expr * n, smt2_pp_environment & e return out; } -std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & env, pp_params const & p, unsigned indent) { +std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & env, params_ref const & p, unsigned indent) { ast_manager & m = env.get_manager(); format_ref r(fm(m)); sbuffer var_names; @@ -1043,7 +1061,7 @@ std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & e return out; } -std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, pp_params const & p, unsigned indent) { +std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, params_ref const & p, unsigned indent) { ast_manager & m = env.get_manager(); format_ref r(fm(m)); sbuffer var_names; @@ -1054,7 +1072,7 @@ std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environmen return out; } -mk_ismt2_pp::mk_ismt2_pp(ast * t, ast_manager & m, pp_params const & p, unsigned indent, unsigned num_vars, char const * var_prefix): +mk_ismt2_pp::mk_ismt2_pp(ast * t, ast_manager & m, params_ref const & p, unsigned indent, unsigned num_vars, char const * var_prefix): m_ast(t), m_manager(m), m_params(p), @@ -1066,7 +1084,7 @@ mk_ismt2_pp::mk_ismt2_pp(ast * t, ast_manager & m, pp_params const & p, unsigned mk_ismt2_pp::mk_ismt2_pp(ast * t, ast_manager & m, unsigned indent, unsigned num_vars, char const * var_prefix): m_ast(t), m_manager(m), - m_params(get_pp_default_params()), + m_params(m_empty), m_indent(indent), m_num_vars(num_vars), m_var_prefix(var_prefix) { diff --git a/src/ast/ast_smt2_pp.h b/src/ast/ast_smt2_pp.h index 048dd8d67..aa84d6e03 100644 --- a/src/ast/ast_smt2_pp.h +++ b/src/ast/ast_smt2_pp.h @@ -23,7 +23,7 @@ Revision History: #define _AST_SMT2_PP_H_ #include"format.h" -#include"pp_params.h" +#include"params.h" #include"arith_decl_plugin.h" #include"bv_decl_plugin.h" #include"array_decl_plugin.h" @@ -82,28 +82,29 @@ public: virtual bool uses(symbol const & s) const { return false; } }; -void mk_smt2_format(expr * n, smt2_pp_environment & env, pp_params const & p, +void mk_smt2_format(expr * n, smt2_pp_environment & env, params_ref const & p, unsigned num_vars, char const * var_prefix, format_ns::format_ref & r, sbuffer & var_names); -void mk_smt2_format(sort * s, smt2_pp_environment & env, pp_params const & p, format_ns::format_ref & r); -void mk_smt2_format(func_decl * f, smt2_pp_environment & env, pp_params const & p, format_ns::format_ref & r); +void mk_smt2_format(sort * s, smt2_pp_environment & env, params_ref const & p, format_ns::format_ref & r); +void mk_smt2_format(func_decl * f, smt2_pp_environment & env, params_ref const & p, format_ns::format_ref & r); -std::ostream & ast_smt2_pp(std::ostream & out, expr * n, smt2_pp_environment & env, pp_params const & p, unsigned indent = 0, +std::ostream & ast_smt2_pp(std::ostream & out, expr * n, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0); -std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & env, pp_params const & p, unsigned indent = 0); -std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, pp_params const & p, unsigned indent = 0); +std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0); +std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0); /** \brief Internal wrapper (for debugging purposes only) */ struct mk_ismt2_pp { - ast * m_ast; - ast_manager & m_manager; - pp_params const & m_params; - unsigned m_indent; - unsigned m_num_vars; - char const * m_var_prefix; - mk_ismt2_pp(ast * t, ast_manager & m, pp_params const & p, unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0); + ast * m_ast; + ast_manager & m_manager; + params_ref m_empty; + params_ref const & m_params; + unsigned m_indent; + unsigned m_num_vars; + char const * m_var_prefix; + mk_ismt2_pp(ast * t, ast_manager & m, params_ref const & p, unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0); mk_ismt2_pp(ast * t, ast_manager & m, unsigned indent = 0, unsigned num_vars = 0, char const * var_prefix = 0); }; diff --git a/src/ast/ast_smt_pp.cpp b/src/ast/ast_smt_pp.cpp index 713727f05..78a1caf68 100644 --- a/src/ast/ast_smt_pp.cpp +++ b/src/ast/ast_smt_pp.cpp @@ -67,8 +67,13 @@ symbol smt_renaming::fix_symbol(symbol s, int k) { buffer << s << k; return symbol(buffer.str().c_str()); } - - buffer << mk_smt2_quoted_symbol(s); + + if (is_smt2_quoted_symbol(s)) { + buffer << mk_smt2_quoted_symbol(s); + } + else { + buffer << s; + } if (k > 0) { buffer << k; } @@ -949,6 +954,10 @@ public: mark.mark(s, true); } + void operator()(sort* s) { + ast_mark mark; + pp_sort_decl(mark, s); + } void operator()(func_decl* d) { if (m_is_smt2) { @@ -962,7 +971,6 @@ public: m_out << ") "; visit_sort(d->get_range()); m_out << ")"; - newline(); } else { m_out << "("; @@ -1021,6 +1029,22 @@ void ast_smt_pp::display_expr_smt2(std::ostream& strm, expr* n, unsigned indent, p(n); } +void ast_smt_pp::display_ast_smt2(std::ostream& strm, ast* a, unsigned indent, unsigned num_var_names, char const* const* var_names) { + ptr_vector ql; + smt_renaming rn; + smt_printer p(strm, m_manager, ql, rn, m_logic, false, true, m_simplify_implies, indent, num_var_names, var_names); + if (is_expr(a)) { + p(to_expr(a)); + } + else if (is_func_decl(a)) { + p(to_func_decl(a)); + } + else { + SASSERT(is_sort(a)); + p(to_sort(a)); + } +} + void ast_smt_pp::display_smt2(std::ostream& strm, expr* n) { ptr_vector ql; @@ -1071,6 +1095,7 @@ void ast_smt_pp::display_smt2(std::ostream& strm, expr* n) { if (!(*m_is_declared)(d)) { smt_printer p(strm, m_manager, ql, rn, m_logic, true, true, m_simplify_implies, 0); p(d); + strm << "\n"; } } @@ -1079,6 +1104,7 @@ void ast_smt_pp::display_smt2(std::ostream& strm, expr* n) { if (!(*m_is_declared)(d)) { smt_printer p(strm, m_manager, ql, rn, m_logic, true, true, m_simplify_implies, 0); p(d); + strm << "\n"; } } diff --git a/src/ast/ast_smt_pp.h b/src/ast/ast_smt_pp.h index 36d4ced2e..97527759a 100644 --- a/src/ast/ast_smt_pp.h +++ b/src/ast/ast_smt_pp.h @@ -79,22 +79,23 @@ public: void display_smt2(std::ostream& strm, expr* n); void display_expr(std::ostream& strm, expr* n); void display_expr_smt2(std::ostream& strm, expr* n, unsigned indent = 0, unsigned num_var_names = 0, char const* const* var_names = 0); + void display_ast_smt2(std::ostream& strm, ast* n, unsigned indent = 0, unsigned num_var_names = 0, char const* const* var_names = 0); }; struct mk_smt_pp { - expr * m_expr; + ast* m_ast; ast_manager& m_manager; unsigned m_indent; unsigned m_num_var_names; char const* const* m_var_names; - mk_smt_pp(expr* e, ast_manager & m, unsigned indent = 0, unsigned num_var_names = 0, char const* const* var_names = 0) : - m_expr(e), m_manager(m), m_indent(indent), m_num_var_names(num_var_names), m_var_names(var_names) {} + mk_smt_pp(ast* e, ast_manager & m, unsigned indent = 0, unsigned num_var_names = 0, char const* const* var_names = 0) : + m_ast(e), m_manager(m), m_indent(indent), m_num_var_names(num_var_names), m_var_names(var_names) {} }; inline std::ostream& operator<<(std::ostream& out, const mk_smt_pp & p) { ast_smt_pp pp(p.m_manager); - pp.display_expr_smt2(out, p.m_expr, p.m_indent, p.m_num_var_names, p.m_var_names); + pp.display_ast_smt2(out, p.m_ast, p.m_indent, p.m_num_var_names, p.m_var_names); return out; } diff --git a/src/ast/dl_decl_plugin.cpp b/src/ast/dl_decl_plugin.cpp index 76f34f316..5b73f944a 100644 --- a/src/ast/dl_decl_plugin.cpp +++ b/src/ast/dl_decl_plugin.cpp @@ -44,8 +44,7 @@ namespace datalog { m_num_sym("N"), m_lt_sym("<"), m_le_sym("<="), - m_rule_sym("R"), - m_hyper_resolve_sym("hyper-res") + m_rule_sym("R") { } diff --git a/src/ast/dl_decl_plugin.h b/src/ast/dl_decl_plugin.h index 6e824b639..32e3c6da9 100644 --- a/src/ast/dl_decl_plugin.h +++ b/src/ast/dl_decl_plugin.h @@ -69,7 +69,6 @@ namespace datalog { symbol m_lt_sym; symbol m_le_sym; symbol m_rule_sym; - symbol m_hyper_resolve_sym; bool check_bounds(char const* msg, unsigned low, unsigned up, unsigned val) const; bool check_domain(unsigned low, unsigned up, unsigned val) const; @@ -93,7 +92,6 @@ namespace datalog { func_decl * mk_compare(decl_kind k, symbol const& sym, sort*const* domain); func_decl * mk_clone(sort* r); func_decl * mk_rule(unsigned arity); - func_decl * mk_hyper_res(unsigned num_params, parameter const* params, unsigned arity, sort *const* domain); sort * mk_finite_sort(unsigned num_params, parameter const* params); sort * mk_relation_sort(unsigned num_params, parameter const* params); diff --git a/src/ast/float_decl_plugin.cpp b/src/ast/float_decl_plugin.cpp index 7cf8f32bd..dbe7d5232 100644 --- a/src/ast/float_decl_plugin.cpp +++ b/src/ast/float_decl_plugin.cpp @@ -348,13 +348,13 @@ func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters, // When the bv_decl_plugin is installed, then we know how to convert 3 bit-vectors into a float! sort * fp = mk_float_sort(domain[2]->get_parameter(0).get_int(), domain[1]->get_parameter(0).get_int()+1); symbol name("asFloat"); - return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters)); - } + return m_manager->mk_func_decl(name, arity, domain, fp, func_decl_info(m_family_id, k, num_parameters, parameters)); + } else { // .. Otherwise we only know how to convert rationals/reals. if (!(num_parameters == 2 && parameters[0].is_int() && parameters[1].is_int())) m_manager->raise_exception("expecting two integer parameters to asFloat"); - if (arity != 2 && arity != 3) + if (arity != 2 && arity != 3) m_manager->raise_exception("invalid number of arguments to asFloat operator"); if (!is_rm_sort(domain[0]) || domain[1] != m_real_sort) m_manager->raise_exception("sort mismatch"); @@ -373,6 +373,23 @@ func_decl * float_decl_plugin::mk_to_float(decl_kind k, unsigned num_parameters, } } +func_decl * float_decl_plugin::mk_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range) { + if (!m_bv_plugin) + m_manager->raise_exception("asIEEEBV unsupported; use a logic with BV support"); + if (arity != 1) + m_manager->raise_exception("invalid number of arguments to asIEEEBV"); + if (!is_float_sort(domain[0])) + m_manager->raise_exception("sort mismatch"); + + // When the bv_decl_plugin is installed, then we know how to convert a float to an IEEE bit-vector. + unsigned float_sz = domain[0]->get_parameter(0).get_int() + domain[0]->get_parameter(1).get_int(); + parameter ps[] = { parameter(float_sz) }; + sort * bv_srt = m_bv_plugin->mk_sort(m_bv_fid, 1, ps); + symbol name("asIEEEBV"); + return m_manager->mk_func_decl(name, 1, domain, bv_srt, func_decl_info(m_family_id, k, num_parameters, parameters)); +} + func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range) { switch (k) { @@ -420,6 +437,8 @@ func_decl * float_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters return mk_rm_unary_decl(k, num_parameters, parameters, arity, domain, range); case OP_FLOAT_FUSED_MA: return mk_fused_ma(k, num_parameters, parameters, arity, domain, range); + case OP_TO_IEEE_BV: + return mk_to_ieee_bv(k, num_parameters, parameters, arity, domain, range); default: m_manager->raise_exception("unsupported floating point operator"); return 0; @@ -462,7 +481,10 @@ void float_decl_plugin::get_op_names(svector & op_names, symbol co op_names.push_back(builtin_name("min", OP_FLOAT_MIN)); op_names.push_back(builtin_name("max", OP_FLOAT_MAX)); - op_names.push_back(builtin_name("asFloat", OP_TO_FLOAT)); + op_names.push_back(builtin_name("asFloat", OP_TO_FLOAT)); + + if (m_bv_plugin) + op_names.push_back(builtin_name("asIEEEBV", OP_TO_IEEE_BV)); } void float_decl_plugin::get_sort_names(svector & sort_names, symbol const & logic) { diff --git a/src/ast/float_decl_plugin.h b/src/ast/float_decl_plugin.h index 416275306..c4503349b 100644 --- a/src/ast/float_decl_plugin.h +++ b/src/ast/float_decl_plugin.h @@ -67,6 +67,7 @@ enum float_op_kind { OP_FLOAT_IS_SIGN_MINUS, OP_TO_FLOAT, + OP_TO_IEEE_BV, LAST_FLOAT_OP }; @@ -118,6 +119,8 @@ class float_decl_plugin : public decl_plugin { unsigned arity, sort * const * domain, sort * range); func_decl * mk_to_float(decl_kind k, unsigned num_parameters, parameter const * parameters, unsigned arity, sort * const * domain, sort * range); + func_decl * mk_to_ieee_bv(decl_kind k, unsigned num_parameters, parameter const * parameters, + unsigned arity, sort * const * domain, sort * range); virtual void set_manager(ast_manager * m, family_id id); unsigned mk_id(mpf const & v); @@ -159,7 +162,7 @@ class float_util { ast_manager & m_manager; float_decl_plugin * m_plugin; family_id m_fid; - arith_util m_a_util; + arith_util m_a_util; public: float_util(ast_manager & m); ~float_util(); @@ -209,7 +212,7 @@ public: bool is_to_float(expr * n) { return is_app_of(n, m_fid, OP_TO_FLOAT); } - app * mk_to_float(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_TO_FLOAT, arg1, arg2); } + app * mk_to_float(expr * arg1, expr * arg2) { return m().mk_app(m_fid, OP_TO_FLOAT, arg1, arg2); } app * mk_add(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_ADD, arg1, arg2, arg3); } app * mk_mul(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_MUL, arg1, arg2, arg3); } app * mk_sub(expr * arg1, expr * arg2, expr * arg3) { return m().mk_app(m_fid, OP_FLOAT_SUB, arg1, arg2, arg3); } @@ -238,6 +241,8 @@ public: app * mk_is_sign_minus(expr * arg1) { return m().mk_app(m_fid, OP_FLOAT_IS_SIGN_MINUS, arg1); } bool is_uminus(expr * a) { return is_app_of(a, m_fid, OP_FLOAT_UMINUS); } + + app * mk_to_ieee_bv(expr * arg1) { return m().mk_app(m_fid, OP_TO_IEEE_BV, arg1); } }; #endif diff --git a/src/ast/normal_forms/cnf.cpp b/src/ast/normal_forms/cnf.cpp deleted file mode 100644 index d454c7f00..000000000 --- a/src/ast/normal_forms/cnf.cpp +++ /dev/null @@ -1,524 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - cnf.cpp - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-01-23. - -Revision History: - ---*/ -#include"cnf.h" -#include"var_subst.h" -#include"ast_util.h" -#include"ast_pp.h" -#include"ast_ll_pp.h" - -unsigned cnf_entry::hash() const { - unsigned a = m_node->get_id(); - unsigned b = m_polarity; - unsigned c = m_in_q; - mix(a,b,c); - return c; -} - -bool cnf_entry::operator==(cnf_entry const & k) const { - return m_node == k.m_node && m_polarity == k.m_polarity && m_in_q == k.m_in_q; -} - -cnf_cache::cnf_cache(ast_manager & m): - m_manager(m) { -} - -void cnf_cache::insert(cnf_entry const & k, expr * r, proof * pr) { - SASSERT(!m_cache.contains(k)); - m_manager.inc_ref(r); - m_manager.inc_ref(pr); - m_cache.insert(k, expr_proof_pair(r, pr)); -} - -void cnf_cache::reset() { - cache::iterator it = m_cache.begin(); - cache::iterator end = m_cache.end(); - for (; it != end; ++it) { - expr_proof_pair & pair = (*it).m_value; - m_manager.dec_ref(pair.first); - m_manager.dec_ref(pair.second); - } - m_cache.reset(); -} - -void cnf::cache_result(expr * e, bool in_q, expr * r, proof * pr) { - SASSERT(r); - TRACE("cnf", tout << "caching result for: " << e->get_id() << " " << r->get_id() << "\n";); - m_cache.insert(cnf_entry(e, true, in_q), r, pr); -} - -void cnf::visit(expr * n, bool in_q, bool & visited) { - if (!is_cached(n, in_q)) { - m_todo.push_back(std::make_pair(n, in_q)); - visited = false; - } -} - -bool cnf::visit_children(expr * n, bool in_q) { - bool visited = true; - switch(n->get_kind()) { - case AST_APP: - if (m_manager.is_or(n) || m_manager.is_and(n) || m_manager.is_label(n)) { - unsigned j = to_app(n)->get_num_args(); - while (j > 0) { - --j; - visit(to_app(n)->get_arg(j), in_q, visited); - } - } - break; - case AST_QUANTIFIER: - visit(to_quantifier(n)->get_expr(), true, visited); - break; - default: - break; - } - return visited; -} - -void cnf::reduce1(expr * n, bool in_q) { - switch(n->get_kind()) { - case AST_APP: - if (m_manager.is_or(n)) - reduce1_or(to_app(n), in_q); - else if (m_manager.is_and(n)) - reduce1_and(to_app(n), in_q); - else if (m_manager.is_label(n)) - reduce1_label(to_app(n), in_q); - else - cache_result(n, in_q, n, 0); - break; - case AST_QUANTIFIER: - reduce1_quantifier(to_quantifier(n), in_q); - break; - default: - cache_result(n, in_q, n, 0); - break; - } -} - -void cnf::get_args(app * n, bool in_q, ptr_buffer & new_args, ptr_buffer & new_arg_prs) { - unsigned num = n->get_num_args(); - for (unsigned i = 0; i < num; i++) { - expr * new_arg = 0; - proof * new_arg_pr = 0; - get_cached(n->get_arg(i), in_q, new_arg, new_arg_pr); - SASSERT(new_arg); - new_args.push_back(new_arg); - if (new_arg_pr) - new_arg_prs.push_back(new_arg_pr); - } -} - -void cnf::flat_args(func_decl * d, ptr_buffer const & args, ptr_buffer & flat_args) { - ptr_buffer::const_iterator it = args.begin(); - ptr_buffer::const_iterator end = args.end(); - for (; it != end; ++it) { - expr * arg = *it; - if (is_app_of(arg, d)) - flat_args.append(to_app(arg)->get_num_args(), to_app(arg)->get_args()); - else - flat_args.push_back(arg); - } -} - -/** - \brief Return the approximated size of distributing OR over AND on - (OR args[0] .... args[sz-1]) -*/ -approx_nat cnf::approx_result_size_for_disj(ptr_buffer const & args) { - approx_nat r(1); - ptr_buffer::const_iterator it = args.begin(); - ptr_buffer::const_iterator end = args.end(); - for (; it != end; ++it) { - expr * arg = *it; - if (m_manager.is_and(arg)) - r *= to_app(arg)->get_num_args(); - } - return r; -} - -/** - \brief Return true if it is too expensive to process the disjunction of args -*/ -inline bool cnf::is_too_expensive(approx_nat approx_result_size, ptr_buffer const & args) { - // (OR A (AND B C)) is always considered cheap. - if (args.size() == 2 && (!m_manager.is_and(args[0]) || !m_manager.is_and(args[1]))) - return false; - return !(approx_result_size < m_params.m_cnf_factor); -} - -/** - \brief Create a (positive) name for the expressions of the form (AND ...) in args. - Store the result in new_args. -*/ -void cnf::name_args(ptr_buffer const & args, expr_ref_buffer & new_args, proof_ref_buffer & new_arg_prs) { - ptr_buffer::const_iterator it = args.begin(); - ptr_buffer::const_iterator end = args.end(); - for (; it != end; ++it) { - expr * arg = *it; - if (m_manager.is_and(arg)) { - expr_ref new_def(m_manager); - proof_ref new_def_pr(m_manager); - app_ref new_arg(m_manager); - proof_ref new_arg_pr(m_manager); - - if (m_defined_names.mk_pos_name(to_app(arg), new_def, new_def_pr, new_arg, new_arg_pr)) { - m_todo_defs.push_back(new_def); - if (m_manager.proofs_enabled()) - m_todo_proofs.push_back(new_def_pr); - } - new_args.push_back(new_arg); - - if (m_manager.fine_grain_proofs()) - new_arg_prs.push_back(new_arg_pr); - else - m_coarse_proofs.push_back(new_arg_pr); - } - else - new_args.push_back(arg); - } -} - -void cnf::distribute(app * n, app * & r, proof * & pr) { - SASSERT(m_manager.is_or(n)); - buffer sz; - buffer it; - ptr_buffer new_args; - unsigned num = n->get_num_args(); - for (unsigned i = 0; i < num; i++) { - expr * arg = n->get_arg(i); - it.push_back(0); - if (m_manager.is_and(arg)) - sz.push_back(to_app(arg)->get_num_args()); - else - sz.push_back(1); - } - - do { - ptr_buffer lits; - for (unsigned i = 0; i < num; i++) { - expr * arg = n->get_arg(i); - if (m_manager.is_and(arg)) { - SASSERT(it[i] < to_app(arg)->get_num_args()); - lits.push_back(to_app(arg)->get_arg(it[i])); - } - else { - SASSERT(it[i] == 0); - lits.push_back(arg); - } - } - app * n = m_manager.mk_or(lits.size(), lits.c_ptr()); - new_args.push_back(n); - } - while (product_iterator_next(sz.size(), sz.c_ptr(), it.c_ptr())); - SASSERT(!new_args.empty()); - if (new_args.size() == 1) - r = to_app(new_args[0]); - else - r = m_manager.mk_and(new_args.size(), new_args.c_ptr()); - pr = 0; - if (m_manager.fine_grain_proofs() && r != n) - pr = m_manager.mk_iff_oeq(m_manager.mk_distributivity(n, r)); -} - -void cnf::push_quant(quantifier * q, expr * & r, proof * & pr) { - SASSERT(is_forall(q)); - expr * e = q->get_expr(); - pr = 0; - if (m_manager.is_and(e)) { - expr_ref_buffer new_args(m_manager); - unsigned num = to_app(e)->get_num_args(); - for (unsigned i = 0; i < num; i++) { - quantifier_ref aux(m_manager); - aux = m_manager.update_quantifier(q, 0, 0, 0, 0, to_app(e)->get_arg(i)); - expr_ref new_arg(m_manager); - elim_unused_vars(m_manager, aux, new_arg); - new_args.push_back(new_arg); - } - r = m_manager.mk_and(new_args.size(), new_args.c_ptr()); - if (m_manager.fine_grain_proofs()) - pr = m_manager.mk_iff_oeq(m_manager.mk_push_quant(q, r)); - } - else { - r = q; - } -} - -void cnf::reduce1_or(app * n, bool in_q) { - ptr_buffer new_args; - ptr_buffer new_arg_prs; - get_args(n, in_q, new_args, new_arg_prs); - expr * r; - proof * pr = 0; - if (in_q || m_params.m_cnf_mode == CNF_OPPORTUNISTIC || m_params.m_cnf_mode == CNF_FULL) { - ptr_buffer f_args; - flat_args(n->get_decl(), new_args, f_args); - TRACE("cnf_or", for (unsigned i = 0; i < f_args.size(); i++) tout << mk_pp(f_args[i], m_manager) << "\n";); - approx_nat result_size = approx_result_size_for_disj(f_args); - TRACE("cnf_or", tout << mk_pp(n, m_manager) << "\napprox. result: " << result_size << "\n";); - if (m_params.m_cnf_mode != CNF_OPPORTUNISTIC || result_size < m_params.m_cnf_factor) { - expr_ref_buffer cheap_args(m_manager); - proof_ref_buffer cheap_args_pr(m_manager); - if (is_too_expensive(result_size, f_args)) { - name_args(f_args, cheap_args, cheap_args_pr); - } - else { - cheap_args.append(f_args.size(), f_args.c_ptr()); - } - - app_ref r1(m_manager); - r1 = m_manager.mk_or(cheap_args.size(), cheap_args.c_ptr()); - - // Proof gen support --------------------------- - // r1 is (OR cheap_args) it is only built if proofs are enabled. - // p1 is a proof for (= n r1) - proof * p1 = 0; - if (m_manager.fine_grain_proofs()) { - proof * prs[3]; - app * r[2]; - r[0] = m_manager.mk_or(new_args.size(), new_args.c_ptr()); - prs[0] = n == r[0] ? 0 : m_manager.mk_oeq_congruence(n, r[0], new_arg_prs.size(), new_arg_prs.c_ptr()); - r[1] = m_manager.mk_or(f_args.size(), f_args.c_ptr()); - prs[1] = r[0] == r[1] ? 0 : m_manager.mk_iff_oeq(m_manager.mk_rewrite(r[0], r[1])); - prs[2] = r[1] == r1 ? 0 : m_manager.mk_oeq_congruence(r[1], r1, cheap_args_pr.size(), cheap_args_pr.c_ptr()); - p1 = m_manager.mk_transitivity(3, prs); - } - // -------------------------------------------- - - expr_ref r2(m_manager); - proof_ref p2(m_manager); - m_pull.pull_quant2(r1, r2, p2); - - if (is_quantifier(r2)) { - expr * e = to_quantifier(r2)->get_expr(); - SASSERT(m_manager.is_or(e)); - app * d_r; - proof * d_pr; - distribute(to_app(e), d_r, d_pr); - quantifier_ref r3(m_manager); - r3 = m_manager.update_quantifier(to_quantifier(r2), d_r); - proof * push_pr; - push_quant(r3, r, push_pr); - if (m_manager.fine_grain_proofs()) { - // p1 is a proof of n == r1 - // p2 is a proof of r1 == r2 - p2 = p2 == 0 ? 0 : m_manager.mk_iff_oeq(p2); - proof * p3 = r2 == r3 ? 0 : m_manager.mk_oeq_quant_intro(to_quantifier(r2), r3, d_pr); - CTRACE("cnf_or", p1, tout << "p1:\n" << mk_pp(m_manager.get_fact(p1), m_manager) << "\n";); - CTRACE("cnf_or", p2, tout << "p2:\n" << mk_pp(m_manager.get_fact(p2), m_manager) << "\n";); - CTRACE("cnf_or", p3, tout << "p3:\n" << mk_pp(m_manager.get_fact(p3), m_manager) << "\n";); - TRACE("cnf_or", tout << "r2 == r3: " << (r2 == r3) << "\n" - << mk_pp(r2, m_manager) << "\n" << mk_pp(r3, m_manager) << "\n";); - pr = m_manager.mk_transitivity(p1, p2, p3, push_pr); - } - cache_result(n, in_q, r, pr); - } - else { - SASSERT(p2 == 0); - SASSERT(r1 == r2); - SASSERT(m_manager.is_or(r2)); - app * r3; - distribute(to_app(r2), r3, pr); - r = r3; - pr = m_manager.mk_transitivity(p1, pr); - cache_result(n, in_q, r, pr); - } - return; - } - } - - r = m_manager.mk_or(new_args.size(), new_args.c_ptr()); - if (m_manager.fine_grain_proofs() && n != r) - pr = m_manager.mk_oeq_congruence(n, to_app(r), new_arg_prs.size(), new_arg_prs.c_ptr()); - cache_result(n, in_q, r, pr); -} - -void cnf::reduce1_and(app * n, bool in_q) { - ptr_buffer new_args; - ptr_buffer new_arg_prs; - get_args(n, in_q, new_args, new_arg_prs); - app * r; - proof * pr = 0; - if (in_q || m_params.m_cnf_mode == CNF_OPPORTUNISTIC || m_params.m_cnf_mode == CNF_FULL) { - ptr_buffer f_args; - flat_args(n->get_decl(), new_args, f_args); - r = m_manager.mk_and(f_args.size(), f_args.c_ptr()); - if (m_manager.fine_grain_proofs() && n != r) { - app * r0 = m_manager.mk_and(new_args.size(), new_args.c_ptr()); - proof * p0 = r0 == n ? 0 : m_manager.mk_oeq_congruence(n, r0, new_arg_prs.size(), new_arg_prs.c_ptr()); - proof * p1 = r0 == r ? 0 : m_manager.mk_iff_oeq(m_manager.mk_rewrite(r0, r)); - pr = m_manager.mk_transitivity(p0, p1); - } - } - else { - r = m_manager.mk_and(new_args.size(), new_args.c_ptr()); - if (m_manager.fine_grain_proofs() && n != r) - pr = m_manager.mk_oeq_congruence(n, r, new_arg_prs.size(), new_arg_prs.c_ptr()); - } - cache_result(n, in_q, r, pr); -} - -void cnf::reduce1_label(app * n, bool in_q) { - expr * r; - proof * pr = 0; - expr * new_arg; - proof * new_arg_pr; - get_cached(n->get_arg(0), true, new_arg, new_arg_pr); - if (in_q || m_params.m_cnf_mode == CNF_FULL) { - // TODO: in the current implementation, labels are removed during CNF translation. - // This is satisfactory for Boogie, since it does not use labels inside quantifiers, - // and we only need CNF_QUANT for Superposition Calculus. - r = new_arg; - if (m_manager.fine_grain_proofs()) { - proof * p0 = m_manager.mk_iff_oeq(m_manager.mk_rewrite(n, n->get_arg(0))); - pr = m_manager.mk_transitivity(p0, new_arg_pr); - } - } - else { - r = m_manager.mk_app(n->get_decl(), new_arg); - if (m_manager.fine_grain_proofs() && n != r) - pr = m_manager.mk_oeq_congruence(n, to_app(r), 1, &new_arg_pr); - } - cache_result(n, in_q, r, pr); -} - -void cnf::reduce1_quantifier(quantifier * q, bool in_q) { - expr * new_expr; - proof * new_expr_pr; - get_cached(q->get_expr(), true, new_expr, new_expr_pr); - expr_ref r(m_manager); - proof_ref pr(m_manager); - if (m_manager.is_and(new_expr) && q->is_forall()) { - quantifier_ref q1(m_manager); - q1 = m_manager.update_quantifier(q, new_expr); - expr_ref q2(m_manager); - proof_ref p2(m_manager); - m_pull.pull_quant2(q1, q2, p2); - expr * q3; - proof * p3; - push_quant(to_quantifier(q2), q3, p3); - r = q3; - if (m_manager.fine_grain_proofs()) { - proof * p1 = q == q1 ? 0 : m_manager.mk_oeq_quant_intro(q, q1, new_expr_pr); - p2 = p2 == 0 ? 0 : m_manager.mk_iff_oeq(p2); - pr = m_manager.mk_transitivity(p1, p2, p3); - } - } - else if ((m_manager.is_or(new_expr) || is_forall(new_expr)) && q->is_forall()) { - quantifier_ref q1(m_manager); - q1 = m_manager.update_quantifier(q, new_expr); - m_pull.pull_quant2(q1, r, pr); - if (m_manager.fine_grain_proofs()) { - pr = pr == 0 ? 0 : m_manager.mk_iff_oeq(pr); - proof * p1 = q == q1 ? 0 : m_manager.mk_oeq_quant_intro(q, q1, new_expr_pr); - pr = m_manager.mk_transitivity(p1, pr); - } - } - else { - r = m_manager.update_quantifier(q, new_expr); - if (m_manager.fine_grain_proofs() && r != q) - pr = q == r ? 0 : m_manager.mk_oeq_quant_intro(q, to_quantifier(r), new_expr_pr); - } - - cache_result(q, in_q, r, pr); - TRACE("cnf_quant", tout << mk_pp(q, m_manager) << "\n" << mk_pp(r, m_manager) << "\n";); -} - -cnf::cnf(ast_manager & m, defined_names & n, cnf_params & params): - m_params(params), - m_manager(m), - m_defined_names(n), - m_pull(m), - m_cache(m), - m_todo_defs(m), - m_todo_proofs(m), - m_coarse_proofs(m) { -} - -cnf::~cnf() { -} - -void cnf::reduce(expr * n, expr_ref & r, proof_ref & pr) { - m_coarse_proofs.reset(); - m_todo.reset(); - m_todo.push_back(expr_bool_pair(n, false)); - while (!m_todo.empty()) { - expr_bool_pair pair = m_todo.back(); - expr * n = pair.first; - bool in_q = pair.second; - if (is_cached(n, in_q)) { - m_todo.pop_back(); - } - else if (visit_children(n, in_q)) { - m_todo.pop_back(); - reduce1(n, in_q); - } - } - expr * r2; - proof * pr2; - get_cached(n, false, r2, pr2); - r = r2; - switch (m_manager.proof_mode()) { - case PGM_DISABLED: - pr = m_manager.mk_undef_proof(); - break; - case PGM_COARSE: - remove_duplicates(m_coarse_proofs); - pr = n == r2 ? m_manager.mk_reflexivity(n) : m_manager.mk_cnf_star(n, r2, m_coarse_proofs.size(), m_coarse_proofs.c_ptr()); - break; - case PGM_FINE: - pr = pr2 == 0 ? m_manager.mk_reflexivity(n) : pr2; - break; - } -} - -void cnf::operator()(expr * n, expr_ref_vector & new_defs, proof_ref_vector & new_def_proofs, expr_ref & r, proof_ref & pr) { - if (m_params.m_cnf_mode == CNF_DISABLED) { - r = n; - pr = m_manager.mk_reflexivity(n); - return; - } - - reset(); - reduce(n, r, pr); - for (unsigned i = 0; i < m_todo_defs.size(); i++) { - expr_ref dr(m_manager); - proof_ref dpr(m_manager); - reduce(m_todo_defs.get(i), dr, dpr); - m_result_defs.push_back(dr); - if (m_manager.proofs_enabled()) { - proof * new_pr = m_manager.mk_modus_ponens(m_todo_proofs.get(i), dpr); - m_result_def_proofs.push_back(new_pr); - } - else - m_result_def_proofs.push_back(m_manager.mk_undef_proof()); - } - std::reverse(m_result_defs.begin(), m_result_defs.end()); - new_defs.append(m_result_defs.size(), m_result_defs.c_ptr()); - std::reverse(m_result_def_proofs.begin(), m_result_def_proofs.end()); - new_def_proofs.append(m_result_def_proofs.size(), m_result_def_proofs.c_ptr()); -} - -void cnf::reset() { - m_cache.reset(); - m_todo.reset(); - m_todo_defs.reset(); - m_todo_proofs.reset(); - m_result_defs.reset(); - m_result_def_proofs.reset(); -} diff --git a/src/ast/normal_forms/cnf.h b/src/ast/normal_forms/cnf.h deleted file mode 100644 index 60c2d2410..000000000 --- a/src/ast/normal_forms/cnf.h +++ /dev/null @@ -1,121 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - cnf.h - -Abstract: - - CNF translation - -Author: - - Leonardo de Moura (leonardo) 2008-01-17. - -Revision History: - ---*/ -#ifndef _CNF_H_ -#define _CNF_H_ - -#include"cnf_params.h" -#include"pull_quant.h" -#include"nnf.h" -#include"approx_nat.h" - -/** - \brief Entry into the todo list of the CNF translator. It is also used as the key in the CNF cache. -*/ -struct cnf_entry { - expr * m_node; - bool m_polarity:1; - bool m_in_q:1; - cnf_entry():m_node(0), m_polarity(false), m_in_q(false) {} - cnf_entry(expr * n, bool p, bool in_q):m_node(n), m_polarity(p), m_in_q(in_q) {} - unsigned hash() const; - bool operator==(cnf_entry const & k) const; -}; - -/** - \brief Cache for CNF transformation. It is a mapping from (expr, polarity, in_q) -> (expr, proof) -*/ -class cnf_cache { -public: - typedef std::pair expr_proof_pair; - - typedef map, default_eq > cache; - - ast_manager & m_manager; - cache m_cache; - -public: - cnf_cache(ast_manager & m); - ~cnf_cache() { reset(); } - void insert(cnf_entry const & k, expr * r, proof * pr); - bool contains(cnf_entry const & k) const { return m_cache.contains(k); } - void get(cnf_entry const & k, expr * & r, proof * & pr) const { expr_proof_pair tmp; m_cache.find(k, tmp); r = tmp.first; pr = tmp.second; } - void reset(); -}; - -/** - \brief Functor for converting expressions into CNF. The functor can - optionally process subformulas nested in quantifiers. New names may be - introduced for subformulas that are too expensive to be put into CNF. - - NNF translation must be applied before converting to CNF. - - - To use CNF_QUANT, we must use at least NNF_QUANT - - To use CNF_OPPORTUNISTIC, we must use at least NNF_QUANT - - To use CNF_FULL, we must use NNF_FULL -*/ -class cnf { - typedef std::pair expr_bool_pair; - cnf_params & m_params; - ast_manager & m_manager; - defined_names & m_defined_names; - pull_quant m_pull; - cnf_cache m_cache; - svector m_todo; - expr_ref_vector m_todo_defs; - proof_ref_vector m_todo_proofs; - ptr_vector m_result_defs; - ptr_vector m_result_def_proofs; - proof_ref_vector m_coarse_proofs; - - void cache_result(expr * e, bool in_q, expr * r, proof * pr); - void get_cached(expr * n, bool in_q, expr * & r, proof * & pr) const { m_cache.get(cnf_entry(n, true, in_q), r, pr); } - bool is_cached(expr * n, bool in_q) const { return m_cache.contains(cnf_entry(n, true, in_q)); } - - void visit(expr * n, bool in_q, bool & visited); - bool visit_children(expr * n, bool in_q); - - void get_args(app * n, bool in_q, ptr_buffer & new_args, ptr_buffer & new_arg_prs); - void flat_args(func_decl * d, ptr_buffer const & args, ptr_buffer & flat_args); - approx_nat approx_result_size_for_disj(ptr_buffer const & args); - bool is_too_expensive(approx_nat approx_result_size, ptr_buffer const & args); - void name_args(ptr_buffer const & args, expr_ref_buffer & new_args, proof_ref_buffer & new_arg_prs); - void distribute(app * arg, app * & r, proof * & pr); - void push_quant(quantifier * q, expr * & r, proof * & pr); - void reduce1(expr * n, bool in_q); - void reduce1_or(app * n, bool in_q); - void reduce1_and(app * n, bool in_q); - void reduce1_label(app * n, bool in_q); - void reduce1_quantifier(quantifier * q, bool in_q); - - void reduce(expr * n, expr_ref & r, proof_ref & pr); -public: - cnf(ast_manager & m, defined_names & n, cnf_params & params); - ~cnf(); - void operator()(expr * n, // [IN] expression that should be put into CNF - expr_ref_vector & new_defs, // [OUT] new definitions - proof_ref_vector & new_def_proofs, // [OUT] proofs of the new definitions - expr_ref & r, // [OUT] resultant expression - proof_ref & p // [OUT] proof for (~ n r) - ); - - void reset(); -}; - -#endif /* _CNF_H_ */ - diff --git a/src/ast/normal_forms/nnf.cpp b/src/ast/normal_forms/nnf.cpp index 8f46139f7..c3ea69e77 100644 --- a/src/ast/normal_forms/nnf.cpp +++ b/src/ast/normal_forms/nnf.cpp @@ -18,6 +18,7 @@ Notes: --*/ #include"nnf.h" +#include"nnf_params.hpp" #include"warning.h" #include"used_vars.h" #include"well_sorted.h" @@ -29,6 +30,40 @@ Notes: #include"ast_smt2_pp.h" +/** + \brief NNF translation mode. The cheapest mode is NNF_SKOLEM, and + the most expensive is NNF_FULL. +*/ +enum nnf_mode { + NNF_SKOLEM, /* A subformula is put into NNF only if it contains + quantifiers or labels. The result of the + transformation will be in skolem normal form. + If a formula is too expensive to be put into NNF, + then nested quantifiers and labels are renamed. + + This mode is sufficient when using E-matching. + */ + NNF_QUANT, /* A subformula is put into NNF if it contains + quantifiers, labels, or is in the scope of a + quantifier. The result of the transformation will be + in skolem normal form, and the body of quantifiers + will be in NNF. If a ground formula is too expensive to + be put into NNF, then nested quantifiers and labels + are renamed. + + This mode is sufficient when using Superposition + Calculus. + + Remark: If the problem does not contain quantifiers, + then NNF_QUANT is identical to NNF_SKOLEM. + */ + NNF_OPPORTUNISTIC, /* Similar to NNF_QUANT, but a subformula is + also put into NNF, if it is + cheap. Otherwise, the nested quantifiers and + labels are renamed. */ + NNF_FULL /* Everything is put into NNF. */ +}; + class skolemizer { typedef act_cache cache; @@ -112,20 +147,16 @@ class skolemizer { } public: - skolemizer(ast_manager & m, params_ref const & p): + skolemizer(ast_manager & m): m_manager(m), m_sk_hack("sk_hack"), + m_sk_hack_enabled(false), m_cache(m), m_cache_pr(m) { - updt_params(p); } - void updt_params(params_ref const & p) { - m_sk_hack_enabled = p.get_bool(":nnf-sk-hack", false); - } - - static void get_param_descrs(param_descrs & r) { - r.insert(":nnf-sk-hack", CPK_BOOL, "(default: false) hack for VCC"); + void set_sk_hack(bool f) { + m_sk_hack_enabled = f; } ast_manager & m() const { return m_manager; } @@ -219,8 +250,6 @@ struct nnf::imp { name_exprs * m_name_nested_formulas; name_exprs * m_name_quant; - symbol m_skolem; - volatile bool m_cancel; unsigned long long m_max_memory; // in bytes @@ -230,10 +259,9 @@ struct nnf::imp { m_todo_defs(m), m_todo_proofs(m), m_result_pr_stack(m), - m_skolemizer(m, p), - m_skolem("skolem"), + m_skolemizer(m), m_cancel(false) { - updt_local_params(p); + updt_params(p); for (unsigned i = 0; i < 4; i++) { m_cache[i] = alloc(act_cache, m); if (m.proofs_enabled()) @@ -257,14 +285,10 @@ struct nnf::imp { del_name_exprs(m_name_quant); } - void updt_params(params_ref const & p) { - updt_local_params(p); - m_skolemizer.updt_params(p); - } - - void updt_local_params(params_ref const & p) { - symbol mode_sym = p.get_sym(":nnf-mode", m_skolem); - if (mode_sym == m_skolem) + void updt_params(params_ref const & _p) { + nnf_params p(_p); + symbol mode_sym = p.mode(); + if (mode_sym == "skolem") m_mode = NNF_SKOLEM; else if (mode_sym == "full") m_mode = NNF_FULL; @@ -272,23 +296,17 @@ struct nnf::imp { m_mode = NNF_QUANT; else throw nnf_params_exception("invalid NNF mode"); + + TRACE("nnf", tout << "nnf-mode: " << m_mode << " " << mode_sym << "\n" << _p << "\n";); - TRACE("nnf", tout << "nnf-mode: " << m_mode << " " << mode_sym << "\n" << p << "\n";); - - m_ignore_labels = p.get_bool(":nnf-ignore-labels", false); - m_skolemize = p.get_bool(":skolemize", true); - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); + m_ignore_labels = p.ignore_labels(); + m_skolemize = p.skolemize(); + m_max_memory = megabytes_to_bytes(p.max_memory()); + m_skolemizer.set_sk_hack(p.sk_hack()); } static void get_param_descrs(param_descrs & r) { - insert_max_memory(r); - r.insert(":nnf-mode", CPK_SYMBOL, - "(default: skolem) NNF translation mode: skolem (skolem normal form), quantifiers (skolem normal form + quantifiers in NNF), full"); - r.insert(":nnf-ignore-labels", CPK_BOOL, - "(default: false) remove/ignore labels in the input formula, this option is ignored if proofs are enabled"); - r.insert(":skolemize", CPK_BOOL, - "(default: true) skolemize (existential force) quantifiers"); - skolemizer::get_param_descrs(r); + nnf_params::collect_param_descrs(r); } void reset() { @@ -880,21 +898,6 @@ nnf::nnf(ast_manager & m, defined_names & n, params_ref const & p) { m_imp = alloc(imp, m, n, p); } -nnf::nnf(ast_manager & m, defined_names & n, nnf_params & np) { - params_ref p; - if (np.m_nnf_mode == NNF_FULL) - p.set_sym(":nnf-mode", symbol("full")); - else if (np.m_nnf_mode == NNF_QUANT) - p.set_sym(":nnf-mode", symbol("quantifiers")); - - if (np.m_nnf_ignore_labels) - p.set_bool(":nnf-ignore-labels", true); - - if (np.m_nnf_sk_hack) - p.set_bool(":nnf-sk-hack", true); - m_imp = alloc(imp, m, n, p); -} - nnf::~nnf() { dealloc(m_imp); } diff --git a/src/ast/normal_forms/nnf.h b/src/ast/normal_forms/nnf.h index 685083ff7..e8296e933 100644 --- a/src/ast/normal_forms/nnf.h +++ b/src/ast/normal_forms/nnf.h @@ -21,7 +21,6 @@ Notes: #define _NNF_H_ #include"ast.h" -#include"nnf_params.h" #include"params.h" #include"defined_names.h" @@ -30,7 +29,6 @@ class nnf { imp * m_imp; public: nnf(ast_manager & m, defined_names & n, params_ref const & p = params_ref()); - nnf(ast_manager & m, defined_names & n, nnf_params & params); // for backward compatibility ~nnf(); void operator()(expr * n, // [IN] expression that should be put into NNF @@ -41,6 +39,9 @@ public: ); void updt_params(params_ref const & p); + /* + REG_MODULE_PARAMS('nnf', 'nnf::get_param_descrs') + */ static void get_param_descrs(param_descrs & r); void cancel() { set_cancel(true); } diff --git a/src/ast/normal_forms/nnf_params.pyg b/src/ast/normal_forms/nnf_params.pyg new file mode 100644 index 000000000..aac8fbb86 --- /dev/null +++ b/src/ast/normal_forms/nnf_params.pyg @@ -0,0 +1,9 @@ +def_module_params('nnf', + description='negation normal form', + export=True, + params=(max_memory_param(), + ('sk_hack', BOOL, False, 'hack for VCC'), + ('mode', SYMBOL, 'skolem', + 'NNF translation mode: skolem (skolem normal form), quantifiers (skolem normal form + quantifiers in NNF), full'), + ('ignore_labels', BOOL, False, 'remove/ignore labels in the input formula, this option is ignored if proofs are enabled'), + ('skolemize', BOOL, True, 'skolemize (existential force) quantifiers'))) diff --git a/src/ast/pattern/expr_pattern_match.cpp b/src/ast/pattern/expr_pattern_match.cpp index 25be8dbf0..86cad58f8 100644 --- a/src/ast/pattern/expr_pattern_match.cpp +++ b/src/ast/pattern/expr_pattern_match.cpp @@ -36,7 +36,6 @@ Notes: #include"ast_pp.h" #include"cmd_context.h" #include"smt2parser.h" -#include"front_end_params.h" expr_pattern_match::expr_pattern_match(ast_manager & manager): m_manager(manager), m_precompiled(manager) { @@ -388,8 +387,7 @@ expr_pattern_match::initialize(char const * spec_string) { m_instrs.push_back(instr(BACKTRACK)); std::istringstream is(spec_string); - front_end_params p; - cmd_context ctx(&p, true, &m_manager); + cmd_context ctx(true, &m_manager); VERIFY(parse_smt2_commands(ctx, is)); ptr_vector::const_iterator it = ctx.begin_assertions(); diff --git a/src/ast/pattern/expr_pattern_match.h b/src/ast/pattern/expr_pattern_match.h index 45295e627..555d6a67e 100644 --- a/src/ast/pattern/expr_pattern_match.h +++ b/src/ast/pattern/expr_pattern_match.h @@ -22,7 +22,6 @@ Notes: #include"ast.h" #include"map.h" -#include"front_end_params.h" class expr_pattern_match { diff --git a/src/ast/pattern/pattern_inference_params.cpp b/src/ast/pattern/pattern_inference_params.cpp new file mode 100644 index 000000000..8adbdb9f1 --- /dev/null +++ b/src/ast/pattern/pattern_inference_params.cpp @@ -0,0 +1,32 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + pattern_inference_params.h + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2012-12-02. + +Revision History: + +--*/ +#include"pattern_inference_params.h" +#include"pattern_inference_params_helper.hpp" + +void pattern_inference_params::updt_params(params_ref const & _p) { + pattern_inference_params_helper p(_p); + m_pi_max_multi_patterns = p.max_multi_patterns(); + m_pi_block_loop_patterns = p.block_loop_patterns(); + m_pi_arith = static_cast(p.arith()); + m_pi_use_database = p.use_database(); + m_pi_arith_weight = p.arith_weight(); + m_pi_non_nested_arith_weight = p.non_nested_arith_weight(); + m_pi_pull_quantifiers = p.pull_quantifiers(); + m_pi_warnings = p.warnings(); +} diff --git a/src/front_end_params/pattern_inference_params.h b/src/ast/pattern/pattern_inference_params.h similarity index 74% rename from src/front_end_params/pattern_inference_params.h rename to src/ast/pattern/pattern_inference_params.h index 79d7b4d87..dc9f0cb9b 100644 --- a/src/front_end_params/pattern_inference_params.h +++ b/src/ast/pattern/pattern_inference_params.h @@ -19,7 +19,7 @@ Revision History: #ifndef _PATTERN_INFERENCE_PARAMS_H_ #define _PATTERN_INFERENCE_PARAMS_H_ -#include"ini_file.h" +#include"params.h" enum arith_pattern_inference_kind { AP_NO, // do not infer patterns with arithmetic terms @@ -39,20 +39,13 @@ struct pattern_inference_params { bool m_pi_avoid_skolems; bool m_pi_warnings; - pattern_inference_params(): - m_pi_max_multi_patterns(0), - m_pi_block_loop_patterns(true), - m_pi_arith(AP_CONSERVATIVE), - m_pi_use_database(false), - m_pi_arith_weight(5), - m_pi_non_nested_arith_weight(10), - m_pi_pull_quantifiers(true), + pattern_inference_params(params_ref const & p = params_ref()): m_pi_nopat_weight(-1), - m_pi_avoid_skolems(true), - m_pi_warnings(false) { + m_pi_avoid_skolems(true) { + updt_params(p); } - void register_params(ini_params & p); + void updt_params(params_ref const & _p); }; #endif /* _PATTERN_INFERENCE_PARAMS_H_ */ diff --git a/src/ast/pattern/pattern_inference_params_helper.pyg b/src/ast/pattern/pattern_inference_params_helper.pyg new file mode 100644 index 000000000..5d64e8e52 --- /dev/null +++ b/src/ast/pattern/pattern_inference_params_helper.pyg @@ -0,0 +1,12 @@ +def_module_params(class_name='pattern_inference_params_helper', + module_name='pi', + description='pattern inference (heuristics) for universal formulas (without annotation)', + export=True, + params=(('max_multi_patterns', UINT, 0, 'when patterns are not provided, the prover uses a heuristic to infer them, this option sets the threshold on the number of extra multi-patterns that can be created; by default, the prover creates at most one multi-pattern when there is no unary pattern'), + ('block_loop_patterns', BOOL, True, 'block looping patterns during pattern inference'), + ('arith', UINT, 1, '0 - do not infer patterns with arithmetic terms, 1 - use patterns with arithmetic terms if there is no other pattern, 2 - always use patterns with arithmetic terms'), + ('use_database', BOOL, True, 'use pattern database'), + ('arith_weight', UINT, 5, 'default weight for quantifiers where the only available pattern has nested arithmetic terms'), + ('non_nested_arith_weight', UINT, 10, 'default weight for quantifiers where the only available pattern has non nested arithmetic terms'), + ('pull_quantifiers', BOOL, True, 'pull nested quantifiers, if no pattern was found'), + ('warnings', BOOL, False, 'enable/disable warning messages in the pattern inference module'))) diff --git a/src/ast/pp.cpp b/src/ast/pp.cpp index 43f19e166..13247127d 100644 --- a/src/ast/pp.cpp +++ b/src/ast/pp.cpp @@ -17,22 +17,9 @@ Revision History: --*/ #include"pp.h" +#include"pp_params.hpp" using namespace format_ns; -pp_params g_pp_params; - -void set_pp_default_params(pp_params const & p) { - g_pp_params = p; -} - -void register_pp_params(ini_params & p) { - g_pp_params.register_params(p); -} - -pp_params const & get_pp_default_params() { - return g_pp_params; -} - static std::pair space_upto_line_break(ast_manager & m, format * f) { unsigned r; SASSERT(f->get_family_id() == fm(m).get_family_id("format")); @@ -69,7 +56,15 @@ inline bool fits(ast_manager & m, format * f, unsigned space_left) { return s <= space_left; } -void pp(std::ostream & out, format * f, ast_manager & m, pp_params const & p) { +void pp(std::ostream & out, format * f, ast_manager & m, params_ref const & _p) { + pp_params p(_p); + unsigned max_width = p.max_width(); + unsigned max_ribbon = p.max_ribbon(); + unsigned max_num_lines = p.max_num_lines(); + unsigned max_indent = p.max_indent(); + bool bounded = p.bounded(); + bool single_line = p.single_line(); + unsigned pos = 0; unsigned ribbon_pos = 0; unsigned line = 0; @@ -80,7 +75,7 @@ void pp(std::ostream & out, format * f, ast_manager & m, pp_params const & p) { todo.push_back(std::make_pair(f, 0)); app_ref space(mk_string(m, " "), fm(m)); while (!todo.empty()) { - if (line >= p.m_pp_max_num_lines) + if (line >= max_num_lines) return; std::pair pair = todo.back(); format * f = pair.first; @@ -89,10 +84,10 @@ void pp(std::ostream & out, format * f, ast_manager & m, pp_params const & p) { SASSERT(f->get_family_id() == fm(m).get_family_id("format")); switch (f->get_decl_kind()) { case OP_STRING: - if (p.m_pp_bounded && pos > p.m_pp_max_width) + if (bounded && pos > max_width) break; len = static_cast(strlen(f->get_decl()->get_parameter(0).get_symbol().bare_str())); - if (p.m_pp_bounded && pos + len > p.m_pp_max_width) { + if (bounded && pos + len > max_width) { out << "..."; break; } @@ -103,7 +98,7 @@ void pp(std::ostream & out, format * f, ast_manager & m, pp_params const & p) { case OP_INDENT: todo.push_back(std::make_pair(to_app(f->get_arg(0)), std::min(indent + f->get_decl()->get_parameter(0).get_int(), - p.m_pp_max_indent))); + max_indent))); break; case OP_COMPOSE: i = f->get_num_args(); @@ -113,7 +108,7 @@ void pp(std::ostream & out, format * f, ast_manager & m, pp_params const & p) { } break; case OP_CHOICE: - space_left = std::min(p.m_pp_max_width - pos, p.m_pp_max_ribbon - pos); + space_left = std::min(max_width - pos, max_ribbon - pos); if (space_left > 0 && fits(m, to_app(f->get_arg(0)), space_left)) todo.push_back(std::make_pair(to_app(f->get_arg(0)), indent)); else @@ -121,14 +116,14 @@ void pp(std::ostream & out, format * f, ast_manager & m, pp_params const & p) { break; case OP_LINE_BREAK: case OP_LINE_BREAK_EXT: - if (p.m_pp_single_line) { + if (single_line) { todo.push_back(std::make_pair(space, indent)); break; } pos = indent; ribbon_pos = 0; line++; - if (line < p.m_pp_max_num_lines) { + if (line < max_num_lines) { out << "\n"; for (unsigned i = 0; i < indent; i++) out << " "; @@ -142,7 +137,3 @@ void pp(std::ostream & out, format * f, ast_manager & m, pp_params const & p) { } } -void pp(std::ostream & out, format_ns::format * f, ast_manager & m) { - pp(out, f, m, g_pp_params); -} - diff --git a/src/ast/pp.h b/src/ast/pp.h index 43c1de7b7..f567afa4a 100644 --- a/src/ast/pp.h +++ b/src/ast/pp.h @@ -20,15 +20,9 @@ Revision History: #define _PP_H_ #include"format.h" -#include"pp_params.h" +#include"params.h" -void set_pp_default_params(pp_params const & p); -void register_pp_params(ini_params & p); - -pp_params const & get_pp_default_params(); - -void pp(std::ostream & out, format_ns::format * f, ast_manager & m, pp_params const & p); -void pp(std::ostream & out, format_ns::format * f, ast_manager & m); +void pp(std::ostream & out, format_ns::format * f, ast_manager & m, params_ref const & p = params_ref()); #endif /* _PP_H_ */ diff --git a/src/ast/pp_params.cpp b/src/ast/pp_params.cpp deleted file mode 100644 index 0cf3e455d..000000000 --- a/src/ast/pp_params.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - pp_params.cpp - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-01-20. - -Revision History: - ---*/ - -#include"pp_params.h" - -pp_params::pp_params(): - m_pp_max_indent(UINT_MAX), - m_pp_max_num_lines(UINT_MAX), - m_pp_max_width(80), - m_pp_max_ribbon(80), - m_pp_max_depth(5), - m_pp_min_alias_size(10), - m_pp_decimal(false), - m_pp_decimal_precision(10), - m_pp_bv_lits(true), - m_pp_bv_neg(false), - m_pp_flat_assoc(true), - m_pp_fixed_indent(false), - m_pp_single_line(false), - m_pp_bounded(false), - m_pp_simplify_implies(false) { -} - -void pp_params::register_params(ini_params & p) { - p.register_unsigned_param("PP_MAX_INDENT", m_pp_max_indent, "max. indentation in pretty printer", true); - p.register_unsigned_param("PP_MAX_NUM_LINES", m_pp_max_num_lines, "max. number of lines to be displayed in pretty printer", true); - p.register_unsigned_param("PP_MAX_WIDTH", m_pp_max_width, "max. width in pretty printer", true); - p.register_unsigned_param("PP_MAX_RIBBON", m_pp_max_ribbon, "max. ribbon (width - indentation) in pretty printer", true); - p.register_unsigned_param("PP_MAX_DEPTH", m_pp_max_depth, "max. term depth (when pretty printing SMT2 terms/formulas)", true); - p.register_unsigned_param("PP_MIN_ALIAS_SIZE", m_pp_min_alias_size, "min. size for creating an alias for a shared term (when pretty printing SMT2 terms/formulas)", true); - p.register_bool_param("PP_DECIMAL", m_pp_decimal, "pretty print real numbers using decimal notation (the output may be truncated). Z3 adds a '?' if the value is not precise", true); - p.register_unsigned_param("PP_DECIMAL_PRECISION", m_pp_decimal_precision, "maximum number of decimal places to be used when PP_DECIMAL=true", true); - p.register_bool_param("PP_BV_LITERALS", m_pp_bv_lits, "use Bit-Vector literals (e.g, #x0F and #b0101) during pretty printing", true); - p.register_bool_param("PP_BV_NEG", m_pp_bv_neg, "use bvneg when displaying Bit-Vector literals where the most significant bit is 1", true); - p.register_bool_param("PP_FLAT_ASSOC", m_pp_flat_assoc, "flat associative operators (when pretty printing SMT2 terms/formulas)", true); - p.register_bool_param("PP_FIXED_INDENT", m_pp_fixed_indent, "use a fixed indentation for applications", true); - p.register_bool_param("PP_SINGLE_LINE", m_pp_single_line, "ignore line breaks when true", true); - p.register_bool_param("PP_BOUNDED", m_pp_bounded, "ignore characters exceeding max widht", true); - p.register_bool_param("PP_SIMPLIFY_IMPLIES", m_pp_simplify_implies, "simplify nested implications for pretty printing", true); -} - diff --git a/src/ast/pp_params.h b/src/ast/pp_params.h deleted file mode 100644 index 970f97968..000000000 --- a/src/ast/pp_params.h +++ /dev/null @@ -1,46 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - pp_params.h - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-01-20. - -Revision History: - ---*/ -#ifndef _PP_PARAMS_H_ -#define _PP_PARAMS_H_ - -#include"ini_file.h" - -struct pp_params { - unsigned m_pp_max_indent; // max. indentation - unsigned m_pp_max_num_lines; // max. num. lines - unsigned m_pp_max_width; // max. width - unsigned m_pp_max_ribbon; // max. ribbon: width - indentation - unsigned m_pp_max_depth; - unsigned m_pp_min_alias_size; - bool m_pp_decimal; // display reals using decimals - unsigned m_pp_decimal_precision; // max. number of decimal places - bool m_pp_bv_lits; - bool m_pp_bv_neg; // use bvneg to display bit-vector literals which the most significant bit is 1 - bool m_pp_flat_assoc; - bool m_pp_fixed_indent; - bool m_pp_single_line; // ignore line breaks if true - bool m_pp_bounded; // ignore characters exceeding max width. - bool m_pp_simplify_implies; // simplify nested implications during pretty printing - - pp_params(); - void register_params(ini_params & p); -}; - -#endif /* _PP_PARAMS_H_ */ - diff --git a/src/ast/pp_params.pyg b/src/ast/pp_params.pyg new file mode 100644 index 000000000..75b2baddd --- /dev/null +++ b/src/ast/pp_params.pyg @@ -0,0 +1,18 @@ +def_module_params('pp', + export=True, + description='pretty printer', + params=(('max_indent', UINT, UINT_MAX, 'max. indentation in pretty printer'), + ('max_num_lines', UINT, UINT_MAX, 'max. number of lines to be displayed in pretty printer'), + ('max_width', UINT, 80, 'max. width in pretty printer'), + ('max_ribbon', UINT, 80, 'max. ribbon (width - indentation) in pretty printer'), + ('max_depth', UINT, 5, 'max. term depth (when pretty printing SMT2 terms/formulas)'), + ('min_alias_size', UINT, 10, 'min. size for creating an alias for a shared term (when pretty printing SMT2 terms/formulas)'), + ('decimal', BOOL, False, 'pretty print real numbers using decimal notation (the output may be truncated). Z3 adds a ? if the value is not precise'), + ('decimal_precision', UINT, 10, 'maximum number of decimal places to be used when pp.decimal=true'), + ('bv_literals', BOOL, True, 'use Bit-Vector literals (e.g, #x0F and #b0101) during pretty printing'), + ('bv_neg', BOOL, False, 'use bvneg when displaying Bit-Vector literals where the most significant bit is 1'), + ('flat_assoc', BOOL, True, 'flat associative operators (when pretty printing SMT2 terms/formulas)'), + ('fixed_indent', BOOL, False, 'use a fixed indentation for applications'), + ('single_line', BOOL, False, 'ignore line breaks when true'), + ('bounded', BOOL, False, 'ignore characters exceeding max widht'), + ('simplify_implies', BOOL, True, 'simplify nested implications for pretty printing'))) diff --git a/src/ast/proof_checker/proof_checker.cpp b/src/ast/proof_checker/proof_checker.cpp index 8a064a315..240504048 100644 --- a/src/ast/proof_checker/proof_checker.cpp +++ b/src/ast/proof_checker/proof_checker.cpp @@ -4,7 +4,6 @@ // include "spc_decl_plugin.h" #include "ast_smt_pp.h" #include "arith_decl_plugin.h" -#include "front_end_params.h" #include "th_rewriter.h" #include "var_subst.h" diff --git a/src/ast/rewriter/arith_rewriter.cpp b/src/ast/rewriter/arith_rewriter.cpp index 3efc14abe..a5dfda6e7 100644 --- a/src/ast/rewriter/arith_rewriter.cpp +++ b/src/ast/rewriter/arith_rewriter.cpp @@ -17,23 +17,25 @@ Notes: --*/ #include"arith_rewriter.h" +#include"arith_rewriter_params.hpp" #include"poly_rewriter_def.h" #include"algebraic_numbers.h" #include"ast_pp.h" -void arith_rewriter::updt_local_params(params_ref const & p) { - m_arith_lhs = p.get_bool(":arith-lhs", false); - m_gcd_rounding = p.get_bool(":gcd-rounding", false); - m_eq2ineq = p.get_bool(":eq2ineq", false); - m_elim_to_real = p.get_bool(":elim-to-real", false); - m_push_to_real = p.get_bool(":push-to-real", true); - m_anum_simp = p.get_bool(":algebraic-number-evaluator", true); - m_max_degree = p.get_uint(":max-degree", 64); - m_expand_power = p.get_bool(":expand-power", false); - m_mul2power = p.get_bool(":mul-to-power", false); - m_elim_rem = p.get_bool(":elim-rem", false); - m_expand_tan = p.get_bool(":expand-tan", false); - set_sort_sums(p.get_bool(":sort-sums", false)); // set here to avoid collision with bvadd +void arith_rewriter::updt_local_params(params_ref const & _p) { + arith_rewriter_params p(_p); + m_arith_lhs = p.arith_lhs(); + m_gcd_rounding = p.gcd_rounding(); + m_eq2ineq = p.eq2ineq(); + m_elim_to_real = p.elim_to_real(); + m_push_to_real = p.push_to_real(); + m_anum_simp = p.algebraic_number_evaluator(); + m_max_degree = p.max_degree(); + m_expand_power = p.expand_power(); + m_mul2power = p.mul_to_power(); + m_elim_rem = p.elim_rem(); + m_expand_tan = p.expand_tan(); + set_sort_sums(p.sort_sums()); } void arith_rewriter::updt_params(params_ref const & p) { @@ -43,18 +45,7 @@ void arith_rewriter::updt_params(params_ref const & p) { void arith_rewriter::get_param_descrs(param_descrs & r) { poly_rewriter::get_param_descrs(r); - r.insert(":algebraic-number-evaluator", CPK_BOOL, "(default: true) simplify/evaluate expressions containing (algebraic) irrational numbers."); - r.insert(":mul-to-power", CPK_BOOL, "(default: false) collpase (* t ... t) into (^ t k), it is ignored if :expand-power is true."); - r.insert(":expand-power", CPK_BOOL, "(default: false) expand (^ t k) into (* t ... t) if 1 < k <= :max-degree."); - r.insert(":expand-tan", CPK_BOOL, "(default: false) replace (tan x) with (/ (sin x) (cos x))."); - r.insert(":max-degree", CPK_UINT, "(default: 64) max degree of algebraic numbers (and power operators) processed by simplifier."); - r.insert(":eq2ineq", CPK_BOOL, "(default: false) split arithmetic equalities into two inequalities."); - r.insert(":sort-sums", CPK_BOOL, "(default: false) sort the arguments of + application."); - r.insert(":gcd-rounding", CPK_BOOL, "(default: false) use gcd rounding on integer arithmetic atoms."); - r.insert(":arith-lhs", CPK_BOOL, "(default: false) all monomials are moved to the left-hand-side, and the right-hand-side is just a constant."); - r.insert(":elim-to-real", CPK_BOOL, "(default: false) eliminate to_real from arithmetic predicates that contain only integers."); - r.insert(":push-to-real", CPK_BOOL, "(default: true) distribute to_real over * and +."); - r.insert(":elim-rem", CPK_BOOL, "(default: false) replace (rem x y) with (ite (>= y 0) (mod x y) (- (mod x y)))."); + arith_rewriter_params::collect_param_descrs(r); } br_status arith_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { diff --git a/src/ast/rewriter/arith_rewriter_params.pyg b/src/ast/rewriter/arith_rewriter_params.pyg new file mode 100644 index 000000000..8a41d838d --- /dev/null +++ b/src/ast/rewriter/arith_rewriter_params.pyg @@ -0,0 +1,15 @@ +def_module_params(module_name='rewriter', + class_name='arith_rewriter_params', + export=True, + params=(("algebraic_number_evaluator", BOOL, True, "simplify/evaluate expressions containing (algebraic) irrational numbers."), + ("mul_to_power", BOOL, False, "collpase (* t ... t) into (^ t k), it is ignored if expand_power is true."), + ("expand_power", BOOL, False, "expand (^ t k) into (* t ... t) if 1 < k <= max_degree."), + ("expand_tan", BOOL, False, "replace (tan x) with (/ (sin x) (cos x))."), + ("max_degree", UINT, 64, "max degree of algebraic numbers (and power operators) processed by simplifier."), + ("eq2ineq", BOOL, False, "split arithmetic equalities into two inequalities."), + ("sort_sums", BOOL, False, "sort the arguments of + application."), + ("gcd_rounding", BOOL, False, "use gcd rounding on integer arithmetic atoms."), + ("arith_lhs", BOOL, False, "all monomials are moved to the left-hand-side, and the right-hand-side is just a constant."), + ("elim_to_real", BOOL, False, "eliminate to_real from arithmetic predicates that contain only integers."), + ("push_to_real", BOOL, True, "distribute to_real over * and +."), + ("elim_rem", BOOL, False, "replace (rem x y) with (ite (>= y 0) (mod x y) (- (mod x y)))."))) diff --git a/src/ast/rewriter/array_rewriter.cpp b/src/ast/rewriter/array_rewriter.cpp index 268f4dca0..9dbbeb231 100644 --- a/src/ast/rewriter/array_rewriter.cpp +++ b/src/ast/rewriter/array_rewriter.cpp @@ -17,17 +17,18 @@ Notes: --*/ #include"array_rewriter.h" +#include"array_rewriter_params.hpp" #include"ast_lt.h" #include"ast_pp.h" -void array_rewriter::updt_params(params_ref const & p) { - m_sort_store = p.get_bool(":sort-store", false); - m_expand_select_store = p.get_bool(":expand-select-store", false); +void array_rewriter::updt_params(params_ref const & _p) { + array_rewriter_params p(_p); + m_sort_store = p.sort_store(); + m_expand_select_store = p.expand_select_store(); } void array_rewriter::get_param_descrs(param_descrs & r) { - r.insert(":expand-select-store", CPK_BOOL, "(default: false) replace a (select (store ...) ...) term by an if-then-else term."); - r.insert(":sort-store", CPK_BOOL, "(default: false) sort nested stores when the indices are known to be different."); + array_rewriter_params::collect_param_descrs(r); } br_status array_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { diff --git a/src/ast/rewriter/array_rewriter_params.pyg b/src/ast/rewriter/array_rewriter_params.pyg new file mode 100644 index 000000000..2e3ae9f6a --- /dev/null +++ b/src/ast/rewriter/array_rewriter_params.pyg @@ -0,0 +1,5 @@ +def_module_params(module_name='rewriter', + class_name='array_rewriter_params', + export=True, + params=(("expand_select_store", BOOL, False, "replace a (select (store ...) ...) term by an if-then-else term"), + ("sort_store", BOOL, False, "sort nested stores when the indices are known to be different"))) diff --git a/src/front_end_params/bit_blaster_params.h b/src/ast/rewriter/bit_blaster/bit_blaster_params.h similarity index 80% rename from src/front_end_params/bit_blaster_params.h rename to src/ast/rewriter/bit_blaster/bit_blaster_params.h index 8196774ca..653c8fc74 100644 --- a/src/front_end_params/bit_blaster_params.h +++ b/src/ast/rewriter/bit_blaster/bit_blaster_params.h @@ -19,8 +19,6 @@ Revision History: #ifndef _BIT_BLASTER_PARAMS_H_ #define _BIT_BLASTER_PARAMS_H_ -#include"ini_file.h" - struct bit_blaster_params { bool m_bb_ext_gates; bool m_bb_quantifiers; @@ -28,10 +26,12 @@ struct bit_blaster_params { m_bb_ext_gates(false), m_bb_quantifiers(false) { } +#if 0 void register_params(ini_params & p) { - p.register_bool_param("BB_EXT_GATES", m_bb_ext_gates, "use extended gates during bit-blasting"); - p.register_bool_param("BB_QUANTIFIERS", m_bb_quantifiers, "convert bit-vectors to Booleans in quantifiers"); + p.register_bool_param("bb_ext_gates", m_bb_ext_gates, "use extended gates during bit-blasting"); + p.register_bool_param("bb_quantifiers", m_bb_quantifiers, "convert bit-vectors to Booleans in quantifiers"); } +#endif }; #endif /* _BIT_BLASTER_PARAMS_H_ */ diff --git a/src/ast/rewriter/bit_blaster/bit_blaster_rewriter.cpp b/src/ast/rewriter/bit_blaster/bit_blaster_rewriter.cpp index c64ea56d0..1fd83e91f 100644 --- a/src/ast/rewriter/bit_blaster/bit_blaster_rewriter.cpp +++ b/src/ast/rewriter/bit_blaster/bit_blaster_rewriter.cpp @@ -125,12 +125,12 @@ struct blaster_rewriter_cfg : public default_rewriter_cfg { } void updt_params(params_ref const & p) { - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); - m_max_steps = p.get_uint(":max-steps", UINT_MAX); - m_blast_add = p.get_bool(":blast-add", true); - m_blast_mul = p.get_bool(":blast-mul", true); - m_blast_full = p.get_bool(":blast-full", false); - m_blast_quant = p.get_bool(":blast-quant", false); + m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); + m_max_steps = p.get_uint("max_steps", UINT_MAX); + m_blast_add = p.get_bool("blast_add", true); + m_blast_mul = p.get_bool("blast_mul", true); + m_blast_full = p.get_bool("blast_full", false); + m_blast_quant = p.get_bool("blast_quant", false); m_blaster.set_max_memory(m_max_memory); } diff --git a/src/ast/rewriter/bool_rewriter.cpp b/src/ast/rewriter/bool_rewriter.cpp index b7fe296c4..4fcaf02fe 100644 --- a/src/ast/rewriter/bool_rewriter.cpp +++ b/src/ast/rewriter/bool_rewriter.cpp @@ -17,24 +17,21 @@ Notes: --*/ #include"bool_rewriter.h" +#include"bool_rewriter_params.hpp" #include"rewriter_def.h" -void bool_rewriter::updt_params(params_ref const & p) { - m_flat = p.get_bool(":flat", true); - m_elim_and = p.get_bool(":elim-and", false); - m_local_ctx = p.get_bool(":local-ctx", false); - m_local_ctx_limit = p.get_uint(":local-ctx-limit", UINT_MAX); - m_blast_distinct = p.get_bool(":blast-distinct", false); - m_ite_extra_rules = p.get_bool(":ite-extra-rules", false); +void bool_rewriter::updt_params(params_ref const & _p) { + bool_rewriter_params p(_p); + m_flat = p.flat(); + m_elim_and = p.elim_and(); + m_local_ctx = p.local_ctx(); + m_local_ctx_limit = p.local_ctx_limit(); + m_blast_distinct = p.blast_distinct(); + m_ite_extra_rules = p.ite_extra_rules(); } void bool_rewriter::get_param_descrs(param_descrs & r) { - r.insert(":ite-extra-rules", CPK_BOOL, "(default: false) extra ite simplifications, these additional simplifications may reduce size locally but increase globally."); - r.insert(":flat", CPK_BOOL, "(default: true) create nary applications for and,or,+,*,bvadd,bvmul,bvand,bvor,bvxor."); - r.insert(":elim-and", CPK_BOOL, "(default: false) conjunctions are rewritten using negation and disjunctions."); - r.insert(":local-ctx", CPK_BOOL, "(default: false) perform local (i.e., cheap) context simplifications."); - r.insert(":local-ctx-limit", CPK_UINT, "(default: inf) limit for applying local context simplifier."); - r.insert(":blast-distinct", CPK_BOOL, "(default: false) expand a distinct predicate into a quadratic number of disequalities."); + bool_rewriter_params::collect_param_descrs(r); } br_status bool_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) { diff --git a/src/ast/rewriter/bool_rewriter_params.pyg b/src/ast/rewriter/bool_rewriter_params.pyg new file mode 100644 index 000000000..a5bcf6f5d --- /dev/null +++ b/src/ast/rewriter/bool_rewriter_params.pyg @@ -0,0 +1,9 @@ +def_module_params(module_name='rewriter', + class_name='bool_rewriter_params', + export=True, + params=(("ite_extra_rules", BOOL, False, "extra ite simplifications, these additional simplifications may reduce size locally but increase globally"), + ("flat", BOOL, True, "create nary applications for and,or,+,*,bvadd,bvmul,bvand,bvor,bvxor"), + ("elim_and", BOOL, False, "conjunctions are rewritten using negation and disjunctions"), + ("local_ctx", BOOL, False, "perform local (i.e., cheap) context simplifications"), + ("local_ctx_limit", UINT, UINT_MAX, "limit for applying local context simplifier"), + ("blast_distinct", BOOL, False, "expand a distinct predicate into a quadratic number of disequalities"))) diff --git a/src/ast/rewriter/bv_rewriter.cpp b/src/ast/rewriter/bv_rewriter.cpp index adef6a5b0..5fd562676 100644 --- a/src/ast/rewriter/bv_rewriter.cpp +++ b/src/ast/rewriter/bv_rewriter.cpp @@ -17,6 +17,7 @@ Notes: --*/ #include"bv_rewriter.h" +#include"bv_rewriter_params.hpp" #include"poly_rewriter_def.h" #include"ast_smt2_pp.h" @@ -53,15 +54,16 @@ app * mk_extract_proc::operator()(unsigned high, unsigned low, expr * arg) { return r; } -void bv_rewriter::updt_local_params(params_ref const & p) { - m_hi_div0 = p.get_bool(":hi-div0", true); - m_elim_sign_ext = p.get_bool(":elim-sign-ext", true); - m_mul2concat = p.get_bool(":mul2concat", false); - m_bit2bool = p.get_bool(":bit2bool", true); - m_blast_eq_value = p.get_bool(":blast-eq-value", false); - m_mkbv2num = p.get_bool(":mkbv2num", false); - m_split_concat_eq = p.get_bool(":split-concat-eq", false); - m_udiv2mul = p.get_bool(":udiv2mul", false); +void bv_rewriter::updt_local_params(params_ref const & _p) { + bv_rewriter_params p(_p); + m_hi_div0 = p.hi_div0(); + m_elim_sign_ext = p.elim_sign_ext(); + m_mul2concat = p.mul2concat(); + m_bit2bool = p.bit2bool(); + m_blast_eq_value = p.blast_eq_value(); + m_split_concat_eq = p.split_concat_eq(); + m_udiv2mul = p.udiv2mul(); + m_mkbv2num = _p.get_bool("mkbv2num", false); } void bv_rewriter::updt_params(params_ref const & p) { @@ -71,15 +73,9 @@ void bv_rewriter::updt_params(params_ref const & p) { void bv_rewriter::get_param_descrs(param_descrs & r) { poly_rewriter::get_param_descrs(r); - r.insert(":udiv2mul", CPK_BOOL, "(default: false) convert constant udiv to mul."); - r.insert(":split-concat-eq", CPK_BOOL, "(default: false) split equalities of the form (= (concat t1 t2) t3)."); - r.insert(":bit2bool", CPK_BOOL, "(default: true) try to convert bit-vector terms of size 1 into Boolean terms."); - r.insert(":blast-eq-value", CPK_BOOL, "(default: false) blast (some) Bit-vector equalities into bits."); - r.insert(":elim-sign-ext", CPK_BOOL, "(default: true) expand sign-ext operator using concat and extract."); - r.insert(":hi-div0", CPK_BOOL, "(default: true) use the 'hardware interpretation' for division by zero (for bit-vector terms)."); - r.insert(":mul2concat", CPK_BOOL, "(default: false) replace multiplication by a power of two into a concatenation."); + bv_rewriter_params::collect_param_descrs(r); #ifndef _EXTERNAL_RELEASE - r.insert(":mkbv2num", CPK_BOOL, "(default: false) convert (mkbv [true/false]*) into a numeral"); + r.insert("mkbv2num", CPK_BOOL, "(default: false) convert (mkbv [true/false]*) into a numeral"); #endif } diff --git a/src/ast/rewriter/bv_rewriter_params.pyg b/src/ast/rewriter/bv_rewriter_params.pyg new file mode 100644 index 000000000..780d8e724 --- /dev/null +++ b/src/ast/rewriter/bv_rewriter_params.pyg @@ -0,0 +1,10 @@ +def_module_params(module_name='rewriter', + class_name='bv_rewriter_params', + export=True, + params=(("udiv2mul", BOOL, False, "convert constant udiv to mul"), + ("split_concat_eq", BOOL, False, "split equalities of the form (= (concat t1 t2) t3)"), + ("bit2bool", BOOL, True, "try to convert bit-vector terms of size 1 into Boolean terms"), + ("blast_eq_value", BOOL, False, "blast (some) Bit-vector equalities into bits"), + ("elim_sign_ext", BOOL, True, "expand sign-ext operator using concat and extract"), + ("hi_div0", BOOL, True, "use the 'hardware interpretation' for division by zero (for bit-vector terms)"), + ("mul2concat", BOOL, False, "replace multiplication by a power of two into a concatenation"))) diff --git a/src/ast/rewriter/float_rewriter.cpp b/src/ast/rewriter/float_rewriter.cpp index ad0709423..9678af216 100644 --- a/src/ast/rewriter/float_rewriter.cpp +++ b/src/ast/rewriter/float_rewriter.cpp @@ -59,6 +59,7 @@ br_status float_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * c case OP_FLOAT_IS_NZERO: SASSERT(num_args == 1); st = mk_is_nzero(args[0], result); break; case OP_FLOAT_IS_PZERO: SASSERT(num_args == 1); st = mk_is_pzero(args[0], result); break; case OP_FLOAT_IS_SIGN_MINUS: SASSERT(num_args == 1); st = mk_is_sign_minus(args[0], result); break; + case OP_TO_IEEE_BV: SASSERT(num_args == 1); st = mk_to_ieee_bv(args[0], result); break; } return st; } @@ -439,3 +440,7 @@ br_status float_rewriter::mk_eq_core(expr * arg1, expr * arg2, expr_ref & result return BR_FAILED; } + +br_status float_rewriter::mk_to_ieee_bv(expr * arg1, expr_ref & result) { + return BR_FAILED; +} \ No newline at end of file diff --git a/src/ast/rewriter/float_rewriter.h b/src/ast/rewriter/float_rewriter.h index e4258895d..7c86a5bc3 100644 --- a/src/ast/rewriter/float_rewriter.h +++ b/src/ast/rewriter/float_rewriter.h @@ -67,6 +67,8 @@ public: br_status mk_is_nzero(expr * arg1, expr_ref & result); br_status mk_is_pzero(expr * arg1, expr_ref & result); br_status mk_is_sign_minus(expr * arg1, expr_ref & result); + + br_status mk_to_ieee_bv(expr * arg1, expr_ref & result); }; #endif diff --git a/src/ast/rewriter/poly_rewriter_def.h b/src/ast/rewriter/poly_rewriter_def.h index e942b453a..290144c75 100644 --- a/src/ast/rewriter/poly_rewriter_def.h +++ b/src/ast/rewriter/poly_rewriter_def.h @@ -17,6 +17,7 @@ Notes: --*/ #include"poly_rewriter.h" +#include"poly_rewriter_params.hpp" #include"ast_lt.h" #include"ast_ll_pp.h" #include"ast_smt2_pp.h" @@ -26,20 +27,18 @@ char const * poly_rewriter::g_ste_blowup_msg = "sum of monomials blowup" template -void poly_rewriter::updt_params(params_ref const & p) { - m_flat = p.get_bool(":flat", true); - m_som = p.get_bool(":som", false); - m_hoist_mul = p.get_bool(":hoist-mul", false); - m_hoist_cmul = p.get_bool(":hoist-cmul", false); - m_som_blowup = p.get_uint(":som-blowup", UINT_MAX); +void poly_rewriter::updt_params(params_ref const & _p) { + poly_rewriter_params p(_p); + m_flat = p.flat(); + m_som = p.som(); + m_hoist_mul = p.hoist_mul(); + m_hoist_cmul = p.hoist_cmul(); + m_som_blowup = p.som_blowup(); } template void poly_rewriter::get_param_descrs(param_descrs & r) { - r.insert(":som", CPK_BOOL, "(default: false) put polynomials in som-of-monomials form."); - r.insert(":som-blowup", CPK_UINT, "(default: infty) maximum number of monomials generated when putting a polynomial in sum-of-monomials normal form"); - r.insert(":hoist-mul", CPK_BOOL, "(default: false) hoist multiplication over summation to minimize number of multiplications"); - r.insert(":hoist-cmul", CPK_BOOL, "(default: false) hoist constant multiplication over summation to minimize number of multiplications"); + poly_rewriter_params::collect_param_descrs(r); } template diff --git a/src/ast/rewriter/poly_rewriter_params.pyg b/src/ast/rewriter/poly_rewriter_params.pyg new file mode 100644 index 000000000..18d1e1dba --- /dev/null +++ b/src/ast/rewriter/poly_rewriter_params.pyg @@ -0,0 +1,8 @@ +def_module_params(module_name='rewriter', + class_name='poly_rewriter_params', + export=True, + params=(("som", BOOL, False, "put polynomials in som-of-monomials form"), + ("som_blowup", UINT, UINT_MAX, "maximum number of monomials generated when putting a polynomial in sum-of-monomials normal form"), + ("hoist_mul", BOOL, False, "hoist multiplication over summation to minimize number of multiplications"), + ("hoist_cmul", BOOL, False, "hoist constant multiplication over summation to minimize number of multiplications"), + ("flat", BOOL, True, "create nary applications for and,or,+,*,bvadd,bvmul,bvand,bvor,bvxor"))) diff --git a/src/ast/rewriter/rewriter_params.pyg b/src/ast/rewriter/rewriter_params.pyg new file mode 100644 index 000000000..3a8ed5d5e --- /dev/null +++ b/src/ast/rewriter/rewriter_params.pyg @@ -0,0 +1,11 @@ +def_module_params('rewriter', + description='new formula simplification module used in the tactic framework, and new solvers', + export=True, + params=(max_memory_param(), + max_steps_param(), + ("flat", BOOL, True, "create nary applications for and,or,+,*,bvadd,bvmul,bvand,bvor,bvxor"), + ("push_ite_arith", BOOL, False, "push if-then-else over arithmetic terms."), + ("push_ite_bv", BOOL, False, "push if-then-else over bit-vector terms."), + ("pull_cheap_ite", BOOL, False, "pull if-then-else terms when cheap."), + ("cache_all", BOOL, False, "cache all intermediate results."))) + diff --git a/src/ast/rewriter/th_rewriter.cpp b/src/ast/rewriter/th_rewriter.cpp index ee55d53e7..29034d396 100644 --- a/src/ast/rewriter/th_rewriter.cpp +++ b/src/ast/rewriter/th_rewriter.cpp @@ -17,6 +17,7 @@ Notes: --*/ #include"th_rewriter.h" +#include"rewriter_params.hpp" #include"bool_rewriter.h" #include"arith_rewriter.h" #include"bv_rewriter.h" @@ -56,14 +57,15 @@ struct th_rewriter_cfg : public default_rewriter_cfg { ast_manager & m() const { return m_b_rw.m(); } - void updt_local_params(params_ref const & p) { - m_flat = p.get_bool(":flat", true); - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); - m_max_steps = p.get_uint(":max-steps", UINT_MAX); - m_pull_cheap_ite = p.get_bool(":pull-cheap-ite", false); - m_cache_all = p.get_bool(":cache-all", false); - m_push_ite_arith = p.get_bool(":push-ite-arith", false); - m_push_ite_bv = p.get_bool(":push-ite-bv", false); + void updt_local_params(params_ref const & _p) { + rewriter_params p(_p); + m_flat = p.flat(); + m_max_memory = megabytes_to_bytes(p.max_memory()); + m_max_steps = p.max_steps(); + m_pull_cheap_ite = p.pull_cheap_ite(); + m_cache_all = p.cache_all(); + m_push_ite_arith = p.push_ite_arith(); + m_push_ite_bv = p.push_ite_bv(); } void updt_params(params_ref const & p) { @@ -481,10 +483,13 @@ struct th_rewriter_cfg : public default_rewriter_cfg { f = to_app(t1)->get_decl(); return unify_core(to_app(t1), t2, new_t1, new_t2, c, first); } - else { + else if (is_arith_bv_app(t2)) { f = to_app(t2)->get_decl(); return unify_core(to_app(t2), t1, new_t2, new_t1, c, first); } + else { + return false; + } } // Apply transformations of the form @@ -693,12 +698,7 @@ void th_rewriter::get_param_descrs(param_descrs & r) { arith_rewriter::get_param_descrs(r); bv_rewriter::get_param_descrs(r); array_rewriter::get_param_descrs(r); - insert_max_memory(r); - insert_max_steps(r); - r.insert(":push-ite-arith", CPK_BOOL, "(default: false) push if-then-else over arithmetic terms."); - r.insert(":push-ite-bv", CPK_BOOL, "(default: false) push if-then-else over bit-vector terms."); - r.insert(":pull-cheap-ite", CPK_BOOL, "(default: false) pull if-then-else terms when cheap."); - r.insert(":cache-all", CPK_BOOL, "(default: false) cache all intermediate results."); + rewriter_params::collect_param_descrs(r); } th_rewriter::~th_rewriter() { diff --git a/src/ast/rewriter/th_rewriter.h b/src/ast/rewriter/th_rewriter.h index 1b77c42c7..b25558dd9 100644 --- a/src/ast/rewriter/th_rewriter.h +++ b/src/ast/rewriter/th_rewriter.h @@ -37,7 +37,6 @@ public: void updt_params(params_ref const & p); static void get_param_descrs(param_descrs & r); - unsigned get_cache_size() const; unsigned get_num_steps() const; diff --git a/src/ast/simplifier/arith_simplifier_params.cpp b/src/ast/simplifier/arith_simplifier_params.cpp new file mode 100644 index 000000000..a3fabe02f --- /dev/null +++ b/src/ast/simplifier/arith_simplifier_params.cpp @@ -0,0 +1,26 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + arith_simplifier_params.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2012-12-02. + +Revision History: + +--*/ +#include"arith_simplifier_params.h" +#include"arith_simplifier_params_helper.hpp" + +void arith_simplifier_params::updt_params(params_ref const & _p) { + arith_simplifier_params_helper p(_p); + m_arith_expand_eqs = p.arith_expand_eqs(); + m_arith_process_all_eqs = p.arith_process_all_eqs(); +} diff --git a/src/front_end_params/arith_simplifier_params.h b/src/ast/simplifier/arith_simplifier_params.h similarity index 65% rename from src/front_end_params/arith_simplifier_params.h rename to src/ast/simplifier/arith_simplifier_params.h index 3e44b5a6e..109f73307 100644 --- a/src/front_end_params/arith_simplifier_params.h +++ b/src/ast/simplifier/arith_simplifier_params.h @@ -19,18 +19,17 @@ Revision History: #ifndef _ARITH_SIMPLIFIER_PARAMS_H_ #define _ARITH_SIMPLIFIER_PARAMS_H_ -#include"ini_file.h" +#include"params.h" -struct arith_simplifier_params { +struct arith_simplifier_params { bool m_arith_expand_eqs; bool m_arith_process_all_eqs; - arith_simplifier_params(): - m_arith_expand_eqs(false), - m_arith_process_all_eqs(false) { + arith_simplifier_params(params_ref const & p = params_ref()) { + updt_params(p); } - - void register_params(ini_params & p); + + void updt_params(params_ref const & _p); }; #endif /* _ARITH_SIMPLIFIER_PARAMS_H_ */ diff --git a/src/ast/simplifier/arith_simplifier_params_helper.pyg b/src/ast/simplifier/arith_simplifier_params_helper.pyg new file mode 100644 index 000000000..49a7cf3d2 --- /dev/null +++ b/src/ast/simplifier/arith_simplifier_params_helper.pyg @@ -0,0 +1,7 @@ +def_module_params(class_name='arith_simplifier_params_helper', + module_name="old_simplify", # Parameters will be in the old_simplify module + description="old simplification (stack) still used in the smt module", + export=True, + params=( + ('arith.expand_eqs', BOOL, False, 'expand equalities into two inequalities'), + ('arith.process_all_eqs', BOOL, False, 'put all equations in the form (= t c), where c is a numeral'))) diff --git a/src/ast/simplifier/array_simplifier_params.cpp b/src/ast/simplifier/array_simplifier_params.cpp new file mode 100644 index 000000000..bffff44d9 --- /dev/null +++ b/src/ast/simplifier/array_simplifier_params.cpp @@ -0,0 +1,26 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + array_simplifier_params.cpp + +Abstract: + + This file was created during code reorg. + +Author: + + Leonardo de Moura (leonardo) 2012-12-02. + +Revision History: + +--*/ +#include"array_simplifier_params.h" +#include"array_simplifier_params_helper.hpp" + +void array_simplifier_params::updt_params(params_ref const & _p) { + array_simplifier_params_helper p(_p); + m_array_canonize_simplify = p.array_canonize(); + m_array_simplify = p.array_simplify(); +} diff --git a/src/ast/simplifier/array_simplifier_params.h b/src/ast/simplifier/array_simplifier_params.h new file mode 100644 index 000000000..2f6fa720b --- /dev/null +++ b/src/ast/simplifier/array_simplifier_params.h @@ -0,0 +1,36 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + array_simplifier_params.h + +Abstract: + + This file was created during code reorg. + +Author: + + Leonardo de Moura (leonardo) 2012-12-02. + +Revision History: + +--*/ +#ifndef _ARRAY_SIMPLIFIER_PARAMS_H_ +#define _ARRAY_SIMPLIFIER_PARAMS_H_ + +#include"params.h" + +struct array_simplifier_params { + bool m_array_canonize_simplify; + bool m_array_simplify; // temporary hack for disabling array simplifier plugin. + + array_simplifier_params(params_ref const & p = params_ref()) { + updt_params(p); + } + + void updt_params(params_ref const & _p); +}; + +#endif /* _ARITH_SIMPLIFIER_PARAMS_H_ */ + diff --git a/src/ast/simplifier/array_simplifier_params_helper.pyg b/src/ast/simplifier/array_simplifier_params_helper.pyg new file mode 100644 index 000000000..93c184c23 --- /dev/null +++ b/src/ast/simplifier/array_simplifier_params_helper.pyg @@ -0,0 +1,6 @@ +def_module_params(class_name='array_simplifier_params_helper', + module_name="old_simplify", # Parameters will be in the old_simplify module + export=True, + params=( + ('array.canonize', BOOL, False, 'normalize array terms into normal form during simplification'), + ('array.simplify', BOOL, True, 'enable/disable array simplifications'))) diff --git a/src/ast/simplifier/array_simplifier_plugin.cpp b/src/ast/simplifier/array_simplifier_plugin.cpp index 8654db275..75c3cdbce 100644 --- a/src/ast/simplifier/array_simplifier_plugin.cpp +++ b/src/ast/simplifier/array_simplifier_plugin.cpp @@ -33,7 +33,7 @@ array_simplifier_plugin::array_simplifier_plugin( ast_manager & m, basic_simplifier_plugin& s, simplifier& simp, - theory_array_params const& p) : + array_simplifier_params const& p) : simplifier_plugin(symbol("array"),m), m_util(m), m_simp(s), diff --git a/src/ast/simplifier/array_simplifier_plugin.h b/src/ast/simplifier/array_simplifier_plugin.h index fffa18c3f..572da9a17 100644 --- a/src/ast/simplifier/array_simplifier_plugin.h +++ b/src/ast/simplifier/array_simplifier_plugin.h @@ -24,7 +24,7 @@ Revision History: #include"array_decl_plugin.h" #include"simplifier_plugin.h" #include"basic_simplifier_plugin.h" -#include"theory_array_params.h" +#include"array_simplifier_params.h" #include"simplifier.h" #include"obj_hashtable.h" #include"lbool.h" @@ -71,7 +71,7 @@ class array_simplifier_plugin : public simplifier_plugin { array_util m_util; basic_simplifier_plugin& m_simp; simplifier& m_simplifier; - theory_array_params const& m_params; + array_simplifier_params const& m_params; select_cache m_select_cache; ptr_vector m_tmp; ptr_vector m_tmp2; @@ -100,7 +100,7 @@ class array_simplifier_plugin : public simplifier_plugin { public: - array_simplifier_plugin(ast_manager & m, basic_simplifier_plugin& s, simplifier& simp, theory_array_params const& p); + array_simplifier_plugin(ast_manager & m, basic_simplifier_plugin& s, simplifier& simp, array_simplifier_params const& p); virtual ~array_simplifier_plugin(); virtual bool reduce(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result); diff --git a/src/ast/simplifier/bv_simplifier_params.cpp b/src/ast/simplifier/bv_simplifier_params.cpp new file mode 100644 index 000000000..aa9dcfc2d --- /dev/null +++ b/src/ast/simplifier/bv_simplifier_params.cpp @@ -0,0 +1,26 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + bv_simplifier_params.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2012-12-02. + +Revision History: + +--*/ +#include"bv_simplifier_params.h" +#include"bv_simplifier_params_helper.hpp" + +void bv_simplifier_params::updt_params(params_ref const & _p) { + bv_simplifier_params_helper p(_p); + m_hi_div0 = p.bv_hi_div0(); + m_bv2int_distribute = p.bv_bv2int_distribute(); +} diff --git a/src/front_end_params/bv_simplifier_params.h b/src/ast/simplifier/bv_simplifier_params.h similarity index 53% rename from src/front_end_params/bv_simplifier_params.h rename to src/ast/simplifier/bv_simplifier_params.h index a6ff749c4..5f5832235 100644 --- a/src/front_end_params/bv_simplifier_params.h +++ b/src/ast/simplifier/bv_simplifier_params.h @@ -19,20 +19,17 @@ Revision History: #ifndef _BV_SIMPLIFIER_PARAMS_H_ #define _BV_SIMPLIFIER_PARAMS_H_ -#include"ini_file.h" +#include"params.h" struct bv_simplifier_params { bool m_hi_div0; //!< if true, uses the hardware interpretation for div0, mod0, ... if false, div0, mod0, ... are considered uninterpreted. bool m_bv2int_distribute; //!< if true allows downward propagation of bv2int. - bv_simplifier_params(): - m_hi_div0(true), - m_bv2int_distribute(true) { - } - void register_params(ini_params & p) { - p.register_bool_param("HI_DIV0", m_hi_div0, "if true, then Z3 uses the usual hardware interpretation for division (rem, mod) by zero. Otherwise, these operations are considered uninterpreted."); - p.register_bool_param("BV2INT_DISTRIBUTE", m_bv2int_distribute, "if true, then int2bv is distributed over arithmetical operators."); + bv_simplifier_params(params_ref const & p = params_ref()) { + updt_params(p); } + + void updt_params(params_ref const & _p); }; #endif /* _BV_SIMPLIFIER_PARAMS_H_ */ diff --git a/src/ast/simplifier/bv_simplifier_params_helper.pyg b/src/ast/simplifier/bv_simplifier_params_helper.pyg new file mode 100644 index 000000000..24bc86150 --- /dev/null +++ b/src/ast/simplifier/bv_simplifier_params_helper.pyg @@ -0,0 +1,6 @@ +def_module_params(class_name='bv_simplifier_params_helper', + module_name="old_simplify", # Parameters will be in the old_simplify module + export=True, + params=( + ('bv.hi_div0', BOOL, True, 'if true, then Z3 uses the usual hardware interpretation for division (rem, mod) by zero; otherwise, these operations are considered uninterpreted'), + ('bv.bv2int_distribute', BOOL, True, 'if true, then int2bv is distributed over arithmetical operators'))) diff --git a/src/ast/substitution/substitution_tree.cpp b/src/ast/substitution/substitution_tree.cpp index 81b2f7be6..037d51e32 100644 --- a/src/ast/substitution/substitution_tree.cpp +++ b/src/ast/substitution/substitution_tree.cpp @@ -607,8 +607,8 @@ void substitution_tree::display(std::ostream & out, node * n, unsigned delta) co out << " "; display(out, n->m_subst); if (n->m_leaf) { - pp_params p; - p.m_pp_single_line = true; + params_ref p; + p.set_bool("single_line", true); out << " ==> "; out << mk_pp(n->m_expr, m_manager, p); out << "\n"; diff --git a/src/cmd_context/basic_cmds.cpp b/src/cmd_context/basic_cmds.cpp index 4c24b5ae6..8f65485ae 100644 --- a/src/cmd_context/basic_cmds.cpp +++ b/src/cmd_context/basic_cmds.cpp @@ -27,7 +27,9 @@ Notes: #include"cmd_util.h" #include"simplify_cmd.h" #include"eval_cmd.h" -#include"front_end_params.h" +#include"gparams.h" +#include"model_params.hpp" +#include"env_params.h" class help_cmd : public cmd { svector m_cmds; @@ -103,9 +105,10 @@ ATOMIC_CMD(get_model_cmd, "get-model", "retrieve model for the last check-sat co throw cmd_exception("model is not available"); model_ref m; ctx.get_check_sat_result()->get_model(m); - if (ctx.params().m_model_v1_pp || ctx.params().m_model_v2_pp) { + model_params p; + if (p.v1() || p.v2()) { std::ostringstream buffer; - model_v2_pp(buffer, *m, ctx.params().m_model_partial); + model_v2_pp(buffer, *m, p.partial()); ctx.regular_stream() << "\"" << escaped(buffer.str().c_str(), true) << "\"" << std::endl; } else { ctx.regular_stream() << "(model " << std::endl; @@ -156,7 +159,7 @@ public: }; ATOMIC_CMD(get_proof_cmd, "get-proof", "retrieve proof", { - if (ctx.params().m_proof_mode == PGM_DISABLED) + if (!ctx.produce_proofs()) throw cmd_exception("proof construction is not enabled, use command (set-option :produce-proofs true)"); if (!ctx.has_manager() || ctx.cs_state() != cmd_context::css_unsat) @@ -219,25 +222,6 @@ UNARY_CMD(pp_cmd, "display", "", "display the given term.", CPK_EXPR, expr UNARY_CMD(echo_cmd, "echo", "", "display the given string", CPK_STRING, char const *, ctx.regular_stream() << arg << std::endl;); -/** - \brief Convert a keyword into an internal Z3 option name -*/ -std::string smt_keyword2opt_name(symbol const & opt) { - std::string r; - SASSERT(opt.bare_str()[0] == ':'); - r = opt.bare_str() + 1; - unsigned sz = static_cast(r.size()); - for (unsigned i = 0; i < sz; i++) { - char curr = r[i]; - if ('a' <= curr && curr <= 'z') - r[i] = 'A' + (curr - 'a'); - else if (curr == '-') - r[i] = '_'; - } - TRACE("smt2_opt_name", tout << opt << " -> '" << r << "'\n";); - return r; -} - class set_get_option_cmd : public cmd { protected: symbol m_true; @@ -259,7 +243,6 @@ protected: symbol m_numeral_as_real; symbol m_error_behavior; symbol m_int_real_coercions; - ini_params m_ini; bool is_builtin_option(symbol const & s) const { return @@ -270,7 +253,7 @@ protected: } public: - set_get_option_cmd(char const * name, front_end_params & params): + set_get_option_cmd(char const * name): cmd(name), m_true("true"), m_false("false"), @@ -289,10 +272,7 @@ public: m_global_decls(":global-decls"), m_numeral_as_real(":numeral-as-real"), m_error_behavior(":error-behavior"), - m_int_real_coercions(":int-real-coercions"), - m_ini(false) { - params.register_params(m_ini); - register_pp_params(m_ini); + m_int_real_coercions(":int-real-coercions") { } virtual ~set_get_option_cmd() {} @@ -324,22 +304,13 @@ class set_option_cmd : public set_get_option_cmd { } void set_param(cmd_context & ctx, char const * value) { - m_ini.freeze(ctx.has_manager()); - std::string internal_opt = smt_keyword2opt_name(m_option); try { - std::string old_value; - if (!m_ini.get_param_value(internal_opt.c_str(), old_value)) { - m_unsupported = true; - return; - } - m_ini.set_param_value(internal_opt.c_str(), value); + gparams::set(m_option, value); + env_params::updt_params(); + ctx.global_params_updated(); } - catch (set_get_param_exception ex) { - std::string msg = "error setting '"; - msg += m_option.str(); - msg += "', "; - msg += ex.get_msg(); - throw cmd_exception(msg); + catch (gparams::exception ex) { + throw cmd_exception(ex.msg()); } } @@ -406,8 +377,8 @@ class set_option_cmd : public set_get_option_cmd { } public: - set_option_cmd(front_end_params & params): - set_get_option_cmd("set-option", params), + set_option_cmd(): + set_get_option_cmd("set-option"), m_unsupported(false) { } @@ -485,8 +456,8 @@ class get_option_cmd : public set_get_option_cmd { } public: - get_option_cmd(front_end_params & params): - set_get_option_cmd("get-option", params) { + get_option_cmd(): + set_get_option_cmd("get-option") { } virtual char const * get_usage() const { return ""; } virtual char const * get_descr(cmd_context & ctx) const { return "get configuration option."; } @@ -507,13 +478,13 @@ public: print_bool(ctx, ctx.interactive_mode()); } else if (opt == m_produce_proofs) { - print_bool(ctx, ctx.params().m_proof_mode != PGM_DISABLED); + print_bool(ctx, ctx.produce_proofs()); } else if (opt == m_produce_unsat_cores) { print_bool(ctx, ctx.produce_unsat_cores()); } else if (opt == m_produce_models) { - print_bool(ctx, ctx.params().m_model); + print_bool(ctx, ctx.produce_models()); } else if (opt == m_produce_assignments) { print_bool(ctx, ctx.produce_assignments()); @@ -545,12 +516,10 @@ public: print_bool(ctx, ctx.m().int_real_coercions()); } else { - std::string iopt = smt_keyword2opt_name(opt); - std::string r; - if (m_ini.get_param_value(iopt.c_str(), r)) { - ctx.regular_stream() << r << std::endl; + try { + ctx.regular_stream() << gparams::get_value(opt) << std::endl; } - else { + catch (gparams::exception ex) { ctx.print_unsupported(opt); } } @@ -744,8 +713,8 @@ void install_basic_cmds(cmd_context & ctx) { ctx.insert(alloc(get_assertions_cmd)); ctx.insert(alloc(get_proof_cmd)); ctx.insert(alloc(get_unsat_core_cmd)); - ctx.insert(alloc(set_option_cmd, ctx.params())); - ctx.insert(alloc(get_option_cmd, ctx.params())); + ctx.insert(alloc(set_option_cmd)); + ctx.insert(alloc(get_option_cmd)); ctx.insert(alloc(get_info_cmd)); ctx.insert(alloc(set_info_cmd)); ctx.insert(alloc(builtin_cmd, "assert", "", "assert term.")); diff --git a/src/cmd_context/cmd_context.cpp b/src/cmd_context/cmd_context.cpp index afcac48ac..0380e91ea 100644 --- a/src/cmd_context/cmd_context.cpp +++ b/src/cmd_context/cmd_context.cpp @@ -16,7 +16,6 @@ Notes: --*/ #include -#include"front_end_params.h" #include"tptr.h" #include"cmd_context.h" #include"func_decl_dependencies.h" @@ -300,10 +299,8 @@ public: } }; -cmd_context::cmd_context(front_end_params * params, bool main_ctx, ast_manager * m, symbol const & l): +cmd_context::cmd_context(bool main_ctx, ast_manager * m, symbol const & l): m_main_ctx(main_ctx), - m_params(params == 0 ? alloc(front_end_params) : params), - m_params_owner(params == 0), m_logic(l), m_interactive_mode(false), m_global_decls(false), // :global-decls is false by default. @@ -343,39 +340,54 @@ cmd_context::~cmd_context() { finalize_probes(); m_solver = 0; m_check_sat_result = 0; - if (m_params_owner) { - dealloc(m_params); +} + +void cmd_context::global_params_updated() { + m_params.updt_params(); + if (m_solver) { + params_ref p; + if (!m_params.m_auto_config) + p.set_bool("auto_config", false); + m_solver->updt_params(p); } } void cmd_context::set_produce_models(bool f) { - params().m_model = f; if (m_solver) m_solver->set_produce_models(f); + m_params.m_model = f; } void cmd_context::set_produce_unsat_cores(bool f) { // can only be set before initialization SASSERT(!has_manager()); - m_produce_unsat_cores = f; + m_params.m_unsat_core = f; } void cmd_context::set_produce_proofs(bool f) { // can only be set before initialization SASSERT(!has_manager()); - params().m_proof_mode = f ? PGM_FINE : PGM_DISABLED; -} - -bool cmd_context::is_smtlib2_compliant() const { - return params().m_smtlib2_compliant; + m_params.m_proof = f; } bool cmd_context::produce_models() const { - return params().m_model; + return m_params.m_model; } bool cmd_context::produce_proofs() const { - return params().m_proof_mode != PGM_DISABLED; + return m_params.m_proof; +} + +bool cmd_context::produce_unsat_cores() const { + return m_params.m_unsat_core; +} + +bool cmd_context::well_sorted_check_enabled() const { + return m_params.m_well_sorted_check; +} + +bool cmd_context::validate_model_enabled() const { + return m_params.m_model_validate; } cmd_context::check_sat_state cmd_context::cs_state() const { @@ -460,6 +472,7 @@ bool cmd_context::logic_has_arith_core(symbol const & s) const { s == "LIA" || s == "LRA" || s == "QF_FPA" || + s == "QF_FPABV" || s == "HORN"; } @@ -478,6 +491,7 @@ bool cmd_context::logic_has_bv_core(symbol const & s) const { s == "QF_ABV" || s == "QF_AUFBV" || s == "QF_BVRE" || + s == "QF_FPABV" || s == "HORN"; } @@ -502,7 +516,7 @@ bool cmd_context::logic_has_seq() const { } bool cmd_context::logic_has_floats() const { - return !has_logic() || m_logic == "QF_FPA"; + return !has_logic() || m_logic == "QF_FPA" || m_logic == "QF_FPABV"; } bool cmd_context::logic_has_array_core(symbol const & s) const { @@ -568,10 +582,7 @@ void cmd_context::init_manager_core(bool new_manager) { insert(pm().mk_plist_decl()); } if (m_solver) { - m_solver->set_produce_unsat_cores(m_produce_unsat_cores); - m_solver->set_produce_models(params().m_model); - m_solver->set_produce_proofs(params().m_proof_mode == PGM_FINE); - m_solver->init(m(), m_logic); + init_solver_options(m_solver.get()); } m_check_logic.set_logic(m(), m_logic); } @@ -580,11 +591,14 @@ void cmd_context::init_manager() { SASSERT(m_manager == 0); SASSERT(m_pmanager == 0); m_check_sat_result = 0; - m_manager = alloc(ast_manager, params().m_proof_mode, params().m_trace_stream); + m_manager = alloc(ast_manager, + produce_proofs() ? PGM_FINE : PGM_DISABLED, + m_params.m_trace ? m_params.m_trace_file_name.c_str() : 0); m_pmanager = alloc(pdecl_manager, *m_manager); init_manager_core(true); - if (params().m_smtlib2_compliant) - m_manager->enable_int_real_coercions(false); + // PARAM-TODO + // if (params().m_smtlib2_compliant) + // m_manager->enable_int_real_coercions(false); } void cmd_context::init_external_manager() { @@ -599,7 +613,7 @@ bool cmd_context::supported_logic(symbol const & s) const { logic_has_arith_core(s) || logic_has_bv_core(s) || logic_has_array_core(s) || logic_has_seq_core(s) || logic_has_horn(s) || - s == "QF_FPA"; + s == "QF_FPA" || s == "QF_FPABV"; } void cmd_context::set_logic(symbol const & s) { @@ -843,7 +857,7 @@ object_ref * cmd_context::find_object_ref(symbol const & s) const { return r; } -#define CHECK_SORT(T) if (params().m_well_sorted_check) m().check_sorts_core(T) +#define CHECK_SORT(T) if (well_sorted_check_enabled()) m().check_sorts_core(T) void cmd_context::mk_const(symbol const & s, expr_ref & result) const { mk_app(s, 0, 0, 0, 0, 0, result); @@ -883,13 +897,13 @@ void cmd_context::mk_app(symbol const & s, unsigned num_args, expr * const * arg return; } SASSERT(num_args > 0); - TRACE("macro_bug", tout << "m_well_sorted_check: " << params().m_well_sorted_check << "\n"; + TRACE("macro_bug", tout << "well_sorted_check_enabled(): " << well_sorted_check_enabled() << "\n"; tout << "s: " << s << "\n"; tout << "body:\n" << mk_ismt2_pp(_m.second, m()) << "\n"; tout << "args:\n"; for (unsigned i = 0; i < num_args; i++) tout << mk_ismt2_pp(args[i], m()) << "\n" << mk_pp(m().get_sort(args[i]), m()) << "\n";); var_subst subst(m()); subst(_m.second, num_args, args, result); - if (params().m_well_sorted_check && !is_well_sorted(m(), result)) + if (well_sorted_check_enabled() && !is_well_sorted(m(), result)) throw cmd_exception("invalid macro application, sort mismatch ", s); return; } @@ -918,7 +932,7 @@ void cmd_context::mk_app(symbol const & s, unsigned num_args, expr * const * arg func_decl * f = fs.find(m(), num_args, args, range); if (f == 0) throw cmd_exception("unknown constant ", s); - if (params().m_well_sorted_check) + if (well_sorted_check_enabled()) m().check_sort(f, num_args, args); result = m().mk_app(f, num_args, args); return; @@ -1139,7 +1153,7 @@ void cmd_context::assert_expr(expr * t) { m_check_sat_result = 0; m().inc_ref(t); m_assertions.push_back(t); - if (m_produce_unsat_cores) + if (produce_unsat_cores()) m_assertion_names.push_back(0); if (m_solver) m_solver->assert_expr(t); @@ -1148,7 +1162,7 @@ void cmd_context::assert_expr(expr * t) { void cmd_context::assert_expr(symbol const & name, expr * t) { if (!m_check_logic(t)) throw cmd_exception(m_check_logic.get_last_error()); - if (!m_produce_unsat_cores || name == symbol::null) { + if (!produce_unsat_cores() || name == symbol::null) { assert_expr(t); return; } @@ -1254,7 +1268,7 @@ void cmd_context::restore_assertions(unsigned old_sz) { SASSERT(old_sz <= m_assertions.size()); SASSERT(!m_interactive_mode || m_assertions.size() == m_assertion_strings.size()); restore(m(), m_assertions, old_sz); - if (m_produce_unsat_cores) + if (produce_unsat_cores()) restore(m(), m_assertion_names, old_sz); if (m_interactive_mode) m_assertion_strings.shrink(old_sz); @@ -1283,18 +1297,12 @@ void cmd_context::pop(unsigned n) { void cmd_context::check_sat(unsigned num_assumptions, expr * const * assumptions) { if (m_ignore_check) return; - IF_VERBOSE(100, verbose_stream() << "check-sat..." << std::endl;); + IF_VERBOSE(100, verbose_stream() << "(started \"check-sat\")" << std::endl;); TRACE("before_check_sat", dump_assertions(tout);); - if (params().m_ignore_checksat) { - m_check_sat_result = 0; - regular_stream() << "unknown" << std::endl; - return; - } if (!has_manager()) init_manager(); if (m_solver) { m_check_sat_result = m_solver.get(); // solver itself stores the result. - m_solver->set_front_end_params(params()); m_solver->set_progress_callback(this); scoped_watch sw(*this); cancel_eh eh(*m_solver); @@ -1392,7 +1400,7 @@ struct contains_array_op_proc { \brief Check if the current model satisfies the quantifier free formulas. */ void cmd_context::validate_model() { - if (!params().m_model_validate) + if (!validate_model_enabled()) return; if (!is_model_available()) return; @@ -1400,9 +1408,9 @@ void cmd_context::validate_model() { get_check_sat_result()->get_model(md); SASSERT(md.get() != 0); params_ref p; - p.set_uint(":max-degree", UINT_MAX); // evaluate algebraic numbers of any degree. - p.set_uint(":sort-store", true); - p.set_bool(":model-completion", true); + p.set_uint("max_degree", UINT_MAX); // evaluate algebraic numbers of any degree. + p.set_uint("sort_store", true); + p.set_bool("model_completion", true); model_evaluator evaluator(*(md.get()), p); contains_array_op_proc contains_array(m()); { @@ -1435,15 +1443,23 @@ void cmd_context::validate_model() { } } +void cmd_context::init_solver_options(solver * s) { + m_solver->set_produce_unsat_cores(produce_unsat_cores()); + m_solver->set_produce_models(produce_models()); + m_solver->set_produce_proofs(produce_proofs()); + m_solver->init(m(), m_logic); + if (!m_params.m_auto_config) { + params_ref p; + p.set_bool("auto_config", false); + m_solver->updt_params(p); + } +} + void cmd_context::set_solver(solver * s) { m_check_sat_result = 0; m_solver = s; - m_solver->set_front_end_params(params()); if (has_manager() && s != 0) { - m_solver->set_produce_unsat_cores(m_produce_unsat_cores); - m_solver->set_produce_models(params().m_model); - m_solver->set_produce_proofs(params().m_proof_mode == PGM_FINE); - m_solver->init(m(), m_logic); + init_solver_options(s); // assert formulas and create scopes in the new solver. unsigned lim = 0; svector::iterator it = m_scopes.begin(); @@ -1497,7 +1513,7 @@ void cmd_context::display_assertions() { } bool cmd_context::is_model_available() const { - if (params().m_model && + if (produce_models() && has_manager() && (cs_state() == css_sat || cs_state() == css_unknown)) { model_ref md; @@ -1520,8 +1536,7 @@ cmd_context::pp_env & cmd_context::get_pp_env() const { } void cmd_context::pp(expr * n, unsigned num_vars, char const * var_prefix, format_ns::format_ref & r, sbuffer & var_names) const { - mk_smt2_format(n, get_pp_env(), get_pp_default_params(), - num_vars, var_prefix, r, var_names); + mk_smt2_format(n, get_pp_env(), params_ref(), num_vars, var_prefix, r, var_names); } void cmd_context::pp(expr * n, format_ns::format_ref & r) const { @@ -1530,7 +1545,7 @@ void cmd_context::pp(expr * n, format_ns::format_ref & r) const { } void cmd_context::pp(func_decl * f, format_ns::format_ref & r) const { - mk_smt2_format(f, get_pp_env(), get_pp_default_params(), r); + mk_smt2_format(f, get_pp_env(), params_ref(), r); } void cmd_context::display(std::ostream & out, sort * s, unsigned indent) const { @@ -1538,7 +1553,7 @@ void cmd_context::display(std::ostream & out, sort * s, unsigned indent) const { f = pp(s); if (indent > 0) f = format_ns::mk_indent(m(), indent, f); - ::pp(out, f.get(), m(), get_pp_default_params()); + ::pp(out, f.get(), m()); } void cmd_context::display(std::ostream & out, expr * n, unsigned indent, unsigned num_vars, char const * var_prefix, sbuffer & var_names) const { @@ -1546,7 +1561,7 @@ void cmd_context::display(std::ostream & out, expr * n, unsigned indent, unsigne pp(n, num_vars, var_prefix, f, var_names); if (indent > 0) f = format_ns::mk_indent(m(), indent, f); - ::pp(out, f.get(), m(), get_pp_default_params()); + ::pp(out, f.get(), m()); } void cmd_context::display(std::ostream & out, expr * n, unsigned indent) const { @@ -1559,7 +1574,7 @@ void cmd_context::display(std::ostream & out, func_decl * d, unsigned indent) co pp(d, f); if (indent > 0) f = format_ns::mk_indent(m(), indent, f); - ::pp(out, f.get(), m(), get_pp_default_params()); + ::pp(out, f.get(), m()); } void cmd_context::dump_assertions(std::ostream & out) const { diff --git a/src/cmd_context/cmd_context.h b/src/cmd_context/cmd_context.h index 5f83e0224..2edc87ca6 100644 --- a/src/cmd_context/cmd_context.h +++ b/src/cmd_context/cmd_context.h @@ -36,8 +36,7 @@ Notes: #include"check_logic.h" #include"progress_callback.h" #include"scoped_ptr_vector.h" - -struct front_end_params; +#include"context_params.h" class func_decls { func_decl * m_decls; @@ -132,9 +131,8 @@ public: }; protected: + context_params m_params; bool m_main_ctx; - front_end_params * m_params; - bool m_params_owner; symbol m_logic; bool m_interactive_mode; bool m_global_decls; @@ -245,10 +243,13 @@ protected: void print_unsupported_msg() { regular_stream() << "unsupported" << std::endl; } void print_unsupported_info(symbol const& s) { if (s != symbol::null) diagnostic_stream() << "; " << s << std::endl;} + void init_solver_options(solver * s); + public: - cmd_context(front_end_params * params = 0, bool main_ctx = true, ast_manager * m = 0, symbol const & l = symbol::null); + cmd_context(bool main_ctx = true, ast_manager * m = 0, symbol const & l = symbol::null); ~cmd_context(); - bool is_smtlib2_compliant() const; + context_params & params() { return m_params; } + void global_params_updated(); // this method should be invoked when global (and module) params are updated. void set_logic(symbol const & s); bool has_logic() const { return m_logic != symbol::null; } symbol const & get_logic() const { return m_logic; } @@ -270,7 +271,9 @@ public: void set_random_seed(unsigned s) { m_random_seed = s; } bool produce_models() const; bool produce_proofs() const; - bool produce_unsat_cores() const { return m_produce_unsat_cores; } + bool produce_unsat_cores() const; + bool well_sorted_check_enabled() const; + bool validate_model_enabled() const; void set_produce_models(bool flag); void set_produce_unsat_cores(bool flag); void set_produce_proofs(bool flag); @@ -285,7 +288,6 @@ public: virtual ast_manager & get_ast_manager() { return m(); } pdecl_manager & pm() const { if (!m_pmanager) const_cast(this)->init_manager(); return *m_pmanager; } sexpr_manager & sm() const { if (!m_sexpr_manager) const_cast(this)->m_sexpr_manager = alloc(sexpr_manager); return *m_sexpr_manager; } - front_end_params & params() const { return *m_params; } void set_solver(solver * s); solver * get_solver() const { return m_solver.get(); } diff --git a/src/cmd_context/context_params.cpp b/src/cmd_context/context_params.cpp new file mode 100644 index 000000000..495f73b75 --- /dev/null +++ b/src/cmd_context/context_params.cpp @@ -0,0 +1,114 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + context_params.cpp + +Abstract: + + Goodies for managing context parameters in the cmd_context and + api_context + +Author: + + Leonardo (leonardo) 2012-12-01 + +Notes: + +--*/ +#include"context_params.h" +#include"gparams.h" +#include"params.h" + +context_params::context_params() { + updt_params(); +} + +void context_params::set_bool(bool & opt, char const * param, char const * value) { + if (strcmp(value, "true") == 0) { + opt = true; + } + else if (strcmp(value, "false") == 0) { + opt = false; + } + else { + throw default_exception("invalid value '%s' for Boolean parameter '%s'", value, param); + } +} + +void context_params::set(char const * param, char const * value) { + std::string p = param; + unsigned n = p.size(); + for (unsigned i = 0; i < n; i++) { + if (p[i] >= 'A' && p[i] <= 'Z') + p[i] = p[i] - 'A' + 'a'; + else if (p[i] == '-') + p[i] = '_'; + } + if (p == "timeout") { + long val = strtol(value, 0, 10); + m_timeout = static_cast(val); + } + else if (p == "type_check" || p == "well_sorted_check") { + set_bool(m_well_sorted_check, param, value); + } + else if (p == "auto_config") { + set_bool(m_auto_config, param, value); + } + else if (p == "proof") { + set_bool(m_proof, param, value); + } + else if (p == "model") { + set_bool(m_model, param, value); + } + else if (p == "model_validate") { + set_bool(m_model_validate, param, value); + } + else if (p == "trace") { + set_bool(m_trace, param, value); + } + else if (p == "trace_file_name") { + m_trace_file_name = value; + } + else if (p == "unsat_core") { + set_bool(m_unsat_core, param, value); + } + else if (p == "debug_ref_count") { + set_bool(m_debug_ref_count, param, value); + } + else { + throw default_exception("unknown parameter '%s'", p.c_str()); + } +} + +void context_params::updt_params() { + updt_params(gparams::get()); +} + +void context_params::updt_params(params_ref const & p) { + m_timeout = p.get_uint("timeout", UINT_MAX); + m_well_sorted_check = p.get_bool("type_check", p.get_bool("well_sorted_check", true)); + m_auto_config = p.get_bool("auto_config", true); + m_proof = p.get_bool("proof", false); + m_model = p.get_bool("model", true); + m_model_validate = p.get_bool("model_validate", false); + m_trace = p.get_bool("trace", false); + m_trace_file_name = p.get_str("trace_file_name", "z3.log"); + m_unsat_core = p.get_bool("unsat_core", false); + m_debug_ref_count = p.get_bool("debug_ref_count", false); +} + +void context_params::collect_param_descrs(param_descrs & d) { + d.insert("timeout", CPK_UINT, "default timeout (in milliseconds) used for solvers", "4294967295"); + d.insert("well_sorted_check", CPK_BOOL, "type checker", "true"); + d.insert("type_check", CPK_BOOL, "type checker (alias for well_sorted_check)", "true"); + d.insert("auto_config", CPK_BOOL, "use heuristics to automatically select solver and configure it", "true"); + d.insert("proof", CPK_BOOL, "proof generation, it must be enabled when the Z3 context is created", "false"); + d.insert("model", CPK_BOOL, "model generation for solvers, this parameter can be overwritten when creating a solver", "true"); + d.insert("model_validate", CPK_BOOL, "validate models produced by solvers", "false"); + d.insert("trace", CPK_BOOL, "trace generation for VCC", "false"); + d.insert("trace_file_name", CPK_STRING, "trace out file name (see option 'trace')", "z3.log"); + d.insert("unsat_core", CPK_BOOL, "unsat-core generation for solvers, this parameter can be overwritten when creating a solver, not every solver in Z3 supports unsat core generation", "false"); + d.insert("debug_ref_count", CPK_BOOL, "debug support for AST reference counting", "false"); +} diff --git a/src/cmd_context/context_params.h b/src/cmd_context/context_params.h new file mode 100644 index 000000000..6b42b5b50 --- /dev/null +++ b/src/cmd_context/context_params.h @@ -0,0 +1,51 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + context_params.h + +Abstract: + + Goodies for managing context parameters in the cmd_context and + api_context + +Author: + + Leonardo (leonardo) 2012-12-01 + +Notes: + +--*/ +#ifndef _CONTEXT_PARAMS_H_ +#define _CONTEXT_PARAMS_H_ + +#include"params.h" + +class context_params { + void set_bool(bool & opt, char const * param, char const * value); + +public: + bool m_auto_config; + bool m_proof; + bool m_debug_ref_count; + bool m_trace; + std::string m_trace_file_name; + bool m_well_sorted_check; + bool m_model; + bool m_model_validate; + bool m_unsat_core; + unsigned m_timeout; + + context_params(); + void set(char const * param, char const * value); + void updt_params(); + void updt_params(params_ref const & p); + static void collect_param_descrs(param_descrs & d); + /* + REG_PARAMS('context_params::collect_param_descrs') + */ +}; + + +#endif diff --git a/src/cmd_context/eval_cmd.cpp b/src/cmd_context/eval_cmd.cpp index fe9c738a2..7ebe2f54f 100644 --- a/src/cmd_context/eval_cmd.cpp +++ b/src/cmd_context/eval_cmd.cpp @@ -62,7 +62,7 @@ public: SASSERT(last_result); last_result->get_model(md); expr_ref r(ctx.m()); - unsigned timeout = m_params.get_uint(":timeout", UINT_MAX); + unsigned timeout = m_params.get_uint("timeout", UINT_MAX); model_evaluator ev(*(md.get()), m_params); cancel_eh eh(ev); { diff --git a/src/cmd_context/extra_cmds/dbg_cmds.cpp b/src/cmd_context/extra_cmds/dbg_cmds.cpp index b7b4f058d..509b5ff2e 100644 --- a/src/cmd_context/extra_cmds/dbg_cmds.cpp +++ b/src/cmd_context/extra_cmds/dbg_cmds.cpp @@ -141,8 +141,8 @@ public: UNARY_CMD(bool_rewriter_cmd, "dbg-bool-rewriter", "", "apply the Boolean rewriter to the given term", CPK_EXPR, expr *, { expr_ref t(ctx.m()); params_ref p; - p.set_bool(":flat", false); - SASSERT(p.get_bool(":flat", true) == false); + p.set_bool("flat", false); + SASSERT(p.get_bool("flat", true) == false); bool_rewriter_star r(ctx.m(), p); r(arg, t); ctx.display(ctx.regular_stream(), t); @@ -153,7 +153,7 @@ UNARY_CMD(bool_frewriter_cmd, "dbg-bool-flat-rewriter", "", "apply the Boo expr_ref t(ctx.m()); { params_ref p; - p.set_bool(":flat", true); + p.set_bool("flat", true); bool_rewriter_star r(ctx.m(), p); r(arg, t); } @@ -165,8 +165,8 @@ UNARY_CMD(elim_and_cmd, "dbg-elim-and", "", "apply the Boolean rewriter (e expr_ref t(ctx.m()); { params_ref p; - p.set_bool(":flat", true); - p.set_bool(":elim-and", true); + p.set_bool("flat", true); + p.set_bool("elim_and", true); bool_rewriter_star r(ctx.m(), p); r(arg, t); } @@ -208,15 +208,15 @@ UNARY_CMD(some_value_cmd, "dbg-some-value", "", "retrieve some value of th void tst_params(cmd_context & ctx) { params_ref p1; params_ref p2; - p1.set_uint(":val", 100); + p1.set_uint("val", 100); p2 = p1; - SASSERT(p2.get_uint(":val", 0) == 100); - p2.set_uint(":val", 200); - SASSERT(p2.get_uint(":val", 0) == 200); - SASSERT(p1.get_uint(":val", 0) == 100); + SASSERT(p2.get_uint("val", 0) == 100); + p2.set_uint("val", 200); + SASSERT(p2.get_uint("val", 0) == 200); + SASSERT(p1.get_uint("val", 0) == 100); p2 = p1; - SASSERT(p2.get_uint(":val", 0) == 100); - SASSERT(p1.get_uint(":val", 0) == 100); + SASSERT(p2.get_uint("val", 0) == 100); + SASSERT(p1.get_uint("val", 0) == 100); ctx.regular_stream() << "worked" << std::endl; } diff --git a/src/cmd_context/extra_cmds/polynomial_cmds.cpp b/src/cmd_context/extra_cmds/polynomial_cmds.cpp index 7b37b750e..e68789dac 100644 --- a/src/cmd_context/extra_cmds/polynomial_cmds.cpp +++ b/src/cmd_context/extra_cmds/polynomial_cmds.cpp @@ -26,10 +26,10 @@ Notes: #include"parametric_cmd.h" #include"mpq.h" #include"algebraic_numbers.h" -#include"pp.h" -#include"pp_params.h" #include"polynomial_var2value.h" #include"expr2var.h" +#include"pp.h" +#include"pp_params.hpp" static void to_poly(cmd_context & ctx, expr * t) { polynomial::numeral_manager nm; @@ -145,9 +145,11 @@ class poly_isolate_roots_cmd : public cmd { scoped_anum_vector rs(m_am); m_am.isolate_roots(m_p, m_x2v, rs); ctx.regular_stream() << "(roots"; + pp_params params; + bool pp_decimal = params.decimal(); for (unsigned i = 0; i < rs.size(); i++) { ctx.regular_stream() << std::endl; - if (!get_pp_default_params().m_pp_decimal) + if (!pp_decimal) m_am.display_root_smt2(ctx.regular_stream(), rs[i]); else m_am.display_decimal(ctx.regular_stream(), rs[i]); diff --git a/src/cmd_context/extra_cmds/subpaving_cmds.cpp b/src/cmd_context/extra_cmds/subpaving_cmds.cpp index 9b84ddf68..632f558dc 100644 --- a/src/cmd_context/extra_cmds/subpaving_cmds.cpp +++ b/src/cmd_context/extra_cmds/subpaving_cmds.cpp @@ -31,7 +31,7 @@ static void to_subpaving(cmd_context & ctx, expr * t) { expr2var e2v(m); expr2subpaving e2s(m, *s, &e2v); params_ref p; - p.set_bool(":mul-to-power", true); + p.set_bool("mul_to_power", true); th_rewriter simp(m, p); expr_ref t_s(m); simp(t, t_s); diff --git a/src/cmd_context/parametric_cmd.cpp b/src/cmd_context/parametric_cmd.cpp index bc06d3ee6..c229bc29c 100644 --- a/src/cmd_context/parametric_cmd.cpp +++ b/src/cmd_context/parametric_cmd.cpp @@ -16,6 +16,7 @@ Notes: --*/ #include +#include"cmd_context.h" #include"parametric_cmd.h" char const * parametric_cmd::get_descr(cmd_context & ctx) const { @@ -37,13 +38,15 @@ cmd_arg_kind parametric_cmd::next_arg_kind(cmd_context & ctx) const { void parametric_cmd::set_next_arg(cmd_context & ctx, symbol const & s) { if (m_last == symbol::null) { - m_last = s; + m_last = symbol(norm_param_name(s).c_str()); if (pdescrs(ctx).get_kind(m_last.bare_str()) == CPK_INVALID) throw cmd_exception("invalid keyword argument"); return; } - m_params.set_sym(m_last.bare_str(), s); - m_last = symbol::null; + else { + m_params.set_sym(m_last.bare_str(), s); + m_last = symbol::null; + } } param_descrs const & parametric_cmd::pdescrs(cmd_context & ctx) const { diff --git a/src/cmd_context/simplify_cmd.cpp b/src/cmd_context/simplify_cmd.cpp index 089eb353b..3a1828a51 100644 --- a/src/cmd_context/simplify_cmd.cpp +++ b/src/cmd_context/simplify_cmd.cpp @@ -40,9 +40,9 @@ public: virtual void init_pdescrs(cmd_context & ctx, param_descrs & p) { th_rewriter::get_param_descrs(p); insert_timeout(p); - p.insert(":print", CPK_BOOL, "(default: true) print the simplified term."); - p.insert(":print-proofs", CPK_BOOL, "(default: false) print a proof showing the original term is equal to the resultant one."); - p.insert(":print-statistics", CPK_BOOL, "(default: false) print statistics."); + p.insert("print", CPK_BOOL, "(default: true) print the simplified term."); + p.insert("print_proofs", CPK_BOOL, "(default: false) print a proof showing the original term is equal to the resultant one."); + p.insert("print_statistics", CPK_BOOL, "(default: false) print statistics."); } virtual ~simplify_cmd() { @@ -67,12 +67,12 @@ public: throw cmd_exception("invalid simplify command, argument expected"); expr_ref r(ctx.m()); proof_ref pr(ctx.m()); - if (m_params.get_bool(":som", false)) - m_params.set_bool(":flat", true); + if (m_params.get_bool("som", false)) + m_params.set_bool("flat", true); th_rewriter s(ctx.m(), m_params); unsigned cache_sz; unsigned num_steps = 0; - unsigned timeout = m_params.get_uint(":timeout", UINT_MAX); + unsigned timeout = m_params.get_uint("timeout", UINT_MAX); bool failed = false; cancel_eh eh(s); { @@ -94,17 +94,17 @@ public: num_steps = s.get_num_steps(); s.cleanup(); } - if (m_params.get_bool(":print", true)) { + if (m_params.get_bool("print", true)) { ctx.display(ctx.regular_stream(), r); ctx.regular_stream() << std::endl; } - if (!failed && m_params.get_bool(":print-proofs", false)) { + if (!failed && m_params.get_bool("print_proofs", false)) { ast_smt_pp pp(ctx.m()); pp.set_logic(ctx.get_logic().str().c_str()); pp.display_expr_smt2(ctx.regular_stream(), pr.get()); ctx.regular_stream() << std::endl; } - if (m_params.get_bool(":print-statistics", false)) { + if (m_params.get_bool("print_statistics", false)) { shared_occs s1(ctx.m()); if (!failed) s1(r); diff --git a/src/cmd_context/tactic_cmds.cpp b/src/cmd_context/tactic_cmds.cpp index 32adb5f47..ca87406c7 100644 --- a/src/cmd_context/tactic_cmds.cpp +++ b/src/cmd_context/tactic_cmds.cpp @@ -24,7 +24,6 @@ Notes: #include"scoped_ctrl_c.h" #include"cancel_eh.h" #include"model_smt2_pp.h" -#include"params2front_end_params.h" #include"ast_smt2_pp.h" #include"tactic.h" #include"tactical.h" @@ -153,7 +152,7 @@ public: virtual void init_pdescrs(cmd_context & ctx, param_descrs & p) { insert_timeout(p); insert_max_memory(p); - p.insert(":print-statistics", CPK_BOOL, "(default: false) print statistics."); + p.insert("print_statistics", CPK_BOOL, "(default: false) print statistics."); } void display_statistics(cmd_context & ctx, tactic * t) { @@ -180,19 +179,17 @@ public: virtual void init_pdescrs(cmd_context & ctx, param_descrs & p) { exec_given_tactic_cmd::init_pdescrs(ctx, p); - p.insert(":print-unsat-core", CPK_BOOL, "(default: false) print unsatisfiable core."); - p.insert(":print-proof", CPK_BOOL, "(default: false) print proof."); - p.insert(":print-model", CPK_BOOL, "(default: false) print model."); + p.insert("print_unsat_core", CPK_BOOL, "(default: false) print unsatisfiable core."); + p.insert("print_proof", CPK_BOOL, "(default: false) print proof."); + p.insert("print_model", CPK_BOOL, "(default: false) print model."); } virtual void execute(cmd_context & ctx) { params_ref p = ps(); - front_end_params2params(ctx.params(), p); tactic_ref tref = using_params(sexpr2tactic(ctx, m_tactic), p); - tref->set_front_end_params(ctx.params()); tref->set_logic(ctx.get_logic()); ast_manager & m = ctx.m(); - unsigned timeout = p.get_uint(":timeout", UINT_MAX); + unsigned timeout = p.get_uint("timeout", UINT_MAX); goal_ref g = alloc(goal, m, ctx.produce_proofs(), ctx.produce_models(), ctx.produce_unsat_cores()); assert_exprs_from(ctx, *g); TRACE("check_sat_using", g->display(tout);); @@ -241,7 +238,7 @@ public: ptr_vector core_elems; m.linearize(core, core_elems); result->m_core.append(core_elems.size(), core_elems.c_ptr()); - if (p.get_bool(":print-unsat-core", false)) { + if (p.get_bool("print_unsat_core", false)) { ctx.regular_stream() << "(unsat-core"; ptr_vector::const_iterator it = core_elems.begin(); ptr_vector::const_iterator end = core_elems.end(); @@ -255,7 +252,7 @@ public: if (ctx.produce_models() && md) { result->m_model = md; - if (p.get_bool(":print-model", false)) { + if (p.get_bool("print_model", false)) { ctx.regular_stream() << "(model " << std::endl; model_smt2_pp(ctx.regular_stream(), ctx, *md, 2); ctx.regular_stream() << ")" << std::endl; @@ -266,12 +263,12 @@ public: if (ctx.produce_proofs() && pr) { result->m_proof = pr; - if (p.get_bool(":print-proof", false)) { + if (p.get_bool("print_proof", false)) { ctx.regular_stream() << mk_ismt2_pp(pr, m) << "\n"; } } - if (p.get_bool(":print-statistics", false)) + if (p.get_bool("print_statistics", false)) display_statistics(ctx, tref.get()); } }; @@ -285,21 +282,20 @@ public: virtual char const * get_main_descr() const { return "apply the given tactic to the current context, and print the resultant set of goals."; } virtual void init_pdescrs(cmd_context & ctx, param_descrs & p) { - p.insert(":print", CPK_BOOL, "(default: true) print resultant goals."); + p.insert("print", CPK_BOOL, "(default: true) print resultant goals."); #ifndef _EXTERNAL_RELEASE - p.insert(":print-proof", CPK_BOOL, "(default: false) print proof associated with each assertion."); + p.insert("print_proof", CPK_BOOL, "(default: false) print proof associated with each assertion."); #endif - p.insert(":print-model-converter", CPK_BOOL, "(default: false) print model converter."); - p.insert(":print-benchmark", CPK_BOOL, "(default: false) display resultant goals as a SMT2 benchmark."); + p.insert("print_model_converter", CPK_BOOL, "(default: false) print model converter."); + p.insert("print_benchmark", CPK_BOOL, "(default: false) display resultant goals as a SMT2 benchmark."); #ifndef _EXTERNAL_RELEASE - p.insert(":print-dependencies", CPK_BOOL, "(default: false) print dependencies when displaying the resultant set of goals."); + p.insert("print_dependencies", CPK_BOOL, "(default: false) print dependencies when displaying the resultant set of goals."); #endif exec_given_tactic_cmd::init_pdescrs(ctx, p); } virtual void execute(cmd_context & ctx) { params_ref p = ps(); - front_end_params2params(ctx.params(), p); tactic_ref tref = using_params(sexpr2tactic(ctx, m_tactic), p); { tactic & t = *(tref.get()); @@ -307,7 +303,7 @@ public: goal_ref g = alloc(goal, m, ctx.produce_proofs(), ctx.produce_models(), ctx.produce_unsat_cores()); assert_exprs_from(ctx, *g); - unsigned timeout = p.get_uint(":timeout", UINT_MAX); + unsigned timeout = p.get_uint("timeout", UINT_MAX); goal_ref_buffer result_goals; model_converter_ref mc; @@ -330,8 +326,8 @@ public: } } - if (!failed && p.get_bool(":print", true)) { - bool print_dependencies = p.get_bool(":print-dependencies", false); + if (!failed && p.get_bool("print", true)) { + bool print_dependencies = p.get_bool("print_dependencies", false); ctx.regular_stream() << "(goals\n"; unsigned sz = result_goals.size(); for (unsigned i = 0; i < sz; i++) { @@ -344,12 +340,12 @@ public: } #ifndef _EXTERNAL_RELEASE - if (!failed && ctx.produce_proofs() && p.get_bool(":print-proof", false)) { + if (!failed && ctx.produce_proofs() && p.get_bool("print_proof", false)) { // TODO } #endif - if (!failed && p.get_bool(":print-benchmark", false)) { + if (!failed && p.get_bool("print_benchmark", false)) { unsigned num_goals = result_goals.size(); SASSERT(num_goals > 0); if (num_goals == 1) { @@ -381,10 +377,10 @@ public: } } - if (!failed && mc && p.get_bool(":print-model-converter", false)) + if (!failed && mc && p.get_bool("print_model_converter", false)) mc->display(ctx.regular_stream()); - if (p.get_bool(":print-statistics", false)) + if (p.get_bool("print_statistics", false)) display_statistics(ctx, tref.get()); } } @@ -501,7 +497,7 @@ static tactic * mk_using_params(cmd_context & ctx, sexpr * n) { throw cmd_exception("invalid using-params combinator, keyword expected", c->get_line(), c->get_pos()); if (i == num_children) throw cmd_exception("invalid using-params combinator, parameter value expected", c->get_line(), c->get_pos()); - symbol param_name = c->get_symbol(); + symbol param_name = symbol(norm_param_name(c->get_symbol()).c_str()); c = n->get_child(i); i++; switch (descrs.get_kind(param_name)) { diff --git a/src/front_end_params/arith_simplifier_params.cpp b/src/front_end_params/arith_simplifier_params.cpp deleted file mode 100644 index 0c2f5c710..000000000 --- a/src/front_end_params/arith_simplifier_params.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - arith_simplifier_params.cpp - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-05-09. - -Revision History: - ---*/ - -#include"arith_simplifier_params.h" - -void arith_simplifier_params::register_params(ini_params & p) { - p.register_bool_param("ARITH_EXPAND_EQS", m_arith_expand_eqs); - p.register_bool_param("ARITH_PROCESS_ALL_EQS", m_arith_process_all_eqs); -} - diff --git a/src/front_end_params/cnf_params.cpp b/src/front_end_params/cnf_params.cpp deleted file mode 100644 index 57d02e8db..000000000 --- a/src/front_end_params/cnf_params.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - cnf_params.cpp - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-01-23. - -Revision History: - ---*/ - -#include"cnf_params.h" - -void cnf_params::register_params(ini_params & p) { - p.register_unsigned_param("CNF_FACTOR", m_cnf_factor, "the maximum number of clauses that can be created when converting a subformula"); - p.register_int_param("CNF_MODE", 0, 3, reinterpret_cast(m_cnf_mode), "CNF translation mode: 0 - disabled, 1 - quantifiers in CNF, 2 - 0 + opportunistic, 3 - full"); -} - diff --git a/src/front_end_params/cnf_params.h b/src/front_end_params/cnf_params.h deleted file mode 100644 index f694e1716..000000000 --- a/src/front_end_params/cnf_params.h +++ /dev/null @@ -1,56 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - cnf_params.h - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-01-23. - -Revision History: - ---*/ -#ifndef _CNF_PARAMS_H_ -#define _CNF_PARAMS_H_ - -#include"ini_file.h" - -/** - \brief CNF translation mode. The cheapest mode is CNF_QUANT, and - the most expensive is CNF_FULL. -*/ -enum cnf_mode { - CNF_DISABLED, /* CNF translator is disabled. - This mode is sufficient when using E-matching. - */ - CNF_QUANT, /* A subformula is put into CNF if it is inside of a - quantifier. - - This mode is sufficient when using Superposition - Calculus. - */ - CNF_OPPORTUNISTIC, /* a subformula is also put in CNF if it is cheap. */ - CNF_FULL /* Everything is put into CNF, new names are introduced - if it is too expensive. */ -}; - -struct cnf_params { - cnf_mode m_cnf_mode; - unsigned m_cnf_factor; - cnf_params(): - m_cnf_mode(CNF_DISABLED), - m_cnf_factor(4) { - } - - void register_params(ini_params & p); -}; - - -#endif /* _CNF_PARAMS_H_ */ - diff --git a/src/front_end_params/front_end_params.cpp b/src/front_end_params/front_end_params.cpp deleted file mode 100644 index 7aea7e7ee..000000000 --- a/src/front_end_params/front_end_params.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - front_end_params.cpp - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2007-05-10. - -Revision History: - ---*/ -#include"front_end_params.h" - -void front_end_params::register_params(ini_params & p) { - p.register_param_vector(m_param_vector.get()); - preprocessor_params::register_params(p); - smt_params::register_params(p); - parser_params::register_params(p); - arith_simplifier_params::register_params(p); - model_params::register_params(p); - p.register_bool_param("AT_LABELS_CEX", m_at_labels_cex, - "only use labels that contain '@' when building multiple counterexamples"); - p.register_bool_param("CHECK_AT_LABELS", m_check_at_labels, - "check that labels containing '@' are used correctly to only produce unique counter examples"); - p.register_bool_param("DEFAULT_QID", m_default_qid, "create a default quantifier id based on its position, the id is used to report profiling information (see QI_PROFILE)"); - - p.register_bool_param("TYPE_CHECK", m_well_sorted_check, "enable/disable type checker"); - p.register_bool_param("WELL_SORTED_CHECK", m_well_sorted_check, "enable/disable type checker"); - p.register_bool_param("INTERACTIVE", m_interactive, "enable interactive mode using Simplify input format"); - p.register_unsigned_param("SOFT_TIMEOUT", m_soft_timeout, "set approximate timeout for each solver query (milliseconds), the value 0 represents no timeout", true); - p.register_double_param("INSTRUCTION_MAX", m_instr_out, "set the (approximate) maximal number of instructions per invocation of check", true); - p.register_bool_param("AUTO_CONFIG", m_auto_config, "use heuristics to set Z3 configuration parameters, it is only available for the SMT-LIB input format"); - p.register_int_param("PROOF_MODE", 0, 2, reinterpret_cast(m_proof_mode), "select proof generation mode: 0 - disabled, 1 - coarse grain, 2 - fine grain"); - p.register_bool_param("TRACE", m_trace, "enable tracing for the Axiom Profiler tool"); - p.register_string_param("TRACE_FILE_NAME", m_trace_file_name, "tracing file name"); - p.register_bool_param("ASYNC_COMMANDS", m_async_commands, "enable/disable support for asynchronous commands in the Simplify front-end."); - p.register_bool_param("DISPLAY_CONFIG", m_display_config, "display configuration used by Z3"); - -#ifdef _WINDOWS - // The non-windows memory manager does not have access to memory sizes. - p.register_unsigned_param("MEMORY_HIGH_WATERMARK", m_memory_high_watermark, - "set high watermark for memory consumption (in megabytes)"); - p.register_unsigned_param("MEMORY_MAX_SIZE", m_memory_max_size, - "set hard upper limit for memory consumption (in megabytes)"); -#endif - -#ifndef _EXTERNAL_RELEASE - // external users should not have access to it. - p.register_bool_param("PREPROCESS", m_preprocess); -#endif - - p.register_bool_param("USER_THEORY_PREPROCESS_AXIOMS", - m_user_theory_preprocess_axioms, - "Apply full pre-processing to user theory axioms", - true); - - p.register_bool_param("USER_THEORY_PERSIST_AXIOMS", - m_user_theory_persist_axioms, - "Persist user axioms to the base level", - true); - - p.register_bool_param("SMTLIB2_COMPLIANT", m_smtlib2_compliant); - - p.register_bool_param("IGNORE_BAD_PATTERNS", m_ignore_bad_patterns); - - PRIVATE_PARAMS({ - p.register_bool_param("IGNORE_CHECKSAT", m_ignore_checksat); - p.register_bool_param("DEBUG_REF_COUNT", m_debug_ref_count); - p.register_bool_param("IGNORE_USER_PATTERNS", m_ignore_user_patterns); - p.register_bool_param("INCREMENTAL_CORE_ASSERT", m_incremental_core_assert); - DEBUG_CODE(p.register_int_param("COPY_PARAMS", m_copy_params);); - }); - - // temporary hack until strategic_solver is ported to new tactic framework - PRIVATE_PARAMS({ - p.register_bool_param("NLSAT", m_nlsat); - }); -} - -void front_end_params::open_trace_file() { - if (m_trace) { - m_trace_stream = alloc(std::fstream, m_trace_file_name.c_str(), std::ios_base::out); - } -} - -void front_end_params::close_trace_file() { - if (m_trace_stream != NULL) { - std::fstream &tmp = *m_trace_stream; - m_trace_stream = NULL; - tmp << "[eof]\n"; - tmp.close(); - // do not delete it, this might be called from a Ctrl-C signal handler - // and there might be someone writing to it - } -} diff --git a/src/front_end_params/front_end_params.h b/src/front_end_params/front_end_params.h deleted file mode 100644 index 7a9b4e8e8..000000000 --- a/src/front_end_params/front_end_params.h +++ /dev/null @@ -1,124 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - front_end_params.h - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2007-05-10. - -Revision History: - ---*/ -#ifndef _FRONT_END_PARAMS_H_ -#define _FRONT_END_PARAMS_H_ - -#include"ini_file.h" -#include"ast.h" -#include"preprocessor_params.h" -#include"smt_params.h" -#include"pp_params.h" -#include"parser_params.h" -#include"arith_simplifier_params.h" -#include"model_params.h" - -struct front_end_params : public preprocessor_params, public smt_params, public parser_params, - public arith_simplifier_params, public model_params - { - ref m_param_vector; - bool m_at_labels_cex; // only use labels which contains the @ symbol when building multiple counterexamples. - bool m_check_at_labels; // check that @ labels are inserted to generate unique counter-examples. - bool m_default_qid; - bool m_interactive; - bool m_well_sorted_check; - bool m_ignore_bad_patterns; - bool m_ignore_user_patterns; - bool m_incremental_core_assert; // assert conditions to the core incrementally - unsigned m_soft_timeout; - double m_instr_out; - unsigned m_memory_high_watermark; - unsigned m_memory_max_size; - proof_gen_mode m_proof_mode; - bool m_auto_config; - bool m_smtlib2_compliant; -#ifdef Z3DEBUG - int m_copy_params; // used for testing copy params... Invoke method copy_params(m_copy_params) in main.cpp when diff -1. -#endif - bool m_preprocess; // temporary hack for disabling all preprocessing.. - bool m_ignore_checksat; // abort before checksat... for internal debugging - bool m_debug_ref_count; - bool m_trace; - std::string m_trace_file_name; - std::fstream* m_trace_stream; - bool m_async_commands; - bool m_display_config; - bool m_user_theory_preprocess_axioms; - bool m_user_theory_persist_axioms; - bool m_nlsat; // temporary hack until strategic_solver is ported to new tactic framework - - front_end_params(): - m_param_vector(alloc(param_vector, this)), - m_at_labels_cex(false), - m_check_at_labels(false), - m_default_qid(false), - m_interactive(false), - m_well_sorted_check(true), - m_ignore_bad_patterns(true), - m_ignore_user_patterns(false), - m_incremental_core_assert(true), - m_soft_timeout(0), - m_instr_out(0.0), - m_memory_high_watermark(0), - m_memory_max_size(0), - m_proof_mode(PGM_DISABLED), -#if defined(SMTCOMP) || defined(_EXTERNAL_RELEASE) - m_auto_config(true), -#else - m_auto_config(false), -#endif -#if 0 - m_smtlib2_compliant(true), -#else - m_smtlib2_compliant(false), -#endif -#ifdef Z3DEBUG - m_copy_params(-1), -#endif - m_preprocess(true), // temporary hack for disabling all preprocessing.. - m_ignore_checksat(false), - m_debug_ref_count(false), - m_trace(false), - m_trace_file_name("z3.log"), - m_trace_stream(NULL), - m_async_commands(true), - m_display_config(false), - m_user_theory_preprocess_axioms(false), - m_user_theory_persist_axioms(false), - m_nlsat(false) { - } - - void register_params(ini_params & p); - - void open_trace_file(); - - void close_trace_file(); - - void copy_params(unsigned idx) { - m_param_vector->copy_params(this, idx); - } - - bool has_auto_config(unsigned idx) { return m_auto_config; } - -private: - - front_end_params& operator=(front_end_params const& other); -}; - -#endif /* _FRONT_END_PARAMS_H_ */ - diff --git a/src/front_end_params/model_params.cpp b/src/front_end_params/model_params.cpp deleted file mode 100644 index df6420b7a..000000000 --- a/src/front_end_params/model_params.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - model_params.cpp - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2007-08-23. - -Revision History: - ---*/ - -#include"model_params.h" - -void model_params::register_params(ini_params & p) { - p.register_bool_param("MODEL_PARTIAL", m_model_partial, "enable/disable partial function interpretations", true); - p.register_bool_param("MODEL_V1", m_model_v1_pp, - "use Z3 version 1.x pretty printer", true); - p.register_bool_param("MODEL_V2", m_model_v2_pp, - "use Z3 version 2.x (x <= 16) pretty printer", true); - p.register_bool_param("MODEL_COMPACT", m_model_compact, - "try to compact function graph (i.e., function interpretations that are lookup tables", true); - p.register_bool_param("MODEL_COMPLETION", m_model_completion, - "assigns an interptetation to symbols that do not have one in the current model, when evaluating expressions in the current model", true); - -} - - diff --git a/src/front_end_params/model_params.h b/src/front_end_params/model_params.h deleted file mode 100644 index 2718d4e5f..000000000 --- a/src/front_end_params/model_params.h +++ /dev/null @@ -1,43 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - model_params.h - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2007-08-23. - -Revision History: - ---*/ -#ifndef _MODEL_PARAMS_H_ -#define _MODEL_PARAMS_H_ - -#include"ini_file.h" - -struct model_params { - bool m_model_partial; - bool m_model_compact; - bool m_model_v1_pp; - bool m_model_v2_pp; - bool m_model_completion; - - model_params(): - m_model_partial(false), - m_model_compact(false), - m_model_v1_pp(false), - m_model_v2_pp(false), - m_model_completion(false) { - } - - void register_params(ini_params & p); -}; - -#endif /* _MODEL_PARAMS_H_ */ - diff --git a/src/front_end_params/nnf_params.cpp b/src/front_end_params/nnf_params.cpp deleted file mode 100644 index 044ca155e..000000000 --- a/src/front_end_params/nnf_params.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - nnf_params.cpp - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-01-14. - -Revision History: - ---*/ -#include"nnf_params.h" - -void nnf_params::register_params(ini_params & p) { - p.register_unsigned_param("NNF_FACTOR", m_nnf_factor, "the maximum growth factor during NNF translation (auxiliary definitions are introduced if the threshold is reached)"); - p.register_int_param("NNF_MODE", 0, 3, reinterpret_cast(m_nnf_mode), "NNF translation mode: 0 - skolem normal form, 1 - 0 + quantifiers in NNF, 2 - 1 + opportunistic, 3 - full"); - p.register_bool_param("NNF_IGNORE_LABELS", m_nnf_ignore_labels, "remove/ignore labels in the input formula, this option is ignored if proofs are enabled"); - p.register_bool_param("NNF_SK_HACK", m_nnf_sk_hack, "hack for VCC"); -} diff --git a/src/front_end_params/nnf_params.h b/src/front_end_params/nnf_params.h deleted file mode 100644 index f759a93ac..000000000 --- a/src/front_end_params/nnf_params.h +++ /dev/null @@ -1,74 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - nnf_params.h - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-01-14. - -Revision History: - ---*/ -#ifndef _NNF_PARAMS_H_ -#define _NNF_PARAMS_H_ - -#include"ini_file.h" - -/** - \brief NNF translation mode. The cheapest mode is NNF_SKOLEM, and - the most expensive is NNF_FULL. -*/ -enum nnf_mode { - NNF_SKOLEM, /* A subformula is put into NNF only if it contains - quantifiers or labels. The result of the - transformation will be in skolem normal form. - If a formula is too expensive to be put into NNF, - then nested quantifiers and labels are renamed. - - This mode is sufficient when using E-matching. - */ - NNF_QUANT, /* A subformula is put into NNF if it contains - quantifiers, labels, or is in the scope of a - quantifier. The result of the transformation will be - in skolem normal form, and the body of quantifiers - will be in NNF. If a ground formula is too expensive to - be put into NNF, then nested quantifiers and labels - are renamed. - - This mode is sufficient when using Superposition - Calculus. - - Remark: If the problem does not contain quantifiers, - then NNF_QUANT is identical to NNF_SKOLEM. - */ - NNF_OPPORTUNISTIC, /* Similar to NNF_QUANT, but a subformula is - also put into NNF, if it is - cheap. Otherwise, the nested quantifiers and - labels are renamed. */ - NNF_FULL /* Everything is put into NNF. */ -}; - -struct nnf_params { - nnf_mode m_nnf_mode; - unsigned m_nnf_factor; - bool m_nnf_ignore_labels; - bool m_nnf_sk_hack; - nnf_params(): - m_nnf_mode(NNF_SKOLEM), - m_nnf_factor(4), - m_nnf_ignore_labels(false), - m_nnf_sk_hack(false) { - } - - void register_params(ini_params & p); -}; - -#endif /* _NNF_PARAMS_H_ */ - diff --git a/src/front_end_params/params2front_end_params.cpp b/src/front_end_params/params2front_end_params.cpp deleted file mode 100644 index a2bae371c..000000000 --- a/src/front_end_params/params2front_end_params.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/*++ -Copyright (c) 2011 Microsoft Corporation - -Module Name: - - params2front_end_params.h - -Abstract: - - Backward compatibility utilities for parameter setting - -Author: - - Leonardo de Moura (leonardo) 2011-05-19. - -Revision History: - ---*/ -#include"front_end_params.h" -#include"params.h" - -/** - Update front_end_params using s. - Only the most frequently used options are updated. - - This function is mainly used to allow smt::context to be used in - the new strategy framework. -*/ -void params2front_end_params(params_ref const & s, front_end_params & t) { - t.m_relevancy_lvl = s.get_uint(":relevancy", t.m_relevancy_lvl); - TRACE("qi_cost", s.display(tout); tout << "\n";); - t.m_qi_cost = s.get_str(":qi-cost", t.m_qi_cost.c_str()); - t.m_mbqi = s.get_bool(":mbqi", t.m_mbqi); - t.m_mbqi_max_iterations = s.get_uint(":mbqi-max-iterations", t.m_mbqi_max_iterations); - t.m_random_seed = s.get_uint(":random-seed", t.m_random_seed); - t.m_model = s.get_bool(":produce-models", t.m_model); - if (s.get_bool(":produce-proofs", false)) - t.m_proof_mode = PGM_FINE; - t.m_well_sorted_check = s.get_bool(":check-sorts", t.m_well_sorted_check); - t.m_qi_eager_threshold = s.get_double(":qi-eager-threshold", t.m_qi_eager_threshold); - t.m_qi_lazy_threshold = s.get_double(":qi-lazy-threshold", t.m_qi_lazy_threshold); - t.m_preprocess = s.get_bool(":preprocess", t.m_preprocess); - t.m_hi_div0 = s.get_bool(":hi-div0", t.m_hi_div0); - t.m_auto_config = s.get_bool(":auto-config", t.m_auto_config); - t.m_array_simplify = s.get_bool(":array-old-simplifier", t.m_array_simplify); - t.m_arith_branch_cut_ratio = s.get_uint(":arith-branch-cut-ratio", t.m_arith_branch_cut_ratio); - t.m_arith_expand_eqs = s.get_bool(":arith-expand-eqs", t.m_arith_expand_eqs); - - if (s.get_bool(":arith-greatest-error-pivot", false)) - t.m_arith_pivot_strategy = ARITH_PIVOT_GREATEST_ERROR; - else if (s.get_bool(":arith-least-error-pivot", false)) - t.m_arith_pivot_strategy = ARITH_PIVOT_LEAST_ERROR; -} - -/** - \brief Copy parameters (from s) that affect the semantics of Z3 (e.g., HI_DIV0). - It also copies the model construction parameter. Thus, model construction - can be enabled at the command line. -*/ -void front_end_params2params(front_end_params const & s, params_ref & t) { - if (s.m_model) - t.set_bool(":produce-models", true); - if (!s.m_hi_div0) - t.set_bool(":hi-div0", false); -} - -/** - \brief Bridge for using params_ref with smt::context. -*/ -void solver_front_end_params_descrs(param_descrs & r) { - r.insert(":hi-div0", CPK_BOOL, "(default: true) if true, then Z3 uses the usual hardware interpretation for division (rem, mod) by zero. Otherwise, these operations are considered uninterpreted"); - r.insert(":relevancy", CPK_UINT, "relevancy propagation heuristic: 0 - disabled, 1 - relevancy is tracked by only affects quantifier instantiation, 2 - relevancy is tracked, and an atom is only asserted if it is relevant"); - r.insert(":mbqi", CPK_BOOL, "model based quantifier instantiation (MBQI)"); - r.insert(":mbqi-max-iterations", CPK_UINT, "maximum number of rounds of MBQI"); - r.insert(":random-seed", CPK_UINT, "random seed for smt solver"); - r.insert(":qi-eager-threshold", CPK_DOUBLE, "threshold for eager quantifier instantiation"); - r.insert(":qi-lazy-threshold", CPK_DOUBLE, "threshold for lazy quantifier instantiation"); - r.insert(":auto_config", CPK_BOOL, "use heuristics to automatically configure smt solver"); - r.insert(":arith-branch-cut-ratio", CPK_UINT, "branch&bound / gomory cut ratio"); -} diff --git a/src/front_end_params/params2front_end_params.h b/src/front_end_params/params2front_end_params.h deleted file mode 100644 index 936928d4a..000000000 --- a/src/front_end_params/params2front_end_params.h +++ /dev/null @@ -1,31 +0,0 @@ -/*++ -Copyright (c) 2011 Microsoft Corporation - -Module Name: - - params2front_end_params.h - -Abstract: - - Backward compatibility utilities for parameter setting - -Author: - - Leonardo de Moura (leonardo) 2011-05-19. - -Revision History: - ---*/ -#ifndef _PARAMS2FRONT_END_PARAMS_H_ -#define _PARAMS2FRONT_END_PARAMS_H_ - -class params_ref; -struct front_end_params; - -void params2front_end_params(params_ref const & s, front_end_params & t); - -void front_end_params2params(front_end_params const & s, params_ref & t); - -void solver_front_end_params_descrs(param_descrs & r); - -#endif diff --git a/src/front_end_params/parser_params.cpp b/src/front_end_params/parser_params.cpp deleted file mode 100644 index 000885fa5..000000000 --- a/src/front_end_params/parser_params.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "parser_params.h" - -parser_params::parser_params() : - m_dump_goal_as_smt(false), - m_display_error_for_vs(false) { -} - -void parser_params::register_params(ini_params & p) { - p.register_bool_param("DUMP_GOAL_AS_SMT", m_dump_goal_as_smt, "write goal back to output in SMT format"); - p.register_bool_param("DISPLAY_ERROR_FOR_VISUAL_STUDIO", m_display_error_for_vs, "display error messages in Visual Studio format"); -} - - - diff --git a/src/front_end_params/parser_params.h b/src/front_end_params/parser_params.h deleted file mode 100644 index eaab4fd81..000000000 --- a/src/front_end_params/parser_params.h +++ /dev/null @@ -1,33 +0,0 @@ -/*++ -Copyright (c) 2008 Microsoft Corporation - -Module Name: - - parser_params.h - -Abstract: - - - -Author: - - Nikolaj Bjorner (nbjorner) 2008-04-21. - -Revision History: - ---*/ -#ifndef _PARSER_PARAMS_H_ -#define _PARSER_PARAMS_H_ - -#include"ini_file.h" - -struct parser_params { - bool m_dump_goal_as_smt; // re-print goal as SMT benchmark. - bool m_display_error_for_vs; // print error in vs format. - - parser_params(); - void register_params(ini_params & p); -}; - -#endif /* _PARSER_PARAMS_H_ */ - diff --git a/src/front_end_params/pattern_inference_params.cpp b/src/front_end_params/pattern_inference_params.cpp deleted file mode 100644 index 176fdd8c2..000000000 --- a/src/front_end_params/pattern_inference_params.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - pattern_inference_params.cpp - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-03-24. - -Revision History: - ---*/ -#include"pattern_inference_params.h" - -void pattern_inference_params::register_params(ini_params & p) { - p.register_unsigned_param("PI_MAX_MULTI_PATTERNS", m_pi_max_multi_patterns, - "when patterns are not provided, the prover uses a heuristic to infer them. This option sets the threshold on the number of extra multi-patterns that can be created. By default, the prover creates at most one multi-pattern when there is no unary pattern"); - p.register_bool_param("PI_BLOCK_LOOP_PATTERNS", m_pi_block_loop_patterns, - "block looping patterns during pattern inference"); - p.register_int_param("PI_ARITH", 0, 2, reinterpret_cast(m_pi_arith), - "0 - do not infer patterns with arithmetic terms, 1 - use patterns with arithmetic terms if there is no other pattern, 2 - always use patterns with arithmetic terms."); - p.register_bool_param("PI_USE_DATABASE", m_pi_use_database); - p.register_unsigned_param("PI_ARITH_WEIGHT", m_pi_arith_weight, "default weight for quantifiers where the only available pattern has nested arithmetic terms."); - p.register_unsigned_param("PI_NON_NESTED_ARITH_WEIGHT", m_pi_non_nested_arith_weight, "default weight for quantifiers where the only available pattern has non nested arithmetic terms."); - p.register_bool_param("PI_PULL_QUANTIFIERS", m_pi_pull_quantifiers, "pull nested quantifiers, if no pattern was found."); - p.register_int_param("PI_NOPAT_WEIGHT", m_pi_nopat_weight, "set weight of quantifiers without patterns, if negative the weight is not changed."); - p.register_bool_param("PI_AVOID_SKOLEMS", m_pi_avoid_skolems); - p.register_bool_param("PI_WARNINGS", m_pi_warnings, "enable/disable warning messages in the pattern inference module."); -} - - diff --git a/src/front_end_params/preprocessor_params.h b/src/front_end_params/preprocessor_params.h deleted file mode 100644 index 4b32feb60..000000000 --- a/src/front_end_params/preprocessor_params.h +++ /dev/null @@ -1,109 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - preprocessor_params.h - -Abstract: - - Preprocess AST before adding them to the logical context - -Author: - - Leonardo de Moura (leonardo) 2008-01-17. - -Revision History: - ---*/ -#ifndef _PREPROCESSOR_PARAMS_H_ -#define _PREPROCESSOR_PARAMS_H_ - -#include"nnf_params.h" -#include"cnf_params.h" -#include"pattern_inference_params.h" -#include"bit_blaster_params.h" -#include"bv_simplifier_params.h" - -enum lift_ite_kind { - LI_NONE, - LI_CONSERVATIVE, - LI_FULL -}; - -struct preprocessor_params : public nnf_params, public cnf_params, public pattern_inference_params, - public bit_blaster_params, public bv_simplifier_params { - lift_ite_kind m_lift_ite; - lift_ite_kind m_ng_lift_ite; // lift ite for non ground terms - bool m_pull_cheap_ite_trees; - bool m_pull_nested_quantifiers; - bool m_eliminate_term_ite; - bool m_eliminate_and; // represent (and a b) as (not (or (not a) (not b))) - bool m_macro_finder; - bool m_propagate_values; - bool m_propagate_booleans; - bool m_refine_inj_axiom; - bool m_eliminate_bounds; - bool m_simplify_bit2int; - bool m_nnf_cnf; - bool m_distribute_forall; - bool m_reduce_args; - bool m_quasi_macros; - bool m_restricted_quasi_macros; - bool m_max_bv_sharing; - bool m_pre_simplifier; - bool m_nlquant_elim; - -public: - preprocessor_params(): - m_lift_ite(LI_NONE), - m_ng_lift_ite(LI_NONE), - m_pull_cheap_ite_trees(false), - m_pull_nested_quantifiers(false), - m_eliminate_term_ite(false), - m_eliminate_and(true), - m_macro_finder(false), - m_propagate_values(true), - m_propagate_booleans(false), // TODO << check peformance - m_refine_inj_axiom(true), - m_eliminate_bounds(false), - m_simplify_bit2int(false), - m_nnf_cnf(true), - m_distribute_forall(false), - m_reduce_args(false), - m_quasi_macros(false), - m_restricted_quasi_macros(false), - m_max_bv_sharing(true), - m_pre_simplifier(true), - m_nlquant_elim(false) { - } - - void register_params(ini_params & p) { - nnf_params::register_params(p); - cnf_params::register_params(p); - pattern_inference_params::register_params(p); - bit_blaster_params::register_params(p); - bv_simplifier_params::register_params(p); - p.register_int_param("LIFT_ITE", 0, 2, reinterpret_cast(m_lift_ite), "ite term lifting: 0 - no lifting, 1 - conservative, 2 - full"); - p.register_int_param("NG_LIFT_ITE", 0, 2, reinterpret_cast(m_ng_lift_ite), "ite (non-ground) term lifting: 0 - no lifting, 1 - conservative, 2 - full"); - p.register_bool_param("ELIM_TERM_ITE", m_eliminate_term_ite, "eliminate term if-then-else in the preprocessor"); - p.register_bool_param("ELIM_AND", m_eliminate_and, "represent (and a b) as (not (or (not a) (not b)))"); - p.register_bool_param("MACRO_FINDER", m_macro_finder, "try to find universally quantified formulas that can be viewed as macros"); - p.register_bool_param("PROPAGATE_VALUES", m_propagate_values, "propagate values during preprocessing step"); - p.register_bool_param("PROPAGATE_BOOLEANS", m_propagate_booleans, "propagate boolean values during preprocessing step"); - p.register_bool_param("PULL_CHEAP_ITE_TREES", m_pull_cheap_ite_trees); - p.register_bool_param("PULL_NESTED_QUANTIFIERS", m_pull_nested_quantifiers, "eliminate nested quantifiers by moving nested quantified variables to the outermost quantifier, it is unnecessary if the formula is converted into CNF"); - p.register_bool_param("REFINE_INJ_AXIOM", m_refine_inj_axiom); - p.register_bool_param("ELIM_BOUNDS", m_eliminate_bounds, "cheap Fourier-Motzkin"); - - p.register_bool_param("BIT2INT", m_simplify_bit2int, "hoist bit2int conversions over arithmetical expressions"); - p.register_bool_param("DISTRIBUTE_FORALL", m_distribute_forall); - p.register_bool_param("REDUCE_ARGS", m_reduce_args); - p.register_bool_param("QUASI_MACROS", m_quasi_macros); - p.register_bool_param("RESTRICTED_QUASI_MACROS", m_restricted_quasi_macros); - p.register_bool_param("BV_MAX_SHARING", m_max_bv_sharing); - p.register_bool_param("PRE_SIMPLIFIER", m_pre_simplifier); - } -}; - -#endif /* _PREPROCESSOR_PARAMS_H_ */ diff --git a/src/front_end_params/smt_params.cpp b/src/front_end_params/smt_params.cpp deleted file mode 100644 index 0c4a0c844..000000000 --- a/src/front_end_params/smt_params.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - smt_params.cpp - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-02-20. - -Revision History: - ---*/ -#include"smt_params.h" -#include"trace.h" - -void smt_params::register_params(ini_params & p) { - dyn_ack_params::register_params(p); - qi_params::register_params(p); - theory_arith_params::register_params(p); - theory_array_params::register_params(p); - theory_bv_params::register_params(p); - theory_datatype_params::register_params(p); - - p.register_bool_param("CHECK_PROOF", m_check_proof); - p.register_bool_param("DISPLAY_PROOF", m_display_proof); - p.register_bool_param("DISPLAY_DOT_PROOF", m_display_dot_proof); - p.register_bool_param("DISPLAY_UNSAT_CORE", m_display_unsat_core); - p.register_bool_param("INTERNALIZER_NNF", m_internalizer_nnf); - p.register_bool_param("EQ_PROPAGATION", m_eq_propagation); - p.register_bool_param("BIN_CLAUSES", m_binary_clause_opt); - p.register_unsigned_param("RELEVANCY", m_relevancy_lvl, "relevancy propagation heuristic: 0 - disabled, 1 - relevancy is tracked by only affects quantifier instantiation, 2 - relevancy is tracked, and an atom is only asserted if it is relevant", true); - p.register_bool_param("RELEVANCY_LEMMA", m_relevancy_lemma, "true if lemmas are used to propagate relevancy"); - p.register_unsigned_param("RANDOM_SEED", m_random_seed, "random seed for Z3"); - p.register_percentage_param("RANDOM_CASE_SPLIT_FREQ", m_random_var_freq, "frequency of random case splits"); - p.register_int_param("PHASE_SELECTION", 0, 6, reinterpret_cast(m_phase_selection), "phase selection heuristic: 0 - always false, 1 - always true, 2 - phase caching, 3 - phase caching conservative, 4 - phase caching conservative 2, 5 - random, 6 - number of occurrences"); - p.register_bool_param("MINIMIZE_LEMMAS", m_minimize_lemmas, "enable/disable lemma minimization algorithm"); - p.register_unsigned_param("MAX_CONFLICTS", m_max_conflicts, "maximum number of conflicts"); - - p.register_unsigned_param("RECENT_LEMMA_THRESHOLD", m_recent_lemmas_size); - p.register_unsigned_param("TICK", m_tick); - - PRIVATE_PARAMS({ - p.register_bool_param("THEORY_RESOLVE", m_theory_resolve, "Apply theory resolution to produce auxiliary conflict clauses", true); - }); - - p.register_int_param("RESTART_STRATEGY", 0, 4, reinterpret_cast(m_restart_strategy), "0 - geometric, 1 - inner-outer-geometric, 2 - luby, 3 - fixed, 4 - arithmetic"); - p.register_unsigned_param("RESTART_INITIAL", m_restart_initial, - "inital restart frequency in number of conflicts, it is also the unit for the luby sequence"); - p.register_double_param("RESTART_FACTOR", m_restart_factor, "when using geometric (or inner-outer-geometric) progression of restarts, it specifies the constant used to multiply the currect restart threshold"); - p.register_bool_param("RESTART_ADAPTIVE", m_restart_adaptive, "disable restarts based on the search 'agility'"); - p.register_percentage_param("RESTART_AGILITY_THRESHOLD", m_restart_agility_threshold); - - p.register_int_param("LEMMA_GC_STRATEGY", 0, 2, reinterpret_cast(m_lemma_gc_strategy), "0 - fixed, 1 - geometric, 2 - at every restart"); - p.register_bool_param("LEMMA_GC_HALF", m_lemma_gc_half, "true for simple gc algorithm (delete approx. half of the clauses)"); - p.register_unsigned_param("LEMMA_GC_INITIAL", m_lemma_gc_initial, "lemma initial gc frequency (in number of conflicts), used by fixed or geometric strategies"); - p.register_double_param("LEMMA_GC_FACTOR", m_lemma_gc_factor, "used by geometric strategy"); - p.register_unsigned_param("LEMMA_GC_NEW_OLD_RATIO", m_new_old_ratio); - p.register_unsigned_param("LEMMA_GC_NEW_CLAUSE_ACTIVITY", m_new_clause_activity); - p.register_unsigned_param("LEMMA_GC_OLD_CLAUSE_ACTIVITY", m_old_clause_activity); - p.register_unsigned_param("LEMMA_GC_NEW_CLAUSE_RELEVANCY", m_new_clause_relevancy); - p.register_unsigned_param("LEMMA_GC_OLD_CLAUSE_RELEVANCY", m_old_clause_activity); - - p.register_bool_param("SIMPLIFY_CLAUSES", m_simplify_clauses); - - p.register_int_param("RANDOM_INITIAL_ACTIVITY", 0, 2, reinterpret_cast(m_random_initial_activity)); - - PRIVATE_PARAMS({ - - p.register_double_param("INV_DECAY", m_inv_decay); - p.register_unsigned_param("PHASE_CACHING_ON_DURATION", m_phase_caching_on); - p.register_unsigned_param("PHASE_CACHING_OFF_DURATION", m_phase_caching_off); - }); - - p.register_bool_param("SMTLIB_DUMP_LEMMAS", m_smtlib_dump_lemmas); - p.register_string_param("SMTLIB_LOGIC", m_smtlib_logic, "Name used for the :logic field when generating SMT-LIB benchmarks"); - p.register_bool_param("DISPLAY_FEATURES", m_display_features); - - p.register_bool_param("NEW_CORE2TH_EQ", m_new_core2th_eq); - p.register_bool_param("EMATCHING", m_ematching, "E-Matching based quantifier instantiation"); - - p.register_bool_param("PROFILE_RES_SUB", m_profile_res_sub); -#ifndef _EXTERNAL_RELEASE - p.register_bool_param("DISPLAY_BOOL_VAR2EXPR", m_display_bool_var2expr); - p.register_bool_param("DISPLAY_LL_BOOL_VAR2EXPR", m_display_ll_bool_var2expr); - p.register_bool_param("ABORT_AFTER_PREPROC", m_abort_after_preproc, "abort after preprocessing step, this flag is only useful for debugging purposes"); - p.register_bool_param("DISPLAY_INSTALLED_THEORIES", m_display_installed_theories, "display theories installed at smt::context", true); -#endif - p.register_int_param("CASE_SPLIT", 0, 5, reinterpret_cast(m_case_split_strategy), "0 - case split based on variable activity, 1 - similar to 0, but delay case splits created during the search, 2 - similar to 0, but cache the relevancy, 3 - case split based on relevancy (structural splitting), 4 - case split on relevancy and activity, 5 - case split on relevancy and current goal"); - p.register_unsigned_param("REL_CASE_SPLIT_ORDER", 0, 2, m_rel_case_split_order, "structural (relevancy) splitting order: 0 - left-to-right (default), 1 - random, 2 - right-to-left"); - p.register_bool_param("LOOKAHEAD_DISEQ", m_lookahead_diseq); - - p.register_bool_param("DELAY_UNITS", m_delay_units); - p.register_unsigned_param("DELAY_UNITS_THRESHOLD", m_delay_units_threshold); - - p.register_bool_param("MODEL", m_model, "enable/disable model construction", true); - p.register_bool_param("MODEL_VALIDATE", m_model_validate, "validate the model", true); - p.register_bool_param("MODEL_ON_TIMEOUT", m_model_on_timeout, "after hitting soft-timeout or memory high watermark, generate a candidate model", true); - p.register_bool_param("MODEL_ON_FINAL_CHECK", m_model_on_final_check, "display candidate model (in the standard output) whenever Z3 hits a final check", true); - - p.register_unsigned_param("PROGRESS_SAMPLING_FREQ", m_progress_sampling_freq, "frequency for progress output in miliseconds"); -} - diff --git a/src/front_end_params/theory_arith_params.cpp b/src/front_end_params/theory_arith_params.cpp deleted file mode 100644 index 2d77b6e73..000000000 --- a/src/front_end_params/theory_arith_params.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - theory_arith_params.cpp - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-05-06. - -Revision History: - ---*/ - -#include"theory_arith_params.h" - -void theory_arith_params::register_params(ini_params & p) { -#ifdef _EXTERNAL_RELEASE - p.register_int_param("ARITH_SOLVER", 0, 3, reinterpret_cast(m_arith_mode), "select arithmetic solver: 0 - no solver, 1 - bellman-ford based solver (diff. logic only), 2 - simplex based solver, 3 - floyd-warshall based solver (diff. logic only) and no theory combination"); -#else - p.register_int_param("ARITH_SOLVER", 0, 4, reinterpret_cast(m_arith_mode), "select arithmetic solver: 0 - no solver, 1 - bellman-ford based solver (diff. logic only), 2 - simplex based solver, 3 - floyd-warshall based solver (diff. logic only) and no theory combination, 4 - model guided arith_solver"); -#endif - p.register_bool_param("ARITH_FORCE_SIMPLEX", m_arith_auto_config_simplex, "force Z3 to use simplex solver."); - p.register_unsigned_param("ARITH_BLANDS_RULE_THRESHOLD", m_arith_blands_rule_threshold); - p.register_bool_param("ARITH_PROPAGATE_EQS", m_arith_propagate_eqs); - p.register_int_param("ARITH_PROPAGATION_MODE", 0, 2, reinterpret_cast(m_arith_bound_prop)); - p.register_bool_param("ARITH_STRONGER_LEMMAS", m_arith_stronger_lemmas); - p.register_bool_param("ARITH_SKIP_BIG_COEFFS", m_arith_skip_rows_with_big_coeffs); - p.register_unsigned_param("ARITH_MAX_LEMMA_SIZE", m_arith_max_lemma_size); - p.register_unsigned_param("ARITH_SMALL_LEMMA_SIZE", m_arith_small_lemma_size); - p.register_bool_param("ARITH_REFLECT", m_arith_reflect); - p.register_bool_param("ARITH_IGNORE_INT", m_arith_ignore_int); - p.register_unsigned_param("ARITH_LAZY_PIVOTING", m_arith_lazy_pivoting_lvl); - p.register_unsigned_param("ARITH_RANDOM_SEED", m_arith_random_seed); - p.register_bool_param("ARITH_RANDOM_INITIAL_VALUE", m_arith_random_initial_value); - p.register_int_param("ARITH_RANDOM_LOWER", m_arith_random_lower); - p.register_int_param("ARITH_RANDOM_UPPER", m_arith_random_upper); - p.register_bool_param("ARITH_ADAPTIVE", m_arith_adaptive); - p.register_double_param("ARITH_ADAPTIVE_ASSERTION_THRESHOLD", m_arith_adaptive_assertion_threshold, "Delay arithmetic atoms if the num-arith-conflicts/total-conflicts < threshold"); - p.register_double_param("ARITH_ADAPTIVE_PROPAGATION_THRESHOLD", m_arith_adaptive_propagation_threshold, "Disable arithmetic theory propagation if the num-arith-conflicts/total-conflicts < threshold"); - p.register_bool_param("ARITH_DUMP_LEMMAS", m_arith_dump_lemmas); - p.register_bool_param("ARITH_EAGER_EQ_AXIOMS", m_arith_eager_eq_axioms); - p.register_unsigned_param("ARITH_BRANCH_CUT_RATIO", m_arith_branch_cut_ratio); - - p.register_bool_param("ARITH_ADD_BINARY_BOUNDS", m_arith_add_binary_bounds); - p.register_unsigned_param("ARITH_PROP_STRATEGY", 0, 1, reinterpret_cast(m_arith_propagation_strategy), "Propagation strategy: 0 - use agility measures based on ration of theory conflicts, 1 - propagate proportional to ratio of theory conflicts (default)"); - - p.register_bool_param("ARITH_EQ_BOUNDS", m_arith_eq_bounds); - p.register_bool_param("ARITH_LAZY_ADAPTER", m_arith_lazy_adapter); - p.register_bool_param("ARITH_GCD_TEST", m_arith_gcd_test); - p.register_bool_param("ARITH_EAGER_GCD", m_arith_eager_gcd); - p.register_bool_param("ARITH_ADAPTIVE_GCD", m_arith_adaptive_gcd); - p.register_unsigned_param("ARITH_PROPAGATION_THRESHOLD", m_arith_propagation_threshold); - - p.register_bool_param("NL_ARITH", m_nl_arith, "enable/disable non linear arithmetic support. This option is ignored when ARITH_SOLVER != 2."); - p.register_bool_param("NL_ARITH_GB", m_nl_arith_gb, "enable/disable Grobner Basis computation. This option is ignored when NL_ARITH=false"); - p.register_bool_param("NL_ARITH_GB_EQS", m_nl_arith_gb_eqs, "enable/disable equations in the Grobner Basis to be copied to the Simplex tableau."); - p.register_bool_param("NL_ARITH_GB_PERTURBATE", m_nl_arith_gb_perturbate, "enable/disable perturbation of the variable order in GB when searching for new polynomials."); - p.register_unsigned_param("NL_ARITH_GB_THRESHOLD", m_nl_arith_gb_threshold, "Grobner basis computation can be very expensive. This is a threshold on the number of new equalities that can be generated."); - p.register_bool_param("NL_ARITH_BRANCHING", m_nl_arith_branching, "enable/disable branching on integer variables in non linear clusters"); - p.register_unsigned_param("NL_ARITH_ROUNDS", m_nl_arith_rounds, "threshold for number of (nested) final checks for non linear arithmetic."); - p.register_unsigned_param("NL_ARITH_MAX_DEGREE", m_nl_arith_max_degree, "max degree for internalizing new monomials."); - PRIVATE_PARAMS({ - p.register_bool_param("ARITH_FIXNUM", m_arith_fixnum); - p.register_bool_param("ARITH_INT_ONLY", m_arith_int_only); - p.register_bool_param("ARITH_ENUM_CONST_MOD", m_arith_enum_const_mod, "Create axioms for the finite set of equalities for (mod x k) where k is a positive numeral constant"); - p.register_bool_param("ARITH_INT_EQ_BRANCHING", m_arith_int_eq_branching, "Determine branch predicates based on integer equation solving"); - }); - p.register_bool_param("ARITH_EUCLIDEAN_SOLVER", m_arith_euclidean_solver, ""); -} - diff --git a/src/front_end_params/theory_bv_params.h b/src/front_end_params/theory_bv_params.h deleted file mode 100644 index 38e1e263f..000000000 --- a/src/front_end_params/theory_bv_params.h +++ /dev/null @@ -1,55 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - theory_bv_params.h - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2008-06-06. - -Revision History: - ---*/ -#ifndef _THEORY_BV_PARAMS_H_ -#define _THEORY_BV_PARAMS_H_ - -#include"ini_file.h" - -enum bv_solver_id { - BS_NO_BV, - BS_BLASTER -}; - -struct theory_bv_params { - bv_solver_id m_bv_mode; - bool m_bv_reflect; - bool m_bv_lazy_le; - bool m_bv_cc; - unsigned m_bv_blast_max_size; - bool m_bv_enable_int2bv2int; - theory_bv_params(): - m_bv_mode(BS_BLASTER), - m_bv_reflect(true), - m_bv_lazy_le(false), - m_bv_cc(false), - m_bv_blast_max_size(INT_MAX), - m_bv_enable_int2bv2int(false) {} - void register_params(ini_params & p) { - p.register_int_param("BV_SOLVER", 0, 2, reinterpret_cast(m_bv_mode), "0 - no bv, 1 - simple"); - p.register_unsigned_param("BV_BLAST_MAX_SIZE", m_bv_blast_max_size, "Maximal size for bit-vectors to blast"); - p.register_bool_param("BV_REFLECT", m_bv_reflect); - p.register_bool_param("BV_LAZY_LE", m_bv_lazy_le); - p.register_bool_param("BV_CC", m_bv_cc, "enable congruence closure for BV operators"); - p.register_bool_param("BV_ENABLE_INT2BV_PROPAGATION", m_bv_enable_int2bv2int, - "enable full (potentially expensive) propagation for int2bv and bv2int"); - } -}; - -#endif /* _THEORY_BV_PARAMS_H_ */ - diff --git a/src/math/polynomial/algebraic.pyg b/src/math/polynomial/algebraic.pyg new file mode 100644 index 000000000..92a2f10df --- /dev/null +++ b/src/math/polynomial/algebraic.pyg @@ -0,0 +1,10 @@ +def_module_params('algebraic', + description='real algebraic number package', + export=True, + params=(('zero_accuracy', UINT, 0, 'one of the most time-consuming operations in the real algebraic number module is determining the sign of a polynomial evaluated at a sample point with non-rational algebraic number values. Let k be the value of this option. If k is 0, Z3 uses precise computation. Otherwise, the result of a polynomial evaluation is considered to be 0 if Z3 can show it is inside the interval (-1/2^k, 1/2^k)'), + ('min_mag', UINT, 16, 'Z3 represents algebraic numbers using a (square-free) polynomial p and an isolating interval (which contains one and only one root of p). This interval may be refined during the computations. This parameter specifies whether to cache the value of a refined interval or not. It says the minimal size of an interval for caching purposes is 1/2^16'), + ('factor', BOOL, True, 'use polynomial factorization to simplify polynomials representing algebraic numbers'), + ('factor_max_prime', UINT, 31, 'parameter for the polynomial factorization procedure in the algebraic number module. Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. This parameter limits the maximum prime number p to be used in the first step'), + ('factor_num_primes', UINT, 1, 'parameter for the polynomial factorization procedure in the algebraic number module. Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. The search space may be reduced by factoring the polynomial in different GF(p)\'s. This parameter specify the maximum number of finite factorizations to be considered, before lifiting and searching'), + ('factor_search_size', UINT, 5000, 'parameter for the polynomial factorization procedure in the algebraic number module. Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. This parameter can be used to limit the search space'))) + diff --git a/src/math/polynomial/algebraic_numbers.cpp b/src/math/polynomial/algebraic_numbers.cpp index f7de4054c..90ad6ea9d 100644 --- a/src/math/polynomial/algebraic_numbers.cpp +++ b/src/math/polynomial/algebraic_numbers.cpp @@ -25,6 +25,7 @@ Notes: #include"scoped_ptr_vector.h" #include"mpbqi.h" #include"timeit.h" +#include"algebraic_params.hpp" namespace algebraic_numbers { @@ -57,12 +58,7 @@ namespace algebraic_numbers { typedef upolynomial::factors factors; void manager::get_param_descrs(param_descrs & r) { - r.insert(":algebraic-zero-accuracy", CPK_UINT, "(default: 0) one of the most time-consuming operations in the real algebraic number module is determining the sign of a polynomial evaluated at a sample point with non-rational algebraic number values. Let k be the value of this option. If k is 0, Z3 uses precise computation. Otherwise, the result of a polynomial evaluation is considered to be 0 if Z3 can show it is inside the interval (-1/2^k, 1/2^k)."); - r.insert(":algebraic-min-mag", CPK_UINT, "(default: 16) Z3 represents algebraic numbers using a (square-free) polynomial p and an isolating interval (which contains one and only one root of p). This interval may be refined during the computations. This parameter specifies whether to cache the value of a refined interval or not. It says the minimal size of an interval for caching purposes is 1/2^16"); - r.insert(":algebraic-factor", CPK_BOOL, "(default: true) use polynomial factorization to simplify polynomials representing algebraic numbers."); - r.insert(":algebraic-factor-max-prime", CPK_UINT, "(default: 31), parameter for the polynomial factorization procedure in the algebraic number module. Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. This parameter limits the maximum prime number p to be used in the first step."); - r.insert(":algebraic-factor-num-primes", CPK_UINT, "(default: 1), parameter for the polynomial factorization procedure in the algebraic number module. Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. The search space may be reduced by factoring the polynomial in different GF(p)'s. This parameter specify the maximum number of finite factorizations to be considered, before lifiting and searching."); - r.insert(":algebraic-factor-search-size", CPK_UINT, "(default: 5000), parameter for the polynomial factorization procedure in the algebraic number module. Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. This parameter can be used to limit the search space."); + algebraic_params::collect_param_descrs(r); } struct manager::imp { @@ -156,13 +152,14 @@ namespace algebraic_numbers { #endif } - void updt_params(params_ref const & p) { - m_min_magnitude = -static_cast(p.get_uint(":algebraic-min-mag", 16)); - m_factor = p.get_bool(":algebraic-factor", true); // use polynomial factorization - m_factor_params.m_max_p = p.get_uint(":algebraic-factor-max-prime", 31); - m_factor_params.m_p_trials = p.get_uint(":algebraic-factor-num-primes", 1); - m_factor_params.m_max_search_size = p.get_uint(":algebraic-factor-max-search-size", 5000); - m_zero_accuracy = -static_cast(p.get_uint(":algebraic-zero-accuracy", 0)); + void updt_params(params_ref const & _p) { + algebraic_params p(_p); + m_min_magnitude = -static_cast(p.min_mag()); + m_factor = p.factor(); + m_factor_params.m_max_p = p.factor_max_prime(); + m_factor_params.m_p_trials = p.factor_num_primes(); + m_factor_params.m_max_search_size = p.factor_search_size(); + m_zero_accuracy = -static_cast(p.zero_accuracy()); } unsynch_mpq_manager & qm() { diff --git a/src/math/polynomial/polynomial.cpp b/src/math/polynomial/polynomial.cpp index 1b5c7965f..4e14c5661 100644 --- a/src/math/polynomial/polynomial.cpp +++ b/src/math/polynomial/polynomial.cpp @@ -50,15 +50,15 @@ namespace polynomial { } void factor_params::updt_params(params_ref const & p) { - m_max_p = p.get_uint(":factor-max-prime", UINT_MAX); - m_p_trials = p.get_uint(":factor-num-primes", 1); - m_max_search_size = p.get_uint(":factor-max-search-size", UINT_MAX); + m_max_p = p.get_uint("max_prime", UINT_MAX); + m_p_trials = p.get_uint("num_primes", 1); + m_max_search_size = p.get_uint("max_search_size", UINT_MAX); } void factor_params::get_param_descrs(param_descrs & r) { - r.insert(":factor-max-search-size", CPK_UINT, "(default: infty) Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. This parameter can be used to limit the search space."); - r.insert(":factor-max-prime", CPK_UINT, "(default: infty) Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. This parameter limits the maximum prime number p to be used in the first step."); - r.insert(":factor-num-primes", CPK_UINT, "(default: 1) Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. The search space may be reduced by factoring the polynomial in different GF(p)'s. This parameter specify the maximum number of finite factorizations to be considered, before lifiting and searching."); + r.insert("max_search_size", CPK_UINT, "(default: infty) Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. This parameter can be used to limit the search space."); + r.insert("max_prime", CPK_UINT, "(default: infty) Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. This parameter limits the maximum prime number p to be used in the first step."); + r.insert("num_primes", CPK_UINT, "(default: 1) Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. The search space may be reduced by factoring the polynomial in different GF(p)'s. This parameter specify the maximum number of finite factorizations to be considered, before lifiting and searching."); } typedef ptr_vector monomial_vector; diff --git a/src/math/polynomial/polynomial.h b/src/math/polynomial/polynomial.h index f6370e5fa..7cefe6f56 100644 --- a/src/math/polynomial/polynomial.h +++ b/src/math/polynomial/polynomial.h @@ -90,6 +90,9 @@ namespace polynomial { factor_params(); factor_params(unsigned max_p, unsigned p_trials, unsigned max_search_size); void updt_params(params_ref const & p); + /* + REG_MODULE_PARAMS('factor', polynomial::factor_params::get_param_descrs') + */ static void get_param_descrs(param_descrs & r); }; diff --git a/src/math/subpaving/subpaving_t_def.h b/src/math/subpaving/subpaving_t_def.h index 7c80de75c..c215ddf98 100644 --- a/src/math/subpaving/subpaving_t_def.h +++ b/src/math/subpaving/subpaving_t_def.h @@ -474,7 +474,7 @@ void context_t::del(interval & a) { template void context_t::updt_params(params_ref const & p) { - unsigned epsilon = p.get_uint(":epsilon", 20); + unsigned epsilon = p.get_uint("epsilon", 20); if (epsilon != 0) { nm().set(m_epsilon, static_cast(epsilon)); nm().inv(m_epsilon); @@ -485,18 +485,18 @@ void context_t::updt_params(params_ref const & p) { m_zero_epsilon = true; } - unsigned max_power = p.get_uint(":max-bound", 10); + unsigned max_power = p.get_uint("max_bound", 10); nm().set(m_max_bound, 10); nm().power(m_max_bound, max_power, m_max_bound); nm().set(m_minus_max_bound, m_max_bound); nm().neg(m_minus_max_bound); - m_max_depth = p.get_uint(":max-depth", 128); - m_max_nodes = p.get_uint(":max-nodes", 8192); + m_max_depth = p.get_uint("max_depth", 128); + m_max_nodes = p.get_uint("max_nodes", 8192); - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); + m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); - unsigned prec = p.get_uint(":nth-root-precision", 8192); + unsigned prec = p.get_uint("nth_root_precision", 8192); if (prec == 0) prec = 1; nm().set(m_nth_root_prec, static_cast(prec)); @@ -505,20 +505,20 @@ void context_t::updt_params(params_ref const & p) { template void context_t::collect_param_descrs(param_descrs & d) { - d.insert(":max-nodes", CPK_UINT, "(default: 8192) maximum number of nodes in the subpaving tree."); - d.insert(":max-depth", CPK_UINT, "(default: 128) maximum depth of the subpaving tree."); - d.insert(":epsilon", CPK_UINT, "(default: 20) value k s.t. a new lower (upper) bound for x is propagated only new-lower(x) > lower(k) + 1/k * max(min(upper(x) - lower(x), |lower|), 1) (new-upper(x) < upper(x) - 1/k * max(min(upper(x) - lower(x), |lower|), 1)). If k = 0, then this restriction is ignored."); - d.insert(":max-bound", CPK_UINT, "(default 10) value k s.t. a new upper (lower) bound for x is propagated only if upper(x) > -10^k or lower(x) = -oo (lower(x) < 10^k or upper(x) = oo)"); - d.insert(":nth-root-precision", CPK_UINT, "(default 8192) value k s.t. 1/k is the precision for computing the nth root in the subpaving module."); + d.insert("max_nodes", CPK_UINT, "(default: 8192) maximum number of nodes in the subpaving tree."); + d.insert("max_depth", CPK_UINT, "(default: 128) maximum depth of the subpaving tree."); + d.insert("epsilon", CPK_UINT, "(default: 20) value k s.t. a new lower (upper) bound for x is propagated only new-lower(x) > lower(k) + 1/k * max(min(upper(x) - lower(x), |lower|), 1) (new-upper(x) < upper(x) - 1/k * max(min(upper(x) - lower(x), |lower|), 1)). If k = 0, then this restriction is ignored."); + d.insert("max_bound", CPK_UINT, "(default 10) value k s.t. a new upper (lower) bound for x is propagated only if upper(x) > -10^k or lower(x) = -oo (lower(x) < 10^k or upper(x) = oo)"); + d.insert("nth_root_precision", CPK_UINT, "(default 8192) value k s.t. 1/k is the precision for computing the nth root in the subpaving module."); } template void context_t::display_params(std::ostream & out) const { - out << ":max-nodes " << m_max_nodes << "\n"; - out << ":max-depth " << m_max_depth << "\n"; - out << ":epsilon " << nm().to_rational_string(m_epsilon) << "\n"; - out << ":max-bound " << nm().to_rational_string(m_max_bound) << "\n"; - out << ":max-memory " << m_max_memory << "\n"; + out << "max_nodes " << m_max_nodes << "\n"; + out << "max_depth " << m_max_depth << "\n"; + out << "epsilon " << nm().to_rational_string(m_epsilon) << "\n"; + out << "max_bound " << nm().to_rational_string(m_max_bound) << "\n"; + out << "max_memory " << m_max_memory << "\n"; } template diff --git a/src/math/subpaving/tactic/subpaving_tactic.cpp b/src/math/subpaving/tactic/subpaving_tactic.cpp index 7bbff4b0b..d03bacebb 100644 --- a/src/math/subpaving/tactic/subpaving_tactic.cpp +++ b/src/math/subpaving/tactic/subpaving_tactic.cpp @@ -81,14 +81,14 @@ class subpaving_tactic : public tactic { void collect_param_descrs(param_descrs & r) { m_ctx->collect_param_descrs(r); // #ifndef _EXTERNAL_RELEASE - r.insert(":numeral", CPK_SYMBOL, "(default: mpq) options: mpq, mpf, hwf, mpff, mpfx."); - r.insert(":print-nodes", CPK_BOOL, "(default: false) display subpaving tree leaves."); + r.insert("numeral", CPK_SYMBOL, "(default: mpq) options: mpq, mpf, hwf, mpff, mpfx."); + r.insert("print_nodes", CPK_BOOL, "(default: false) display subpaving tree leaves."); // #endif } void updt_params(params_ref const & p) { - m_display = p.get_bool(":print-nodes", false); - symbol engine = p.get_sym(":numeral", symbol("mpq")); + m_display = p.get_bool("print_nodes", false); + symbol engine = p.get_sym("numeral", symbol("mpq")); engine_kind new_kind; if (engine == "mpq") new_kind = MPQ; @@ -293,16 +293,16 @@ tactic * mk_subpaving_tactic_core(ast_manager & m, params_ref const & p) { tactic * mk_subpaving_tactic(ast_manager & m, params_ref const & p) { params_ref simp_p = p; - simp_p.set_bool(":arith-lhs", true); - simp_p.set_bool(":expand-power", true); - simp_p.set_uint(":max-power", UINT_MAX); - simp_p.set_bool(":som", true); - simp_p.set_bool(":eq2ineq", true); - simp_p.set_bool(":elim-and", true); - simp_p.set_bool(":blast-distinct", true); + simp_p.set_bool("arith_lhs", true); + simp_p.set_bool("expand_power", true); + simp_p.set_uint("max_power", UINT_MAX); + simp_p.set_bool("som", true); + simp_p.set_bool("eq2ineq", true); + simp_p.set_bool("elim_and", true); + simp_p.set_bool("blast_distinct", true); params_ref simp2_p = p; - simp2_p.set_bool(":mul-to-power", true); + simp2_p.set_bool("mul_to_power", true); return and_then(using_params(mk_simplify_tactic(m, p), simp_p), diff --git a/src/model/model_evaluator.cpp b/src/model/model_evaluator.cpp index bccade304..beed0061e 100644 --- a/src/model/model_evaluator.cpp +++ b/src/model/model_evaluator.cpp @@ -60,10 +60,10 @@ struct evaluator_cfg : public default_rewriter_cfg { } void updt_params(params_ref const & p) { - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); - m_max_steps = p.get_uint(":max-steps", UINT_MAX); - m_model_completion = p.get_bool(":model-completion", false); - m_cache = p.get_bool(":cache", true); + m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); + m_max_steps = p.get_uint("max_steps", UINT_MAX); + m_model_completion = p.get_bool("model_completion", false); + m_cache = p.get_bool("cache", true); } ast_manager & m() const { return m_model.get_manager(); } @@ -147,7 +147,7 @@ struct evaluator_cfg : public default_rewriter_cfg { return m_a_rw.mk_app_core(f, num, args, result); if (fid == m_bv_rw.get_fid()) return m_bv_rw.mk_app_core(f, num, args, result); - if (fid == m_ar_rw.get_fid()) + if (fid == m_ar_rw.get_fid()) return m_ar_rw.mk_app_core(f, num, args, result); if (fid == m_dt_rw.get_fid()) return m_dt_rw.mk_app_core(f, num, args, result); @@ -232,8 +232,8 @@ void model_evaluator::updt_params(params_ref const & p) { void model_evaluator::get_param_descrs(param_descrs & r) { insert_max_memory(r); insert_max_steps(r); - r.insert(":model-completion", CPK_BOOL, "(default: false) assigns an interpretation to symbols that are not intepreted by the model."); - r.insert(":cache", CPK_BOOL, "(default: true) cache intermediate results."); + r.insert("model_completion", CPK_BOOL, "(default: false) assigns an interpretation to symbols that are not intepreted by the model."); + r.insert("cache", CPK_BOOL, "(default: true) cache intermediate results."); } void model_evaluator::set_model_completion(bool f) { diff --git a/src/model/model_params.pyg b/src/model/model_params.pyg new file mode 100644 index 000000000..977538163 --- /dev/null +++ b/src/model/model_params.pyg @@ -0,0 +1,8 @@ +def_module_params('model', + export=True, + params=(('partial', BOOL, False, 'enable/disable partial function interpretations'), + ('v1', BOOL, False, 'use Z3 version 1.x pretty printer'), + ('v2', BOOL, False, 'use Z3 version 2.x (x <= 16) pretty printer'), + ('compact', BOOL, False, 'try to compact function graph (i.e., function interpretations that are lookup tables)'), + ('completion', BOOL, False, 'assigns an interptetation to symbols that do not have one in the current model, when evaluating expressions in the current model'))) + diff --git a/src/model/model_pp.cpp b/src/model/model_pp.cpp index a8e8a0880..b968c7184 100644 --- a/src/model/model_pp.cpp +++ b/src/model/model_pp.cpp @@ -85,8 +85,7 @@ static void display_functions(std::ostream & out, model_core const & md) { if (fi->is_partial()) out << " #unspecified"; else { - pp_params const & params = get_pp_default_params(); - out << " " << mk_ismt2_pp(fi->get_else(), m, params, 5, arity, "x"); + out << " " << mk_ismt2_pp(fi->get_else(), m, params_ref(), 5, arity, "x"); } for (unsigned j = 0; j < num_entries; j++) out << ")"; diff --git a/src/model/model_smt2_pp.cpp b/src/model/model_smt2_pp.cpp index 1a639b5f1..929668638 100644 --- a/src/model/model_smt2_pp.cpp +++ b/src/model/model_smt2_pp.cpp @@ -128,7 +128,7 @@ static void pp_uninterp_sorts(std::ostream & out, ast_printer_context & ctx, mod format_ref f_card(fm(m)); f_card = mk_indent(m, indent, mk_seq1(m, f_args, f_args+2, f2f(), "forall")); pp_indent(out, indent); - pp(out, f_card, m, get_pp_default_params()); + pp(out, f_card, m); out << "\n"; pp_indent(out, indent); out << ";; -----------\n"; @@ -284,7 +284,7 @@ static void pp_funs(std::ostream & out, ast_printer_context & ctx, model_core co body.get(), mk_string(m, ")"))))); pp_indent(out, indent); - pp(out, def.get(), m, get_pp_default_params()); + pp(out, def.get(), m); out << "\n"; } } diff --git a/src/muz_qe/datalog_parser.cpp b/src/muz_qe/datalog_parser.cpp index f527bb25a..cfe283410 100644 --- a/src/muz_qe/datalog_parser.cpp +++ b/src/muz_qe/datalog_parser.cpp @@ -1160,9 +1160,9 @@ class wpa_parser_impl : public wpa_parser, dparser { public: wpa_parser_impl(context & ctx) : dparser(ctx, ctx.get_manager()), - m_bool_sort(ctx.get_manager()), - m_short_sort(ctx.get_manager()), - m_use_map_names(ctx.get_params().get_bool(":use-map-names", true)) { + m_bool_sort(ctx.get_manager()), + m_short_sort(ctx.get_manager()), + m_use_map_names(ctx.get_params().use_map_names()) { } ~wpa_parser_impl() { reset_dealloc_values(m_sort_contents); @@ -1326,9 +1326,6 @@ private: throw default_exception("tuple file %s for undeclared predicate %s", m_current_file.c_str(), predicate_name.bare_str()); } - if(!m_context.can_add_table_fact(pred)) { - NOT_IMPLEMENTED_YET(); - } unsigned pred_arity = pred->get_arity(); sort * const * arg_sorts = pred->get_domain(); diff --git a/src/muz_qe/dl_bmc_engine.cpp b/src/muz_qe/dl_bmc_engine.cpp index 02791bc6f..27161320e 100644 --- a/src/muz_qe/dl_bmc_engine.cpp +++ b/src/muz_qe/dl_bmc_engine.cpp @@ -57,7 +57,6 @@ namespace datalog { m_ctx.ensure_opened(); m_rules.reset(); - m_ctx.get_rmanager().reset_relations(); datalog::rule_manager& rule_manager = m_ctx.get_rule_manager(); datalog::rule_set old_rules(m_ctx.get_rules()); datalog::rule_ref_vector query_rules(rule_manager); @@ -71,7 +70,7 @@ namespace datalog { m_ctx.set_output_predicate(m_query_pred); m_ctx.apply_default_transformation(mc, m_pc); - if (m_ctx.get_params().get_bool(":slice", true)) { + if (m_ctx.get_params().slice()) { datalog::rule_transformer transformer(m_ctx); datalog::mk_slice* slice = alloc(datalog::mk_slice, m_ctx); transformer.register_plugin(slice); @@ -1100,9 +1099,6 @@ namespace datalog { m_solver.reset_statistics(); } - void bmc::collect_params(param_descrs& p) { - } - expr_ref bmc::get_answer() { return m_answer; } diff --git a/src/muz_qe/dl_bmc_engine.h b/src/muz_qe/dl_bmc_engine.h index 5de54f843..5b6e433cd 100644 --- a/src/muz_qe/dl_bmc_engine.h +++ b/src/muz_qe/dl_bmc_engine.h @@ -24,6 +24,7 @@ Revision History: #include "statistics.h" #include "smt_kernel.h" #include "bv_decl_plugin.h" +#include "smt_params.h" namespace datalog { @@ -32,7 +33,7 @@ namespace datalog { class bmc { context& m_ctx; ast_manager& m; - front_end_params m_fparams; + smt_params m_fparams; smt::kernel m_solver; obj_map m_pred2sort; obj_map m_sort2pred; @@ -130,8 +131,6 @@ namespace datalog { void reset_statistics(); expr_ref get_answer(); - - static void collect_params(param_descrs& p); }; }; diff --git a/src/muz_qe/dl_cmds.cpp b/src/muz_qe/dl_cmds.cpp index e19b9fef8..bf9c24203 100644 --- a/src/muz_qe/dl_cmds.cpp +++ b/src/muz_qe/dl_cmds.cpp @@ -32,7 +32,10 @@ Notes: #include -class dl_context { +struct dl_context { + smt_params m_fparams; + params_ref m_params_ref; + fixedpoint_params m_params; cmd_context & m_cmd; dl_collected_cmds* m_collected_cmds; unsigned m_ref_count; @@ -40,8 +43,13 @@ class dl_context { scoped_ptr m_context; trail_stack m_trail; -public: + fixedpoint_params const& get_params() { + init(); + return m_context->get_params(); + } + dl_context(cmd_context & ctx, dl_collected_cmds* collected_cmds): + m_params(m_params_ref), m_cmd(ctx), m_collected_cmds(collected_cmds), m_ref_count(0), @@ -62,7 +70,7 @@ public: void init() { ast_manager& m = m_cmd.m(); if (!m_context) { - m_context = alloc(datalog::context, m, m_cmd.params()); + m_context = alloc(datalog::context, m, m_fparams, m_params_ref); } if (!m_decl_plugin) { symbol name("datalog_relation"); @@ -210,7 +218,7 @@ public: datalog::context& dlctx = m_dl_ctx->dlctx(); set_background(ctx); dlctx.updt_params(m_params); - unsigned timeout = m_params.get_uint(":timeout", UINT_MAX); + unsigned timeout = m_dl_ctx->get_params().timeout(); cancel_eh eh(dlctx); lbool status = l_undef; { @@ -265,10 +273,6 @@ public: virtual void init_pdescrs(cmd_context & ctx, param_descrs & p) { m_dl_ctx->dlctx().collect_params(p); - insert_timeout(p); - p.insert(":print-answer", CPK_BOOL, "(default: false) print answer instance(s) to query."); - p.insert(":print-certificate", CPK_BOOL, "(default: false) print certificate for reachability or non-reachability."); - p.insert(":print-statistics", CPK_BOOL, "(default: false) print statistics."); } @@ -283,7 +287,7 @@ private: } void print_answer(cmd_context& ctx) { - if (m_params.get_bool(":print-answer", false)) { + if (m_dl_ctx->get_params().print_answer()) { datalog::context& dlctx = m_dl_ctx->dlctx(); ast_manager& m = ctx.m(); expr_ref query_result(dlctx.get_answer_as_formula(), m); @@ -298,7 +302,7 @@ private: } void print_statistics(cmd_context& ctx) { - if (m_params.get_bool(":print-statistics", false)) { + if (m_dl_ctx->get_params().print_statistics()) { statistics st; datalog::context& dlctx = m_dl_ctx->dlctx(); unsigned long long max_mem = memory::get_max_used_memory(); @@ -312,7 +316,7 @@ private: } void print_certificate(cmd_context& ctx) { - if (m_params.get_bool(":print-certificate", false)) { + if (m_dl_ctx->get_params().print_certificate()) { datalog::context& dlctx = m_dl_ctx->dlctx(); if (!dlctx.display_certificate(ctx.regular_stream())) { throw cmd_exception("certificates are not supported for the selected engine"); @@ -472,8 +476,10 @@ static void install_dl_cmds_aux(cmd_context& ctx, dl_collected_cmds* collected_c ctx.insert(alloc(dl_query_cmd, dl_ctx)); ctx.insert(alloc(dl_declare_rel_cmd, dl_ctx)); ctx.insert(alloc(dl_declare_var_cmd, dl_ctx)); - PRIVATE_PARAMS(ctx.insert(alloc(dl_push_cmd, dl_ctx));); // not exposed to keep command-extensions simple. - PRIVATE_PARAMS(ctx.insert(alloc(dl_pop_cmd, dl_ctx));); +#ifndef _EXTERNAL_RELEASE + ctx.insert(alloc(dl_push_cmd, dl_ctx)); // not exposed to keep command-extensions simple. + ctx.insert(alloc(dl_pop_cmd, dl_ctx)); +#endif } void install_dl_cmds(cmd_context & ctx) { diff --git a/src/muz_qe/dl_compiler.cpp b/src/muz_qe/dl_compiler.cpp index 99c7b86f5..d403b5b5c 100644 --- a/src/muz_qe/dl_compiler.cpp +++ b/src/muz_qe/dl_compiler.cpp @@ -42,7 +42,7 @@ namespace datalog { return; } relation_signature sig; - m_context.get_rmanager().from_predicate(pred, sig); + m_context.get_rel_context().get_rmanager().from_predicate(pred, sig); reg_idx reg = get_fresh_register(sig); e->get_data().m_value=reg; @@ -563,7 +563,7 @@ namespace datalog { } SASSERT(is_app(e)); relation_sort arg_sort; - m_context.get_rmanager().from_predicate(neg_pred, i, arg_sort); + m_context.get_rel_context().get_rmanager().from_predicate(neg_pred, i, arg_sort); reg_idx new_reg; make_add_constant_column(head_pred, filtered_res, arg_sort, to_app(e), new_reg, acc); @@ -1096,7 +1096,7 @@ namespace datalog { func_decl_set::iterator fdit = preds.begin(); func_decl_set::iterator fdend = preds.end(); for(; fdit!=fdend; ++fdit) { - if(!m_context.get_rmanager().is_saturated(*fdit)) { + if(!m_context.get_rel_context().get_rmanager().is_saturated(*fdit)) { return false; } } @@ -1181,7 +1181,7 @@ namespace datalog { acc.set_observer(0); - TRACE("dl", execution_code.display(m_context, tout);); + TRACE("dl", execution_code.display(m_context.get_rel_context(), tout);); } diff --git a/src/muz_qe/dl_context.cpp b/src/muz_qe/dl_context.cpp index 91e396671..7a46228ce 100644 --- a/src/muz_qe/dl_context.cpp +++ b/src/muz_qe/dl_context.cpp @@ -24,18 +24,12 @@ Revision History: #include"arith_decl_plugin.h" #include"bv_decl_plugin.h" #include"dl_table.h" -#include"dl_sparse_table.h" #include"dl_table_relation.h" -#include"dl_bound_relation.h" -#include"dl_interval_relation.h" -#include"dl_finite_product_relation.h" -#include"dl_product_relation.h" #include"dl_rule_transformer.h" #include"dl_mk_coi_filter.h" #include"dl_mk_explanations.h" #include"dl_mk_filter_rules.h" #include"dl_mk_interp_tail_simplifier.h" -#include"dl_mk_magic_sets.h" #include"dl_mk_rule_inliner.h" #include"dl_mk_simple_joins.h" #include"dl_mk_similarity_compressor.h" @@ -44,16 +38,13 @@ Revision History: #include"dl_compiler.h" #include"dl_instruction.h" #include"dl_context.h" -#include"dl_smt_relation.h" -#ifndef _EXTERNAL_RELEASE -#include"dl_skip_table.h" -#endif #include"for_each_expr.h" #include"ast_smt_pp.h" #include"ast_smt2_pp.h" #include"expr_functors.h" #include"dl_mk_partial_equiv.h" #include"dl_mk_bit_blast.h" +#include"dl_mk_array_blast.h" #include"datatype_decl_plugin.h" #include"expr_abstract.h" @@ -189,7 +180,6 @@ namespace datalog { virtual ~restore_rules() {} virtual void undo(context& ctx) { - ctx.reset_tables(); ctx.replace_rules(*m_old_rules); reset(); } @@ -209,7 +199,6 @@ namespace datalog { m_trail.push_scope(); m_trail.push(restore_rules(m_rule_set)); m_trail.push(restore_vec_size_trail(m_background)); - m_trail.push(restore_vec_size_trail(m_table_facts)); } void context::pop() { @@ -225,14 +214,14 @@ namespace datalog { // // ----------------------------------- - context::context(ast_manager & m, front_end_params& fp, params_ref const& pa): + context::context(ast_manager & m, smt_params& fp, params_ref const& pa): m(m), m_fparams(fp), - m_params(pa), + m_params_ref(pa), + m_params(m_params_ref), m_decl_util(m), m_rewriter(m), m_var_subst(m), - m_rmanager(*this), m_rule_manager(*this), m_trail(*this), m_pinned(m), @@ -242,26 +231,11 @@ namespace datalog { m_background(m), m_closed(false), m_saturation_was_run(false), - m_last_result_relation(0), m_last_answer(m), m_engine(LAST_ENGINE), m_cancel(false) { //register plugins for builtin tables - get_rmanager().register_plugin(alloc(sparse_table_plugin, get_rmanager())); - get_rmanager().register_plugin(alloc(hashtable_table_plugin, get_rmanager())); - get_rmanager().register_plugin(alloc(bitvector_table_plugin, get_rmanager())); - get_rmanager().register_plugin(alloc(equivalence_table_plugin, get_rmanager())); - -#ifndef _EXTERNAL_RELEASE - get_rmanager().register_plugin(alloc(skip_table_plugin, get_rmanager())); -#endif - - //register plugins for builtin relations - get_rmanager().register_plugin(alloc(smt_relation_plugin, get_rmanager())); - - get_rmanager().register_plugin(alloc(bound_relation_plugin, get_rmanager())); - get_rmanager().register_plugin(alloc(interval_relation_plugin, get_rmanager())); } context::~context() { @@ -272,14 +246,12 @@ namespace datalog { m_trail.reset(); m_rule_set.reset(); m_argument_var_names.reset(); - m_output_preds.reset(); m_preds.reset(); m_preds_by_name.reset(); reset_dealloc_values(m_sorts); - if (m_last_result_relation) { - m_last_result_relation->deallocate(); - m_last_result_relation = 0; - } + m_pdr = 0; + m_bmc = 0; + m_rel = 0; } bool context::is_fact(app * head) const { @@ -337,7 +309,7 @@ namespace datalog { expr_ref context::bind_variables(expr* fml, bool is_forall) { expr_ref result(m); - app_ref_vector const& vars = m_vars; + app_ref_vector const & vars = m_vars; if (vars.empty()) { result = fml; } @@ -352,9 +324,19 @@ namespace datalog { svector names; for (unsigned i = 0; i < sorts.size(); ++i) { if (!sorts[i]) { - sorts[i] = vars[i]->get_decl()->get_range(); + if (i < vars.size()) { + sorts[i] = vars[i]->get_decl()->get_range(); + } + else { + sorts[i] = m.mk_bool_sort(); + } + } + if (i < vars.size()) { + names.push_back(vars[i]->get_decl()->get_name()); + } + else { + names.push_back(symbol(i)); } - names.push_back(vars[i]->get_decl()->get_name()); } quantifier_ref q(m); sorts.reverse(); @@ -445,59 +427,13 @@ namespace datalog { return e->get_data().m_value[arg_index]; } - relation_plugin & context::get_ordinary_relation_plugin(symbol relation_name) { - relation_plugin * plugin = get_rmanager().get_relation_plugin(relation_name); - if (!plugin) { - std::stringstream sstm; - sstm << "relation plugin " << relation_name << " does not exist"; - throw default_exception(sstm.str()); - } - if (plugin->is_product_relation()) { - throw default_exception("cannot request product relation directly"); - } - if (plugin->is_sieve_relation()) { - throw default_exception("cannot request sieve relation directly"); - } - if (plugin->is_finite_product_relation()) { - throw default_exception("cannot request finite product relation directly"); - } - return *plugin; - } void context::set_predicate_representation(func_decl * pred, unsigned relation_name_cnt, symbol const * relation_names) { - relation_manager & rmgr = get_rmanager(); - - family_id target_kind = null_family_id; - switch (relation_name_cnt) { - case 0: - return; - case 1: - target_kind = get_ordinary_relation_plugin(relation_names[0]).get_kind(); - break; - default: { - svector rel_kinds; // kinds of plugins that are not table plugins - family_id rel_kind; // the aggregate kind of non-table plugins - for (unsigned i = 0; i < relation_name_cnt; i++) { - relation_plugin & p = get_ordinary_relation_plugin(relation_names[i]); - rel_kinds.push_back(p.get_kind()); - } - if (rel_kinds.size() == 1) { - rel_kind = rel_kinds[0]; - } - else { - relation_signature rel_sig; - //rmgr.from_predicate(pred, rel_sig); - product_relation_plugin & prod_plugin = product_relation_plugin::get_plugin(rmgr); - rel_kind = prod_plugin.get_relation_kind(rel_sig, rel_kinds); - } - target_kind = rel_kind; - break; - } + if (relation_name_cnt > 0) { + ensure_rel(); + m_rel->set_predicate_representation(pred, relation_name_cnt, relation_names); } - - SASSERT(target_kind != null_family_id); - get_rmanager().set_predicate_kind(pred, target_kind); } func_decl * context::mk_fresh_head_predicate(symbol const & prefix, symbol const & suffix, @@ -507,19 +443,25 @@ namespace datalog { register_predicate(new_pred); - if (orig_pred) { - family_id target_kind = get_rmanager().get_requested_predicate_kind(orig_pred); - if (target_kind != null_family_id) { - get_rmanager().set_predicate_kind(new_pred, target_kind); - } + if (m_rel.get()) { + m_rel->inherit_predicate_kind(new_pred, orig_pred); } return new_pred; } void context::set_output_predicate(func_decl * pred) { - if (!m_output_preds.contains(pred)) { - m_output_preds.insert(pred); - } + ensure_rel(); + m_rel->set_output_predicate(pred); + } + + bool context::is_output_predicate(func_decl * pred) { + ensure_rel(); + return m_rel->is_output_predicate(pred); + } + + const decl_set & context::get_output_predicates() { + ensure_rel(); + return m_rel->get_output_predicates(); } void context::add_rule(expr* rl, symbol const& name) { @@ -552,7 +494,6 @@ namespace datalog { throw default_exception(strm.str()); } rule_ref r(rules[0].get(), rm); - get_rmanager().reset_saturated_marks(); rule_ref_vector const& rls = m_rule_set.get_rules(); rule* old_rule = 0; for (unsigned i = 0; i < rls.size(); ++i) { @@ -785,7 +726,6 @@ namespace datalog { } void context::add_rule(rule_ref& r) { - get_rmanager().reset_saturated_marks(); m_rule_set.add_rule(r); } @@ -799,12 +739,10 @@ namespace datalog { void context::add_fact(func_decl * pred, const relation_fact & fact) { if (get_engine() == DATALOG_ENGINE) { - get_rmanager().reset_saturated_marks(); - get_relation(pred).add_fact(fact); - m_table_facts.push_back(std::make_pair(pred, fact)); + ensure_rel(); + m_rel->add_fact(pred, fact); } else { - ast_manager& m = get_manager(); expr_ref rule(m.mk_app(pred, fact.size(), (expr*const*)fact.c_ptr()), m); add_rule(rule, symbol::null); } @@ -822,26 +760,18 @@ namespace datalog { add_fact(head->get_decl(), fact); } - bool context::can_add_table_fact(func_decl * pred) { - return get_relation(pred).from_table(); - } - void context::add_table_fact(func_decl * pred, const table_fact & fact) { - relation_base & rel0 = get_relation(pred); - if (get_engine() != DATALOG_ENGINE || - !can_add_table_fact(pred) || - !rel0.from_table()) { + if (get_engine() == DATALOG_ENGINE) { + ensure_rel(); + m_rel->add_fact(pred, fact); + } + else { relation_fact rfact(m); for (unsigned i = 0; i < fact.size(); ++i) { rfact.push_back(m_decl_util.mk_numeral(fact[i], pred->get_domain()[i])); } add_fact(pred, rfact); } - else { - get_rmanager().reset_saturated_marks(); - table_relation & rel = static_cast(rel0); - rel.add_table_fact(fact); - } } void context::add_table_fact(func_decl * pred, unsigned num_args, unsigned args[]) { @@ -944,181 +874,28 @@ namespace datalog { transf.register_plugin(alloc(datalog::mk_subsumption_checker, *this, 34880)); transf.register_plugin(alloc(datalog::mk_bit_blast, *this, 35000)); + transf.register_plugin(alloc(datalog::mk_array_blast, *this, 36000)); transform_rules(transf, mc, pc); } void context::collect_params(param_descrs& p) { - p.insert(":engine", CPK_SYMBOL, "(default: automatically configured) select 'datalog', PDR 'pdr' engine."); - p.insert(":bit-blast", CPK_BOOL, "(default: false) bit-blast bit-vectors (for PDR engine)."); - p.insert(":default-table", CPK_SYMBOL, "default table implementation: 'sparse' (default), 'hashtable', 'bitvector', 'interval'"); - p.insert(":default-relation", CPK_SYMBOL, "default relation implementation: 'external_relation', 'pentagon'"); - - p.insert(":generate-explanations", CPK_BOOL, "if true, signature of relations will be extended to contain explanations for facts"); - p.insert(":explanations-on-relation-level", CPK_BOOL, "if true, explanations are generated as history of each relation, " - "rather than per fact (:generate-explanations must be set to true for this option to have any effect)"); - - p.insert(":magic-sets-for-queries", CPK_BOOL, "magic set transformation will be used for queries"); - p.insert(":unbound-compressor", CPK_BOOL, "auxiliary relations will be introduced to avoid unbound variables in rule heads"); - p.insert(":similarity-compressor", CPK_BOOL, "rules that differ only in values of constants will be merged into a single rule"); - p.insert(":similarity-compressor-threshold", CPK_UINT, "if :dl-similiaryt-compressor is on, this value determines how many " - "similar rules there must be in order for them to be merged"); - - p.insert(":all-or-nothing-deltas", CPK_BOOL, "compile rules so that it is enough for the delta relation in union and widening " - "operations to determine only whether the updated relation was modified or not"); - p.insert(":compile-with-widening", CPK_BOOL, "widening will be used to compile recursive rules"); - p.insert(":eager-emptiness-checking", CPK_BOOL, "emptiness of affected relations will be checked after each instruction, " - "so that we may ommit unnecessary instructions"); - p.insert(":default-table-checked", CPK_BOOL, - "if true, the detault table will be :default-table inside a wrapper that checks that " - "its results are the same as of :default-table-checker table"); - - - p.insert(":initial-restart-timeout", CPK_UINT, "length of saturation run before the first restart (in ms); zero means no restarts"); - p.insert(":restart-timeout-quotient", CPK_UINT, "restart timeout will be multiplied by this number after each restart"); - p.insert(":use-map-names", CPK_BOOL, "use names from map files when displaying tuples"); - - p.insert(":output-profile", CPK_BOOL, "determines whether profile informations should be output when outputting Datalog rules or instructions"); - p.insert(":output-tuples", CPK_BOOL, "determines whether tuples for output predicates should be output"); - p.insert(":profile-timeout-milliseconds", CPK_UINT, "instructions and rules that took less than the threshold will not be printed when printed the instruction/rule list"); - - p.insert(":print-with-fixedpoint-extensions", CPK_BOOL, "(default true) use SMT-LIB2 fixedpoint extensions, instead of pure SMT2, when printing rules"); - - PRIVATE_PARAMS( - p.insert(":dbg-fpr-nonempty-relation-signature", CPK_BOOL, - "if true, finite_product_relation will attempt to avoid creating inner relation with empty signature " - "by putting in half of the table columns, if it would have been empty otherwise"); - - p.insert(":smt-relation-ground-recursive", CPK_BOOL, "Ensure recursive relation is ground in union"); - ); - - p.insert(":fix-unbound-vars", CPK_BOOL, "fix unbound variables in tail"); - p.insert(":default-table-checker", CPK_SYMBOL, "see :default-table-checked"); - p.insert(":inline-linear", CPK_BOOL, "(default true) try linear inlining method"); - p.insert(":inline-eager", CPK_BOOL, "(default true) try eager inlining of rules"); - PRIVATE_PARAMS(p.insert(":inline-linear-branch", CPK_BOOL, "try linear inlining method with potential expansion");); - - pdr::dl_interface::collect_params(p); - bmc::collect_params(p); + fixedpoint_params::collect_param_descrs(p); insert_timeout(p); } void context::updt_params(params_ref const& p) { - m_params.copy(p); - if (m_pdr.get()) m_pdr->updt_params(); - + m_params_ref.copy(p); + if (m_pdr.get()) m_pdr->updt_params(); } - void context::collect_predicates(decl_set & res) { - unsigned rule_cnt = m_rule_set.get_num_rules(); - for (unsigned rindex=0; rindexget_head()->get_decl()); - unsigned tail_len = r->get_uninterpreted_tail_size(); - for (unsigned tindex=0; tindexget_tail(tindex)->get_decl()); - } - } - decl_set::iterator oit = m_output_preds.begin(); - decl_set::iterator oend = m_output_preds.end(); - for (; oit!=oend; ++oit) { - res.insert(*oit); - } - get_rmanager().collect_predicates(res); + void context::collect_predicates(decl_set& res) { + ensure_rel(); + m_rel->collect_predicates(res); } - - void context::restrict_predicates( const decl_set & res ) { - set_intersection(m_output_preds, res); - get_rmanager().restrict_predicates(res); - } - - lbool context::dl_saturate() { - if (!m_closed) { - close(); - } - bool time_limit = soft_timeout()!=0; - unsigned remaining_time_limit = soft_timeout(); - unsigned restart_time = initial_restart_timeout(); - - rule_set original_rules(get_rules()); - decl_set original_predicates; - collect_predicates(original_predicates); - - instruction_block rules_code; - instruction_block termination_code; - execution_context ex_ctx(*this); - lbool result; - - TRACE("dl", display(tout);); - - while (true) { - model_converter_ref mc; // Ignored in Datalog mode - proof_converter_ref pc; // Ignored in Datalog mode - transform_rules(mc, pc); - compiler::compile(*this, get_rules(), rules_code, termination_code); - - TRACE("dl", rules_code.display(*this, tout); ); - - bool timeout_after_this_round = time_limit && (restart_time==0 || remaining_time_limit<=restart_time); - - if (time_limit || restart_time!=0) { - unsigned timeout = time_limit ? (restart_time!=0) ? - std::min(remaining_time_limit, restart_time) - : remaining_time_limit : restart_time; - ex_ctx.set_timelimit(timeout); - } - - bool early_termination = !rules_code.perform(ex_ctx); - ex_ctx.reset_timelimit(); - VERIFY( termination_code.perform(ex_ctx) ); - - rules_code.process_all_costs(); - - IF_VERBOSE(10, ex_ctx.report_big_relations(1000, verbose_stream());); - - if (!early_termination) { - m_last_status = OK; - result = l_true; - break; - } - - if (memory::above_high_watermark()) { - m_last_status = MEMOUT; - result = l_undef; - break; - } - if (timeout_after_this_round || m_cancel) { - m_last_status = TIMEOUT; - result = l_undef; - break; - } - SASSERT(restart_time!=0); - if (time_limit) { - SASSERT(remaining_time_limit>restart_time); - remaining_time_limit-=restart_time; - } - uint64 new_restart_time = static_cast(restart_time)*initial_restart_timeout(); - if (new_restart_time>UINT_MAX) { - restart_time=UINT_MAX; - } - else { - restart_time=static_cast(new_restart_time); - } - - rules_code.reset(); - termination_code.reset(); - ex_ctx.reset(); - reopen(); - restrict_predicates(original_predicates); - replace_rules(original_rules); - close(); - } - reopen(); - restrict_predicates(original_predicates); - replace_rules(original_rules); - close(); - TRACE("dl", ex_ctx.report_big_relations(100, tout);); - return result; + void context::restrict_predicates(decl_set const& res) { + ensure_rel(); + m_rel->restrict_predicates(res); } expr_ref context::get_background_assertion() { @@ -1141,19 +918,21 @@ namespace datalog { m_cancel = true; if (m_pdr.get()) m_pdr->cancel(); if (m_bmc.get()) m_bmc->cancel(); + if (m_rel.get()) m_rel->cancel(); } void context::cleanup() { m_cancel = false; if (m_pdr.get()) m_pdr->cleanup(); if (m_bmc.get()) m_bmc->cleanup(); + if (m_rel.get()) m_rel->cleanup(); } class context::engine_type_proc { - ast_manager& m; - arith_util a; + ast_manager& m; + arith_util a; datatype_util dt; - DL_ENGINE m_engine; + DL_ENGINE m_engine; public: engine_type_proc(ast_manager& m): m(m), a(m), dt(m), m_engine(DATALOG_ENGINE) {} @@ -1176,7 +955,7 @@ namespace datalog { }; void context::configure_engine() { - symbol e = m_params.get_sym(":engine", symbol()); + symbol e = m_params.engine(); if (e == symbol("datalog")) { m_engine = DATALOG_ENGINE; @@ -1220,7 +999,7 @@ namespace datalog { switch(get_engine()) { case DATALOG_ENGINE: - return dl_query(query); + return rel_query(query); case PDR_ENGINE: case QPDR_ENGINE: return pdr_query(query); @@ -1229,18 +1008,14 @@ namespace datalog { return bmc_query(query); default: UNREACHABLE(); - return dl_query(query); + return rel_query(query); } } void context::new_query() { flush_add_rules(); - if (m_last_result_relation) { - m_last_result_relation->deallocate(); - m_last_result_relation = 0; - } m_last_status = OK; - m_last_answer = get_manager().mk_true(); + m_last_answer = 0; } model_ref context::get_model() { @@ -1273,7 +1048,6 @@ namespace datalog { lbool context::pdr_query(expr* query) { ensure_pdr(); - m_last_answer = 0; return m_pdr->query(query); } @@ -1285,218 +1059,25 @@ namespace datalog { lbool context::bmc_query(expr* query) { ensure_bmc(); - m_last_answer = 0; return m_bmc->query(query); } -#define BEGIN_QUERY() \ - rule_set original_rules(get_rules()); \ - decl_set original_preds; \ - collect_predicates(original_preds); \ - bool was_closed = m_closed; \ - if (m_closed) { \ - reopen(); \ - } \ - -#define END_QUERY() \ - reopen(); \ - replace_rules(original_rules); \ - restrict_predicates(original_preds); \ - \ - if (was_closed) { \ - close(); \ - } \ - - lbool context::dl_query(unsigned num_rels, func_decl * const* rels) { - BEGIN_QUERY(); - for (unsigned i = 0; i < num_rels; ++i) { - set_output_predicate(rels[i]); + void context::ensure_rel() { + if (!m_rel.get()) { + m_rel = alloc(rel_context, *this); } - close(); - reset_negated_tables(); - lbool res = dl_saturate(); + } - switch(res) { - case l_true: { - expr_ref_vector ans(m); - expr_ref e(m); - bool some_non_empty = num_rels == 0; - for (unsigned i = 0; i < num_rels; ++i) { - relation_base& rel = get_relation(rels[i]); - if (!rel.empty()) { - some_non_empty = true; - } - rel.to_formula(e); - ans.push_back(e); - } - SASSERT(!m_last_result_relation); - if (some_non_empty) { - m_last_answer = m.mk_and(ans.size(), ans.c_ptr()); - } - else { - m_last_answer = m.mk_false(); - res = l_false; - } - break; - } - case l_false: - m_last_answer = m.mk_false(); - break; - case l_undef: - break; - } - END_QUERY(); - return res; + lbool context::rel_query(unsigned num_rels, func_decl * const* rels) { + ensure_rel(); + return m_rel->query(num_rels, rels); } - lbool context::dl_query(expr* query) { - BEGIN_QUERY(); - rule_manager& rm = get_rule_manager(); - rule_ref qrule(rm); - rule_ref_vector qrules(rm); - func_decl_ref query_pred(get_manager()); - try { - rm.mk_query(query, query_pred, qrules, qrule); - } - catch(default_exception& exn) { - close(); - m_last_status = INPUT_ERROR; - throw exn; - } - try { - add_rules(qrules); - } - catch (default_exception& exn) { - close(); - m_last_status = INPUT_ERROR; - throw exn; - } - - set_output_predicate(qrule->get_head()->get_decl()); - close(); - reset_negated_tables(); - - if (generate_explanations()) { - model_converter_ref mc; // ignored in Datalog mode - proof_converter_ref pc; // ignored in Datalog mode - rule_transformer transformer(*this); - //expl_plugin is deallocated when transformer goes out of scope - mk_explanations * expl_plugin = - alloc(mk_explanations, *this, explanations_on_relation_level()); - transformer.register_plugin(expl_plugin); - transform_rules(transformer, mc, pc); - - //we will retrieve the predicate with explanations instead of the original query predicate - query_pred = expl_plugin->get_e_decl(query_pred); - const rule_vector & query_rules = get_rules().get_predicate_rules(query_pred); - SASSERT(query_rules.size()==1); - qrule = query_rules.back(); - } - - if (magic_sets_for_queries()) { - model_converter_ref mc; // Ignored in Datalog mode - proof_converter_ref pc; // Ignored in Datalog mode - rule_transformer transformer(*this); - transformer.register_plugin(alloc(mk_magic_sets, *this, qrule.get())); - transform_rules(transformer, mc, pc); - } - - lbool res = dl_saturate(); - - if (res != l_undef) { - m_last_result_relation = get_relation(query_pred).clone(); - if (m_last_result_relation->empty()) { - res = l_false; - m_last_answer = m.mk_false(); - } - else { - m_last_result_relation->to_formula(m_last_answer); - } - } - - END_QUERY(); - return res; + lbool context::rel_query(expr* query) { + ensure_rel(); + return m_rel->query(query); } - void context::reset_tables() { - get_rmanager().reset_saturated_marks(); - rule_set::decl2rules::iterator it = m_rule_set.begin_grouped_rules(); - rule_set::decl2rules::iterator end = m_rule_set.end_grouped_rules(); - for (; it != end; ++it) { - func_decl* p = it->m_key; - relation_base & rel = get_relation(p); - rel.reset(); - } - for (unsigned i = 0; i < m_table_facts.size(); ++i) { - func_decl* pred = m_table_facts[i].first; - relation_fact const& fact = m_table_facts[i].second; - get_relation(pred).add_fact(fact); - } - } - - void context::reset_negated_tables() { - rule_set::pred_set_vector const & pred_sets = m_rule_set.get_strats(); - bool non_empty = false; - for (unsigned i = 1; i < pred_sets.size(); ++i) { - func_decl_set::iterator it = pred_sets[i]->begin(), end = pred_sets[i]->end(); - for (; it != end; ++it) { - func_decl* pred = *it; - relation_base & rel = get_relation(pred); - if (!rel.empty()) { - non_empty = true; - break; - } - } - } - if (!non_empty) { - return; - } - // collect predicates that depend on negation. - func_decl_set depends_on_negation; - for (unsigned i = 1; i < pred_sets.size(); ++i) { - bool change = true; - while (change) { - change = false; - func_decl_set::iterator it = pred_sets[i]->begin(), end = pred_sets[i]->end(); - for (; it != end; ++it) { - func_decl* pred = *it; - if (depends_on_negation.contains(pred)) { - continue; - } - rule_vector const& rules = m_rule_set.get_predicate_rules(pred); - bool inserted = false; - for (unsigned j = 0; !inserted && j < rules.size(); ++j) { - rule* r = rules[j]; - unsigned psz = r->get_positive_tail_size(); - unsigned tsz = r->get_uninterpreted_tail_size(); - if (psz < tsz) { - depends_on_negation.insert(pred); - change = true; - inserted = true; - } - for (unsigned k = 0; !inserted && k < tsz; ++k) { - func_decl* tail_decl = r->get_tail(k)->get_decl(); - if (depends_on_negation.contains(tail_decl)) { - depends_on_negation.insert(pred); - change = true; - inserted = true; - } - } - } - } - } - } - func_decl_set::iterator it = depends_on_negation.begin(), end = depends_on_negation.end(); - for (; it != end; ++it) { - func_decl* pred = *it; - relation_base & rel = get_relation(pred); - - if (!rel.empty()) { - TRACE("dl", tout << "Resetting: " << mk_ismt2_pp(pred, m) << "\n";); - rel.reset(); - } - } - } expr* context::get_answer_as_formula() { if (m_last_answer) { @@ -1513,6 +1094,10 @@ namespace datalog { ensure_bmc(); m_last_answer = m_bmc->get_answer(); return m_last_answer.get(); + case DATALOG_ENGINE: + ensure_rel(); + m_last_answer = m_rel->get_last_answer(); + return m_last_answer.get(); default: UNREACHABLE(); } @@ -1573,8 +1158,8 @@ namespace datalog { execution_result context::get_status() { return m_last_status; } bool context::result_contains_fact(relation_fact const& f) { - SASSERT(m_last_result_relation); - return m_last_result_relation->contains_fact(f); + ensure_rel(); + return m_rel->result_contains_fact(f); } // TBD: algebraic data-types declarations will not be printed. @@ -1612,6 +1197,23 @@ namespace datalog { void context::get_rules_as_formulas(expr_ref_vector& rules, svector& names) { expr_ref fml(m); + datalog::rule_manager& rm = get_rule_manager(); + datalog::rule_ref_vector rule_refs(rm); + + // ensure that rules are all using bound variables. + for (unsigned i = 0; i < m_rule_fmls.size(); ++i) { + ptr_vector sorts; + get_free_vars(m_rule_fmls[i].get(), sorts); + if (!sorts.empty()) { + rm.mk_rule(m_rule_fmls[i].get(), rule_refs, m_rule_names[i]); + m_rule_fmls[i] = m_rule_fmls.back(); + m_rule_names[i] = m_rule_names.back(); + m_rule_fmls.pop_back(); + m_rule_names.pop_back(); + --i; + } + } + add_rules(rule_refs); rule_set::iterator it = m_rule_set.begin(), end = m_rule_set.end(); for (; it != end; ++it) { (*it)->to_formula(fml); @@ -1637,12 +1239,15 @@ namespace datalog { expr_ref fml(m); expr_ref_vector rules(m); svector names; - bool use_fixedpoint_extensions = m_params.get_bool(":print-with-fixedpoint-extensions", true); + bool use_fixedpoint_extensions = m_params.print_with_fixedpoint_extensions(); + bool print_low_level = m_params.print_low_level_smt2(); + bool do_declare_vars = m_params.print_with_variable_declarations(); + +#define PP(_e_) if (print_low_level) out << mk_smt_pp(_e_, m); else ast_smt2_pp(out, _e_, env); get_rules_as_formulas(rules, names); smt2_pp_environment_dbg env(m); - pp_params params; mk_fresh_name fresh_names; collect_free_funcs(num_axioms, axioms, visited, visitor, fresh_names); collect_free_funcs(rules.size(), rules.c_ptr(), visited, visitor, fresh_names); @@ -1672,19 +1277,19 @@ namespace datalog { obj_hashtable& sorts = visitor.sorts(); obj_hashtable::iterator sit = sorts.begin(), send = sorts.end(); for (; sit != send; ++sit) { - ast_smt2_pp(out, *sit, env, params); + PP(*sit); } for (; it != end; ++it) { func_decl* f = *it; - ast_smt2_pp(out, f, env, params); + PP(f); out << "\n"; } it = rels.begin(); end = rels.end(); for (; it != end; ++it) { func_decl* f = *it; out << "(declare-rel " << f->get_name() << " ("; - for (unsigned i = 0; i < f->get_arity(); ++i) { - ast_smt2_pp(out, f->get_domain(i), env, params); + for (unsigned i = 0; i < f->get_arity(); ++i) { + ast_smt2_pp(out, f->get_domain(i), env); if (i + 1 < f->get_arity()) { out << " "; } @@ -1692,7 +1297,7 @@ namespace datalog { out << "))\n"; } - if (use_fixedpoint_extensions) { + if (use_fixedpoint_extensions && do_declare_vars) { declare_vars(rules, fresh_names, out); } @@ -1702,7 +1307,7 @@ namespace datalog { for (unsigned i = 0; i < num_axioms; ++i) { out << "(assert "; - ast_smt2_pp(out, axioms[i], env, params); + PP(axioms[i]); out << ")\n"; } for (unsigned i = 0; i < rules.size(); ++i) { @@ -1712,27 +1317,29 @@ namespace datalog { if (symbol::null != nm) { out << "(! "; } - if (use_fixedpoint_extensions) { - ast_smt2_pp(out, r, env, params); - } - else { - out << mk_smt_pp(r, m); - } + PP(r); if (symbol::null != nm) { + out << " :named "; while (fresh_names.contains(nm)) { std::ostringstream s; s << nm << "!"; nm = symbol(s.str().c_str()); } fresh_names.add(nm); - out << " :named " << nm << ")"; + if (is_smt2_quoted_symbol(nm)) { + out << mk_smt2_quoted_symbol(nm); + } + else { + out << nm; + } + out << ")"; } out << ")\n"; } if (use_fixedpoint_extensions) { for (unsigned i = 0; i < num_queries; ++i) { out << "(query "; - ast_smt2_pp(out, queries[i], env, params); + PP(queries[i]); out << ")\n"; } } @@ -1742,7 +1349,7 @@ namespace datalog { out << "(assert "; expr_ref q(m); q = m.mk_not(queries[i]); - ast_smt2_pp(out, q, env, params); + PP(q); out << ")\n"; out << "(check-sat)\n"; if (num_queries > 1) out << "(pop)\n"; @@ -1759,7 +1366,6 @@ namespace datalog { // smt2_pp_environment_dbg env(m); var_subst vsubst(m, false); - pp_params param; expr_ref_vector fresh_vars(m), subst(m); expr_ref res(m); @@ -1802,7 +1408,7 @@ namespace datalog { symbol name = fresh_names.next(); fresh_vars.push_back(m.mk_const(name, s)); out << "(declare-var " << name << " "; - ast_smt2_pp(out, s, env, param); + ast_smt2_pp(out, s, env); out << ")\n"; } subst.push_back(fresh_vars[vars[max_var]].get()); diff --git a/src/muz_qe/dl_context.h b/src/muz_qe/dl_context.h index 229bbc474..f84050e68 100644 --- a/src/muz_qe/dl_context.h +++ b/src/muz_qe/dl_context.h @@ -24,7 +24,6 @@ Revision History: #undef max #endif #include"arith_decl_plugin.h" -#include"front_end_params.h" #include"map.h" #include"th_rewriter.h" #include"str_hashtable.h" @@ -36,14 +35,15 @@ Revision History: #include"dl_rule_set.h" #include"pdr_dl_interface.h" #include"dl_bmc_engine.h" +#include"rel_context.h" #include"lbool.h" #include"statistics.h" #include"params.h" #include"trail.h" -#include"dl_external_relation.h" #include"model_converter.h" #include"proof_converter.h" #include"model2expr.h" +#include"smt_params.h" namespace datalog { @@ -75,15 +75,14 @@ namespace datalog { typedef map sym2decl; typedef obj_map > pred2syms; typedef obj_map sort_domain_map; - typedef vector > fact_vector; ast_manager & m; - front_end_params& m_fparams; - params_ref m_params; + smt_params & m_fparams; + params_ref m_params_ref; + fixedpoint_params m_params; dl_decl_util m_decl_util; th_rewriter m_rewriter; var_subst m_var_subst; - relation_manager m_rmanager; rule_manager m_rule_manager; trail_stack m_trail; @@ -93,7 +92,6 @@ namespace datalog { func_decl_set m_preds; sym2decl m_preds_by_name; pred2syms m_argument_var_names; - decl_set m_output_preds; rule_set m_rule_set; expr_ref_vector m_rule_fmls; svector m_rule_names; @@ -101,80 +99,64 @@ namespace datalog { scoped_ptr m_pdr; scoped_ptr m_bmc; + scoped_ptr m_rel; bool m_closed; bool m_saturation_was_run; execution_result m_last_status; - relation_base * m_last_result_relation; expr_ref m_last_answer; DL_ENGINE m_engine; volatile bool m_cancel; - fact_vector m_table_facts; bool is_fact(app * head) const; bool has_sort_domain(relation_sort s) const; sort_domain & get_sort_domain(relation_sort s); const sort_domain & get_sort_domain(relation_sort s) const; - relation_plugin & get_ordinary_relation_plugin(symbol relation_name); - class engine_type_proc; public: - context(ast_manager & m, front_end_params& params, params_ref const& p = params_ref()); + context(ast_manager & m, smt_params& fp, params_ref const& p = params_ref()); ~context(); void reset(); void push(); void pop(); - relation_base & get_relation(func_decl * pred) { return get_rmanager().get_relation(pred); } - relation_base * try_get_relation(func_decl * pred) const { return get_rmanager().try_get_relation(pred); } - bool saturation_was_run() const { return m_saturation_was_run; } void notify_saturation_was_run() { m_saturation_was_run = true; } - /** - \brief Store the relation \c rel under the predicate \c pred. The \c context object - takes over the ownership of the relation object. - */ - void store_relation(func_decl * pred, relation_base * rel) { - get_rmanager().store_relation(pred, rel); - } - void configure_engine(); ast_manager & get_manager() const { return m; } - relation_manager & get_rmanager() { return m_rmanager; } - const relation_manager & get_rmanager() const { return m_rmanager; } rule_manager & get_rule_manager() { return m_rule_manager; } - front_end_params & get_fparams() const { return m_fparams; } - params_ref const& get_params() const { return m_params; } + smt_params & get_fparams() const { return m_fparams; } + fixedpoint_params const& get_params() const { return m_params; } DL_ENGINE get_engine() { configure_engine(); return m_engine; } th_rewriter& get_rewriter() { return m_rewriter; } var_subst & get_var_subst() { return m_var_subst; } dl_decl_util & get_decl_util() { return m_decl_util; } - bool output_profile() const { return m_params.get_bool(":output-profile", false); } - bool fix_unbound_vars() const { return m_params.get_bool(":fix-unbound-vars", false); } - symbol default_table() const { return m_params.get_sym(":default-table", symbol("sparse")); } - symbol default_relation() const { return m_params.get_sym(":default-relation", external_relation_plugin::get_name()); } - symbol default_table_checker() const { return m_params.get_sym(":default-table-checker", symbol("sparse")); } - bool default_table_checked() const { return m_params.get_bool(":default-table-checked", false); } - bool dbg_fpr_nonempty_relation_signature() const { return m_params.get_bool(":dbg-fpr-nonempty-relation-signatures", false); } - unsigned dl_profile_milliseconds_threshold() const { return m_params.get_uint(":profile-milliseconds-threshold", 0); } - bool all_or_nothing_deltas() const { return m_params.get_bool(":all-or-nothing-deltas", false); } - bool compile_with_widening() const { return m_params.get_bool(":compile-with-widening", false); } - bool unbound_compressor() const { return m_params.get_bool(":unbound-compressor", true); } - bool similarity_compressor() const { return m_params.get_bool(":similarity-compressor", true); } - unsigned similarity_compressor_threshold() const { return m_params.get_uint(":similarity-compressor-threshold", 11); } + bool output_profile() const { return m_params.output_profile(); } + bool fix_unbound_vars() const { return m_params.fix_unbound_vars(); } + symbol default_table() const { return m_params.default_table(); } + symbol default_relation() const { return m_params.default_relation(); } // external_relation_plugin::get_name()); + symbol default_table_checker() const { return m_params.default_table_checker(); } + bool default_table_checked() const { return m_params.default_table_checked(); } + bool dbg_fpr_nonempty_relation_signature() const { return m_params.dbg_fpr_nonempty_relation_signature(); } + unsigned dl_profile_milliseconds_threshold() const { return m_params.profile_timeout_milliseconds(); } + bool all_or_nothing_deltas() const { return m_params.all_or_nothing_deltas(); } + bool compile_with_widening() const { return m_params.compile_with_widening(); } + bool unbound_compressor() const { return m_params.unbound_compressor(); } + bool similarity_compressor() const { return m_params.similarity_compressor(); } + unsigned similarity_compressor_threshold() const { return m_params.similarity_compressor_threshold(); } unsigned soft_timeout() const { return m_fparams.m_soft_timeout; } - unsigned initial_restart_timeout() const { return m_params.get_uint(":initial-restart-timeout", 0); } - bool generate_explanations() const { return m_params.get_bool(":generate-explanations", false); } - bool explanations_on_relation_level() const { return m_params.get_bool(":explanations-on-relation-level", false); } - bool magic_sets_for_queries() const { return m_params.get_bool(":magic-sets-for-queries", false); } - bool eager_emptiness_checking() const { return m_params.get_bool(":eager-emptiness-checking", true); } + unsigned initial_restart_timeout() const { return m_params.initial_restart_timeout(); } + bool generate_explanations() const { return m_params.generate_explanations(); } + bool explanations_on_relation_level() const { return m_params.explanations_on_relation_level(); } + bool magic_sets_for_queries() const { return m_params.magic_sets_for_queries(); } + bool eager_emptiness_checking() const { return m_params.eager_emptiness_checking(); } void register_finite_sort(sort * s, sort_kind k); @@ -246,8 +228,8 @@ namespace datalog { symbol const * relation_names); void set_output_predicate(func_decl * pred); - bool is_output_predicate(func_decl * pred) { return m_output_preds.contains(pred); } - const decl_set & get_output_predicates() const { return m_output_preds; } + bool is_output_predicate(func_decl * pred); + const decl_set & get_output_predicates(); rule_set const & get_rules() { flush_add_rules(); return m_rule_set; } @@ -313,7 +295,6 @@ namespace datalog { and there is no transformation of relation values before they are put into the table. */ - bool can_add_table_fact(func_decl * pred); void add_table_fact(func_decl * pred, const table_fact & fact); void add_table_fact(func_decl * pred, unsigned num_args, unsigned args[]); @@ -322,6 +303,7 @@ namespace datalog { */ void close(); void ensure_closed(); + bool is_closed() { return m_closed; } /** \brief Undo the effect of the \c close operation. @@ -350,13 +332,10 @@ namespace datalog { void display_rules(std::ostream & out) const { m_rule_set.display(out); } - void display_facts(std::ostream & out) const { - m_rmanager.display(out); - } void display(std::ostream & out) const { display_rules(out); - display_facts(out); + if (m_rel) m_rel->display_facts(out); } void display_smt2(unsigned num_queries, expr* const* queries, std::ostream& out); @@ -406,23 +385,16 @@ namespace datalog { /** Query multiple output relations. */ - lbool dl_query(unsigned num_rels, func_decl * const* rels); + lbool rel_query(unsigned num_rels, func_decl * const* rels); - /** - Reset tables that are under negation. - */ - void reset_negated_tables(); - - /** - Just reset all tables. - */ - void reset_tables(); /** \brief retrieve last proof status. */ execution_result get_status(); + void set_status(execution_result r) { m_last_status = r; } + /** \brief retrieve formula corresponding to query that returns l_true. The formula describes one or more instances of the existential variables @@ -445,29 +417,27 @@ namespace datalog { */ bool result_contains_fact(relation_fact const& f); - /** - \brief display facts generated for query. - */ - void display_output_facts(std::ostream & out) const { - m_rmanager.display_output_tables(out); - } - - /** - \brief expose datalog saturation for test. - */ - lbool dl_saturate(); + rel_context& get_rel_context() { ensure_rel(); return *m_rel; } private: + /** + Just reset all tables. + */ + void reset_tables(); + + void flush_add_rules(); void ensure_pdr(); void ensure_bmc(); + void ensure_rel(); + void new_query(); - lbool dl_query(expr* query); + lbool rel_query(expr* query); lbool pdr_query(expr* query); diff --git a/src/muz_qe/dl_costs.cpp b/src/muz_qe/dl_costs.cpp index 0b7641093..fe085d7f7 100644 --- a/src/muz_qe/dl_costs.cpp +++ b/src/muz_qe/dl_costs.cpp @@ -115,7 +115,7 @@ namespace datalog { } - void accounted_object::output_profile(context & ctx, std::ostream & out) const { + void accounted_object::output_profile(std::ostream & out) const { costs c; get_total_cost(c); c.output(out); diff --git a/src/muz_qe/dl_costs.h b/src/muz_qe/dl_costs.h index 0fc60451d..16cfc16b1 100644 --- a/src/muz_qe/dl_costs.h +++ b/src/muz_qe/dl_costs.h @@ -79,7 +79,7 @@ namespace datalog { void process_costs(); bool passes_output_thresholds(context & ctx) const; - void output_profile(context & ctx, std::ostream & out) const; + void output_profile(std::ostream & out) const; private: //private and undefined copy constructor and operator= to avoid the default ones diff --git a/src/muz_qe/dl_instruction.cpp b/src/muz_qe/dl_instruction.cpp index 9d6e9036f..503ffec3b 100644 --- a/src/muz_qe/dl_instruction.cpp +++ b/src/muz_qe/dl_instruction.cpp @@ -33,11 +33,11 @@ namespace datalog { // // ----------------------------------- - execution_context::execution_context(context & datalog_context) - : m_datalog_context(datalog_context), + execution_context::execution_context(context & context) + : m_context(context), m_stopwatch(0), m_timelimit_ms(0), - m_eager_emptiness_checking(datalog_context.eager_emptiness_checking()) {} + m_eager_emptiness_checking(context.eager_emptiness_checking()) {} execution_context::~execution_context() { reset(); @@ -135,12 +135,12 @@ namespace datalog { process_costs(); } - void instruction::display_indented(context & ctx, std::ostream & out, std::string indentation) const { + void instruction::display_indented(rel_context & ctx, std::ostream & out, std::string indentation) const { out << indentation; display_head_impl(ctx, out); if (ctx.output_profile()) { out << " {"; - output_profile(ctx, out); + output_profile(out); out << '}'; } out << "\n"; @@ -157,10 +157,10 @@ namespace datalog { virtual bool perform(execution_context & ctx) { if (m_store) { if (ctx.reg(m_reg)) { - ctx.get_datalog_context().store_relation(m_pred, ctx.release_reg(m_reg)); + ctx.get_rel_context().store_relation(m_pred, ctx.release_reg(m_reg)); } else { - context & dctx = ctx.get_datalog_context(); + rel_context & dctx = ctx.get_rel_context(); relation_base * empty_rel; //the object referenced by sig is valid only until we call dctx.store_relation() const relation_signature & sig = dctx.get_relation(m_pred).get_signature(); @@ -169,7 +169,7 @@ namespace datalog { } } else { - relation_base& rel = ctx.get_datalog_context().get_relation(m_pred); + relation_base& rel = ctx.get_rel_context().get_relation(m_pred); if ((!ctx.eager_emptiness_checking() || !rel.empty())) { ctx.set_reg(m_reg, rel.clone()); } @@ -182,7 +182,7 @@ namespace datalog { virtual void make_annotations(execution_context & ctx) { ctx.set_register_annotation(m_reg, m_pred->get_name().bare_str()); } - virtual void display_head_impl(context & ctx, std::ostream & out) const { + virtual void display_head_impl(rel_context & ctx, std::ostream & out) const { const char * rel_name = m_pred->get_name().bare_str(); if (m_store) { out << "store " << m_reg << " into " << rel_name; @@ -213,7 +213,7 @@ namespace datalog { virtual void make_annotations(execution_context & ctx) { ctx.set_register_annotation(m_reg, "alloc"); } - virtual void display_head_impl(context & ctx, std::ostream & out) const { + virtual void display_head_impl(rel_context & ctx, std::ostream & out) const { out << "dealloc " << m_reg; } }; @@ -248,7 +248,7 @@ namespace datalog { ctx.set_register_annotation(m_src, str); } } - virtual void display_head_impl(context & ctx, std::ostream & out) const { + virtual void display_head_impl(rel_context & ctx, std::ostream & out) const { out << (m_clone ? "clone " : "move ") << m_src << " into " << m_tgt; } }; @@ -304,11 +304,11 @@ namespace datalog { virtual void make_annotations(execution_context & ctx) { m_body->make_annotations(ctx); } - virtual void display_head_impl(context & ctx, std::ostream & out) const { + virtual void display_head_impl(rel_context & ctx, std::ostream & out) const { out << "while"; print_container(m_controls, out); } - virtual void display_body_impl(context & ctx, std::ostream & out, std::string indentation) const { + virtual void display_body_impl(rel_context & ctx, std::ostream & out, std::string indentation) const { m_body->display_indented(ctx, out, indentation+" "); } }; @@ -349,9 +349,9 @@ namespace datalog { } TRACE("dl", - r1.get_signature().output(ctx.get_datalog_context().get_manager(), tout); + r1.get_signature().output(ctx.get_rel_context().get_manager(), tout); tout<<":"<\n";); try { @@ -371,7 +371,7 @@ namespace datalog { } TRACE("dl", - ctx.reg(m_res)->get_signature().output(ctx.get_datalog_context().get_manager(), tout); + ctx.reg(m_res)->get_signature().output(ctx.get_rel_context().get_manager(), tout); tout<<":"<get_size_estimate_rows()<<"\n";); if (ctx.eager_emptiness_checking() && ctx.reg(m_res)->empty()) { @@ -385,7 +385,7 @@ namespace datalog { ctx.get_register_annotation(m_rel1, a1); ctx.set_register_annotation(m_res, "join " + a1 + " " + a2); } - virtual void display_head_impl(context & ctx, std::ostream & out) const { + virtual void display_head_impl(rel_context & ctx, std::ostream & out) const { out << "join " << m_rel1; print_container(m_cols1, out); out << " and " << m_rel2; @@ -431,10 +431,10 @@ namespace datalog { } virtual void make_annotations(execution_context & ctx) { std::stringstream a; - a << "filter_equal " << m_col << " val: " << ctx.get_datalog_context().get_rmanager().to_nice_string(m_value); + a << "filter_equal " << m_col << " val: " << ctx.get_rel_context().get_rmanager().to_nice_string(m_value); ctx.set_register_annotation(m_reg, a.str()); } - virtual void display_head_impl(context & ctx, std::ostream & out) const { + virtual void display_head_impl(rel_context & ctx, std::ostream & out) const { out << "filter_equal " << m_reg << " col: " << m_col << " val: " << ctx.get_rmanager().to_nice_string(m_value); } @@ -476,7 +476,7 @@ namespace datalog { } return true; } - virtual void display_head_impl(context & ctx, std::ostream & out) const { + virtual void display_head_impl(rel_context & ctx, std::ostream & out) const { out << "filter_identical " << m_reg << " "; print_container(m_cols, out); } @@ -519,7 +519,7 @@ namespace datalog { } return true; } - virtual void display_head_impl(context & ctx, std::ostream & out) const { + virtual void display_head_impl(rel_context & ctx, std::ostream & out) const { out << "filter_interpreted " << m_reg << " using " << mk_pp(m_cond, m_cond.get_manager()); } @@ -624,7 +624,7 @@ namespace datalog { ctx.set_register_annotation(m_delta, "delta of "+str); } } - virtual void display_head_impl(context & ctx, std::ostream & out) const { + virtual void display_head_impl(rel_context & ctx, std::ostream & out) const { out << (m_widen ? "widen " : "union ") << m_src << " into " << m_tgt; if (m_delta!=execution_context::void_register) { out << " with delta " << m_delta; @@ -678,7 +678,7 @@ namespace datalog { return true; } - virtual void display_head_impl(context & ctx, std::ostream & out) const { + virtual void display_head_impl(rel_context & ctx, std::ostream & out) const { out << (m_projection ? "project " : "rename ") << m_src << " into " << m_tgt; out << (m_projection ? " deleting columns " : " with cycle "); print_container(m_cols, out); @@ -739,7 +739,7 @@ namespace datalog { } return true; } - virtual void display_head_impl(context & ctx, std::ostream & out) const { + virtual void display_head_impl(rel_context & ctx, std::ostream & out) const { out << "join_project " << m_rel1; print_container(m_cols1, out); out << " and " << m_rel2; @@ -800,7 +800,7 @@ namespace datalog { } return true; } - virtual void display_head_impl(context & ctx, std::ostream & out) const { + virtual void display_head_impl(rel_context & ctx, std::ostream & out) const { out << "select_equal_and_project " << m_src <<" into " << m_result << " col: " << m_col << " val: " << ctx.get_rmanager().to_nice_string(m_value); } @@ -809,7 +809,7 @@ namespace datalog { std::string s1 = "src"; ctx.get_register_annotation(m_src, s1); s << "select equal project col " << m_col << " val: " - << ctx.get_datalog_context().get_rmanager().to_nice_string(m_value) << " " << s1; + << ctx.get_rel_context().get_rmanager().to_nice_string(m_value) << " " << s1; ctx.set_register_annotation(m_result, s.str()); } }; @@ -854,7 +854,7 @@ namespace datalog { } return true; } - virtual void display_head_impl(context & ctx, std::ostream & out) const { + virtual void display_head_impl(rel_context & ctx, std::ostream & out) const { out << "filter_by_negation on " << m_tgt; print_container(m_cols1, out); out << " with " << m_neg_rel; @@ -887,12 +887,12 @@ namespace datalog { } virtual bool perform(execution_context & ctx) { ctx.make_empty(m_tgt); - relation_base * rel = ctx.get_datalog_context().get_rmanager().mk_empty_relation(m_sig, m_pred); + relation_base * rel = ctx.get_rel_context().get_rmanager().mk_empty_relation(m_sig, m_pred); rel->add_fact(m_fact); ctx.set_reg(m_tgt, rel); return true; } - virtual void display_head_impl(context & ctx, std::ostream & out) const { + virtual void display_head_impl(rel_context & ctx, std::ostream & out) const { out << "mk_unary_singleton into " << m_tgt << " sort:" << ctx.get_rmanager().to_nice_string(m_sig[0]) << " val:" << ctx.get_rmanager().to_nice_string(m_sig[0], m_fact[0]); @@ -919,10 +919,10 @@ namespace datalog { instr_mk_total(const relation_signature & sig, func_decl* p, reg_idx tgt) : m_sig(sig), m_pred(p), m_tgt(tgt) {} virtual bool perform(execution_context & ctx) { ctx.make_empty(m_tgt); - ctx.set_reg(m_tgt, ctx.get_datalog_context().get_rmanager().mk_full_relation(m_sig, m_pred)); + ctx.set_reg(m_tgt, ctx.get_rel_context().get_rmanager().mk_full_relation(m_sig, m_pred)); return true; } - virtual void display_head_impl(context & ctx, std::ostream & out) const { + virtual void display_head_impl(rel_context & ctx, std::ostream & out) const { out << "mk_total into " << m_tgt << " sort:" << ctx.get_rmanager().to_nice_string(m_sig); } @@ -944,10 +944,10 @@ namespace datalog { instr_mark_saturated(ast_manager & m, func_decl * pred) : m_pred(pred, m) {} virtual bool perform(execution_context & ctx) { - ctx.get_datalog_context().get_rmanager().mark_saturated(m_pred); + ctx.get_rel_context().get_rmanager().mark_saturated(m_pred); return true; } - virtual void display_head_impl(context & ctx, std::ostream & out) const { + virtual void display_head_impl(rel_context & ctx, std::ostream & out) const { out << "mark_saturated " << m_pred->get_name().bare_str(); } virtual void make_annotations(execution_context & ctx) { @@ -970,7 +970,7 @@ namespace datalog { } return true; } - virtual void display_head_impl(context & ctx, std::ostream & out) const { + virtual void display_head_impl(rel_context & ctx, std::ostream & out) const { out << "instr_assert_signature of " << m_tgt << " signature:"; print_container(m_sig, out); } @@ -1019,7 +1019,7 @@ namespace datalog { TRACE("dl", tout <<"% "; - instr->display_head_impl(ctx.get_datalog_context(), tout); + instr->display_head_impl(ctx.get_rel_context(), tout); tout <<"\n";); success = !ctx.should_terminate() && instr->perform(ctx); } @@ -1042,12 +1042,12 @@ namespace datalog { } } - void instruction_block::display_indented(context & ctx, std::ostream & out, std::string indentation) const { + void instruction_block::display_indented(rel_context & ctx, std::ostream & out, std::string indentation) const { instr_seq_type::const_iterator it = m_data.begin(); instr_seq_type::const_iterator end = m_data.end(); for(; it!=end; ++it) { instruction * i = (*it); - if (i->passes_output_thresholds(ctx) || i->being_recorded()) { + if (i->passes_output_thresholds(ctx.get_context()) || i->being_recorded()) { i->display_indented(ctx, out, indentation); } } diff --git a/src/muz_qe/dl_instruction.h b/src/muz_qe/dl_instruction.h index c44c860a0..89f95c860 100644 --- a/src/muz_qe/dl_instruction.h +++ b/src/muz_qe/dl_instruction.h @@ -58,7 +58,7 @@ namespace datalog { private: typedef u_map reg_annotations; - context & m_datalog_context; + context & m_context; reg_vector m_registers; reg_annotations m_reg_annotation; @@ -73,12 +73,12 @@ namespace datalog { */ bool m_eager_emptiness_checking; public: - execution_context(context & datalog_context); + execution_context(context & context); ~execution_context(); void reset(); - context & get_datalog_context() { return m_datalog_context; }; + rel_context & get_rel_context() { return m_context.get_rel_context(); }; void set_timelimit(unsigned time_in_ms); void reset_timelimit(); @@ -208,7 +208,7 @@ namespace datalog { The newline character at the end should not be printed. */ - virtual void display_head_impl(context & ctx, std::ostream & out) const { + virtual void display_head_impl(rel_context & ctx, std::ostream & out) const { out << ""; } /** @@ -216,7 +216,7 @@ namespace datalog { Each line must be prepended by \c indentation and ended by a newline character. */ - virtual void display_body_impl(context & ctx, std::ostream & out, std::string indentation) const {} + virtual void display_body_impl(rel_context & ctx, std::ostream & out, std::string indentation) const {} public: typedef execution_context::reg_type reg_type; typedef execution_context::reg_idx reg_idx; @@ -227,10 +227,10 @@ namespace datalog { virtual void make_annotations(execution_context & ctx) = 0; - void display(context & ctx, std::ostream & out) const { + void display(rel_context & ctx, std::ostream & out) const { display_indented(ctx, out, ""); } - void display_indented(context & ctx, std::ostream & out, std::string indentation) const; + void display_indented(rel_context & ctx, std::ostream & out, std::string indentation) const; static instruction * mk_load(ast_manager & m, func_decl * pred, reg_idx tgt); /** @@ -329,10 +329,10 @@ namespace datalog { void make_annotations(execution_context & ctx); - void display(context & ctx, std::ostream & out) const { + void display(rel_context & ctx, std::ostream & out) const { display_indented(ctx, out, ""); } - void display_indented(context & ctx, std::ostream & out, std::string indentation) const; + void display_indented(rel_context & ctx, std::ostream & out, std::string indentation) const; }; diff --git a/src/muz_qe/dl_mk_array_blast.cpp b/src/muz_qe/dl_mk_array_blast.cpp new file mode 100644 index 000000000..a5259ba8a --- /dev/null +++ b/src/muz_qe/dl_mk_array_blast.cpp @@ -0,0 +1,147 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + dl_mk_array_blast.cpp + +Abstract: + + Remove array stores from rules. + +Author: + + Nikolaj Bjorner (nbjorner) 2012-11-23 + +Revision History: + +--*/ + +#include "dl_mk_array_blast.h" +#include "expr_replacer.h" + +namespace datalog { + + + mk_array_blast::mk_array_blast(context & ctx, unsigned priority) : + rule_transformer::plugin(priority, false), + m_ctx(ctx), + m(ctx.get_manager()), + a(m), + rm(ctx.get_rule_manager()), + m_rewriter(m, m_params){ + m_params.set_bool("expand_select_store",true); + m_rewriter.updt_params(m_params); + } + + mk_array_blast::~mk_array_blast() { + } + + bool mk_array_blast::is_store_def(expr* e, expr*& x, expr*& y) { + if (m.is_iff(e, x, y) || m.is_eq(e, x, y)) { + if (!a.is_store(y)) { + std::swap(x,y); + } + if (is_var(x) && a.is_store(y)) { + return true; + } + } + return false; + } + + bool mk_array_blast::blast(rule& r, rule_set& rules) { + unsigned utsz = r.get_uninterpreted_tail_size(); + unsigned tsz = r.get_tail_size(); + expr_ref_vector conjs(m), new_conjs(m); + expr_ref tmp(m); + expr_substitution sub(m); + uint_set lhs_vars, rhs_vars; + bool change = false; + + for (unsigned i = 0; i < utsz; ++i) { + new_conjs.push_back(r.get_tail(i)); + } + for (unsigned i = utsz; i < tsz; ++i) { + conjs.push_back(r.get_tail(i)); + } + flatten_and(conjs); + for (unsigned i = 0; i < conjs.size(); ++i) { + expr* x, *y, *e = conjs[i].get(); + + if (is_store_def(e, x, y)) { + // enforce topological order consistency: + uint_set lhs; + collect_vars(m, x, lhs_vars); + collect_vars(m, y, rhs_vars); + lhs = lhs_vars; + lhs &= rhs_vars; + if (!lhs.empty()) { + TRACE("dl", tout << "unusable equality " << mk_pp(e, m) << "\n";); + new_conjs.push_back(e); + } + else { + sub.insert(x, y); + } + } + else { + m_rewriter(e, tmp); + change = change || (tmp != e); + new_conjs.push_back(tmp); + } + } + if (sub.empty() && !change) { + rules.add_rule(&r); + return false; + } + + rule_ref_vector new_rules(rm); + expr_ref fml1(m), fml2(m), body(m), head(m); + r.to_formula(fml1); + body = m.mk_and(new_conjs.size(), new_conjs.c_ptr()); + head = r.get_head(); + scoped_ptr replace = mk_default_expr_replacer(m); + replace->set_substitution(&sub); + (*replace)(body); + m_rewriter(body); + (*replace)(head); + m_rewriter(head); + fml2 = m.mk_implies(body, head); + rm.mk_rule(fml2, new_rules, r.name()); + SASSERT(new_rules.size() == 1); + + TRACE("dl", tout << "new body " << mk_pp(fml2, m) << "\n";); + + rules.add_rule(new_rules[0].get()); + if (m_pc) { + new_rules[0]->to_formula(fml2); + m_pc->insert(fml1, fml2); + } + return true; + } + + rule_set * mk_array_blast::operator()(rule_set const & source, model_converter_ref& mc, proof_converter_ref& pc) { + ref epc; + if (pc) { + epc = alloc(equiv_proof_converter, m); + } + m_pc = epc.get(); + + rule_set* rules = alloc(rule_set, m_ctx); + rule_set::iterator it = source.begin(), end = source.end(); + bool change = false; + for (; it != end; ++it) { + change = blast(**it, *rules) || change; + } + if (!change) { + dealloc(rules); + rules = 0; + } + if (pc) { + pc = concat(pc.get(), epc.get()); + } + return rules; + } + +}; + + diff --git a/src/muz_qe/dl_mk_array_blast.h b/src/muz_qe/dl_mk_array_blast.h new file mode 100644 index 000000000..858b9c778 --- /dev/null +++ b/src/muz_qe/dl_mk_array_blast.h @@ -0,0 +1,61 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + dl_mk_array_blast.h + +Abstract: + + Remove array variables from rules. + +Author: + + Nikolaj Bjorner (nbjorner) 2012-11-23 + +Revision History: + +--*/ +#ifndef _DL_MK_ARRAY_BLAST_H_ +#define _DL_MK_ARRAY_BLAST_H_ + +#include"dl_context.h" +#include"dl_rule_set.h" +#include"dl_rule_transformer.h" +#include "equiv_proof_converter.h" +#include "array_decl_plugin.h" + +namespace datalog { + + /** + \brief Blast occurrences of arrays in rules + */ + class mk_array_blast : public rule_transformer::plugin { + context& m_ctx; + ast_manager& m; + array_util a; + rule_manager& rm; + params_ref m_params; + th_rewriter m_rewriter; + equiv_proof_converter* m_pc; + + bool blast(rule& r, rule_set& new_rules); + + bool is_store_def(expr* e, expr*& x, expr*& y); + + public: + /** + \brief Create rule transformer that extracts universal quantifiers (over recursive predicates). + */ + mk_array_blast(context & ctx, unsigned priority); + + virtual ~mk_array_blast(); + + rule_set * operator()(rule_set const & source, model_converter_ref& mc, proof_converter_ref& pc); + + }; + +}; + +#endif /* _DL_MK_ARRAY_BLAST_H_ */ + diff --git a/src/muz_qe/dl_mk_bit_blast.cpp b/src/muz_qe/dl_mk_bit_blast.cpp index 9c503360c..1fa93a0ca 100644 --- a/src/muz_qe/dl_mk_bit_blast.cpp +++ b/src/muz_qe/dl_mk_bit_blast.cpp @@ -161,18 +161,18 @@ namespace datalog { impl(context& ctx): m_context(ctx), m(ctx.get_manager()), - m_params(ctx.get_params()), + m_params(ctx.get_params().p), m_rules(ctx.get_rule_manager()), m_blaster(ctx.get_manager(), m_params), m_rewriter(ctx.get_manager(), ctx, m_rules) { - m_params.set_bool(":blast-full", true); - m_params.set_bool(":blast-quant", true); + m_params.set_bool("blast_full", true); + m_params.set_bool("blast_quant", true); m_blaster.updt_params(m_params); } rule_set * operator()(rule_set const & source, model_converter_ref& mc, proof_converter_ref& pc) { // TODO mc, pc - if (!m_context.get_params().get_bool(":bit-blast", false)) { + if (!m_context.get_params().bit_blast()) { return 0; } if (m_context.get_engine() != PDR_ENGINE) { diff --git a/src/muz_qe/dl_mk_explanations.cpp b/src/muz_qe/dl_mk_explanations.cpp index 425d3fb60..b4683bdbe 100644 --- a/src/muz_qe/dl_mk_explanations.cpp +++ b/src/muz_qe/dl_mk_explanations.cpp @@ -607,7 +607,7 @@ namespace datalog { m_e_sort = m_decl_util.mk_rule_sort(); m_pinned.push_back(m_e_sort); - relation_manager & rmgr = ctx.get_rmanager(); + relation_manager & rmgr = ctx.get_rel_context().get_rmanager(); symbol er_symbol = explanation_relation_plugin::get_name(relation_level); m_er_plugin = static_cast(rmgr.get_relation_plugin(er_symbol)); if(!m_er_plugin) { @@ -640,7 +640,7 @@ namespace datalog { void mk_explanations::assign_rel_level_kind(func_decl * e_decl, func_decl * orig) { SASSERT(m_relation_level); - relation_manager & rmgr = m_context.get_rmanager(); + relation_manager & rmgr = m_context.get_rel_context().get_rmanager(); unsigned sz = e_decl->get_arity(); relation_signature sig; rmgr.from_predicate(e_decl, sig); @@ -884,7 +884,7 @@ namespace datalog { m_context.collect_predicates(m_original_preds); rule_set * res = alloc(rule_set, m_context); - transform_facts(m_context.get_rmanager()); + transform_facts(m_context.get_rel_context().get_rmanager()); transform_rules(source, *res); return res; } diff --git a/src/muz_qe/dl_mk_extract_quantifiers.cpp b/src/muz_qe/dl_mk_extract_quantifiers.cpp index 614e9dbc8..d2b4f0cec 100644 --- a/src/muz_qe/dl_mk_extract_quantifiers.cpp +++ b/src/muz_qe/dl_mk_extract_quantifiers.cpp @@ -38,31 +38,81 @@ namespace datalog { m_refs.reset(); } + app_ref mk_extract_quantifiers::ensure_app(expr* e) { + if (is_app(e)) { + return app_ref(to_app(e), m); + } + else { + return app_ref(m.mk_eq(e, m.mk_true()), m); + } + } + + void mk_extract_quantifiers::ensure_predicate(expr* e, unsigned& max_var, app_ref_vector& tail) { + SASSERT(is_app(e)); + SASSERT(to_app(e)->get_decl()->get_family_id() == null_family_id); + app* a = to_app(e); + expr_ref_vector args(m); + for (unsigned i = 0; i < a->get_num_args(); ++i) { + expr* arg = a->get_arg(i); + if (is_var(arg) || m.is_value(arg)) { + args.push_back(arg); + } + else { + expr_ref new_var(m); + new_var = m.mk_var(++max_var, m.get_sort(arg)); + args.push_back(new_var); + tail.push_back(m.mk_eq(new_var, arg)); + } + } + tail.push_back(m.mk_app(a->get_decl(), args.size(), args.c_ptr())); + } + void mk_extract_quantifiers::extract(rule& r, rule_set& new_rules) { app_ref_vector tail(m); - svector neg_tail; quantifier_ref_vector quantifiers(m); unsigned utsz = r.get_uninterpreted_tail_size(); unsigned tsz = r.get_tail_size(); + var_counter vc(true); + unsigned max_var = vc.get_max_var(r); for (unsigned i = 0; i < utsz; ++i) { tail.push_back(r.get_tail(i)); - neg_tail.push_back(r.is_neg_tail(i)); + if (r.is_neg_tail(i)) { + new_rules.add_rule(&r); + return; + } } + var_subst vs(m, true); for (unsigned i = utsz; i < tsz; ++i) { - SASSERT(!r.is_neg_tail(i)); app* t = r.get_tail(i); expr_ref_vector conjs(m); datalog::flatten_and(t, conjs); + expr_ref qe(m); + quantifier* q = 0; for (unsigned j = 0; j < conjs.size(); ++j) { expr* e = conjs[j].get(); - quantifier* q = 0; if (rule_manager::is_forall(m, e, q)) { quantifiers.push_back(q); + expr_ref_vector sub(m); + ptr_vector fv; + unsigned num_decls = q->get_num_decls(); + get_free_vars(q, fv); + for (unsigned k = 0; k < fv.size(); ++k) { + unsigned idx = fv.size()-k-1; + if (!fv[idx]) { + fv[idx] = m.mk_bool_sort(); + } + sub.push_back(m.mk_var(idx, fv[idx])); + } + for (unsigned k = 0; k < num_decls; ++k) { + sub.push_back(m.mk_var(num_decls+max_var-k, q->get_decl_sort(k))); + } + max_var += num_decls; + vs(q->get_expr(), sub.size(), sub.c_ptr(), qe); + ensure_predicate(qe, max_var, tail); } else { - tail.push_back(is_app(e)?to_app(e):m.mk_eq(e, m.mk_true())); - neg_tail.push_back(false); + tail.push_back(ensure_app(e)); } } } @@ -70,11 +120,17 @@ namespace datalog { new_rules.add_rule(&r); } else { - rule* new_rule = rm.mk(r.get_head(), tail.size(), tail.c_ptr(), neg_tail.c_ptr(), r.name(), false); - new_rules.add_rule(new_rule); + rule_ref new_rule(rm); + TRACE("dl", + tout << mk_pp(r.get_head(), m) << " :- \n"; + for (unsigned i = 0; i < tail.size(); ++i) { + tout << " " << mk_pp(tail[i].get(), m) << "\n"; + }); + new_rule = rm.mk(r.get_head(), tail.size(), tail.c_ptr(), 0, r.name(), false); quantifier_ref_vector* qs = alloc(quantifier_ref_vector, quantifiers); - m_quantifiers.insert(new_rule, qs); m_refs.push_back(qs); + new_rules.add_rule(new_rule); + m_quantifiers.insert(new_rule, qs); } } diff --git a/src/muz_qe/dl_mk_extract_quantifiers.h b/src/muz_qe/dl_mk_extract_quantifiers.h index 512e386cd..5da5d59d7 100644 --- a/src/muz_qe/dl_mk_extract_quantifiers.h +++ b/src/muz_qe/dl_mk_extract_quantifiers.h @@ -37,6 +37,8 @@ namespace datalog { void extract(rule& r, rule_set& new_rules); + app_ref ensure_app(expr* e); + public: /** \brief Create rule transformer that extracts universal quantifiers (over recursive predicates). @@ -51,6 +53,8 @@ namespace datalog { bool has_quantifiers() const { return !m_quantifiers.empty(); } + void ensure_predicate(expr* e, unsigned& max_var, app_ref_vector& tail); + }; }; diff --git a/src/muz_qe/dl_mk_interp_tail_simplifier.cpp b/src/muz_qe/dl_mk_interp_tail_simplifier.cpp index 74ab001b4..9861c48ca 100644 --- a/src/muz_qe/dl_mk_interp_tail_simplifier.cpp +++ b/src/muz_qe/dl_mk_interp_tail_simplifier.cpp @@ -461,6 +461,11 @@ namespace datalog { { rule_ref r(r0, m_context.get_rule_manager()); + if (r->has_quantifiers()) { + res = r; + return true; + } + start: unsigned u_len = r->get_uninterpreted_tail_size(); unsigned len = r->get_tail_size(); diff --git a/src/muz_qe/dl_mk_magic_sets.cpp b/src/muz_qe/dl_mk_magic_sets.cpp index 668cbf939..373a90969 100644 --- a/src/muz_qe/dl_mk_magic_sets.cpp +++ b/src/muz_qe/dl_mk_magic_sets.cpp @@ -365,7 +365,7 @@ namespace datalog { rule * r = *it; transform_rule(task.m_adornment, r); } - if(!m_context.get_relation(task.m_pred).empty()) { + if(!m_context.get_rel_context().get_relation(task.m_pred).empty()) { //we need a rule to copy facts that are already in a relation into the adorned //relation (since out intentional predicates can have facts, not only rules) create_transfer_rule(task); diff --git a/src/muz_qe/dl_mk_partial_equiv.cpp b/src/muz_qe/dl_mk_partial_equiv.cpp index 68f333b1b..367a15743 100644 --- a/src/muz_qe/dl_mk_partial_equiv.cpp +++ b/src/muz_qe/dl_mk_partial_equiv.cpp @@ -97,7 +97,7 @@ namespace datalog { return 0; } - relation_manager & rm = m_context.get_rmanager(); + relation_manager & rm = m_context.get_rel_context().get_rmanager(); rule_set::decl2rules::iterator it = source.begin_grouped_rules(); rule_set::decl2rules::iterator end = source.end_grouped_rules(); diff --git a/src/muz_qe/dl_mk_rule_inliner.cpp b/src/muz_qe/dl_mk_rule_inliner.cpp index 1d3d62020..fa532ee6c 100644 --- a/src/muz_qe/dl_mk_rule_inliner.cpp +++ b/src/muz_qe/dl_mk_rule_inliner.cpp @@ -205,7 +205,7 @@ namespace datalog { void mk_rule_inliner::count_pred_occurrences(rule_set const & orig) { - m_context.get_rmanager().collect_non_empty_predicates(m_preds_with_facts); + m_context.get_rel_context().get_rmanager().collect_non_empty_predicates(m_preds_with_facts); rule_set::iterator rend = orig.end(); for (rule_set::iterator rit = orig.begin(); rit!=rend; ++rit) { @@ -750,8 +750,7 @@ namespace datalog { valid.reset(); valid.resize(sz, true); - params_ref const& params = m_context.get_params(); - bool allow_branching = params.get_bool(":inline-linear-branch", false); + bool allow_branching = m_context.get_params().inline_linear_branch(); for (unsigned i = 0; i < sz; ++i) { @@ -842,7 +841,6 @@ namespace datalog { bool something_done = false; ref hsmc; ref hpc; - params_ref const& params = m_context.get_params(); if (source.get_num_rules() == 0) { return 0; @@ -867,7 +865,7 @@ namespace datalog { scoped_ptr res = alloc(rule_set, m_context); - if (params.get_bool(":inline-eager", true)) { + if (m_context.get_params().inline_eager()) { TRACE("dl", source.display(tout << "before eager inlining\n");); plan_inlining(source); something_done = transform_rules(source, *res); @@ -879,7 +877,7 @@ namespace datalog { TRACE("dl", res->display(tout << "after eager inlining\n");); } - if (params.get_bool(":inline-linear", true) && inline_linear(res)) { + if (m_context.get_params().inline_linear() && inline_linear(res)) { something_done = true; } diff --git a/src/muz_qe/dl_mk_similarity_compressor.cpp b/src/muz_qe/dl_mk_similarity_compressor.cpp index 8225aa315..42a5ba367 100644 --- a/src/muz_qe/dl_mk_similarity_compressor.cpp +++ b/src/muz_qe/dl_mk_similarity_compressor.cpp @@ -361,7 +361,7 @@ namespace datalog { collect_orphan_consts(*it, const_infos, val_fact); m_context.add_fact(aux_pred, val_fact); } - m_context.get_rmanager().mark_saturated(aux_pred); + m_context.get_rel_context().get_rmanager().mark_saturated(aux_pred); app * new_head = r->get_head(); ptr_vector new_tail; diff --git a/src/muz_qe/dl_mk_simple_joins.cpp b/src/muz_qe/dl_mk_simple_joins.cpp index da1f80a53..363a4f0f7 100644 --- a/src/muz_qe/dl_mk_simple_joins.cpp +++ b/src/muz_qe/dl_mk_simple_joins.cpp @@ -569,10 +569,11 @@ namespace datalog { cost estimate_size(app * t) const { func_decl * pred = t->get_decl(); unsigned n=pred->get_arity(); - if( (m_context.saturation_was_run() && m_context.get_rmanager().try_get_relation(pred)) - || m_context.get_rmanager().is_saturated(pred)) { - SASSERT(m_context.get_rmanager().try_get_relation(pred)); //if it is saturated, it should exist - unsigned rel_size_int = m_context.get_relation(pred).get_size_estimate_rows(); + relation_manager& rm = m_context.get_rel_context().get_rmanager(); + if( (m_context.saturation_was_run() && rm.try_get_relation(pred)) + || rm.is_saturated(pred)) { + SASSERT(rm.try_get_relation(pred)); //if it is saturated, it should exist + unsigned rel_size_int = m_context.get_rel_context().get_relation(pred).get_size_estimate_rows(); if(rel_size_int!=0) { cost rel_size = static_cast(rel_size_int); cost curr_size = rel_size; diff --git a/src/muz_qe/dl_mk_subsumption_checker.cpp b/src/muz_qe/dl_mk_subsumption_checker.cpp index d20ad5055..19c28c036 100644 --- a/src/muz_qe/dl_mk_subsumption_checker.cpp +++ b/src/muz_qe/dl_mk_subsumption_checker.cpp @@ -250,7 +250,7 @@ namespace datalog { } void mk_subsumption_checker::scan_for_relations_total_due_to_facts() { - relation_manager& rm = m_context.get_rmanager(); + relation_manager& rm = m_context.get_rel_context().get_rmanager(); decl_set candidate_preds; m_context.collect_predicates(candidate_preds); diff --git a/src/muz_qe/dl_mk_unbound_compressor.cpp b/src/muz_qe/dl_mk_unbound_compressor.cpp index 000a70b22..e3db82759 100644 --- a/src/muz_qe/dl_mk_unbound_compressor.cpp +++ b/src/muz_qe/dl_mk_unbound_compressor.cpp @@ -337,7 +337,7 @@ namespace datalog { // TODO mc, pc m_modified = false; - m_context.get_rmanager().collect_non_empty_predicates(m_non_empty_rels); + m_context.get_rel_context().get_rmanager().collect_non_empty_predicates(m_non_empty_rels); unsigned init_rule_cnt = source.get_num_rules(); SASSERT(m_rules.empty()); diff --git a/src/muz_qe/dl_rule.cpp b/src/muz_qe/dl_rule.cpp index 9b0af2554..dedd37a78 100644 --- a/src/muz_qe/dl_rule.cpp +++ b/src/muz_qe/dl_rule.cpp @@ -1014,7 +1014,7 @@ namespace datalog { out << '.'; if (ctx.output_profile()) { out << " {"; - output_profile(ctx, out); + output_profile(out); out << '}'; } out << '\n'; diff --git a/src/muz_qe/dl_smt_relation.cpp b/src/muz_qe/dl_smt_relation.cpp deleted file mode 100644 index 55d3f7199..000000000 --- a/src/muz_qe/dl_smt_relation.cpp +++ /dev/null @@ -1,766 +0,0 @@ -/*++ -Copyright (c) 2010 Microsoft Corporation - -Module Name: - - dl_smt_relation.cpp - -Abstract: - - Relation based on SMT signature. - - -Author: - - Nikolaj Bjorner (nbjorner) 2010-10-10 - -Revision History: - ---*/ -#include -#include "debug.h" -#include "ast_pp.h" -#include "dl_context.h" -#include "dl_smt_relation.h" -#include "expr_abstract.h" -#include "smt_kernel.h" -#include "th_rewriter.h" -#include "qe.h" -#include "datatype_decl_plugin.h" -#include "bv_decl_plugin.h" -#include "ast_ll_pp.h" -#include "expr_context_simplifier.h" -#include "has_free_vars.h" -#include "ast_smt_pp.h" - -namespace datalog { - - - smt_relation::smt_relation(smt_relation_plugin & p, const relation_signature & s, expr* r) - : relation_base(p, s), - m_rel(r, p.get_ast_manager()), - m_bound_vars(p.get_ast_manager()) - { - ast_manager& m = p.get_ast_manager(); - for (unsigned i = 0; m_bound_vars.size() < s.size(); ++i) { - unsigned j = s.size() - i - 1; - m_bound_vars.push_back(m.mk_const(symbol(j), s[j])); - } - SASSERT(is_well_formed()); - } - - smt_relation::~smt_relation() { - } - - bool smt_relation::is_well_formed() const { - ast_manager& m = get_manager(); - ptr_vector bound_sorts; - for (unsigned i = 0; i < m_bound_vars.size(); ++i) { - bound_sorts.push_back(m.get_sort(m_bound_vars[i])); - } - return is_well_formed_vars(bound_sorts, get_relation()); - } - - void smt_relation::instantiate(expr* r, expr_ref& result) const { - ast_manager& m = get_manager(); - var_subst subst(m); - ptr_vector bound_sorts; - for (unsigned i = 0; i < m_bound_vars.size(); ++i) { - bound_sorts.push_back(m.get_sort(m_bound_vars[i])); - } - TRACE("smt_relation", - tout << mk_ll_pp(r, m) << "\n"; - for (unsigned i = 0; i < bound_sorts.size(); ++i) { - tout << mk_pp(bound_sorts[i], m) << " "; - } - tout << "\n"; - ); - SASSERT(is_well_formed_vars(bound_sorts, r)); - - subst(r, m_bound_vars.size(), m_bound_vars.c_ptr(), result); - } - - void smt_relation::mk_abstract(expr* r, expr_ref& result) const { - ast_manager& m = get_manager(); - TRACE("smt_relation", tout << mk_ll_pp(r, m) << "\n";); - expr_abstract(m, 0, m_bound_vars.size(), m_bound_vars.c_ptr(), r, result); - TRACE("smt_relation", tout << mk_ll_pp(result, m) << "\n";); - ptr_vector bound_sorts; - for (unsigned i = 0; i < m_bound_vars.size(); ++i) { - bound_sorts.push_back(m.get_sort(m_bound_vars[i])); - } - SASSERT(is_well_formed_vars(bound_sorts, r)); - } - - void smt_relation::set_relation(expr* r) { - m_rel = r; - is_well_formed(); - } - - void smt_relation::add_relation(expr* s) { - ast_manager& m = get_manager(); - m_rel = m.mk_or(m_rel, s); - is_well_formed(); - } - - void smt_relation::filter_relation(expr* s) { - ast_manager& m = get_manager(); - m_rel = m.mk_and(m_rel, s); - is_well_formed(); - } - - expr* smt_relation::get_relation() const { - return m_rel.get(); - } - - void smt_relation::simplify(expr_ref& fml) const { - th_rewriter rw(get_manager()); - rw(fml); - } - - bool smt_relation::empty() const { - ast_manager& m = get_manager(); - expr* r = get_relation(); - if (m.is_true(r)) { - return false; - } - if (m.is_false(r)) { - return true; - } - IF_VERBOSE(10, verbose_stream() << "Checking emptiness...\n"; ); - - front_end_params& params = get_plugin().get_fparams(); - // [Leo]: asserted_formulas do not have support for der. - // We should use the tactics der. - // flet flet2(params.m_der, true); - smt::kernel ctx(m, params); - expr_ref tmp(m); - instantiate(r, tmp); - ctx.assert_expr(tmp); - if (get_plugin().get_fparams().m_dump_goal_as_smt) { - static unsigned n = 0; - std::ostringstream strm; - strm << "File" << n << ".smt2"; - std::ofstream out(strm.str().c_str()); - ast_smt_pp pp(m); - pp.display_smt2(out, tmp); - ++n; - } - return l_false == ctx.check(); - } - - void smt_relation::add_fact(const relation_fact & f) { - SASSERT(f.size() == size()); - ast_manager& m = get_manager(); - expr_ref_vector eqs(m); - for (unsigned i = 0; i < f.size(); ++i) { - eqs.push_back(m.mk_eq(m.mk_var(i,m.get_sort(f[i])), f[i])); - } - expr_ref e1(m.mk_and(eqs.size(), eqs.c_ptr()), m); - add_relation(e1); - } - - - bool smt_relation::contains_fact(const relation_fact & f) const { - ast_manager& m = get_manager(); - expr_ref_vector eqs(m); - expr_ref cond(m); - for (unsigned i = 0; i < f.size(); ++i) { - eqs.push_back(m.mk_eq(m.mk_var(i,m.get_sort(f[i])), f[i])); - } - cond = m.mk_and(eqs.size(), eqs.c_ptr()); - return const_cast(this)->contains(cond); - } - - // - // facts in Rel iff - // facts => Rel iff - // facts & not Rel is unsat - // - bool smt_relation::contains(expr* facts) { - ast_manager& m = get_manager(); - expr_ref fml_free(m), fml_inst(m); - fml_free = m.mk_and(facts, m.mk_not(get_relation())); - instantiate(fml_free, fml_inst); - front_end_params& params = get_plugin().get_fparams(); - // [Leo]: asserted_formulas do not have support for qe nor der. - // We should use the tactics qe and der. - // BTW, qe at asserted_formulas was disabled when we moved to codeplex, but the field m_quant_elim was not deleted. - // - // flet flet0(params.m_quant_elim, true); - flet flet1(params.m_nnf_cnf, false); - // flet flet2(params.m_der, true); - smt::kernel ctx(m, params); - ctx.assert_expr(fml_inst); - lbool result = ctx.check(); - TRACE("smt_relation", - display(tout); - tout << mk_pp(facts, m) << "\n"; - tout << ((result == l_false)?"true":"false") << "\n";); - return result == l_false; - } - - smt_relation * smt_relation::clone() const { - return alloc(smt_relation, get_plugin(), get_signature(), get_relation()); - } - - smt_relation * smt_relation::complement(func_decl* p) const { - ast_manager& m = get_manager(); - smt_relation* result = alloc(smt_relation, get_plugin(), get_signature(), m.mk_not(get_relation())); - TRACE("smt_relation", - display(tout<<"src:\n"); - result->display(tout<<"complement:\n");); - return result; - } - - void smt_relation::display(std::ostream & out) const { - if (is_finite_domain()) { - display_finite(out); - } - else { - out << mk_ll_pp(get_relation(), get_manager()) << "\n"; - } - } - - smt_relation_plugin & smt_relation::get_plugin() const { - return static_cast(relation_base::get_plugin()); - } - - bool smt_relation::is_finite_domain() const { - relation_signature const& sig = get_signature(); - for (unsigned i = 0; i < sig.size(); ++i) { - if (!get_plugin().is_finite_domain(sig[i])) { - return false; - } - } - return true; - } - - - void smt_relation::display_finite(std::ostream & out) const { - ast_manager& m = get_manager(); - front_end_params& params = get_plugin().get_fparams(); - expr* r = get_relation(); - expr_ref tmp(m); - expr_ref_vector values(m), eqs(m); - unsigned num_vars = m_bound_vars.size(); - values.resize(num_vars); - eqs.resize(num_vars); - instantiate(r, tmp); - flet flet4(params.m_model, true); - smt::kernel ctx(m, params); - ctx.assert_expr(tmp); - - while (true) { - lbool is_sat = ctx.check(); - if (is_sat == l_false) { - break; - } - model_ref mod; - ctx.get_model(mod); - for (unsigned i = 0; i < num_vars; ++i) { - mod->eval(m_bound_vars[i], tmp, true); - values[i] = tmp; - eqs[i] = m.mk_eq(values[i].get(), m_bound_vars[i]); - - } - out << " ("; - for (unsigned i = 0; i < num_vars; ++i) { - unsigned j = num_vars - 1 - i; - out << mk_pp(values[j].get(), m); - if (i + 1 < num_vars) { - out << " "; - } - } - out << ")\n"; - tmp = m.mk_not(m.mk_and(num_vars, eqs.c_ptr())); - ctx.assert_expr(tmp); - } - } - - // ----------------------------------- - // - // smt_relation_plugin - // - // ----------------------------------- - - - smt_relation_plugin::smt_relation_plugin(relation_manager & m) - : relation_plugin(smt_relation_plugin::get_name(), m), m_counter(0) {} - - - relation_base * smt_relation_plugin::mk_empty(const relation_signature & s) { - return alloc(smt_relation, *this, s, get_ast_manager().mk_false()); - } - - - class smt_relation_plugin::join_fn : public convenient_relation_join_fn { - smt_relation_plugin& m_plugin; - expr_ref_vector m_conjs; - public: - join_fn(smt_relation_plugin& p, const relation_signature & o1_sig, const relation_signature & o2_sig, unsigned col_cnt, - const unsigned * cols1, const unsigned * cols2) - : convenient_relation_join_fn(o1_sig, o2_sig, col_cnt, cols1, cols2), - m_plugin(p), - m_conjs(p.get_ast_manager()) { - ast_manager& m = p.get_ast_manager(); - unsigned sz = m_cols1.size(); - for (unsigned i = 0; i < sz; ++i) { - unsigned col1 = m_cols1[i]; - unsigned col2 = m_cols2[i]; - var* v1 = m.mk_var(col1, o1_sig[col1]); - var* v2 = m.mk_var(col2 + o1_sig.size(), o2_sig[col2]); - m_conjs.push_back(m.mk_eq(v1, v2)); - } - } - - virtual relation_base * operator()(const relation_base & r1, const relation_base & r2) { - ast_manager& m = m_plugin.get_ast_manager(); - expr_ref e2(m), res(m); - shift_vars sh(m); - sh(get(r2).get_relation(), r1.get_signature().size(), e2); - m_conjs.push_back(get(r1).get_relation()); - m_conjs.push_back(e2); - res = m.mk_and(m_conjs.size(), m_conjs.c_ptr()); - m_conjs.pop_back(); - m_conjs.pop_back(); - smt_relation* result = alloc(smt_relation, m_plugin, get_result_signature(), res); - TRACE("smt_relation", - get(r1).display(tout << "src1:\n"); - get(r2).display(tout << "src2:\n"); - for (unsigned i = 0; i < m_conjs.size(); ++i) { - tout << m_cols1[i] << " = " << m_cols2[i] << " -- "; - tout << mk_pp(m_conjs[i].get(), m) << "\n"; - } - result->display(tout << "dst:\n"); - ); - return result; - } - }; - - relation_join_fn * smt_relation_plugin::mk_join_fn(const relation_base & r1, const relation_base & r2, - unsigned col_cnt, const unsigned * cols1, const unsigned * cols2) { - if (!check_kind(r1) || !check_kind(r2)) { - return 0; - } - return alloc(join_fn, *this, r1.get_signature(), r2.get_signature(), col_cnt, cols1, cols2); - } - - class smt_relation_plugin::project_fn : public convenient_relation_project_fn { - smt_relation_plugin& m_plugin; - expr_ref_vector m_subst; - sort_ref_vector m_sorts; - svector m_names; - public: - project_fn(smt_relation_plugin& p, - const relation_signature & orig_sig, unsigned removed_col_cnt, const unsigned * removed_cols) - : convenient_relation_project_fn(orig_sig, removed_col_cnt, removed_cols), - m_plugin(p), - m_subst(p.get_ast_manager()), - m_sorts(p.get_ast_manager()) { - ast_manager& m = p.get_ast_manager(); - unsigned_vector const& cols = m_removed_cols; - unsigned num_cols = cols.size(); - - unsigned lo = 0, hi = num_cols; - for (unsigned i = 0, c = 0; i < orig_sig.size(); ++i) { - SASSERT(c <= num_cols); - if (c == num_cols) { - SASSERT(lo == num_cols); - m_subst.push_back(m.mk_var(hi, orig_sig[i])); - ++hi; - continue; - } - SASSERT(c < num_cols); - unsigned col = cols[c]; - SASSERT(i <= col); - if (i == col) { - m_names.push_back(symbol(p.fresh_name())); - m_sorts.push_back(orig_sig[col]); - m_subst.push_back(m.mk_var(lo, orig_sig[i])); - ++lo; - ++c; - continue; - } - m_subst.push_back(m.mk_var(hi, orig_sig[i])); - ++hi; - } - m_subst.reverse(); - m_sorts.reverse(); - m_names.reverse(); - } - - virtual relation_base * operator()(const relation_base & r) { - ast_manager& m = m_plugin.get_ast_manager(); - expr_ref tmp1(m), tmp2(m); - var_subst subst(m); - smt_relation* result = 0; - tmp1 = get(r).get_relation(); - subst(tmp1, m_subst.size(), m_subst.c_ptr(), tmp2); - tmp2 = m.mk_exists(m_sorts.size(), m_sorts.c_ptr(), m_names.c_ptr(), tmp2); - result = alloc(smt_relation, m_plugin, get_result_signature(), tmp2); - TRACE("smt_relation", - tout << "Signature: "; - for (unsigned i = 0; i < r.get_signature().size(); ++i) { - tout << mk_pp(r.get_signature()[i], m) << " "; - } - tout << "Remove: "; - for (unsigned i = 0; i < m_removed_cols.size(); ++i) { - tout << m_removed_cols[i] << " "; - } - tout << "\n"; - tout << "Subst: "; - for (unsigned i = 0; i < m_subst.size(); ++i) { - tout << mk_pp(m_subst[i].get(), m) << " "; - } - tout << "\n"; - get(r).display(tout); - tout << " --> \n"; - result->display(tout);); - return result; - } - }; - - relation_transformer_fn * smt_relation_plugin::mk_project_fn(const relation_base & r, - unsigned col_cnt, const unsigned * removed_cols) { - return alloc(project_fn, *this, r.get_signature(), col_cnt, removed_cols); - } - - - class smt_relation_plugin::rename_fn : public convenient_relation_rename_fn { - smt_relation_plugin& m_plugin; - expr_ref_vector m_subst; - public: - rename_fn(smt_relation_plugin& p, const relation_signature & orig_sig, unsigned cycle_len, const unsigned * cycle) - : convenient_relation_rename_fn(orig_sig, cycle_len, cycle), - m_plugin(p), - m_subst(p.get_ast_manager()) { - - ast_manager& m = p.get_ast_manager(); - for (unsigned i = 0; i < orig_sig.size(); ++i) { - m_subst.push_back(m.mk_var(i, orig_sig[i])); - } - unsigned col1, col2; - for (unsigned i = 0; i +1 < cycle_len; ++i) { - col1 = cycle[i]; - col2 = cycle[i+1]; - m_subst[col2] = m.mk_var(col1, orig_sig[col2]); - } - col1 = cycle[cycle_len-1]; - col2 = cycle[0]; - m_subst[col2] = m.mk_var(col1, orig_sig[col2]); - m_subst.reverse(); - } - - virtual relation_base * operator()(const relation_base & r) { - ast_manager& m = m_plugin.get_ast_manager(); - expr_ref res(m); - var_subst subst(m); - subst(get(r).get_relation(), m_subst.size(), m_subst.c_ptr(), res); - TRACE("smt_relation3", - tout << "cycle: "; - for (unsigned i = 0; i < m_cycle.size(); ++i) { - tout << m_cycle[i] << " "; - } - tout << "\n"; - tout << "old_sig: "; - for (unsigned i = 0; i < r.get_signature().size(); ++i) { - tout << mk_pp(r.get_signature()[i], m) << " "; - } - tout << "\n"; - tout << "new_sig: "; - for (unsigned i = 0; i < get_result_signature().size(); ++i) { - tout << mk_pp(get_result_signature()[i], m) << " "; - } - tout << "\n"; - tout << "subst: "; - for (unsigned i = 0; i < m_subst.size(); ++i) { - tout << mk_pp(m_subst[i].get(), m) << " "; - } - tout << "\n"; - get(r).display(tout << "src:\n"); - tout << "dst:\n" << mk_ll_pp(res, m) << "\n"; - ); - smt_relation* result = alloc(smt_relation, m_plugin, get_result_signature(), res); - - return result; - } - }; - - relation_transformer_fn * smt_relation_plugin::mk_rename_fn(const relation_base & r, - unsigned cycle_len, const unsigned * permutation_cycle) { - if(!check_kind(r)) { - return 0; - } - return alloc(rename_fn, *this, r.get_signature(), cycle_len, permutation_cycle); - } - - - class smt_relation_plugin::union_fn : public relation_union_fn { - smt_relation_plugin& m_plugin; - - public: - union_fn(smt_relation_plugin& p) : - m_plugin(p) { - } - - virtual void operator()(relation_base & r, const relation_base & src, relation_base * delta) { - ast_manager& m = m_plugin.get_ast_manager(); - expr* srcE = get(src).get_relation(); - TRACE("smt_relation", - tout << "dst:\n"; - get(r).display(tout); - tout << "src:\n"; - get(src).display(tout);); - - SASSERT(get(src).is_well_formed()); - SASSERT(get(r).is_well_formed()); - - if (delta) { - // - // delta(a) <- - // exists x . srcE(a, x) & not rE(a, y) - - - expr_ref rInst(m), srcInst(m), tmp(m), tmp1(m); - expr_ref notR(m), srcGround(m); - front_end_params& fparams = get(r).get_plugin().get_fparams(); - params_ref const& params = get(r).get_plugin().get_params(); - - get(r).instantiate(get(r).get_relation(), rInst); - get(src).instantiate(get(src).get_relation(), srcInst); - qe::expr_quant_elim_star1 qe(m, fparams); - - IF_VERBOSE(10, verbose_stream() << "Computing delta...\n"; ); - - if (params.get_bool(":smt-relation-ground-recursive", false)) { - // ensure R is ground. Simplify S using assumption not R - if (!is_ground(rInst)) { - proof_ref pr(m); - qe(rInst, tmp, pr); - rInst = tmp; - get(r).set_relation(rInst); - } - SASSERT(is_ground(rInst)); - notR = m.mk_not(rInst); - qe.reduce_with_assumption(notR, srcInst, tmp); - SASSERT(is_ground(tmp)); - } - else { - // Simplify not R usng assumption Exists x . S. - expr_ref srcGround(srcInst, m); - app_ref_vector srcVars(m); - qe::hoist_exists(srcGround, srcVars); - SASSERT(is_ground(srcGround)); - notR = m.mk_not(rInst); - qe.reduce_with_assumption(srcGround, notR, tmp1); - tmp = m.mk_and(srcInst, tmp1); - SASSERT(!has_free_vars(tmp)); - TRACE("smt_relation", - tout << "elim_exists result:\n" << mk_ll_pp(tmp, m) << "\n";); - } - - SASSERT(!has_free_vars(tmp)); - get(r).simplify(tmp); - - get(src).mk_abstract(tmp, tmp1); - TRACE("smt_relation", tout << "abstracted:\n"; tout << mk_ll_pp(tmp1, m) << "\n";); - get(*delta).set_relation(tmp1); - get(r).add_relation(tmp1); - } - else { - get(r).add_relation(srcE); - } - TRACE("smt_relation", get(r).display(tout << "dst':\n");); - } - }; - - relation_union_fn * smt_relation_plugin::mk_union_fn(const relation_base & tgt, const relation_base & src, - const relation_base * delta) { - if (!check_kind(tgt) || !check_kind(src) || (delta && !check_kind(*delta))) { - return 0; - } - return alloc(union_fn, *this); - } - - relation_union_fn * smt_relation_plugin::mk_widen_fn(const relation_base & tgt, const relation_base & src, - const relation_base * delta) { - if (!check_kind(tgt) || !check_kind(src) || (delta && !check_kind(*delta))) { - return 0; - } - return alloc(union_fn, *this); - } - - class smt_relation_plugin::filter_interpreted_fn : public relation_mutator_fn { - smt_relation_plugin& m_plugin; - app_ref m_condition; - public: - filter_interpreted_fn(smt_relation_plugin& p, app * condition) - : m_plugin(p), - m_condition(condition, p.get_ast_manager()) { - } - - virtual void operator()(relation_base & r) { - SASSERT(m_plugin.check_kind(r)); - get(r).filter_relation(m_condition); - TRACE("smt_relation", - tout << mk_pp(m_condition, m_plugin.get_ast_manager()) << "\n"; - get(r).display(tout); - ); - } - }; - - relation_mutator_fn * smt_relation_plugin::mk_filter_interpreted_fn(const relation_base & r, app * condition) { - if(!check_kind(r)) { - return 0; - } - return alloc(filter_interpreted_fn, *this, condition); - } - - relation_mutator_fn * smt_relation_plugin::mk_filter_equal_fn(const relation_base & r, - const relation_element & value, unsigned col) { - if(!check_kind(r)) { - return 0; - } - ast_manager& m = get_ast_manager(); - app_ref condition(m); - expr_ref var(m.mk_var(col, r.get_signature()[col]), m); - condition = m.mk_eq(var, value); - return mk_filter_interpreted_fn(r, condition); - } - - class smt_relation_plugin::filter_identical_fn : public relation_mutator_fn { - smt_relation_plugin& m_plugin; - expr_ref m_condition; - public: - filter_identical_fn(smt_relation_plugin& p, const relation_signature & sig, unsigned col_cnt, const unsigned * identical_cols) - : m_plugin(p), - m_condition(p.get_ast_manager()) { - if (col_cnt <= 1) { - return; - } - ast_manager& m = p.get_ast_manager(); - unsigned col = identical_cols[0]; - expr_ref v0(m.mk_var(col, sig[col]), m); - expr_ref_vector eqs(m); - for (unsigned i = 1; i < col_cnt; ++i) { - col = identical_cols[i]; - eqs.push_back(m.mk_eq(v0, m.mk_var(col, sig[col]))); - } - m_condition = m.mk_and(eqs.size(), eqs.c_ptr()); - } - - virtual void operator()(relation_base & r) { - get(r).filter_relation(m_condition); - TRACE("smt_relation", - tout << mk_pp(m_condition, m_plugin.get_ast_manager()) << "\n"; - get(r).display(tout); - ); - } - }; - - relation_mutator_fn * smt_relation_plugin::mk_filter_identical_fn(const relation_base & r, - unsigned col_cnt, const unsigned * identical_cols) { - if (!check_kind(r)) { - return 0; - } - return alloc(filter_identical_fn, *this, r.get_signature(), col_cnt, identical_cols); - } - - - class smt_relation_plugin::negation_filter_fn : public convenient_relation_negation_filter_fn { - smt_relation_plugin& m_plugin; - expr_ref_vector m_conjs; - public: - negation_filter_fn(smt_relation_plugin& p, - const relation_base & tgt, const relation_base & neg_t, - unsigned joined_col_cnt, const unsigned * t_cols, const unsigned * negated_cols) : - convenient_negation_filter_fn(tgt, neg_t, joined_col_cnt, t_cols, negated_cols), - m_plugin(p), - m_conjs(p.get_ast_manager()) { - ast_manager& m = p.get_ast_manager(); - unsigned sz = m_cols1.size(); - for (unsigned i = 0; i < sz; ++i) { - unsigned col1 = m_cols1[i]; - unsigned col2 = m_cols2[i]; - var* v1 = m.mk_var(col1, tgt.get_signature()[col1]); - var* v2 = m.mk_var(col2, neg_t.get_signature()[col2]); - m_conjs.push_back(m.mk_eq(v1, v2)); - } - } - - void operator()(relation_base & t, const relation_base & negated_obj) { - // TBD: fixme. - NOT_IMPLEMENTED_YET(); - ast_manager& m = m_plugin.get_ast_manager(); - expr_ref res(m), e2(m); - shift_vars sh(m); - sh(get(negated_obj).get_relation(), t.get_signature().size(), e2); - m_conjs.push_back(get(t).get_relation()); - m_conjs.push_back(m.mk_not(e2)); - res = m.mk_and(m_conjs.size(), m_conjs.c_ptr()); - m_conjs.pop_back(); - m_conjs.pop_back(); - // TBD: free variables in negation? - } - }; - - relation_intersection_filter_fn * smt_relation_plugin::mk_filter_by_negation_fn(const relation_base & t, - const relation_base & negated_obj, unsigned joined_col_cnt, - const unsigned * t_cols, const unsigned * negated_cols) { - if (!check_kind(t) || !check_kind(negated_obj)) { - return 0; - } - return alloc(negation_filter_fn, *this, t, negated_obj, joined_col_cnt, t_cols, negated_cols); - } - - - smt_relation& smt_relation_plugin::get(relation_base& r) { return dynamic_cast(r); } - - smt_relation const & smt_relation_plugin::get(relation_base const& r) { return dynamic_cast(r); } - - bool smt_relation_plugin::can_handle_signature(relation_signature const& sig) { - // TBD: refine according to theories handled by quantifier elimination - return get_manager().is_non_explanation(sig); - } - - // TBD: when relations are finite domain, they also support table iterators. - - symbol smt_relation_plugin::fresh_name() { - return symbol(m_counter++); - } - - front_end_params& smt_relation_plugin::get_fparams() { - return const_cast(get_manager().get_context().get_fparams()); - } - - params_ref const& smt_relation_plugin::get_params() { - return get_manager().get_context().get_params(); - } - - bool smt_relation_plugin::is_finite_domain(sort *s) const { - ast_manager& m = get_ast_manager(); - if (m.is_bool(s)) { - return true; - } - bv_util bv(m); - if (bv.is_bv_sort(s)) { - return true; - } - datatype_util dt(m); - if (dt.is_datatype(s) && !dt.is_recursive(s)) { - ptr_vector const& constrs = *dt.get_datatype_constructors(s); - for (unsigned i = 0; i < constrs.size(); ++i) { - func_decl* f = constrs[i]; - for (unsigned j = 0; j < f->get_arity(); ++j) { - if (!is_finite_domain(f->get_domain(j))) { - return false; - } - } - } - return true; - } - return false; - } -}; - diff --git a/src/muz_qe/dl_smt_relation.h b/src/muz_qe/dl_smt_relation.h deleted file mode 100644 index 99de2ad83..000000000 --- a/src/muz_qe/dl_smt_relation.h +++ /dev/null @@ -1,141 +0,0 @@ -/*++ -Copyright (c) 2010 Microsoft Corporation - -Module Name: - - dl_smt_relation.h - -Abstract: - - Relation signature represented by signatures that have quantifier elimination. - -Author: - - Nikolaj Bjorner (nbjorner) 2010-10-10 - -Revision History: - ---*/ -#ifndef _DL_SMT_RELATION_H_ -#define _DL_SMT_RELATION_H_ - -#include "dl_base.h" -#include "front_end_params.h" -#include "params.h" - -namespace datalog { - - class smt_relation; - - class smt_relation_plugin : public relation_plugin { - - unsigned m_counter; - - friend class smt_relation; - class join_fn; - class project_fn; - class rename_fn; - class union_fn; - class filter_identical_fn; - class filter_interpreted_fn; - class negation_filter_fn; - - public: - smt_relation_plugin(relation_manager & m); - - virtual bool can_handle_signature(const relation_signature & s); - - static symbol get_name() { return symbol("smt_relation"); } - - virtual relation_base * mk_empty(const relation_signature & s); - - virtual relation_join_fn * mk_join_fn(const relation_base & t1, const relation_base & t2, - unsigned col_cnt, const unsigned * cols1, const unsigned * cols2); - virtual relation_transformer_fn * mk_project_fn(const relation_base & t, unsigned col_cnt, - const unsigned * removed_cols); - virtual relation_transformer_fn * mk_rename_fn(const relation_base & t, unsigned permutation_cycle_len, - const unsigned * permutation_cycle); - virtual relation_union_fn * mk_union_fn(const relation_base & tgt, const relation_base & src, - const relation_base * delta); - virtual relation_union_fn * mk_widen_fn(const relation_base & tgt, const relation_base & src, - const relation_base * delta); - virtual relation_mutator_fn * mk_filter_identical_fn(const relation_base & t, unsigned col_cnt, - const unsigned * identical_cols); - virtual relation_mutator_fn * mk_filter_equal_fn(const relation_base & t, const relation_element & value, - unsigned col); - virtual relation_mutator_fn * mk_filter_interpreted_fn(const relation_base & t, app * condition); - virtual relation_intersection_filter_fn * mk_filter_by_negation_fn(const relation_base & t, - const relation_base & negated_obj, unsigned joined_col_cnt, - const unsigned * t_cols, const unsigned * negated_cols); - - symbol fresh_name(); - - front_end_params& get_fparams(); - - params_ref const& get_params(); - - bool is_finite_domain(sort* s) const; - - private: - static smt_relation& get(relation_base& r); - - static smt_relation const & get(relation_base const& r); - }; - - class smt_relation : public relation_base { - friend class smt_relation_plugin; - friend class smt_relation_plugin::join_fn; - friend class smt_relation_plugin::project_fn; - friend class smt_relation_plugin::rename_fn; - friend class smt_relation_plugin::union_fn; - friend class smt_relation_plugin::filter_identical_fn; - friend class smt_relation_plugin::filter_interpreted_fn; - friend class smt_relation_plugin::negation_filter_fn; - - expr_ref m_rel; // relation. - expr_ref_vector m_bound_vars; - - unsigned size() const { return get_signature().size(); } - - ast_manager& get_manager() const { return get_plugin().get_ast_manager(); } - - smt_relation(smt_relation_plugin & p, const relation_signature & s, expr* r); - - virtual ~smt_relation(); - - void instantiate(expr* e, expr_ref& result) const; - - void mk_abstract(expr* e, expr_ref& result) const; - - bool contains(expr* facts); - - bool is_finite_domain() const; - - bool is_well_formed() const; - - void display_finite(std::ostream & out) const; - - void simplify(expr_ref& e) const; - - public: - - virtual bool empty() const; - - virtual void add_fact(const relation_fact & f); - - virtual bool contains_fact(const relation_fact & f) const; - virtual smt_relation * clone() const; - virtual smt_relation * complement(func_decl*) const; - virtual void display(std::ostream & out) const; - virtual void to_formula(expr_ref& fml) const { fml = get_relation(); simplify(fml); } - - expr* get_relation() const; - void set_relation(expr* r); - void add_relation(expr* s); // add s to relation. - void filter_relation(expr* s); // restrict relation with s - smt_relation_plugin& get_plugin() const; - - }; -}; - -#endif diff --git a/src/muz_qe/dl_util.h b/src/muz_qe/dl_util.h index 1685bec9c..d9e437ccc 100644 --- a/src/muz_qe/dl_util.h +++ b/src/muz_qe/dl_util.h @@ -26,6 +26,7 @@ Revision History: #include"horn_subsume_model_converter.h" #include"replace_proof_converter.h" #include"substitution.h" +#include"fixedpoint_params.hpp" namespace datalog { @@ -191,11 +192,22 @@ namespace datalog { scoped_coarse_proof(ast_manager& m): scoped_proof_mode(m, PGM_COARSE) {} }; + class scoped_fine_proof : public scoped_proof_mode { + public: + scoped_fine_proof(ast_manager& m): scoped_proof_mode(m, PGM_FINE) {} + }; + class scoped_no_proof : public scoped_proof_mode { public: scoped_no_proof(ast_manager& m): scoped_proof_mode(m, PGM_DISABLED) {} }; + class scoped_restore_proof : public scoped_proof_mode { + public: + scoped_restore_proof(ast_manager& m): scoped_proof_mode(m, m.proof_mode()) {} + }; + + class variable_intersection diff --git a/src/muz_qe/equiv_proof_converter.cpp b/src/muz_qe/equiv_proof_converter.cpp new file mode 100644 index 000000000..8b821227b --- /dev/null +++ b/src/muz_qe/equiv_proof_converter.cpp @@ -0,0 +1,33 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + equiv_proof_converter.cpp + +Abstract: + + Proof converter that applies equivalence rule to leaves. + +Author: + + Nikolaj Bjorner (nbjorner) 2012-11-23 + +Revision History: + +--*/ + +#include "equiv_proof_converter.h" +#include "ast_pp.h" +#include "dl_util.h" + +void equiv_proof_converter::insert(expr* fml1, expr* fml2) { + datalog::scoped_fine_proof _sp(m); + proof_ref p1(m), p2(m), p3(m); + p1 = m.mk_asserted(fml1); + p2 = m.mk_rewrite(fml1, fml2); + p3 = m.mk_modus_ponens(p1, p2); + TRACE("proof_converter", tout << mk_pp(p3.get(), m) << "\n";); + SASSERT(m.has_fact(p3)); + m_replace.insert(p3); +} diff --git a/src/muz_qe/equiv_proof_converter.h b/src/muz_qe/equiv_proof_converter.h new file mode 100644 index 000000000..01dd0a238 --- /dev/null +++ b/src/muz_qe/equiv_proof_converter.h @@ -0,0 +1,52 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + equiv_proof_converter.h + +Abstract: + + Proof converter that applies equivalence rule to leaves. + + Given a proof P with occurrences of [asserted fml] + replace [asserted fml] by a proof of the form + [mp [asserted fml'] [~ fml fml']] + +Author: + + Nikolaj Bjorner (nbjorner) 2012-11-23 + +Revision History: + +--*/ + +#ifndef _EQUIV_PROOF_CONVERTER_H_ +#define _EQUIV_PROOF_CONVERTER_H_ + +#include "replace_proof_converter.h" + +class equiv_proof_converter : public proof_converter { + ast_manager& m; + replace_proof_converter m_replace; +public: + + equiv_proof_converter(ast_manager& m): m(m), m_replace(m) {} + + virtual ~equiv_proof_converter() {} + + virtual void operator()(ast_manager & m, unsigned num_source, proof * const * source, proof_ref & result) { + m_replace(m, num_source, source, result); + } + + virtual proof_converter * translate(ast_translation & translator) { + return m_replace.translate(translator); + } + + void insert(expr* fml1, expr* fml2); + + ast_manager& get_manager() { return m; } + +}; + +#endif diff --git a/src/muz_qe/expr_safe_replace.cpp b/src/muz_qe/expr_safe_replace.cpp new file mode 100644 index 000000000..b3b4d5138 --- /dev/null +++ b/src/muz_qe/expr_safe_replace.cpp @@ -0,0 +1,102 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + expr_safe_replace.cpp + +Abstract: + + Version of expr_replace/expr_substitution that is safe for quantifiers. + +Author: + + Nikolaj Bjorner (nbjorner) 2012-11-30 + +Revision History: + + +--*/ + +#include "expr_safe_replace.h" +#include "rewriter.h" + + +void expr_safe_replace::insert(expr* src, expr* dst) { + m_src.push_back(src); + m_dst.push_back(dst); + m_subst.insert(src, dst); +} + +void expr_safe_replace::operator()(expr* e, expr_ref& res) { + obj_map cache; + ptr_vector todo, args; + expr_ref_vector refs(m); + todo.push_back(e); + expr* a, *b, *d; + todo.push_back(e); + + while (!todo.empty()) { + a = todo.back(); + if (cache.contains(a)) { + todo.pop_back(); + } + else if (m_subst.find(a, b)) { + cache.insert(a, b); + todo.pop_back(); + } + else if (is_var(a)) { + cache.insert(a, a); + todo.pop_back(); + } + else if (is_app(a)) { + app* c = to_app(a); + unsigned n = c->get_num_args(); + args.reset(); + for (unsigned i = 0; i < n; ++i) { + if (cache.find(c->get_arg(i), d)) { + args.push_back(d); + } + else { + todo.push_back(c->get_arg(i)); + } + } + if (args.size() == n) { + b = m.mk_app(c->get_decl(), args.size(), args.c_ptr()); + refs.push_back(b); + cache.insert(a, b); + todo.pop_back(); + } + } + else { + SASSERT(is_quantifier(a)); + quantifier* q = to_quantifier(a); + expr_safe_replace replace(m); + var_shifter shift(m); + expr_ref new_body(m), src(m), dst(m), tmp(m); + expr_ref_vector pats(m), nopats(m); + unsigned num_decls = q->get_num_decls(); + for (unsigned i = 0; i < m_src.size(); ++i) { + shift(m_src[i].get(), num_decls, src); + shift(m_dst[i].get(), num_decls, dst); + replace.insert(src, dst); + } + unsigned np = q->get_num_patterns(); + for (unsigned i = 0; i < np; ++i) { + replace(q->get_pattern(i), tmp); + pats.push_back(tmp); + } + np = q->get_num_no_patterns(); + for (unsigned i = 0; i < np; ++i) { + replace(q->get_no_pattern(i), tmp); + nopats.push_back(tmp); + } + replace(q->get_expr(), new_body); + b = m.update_quantifier(q, pats.size(), pats.c_ptr(), nopats.size(), nopats.c_ptr(), new_body); + refs.push_back(b); + cache.insert(a, b); + todo.pop_back(); + } + } + res = cache.find(e); +} diff --git a/src/muz_qe/expr_safe_replace.h b/src/muz_qe/expr_safe_replace.h new file mode 100644 index 000000000..6af819596 --- /dev/null +++ b/src/muz_qe/expr_safe_replace.h @@ -0,0 +1,43 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + expr_safe_replace.h + +Abstract: + + Version of expr_replace/expr_substitution that is safe for quantifiers. + + +Author: + + Nikolaj Bjorner (nbjorner) 2012-11-30 + +Revision History: + + +--*/ + +#ifndef __EXPR_SAFE_REPLACE_H__ +#define __EXPR_SAFE_REPLACE_H__ + +#include "ast.h" + +class expr_safe_replace { + ast_manager& m; + expr_ref_vector m_src; + expr_ref_vector m_dst; + obj_map m_subst; + +public: + expr_safe_replace(ast_manager& m): m(m), m_src(m), m_dst(m) {} + + void insert(expr* src, expr* dst); + + void operator()(expr_ref& e) { (*this)(e.get(), e); } + + void operator()(expr* src, expr_ref& e); +}; + +#endif /* __EXPR_SAFE_REPLACE_H__ */ diff --git a/src/muz_qe/fixedpoint_params.pyg b/src/muz_qe/fixedpoint_params.pyg new file mode 100644 index 000000000..61f993c0a --- /dev/null +++ b/src/muz_qe/fixedpoint_params.pyg @@ -0,0 +1,62 @@ +def_module_params('fixedpoint', + description='fixedpoint parameters', + export=True, + params=(('timeout', UINT, UINT_MAX, 'set timeout'), + ('engine', SYMBOL, 'auto-config', 'Select: auto-config, datalog, pdr, bmc'), + ('default_table', SYMBOL, 'sparse', 'default table implementation: sparse, hashtable, bitvector, interval'), + ('default_relation', SYMBOL, 'pentagon', 'default relation implementation: external_relation, pentagon'), + ('generate_explanations', BOOL, False, '(DATALOG) produce explanations for produced facts when using the datalog engine'), + ('use_map_names', BOOL, True, "(DATALOG) use names from map files when displaying tuples"), + ('bit_blast', BOOL, False, '(PDR) bit-blast bit-vectors'), + ('explanations_on_relation_level', BOOL, False, '(DATALOG) if true, explanations are generated as history of each relation, rather than per fact (generate_explanations must be set to true for this option to have any effect)'), + ('magic_sets_for_queries', BOOL, False, "(DATALOG) magic set transformation will be used for queries"), + ('unbound_compressor', BOOL, True, "auxiliary relations will be introduced to avoid unbound variables in rule heads"), + ('similarity_compressor', BOOL, True, "(DATALOG) rules that differ only in values of constants will be merged into a single rule"), + ('similarity_compressor_threshold', UINT, 11, "(DATALOG) if similarity_compressor is on, this value determines how many similar rules there must be in order for them to be merged"), + ('all_or_nothing_deltas', BOOL, False, "(DATALOG) compile rules so that it is enough for the delta relation in union and widening operations to determine only whether the updated relation was modified or not"), + ('compile_with_widening', BOOL, False, "(DATALOG) widening will be used to compile recursive rules"), + ('eager_emptiness_checking', BOOL, True, "(DATALOG) emptiness of affected relations will be checked after each instruction, so that we may ommit unnecessary instructions"), + ('default_table_checked', BOOL, False, "if true, the detault table will be default_table inside a wrapper that checks that its results are the same as of default_table_checker table"), + ('default_table_checker', SYMBOL, 'null', "see default_table_checked"), + + + ('initial_restart_timeout', UINT, 0, "length of saturation run before the first restart (in ms), zero means no restarts"), + ('output_profile', BOOL, False, "determines whether profile informations should be output when outputting Datalog rules or instructions"), + ('inline_linear', BOOL, True, "try linear inlining method"), + ('inline_eager', BOOL, True, "try eager inlining of rules"), + ('inline_linear_branch', BOOL, False, "try linear inlining method with potential expansion"), + ('fix_unbound_vars', BOOL, False, "fix unbound variables in tail"), + ('output_tuples', BOOL, True, "determines whether tuples for output predicates should be output"), + ('print_with_fixedpoint_extensions', BOOL, True, "use SMT-LIB2 fixedpoint extensions, instead of pure SMT2, when printing rules"), + ('print_low_level_smt2', BOOL, False, "use (faster) low-level SMT2 printer (the printer is scalable but the result may not be as readable)"), + ('print_with_variable_declarations', BOOL, True, "use variable declarations when displaying rules (instead of attempting to use original names)"), + ('bfs_model_search', BOOL, True, "PDR: use BFS strategy for expanding model search"), + ('use_farkas', BOOL, True, "PDR: use lemma generator based on Farkas (for linear real arithmetic)"), + ('generate_proof_trace', BOOL, False, "PDR: trace for 'sat' answer as proof object"), + ('flexible_trace', BOOL, False, "PDR: allow PDR generate long counter-examples " + "by extending candidate trace within search area"), + ('unfold_rules', UINT, 0, "PDR: unfold rules statically using iterative squarring"), + ('use_model_generalizer', BOOL, False, "PDR: use model for backwards propagation (instead of symbolic simulation)"), + ('validate_result', BOOL, False, "PDR validate result (by proof checking or model checking)"), + ('simplify_formulas_pre', BOOL, False, "PDR: simplify derived formulas before inductive propagation"), + ('simplify_formulas_post', BOOL, False, "PDR: simplify derived formulas after inductive propagation"), + ('slice', BOOL, True, "PDR: simplify clause set using slicing"), + ('coalesce_rules', BOOL, False, "BMC: coalesce rules"), + ('use_multicore_generalizer', BOOL, False, "PDR: extract multiple cores for blocking states"), + ('use_inductive_generalizer', BOOL, True, "PDR: generalize lemmas using induction strengthening"), + ('cache_mode', UINT, 0, "PDR: use no (0), symbolic (1) or explicit cache (2) for model search"), + ('inductive_reachability_check', BOOL, False, "PDR: assume negation of the cube on the previous level when " + "checking for reachability (not only during cube weakening)"), + ('max_num_contexts', UINT, 500, "PDR: maximal number of contexts to create"), + ('try_minimize_core', BOOL, False, "PDR: try to reduce core size (before inductive minimization)"), + ('profile_timeout_milliseconds', UINT, 0, "instructions and rules that took less than the threshold will not be printed when printed the instruction/rule list"), + ('dbg_fpr_nonempty_relation_signature', BOOL, False, + "if true, finite_product_relation will attempt to avoid creating inner relation with empty signature " + "by putting in half of the table columns, if it would have been empty otherwise"), + ('print_answer', BOOL, False, 'print answer instance(s) to query'), + ('print_certificate', BOOL, False, 'print certificate for reacahbility or non-reachability'), + ('print_statistics', BOOL, False, 'print statistics'), + )) + + + diff --git a/src/muz_qe/horn_tactic.cpp b/src/muz_qe/horn_tactic.cpp index 59e9e6fec..98b6130b8 100644 --- a/src/muz_qe/horn_tactic.cpp +++ b/src/muz_qe/horn_tactic.cpp @@ -26,7 +26,7 @@ class horn_tactic : public tactic { struct imp { ast_manager& m; datalog::context m_ctx; - front_end_params m_fparams; + smt_params m_fparams; imp(ast_manager & m, params_ref const & p): m(m), @@ -90,21 +90,30 @@ class horn_tactic : public tactic { m_ctx.register_predicate(to_app(a)->get_decl(), true); } - void check_predicate(expr* a) { - expr* a1 = 0; - while (true) { + void check_predicate(ast_mark& mark, expr* a) { + ptr_vector todo; + todo.push_back(a); + while (!todo.empty()) { + a = todo.back(); + todo.pop_back(); + if (mark.is_marked(a)) { + continue; + } + mark.mark(a, true); if (is_quantifier(a)) { a = to_quantifier(a)->get_expr(); - continue; + todo.push_back(a); } - if (m.is_not(a, a1)) { - a = a1; - continue; + else if (m.is_not(a) || m.is_and(a) || m.is_or(a) || m.is_implies(a)) { + todo.append(to_app(a)->get_num_args(), to_app(a)->get_args()); } - if (is_predicate(a)) { + else if (m.is_ite(a)) { + todo.append(to_app(a)->get_arg(1)); + todo.append(to_app(a)->get_arg(2)); + } + else if (is_predicate(a)) { register_predicate(a); } - break; } } @@ -112,14 +121,15 @@ class horn_tactic : public tactic { formula_kind get_formula_kind(expr_ref& f) { normalize(f); + ast_mark mark; expr_ref_vector args(m), body(m); expr_ref head(m); expr* a = 0, *a1 = 0; datalog::flatten_or(f, args); for (unsigned i = 0; i < args.size(); ++i) { - a = args[i].get(); - check_predicate(a); - if (m.is_not(a, a1) && is_predicate(a1)) { + a = args[i].get(); + check_predicate(mark, a); + if (m.is_not(a, a1)) { body.push_back(a1); } else if (is_predicate(a)) { @@ -128,9 +138,6 @@ class horn_tactic : public tactic { } head = a; } - else if (m.is_not(a, a1)) { - body.push_back(a1); - } else { body.push_back(m.mk_not(a)); } @@ -161,9 +168,9 @@ class horn_tactic : public tactic { bool produce_proofs = g->proofs_enabled(); if (produce_proofs) { - if (!m_ctx.get_params().get_bool(":generate-proof-trace", true)) { - params_ref params = m_ctx.get_params(); - params.set_bool(":generate-proof-trace", true); + if (!m_ctx.get_params().generate_proof_trace()) { + params_ref params = m_ctx.get_params().p; + params.set_bool("generate_proof_trace", true); updt_params(params); } } diff --git a/src/muz_qe/nlarith_util.cpp b/src/muz_qe/nlarith_util.cpp index 039b57acf..5f8a24e99 100644 --- a/src/muz_qe/nlarith_util.cpp +++ b/src/muz_qe/nlarith_util.cpp @@ -72,7 +72,7 @@ namespace nlarith { bool m_enable_linear; app_ref m_zero; app_ref m_one; - front_end_params m_params; + smt_params m_params; basic_simplifier_plugin m_bs; arith_simplifier_plugin m_rw; arith_rewriter m_rw1; diff --git a/src/muz_qe/pdr_context.cpp b/src/muz_qe/pdr_context.cpp index f056342a2..c8c1e3b2a 100644 --- a/src/muz_qe/pdr_context.cpp +++ b/src/muz_qe/pdr_context.cpp @@ -35,7 +35,6 @@ Notes: #include "pdr_generalizers.h" #include "datatype_decl_plugin.h" #include "for_each_expr.h" -#include "model_v2_pp.h" #include "dl_rule_set.h" #include "unit_subsumption_tactic.h" #include "model_smt2_pp.h" @@ -44,6 +43,7 @@ Notes: #include "qe_lite.h" #include "ast_ll_pp.h" #include "proof_checker.h" +#include "smt_value_sort.h" namespace pdr { @@ -146,7 +146,6 @@ namespace pdr { expr_ref vl(m); for (; it != end; ++it) { expr* pred = it->m_key; - TRACE("pdr", tout << mk_pp(pred, m) << "\n";); if (model.eval(to_app(pred)->get_decl(), vl) && m.is_true(vl)) { return *it->m_value; } @@ -163,9 +162,6 @@ namespace pdr { } } - void pred_transformer::find_predecessors(model_core const& model, ptr_vector& preds) const { - find_predecessors(find_rule(model), preds); - } void pred_transformer::remove_predecessors(expr_ref_vector& literals) { // remove tags @@ -267,7 +263,7 @@ namespace pdr { } else if (is_invariant(tgt_level, curr, false, assumes_level)) { - add_property(curr, tgt_level); // assumes_level?tgt_level:infty_level + add_property(curr, assumes_level?tgt_level:infty_level); TRACE("pdr", tout << "is invariant: "<< tgt_level << " " << mk_pp(curr, m) << "\n";); src[i] = src.back(); src.pop_back(); @@ -294,12 +290,10 @@ namespace pdr { bool pred_transformer::add_property1(expr * lemma, unsigned lvl) { if (is_infty_level(lvl)) { - if (m.is_false(lemma)) { - return false; - } if (!m_invariants.contains(lemma)) { TRACE("pdr", tout << "property1: " << head()->get_name() << " " << mk_pp(lemma, m) << "\n";); m_invariants.push_back(lemma); + m_prop2level.insert(lemma, lvl); m_solver.add_formula(lemma); return true; } @@ -362,7 +356,7 @@ namespace pdr { } // replace local constants by bound variables. expr_substitution sub(m); - for (unsigned i = 0; i < m_sig.size(); ++i) { + for (unsigned i = 0; i < sig_size(); ++i) { c = m.mk_const(pm.o2n(sig(i), 0)); v = m.mk_var(i, sig(i)->get_range()); sub.insert(c, v); @@ -397,7 +391,7 @@ namespace pdr { // replace bound variables by local constants. expr_ref result(property, m), v(m), c(m); expr_substitution sub(m); - for (unsigned i = 0; i < m_sig.size(); ++i) { + for (unsigned i = 0; i < sig_size(); ++i) { c = m.mk_const(pm.o2n(sig(i), 0)); v = m.mk_var(i, sig(i)->get_range()); sub.insert(v, c); @@ -410,7 +404,7 @@ namespace pdr { add_property(result, level); } - lbool pred_transformer::is_reachable(model_node& n, expr_ref_vector* core) { + lbool pred_transformer::is_reachable(model_node& n, expr_ref_vector* core, bool& uses_level) { TRACE("pdr", tout << "is-reachable: " << head()->get_name() << " level: " << n.level() << "\n"; tout << mk_pp(n.state(), m) << "\n";); @@ -427,6 +421,9 @@ namespace pdr { tout << mk_pp(n.state(), m) << "\n";); n.set_model(model); } + else if (is_sat == l_false) { + uses_level = m_solver.assumes_level(); + } return is_sat; } @@ -442,6 +439,7 @@ namespace pdr { tmp = pm.mk_and(conj); prop_solver::scoped_level _sl(m_solver, level); m_solver.set_core(core); + m_solver.set_model(0); lbool r = m_solver.check_conjunction_as_assumptions(tmp); if (r == l_false) { assumes_level = m_solver.assumes_level(); @@ -602,6 +600,12 @@ namespace pdr { } m_rule2inst.insert(&rule,&var_reprs); m_rule2vars.insert(&rule, aux_vars); + TRACE("pdr", + tout << rule.get_decl()->get_name() << "\n"; + for (unsigned i = 0; i < var_reprs.size(); ++i) { + tout << mk_pp(var_reprs[i].get(), m) << " "; + } + tout << "\n";); } bool pred_transformer::check_filled(app_ref_vector const& v) const { @@ -699,16 +703,10 @@ namespace pdr { void pred_transformer::inherit_properties(pred_transformer& other) { SASSERT(m_head == other.m_head); obj_map::iterator it = other.m_prop2level.begin(); - obj_map::iterator end = other.m_prop2level.end(); - + obj_map::iterator end = other.m_prop2level.end(); for (; it != end; ++it) { add_property(it->m_key, it->m_value); } - for (unsigned i = 0; i < other.m_invariants.size(); ++i) { - expr* e = other.m_invariants[i].get(); - m_invariants.push_back(e); - m_solver.add_formula(e); - } } // ---------------- @@ -723,24 +721,60 @@ namespace pdr { pred_transformer& p = pt(); ast_manager& m = p.get_manager(); manager& pm = p.get_pdr_manager(); - TRACE("pdr", model_v2_pp(tout, get_model());); + TRACE("pdr", model_smt2_pp(tout, m, get_model(), 0);); func_decl* f = p.head(); unsigned arity = f->get_arity(); + model_ref model = get_model_ptr(); expr_ref_vector args(m); - func_decl_ref v(m); + expr_ref v(m); + model_evaluator mev(m); + for (unsigned i = 0; i < arity; ++i) { - v = pm.o2n(p.sig(i),0); - expr* e = get_model().get_const_interp(v); - if (e) { - args.push_back(e); - } - else { - args.push_back(m.mk_const(v)); - } + v = m.mk_const(pm.o2n(p.sig(i),0)); + expr_ref e = mev.eval(model, v); + args.push_back(e); } return expr_ref(m.mk_app(f, args.size(), args.c_ptr()), m); } + static bool is_ini(datalog::rule const& r) { + return r.get_uninterpreted_tail_size() == 0; + } + + datalog::rule* model_node::get_rule() { + if (m_rule) { + return const_cast(m_rule); + } + // only initial states are not set by the PDR search. + datalog::rule const& rl1 = pt().find_rule(*m_model); + if (is_ini(rl1)) { + set_rule(&rl1); + return const_cast(m_rule); + } + ast_manager& m = pt().get_manager(); + // otherwise, the initial state is reachable. + ptr_vector const& rules = pt().rules(); + ptr_vector ini_rules; + expr_ref_vector tags(m); + expr_ref ini_tags(m), ini_state(m); + for (unsigned i = 0; i < rules.size(); ++i) { + datalog::rule* rl = rules[i]; + if (is_ini(*rl)) { + tags.push_back(pt().rule2tag(rl)); + } + } + SASSERT(!tags.empty()); + ini_tags = m.mk_or(tags.size(), tags.c_ptr()); + ini_state = m.mk_and(ini_tags, pt().initial_state(), state()); + model_ref mdl; + pt().get_solver().set_model(&mdl); + VERIFY(l_true == pt().get_solver().check_conjunction_as_assumptions(ini_state)); + datalog::rule const& rl2 = pt().find_rule(*mdl); + SASSERT(is_ini(rl2)); + set_rule(&rl2); + return const_cast(m_rule); + } + void model_node::mk_instantiate(datalog::rule_ref& r0, datalog::rule_ref& r1, expr_ref_vector& binding) { ast_manager& m = pt().get_manager(); @@ -764,7 +798,7 @@ namespace pdr { model.insert(e, m.mk_true()); } } - r0 = const_cast(&pt().find_rule(*m_model.get())); + r0 = get_rule(); app_ref_vector& inst = pt().get_inst(r0); TRACE("pdr", tout << mk_pp(state(), m) << " instance: " << inst.size() << "\n";); for (unsigned i = 0; i < inst.size(); ++i) { @@ -1088,18 +1122,18 @@ namespace pdr { // context context::context( - front_end_params& fparams, - params_ref const& params, + smt_params& fparams, + fixedpoint_params const& params, ast_manager& m ) : m_fparams(fparams), m_params(params), m(m), m_context(0), - m_pm(m_fparams, m_params, m), + m_pm(m_fparams, params, m), m_query_pred(m), m_query(0), - m_search(m_params.get_bool(":bfs-model-search", true)), + m_search(m_params.bfs_model_search()), m_last_result(l_undef), m_inductive_lvl(0), m_cancel(false) @@ -1324,7 +1358,7 @@ namespace pdr { }; void context::validate() { - if (!m_params.get_bool(":validate-result", false)) { + if (!m_params.validate_result()) { return; } switch(m_last_result) { @@ -1353,7 +1387,7 @@ namespace pdr { break; } case l_false: { - expr_ref_vector refs(m), fmls(m); + expr_ref_vector refs(m); expr_ref tmp(m); model_ref model; vector rs; @@ -1368,6 +1402,7 @@ namespace pdr { for (unsigned i = 0; i < rules.size(); ++i) { datalog::rule& r = *rules[i]; model->eval(r.get_head(), tmp); + expr_ref_vector fmls(m); fmls.push_back(m.mk_not(tmp)); unsigned utsz = r.get_uninterpreted_tail_size(); unsigned tsz = r.get_tail_size(); @@ -1415,34 +1450,25 @@ namespace pdr { void context::init_core_generalizers(datalog::rule_set& rules) { reset_core_generalizers(); classifier_proc classify(m, rules); - bool use_mc = m_params.get_bool(":use-multicore-generalizer", false); + bool use_mc = m_params.use_multicore_generalizer(); if (use_mc) { m_core_generalizers.push_back(alloc(core_multi_generalizer, *this, 0)); } - if (m_params.get_bool(":use-farkas", true) && !classify.is_bool()) { - if (m_params.get_bool(":inline-proof-mode", true)) { - m.toggle_proof_mode(PGM_FINE); - m_fparams.m_proof_mode = PGM_FINE; - m_fparams.m_arith_bound_prop = BP_NONE; - m_fparams.m_arith_auto_config_simplex = true; - m_fparams.m_arith_propagate_eqs = false; - m_fparams.m_arith_eager_eq_axioms = false; - if (classify.is_dl()) { - m_fparams.m_arith_mode = AS_DIFF_LOGIC; - m_fparams.m_arith_expand_eqs = true; - } - } - else { - m_core_generalizers.push_back(alloc(core_farkas_generalizer, *this, m, m_fparams)); + if (m_params.use_farkas() && !classify.is_bool()) { + m.toggle_proof_mode(PGM_FINE); + m_fparams.m_arith_bound_prop = BP_NONE; + m_fparams.m_arith_auto_config_simplex = true; + m_fparams.m_arith_propagate_eqs = false; + m_fparams.m_arith_eager_eq_axioms = false; + if (classify.is_dl()) { + m_fparams.m_arith_mode = AS_DIFF_LOGIC; + m_fparams.m_arith_expand_eqs = true; } } - if (!use_mc && m_params.get_bool(":use-inductive-generalizer", true)) { + if (!use_mc && m_params.use_inductive_generalizer()) { m_core_generalizers.push_back(alloc(core_bool_inductive_generalizer, *this, 0)); } - if (m_params.get_bool(":use-interpolants", false)) { - m_core_generalizers.push_back(alloc(core_interpolant_generalizer, *this)); - } - if (m_params.get_bool(":inductive-reachability-check", false)) { + if (m_params.inductive_reachability_check()) { m_core_generalizers.push_back(alloc(core_induction_generalizer, *this)); } } @@ -1554,7 +1580,7 @@ namespace pdr { \brief Retrieve satisfying assignment with explanation. */ expr_ref context::mk_sat_answer() const { - if (m_params.get_bool(":generate-proof-trace", false)) { + if (m_params.generate_proof_trace()) { proof_ref pr = get_proof(); return expr_ref(pr.get(), m); } @@ -1641,10 +1667,11 @@ namespace pdr { close_node(n); } else { - switch (expand_state(n, cube)) { + bool uses_level = true; + switch (expand_state(n, cube, uses_level)) { case l_true: if (n.level() == 0) { - TRACE("pdr", tout << "reachable\n";); + TRACE("pdr", tout << "reachable at level 0\n";); close_node(n); } else { @@ -1654,7 +1681,7 @@ namespace pdr { break; case l_false: { core_generalizer::cores cores; - cores.push_back(std::make_pair(cube, true)); + cores.push_back(std::make_pair(cube, uses_level)); for (unsigned i = 0; !cores.empty() && i < m_core_generalizers.size(); ++i) { core_generalizer::cores new_cores; @@ -1667,14 +1694,14 @@ namespace pdr { bool found_invariant = false; for (unsigned i = 0; i < cores.size(); ++i) { expr_ref_vector const& core = cores[i].first; - bool uses_level = cores[i].second; + uses_level = cores[i].second; found_invariant = !uses_level || found_invariant; expr_ref ncore(m_pm.mk_not_and(core), m); TRACE("pdr", tout << "invariant state: " << (uses_level?"":"(inductive) ") << mk_pp(ncore, m) << "\n";); n.pt().add_property(ncore, uses_level?n.level():infty_level); } CASSERT("pdr",n.level() == 0 || check_invariant(n.level()-1)); - m_search.backtrack_level(!found_invariant && m_params.get_bool(":flexible-trace", false), n); + m_search.backtrack_level(!found_invariant && m_params.flexible_trace(), n); break; } case l_undef: { @@ -1691,12 +1718,12 @@ namespace pdr { // return a property that blocks state and is implied by the // predicate transformer (or some unfolding of it). // - lbool context::expand_state(model_node& n, expr_ref_vector& result) { - return n.pt().is_reachable(n, &result); + lbool context::expand_state(model_node& n, expr_ref_vector& result, bool& uses_level) { + return n.pt().is_reachable(n, &result, uses_level); } void context::propagate(unsigned max_prop_lvl) { - if (m_params.get_bool(":simplify-formulas-pre", false)) { + if (m_params.simplify_formulas_pre()) { simplify_formulas(); } for (unsigned lvl = 0; lvl <= max_prop_lvl; lvl++) { @@ -1715,7 +1742,7 @@ namespace pdr { throw inductive_exception(); } } - if (m_params.get_bool(":simplify-formulas-post", false)) { + if (m_params.simplify_formulas_post()) { simplify_formulas(); } } @@ -1763,7 +1790,7 @@ namespace pdr { */ void context::create_children(model_node& n) { SASSERT(n.level() > 0); - bool use_model_generalizer = m_params.get_bool(":use-model-generalizer", false); + bool use_model_generalizer = m_params.use_model_generalizer(); datalog::scoped_no_proof _sc(m); pred_transformer& pt = n.pt(); @@ -1772,11 +1799,14 @@ namespace pdr { expr* T = pt.get_transition(r); expr* phi = n.state(); - IF_VERBOSE(3, verbose_stream() << "Model:\n"; - model_smt2_pp(verbose_stream(), m, *M, 0); - verbose_stream() << "\n"; - verbose_stream() << "Transition:\n" << mk_pp(T, m) << "\n"; - verbose_stream() << "Phi:\n" << mk_pp(phi, m) << "\n";); + n.set_rule(&r); + + TRACE("pdr", + tout << "Model:\n"; + model_smt2_pp(tout, m, *M, 0); + tout << "\n"; + tout << "Transition:\n" << mk_pp(T, m) << "\n"; + tout << "Phi:\n" << mk_pp(phi, m) << "\n";); model_evaluator mev(m); expr_ref_vector mdl(m), forms(m), Phi(m); @@ -1806,36 +1836,36 @@ namespace pdr { qe_lite qe(m); expr_ref phi1 = m_pm.mk_and(Phi); qe(vars, phi1); + TRACE("pdr", tout << "Eliminated\n" << mk_pp(phi1, m) << "\n";); if (!use_model_generalizer) { reduce_disequalities(*M, 3, phi1); + TRACE("pdr", tout << "Reduced-eq\n" << mk_pp(phi1, m) << "\n";); } get_context().get_rewriter()(phi1); - IF_VERBOSE(2, - verbose_stream() << "Vars:\n"; - for (unsigned i = 0; i < vars.size(); ++i) { - verbose_stream() << mk_pp(vars[i].get(), m) << "\n"; - } - verbose_stream() << "Literals\n"; - verbose_stream() << mk_pp(m_pm.mk_and(Phi), m) << "\n"; - verbose_stream() << "Reduced\n" << mk_pp(phi1, m) << "\n";); + TRACE("pdr", + tout << "Vars:\n"; + for (unsigned i = 0; i < vars.size(); ++i) { + tout << mk_pp(vars[i].get(), m) << "\n"; + } + tout << "Literals\n"; + tout << mk_pp(m_pm.mk_and(Phi), m) << "\n"; + tout << "Reduced\n" << mk_pp(phi1, m) << "\n";); if (!vars.empty()) { // also fresh names for auxiliary variables in body? expr_substitution sub(m); - expr_ref_vector refs(m); expr_ref tmp(m); proof_ref pr(m); pr = m.mk_asserted(m.mk_true()); - for (unsigned i = 0; i < vars.size(); ++i) { - VERIFY (M->eval(vars[i].get(), tmp, true)); - refs.push_back(tmp); + for (unsigned i = 0; i < vars.size(); ++i) { + tmp = mev.eval(M, vars[i].get()); sub.insert(vars[i].get(), tmp, pr); } if (!rep) rep = mk_expr_simp_replacer(m); rep->set_substitution(&sub); (*rep)(phi1); - IF_VERBOSE(2, verbose_stream() << "Projected:\n" << mk_pp(phi1, m) << "\n";); + TRACE("pdr", tout << "Projected:\n" << mk_pp(phi1, m) << "\n";); } Phi.reset(); datalog::flatten_and(phi1, Phi); @@ -1861,7 +1891,7 @@ namespace pdr { for (unsigned j = 1; j < indices.size(); ++j) { ptr_vector const& vs = vars[indices[j]]; for (unsigned k = 0; k < vs.size(); ++k) { - M->eval(vs[k]->get_decl(), tmp); + tmp = mev.eval(M, vs[k]); sub.insert(vs[k], tmp, pr); child_states[indices[j]].push_back(m.mk_eq(vs[k], tmp)); } diff --git a/src/muz_qe/pdr_context.h b/src/muz_qe/pdr_context.h index 4b578a188..7491327dd 100644 --- a/src/muz_qe/pdr_context.h +++ b/src/muz_qe/pdr_context.h @@ -30,6 +30,7 @@ Revision History: #include "pdr_prop_solver.h" #include "pdr_reachable_cache.h" + namespace datalog { class rule_set; class context; @@ -116,6 +117,7 @@ namespace pdr { ptr_vector const& rules() const { return m_rules; } func_decl* sig(unsigned i) { init_sig(); return m_sig[i].get(); } // signature func_decl* const* sig() { init_sig(); return m_sig.c_ptr(); } + unsigned sig_size() { init_sig(); return m_sig.size(); } expr* transition() const { return m_transition; } expr* initial_state() const { return m_initial_state; } expr* rule2tag(datalog::rule const* r) { return m_rule2tag.find(r); } @@ -131,7 +133,6 @@ namespace pdr { bool is_reachable(expr* state); void remove_predecessors(expr_ref_vector& literals); void find_predecessors(datalog::rule const& r, ptr_vector& predicates) const; - void find_predecessors(model_core const& model, ptr_vector& preds) const; datalog::rule const& find_rule(model_core const& model) const; expr* get_transition(datalog::rule const& r) { return m_rule2transition.find(&r); } ptr_vector& get_aux_vars(datalog::rule const& r) { return m_rule2vars.find(&r); } @@ -139,7 +140,7 @@ namespace pdr { bool propagate_to_next_level(unsigned level); void add_property(expr * lemma, unsigned lvl); // add property 'p' to state at level. - lbool is_reachable(model_node& n, expr_ref_vector* core); + lbool is_reachable(model_node& n, expr_ref_vector* core, bool& uses_level); bool is_invariant(unsigned level, expr* co_state, bool inductive, bool& assumes_level, expr_ref_vector* core = 0); bool check_inductive(unsigned level, expr_ref_vector& state, bool& assumes_level); @@ -162,6 +163,8 @@ namespace pdr { void ground_free_vars(expr* e, app_ref_vector& vars, ptr_vector& aux_vars); + prop_solver& get_solver() { return m_solver; } + }; @@ -176,10 +179,11 @@ namespace pdr { unsigned m_orig_level; unsigned m_depth; bool m_closed; + datalog::rule const* m_rule; public: model_node(model_node* parent, expr_ref& state, pred_transformer& pt, unsigned level): m_parent(parent), m_pt(pt), m_state(state), m_model(0), - m_level(level), m_orig_level(level), m_depth(0), m_closed(false) { + m_level(level), m_orig_level(level), m_depth(0), m_closed(false), m_rule(0) { if (m_parent) { m_parent->m_children.push_back(this); SASSERT(m_parent->m_level == level+1); @@ -216,6 +220,9 @@ namespace pdr { void set_pre_closed() { m_closed = true; } void reset() { m_children.reset(); } + void set_rule(datalog::rule const* r) { m_rule = r; } + datalog::rule* get_rule(); + expr_ref get_trace() const; void mk_instantiate(datalog::rule_ref& r0, datalog::rule_ref& r1, expr_ref_vector& binding); @@ -284,8 +291,8 @@ namespace pdr { void reset() { memset(this, 0, sizeof(*this)); } }; - front_end_params& m_fparams; - params_ref const& m_params; + smt_params& m_fparams; + fixedpoint_params const& m_params; ast_manager& m; datalog::context* m_context; manager m_pm; @@ -308,7 +315,7 @@ namespace pdr { void close_node(model_node& n); void check_pre_closed(model_node& n); void expand_node(model_node& n); - lbool expand_state(model_node& n, expr_ref_vector& cube); + lbool expand_state(model_node& n, expr_ref_vector& cube, bool& uses_level); void create_children(model_node& n); expr_ref mk_sat_answer() const; expr_ref mk_unsat_answer() const; @@ -342,14 +349,14 @@ namespace pdr { We check whether there is some reachable state of the relation checked_relation. */ context( - front_end_params& fparams, - params_ref const& params, + smt_params& fparams, + fixedpoint_params const& params, ast_manager& m); ~context(); - front_end_params& get_fparams() const { return m_fparams; } - params_ref const& get_params() const { return m_params; } + smt_params& get_fparams() const { return m_fparams; } + fixedpoint_params const& get_params() const { return m_params; } ast_manager& get_manager() const { return m; } manager& get_pdr_manager() { return m_pm; } decl2rel const& get_pred_transformers() const { return m_rels; } diff --git a/src/muz_qe/pdr_dl_interface.cpp b/src/muz_qe/pdr_dl_interface.cpp index be31f4724..0482ece05 100644 --- a/src/muz_qe/pdr_dl_interface.cpp +++ b/src/muz_qe/pdr_dl_interface.cpp @@ -58,18 +58,18 @@ dl_interface::~dl_interface() { // void dl_interface::check_reset() { datalog::rule_ref_vector const& new_rules = m_ctx.get_rules().get_rules(); - datalog::rule_ref_vector const& old_rules = m_old_rules.get_rules(); - for (unsigned i = 0; i < new_rules.size(); ++i) { - bool found = false; - for (unsigned j = 0; !found && j < old_rules.size(); ++j) { + datalog::rule_ref_vector const& old_rules = m_old_rules.get_rules(); + bool is_subsumed = !old_rules.empty(); + for (unsigned i = 0; is_subsumed && i < new_rules.size(); ++i) { + is_subsumed = false; + for (unsigned j = 0; !is_subsumed && j < old_rules.size(); ++j) { if (m_ctx.check_subsumes(*old_rules[j], *new_rules[i])) { - found = true; + is_subsumed = true; } } - if (!found) { - CTRACE("pdr", (old_rules.size() > 0), new_rules[i]->display(m_ctx, tout << "Fresh rule ");); + if (!is_subsumed) { + TRACE("pdr", new_rules[i]->display(m_ctx, tout << "Fresh rule ");); m_context->reset(); - break; } } m_old_rules.reset(); @@ -83,7 +83,6 @@ lbool dl_interface::query(expr * query) { m_pdr_rules.reset(); m_refs.reset(); m_pred2slice.reset(); - m_ctx.get_rmanager().reset_relations(); ast_manager& m = m_ctx.get_manager(); datalog::rule_manager& rule_manager = m_ctx.get_rule_manager(); datalog::rule_set old_rules(m_ctx.get_rules()); @@ -108,13 +107,13 @@ lbool dl_interface::query(expr * query) { model_converter_ref mc = datalog::mk_skip_model_converter(); proof_converter_ref pc; - if (m_ctx.get_params().get_bool(":generate-proof-trace", false)) { + if (m_ctx.get_params().generate_proof_trace()) { pc = datalog::mk_skip_proof_converter(); } m_ctx.set_output_predicate(query_pred); m_ctx.apply_default_transformation(mc, pc); - if (m_ctx.get_params().get_bool(":slice", true)) { + if (m_ctx.get_params().slice()) { datalog::rule_transformer transformer(m_ctx); datalog::mk_slice* slice = alloc(datalog::mk_slice, m_ctx); transformer.register_plugin(slice); @@ -133,10 +132,10 @@ lbool dl_interface::query(expr * query) { } } - if (m_ctx.get_params().get_uint(":unfold-rules",0) > 0) { - unsigned num_unfolds = m_ctx.get_params().get_uint(":unfold-rules", 0); + if (m_ctx.get_params().unfold_rules() > 0) { + unsigned num_unfolds = m_ctx.get_params().unfold_rules(); datalog::rule_transformer transformer1(m_ctx), transformer2(m_ctx); - if (m_ctx.get_params().get_uint(":coalesce-rules", false)) { + if (m_ctx.get_params().coalesce_rules()) { transformer1.register_plugin(alloc(datalog::mk_coalesce, m_ctx)); m_ctx.transform_rules(transformer1, mc, pc); } @@ -160,6 +159,8 @@ lbool dl_interface::query(expr * query) { m_ctx.replace_rules(old_rules); quantifier_model_checker quantifier_mc(*m_context, m, extract_quantifiers->quantifiers(), m_pdr_rules); + + datalog::scoped_restore_proof _sc(m); // update_rules may overwrite the proof mode. m_context->set_proof_converter(pc); m_context->set_model_converter(mc); @@ -196,7 +197,7 @@ expr_ref dl_interface::get_cover_delta(int level, func_decl* pred_orig) { } void dl_interface::add_cover(int level, func_decl* pred, expr* property) { - if (m_ctx.get_params().get_bool(":slice", true)) { + if (m_ctx.get_params().slice()) { throw default_exception("Covers are incompatible with slicing. Disable slicing before using covers"); } m_context->add_cover(level, pred, property); @@ -244,30 +245,3 @@ model_ref dl_interface::get_model() { proof_ref dl_interface::get_proof() { return m_context->get_proof(); } - -void dl_interface::collect_params(param_descrs& p) { - p.insert(":bfs-model-search", CPK_BOOL, "PDR: (default true) use BFS strategy for expanding model search"); - p.insert(":use-farkas", CPK_BOOL, "PDR: (default true) use lemma generator based on Farkas (for linear real arithmetic)"); - p.insert(":generate-proof-trace", CPK_BOOL, "PDR: (default false) trace for 'sat' answer as proof object"); - p.insert(":inline-proofs", CPK_BOOL, "PDR: (default true) run PDR with proof mode turned on and extract " - "Farkas coefficients directly (instead of creating a separate proof object when extracting coefficients)"); - p.insert(":flexible-trace", CPK_BOOL, "PDR: (default false) allow PDR generate long counter-examples " - "by extending candidate trace within search area"); - p.insert(":unfold-rules", CPK_UINT, "PDR: (default 0) unfold rules statically using iterative squarring"); - p.insert(":use-model-generalizer", CPK_BOOL, "PDR: (default false) use model for backwards propagation (instead of symbolic simulation)"); - p.insert(":validate-result", CPK_BOOL, "PDR (default false) validate result (by proof checking or model checking)"); - PRIVATE_PARAMS(p.insert(":use-multicore-generalizer", CPK_BOOL, "PDR: (default false) extract multiple cores for blocking states");); - PRIVATE_PARAMS(p.insert(":use-inductive-generalizer", CPK_BOOL, "PDR: (default true) generalize lemmas using induction strengthening");); - PRIVATE_PARAMS(p.insert(":use-interpolants", CPK_BOOL, "PDR: (default false) use iZ3 interpolation for lemma generation");); - PRIVATE_PARAMS(p.insert(":dump-interpolants", CPK_BOOL, "PDR: (default false) display interpolants");); - PRIVATE_PARAMS(p.insert(":cache-mode", CPK_UINT, "PDR: use no (0 - default) symbolic (1) or explicit cache (2) for model search");); - PRIVATE_PARAMS(p.insert(":inductive-reachability-check", CPK_BOOL, - "PDR: (default false) assume negation of the cube on the previous level when " - "checking for reachability (not only during cube weakening)");); - PRIVATE_PARAMS(p.insert(":max-num-contexts", CPK_UINT, "PDR: (default 500) maximal number of contexts to create");); - PRIVATE_PARAMS(p.insert(":try-minimize-core", CPK_BOOL, "PDR: (default false) try to reduce core size (before inductive minimization)");); - p.insert(":simplify-formulas-pre", CPK_BOOL, "PDR: (default false) simplify derived formulas before inductive propagation"); - p.insert(":simplify-formulas-post", CPK_BOOL, "PDR: (default false) simplify derived formulas after inductive propagation"); - p.insert(":slice", CPK_BOOL, "PDR: (default true) simplify clause set using slicing"); - p.insert(":coalesce-rules", CPK_BOOL, "BMC: (default false) coalesce rules"); -} diff --git a/src/muz_qe/pdr_dl_interface.h b/src/muz_qe/pdr_dl_interface.h index 61f56282e..c4844f892 100644 --- a/src/muz_qe/pdr_dl_interface.h +++ b/src/muz_qe/pdr_dl_interface.h @@ -66,8 +66,6 @@ namespace pdr { expr_ref get_cover_delta(int level, func_decl* pred); void add_cover(int level, func_decl* pred, expr* property); - - static void collect_params(param_descrs& p); void updt_params(); diff --git a/src/muz_qe/pdr_farkas_learner.cpp b/src/muz_qe/pdr_farkas_learner.cpp index 3206c64da..06b8f5eeb 100644 --- a/src/muz_qe/pdr_farkas_learner.cpp +++ b/src/muz_qe/pdr_farkas_learner.cpp @@ -29,7 +29,6 @@ Revision History: #include "pdr_util.h" #include "pdr_farkas_learner.h" #include "th_rewriter.h" -#include "pdr_interpolant_provider.h" #include "ast_ll_pp.h" #include "arith_bounds_tactic.h" #include "proof_utils.h" @@ -244,7 +243,7 @@ namespace pdr { } }; - farkas_learner::farkas_learner(front_end_params& params, ast_manager& outer_mgr) + farkas_learner::farkas_learner(smt_params& params, ast_manager& outer_mgr) : m_proof_params(get_proof_params(params)), m_pr(PROOF_MODE), p2o(m_pr, outer_mgr), @@ -254,9 +253,8 @@ namespace pdr { m_ctx = alloc(smt::kernel, m_pr, m_proof_params); } - front_end_params farkas_learner::get_proof_params(front_end_params& orig_params) { - front_end_params res(orig_params); - res.m_proof_mode = PROOF_MODE; + smt_params farkas_learner::get_proof_params(smt_params& orig_params) { + smt_params res(orig_params); res.m_arith_bound_prop = BP_NONE; // temp hack to fix the build // res.m_conflict_resolution_strategy = CR_ALL_DECIDED; @@ -796,7 +794,7 @@ namespace pdr { void farkas_learner::test() { - front_end_params params; + smt_params params; enable_trace("farkas_learner"); bool res; @@ -883,7 +881,7 @@ namespace pdr { end = p->get_benchmark()->end_formulas(); B = m.mk_and(static_cast(end-it), it); - front_end_params params; + smt_params params; pdr::farkas_learner fl(params, m); expr_ref_vector lemmas(m); bool res = fl.get_lemma_guesses(A, B, lemmas); diff --git a/src/muz_qe/pdr_farkas_learner.h b/src/muz_qe/pdr_farkas_learner.h index 56cb3640c..809f4cd7e 100644 --- a/src/muz_qe/pdr_farkas_learner.h +++ b/src/muz_qe/pdr_farkas_learner.h @@ -26,7 +26,7 @@ Revision History: #include "smt_kernel.h" #include "bool_rewriter.h" #include "pdr_util.h" -#include "front_end_params.h" +#include "smt_params.h" #include "tactic.h" namespace pdr { @@ -39,12 +39,12 @@ class farkas_learner { typedef obj_hashtable expr_set; - front_end_params m_proof_params; + smt_params m_proof_params; ast_manager m_pr; scoped_ptr m_ctx; - static front_end_params get_proof_params(front_end_params& orig_params); + static smt_params get_proof_params(smt_params& orig_params); // // all ast objects passed to private functions have m_proof_mgs as their ast_manager @@ -72,7 +72,7 @@ class farkas_learner { static void test(); public: - farkas_learner(front_end_params& params, ast_manager& m); + farkas_learner(smt_params& params, ast_manager& m); /** All ast objects have the ast_manager which was passed as diff --git a/src/muz_qe/pdr_generalizers.cpp b/src/muz_qe/pdr_generalizers.cpp index 3105485e0..5a6ab4240 100644 --- a/src/muz_qe/pdr_generalizers.cpp +++ b/src/muz_qe/pdr_generalizers.cpp @@ -20,7 +20,6 @@ Revision History: #include "pdr_context.h" #include "pdr_farkas_learner.h" -#include "pdr_interpolant_provider.h" #include "pdr_generalizers.h" #include "expr_abstract.h" #include "var_subst.h" @@ -103,7 +102,7 @@ namespace pdr { // weaken predecessor. // - core_farkas_generalizer::core_farkas_generalizer(context& ctx, ast_manager& m, front_end_params& p): + core_farkas_generalizer::core_farkas_generalizer(context& ctx, ast_manager& m, smt_params& p): core_generalizer(ctx), m_farkas_learner(p, m) {} @@ -143,77 +142,6 @@ namespace pdr { } - /** - < F, phi, i + 1 > - / \ - < G, psi, i > < H, theta, i > - core - - Given: - 1. psi => core - 2. Gi => not core - 3. phi & psi & theta => F_{i+1} - - Then, by weakening 2: - Gi => (F_{i+1} => not (phi & core & theta)) - - Find interpolant I, such that - - Gi => I, I => (F_{i+1} => not (phi & core' & theta')) - - where core => core', theta => theta' - - This implementation checks if - - Gi => (F_{i+1} => not (phi & theta)) - - */ - void core_interpolant_generalizer::operator()(model_node& n, expr_ref_vector& core, bool& uses_level) { - if (!n.parent()) { - return; - } - manager& pm = n.pt().get_pdr_manager(); - ast_manager& m = n.pt().get_manager(); - model_node& p = *n.parent(); - - // find index of node into parent. - unsigned index = 0; - for (; index < p.children().size() && (&n != p.children()[index]); ++index); - SASSERT(index < p.children().size()); - - expr_ref G(m), F(m), r(m), B(m), I(m), cube(m); - expr_ref_vector fmls(m); - - F = p.pt().get_formulas(p.level(), true); - G = n.pt().get_formulas(n.level(), true); - pm.formula_n2o(index, false, G); - - // get formulas from siblings. - for (unsigned i = 0; i < p.children().size(); ++i) { - if (i != index) { - pm.formula_n2o(p.children()[i]->state(), r, i, true); - fmls.push_back(r); - } - } - fmls.push_back(F); - fmls.push_back(p.state()); - B = pm.mk_and(fmls); - - // when G & B is unsat, find I such that G => I, I => not B - lbool res = pm.get_interpolator().get_interpolant(G, B, I); - - TRACE("pdr", - tout << "Interpolating:\n" << mk_pp(G, m) << "\n" << mk_pp(B, m) << "\n"; - if (res == l_true) tout << mk_pp(I, m) << "\n"; else tout << "failed\n";); - - if(res == l_true) { - pm.formula_o2n(I, cube, index, true); - TRACE("pdr", tout << "After renaming: " << mk_pp(cube, m) << "\n";); - core.reset(); - datalog::flatten_and(cube, core); - uses_level = true; - } - } // @@ -463,7 +391,7 @@ namespace pdr { imp imp(m_ctx); ast_manager& m = core.get_manager(); expr_ref goal = imp.mk_induction_goal(p->pt(), p->level(), depth); - smt::kernel ctx(m, m_ctx.get_fparams(), m_ctx.get_params()); + smt::kernel ctx(m, m_ctx.get_fparams(), m_ctx.get_params().p); ctx.assert_expr(goal); lbool r = ctx.check(); TRACE("pdr", tout << r << "\n"; diff --git a/src/muz_qe/pdr_generalizers.h b/src/muz_qe/pdr_generalizers.h index 3b9851ca5..5f3393682 100644 --- a/src/muz_qe/pdr_generalizers.h +++ b/src/muz_qe/pdr_generalizers.h @@ -36,7 +36,7 @@ namespace pdr { class core_farkas_generalizer : public core_generalizer { farkas_learner m_farkas_learner; public: - core_farkas_generalizer(context& ctx, ast_manager& m, front_end_params& p); + core_farkas_generalizer(context& ctx, ast_manager& m, smt_params& p); virtual ~core_farkas_generalizer() {} virtual void operator()(model_node& n, expr_ref_vector& core, bool& uses_level); virtual void collect_statistics(statistics& st) const; @@ -51,13 +51,6 @@ namespace pdr { virtual void operator()(model_node& n, expr_ref_vector const& core, bool uses_level, cores& new_cores); }; - class core_interpolant_generalizer : public core_generalizer { - public: - core_interpolant_generalizer(context& ctx): core_generalizer(ctx) {} - virtual ~core_interpolant_generalizer() {} - virtual void operator()(model_node& n, expr_ref_vector& core, bool& uses_level); - }; - class core_induction_generalizer : public core_generalizer { class imp; public: diff --git a/src/muz_qe/pdr_interpolant_provider.cpp b/src/muz_qe/pdr_interpolant_provider.cpp deleted file mode 100644 index 85655c737..000000000 --- a/src/muz_qe/pdr_interpolant_provider.cpp +++ /dev/null @@ -1,382 +0,0 @@ -/*++ -Copyright (c) 2011 Microsoft Corporation - -Module Name: - - pdr_interpolant_provider.cpp - -Abstract: - - Interface for obtaining interpolants. - - This file is Windows specific. - -Author: - - Krystof Hoder (t-khoder) 2011-10-19. - -Revision History: - ---*/ - -//disables the warning on deprecation of fgets function -- didn't really find by what it should be replaced -#ifdef _WINDOWS -#pragma warning(disable: 4995) -#endif - -#include -#include "ast_smt_pp.h" -#include "cmd_context.h" -#include "for_each_expr.h" -#include "obj_hashtable.h" -#include "smt2parser.h" -#include "rewriter.h" -#include "rewriter_def.h" -#include "pdr_util.h" -#include "pdr_interpolant_provider.h" -#include "expr_context_simplifier.h" - -#ifdef _WINDOWS -#include -#include -#include -#include - -/** -Requirements for the use of this object: - -The directory where the expcutable is must contain also executable -PdrInterpolator.exe. - -This executable takes one argument with a file name that contains -two SMTLIB problem instances, each terminated by string "\n##next##\n". - -The output of the executable is given to the standard output and -is also terminated by the "\n##next##\n" string. - -If formulas in the two input problems are unsatisfiable, they problem -is printed at the output in the format -(assert FORM) - -If the formulas are satisfiable, "0" is output and if the result cannot -be determined, the output is "?". (Both are still followed by "\n##next##\n"). - -*/ -class interpolant_provider_impl : public interpolant_provider -{ - static std::string s_terminator_str; - static std::string s_satisfiable_str; - static std::string s_unknown_str; - - std::string m_exec_name; - params_ref const & m_params; - - /** - If non-empty, contains name of a temporary file that is used for passing the - interpolation problem to the interpolating engine. - */ - std::string m_tmp_file_name; - - simplifier m_simpl; - - PROCESS_INFORMATION m_pi; - STARTUPINFOA m_si; - HANDLE m_in_rd; - HANDLE m_out_rd; - HANDLE m_in_wr; - HANDLE m_out_wr; - - - class used_symbol_inserter { - typedef obj_hashtable func_decl_set; - typedef obj_hashtable sort_set; - - ast_manager& m; - cmd_context& m_cctx; - - func_decl_set m_funcs; - sort_set m_sorts; - - void handle_sort(sort * s) { - if(s->get_family_id()!=null_family_id || m_sorts.contains(s)) { - return; - } - m_sorts.insert(s); - NOT_IMPLEMENTED_YET(); - //we should insert it into the context somehow, but now not sure how and - //we don't deal with user defined sorts (yet)... - //m_cctx.insert(s); - } - void handle_func_decl(func_decl * fn) { - if(fn->get_family_id()!=null_family_id || m_funcs.contains(fn)) { - return; - } - m_funcs.insert(fn); - m_cctx.insert(fn); - } - - public: - - used_symbol_inserter(cmd_context& cctx) : m(cctx.m()), m_cctx(cctx) {} - - void operator()(var * n) { - handle_sort(n->get_sort()); - } - void operator()(app * n) { - if (is_uninterp(n)) { - handle_func_decl(n->get_decl()); - } - handle_sort(n->get_decl()->get_range()); - } - void operator()(quantifier * n) { - unsigned sz = n->get_num_decls(); - for(unsigned i=0; iget_decl_sort(i)); - } - } - }; - - class form_fixer_cfg : public default_rewriter_cfg - { - ast_manager& m; - public: - form_fixer_cfg(ast_manager& m) : m(m) {} - - br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, - proof_ref & result_pr) - { - if(m.is_or(f) && num==0) { - result = m.mk_false(); - return BR_DONE; - } - return BR_FAILED; - } - }; - - - std::string get_tmp_file_name(); - - std::string execute_interpolator(std::string input); - - void simplify_expr(expr* f, expr_ref& result); - void output_interpolant_problem(std::ostream& out, expr * f1, expr * f2); - -public: - - interpolant_provider_impl(ast_manager& m, params_ref const& params, std::string exec_name) - : interpolant_provider(m), - m_params(params), - m_exec_name(exec_name), - m_simpl(m) { - memset(&m_si, 0, sizeof(m_si)); - memset(&m_pi, 0, sizeof(m_pi)); - } - - ~interpolant_provider_impl(); - - - /** - If (f1 /\ f2) is unsatisfiable, return true and into res assign a formula - I such that f1 --> I, I --> ~f2, and the language if I is in the intersection - of languages of f1 and f2. - - If (f1 /\ f2) is satisfiable, return false. - */ - virtual lbool get_interpolant(expr * f1, expr * f2, expr_ref& res); -}; - -std::string interpolant_provider_impl::s_terminator_str = ";##next##"; -std::string interpolant_provider_impl::s_satisfiable_str = ";#sat#"; -std::string interpolant_provider_impl::s_unknown_str = ";#unknown#"; - -interpolant_provider_impl::~interpolant_provider_impl() { - if(m_tmp_file_name.size()!=0) { - DeleteFileA(m_tmp_file_name.c_str()); - } - CloseHandle(m_pi.hProcess); - CloseHandle(m_pi.hThread); - CloseHandle(m_in_rd); - CloseHandle(m_in_wr); - CloseHandle(m_out_rd); - CloseHandle(m_out_wr); -} - -void interpolant_provider_impl::simplify_expr(expr* f, expr_ref& result) { - expr_ref rwr_f(m); - form_fixer_cfg fixer(m); - rewriter_tpl rwr(m, false, fixer); - rwr(f, rwr_f); - proof_ref pr(m); - m_simpl(rwr_f, result, pr); -} - - -std::string interpolant_provider_impl::get_tmp_file_name() { - //return "c:\\test.txt"; - if(m_tmp_file_name.length()!=0) { - return m_tmp_file_name; - } - char path[MAX_PATH]; - if(GetTempPathA(256, path)==0) { - throw default_exception("cannot get temp directory"); - } - - std::stringstream name_prefix_builder; - - name_prefix_builder<<"pdr"<(input.size()), &wr, 0)) { - throw default_exception("Cold not write to pipe"); - } - - std::string result; - char line[256]; - while (true) { - memset(line, 0, sizeof(line)); - if (!ReadFile(m_out_rd, line, sizeof(line)-1, &rd, 0)) { - throw default_exception("Cold not write to pipe"); - } - result += line; - if (strstr(result.c_str(), s_terminator_str.c_str())) { - return result; - } - } -} - -lbool interpolant_provider_impl::get_interpolant(expr * f1, expr * f2, expr_ref& res) { - std::ostringstream prb; - output_interpolant_problem(prb, f1, f2); - std::string res_text = execute_interpolator(prb.str()); - if(strstr(res_text.c_str(), s_satisfiable_str.c_str())) { - return l_false; - } - if(strstr(res_text.c_str(), s_unknown_str.c_str())) { - return l_undef; - } - - front_end_params dummy_params; - cmd_context cctx(&dummy_params, false, &m); - for_each_expr(used_symbol_inserter(cctx), f1); - - parse_smt2_commands(cctx, std::istringstream(res_text), false); - - ptr_vector::const_iterator ait = cctx.begin_assertions(); - ptr_vector::const_iterator aend = cctx.end_assertions(); - if(ait+1!=aend) { - throw default_exception("invalid interpolator output"); - } - res = *ait; - if (m_params.get_bool(":dump-interpolants", false)) { - interpolant_provider::output_interpolant(m, f1, f2, res); - } - return l_true; -} - -interpolant_provider * interpolant_provider::mk(ast_manager& m, params_ref const& p) -{ - char self_name[MAX_PATH]; - GetModuleFileNameA(NULL, self_name, MAX_PATH); - char * last_backslash = strrchr(self_name,'\\'); - if(last_backslash==NULL) { - throw default_exception("GetModuleFileNameA did not return full path to the executable"); - } - //we cut the string at the last backslash - *last_backslash = 0; - - std::string exec_name = self_name + std::string(".\\PdrInterpolator.exe"); - - return alloc(interpolant_provider_impl, m, p, exec_name); -} - -#else - -interpolant_provider * -interpolant_provider::mk(ast_manager& m, params_ref const& p) { - // interpolations are windows specific and private. - return 0; -} - - -#endif - - -void interpolant_provider::output_interpolant(ast_manager& m, expr* A, expr* B, expr* I) { - static unsigned file_num = 0; - - std::ostringstream filename; - filename << "interpolation_" << file_num++ << ".smt"; - std::ofstream out(filename.str().c_str()); - - ast_smt_pp pp(m); - pp.add_assumption(A); - pp.display(out, B); - std::ostringstream strm; - strm << ";" << mk_pp(I, m) << "\n"; - - buffer buff; - std::string s = strm.str(); - char const* i_str = s.c_str(); - while (*i_str) { - buff.push_back(*i_str); - if (*i_str == '\n') { - buff.push_back(';'); - } - ++i_str; - } - buff.push_back(0); - out << buff.c_ptr(); - out << "##next##\n"; - out.close(); -} diff --git a/src/muz_qe/pdr_interpolant_provider.h b/src/muz_qe/pdr_interpolant_provider.h deleted file mode 100644 index 84197a265..000000000 --- a/src/muz_qe/pdr_interpolant_provider.h +++ /dev/null @@ -1,54 +0,0 @@ -/*++ -Copyright (c) 2011 Microsoft Corporation - -Module Name: - - interpolant_provider.h - -Abstract: - - Interface for obtaining interpolants. - -Author: - - Krystof Hoder (t-khoder) 2011-10-19. - -Revision History: - ---*/ - -#include "ast.h" -#include "lbool.h" -#include "model.h" -#include "params.h" - -#ifndef _PDR_INTERPOLANT_PROVIDER_H_ -#define _PDR_INTERPOLANT_PROVIDER_H_ - -class interpolant_provider -{ -protected: - ast_manager & m; - - interpolant_provider(ast_manager& m) : m(m) {} - -public: - - virtual ~interpolant_provider() {} - - /** - If (f1 /\ f2) is unsatisfiable, return true and into res assign a formula - I such that f1 --> I, I --> ~f2, and the language if I is in the intersection - of languages of f1 and f2. - - If (f1 /\ f2) is satisfiable, return false. - */ - virtual lbool get_interpolant(expr * f1, expr * f2, expr_ref& res) = 0; - - static interpolant_provider * mk(ast_manager& m, params_ref const& p); - - static void output_interpolant(ast_manager& m, expr* A, expr* B, expr* I); -}; - - -#endif diff --git a/src/muz_qe/pdr_manager.cpp b/src/muz_qe/pdr_manager.cpp index ad53f45db..04facc776 100644 --- a/src/muz_qe/pdr_manager.cpp +++ b/src/muz_qe/pdr_manager.cpp @@ -29,7 +29,6 @@ Revision History: #include "model_smt2_pp.h" #include "model_converter.h" - namespace pdr { class collect_decls_proc { @@ -143,11 +142,10 @@ namespace pdr { } } smt2_pp_environment_dbg env(m); - pp_params params; func_decl_set::iterator it = aux_decls.begin(), end = aux_decls.end(); for (; it != end; ++it) { func_decl* f = *it; - ast_smt2_pp(out, f, env, params); + ast_smt2_pp(out, f, env); out << "\n"; } @@ -168,7 +166,7 @@ namespace pdr { return res; } - manager::manager(front_end_params& fparams, params_ref const& params, ast_manager& manager) : + manager::manager(smt_params& fparams, fixedpoint_params const& params, ast_manager& manager) : m(manager), m_fparams(fparams), m_params(params), @@ -313,17 +311,8 @@ namespace pdr { else { return false; } - } - - - interpolant_provider& manager::get_interpolator() { - if(!m_interpolator) { - m_interpolator = interpolant_provider::mk(m, get_params()); - } - return *m_interpolator; - } - - + } + bool manager::implication_surely_holds(expr * lhs, expr * rhs, expr * bg) { smt::kernel sctx(m, get_fparams()); if(bg) { diff --git a/src/muz_qe/pdr_manager.h b/src/muz_qe/pdr_manager.h index 85f2116e9..cb2c9b253 100644 --- a/src/muz_qe/pdr_manager.h +++ b/src/muz_qe/pdr_manager.h @@ -32,7 +32,6 @@ Revision History: #include "pdr_util.h" #include "pdr_sym_mux.h" #include "pdr_farkas_learner.h" -#include "pdr_interpolant_provider.h" #include "pdr_smt_context_manager.h" #include "dl_rule.h" @@ -78,8 +77,8 @@ namespace pdr { class manager { ast_manager& m; - front_end_params& m_fparams; - params_ref const& m_params; + smt_params& m_fparams; + fixedpoint_params const& m_params; mutable bool_rewriter m_brwr; @@ -91,16 +90,6 @@ namespace pdr { /** whenever we need an unique number, we get this one and increase */ unsigned m_next_unique_num; - /** - It would make more sense to have interpolantor inside the prop_solver, - however we have one prop_solver instance in each relation. - Each instance of interpolant_provider creates a temporary file and - interpolant_provider can be shared, so it makes more sence to have - it in pdr_manager which is created only once. - */ - - scoped_ptr m_interpolator; - static vector get_state_suffixes(); @@ -110,12 +99,12 @@ namespace pdr { void add_new_state(func_decl * s); public: - manager(front_end_params& fparams, params_ref const& params, + manager(smt_params& fparams, fixedpoint_params const& params, ast_manager & manager); ast_manager& get_manager() const { return m; } - front_end_params& get_fparams() const { return m_fparams; } - params_ref const& get_params() const { return m_params; } + smt_params& get_fparams() const { return m_fparams; } + fixedpoint_params const& get_params() const { return m_params; } bool_rewriter& get_brwr() const { return m_brwr; } expr_ref mk_and(unsigned sz, expr* const* exprs); @@ -298,7 +287,6 @@ namespace pdr { expr* get_background() const { return m_background; } - interpolant_provider& get_interpolator(); /** Return true if we can show that lhs => rhs. The function can have false negatives diff --git a/src/muz_qe/pdr_prop_solver.cpp b/src/muz_qe/pdr_prop_solver.cpp index d70675d80..43d75b7bf 100644 --- a/src/muz_qe/pdr_prop_solver.cpp +++ b/src/muz_qe/pdr_prop_solver.cpp @@ -24,7 +24,7 @@ Revision History: #include "ast_smt2_pp.h" #include "dl_util.h" #include "model_pp.h" -#include "front_end_params.h" +#include "smt_params.h" #include "datatype_decl_plugin.h" #include "bv_decl_plugin.h" #include "pdr_farkas_learner.h" @@ -212,7 +212,7 @@ namespace pdr { m(pm.get_manager()), m_pm(pm), m_name(name), - m_try_minimize_core(pm.get_params().get_bool(":try-minimize-core", false)), + m_try_minimize_core(pm.get_params().try_minimize_core()), m_ctx(pm.mk_fresh()), m_pos_level_atoms(m), m_neg_level_atoms(m), diff --git a/src/muz_qe/pdr_prop_solver.h b/src/muz_qe/pdr_prop_solver.h index 15122a21a..165a37845 100644 --- a/src/muz_qe/pdr_prop_solver.h +++ b/src/muz_qe/pdr_prop_solver.h @@ -35,7 +35,7 @@ namespace pdr { class prop_solver { private: - front_end_params& m_fparams; + smt_params& m_fparams; ast_manager& m; manager& m_pm; symbol m_name; @@ -94,7 +94,7 @@ namespace pdr { scoped_level(prop_solver& ps, unsigned lvl):m_lev(ps.m_in_level) { SASSERT(!m_lev); m_lev = true; ps.m_current_level = lvl; } - ~scoped_level() { m_lev = false; } + ~scoped_level() { m_lev = false; } }; void add_formula(expr * form); diff --git a/src/muz_qe/pdr_quantifiers.cpp b/src/muz_qe/pdr_quantifiers.cpp index d52a0bf07..2816a58d4 100644 --- a/src/muz_qe/pdr_quantifiers.cpp +++ b/src/muz_qe/pdr_quantifiers.cpp @@ -19,11 +19,17 @@ Revision History: #include "pdr_quantifiers.h" #include "pdr_context.h" -#include "model_smt2_pp.h" -#include "ast_smt2_pp.h" #include "qe.h" #include "var_subst.h" #include "dl_rule_set.h" +#include "ast_smt2_pp.h" +#include "model_smt2_pp.h" +#include "ast_smt_pp.h" +#include "expr_abstract.h" +#include "dl_mk_extract_quantifiers.h" +#include "qe_lite.h" +#include "well_sorted.h" +#include "expr_safe_replace.h" namespace pdr { @@ -46,6 +52,12 @@ namespace pdr { } } + quantifier_model_checker::~quantifier_model_checker() { + obj_map::iterator it = m_reachable.begin(), end = m_reachable.end(); + for (; it != end; ++it) { + m.dec_ref(it->m_value); + } + } void quantifier_model_checker::generalize_binding(expr_ref_vector const& binding, vector& bindings) { expr_ref_vector new_binding(m); @@ -93,7 +105,11 @@ namespace pdr { } - void quantifier_model_checker::add_binding(quantifier* q, expr_ref_vector& binding) { + void quantifier_model_checker::add_binding(quantifier* q, expr_ref_vector& binding) { + if (binding.size() != q->get_num_decls()) { + // not a full binding. It may happen that the quantifier got simplified. + return; + } apply_binding(q, binding); vector bindings; generalize_binding(binding, bindings); @@ -103,21 +119,35 @@ namespace pdr { } void quantifier_model_checker::apply_binding(quantifier* q, expr_ref_vector& binding) { + datalog::scoped_no_proof _scp(m); app_ref_vector& var_inst = m_current_pt->get_inst(m_current_rule); - expr_substitution sub(m); - for (unsigned i = 0; i < var_inst.size(); ++i) { - expr* v = var_inst[i].get(); - sub.insert(v, m.mk_var(i, m.get_sort(v))); - } - scoped_ptr rep = mk_default_expr_replacer(m); - rep->set_substitution(&sub); expr_ref e(m); var_subst vs(m, false); + inv_var_shifter invsh(m); vs(q->get_expr(), binding.size(), binding.c_ptr(), e); - (*rep)(e); + invsh(e, q->get_num_decls(), e); + expr_ref_vector inst(m); + inst.append(var_inst.size(), (expr*const*)var_inst.c_ptr()); + inst.reverse(); + expr_abstract(m, 0, inst.size(), inst.c_ptr(), e, e); + if (m_instantiations.contains(to_app(e))) { + return; + } m_instantiated_rules.push_back(m_current_rule); m_instantiations.push_back(to_app(e)); - TRACE("pdr", tout << mk_pp(e, m) << "\n";); + TRACE("pdr", tout << mk_pp(q, m) << "\n"; + tout << "binding: "; + for (unsigned i = 0; i < binding.size(); ++i) { + tout << mk_pp(binding[i].get(), m) << " "; + } + tout << "\n"; + tout << "inst: "; + for (unsigned i = 0; i < var_inst.size(); ++i) { + tout << mk_pp(var_inst[i].get(), m) << " "; + } + tout << "\n"; + tout << mk_pp(e, m) << "\n"; + ); } @@ -179,35 +209,35 @@ namespace pdr { bool quantifier_model_checker::find_instantiations_proof_based(quantifier_ref_vector const& qs, unsigned level) { bool found_instance = false; - TRACE("pdr", tout << mk_pp(m_A,m) << "\n";); - ast_manager mp(PGM_COARSE); - ast_translation tr(m, mp); - ast_translation rev_tr(mp, m); - expr_ref_vector fmls(mp); - front_end_params fparams; - fparams.m_proof_mode = PGM_COARSE; - // TBD: does not work on integers: fparams.m_mbqi = true; - expr_ref C(m); - fmls.push_back(tr(m_A.get())); - for (unsigned i = 0; i < m_Bs.size(); ++i) { - C = m.update_quantifier(qs[i], m_Bs[i].get()); - fmls.push_back(tr(C.get())); - } + datalog::scoped_fine_proof _scp(m); + + expr_ref_vector fmls(m); + smt_params fparams; + SASSERT(m.proofs_enabled()); + fparams.m_mbqi = true; + + fmls.push_back(m_A.get()); + fmls.append(m_Bs); TRACE("pdr", tout << "assert\n"; for (unsigned i = 0; i < fmls.size(); ++i) { - tout << mk_pp(fmls[i].get(), mp) << "\n"; + tout << mk_pp(fmls[i].get(), m) << "\n"; }); - smt::kernel solver(mp, fparams); + + smt::kernel solver(m, fparams); for (unsigned i = 0; i < fmls.size(); ++i) { solver.assert_expr(fmls[i].get()); } lbool result = solver.check(); + + TRACE("pdr", tout << result << "\n";); + if (result != l_false) { - TRACE("pdr", tout << result << "\n";); - return found_instance; + return false; } + m_rules_model_check = false; + map qid_map; quantifier* q; for (unsigned i = 0; i < qs.size(); ++i) { @@ -216,53 +246,287 @@ namespace pdr { } proof* p = solver.get_proof(); - TRACE("pdr", tout << mk_ismt2_pp(p, mp) << "\n";); - collect_insts collector(mp); + TRACE("pdr", tout << mk_ismt2_pp(p, m) << "\n";); + collect_insts collector(m); for_each_expr(collector, p); ptr_vector const& quants = collector.quantifiers(); for (unsigned i = 0; i < collector.size(); ++i) { symbol qid = quants[i]->get_qid(); if (!qid_map.find(qid, q)) { - TRACE("pdr", tout << "Could not find quantifier " - << mk_pp(quants[i], mp) << "\n";); + TRACE("pdr", tout << "Could not find quantifier " << mk_pp(quants[i], m) << "\n";); continue; } expr_ref_vector const& binding = collector.bindings()[i]; - TRACE("pdr", tout << "Instantiating:\n" << mk_pp(quants[i], mp) << "\n"; + TRACE("pdr", tout << "Instantiating:\n" << mk_pp(quants[i], m) << "\n"; for (unsigned j = 0; j < binding.size(); ++j) { - tout << mk_pp(binding[j], mp) << " "; + tout << mk_pp(binding[j], m) << " "; } tout << "\n";); expr_ref_vector new_binding(m); for (unsigned j = 0; j < binding.size(); ++j) { - new_binding.push_back(rev_tr(binding[j])); + new_binding.push_back(binding[j]); } add_binding(q, new_binding); found_instance = true; } - if (collector.size() == 0) { - // Try to create dummy instances. - for (unsigned i = 0; i < m_Bs.size(); ++i) { - q = qs[i]; - expr_ref_vector binding(m); - for (unsigned j = 0; j < q->get_num_decls(); ++j) { - binding.push_back(m.mk_fresh_const("B", q->get_decl_sort(j))); - } - add_binding(q, binding); - } - found_instance = true; - } return found_instance; } + + /** + For under-approximations: + + m_reachable: set of reachable states, per predicate + + rules: P(x) :- B[x,y] & Fa z . Q(y,z) + Q(y,z) :- C[y,z,u] & Fa w . R(u,w) + + qis: Fa z . Q(y,z) + + M: model satisfying P(x) & B[x,y] + + B'[x,y]: body with reachable states substituted for predicates. + + Q'[y,z]: reachable states substituted for Q. + + S'[x]: Ex y . B'[x,y] & Fa z . Q'[y, z] + + Method: + + 1. M |= Fa z . Q'[y, z] => done + + Weaker variant: + Check B[x,y] & Fa z . Q'[y, z] for consistency. + + 2. Otherwise, extract instantiations. + + 3. Update reachable (for next round): + + Q'[y,z] := Q'[y,z] \/ C'[y,z,u] & Fa w . R'(u,w) + + */ + + + /** + For over-approximations: + + - pt - predicate transformer for rule: + P(x) :- Body1(x,y) || Body2(x,z) & (Fa u . Q(u,x,z)). + - rule - P(x) :- Body2(x,z) + + - qis - Fa u . Q(u,x,z) + + - A := node.state(x) && Body2(x,y) + + + - Bs := array of Bs of the form: + . Fa u . Q(u, P_x, P_y) - instantiate quantifier to P variables. + . B := inv(Q_0,Q_1,Q_2) + . B := inv(u, P_x, P_y) := B[u/Q_0, P_x/Q_1, P_y/Q_2] + . B := Fa u . inv(u, P_x, P_y) + + */ + + void quantifier_model_checker::update_reachable(func_decl* f, expr* e) { + expr* e_old; + m.inc_ref(e); + if (m_reachable.find(f, e_old)) { + m.dec_ref(e_old); + } + m_reachable.insert(f, e); + } + + + expr_ref quantifier_model_checker::get_reachable(func_decl* p) { + expr* e = 0; + if (!m_reachable.find(p, e)) { + e = m_ctx.get_pred_transformer(p).initial_state(); + update_reachable(p, e); + } + return expr_ref(e, m); + } + + void quantifier_model_checker::add_over_approximations(quantifier_ref_vector& qis, model_node& n) { + add_approximations(qis, n, true); + } + + void quantifier_model_checker::add_under_approximations(quantifier_ref_vector& qis, model_node& n) { + add_approximations(qis, n, false); + } + + void quantifier_model_checker::add_approximations(quantifier_ref_vector& qis, model_node& n, bool is_over) { + pred_transformer& pt = n.pt(); + manager& pm = pt.get_pdr_manager(); + unsigned level = n.level(); + expr_ref_vector Bs(m); + expr_ref B(m), v(m); + quantifier_ref q(m); + datalog::scoped_no_proof _no_proof(m); + scoped_ptr rep = mk_default_expr_replacer(m); + for (unsigned j = 0; j < qis.size(); ++j) { + q = qis[j].get(); + SASSERT(is_forall(q)); + app_ref_vector& inst = pt.get_inst(m_current_rule); + TRACE("pdr", + tout << "q:\n" << mk_pp(q, m) << "\n"; + tout << "level: " << level << "\n"; + model_smt2_pp(tout, m, n.get_model(), 0); + m_current_rule->display(m_ctx.get_context(), tout << "rule:\n"); + ); + + var_subst vs(m, false); + vs(q, inst.size(), (expr*const*)inst.c_ptr(), B); + q = to_quantifier(B); + TRACE("pdr", tout << "q instantiated:\n" << mk_pp(q, m) << "\n";); + + app* a = to_app(q->get_expr()); + func_decl* f = a->get_decl(); + pred_transformer& pt2 = m_ctx.get_pred_transformer(f); + if (is_over) { + B = pt2.get_formulas(level - 1, false); + } + else { + B = get_reachable(f); + SASSERT(is_well_sorted(m, B)); + } + TRACE("pdr", tout << "B:\n" << mk_pp(B, m) << "\n";); + + expr_safe_replace sub(m); + for (unsigned i = 0; i < a->get_num_args(); ++i) { + v = m.mk_const(pm.o2n(pt2.sig(i),0)); + sub.insert(v, a->get_arg(i)); + } + sub(B); + TRACE("pdr", tout << "B substituted:\n" << mk_pp(B, m) << "\n";); + datalog::flatten_and(B, Bs); + for (unsigned i = 0; i < Bs.size(); ++i) { + m_Bs.push_back(m.update_quantifier(q, Bs[i].get())); + } + } + } + + /** + \brief compute strongest post-conditions for each predicate transformer. + (or at least something sufficient to change the set of current counter-examples) + */ + void quantifier_model_checker::weaken_under_approximation() { + + datalog::rule_set::decl2rules::iterator it = m_rules.begin_grouped_rules(), end = m_rules.end_grouped_rules(); + + for (; it != end; ++it) { + func_decl* p = it->m_key; + datalog::rule_vector& rules = *it->m_value; + expr_ref_vector bodies(m); + for (unsigned i = 0; i < rules.size(); ++i) { + bodies.push_back(strongest_post_condition(*rules[i])); + } + update_reachable(p, m.mk_or(bodies.size(), bodies.c_ptr())); + } + } + + expr_ref quantifier_model_checker::strongest_post_condition(datalog::rule& r) { + pred_transformer& pt = m_ctx.get_pred_transformer(r.get_decl()); + manager& pm = pt.get_pdr_manager(); + quantifier_ref_vector* qis = 0; + m_quantifiers.find(&r, qis); + expr_ref_vector body(m), inst(m); + expr_ref fml(m), v(m); + app* a; + func_decl* p; + svector names; + unsigned ut_size = r.get_uninterpreted_tail_size(); + unsigned t_size = r.get_tail_size(); + var_subst vs(m, false); + sort_ref_vector vars(m); + uint_set empty_index_set; + qe_lite qe(m); + + r.get_vars(vars); +#if 1 + if (qis) { + quantifier_ref_vector const& qi = *qis; + for (unsigned i = 0; i < qi.size(); ++i) { + quantifier* q = qi[i]; + fml = q->get_expr(); + a = to_app(fml); + p = a->get_decl(); + expr* p_reach = get_reachable(p); + pred_transformer& pt2 = m_ctx.get_pred_transformer(p); + expr_safe_replace sub(m); + for (unsigned j = 0; j < a->get_num_args(); ++j) { + v = m.mk_const(pm.o2n(pt2.sig(j),0)); + sub.insert(v, a->get_arg(j)); + } + sub(p_reach, fml); + uint_set is; + for (unsigned j = 0; j < q->get_num_decls(); ++j) { + is.insert(j); + } + fml = m.mk_not(fml); + qe(is, true, fml); + fml = m.mk_not(fml); + body.push_back(m.update_quantifier(q, fml)); + } + } +#endif + a = r.get_head(); + for (unsigned i = 0; i < a->get_num_args(); ++i) { + v = m.mk_var(vars.size()+i, m.get_sort(a->get_arg(i))); + body.push_back(m.mk_eq(v, a->get_arg(i))); + } + for (unsigned i = 0; i < ut_size; ++i) { + a = r.get_tail(i); + p = a->get_decl(); + pred_transformer& pt2 = m_ctx.get_pred_transformer(p); + expr* p_reach = get_reachable(p); + expr_safe_replace sub(m); + for (unsigned i = 0; i < a->get_num_args(); ++i) { + v = m.mk_const(pm.o2n(pt2.sig(i),0)); + sub.insert(v, a->get_arg(i)); + } + sub(p_reach, fml); + body.push_back(fml); + } + for (unsigned i = ut_size; i < t_size; ++i) { + body.push_back(r.get_tail(i)); + } + fml = m.mk_and(body.size(), body.c_ptr()); + vars.reverse(); + for (unsigned i = 0; i < vars.size(); ++i) { + names.push_back(symbol(i)); + } + if (!vars.empty()) { + fml = m.mk_exists(vars.size(), vars.c_ptr(), names.c_ptr(), fml); + SASSERT(is_well_sorted(m, fml)); + } + + for (unsigned i = 0; i < r.get_head()->get_num_args(); ++i) { + inst.push_back(m.mk_const(pm.o2n(pt.sig(i),0))); + } + vs(fml, inst.size(), inst.c_ptr(), fml); + SASSERT(is_well_sorted(m, fml)); + if (!vars.empty()) { + fml = to_quantifier(fml)->get_expr(); + qe(empty_index_set, false, fml); + fml = m.mk_exists(vars.size(), vars.c_ptr(), names.c_ptr(), fml); + SASSERT(is_well_sorted(m, fml)); + m_ctx.get_context().get_rewriter()(fml); + } + SASSERT(is_well_sorted(m, fml)); + + IF_VERBOSE(0, verbose_stream() << "instantiate to:\n" << mk_pp(fml, m) << "\n";); + return fml; + } + + void quantifier_model_checker::model_check_node(model_node& node) { TRACE("pdr", node.display(tout, 0);); pred_transformer& pt = node.pt(); manager& pm = pt.get_pdr_manager(); - expr_ref A(m), B(m), C(m); + expr_ref A(m), C(m); expr_ref_vector As(m); m_Bs.reset(); // @@ -272,7 +536,7 @@ namespace pdr { if (!node.get_model_ptr()) { return; } - m_current_rule = &pt.find_rule(node.get_model()); + m_current_rule = node.get_rule(); m_current_pt = &pt; m_current_node = &node; if (!m_current_rule) { @@ -285,49 +549,36 @@ namespace pdr { return; } unsigned level = node.level(); - unsigned previous_level = (level == 0)?0:(level-1); - + if (level == 0) { + return; + } + As.push_back(pt.get_propagation_formula(m_ctx.get_pred_transformers(), level)); As.push_back(node.state()); As.push_back(pt.rule2tag(m_current_rule)); m_A = pm.mk_and(As); // Add quantifiers: - - { - datalog::scoped_no_proof _no_proof(m); - scoped_ptr rep = mk_default_expr_replacer(m); - for (unsigned j = 0; j < qis->size(); ++j) { - quantifier* q = (*qis)[j].get(); - app* a = to_app(q->get_expr()); - func_decl* f = a->get_decl(); - pred_transformer& pt2 = m_ctx.get_pred_transformer(f); - B = pt2.get_formulas(previous_level, true); - - expr_substitution sub(m); - expr_ref_vector refs(m); - for (unsigned i = 0; i < a->get_num_args(); ++i) { - expr* v = m.mk_const(pm.o2n(pt2.sig(i),0)); - sub.insert(v, a->get_arg(i)); - refs.push_back(v); - } - rep->set_substitution(&sub); - (*rep)(B); - app_ref_vector& inst = pt.get_inst(m_current_rule); - ptr_vector& aux_vars = pt.get_aux_vars(*m_current_rule); - pt.ground_free_vars(B, inst, aux_vars); - var_subst vs(m, false); - vs(B, inst.size(), (expr*const*)inst.c_ptr(), B); - m_Bs.push_back(B); - } - } + // add_over_approximations(*qis, node); + add_under_approximations(*qis, node); TRACE("pdr", tout << "A:\n" << mk_pp(m_A, m) << "\n"; + tout << "quantifier:\n"; + for (unsigned i = 0; i < qis->size(); ++i) { + tout << mk_pp((*qis)[i].get(), m) << " "; + } + tout << "\n"; tout << "B:\n"; for (unsigned i = 0; i < m_Bs.size(); ++i) { - tout << mk_pp((*qis)[i].get(), m) << "\n" << mk_pp(m_Bs[i].get(), m) << "\n"; + tout << mk_pp(m_Bs[i].get(), m) << "\n"; } + ast_smt_pp pp(m); + pp.add_assumption(m_A); + for (unsigned i = 0; i < m_Bs.size(); ++i) { + pp.add_assumption(m_Bs[i].get()); + } + pp.display_smt2(tout, m.mk_true()); ); find_instantiations(*qis, level); @@ -336,26 +587,32 @@ namespace pdr { bool quantifier_model_checker::model_check(model_node& root) { m_instantiations.reset(); m_instantiated_rules.reset(); + m_rules_model_check = true; ptr_vector nodes; get_nodes(root, nodes); for (unsigned i = nodes.size(); i > 0; ) { --i; model_check_node(*nodes[i]); } - return m_instantiations.empty(); + if (!m_rules_model_check) { + weaken_under_approximation(); + } + return m_rules_model_check; } void quantifier_model_checker::refine() { - IF_VERBOSE(1, verbose_stream() << "instantiating quantifiers\n";); - datalog::rule_manager& rule_m = m_rules.get_rule_manager(); + datalog::mk_extract_quantifiers eq(m_ctx.get_context()); + datalog::rule_manager& rm = m_rules.get_rule_manager(); datalog::rule_set new_rules(m_rules.get_context()); datalog::rule_set::iterator it = m_rules.begin(), end = m_rules.end(); for (; it != end; ++it) { datalog::rule* r = *it; - expr_ref_vector body(m); + datalog::var_counter vc(true); + unsigned max_var = vc.get_max_var(*r); + app_ref_vector body(m); for (unsigned i = 0; i < m_instantiations.size(); ++i) { if (r == m_instantiated_rules[i]) { - body.push_back(m_instantiations[i].get()); + eq.ensure_predicate(m_instantiations[i].get(), max_var, body); } } if (body.empty()) { @@ -367,17 +624,19 @@ namespace pdr { } quantifier_ref_vector* qs = 0; m_quantifiers.find(r, qs); - m_quantifiers.remove(r); - datalog::rule_ref_vector rules(rule_m); - expr_ref rule(m.mk_implies(m.mk_and(body.size(), body.c_ptr()), r->get_head()), m); - rule_m.mk_rule(rule, rules, r->name()); - for (unsigned i = 0; i < rules.size(); ++i) { - new_rules.add_rule(rules[i].get()); - m_quantifiers.insert(rules[i].get(), qs); - } + m_quantifiers.remove(r); + datalog::rule_ref new_rule(rm); + new_rule = rm.mk(r->get_head(), body.size(), body.c_ptr(), 0, r->name(), false); + new_rules.add_rule(new_rule); + m_quantifiers.insert(new_rule, qs); + IF_VERBOSE(1, + verbose_stream() << "instantiating quantifiers\n"; + r->display(m_ctx.get_context(), verbose_stream()); + verbose_stream() << "replaced by\n"; + new_rule->display(m_ctx.get_context(), verbose_stream());); } } - new_rules.close(); + new_rules.close(); m_rules.reset(); m_rules.add_rules(new_rules); m_rules.close(); @@ -394,136 +653,3 @@ namespace pdr { } }; - -#if 0 - // - // Build: - // - // A & forall x . B1 & forall y . B2 & ... - // = - // not exists x y . (!A or !B1 or !B2 or ...) - // - // Find an instance that satisfies formula. - // (or find all instances?) - // - bool quantifier_model_checker::find_instantiations_qe_based(quantifier_ref_vector const& qs, unsigned level) { - expr_ref_vector fmls(m), conjs(m), fresh_vars(m); - app_ref_vector all_vars(m); - expr_ref C(m); - qe::def_vector defs(m); - front_end_params fparams; - qe::expr_quant_elim qe(m, fparams); - for (unsigned i = 0; i < m_Bs.size(); ++i) { - quantifier* q = qs[i]; - unsigned num_decls = q->get_num_decls(); - unsigned offset = all_vars.size(); - for (unsigned j = 0; j < num_decls; ++j) { - all_vars.push_back(m.mk_fresh_const("V",q->get_decl_sort(j))); - } - var_subst varsubst(m, false); - varsubst(m_Bs[i].get(), num_decls, (expr**)(all_vars.c_ptr() + offset), C); - fmls.push_back(C); - } - conjs.push_back(m_A); - conjs.push_back(m.mk_not(m.mk_and(fmls.size(), fmls.c_ptr()))); - // add previous instances. - expr* r = m.mk_and(m_Bs.size(), m_Bs.c_ptr()); - m_trail.push_back(r); - expr* inst; - if (!m_bound.find(m_current_rule, r, inst)) { - TRACE("pdr", tout << "did not find: " << mk_pp(r, m) << "\n";); - m_trail.push_back(r);Newton Sanches - inst = m.mk_true(); - m_bound.insert(m_current_rule, r, inst); - } - else { - TRACE("pdr", tout << "blocking: " << mk_pp(inst, m) << "\n";); - conjs.push_back(inst); - } - C = m.mk_and(conjs.size(), conjs.c_ptr()); - lbool result = qe.first_elim(all_vars.size(), all_vars.c_ptr(), C, defs); - TRACE("pdr", tout << mk_pp(C.get(), m) << "\n" << result << "\n";); - if (result != l_true) { - return false; - } - inst = m.mk_and(inst, m.mk_not(C)); - m_trail.push_back(inst); - m_bound.insert(m_current_rule, r, inst); - TRACE("pdr", - tout << "Instantiating\n"; - for (unsigned i = 0; i < defs.size(); ++i) { - tout << defs.var(i)->get_name() << " " << mk_pp(defs.def(i), m) << "\n"; - } - ); - expr_substitution sub(m); - for (unsigned i = 0; i < defs.size(); ++i) { - sub.insert(m.mk_const(defs.var(i)), defs.def(i)); - } - scoped_ptr rep = mk_default_expr_replacer(m); - rep->set_substitution(&sub); - for (unsigned i = 0; i < all_vars.size(); ++i) { - expr_ref tmp(all_vars[i].get(), m); - (*rep)(tmp); - all_vars[i] = to_app(tmp); - } - unsigned offset = 0; - for (unsigned i = 0; i < m_Bs.size(); ++i) { - quantifier* q = qs[i]; - unsigned num_decls = q->get_num_decls(); - expr_ref_vector new_binding(m); - for (unsigned j = 0; j < num_decls; ++j) { - new_binding.push_back(all_vars[offset+j].get()); - } - offset += num_decls; - add_binding(q, new_binding); - } - return true; - } - - bool quantifier_model_checker::find_instantiations_model_based(quantifier_ref_vector const& qs, unsigned level) { - bool found_instance = false; - expr_ref C(m); - front_end_params fparams; - smt::kernel solver(m, fparams); - solver.assert_expr(m_A); - for (unsigned i = 0; i < m_Bs.size(); ++i) { - expr_ref_vector fresh_vars(m); - quantifier* q = qs[i]; - for (unsigned j = 0; j < q->get_num_decls(); ++j) { - fresh_vars.push_back(m.mk_fresh_const("V",q->get_decl_sort(j))); - } - var_subst varsubst(m, false); - varsubst(m_Bs[i].get(), fresh_vars.size(), fresh_vars.c_ptr(), C); - TRACE("pdr", tout << "updated propagation formula: " << mk_pp(C,m) << "\n";); - - solver.push(); - // TBD: what to do with the different tags when unfolding the same predicate twice? - solver.assert_expr(m.mk_not(C)); - lbool result = solver.check(); - if (result == l_true) { - found_instance = true; - model_ref mr; - solver.get_model(mr); - TRACE("pdr", model_smt2_pp(tout, m, *mr, 0);); - - expr_ref_vector insts(m); - for (unsigned j = 0; j < fresh_vars.size(); ++j) { - expr* interp = mr->get_const_interp(to_app(fresh_vars[j].get())->get_decl()); - if (interp) { - insts.push_back(interp); - } - else { - insts.push_back(fresh_vars[j].get()); - } - TRACE("pdr", tout << mk_pp(insts.back(), m) << "\n";); - } - add_binding(q, insts); - } - solver.pop(1); - } - return found_instance; - } - - -#endif - diff --git a/src/muz_qe/pdr_quantifiers.h b/src/muz_qe/pdr_quantifiers.h index bae323cf8..2a7dcaf2c 100644 --- a/src/muz_qe/pdr_quantifiers.h +++ b/src/muz_qe/pdr_quantifiers.h @@ -33,24 +33,27 @@ namespace pdr { class model_node; class pred_transformer; class context; - - + class quantifier_model_checker { context& m_ctx; ast_manager& m; obj_map& m_quantifiers; datalog::rule_set& m_rules; - expr_ref_vector m_trail; + + obj_map m_reachable; // set of reachable states expr_ref m_A; expr_ref_vector m_Bs; pred_transformer* m_current_pt; datalog::rule const* m_current_rule; model_node* m_current_node; + bool m_rules_model_check; app_ref_vector m_instantiations; ptr_vector m_instantiated_rules; void model_check_node(model_node& node); + void weaken_under_approximation(); + bool find_instantiations(quantifier_ref_vector const& qs, unsigned level); bool find_instantiations_model_based(quantifier_ref_vector const& qs, unsigned level); @@ -79,6 +82,18 @@ namespace pdr { bool model_check(model_node& root); + void add_over_approximations(quantifier_ref_vector& qis, model_node& n); + + void add_under_approximations(quantifier_ref_vector& qis, model_node& n); + + void add_approximations(quantifier_ref_vector& qis, model_node& n, bool is_over); + + expr_ref get_reachable(func_decl* f); + + void update_reachable(func_decl* f, expr* e); + + expr_ref strongest_post_condition(datalog::rule& r); + public: quantifier_model_checker( context& ctx, @@ -89,9 +104,14 @@ namespace pdr { m(m), m_quantifiers(quantifiers), m_rules(rules), - m_trail(m), m_A(m), m_Bs(m), - m_current_pt(0), m_current_rule(0), - m_current_node(0), m_instantiations(m) {} + m_A(m), + m_Bs(m), + m_current_pt(0), + m_current_rule(0), + m_current_node(0), + m_instantiations(m) {} + + ~quantifier_model_checker(); bool check(); }; diff --git a/src/muz_qe/pdr_reachable_cache.cpp b/src/muz_qe/pdr_reachable_cache.cpp index ed9926f85..4f4f620de 100644 --- a/src/muz_qe/pdr_reachable_cache.cpp +++ b/src/muz_qe/pdr_reachable_cache.cpp @@ -21,13 +21,13 @@ Revision History: namespace pdr { - reachable_cache::reachable_cache(pdr::manager & pm, params_ref const& params) + reachable_cache::reachable_cache(pdr::manager & pm, fixedpoint_params const& params) : m(pm.get_manager()), m_pm(pm), m_ctx(0), m_ref_holder(m), m_disj_connector(m), - m_cache_mode((datalog::PDR_CACHE_MODE)params.get_uint(":cache-mode",0)) { + m_cache_mode((datalog::PDR_CACHE_MODE)params.cache_mode()) { if (m_cache_mode == datalog::CONSTRAINT_CACHE) { m_ctx = pm.mk_fresh(); m_ctx->assert_expr(m_pm.get_background()); diff --git a/src/muz_qe/pdr_reachable_cache.h b/src/muz_qe/pdr_reachable_cache.h index d8096f15c..48caa22a5 100644 --- a/src/muz_qe/pdr_reachable_cache.h +++ b/src/muz_qe/pdr_reachable_cache.h @@ -17,14 +17,13 @@ Revision History: --*/ -#include "ast.h" -#include "params.h" -#include "ref_vector.h" -#include "pdr_manager.h" -#include "pdr_smt_context_manager.h" #ifndef _REACHABLE_CACHE_H_ #define _REACHABLE_CACHE_H_ +#include "ast.h" +#include "ref_vector.h" +#include "pdr_manager.h" +#include "pdr_smt_context_manager.h" namespace pdr { class reachable_cache { @@ -48,7 +47,7 @@ namespace pdr { void add_disjuncted_formula(expr * f); public: - reachable_cache(pdr::manager & pm, params_ref const& params); + reachable_cache(pdr::manager & pm, fixedpoint_params const& params); void add_init(app * f) { add_disjuncted_formula(f); } diff --git a/src/muz_qe/pdr_smt_context_manager.cpp b/src/muz_qe/pdr_smt_context_manager.cpp index d79192769..ca308954c 100644 --- a/src/muz_qe/pdr_smt_context_manager.cpp +++ b/src/muz_qe/pdr_smt_context_manager.cpp @@ -21,7 +21,7 @@ Revision History: #include "has_free_vars.h" #include "ast_pp.h" #include -#include "front_end_params.h" +#include "smt_params.h" namespace pdr { @@ -93,10 +93,10 @@ namespace pdr { return m_context.get_proof(); } - smt_context_manager::smt_context_manager(front_end_params& fp, params_ref const& p, ast_manager& m): + smt_context_manager::smt_context_manager(smt_params& fp, fixedpoint_params const& p, ast_manager& m): m_fparams(fp), m(m), - m_max_num_contexts(p.get_uint(":max-num-contexts", 500)), + m_max_num_contexts(p.max_num_contexts()), m_num_contexts(0), m_predicate_list(m) { } diff --git a/src/muz_qe/pdr_smt_context_manager.h b/src/muz_qe/pdr_smt_context_manager.h index 31fb8ccb3..7d6eebfbd 100644 --- a/src/muz_qe/pdr_smt_context_manager.h +++ b/src/muz_qe/pdr_smt_context_manager.h @@ -23,6 +23,7 @@ Revision History: #include "smt_kernel.h" #include "sat_solver.h" #include "func_decl_dependencies.h" +#include "dl_util.h" namespace pdr { @@ -88,7 +89,7 @@ namespace pdr { }; class smt_context_manager { - front_end_params& m_fparams; + smt_params& m_fparams; ast_manager& m; unsigned m_max_num_contexts; ptr_vector m_contexts; @@ -96,7 +97,7 @@ namespace pdr { app_ref_vector m_predicate_list; func_decl_set m_predicate_set; public: - smt_context_manager(front_end_params& fp, params_ref const& p, ast_manager& m); + smt_context_manager(smt_params& fp, fixedpoint_params const& p, ast_manager& m); ~smt_context_manager(); smt_context* mk_fresh(); void collect_statistics(statistics& st) const; diff --git a/src/muz_qe/pdr_util.cpp b/src/muz_qe/pdr_util.cpp index 512d94956..fd08b1aad 100644 --- a/src/muz_qe/pdr_util.cpp +++ b/src/muz_qe/pdr_util.cpp @@ -30,7 +30,7 @@ Notes: #include "bool_rewriter.h" #include "dl_util.h" #include "for_each_expr.h" -#include "front_end_params.h" +#include "smt_params.h" #include "model.h" #include "model_v2_pp.h" #include "ref_vector.h" @@ -87,558 +87,569 @@ namespace pdr { } -///////////////////////// -// model_evaluator -// - -void model_evaluator::assign_value(expr* e, expr* val) { - rational r; - if (m.is_true(val)) { - set_true(e); - } - else if (m.is_false(val)) { - set_false(e); - } - else if (m_arith.is_numeral(val, r)) { - set_number(e, r); - } - else if (m.is_value(val)) { - set_value(e, val); - } - else { - IF_VERBOSE(3, verbose_stream() << "Not evaluated " << mk_pp(e, m) << "\n";); - TRACE("pdr", tout << "Variable is not tracked: " << mk_pp(e, m) << "\n";); - set_x(e); - } -} - -void model_evaluator::setup_model(model_ref& model) { - m_numbers.reset(); - m_values.reset(); - m_model = model; - rational r; - unsigned sz = model->get_num_constants(); - for (unsigned i = 0; i < sz; i++) { - func_decl * d = model->get_constant(i); - expr* val = model->get_const_interp(d); - expr* e = m.mk_const(d); - m_refs.push_back(e); - assign_value(e, val); - } -} - -void model_evaluator::reset() { - m1.reset(); - m2.reset(); - m_values.reset(); - m_visited.reset(); - m_numbers.reset(); - m_refs.reset(); - m_model = 0; -} - -expr_ref_vector model_evaluator::minimize_model(ptr_vector const & formulas, model_ref& mdl) { - setup_model(mdl); - - TRACE("pdr_verbose", - tout << "formulas:\n"; - for (unsigned i = 0; i < formulas.size(); ++i) tout << mk_pp(formulas[i], m) << "\n"; - ); - - expr_ref_vector model = prune_by_cone_of_influence(formulas); - TRACE("pdr_verbose", - tout << "pruned model:\n"; - for (unsigned i = 0; i < model.size(); ++i) tout << mk_pp(model[i].get(), m) << "\n";); - - reset(); - - DEBUG_CODE( - setup_model(mdl); - VERIFY(check_model(formulas)); - reset();); - - return model; -} - -expr_ref_vector model_evaluator::minimize_literals(ptr_vector const& formulas, model_ref& mdl) { - - TRACE("pdr", - tout << "formulas:\n"; - for (unsigned i = 0; i < formulas.size(); ++i) tout << mk_pp(formulas[i], m) << "\n"; - ); - - expr_ref_vector result(m); - ptr_vector tocollect; + ///////////////////////// + // model_evaluator + // - setup_model(mdl); - collect(formulas, tocollect); - for (unsigned i = 0; i < tocollect.size(); ++i) { - expr* e = tocollect[i]; - SASSERT(m.is_bool(e)); - SASSERT(is_true(e) || is_false(e)); - if (is_true(e)) { - result.push_back(e); + + void model_evaluator::assign_value(expr* e, expr* val) { + rational r; + if (m.is_true(val)) { + set_true(e); + } + else if (m.is_false(val)) { + set_false(e); + } + else if (m_arith.is_numeral(val, r)) { + set_number(e, r); + } + else if (m.is_value(val)) { + set_value(e, val); } else { - result.push_back(m.mk_not(e)); + IF_VERBOSE(3, verbose_stream() << "Not evaluated " << mk_pp(e, m) << "\n";); + TRACE("pdr", tout << "Variable is not tracked: " << mk_pp(e, m) << "\n";); + set_x(e); } } - reset(); - return result; -} -void model_evaluator::process_formula(app* e, ptr_vector& todo, ptr_vector& tocollect) { - SASSERT(m.is_bool(e)); - SASSERT(is_true(e) || is_false(e)); - unsigned v = is_true(e); - unsigned sz = e->get_num_args(); - expr* const* args = e->get_args(); - if (e->get_family_id() == m.get_basic_family_id()) { - switch(e->get_decl_kind()) { - case OP_TRUE: - break; - case OP_FALSE: - break; - case OP_EQ: - case OP_IFF: - if (args[0] == args[1]) { - SASSERT(v); - // no-op + void model_evaluator::setup_model(model_ref& model) { + m_numbers.reset(); + m_values.reset(); + m_model = model; + rational r; + unsigned sz = model->get_num_constants(); + for (unsigned i = 0; i < sz; i++) { + func_decl * d = model->get_constant(i); + expr* val = model->get_const_interp(d); + expr* e = m.mk_const(d); + m_refs.push_back(e); + assign_value(e, val); + } + } + + void model_evaluator::reset() { + m1.reset(); + m2.reset(); + m_values.reset(); + m_visited.reset(); + m_numbers.reset(); + m_refs.reset(); + m_model = 0; + } + + expr_ref_vector model_evaluator::minimize_model(ptr_vector const & formulas, model_ref& mdl) { + setup_model(mdl); + + TRACE("pdr_verbose", + tout << "formulas:\n"; + for (unsigned i = 0; i < formulas.size(); ++i) tout << mk_pp(formulas[i], m) << "\n"; + ); + + expr_ref_vector model = prune_by_cone_of_influence(formulas); + TRACE("pdr_verbose", + tout << "pruned model:\n"; + for (unsigned i = 0; i < model.size(); ++i) tout << mk_pp(model[i].get(), m) << "\n";); + + reset(); + + DEBUG_CODE( + setup_model(mdl); + VERIFY(check_model(formulas)); + reset();); + + return model; + } + + expr_ref_vector model_evaluator::minimize_literals(ptr_vector const& formulas, model_ref& mdl) { + + TRACE("pdr", + tout << "formulas:\n"; + for (unsigned i = 0; i < formulas.size(); ++i) tout << mk_pp(formulas[i], m) << "\n"; + ); + + expr_ref_vector result(m); + expr_ref tmp(m); + ptr_vector tocollect; + + setup_model(mdl); + collect(formulas, tocollect); + for (unsigned i = 0; i < tocollect.size(); ++i) { + expr* e = tocollect[i]; + expr* e1, *e2; + SASSERT(m.is_bool(e)); + SASSERT(is_true(e) || is_false(e)); + if (is_true(e)) { + result.push_back(e); } - else if (!m.is_bool(args[0])) { - tocollect.push_back(e); - } - else { - todo.append(sz, args); - } - break; - case OP_DISTINCT: - tocollect.push_back(e); - break; - case OP_ITE: - if (args[1] == args[2]) { - tocollect.push_back(args[1]); - } - else if (is_true(args[1]) && is_true(args[2])) { - todo.append(2, args+1); - } - else if (is_false(args[1]) && is_false(args[2])) { - todo.append(2, args+1); - } - else if (is_true(args[0])) { - todo.append(2, args); - } - else { - SASSERT(is_false(args[0])); - todo.push_back(args[0]); - todo.push_back(args[2]); - } - break; - case OP_AND: - if (v) { - todo.append(sz, args); - } - else { - unsigned i = 0; - for (; !is_false(args[i]) && i < sz; ++i); - if (i == sz) { - fatal_error(1); - } - VERIFY(i < sz); - todo.push_back(args[i]); - } - break; - case OP_OR: - if (v) { - unsigned i = 0; - for (; !is_true(args[i]) && i < sz; ++i); - if (i == sz) { - fatal_error(1); - } - VERIFY(i < sz); - todo.push_back(args[i]); - } - else { - todo.append(sz, args); - } - break; - case OP_XOR: - case OP_NOT: - todo.append(sz, args); - break; - case OP_IMPLIES: - if (v) { - if (is_true(args[1])) { - todo.push_back(args[1]); - } - else if (is_false(args[0])) { - todo.push_back(args[0]); + // hack to break disequalities for arithmetic variables. + else if (m.is_eq(e, e1, e2) && m_arith.is_int_real(e1)) { + if (get_number(e1) < get_number(e2)) { + result.push_back(m_arith.mk_lt(e1,e2)); } else { - IF_VERBOSE(0, verbose_stream() << "Term not handled " << mk_pp(e, m) << "\n";); - UNREACHABLE(); + result.push_back(m_arith.mk_lt(e2,e1)); } } else { - todo.append(sz, args); + result.push_back(m.mk_not(e)); } + } + reset(); + TRACE("pdr", + tout << "minimized model:\n"; + for (unsigned i = 0; i < result.size(); ++i) tout << mk_pp(result[i].get(), m) << "\n"; + ); + + return result; + } + + void model_evaluator::process_formula(app* e, ptr_vector& todo, ptr_vector& tocollect) { + SASSERT(m.is_bool(e)); + SASSERT(is_true(e) || is_false(e)); + unsigned v = is_true(e); + unsigned sz = e->get_num_args(); + expr* const* args = e->get_args(); + if (e->get_family_id() == m.get_basic_family_id()) { + switch(e->get_decl_kind()) { + case OP_TRUE: + break; + case OP_FALSE: + break; + case OP_EQ: + case OP_IFF: + if (args[0] == args[1]) { + SASSERT(v); + // no-op + } + else if (m.is_bool(args[0])) { + todo.append(sz, args); + } + else { + tocollect.push_back(e); + } + break; + case OP_DISTINCT: + tocollect.push_back(e); + break; + case OP_ITE: + if (args[1] == args[2]) { + tocollect.push_back(args[1]); + } + else if (is_true(args[1]) && is_true(args[2])) { + todo.append(2, args+1); + } + else if (is_false(args[1]) && is_false(args[2])) { + todo.append(2, args+1); + } + else if (is_true(args[0])) { + todo.append(2, args); + } + else { + SASSERT(is_false(args[0])); + todo.push_back(args[0]); + todo.push_back(args[2]); + } + break; + case OP_AND: + if (v) { + todo.append(sz, args); + } + else { + unsigned i = 0; + for (; !is_false(args[i]) && i < sz; ++i); + if (i == sz) { + fatal_error(1); + } + VERIFY(i < sz); + todo.push_back(args[i]); + } + break; + case OP_OR: + if (v) { + unsigned i = 0; + for (; !is_true(args[i]) && i < sz; ++i); + if (i == sz) { + fatal_error(1); + } + VERIFY(i < sz); + todo.push_back(args[i]); + } + else { + todo.append(sz, args); + } + break; + case OP_XOR: + case OP_NOT: + todo.append(sz, args); + break; + case OP_IMPLIES: + if (v) { + if (is_true(args[1])) { + todo.push_back(args[1]); + } + else if (is_false(args[0])) { + todo.push_back(args[0]); + } + else { + IF_VERBOSE(0, verbose_stream() << "Term not handled " << mk_pp(e, m) << "\n";); + UNREACHABLE(); + } + } + else { + todo.append(sz, args); + } + break; + default: + IF_VERBOSE(0, verbose_stream() << "Term not handled " << mk_pp(e, m) << "\n";); + UNREACHABLE(); + } + } + else { + tocollect.push_back(e); + } + } + + void model_evaluator::collect(ptr_vector const& formulas, ptr_vector& tocollect) { + ptr_vector todo; + todo.append(formulas); + m_visited.reset(); + + VERIFY(check_model(formulas)); + + while (!todo.empty()) { + app* e = to_app(todo.back()); + todo.pop_back(); + if (!m_visited.is_marked(e)) { + process_formula(e, todo, tocollect); + m_visited.mark(e, true); + } + } + m_visited.reset(); + } + + expr_ref_vector model_evaluator::prune_by_cone_of_influence(ptr_vector const & formulas) { + ptr_vector tocollect; + collect(formulas, tocollect); + m1.reset(); + m2.reset(); + for (unsigned i = 0; i < tocollect.size(); ++i) { + TRACE("pdr_verbose", tout << "collect: " << mk_pp(tocollect[i], m) << "\n";); + for_each_expr(*this, m_visited, tocollect[i]); + } + unsigned sz = m_model->get_num_constants(); + expr_ref e(m), eq(m), val(m); + expr_ref_vector model(m); + for (unsigned i = 0; i < sz; i++) { + e = m.mk_const(m_model->get_constant(i)); + if (m_visited.is_marked(e)) { + val = eval(m_model, e); + eq = m.mk_eq(e, val); + model.push_back(eq); + } + } + m_visited.reset(); + TRACE("pdr", tout << sz << " ==> " << model.size() << "\n";); + return model; + + } + + void model_evaluator::eval_arith(app* e) { + rational r, r2; + +#define ARG1 e->get_arg(0) +#define ARG2 e->get_arg(1) + + unsigned arity = e->get_num_args(); + for (unsigned i = 0; i < arity; ++i) { + expr* arg = e->get_arg(i); + if (is_x(arg)) { + set_x(e); + return; + } + SASSERT(!is_unknown(arg)); + } + switch(e->get_decl_kind()) { + case OP_NUM: + VERIFY(m_arith.is_numeral(e, r)); + set_number(e, r); + break; + case OP_IRRATIONAL_ALGEBRAIC_NUM: + set_x(e); + break; + case OP_LE: + set_bool(e, get_number(ARG1) <= get_number(ARG2)); + break; + case OP_GE: + set_bool(e, get_number(ARG1) >= get_number(ARG2)); + break; + case OP_LT: + set_bool(e, get_number(ARG1) < get_number(ARG2)); + break; + case OP_GT: + set_bool(e, get_number(ARG1) > get_number(ARG2)); + break; + case OP_ADD: + r = rational::zero(); + for (unsigned i = 0; i < arity; ++i) { + r += get_number(e->get_arg(i)); + } + set_number(e, r); + break; + case OP_SUB: + r = get_number(e->get_arg(0)); + for (unsigned i = 1; i < arity; ++i) { + r -= get_number(e->get_arg(i)); + } + set_number(e, r); + break; + case OP_UMINUS: + SASSERT(arity == 1); + set_number(e, get_number(e->get_arg(0))); + break; + case OP_MUL: + r = rational::one(); + for (unsigned i = 0; i < arity; ++i) { + r *= get_number(e->get_arg(i)); + } + set_number(e, r); + break; + case OP_DIV: + SASSERT(arity == 2); + r = get_number(ARG2); + if (r.is_zero()) { + set_x(e); + } + else { + set_number(e, get_number(ARG1) / r); + } + break; + case OP_IDIV: + SASSERT(arity == 2); + r = get_number(ARG2); + if (r.is_zero()) { + set_x(e); + } + else { + set_number(e, div(get_number(ARG1), r)); + } + break; + case OP_REM: + // rem(v1,v2) = if v2 >= 0 then mod(v1,v2) else -mod(v1,v2) + SASSERT(arity == 2); + r = get_number(ARG2); + if (r.is_zero()) { + set_x(e); + } + else { + r2 = mod(get_number(ARG1), r); + if (r.is_neg()) r2.neg(); + set_number(e, r2); + } + break; + case OP_MOD: + SASSERT(arity == 2); + r = get_number(ARG2); + if (r.is_zero()) { + set_x(e); + } + else { + set_number(e, mod(get_number(ARG1), r)); + } + break; + case OP_TO_REAL: + SASSERT(arity == 1); + set_number(e, get_number(ARG1)); + break; + case OP_TO_INT: + SASSERT(arity == 1); + set_number(e, floor(get_number(ARG1))); + break; + case OP_IS_INT: + SASSERT(arity == 1); + set_bool(e, get_number(ARG1).is_int()); + break; + case OP_POWER: + set_x(e); break; default: IF_VERBOSE(0, verbose_stream() << "Term not handled " << mk_pp(e, m) << "\n";); UNREACHABLE(); + break; } } - else { - tocollect.push_back(e); - } -} - -void model_evaluator::collect(ptr_vector const& formulas, ptr_vector& tocollect) { - ptr_vector todo; - todo.append(formulas); - m_visited.reset(); - VERIFY(check_model(formulas)); - - while (!todo.empty()) { - app* e = to_app(todo.back()); - todo.pop_back(); - if (!m_visited.is_marked(e)) { - process_formula(e, todo, tocollect); - m_visited.mark(e, true); - } - } - m_visited.reset(); -} - -expr_ref_vector model_evaluator::prune_by_cone_of_influence(ptr_vector const & formulas) { - ptr_vector tocollect; - collect(formulas, tocollect); - m1.reset(); - m2.reset(); - for (unsigned i = 0; i < tocollect.size(); ++i) { - TRACE("pdr_verbose", tout << "collect: " << mk_pp(tocollect[i], m) << "\n";); - for_each_expr(*this, m_visited, tocollect[i]); - } - unsigned sz = m_model->get_num_constants(); - expr_ref e(m), eq(m); - expr_ref_vector model(m); - for (unsigned i = 0; i < sz; i++) { - func_decl * d = m_model->get_constant(i); - expr* val = m_model->get_const_interp(d); - e = m.mk_const(d); - if (m_visited.is_marked(e)) { - eq = m.mk_eq(e, val); - model.push_back(eq); - } - } - m_visited.reset(); - TRACE("pdr", tout << sz << " ==> " << model.size() << "\n";); - return model; - -} - -void model_evaluator::eval_arith(app* e) { - rational r, r2; - -#define ARG1 e->get_arg(0) -#define ARG2 e->get_arg(1) - - unsigned arity = e->get_num_args(); - for (unsigned i = 0; i < arity; ++i) { - expr* arg = e->get_arg(i); - if (is_x(arg)) { - set_x(e); - return; - } - SASSERT(!is_unknown(arg)); - } - switch(e->get_decl_kind()) { - case OP_NUM: - VERIFY(m_arith.is_numeral(e, r)); - set_number(e, r); - break; - case OP_IRRATIONAL_ALGEBRAIC_NUM: - set_x(e); - break; - case OP_LE: - set_bool(e, get_number(ARG1) <= get_number(ARG2)); - break; - case OP_GE: - set_bool(e, get_number(ARG1) >= get_number(ARG2)); - break; - case OP_LT: - set_bool(e, get_number(ARG1) < get_number(ARG2)); - break; - case OP_GT: - set_bool(e, get_number(ARG1) > get_number(ARG2)); - break; - case OP_ADD: - r = rational::zero(); - for (unsigned i = 0; i < arity; ++i) { - r += get_number(e->get_arg(i)); - } - set_number(e, r); - break; - case OP_SUB: - r = get_number(e->get_arg(0)); - for (unsigned i = 1; i < arity; ++i) { - r -= get_number(e->get_arg(i)); - } - set_number(e, r); - break; - case OP_UMINUS: - SASSERT(arity == 1); - set_number(e, get_number(e->get_arg(0))); - break; - case OP_MUL: - r = rational::one(); - for (unsigned i = 0; i < arity; ++i) { - r *= get_number(e->get_arg(i)); - } - set_number(e, r); - break; - case OP_DIV: - SASSERT(arity == 2); - r = get_number(ARG2); - if (r.is_zero()) { + void model_evaluator::inherit_value(expr* e, expr* v) { + expr* w; + SASSERT(!is_unknown(v)); + SASSERT(m.get_sort(e) == m.get_sort(v)); + if (is_x(v)) { set_x(e); } - else { - set_number(e, get_number(ARG1) / r); + else if (m.is_bool(e)) { + SASSERT(m.is_bool(v)); + if (is_true(v)) set_true(e); + else if (is_false(v)) set_false(e); + else { + TRACE("pdr", tout << "not inherited:\n" << mk_pp(e, m) << "\n" << mk_pp(v, m) << "\n";); + set_x(e); + } } - break; - case OP_IDIV: - SASSERT(arity == 2); - r = get_number(ARG2); - if (r.is_zero()) { - set_x(e); + else if (m_arith.is_int_real(e)) { + set_number(e, get_number(v)); } - else { - set_number(e, div(get_number(ARG1), r)); + else if (m.is_value(v)) { + set_value(e, v); } - break; - case OP_REM: - // rem(v1,v2) = if v2 >= 0 then mod(v1,v2) else -mod(v1,v2) - SASSERT(arity == 2); - r = get_number(ARG2); - if (r.is_zero()) { - set_x(e); + else if (m_values.find(v, w)) { + set_value(e, w); } - else { - r2 = mod(get_number(ARG1), r); - if (r.is_neg()) r2.neg(); - set_number(e, r2); - } - break; - case OP_MOD: - SASSERT(arity == 2); - r = get_number(ARG2); - if (r.is_zero()) { - set_x(e); - } - else { - set_number(e, mod(get_number(ARG1), r)); - } - break; - case OP_TO_REAL: - SASSERT(arity == 1); - set_number(e, get_number(ARG1)); - break; - case OP_TO_INT: - SASSERT(arity == 1); - set_number(e, floor(get_number(ARG1))); - break; - case OP_IS_INT: - SASSERT(arity == 1); - set_bool(e, get_number(ARG1).is_int()); - break; - case OP_POWER: - set_x(e); - break; - default: - IF_VERBOSE(0, verbose_stream() << "Term not handled " << mk_pp(e, m) << "\n";); - UNREACHABLE(); - break; - } -} - -void model_evaluator::inherit_value(expr* e, expr* v) { - expr* w; - SASSERT(!is_unknown(v)); - SASSERT(m.get_sort(e) == m.get_sort(v)); - if (is_x(v)) { - set_x(e); - } - else if (m.is_bool(e)) { - SASSERT(m.is_bool(v)); - if (is_true(v)) set_true(e); - else if (is_false(v)) set_false(e); else { TRACE("pdr", tout << "not inherited:\n" << mk_pp(e, m) << "\n" << mk_pp(v, m) << "\n";); set_x(e); } } - else if (m_arith.is_int_real(e)) { - set_number(e, get_number(v)); - } - else if (m.is_value(v)) { - set_value(e, v); - } - else if (m_values.find(v, w)) { - set_value(e, w); - } - else { - TRACE("pdr", tout << "not inherited:\n" << mk_pp(e, m) << "\n" << mk_pp(v, m) << "\n";); - set_x(e); - } -} - -void model_evaluator::eval_iff(app* e, expr* arg1, expr* arg2) { - if (arg1 == arg2) { - set_true(e); - } - else if (is_x(arg1) || is_x(arg2)) { - set_x(e); - } - else { - bool val = is_true(arg1) == is_true(arg2); - SASSERT(val == (is_false(arg1) == is_false(arg2))); - if (val) { - set_true(e); + + bool model_evaluator::extract_array_func_interp(expr* a, vector& stores, expr_ref& else_case) { + SASSERT(m_array.is_array(a)); + + while (m_array.is_store(a)) { + expr_ref_vector store(m); + store.append(to_app(a)->get_num_args()-1, to_app(a)->get_args()+1); + stores.push_back(store); + a = to_app(a)->get_arg(0); + } + + if (m_array.is_const(a)) { + else_case = to_app(a)->get_arg(0); + return true; + } + + if (m_array.is_as_array(a)) { + func_decl* f = m_array.get_as_array_func_decl(to_app(a)); + func_interp* g = m_model->get_func_interp(f); + unsigned sz = g->num_entries(); + unsigned arity = f->get_arity(); + for (unsigned i = 0; i < sz; ++i) { + expr_ref_vector store(m); + func_entry const* fe = g->get_entry(i); + store.append(arity, fe->get_args()); + store.push_back(fe->get_result()); + for (unsigned j = 0; j < store.size(); ++j) { + if (!is_ground(store[j].get())) { + return false; + } + } + stores.push_back(store); + } + else_case = g->get_else(); + if (!else_case) { + return false; + } + if (!is_ground(else_case)) { + return false; + } + return true; + } + + return false; + } + + /** + best effort evaluator of extensional array equality. + */ + void model_evaluator::eval_array_eq(app* e, expr* arg1, expr* arg2) { + TRACE("pdr", tout << "array equality: " << mk_pp(e, m) << "\n";); + expr_ref v1(m), v2(m); + m_model->eval(arg1, v1); + m_model->eval(arg2, v2); + if (v1 == v2) { + set_true(e); + return; + } + sort* s = m.get_sort(arg1); + sort* r = get_array_range(s); + if (!r->is_infinite() && !r->is_very_big()) { + TRACE("pdr", tout << "equality is unknown: " << mk_pp(e, m) << "\n";); + set_x(e); + return; + } + vector store; + expr_ref else1(m), else2(m); + if (!extract_array_func_interp(v1, store, else1) || + !extract_array_func_interp(v2, store, else2)) { + TRACE("pdr", tout << "equality is unknown: " << mk_pp(e, m) << "\n";); + set_x(e); + return; } - else { - set_false(e); - } - } -} -void model_evaluator::eval_basic(app* e) { - expr* arg1, *arg2; - expr *argCond, *argThen, *argElse, *arg; - bool has_x = false; - unsigned arity = e->get_num_args(); - switch(e->get_decl_kind()) { - case OP_AND: - for (unsigned j = 0; j < arity; ++j) { - expr * arg = e->get_arg(j); - if (is_false(arg)) { + if (else1 != else2) { + if (m.is_value(else1) && m.is_value(else2)) { + TRACE("pdr", tout + << "defaults are different: " << mk_pp(e, m) << " " + << mk_pp(else1, m) << " " << mk_pp(else2, m) << "\n";); + set_false(e); + } + else { + TRACE("pdr", tout << "equality is unknown: " << mk_pp(e, m) << "\n";); + set_x(e); + } + return; + } + + expr_ref s1(m), s2(m), w1(m), w2(m); + expr_ref_vector args1(m), args2(m); + args1.push_back(v1); + args2.push_back(v2); + for (unsigned i = 0; i < store.size(); ++i) { + args1.resize(1); + args2.resize(1); + args1.append(store[i].size()-1, store[i].c_ptr()); + args2.append(store[i].size()-1, store[i].c_ptr()); + s1 = m_array.mk_select(args1.size(), args1.c_ptr()); + s2 = m_array.mk_select(args2.size(), args2.c_ptr()); + m_model->eval(s1, w1); + m_model->eval(s2, w2); + if (w1 == w2) { + continue; + } + else if (m.is_value(w1) && m.is_value(w2)) { + TRACE("pdr", tout << "Equality evaluation: " << mk_pp(e, m) << "\n"; + tout << mk_pp(s1, m) << " |-> " << mk_pp(w1, m) << "\n"; + tout << mk_pp(s2, m) << " |-> " << mk_pp(w2, m) << "\n";); set_false(e); return; } - else if (is_x(arg)) { - has_x = true; - } else { - SASSERT(is_true(arg)); - } - } - if (has_x) { - set_x(e); - } - else { - set_true(e); - } - break; - case OP_OR: - for (unsigned j = 0; j < arity; ++j) { - expr * arg = e->get_arg(j); - if (is_true(arg)) { - set_true(e); + TRACE("pdr", tout << "equality is unknown: " << mk_pp(e, m) << "\n";); + set_x(e); return; } - else if (is_x(arg)) { - has_x = true; - } - else { - SASSERT(is_false(arg)); - } } - if (has_x) { - set_x(e); - } - else { - set_false(e); - } - break; - case OP_NOT: - VERIFY(m.is_not(e, arg)); - if (is_true(arg)) { - set_false(e); - } - else if (is_false(arg)) { - set_true(e); - } - else { - SASSERT(is_x(arg)); - set_x(e); - } - break; - case OP_IMPLIES: - VERIFY(m.is_implies(e, arg1, arg2)); - if (is_false(arg1) || is_true(arg2)) { - set_true(e); - } - else if (arg1 == arg2) { - set_true(e); - } - else if (is_true(arg1) && is_false(arg2)) { - set_false(e); - } - else { - SASSERT(is_x(arg1) || is_x(arg2)); - set_x(e); - } - break; - case OP_IFF: - VERIFY(m.is_iff(e, arg1, arg2)); - eval_iff(e, arg1, arg2); - break; - case OP_ITE: - VERIFY(m.is_ite(e, argCond, argThen, argElse)); - if (is_true(argCond)) { - inherit_value(e, argThen); - } - else if (is_false(argCond)) { - inherit_value(e, argElse); - } - else if (argThen == argElse) { - inherit_value(e, argThen); - } - else if (m.is_bool(e)) { - SASSERT(is_x(argCond)); - if (is_x(argThen) || is_x(argElse)) { - set_x(e); - } - else if (is_true(argThen) == is_true(argElse)) { - inherit_value(e, argThen); - } - else { - set_x(e); - } - } - else { - set_x(e); - } - break; - case OP_TRUE: set_true(e); - break; - case OP_FALSE: - set_false(e); - break; - case OP_EQ: - VERIFY(m.is_eq(e, arg1, arg2)); - if (m.is_bool(arg1)) { - eval_iff(e, arg1, arg2); - } - else if (arg1 == arg2) { + } + + void model_evaluator::eval_eq(app* e, expr* arg1, expr* arg2) { + if (arg1 == arg2) { set_true(e); } + else if (m_array.is_array(arg1)) { + eval_array_eq(e, arg1, arg2); + } else if (is_x(arg1) || is_x(arg2)) { set_x(e); } + else if (m.is_bool(arg1)) { + bool val = is_true(arg1) == is_true(arg2); + SASSERT(val == (is_false(arg1) == is_false(arg2))); + if (val) { + set_true(e); + } + else { + set_false(e); + } + } else if (m_arith.is_int_real(arg1)) { set_bool(e, get_number(arg1) == get_number(arg2)); } @@ -648,164 +659,263 @@ void model_evaluator::eval_basic(app* e) { if (m.is_value(e1) && m.is_value(e2)) { set_bool(e, e1 == e2); } + else if (e1 == e2) { + set_bool(e, true); + } else { TRACE("pdr", tout << "not value equal:\n" << mk_pp(e1, m) << "\n" << mk_pp(e2, m) << "\n";); set_x(e); } } - break; - case OP_DISTINCT: { - vector values; - for (unsigned i = 0; i < arity; ++i) { - expr* arg = e->get_arg(i); - if (is_x(arg)) { + } + + void model_evaluator::eval_basic(app* e) { + expr* arg1, *arg2; + expr *argCond, *argThen, *argElse, *arg; + bool has_x = false; + unsigned arity = e->get_num_args(); + switch(e->get_decl_kind()) { + case OP_AND: + for (unsigned j = 0; j < arity; ++j) { + expr * arg = e->get_arg(j); + if (is_false(arg)) { + set_false(e); + return; + } + else if (is_x(arg)) { + has_x = true; + } + else { + SASSERT(is_true(arg)); + } + } + if (has_x) { set_x(e); - return; } - values.push_back(get_number(arg)); - } - std::sort(values.begin(), values.end()); - for (unsigned i = 0; i + 1 < values.size(); ++i) { - if (values[i] == values[i+1]) { + else { + set_true(e); + } + break; + case OP_OR: + for (unsigned j = 0; j < arity; ++j) { + expr * arg = e->get_arg(j); + if (is_true(arg)) { + set_true(e); + return; + } + else if (is_x(arg)) { + has_x = true; + } + else { + SASSERT(is_false(arg)); + } + } + if (has_x) { + set_x(e); + } + else { set_false(e); - return; + } + break; + case OP_NOT: + VERIFY(m.is_not(e, arg)); + if (is_true(arg)) { + set_false(e); + } + else if (is_false(arg)) { + set_true(e); + } + else { + SASSERT(is_x(arg)); + set_x(e); + } + break; + case OP_IMPLIES: + VERIFY(m.is_implies(e, arg1, arg2)); + if (is_false(arg1) || is_true(arg2)) { + set_true(e); + } + else if (arg1 == arg2) { + set_true(e); + } + else if (is_true(arg1) && is_false(arg2)) { + set_false(e); + } + else { + SASSERT(is_x(arg1) || is_x(arg2)); + set_x(e); + } + break; + case OP_IFF: + VERIFY(m.is_iff(e, arg1, arg2)); + eval_eq(e, arg1, arg2); + break; + case OP_ITE: + VERIFY(m.is_ite(e, argCond, argThen, argElse)); + if (is_true(argCond)) { + inherit_value(e, argThen); + } + else if (is_false(argCond)) { + inherit_value(e, argElse); + } + else if (argThen == argElse) { + inherit_value(e, argThen); + } + else if (m.is_bool(e)) { + SASSERT(is_x(argCond)); + if (is_x(argThen) || is_x(argElse)) { + set_x(e); + } + else if (is_true(argThen) == is_true(argElse)) { + inherit_value(e, argThen); + } + else { + set_x(e); + } + } + else { + set_x(e); + } + break; + case OP_TRUE: + set_true(e); + break; + case OP_FALSE: + set_false(e); + break; + case OP_EQ: + VERIFY(m.is_eq(e, arg1, arg2)); + eval_eq(e, arg1, arg2); + break; + case OP_DISTINCT: { + vector values; + for (unsigned i = 0; i < arity; ++i) { + expr* arg = e->get_arg(i); + if (is_x(arg)) { + set_x(e); + return; + } + values.push_back(get_number(arg)); + } + std::sort(values.begin(), values.end()); + for (unsigned i = 0; i + 1 < values.size(); ++i) { + if (values[i] == values[i+1]) { + set_false(e); + return; + } + } + set_true(e); + break; + } + default: + IF_VERBOSE(0, verbose_stream() << "Term not handled " << mk_pp(e, m) << "\n";); + UNREACHABLE(); + } + } + + bool model_evaluator::check_model(ptr_vector const& formulas) { + ptr_vector todo(formulas); + + while (!todo.empty()) { + expr * curr_e = todo.back(); + + if (!is_app(curr_e)) { + todo.pop_back(); + continue; + } + app * curr = to_app(curr_e); + + if (!is_unknown(curr)) { + todo.pop_back(); + continue; + } + unsigned arity = curr->get_num_args(); + for (unsigned i = 0; i < arity; ++i) { + if (is_unknown(curr->get_arg(i))) { + todo.push_back(curr->get_arg(i)); + } + } + if (todo.back() != curr) { + continue; + } + todo.pop_back(); + if (curr->get_family_id() == m_arith.get_family_id()) { + eval_arith(curr); + } + else if (curr->get_family_id() == m.get_basic_family_id()) { + eval_basic(curr); + } + else { + expr_ref vl(m); + m_model->eval(curr, vl); + assign_value(curr, vl); + } + + IF_VERBOSE(35,verbose_stream() << "assigned "< const& formulas) { - ptr_vector todo(formulas); - - while (!todo.empty()) { - expr * curr_e = todo.back(); - - if (!is_app(curr_e)) { - todo.pop_back(); - continue; - } - app * curr = to_app(curr_e); - - if (!is_unknown(curr)) { - todo.pop_back(); - continue; - } - unsigned arity = curr->get_num_args(); - for (unsigned i = 0; i < arity; ++i) { - if (is_unknown(curr->get_arg(i))) { - todo.push_back(curr->get_arg(i)); - } - } - if (todo.back() != curr) { - continue; - } - todo.pop_back(); - if (curr->get_family_id() == m_arith.get_family_id()) { - eval_arith(curr); - } - else if (curr->get_family_id() == m.get_basic_family_id()) { - eval_basic(curr); + expr_ref model_evaluator::eval(model_ref& model, func_decl* d) { + SASSERT(d->get_arity() == 0); + expr_ref result(m); + if (m_array.is_array(d->get_range())) { + expr_ref e(m); + e = m.mk_const(d); + result = eval(model, e); } else { - expr_ref vl(m); - m_model->eval(curr, vl); - assign_value(curr, vl); + result = model->get_const_interp(d); } - - IF_VERBOSE(35,verbose_stream() << "assigned "<get_num_parameters(); - - ptr_vector domain; - domain.push_back(arr_sort); - - //we push params of the array as remaining arguments of the store. The first - //num_params-1 parameters are indices and the last one is the range of the array - for (unsigned i=0; iget_parameter(i).get_ast())); - } - - return m.mk_func_decl(array_fid, OP_STORE, - arr_sort->get_num_parameters(), arr_sort->get_parameters(), - domain.size(), domain.c_ptr(), arr_sort); + return result; } - void get_as_array_value(const model_core & mdl, expr * arr_e, expr_ref& res) { - ast_manager& m = mdl.get_manager(); - array_util pl(m); - SASSERT(pl.is_as_array(arr_e)); - - app * arr = to_app(arr_e); - - unsigned sz = 0; - func_decl_ref f(pl.get_as_array_func_decl(arr), m); - sort * arr_sort = arr->get_decl()->get_range(); - func_interp* g = mdl.get_func_interp(f); - - res = pl.mk_const_array(arr_sort, g->get_else()); - - unsigned arity = f->get_arity(); - - sz = g->num_entries(); - if (sz) { - func_decl_ref store_fn(mk_store(m, arr_sort), m); - ptr_vector store_args; - for (unsigned i = 0; i < sz; ++i) { - const func_entry * fe = g->get_entry(i); - store_args.reset(); - store_args.push_back(res); - store_args.append(arity, fe->get_args()); - store_args.push_back(fe->get_result()); - res = m.mk_app(store_fn, store_args.size(), store_args.c_ptr()); + expr_ref model_evaluator::eval(model_ref& model, expr* e) { + expr_ref result(m); + m_model = model; + VERIFY(m_model->eval(e, result, true)); + if (m_array.is_array(e)) { + vector stores; + expr_ref_vector args(m); + expr_ref else_case(m); + if (extract_array_func_interp(result, stores, else_case)) { + result = m_array.mk_const_array(m.get_sort(e), else_case); + while (!stores.empty() && stores.back().back() == else_case) { + stores.pop_back(); + } + for (unsigned i = stores.size(); i > 0; ) { + --i; + args.resize(1); + args[0] = result; + args.append(stores[i]); + result = m_array.mk_store(args.size(), args.c_ptr()); + } + return result; } } + return result; } - void get_value_from_model(const model_core & mdl, func_decl * f, expr_ref& res) { - SASSERT(f->get_arity()==0); - ast_manager& m = mdl.get_manager(); - - res = mdl.get_const_interp(f); - - array_util pl(m); - - if (pl.is_as_array(res)) { - get_as_array_value(mdl, res, res); - } - } - + void reduce_disequalities(model& model, unsigned threshold, expr_ref& fml) { ast_manager& m = fml.get_manager(); expr_ref_vector conjs(m); @@ -914,8 +1024,7 @@ bool model_evaluator::check_model(ptr_vector const& formulas) { br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) { return m_r.mk_app_core(f, num, args, result); } - ite_hoister_cfg(ast_manager & m, params_ref const & p):m_r(m) {} - + ite_hoister_cfg(ast_manager & m, params_ref const & p):m_r(m) {} }; class ite_hoister_star : public rewriter_tpl { diff --git a/src/muz_qe/pdr_util.h b/src/muz_qe/pdr_util.h index 1d1e86262..220e56b3c 100644 --- a/src/muz_qe/pdr_util.h +++ b/src/muz_qe/pdr_util.h @@ -28,6 +28,7 @@ Revision History: #include "trace.h" #include "vector.h" #include "arith_decl_plugin.h" +#include "array_decl_plugin.h" #include "bv_decl_plugin.h" @@ -56,6 +57,7 @@ namespace pdr { class model_evaluator { ast_manager& m; arith_util m_arith; + array_util m_array; obj_map m_numbers; expr_ref_vector m_refs; obj_map m_values; @@ -78,7 +80,8 @@ namespace pdr { expr_ref_vector prune_by_cone_of_influence(ptr_vector const & formulas); void eval_arith(app* e); void eval_basic(app* e); - void eval_iff(app* e, expr* arg1, expr* arg2); + void eval_eq(app* e, expr* arg1, expr* arg2); + void eval_array_eq(app* e, expr* arg1, expr* arg2); void inherit_value(expr* e, expr* v); inline bool is_unknown(expr* x) { return !m1.is_marked(x) && !m2.is_marked(x); } @@ -99,9 +102,11 @@ namespace pdr { inline void set_value(expr* x, expr* v) { set_v(x); m_refs.push_back(v); m_values.insert(x, v); } bool check_model(ptr_vector const & formulas); + + bool extract_array_func_interp(expr* a, vector& stores, expr_ref& else_case); public: - model_evaluator(ast_manager& m) : m(m), m_arith(m), m_refs(m) {} + model_evaluator(ast_manager& m) : m(m), m_arith(m), m_array(m), m_refs(m) {} /** \brief extract equalities from model that suffice to satisfy formula. @@ -118,12 +123,15 @@ namespace pdr { */ expr_ref_vector minimize_literals(ptr_vector const & formulas, model_ref& mdl); - - // for_each_expr visitor. + /** + for_each_expr visitor. + */ void operator()(expr* e) {} - }; - void get_value_from_model(const model_core & mdl, func_decl * f, expr_ref& res); + expr_ref eval(model_ref& mdl, expr* e); + + expr_ref eval(model_ref& mdl, func_decl* d); + }; /** \brief replace variables that are used in many disequalities by diff --git a/src/muz_qe/qe.cpp b/src/muz_qe/qe.cpp index a01500fe3..bb65f8bf8 100644 --- a/src/muz_qe/qe.cpp +++ b/src/muz_qe/qe.cpp @@ -1319,7 +1319,7 @@ namespace qe { public: - quant_elim_plugin(ast_manager& m, quant_elim& qe, front_end_params& p): + quant_elim_plugin(ast_manager& m, quant_elim& qe, smt_params& p): m(m), m_qe(qe), m_rewriter(m), @@ -1340,7 +1340,7 @@ namespace qe { m_nnf(m, get_is_relevant(), get_mk_atom()) { params_ref params; - params.set_bool(":gcd-rounding", true); + params.set_bool("gcd_rounding", true); m_rewriter.updt_params(params); } @@ -1959,7 +1959,7 @@ namespace qe { class quant_elim_new : public quant_elim { ast_manager& m; - front_end_params& m_fparams; + smt_params& m_fparams; expr_ref m_assumption; bool m_produce_models; ptr_vector m_plugins; @@ -1968,7 +1968,7 @@ namespace qe { bool m_eliminate_variables_as_block; public: - quant_elim_new(ast_manager& m, front_end_params& p) : + quant_elim_new(ast_manager& m, smt_params& p) : m(m), m_fparams(p), m_assumption(m), @@ -2010,7 +2010,7 @@ namespace qe { } void updt_params(params_ref const& p) { - m_eliminate_variables_as_block = p.get_bool(":eliminate-variables-as-block", m_eliminate_variables_as_block); + m_eliminate_variables_as_block = p.get_bool("eliminate_variables_as_block", m_eliminate_variables_as_block); } void eliminate(bool is_forall, unsigned num_vars, app* const* vars, expr_ref& fml) { @@ -2165,7 +2165,7 @@ namespace qe { // ------------------------------------------------ // expr_quant_elim - expr_quant_elim::expr_quant_elim(ast_manager& m, front_end_params const& fp, params_ref const& p): + expr_quant_elim::expr_quant_elim(ast_manager& m, smt_params const& fp, params_ref const& p): m(m), m_fparams(fp), m_params(p), @@ -2194,7 +2194,7 @@ namespace qe { } void expr_quant_elim::updt_params(params_ref const& p) { - bool r = p.get_bool(":use-neq-qe", m_use_new_qe); + bool r = p.get_bool("use_neq_qe", m_use_new_qe); if (r != m_use_new_qe) { dealloc(m_qe); m_qe = 0; @@ -2205,14 +2205,14 @@ namespace qe { } void expr_quant_elim::collect_param_descrs(param_descrs& r) { - r.insert(":eliminate-variables-as-block", CPK_BOOL, + r.insert("eliminate_variables_as_block", CPK_BOOL, "(default: true) eliminate variables as a block (true) or one at a time (false)"); - // r.insert(":use-new-qe", CPK_BOOL, "(default: true) invoke quantifier engine based on abstracted solver"); + // r.insert("use_new_qe", CPK_BOOL, "(default: true) invoke quantifier engine based on abstracted solver"); } void expr_quant_elim::init_qe() { if (!m_qe) { - m_qe = alloc(quant_elim_new, m, const_cast(m_fparams)); + m_qe = alloc(quant_elim_new, m, const_cast(m_fparams)); } } @@ -2399,7 +2399,7 @@ namespace qe { cache_result(q, r, pr); } - expr_quant_elim_star1::expr_quant_elim_star1(ast_manager& m, front_end_params const& p): + expr_quant_elim_star1::expr_quant_elim_star1(ast_manager& m, smt_params const& p): simplifier(m), m_quant_elim(m, p), m_assumption(m.mk_true()) { } @@ -2437,7 +2437,7 @@ namespace qe { class simplify_solver_context : public i_solver_context { ast_manager& m; - front_end_params m_fparams; + smt_params m_fparams; app_ref_vector* m_vars; expr_ref* m_fml; ptr_vector m_contains; @@ -2612,7 +2612,7 @@ namespace qe { } void simplify_exists(app_ref_vector& vars, expr_ref& fml) { - front_end_params params; + smt_params params; ast_manager& m = fml.get_manager(); simplify_solver_context ctx(m); ctx.solve(fml, vars); diff --git a/src/muz_qe/qe.h b/src/muz_qe/qe.h index 4ca098f73..1697a5cbd 100644 --- a/src/muz_qe/qe.h +++ b/src/muz_qe/qe.h @@ -22,7 +22,7 @@ Revision History: #define __QE_H__ #include "ast.h" -#include "front_end_params.h" +#include "smt_params.h" #include "statistics.h" #include "lbool.h" #include "expr_functors.h" @@ -221,7 +221,7 @@ namespace qe { qe_solver_plugin* mk_array_plugin(i_solver_context& ctx); - qe_solver_plugin* mk_arith_plugin(i_solver_context& ctx, bool produce_models, front_end_params& p); + qe_solver_plugin* mk_arith_plugin(i_solver_context& ctx, bool produce_models, smt_params& p); class def_vector { func_decl_ref_vector m_vars; @@ -275,7 +275,7 @@ namespace qe { class expr_quant_elim { ast_manager& m; - front_end_params const& m_fparams; + smt_params const& m_fparams; params_ref m_params; expr_ref_vector m_trail; obj_map m_visited; @@ -283,7 +283,7 @@ namespace qe { expr* m_assumption; bool m_use_new_qe; public: - expr_quant_elim(ast_manager& m, front_end_params const& fp, params_ref const& p = params_ref()); + expr_quant_elim(ast_manager& m, smt_params const& fp, params_ref const& p = params_ref()); ~expr_quant_elim(); void operator()(expr* assumption, expr* fml, expr_ref& result); @@ -331,7 +331,7 @@ namespace qe { virtual void reduce1_quantifier(quantifier * q); virtual bool is_target(quantifier * q) const { return q->get_num_patterns() == 0 && q->get_num_no_patterns() == 0; } public: - expr_quant_elim_star1(ast_manager & m, front_end_params const& p); + expr_quant_elim_star1(ast_manager & m, smt_params const& p); virtual ~expr_quant_elim_star1() {} void collect_statistics(statistics & st) const { diff --git a/src/muz_qe/qe_arith_plugin.cpp b/src/muz_qe/qe_arith_plugin.cpp index 14cb5ee53..69c036639 100644 --- a/src/muz_qe/qe_arith_plugin.cpp +++ b/src/muz_qe/qe_arith_plugin.cpp @@ -98,7 +98,7 @@ namespace qe { bool_rewriter m_bool_rewriter; arith_rewriter m_arith_rewriter; - arith_qe_util(ast_manager& m, front_end_params& p, i_solver_context& ctx) : + arith_qe_util(ast_manager& m, smt_params& p, i_solver_context& ctx) : m(m), m_ctx(ctx), m_arith(m), @@ -1511,7 +1511,7 @@ public: subst_cache m_subst; public: - arith_plugin(i_solver_context& ctx, ast_manager& m, front_end_params& p): + arith_plugin(i_solver_context& ctx, ast_manager& m, smt_params& p): qe_solver_plugin(m, m.get_family_id("arith"), ctx), m_util(m, p, ctx), m_trail(m) @@ -2562,7 +2562,7 @@ public: }; - qe_solver_plugin* mk_arith_plugin(i_solver_context& ctx, bool produce_models, front_end_params& p) { + qe_solver_plugin* mk_arith_plugin(i_solver_context& ctx, bool produce_models, smt_params& p) { if (p.m_nlquant_elim) { return alloc(nlarith_plugin, ctx, ctx.get_manager(), produce_models); } diff --git a/src/muz_qe/qe_cmd.cpp b/src/muz_qe/qe_cmd.cpp index 218224c51..6f001c9da 100644 --- a/src/muz_qe/qe_cmd.cpp +++ b/src/muz_qe/qe_cmd.cpp @@ -16,8 +16,8 @@ public: virtual void init_pdescrs(cmd_context & ctx, param_descrs & p) { insert_timeout(p); - p.insert(":print", CPK_BOOL, "(default: true) print the simplified term."); - p.insert(":print-statistics", CPK_BOOL, "(default: false) print statistics."); + p.insert("print", CPK_BOOL, "(default: true) print the simplified term."); + p.insert("print_statistics", CPK_BOOL, "(default: false) print statistics."); } virtual ~qe_cmd() { @@ -38,18 +38,18 @@ public: } virtual void execute(cmd_context & ctx) { - front_end_params par; + smt_params par; proof_ref pr(ctx.m()); qe::expr_quant_elim_star1 qe(ctx.m(), par); expr_ref result(ctx.m()); qe(m_target, result, pr); - if (m_params.get_bool(":print", true)) { + if (m_params.get_bool("print", true)) { ctx.display(ctx.regular_stream(), result); ctx.regular_stream() << std::endl; } - if (m_params.get_bool(":print-statistics", false)) { + if (m_params.get_bool("print_statistics", false)) { statistics st; qe.collect_statistics(st); st.display(ctx.regular_stream()); diff --git a/src/muz_qe/qe_lite.cpp b/src/muz_qe/qe_lite.cpp index 6baa7ad80..8880a9ba5 100644 --- a/src/muz_qe/qe_lite.cpp +++ b/src/muz_qe/qe_lite.cpp @@ -33,6 +33,8 @@ Revision History: #include "dl_util.h" #include "th_rewriter.h" #include "dl_util.h" +#include "for_each_expr.h" +#include "expr_safe_replace.h" class is_variable_proc { @@ -74,462 +76,672 @@ public: }; -class der2 { - ast_manager & m; - is_variable_proc* m_is_variable; - var_subst m_subst; - expr_ref_buffer m_new_exprs; - - ptr_vector m_map; - int_vector m_pos2var; - ptr_vector m_inx2var; - unsigned_vector m_order; - expr_ref_vector m_subst_map; - expr_ref_buffer m_new_args; - th_rewriter m_rewriter; - - void der_sort_vars(ptr_vector & vars, ptr_vector & definitions, unsigned_vector & order) { - order.reset(); +namespace eq { + class der { + ast_manager & m; + arith_util a; + is_variable_proc* m_is_variable; + var_subst m_subst; + expr_ref_vector m_new_exprs; - // eliminate self loops, and definitions containing quantifiers. - bool found = false; - for (unsigned i = 0; i < definitions.size(); i++) { - var * v = vars[i]; - expr * t = definitions[i]; - if (t == 0 || has_quantifiers(t) || occurs(v, t)) - definitions[i] = 0; - else - found = true; // found at least one candidate - } + ptr_vector m_map; + int_vector m_pos2var; + ptr_vector m_inx2var; + unsigned_vector m_order; + expr_ref_vector m_subst_map; + expr_ref_buffer m_new_args; + th_rewriter m_rewriter; - if (!found) - return; - - typedef std::pair frame; - svector todo; - - expr_fast_mark1 visiting; - expr_fast_mark2 done; - - unsigned vidx, num; - - for (unsigned i = 0; i < definitions.size(); i++) { - if (definitions[i] == 0) - continue; - var * v = vars[i]; - SASSERT(v->get_idx() == i); - SASSERT(todo.empty()); - todo.push_back(frame(v, 0)); - while (!todo.empty()) { - start: - frame & fr = todo.back(); - expr * t = fr.first; - if (t->get_ref_count() > 1 && done.is_marked(t)) { - todo.pop_back(); + void der_sort_vars(ptr_vector & vars, ptr_vector & definitions, unsigned_vector & order) { + order.reset(); + + // eliminate self loops, and definitions containing quantifiers. + bool found = false; + for (unsigned i = 0; i < definitions.size(); i++) { + var * v = vars[i]; + expr * t = definitions[i]; + if (t == 0 || has_quantifiers(t) || occurs(v, t)) + definitions[i] = 0; + else + found = true; // found at least one candidate + } + + if (!found) + return; + + typedef std::pair frame; + svector todo; + + expr_fast_mark1 visiting; + expr_fast_mark2 done; + + unsigned vidx, num; + + for (unsigned i = 0; i < definitions.size(); i++) { + if (definitions[i] == 0) continue; - } - switch (t->get_kind()) { - case AST_VAR: - vidx = to_var(t)->get_idx(); - if (fr.second == 0) { - CTRACE("der_bug", vidx >= definitions.size(), tout << "vidx: " << vidx << "\n";); - // Remark: The size of definitions may be smaller than the number of variables occuring in the quantified formula. - if (definitions.get(vidx, 0) != 0) { - if (visiting.is_marked(t)) { - // cycle detected: remove t - visiting.reset_mark(t); - definitions[vidx] = 0; - } - else { - visiting.mark(t); - fr.second = 1; - todo.push_back(frame(definitions[vidx], 0)); - goto start; - } - } + var * v = vars[i]; + SASSERT(v->get_idx() == i); + SASSERT(todo.empty()); + todo.push_back(frame(v, 0)); + while (!todo.empty()) { + start: + frame & fr = todo.back(); + expr * t = fr.first; + if (t->get_ref_count() > 1 && done.is_marked(t)) { + todo.pop_back(); + continue; } - else { - SASSERT(fr.second == 1); - if (definitions.get(vidx, 0) != 0) { - visiting.reset_mark(t); - order.push_back(vidx); + switch (t->get_kind()) { + case AST_VAR: + vidx = to_var(t)->get_idx(); + if (fr.second == 0) { + CTRACE("der_bug", vidx >= definitions.size(), tout << "vidx: " << vidx << "\n";); + // Remark: The size of definitions may be smaller than the number of variables occuring in the quantified formula. + if (definitions.get(vidx, 0) != 0) { + if (visiting.is_marked(t)) { + // cycle detected: remove t + visiting.reset_mark(t); + definitions[vidx] = 0; + } + else { + visiting.mark(t); + fr.second = 1; + todo.push_back(frame(definitions[vidx], 0)); + goto start; + } + } } else { - // var was removed from the list of candidate vars to elim cycle - // do nothing + SASSERT(fr.second == 1); + if (definitions.get(vidx, 0) != 0) { + visiting.reset_mark(t); + order.push_back(vidx); + } + else { + // var was removed from the list of candidate vars to elim cycle + // do nothing + } } + if (t->get_ref_count() > 1) + done.mark(t); + todo.pop_back(); + break; + case AST_QUANTIFIER: + UNREACHABLE(); + todo.pop_back(); + break; + case AST_APP: + num = to_app(t)->get_num_args(); + while (fr.second < num) { + expr * arg = to_app(t)->get_arg(fr.second); + fr.second++; + if (arg->get_ref_count() > 1 && done.is_marked(arg)) + continue; + todo.push_back(frame(arg, 0)); + goto start; + } + if (t->get_ref_count() > 1) + done.mark(t); + todo.pop_back(); + break; + default: + UNREACHABLE(); + todo.pop_back(); + break; } - if (t->get_ref_count() > 1) - done.mark(t); - todo.pop_back(); - break; - case AST_QUANTIFIER: - UNREACHABLE(); - todo.pop_back(); - break; - case AST_APP: - num = to_app(t)->get_num_args(); - while (fr.second < num) { - expr * arg = to_app(t)->get_arg(fr.second); - fr.second++; - if (arg->get_ref_count() > 1 && done.is_marked(arg)) - continue; - todo.push_back(frame(arg, 0)); - goto start; - } - if (t->get_ref_count() > 1) - done.mark(t); - todo.pop_back(); - break; - default: - UNREACHABLE(); - todo.pop_back(); - break; } } } - } - - bool is_variable(expr * e) const { - return (*m_is_variable)(e); - } - - bool is_neg_var(ast_manager & m, expr * e) { - expr* e1; - return m.is_not(e, e1) && is_variable(e1); - } - - - /** - \brief Return true if e can be viewed as a variable disequality. - Store the variable id in v and the definition in t. - For example: - - if e is (not (= (VAR 1) T)), then v assigned to 1, and t to T. - if e is (iff (VAR 2) T), then v is assigned to 2, and t to (not T). - (not T) is used because this formula is equivalent to (not (iff (VAR 2) (not T))), - and can be viewed as a disequality. - */ - bool is_var_diseq(expr * e, var * & v, expr_ref & t) { - expr* e1; - if (m.is_not(e, e1)) { - return is_var_eq(e, v, t); + + bool is_variable(expr * e) const { + return (*m_is_variable)(e); } - else if (is_var_eq(e, v, t) && m.is_bool(v)) { - bool_rewriter(m).mk_not(t, t); - m_new_exprs.push_back(t); + + bool is_neg_var(ast_manager & m, expr * e) { + expr* e1; + return m.is_not(e, e1) && is_variable(e1); + } + + + /** + \brief Return true if e can be viewed as a variable disequality. + Store the variable id in v and the definition in t. + For example: + + if e is (not (= (VAR 1) T)), then v assigned to 1, and t to T. + if e is (iff (VAR 2) T), then v is assigned to 2, and t to (not T). + (not T) is used because this formula is equivalent to (not (iff (VAR 2) (not T))), + and can be viewed as a disequality. + */ + bool is_var_diseq(expr * e, var * & v, expr_ref & t) { + expr* e1; + if (m.is_not(e, e1)) { + return is_var_eq(e, v, t); + } + else if (is_var_eq(e, v, t) && m.is_bool(v)) { + bool_rewriter(m).mk_not(t, t); + m_new_exprs.push_back(t); + return true; + } + else { + return false; + } + } + + bool solve_arith_core(app * lhs, expr * rhs, expr * eq, var* & var, expr_ref & def) { + SASSERT(a.is_add(lhs)); + bool is_int = a.is_int(lhs); + expr * a1; + expr * v; + rational a_val; + unsigned num = lhs->get_num_args(); + unsigned i; + for (i = 0; i < num; i++) { + expr * arg = lhs->get_arg(i); + if (is_variable(arg)) { + a_val = rational(1); + v = arg; + break; + } + else if (a.is_mul(arg, a1, v) && + is_variable(v) && + a.is_numeral(a1, a_val) && + !a_val.is_zero() && + (!is_int || a_val.is_minus_one())) { + break; + } + } + if (i == num) + return false; + var = to_var(v); + expr_ref inv_a(m); + if (!a_val.is_one()) { + inv_a = a.mk_numeral(rational(1)/a_val, is_int); + rhs = a.mk_mul(inv_a, rhs); + } + + ptr_buffer other_args; + for (unsigned j = 0; j < num; j++) { + if (i != j) { + if (inv_a) + other_args.push_back(a.mk_mul(inv_a, lhs->get_arg(j))); + else + other_args.push_back(lhs->get_arg(j)); + } + } + switch (other_args.size()) { + case 0: + def = rhs; + break; + case 1: + def = a.mk_sub(rhs, other_args[0]); + break; + default: + def = a.mk_sub(rhs, a.mk_add(other_args.size(), other_args.c_ptr())); + break; + } + m_new_exprs.push_back(def); return true; } - else { - return false; - } - } - - - - /** - \brief Return true if e can be viewed as a variable equality. - */ - - bool is_var_eq(expr * e, var * & v, expr_ref & t) { - expr* lhs, *rhs; - // (= VAR t), (iff VAR t), (iff (not VAR) t), (iff t (not VAR)) cases - if (m.is_eq(e, lhs, rhs) || m.is_iff(e, lhs, rhs)) { - // (iff (not VAR) t) (iff t (not VAR)) cases - if (!is_variable(lhs) && !is_variable(rhs) && m.is_bool(lhs)) { - if (!is_neg_var(m, lhs)) { - std::swap(lhs, rhs); + bool arith_solve(expr * lhs, expr * rhs, expr * eq, var* & var, expr_ref & t) { + return + (a.is_add(lhs) && solve_arith_core(to_app(lhs), rhs, eq, var, t)) || + (a.is_add(rhs) && solve_arith_core(to_app(rhs), lhs, eq, var, t)); + } + + bool trival_solve(expr* lhs, expr* rhs, expr* eq, var* & v, expr_ref& t) { + if (!is_variable(lhs)) { + std::swap(lhs, rhs); + } + if (!is_variable(lhs)) { + return false; + } + v = to_var(lhs); + t = rhs; + TRACE("der", tout << mk_pp(eq, m) << "\n";); + return true; + } + + + /** + \brief Return true if e can be viewed as a variable equality. + */ + + bool is_var_eq(expr * e, var * & v, expr_ref & t) { + expr* lhs, *rhs; + + // (= VAR t), (iff VAR t), (iff (not VAR) t), (iff t (not VAR)) cases + if (m.is_eq(e, lhs, rhs) || m.is_iff(e, lhs, rhs)) { + // (iff (not VAR) t) (iff t (not VAR)) cases + if (!is_variable(lhs) && !is_variable(rhs) && m.is_bool(lhs)) { + if (!is_neg_var(m, lhs)) { + std::swap(lhs, rhs); + } + if (!is_neg_var(m, lhs)) { + return false; + } + v = to_var(lhs); + t = m.mk_not(rhs); + m_new_exprs.push_back(t); + TRACE("der", tout << mk_pp(e, m) << "\n";); + return true; } - if (!is_neg_var(m, lhs)) { - return false; + if (trival_solve(lhs, rhs, e, v, t)) { + return true; } - v = to_var(lhs); - t = m.mk_not(rhs); - m_new_exprs.push_back(t); + if (arith_solve(lhs, rhs, e, v, t)) { + return true; + } + return false; + } + + // (ite cond (= VAR t) (= VAR t2)) case + expr* cond, *e2, *e3; + if (m.is_ite(e, cond, e2, e3)) { + if (is_var_eq(e2, v, t)) { + expr_ref t2(m); + var* v2; + if (is_var_eq(e3, v2, t2) && v2 == v) { + t = m.mk_ite(cond, t, t2); + m_new_exprs.push_back(t); + return true; + } + } + return false; + } + + // VAR = true case + if (is_variable(e)) { + t = m.mk_true(); + v = to_var(e); TRACE("der", tout << mk_pp(e, m) << "\n";); return true; } - if (!is_variable(lhs)) - std::swap(lhs, rhs); - if (!is_variable(lhs)) - return false; - v = to_var(lhs); - t = rhs; - TRACE("der", tout << mk_pp(e, m) << "\n";); - return true; + + // VAR = false case + if (is_neg_var(m, e)) { + t = m.mk_false(); + v = to_var(to_app(e)->get_arg(0)); + TRACE("der", tout << mk_pp(e, m) << "\n";); + return true; + } + + return false; } - // (ite cond (= VAR t) (= VAR t2)) case - expr* cond, *e2, *e3; - if (m.is_ite(e, cond, e2, e3)) { - if (is_var_eq(e2, v, t)) { - expr_ref t2(m); - var* v2; - if (is_var_eq(e3, v2, t2) && v2 == v) { - t = m.mk_ite(cond, t, t2); - m_new_exprs.push_back(t); + + bool is_var_def(bool check_eq, expr* e, var*& v, expr_ref& t) { + if (check_eq) { + return is_var_eq(e, v, t); + } + else { + return is_var_diseq(e, v, t); + } + } + + void get_elimination_order() { + m_order.reset(); + + TRACE("top_sort", + tout << "DEFINITIONS: " << std::endl; + for(unsigned i = 0; i < m_map.size(); i++) + if(m_map[i]) tout << "VAR " << i << " = " << mk_pp(m_map[i], m) << std::endl; + ); + + der_sort_vars(m_inx2var, m_map, m_order); + + TRACE("der", + tout << "Elimination m_order:" << std::endl; + for(unsigned i=0; iget_expr(); + if ((q->is_forall() && m.is_or(e)) || + (q->is_exists() && m.is_and(e))) { + num_args = to_app(e)->get_num_args(); + args = to_app(e)->get_args(); + } + } + + void apply_substitution(quantifier * q, expr_ref & r) { + + expr * e = q->get_expr(); + unsigned num_args = 1; + expr* const* args = &e; + flatten_args(q, num_args, args); + bool_rewriter rw(m); + + // get a new expression + m_new_args.reset(); + for(unsigned i = 0; i < num_args; i++) { + int x = m_pos2var[i]; + if (x == -1 || m_map[x] == 0) { + m_new_args.push_back(args[i]); + } + } + + expr_ref t(m); + if (q->is_forall()) { + rw.mk_or(m_new_args.size(), m_new_args.c_ptr(), t); + } + else { + rw.mk_and(m_new_args.size(), m_new_args.c_ptr(), t); + } + expr_ref new_e(m); + m_subst(t, m_subst_map.size(), m_subst_map.c_ptr(), new_e); + + // don't forget to update the quantifier patterns + expr_ref_buffer new_patterns(m); + expr_ref_buffer new_no_patterns(m); + for (unsigned j = 0; j < q->get_num_patterns(); j++) { + expr_ref new_pat(m); + m_subst(q->get_pattern(j), m_subst_map.size(), m_subst_map.c_ptr(), new_pat); + new_patterns.push_back(new_pat); + } + + for (unsigned j = 0; j < q->get_num_no_patterns(); j++) { + expr_ref new_nopat(m); + m_subst(q->get_no_pattern(j), m_subst_map.size(), m_subst_map.c_ptr(), new_nopat); + new_no_patterns.push_back(new_nopat); + } + + r = m.update_quantifier(q, new_patterns.size(), new_patterns.c_ptr(), + new_no_patterns.size(), new_no_patterns.c_ptr(), new_e); + } + + void reduce_quantifier1(quantifier * q, expr_ref & r, proof_ref & pr) { + expr * e = q->get_expr(); + is_variable_test is_v(q->get_num_decls()); + set_is_variable_proc(is_v); + unsigned num_args = 1; + expr* const* args = &e; + flatten_args(q, num_args, args); + + unsigned def_count = 0; + unsigned largest_vinx = 0; + + find_definitions(num_args, args, q->is_exists(), def_count, largest_vinx); + + if (def_count > 0) { + get_elimination_order(); + SASSERT(m_order.size() <= def_count); // some might be missing because of cycles + + if (!m_order.empty()) { + create_substitution(largest_vinx + 1); + apply_substitution(q, r); + } + else { + r = q; + } + } + else { + TRACE("der_bug", tout << "Did not find any diseq\n" << mk_pp(q, m) << "\n";); + r = q; + } + + if (m.proofs_enabled()) { + pr = r == q ? 0 : m.mk_der(q, r); + } + } + + void elim_unused_vars(expr_ref& r, proof_ref &pr) { + if (is_quantifier(r)) { + quantifier * q = to_quantifier(r); + ::elim_unused_vars(m, q, r); + if (m.proofs_enabled()) { + proof * p1 = m.mk_elim_unused_vars(q, r); + pr = m.mk_transitivity(pr, p1); + } + } + } + + void find_definitions(unsigned num_args, expr* const* args, bool is_exists, unsigned& def_count, unsigned& largest_vinx) { + var * v = 0; + expr_ref t(m); + def_count = 0; + largest_vinx = 0; + m_map.reset(); + m_pos2var.reset(); + m_inx2var.reset(); + m_pos2var.reserve(num_args, -1); + + // Find all definitions + for (unsigned i = 0; i < num_args; i++) { + if (is_var_def(is_exists, args[i], v, t)) { + unsigned idx = v->get_idx(); + if(m_map.get(idx, 0) == 0) { + m_map.reserve(idx + 1, 0); + m_inx2var.reserve(idx + 1, 0); + m_map[idx] = t; + m_inx2var[idx] = v; + m_pos2var[i] = idx; + def_count++; + largest_vinx = std::max(idx, largest_vinx); + } + } + } + } + + bool reduce_var_set(expr_ref_vector& conjs) { + unsigned def_count = 0; + unsigned largest_vinx = 0; + + find_definitions(conjs.size(), conjs.c_ptr(), true, def_count, largest_vinx); + + if (def_count > 0) { + get_elimination_order(); + SASSERT(m_order.size() <= def_count); // some might be missing because of cycles + + if (!m_order.empty()) { + expr_ref r(m), new_r(m); + r = m.mk_and(conjs.size(), conjs.c_ptr()); + create_substitution(largest_vinx + 1); + m_subst(r, m_subst_map.size(), m_subst_map.c_ptr(), new_r); + m_rewriter(new_r); + conjs.reset(); + datalog::flatten_and(new_r, conjs); return true; } } return false; } - - // VAR = true case - if (is_variable(e)) { - t = m.mk_true(); - v = to_var(e); - TRACE("der", tout << mk_pp(e, m) << "\n";); - return true; - } - - // VAR = false case - if (is_neg_var(m, e)) { - t = m.mk_false(); - v = to_var(to_app(e)->get_arg(0)); - TRACE("der", tout << mk_pp(e, m) << "\n";); - return true; - } - - return false; - } - - bool is_var_def(bool check_eq, expr* e, var*& v, expr_ref& t) { - if (check_eq) { - return is_var_eq(e, v, t); - } - else { - return is_var_diseq(e, v, t); - } - } - - void get_elimination_order() { - m_order.reset(); - - TRACE("top_sort", - tout << "DEFINITIONS: " << std::endl; - for(unsigned i = 0; i < m_map.size(); i++) - if(m_map[i]) tout << "VAR " << i << " = " << mk_pp(m_map[i], m) << std::endl; - ); + public: + der(ast_manager & m): m(m), a(m), m_is_variable(0), m_subst(m), m_new_exprs(m), m_subst_map(m), m_new_args(m), m_rewriter(m) {} - der_sort_vars(m_inx2var, m_map, m_order); + void set_is_variable_proc(is_variable_proc& proc) { m_is_variable = &proc;} - TRACE("der", - tout << "Elimination m_order:" << std::endl; - for(unsigned i=0; iget_expr(); - if ((q->is_forall() && m.is_or(e)) || - (q->is_exists() && m.is_and(e))) { - num_args = to_app(e)->get_num_args(); - args = to_app(e)->get_args(); - } - } - - void apply_substitution(quantifier * q, expr_ref & r) { - - expr * e = q->get_expr(); - unsigned num_args = 1; - expr* const* args = &e; - flatten_args(q, num_args, args); - bool_rewriter rw(m); - - // get a new expression - m_new_args.reset(); - for(unsigned i = 0; i < num_args; i++) { - int x = m_pos2var[i]; - if (x == -1 || m_map[x] == 0) { - m_new_args.push_back(args[i]); + void operator()(quantifier * q, expr_ref & r, proof_ref & pr) { + TRACE("der", tout << mk_pp(q, m) << "\n";); + pr = 0; + r = q; + reduce_quantifier(q, r, pr); + if (r != q) { + elim_unused_vars(r, pr); } } - expr_ref t(m); - if (q->is_forall()) { - rw.mk_or(m_new_args.size(), m_new_args.c_ptr(), t); - } - else { - rw.mk_and(m_new_args.size(), m_new_args.c_ptr(), t); - } - expr_ref new_e(m); - m_subst(t, m_subst_map.size(), m_subst_map.c_ptr(), new_e); - - // don't forget to update the quantifier patterns - expr_ref_buffer new_patterns(m); - expr_ref_buffer new_no_patterns(m); - for (unsigned j = 0; j < q->get_num_patterns(); j++) { - expr_ref new_pat(m); - m_subst(q->get_pattern(j), m_subst_map.size(), m_subst_map.c_ptr(), new_pat); - new_patterns.push_back(new_pat); - } - - for (unsigned j = 0; j < q->get_num_no_patterns(); j++) { - expr_ref new_nopat(m); - m_subst(q->get_no_pattern(j), m_subst_map.size(), m_subst_map.c_ptr(), new_nopat); - new_no_patterns.push_back(new_nopat); - } - - r = m.update_quantifier(q, new_patterns.size(), new_patterns.c_ptr(), - new_no_patterns.size(), new_no_patterns.c_ptr(), new_e); - } - - void reduce_quantifier1(quantifier * q, expr_ref & r, proof_ref & pr) { - expr * e = q->get_expr(); - is_variable_test is_v(q->get_num_decls()); - set_is_variable_proc(is_v); - unsigned num_args = 1; - expr* const* args = &e; - flatten_args(q, num_args, args); - - unsigned def_count = 0; - unsigned largest_vinx = 0; - - find_definitions(num_args, args, q->is_exists(), def_count, largest_vinx); - - if (def_count > 0) { - get_elimination_order(); - SASSERT(m_order.size() <= def_count); // some might be missing because of cycles - - if (!m_order.empty()) { - create_substitution(largest_vinx + 1); - apply_substitution(q, r); - } - else { - r = q; - } - } - else { - TRACE("der_bug", tout << "Did not find any diseq\n" << mk_pp(q, m) << "\n";); + void reduce_quantifier(quantifier * q, expr_ref & r, proof_ref & pr) { r = q; + // Keep applying reduce_quantifier1 until r doesn't change anymore + do { + proof_ref curr_pr(m); + q = to_quantifier(r); + reduce_quantifier1(q, r, curr_pr); + if (m.proofs_enabled()) { + pr = m.mk_transitivity(pr, curr_pr); + } + } while (q != r && is_quantifier(r)); + + m_new_exprs.reset(); } - if (m.proofs_enabled()) { - pr = r == q ? 0 : m.mk_der(q, r); - } - } - - void elim_unused_vars(expr_ref& r, proof_ref &pr) { - if (is_quantifier(r)) { - quantifier * q = to_quantifier(r); - ::elim_unused_vars(m, q, r); - if (m.proofs_enabled()) { - proof * p1 = m.mk_elim_unused_vars(q, r); - pr = m.mk_transitivity(pr, p1); - } + void operator()(expr_ref_vector& r) { + while (reduce_var_set(r)) ; + m_new_exprs.reset(); } - } - - void find_definitions(unsigned num_args, expr* const* args, bool is_exists, unsigned& def_count, unsigned& largest_vinx) { - var * v = 0; - expr_ref t(m); - def_count = 0; - largest_vinx = 0; - m_map.reset(); - m_pos2var.reset(); - m_inx2var.reset(); - m_pos2var.reserve(num_args, -1); - // Find all definitions - for (unsigned i = 0; i < num_args; i++) { - if (is_var_def(is_exists, args[i], v, t)) { - unsigned idx = v->get_idx(); - if(m_map.get(idx, 0) == 0) { - m_map.reserve(idx + 1, 0); - m_inx2var.reserve(idx + 1, 0); - m_map[idx] = t; - m_inx2var[idx] = v; - m_pos2var[i] = idx; - def_count++; - largest_vinx = std::max(idx, largest_vinx); + ast_manager& get_manager() const { return m; } + }; +}; // namespace eq + +// ------------------------------------------------------------ +// basic destructive equality (and disequality) resolution for arrays. + +namespace ar { + class der { + ast_manager& m; + array_util a; + is_variable_proc* m_is_variable; + ptr_vector m_todo; + expr_mark m_visited; + + bool is_variable(expr * e) const { + return (*m_is_variable)(e); + } + + void mark_all(expr* e) { + for_each_expr(*this, m_visited, e); + } + + void mark_all(expr_ref_vector const& fmls, unsigned j) { + for (unsigned i = 0; i < fmls.size(); ++i) { + if (i != j) { + mark_all(fmls[i]); } } } - } - bool reduce_var_set(expr_ref_vector& conjs) { - unsigned def_count = 0; - unsigned largest_vinx = 0; - - find_definitions(conjs.size(), conjs.c_ptr(), true, def_count, largest_vinx); - - if (def_count > 0) { - get_elimination_order(); - SASSERT(m_order.size() <= def_count); // some might be missing because of cycles - - if (!m_order.empty()) { - expr_ref r(m), new_r(m); - r = m.mk_and(conjs.size(), conjs.c_ptr()); - create_substitution(largest_vinx + 1); - m_subst(r, m_subst_map.size(), m_subst_map.c_ptr(), new_r); - m_rewriter(new_r); - conjs.reset(); - datalog::flatten_and(new_r, conjs); + /** + Ex A. A[x] = t & Phi where x \not\in A, t. + => + Ex A. Phi[store(A,x,t)] + */ + + bool solve_select(expr_ref_vector& conjs, unsigned i, expr* e1, expr* e2) { + if (a.is_select(e1)) { + app* a1 = to_app(e1); + expr* A = a1->get_arg(0); + if (!is_variable(A)) { + return false; + } + m_visited.reset(); + for (unsigned j = 1; j < a1->get_num_args(); ++j) { + mark_all(a1->get_arg(j)); + } + mark_all(e2); + if (m_visited.is_marked(A)) { + return false; + } + ptr_vector args; + args.push_back(A); + args.append(a1->get_num_args()-1, a1->get_args()+1); + args.push_back(e2); + expr* B = a.mk_store(args.size(), args.c_ptr()); + expr_safe_replace rep(m); + rep.insert(A, B); + expr_ref tmp(m); + for (unsigned j = 0; j < conjs.size(); ++j) { + if (i == j) { + conjs[j] = m.mk_true(); + } + else { + rep(conjs[j].get(), tmp); + conjs[j] = tmp; + } + } return true; } + return false; } - return false; - } - -public: - der2(ast_manager & m): m(m), m_is_variable(0), m_subst(m), m_new_exprs(m), m_subst_map(m), m_new_args(m), m_rewriter(m) {} - - void set_is_variable_proc(is_variable_proc& proc) { m_is_variable = &proc;} - - void operator()(quantifier * q, expr_ref & r, proof_ref & pr) { - TRACE("der", tout << mk_pp(q, m) << "\n";); - pr = 0; - r = q; - reduce_quantifier(q, r, pr); - if (r != q) { - elim_unused_vars(r, pr); + bool solve_select(expr_ref_vector& conjs, unsigned i, expr* e) { + expr* e1, *e2; + return + m.is_eq(e, e1, e2) && + (solve_select(conjs, i, e1, e2) || + solve_select(conjs, i, e2, e1)); } - } - void reduce_quantifier(quantifier * q, expr_ref & r, proof_ref & pr) { - r = q; - // Keep applying reduce_quantifier1 until r doesn't change anymore - do { - proof_ref curr_pr(m); - q = to_quantifier(r); - reduce_quantifier1(q, r, curr_pr); - if (m.proofs_enabled()) { - pr = m.mk_transitivity(pr, curr_pr); + /** + Ex x. A[x] != B[x] & Phi where x \not\in A, B, Phi + => + A != B & Phi + */ + bool solve_neq_select(expr_ref_vector& conjs, unsigned i, expr* e) { + expr* e1, *a1, *a2; + if (m.is_not(e, e1) && m.is_eq(e1, a1, a2)) { + if (a.is_select(a1) && + a.is_select(a2) && + to_app(a1)->get_num_args() == to_app(a2)->get_num_args()) { + expr* e1 = to_app(a1)->get_arg(0); + expr* e2 = to_app(a2)->get_arg(0); + m_visited.reset(); + mark_all(conjs, i); + mark_all(e1); + mark_all(e2); + for (unsigned j = 1; j < to_app(a1)->get_num_args(); ++j) { + expr* x = to_app(a1)->get_arg(j); + expr* y = to_app(a2)->get_arg(j); + if (!is_variable(x)) { + return false; + } + if (x != y) { + return false; + } + if (m_visited.is_marked(x)) { + return false; + } + } + conjs[i] = m.mk_not(m.mk_eq(e1, e2)); + return true; + } } - } while (q != r && is_quantifier(r)); + return false; + } + + + public: + + der(ast_manager& m): m(m), a(m), m_is_variable(0) {} + + void operator()(expr_ref_vector& fmls) { + for (unsigned i = 0; i < fmls.size(); ++i) { + solve_select(fmls, i, fmls[i].get()); + solve_neq_select(fmls, i, fmls[i].get()); + } + } + + void operator()(expr* e) {} + + void set_is_variable_proc(is_variable_proc& proc) { m_is_variable = &proc;} - m_new_exprs.reset(); - } + }; +}; // namespace ar - void operator()(expr_ref_vector& r) { - while (reduce_var_set(r)) ; - m_new_exprs.reset(); - } - - ast_manager& get_manager() const { return m; } -}; // ------------------------------------------------------------ // fm_tactic adapted to eliminate designated de-Brujin indices. @@ -1048,13 +1260,13 @@ namespace fm { } void updt_params(params_ref const & p) { - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); - m_fm_real_only = p.get_bool(":fm-real-only", true); - m_fm_limit = p.get_uint(":fm-limit", 5000000); - m_fm_cutoff1 = p.get_uint(":fm-cutoff1", 8); - m_fm_cutoff2 = p.get_uint(":fm-cutoff2", 256); - m_fm_extra = p.get_uint(":fm-extra", 0); - m_fm_occ = p.get_bool(":fm-occ", false); + m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); + m_fm_real_only = p.get_bool("fm_real_only", true); + m_fm_limit = p.get_uint("fm_limit", 5000000); + m_fm_cutoff1 = p.get_uint("fm_cutoff1", 8); + m_fm_cutoff2 = p.get_uint("fm_cutoff2", 256); + m_fm_extra = p.get_uint("fm_extra", 0); + m_fm_occ = p.get_bool("fm_occ", false); } void set_cancel(bool f) { @@ -1808,7 +2020,6 @@ namespace fm { void set_is_variable_proc(is_variable_proc& proc) { m_is_variable = &proc;} - void operator()(expr_ref_vector& fmls) { init(fmls); init_use_list(fmls); @@ -1873,12 +2084,29 @@ namespace fm { class qe_lite::impl { ast_manager& m; - der2 m_der; params_ref m_params; + eq::der m_der; fm::fm m_fm; + ar::der m_array_der; + + bool has_unique_non_ground(expr_ref_vector const& fmls, unsigned& index) { + index = fmls.size(); + if (index <= 1) { + return false; + } + for (unsigned i = 0; i < fmls.size(); ++i) { + if (!is_ground(fmls[i])) { + if (index != fmls.size()) { + return false; + } + index = i; + } + } + return index < fmls.size(); + } public: - impl(ast_manager& m): m(m), m_der(m), m_fm(m, m_params) {} + impl(ast_manager& m): m(m), m_der(m), m_fm(m, m_params), m_array_der(m) {} void operator()(app_ref_vector& vars, expr_ref& fml) { if (vars.empty()) { @@ -1928,22 +2156,42 @@ public: } void operator()(uint_set const& index_set, bool index_of_bound, expr_ref& fml) { - expr_ref_vector conjs(m); - conjs.push_back(fml); - (*this)(index_set, index_of_bound, conjs); - bool_rewriter(m).mk_and(conjs.size(), conjs.c_ptr(), fml); + expr_ref_vector disjs(m); + datalog::flatten_or(fml, disjs); + for (unsigned i = 0; i < disjs.size(); ++i) { + expr_ref_vector conjs(m); + conjs.push_back(disjs[i].get()); + (*this)(index_set, index_of_bound, conjs); + bool_rewriter(m).mk_and(conjs.size(), conjs.c_ptr(), fml); + disjs[i] = fml; + } + bool_rewriter(m).mk_or(disjs.size(), disjs.c_ptr(), fml); } void operator()(uint_set const& index_set, bool index_of_bound, expr_ref_vector& fmls) { datalog::flatten_and(fmls); + unsigned index; + if (has_unique_non_ground(fmls, index)) { + expr_ref fml(m); + fml = fmls[index].get(); + (*this)(index_set, index_of_bound, fml); + fmls[index] = fml; + return; + } + TRACE("qe_lite", for (unsigned i = 0; i < fmls.size(); ++i) { + tout << mk_pp(fmls[i].get(), m) << "\n"; + }); + IF_VERBOSE(3, for (unsigned i = 0; i < fmls.size(); ++i) { + verbose_stream() << mk_pp(fmls[i].get(), m) << "\n"; + }); is_variable_test is_var(index_set, index_of_bound); - TRACE("qe_lite", for (unsigned i = 0; i < fmls.size(); ++i) tout << mk_pp(fmls[i].get(), m) << "\n";); - IF_VERBOSE(3, for (unsigned i = 0; i < fmls.size(); ++i) verbose_stream() << mk_pp(fmls[i].get(), m) << "\n";); m_der.set_is_variable_proc(is_var); - m_der(fmls); m_fm.set_is_variable_proc(is_var); + m_array_der.set_is_variable_proc(is_var); + m_der(fmls); m_fm(fmls); + m_array_der(fmls); TRACE("qe_lite", for (unsigned i = 0; i < fmls.size(); ++i) tout << mk_pp(fmls[i].get(), m) << "\n";); } diff --git a/src/muz_qe/qe_lite.h b/src/muz_qe/qe_lite.h index 3a23c7188..3ffbf8fad 100644 --- a/src/muz_qe/qe_lite.h +++ b/src/muz_qe/qe_lite.h @@ -1,5 +1,5 @@ /*++ -Copyright (c) 2010 Microsoft Corporation +Copyright (c) 2012 Microsoft Corporation Module Name: diff --git a/src/muz_qe/qe_sat_tactic.cpp b/src/muz_qe/qe_sat_tactic.cpp index 1480a8ca0..854e15493 100644 --- a/src/muz_qe/qe_sat_tactic.cpp +++ b/src/muz_qe/qe_sat_tactic.cpp @@ -59,7 +59,7 @@ namespace qe { ast_manager& m; expr_ref m_false; volatile bool m_cancel; - front_end_params m_fparams; + smt_params m_fparams; params_ref m_params; unsigned m_extrapolate_strategy_param; bool m_projection_mode_param; @@ -301,17 +301,17 @@ namespace qe { virtual void cleanup() {} virtual void updt_params(params_ref const & p) { - m_extrapolate_strategy_param = p.get_uint(":extrapolate-strategy", m_extrapolate_strategy_param); - m_projection_mode_param = p.get_bool(":projection-mode", m_projection_mode_param); - m_strong_context_simplify_param = p.get_bool(":strong-context-simplify", m_strong_context_simplify_param); - m_ctx_simplify_local_param = p.get_bool(":strong-context-simplify-local", m_ctx_simplify_local_param); + m_extrapolate_strategy_param = p.get_uint("extrapolate_strategy", m_extrapolate_strategy_param); + m_projection_mode_param = p.get_bool("projection_mode", m_projection_mode_param); + m_strong_context_simplify_param = p.get_bool("strong_context_simplify", m_strong_context_simplify_param); + m_ctx_simplify_local_param = p.get_bool("strong_context_simplify_local", m_ctx_simplify_local_param); } virtual void collect_param_descrs(param_descrs & r) { - r.insert(":extrapolate-strategy",CPK_UINT, "(default: 0 trivial extrapolation) 1 - nnf strengthening 2 - smt-test 3 - nnf_weakening"); - r.insert(":projection-mode", CPK_BOOL, "(default: true - full) false - partial quantifier instantiation"); - r.insert(":strong-context-simplify", CPK_BOOL, "(default: true) use strong context simplifier on result of quantifier elimination"); - r.insert(":strong-context-simplify-local", CPK_BOOL, "(default: false) use strong context simplifier locally on the new formula only"); + r.insert("extrapolate_strategy",CPK_UINT, "(default: 0 trivial extrapolation) 1 - nnf strengthening 2 - smt-test 3 - nnf_weakening"); + r.insert("projection_mode", CPK_BOOL, "(default: true - full) false - partial quantifier instantiation"); + r.insert("strong_context_simplify", CPK_BOOL, "(default: true) use strong context simplifier on result of quantifier elimination"); + r.insert("strong_context_simplify_local", CPK_BOOL, "(default: false) use strong context simplifier locally on the new formula only"); } @@ -629,7 +629,7 @@ namespace qe { expr_ref fml(_fml, m); if (m_strong_context_simplify_param && m_ctx_simplify_local_param) { m_ctx_rewriter.push(); - m_ctx_rewriter.assert(M(idx)); + m_ctx_rewriter.assert_expr(M(idx)); m_ctx_rewriter(fml); m_ctx_rewriter.pop(); TRACE("qe", tout << mk_pp(_fml, m) << "\n-- context simplify -->\n" << mk_pp(fml, m) << "\n";); @@ -650,7 +650,7 @@ namespace qe { m_rewriter(not_fml); if (m_strong_context_simplify_param && !m_ctx_simplify_local_param) { m_ctx_rewriter.push(); - m_ctx_rewriter.assert(M(idx)); + m_ctx_rewriter.assert_expr(M(idx)); m_ctx_rewriter(not_fml); m_ctx_rewriter.pop(); } diff --git a/src/muz_qe/qe_tactic.cpp b/src/muz_qe/qe_tactic.cpp index f17d15d6a..5b522e041 100644 --- a/src/muz_qe/qe_tactic.cpp +++ b/src/muz_qe/qe_tactic.cpp @@ -24,7 +24,7 @@ Revision History: class qe_tactic : public tactic { struct imp { ast_manager & m; - front_end_params m_fparams; + smt_params m_fparams; volatile bool m_cancel; qe::expr_quant_elim m_qe; @@ -36,7 +36,7 @@ class qe_tactic : public tactic { } void updt_params(params_ref const & p) { - m_fparams.m_nlquant_elim = p.get_bool(":qe-nonlinear", false); + m_fparams.m_nlquant_elim = p.get_bool("qe_nonlinear", false); m_qe.updt_params(p); } @@ -113,7 +113,7 @@ public: virtual void collect_param_descrs(param_descrs & r) { - r.insert(":qe-nonlinear", CPK_BOOL, "(default: false) enable virtual term substitution."); + r.insert("qe_nonlinear", CPK_BOOL, "(default: false) enable virtual term substitution."); m_imp->collect_param_descrs(r); } diff --git a/src/muz_qe/rel_context.cpp b/src/muz_qe/rel_context.cpp new file mode 100644 index 000000000..1b4042ab9 --- /dev/null +++ b/src/muz_qe/rel_context.cpp @@ -0,0 +1,517 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + rel_context.cpp + +Abstract: + + context for relational datalog engine. + +Author: + + Nikolaj Bjorner (nbjorner) 2012-12-3. + +Revision History: + + Extracted from dl_context + +--*/ +#include"rel_context.h" +#include"dl_context.h" +#include"dl_compiler.h" +#include"dl_instruction.h" +#include"dl_mk_explanations.h" +#include"dl_mk_magic_sets.h" +#include"dl_product_relation.h" +#include"dl_bound_relation.h" +#include"dl_interval_relation.h" +#include"dl_finite_product_relation.h" +#include"dl_sparse_table.h" +#include"dl_table.h" +#include"dl_table_relation.h" +#ifndef _EXTERNAL_RELEASE +#include"dl_skip_table.h" +#endif + +namespace datalog { + + rel_context::rel_context(context& ctx) + : m_context(ctx), + m(ctx.get_manager()), + m_rmanager(ctx), + m_answer(m), + m_cancel(false), + m_last_result_relation(0) { + get_rmanager().register_plugin(alloc(sparse_table_plugin, get_rmanager())); + get_rmanager().register_plugin(alloc(hashtable_table_plugin, get_rmanager())); + get_rmanager().register_plugin(alloc(bitvector_table_plugin, get_rmanager())); + get_rmanager().register_plugin(alloc(equivalence_table_plugin, get_rmanager())); + +#ifndef _EXTERNAL_RELEASE + get_rmanager().register_plugin(alloc(skip_table_plugin, get_rmanager())); +#endif + + //register plugins for builtin relations + + get_rmanager().register_plugin(alloc(bound_relation_plugin, get_rmanager())); + get_rmanager().register_plugin(alloc(interval_relation_plugin, get_rmanager())); + +} + + rel_context::~rel_context() { + if (m_last_result_relation) { + m_last_result_relation->deallocate(); + m_last_result_relation = 0; + } + } + + void rel_context::collect_predicates(decl_set & res) { + unsigned rule_cnt = m_context.get_rules().get_num_rules(); + for (unsigned rindex=0; rindexget_head()->get_decl()); + unsigned tail_len = r->get_uninterpreted_tail_size(); + for (unsigned tindex=0; tindexget_tail(tindex)->get_decl()); + } + } + decl_set::iterator oit = m_output_preds.begin(); + decl_set::iterator oend = m_output_preds.end(); + for (; oit!=oend; ++oit) { + res.insert(*oit); + } + get_rmanager().collect_predicates(res); + } + + + lbool rel_context::saturate() { + m_context.ensure_closed(); + + bool time_limit = m_context.soft_timeout()!=0; + unsigned remaining_time_limit = m_context.soft_timeout(); + unsigned restart_time = m_context.initial_restart_timeout(); + + rule_set original_rules(m_context.get_rules()); + decl_set original_predicates; + m_context.collect_predicates(original_predicates); + + instruction_block rules_code; + instruction_block termination_code; + execution_context ex_ctx(m_context); + + lbool result; + + TRACE("dl", m_context.display(tout);); + + while (true) { + model_converter_ref mc; // Ignored in Datalog mode + proof_converter_ref pc; // Ignored in Datalog mode + m_context.transform_rules(mc, pc); + compiler::compile(m_context, m_context.get_rules(), rules_code, termination_code); + + TRACE("dl", rules_code.display(*this, tout); ); + + bool timeout_after_this_round = time_limit && (restart_time==0 || remaining_time_limit<=restart_time); + + if (time_limit || restart_time!=0) { + unsigned timeout = time_limit ? (restart_time!=0) ? + std::min(remaining_time_limit, restart_time) + : remaining_time_limit : restart_time; + ex_ctx.set_timelimit(timeout); + } + + bool early_termination = !rules_code.perform(ex_ctx); + ex_ctx.reset_timelimit(); + VERIFY( termination_code.perform(ex_ctx) ); + + rules_code.process_all_costs(); + + IF_VERBOSE(10, ex_ctx.report_big_relations(1000, verbose_stream());); + + if (!early_termination) { + m_context.set_status(OK); + result = l_true; + break; + } + + if (memory::above_high_watermark()) { + m_context.set_status(MEMOUT); + result = l_undef; + break; + } + if (timeout_after_this_round || m_cancel) { + m_context.set_status(TIMEOUT); + result = l_undef; + break; + } + SASSERT(restart_time != 0); + if (time_limit) { + SASSERT(remaining_time_limit>restart_time); + remaining_time_limit -= restart_time; + } + uint64 new_restart_time = static_cast(restart_time)*m_context.initial_restart_timeout(); + if (new_restart_time > UINT_MAX) { + restart_time = UINT_MAX; + } + else { + restart_time = static_cast(new_restart_time); + } + + rules_code.reset(); + termination_code.reset(); + ex_ctx.reset(); + m_context.reopen(); + restrict_predicates(original_predicates); + m_context.replace_rules(original_rules); + m_context.close(); + } + m_context.reopen(); + restrict_predicates(original_predicates); + m_context.replace_rules(original_rules); + m_context.close(); + TRACE("dl", ex_ctx.report_big_relations(100, tout);); + m_cancel = false; + return result; + } + +#define BEGIN_QUERY() \ + rule_set original_rules(m_context.get_rules()); \ + decl_set original_preds; \ + m_context.collect_predicates(original_preds); \ + bool was_closed = m_context.is_closed(); \ + if (was_closed) { \ + m_context.reopen(); \ + } \ + +#define END_QUERY() \ + m_context.reopen(); \ + m_context.replace_rules(original_rules); \ + restrict_predicates(original_preds); \ + \ + if (was_closed) { \ + m_context.close(); \ + } \ + + lbool rel_context::query(unsigned num_rels, func_decl * const* rels) { + get_rmanager().reset_saturated_marks(); + BEGIN_QUERY(); + for (unsigned i = 0; i < num_rels; ++i) { + set_output_predicate(rels[i]); + } + m_context.close(); + reset_negated_tables(); + lbool res = saturate(); + + switch(res) { + case l_true: { + expr_ref_vector ans(m); + expr_ref e(m); + bool some_non_empty = num_rels == 0; + for (unsigned i = 0; i < num_rels; ++i) { + relation_base& rel = get_relation(rels[i]); + if (!rel.empty()) { + some_non_empty = true; + } + rel.to_formula(e); + ans.push_back(e); + } + SASSERT(!m_last_result_relation); + if (some_non_empty) { + m_answer = m.mk_and(ans.size(), ans.c_ptr()); + } + else { + m_answer = m.mk_false(); + res = l_false; + } + break; + } + case l_false: + m_answer = m.mk_false(); + break; + case l_undef: + break; + } + END_QUERY(); + return res; + } + + lbool rel_context::query(expr* query) { + get_rmanager().reset_saturated_marks(); + BEGIN_QUERY(); + rule_manager& rm = m_context.get_rule_manager(); + rule_ref qrule(rm); + rule_ref_vector qrules(rm); + func_decl_ref query_pred(m); + try { + rm.mk_query(query, query_pred, qrules, qrule); + } + catch(default_exception& exn) { + m_context.close(); + m_context.set_status(INPUT_ERROR); + throw exn; + } + try { + m_context.add_rules(qrules); + } + catch (default_exception& exn) { + m_context.close(); + m_context.set_status(INPUT_ERROR); + throw exn; + } + + set_output_predicate(qrule->get_head()->get_decl()); + m_context.close(); + reset_negated_tables(); + + if (m_context.generate_explanations()) { + model_converter_ref mc; // ignored in Datalog mode + proof_converter_ref pc; // ignored in Datalog mode + rule_transformer transformer(m_context); + //expl_plugin is deallocated when transformer goes out of scope + mk_explanations * expl_plugin = + alloc(mk_explanations, m_context, m_context.explanations_on_relation_level()); + transformer.register_plugin(expl_plugin); + m_context.transform_rules(transformer, mc, pc); + + //we will retrieve the predicate with explanations instead of the original query predicate + query_pred = expl_plugin->get_e_decl(query_pred); + const rule_vector & query_rules = m_context.get_rules().get_predicate_rules(query_pred); + SASSERT(query_rules.size()==1); + qrule = query_rules.back(); + } + + if (m_context.magic_sets_for_queries()) { + model_converter_ref mc; // Ignored in Datalog mode + proof_converter_ref pc; // Ignored in Datalog mode + rule_transformer transformer(m_context); + transformer.register_plugin(alloc(mk_magic_sets, m_context, qrule.get())); + m_context.transform_rules(transformer, mc, pc); + } + + lbool res = saturate(); + + if (res != l_undef) { + m_last_result_relation = get_relation(query_pred).clone(); + if (m_last_result_relation->empty()) { + res = l_false; + m_answer = m.mk_false(); + } + else { + m_last_result_relation->to_formula(m_answer); + } + } + + END_QUERY(); + return res; + } + + void rel_context::reset_negated_tables() { + rule_set::pred_set_vector const & pred_sets = m_context.get_rules().get_strats(); + bool non_empty = false; + for (unsigned i = 1; i < pred_sets.size(); ++i) { + func_decl_set::iterator it = pred_sets[i]->begin(), end = pred_sets[i]->end(); + for (; it != end; ++it) { + func_decl* pred = *it; + relation_base & rel = get_relation(pred); + if (!rel.empty()) { + non_empty = true; + break; + } + } + } + if (!non_empty) { + return; + } + // collect predicates that depend on negation. + func_decl_set depends_on_negation; + for (unsigned i = 1; i < pred_sets.size(); ++i) { + bool change = true; + while (change) { + change = false; + func_decl_set::iterator it = pred_sets[i]->begin(), end = pred_sets[i]->end(); + for (; it != end; ++it) { + func_decl* pred = *it; + if (depends_on_negation.contains(pred)) { + continue; + } + rule_vector const& rules = m_context.get_rules().get_predicate_rules(pred); + bool inserted = false; + for (unsigned j = 0; !inserted && j < rules.size(); ++j) { + rule* r = rules[j]; + unsigned psz = r->get_positive_tail_size(); + unsigned tsz = r->get_uninterpreted_tail_size(); + if (psz < tsz) { + depends_on_negation.insert(pred); + change = true; + inserted = true; + } + for (unsigned k = 0; !inserted && k < tsz; ++k) { + func_decl* tail_decl = r->get_tail(k)->get_decl(); + if (depends_on_negation.contains(tail_decl)) { + depends_on_negation.insert(pred); + change = true; + inserted = true; + } + } + } + } + } + } + func_decl_set::iterator it = depends_on_negation.begin(), end = depends_on_negation.end(); + for (; it != end; ++it) { + func_decl* pred = *it; + relation_base & rel = get_relation(pred); + + if (!rel.empty()) { + TRACE("dl", tout << "Resetting: " << mk_ismt2_pp(pred, m) << "\n";); + rel.reset(); + } + } + } + + void rel_context::set_output_predicate(func_decl * pred) { + if (!m_output_preds.contains(pred)) { + m_output_preds.insert(pred); + } + } + + void rel_context::restrict_predicates( const decl_set & res ) { + set_intersection(m_output_preds, res); + get_rmanager().restrict_predicates(res); + } + + relation_base & rel_context::get_relation(func_decl * pred) { return get_rmanager().get_relation(pred); } + relation_base * rel_context::try_get_relation(func_decl * pred) const { return get_rmanager().try_get_relation(pred); } + + relation_manager & rel_context::get_rmanager() { return m_rmanager; } + + const relation_manager & rel_context::get_rmanager() const { return m_rmanager; } + + bool rel_context::output_profile() const { return m_context.output_profile(); } + + + void rel_context::set_predicate_representation(func_decl * pred, unsigned relation_name_cnt, + symbol const * relation_names) { + + relation_manager & rmgr = get_rmanager(); + + family_id target_kind = null_family_id; + switch (relation_name_cnt) { + case 0: + return; + case 1: + target_kind = get_ordinary_relation_plugin(relation_names[0]).get_kind(); + break; + default: { + svector rel_kinds; // kinds of plugins that are not table plugins + family_id rel_kind; // the aggregate kind of non-table plugins + for (unsigned i = 0; i < relation_name_cnt; i++) { + relation_plugin & p = get_ordinary_relation_plugin(relation_names[i]); + rel_kinds.push_back(p.get_kind()); + } + if (rel_kinds.size() == 1) { + rel_kind = rel_kinds[0]; + } + else { + relation_signature rel_sig; + //rmgr.from_predicate(pred, rel_sig); + product_relation_plugin & prod_plugin = product_relation_plugin::get_plugin(rmgr); + rel_kind = prod_plugin.get_relation_kind(rel_sig, rel_kinds); + } + target_kind = rel_kind; + break; + } + } + + SASSERT(target_kind != null_family_id); + get_rmanager().set_predicate_kind(pred, target_kind); + } + + relation_plugin & rel_context::get_ordinary_relation_plugin(symbol relation_name) { + relation_plugin * plugin = get_rmanager().get_relation_plugin(relation_name); + if (!plugin) { + std::stringstream sstm; + sstm << "relation plugin " << relation_name << " does not exist"; + throw default_exception(sstm.str()); + } + if (plugin->is_product_relation()) { + throw default_exception("cannot request product relation directly"); + } + if (plugin->is_sieve_relation()) { + throw default_exception("cannot request sieve relation directly"); + } + if (plugin->is_finite_product_relation()) { + throw default_exception("cannot request finite product relation directly"); + } + return *plugin; + } + + bool rel_context::result_contains_fact(relation_fact const& f) { + SASSERT(m_last_result_relation); + return m_last_result_relation->contains_fact(f); + } + + void rel_context::reset_tables() { + get_rmanager().reset_saturated_marks(); + rule_set::decl2rules::iterator it = m_context.get_rules().begin_grouped_rules(); + rule_set::decl2rules::iterator end = m_context.get_rules().end_grouped_rules(); + for (; it != end; ++it) { + func_decl* p = it->m_key; + relation_base & rel = get_relation(p); + rel.reset(); + } + for (unsigned i = 0; i < m_table_facts.size(); ++i) { + func_decl* pred = m_table_facts[i].first; + relation_fact const& fact = m_table_facts[i].second; + get_relation(pred).add_fact(fact); + } + } + + void rel_context::add_fact(func_decl* pred, relation_fact const& fact) { + get_rmanager().reset_saturated_marks(); + get_relation(pred).add_fact(fact); + m_table_facts.push_back(std::make_pair(pred, fact)); + } + + void rel_context::add_fact(func_decl* pred, table_fact const& fact) { + get_rmanager().reset_saturated_marks(); + relation_base & rel0 = get_relation(pred); + if (rel0.from_table()) { + table_relation & rel = static_cast(rel0); + rel.add_table_fact(fact); + // TODO: table facts? + } + else { + relation_fact rfact(m); + for (unsigned i = 0; i < fact.size(); ++i) { + rfact.push_back(m_context.get_decl_util().mk_numeral(fact[i], pred->get_domain()[i])); + } + add_fact(pred, rfact); + } + } + + void rel_context::store_relation(func_decl * pred, relation_base * rel) { + get_rmanager().store_relation(pred, rel); + } + + void rel_context::inherit_predicate_kind(func_decl* new_pred, func_decl* orig_pred) { + if (orig_pred) { + family_id target_kind = get_rmanager().get_requested_predicate_kind(orig_pred); + if (target_kind != null_family_id) { + get_rmanager().set_predicate_kind(new_pred, target_kind); + } + } + } + + void rel_context::display_output_facts(std::ostream & out) const { + get_rmanager().display_output_tables(out); + } + + void rel_context::display_facts(std::ostream& out) const { + get_rmanager().display(out); + } + + +}; diff --git a/src/muz_qe/rel_context.h b/src/muz_qe/rel_context.h new file mode 100644 index 000000000..b05532d14 --- /dev/null +++ b/src/muz_qe/rel_context.h @@ -0,0 +1,115 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + rel_context.h + +Abstract: + + context for relational datalog engine. + +Author: + + Nikolaj Bjorner (nbjorner) 2012-12-3. + +Revision History: + + Extracted from dl_context + +--*/ +#ifndef _REL_CONTEXT_H_ +#define _REL_CONTEXT_H_ +#include "ast.h" +#include "dl_relation_manager.h" +#include "lbool.h" + +namespace datalog { + + class context; + + class rel_context { + typedef vector > fact_vector; + + context& m_context; + ast_manager& m; + relation_manager m_rmanager; + expr_ref m_answer; + volatile bool m_cancel; + relation_base * m_last_result_relation; + decl_set m_output_preds; + fact_vector m_table_facts; + + void reset_negated_tables(); + + relation_plugin & get_ordinary_relation_plugin(symbol relation_name); + + void reset_tables(); + + public: + rel_context(context& ctx); + + ~rel_context(); + + relation_manager & get_rmanager(); + const relation_manager & get_rmanager() const; + ast_manager& get_manager() { return m; } + context& get_context() { return m_context; } + relation_base & get_relation(func_decl * pred); + relation_base * try_get_relation(func_decl * pred) const; + expr_ref get_last_answer() { return m_answer; } + + bool output_profile() const; + + + lbool query(expr* q); + lbool query(unsigned num_rels, func_decl * const* rels); + + void set_predicate_representation(func_decl * pred, unsigned relation_name_cnt, + symbol const * relation_names); + + void inherit_predicate_kind(func_decl* new_pred, func_decl* orig_pred); + + void cancel() { m_cancel = true; } + + void cleanup() { m_cancel = false; } + + + /** + \brief Restrict the set of used predicates to \c res. + + The function deallocates unsused relations, it does not deal with rules. + */ + void restrict_predicates(const decl_set & res); + + void collect_predicates(decl_set & res); + + void set_output_predicate(func_decl * pred); + bool is_output_predicate(func_decl * pred) { return m_output_preds.contains(pred); } + const decl_set & get_output_predicates() const { return m_output_preds; } + + + /** + \brief query result if it contains fact. + */ + bool result_contains_fact(relation_fact const& f); + + void add_fact(func_decl* pred, relation_fact const& fact); + + void add_fact(func_decl* pred, table_fact const& fact); + + /** + \brief Store the relation \c rel under the predicate \c pred. The \c context object + takes over the ownership of the relation object. + */ + void store_relation(func_decl * pred, relation_base * rel); + + void display_output_facts(std::ostream & out) const; + void display_facts(std::ostream & out) const; + + lbool saturate(); + + }; +}; + +#endif /* _REL_CONTEXT_H_ */ diff --git a/src/muz_qe/unit_subsumption_tactic.cpp b/src/muz_qe/unit_subsumption_tactic.cpp index cd43e73e3..afc81723a 100644 --- a/src/muz_qe/unit_subsumption_tactic.cpp +++ b/src/muz_qe/unit_subsumption_tactic.cpp @@ -21,7 +21,7 @@ Author: struct unit_subsumption_tactic : public tactic { ast_manager& m; params_ref m_params; - front_end_params m_fparams; + smt_params m_fparams; volatile bool m_cancel; smt::context m_context; expr_ref_vector m_clauses; @@ -37,7 +37,6 @@ struct unit_subsumption_tactic : public tactic { m_cancel(false), m_context(m, m_fparams, p), m_clauses(m) { - m_fparams.m_proof_mode = m.proof_mode(); } void set_cancel(bool f) { diff --git a/src/muz_qe/vsubst_tactic.cpp b/src/muz_qe/vsubst_tactic.cpp index 83e1c448b..c389d9a66 100644 --- a/src/muz_qe/vsubst_tactic.cpp +++ b/src/muz_qe/vsubst_tactic.cpp @@ -45,7 +45,6 @@ Notes: #include"arith_decl_plugin.h" #include"for_each_expr.h" #include"extension_model_converter.h" -#include"params2front_end_params.h" #include"ast_smt2_pp.h" class vsubst_tactic : public tactic { @@ -93,8 +92,8 @@ class vsubst_tactic : public tactic { throw tactic_exception("there are no real variables"); } - front_end_params params; - params2front_end_params(p, params); + smt_params params; + params.updt_params(p); params.m_model = false; flet fl1(params.m_nlquant_elim, true); flet fl2(params.m_nl_arith_gb, false); diff --git a/src/nlsat/nlsat_params.pyg b/src/nlsat/nlsat_params.pyg new file mode 100644 index 000000000..4faad3379 --- /dev/null +++ b/src/nlsat/nlsat_params.pyg @@ -0,0 +1,14 @@ + +def_module_params('nlsat', + description='nonlinear solver', + export=True, + params=(max_memory_param(), + ('lazy', UINT, 0, "how lazy the solver is."), + ('reorder', BOOL, True, "reorder variables."), + ('simplify_conflicts', BOOL, True, "simplify conflicts using equalities before resolving them in nlsat solver."), + ('minimize_conflicts', BOOL, False, "minimize conflicts"), + ('randomize', BOOL, True, "randomize selection of a witness in nlsat."), + ('max_conflicts', UINT, UINT_MAX, "maximum number of conflicts."), + ('shuffle_vars', BOOL, False, "use a random variable order."), + ('seed', UINT, 0, "random seed."))) + diff --git a/src/nlsat/nlsat_solver.cpp b/src/nlsat/nlsat_solver.cpp index 837e76ecd..341431556 100644 --- a/src/nlsat/nlsat_solver.cpp +++ b/src/nlsat/nlsat_solver.cpp @@ -31,6 +31,7 @@ Revision History: #include"dependency.h" #include"polynomial_cache.h" #include"permutation.h" +#include"nlsat_params.hpp" #define NLSAT_EXTRA_VERBOSE @@ -197,20 +198,21 @@ namespace nlsat { mk_clause(1, &true_lit, false, 0); } - void updt_params(params_ref const & p) { - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); - m_lazy = p.get_uint(":lazy", 0); - m_simplify_cores = p.get_bool(":simplify-conflicts", true); - bool min_cores = p.get_bool(":minimize-conflicts", false); - m_reorder = p.get_bool(":reorder", true); - m_randomize = p.get_bool(":randomize", true); - m_max_conflicts = p.get_uint(":max-conflicts", UINT_MAX); - m_random_order = p.get_bool(":shuffle-vars", false); - m_random_seed = p.get_uint(":seed", 0); + void updt_params(params_ref const & _p) { + nlsat_params p(_p); + m_max_memory = p.max_memory(); + m_lazy = p.lazy(); + m_simplify_cores = p.simplify_conflicts(); + bool min_cores = p.minimize_conflicts(); + m_reorder = p.reorder(); + m_randomize = p.randomize(); + m_max_conflicts = p.max_conflicts(); + m_random_order = p.shuffle_vars(); + m_random_seed = p.seed(); m_ism.set_seed(m_random_seed); m_explain.set_simplify_cores(m_simplify_cores); m_explain.set_minimize_cores(min_cores); - m_am.updt_params(p); + m_am.updt_params(p.p); } void set_cancel(bool f) { @@ -2570,15 +2572,8 @@ namespace nlsat { } void solver::collect_param_descrs(param_descrs & d) { - insert_max_memory(d); algebraic_numbers::manager::collect_param_descrs(d); - d.insert(":max-conflicts", CPK_UINT, "(default: inf) maximum number of conflicts."); - d.insert(":shuffle-vars", CPK_BOOL, "(default: false) use a variable order."); - d.insert(":seed", CPK_UINT, "(default: 0) random seed."); - d.insert(":randomize", CPK_BOOL, "(default: true) randomize selection of a witness in nlsat."); - d.insert(":reorder", CPK_BOOL, "(default: true) reorder variables."); - d.insert(":lazy", CPK_UINT, "(default: 0) how lazy the solver is."); - d.insert(":simplify-conflicts", CPK_BOOL, "(default: true) simplify conflicts using equalities before resolving them in nlsat solver."); + nlsat_params::collect_param_descrs(d); } unsynch_mpq_manager & solver::qm() { diff --git a/src/nlsat/tactic/goal2nlsat.cpp b/src/nlsat/tactic/goal2nlsat.cpp index 75e3c4a40..1af98c7e8 100644 --- a/src/nlsat/tactic/goal2nlsat.cpp +++ b/src/nlsat/tactic/goal2nlsat.cpp @@ -77,8 +77,8 @@ struct goal2nlsat::imp { } void updt_params(params_ref const & p) { - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); - m_factor = p.get_bool(":factor", true); + m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); + m_factor = p.get_bool("factor", true); m_fparams.updt_params(p); } @@ -293,7 +293,7 @@ goal2nlsat::~goal2nlsat() { void goal2nlsat::collect_param_descrs(param_descrs & r) { insert_max_memory(r); - r.insert(":factor", CPK_BOOL, "(default: true) factor polynomials."); + r.insert("factor", CPK_BOOL, "(default: true) factor polynomials."); polynomial::factor_params::get_param_descrs(r); } diff --git a/src/nlsat/tactic/qfnra_nlsat_tactic.cpp b/src/nlsat/tactic/qfnra_nlsat_tactic.cpp index 7bb6bd019..b05636541 100644 --- a/src/nlsat/tactic/qfnra_nlsat_tactic.cpp +++ b/src/nlsat/tactic/qfnra_nlsat_tactic.cpp @@ -31,13 +31,13 @@ Notes: tactic * mk_qfnra_nlsat_tactic(ast_manager & m, params_ref const & p) { params_ref main_p = p; - main_p.set_bool(":elim-and", true); - main_p.set_bool(":blast-distinct", true); + main_p.set_bool("elim_and", true); + main_p.set_bool("blast_distinct", true); params_ref purify_p = p; - purify_p.set_bool(":complete", false); // temporary hack, solver does not support uninterpreted functions for encoding (div0 x) applications. So, we replace it application of this kind with an uninterpreted function symbol. + purify_p.set_bool("complete", false); // temporary hack, solver does not support uninterpreted functions for encoding (div0 x) applications. So, we replace it application of this kind with an uninterpreted function symbol. tactic * factor; - if (p.get_bool(":factor", true)) + if (p.get_bool("factor", true)) factor = mk_factor_tactic(m, p); else factor = mk_skip_tactic(); diff --git a/src/parsers/smt/smtlib_solver.cpp b/src/parsers/smt/smtlib_solver.cpp index dd54de350..ef28216bf 100644 --- a/src/parsers/smt/smtlib_solver.cpp +++ b/src/parsers/smt/smtlib_solver.cpp @@ -28,15 +28,18 @@ Revision History: #include"solver.h" #include"smt_strategic_solver.h" #include"cmd_context.h" +#include"model_params.hpp" +#include"parser_params.hpp" namespace smtlib { - solver::solver(front_end_params & params): - m_ast_manager(params.m_proof_mode, params.m_trace_stream), - m_params(params), + solver::solver(): + m_ast_manager(m_params.m_proof ? PGM_FINE : PGM_DISABLED, + m_params.m_trace ? m_params.m_trace_file_name.c_str() : 0), m_ctx(0), - m_parser(parser::create(m_ast_manager, params.m_ignore_user_patterns)), m_error_code(0) { + parser_params ps; + m_parser = parser::create(m_ast_manager, ps.ignore_user_patterns()); m_parser->initialize_smtlib(); } @@ -82,7 +85,7 @@ namespace smtlib { // Hack: it seems SMT-LIB allow benchmarks without any :formula benchmark.add_formula(m_ast_manager.mk_true()); } - m_ctx = alloc(cmd_context, &m_params, true, &m_ast_manager, benchmark.get_logic()); + m_ctx = alloc(cmd_context, true, &m_ast_manager, benchmark.get_logic()); m_ctx->set_solver(mk_smt_strategic_solver(false)); theory::expr_iterator fit = benchmark.begin_formulas(); theory::expr_iterator fend = benchmark.end_formulas(); @@ -100,12 +103,13 @@ namespace smtlib { check_sat_result * r = m_ctx->get_check_sat_result(); if (r != 0) { proof * pr = r->get_proof(); - if (pr != 0 && m_params.m_display_proof) + if (pr != 0 && m_params.m_proof) std::cout << mk_ll_pp(pr, m_ast_manager, false, false); model_ref md; if (r->status() != l_false) r->get_model(md); if (md.get() != 0 && m_params.m_model) { - model_v2_pp(std::cout, *(md.get()), m_params.m_model_partial); + model_params p; + model_v2_pp(std::cout, *(md.get()), p.partial()); } } else { diff --git a/src/parsers/smt/smtlib_solver.h b/src/parsers/smt/smtlib_solver.h index a84f2c98f..4e9815d38 100644 --- a/src/parsers/smt/smtlib_solver.h +++ b/src/parsers/smt/smtlib_solver.h @@ -20,20 +20,20 @@ Revision History: #define _SMTLIB_SOLVER_H_ #include"smtparser.h" -#include"front_end_params.h" +#include"context_params.h" #include"lbool.h" class cmd_context; namespace smtlib { class solver { + context_params m_params; ast_manager m_ast_manager; - front_end_params & m_params; cmd_context * m_ctx; scoped_ptr m_parser; unsigned m_error_code; public: - solver(front_end_params & params); + solver(); ~solver(); bool solve_smt(char const * benchmark_file); bool solve_smt_string(char const * benchmark_string); diff --git a/src/parsers/smt/smtparser.cpp b/src/parsers/smt/smtparser.cpp index 53dffb28c..d3b2feeb7 100644 --- a/src/parsers/smt/smtparser.cpp +++ b/src/parsers/smt/smtparser.cpp @@ -37,7 +37,6 @@ Revision History: #include"var_subst.h" #include"well_sorted.h" #include"str_hashtable.h" -#include"front_end_params.h" #include"stopwatch.h" class id_param_info { diff --git a/src/parsers/smt2/smt2parser.cpp b/src/parsers/smt2/smt2parser.cpp index f288c526e..ee93dca2f 100644 --- a/src/parsers/smt2/smt2parser.cpp +++ b/src/parsers/smt2/smt2parser.cpp @@ -28,13 +28,14 @@ Revision History: #include"rewriter.h" #include"has_free_vars.h" #include"ast_smt2_pp.h" -#include"front_end_params.h" +#include"parser_params.hpp" namespace smt2 { typedef cmd_exception parser_exception; class parser { cmd_context & m_ctx; + params_ref m_params; scanner m_scanner; scanner::token m_curr; cmd * m_curr_cmd; @@ -106,9 +107,14 @@ namespace smt2 { ast_manager & m() const { return m_ctx.m(); } pdecl_manager & pm() const { return m_ctx.pm(); } sexpr_manager & sm() const { return m_ctx.sm(); } + + bool m_ignore_user_patterns; + bool m_ignore_bad_patterns; + bool m_display_error_for_vs; - bool ignore_user_patterns() const { return m_ctx.params().m_ignore_user_patterns; } - bool ignore_bad_patterns() const { return m_ctx.params().m_ignore_bad_patterns; } + bool ignore_user_patterns() const { return m_ignore_user_patterns; } + bool ignore_bad_patterns() const { return m_ignore_bad_patterns; } + bool use_vs_format() const { return m_display_error_for_vs; } struct psort_frame { psort_decl * m_decl; @@ -383,8 +389,6 @@ namespace smt2 { void check_int(char const * msg) { if (!curr_is_int()) throw parser_exception(msg); } void check_float(char const * msg) { if (!curr_is_float()) throw parser_exception(msg); } - bool use_vs_format() const { return m_ctx.params().m_display_error_for_vs; } - void error(unsigned line, unsigned pos, char const * msg) { if (use_vs_format()) { m_ctx.diagnostic_stream() << "Z3(" << line << ", " << pos << "): ERROR: " << msg; @@ -2282,6 +2286,10 @@ namespace smt2 { shrink(m_sexpr_stack, sexpr_spos); m_symbol_stack.shrink(sym_spos); m_num_bindings = 0; + // HACK for propagating the update of parser parameters + if (norm_param_name(s) == "set_option") { + updt_params(); + } return; } else { @@ -2354,9 +2362,10 @@ namespace smt2 { } public: - parser(cmd_context & ctx, std::istream & is, bool interactive): + parser(cmd_context & ctx, std::istream & is, bool interactive, params_ref const & p): m_ctx(ctx), - m_scanner(ctx, is, interactive), + m_params(p), + m_scanner(ctx, is, interactive, p), m_curr(scanner::NULL_TOKEN), m_curr_cmd(0), m_num_bindings(0), @@ -2393,11 +2402,20 @@ namespace smt2 { m_num_open_paren(0) { // the following assertion does not hold if ctx was already attached to an AST manager before the parser object is created. // SASSERT(!m_ctx.has_manager()); + + updt_params(); } ~parser() { reset_stack(); } + + void updt_params() { + parser_params p(m_params); + m_ignore_user_patterns = p.ignore_user_patterns(); + m_ignore_bad_patterns = p.ignore_bad_patterns(); + m_display_error_for_vs = p.error_for_visual_studio(); + } void reset() { reset_stack(); @@ -2487,8 +2505,8 @@ namespace smt2 { }; }; -bool parse_smt2_commands(cmd_context & ctx, std::istream & is, bool interactive) { - smt2::parser p(ctx, is, interactive); +bool parse_smt2_commands(cmd_context & ctx, std::istream & is, bool interactive, params_ref const & ps) { + smt2::parser p(ctx, is, interactive, ps); return p(); } diff --git a/src/parsers/smt2/smt2parser.h b/src/parsers/smt2/smt2parser.h index a7264ff63..d230e5ae0 100644 --- a/src/parsers/smt2/smt2parser.h +++ b/src/parsers/smt2/smt2parser.h @@ -21,6 +21,6 @@ Revision History: #include"cmd_context.h" -bool parse_smt2_commands(cmd_context & ctx, std::istream & is, bool interactive = false); +bool parse_smt2_commands(cmd_context & ctx, std::istream & is, bool interactive = false, params_ref const & p = params_ref()); #endif diff --git a/src/parsers/smt2/smt2scanner.cpp b/src/parsers/smt2/smt2scanner.cpp index b350796fc..e2b2030ac 100644 --- a/src/parsers/smt2/smt2scanner.cpp +++ b/src/parsers/smt2/smt2scanner.cpp @@ -17,6 +17,7 @@ Revision History: --*/ #include"smt2scanner.h" +#include"parser_params.hpp" namespace smt2 { @@ -241,7 +242,7 @@ namespace smt2 { } } - scanner::scanner(cmd_context & ctx, std::istream& stream, bool interactive): + scanner::scanner(cmd_context & ctx, std::istream& stream, bool interactive, params_ref const & _p): m_ctx(ctx), m_interactive(interactive), m_spos(0), @@ -253,6 +254,10 @@ namespace smt2 { m_bend(0), m_stream(stream), m_cache_input(false) { + + parser_params p(_p); + m_smtlib2_compliant = p.smt2_compliant(); + for (int i = 0; i < 256; ++i) { m_normalized[i] = (char) i; } @@ -325,7 +330,7 @@ namespace smt2 { case '#': return read_bv_literal(); case '-': - if (m_ctx.is_smtlib2_compliant()) + if (m_smtlib2_compliant) return read_symbol(); else return read_signed_number(); diff --git a/src/parsers/smt2/smt2scanner.h b/src/parsers/smt2/smt2scanner.h index 015f05fa1..c63a09ff1 100644 --- a/src/parsers/smt2/smt2scanner.h +++ b/src/parsers/smt2/smt2scanner.h @@ -55,6 +55,8 @@ namespace smt2 { svector m_cache; svector m_cache_result; + bool m_smtlib2_compliant; + char curr() const { return m_curr; } void new_line() { m_line++; m_spos = 0; } void next(); @@ -74,7 +76,7 @@ namespace smt2 { EOF_TOKEN }; - scanner(cmd_context & ctx, std::istream& stream, bool interactive = false); + scanner(cmd_context & ctx, std::istream& stream, bool interactive = false, params_ref const & p = params_ref()); ~scanner() {} diff --git a/src/parsers/util/parser_params.pyg b/src/parsers/util/parser_params.pyg new file mode 100644 index 000000000..fa8f17a00 --- /dev/null +++ b/src/parsers/util/parser_params.pyg @@ -0,0 +1,6 @@ +def_module_params('parser', + export=True, + params=(('ignore_user_patterns', BOOL, False, 'ignore patterns provided by the user'), + ('ignore_bad_patterns', BOOL, True, 'ignore malformed patterns'), + ('error_for_visual_studio', BOOL, False, 'display error messages in Visual Studio format'), + ('smt2_compliant', BOOL, False, 'enable/disable SMT-LIB 2.0 compliance'))) diff --git a/src/parsers/util/simple_parser.cpp b/src/parsers/util/simple_parser.cpp index 65f75e870..045a45b24 100644 --- a/src/parsers/util/simple_parser.cpp +++ b/src/parsers/util/simple_parser.cpp @@ -112,7 +112,7 @@ expr * simple_parser::parse_expr(scanner & s) { } bool simple_parser::parse(std::istream & in, expr_ref & result) { - scanner s(in, std::cerr, false); + scanner s(in, std::cerr, false); try { result = parse_expr(s); if (!result) diff --git a/src/sat/sat_asymm_branch.cpp b/src/sat/sat_asymm_branch.cpp index bc2a7120d..81d631e4e 100644 --- a/src/sat/sat_asymm_branch.cpp +++ b/src/sat/sat_asymm_branch.cpp @@ -17,6 +17,7 @@ Revision History: --*/ #include"sat_asymm_branch.h" +#include"sat_asymm_branch_params.hpp" #include"sat_solver.h" #include"stopwatch.h" #include"trace.h" @@ -193,18 +194,17 @@ namespace sat { } } - void asymm_branch::updt_params(params_ref const & p) { - m_asymm_branch = p.get_bool(":asymm-branch", true); - m_asymm_branch_rounds = p.get_uint(":asymm-branch-rounds", 32); - m_asymm_branch_limit = p.get_uint(":asymm-branch-limit", 100000000); + void asymm_branch::updt_params(params_ref const & _p) { + sat_asymm_branch_params p(_p); + m_asymm_branch = p.asymm_branch(); + m_asymm_branch_rounds = p.asymm_branch_rounds(); + m_asymm_branch_limit = p.asymm_branch_limit(); if (m_asymm_branch_limit > INT_MAX) m_asymm_branch_limit = INT_MAX; } void asymm_branch::collect_param_descrs(param_descrs & d) { - d.insert(":asymm-branch", CPK_BOOL, "(default: true) asymmetric branching."); - d.insert(":asymm-branch-rounds", CPK_UINT, "(default: 32) maximum number of rounds of asymmetric branching."); - d.insert(":asymm-branch-limit", CPK_UINT, "approx. maximum number of literals visited during asymmetric branching."); + sat_asymm_branch_params::collect_param_descrs(d); } void asymm_branch::collect_statistics(statistics & st) { diff --git a/src/sat/sat_asymm_branch_params.pyg b/src/sat/sat_asymm_branch_params.pyg new file mode 100644 index 000000000..8940c64a6 --- /dev/null +++ b/src/sat/sat_asymm_branch_params.pyg @@ -0,0 +1,6 @@ +def_module_params(module_name='sat', + class_name='sat_asymm_branch_params', + export=True, + params=(('asymm_branch', BOOL, True, 'asymmetric branching'), + ('asymm_branch.rounds', UINT, 32, 'maximum number of rounds of asymmetric branching'), + ('asymm_branch.limit', UINT, 100000000, 'approx. maximum number of literals visited during asymmetric branching'))) diff --git a/src/sat/sat_config.cpp b/src/sat/sat_config.cpp index 48aa270e4..cc0f97ff0 100644 --- a/src/sat/sat_config.cpp +++ b/src/sat/sat_config.cpp @@ -18,28 +18,30 @@ Revision History: --*/ #include"sat_config.h" #include"sat_types.h" +#include"sat_params.hpp" namespace sat { config::config(params_ref const & p): - m_always_true("always-true"), - m_always_false("always-false"), + m_always_true("always_true"), + m_always_false("always_false"), m_caching("caching"), m_random("random"), m_geometric("geometric"), m_luby("luby"), - m_dyn_psm("dyn-psm"), + m_dyn_psm("dyn_psm"), m_psm("psm"), m_glue("glue"), - m_glue_psm("glue-psm"), - m_psm_glue("psm-glue") { + m_glue_psm("glue_psm"), + m_psm_glue("psm_glue") { updt_params(p); } - void config::updt_params(params_ref const & p) { - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); + void config::updt_params(params_ref const & _p) { + sat_params p(_p); + m_max_memory = megabytes_to_bytes(p.max_memory()); - symbol s = p.get_sym(":restart", m_luby); + symbol s = p.restart(); if (s == m_luby) m_restart = RS_LUBY; else if (s == m_geometric) @@ -47,7 +49,7 @@ namespace sat { else throw sat_param_exception("invalid restart strategy"); - s = p.get_sym(":phase", m_caching); + s = p.phase(); if (s == m_always_false) m_phase = PS_ALWAYS_FALSE; else if (s == m_always_true) @@ -59,29 +61,31 @@ namespace sat { else throw sat_param_exception("invalid phase selection strategy"); - m_phase_caching_on = p.get_uint(":phase-caching-on", 400); - m_phase_caching_off = p.get_uint(":phase-caching-off", 100); + m_phase_caching_on = p.phase_caching_on(); + m_phase_caching_off = p.phase_caching_off(); - m_restart_initial = p.get_uint(":restart-initial", 100); - m_restart_factor = p.get_double(":restart-factor", 1.5); + m_restart_initial = p.restart_initial(); + m_restart_factor = p.restart_factor(); - m_random_freq = p.get_double(":random-freq", 0.01); + m_random_freq = p.random_freq(); - m_burst_search = p.get_uint(":burst-search", 100); + m_burst_search = p.burst_search(); - m_max_conflicts = p.get_uint(":max-conflicts", UINT_MAX); + m_max_conflicts = p.max_conflicts(); + + // These parameters are not exposed + m_simplify_mult1 = _p.get_uint("simplify_mult1", 300); + m_simplify_mult2 = _p.get_double("simplify_mult2", 1.5); + m_simplify_max = _p.get_uint("simplify_max", 500000); + // -------------------------------- - m_simplify_mult1 = p.get_uint(":simplify-mult1", 300); - m_simplify_mult2 = p.get_double(":simplify-mult2", 1.5); - m_simplify_max = p.get_uint(":simplify-max", 500000); - - s = p.get_sym(":gc-strategy", m_glue_psm); + s = p.gc(); if (s == m_dyn_psm) { m_gc_strategy = GC_DYN_PSM; - m_gc_initial = p.get_uint(":gc-initial", 500); - m_gc_increment = p.get_uint(":gc-increment", 100); - m_gc_small_lbd = p.get_uint(":gc-small-lbd", 3); - m_gc_k = p.get_uint(":gc-k", 7); + m_gc_initial = p.gc_initial(); + m_gc_increment = p.gc_increment(); + m_gc_small_lbd = p.gc_small_lbd(); + m_gc_k = p.gc_k(); if (m_gc_k > 255) m_gc_k = 255; } @@ -96,31 +100,15 @@ namespace sat { m_gc_strategy = GC_PSM_GLUE; else throw sat_param_exception("invalid gc strategy"); - m_gc_initial = p.get_uint(":gc-initial", 20000); - m_gc_increment = p.get_uint(":gc-increment", 500); + m_gc_initial = p.gc_initial(); + m_gc_increment = p.gc_increment(); } - m_minimize_lemmas = p.get_bool(":minimize-lemmas", true); - m_dyn_sub_res = p.get_bool(":dyn-sub-res", true); + m_minimize_lemmas = p.minimize_lemmas(); + m_dyn_sub_res = p.dyn_sub_res(); } void config::collect_param_descrs(param_descrs & r) { - insert_max_memory(r); - r.insert(":phase", CPK_SYMBOL, "(default: caching) phase selection strategy: always-false, always-true, caching, random."); - r.insert(":phase-caching-on", CPK_UINT, "(default: 400)"); - r.insert(":phase-caching-off", CPK_UINT, "(default: 100)"); - r.insert(":restart", CPK_SYMBOL, "(default: luby) restart strategy: luby or geometric."); - r.insert(":restart-initial", CPK_UINT, "(default: 100) initial restart (number of conflicts)."); - r.insert(":restart-factor", CPK_DOUBLE, "(default: 1.5) restart increment factor for geometric strategy."); - r.insert(":random-freq", CPK_DOUBLE, "(default: 0.01) frequency of random case splits."); - r.insert(":burst-search", CPK_UINT, "(default: 100) number of conflicts before first global simplification."); - r.insert(":max-conflicts", CPK_UINT, "(default: inf) maximum number of conflicts."); - r.insert(":gc-strategy", CPK_SYMBOL, "(default: glue-psm) garbage collection strategy: psm, glue, glue-psm, dyn-psm."); - r.insert(":gc-initial", CPK_UINT, "(default: 20000) learned clauses garbage collection frequence."); - r.insert(":gc-increment", CPK_UINT, "(default: 500) increment to the garbage collection threshold."); - r.insert(":gc-small-lbd", CPK_UINT, "(default: 3) learned clauses with small LBD are never deleted (only used in dyn-psm)."); - r.insert(":gc-k", CPK_UINT, "(default: 7) learned clauses that are inactive for k gc rounds are permanently deleted (only used in dyn-psm)."); - r.insert(":minimize-lemmas", CPK_BOOL, "(default: true) minimize learned clauses."); - r.insert(":dyn-sub-res", CPK_BOOL, "(default: true) dynamic subsumption resolution for minimizing learned clauses."); + sat_params::collect_param_descrs(r); } }; diff --git a/src/sat/sat_params.pyg b/src/sat/sat_params.pyg new file mode 100644 index 000000000..71579b86a --- /dev/null +++ b/src/sat/sat_params.pyg @@ -0,0 +1,20 @@ +def_module_params('sat', + export=True, + description='propositional SAT solver', + params=(max_memory_param(), + ('phase', SYMBOL, 'caching', 'phase selection strategy: always_false, always_true, caching, random'), + ('phase.caching.on', UINT, 400, 'phase caching on period (in number of conflicts)'), + ('phase.caching.off', UINT, 100, 'phase caching off period (in number of conflicts)'), + ('restart', SYMBOL, 'luby', 'restart strategy: luby or geometric'), + ('restart.initial', UINT, 100, 'initial restart (number of conflicts)'), + ('restart.factor', DOUBLE, 1.5, 'restart increment factor for geometric strategy'), + ('random_freq', DOUBLE, 0.01, 'frequency of random case splits'), + ('burst_search', UINT, 100, 'number of conflicts before first global simplification'), + ('max_conflicts', UINT, UINT_MAX, 'maximum number of conflicts'), + ('gc', SYMBOL, 'glue_psm', 'garbage collection strategy: psm, glue, glue_psm, dyn_psm'), + ('gc.initial', UINT, 20000, 'learned clauses garbage collection frequence'), + ('gc.increment', UINT, 500, 'increment to the garbage collection threshold'), + ('gc.small_lbd', UINT, 3, 'learned clauses with small LBD are never deleted (only used in dyn_psm)'), + ('gc.k', UINT, 7, 'learned clauses that are inactive for k gc rounds are permanently deleted (only used in dyn_psm)'), + ('minimize_lemmas', BOOL, True, 'minimize learned clauses'), + ('dyn_sub_res', BOOL, True, 'dynamic subsumption resolution for minimizing learned clauses'))) diff --git a/src/sat/sat_probing.cpp b/src/sat/sat_probing.cpp index f51b16033..f9741cd7b 100644 --- a/src/sat/sat_probing.cpp +++ b/src/sat/sat_probing.cpp @@ -243,11 +243,11 @@ namespace sat { } void probing::updt_params(params_ref const & p) { - m_probing = p.get_bool(":probing", true); - m_probing_limit = p.get_uint(":probing-limit", 5000000); - m_probing_cache = p.get_bool(":probing-cache", true); - m_probing_binary = p.get_bool(":probing-binary", true); - m_probing_cache_limit = megabytes_to_bytes(p.get_uint(":probing-chache-limit", 1024)); + m_probing = p.get_bool("probing", true); + m_probing_limit = p.get_uint("probing_limit", 5000000); + m_probing_cache = p.get_bool("probing_cache", true); + m_probing_binary = p.get_bool("probing_binary", true); + m_probing_cache_limit = megabytes_to_bytes(p.get_uint("probing_chache_limit", 1024)); } void probing::collect_param_descrs(param_descrs & d) { diff --git a/src/sat/sat_scc.cpp b/src/sat/sat_scc.cpp index 5e351290f..29f3f006f 100644 --- a/src/sat/sat_scc.cpp +++ b/src/sat/sat_scc.cpp @@ -21,6 +21,7 @@ Revision History: #include"sat_elim_eqs.h" #include"stopwatch.h" #include"trace.h" +#include"sat_scc_params.hpp" namespace sat { @@ -230,12 +231,13 @@ namespace sat { m_num_elim = 0; } - void scc::updt_params(params_ref const & p) { - m_scc = p.get_bool(":scc", true); + void scc::updt_params(params_ref const & _p) { + sat_scc_params p(_p); + m_scc = p.scc(); } void scc::collect_param_descrs(param_descrs & d) { - d.insert(":scc", CPK_BOOL, "(default: true) eliminate Boolean variables by computing strongly connected components."); + sat_scc_params::collect_param_descrs(d); } }; diff --git a/src/sat/sat_scc_params.pyg b/src/sat/sat_scc_params.pyg new file mode 100644 index 000000000..b88de4de8 --- /dev/null +++ b/src/sat/sat_scc_params.pyg @@ -0,0 +1,5 @@ +def_module_params(module_name='sat', + class_name='sat_scc_params', + export=True, + params=(('scc', BOOL, True, 'eliminate Boolean variables by computing strongly connected components'),)) + diff --git a/src/sat/sat_simplifier.cpp b/src/sat/sat_simplifier.cpp index 3f3015967..623c73758 100644 --- a/src/sat/sat_simplifier.cpp +++ b/src/sat/sat_simplifier.cpp @@ -19,6 +19,7 @@ Revision History: --*/ #include"sat_simplifier.h" +#include"sat_simplifier_params.hpp" #include"sat_solver.h" #include"stopwatch.h" #include"trace.h" @@ -1430,45 +1431,28 @@ namespace sat { m_new_cls.finalize(); } - void simplifier::updt_params(params_ref const & p) { - m_elim_blocked_clauses = p.get_bool(":elim-blocked-clauses", false); - m_elim_blocked_clauses_at = p.get_uint(":elim-blocked-clauses-at", 2); - m_blocked_clause_limit = p.get_uint(":blocked-clause-limit", 100000000); - m_resolution = p.get_bool(":resolution", true); - m_res_limit = p.get_uint(":resolution-limit", 500000000); - m_res_occ_cutoff = p.get_uint(":res-occ-cutoff", 10); - m_res_occ_cutoff1 = p.get_uint(":res-occ-cutoff-range1", 8); - m_res_occ_cutoff2 = p.get_uint(":res-occ-cutoff-range2", 5); - m_res_occ_cutoff3 = p.get_uint(":res-occ-cutoff-range3", 3); - m_res_lit_cutoff1 = p.get_uint(":res-lit-cutoff-range1", 700); - m_res_lit_cutoff2 = p.get_uint(":res-lit-cutoff-range2", 400); - m_res_lit_cutoff3 = p.get_uint(":res-lit-cutoff-range3", 300); - m_res_cls_cutoff1 = p.get_uint(":res-cls-cutoff1", 100000); - m_res_cls_cutoff2 = p.get_uint(":res-cls-cutoff2", 700000); - m_subsumption = p.get_bool(":subsumption", true); - m_subsumption_limit = p.get_uint(":subsumption-limit", 100000000); + void simplifier::updt_params(params_ref const & _p) { + sat_simplifier_params p(_p); + m_elim_blocked_clauses = p.elim_blocked_clauses(); + m_elim_blocked_clauses_at = p.elim_blocked_clauses_at(); + m_blocked_clause_limit = p.blocked_clause_limit(); + m_resolution = p.resolution(); + m_res_limit = p.resolution_limit(); + m_res_occ_cutoff = p.resolution_occ_cutoff(); + m_res_occ_cutoff1 = p.resolution_occ_cutoff_range1(); + m_res_occ_cutoff2 = p.resolution_occ_cutoff_range2(); + m_res_occ_cutoff3 = p.resolution_occ_cutoff_range3(); + m_res_lit_cutoff1 = p.resolution_lit_cutoff_range1(); + m_res_lit_cutoff2 = p.resolution_lit_cutoff_range2(); + m_res_lit_cutoff3 = p.resolution_lit_cutoff_range3(); + m_res_cls_cutoff1 = p.resolution_cls_cutoff1(); + m_res_cls_cutoff2 = p.resolution_cls_cutoff2(); + m_subsumption = p.subsumption(); + m_subsumption_limit = p.subsumption_limit(); } void simplifier::collect_param_descrs(param_descrs & r) { - r.insert(":elim-blocked-clauses", CPK_BOOL, "(default: false) eliminate blocked clauses."); - r.insert(":elim-blocked-clauses-at", CPK_UINT, "(default: 2) eliminate blocked clauses only once at the given simplification round."); - r.insert(":blocked-clause-limit", CPK_UINT, "(default: 100000000) maximum number of literals visited during blocked clause elimination."); - r.insert(":resolution", CPK_BOOL, "(default: true) eliminate boolean variables using resolution."); - r.insert(":resolution-limit", CPK_UINT, "(default: 500000000) approx. maximum number of literals visited during variable elimination."); - r.insert(":res-occ-cutoff", CPK_UINT, "(default: 10) first cutoff (on number of positive/negative occurrences) for Boolean variable elimination."); - r.insert(":res-occ-cutoff-range1", CPK_UINT, "(default: 8) second cutoff (number of positive/negative occurrences) for Boolean variable elimination, for problems containing less than :res-cls-cutoff1 clauses."); - r.insert(":res-occ-cutoff-range2", CPK_UINT, "(default: 5) second cutoff (number of positive/negative occurrences) for Boolean variable elimination, for problems containing more than :res-cls-cutoff1 and less than :res-cls-cutoff2."); - r.insert(":res-occ-cutoff-range3", CPK_UINT, "(default: 3) second cutoff (number of positive/negative occurrences) for Boolean variable elimination, for problems containing more than :res-cls-cutoff2."); - - r.insert(":res-lit-cutoff-range1", CPK_UINT, "(default: 700) second cutoff (total number of literals) for Boolean variable elimination, for problems containing less than :res-cls-cutoff1 clauses."); - r.insert(":res-lit-cutoff-range2", CPK_UINT, "(default: 400) second cutoff (total number of literals) for Boolean variable elimination, for problems containing more than :res-cls-cutoff1 and less than :res-cls-cutoff2."); - r.insert(":res-lit-cutoff-range3", CPK_UINT, "(default: 300) second cutoff (total number of literals) for Boolean variable elimination, for problems containing more than :res-cls-cutoff2."); - - r.insert(":res-cls-cutoff1", CPK_UINT, "(default: 100000000) limit1 - total number of problems clauses for the second cutoff of Boolean variable elimination."); - r.insert(":res-cls-cutoff2", CPK_UINT, "(default: 700000000) limit2 - total number of problems clauses for the second cutoff of Boolean variable elimination."); - - r.insert(":subsumption", CPK_BOOL, "(default: true) eliminate subsumed clauses."); - r.insert(":subsumption-limit", CPK_UINT, "(default: 100000000) approx. maximum number of literals visited during subsumption (and subsumption resolution)."); + sat_simplifier_params::collect_param_descrs(r); } void simplifier::collect_statistics(statistics & st) { diff --git a/src/sat/sat_simplifier_params.pyg b/src/sat/sat_simplifier_params.pyg new file mode 100644 index 000000000..6165e7e62 --- /dev/null +++ b/src/sat/sat_simplifier_params.pyg @@ -0,0 +1,19 @@ +def_module_params(module_name='sat', + class_name='sat_simplifier_params', + export=True, + params=(('elim_blocked_clauses', BOOL, False, 'eliminate blocked clauses'), + ('elim_blocked_clauses_at', UINT, 2, 'eliminate blocked clauses only once at the given simplification round'), + ('blocked_clause_limit', UINT, 100000000, 'maximum number of literals visited during blocked clause elimination'), + ('resolution', BOOL, True, 'eliminate boolean variables using resolution'), + ('resolution.limit', UINT, 500000000, 'approx. maximum number of literals visited during variable elimination'), + ('resolution.occ_cutoff', UINT, 10, 'first cutoff (on number of positive/negative occurrences) for Boolean variable elimination'), + ('resolution.occ_cutoff_range1', UINT, 8, 'second cutoff (number of positive/negative occurrences) for Boolean variable elimination, for problems containing less than res_cls_cutoff1 clauses'), + ('resolution.occ_cutoff_range2', UINT, 5, 'second cutoff (number of positive/negative occurrences) for Boolean variable elimination, for problems containing more than res_cls_cutoff1 and less than res_cls_cutoff2'), + ('resolution.occ_cutoff_range3', UINT, 3, 'second cutoff (number of positive/negative occurrences) for Boolean variable elimination, for problems containing more than res_cls_cutoff2'), + ('resolution.lit_cutoff_range1', UINT, 700, 'second cutoff (total number of literals) for Boolean variable elimination, for problems containing less than res_cls_cutoff1 clauses'), + ('resolution.lit_cutoff_range2', UINT, 400, 'second cutoff (total number of literals) for Boolean variable elimination, for problems containing more than res_cls_cutoff1 and less than res_cls_cutoff2'), + ('resolution.lit_cutoff_range3', UINT, 300, 'second cutoff (total number of literals) for Boolean variable elimination, for problems containing more than res_cls_cutoff2'), + ('resolution.cls_cutoff1', UINT, 100000000, 'limit1 - total number of problems clauses for the second cutoff of Boolean variable elimination'), + ('resolution.cls_cutoff2', UINT, 700000000, 'limit2 - total number of problems clauses for the second cutoff of Boolean variable elimination'), + ('subsumption', BOOL, True, 'eliminate subsumed clauses'), + ('subsumption.limit', UINT, 100000000, 'approx. maximum number of literals visited during subsumption (and subsumption resolution)'))) diff --git a/src/sat/sat_solver.cpp b/src/sat/sat_solver.cpp index 0322e80c5..399fb2c61 100644 --- a/src/sat/sat_solver.cpp +++ b/src/sat/sat_solver.cpp @@ -1909,7 +1909,7 @@ namespace sat { m_asymm_branch.updt_params(p); m_probing.updt_params(p); m_scc.updt_params(p); - m_rand.set_seed(p.get_uint(":random-seed", 0)); + m_rand.set_seed(p.get_uint("random_seed", 0)); } void solver::collect_param_descrs(param_descrs & d) { diff --git a/src/sat/tactic/goal2sat.cpp b/src/sat/tactic/goal2sat.cpp index b6c2e39cf..16184e2bc 100644 --- a/src/sat/tactic/goal2sat.cpp +++ b/src/sat/tactic/goal2sat.cpp @@ -67,8 +67,8 @@ struct goal2sat::imp { } void updt_params(params_ref const & p) { - m_ite_extra = p.get_bool(":ite-extra", true); - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); + m_ite_extra = p.get_bool("ite_extra", true); + m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); } void throw_op_not_handled() { @@ -420,7 +420,7 @@ goal2sat::goal2sat():m_imp(0) { void goal2sat::collect_param_descrs(param_descrs & r) { insert_max_memory(r); - r.insert(":ite-extra", CPK_BOOL, "(default: true) add redundant clauses (that improve unit propagation) when encoding if-then-else formulas"); + r.insert("ite_extra", CPK_BOOL, "(default: true) add redundant clauses (that improve unit propagation) when encoding if-then-else formulas"); } struct goal2sat::scoped_set_imp { @@ -575,8 +575,8 @@ struct sat2goal::imp { } void updt_params(params_ref const & p) { - m_learned = p.get_bool(":learned", false); - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); + m_learned = p.get_bool("learned", false); + m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); } void checkpoint() { @@ -676,7 +676,7 @@ sat2goal::sat2goal():m_imp(0) { void sat2goal::collect_param_descrs(param_descrs & r) { insert_max_memory(r); - r.insert(":learned", CPK_BOOL, "(default: false) collect also learned clauses."); + r.insert("learned", CPK_BOOL, "(default: false) collect also learned clauses."); } struct sat2goal::scoped_set_imp { diff --git a/src/sat/tactic/sat_tactic.cpp b/src/sat/tactic/sat_tactic.cpp index 015eb6c66..d48994861 100644 --- a/src/sat/tactic/sat_tactic.cpp +++ b/src/sat/tactic/sat_tactic.cpp @@ -210,7 +210,7 @@ tactic * mk_sat_tactic(ast_manager & m, params_ref const & p) { tactic * mk_sat_preprocessor_tactic(ast_manager & m, params_ref const & p) { params_ref p_aux; - p_aux.set_uint(":max-conflicts", 0); + p_aux.set_uint("max_conflicts", 0); tactic * t = clean(using_params(mk_sat_tactic(m, p), p_aux)); t->updt_params(p); return t; diff --git a/src/shell/datalog_frontend.cpp b/src/shell/datalog_frontend.cpp index 14dcc91c3..44a9d9b66 100644 --- a/src/shell/datalog_frontend.cpp +++ b/src/shell/datalog_frontend.cpp @@ -25,13 +25,13 @@ Revision History: #undef min #undef max #endif -#include"front_end_params.h" -#include"datalog_parser.h" +#include"smt_params.h" #include"arith_decl_plugin.h" #include"dl_compiler.h" -#include"dl_context.h" #include"dl_mk_filter_rules.h" #include"dl_finite_product_relation.h" +#include"dl_context.h" +#include"datalog_parser.h" #include"datalog_frontend.h" #include"timeout.h" @@ -43,17 +43,17 @@ static datalog::context * g_ctx = 0; static datalog::rule_set * g_orig_rules; static datalog::instruction_block * g_code; static datalog::execution_context * g_ectx; -static front_end_params * g_params; +static smt_params * g_params; datalog_params::datalog_params(): m_default_table("sparse"), m_default_table_checked(false) {} -void datalog_params::register_params(ini_params& p) { - p.register_symbol_param("DEFAULT_TABLE", m_default_table, "Datalog engine: default table (sparse)"); - p.register_bool_param("DEFAULT_TABLE_CHECKED", m_default_table_checked, "Wrap default table with a sanity checker"); -} +// void datalog_params::register_params(ini_params& p) { +// p.register_symbol_param("DEFAULT_TABLE", m_default_table, "Datalog engine: default table (sparse)"); +// p.register_bool_param("DEFAULT_TABLE_CHECKED", m_default_table_checked, "Wrap default table with a sanity checker"); +// } static void display_statistics( std::ostream& out, @@ -61,7 +61,7 @@ static void display_statistics( datalog::rule_set& orig_rules, datalog::instruction_block& code, datalog::execution_context& ex_ctx, - front_end_params& params, + smt_params& params, bool verbose ) { @@ -71,9 +71,9 @@ static void display_statistics( code.process_all_costs(); { - params_ref p(ctx.get_params()); - p.set_bool(":output-profile", true); - p.set_uint(":profile-milliseconds-threshold", 100); + params_ref p; + p.set_bool("output_profile", true); + p.set_uint("profile_milliseconds_threshold", 100); ctx.updt_params(p); out << "--------------\n"; @@ -86,7 +86,7 @@ static void display_statistics( out << "--------------\n"; out << "instructions \n"; - code.display(ctx, out); + code.display(ctx.get_rel_context(), out); out << "--------------\n"; out << "big relations \n"; @@ -94,7 +94,7 @@ static void display_statistics( } out << "--------------\n"; out << "relation sizes\n"; - ctx.get_rmanager().display_relation_sizes(out); + ctx.get_rel_context().get_rmanager().display_relation_sizes(out); if (verbose) { out << "--------------\n"; @@ -125,23 +125,21 @@ static void on_ctrl_c(int) { } -unsigned read_datalog(char const * file, datalog_params const& dl_params, front_end_params & front_end_params) { +unsigned read_datalog(char const * file) { IF_VERBOSE(1, verbose_stream() << "Z3 Datalog Engine\n";); + datalog_params dl_params; + smt_params s_params; ast_manager m; g_overall_time.start(); register_on_timeout_proc(on_timeout); signal(SIGINT, on_ctrl_c); params_ref params; - params.set_sym(":engine", symbol("datalog")); - params.set_sym(":default-table", dl_params.m_default_table); - params.set_bool(":default-table-checked", dl_params.m_default_table_checked); + params.set_sym("engine", symbol("datalog")); + params.set_sym("default_table", dl_params.m_default_table); + params.set_bool("default_table_checked", dl_params.m_default_table_checked); - datalog::context ctx(m, front_end_params, params); - size_t watermark = front_end_params.m_memory_high_watermark; - if (watermark == 0) { - memory::set_high_watermark(static_cast(UINT_MAX)); - } - datalog::relation_manager & rmgr = ctx.get_rmanager(); + datalog::context ctx(m, s_params, params); + datalog::relation_manager & rmgr = ctx.get_rel_context().get_rmanager(); datalog::relation_plugin & inner_plg = *rmgr.get_relation_plugin(symbol("tr_hashtable")); SASSERT(&inner_plg); rmgr.register_plugin(alloc(datalog::finite_product_relation_plugin, inner_plg, rmgr)); @@ -190,7 +188,7 @@ unsigned read_datalog(char const * file, datalog_params const& dl_params, front_ g_orig_rules = &original_rules; g_code = &rules_code; g_ectx = &ex_ctx; - g_params = &front_end_params; + g_params = &s_params; try { g_piece_timer.reset(); @@ -208,7 +206,7 @@ unsigned read_datalog(char const * file, datalog_params const& dl_params, front_ datalog::compiler::compile(ctx, ctx.get_rules(), rules_code, termination_code); - TRACE("dl_compiler", rules_code.display(ctx, tout);); + TRACE("dl_compiler", rules_code.display(ctx.get_rel_context(), tout);); rules_code.make_annotations(ex_ctx); @@ -250,10 +248,10 @@ unsigned read_datalog(char const * file, datalog_params const& dl_params, front_ TRACE("dl_compiler", ctx.display(tout); - rules_code.display(ctx, tout);); + rules_code.display(ctx.get_rel_context(), tout);); - if (ctx.get_params().get_bool(":output-tuples", true)) { - ctx.display_output_facts(std::cout); + if (ctx.get_params().output_tuples()) { + ctx.get_rel_context().display_output_facts(std::cout); } display_statistics( @@ -262,7 +260,7 @@ unsigned read_datalog(char const * file, datalog_params const& dl_params, front_ original_rules, rules_code, ex_ctx, - front_end_params, + s_params, false); } @@ -274,7 +272,7 @@ unsigned read_datalog(char const * file, datalog_params const& dl_params, front_ original_rules, rules_code, ex_ctx, - front_end_params, + s_params, true); return ERR_MEMOUT; } diff --git a/src/shell/datalog_frontend.h b/src/shell/datalog_frontend.h index 898a7fd97..e53e35c89 100644 --- a/src/shell/datalog_frontend.h +++ b/src/shell/datalog_frontend.h @@ -23,10 +23,9 @@ struct datalog_params { symbol m_default_table; bool m_default_table_checked; datalog_params(); - virtual void register_params(ini_params& p); }; -unsigned read_datalog(char const * file, datalog_params const& dl_params, front_end_params & front_end_params); +unsigned read_datalog(char const * file); #endif /* _DATALOG_FRONTEND_H_ */ diff --git a/src/shell/dimacs_frontend.cpp b/src/shell/dimacs_frontend.cpp index cf64ed110..0acd222dd 100644 --- a/src/shell/dimacs_frontend.cpp +++ b/src/shell/dimacs_frontend.cpp @@ -22,7 +22,6 @@ Revision History: #include"timeout.h" #include"dimacs.h" #include"sat_solver.h" -#include"front_end_params.h" extern bool g_display_statistics; static sat::solver * g_solver = 0; @@ -64,12 +63,12 @@ static void display_model(sat::solver const & s) { std::cout << "\n"; } -unsigned read_dimacs(char const * file_name, front_end_params & front_end_params) { +unsigned read_dimacs(char const * file_name) { g_start_time = clock(); register_on_timeout_proc(on_timeout); signal(SIGINT, on_ctrl_c); params_ref p; - p.set_bool(":produce-models", front_end_params.m_model); + p.set_bool("produce_models", true); sat::solver solver(p, 0); g_solver = &solver; @@ -90,8 +89,7 @@ unsigned read_dimacs(char const * file_name, front_end_params & front_end_params switch (r) { case l_true: std::cout << "sat\n"; - if (front_end_params.m_model) - display_model(solver); + display_model(solver); break; case l_undef: std::cout << "unknown\n"; diff --git a/src/shell/dimacs_frontend.h b/src/shell/dimacs_frontend.h index 22ab63529..9521c8256 100644 --- a/src/shell/dimacs_frontend.h +++ b/src/shell/dimacs_frontend.h @@ -19,7 +19,7 @@ Revision History: #ifndef _DIMACS_FRONTEND_H_ #define _DIMACS_FRONTEND_H_ -unsigned read_dimacs(char const * benchmark_file, front_end_params & front_end_params); +unsigned read_dimacs(char const * benchmark_file); #endif /* _DATALOG_FRONTEND_H_ */ diff --git a/src/shell/main.cpp b/src/shell/main.cpp index 6dc5a7ebe..d91038b39 100644 --- a/src/shell/main.cpp +++ b/src/shell/main.cpp @@ -32,6 +32,8 @@ Revision History: #include"timeout.h" #include"z3_exception.h" #include"error_codes.h" +#include"gparams.h" +#include"env_params.h" typedef enum { IN_UNSPECIFIED, IN_SMTLIB, IN_SMTLIB_2, IN_DATALOG, IN_DIMACS, IN_Z3_LOG } input_kind; @@ -39,19 +41,12 @@ std::string g_aux_input_file; char const * g_input_file = 0; bool g_standard_input = false; input_kind g_input_kind = IN_UNSPECIFIED; -front_end_params * g_front_end_params = 0; bool g_display_statistics = false; bool g_display_istatistics = false; -#ifdef _WINDOWS -#define OPT "/" -#else -#define OPT "-" -#endif - void error(const char * msg) { std::cerr << "Error: " << msg << "\n"; - std::cerr << "For usage information: z3 " << OPT << "h\n"; + std::cerr << "For usage information: z3 -h\n"; exit(ERR_CMD_LINE); } @@ -63,112 +58,48 @@ void display_usage() { std::cout << "32"; #endif std::cout << " bit]. (C) Copyright 2006 Microsoft Corp.\n"; - std::cout << "Usage: z3 [options] [" << OPT << "file:]file\n"; + std::cout << "Usage: z3 [options] [-file:]file\n"; std::cout << "\nInput format:\n"; - std::cout << " " << OPT << "smt use parser for SMT input format.\n"; - std::cout << " " << OPT << "smt2 use parser for SMT 2 input format.\n"; - std::cout << " " << OPT << "dl use parser for Datalog input format.\n"; - std::cout << " " << OPT << "dimacs use parser for DIMACS input format.\n"; - std::cout << " " << OPT << "log use parser for Z3 log input format.\n"; - std::cout << " " << OPT << "in read formula from standard input.\n"; + std::cout << " -smt use parser for SMT input format.\n"; + std::cout << " -smt2 use parser for SMT 2 input format.\n"; + std::cout << " -dl use parser for Datalog input format.\n"; + std::cout << " -dimacs use parser for DIMACS input format.\n"; + std::cout << " -log use parser for Z3 log input format.\n"; + std::cout << " -in read formula from standard input.\n"; std::cout << "\nMiscellaneous:\n"; - std::cout << " " << OPT << "h, " << OPT << "? prints this message.\n"; - std::cout << " " << OPT << "version prints version number of Z3.\n"; - std::cout << " " << OPT << "v:level be verbose, where is the verbosity level.\n"; - std::cout << " " << OPT << "nw disable warning messages.\n"; - std::cout << " " << OPT << "ini:file configuration file.\n"; - std::cout << " " << OPT << "ini? display all available INI file parameters.\n"; + std::cout << " -h, -? prints this message.\n"; + std::cout << " -version prints version number of Z3.\n"; + std::cout << " -v:level be verbose, where is the verbosity level.\n"; + std::cout << " -nw disable warning messages.\n"; + std::cout << " -p display Z3 global (and module) parameters.\n"; + std::cout << " -pd display Z3 global (and module) parameter descriptions.\n"; + std::cout << " -pm:name display Z3 module ('name') parameters.\n"; + std::cout << " -pp:name display Z3 parameter description, if 'name' is not provided, then all module names are listed.\n"; std::cout << " --" << " all remaining arguments are assumed to be part of the input file name. This option allows Z3 to read files with strange names such as: -foo.smt2.\n"; std::cout << "\nResources:\n"; // timeout and memout are now available on Linux and OSX too. - std::cout << " " << OPT << "T:timeout set the timeout (in seconds).\n"; - std::cout << " " << OPT << "t:timeout set the soft timeout (in seconds). It only kills the current query.\n"; - std::cout << " " << OPT << "memory:Megabytes set a limit for virtual memory consumption.\n"; + std::cout << " -T:timeout set the timeout (in seconds).\n"; + std::cout << " -t:timeout set the soft timeout (in seconds). It only kills the current query.\n"; + std::cout << " -memory:Megabytes set a limit for virtual memory consumption.\n"; // std::cout << "\nOutput:\n"; - std::cout << " " << OPT << "st display statistics.\n"; - std::cout << "\nSearch heuristics:\n"; - std::cout << " " << OPT << "rs:num random seed.\n"; + std::cout << " -st display statistics.\n"; #if defined(Z3DEBUG) || defined(_TRACE) std::cout << "\nDebugging support:\n"; #endif #ifdef _TRACE - std::cout << " " << OPT << "tr:tag enable trace messages tagged with .\n"; + std::cout << " -tr:tag enable trace messages tagged with .\n"; #endif #ifdef Z3DEBUG - std::cout << " " << OPT << "dbg:tag enable assertions tagged with .\n"; + std::cout << " -dbg:tag enable assertions tagged with .\n"; #endif + std::cout << "\nParameter setting:\n"; + std::cout << "Global and module parameters can be set in the command line.\n"; + std::cout << " param_name=value for setting global parameters.\n"; + std::cout << " module_name.param_name=value for setting module parameters.\n"; + std::cout << "Use 'z3 -p' for the complete list of global and module parameters.\n"; } - -class extra_params : public datalog_params { - bool & m_statistics; -public: - extra_params(): - m_statistics(g_display_statistics) { - } - - virtual ~extra_params() {} - - virtual void register_params(ini_params & p) { - datalog_params::register_params(p); - p.register_bool_param("STATISTICS", m_statistics, "display statistics"); - } -}; - -ini_params* g_params = 0; -extra_params* g_extra_params = 0; -bool g_params_initialized = false; - -void init_params() { - if (!g_params_initialized) { - z3_bound_num_procs(); - g_front_end_params = new front_end_params(); - g_params = new ini_params(); - g_extra_params = new extra_params(); - register_verbosity_level(*g_params); - register_warning(*g_params); - register_pp_params(*g_params); - g_front_end_params->register_params(*g_params); - g_extra_params->register_params(*g_params); - g_params_initialized = true; - } -} - -void del_params() { - if (g_front_end_params != NULL) - g_front_end_params->close_trace_file(); - delete g_extra_params; - delete g_params; - delete g_front_end_params; - g_extra_params = 0; - g_params = 0; - g_front_end_params = 0; -} - - -void read_ini_file(const char * file_name) { - std::ifstream in(file_name); - if (in.bad() || in.fail()) { - std::cerr << "Error: failed to open init file \"" << file_name << "\".\n"; - exit(ERR_INI_FILE); - } - g_params->read_ini_file(in); -} - -void display_ini_help() { - g_params->display_params(std::cout); -} - -void display_config() { - if (g_front_end_params->m_display_config) { - display_ini_help(); - } -} - -void display_ini_doc() { - g_params->display_params_documentation(std::cout); -} - + void parse_cmd_line_args(int argc, char ** argv) { int i = 1; char * eq_pos = 0; @@ -185,10 +116,7 @@ void parse_cmd_line_args(int argc, char ** argv) { if (i < argc - 1) g_aux_input_file += " "; } - if (g_front_end_params->m_interactive) { - warning_msg("ignoring input file in interactive mode."); - } - else if (g_input_file) { + if (g_input_file) { warning_msg("input file was already specified."); } else { @@ -203,6 +131,9 @@ void parse_cmd_line_args(int argc, char ** argv) { #endif ) { char * opt_name = arg + 1; + // allow names such as --help + if (*opt_name == '-') + opt_name++; char * opt_arg = 0; char * colon = strchr(arg, ':'); if (colon) { @@ -240,86 +171,73 @@ void parse_cmd_line_args(int argc, char ** argv) { } else if (strcmp(opt_name, "v") == 0) { if (!opt_arg) - error("option argument (/v:level) is missing."); + error("option argument (-v:level) is missing."); long lvl = strtol(opt_arg, 0, 10); set_verbosity_level(lvl); } - else if (strcmp(opt_name, "vldt") == 0) { - g_front_end_params->m_model_validate = true; - } else if (strcmp(opt_name, "file") == 0) { g_input_file = opt_arg; } - else if (strcmp(opt_name, "r") == 0) { - if (!opt_arg) { - error("optional argument (/r:level) is missing."); - } - g_front_end_params->m_relevancy_lvl = strtol(opt_arg, 0, 10); - } - else if (strcmp(opt_name, "rd") == 0) { - if (!opt_arg) { - error("optional argument (/rd:num) is missing."); - } - g_front_end_params->m_random_var_freq = static_cast(strtol(opt_arg, 0, 10)) / 100.0; - } - else if (strcmp(opt_name, "rs") == 0) { - if (!opt_arg) { - error("optional argument (/rs:num) is missing."); - } - long seed = strtol(opt_arg, 0, 10); - g_front_end_params->m_random_seed = seed; - g_front_end_params->m_arith_random_seed = seed; - } else if (strcmp(opt_name, "T") == 0) { if (!opt_arg) - error("option argument (/T:timeout) is missing."); + error("option argument (-T:timeout) is missing."); long tm = strtol(opt_arg, 0, 10); set_timeout(tm * 1000); } else if (strcmp(opt_name, "t") == 0) { if (!opt_arg) - error("option argument (/t:timeout) is missing."); - long tm = strtol(opt_arg, 0, 10); - g_front_end_params->m_soft_timeout = tm*1000; + error("option argument (-t:timeout) is missing."); + gparams::set("timeout", opt_arg); } else if (strcmp(opt_name, "nw") == 0) { enable_warning_messages(false); } - else if (strcmp(opt_name, "ini") == 0) { - if (!opt_arg) - error("option argument (/ini:file) is missing."); - read_ini_file(opt_arg); - } - else if (strcmp(opt_name, "ini?") == 0) { - display_ini_help(); + else if (strcmp(opt_name, "p") == 0) { + gparams::display(std::cout, 0, false, false); exit(0); } - else if (strcmp(opt_name, "geninidoc") == 0) { - display_ini_doc(); + else if (strcmp(opt_name, "pd") == 0) { + gparams::display(std::cout, 0, false, true); + exit(0); + } + else if (strcmp(opt_name, "pm") == 0) { + if (opt_arg) { + gparams::display_module(std::cout, opt_arg); + } + else { + gparams::display_modules(std::cout); + std::cout << "\nUse -pm:name to display all parameters available at module 'name'\n"; + } + exit(0); + } + else if (strcmp(opt_name, "pp") == 0) { + if (!opt_arg) + error("option argument (-pp:name) is missing."); + gparams::display_parameter(std::cout, opt_arg); exit(0); } #ifdef _TRACE else if (strcmp(opt_name, "tr") == 0) { if (!opt_arg) - error("option argument (/tr:tag) is missing."); + error("option argument (-tr:tag) is missing."); enable_trace(opt_arg); } #endif #ifdef Z3DEBUG else if (strcmp(opt_name, "dbg") == 0) { if (!opt_arg) - error("option argument (/dbg:tag) is missing."); + error("option argument (-dbg:tag) is missing."); enable_debug(opt_arg); } #endif else if (strcmp(opt_name, "memory") == 0) { if (!opt_arg) - error("option argument (/memory:val) is missing."); - g_front_end_params->m_memory_high_watermark = strtoul(opt_arg, 0, 10); + error("option argument (-memory:val) is missing."); + gparams::set("memory_max_size", opt_arg); } else { std::cerr << "Error: invalid command line option: " << arg << "\n"; - std::cerr << "For usage information: z3 " << OPT << "h\n"; + std::cerr << "For usage information: z3 -h\n"; exit(ERR_CMD_LINE); } } @@ -327,13 +245,10 @@ void parse_cmd_line_args(int argc, char ** argv) { char * key = argv[i]; *eq_pos = 0; char * value = eq_pos+1; - g_params->set_param_value(key, value); + gparams::set(key, value); } else { - if (g_front_end_params->m_interactive) { - warning_msg("ignoring input file in interactive mode."); - } - else if (g_input_file) { + if (g_input_file) { warning_msg("input file was already specified."); } else { @@ -358,44 +273,18 @@ char const * get_extension(char const * file_name) { } } -class global_state_initialiser { -public: - global_state_initialiser() { - memory::initialize(0); -#if defined(_WINDOWS) && defined(_Z3_BUILD_PARALLEL_SMT) - memory::mem->set_threaded_mode(true); -#endif - init_params(); - } - - void reset() { - del_params(); - memory::finalize(); - } - - ~global_state_initialiser() { - reset(); - } -}; - int main(int argc, char ** argv) { try{ unsigned return_value = 0; - global_state_initialiser global_state; + memory::initialize(0); memory::exit_when_out_of_memory(true, "ERROR: out of memory"); parse_cmd_line_args(argc, argv); - memory::set_high_watermark(static_cast(g_front_end_params->m_memory_high_watermark) * 1024 * 1024); - memory::set_max_size(static_cast(g_front_end_params->m_memory_max_size) * 1024 * 1024); - g_front_end_params->open_trace_file(); - DEBUG_CODE( - if (g_front_end_params->m_copy_params != -1) { - g_front_end_params->copy_params(g_front_end_params->m_copy_params); - TRACE("copy_params", g_params->display_params(tout);); - }); + env_params::updt_params(); + if (g_input_file && g_standard_input) { error("using standard input to read formula."); } - if (!g_input_file && !g_front_end_params->m_interactive && !g_standard_input) { + if (!g_input_file && !g_standard_input) { error("input file was not specified."); } @@ -422,17 +311,17 @@ int main(int argc, char ** argv) { } switch (g_input_kind) { case IN_SMTLIB: - return_value = read_smtlib_file(g_input_file, *g_front_end_params); + return_value = read_smtlib_file(g_input_file); break; case IN_SMTLIB_2: memory::exit_when_out_of_memory(true, "(error \"out of memory\")"); - return_value = read_smtlib2_commands(g_input_file, *g_front_end_params); + return_value = read_smtlib2_commands(g_input_file); break; case IN_DIMACS: - return_value = read_dimacs(g_input_file, *g_front_end_params); + return_value = read_dimacs(g_input_file); break; case IN_DATALOG: - read_datalog(g_input_file, *g_extra_params, *g_front_end_params); + read_datalog(g_input_file); break; case IN_Z3_LOG: replay_z3_log(g_input_file); @@ -440,7 +329,6 @@ int main(int argc, char ** argv) { default: UNREACHABLE(); } - global_state.reset(); #ifdef _WINDOWS _CrtDumpMemoryLeaks(); #endif diff --git a/src/shell/smtlib_frontend.cpp b/src/shell/smtlib_frontend.cpp index 08b070183..1551329c6 100644 --- a/src/shell/smtlib_frontend.cpp +++ b/src/shell/smtlib_frontend.cpp @@ -40,7 +40,6 @@ static smtlib::solver* g_solver = 0; static cmd_context * g_cmd_context = 0; static void display_statistics() { - display_config(); clock_t end_time = clock(); if ((g_solver || g_cmd_context) && g_display_statistics) { std::cout.flush(); @@ -68,11 +67,11 @@ static void on_ctrl_c(int) { raise(SIGINT); } -unsigned read_smtlib_file(char const * benchmark_file, front_end_params & front_end_params) { +unsigned read_smtlib_file(char const * benchmark_file) { g_start_time = clock(); register_on_timeout_proc(on_timeout); signal(SIGINT, on_ctrl_c); - smtlib::solver solver(front_end_params); + smtlib::solver solver; g_solver = &solver; bool ok = true; @@ -93,22 +92,15 @@ unsigned read_smtlib_file(char const * benchmark_file, front_end_params & front_ return solver.get_error_code(); } -unsigned read_smtlib2_commands(char const* file_name, front_end_params& front_end_params) { +unsigned read_smtlib2_commands(char const * file_name) { g_start_time = clock(); register_on_timeout_proc(on_timeout); signal(SIGINT, on_ctrl_c); - cmd_context ctx(&front_end_params); + cmd_context ctx; + + solver * s = mk_smt_strategic_solver(false); + ctx.set_solver(s); - // temporary hack until strategic_solver is ported to new tactic framework - if (front_end_params.m_nlsat) { - tactic_factory2solver * s = alloc(tactic_factory2solver); - s->set_tactic(alloc(qfnra_nlsat_fct)); - ctx.set_solver(s); - } - else { - solver * s = mk_smt_strategic_solver(false); - ctx.set_solver(s); - } install_dl_cmds(ctx); install_dbg_cmds(ctx); install_polynomial_cmds(ctx); diff --git a/src/shell/smtlib_frontend.h b/src/shell/smtlib_frontend.h index 0db1571e4..2c5eed70c 100644 --- a/src/shell/smtlib_frontend.h +++ b/src/shell/smtlib_frontend.h @@ -19,16 +19,8 @@ Revision History: #ifndef _SMTLIB_FRONTEND_H_ #define _SMTLIB_FRONTEND_H_ -#include"front_end_params.h" - -unsigned read_smtlib_file(char const * benchmark_file, front_end_params & front_end_params); - -unsigned read_smtlib_commands(char const* command_file, front_end_params& front_end_params); -unsigned read_smtlib2_commands(char const* command_file, front_end_params& front_end_params); - -#ifdef _Z3_BUILD_PARALLEL_MPI -unsigned start_mpi_subordinate(front_end_params& front_end_params); -#endif +unsigned read_smtlib_file(char const * benchmark_file); +unsigned read_smtlib2_commands(char const * command_file); #endif /* _SMTLIB_FRONTEND_H_ */ diff --git a/src/smt/arith_eq_solver.cpp b/src/smt/arith_eq_solver.cpp index 417f8022b..41a61bf73 100644 --- a/src/smt/arith_eq_solver.cpp +++ b/src/smt/arith_eq_solver.cpp @@ -26,8 +26,8 @@ arith_eq_solver::arith_eq_solver(ast_manager & m, params_ref const& p): m_util(m), m_arith_rewriter(m) { - m_params.set_bool(":gcd-rounding", true); - // m_params.set_bool(":sum", true); + m_params.set_bool("gcd_rounding", true); + // m_params.set_bool("sum", true); m_arith_rewriter.updt_params(m_params); } diff --git a/src/smt/asserted_formulas.cpp b/src/smt/asserted_formulas.cpp index f86da835c..6da2c15f5 100644 --- a/src/smt/asserted_formulas.cpp +++ b/src/smt/asserted_formulas.cpp @@ -25,12 +25,12 @@ Revision History: #include"bv_simplifier_plugin.h" #include"for_each_expr.h" #include"well_sorted.h" +#include"pull_quant.h" #include"pull_ite_tree.h" #include"push_app_ite.h" #include"elim_term_ite.h" #include"pattern_inference.h" #include"nnf.h" -#include"cnf.h" #include"bv_elim.h" #include"inj_axiom.h" #include"der.h" @@ -40,7 +40,7 @@ Revision History: #include"distribute_forall.h" #include"quasi_macros.h" -asserted_formulas::asserted_formulas(ast_manager & m, front_end_params & p): +asserted_formulas::asserted_formulas(ast_manager & m, smt_params & p): m_manager(m), m_params(p), m_pre_simplifier(m), @@ -86,22 +86,6 @@ void asserted_formulas::setup() { if (m_params.m_relevancy_lvl == 0) m_params.m_relevancy_lemma = false; - - switch (m_params.m_cnf_mode) { - case CNF_QUANT: - if (m_params.m_nnf_mode == NNF_SKOLEM) - m_params.m_nnf_mode = NNF_QUANT; - break; - case CNF_OPPORTUNISTIC: - if (m_params.m_nnf_mode == NNF_SKOLEM) - m_params.m_nnf_mode = NNF_QUANT; - break; - case CNF_FULL: - m_params.m_nnf_mode = NNF_FULL; - break; - default: - break; - } } void asserted_formulas::setup_simplifier_plugins(simplifier & s, basic_simplifier_plugin * & bsimp, arith_simplifier_plugin * & asimp, bv_simplifier_plugin * & bvsimp) { @@ -264,7 +248,6 @@ void asserted_formulas::reduce() { if (m_macro_manager.has_macros()) expand_macros(); TRACE("before_reduce", display(tout);); - IF_VERBOSE(10000, verbose_stream() << "total size: " << get_total_size() << "\n";); CASSERT("well_sorted", check_well_sorted()); #define INVOKE(COND, FUNC) if (COND) { FUNC; IF_VERBOSE(10000, verbose_stream() << "total size: " << get_total_size() << "\n";); } TRACE("reduce_step_ll", ast_mark visited; display_ll(tout, visited);); TRACE("reduce_step", display(tout << #FUNC << " ");); CASSERT("well_sorted",check_well_sorted()); if (inconsistent() || canceled()) { TRACE("after_reduce", display(tout);); TRACE("after_reduce_ll", ast_mark visited; display_ll(tout, visited);); return; } @@ -287,6 +270,7 @@ void asserted_formulas::reduce() { INVOKE(m_params.m_quasi_macros && has_quantifiers(), apply_quasi_macros()); INVOKE(m_params.m_simplify_bit2int, apply_bit2int()); INVOKE(m_params.m_eliminate_bounds && has_quantifiers(), cheap_quant_fourier_motzkin()); + INVOKE(m_params.m_ematching && has_quantifiers(), infer_patterns()); INVOKE(m_params.m_max_bv_sharing && has_bv(), max_bv_sharing()); INVOKE(m_params.m_bb_quantifiers, elim_bvs_from_quantifiers()); // temporary HACK: make sure that arith & bv are list-assoc @@ -295,7 +279,7 @@ void asserted_formulas::reduce() { CASSERT("well_sorted",check_well_sorted()); - IF_VERBOSE(10, verbose_stream() << "simplifier done.\n";); + IF_VERBOSE(10, verbose_stream() << "(smt.simplifier-done)\n";); TRACE("after_reduce", display(tout);); TRACE("after_reduce_ll", ast_mark visited; display_ll(tout, visited);); TRACE("macros", m_macro_manager.display(tout);); @@ -303,7 +287,7 @@ void asserted_formulas::reduce() { } void asserted_formulas::eliminate_and() { - IF_IVERBOSE(10, verbose_stream() << "eliminating and...\n";); + IF_IVERBOSE(10, verbose_stream() << "(smt.eliminating-and)\n";); set_eliminate_and(true); reduce_asserted_formulas(); TRACE("after_elim_and", display(tout);); @@ -408,19 +392,19 @@ void asserted_formulas::find_macros_core() { } void asserted_formulas::find_macros() { - IF_IVERBOSE(10, verbose_stream() << "trying to find macros...\n";); + IF_IVERBOSE(10, verbose_stream() << "(smt.find-macros)\n";); TRACE("before_find_macros", display(tout);); find_macros_core(); TRACE("after_find_macros", display(tout);); } void asserted_formulas::expand_macros() { - IF_IVERBOSE(10, verbose_stream() << "expanding macros...\n";); + IF_IVERBOSE(10, verbose_stream() << "(smt.expand-macros)\n";); find_macros_core(); } void asserted_formulas::apply_quasi_macros() { - IF_IVERBOSE(10, verbose_stream() << "finding quasi macros...\n";); + IF_IVERBOSE(10, verbose_stream() << "(smt.find-quasi-macros)\n";); TRACE("before_quasi_macros", display(tout);); expr_ref_vector new_exprs(m_manager); proof_ref_vector new_prs(m_manager); @@ -438,13 +422,10 @@ void asserted_formulas::apply_quasi_macros() { } void asserted_formulas::nnf_cnf() { - IF_IVERBOSE(10, verbose_stream() << "applying nnf&cnf...\n";); - nnf apply_nnf(m_manager, m_defined_names, m_params); - cnf apply_cnf(m_manager, m_defined_names, m_params); + IF_IVERBOSE(10, verbose_stream() << "(smt.nnf)\n";); + nnf apply_nnf(m_manager, m_defined_names); expr_ref_vector new_exprs(m_manager); proof_ref_vector new_prs(m_manager); - expr_ref_vector cnf_todo(m_manager); - proof_ref_vector cnf_todo_prs(m_manager); expr_ref_vector push_todo(m_manager); proof_ref_vector push_todo_prs(m_manager); @@ -455,60 +436,33 @@ void asserted_formulas::nnf_cnf() { expr * n = m_asserted_formulas.get(i); TRACE("nnf_bug", tout << "processing:\n" << mk_pp(n, m_manager) << "\n";); proof * pr = m_asserted_formula_prs.get(i, 0); - cnf_todo.reset(); - cnf_todo_prs.reset(); expr_ref r1(m_manager); proof_ref pr1(m_manager); CASSERT("well_sorted",is_well_sorted(m_manager, n)); - apply_nnf(n, cnf_todo, cnf_todo_prs, r1, pr1); + apply_nnf(n, push_todo, push_todo_prs, r1, pr1); CASSERT("well_sorted",is_well_sorted(m_manager, r1)); pr = m_manager.mk_modus_ponens(pr, pr1); - cnf_todo.push_back(r1); - cnf_todo_prs.push_back(pr); + push_todo.push_back(r1); + push_todo_prs.push_back(pr); if (canceled()) { return; } - - unsigned sz1 = cnf_todo.size(); - for (unsigned j = 0; j < sz1; j++) { - push_todo.reset(); - push_todo_prs.reset(); - + unsigned sz2 = push_todo.size(); + for (unsigned k = 0; k < sz2; k++) { + expr * n = push_todo.get(k); + proof * pr = 0; + m_simplifier(n, r1, pr1); + CASSERT("well_sorted",is_well_sorted(m_manager, r1)); if (canceled()) { return; } - - expr * n = cnf_todo.get(j); - proof * pr = m_manager.proofs_enabled() ? cnf_todo_prs.get(j) : 0; - - CASSERT("well_sorted",is_well_sorted(m_manager, n)); - apply_cnf(n, push_todo, push_todo_prs, r1, pr1); - CASSERT("well_sorted",is_well_sorted(m_manager, r1)); - - push_todo.push_back(r1); - - if (m_manager.proofs_enabled()) { - pr = m_manager.mk_modus_ponens(pr, pr1); - push_todo_prs.push_back(pr); - } - - unsigned sz2 = push_todo.size(); - for (unsigned k = 0; k < sz2; k++) { - expr * n = push_todo.get(k); - proof * pr = 0; - m_simplifier(n, r1, pr1); - CASSERT("well_sorted",is_well_sorted(m_manager, r1)); - if (canceled()) { - return; - } - - if (m_manager.proofs_enabled()) - pr = m_manager.mk_modus_ponens(push_todo_prs.get(k), pr1); - else - pr = 0; - push_assertion(r1, pr, new_exprs, new_prs); - } + + if (m_manager.proofs_enabled()) + pr = m_manager.mk_modus_ponens(push_todo_prs.get(k), pr1); + else + pr = 0; + push_assertion(r1, pr, new_exprs, new_prs); } } swap_asserted_formulas(new_exprs, new_prs); @@ -516,7 +470,7 @@ void asserted_formulas::nnf_cnf() { #define MK_SIMPLE_SIMPLIFIER(NAME, FUNCTOR_DEF, LABEL, MSG) \ void asserted_formulas::NAME() { \ - IF_IVERBOSE(10, verbose_stream() << MSG << "...\n";); \ + IF_IVERBOSE(10, verbose_stream() << "(smt." << MSG << ")\n";); \ TRACE(LABEL, tout << "before:\n"; display(tout);); \ FUNCTOR_DEF; \ expr_ref_vector new_exprs(m_manager); \ @@ -548,16 +502,16 @@ void asserted_formulas::NAME() { TRACE(LABEL, display(tout);); \ } -MK_SIMPLE_SIMPLIFIER(apply_distribute_forall, distribute_forall functor(m_manager, *m_bsimp), "distribute_forall", "distribute forall"); +MK_SIMPLE_SIMPLIFIER(apply_distribute_forall, distribute_forall functor(m_manager, *m_bsimp), "distribute_forall", "distribute-forall"); void asserted_formulas::reduce_and_solve() { - IF_IVERBOSE(10, verbose_stream() << "reducing...\n";); + IF_IVERBOSE(10, verbose_stream() << "(smt.reducing)\n";); flush_cache(); // collect garbage reduce_asserted_formulas(); } void asserted_formulas::infer_patterns() { - IF_IVERBOSE(10, verbose_stream() << "pattern inference...\n";); + IF_IVERBOSE(10, verbose_stream() << "(smt.pattern-inference)\n";); TRACE("before_pattern_inference", display(tout);); pattern_inference infer(m_manager, m_params); expr_ref_vector new_exprs(m_manager); @@ -591,7 +545,7 @@ void asserted_formulas::commit() { } void asserted_formulas::eliminate_term_ite() { - IF_IVERBOSE(10, verbose_stream() << "eliminating ite term...\n";); + IF_IVERBOSE(10, verbose_stream() << "(smt.eliminating-ite-term)\n";); TRACE("before_elim_term_ite", display(tout);); elim_term_ite elim(m_manager, m_defined_names); expr_ref_vector new_exprs(m_manager); @@ -628,7 +582,7 @@ void asserted_formulas::eliminate_term_ite() { } void asserted_formulas::propagate_values() { - IF_IVERBOSE(10, verbose_stream() << "constant propagation...\n";); + IF_IVERBOSE(10, verbose_stream() << "(smt.constant-propagation)\n";); TRACE("propagate_values", tout << "before:\n"; display(tout);); flush_cache(); bool found = false; @@ -706,7 +660,7 @@ void asserted_formulas::propagate_booleans() { flush_cache(); while (cont) { TRACE("propagate_booleans", tout << "before:\n"; display(tout);); - IF_IVERBOSE(10, verbose_stream() << "boolean propagation...\n";); + IF_IVERBOSE(10, verbose_stream() << "(smt.propagate-booleans)\n";); cont = false; unsigned i = m_asserted_qhead; unsigned sz = m_asserted_formulas.size(); @@ -749,7 +703,7 @@ void asserted_formulas::propagate_booleans() { #define MK_SIMPLIFIER(NAME, FUNCTOR, TAG, MSG, REDUCE) \ bool asserted_formulas::NAME() { \ - IF_IVERBOSE(10, verbose_stream() << MSG << "...\n";); \ + IF_IVERBOSE(10, verbose_stream() << "(smt." << MSG << ")\n";); \ TRACE(TAG, ast_mark visited; display_ll(tout, visited);); \ FUNCTOR; \ bool changed = false; \ @@ -786,9 +740,9 @@ bool asserted_formulas::NAME() { \ return changed; \ } -MK_SIMPLIFIER(pull_cheap_ite_trees, pull_cheap_ite_tree_star functor(m_manager, m_simplifier), "pull_cheap_ite_trees", "pull cheap ite trees", false); +MK_SIMPLIFIER(pull_cheap_ite_trees, pull_cheap_ite_tree_star functor(m_manager, m_simplifier), "pull_cheap_ite_trees", "pull-cheap-ite-trees", false); -MK_SIMPLIFIER(pull_nested_quantifiers, pull_nested_quant functor(m_manager), "pull_nested_quantifiers", "pull nested quantifiers", false); +MK_SIMPLIFIER(pull_nested_quantifiers, pull_nested_quant functor(m_manager), "pull_nested_quantifiers", "pull-nested-quantifiers", false); proof * asserted_formulas::get_inconsistency_proof() const { if (!inconsistent()) @@ -806,7 +760,7 @@ proof * asserted_formulas::get_inconsistency_proof() const { } void asserted_formulas::refine_inj_axiom() { - IF_IVERBOSE(10, verbose_stream() << "refining injectivity...\n";); + IF_IVERBOSE(10, verbose_stream() << "(smt.refine-injectivity)\n";); TRACE("inj_axiom", display(tout);); unsigned i = m_asserted_qhead; unsigned sz = m_asserted_formulas.size(); @@ -828,9 +782,9 @@ void asserted_formulas::refine_inj_axiom() { TRACE("inj_axiom", display(tout);); } -MK_SIMPLIFIER(apply_bit2int, bit2int& functor = m_bit2int, "bit2int", "propagate bit-vector over integers", true); +MK_SIMPLIFIER(apply_bit2int, bit2int& functor = m_bit2int, "bit2int", "propagate-bit-vector-over-integers", true); -MK_SIMPLIFIER(cheap_quant_fourier_motzkin, elim_bounds_star functor(m_manager), "elim_bounds", "cheap fourier-motzkin", true); +MK_SIMPLIFIER(cheap_quant_fourier_motzkin, elim_bounds_star functor(m_manager), "elim_bounds", "cheap-fourier-motzkin", true); // MK_SIMPLIFIER(quant_elim, qe::expr_quant_elim_star1 &functor = m_quant_elim, // "quantifiers", "quantifier elimination procedures", true); @@ -840,11 +794,11 @@ bool asserted_formulas::quant_elim() { return false; } -MK_SIMPLIFIER(elim_bvs_from_quantifiers, bv_elim_star functor(m_manager), "bv_elim", "eliminate bit-vectors from quantifiers", true); +MK_SIMPLIFIER(elim_bvs_from_quantifiers, bv_elim_star functor(m_manager), "bv_elim", "eliminate-bit-vectors-from-quantifiers", true); #define LIFT_ITE(NAME, FUNCTOR, MSG) \ void asserted_formulas::NAME() { \ - IF_IVERBOSE(10, verbose_stream() << MSG;); \ + IF_IVERBOSE(10, verbose_stream() << "(smt." << MSG << ")\n";); \ TRACE("lift_ite", display(tout);); \ FUNCTOR; \ unsigned i = m_asserted_qhead; \ @@ -867,8 +821,8 @@ void asserted_formulas::NAME() { reduce_and_solve(); \ } -LIFT_ITE(lift_ite, push_app_ite functor(m_simplifier, m_params.m_lift_ite == LI_CONSERVATIVE), "lifting ite...\n"); -LIFT_ITE(ng_lift_ite, ng_push_app_ite functor(m_simplifier, m_params.m_ng_lift_ite == LI_CONSERVATIVE), "lifting ng ite...\n"); +LIFT_ITE(lift_ite, push_app_ite functor(m_simplifier, m_params.m_lift_ite == LI_CONSERVATIVE), "lifting ite"); +LIFT_ITE(ng_lift_ite, ng_push_app_ite functor(m_simplifier, m_params.m_ng_lift_ite == LI_CONSERVATIVE), "lifting ng ite"); unsigned asserted_formulas::get_total_size() const { expr_mark visited; @@ -880,7 +834,7 @@ unsigned asserted_formulas::get_total_size() const { } void asserted_formulas::max_bv_sharing() { - IF_IVERBOSE(10, verbose_stream() << "maximizing bv sharing...\n";); + IF_IVERBOSE(10, verbose_stream() << "(smt.maximizing-bv-sharing)\n";); TRACE("bv_sharing", display(tout);); unsigned i = m_asserted_qhead; unsigned sz = m_asserted_formulas.size(); diff --git a/src/smt/asserted_formulas.h b/src/smt/asserted_formulas.h index 23be4ae7c..e888a974e 100644 --- a/src/smt/asserted_formulas.h +++ b/src/smt/asserted_formulas.h @@ -19,7 +19,7 @@ Revision History: #ifndef _ASSERTED_FORMULAS_H_ #define _ASSERTED_FORMULAS_H_ -#include"front_end_params.h" +#include"smt_params.h" #include"simplifier.h" #include"basic_simplifier_plugin.h" #include"static_features.h" @@ -36,7 +36,7 @@ class bv_simplifier_plugin; class asserted_formulas { ast_manager & m_manager; - front_end_params & m_params; + smt_params & m_params; simplifier m_pre_simplifier; simplifier m_simplifier; basic_simplifier_plugin * m_bsimp; @@ -100,7 +100,7 @@ class asserted_formulas { bool canceled() { return m_cancel_flag; } public: - asserted_formulas(ast_manager & m, front_end_params & p); + asserted_formulas(ast_manager & m, smt_params & p); ~asserted_formulas(); void setup(); diff --git a/src/smt/dyn_ack.cpp b/src/smt/dyn_ack.cpp index fc9b8939f..533d143c3 100644 --- a/src/smt/dyn_ack.cpp +++ b/src/smt/dyn_ack.cpp @@ -58,7 +58,7 @@ namespace smt { \remark if negate == true, then the hypothesis is actually (not (= lhs rhs)) */ proof * mk_hypothesis(ast_manager & m, app * eq, bool negate, expr * lhs, expr * rhs) { - SASSERT(m.is_eq(eq)); + SASSERT(m.is_eq(eq) || m.is_iff(eq)); SASSERT((eq->get_arg(0) == lhs && eq->get_arg(1) == rhs) || (eq->get_arg(0) == rhs && eq->get_arg(1) == lhs)); app * h = negate ? m.mk_not(eq) : eq; diff --git a/src/smt/expr_context_simplifier.cpp b/src/smt/expr_context_simplifier.cpp index 8fd5b41bb..b23bb3bdc 100644 --- a/src/smt/expr_context_simplifier.cpp +++ b/src/smt/expr_context_simplifier.cpp @@ -310,7 +310,7 @@ bool expr_context_simplifier::is_false(expr* e) const { // it occurs in the context (on the path) where it was inserted. // -expr_strong_context_simplifier::expr_strong_context_simplifier(front_end_params& p, ast_manager& m): +expr_strong_context_simplifier::expr_strong_context_simplifier(smt_params& p, ast_manager& m): m_manager(m), m_params(p), m_arith(m), m_id(0), m_fn(0,m), m_solver(m, p) { sort* i_sort = m_arith.mk_int(); m_fn = m.mk_func_decl(symbol(0xbeef101), i_sort, m.mk_bool_sort()); diff --git a/src/smt/expr_context_simplifier.h b/src/smt/expr_context_simplifier.h index 6e13dcf43..982b65878 100644 --- a/src/smt/expr_context_simplifier.h +++ b/src/smt/expr_context_simplifier.h @@ -22,7 +22,7 @@ Revision History: #include "ast.h" #include "obj_hashtable.h" #include "basic_simplifier_plugin.h" -#include "front_end_params.h" +#include "smt_params.h" #include "smt_kernel.h" #include "arith_decl_plugin.h" @@ -57,7 +57,7 @@ private: class expr_strong_context_simplifier { ast_manager& m_manager; - front_end_params & m_params; + smt_params & m_params; arith_util m_arith; unsigned m_id; func_decl_ref m_fn; @@ -70,12 +70,12 @@ class expr_strong_context_simplifier { bool is_forced(expr* e, expr* v); public: - expr_strong_context_simplifier(front_end_params& p, ast_manager& m); + expr_strong_context_simplifier(smt_params& p, ast_manager& m); void operator()(expr* e, expr_ref& result) { simplify(e, result); } void operator()(expr_ref& result) { simplify(result.get(), result); } void push() { m_solver.push(); } void pop() { m_solver.pop(1); } - void assert(expr* e) { m_solver.assert_expr(e); } + void assert_expr(expr* e) { m_solver.assert_expr(e); } void collect_statistics(statistics & st) const { m_solver.collect_statistics(st); } void reset_statistics() { m_solver.reset_statistics(); } diff --git a/src/smt/mam.cpp b/src/smt/mam.cpp index ba97d8939..24b8e2e7c 100644 --- a/src/smt/mam.cpp +++ b/src/smt/mam.cpp @@ -1824,7 +1824,6 @@ namespace smt { backtrack_stack m_backtrack_stack; unsigned m_top; const instruction * m_pc; - std::ostream* m_trace_stream; // auxiliary temporary variables unsigned m_max_generation; // the maximum generation of an app enode processed. @@ -1855,10 +1854,9 @@ namespace smt { void update_max_generation(enode * n) { m_max_generation = std::max(m_max_generation, n->get_generation()); -#ifndef SMTCOMP - if (m_trace_stream != NULL) + + if (m_ast_manager.has_trace_stream()) m_used_enodes.push_back(n); -#endif } // We have to provide the number of expected arguments because we have flat-assoc applications such as +. @@ -1965,12 +1963,11 @@ namespace smt { #define INIT_ARGS_SIZE 16 public: - interpreter(context & ctx, mam & m, bool use_filters, std::ostream *trace_stream): + interpreter(context & ctx, mam & m, bool use_filters): m_context(ctx), m_ast_manager(ctx.get_manager()), m_mam(m), - m_use_filters(use_filters), - m_trace_stream(trace_stream) { + m_use_filters(use_filters) { m_args.resize(INIT_ARGS_SIZE, 0); } @@ -2266,12 +2263,12 @@ namespace smt { m_pattern_instances.reset(); m_pattern_instances.push_back(n); m_max_generation = n->get_generation(); -#ifndef SMTCOMP - if (m_trace_stream != NULL) { + + if (m_ast_manager.has_trace_stream()) { m_used_enodes.reset(); m_used_enodes.push_back(n); } -#endif + m_pc = t->get_root(); m_registers[0] = n; m_top = 0; @@ -2638,10 +2635,10 @@ namespace smt { } backtrack_point & bp = m_backtrack_stack[m_top - 1]; m_max_generation = bp.m_old_max_generation; -#ifndef SMTCOMP - if (m_trace_stream != NULL) + + if (m_ast_manager.has_trace_stream()) m_used_enodes.shrink(bp.m_old_used_enodes_size); -#endif + TRACE("mam_int", tout << "backtrack top: " << bp.m_instr << " " << *(bp.m_instr) << "\n";); #ifdef _PROFILE_MAM if (bp.m_instr->m_opcode != CHOOSE) // CHOOSE has a different status. It is a control flow backtracking. @@ -3759,14 +3756,14 @@ namespace smt { } public: - mam_impl(context & ctx, bool use_filters, std::ostream *trace): - mam(ctx, trace), + mam_impl(context & ctx, bool use_filters): + mam(ctx), m_ast_manager(ctx.get_manager()), m_use_filters(use_filters), m_trail_stack(*this), m_ct_manager(m_lbl_hasher, m_trail_stack), m_compiler(ctx, m_ct_manager, m_lbl_hasher, use_filters), - m_interpreter(ctx, *this, use_filters, trace), + m_interpreter(ctx, *this, use_filters), m_trees(m_ast_manager, m_compiler, m_trail_stack), m_region(m_trail_stack.get_region()), m_r1(0), @@ -3980,8 +3977,8 @@ namespace smt { } }; - mam * mk_mam(context & ctx, std::ostream *trace) { - return alloc(mam_impl, ctx, true, trace); + mam * mk_mam(context & ctx) { + return alloc(mam_impl, ctx, true); } }; diff --git a/src/smt/mam.h b/src/smt/mam.h index cee6f6e2f..c9f813150 100644 --- a/src/smt/mam.h +++ b/src/smt/mam.h @@ -29,11 +29,9 @@ namespace smt { class mam { protected: context & m_context; - std::ostream * m_trace_stream; public: - mam(context & ctx, std::ostream *trace): - m_context(ctx), - m_trace_stream(trace) { + mam(context & ctx): + m_context(ctx) { } virtual ~mam() { @@ -68,7 +66,7 @@ namespace smt { #endif }; - mam * mk_mam(context & ctx, std::ostream *trace); + mam * mk_mam(context & ctx); }; #endif /* _MAM_H_ */ diff --git a/src/front_end_params/dyn_ack_params.cpp b/src/smt/params/dyn_ack_params.cpp similarity index 65% rename from src/front_end_params/dyn_ack_params.cpp rename to src/smt/params/dyn_ack_params.cpp index b4d0546a9..2e94c376d 100644 --- a/src/front_end_params/dyn_ack_params.cpp +++ b/src/smt/params/dyn_ack_params.cpp @@ -18,14 +18,15 @@ Revision History: --*/ #include"dyn_ack_params.h" +#if 0 void dyn_ack_params::register_params(ini_params & p) { - p.register_int_param("DACK", 0, 2, reinterpret_cast(m_dack), + p.register_int_param("dack", 0, 2, reinterpret_cast(m_dack), "0 - disable dynamic ackermannization, 1 - expand Leibniz's axiom if a congruence is the root of a conflict, 2 - expand Leibniz's axiom if a congruence is used during conflict resolution."); - p.register_bool_param("DACK_EQ", m_dack_eq, "enable dynamic ackermannization for transtivity of equalities"); - p.register_unsigned_param("DACK_THRESHOLD", m_dack_threshold, "number of times the congruence rule must be used before Leibniz's axiom is expanded"); - p.register_double_param("DACK_FACTOR", m_dack_factor, "number of instance per conflict"); - p.register_unsigned_param("DACK_GC", m_dack_gc, "Dynamic ackermannization garbage collection frequency (per conflict)."); - p.register_double_param("DACK_GC_INV_DECAY", m_dack_gc_inv_decay); + p.register_bool_param("dack_eq", m_dack_eq, "enable dynamic ackermannization for transtivity of equalities"); + p.register_unsigned_param("dack_threshold", m_dack_threshold, "number of times the congruence rule must be used before Leibniz's axiom is expanded"); + p.register_double_param("dack_factor", m_dack_factor, "number of instance per conflict"); + p.register_unsigned_param("dack_gc", m_dack_gc, "Dynamic ackermannization garbage collection frequency (per conflict)."); + p.register_double_param("dack_gc_inv_decay", m_dack_gc_inv_decay); } - +#endif diff --git a/src/front_end_params/dyn_ack_params.h b/src/smt/params/dyn_ack_params.h similarity index 93% rename from src/front_end_params/dyn_ack_params.h rename to src/smt/params/dyn_ack_params.h index c5325195e..9f7ce578c 100644 --- a/src/front_end_params/dyn_ack_params.h +++ b/src/smt/params/dyn_ack_params.h @@ -19,8 +19,6 @@ Revision History: #ifndef _DYN_ACK_PARAMS_H_ #define _DYN_ACK_PARAMS_H_ -#include"ini_file.h" - enum dyn_ack_strategy { DACK_DISABLED, DACK_ROOT, // congruence is the root of the conflict @@ -45,7 +43,6 @@ public: m_dack_gc_inv_decay(0.8) { } - void register_params(ini_params & p); }; diff --git a/src/smt/params/preprocessor_params.cpp b/src/smt/params/preprocessor_params.cpp new file mode 100644 index 000000000..4799b8b9f --- /dev/null +++ b/src/smt/params/preprocessor_params.cpp @@ -0,0 +1,33 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + preprocessor_params.h + +Abstract: + + Preprocess AST before adding them to the logical context + +Author: + + Leonardo de Moura (leonardo) 2012-12-02. + +Revision History: + +--*/ +#include"preprocessor_params.h" +#include"smt_params_helper.hpp" + +void preprocessor_params::updt_local_params(params_ref const & _p) { + smt_params_helper p(_p); + m_macro_finder = p.macro_finder(); + m_pull_nested_quantifiers = p.pull_nested_quantifiers(); +} + +void preprocessor_params::updt_params(params_ref const & p) { + pattern_inference_params::updt_params(p); + bv_simplifier_params::updt_params(p); + arith_simplifier_params::updt_params(p); + updt_local_params(p); +} diff --git a/src/smt/params/preprocessor_params.h b/src/smt/params/preprocessor_params.h new file mode 100644 index 000000000..d53f26318 --- /dev/null +++ b/src/smt/params/preprocessor_params.h @@ -0,0 +1,88 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + preprocessor_params.h + +Abstract: + + Preprocess AST before adding them to the logical context + +Author: + + Leonardo de Moura (leonardo) 2008-01-17. + +Revision History: + +--*/ +#ifndef _PREPROCESSOR_PARAMS_H_ +#define _PREPROCESSOR_PARAMS_H_ + +#include"pattern_inference_params.h" +#include"bit_blaster_params.h" +#include"bv_simplifier_params.h" +#include"arith_simplifier_params.h" + +enum lift_ite_kind { + LI_NONE, + LI_CONSERVATIVE, + LI_FULL +}; + +struct preprocessor_params : public pattern_inference_params, + public bit_blaster_params, + public bv_simplifier_params, + public arith_simplifier_params { + lift_ite_kind m_lift_ite; + lift_ite_kind m_ng_lift_ite; // lift ite for non ground terms + bool m_pull_cheap_ite_trees; + bool m_pull_nested_quantifiers; + bool m_eliminate_term_ite; + bool m_eliminate_and; // represent (and a b) as (not (or (not a) (not b))) + bool m_macro_finder; + bool m_propagate_values; + bool m_propagate_booleans; + bool m_refine_inj_axiom; + bool m_eliminate_bounds; + bool m_simplify_bit2int; + bool m_nnf_cnf; + bool m_distribute_forall; + bool m_reduce_args; + bool m_quasi_macros; + bool m_restricted_quasi_macros; + bool m_max_bv_sharing; + bool m_pre_simplifier; + bool m_nlquant_elim; + +public: + preprocessor_params(params_ref const & p = params_ref()): + m_lift_ite(LI_NONE), + m_ng_lift_ite(LI_NONE), + m_pull_cheap_ite_trees(false), + m_pull_nested_quantifiers(false), + m_eliminate_term_ite(false), + m_eliminate_and(true), + m_macro_finder(false), + m_propagate_values(true), + m_propagate_booleans(false), // TODO << check peformance + m_refine_inj_axiom(true), + m_eliminate_bounds(false), + m_simplify_bit2int(false), + m_nnf_cnf(true), + m_distribute_forall(false), + m_reduce_args(false), + m_quasi_macros(false), + m_restricted_quasi_macros(false), + m_max_bv_sharing(true), + m_pre_simplifier(true), + m_nlquant_elim(false) { + updt_local_params(p); + } + + void updt_local_params(params_ref const & p); + + void updt_params(params_ref const & p); +}; + +#endif /* _PREPROCESSOR_PARAMS_H_ */ diff --git a/src/smt/params/qi_params.cpp b/src/smt/params/qi_params.cpp new file mode 100644 index 000000000..f5506d35b --- /dev/null +++ b/src/smt/params/qi_params.cpp @@ -0,0 +1,37 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + qi_params.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2012-12-02. + +Revision History: + +--*/ +#include"qi_params.h" +#include"smt_params_helper.hpp" + +void qi_params::updt_params(params_ref const & _p) { + smt_params_helper p(_p); + m_mbqi = p.mbqi(); + m_mbqi_max_cexs = p.mbqi_max_cexs(); + m_mbqi_max_cexs_incr = p.mbqi_max_cexs_incr(); + m_mbqi_max_iterations = p.mbqi_max_iterations(); + m_mbqi_trace = p.mbqi_trace(); + m_mbqi_force_template = p.mbqi_force_template(); + m_qi_profile = p.qi_profile(); + m_qi_profile_freq = p.qi_profile_freq(); + m_qi_max_instances = p.qi_max_instances(); + m_qi_eager_threshold = p.qi_eager_threshold(); + m_qi_lazy_threshold = p.qi_lazy_threshold(); + m_qi_cost = p.qi_cost(); + m_qi_max_eager_multipatterns = p.qi_max_multi_patterns(); +} diff --git a/src/front_end_params/qi_params.h b/src/smt/params/qi_params.h similarity index 53% rename from src/front_end_params/qi_params.h rename to src/smt/params/qi_params.h index bd41de12c..b0a21e75b 100644 --- a/src/front_end_params/qi_params.h +++ b/src/smt/params/qi_params.h @@ -19,7 +19,8 @@ Revision History: #ifndef _QI_PARAMS_H_ #define _QI_PARAMS_H_ -#include"ini_file.h" +#include"util.h" +#include"params.h" enum quick_checker_mode { MC_NO, // do not use (cheap) model checking based instantiation @@ -53,7 +54,7 @@ struct qi_params { bool m_instgen; - qi_params(): + qi_params(params_ref const & p = params_ref()): /* The "weight 0" performance bug ------------------------------ @@ -93,46 +94,17 @@ struct qi_params { m_qi_max_instances(UINT_MAX), m_qi_lazy_instantiation(false), m_qi_conservative_final_check(false), -#ifdef _EXTERNAL_RELEASE m_mbqi(true), // enabled by default -#else - m_mbqi(false), // to avoid Rustan whining that the models are not partial anymore. -#endif m_mbqi_max_cexs(1), m_mbqi_max_cexs_incr(1), m_mbqi_max_iterations(1000), m_mbqi_trace(false), m_mbqi_force_template(10), m_instgen(false) { + updt_params(p); } - - void register_params(ini_params & p) { - p.register_unsigned_param("QI_MAX_EAGER_MULTI_PATTERNS", m_qi_max_eager_multipatterns, - "Specify the number of extra multi patterns that are processed eagerly. By default, the prover use at most one multi-pattern eagerly when there is no unary pattern. This value should be smaller than or equal to PI_MAX_MULTI_PATTERNS"); - p.register_unsigned_param("QI_MAX_LAZY_MULTI_PATTERN_MATCHING", m_qi_max_lazy_multipattern_matching, "Maximum number of rounds of matching in a branch for delayed multipatterns. A multipattern is delayed based on the value of QI_MAX_EAGER_MULTI_PATTERNS"); - p.register_string_param("QI_COST", m_qi_cost, "The cost function for quantifier instantiation"); - p.register_string_param("QI_NEW_GEN", m_qi_new_gen, "The function for calculating the generation of newly constructed terms"); - p.register_double_param("QI_EAGER_THRESHOLD", m_qi_eager_threshold, "Threshold for eager quantifier instantiation"); - p.register_double_param("QI_LAZY_THRESHOLD", m_qi_lazy_threshold, "Threshold for lazy quantifier instantiation"); - p.register_bool_param("QI_PROFILE", m_qi_profile); - p.register_unsigned_param("QI_PROFILE_FREQ", m_qi_profile_freq); - p.register_int_param("QI_QUICK_CHECKER", 0, 2, reinterpret_cast(m_qi_quick_checker), "0 - do not use (cheap) model checker, 1 - instantiate instances unsatisfied by current model, 2 - 1 + instantiate instances not satisfied by current model"); - p.register_bool_param("QI_LAZY_QUICK_CHECKER", m_qi_lazy_quick_checker); - p.register_bool_param("QI_PROMOTE_UNSAT", m_qi_promote_unsat); - p.register_unsigned_param("QI_MAX_INSTANCES", m_qi_max_instances); - p.register_bool_param("QI_LAZY_INSTANTIATION", m_qi_lazy_instantiation); - p.register_bool_param("QI_CONSERVATIVE_FINAL_CHECK", m_qi_conservative_final_check); - - p.register_bool_param("MBQI", m_mbqi, "Model Based Quantifier Instantiation (MBQI)"); - p.register_unsigned_param("MBQI_MAX_CEXS", m_mbqi_max_cexs, "Initial maximal number of counterexamples used in MBQI, each counterexample generates a quantifier instantiation", true); - p.register_unsigned_param("MBQI_MAX_CEXS_INCR", m_mbqi_max_cexs_incr, "Increment for MBQI_MAX_CEXS, the increment is performed after each round of MBQI", true); - p.register_unsigned_param("MBQI_MAX_ITERATIONS", m_mbqi_max_iterations, "Maximum number of rounds of MBQI", true); - p.register_bool_param("MBQI_TRACE", m_mbqi_trace, "Generate tracing messages for Model Based Quantifier Instantiation (MBQI). It will display a message before every round of MBQI, and the quantifiers that were not satisfied.", true); - p.register_unsigned_param("MBQI_FORCE_TEMPLATE", m_mbqi_force_template, "Some quantifiers can be used as templates for building interpretations for functions. Z3 uses heuristics to decide whether a quantifier will be used as a template or not. Quantifiers with weight >= MBQI_FORCE_TEMPLATE are forced to be used as a template", true); - - p.register_bool_param("INST_GEN", m_instgen, "Enable Instantiation Generation solver (disables other quantifier reasoning)", false); - } + void updt_params(params_ref const & p); }; #endif /* _QI_PARAMS_H_ */ diff --git a/src/smt/params/smt_params.cpp b/src/smt/params/smt_params.cpp new file mode 100644 index 000000000..22122cd83 --- /dev/null +++ b/src/smt/params/smt_params.cpp @@ -0,0 +1,55 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + smt_params.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2008-02-20. + +Revision History: + +--*/ +#include"smt_params.h" +#include"smt_params_helper.hpp" + +void smt_params::updt_local_params(params_ref const & _p) { + smt_params_helper p(_p); + m_auto_config = p.auto_config(); + m_random_seed = p.random_seed(); + m_relevancy_lvl = p.relevancy(); + m_ematching = p.ematching(); + m_phase_selection = static_cast(p.phase_selection()); + m_restart_strategy = static_cast(p.restart_strategy()); + m_restart_factor = p.restart_factor(); + m_case_split_strategy = static_cast(p.case_split()); + m_delay_units = p.delay_units(); + m_delay_units_threshold = p.delay_units_threshold(); + m_preprocess = _p.get_bool("preprocess", true); // hidden parameter + if (_p.get_bool("arith.greatest_error_pivot", false)) + m_arith_pivot_strategy = ARITH_PIVOT_GREATEST_ERROR; + else if (_p.get_bool("arith.least_error_pivot", false)) + m_arith_pivot_strategy = ARITH_PIVOT_LEAST_ERROR; +} + +void smt_params::updt_params(params_ref const & p) { + preprocessor_params::updt_params(p); + qi_params::updt_params(p); + theory_arith_params::updt_params(p); + theory_bv_params::updt_params(p); + updt_local_params(p); +} + +void smt_params::updt_params(context_params const & p) { + m_auto_config = p.m_auto_config; + m_soft_timeout = p.m_timeout; + m_model = p.m_model; + m_model_validate = p.m_model_validate; +} + diff --git a/src/front_end_params/smt_params.h b/src/smt/params/smt_params.h similarity index 81% rename from src/front_end_params/smt_params.h rename to src/smt/params/smt_params.h index 20a150c64..3d823cb51 100644 --- a/src/front_end_params/smt_params.h +++ b/src/smt/params/smt_params.h @@ -19,13 +19,15 @@ Revision History: #ifndef _SMT_PARAMS_H_ #define _SMT_PARAMS_H_ -#include"ini_file.h" +#include"ast.h" #include"dyn_ack_params.h" #include"qi_params.h" #include"theory_arith_params.h" #include"theory_array_params.h" #include"theory_bv_params.h" #include"theory_datatype_params.h" +#include"preprocessor_params.h" +#include"context_params.h" enum phase_selection { PS_ALWAYS_FALSE, @@ -66,13 +68,17 @@ enum case_split_strategy { CS_RELEVANCY_GOAL, // based on relevancy and the current goal }; -struct smt_params : public dyn_ack_params, public qi_params, public theory_arith_params, public theory_array_params, public theory_bv_params, +struct smt_params : public preprocessor_params, + public dyn_ack_params, + public qi_params, + public theory_arith_params, + public theory_array_params, + public theory_bv_params, public theory_datatype_params { bool m_display_proof; bool m_display_dot_proof; bool m_display_unsat_core; bool m_check_proof; - bool m_internalizer_nnf; bool m_eq_propagation; bool m_binary_clause_opt; unsigned m_relevancy_lvl; @@ -170,6 +176,7 @@ struct smt_params : public dyn_ack_params, public qi_params, public theory_arith // // ----------------------------------- bool m_model; + bool m_model_compact; bool m_model_validate; bool m_model_on_timeout; bool m_model_on_final_check; @@ -188,12 +195,25 @@ struct smt_params : public dyn_ack_params, public qi_params, public theory_arith // ----------------------------------- bool m_display_installed_theories; - smt_params(): + // ----------------------------------- + // + // From front_end_params + // + // ----------------------------------- + bool m_preprocess; // temporary hack for disabling all preprocessing.. + bool m_user_theory_preprocess_axioms; + bool m_user_theory_persist_axioms; + unsigned m_soft_timeout; + bool m_at_labels_cex; // only use labels which contains the @ symbol when building multiple counterexamples. + bool m_check_at_labels; // check that @ labels are inserted to generate unique counter-examples. + bool m_dump_goal_as_smt; + bool m_auto_config; + + smt_params(params_ref const & p = params_ref()): m_display_proof(false), m_display_dot_proof(false), m_display_unsat_core(false), m_check_proof(false), - m_internalizer_nnf(false), m_eq_propagation(true), m_binary_clause_opt(true), m_relevancy_lvl(2), @@ -243,14 +263,28 @@ struct smt_params : public dyn_ack_params, public qi_params, public theory_arith m_display_ll_bool_var2expr(false), m_abort_after_preproc(false), m_model(true), + m_model_compact(false), m_model_validate(false), m_model_on_timeout(false), m_model_on_final_check(false), m_progress_sampling_freq(0), - m_display_installed_theories(false) { + m_display_installed_theories(false), + m_preprocess(true), // temporary hack for disabling all preprocessing.. + m_user_theory_preprocess_axioms(false), + m_user_theory_persist_axioms(false), + m_soft_timeout(0), + m_at_labels_cex(false), + m_check_at_labels(false), + m_dump_goal_as_smt(false), + m_auto_config(true) { + updt_local_params(p); } - void register_params(ini_params & p); + void updt_local_params(params_ref const & p); + + void updt_params(params_ref const & p); + + void updt_params(context_params const & p); }; #endif /* _SMT_PARAMS_H_ */ diff --git a/src/smt/params/smt_params_helper.pyg b/src/smt/params/smt_params_helper.pyg new file mode 100644 index 000000000..071d843a3 --- /dev/null +++ b/src/smt/params/smt_params_helper.pyg @@ -0,0 +1,42 @@ +def_module_params(module_name='smt', + class_name='smt_params_helper', + description='smt solver based on lazy smt', + export=True, + params=(('auto_config', BOOL, True, 'automatically configure solver'), + ('random_seed', UINT, 0, 'random seed for the smt solver'), + ('relevancy', UINT, 2, 'relevancy propagation heuristic: 0 - disabled, 1 - relevancy is tracked by only affects quantifier instantiation, 2 - relevancy is tracked, and an atom is only asserted if it is relevant'), + ('macro_finder', BOOL, False, 'try to find universally quantified formulas that can be viewed as macros'), + ('ematching', BOOL, True, 'E-Matching based quantifier instantiation'), + ('phase_selection', UINT, 4, 'phase selection heuristic: 0 - always false, 1 - always true, 2 - phase caching, 3 - phase caching conservative, 4 - phase caching conservative 2, 5 - random, 6 - number of occurrences'), + ('restart_strategy', UINT, 1, '0 - geometric, 1 - inner-outer-geometric, 2 - luby, 3 - fixed, 4 - arithmetic'), + ('restart_factor', DOUBLE, 1.1, 'when using geometric (or inner-outer-geometric) progression of restarts, it specifies the constant used to multiply the currect restart threshold'), + ('case_split', UINT, 1, '0 - case split based on variable activity, 1 - similar to 0, but delay case splits created during the search, 2 - similar to 0, but cache the relevancy, 3 - case split based on relevancy (structural splitting), 4 - case split on relevancy and activity, 5 - case split on relevancy and current goal'), + ('delay_units', BOOL, False, 'if true then z3 will not restart when a unit clause is learned'), + ('delay_units_threshold', UINT, 32, 'maximum number of learned unit clauses before restarting, ingored if delay_units is false'), + ('pull_nested_quantifiers', BOOL, False, 'pull nested quantifiers'), + ('mbqi', BOOL, True, 'model based quantifier instantiation (MBQI)'), + ('mbqi.max_cexs', UINT, 1, 'initial maximal number of counterexamples used in MBQI, each counterexample generates a quantifier instantiation'), + ('mbqi.max_cexs_incr', UINT, 0, 'increment for MBQI_MAX_CEXS, the increment is performed after each round of MBQI'), + ('mbqi.max_iterations', UINT, 1000, 'maximum number of rounds of MBQI'), + ('mbqi.trace', BOOL, False, 'generate tracing messages for Model Based Quantifier Instantiation (MBQI). It will display a message before every round of MBQI, and the quantifiers that were not satisfied'), + ('mbqi.force_template', UINT, 10, 'some quantifiers can be used as templates for building interpretations for functions. Z3 uses heuristics to decide whether a quantifier will be used as a template or not. Quantifiers with weight >= mbqi.force_template are forced to be used as a template'), + ('qi.profile', BOOL, False, 'profile quantifier instantiation'), + ('qi.profile_freq', UINT, UINT_MAX, 'how frequent results are reported by qi.profile'), + ('qi.max_instances', UINT, UINT_MAX, 'maximum number of quantifier instantiations'), + ('qi.eager_threshold', DOUBLE, 10.0, 'threshold for eager quantifier instantiation'), + ('qi.lazy_threshold', DOUBLE, 20.0, 'threshold for lazy quantifier instantiation'), + ('qi.cost', STRING, '(+ weight generation)', 'expression specifying what is the cost of a given quantifier instantiation'), + ('qi.max_multi_patterns', UINT, 0, 'specify the number of extra multi patterns'), + ('bv.reflect', BOOL, True, 'create enode for every bit-vector term'), + ('arith.random_initial_value', BOOL, False, 'use random initial values in the simplex-based procedure for linear arithmetic'), + ('arith.solver', UINT, 2, 'arithmetic solver: 0 - no solver, 1 - bellman-ford based solver (diff. logic only), 2 - simplex based solver, 3 - floyd-warshall based solver (diff. logic only) and no theory combination'), + ('arith.nl', BOOL, True, '(incomplete) nonlinear arithmetic support based on Groebner basis and interval propagation'), + ('arith.nl.gb', BOOL, True, 'groebner Basis computation, this option is ignored when arith.nl=false'), + ('arith.nl.branching', BOOL, True, 'branching on integer variables in non linear clusters'), + ('arith.nl.rounds', UINT, 1024, 'threshold for number of (nested) final checks for non linear arithmetic'), + ('arith.euclidean_solver', BOOL, False, 'eucliean solver for linear integer arithmetic'), + ('arith.propagate_eqs', BOOL, True, 'propagate (cheap) equalities'), + ('arith.propagation_mode', UINT, 2, '0 - no propagation, 1 - propagate existing literals, 2 - refine bounds'), + ('arith.branch_cut_ratio', UINT, 2, 'branch/cut ratio for linear integer arithmetic'), + ('arith.int_eq_branch', BOOL, False, 'branching using derived integer equations'), + ('arith.ignore_int', BOOL, False, 'treat integer variables as real'))) diff --git a/src/smt/params/theory_arith_params.cpp b/src/smt/params/theory_arith_params.cpp new file mode 100644 index 000000000..7281a5daa --- /dev/null +++ b/src/smt/params/theory_arith_params.cpp @@ -0,0 +1,38 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + theory_arith_params.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2008-05-06. + +Revision History: + +--*/ +#include"theory_arith_params.h" +#include"smt_params_helper.hpp" + +void theory_arith_params::updt_params(params_ref const & _p) { + smt_params_helper p(_p); + m_arith_random_initial_value = p.arith_random_initial_value(); + m_arith_mode = static_cast(p.arith_solver()); + m_nl_arith = p.arith_nl(); + m_nl_arith_gb = p.arith_nl_gb(); + m_nl_arith_branching = p.arith_nl_branching(); + m_nl_arith_rounds = p.arith_nl_rounds(); + m_arith_euclidean_solver = p.arith_euclidean_solver(); + m_arith_propagate_eqs = p.arith_propagate_eqs(); + m_arith_branch_cut_ratio = p.arith_branch_cut_ratio(); + m_arith_int_eq_branching = p.arith_int_eq_branch(); + m_arith_ignore_int = p.arith_ignore_int(); + m_arith_bound_prop = static_cast(p.arith_propagation_mode()); +} + + diff --git a/src/front_end_params/theory_arith_params.h b/src/smt/params/theory_arith_params.h similarity index 96% rename from src/front_end_params/theory_arith_params.h rename to src/smt/params/theory_arith_params.h index 290049037..52fef8ca4 100644 --- a/src/front_end_params/theory_arith_params.h +++ b/src/smt/params/theory_arith_params.h @@ -19,7 +19,8 @@ Revision History: #ifndef _THEORY_ARITH_PARAMS_H_ #define _THEORY_ARITH_PARAMS_H_ -#include"ini_file.h" +#include +#include"params.h" enum arith_solver_id { AS_NO_ARITH, @@ -104,7 +105,7 @@ struct theory_arith_params { bool m_arith_euclidean_solver; - theory_arith_params(): + theory_arith_params(params_ref const & p = params_ref()): m_arith_mode(AS_ARITH), m_arith_auto_config_simplex(false), m_arith_blands_rule_threshold(1000), @@ -149,9 +150,10 @@ struct theory_arith_params { m_nl_arith_branching(true), m_nl_arith_rounds(1024), m_arith_euclidean_solver(false) { + updt_params(p); } - void register_params(ini_params & p); + void updt_params(params_ref const & p); }; #endif /* _THEORY_ARITH_PARAMS_H_ */ diff --git a/src/front_end_params/theory_array_params.h b/src/smt/params/theory_array_params.h similarity index 61% rename from src/front_end_params/theory_array_params.h rename to src/smt/params/theory_array_params.h index 9e93fefbe..c1ae8ce32 100644 --- a/src/front_end_params/theory_array_params.h +++ b/src/smt/params/theory_array_params.h @@ -19,7 +19,7 @@ Revision History: #ifndef _THEORY_ARRAY_PARAMS_H_ #define _THEORY_ARRAY_PARAMS_H_ -#include"ini_file.h" +#include"array_simplifier_params.h" enum array_solver_id { AR_NO_ARRAY, @@ -28,7 +28,7 @@ enum array_solver_id { AR_FULL }; -struct theory_array_params { +struct theory_array_params : public array_simplifier_params { array_solver_id m_array_mode; bool m_array_weak; bool m_array_extensional; @@ -38,8 +38,6 @@ struct theory_array_params { bool m_array_always_prop_upward; bool m_array_lazy_ieq; unsigned m_array_lazy_ieq_delay; - bool m_array_canonize_simplify; - bool m_array_simplify; // temporary hack for disabling array simplifier plugin. theory_array_params(): m_array_mode(AR_FULL), @@ -50,25 +48,26 @@ struct theory_array_params { m_array_cg(false), m_array_always_prop_upward(true), // UPWARDs filter is broken... TODO: fix it m_array_lazy_ieq(false), - m_array_lazy_ieq_delay(10), - m_array_canonize_simplify(false), - m_array_simplify(true) { + m_array_lazy_ieq_delay(10) { } +#if 0 void register_params(ini_params & p) { - p.register_int_param("ARRAY_SOLVER", 0, 3, reinterpret_cast(m_array_mode), "0 - no array, 1 - simple, 2 - model based, 3 - full"); - p.register_bool_param("ARRAY_WEAK", m_array_weak); - p.register_bool_param("ARRAY_EXTENSIONAL", m_array_extensional); - p.register_unsigned_param("ARRAY_LAZINESS", m_array_laziness); - p.register_bool_param("ARRAY_DELAY_EXP_AXIOM", m_array_delay_exp_axiom); - p.register_bool_param("ARRAY_CG", m_array_cg); - p.register_bool_param("ARRAY_ALWAYS_PROP_UPWARD", m_array_always_prop_upward, + p.register_int_param("array_solver", 0, 3, reinterpret_cast(m_array_mode), "0 - no array, 1 - simple, 2 - model based, 3 - full"); + p.register_bool_param("array_weak", m_array_weak); + p.register_bool_param("array_extensional", m_array_extensional); + p.register_unsigned_param("array_laziness", m_array_laziness); + p.register_bool_param("array_delay_exp_axiom", m_array_delay_exp_axiom); + p.register_bool_param("array_cg", m_array_cg); + p.register_bool_param("array_always_prop_upward", m_array_always_prop_upward, "Disable the built-in filter upwards propagation"); - p.register_bool_param("ARRAY_LAZY_IEQ", m_array_lazy_ieq); - p.register_unsigned_param("ARRAY_LAZY_IEQ_DELAY", m_array_lazy_ieq_delay); - p.register_bool_param("ARRAY_CANONIZE", m_array_canonize_simplify, + p.register_bool_param("array_lazy_ieq", m_array_lazy_ieq); + p.register_unsigned_param("array_lazy_ieq_delay", m_array_lazy_ieq_delay); + p.register_bool_param("array_canonize", m_array_canonize_simplify, "Normalize arrays into normal form during simplification"); } +#endif + }; diff --git a/src/smt/params/theory_bv_params.cpp b/src/smt/params/theory_bv_params.cpp new file mode 100644 index 000000000..c2a31c59d --- /dev/null +++ b/src/smt/params/theory_bv_params.cpp @@ -0,0 +1,25 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + theory_bv_params.cpp + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2012-12-02. + +Revision History: + +--*/ +#include"theory_bv_params.h" +#include"smt_params_helper.hpp" + +void theory_bv_params::updt_params(params_ref const & _p) { + smt_params_helper p(_p); + m_bv_reflect = p.bv_reflect(); +} diff --git a/src/smt/params/theory_bv_params.h b/src/smt/params/theory_bv_params.h new file mode 100644 index 000000000..a3052b4e9 --- /dev/null +++ b/src/smt/params/theory_bv_params.h @@ -0,0 +1,50 @@ +/*++ +Copyright (c) 2006 Microsoft Corporation + +Module Name: + + theory_bv_params.h + +Abstract: + + + +Author: + + Leonardo de Moura (leonardo) 2008-06-06. + +Revision History: + +--*/ +#ifndef _THEORY_BV_PARAMS_H_ +#define _THEORY_BV_PARAMS_H_ + +#include"params.h" + +enum bv_solver_id { + BS_NO_BV, + BS_BLASTER +}; + +struct theory_bv_params { + bv_solver_id m_bv_mode; + bool m_bv_reflect; + bool m_bv_lazy_le; + bool m_bv_cc; + unsigned m_bv_blast_max_size; + bool m_bv_enable_int2bv2int; + theory_bv_params(params_ref const & p = params_ref()): + m_bv_mode(BS_BLASTER), + m_bv_reflect(true), + m_bv_lazy_le(false), + m_bv_cc(false), + m_bv_blast_max_size(INT_MAX), + m_bv_enable_int2bv2int(false) { + updt_params(p); + } + + void updt_params(params_ref const & p); +}; + +#endif /* _THEORY_BV_PARAMS_H_ */ + diff --git a/src/front_end_params/theory_datatype_params.h b/src/smt/params/theory_datatype_params.h similarity index 87% rename from src/front_end_params/theory_datatype_params.h rename to src/smt/params/theory_datatype_params.h index 000c4da07..8f914ac7b 100644 --- a/src/front_end_params/theory_datatype_params.h +++ b/src/smt/params/theory_datatype_params.h @@ -19,8 +19,6 @@ Revision History: #ifndef _THEORY_DATATYPE_PARAMS_H_ #define _THEORY_DATATYPE_PARAMS_H_ -#include"ini_file.h" - struct theory_datatype_params { unsigned m_dt_lazy_splits; @@ -28,9 +26,11 @@ struct theory_datatype_params { m_dt_lazy_splits(1) { } +#if 0 void register_params(ini_params & p) { - p.register_unsigned_param("DT_LAZY_SPLITS", m_dt_lazy_splits, "How lazy datatype splits are performed: 0- eager, 1- lazy for infinite types, 2- lazy"); + p.register_unsigned_param("dt_lazy_splits", m_dt_lazy_splits, "How lazy datatype splits are performed: 0- eager, 1- lazy for infinite types, 2- lazy"); } +#endif }; diff --git a/src/smt/proto_model/proto_model.cpp b/src/smt/proto_model/proto_model.cpp index 4cedea228..34742e3a0 100644 --- a/src/smt/proto_model/proto_model.cpp +++ b/src/smt/proto_model/proto_model.cpp @@ -17,6 +17,7 @@ Revision History: --*/ #include"proto_model.h" +#include"model_params.hpp" #include"ast_pp.h" #include"ast_ll_pp.h" #include"var_subst.h" @@ -26,15 +27,16 @@ Revision History: #include"model_v2_pp.h" #include"basic_simplifier_plugin.h" -proto_model::proto_model(ast_manager & m, simplifier & s, model_params const & p): +proto_model::proto_model(ast_manager & m, simplifier & s, params_ref const & p): model_core(m), - m_params(p), m_asts(m), m_simplifier(s), m_afid(m.get_family_id(symbol("array"))) { register_factory(alloc(basic_factory, m)); m_user_sort_factory = alloc(user_sort_factory, m); register_factory(m_user_sort_factory); + + m_model_partial = model_params(p).partial(); } void proto_model::reset_finterp() { @@ -620,7 +622,7 @@ void proto_model::complete_partial_func(func_decl * f) { \brief Set the (else) field of function interpretations... */ void proto_model::complete_partial_funcs() { - if (m_params.m_model_partial) + if (m_model_partial) return; // m_func_decls may be "expanded" when we invoke get_some_value. diff --git a/src/smt/proto_model/proto_model.h b/src/smt/proto_model/proto_model.h index bd5609f33..d16586698 100644 --- a/src/smt/proto_model/proto_model.h +++ b/src/smt/proto_model/proto_model.h @@ -29,16 +29,15 @@ Revision History: #define _PROTO_MODEL_H_ #include"model_core.h" -#include"model_params.h" #include"value_factory.h" #include"plugin_manager.h" #include"simplifier.h" #include"arith_decl_plugin.h" #include"func_decl_dependencies.h" #include"model.h" +#include"params.h" class proto_model : public model_core { - model_params const & m_params; ast_ref_vector m_asts; plugin_manager m_factories; user_sort_factory * m_user_sort_factory; @@ -47,6 +46,8 @@ class proto_model : public model_core { func_decl_set m_aux_decls; ptr_vector m_tmp; + bool m_model_partial; + void reset_finterp(); expr * mk_some_interp_for(func_decl * d); @@ -60,11 +61,9 @@ class proto_model : public model_core { public: - proto_model(ast_manager & m, simplifier & s, model_params const & p); + proto_model(ast_manager & m, simplifier & s, params_ref const & p = params_ref()); virtual ~proto_model(); - model_params const & get_model_params() const { return m_params; } - void register_factory(value_factory * f) { m_factories.register_plugin(f); } bool eval(expr * e, expr_ref & result, bool model_completion = false); diff --git a/src/smt/qi_queue.cpp b/src/smt/qi_queue.cpp index a2a2cc9de..35dd19087 100644 --- a/src/smt/qi_queue.cpp +++ b/src/smt/qi_queue.cpp @@ -26,7 +26,7 @@ Revision History: namespace smt { - qi_queue::qi_queue(quantifier_manager & qm, context & ctx, qi_params & params, std::ostream *trace_stream): + qi_queue::qi_queue(quantifier_manager & qm, context & ctx, qi_params & params): m_qm(qm), m_context(ctx), m_manager(m_context.get_manager()), @@ -37,7 +37,6 @@ namespace smt { m_parser(m_manager), m_evaluator(m_manager), m_subst(m_manager), - m_trace_stream(trace_stream), m_instances(m_manager) { init_parser_vars(); m_vals.resize(15, 0.0f); @@ -48,10 +47,21 @@ namespace smt { void qi_queue::setup() { TRACE("qi_cost", tout << "qi_cost: " << m_params.m_qi_cost << "\n";); - if (!m_parser.parse_string(m_params.m_qi_cost.c_str(), m_cost_function)) - throw default_exception("invalid cost function %s", m_params.m_qi_cost.c_str()); - if (!m_parser.parse_string(m_params.m_qi_new_gen.c_str(), m_new_gen_function)) - throw default_exception("invalid new-gen function %s", m_params.m_qi_new_gen.c_str()); + if (!m_parser.parse_string(m_params.m_qi_cost.c_str(), m_cost_function)) { + // it is not reasonable to abort here during the creation of smt::context just because an invalid option was provided. + // throw default_exception("invalid cost function %s", m_params.m_qi_cost.c_str()); + + // using warning message instead + warning_msg("invalid cost function '%s', switching to default one", m_params.m_qi_cost.c_str()); + // Trying again with default function + VERIFY(m_parser.parse_string("(+ weight generation)", m_cost_function)); + } + if (!m_parser.parse_string(m_params.m_qi_new_gen.c_str(), m_new_gen_function)) { + // See comment above + // throw default_exception("invalid new-gen function %s", m_params.m_qi_new_gen.c_str()); + warning_msg("invalid new_gen function '%s', switching to default one", m_params.m_qi_new_gen.c_str()); + VERIFY(m_parser.parse_string("cost", m_new_gen_function)); + } m_eager_cost_threshold = m_params.m_qi_eager_threshold; } @@ -173,25 +183,23 @@ namespace smt { } void qi_queue::display_instance_profile(fingerprint * f, quantifier * q, unsigned num_bindings, enode * const * bindings, unsigned proof_id, unsigned generation) { -#ifndef SMTCOMP - if (m_trace_stream != NULL) { - *m_trace_stream << "[instance] "; + if (m_manager.has_trace_stream()) { + m_manager.trace_stream() << "[instance] "; #if 1 - *m_trace_stream << static_cast(f); + m_manager.trace_stream() << static_cast(f); #else for (unsigned i = 0; i < num_bindings; i++) { // I don't want to use mk_pp because it creates expressions for pretty printing. // This nasty side-effect may change the behavior of Z3. - *m_trace_stream << " #" << bindings[i]->get_owner_id(); + m_manager.trace_stream() << " #" << bindings[i]->get_owner_id(); } #endif if (m_manager.proofs_enabled()) - *m_trace_stream << " #" << proof_id; - *m_trace_stream << " ; " << generation; - *m_trace_stream << "\n"; + m_manager.trace_stream() << " #" << proof_id; + m_manager.trace_stream() << " ; " << generation; + m_manager.trace_stream() << "\n"; } -#endif } void qi_queue::instantiate(entry & ent) { @@ -224,10 +232,10 @@ namespace smt { TRACE("qi_queue_bug", tout << "new instance after simplification:\n" << mk_pp(s_instance, m_manager) << "\n";); if (m_manager.is_true(s_instance)) { TRACE("checker", tout << "reduced to true, before:\n" << mk_ll_pp(instance, m_manager);); -#ifndef SMTCOMP - if (m_trace_stream != NULL) - *m_trace_stream << "[end-of-instance]\n"; -#endif + + if (m_manager.has_trace_stream()) + m_manager.trace_stream() << "[end-of-instance]\n"; + return; } quantifier_stat * stat = m_qm.get_stat(q); @@ -308,10 +316,10 @@ namespace smt { } } }); -#ifndef SMTCOMP - if (m_trace_stream != NULL) - *m_trace_stream << "[end-of-instance]\n"; -#endif + + if (m_manager.has_trace_stream()) + m_manager.trace_stream() << "[end-of-instance]\n"; + } void qi_queue::push_scope() { diff --git a/src/smt/qi_queue.h b/src/smt/qi_queue.h index 43d57d84f..1060f083b 100644 --- a/src/smt/qi_queue.h +++ b/src/smt/qi_queue.h @@ -53,7 +53,6 @@ namespace smt { cached_var_subst m_subst; svector m_vals; double m_eager_cost_threshold; - std::ostream * m_trace_stream; struct entry { fingerprint * m_qb; float m_cost; @@ -81,7 +80,7 @@ namespace smt { void display_instance_profile(fingerprint * f, quantifier * q, unsigned num_bindings, enode * const * bindings, unsigned proof_id, unsigned generation); public: - qi_queue(quantifier_manager & qm, context & ctx, qi_params & params, std::ostream *trace); + qi_queue(quantifier_manager & qm, context & ctx, qi_params & params); ~qi_queue(); void setup(); /** diff --git a/src/smt/smt_case_split_queue.cpp b/src/smt/smt_case_split_queue.cpp index 66d08e9fc..7a03224cf 100644 --- a/src/smt/smt_case_split_queue.cpp +++ b/src/smt/smt_case_split_queue.cpp @@ -278,7 +278,7 @@ namespace smt { }; typedef int_hashtable > bool_var_set; context & m_context; - front_end_params &m_params; + smt_params &m_params; ast_manager & m_manager; ptr_vector m_queue; unsigned m_head; @@ -287,7 +287,7 @@ namespace smt { unsigned m_head2; svector m_scopes; public: - rel_case_split_queue(context & ctx, front_end_params & p): + rel_case_split_queue(context & ctx, smt_params & p): m_context(ctx), m_params(p), m_manager(ctx.get_manager()), @@ -395,8 +395,8 @@ namespace smt { if ((is_or && val == l_true) || (is_and && val == l_false)) { expr * undef_child = 0; if (!has_child_assigned_to(m_context, to_app(curr), val, undef_child, m_params.m_rel_case_split_order)) { - if (m_params.m_trace_stream != NULL) { - *m_params.m_trace_stream << "[decide-and-or] #" << curr->get_id() << " #" << undef_child->get_id() << "\n"; + if (m_manager.has_trace_stream()) { + m_manager.trace_stream() << "[decide-and-or] #" << curr->get_id() << " #" << undef_child->get_id() << "\n"; } TRACE("case_split", tout << "found AND/OR candidate: #" << curr->get_id() << " #" << undef_child->get_id() << "\n";); literal l = m_context.get_literal(undef_child); @@ -465,14 +465,14 @@ namespace smt { typedef int_hashtable > bool_var_set; context & m_context; ast_manager & m_manager; - front_end_params &m_params; + smt_params &m_params; ptr_vector m_queue; unsigned m_head; int m_bs_num_bool_vars; //!< Number of boolean variable before starting to search. bool_var_act_queue m_delayed_queue; svector m_scopes; public: - rel_act_case_split_queue(context & ctx, front_end_params & p): + rel_act_case_split_queue(context & ctx, smt_params & p): m_context(ctx), m_manager(ctx.get_manager()), m_params(p), @@ -694,7 +694,7 @@ namespace smt { typedef int_hashtable > bool_var_set; context & m_context; - front_end_params & m_params; + smt_params & m_params; ast_manager & m_manager; ptr_vector m_queue; unsigned m_head; @@ -714,7 +714,7 @@ namespace smt { public: - rel_goal_case_split_queue(context & ctx, front_end_params & p): + rel_goal_case_split_queue(context & ctx, smt_params & p): m_context(ctx), m_params(p), m_manager(ctx.get_manager()), @@ -851,8 +851,8 @@ namespace smt { if ((is_or && val == l_true) || (is_and && val == l_false)) { expr * undef_child = 0; if (!has_child_assigned_to(m_context, to_app(curr), val, undef_child, m_params.m_rel_case_split_order)) { - if (m_params.m_trace_stream != NULL) { - *m_params.m_trace_stream << "[decide-and-or] #" << curr->get_id() << " #" << undef_child->get_id() << "\n"; + if (m_manager.has_trace_stream()) { + m_manager.trace_stream() << "[decide-and-or] #" << curr->get_id() << " #" << undef_child->get_id() << "\n"; } TRACE("case_split", tout << "found AND/OR candidate: #" << curr->get_id() << " #" << undef_child->get_id() << "\n";); literal l = m_context.get_literal(undef_child); @@ -900,11 +900,6 @@ namespace smt { // does the push after calling us m_priority_queue2.insert(idx); e.m_last_decided = -1; - /* - if (m_params.m_trace_stream != NULL) { - *m_params.m_trace_stream << "[generation] #" << e.m_expr->get_id() << " " << e.m_generation << "\n"; - } - */ return; } } @@ -1093,7 +1088,7 @@ namespace smt { }; - case_split_queue * mk_case_split_queue(context & ctx, front_end_params & p) { + case_split_queue * mk_case_split_queue(context & ctx, smt_params & p) { if (p.m_relevancy_lvl < 2 && (p.m_case_split_strategy == CS_RELEVANCY || p.m_case_split_strategy == CS_RELEVANCY_ACTIVITY || p.m_case_split_strategy == CS_RELEVANCY_GOAL)) { warning_msg("relevacy must be enabled to use option CASE_SPLIT=3, 4 or 5"); diff --git a/src/smt/smt_case_split_queue.h b/src/smt/smt_case_split_queue.h index 106b97e38..d78739df1 100644 --- a/src/smt/smt_case_split_queue.h +++ b/src/smt/smt_case_split_queue.h @@ -48,7 +48,7 @@ namespace smt { virtual ~case_split_queue() {} }; - case_split_queue * mk_case_split_queue(context & ctx, front_end_params & p); + case_split_queue * mk_case_split_queue(context & ctx, smt_params & p); }; #endif /* _SMT_CASE_SPLIT_QUEUE_H_ */ diff --git a/src/smt/smt_conflict_resolution.cpp b/src/smt/smt_conflict_resolution.cpp index 2bc32e217..d34aa2ec8 100644 --- a/src/smt/smt_conflict_resolution.cpp +++ b/src/smt/smt_conflict_resolution.cpp @@ -32,7 +32,7 @@ namespace smt { conflict_resolution::conflict_resolution(ast_manager & m, context & ctx, dyn_ack_manager & dyn_ack_manager, - front_end_params const & params, + smt_params const & params, literal_vector const & assigned_literals, vector & watches ): @@ -304,13 +304,13 @@ namespace smt { if (th) th->conflict_resolution_eh(to_app(n), var); } -#ifndef SMTCOMP - if (m_params.m_trace_stream != NULL) { - *m_params.m_trace_stream << "[resolve-lit] " << m_conflict_lvl - lvl << " "; - m_ctx.display_literal(*m_params.m_trace_stream, ~antecedent); - *m_params.m_trace_stream << "\n"; + + if (get_manager().has_trace_stream()) { + get_manager().trace_stream() << "[resolve-lit] " << m_conflict_lvl - lvl << " "; + m_ctx.display_literal(get_manager().trace_stream(), ~antecedent); + get_manager().trace_stream() << "\n"; } -#endif + if (lvl == m_conflict_lvl) { num_marks++; } @@ -478,13 +478,12 @@ namespace smt { } do { -#ifndef SMTCOMP - if (m_params.m_trace_stream != NULL) { - *m_params.m_trace_stream << "[resolve-process] "; - m_ctx.display_literal(*m_params.m_trace_stream, ~consequent); - *m_params.m_trace_stream << "\n"; + + if (get_manager().has_trace_stream()) { + get_manager().trace_stream() << "[resolve-process] "; + m_ctx.display_literal(get_manager().trace_stream(), ~consequent); + get_manager().trace_stream() << "\n"; } -#endif TRACE("conflict", tout << "processing consequent: "; m_ctx.display_literal(tout, consequent); tout << "\n"; tout << "num_marks: " << num_marks << ", js kind: " << js.get_kind() << "\n";); @@ -1420,7 +1419,7 @@ namespace smt { conflict_resolution * mk_conflict_resolution(ast_manager & m, context & ctx, dyn_ack_manager & dack_manager, - front_end_params const & params, + smt_params const & params, literal_vector const & assigned_literals, vector & watches) { return alloc(conflict_resolution, m, ctx, dack_manager, params, assigned_literals, watches); diff --git a/src/smt/smt_conflict_resolution.h b/src/smt/smt_conflict_resolution.h index 5287b4e26..a55b331dc 100644 --- a/src/smt/smt_conflict_resolution.h +++ b/src/smt/smt_conflict_resolution.h @@ -25,7 +25,7 @@ Revision History: #include"smt_enode.h" #include"dyn_ack.h" #include"obj_pair_hashtable.h" -#include"front_end_params.h" +#include"smt_params.h" #include"obj_pair_hashtable.h" #include"map.h" #include"watch_list.h" @@ -46,7 +46,7 @@ namespace smt { typedef obj_pair_set enode_pair_set; ast_manager & m_manager; - front_end_params const & m_params; + smt_params const & m_params; context & m_ctx; dyn_ack_manager & m_dyn_ack_manager; literal_vector const & m_assigned_literals; @@ -204,7 +204,7 @@ namespace smt { conflict_resolution(ast_manager & m, context & ctx, dyn_ack_manager & dack_manager, - front_end_params const & params, + smt_params const & params, literal_vector const & assigned_literals, vector & watches ); @@ -266,7 +266,7 @@ namespace smt { conflict_resolution * mk_conflict_resolution(ast_manager & m, context & ctx, dyn_ack_manager & dack_manager, - front_end_params const & params, + smt_params const & params, literal_vector const & assigned_literals, vector & watches ); diff --git a/src/smt/smt_context.cpp b/src/smt/smt_context.cpp index 9ab21ccc5..a7623832f 100644 --- a/src/smt/smt_context.cpp +++ b/src/smt/smt_context.cpp @@ -39,7 +39,7 @@ Revision History: namespace smt { - context::context(ast_manager & m, front_end_params & p, params_ref const & _p): + context::context(ast_manager & m, smt_params & p, params_ref const & _p): m_manager(m), m_fparams(p), m_params(_p), @@ -102,7 +102,7 @@ namespace smt { flush(); } - context * context::mk_fresh(symbol const * l, front_end_params * p) { + context * context::mk_fresh(symbol const * l, smt_params * p) { context * new_ctx = alloc(context, m_manager, p == 0 ? m_fparams : *p); new_ctx->set_logic(l == 0 ? m_setup.get_logic() : *l); // copy missing simplifier_plugins @@ -190,11 +190,10 @@ namespace smt { TRACE("phase_selection", tout << "saving phase, is_pos: " << d.m_phase << " l: " << l << "\n";); if (d.is_atom() && (m_fparams.m_relevancy_lvl == 0 || (m_fparams.m_relevancy_lvl == 1 && !d.is_quantifier()) || is_relevant_core(bool_var2expr(l.var())))) m_atom_propagation_queue.push_back(l); -#ifndef SMTCOMP - if (m_fparams.m_trace_stream != NULL) + + if (m_manager.has_trace_stream()) trace_assign(l, j, decision); m_case_split_queue->assign_lit_eh(l); -#endif } bool context::bcp() { @@ -1789,10 +1788,10 @@ namespace smt { \brief Create an internal backtracking point */ void context::push_scope() { -#ifndef SMTCOMP - if (m_fparams.m_trace_stream != NULL) - *m_fparams.m_trace_stream << "[push] " << m_scope_lvl << "\n"; -#endif + + if (m_manager.has_trace_stream()) + m_manager.trace_stream() << "[push] " << m_scope_lvl << "\n"; + m_scope_lvl++; m_region.push_scope(); m_scopes.push_back(scope()); @@ -2237,10 +2236,10 @@ namespace smt { \warning This method will not invoke reset_cache_generation. */ unsigned context::pop_scope_core(unsigned num_scopes) { -#ifndef SMTCOMP - if (m_fparams.m_trace_stream != NULL) - *m_fparams.m_trace_stream << "[pop] " << num_scopes << " " << m_scope_lvl << "\n"; -#endif + + if (m_manager.has_trace_stream()) + m_manager.trace_stream() << "[pop] " << num_scopes << " " << m_scope_lvl << "\n"; + TRACE("context", tout << "backtracking: " << num_scopes << "\n";); TRACE("pop_scope_detail", display(tout);); SASSERT(num_scopes > 0); @@ -2488,7 +2487,7 @@ namespace smt { SASSERT(check_clauses(m_lemmas)); SASSERT(check_clauses(m_aux_clauses)); - IF_VERBOSE(2, verbose_stream() << "simplifying clause set... "; verbose_stream().flush();); + IF_VERBOSE(2, verbose_stream() << "(smt.simplifying-clause-set"; verbose_stream().flush();); // m_simp_counter is used to balance the cost of simplify_clause. // @@ -2503,8 +2502,7 @@ namespace smt { // the field m_simp_qhead is used to check whether there are // new assigned literals at the base level. m_simp_qhead = m_assigned_literals.size(); - - unsigned num_clauses = m_aux_clauses.size() + m_lemmas.size(); + unsigned num_del_clauses = 0; SASSERT(m_scope_lvl == m_base_lvl); @@ -2519,7 +2517,7 @@ namespace smt { num_del_clauses += simplify_clauses(m_lemmas, bs.m_lemmas_lim); } TRACE("simp_counter", tout << "simp_counter: " << m_simp_counter << " scope_lvl: " << m_scope_lvl << "\n";); - IF_VERBOSE(2, verbose_stream() << "num. deleted clauses: " << num_del_clauses << " (out of " << num_clauses << ")" << std::endl;); + IF_VERBOSE(2, verbose_stream() << " :num-deleted-clauses " << num_del_clauses << ")" << std::endl;); TRACE("simplify_clauses_detail", tout << "after:\n"; display_clauses(tout, m_lemmas);); SASSERT(check_clauses(m_lemmas) && check_clauses(m_aux_clauses)); } @@ -2551,7 +2549,7 @@ namespace smt { SASSERT(start_at <= sz); if (start_at + m_fparams.m_recent_lemmas_size >= sz) return; - IF_VERBOSE(2, verbose_stream() << "deleting inactive lemmas... "; verbose_stream().flush();); + IF_VERBOSE(2, verbose_stream() << "(smt.delete-inactive-lemmas"; verbose_stream().flush();); SASSERT (m_fparams.m_recent_lemmas_size < sz); unsigned end_at = sz - m_fparams.m_recent_lemmas_size; SASSERT(start_at < end_at); @@ -2595,7 +2593,7 @@ namespace smt { cls->set_activity(cls->get_activity() / m_fparams.m_clause_decay); } } - IF_VERBOSE(2, verbose_stream() << "num. deleted clauses: " << num_del_cls << " (out of " << sz << ")" << std::endl;); + IF_VERBOSE(2, verbose_stream() << " :num-deleted-clauses " << num_del_cls << ")" << std::endl;); } /** @@ -2606,7 +2604,7 @@ namespace smt { depends on which group the clauses is in. */ void context::del_inactive_lemmas2() { - IF_VERBOSE(2, verbose_stream() << "deleting inactive clauses... "; verbose_stream().flush();); + IF_VERBOSE(2, verbose_stream() << "(smt.delete-inactive-clauses "; verbose_stream().flush();); unsigned sz = m_lemmas.size(); unsigned start_at = m_base_lvl == 0 ? 0 : m_base_scopes[m_base_lvl - 1].m_lemmas_lim; SASSERT(start_at <= sz); @@ -2645,7 +2643,7 @@ namespace smt { } SASSERT(j <= sz); m_lemmas.shrink(j); - IF_VERBOSE(2, verbose_stream() << "num. deleted clauses: " << num_del_cls << " (out of " << sz << ")" << std::endl;); + IF_VERBOSE(2, verbose_stream() << " :num-deleted-clauses " << num_del_cls << ")" << std::endl;); } /** @@ -2786,7 +2784,7 @@ namespace smt { } void context::assert_expr(expr * e, proof * pr) { - timeit tt(get_verbosity_level() >= 100, "simplifying"); + timeit tt(get_verbosity_level() >= 100, "smt.simplifying"); assert_expr_core(e, pr); } @@ -2800,7 +2798,7 @@ namespace smt { void context::internalize_assertions() { TRACE("internalize_assertions", tout << "internalize_assertions()...\n";); - timeit tt(get_verbosity_level() >= 100, "preprocessing"); + timeit tt(get_verbosity_level() >= 100, "smt.preprocessing"); reduce_assertions(); if (!m_asserted_formulas.inconsistent()) { unsigned sz = m_asserted_formulas.get_num_formulas(); @@ -2928,10 +2926,8 @@ namespace smt { Return true if succeeded. */ bool context::check_preamble(bool reset_cancel) { -#ifndef SMTCOMP - if (m_fparams.m_trace_stream != NULL) - *m_fparams.m_trace_stream << "[begin-check] " << m_scope_lvl << "\n"; -#endif + if (m_manager.has_trace_stream()) + m_manager.trace_stream() << "[begin-check] " << m_scope_lvl << "\n"; if (reset_cancel) { m_cancel_flag = false; @@ -3103,7 +3099,6 @@ namespace smt { m_next_progress_sample = 0; TRACE("literal_occ", display_literal_num_occs(tout);); m_timer.start(); - m_instr.start(); } void context::end_search() { @@ -3159,7 +3154,7 @@ namespace smt { exit(1); } #endif - timeit tt(get_verbosity_level() >= 100, "searching"); + timeit tt(get_verbosity_level() >= 100, "smt.stats"); scoped_mk_model smk(*this); SASSERT(at_search_level()); TRACE("search", display(tout); display_enodes_lbls(tout);); @@ -3167,7 +3162,7 @@ namespace smt { init_search(); flet l(m_searching, true); TRACE("after_init_search", display(tout);); - IF_VERBOSE(2, verbose_stream() << "searching...\n";); + IF_VERBOSE(2, verbose_stream() << "(smt.searching)\n";); TRACE("search_lite", tout << "searching...\n";); lbool status = l_undef; unsigned curr_lvl = m_scope_lvl; @@ -3216,16 +3211,16 @@ namespace smt { inc_limits(); if (force_restart || !m_fparams.m_restart_adaptive || m_agility < m_fparams.m_restart_agility_threshold) { SASSERT(!inconsistent()); - IF_VERBOSE(1, verbose_stream() << "restarting... propagations: " << m_stats.m_num_propagations - << ", decisions: " << m_stats.m_num_decisions - << ", conflicts: " << m_stats.m_num_conflicts << ", restart: " << m_restart_threshold; + IF_VERBOSE(1, verbose_stream() << "(smt.restarting :propagations " << m_stats.m_num_propagations + << " :decisions " << m_stats.m_num_decisions + << " :conflicts " << m_stats.m_num_conflicts << " :restart " << m_restart_threshold; if (m_fparams.m_restart_strategy == RS_IN_OUT_GEOMETRIC) { - verbose_stream() << ", restart-outer: " << m_restart_outer_threshold; + verbose_stream() << " :restart-outer " << m_restart_outer_threshold; } if (m_fparams.m_restart_adaptive) { - verbose_stream() << ", agility: " << m_agility; + verbose_stream() << " :agility " << m_agility; } - verbose_stream() << std::endl; verbose_stream().flush();); + verbose_stream() << ")" << std::endl; verbose_stream().flush();); // execute the restart m_stats.m_num_restarts++; if (m_scope_lvl > curr_lvl) { @@ -3260,12 +3255,12 @@ namespace smt { void context::tick(unsigned & counter) const { counter++; if (counter > m_fparams.m_tick) { - IF_VERBOSE(3, verbose_stream() << "working..."; - verbose_stream() << " num. conflicts: " << m_num_conflicts; + IF_VERBOSE(3, verbose_stream() << "(smt.working"; + verbose_stream() << " :conflicts " << m_num_conflicts; // verbose_stream() << " lemma avg. activity: " << get_lemma_avg_activity(); if (m_fparams.m_restart_adaptive) - verbose_stream() << " agility: " << m_agility; - verbose_stream() << std::endl; verbose_stream().flush();); + verbose_stream() << " :agility " << m_agility; + verbose_stream() << ")" << std::endl; verbose_stream().flush();); TRACE("assigned_literals_per_lvl", display_num_assigned_literals_per_lvl(tout); tout << "\n";); counter = 0; } @@ -3359,11 +3354,6 @@ namespace smt { return true; } - if (m_instr.is_instruction_maxed(m_fparams.m_instr_out)) { - m_last_search_failure = TIMEOUT; - return true; - } - if (m_progress_callback) { m_progress_callback->fast_progress_sample(); if (m_fparams.m_progress_sampling_freq > 0 && m_timer.ms_timeout(m_next_progress_sample + 1)) { @@ -3416,7 +3406,7 @@ namespace smt { final_check_status ok; if (m_final_check_idx < num_th) { theory * th = m_theory_set[m_final_check_idx]; - IF_VERBOSE(100, verbose_stream() << "final check '" << th->get_name() << "' ...\n";); + IF_VERBOSE(100, verbose_stream() << "(smt.final-check \"" << th->get_name() << "\")\n";); ok = th->final_check_eh(); TRACE("final_check_step", tout << "final check '" << th->get_name() << " ok: " << ok << " inconsistent " << inconsistent() << "\n";); if (ok == FC_GIVEUP) { @@ -3541,13 +3531,13 @@ namespace smt { tout << ", ilvl: " << get_intern_level(l.var()) << "\n" << mk_pp(bool_var2expr(l.var()), m_manager) << "\n"; }); -#ifndef SMTCOMP - if (m_fparams.m_trace_stream != NULL) { - *m_fparams.m_trace_stream << "[conflict] "; - display_literals(*m_fparams.m_trace_stream, num_lits, lits); - *m_fparams.m_trace_stream << "\n"; + + if (m_manager.has_trace_stream()) { + m_manager.trace_stream() << "[conflict] "; + display_literals(m_manager.trace_stream(), num_lits, lits); + m_manager.trace_stream() << "\n"; } -#endif + #ifdef Z3DEBUG expr_ref_vector expr_lits(m_manager); svector expr_signs; diff --git a/src/smt/smt_context.h b/src/smt/smt_context.h index b44d42fc8..7940b17be 100644 --- a/src/smt/smt_context.h +++ b/src/smt/smt_context.h @@ -47,7 +47,6 @@ Revision History: #include"proto_model.h" #include"model.h" #include"timer.h" -#include"instruction_count.h" #include"statistics.h" #include"progress_callback.h" @@ -72,12 +71,11 @@ namespace smt { protected: ast_manager & m_manager; - front_end_params & m_fparams; + smt_params & m_fparams; params_ref m_params; setup m_setup; volatile bool m_cancel_flag; timer m_timer; - instruction_count m_instr; asserted_formulas m_asserted_formulas; scoped_ptr m_qmanager; scoped_ptr m_model_generator; @@ -222,7 +220,7 @@ namespace smt { return m_asserted_formulas.get_simplifier(); } - front_end_params & get_fparams() { + smt_params & get_fparams() { return m_fparams; } @@ -654,10 +652,6 @@ namespace smt { protected: unsigned m_generation; //!< temporary variable used during internalization - bool expand_pos_def_only() const { - return m_fparams.m_nnf_mode == NNF_FULL && m_fparams.m_internalizer_nnf; - } - public: bool binary_clause_opt_enabled() const { return !m_manager.proofs_enabled() && m_fparams.m_binary_clause_opt; @@ -1320,7 +1314,7 @@ namespace smt { void assert_expr_core(expr * e, proof * pr); public: - context(ast_manager & m, front_end_params & fp, params_ref const & p = params_ref()); + context(ast_manager & m, smt_params & fp, params_ref const & p = params_ref()); virtual ~context(); @@ -1331,7 +1325,7 @@ namespace smt { If l == 0, then the logic of this context is used in the new context. If p == 0, then this->m_params is used */ - context * mk_fresh(symbol const * l = 0, front_end_params * p = 0); + context * mk_fresh(symbol const * l = 0, smt_params * p = 0); app * mk_eq_atom(expr * lhs, expr * rhs); diff --git a/src/smt/smt_context_pp.cpp b/src/smt/smt_context_pp.cpp index 4bc5dfd74..9ce684440 100644 --- a/src/smt/smt_context_pp.cpp +++ b/src/smt/smt_context_pp.cpp @@ -583,7 +583,8 @@ namespace smt { } void context::trace_assign(literal l, b_justification j, bool decision) const { - std::ostream & out = *m_fparams.m_trace_stream; + SASSERT(m_manager.has_trace_stream()); + std::ostream & out = m_manager.trace_stream(); out << "[assign] "; display_literal(out, l); if (decision) diff --git a/src/smt/smt_implied_equalities.cpp b/src/smt/smt_implied_equalities.cpp index ef8d27e2f..c6f28d4b2 100644 --- a/src/smt/smt_implied_equalities.cpp +++ b/src/smt/smt_implied_equalities.cpp @@ -29,6 +29,7 @@ Revision History: #include "array_decl_plugin.h" #include "uint_set.h" #include "model_v2_pp.h" +#include "smt_value_sort.h" namespace smt { @@ -134,44 +135,7 @@ namespace smt { } } } - } - - bool is_simple_type(sort* s) { - arith_util arith(m); - datatype_util data(m); - - ptr_vector sorts; - ast_mark mark; - sorts.push_back(s); - - while (!sorts.empty()) { - s = sorts.back(); - sorts.pop_back(); - if (mark.is_marked(s)) { - continue; - } - mark.mark(s, true); - if (arith.is_int_real(s)) { - // simple - } - else if (m.is_bool(s)) { - // simple - } - else if (data.is_datatype(s)) { - ptr_vector const& cs = *data.get_datatype_constructors(s); - for (unsigned i = 0; i < cs.size(); ++i) { - func_decl* f = cs[i]; - for (unsigned j = 0; j < f->get_arity(); ++j) { - sorts.push_back(f->get_domain(j)); - } - } - } - else { - return false; - } - } - return true; - } + } /** \brief Extract implied equalities for a collection of terms in the current context. @@ -216,7 +180,7 @@ namespace smt { uint_set non_values; - if (!is_simple_type(srt)) { + if (!is_value_sort(m, srt)) { for (unsigned i = 0; i < terms.size(); ++i) { non_values.insert(i); } @@ -233,7 +197,7 @@ namespace smt { s_stats_val_eq_timer.start(); params_ref p; - p.set_bool(":produce-models", false); + p.set_bool("produce_models", false); m_solver.updt_params(p); for (unsigned i = 0; i < terms.size(); ++i) { @@ -268,7 +232,7 @@ namespace smt { } m_stats_val_eq_timer.stop(); s_stats_val_eq_timer.stop(); - p.set_bool(":produce-models", true); + p.set_bool("produce_models", true); m_solver.updt_params(p); @@ -361,7 +325,7 @@ namespace smt { lbool operator()(unsigned num_terms, expr* const* terms, unsigned* class_ids) { params_ref p; - p.set_bool(":produce-models", true); + p.set_bool("produce_models", true); m_solver.updt_params(p); sort2term_ids termids; stopwatch timer; diff --git a/src/smt/smt_internalizer.cpp b/src/smt/smt_internalizer.cpp index 86b1641bc..556222c33 100644 --- a/src/smt/smt_internalizer.cpp +++ b/src/smt/smt_internalizer.cpp @@ -952,10 +952,10 @@ namespace smt { tout << "is_true_eq: " << e->is_true_eq() << " in cg_table: " << m_cg_table.contains_ptr(e) << " is_cgr: " << e->is_cgr() << "\n"; }); -#ifndef SMTCOMP - if (m_fparams.m_trace_stream != NULL) - *m_fparams.m_trace_stream << "[attach-enode] #" << n->get_id() << " " << m_generation << "\n"; -#endif + + if (m_manager.has_trace_stream()) + m_manager.trace_stream() << "[attach-enode] #" << n->get_id() << " " << m_generation << "\n"; + return e; } @@ -1566,9 +1566,7 @@ namespace smt { mk_gate_clause(~l, l_arg); buffer.push_back(~l_arg); } - if (!expand_pos_def_only()) { - mk_gate_clause(buffer.size(), buffer.c_ptr()); - } + mk_gate_clause(buffer.size(), buffer.c_ptr()); } void context::mk_or_cnstr(app * n) { @@ -1578,8 +1576,7 @@ namespace smt { unsigned num_args = n->get_num_args(); for (unsigned i = 0; i < num_args; i++) { literal l_arg = get_literal(n->get_arg(i)); - if (!expand_pos_def_only()) - mk_gate_clause(l, ~l_arg); + mk_gate_clause(l, ~l_arg); buffer.push_back(l_arg); } mk_gate_clause(buffer.size(), buffer.c_ptr()); diff --git a/src/smt/smt_kernel.cpp b/src/smt/smt_kernel.cpp index 9d87b1363..779c68625 100644 --- a/src/smt/smt_kernel.cpp +++ b/src/smt/smt_kernel.cpp @@ -19,7 +19,7 @@ Revision History: #include"smt_kernel.h" #include"smt_context.h" #include"ast_smt2_pp.h" -#include"params2front_end_params.h" +#include"smt_params_helper.hpp" namespace smt { @@ -27,12 +27,12 @@ namespace smt { smt::context m_kernel; params_ref m_params; - imp(ast_manager & m, front_end_params & fp, params_ref const & p): + imp(ast_manager & m, smt_params & fp, params_ref const & p): m_kernel(m, fp, p), m_params(p) { } - front_end_params & fparams() { + smt_params & fparams() { return m_kernel.get_fparams(); } @@ -179,11 +179,13 @@ namespace smt { } void updt_params(params_ref const & p) { - params2front_end_params(p, fparams()); + // We don't need params2smt_params anymore. smt_params has support for reading params_ref. + // The update is performed at smt_kernel "users". + // params2smt_params(p, fparams()); } }; - kernel::kernel(ast_manager & m, front_end_params & fp, params_ref const & p) { + kernel::kernel(ast_manager & m, smt_params & fp, params_ref const & p) { m_imp = alloc(imp, m, fp, p); } @@ -237,7 +239,7 @@ namespace smt { void kernel::reset() { ast_manager & _m = m(); - front_end_params & fps = m_imp->fparams(); + smt_params & fps = m_imp->fparams(); params_ref ps = m_imp->params(); #pragma omp critical (smt_kernel) { @@ -343,7 +345,7 @@ namespace smt { } void kernel::collect_param_descrs(param_descrs & d) { - solver_front_end_params_descrs(d); + smt_params_helper::collect_param_descrs(d); } context & kernel::get_context() { diff --git a/src/smt/smt_kernel.h b/src/smt/smt_kernel.h index 4c381e113..37b044af1 100644 --- a/src/smt/smt_kernel.h +++ b/src/smt/smt_kernel.h @@ -34,7 +34,7 @@ Revision History: #include"statistics.h" #include"smt_failure.h" -struct front_end_params; +struct smt_params; class progress_callback; namespace smt { @@ -46,7 +46,7 @@ namespace smt { struct imp; imp * m_imp; public: - kernel(ast_manager & m, front_end_params & fp, params_ref const & p = params_ref()); + kernel(ast_manager & m, smt_params & fp, params_ref const & p = params_ref()); ~kernel(); diff --git a/src/smt/smt_model_checker.cpp b/src/smt/smt_model_checker.cpp index 58921bb35..53f3af961 100644 --- a/src/smt/smt_model_checker.cpp +++ b/src/smt/smt_model_checker.cpp @@ -281,7 +281,7 @@ namespace smt { void model_checker::init_aux_context() { if (!m_fparams) { - m_fparams = alloc(front_end_params, m_context->get_fparams()); + m_fparams = alloc(smt_params, m_context->get_fparams()); m_fparams->m_relevancy_lvl = 0; // no relevancy since the model checking problems are quantifier free } if (!m_aux_context) { @@ -312,7 +312,7 @@ namespace smt { TRACE("model_checker", tout << "MODEL_CHECKER INVOKED\n"; tout << "model:\n"; model_pp(tout, *m_curr_model);); if (m_params.m_mbqi_trace) { - verbose_stream() << "[mbqi] started\n"; + verbose_stream() << "(smt.mbqi \"started\")\n"; } init_aux_context(); @@ -324,13 +324,12 @@ namespace smt { quantifier * q = *it; if (m_context->is_relevant(q) && m_context->get_assignment(q) == l_true) { if (m_params.m_mbqi_trace && q->get_qid() != symbol::null) { - verbose_stream() << "[mbqi] checking: " << q->get_qid() << "\n"; + verbose_stream() << "(smt.mbqi :checking " << q->get_qid() << ")\n"; } found_relevant = true; if (!check(q)) { - IF_VERBOSE(5, verbose_stream() << "current model does not satisfy: " << q->get_qid() << "\n";); - if (m_params.m_mbqi_trace) { - verbose_stream() << "[mbqi] failed " << q->get_qid() << "\n"; + if (m_params.m_mbqi_trace || get_verbosity_level() >= 5) { + verbose_stream() << "(smt.mbqi :failed " << q->get_qid() << ")\n"; } num_failures++; } @@ -347,9 +346,9 @@ namespace smt { m_curr_model->cleanup(); if (m_params.m_mbqi_trace) { if (num_failures == 0) - verbose_stream() << "[mbqi] succeeded\n"; + verbose_stream() << "(smt.mbqi :succeeded true)\n"; else - verbose_stream() << "[mbqi] num failures " << num_failures << "\n"; + verbose_stream() << "(smt.mbqi :num-failures " << num_failures << ")\n"; } return num_failures == 0; } @@ -360,7 +359,7 @@ namespace smt { } void model_checker::restart_eh() { - IF_VERBOSE(100, verbose_stream() << "instantiating new instances...\n";); + IF_VERBOSE(100, verbose_stream() << "(smt.mbqi \"instantiating new instances...\")\n";); assert_new_instances(); reset_new_instances(); } diff --git a/src/smt/smt_model_checker.h b/src/smt/smt_model_checker.h index fca576090..5af7859ce 100644 --- a/src/smt/smt_model_checker.h +++ b/src/smt/smt_model_checker.h @@ -24,7 +24,7 @@ Revision History: #include"ast.h" #include"obj_hashtable.h" #include"qi_params.h" -#include"front_end_params.h" +#include"smt_params.h" #include"region.h" class proto_model; @@ -39,9 +39,9 @@ namespace smt { class model_checker { ast_manager & m_manager; qi_params const & m_params; - // copy of front_end_params for auxiliary context. + // copy of smt_params for auxiliary context. // the idea is to use a different configuration for the aux context (e.g., disable relevancy) - scoped_ptr m_fparams; + scoped_ptr m_fparams; quantifier_manager * m_qm; context * m_context; // owner of the model checker obj_map const * m_root2value; // temp field to store mapping received in the check method. diff --git a/src/smt/smt_model_generator.cpp b/src/smt/smt_model_generator.cpp index 1c441ad11..cf22c3e3a 100644 --- a/src/smt/smt_model_generator.cpp +++ b/src/smt/smt_model_generator.cpp @@ -48,7 +48,8 @@ namespace smt { void model_generator::init_model() { SASSERT(!m_model); - m_model = alloc(proto_model, m_manager, m_context->get_simplifier(), m_context->get_fparams()); + // PARAM-TODO smt_params ---> params_ref + m_model = alloc(proto_model, m_manager, m_context->get_simplifier()); // , m_context->get_fparams()); ptr_vector::const_iterator it = m_context->begin_theories(); ptr_vector::const_iterator end = m_context->end_theories(); for (; it != end; ++it) { diff --git a/src/smt/smt_quantifier.cpp b/src/smt/smt_quantifier.cpp index c11f226ed..d56fe0cff 100644 --- a/src/smt/smt_quantifier.cpp +++ b/src/smt/smt_quantifier.cpp @@ -33,7 +33,7 @@ namespace smt { struct quantifier_manager::imp { quantifier_manager & m_wrapper; context & m_context; - front_end_params & m_params; + smt_params & m_params; qi_queue m_qi_queue; obj_map m_quantifier_stat; quantifier_stat_gen m_qstat_gen; @@ -41,17 +41,20 @@ namespace smt { scoped_ptr m_plugin; unsigned m_num_instances; - imp(quantifier_manager & wrapper, context & ctx, front_end_params & p, quantifier_manager_plugin * plugin): + imp(quantifier_manager & wrapper, context & ctx, smt_params & p, quantifier_manager_plugin * plugin): m_wrapper(wrapper), m_context(ctx), m_params(p), - m_qi_queue(m_wrapper, ctx, p, p.m_trace_stream), + m_qi_queue(m_wrapper, ctx, p), m_qstat_gen(ctx.get_manager(), ctx.get_region()), m_plugin(plugin) { m_num_instances = 0; m_qi_queue.setup(); } + bool has_trace_stream() const { return m_context.get_manager().has_trace_stream(); } + std::ostream & trace_stream() { return m_context.get_manager().trace_stream(); } + quantifier_stat * get_stat(quantifier * q) const { return m_quantifier_stat.find(q); } @@ -112,8 +115,8 @@ namespace smt { get_stat(q)->update_max_generation(max_generation); fingerprint * f = m_context.add_fingerprint(q, q->get_id(), num_bindings, bindings); if (f) { - if (m_params.m_trace_stream != NULL) { - std::ostream & out = *m_params.m_trace_stream; + if (has_trace_stream()) { + std::ostream & out = trace_stream(); out << "[new-match] " << static_cast(f) << " #" << q->get_id(); for (unsigned i = 0; i < num_bindings; i++) { // I don't want to use mk_pp because it creates expressions for pretty printing. @@ -211,7 +214,7 @@ namespace smt { final_check_status final_check_eh(bool full) { if (full) { - IF_VERBOSE(100, verbose_stream() << "final check 'quantifiers'...\n";); + IF_VERBOSE(100, verbose_stream() << "(smt.final-check \"quantifiers\")\n";); final_check_status result = m_qi_queue.final_check_eh() ? FC_DONE : FC_CONTINUE; final_check_status presult = m_plugin->final_check_eh(full); if (presult != FC_DONE) @@ -239,7 +242,7 @@ namespace smt { }; - quantifier_manager::quantifier_manager(context & ctx, front_end_params & fp, params_ref const & p) { + quantifier_manager::quantifier_manager(context & ctx, smt_params & fp, params_ref const & p) { m_imp = alloc(imp, *this, ctx, fp, mk_default_plugin()); m_imp->m_plugin->set_manager(*this); } @@ -352,7 +355,7 @@ namespace smt { #pragma omp critical (quantifier_manager) { context & ctx = m_imp->m_context; - front_end_params & p = m_imp->m_params; + smt_params & p = m_imp->m_params; quantifier_manager_plugin * plugin = m_imp->m_plugin->mk_fresh(); dealloc(m_imp); m_imp = alloc(imp, *this, ctx, p, plugin); @@ -392,7 +395,7 @@ namespace smt { // The default plugin uses E-matching, MBQI and quick-checker class default_qm_plugin : public quantifier_manager_plugin { quantifier_manager * m_qm; - front_end_params * m_fparams; + smt_params * m_fparams; context * m_context; scoped_ptr m_mam; scoped_ptr m_lazy_mam; @@ -418,8 +421,8 @@ namespace smt { m_fparams = &(m_context->get_fparams()); ast_manager & m = m_context->get_manager(); - m_mam = mk_mam(*m_context, m_fparams->m_trace_stream); - m_lazy_mam = mk_mam(*m_context, m_fparams->m_trace_stream); + m_mam = mk_mam(*m_context); + m_lazy_mam = mk_mam(*m_context); m_model_finder = alloc(model_finder, m, m_context->get_simplifier()); m_model_checker = alloc(model_checker, m, *m_fparams, *(m_model_finder.get())); @@ -559,7 +562,7 @@ namespace smt { virtual quantifier_manager::check_model_result check_model(proto_model * m, obj_map const & root2value) { if (m_fparams->m_mbqi) { - IF_VERBOSE(10, verbose_stream() << "model based quantifier instantiation...\n";); + IF_VERBOSE(10, verbose_stream() << "(smt.mbqi)\n";); if (m_model_checker->check(m, root2value)) { return quantifier_manager::SAT; } @@ -591,7 +594,6 @@ namespace smt { final_check_status final_check_quant() { if (use_ematching()) { if (m_lazy_matching_idx < m_fparams->m_qi_max_lazy_multipattern_matching) { - IF_VERBOSE(100, verbose_stream() << "matching delayed multi-patterns... \n";); m_lazy_mam->rematch(); m_context->push_trail(value_trail(m_lazy_matching_idx)); m_lazy_matching_idx++; diff --git a/src/smt/smt_quantifier.h b/src/smt/smt_quantifier.h index 3873c9737..19113229c 100644 --- a/src/smt/smt_quantifier.h +++ b/src/smt/smt_quantifier.h @@ -25,7 +25,7 @@ Revision History: #include"smt_types.h" class proto_model; -struct front_end_params; +struct smt_params; namespace smt { class quantifier_manager_plugin; @@ -35,7 +35,7 @@ namespace smt { struct imp; imp * m_imp; public: - quantifier_manager(context & ctx, front_end_params & fp, params_ref const & p); + quantifier_manager(context & ctx, smt_params & fp, params_ref const & p); ~quantifier_manager(); context & get_context() const; diff --git a/src/smt/smt_setup.cpp b/src/smt/smt_setup.cpp index bd9196056..ac31eb1a9 100644 --- a/src/smt/smt_setup.cpp +++ b/src/smt/smt_setup.cpp @@ -33,7 +33,7 @@ Revision History: namespace smt { - setup::setup(context & c, front_end_params & params): + setup::setup(context & c, smt_params & params): m_context(c), m_manager(c.get_manager()), m_params(params), @@ -55,7 +55,6 @@ namespace smt { case CFG_LOGIC: setup_default(); break; case CFG_AUTO: setup_auto_config(); break; } - TRACE("setup", ini_params p; m_params.register_params(p); p.display_params(tout);); } void setup::setup_default() { @@ -119,7 +118,7 @@ namespace smt { void setup::setup_auto_config() { static_features st(m_manager); - IF_VERBOSE(100, verbose_stream() << "configuring...\n";); + IF_VERBOSE(100, verbose_stream() << "(smt.configuring)\n";); TRACE("setup", tout << "setup, logic: " << m_logic << "\n";); // HACK: do not collect features for QF_BV and QF_AUFBV... since they do not use them... if (m_logic == "QF_BV") { @@ -129,7 +128,7 @@ namespace smt { setup_QF_AUFBV(); } else { - IF_VERBOSE(100, verbose_stream() << "collecting features...\n";); + IF_VERBOSE(100, verbose_stream() << "(smt.collecting-features)\n";); st.collect(m_context.get_num_asserted_formulas(), m_context.get_asserted_formulas()); IF_VERBOSE(1000, st.display_primitive(verbose_stream());); if (m_logic == "QF_UF") @@ -267,8 +266,8 @@ namespace smt { // Moreover, if model construction is enabled, then rational numbers may be needed // to compute the actual value of epsilon even if the input does not have rational numbers. // Example: (x < 1) and (x > 0) - if (m_params.m_proof_mode != PGM_DISABLED) { - m_context.register_plugin(alloc(smt::theory_mi_arith_w_proofs, m_manager, m_params)); + if (m_manager.proofs_enabled()) { + m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params)); } else if (!m_params.m_arith_auto_config_simplex && is_dense(st)) { if (!st.m_has_rational && !m_params.m_model && st.m_arith_k_sum < rational(INT_MAX / 8)) @@ -344,8 +343,8 @@ namespace smt { tout << "RELEVANCY: " << m_params.m_relevancy_lvl << "\n"; tout << "ARITH_EQ_BOUNDS: " << m_params.m_arith_eq_bounds << "\n";); - if (m_params.m_proof_mode != PGM_DISABLED) { - m_context.register_plugin(alloc(smt::theory_mi_arith_w_proofs, m_manager, m_params)); + if (m_manager.proofs_enabled()) { + m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params)); } else if (!m_params.m_arith_auto_config_simplex && is_dense(st)) { TRACE("setup", tout << "using dense diff logic...\n";); @@ -395,8 +394,8 @@ namespace smt { m_params.m_lemma_gc_half = true; m_params.m_restart_strategy = RS_GEOMETRIC; - if (m_params.m_proof_mode != PGM_DISABLED) { - m_context.register_plugin(alloc(smt::theory_mi_arith_w_proofs, m_manager, m_params)); + if (m_manager.proofs_enabled()) { + m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params)); } else if (st.m_arith_k_sum < rational(INT_MAX / 8)) m_context.register_plugin(alloc(smt::theory_dense_si, m_manager, m_params)); @@ -410,8 +409,8 @@ namespace smt { m_params.m_restart_strategy = RS_GEOMETRIC; m_params.m_restart_factor = 1.5; m_params.m_restart_adaptive = false; - if (m_params.m_proof_mode != PGM_DISABLED) { - m_context.register_plugin(alloc(smt::theory_mi_arith_w_proofs, m_manager, m_params)); + if (m_manager.proofs_enabled()) { + m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params)); } // else if (st.m_arith_k_sum < rational(INT_MAX / 8)) // m_context.register_plugin(alloc(smt::theory_si_arith, m_manager, m_params)); @@ -684,21 +683,11 @@ namespace smt { } void setup::setup_i_arith() { - if (m_params.m_proof_mode != PGM_DISABLED) { - m_context.register_plugin(alloc(smt::theory_mi_arith_w_proofs, m_manager, m_params)); - } - else { - m_context.register_plugin(alloc(smt::theory_i_arith, m_manager, m_params)); - } + m_context.register_plugin(alloc(smt::theory_i_arith, m_manager, m_params)); } void setup::setup_mi_arith() { - if (m_params.m_proof_mode != PGM_DISABLED) { - m_context.register_plugin(alloc(smt::theory_mi_arith_w_proofs, m_manager, m_params)); - } - else { - m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params)); - } + m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params)); } void setup::setup_arith() { @@ -735,21 +724,10 @@ namespace smt { } break; default: - if (m_params.m_proof_mode != PGM_DISABLED) { - m_context.register_plugin(alloc(smt::theory_mi_arith_w_proofs, m_manager, m_params)); - } - // else if (m_params.m_arith_fixnum) { - // if (m_params.m_arith_int_only) - // m_context.register_plugin(alloc(smt::theory_si_arith, m_manager, m_params)); - // else - // m_context.register_plugin(alloc(smt::theory_smi_arith, m_manager, m_params)); - // } - else { - if (m_params.m_arith_int_only) - m_context.register_plugin(alloc(smt::theory_i_arith, m_manager, m_params)); - else - m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params)); - } + if (m_params.m_arith_int_only) + m_context.register_plugin(alloc(smt::theory_i_arith, m_manager, m_params)); + else + m_context.register_plugin(alloc(smt::theory_mi_arith, m_manager, m_params)); break; } } diff --git a/src/smt/smt_setup.h b/src/smt/smt_setup.h index 5c017a498..e0188537e 100644 --- a/src/smt/smt_setup.h +++ b/src/smt/smt_setup.h @@ -20,7 +20,7 @@ Revision History: #define _SMT_SETUP_H_ #include"ast.h" -#include"front_end_params.h" +#include"smt_params.h" struct static_features; namespace smt { @@ -42,7 +42,7 @@ namespace smt { class setup { context & m_context; ast_manager & m_manager; - front_end_params & m_params; + smt_params & m_params; symbol m_logic; bool m_already_configured; void setup_auto_config(); @@ -96,7 +96,7 @@ namespace smt { void setup_i_arith(); void setup_mi_arith(); public: - setup(context & c, front_end_params & params); + setup(context & c, smt_params & params); void mark_already_configured() { m_already_configured = true; } bool already_configured() const { return m_already_configured; } bool set_logic(symbol logic) { diff --git a/src/smt/smt_solver.cpp b/src/smt/smt_solver.cpp index 888e1b34c..e8c1c6698 100644 --- a/src/smt/smt_solver.cpp +++ b/src/smt/smt_solver.cpp @@ -19,27 +19,24 @@ Notes: #include"solver_na2as.h" #include"smt_kernel.h" #include"reg_decl_plugins.h" -#include"front_end_params.h" +#include"smt_params.h" namespace smt { class solver : public solver_na2as { - front_end_params * m_params; + smt_params m_params; smt::kernel * m_context; progress_callback * m_callback; public: - solver():m_params(0), m_context(0), m_callback(0) {} + solver():m_context(0), m_callback(0) {} virtual ~solver() { if (m_context != 0) dealloc(m_context); } - virtual void set_front_end_params(front_end_params & p) { - m_params = &p; - } - virtual void updt_params(params_ref const & p) { + m_params.updt_params(p); if (m_context == 0) return; m_context->updt_params(p); @@ -49,8 +46,7 @@ namespace smt { if (m_context == 0) { ast_manager m; reg_decl_plugins(m); - front_end_params p; - smt::kernel s(m, p); + smt::kernel s(m, m_params); s.collect_param_descrs(r); } else { @@ -59,11 +55,14 @@ namespace smt { } virtual void init_core(ast_manager & m, symbol const & logic) { - SASSERT(m_params); reset(); -#pragma omp critical (solver) + // We can throw exceptions when creating a smt::kernel object + // So, we should create the smt::kernel outside of the criticial section + // block. OMP does not allow exceptions to cross critical section boundaries. + smt::kernel * new_kernel = alloc(smt::kernel, m, m_params); + #pragma omp critical (solver) { - m_context = alloc(smt::kernel, m, *m_params); + m_context = new_kernel; if (m_callback) m_context->set_progress_callback(m_callback); } @@ -82,59 +81,67 @@ namespace smt { virtual void reset_core() { if (m_context != 0) { -#pragma omp critical (solver) + #pragma omp critical (solver) { dealloc(m_context); m_context = 0; } } } + + // An exception may be thrown when creating a smt::kernel. + // So, there is no guarantee that m_context != 0 when + // using smt_solver from the SMT 2.0 command line frontend. + void check_context() const { + if (m_context == 0) + throw default_exception("Z3 failed to create solver, check previous error messages"); + } virtual void assert_expr(expr * t) { - SASSERT(m_context); + check_context(); m_context->assert_expr(t); } virtual void push_core() { - SASSERT(m_context); + check_context(); m_context->push(); } virtual void pop_core(unsigned n) { - SASSERT(m_context); + check_context(); m_context->pop(n); } virtual lbool check_sat_core(unsigned num_assumptions, expr * const * assumptions) { - SASSERT(m_context); + check_context(); TRACE("solver_na2as", tout << "smt_solver::check_sat_core: " << num_assumptions << "\n";); return m_context->check(num_assumptions, assumptions); } virtual void get_unsat_core(ptr_vector & r) { - SASSERT(m_context); + check_context(); unsigned sz = m_context->get_unsat_core_size(); for (unsigned i = 0; i < sz; i++) r.push_back(m_context->get_unsat_core_expr(i)); } virtual void get_model(model_ref & m) { - SASSERT(m_context); + check_context(); m_context->get_model(m); } virtual proof * get_proof() { - SASSERT(m_context); + check_context(); return m_context->get_proof(); } virtual std::string reason_unknown() const { - SASSERT(m_context); + check_context(); return m_context->last_failure_as_string(); } virtual void get_labels(svector & r) { - SASSERT(m_context); + check_context(); buffer tmp; m_context->get_relevant_labels(0, tmp); r.append(tmp.size(), tmp.c_ptr()); diff --git a/src/smt/smt_value_sort.cpp b/src/smt/smt_value_sort.cpp new file mode 100644 index 000000000..a840b77b7 --- /dev/null +++ b/src/smt/smt_value_sort.cpp @@ -0,0 +1,74 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + smt_value_sort.cpp + +Abstract: + + Determine if elements of a given sort can be values. + +Author: + + Nikolaj Bjorner (nbjorner) 2012-11-25 + +Revision History: + + +--*/ + +#include "smt_value_sort.h" +#include "bv_decl_plugin.h" +#include "arith_decl_plugin.h" +#include "datatype_decl_plugin.h" + +namespace smt { + + + bool is_value_sort(ast_manager& m, sort* s) { + arith_util arith(m); + datatype_util data(m); + bv_util bv(m); + + ptr_vector sorts; + ast_mark mark; + sorts.push_back(s); + + while (!sorts.empty()) { + s = sorts.back(); + sorts.pop_back(); + if (mark.is_marked(s)) { + continue; + } + mark.mark(s, true); + if (arith.is_int_real(s)) { + // simple + } + else if (m.is_bool(s)) { + // simple + } + else if (bv.is_bv_sort(s)) { + // simple + } + else if (data.is_datatype(s)) { + ptr_vector const& cs = *data.get_datatype_constructors(s); + for (unsigned i = 0; i < cs.size(); ++i) { + func_decl* f = cs[i]; + for (unsigned j = 0; j < f->get_arity(); ++j) { + sorts.push_back(f->get_domain(j)); + } + } + } + else { + return false; + } + } + return true; + } + + bool is_value_sort(ast_manager& m, expr* e) { + return is_value_sort(m, m.get_sort(e)); + } + +} diff --git a/src/smt/smt_value_sort.h b/src/smt/smt_value_sort.h new file mode 100644 index 000000000..ae32be62a --- /dev/null +++ b/src/smt/smt_value_sort.h @@ -0,0 +1,37 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + smt_value_sort.h + +Abstract: + + Determine if elements of a given sort can be values. + +Author: + + Nikolaj Bjorner (nbjorner) 2012-11-25 + +Revision History: + + +--*/ + + +#ifndef __SMT_VALUE_SORT_H__ +#define __SMT_VALUE_SORT_H__ + +#include "ast.h" + + +namespace smt { + + bool is_value_sort(ast_manager& m, sort* s); + + bool is_value_sort(ast_manager& m, expr* e); + +}; + + +#endif diff --git a/src/smt/tactic/ctx_solver_simplify_tactic.cpp b/src/smt/tactic/ctx_solver_simplify_tactic.cpp index e5b625661..25c41c2a2 100644 --- a/src/smt/tactic/ctx_solver_simplify_tactic.cpp +++ b/src/smt/tactic/ctx_solver_simplify_tactic.cpp @@ -19,7 +19,7 @@ Notes: #include"ctx_solver_simplify_tactic.h" #include"arith_decl_plugin.h" -#include"front_end_params.h" +#include"smt_params.h" #include"smt_kernel.h" #include"ast_pp.h" #include"mk_simplified_app.h" @@ -28,7 +28,7 @@ Notes: class ctx_solver_simplify_tactic : public tactic { ast_manager& m; params_ref m_params; - front_end_params m_front_p; + smt_params m_front_p; smt::kernel m_solver; arith_util m_arith; mk_simplified_app m_mk_app; diff --git a/src/smt/tactic/smt_tactic.cpp b/src/smt/tactic/smt_tactic.cpp index 84587b6c9..2c7d58b1a 100644 --- a/src/smt/tactic/smt_tactic.cpp +++ b/src/smt/tactic/smt_tactic.cpp @@ -19,12 +19,12 @@ Notes: #include"tactic.h" #include"tactical.h" #include"smt_kernel.h" -#include"front_end_params.h" -#include"params2front_end_params.h" +#include"smt_params.h" +#include"smt_params_helper.hpp" #include"rewriter_types.h" class smt_tactic : public tactic { - scoped_ptr m_params; + smt_params m_params; params_ref m_params_ref; statistics m_stats; std::string m_failure; @@ -51,31 +51,26 @@ public: SASSERT(m_ctx == 0); } - front_end_params & fparams() { - if (!m_params) { - m_params = alloc(front_end_params); - params2front_end_params(m_params_ref, fparams()); - } - return *m_params; + smt_params & fparams() { + return m_params; } void updt_params_core(params_ref const & p) { - m_candidate_models = p.get_bool(":candidate-models", false); - m_fail_if_inconclusive = p.get_bool(":fail-if-inconclusive", true); + m_candidate_models = p.get_bool("candidate_models", false); + m_fail_if_inconclusive = p.get_bool("fail_if_inconclusive", true); } virtual void updt_params(params_ref const & p) { TRACE("smt_tactic", tout << this << "\nupdt_params: " << p << "\n";); updt_params_core(p); - m_params_ref = p; - params2front_end_params(m_params_ref, fparams()); - SASSERT(p.get_bool(":auto_config", fparams().m_auto_config) == fparams().m_auto_config); + fparams().updt_params(p); + SASSERT(p.get_bool("auto_config", fparams().m_auto_config) == fparams().m_auto_config); } virtual void collect_param_descrs(param_descrs & r) { - r.insert(":candidate-models", CPK_BOOL, "(default: false) create candidate models even when quantifier or theory reasoning is incomplete."); - r.insert(":fail-if-inconclusive", CPK_BOOL, "(default: true) fail if found unsat (sat) for under (over) approximated goal."); - solver_front_end_params_descrs(r); + r.insert("candidate_models", CPK_BOOL, "(default: false) create candidate models even when quantifier or theory reasoning is incomplete."); + r.insert("fail_if_inconclusive", CPK_BOOL, "(default: true) fail if found unsat (sat) for under (over) approximated goal."); + smt_params_helper::collect_param_descrs(r); } virtual void set_cancel(bool f) { @@ -97,14 +92,6 @@ public: m_stats.reset(); } - // for backward compatibility - virtual void set_front_end_params(front_end_params & p) { - m_params = alloc(front_end_params, p); - SASSERT(m_params.get() == &fparams()); - // must propagate the params_ref to fparams - params2front_end_params(m_params_ref, fparams()); - } - virtual void set_logic(symbol const & l) { m_logic = l; } @@ -315,7 +302,7 @@ tactic * mk_smt_tactic(params_ref const & p) { tactic * mk_smt_tactic_using(bool auto_config, params_ref const & _p) { params_ref p = _p; - p.set_bool(":auto-config", auto_config); + p.set_bool("auto_config", auto_config); tactic * r = mk_smt_tactic(p); TRACE("smt_tactic", tout << "auto_config: " << auto_config << "\nr: " << r << "\np: " << p << "\n";); return using_params(r, p); diff --git a/src/smt/theory_arith.cpp b/src/smt/theory_arith.cpp index d57812b7a..0bb356b95 100644 --- a/src/smt/theory_arith.cpp +++ b/src/smt/theory_arith.cpp @@ -21,7 +21,6 @@ Revision History: namespace smt { - template class theory_arith; template class theory_arith; template class theory_arith; // template class theory_arith; diff --git a/src/smt/theory_arith.h b/src/smt/theory_arith.h index c125558f7..e7037f31a 100644 --- a/src/smt/theory_arith.h +++ b/src/smt/theory_arith.h @@ -87,8 +87,8 @@ namespace smt { typedef vector numeral_vector; static const int dead_row_id = -1; - static const bool proofs_enabled = Ext::proofs_enabled; protected: + bool proofs_enabled() const { return get_manager().proofs_enabled(); } struct linear_monomial { numeral m_coeff; @@ -233,8 +233,8 @@ namespace smt { void reset(); literal_vector& lits() { return m_lits; } eq_vector& eqs() { return m_eqs; } - void push_lit(literal l, numeral const& r); - void push_eq(enode_pair const& p, numeral const& r); + void push_lit(literal l, numeral const& r, bool proofs_enabled); + void push_eq(enode_pair const& p, numeral const& r, bool proofs_enabled); unsigned num_params() const { return empty()?0:m_eq_coeffs.size() + m_lit_coeffs.size() + 1; } numeral const* lit_coeffs() const { return m_lit_coeffs.c_ptr(); } numeral const* eq_coeffs() const { return m_eq_coeffs.c_ptr(); } @@ -260,7 +260,7 @@ namespace smt { bool is_atom() const { return m_atom; } inf_numeral const & get_value() const { return m_value; } virtual bool has_justification() const { return false; } - virtual void push_justification(antecedents& antecedents, numeral const& coeff) {} + virtual void push_justification(antecedents& antecedents, numeral const& coeff, bool proofs_enabled) {} }; @@ -284,8 +284,8 @@ namespace smt { bool is_true() const { return m_is_true; } void assign_eh(bool is_true, inf_numeral const & epsilon); virtual bool has_justification() const { return true; } - virtual void push_justification(antecedents& a, numeral const& coeff) { - a.push_lit(literal(get_bool_var(), !m_is_true), coeff); + virtual void push_justification(antecedents& a, numeral const& coeff, bool proofs_enabled) { + a.push_lit(literal(get_bool_var(), !m_is_true), coeff, proofs_enabled); } }; @@ -301,9 +301,9 @@ namespace smt { } virtual ~eq_bound() {} virtual bool has_justification() const { return true; } - virtual void push_justification(antecedents& a, numeral const& coeff) { + virtual void push_justification(antecedents& a, numeral const& coeff, bool proofs_enabled) { SASSERT(m_lhs->get_root() == m_rhs->get_root()); - a.push_eq(enode_pair(m_lhs, m_rhs), coeff); + a.push_eq(enode_pair(m_lhs, m_rhs), coeff, proofs_enabled); } }; @@ -316,7 +316,7 @@ namespace smt { derived_bound(theory_var v, inf_numeral const & val, bound_kind k):bound(v, val, k, false) {} virtual ~derived_bound() {} virtual bool has_justification() const { return true; } - virtual void push_justification(antecedents& a, numeral const& coeff); + virtual void push_justification(antecedents& a, numeral const& coeff, bool proofs_enabled); virtual void push_lit(literal l, numeral const&) { m_lits.push_back(l); } virtual void push_eq(enode_pair const& p, numeral const&) { m_eqs.push_back(p); } }; @@ -329,7 +329,7 @@ namespace smt { justified_derived_bound(theory_var v, inf_numeral const & val, bound_kind k):derived_bound(v, val, k) {} virtual ~justified_derived_bound() {} virtual bool has_justification() const { return true; } - virtual void push_justification(antecedents& a, numeral const& coeff); + virtual void push_justification(antecedents& a, numeral const& coeff, bool proofs_enabled); virtual void push_lit(literal l, numeral const& coeff); virtual void push_eq(enode_pair const& p, numeral const& coeff); @@ -1053,30 +1053,9 @@ namespace smt { static inf_numeral mk_inf_numeral(numeral const & n, numeral const & r) { return inf_numeral(n, r); } - static const bool proofs_enabled = false; mi_ext() : m_int_epsilon(rational(1)), m_real_epsilon(rational(0), true) {} }; - class mi_ext_with_proofs { - public: - typedef rational numeral; - typedef inf_rational inf_numeral; - inf_numeral m_int_epsilon; - inf_numeral m_real_epsilon; - numeral fractional_part(inf_numeral const& n) { - SASSERT(n.is_rational()); - return n.get_rational() - floor(n); - } - static numeral fractional_part(numeral const & n) { - return n - floor(n); - } - static inf_numeral mk_inf_numeral(numeral const & n, numeral const & r) { - return inf_numeral(n, r); - } - static const bool proofs_enabled = true; - mi_ext_with_proofs() : m_int_epsilon(rational(1)), m_real_epsilon(rational(0), true) {} - }; - class i_ext { public: typedef rational numeral; @@ -1090,7 +1069,6 @@ namespace smt { UNREACHABLE(); return inf_numeral(n); } - static const bool proofs_enabled = false; i_ext() : m_int_epsilon(1), m_real_epsilon(1) {} }; @@ -1107,7 +1085,6 @@ namespace smt { UNREACHABLE(); return inf_numeral(n); } - static const bool proofs_enabled = false; si_ext(): m_int_epsilon(s_integer(1)), m_real_epsilon(s_integer(1)) {} }; @@ -1128,12 +1105,10 @@ namespace smt { static inf_numeral mk_inf_numeral(numeral const& n, numeral const& i) { return inf_numeral(n, i); } - static const bool proofs_enabled = false; smi_ext() : m_int_epsilon(s_integer(1)), m_real_epsilon(s_integer(0), true) {} }; typedef theory_arith theory_mi_arith; - typedef theory_arith theory_mi_arith_w_proofs; typedef theory_arith theory_i_arith; // typedef theory_arith theory_si_arith; // typedef theory_arith theory_smi_arith; diff --git a/src/smt/theory_arith_aux.h b/src/smt/theory_arith_aux.h index 4d22287ed..9f77934e5 100644 --- a/src/smt/theory_arith_aux.h +++ b/src/smt/theory_arith_aux.h @@ -336,7 +336,7 @@ namespace smt { } template - void theory_arith::antecedents::push_lit(literal l, numeral const& r) { + void theory_arith::antecedents::push_lit(literal l, numeral const& r, bool proofs_enabled) { m_lits.push_back(l); if (proofs_enabled) { m_lit_coeffs.push_back(r); @@ -344,7 +344,7 @@ namespace smt { } template - void theory_arith::antecedents::push_eq(enode_pair const& p, numeral const& r) { + void theory_arith::antecedents::push_eq(enode_pair const& p, numeral const& r, bool proofs_enabled) { m_eqs.push_back(p); if (proofs_enabled) { m_eq_coeffs.push_back(r); @@ -690,14 +690,14 @@ namespace smt { // ----------------------------------- template - void theory_arith::derived_bound::push_justification(antecedents& a, numeral const& coeff) { + void theory_arith::derived_bound::push_justification(antecedents& a, numeral const& coeff, bool proofs_enabled) { if (proofs_enabled) { for (unsigned i = 0; i < m_lits.size(); ++i) { - a.push_lit(m_lits[i], coeff); + a.push_lit(m_lits[i], coeff, proofs_enabled); } for (unsigned i = 0; i < m_eqs.size(); ++i) { - a.push_eq(m_eqs[i], coeff); + a.push_eq(m_eqs[i], coeff, proofs_enabled); } } else { @@ -708,12 +708,12 @@ namespace smt { template - void theory_arith::justified_derived_bound::push_justification(antecedents& a, numeral const& coeff) { + void theory_arith::justified_derived_bound::push_justification(antecedents& a, numeral const& coeff, bool proofs_enabled) { for (unsigned i = 0; i < this->m_lits.size(); ++i) { - a.push_lit(this->m_lits[i], coeff*m_lit_coeffs[i]); + a.push_lit(this->m_lits[i], coeff*m_lit_coeffs[i], proofs_enabled); } for (unsigned i = 0; i < this->m_eqs.size(); ++i) { - a.push_eq(this->m_eqs[i], coeff*m_eq_coeffs[i]); + a.push_eq(this->m_eqs[i], coeff*m_eq_coeffs[i], proofs_enabled); } } @@ -749,13 +749,13 @@ namespace smt { void theory_arith::accumulate_justification(bound & b, derived_bound& new_bound, numeral const& coeff, literal_idx_set & lits, eq_set & eqs) { antecedents& ante = m_tmp_antecedents; ante.reset(); - b.push_justification(ante, coeff); + b.push_justification(ante, coeff, proofs_enabled()); unsigned num_lits = ante.lits().size(); for (unsigned i = 0; i < num_lits; ++i) { literal l = ante.lits()[i]; if (lits.contains(l.index())) continue; - if (proofs_enabled) { + if (proofs_enabled()) { new_bound.push_lit(l, ante.lit_coeffs()[i]); } else { @@ -768,7 +768,7 @@ namespace smt { enode_pair const & p = ante.eqs()[i]; if (eqs.contains(p)) continue; - if (proofs_enabled) { + if (proofs_enabled()) { new_bound.push_eq(p, ante.eq_coeffs()[i]); } else { @@ -796,7 +796,7 @@ namespace smt { template void theory_arith::mk_bound_from_row(theory_var v, inf_numeral const & k, bound_kind kind, row const & r) { inf_numeral k_norm = normalize_bound(v, k, kind); - derived_bound * new_bound = proofs_enabled?alloc(justified_derived_bound, v, k_norm, kind):alloc(derived_bound, v, k_norm, kind); + derived_bound * new_bound = proofs_enabled()?alloc(justified_derived_bound, v, k_norm, kind):alloc(derived_bound, v, k_norm, kind); m_bounds_to_delete.push_back(new_bound); m_asserted_bounds.push_back(new_bound); m_tmp_lit_set.reset(); diff --git a/src/smt/theory_arith_core.h b/src/smt/theory_arith_core.h index a691096ec..b774fb3d9 100644 --- a/src/smt/theory_arith_core.h +++ b/src/smt/theory_arith_core.h @@ -1979,7 +1979,7 @@ namespace smt { tout << "is_below_lower: " << below_lower(x_i) << ", is_above_upper: " << above_upper(x_i) << "\n";); antecedents& ante = get_antecedents(); explain_bound(r, idx, !is_below, delta, ante); - b->push_justification(ante, numeral(1)); + b->push_justification(ante, numeral(1), proofs_enabled()); set_conflict(ante.lits().size(), ante.lits().c_ptr(), @@ -2122,8 +2122,8 @@ namespace smt { void theory_arith::sign_bound_conflict(bound * b1, bound * b2) { SASSERT(b1->get_var() == b2->get_var()); antecedents& ante = get_antecedents(); - b1->push_justification(ante, numeral(1)); - b2->push_justification(ante, numeral(1)); + b1->push_justification(ante, numeral(1), proofs_enabled()); + b2->push_justification(ante, numeral(1), proofs_enabled()); set_conflict(ante.lits().size(), ante.lits().c_ptr(), ante.eqs().size(), ante.eqs().c_ptr(), ante, is_int(b1->get_var()), "farkas"); TRACE("arith_conflict", tout << "bound conflict\n";); @@ -2382,7 +2382,7 @@ namespace smt { if (!b->has_justification()) continue; if (!relax_bounds() || delta.is_zero()) { - b->push_justification(ante, it->m_coeff); + b->push_justification(ante, it->m_coeff, proofs_enabled()); continue; } numeral coeff = it->m_coeff; @@ -2442,7 +2442,7 @@ namespace smt { SASSERT(!is_b_lower || k_2 <= k_1); SASSERT(is_b_lower || k_2 >= k_1); if (new_atom == 0) { - b->push_justification(ante, coeff); + b->push_justification(ante, coeff, proofs_enabled()); continue; } SASSERT(!is_b_lower || k_2 < k_1); @@ -2456,7 +2456,7 @@ namespace smt { delta -= coeff*(k_2 - k_1); } TRACE("propagate_bounds", tout << "delta (after replace): " << delta << "\n";); - new_atom->push_justification(ante, coeff); + new_atom->push_justification(ante, coeff, proofs_enabled()); SASSERT(delta >= inf_numeral::zero()); } } @@ -2569,7 +2569,7 @@ namespace smt { for (; it != end; ++it) lits.push_back(~(*it)); justification * js = 0; - if (proofs_enabled) { + if (proofs_enabled()) { js = alloc(theory_lemma_justification, get_id(), ctx, lits.size(), lits.c_ptr(), ante.num_params(), ante.params("assign-bounds")); } @@ -2656,13 +2656,13 @@ namespace smt { for (unsigned i = 0; i < num_literals; i++) { ctx.display_detailed_literal(tout, lits[i]); tout << " "; - if (proofs_enabled) { + if (proofs_enabled()) { tout << "bound: " << bounds.lit_coeffs()[i] << "\n"; } } for (unsigned i = 0; i < num_eqs; i++) { tout << "#" << eqs[i].first->get_owner_id() << "=#" << eqs[i].second->get_owner_id() << " "; - if (proofs_enabled) { + if (proofs_enabled()) { tout << "bound: " << bounds.eq_coeffs()[i] << "\n"; } } @@ -2686,8 +2686,8 @@ namespace smt { typename vector::const_iterator end = r.end_entries(); for (; it != end; ++it) { if (!it->is_dead() && is_fixed(it->m_var)) { - lower(it->m_var)->push_justification(antecedents, it->m_coeff); - upper(it->m_var)->push_justification(antecedents, it->m_coeff); + lower(it->m_var)->push_justification(antecedents, it->m_coeff, proofs_enabled()); + upper(it->m_var)->push_justification(antecedents, it->m_coeff, proofs_enabled()); } } } diff --git a/src/smt/theory_arith_eq.h b/src/smt/theory_arith_eq.h index e6130acfe..04e16e778 100644 --- a/src/smt/theory_arith_eq.h +++ b/src/smt/theory_arith_eq.h @@ -59,10 +59,10 @@ namespace smt { // v >= k >= v2 => v >= v2 // - lower(v)->push_justification(ante, numeral::zero()); - upper(v2)->push_justification(ante, numeral::zero()); - lower(v2)->push_justification(ante, numeral::zero()); - upper(v)->push_justification(ante, numeral::zero()); + lower(v)->push_justification(ante, numeral::zero(), proofs_enabled()); + upper(v2)->push_justification(ante, numeral::zero(), proofs_enabled()); + lower(v2)->push_justification(ante, numeral::zero(), proofs_enabled()); + upper(v)->push_justification(ante, numeral::zero(), proofs_enabled()); TRACE("arith_fixed_propagate_eq", tout << "propagate eq: v" << v << " = v" << v2 << "\n"; display_var(tout, v); @@ -247,8 +247,8 @@ namespace smt { // // x1 <= k1 x1 >= k1, x2 <= x1 + k2 x2 >= x1 + k2 // - lower(x2)->push_justification(ante, numeral::zero()); - upper(x2)->push_justification(ante, numeral::zero()); + lower(x2)->push_justification(ante, numeral::zero(), proofs_enabled()); + upper(x2)->push_justification(ante, numeral::zero(), proofs_enabled()); m_stats.m_fixed_eqs++; propagate_eq_to_core(x, x2, ante); } diff --git a/src/smt/theory_arith_int.h b/src/smt/theory_arith_int.h index 2a3bff804..e0ecc087a 100644 --- a/src/smt/theory_arith_int.h +++ b/src/smt/theory_arith_int.h @@ -525,7 +525,7 @@ namespace smt { } // k += new_a_ij * lower_bound(x_j).get_rational(); k.addmul(new_a_ij, lower_bound(x_j).get_rational()); - lower(x_j)->push_justification(ante, numeral::zero()); + lower(x_j)->push_justification(ante, numeral::zero(), proofs_enabled()); } else { SASSERT(at_upper(x_j)); @@ -541,7 +541,7 @@ namespace smt { } // k += new_a_ij * upper_bound(x_j).get_rational(); k.addmul(new_a_ij, upper_bound(x_j).get_rational()); - upper(x_j)->push_justification(ante, numeral::zero()); + upper(x_j)->push_justification(ante, numeral::zero(), proofs_enabled()); } pol.push_back(row_entry(new_a_ij, x_j)); } @@ -566,7 +566,7 @@ namespace smt { } // k += new_a_ij * lower_bound(x_j).get_rational(); k.addmul(new_a_ij, lower_bound(x_j).get_rational()); - lower(x_j)->push_justification(ante, numeral::zero()); + lower(x_j)->push_justification(ante, numeral::zero(), proofs_enabled()); } else { SASSERT(at_upper(x_j)); @@ -579,7 +579,7 @@ namespace smt { new_a_ij.neg(); // the upper terms are inverted // k += new_a_ij * upper_bound(x_j).get_rational(); k.addmul(new_a_ij, upper_bound(x_j).get_rational()); - upper(x_j)->push_justification(ante, numeral::zero()); + upper(x_j)->push_justification(ante, numeral::zero(), proofs_enabled()); } TRACE("gomory_cut_detail", tout << "new_a_ij: " << new_a_ij << "\n";); pol.push_back(row_entry(new_a_ij, x_j)); @@ -772,8 +772,8 @@ namespace smt { // u += ncoeff * lower_bound(v).get_rational(); u.addmul(ncoeff, lower_bound(v).get_rational()); } - lower(v)->push_justification(ante, numeral::zero()); - upper(v)->push_justification(ante, numeral::zero()); + lower(v)->push_justification(ante, numeral::zero(), proofs_enabled()); + upper(v)->push_justification(ante, numeral::zero(), proofs_enabled()); } else if (gcds.is_zero()) { gcds = abs_ncoeff; diff --git a/src/smt/theory_diff_logic.h b/src/smt/theory_diff_logic.h index 80d729001..264ab9b2d 100644 --- a/src/smt/theory_diff_logic.h +++ b/src/smt/theory_diff_logic.h @@ -32,7 +32,7 @@ Revision History: #include"arith_decl_plugin.h" #include"smt_justification.h" #include"map.h" -#include"front_end_params.h" +#include"smt_params.h" #include"arith_eq_adapter.h" #include"smt_model_generator.h" #include"numeral_factory.h" @@ -251,7 +251,7 @@ namespace smt { } }; - front_end_params & m_params; + smt_params & m_params; arith_util m_util; arith_eq_adapter m_arith_eq_adapter; theory_diff_logic_statistics m_stats; @@ -305,7 +305,7 @@ namespace smt { void del_clause_eh(clause* cls); public: - theory_diff_logic(ast_manager& m, front_end_params & params): + theory_diff_logic(ast_manager& m, smt_params & params): theory(m.get_family_id("arith")), m_params(params), m_util(m), diff --git a/src/smt/theory_diff_logic_def.h b/src/smt/theory_diff_logic_def.h index f0c491f64..9f2c97a84 100644 --- a/src/smt/theory_diff_logic_def.h +++ b/src/smt/theory_diff_logic_def.h @@ -102,6 +102,7 @@ template bool theory_diff_logic::internalize_term(app * term) { bool result = null_theory_var != mk_term(term); CTRACE("arith", !result, tout << "Did not internalize " << mk_pp(term, get_manager()) << "\n";); + TRACE("non_diff_logic", tout << "Terms may not be internalized\n";); found_non_diff_logic_expr(term); return result; } @@ -831,6 +832,7 @@ theory_var theory_diff_logic::mk_var(app* n) { v = mk_var(e); } if (is_interpreted(n)) { + TRACE("non_diff_logic", tout << "Variable should not be interpreted\n";); found_non_diff_logic_expr(n); } TRACE("arith", tout << mk_pp(n, get_manager()) << " |-> " << v << "\n";); diff --git a/src/smt/theory_instgen.cpp b/src/smt/theory_instgen.cpp index f631fd04c..68e04aab0 100644 --- a/src/smt/theory_instgen.cpp +++ b/src/smt/theory_instgen.cpp @@ -230,12 +230,12 @@ namespace smt { class clause_subsumption { ast_manager& m; grounder m_grounder; - front_end_params m_params; + smt_params m_params; context m_ctx; quantifier_ref_vector m_assumptions; unsigned_vector m_limit; public: - clause_subsumption(ast_manager& m, front_end_params& p): + clause_subsumption(ast_manager& m, smt_params& p): m(m), m_grounder(m), m_params(p), m_ctx(m,m_params), m_assumptions(m) { m_params.m_instgen = false; } @@ -1131,7 +1131,7 @@ namespace smt { }; ast_manager& m_manager; - front_end_params& m_params; + smt_params& m_params; fo_clause_internalizer m_internalizer; instantiator m_instantiator; clause_subsumption m_subsumer; @@ -1184,7 +1184,7 @@ namespace smt { public: - theory_instgen_impl(ast_manager& m, front_end_params& p): + theory_instgen_impl(ast_manager& m, smt_params& p): theory_instgen(m.get_family_id("inst_gen")), m_manager(m), m_params(p), @@ -1277,7 +1277,7 @@ namespace smt { }; - theory_instgen* mk_theory_instgen(ast_manager& m, front_end_params& p) { + theory_instgen* mk_theory_instgen(ast_manager& m, smt_params& p) { return alloc(theory_instgen_impl, m, p); } diff --git a/src/smt/theory_instgen.h b/src/smt/theory_instgen.h index 076dad748..c32636e9b 100644 --- a/src/smt/theory_instgen.h +++ b/src/smt/theory_instgen.h @@ -25,7 +25,7 @@ Revision History: #define _THEORY_INST_GEN_H_ #include "smt_theory.h" -#include "front_end_params.h" +#include "smt_params.h" namespace smt { @@ -37,7 +37,7 @@ namespace smt { virtual char const * get_name() const { return "instgen"; } }; - theory_instgen* mk_theory_instgen(ast_manager& m, front_end_params& p); + theory_instgen* mk_theory_instgen(ast_manager& m, smt_params& p); }; diff --git a/src/smt/user_plugin/user_smt_theory.cpp b/src/smt/user_plugin/user_smt_theory.cpp index d95346469..ab4cc62c4 100644 --- a/src/smt/user_plugin/user_smt_theory.cpp +++ b/src/smt/user_plugin/user_smt_theory.cpp @@ -44,7 +44,7 @@ namespace smt { {} }; - user_theory::user_theory(ast_manager & m, front_end_params const& p, void * ext_context, void * ext_data, char const * name, family_id fid, user_decl_plugin * dp, user_simplifier_plugin * sp): + user_theory::user_theory(ast_manager & m, smt_params const& p, void * ext_context, void * ext_data, char const * name, family_id fid, user_decl_plugin * dp, user_simplifier_plugin * sp): theory(fid), m_params(p), m_ext_context(ext_context), diff --git a/src/smt/user_plugin/user_smt_theory.h b/src/smt/user_plugin/user_smt_theory.h index 3dd664738..56851b768 100644 --- a/src/smt/user_plugin/user_smt_theory.h +++ b/src/smt/user_plugin/user_smt_theory.h @@ -43,7 +43,7 @@ namespace smt { typedef union_find th_union_find; typedef std::pair var_pair; - front_end_params const& m_params; + smt_params const& m_params; void * m_ext_context; void * m_ext_data; std::string m_name; @@ -134,7 +134,7 @@ namespace smt { void assert_axiom_core(app* axiom); public: - user_theory(ast_manager & m, front_end_params const& p, void * ext_context, void * ext_data, char const * name, family_id fid, user_decl_plugin * dp, user_simplifier_plugin * sp); + user_theory(ast_manager & m, smt_params const& p, void * ext_context, void * ext_data, char const * name, family_id fid, user_decl_plugin * dp, user_simplifier_plugin * sp); virtual ~user_theory(); virtual theory * mk_fresh(context * new_ctx); diff --git a/src/solver/solver.h b/src/solver/solver.h index 6f9887c1a..5cd3da52b 100644 --- a/src/solver/solver.h +++ b/src/solver/solver.h @@ -23,8 +23,6 @@ Notes: #include"progress_callback.h" #include"params.h" -struct front_end_params; - /** \brief Abstract interface for making solvers available in the Z3 API and front-ends such as SMT 2.0 and (legacy) SMT 1.0. @@ -41,15 +39,6 @@ struct front_end_params; class solver : public check_sat_result { public: virtual ~solver() {} - - /** - \brief This method is invoked to allow the solver to access the front_end_params (environment parameters). - - \warning This method is used for backward compatibility. The first solver implemented in Z3 used - front_end_params to store its configuration parameters. - */ - virtual void set_front_end_params(front_end_params & p) {} - /** \brief Update the solver internal settings. */ diff --git a/src/solver/strategic_solver.cpp b/src/solver/strategic_solver.cpp index 616ec5342..40d77066e 100644 --- a/src/solver/strategic_solver.cpp +++ b/src/solver/strategic_solver.cpp @@ -18,8 +18,6 @@ Notes: --*/ #include"strategic_solver.h" #include"scoped_timer.h" -#include"front_end_params.h" -#include"params2front_end_params.h" #include"ast_smt2_pp.h" // minimum verbosity level for portfolio verbose messages @@ -33,7 +31,6 @@ strategic_solver::ctx::ctx(ast_manager & m): strategic_solver::strategic_solver(): m_manager(0), - m_fparams(0), m_force_tactic(false), m_inc_mode(false), m_check_sat_executed(false), @@ -50,6 +47,7 @@ strategic_solver::strategic_solver(): m_produce_proofs = false; m_produce_models = false; m_produce_unsat_cores = false; + m_auto_config = true; } strategic_solver::~strategic_solver() { @@ -99,11 +97,10 @@ void strategic_solver::set_inc_solver(solver * s) { void strategic_solver::updt_params(params_ref const & p) { if (m_inc_solver) m_inc_solver->updt_params(p); - if (m_fparams) - params2front_end_params(p, *m_fparams); + m_params = p; + m_auto_config = p.get_bool("auto_config", true); } - void strategic_solver::collect_param_descrs(param_descrs & r) { if (m_inc_solver) m_inc_solver->collect_param_descrs(r); @@ -191,7 +188,6 @@ void strategic_solver::init_inc_solver() { m_inc_solver->set_produce_proofs(m_produce_proofs); m_inc_solver->set_produce_models(m_produce_models); m_inc_solver->set_produce_unsat_cores(m_produce_unsat_cores); - m_inc_solver->set_front_end_params(*m_fparams); m_inc_solver->init(m(), m_logic); unsigned sz = get_num_assertions(); if (m_produce_unsat_cores) { @@ -308,7 +304,7 @@ void strategic_solver::pop(unsigned n) { unsigned strategic_solver::get_scope_level() const { if (m_ctx == 0) return 0; - return m_ctx->m_assertions.size(); + return m_ctx->m_scopes.size(); } struct aux_timeout_eh : public event_handler { @@ -324,12 +320,9 @@ struct aux_timeout_eh : public event_handler { struct strategic_solver::mk_tactic { strategic_solver * m_solver; - mk_tactic(strategic_solver * s, tactic_factory * f):m_solver(s) { + mk_tactic(strategic_solver * s, tactic_factory * f, params_ref const & p):m_solver(s) { ast_manager & m = s->m(); - params_ref p; - front_end_params2params(*s->m_fparams, p); tactic * tct = (*f)(m, p); - tct->set_front_end_params(*s->m_fparams); tct->set_logic(s->m_logic); if (s->m_callback) tct->set_progress_callback(s->m_callback); @@ -376,7 +369,7 @@ lbool strategic_solver::check_sat(unsigned num_assumptions, expr * const * assum reset_results(); m_check_sat_executed = true; if (num_assumptions > 0 || // assumptions were provided - (!m_fparams->m_auto_config && !m_force_tactic) // auto config and force_tactic are turned off + (!m_auto_config && !m_force_tactic) // auto config and force_tactic are turned off ) { // must use incremental solver return check_sat_with_assumptions(num_assumptions, assumptions); @@ -440,7 +433,7 @@ lbool strategic_solver::check_sat(unsigned num_assumptions, expr * const * assum TRACE("strategic_solver", tout << "using goal...\n"; g->display_with_dependencies(tout);); - mk_tactic tct_maker(this, factory); + mk_tactic tct_maker(this, factory, m_params); SASSERT(m_curr_tactic); proof_ref pr(m()); diff --git a/src/solver/strategic_solver.h b/src/solver/strategic_solver.h index e903e9bd0..1883a88cd 100644 --- a/src/solver/strategic_solver.h +++ b/src/solver/strategic_solver.h @@ -23,7 +23,6 @@ Notes: #include"tactic.h" class progress_callback; -struct front_end_params; /** \brief Implementation of the solver API that supports: @@ -57,7 +56,7 @@ public: private: ast_manager * m_manager; - front_end_params * m_fparams; + params_ref m_params; symbol m_logic; bool m_force_tactic; // use tactics even when auto_config = false bool m_inc_mode; @@ -93,6 +92,8 @@ private: bool m_produce_models; bool m_produce_unsat_cores; + bool m_auto_config; + progress_callback * m_callback; void reset_results(); @@ -118,8 +119,6 @@ public: void set_inc_unknown_behavior(inc_unknown_behavior b) { m_inc_unknown_behavior = b; } void force_tactic(bool f) { m_force_tactic = f; } - virtual void set_front_end_params(front_end_params & p) { m_fparams = &p; } - virtual void updt_params(params_ref const & p); virtual void collect_param_descrs(param_descrs & r); diff --git a/src/solver/tactic2solver.cpp b/src/solver/tactic2solver.cpp index 63308bd27..e630f9c78 100644 --- a/src/solver/tactic2solver.cpp +++ b/src/solver/tactic2solver.cpp @@ -20,7 +20,6 @@ Notes: --*/ #include"tactic2solver.h" -#include"params2front_end_params.h" #include"ast_smt2_pp.h" tactic2solver_core::ctx::ctx(ast_manager & m, symbol const & logic): @@ -94,8 +93,6 @@ lbool tactic2solver_core::check_sat_core(unsigned num_assumptions, expr * const SASSERT(m_ctx); ast_manager & m = m_ctx->m(); params_ref p = m_params; - if (m_fparams) - front_end_params2params(*m_fparams, p); #pragma omp critical (tactic2solver_core) { m_ctx->m_tactic = get_tactic(m, p); @@ -107,8 +104,6 @@ lbool tactic2solver_core::check_sat_core(unsigned num_assumptions, expr * const return l_undef; tactic & t = *(m_ctx->m_tactic); simple_check_sat_result & result = *(m_ctx->m_result); - if (m_fparams) - t.set_front_end_params(*m_fparams); goal_ref g = alloc(goal, m, m_produce_proofs, m_produce_models, m_produce_unsat_cores); t.set_logic(m_ctx->m_logic); unsigned sz = m_ctx->m_assertions.size(); diff --git a/src/solver/tactic2solver.h b/src/solver/tactic2solver.h index 8cf3551b4..0a057b04b 100644 --- a/src/solver/tactic2solver.h +++ b/src/solver/tactic2solver.h @@ -43,19 +43,16 @@ class tactic2solver_core : public solver_na2as { ast_manager & m() const { return m_assertions.m(); } }; scoped_ptr m_ctx; - front_end_params * m_fparams; params_ref m_params; bool m_produce_models; bool m_produce_proofs; bool m_produce_unsat_cores; public: - tactic2solver_core():m_ctx(0), m_fparams(0), m_produce_models(false), m_produce_proofs(false), m_produce_unsat_cores(false) {} + tactic2solver_core():m_ctx(0), m_produce_models(false), m_produce_proofs(false), m_produce_unsat_cores(false) {} virtual ~tactic2solver_core(); virtual tactic * get_tactic(ast_manager & m, params_ref const & p) = 0; - virtual void set_front_end_params(front_end_params & p) { m_fparams = &p; } - virtual void updt_params(params_ref const & p); virtual void collect_param_descrs(param_descrs & r); diff --git a/src/tactic/aig/aig_tactic.cpp b/src/tactic/aig/aig_tactic.cpp index 617db0b8c..dc577eb73 100644 --- a/src/tactic/aig/aig_tactic.cpp +++ b/src/tactic/aig/aig_tactic.cpp @@ -62,14 +62,14 @@ public: } virtual void updt_params(params_ref const & p) { - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); - m_aig_gate_encoding = p.get_bool(":aig-default-gate-encoding", true); - m_aig_per_assertion = p.get_bool(":aig-per-assertion", true); + m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); + m_aig_gate_encoding = p.get_bool("aig_default_gate_encoding", true); + m_aig_per_assertion = p.get_bool("aig_per_assertion", true); } virtual void collect_param_descrs(param_descrs & r) { insert_max_memory(r); - r.insert(":aig-per-assertion", CPK_BOOL, "(default: true) process one assertion at a time."); + r.insert("aig_per_assertion", CPK_BOOL, "(default: true) process one assertion at a time."); } void operator()(goal_ref const & g) { diff --git a/src/tactic/arith/add_bounds_tactic.cpp b/src/tactic/arith/add_bounds_tactic.cpp index 81e9c26cf..d396359a3 100644 --- a/src/tactic/arith/add_bounds_tactic.cpp +++ b/src/tactic/arith/add_bounds_tactic.cpp @@ -70,8 +70,8 @@ class add_bounds_tactic : public tactic { } void updt_params(params_ref const & p) { - m_lower = p.get_rat(":add-bound-lower", rational(-2)); - m_upper = p.get_rat(":add-bound-upper", rational(2)); + m_lower = p.get_rat("add_bound_lower", rational(-2)); + m_upper = p.get_rat("add_bound_upper", rational(2)); } void set_cancel(bool f) { @@ -159,8 +159,8 @@ public: } virtual void collect_param_descrs(param_descrs & r) { - r.insert(":add-bound-lower", CPK_NUMERAL, "(default: -2) lower bound to be added to unbounded variables."); - r.insert(":add-bound-upper", CPK_NUMERAL, "(default: 2) upper bound to be added to unbounded variables."); + r.insert("add_bound_lower", CPK_NUMERAL, "(default: -2) lower bound to be added to unbounded variables."); + r.insert("add_bound_upper", CPK_NUMERAL, "(default: 2) upper bound to be added to unbounded variables."); } virtual void operator()(goal_ref const & g, diff --git a/src/tactic/arith/bound_propagator.cpp b/src/tactic/arith/bound_propagator.cpp index 40c2ed49b..dbd7c5f69 100644 --- a/src/tactic/arith/bound_propagator.cpp +++ b/src/tactic/arith/bound_propagator.cpp @@ -116,15 +116,15 @@ void bound_propagator::del_constraint(constraint & c) { } void bound_propagator::updt_params(params_ref const & p) { - m_max_refinements = p.get_uint(":bound-max-refinements", 16); - m_threshold = p.get_double(":bound-threshold", 0.05); - m_small_interval = p.get_double(":bound-small-interval", 128); - m_strict2double = p.get_double(":strict2double", 0.00001); + m_max_refinements = p.get_uint("bound_max_refinements", 16); + m_threshold = p.get_double("bound_threshold", 0.05); + m_small_interval = p.get_double("bound_small_interval", 128); + m_strict2double = p.get_double("strict2double", 0.00001); } void bound_propagator::get_param_descrs(param_descrs & r) { - r.insert(":bound-max-refinements", CPK_UINT, "(default: 16) maximum number of bound refinements (per round) for unbounded variables."); - r.insert(":bound-threshold", CPK_DOUBLE, "(default: 0.05) bound propagation improvement threshold ratio."); + r.insert("bound_max_refinements", CPK_UINT, "(default: 16) maximum number of bound refinements (per round) for unbounded variables."); + r.insert("bound_threshold", CPK_DOUBLE, "(default: 0.05) bound propagation improvement threshold ratio."); } void bound_propagator::collect_statistics(statistics & st) const { diff --git a/src/tactic/arith/bv2int_rewriter.cpp b/src/tactic/arith/bv2int_rewriter.cpp index e8ddf18c9..0965f36f2 100644 --- a/src/tactic/arith/bv2int_rewriter.cpp +++ b/src/tactic/arith/bv2int_rewriter.cpp @@ -21,7 +21,7 @@ Notes: #include "ast_pp.h" void bv2int_rewriter_ctx::update_params(params_ref const& p) { - m_max_size = p.get_uint(":max-bv-size", UINT_MAX); + m_max_size = p.get_uint("max_bv_size", UINT_MAX); } struct lt_rational { diff --git a/src/tactic/arith/degree_shift_tactic.cpp b/src/tactic/arith/degree_shift_tactic.cpp index 8e2c6d7cb..a1aa0bdc8 100644 --- a/src/tactic/arith/degree_shift_tactic.cpp +++ b/src/tactic/arith/degree_shift_tactic.cpp @@ -342,7 +342,7 @@ protected: tactic * mk_degree_shift_tactic(ast_manager & m, params_ref const & p) { params_ref mul2power_p; - mul2power_p.set_bool(":mul-to-power", true); + mul2power_p.set_bool("mul_to_power", true); return and_then(using_params(mk_simplify_tactic(m), mul2power_p), clean(alloc(degree_shift_tactic, m))); } diff --git a/src/tactic/arith/diff_neq_tactic.cpp b/src/tactic/arith/diff_neq_tactic.cpp index 93ac6912d..b534c8295 100644 --- a/src/tactic/arith/diff_neq_tactic.cpp +++ b/src/tactic/arith/diff_neq_tactic.cpp @@ -62,7 +62,7 @@ class diff_neq_tactic : public tactic { } void updt_params(params_ref const & p) { - m_max_k = rational(p.get_uint(":diff-neq-max-k", 1024)); + m_max_k = rational(p.get_uint("diff_neq_max_k", 1024)); m_max_neg_k = -m_max_k; if (m_max_k >= rational(INT_MAX/2)) m_max_k = rational(INT_MAX/2); @@ -374,7 +374,7 @@ public: } virtual void collect_param_descrs(param_descrs & r) { - r.insert(":diff-neq-max-k", CPK_UINT, "(default: 1024) maximum variable upper bound for diff neq solver."); + r.insert("diff_neq_max_k", CPK_UINT, "(default: 1024) maximum variable upper bound for diff neq solver."); } virtual void collect_statistics(statistics & st) const { diff --git a/src/tactic/arith/factor_tactic.cpp b/src/tactic/arith/factor_tactic.cpp index 2cfbc9ef8..752f6681d 100644 --- a/src/tactic/arith/factor_tactic.cpp +++ b/src/tactic/arith/factor_tactic.cpp @@ -40,7 +40,7 @@ class factor_tactic : public tactic { } void updt_params(params_ref const & p) { - m_split_factors = p.get_bool(":split-factors", true); + m_split_factors = p.get_bool("split_factors", true); m_fparams.updt_params(p); } @@ -311,7 +311,7 @@ public: } virtual void collect_param_descrs(param_descrs & r) { - r.insert(":split-factors", CPK_BOOL, + r.insert("split_factors", CPK_BOOL, "(default: true) apply simplifications such as (= (* p1 p2) 0) --> (or (= p1 0) (= p2 0))."); polynomial::factor_params::get_param_descrs(r); } diff --git a/src/tactic/arith/fm_tactic.cpp b/src/tactic/arith/fm_tactic.cpp index 4796e7f39..c4b7cbaf3 100644 --- a/src/tactic/arith/fm_tactic.cpp +++ b/src/tactic/arith/fm_tactic.cpp @@ -792,13 +792,13 @@ class fm_tactic : public tactic { } void updt_params(params_ref const & p) { - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); - m_fm_real_only = p.get_bool(":fm-real-only", true); - m_fm_limit = p.get_uint(":fm-limit", 5000000); - m_fm_cutoff1 = p.get_uint(":fm-cutoff1", 8); - m_fm_cutoff2 = p.get_uint(":fm-cutoff2", 256); - m_fm_extra = p.get_uint(":fm-extra", 0); - m_fm_occ = p.get_bool(":fm-occ", false); + m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); + m_fm_real_only = p.get_bool("fm_real_only", true); + m_fm_limit = p.get_uint("fm_limit", 5000000); + m_fm_cutoff1 = p.get_uint("fm_cutoff1", 8); + m_fm_cutoff2 = p.get_uint("fm_cutoff2", 256); + m_fm_extra = p.get_uint("fm_extra", 0); + m_fm_occ = p.get_bool("fm_occ", false); } void set_cancel(bool f) { @@ -1668,12 +1668,12 @@ public: virtual void collect_param_descrs(param_descrs & r) { insert_produce_models(r); insert_max_memory(r); - r.insert(":fm-real-only", CPK_BOOL, "(default: true) consider only real variables for fourier-motzkin elimination."); - r.insert(":fm-occ", CPK_BOOL, "(default: false) consider inequalities occurring in clauses for FM."); - r.insert(":fm-limit", CPK_UINT, "(default: 5000000) maximum number of constraints, monomials, clauses visited during FM."); - r.insert(":fm-cutoff1", CPK_UINT, "(default: 8) first cutoff for FM based on maximum number of lower/upper occurrences."); - r.insert(":fm-cutoff2", CPK_UINT, "(default: 256) second cutoff for FM based on num_lower * num_upper occurrences."); - r.insert(":fm-extra", CPK_UINT, "(default: 0) max. increase on the number of inequalities for each FM variable elimination step."); + r.insert("fm_real_only", CPK_BOOL, "(default: true) consider only real variables for fourier-motzkin elimination."); + r.insert("fm_occ", CPK_BOOL, "(default: false) consider inequalities occurring in clauses for FM."); + r.insert("fm_limit", CPK_UINT, "(default: 5000000) maximum number of constraints, monomials, clauses visited during FM."); + r.insert("fm_cutoff1", CPK_UINT, "(default: 8) first cutoff for FM based on maximum number of lower/upper occurrences."); + r.insert("fm_cutoff2", CPK_UINT, "(default: 256) second cutoff for FM based on num_lower * num_upper occurrences."); + r.insert("fm_extra", CPK_UINT, "(default: 0) max. increase on the number of inequalities for each FM variable elimination step."); } virtual void set_cancel(bool f) { @@ -1707,9 +1707,9 @@ public: tactic * mk_fm_tactic(ast_manager & m, params_ref const & p) { params_ref s_p = p; - s_p.set_bool(":arith-lhs", true); - s_p.set_bool(":elim-and", true); - s_p.set_bool(":som", true); + s_p.set_bool("arith_lhs", true); + s_p.set_bool("elim_and", true); + s_p.set_bool("som", true); return and_then(using_params(mk_simplify_tactic(m, s_p), s_p), clean(alloc(fm_tactic, m, p))); } diff --git a/src/tactic/arith/lia2pb_tactic.cpp b/src/tactic/arith/lia2pb_tactic.cpp index 871614c1b..6fee55e4b 100644 --- a/src/tactic/arith/lia2pb_tactic.cpp +++ b/src/tactic/arith/lia2pb_tactic.cpp @@ -50,9 +50,9 @@ class lia2pb_tactic : public tactic { } void updt_params_core(params_ref const & p) { - m_partial_lia2pb = p.get_bool(":lia2pb-partial", false); - m_max_bits = p.get_uint(":lia2pb-max-bits", 32); - m_total_bits = p.get_uint(":lia2pb-total-bits", 2048); + m_partial_lia2pb = p.get_bool("lia2pb_partial", false); + m_max_bits = p.get_uint("lia2pb_max_bits", 32); + m_total_bits = p.get_uint("lia2pb_total_bits", 2048); } void updt_params(params_ref const & p) { @@ -325,9 +325,9 @@ public: } virtual void collect_param_descrs(param_descrs & r) { - r.insert(":lia2pb-partial", CPK_BOOL, "(default: false) partial lia2pb conversion."); - r.insert(":lia2pb-max-bits", CPK_UINT, "(default: 32) maximum number of bits to be used (per variable) in lia2pb."); - r.insert(":lia2pb-total-bits", CPK_UINT, "(default: 2048) total number of bits to be used (per problem) in lia2pb."); + r.insert("lia2pb_partial", CPK_BOOL, "(default: false) partial lia2pb conversion."); + r.insert("lia2pb_max_bits", CPK_UINT, "(default: 32) maximum number of bits to be used (per variable) in lia2pb."); + r.insert("lia2pb_total_bits", CPK_UINT, "(default: 2048) total number of bits to be used (per problem) in lia2pb."); } virtual void operator()(goal_ref const & in, diff --git a/src/tactic/arith/nla2bv_tactic.cpp b/src/tactic/arith/nla2bv_tactic.cpp index a9033bcd3..188ea7d70 100644 --- a/src/tactic/arith/nla2bv_tactic.cpp +++ b/src/tactic/arith/nla2bv_tactic.cpp @@ -68,7 +68,7 @@ class nla2bv_tactic : public tactic { m_is_sat_preserving(true), m_arith(m), m_bv(m), - m_bv2real(m, rational(p.get_uint(":nla2bv-root",2)), rational(p.get_uint(":nla2bv-divisor",2)), p.get_uint(":nla2bv-max-bv-size", UINT_MAX)), + m_bv2real(m, rational(p.get_uint("nla2bv_root",2)), rational(p.get_uint("nla2bv_divisor",2)), p.get_uint("nla2bv_max_bv_size", UINT_MAX)), m_bv2int_ctx(m, p), m_bounds(m), m_subst(m), @@ -76,7 +76,7 @@ class nla2bv_tactic : public tactic { m_defs(m), m_trail(m), m_fmc(0) { - m_default_bv_size = m_num_bits = p.get_uint(":nla2bv-bv-size", 4); + m_default_bv_size = m_num_bits = p.get_uint("nla2bv_bv_size", 4); } ~imp() {} @@ -436,10 +436,10 @@ public: } virtual void collect_param_descrs(param_descrs & r) { - r.insert(":nla2bv-max-bv-size", CPK_UINT, "(default: inf) maximum bit-vector size used by nla2bv tactic"); - r.insert(":nla2bv-bv-size", CPK_UINT, "(default: 4) default bit-vector size used by nla2bv tactic."); - r.insert(":nla2bv-root", CPK_UINT, "(default: 2) nla2bv tactic encodes reals into bit-vectors using expressions of the form a+b*sqrt(c), this parameter sets the value of c used in the encoding."); - r.insert(":nla2bv-divisor", CPK_UINT, "(default: 2) nla2bv tactic parameter."); + r.insert("nla2bv_max_bv_size", CPK_UINT, "(default: inf) maximum bit-vector size used by nla2bv tactic"); + r.insert("nla2bv_bv_size", CPK_UINT, "(default: 4) default bit-vector size used by nla2bv tactic."); + r.insert("nla2bv_root", CPK_UINT, "(default: 2) nla2bv tactic encodes reals into bit-vectors using expressions of the form a+b*sqrt(c), this parameter sets the value of c used in the encoding."); + r.insert("nla2bv_divisor", CPK_UINT, "(default: 2) nla2bv tactic parameter."); } /** diff --git a/src/tactic/arith/normalize_bounds_tactic.cpp b/src/tactic/arith/normalize_bounds_tactic.cpp index f7aa968ef..a62b311b5 100644 --- a/src/tactic/arith/normalize_bounds_tactic.cpp +++ b/src/tactic/arith/normalize_bounds_tactic.cpp @@ -44,7 +44,7 @@ class normalize_bounds_tactic : public tactic { } void updt_params_core(params_ref const & p) { - m_normalize_int_only = p.get_bool(":norm-int-only", true); + m_normalize_int_only = p.get_bool("norm_int_only", true); } void updt_params(params_ref const & p) { @@ -173,7 +173,7 @@ public: virtual void collect_param_descrs(param_descrs & r) { insert_produce_models(r); - r.insert(":norm-int-only", CPK_BOOL, "(default: true) normalize only the bounds of integer constants."); + r.insert("norm_int_only", CPK_BOOL, "(default: true) normalize only the bounds of integer constants."); } virtual void operator()(goal_ref const & in, diff --git a/src/tactic/arith/pb2bv_tactic.cpp b/src/tactic/arith/pb2bv_tactic.cpp index 36cc801dc..8790ca5a7 100644 --- a/src/tactic/arith/pb2bv_tactic.cpp +++ b/src/tactic/arith/pb2bv_tactic.cpp @@ -863,15 +863,15 @@ private: } void updt_params(params_ref const & p) { - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); - m_all_clauses_limit = p.get_uint(":pb2bv-all-clauses-limit", 8); - m_cardinality_limit = p.get_uint(":pb2bv-cardinality-limit", UINT_MAX); + m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); + m_all_clauses_limit = p.get_uint("pb2bv_all_clauses_limit", 8); + m_cardinality_limit = p.get_uint("pb2bv_cardinality_limit", UINT_MAX); } void collect_param_descrs(param_descrs & r) { insert_max_memory(r); - r.insert(":pb2bv-all-clauses-limit", CPK_UINT, "(default: 8) maximum number of literals for using equivalent CNF encoding of PB constraint."); - r.insert(":pb2bv-cardinality-limit", CPK_UINT, "(default: inf) limit for using arc-consistent cardinality constraint encoding."); + r.insert("pb2bv_all_clauses_limit", CPK_UINT, "(default: 8) maximum number of literals for using equivalent CNF encoding of PB constraint."); + r.insert("pb2bv_cardinality_limit", CPK_UINT, "(default: inf) limit for using arc-consistent cardinality constraint encoding."); } void set_cancel(bool f) { diff --git a/src/tactic/arith/purify_arith_tactic.cpp b/src/tactic/arith/purify_arith_tactic.cpp index 4bea07269..d2292ede9 100644 --- a/src/tactic/arith/purify_arith_tactic.cpp +++ b/src/tactic/arith/purify_arith_tactic.cpp @@ -856,11 +856,11 @@ public: } virtual void collect_param_descrs(param_descrs & r) { - r.insert(":complete", CPK_BOOL, + r.insert("complete", CPK_BOOL, "(default: true) add constraints to make sure that any interpretation of a underspecified arithmetic operators is a functio. The result will include additional uninterpreted functions/constants: /0, div0, mod0, 0^0, neg-root"); - r.insert(":elim-root-objects", CPK_BOOL, + r.insert("elim_root_objects", CPK_BOOL, "(default: true) eliminate root objects."); - r.insert(":elim-inverses", CPK_BOOL, + r.insert("elim_inverses", CPK_BOOL, "(default: true) eliminate inverse trigonometric functions (asin, acos, atan)."); th_rewriter::get_param_descrs(r); } @@ -876,9 +876,9 @@ public: tactic_report report("purify-arith", *g); bool produce_proofs = g->proofs_enabled(); bool produce_models = g->models_enabled(); - bool elim_root_objs = m_params.get_bool(":elim-root-objects", true); - bool elim_inverses = m_params.get_bool(":elim-inverses", true); - bool complete = m_params.get_bool(":complete", true); + bool elim_root_objs = m_params.get_bool("elim_root_objects", true); + bool elim_inverses = m_params.get_bool("elim_inverses", true); + bool complete = m_params.get_bool("complete", true); purify_arith_proc proc(m_util, m_aux_decls, produce_proofs, elim_root_objs, elim_inverses, complete); proc(*(g.get()), mc, produce_models); @@ -902,10 +902,10 @@ public: tactic * mk_purify_arith_tactic(ast_manager & m, params_ref const & p) { params_ref elim_rem_p = p; - elim_rem_p.set_bool(":elim-rem", true); + elim_rem_p.set_bool("elim_rem", true); params_ref skolemize_p; - skolemize_p.set_bool(":skolemize", false); + skolemize_p.set_bool("skolemize", false); return and_then(using_params(mk_snf_tactic(m, skolemize_p), skolemize_p), using_params(mk_simplify_tactic(m, elim_rem_p), elim_rem_p), diff --git a/src/tactic/arith/recover_01_tactic.cpp b/src/tactic/arith/recover_01_tactic.cpp index a42bedc44..3b1a86345 100644 --- a/src/tactic/arith/recover_01_tactic.cpp +++ b/src/tactic/arith/recover_01_tactic.cpp @@ -58,7 +58,7 @@ class recover_01_tactic : public tactic { } void updt_params_core(params_ref const & p) { - m_cls_max_size = p.get_uint(":recover-01-max-bits", 10); + m_cls_max_size = p.get_uint("recover_01_max_bits", 10); } void updt_params(params_ref const & p) { @@ -408,7 +408,7 @@ public: virtual void collect_param_descrs(param_descrs & r) { th_rewriter::get_param_descrs(r); - r.insert(":recover-01-max-bits", CPK_UINT, "(default: 10) maximum number of bits to consider in a clause."); + r.insert("recover_01_max_bits", CPK_UINT, "(default: 10) maximum number of bits to consider in a clause."); } void operator()(goal_ref const & g, diff --git a/src/tactic/bv/bit_blaster_tactic.cpp b/src/tactic/bv/bit_blaster_tactic.cpp index 63d534cbb..0330141cb 100644 --- a/src/tactic/bv/bit_blaster_tactic.cpp +++ b/src/tactic/bv/bit_blaster_tactic.cpp @@ -36,7 +36,7 @@ class bit_blaster_tactic : public tactic { } void updt_params_core(params_ref const & p) { - m_blast_quant = p.get_bool(":blast-quant", false); + m_blast_quant = p.get_bool("blast_quant", false); } void updt_params(params_ref const & p) { @@ -120,10 +120,10 @@ public: virtual void collect_param_descrs(param_descrs & r) { insert_max_memory(r); insert_max_steps(r); - r.insert(":blast-mul", CPK_BOOL, "(default: true) bit-blast multipliers (and dividers, remainders)."); - r.insert(":blast-add", CPK_BOOL, "(default: true) bit-blast adders."); - r.insert(":blast-quant", CPK_BOOL, "(default: false) bit-blast quantified variables."); - r.insert(":blast-full", CPK_BOOL, "(default: false) bit-blast any term with bit-vector sort, this option will make E-matching ineffective in any pattern containing bit-vector terms."); + r.insert("blast_mul", CPK_BOOL, "(default: true) bit-blast multipliers (and dividers, remainders)."); + r.insert("blast_add", CPK_BOOL, "(default: true) bit-blast adders."); + r.insert("blast_quant", CPK_BOOL, "(default: false) bit-blast quantified variables."); + r.insert("blast_full", CPK_BOOL, "(default: false) bit-blast any term with bit-vector sort, this option will make E-matching ineffective in any pattern containing bit-vector terms."); } virtual void operator()(goal_ref const & g, diff --git a/src/tactic/bv/bv1_blaster_tactic.cpp b/src/tactic/bv/bv1_blaster_tactic.cpp index 77ab1be31..8dcaf2112 100644 --- a/src/tactic/bv/bv1_blaster_tactic.cpp +++ b/src/tactic/bv/bv1_blaster_tactic.cpp @@ -63,9 +63,9 @@ class bv1_blaster_tactic : public tactic { } void updt_params(params_ref const & p) { - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); - m_max_steps = p.get_uint(":max-steps", UINT_MAX); - m_produce_models = p.get_bool(":produce-models", false); + m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); + m_max_steps = p.get_uint("max_steps", UINT_MAX); + m_produce_models = p.get_bool("produce_models", false); } bool rewrite_patterns() const { UNREACHABLE(); return false; } diff --git a/src/tactic/bv/max_bv_sharing_tactic.cpp b/src/tactic/bv/max_bv_sharing_tactic.cpp index 462c9f3e2..251e2b754 100644 --- a/src/tactic/bv/max_bv_sharing_tactic.cpp +++ b/src/tactic/bv/max_bv_sharing_tactic.cpp @@ -55,9 +55,9 @@ class max_bv_sharing_tactic : public tactic { } void updt_params(params_ref const & p) { - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); - m_max_steps = p.get_uint(":max-steps", UINT_MAX); - m_max_args = p.get_uint(":max-args", 128); + m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); + m_max_steps = p.get_uint("max_steps", UINT_MAX); + m_max_args = p.get_uint("max_args", 128); } bool max_steps_exceeded(unsigned num_steps) const { @@ -298,7 +298,7 @@ public: virtual void collect_param_descrs(param_descrs & r) { insert_max_memory(r); insert_max_steps(r); - r.insert(":max-args", CPK_UINT, + r.insert("max_args", CPK_UINT, "(default: 128) maximum number of arguments (per application) that will be considered by the greedy (quadratic) heuristic."); } diff --git a/src/tactic/core/cofactor_elim_term_ite.cpp b/src/tactic/core/cofactor_elim_term_ite.cpp index b39d82201..78d532357 100644 --- a/src/tactic/core/cofactor_elim_term_ite.cpp +++ b/src/tactic/core/cofactor_elim_term_ite.cpp @@ -304,7 +304,7 @@ struct cofactor_elim_term_ite::imp { } void updt_params(params_ref const & p) { - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); + m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); } void set_cancel(bool f) { diff --git a/src/tactic/core/ctx_simplify_tactic.cpp b/src/tactic/core/ctx_simplify_tactic.cpp index 91334fd5c..cca21b90e 100644 --- a/src/tactic/core/ctx_simplify_tactic.cpp +++ b/src/tactic/core/ctx_simplify_tactic.cpp @@ -90,10 +90,10 @@ struct ctx_simplify_tactic::imp { } void updt_params(params_ref const & p) { - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); - m_max_steps = p.get_uint(":max-steps", UINT_MAX); - m_max_depth = p.get_uint(":max-depth", 1024); - m_bail_on_blowup = p.get_bool(":bail-on-blowup", false); + m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); + m_max_steps = p.get_uint("max_steps", UINT_MAX); + m_max_depth = p.get_uint("max_depth", 1024); + m_bail_on_blowup = p.get_bool("bail_on_blowup", false); } void checkpoint() { @@ -519,7 +519,7 @@ void ctx_simplify_tactic::updt_params(params_ref const & p) { void ctx_simplify_tactic::get_param_descrs(param_descrs & r) { insert_max_memory(r); insert_max_steps(r); - r.insert(":max-depth", CPK_UINT, "(default: 1024) maximum term depth."); + r.insert("max_depth", CPK_UINT, "(default: 1024) maximum term depth."); } void ctx_simplify_tactic::operator()(goal_ref const & in, diff --git a/src/tactic/core/elim_term_ite_tactic.cpp b/src/tactic/core/elim_term_ite_tactic.cpp index 4f04859ac..456bad5e0 100644 --- a/src/tactic/core/elim_term_ite_tactic.cpp +++ b/src/tactic/core/elim_term_ite_tactic.cpp @@ -72,7 +72,7 @@ class elim_term_ite_tactic : public tactic { } void updt_params(params_ref const & p) { - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); + m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); } }; @@ -160,7 +160,7 @@ public: virtual void collect_param_descrs(param_descrs & r) { insert_max_memory(r); insert_max_steps(r); - r.insert(":max-args", CPK_UINT, + r.insert("max_args", CPK_UINT, "(default: 128) maximum number of arguments (per application) that will be considered by the greedy (quadratic) heuristic."); } diff --git a/src/tactic/core/elim_uncnstr_tactic.cpp b/src/tactic/core/elim_uncnstr_tactic.cpp index 7d15bc7c0..d1dca296a 100644 --- a/src/tactic/core/elim_uncnstr_tactic.cpp +++ b/src/tactic/core/elim_uncnstr_tactic.cpp @@ -881,8 +881,8 @@ class elim_uncnstr_tactic : public tactic { } void updt_params(params_ref const & p) { - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); - m_max_steps = p.get_uint(":max-steps", UINT_MAX); + m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); + m_max_steps = p.get_uint("max_steps", UINT_MAX); } ast_manager & m() { return m_manager; } diff --git a/src/tactic/core/nnf_tactic.cpp b/src/tactic/core/nnf_tactic.cpp index 157c7078e..a79a4ed06 100644 --- a/src/tactic/core/nnf_tactic.cpp +++ b/src/tactic/core/nnf_tactic.cpp @@ -120,7 +120,7 @@ tactic * mk_snf_tactic(ast_manager & m, params_ref const & p) { tactic * mk_nnf_tactic(ast_manager & m, params_ref const & p) { params_ref new_p(p); - new_p.set_sym(":nnf-mode", symbol("full")); + new_p.set_sym("mode", symbol("full")); TRACE("nnf", tout << "mk_nnf: " << new_p << "\n";); return using_params(mk_snf_tactic(m, p), new_p); } diff --git a/src/tactic/core/propagate_values_tactic.cpp b/src/tactic/core/propagate_values_tactic.cpp index 9ab597dfa..6d9e6ccbd 100644 --- a/src/tactic/core/propagate_values_tactic.cpp +++ b/src/tactic/core/propagate_values_tactic.cpp @@ -44,7 +44,7 @@ class propagate_values_tactic : public tactic { } void updt_params_core(params_ref const & p) { - m_max_rounds = p.get_uint(":max-rounds", 4); + m_max_rounds = p.get_uint("max_rounds", 4); } void updt_params(params_ref const & p) { @@ -237,7 +237,7 @@ public: virtual void collect_param_descrs(param_descrs & r) { th_rewriter::get_param_descrs(r); - r.insert(":max-rounds", CPK_UINT, "(default: 2) maximum number of rounds."); + r.insert("max_rounds", CPK_UINT, "(default: 2) maximum number of rounds."); } virtual void operator()(goal_ref const & in, diff --git a/src/tactic/core/simplify_tactic.cpp b/src/tactic/core/simplify_tactic.cpp index 0408f8c8d..95db962a7 100644 --- a/src/tactic/core/simplify_tactic.cpp +++ b/src/tactic/core/simplify_tactic.cpp @@ -138,7 +138,7 @@ tactic * mk_simplify_tactic(ast_manager & m, params_ref const & p) { tactic * mk_elim_and_tactic(ast_manager & m, params_ref const & p) { params_ref xp = p; - xp.set_bool(":elim-and", true); + xp.set_bool("elim_and", true); return using_params(mk_simplify_tactic(m, xp), xp); } diff --git a/src/tactic/core/solve_eqs_tactic.cpp b/src/tactic/core/solve_eqs_tactic.cpp index aa8fb03c2..995940406 100644 --- a/src/tactic/core/solve_eqs_tactic.cpp +++ b/src/tactic/core/solve_eqs_tactic.cpp @@ -71,9 +71,9 @@ class solve_eqs_tactic : public tactic { ast_manager & m() const { return m_manager; } void updt_params(params_ref const & p) { - m_ite_solver = p.get_bool(":ite-solver", true); - m_theory_solver = p.get_bool(":theory-solver", true); - m_max_occs = p.get_uint(":solve-eqs-max-occs", UINT_MAX); + m_ite_solver = p.get_bool("ite_solver", true); + m_theory_solver = p.get_bool("theory_solver", true); + m_max_occs = p.get_uint("solve_eqs_max_occs", UINT_MAX); } void set_cancel(bool f) { @@ -732,9 +732,9 @@ public: } virtual void collect_param_descrs(param_descrs & r) { - r.insert(":solve-eqs-max-occs", CPK_UINT, "(default: infty) maximum number of occurrences for considering a variable for gaussian eliminations."); - r.insert(":theory-solver", CPK_BOOL, "(default: true) use theory solvers."); - r.insert(":ite-solver", CPK_BOOL, "(default: true) use if-then-else solver."); + r.insert("solve_eqs_max_occs", CPK_UINT, "(default: infty) maximum number of occurrences for considering a variable for gaussian eliminations."); + r.insert("theory_solver", CPK_BOOL, "(default: true) use theory solvers."); + r.insert("ite_solver", CPK_BOOL, "(default: true) use if-then-else solver."); } virtual void operator()(goal_ref const & in, diff --git a/src/tactic/core/split_clause_tactic.cpp b/src/tactic/core/split_clause_tactic.cpp index f259ca8ad..5699aa178 100644 --- a/src/tactic/core/split_clause_tactic.cpp +++ b/src/tactic/core/split_clause_tactic.cpp @@ -96,11 +96,11 @@ public: } virtual void updt_params(params_ref const & p) { - m_largest_clause = p.get_bool(":split-largest-clause", false); + m_largest_clause = p.get_bool("split_largest_clause", false); } virtual void collect_param_descrs(param_descrs & r) { - r.insert(":split-largest-clause", CPK_BOOL, "(default: false) split the largest clause in the goal."); + r.insert("split_largest_clause", CPK_BOOL, "(default: false) split the largest clause in the goal."); } virtual void operator()(goal_ref const & in, diff --git a/src/tactic/core/tseitin_cnf_tactic.cpp b/src/tactic/core/tseitin_cnf_tactic.cpp index 2a4f3df2e..b6c4b0655 100644 --- a/src/tactic/core/tseitin_cnf_tactic.cpp +++ b/src/tactic/core/tseitin_cnf_tactic.cpp @@ -122,12 +122,12 @@ class tseitin_cnf_tactic : public tactic { } void updt_params(params_ref const & p) { - m_common_patterns = p.get_bool(":common-patterns", true); - m_distributivity = p.get_bool(":distributivity", true); - m_distributivity_blowup = p.get_uint(":distributivity-blowup", 32); - m_ite_chains = p.get_bool(":ite-chains", true); - m_ite_extra = p.get_bool(":ite-extra", true); - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); + m_common_patterns = p.get_bool("common_patterns", true); + m_distributivity = p.get_bool("distributivity", true); + m_distributivity_blowup = p.get_uint("distributivity_blowup", 32); + m_ite_chains = p.get_bool("ite_chains", true); + m_ite_extra = p.get_bool("ite_extra", true); + m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); } void push_frame(app * n) { m_frame_stack.push_back(frame(n)); } @@ -881,11 +881,11 @@ public: virtual void collect_param_descrs(param_descrs & r) { insert_max_memory(r); - r.insert(":common-patterns", CPK_BOOL, "(default: true) minimize the number of auxiliary variables during CNF encoding by identifing commonly used patterns"); - r.insert(":distributivity", CPK_BOOL, "(default: true) minimize the number of auxiliary variables during CNF encoding by applying distributivity over unshared subformulas"); - r.insert(":distributivity-blowup", CPK_UINT, "(default: 32) maximum overhead for applying distributivity during CNF encoding"); - r.insert("ite-chaing", CPK_BOOL, "(default: true) minimize the number of auxiliary variables during CNF encoding by identifing if-then-else chains"); - r.insert(":ite-extra", CPK_BOOL, "(default: true) add redundant clauses (that improve unit propagation) when encoding if-then-else formulas"); + r.insert("common_patterns", CPK_BOOL, "(default: true) minimize the number of auxiliary variables during CNF encoding by identifing commonly used patterns"); + r.insert("distributivity", CPK_BOOL, "(default: true) minimize the number of auxiliary variables during CNF encoding by applying distributivity over unshared subformulas"); + r.insert("distributivity_blowup", CPK_UINT, "(default: 32) maximum overhead for applying distributivity during CNF encoding"); + r.insert("ite_chaing", CPK_BOOL, "(default: true) minimize the number of auxiliary variables during CNF encoding by identifing if-then-else chains"); + r.insert("ite_extra", CPK_BOOL, "(default: true) add redundant clauses (that improve unit propagation) when encoding if-then-else formulas"); } virtual void operator()(goal_ref const & in, @@ -934,8 +934,8 @@ tactic * mk_tseitin_cnf_core_tactic(ast_manager & m, params_ref const & p) { tactic * mk_tseitin_cnf_tactic(ast_manager & m, params_ref const & p) { params_ref simp_p = p; - simp_p.set_bool(":elim-and", true); - simp_p.set_bool(":blast-distinct", true); + simp_p.set_bool("elim_and", true); + simp_p.set_bool("blast_distinct", true); return or_else(mk_tseitin_cnf_core_tactic(m, p), and_then(using_params(mk_simplify_tactic(m, p), simp_p), mk_tseitin_cnf_core_tactic(m, p))); diff --git a/src/tactic/fpa/fpa2bv_converter.cpp b/src/tactic/fpa/fpa2bv_converter.cpp index 77ff50e9b..8a4b31612 100644 --- a/src/tactic/fpa/fpa2bv_converter.cpp +++ b/src/tactic/fpa/fpa2bv_converter.cpp @@ -105,7 +105,7 @@ void fpa2bv_converter::mk_value(func_decl * f, unsigned num, expr * const * args mk_triple(bv_sgn, bv_sig, biased_exp, result); TRACE("fpa2bv_dbg", tout << "value of [" << sign << " " << m_mpz_manager.to_string(sig) << " " << exp << "] is " - << mk_ismt2_pp(result, m) << std::endl;); + << mk_ismt2_pp(result, m) << std::endl;); } } @@ -1399,6 +1399,13 @@ void fpa2bv_converter::mk_to_float(func_decl * f, unsigned num, expr * const * a } } +void fpa2bv_converter::mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * args, expr_ref & result) { + SASSERT(num == 1); + expr * sgn, * s, * e; + split(args[0], sgn, s, e); + result = m_bv_util.mk_concat(m_bv_util.mk_concat(sgn, e), s); +} + void fpa2bv_converter::split(expr * e, expr * & sgn, expr * & sig, expr * & exp) const { SASSERT(is_app_of(e, m_plugin->get_family_id(), OP_TO_FLOAT)); SASSERT(to_app(e)->get_num_args() == 3); @@ -2035,7 +2042,8 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { tout << bv_mdl->get_constant(i)->get_name() << " --> " << mk_ismt2_pp(bv_mdl->get_const_interp(bv_mdl->get_constant(i)), m) << std::endl; ); - + + obj_hashtable seen; for (obj_map::iterator it = m_const2bv.begin(); it != m_const2bv.end(); @@ -2053,6 +2061,10 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { expr * sig = bv_mdl->get_const_interp(to_app(a->get_arg(1))->get_decl()); expr * exp = bv_mdl->get_const_interp(to_app(a->get_arg(2))->get_decl()); + seen.insert(to_app(a->get_arg(0))->get_decl()); + seen.insert(to_app(a->get_arg(1))->get_decl()); + seen.insert(to_app(a->get_arg(2))->get_decl()); + if (!sgn && !sig && !exp) continue; @@ -2080,7 +2092,7 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { fu.fm().set(fp_val, ebits, sbits, !mpqm.is_zero(sgn_q.to_mpq()), sig_z, exp_z); float_mdl->register_decl(var, fu.mk_value(fp_val)); - + mpzm.del(sig_z); } @@ -2104,9 +2116,36 @@ void fpa2bv_model_converter::convert(model * bv_mdl, model * float_mdl) { case BV_RM_TO_POSITIVE: float_mdl->register_decl(var, fu.mk_round_toward_positive()); break; case BV_RM_TO_ZERO: default: float_mdl->register_decl(var, fu.mk_round_toward_zero()); - } + } + seen.insert(var); } } fu.fm().del(fp_val); + + // Keep all the non-float constants. + unsigned sz = bv_mdl->get_num_constants(); + for (unsigned i = 0; i < sz; i++) + { + func_decl * c = bv_mdl->get_constant(i); + if (seen.contains(c)) + continue; + float_mdl->register_decl(c, bv_mdl->get_const_interp(c)); + } + + // And keep everything else + sz = bv_mdl->get_num_functions(); + for (unsigned i = 0; i < sz; i++) + { + func_decl * c = bv_mdl->get_function(i); + float_mdl->register_decl(c, bv_mdl->get_const_interp(c)); + } + + sz = bv_mdl->get_num_uninterpreted_sorts(); + for (unsigned i = 0; i < sz; i++) + { + sort * s = bv_mdl->get_uninterpreted_sort(i); + ptr_vector u = bv_mdl->get_universe(s); + float_mdl->register_usort(s, u.size(), u.c_ptr()); + } } diff --git a/src/tactic/fpa/fpa2bv_converter.h b/src/tactic/fpa/fpa2bv_converter.h index 291120e92..1ee374941 100644 --- a/src/tactic/fpa/fpa2bv_converter.h +++ b/src/tactic/fpa/fpa2bv_converter.h @@ -100,6 +100,7 @@ public: void mk_is_sign_minus(func_decl * f, unsigned num, expr * const * args, expr_ref & result); void mk_to_float(func_decl * f, unsigned num, expr * const * args, expr_ref & result); + void mk_to_ieee_bv(func_decl * f, unsigned num, expr * const * args, expr_ref & result); fpa2bv_model_converter * mk_model_converter(); diff --git a/src/tactic/fpa/fpa2bv_rewriter.h b/src/tactic/fpa/fpa2bv_rewriter.h index 62c6f1a2d..94694867a 100644 --- a/src/tactic/fpa/fpa2bv_rewriter.h +++ b/src/tactic/fpa/fpa2bv_rewriter.h @@ -54,8 +54,8 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { } void updt_params(params_ref const & p) { - m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX)); - m_max_steps = p.get_uint(":max-steps", UINT_MAX); + m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX)); + m_max_steps = p.get_uint("max_steps", UINT_MAX); } bool max_steps_exceeded(unsigned num_steps) const { @@ -129,6 +129,7 @@ struct fpa2bv_rewriter_cfg : public default_rewriter_cfg { case OP_FLOAT_IS_PZERO: m_conv.mk_is_pzero(f, num, args, result); return BR_DONE; case OP_FLOAT_IS_SIGN_MINUS: m_conv.mk_is_sign_minus(f, num, args, result); return BR_DONE; case OP_TO_FLOAT: m_conv.mk_to_float(f, num, args, result); return BR_DONE; + case OP_TO_IEEE_BV: m_conv.mk_to_ieee_bv(f, num, args, result); return BR_DONE; default: TRACE("fpa2bv", tout << "unsupported operator: " << f->get_name() << "\n"; for (unsigned i = 0; i < num; i++) tout << mk_ismt2_pp(args[i], m()) << std::endl;); diff --git a/src/tactic/fpa/qffpa_tactic.cpp b/src/tactic/fpa/qffpa_tactic.cpp index d034000c4..f3c913ccc 100644 --- a/src/tactic/fpa/qffpa_tactic.cpp +++ b/src/tactic/fpa/qffpa_tactic.cpp @@ -26,7 +26,7 @@ Notes: tactic * mk_qffpa_tactic(ast_manager & m, params_ref const & p) { params_ref sat_simp_p = p; - sat_simp_p .set_bool(":elim-and", true); + sat_simp_p .set_bool("elim_and", true); return and_then(mk_simplify_tactic(m, p), mk_fpa2bv_tactic(m, p), diff --git a/src/tactic/fpa/qffpa_tactic.h b/src/tactic/fpa/qffpa_tactic.h index 660565463..8ca2183c1 100644 --- a/src/tactic/fpa/qffpa_tactic.h +++ b/src/tactic/fpa/qffpa_tactic.h @@ -27,6 +27,7 @@ class tactic; tactic * mk_qffpa_tactic(ast_manager & m, params_ref const & p = params_ref()); /* ADD_TACTIC("qffpa", "(try to) solve goal using the tactic for QF_FPA.", "mk_qffpa_tactic(m, p)") + ADD_TACTIC("qffpabv", "(try to) solve goal using the tactic for QF_FPABV (floats+bit-vectors).", "mk_qffpa_tactic(m, p)") */ #endif diff --git a/src/tactic/portfolio/smt_strategic_solver.cpp b/src/tactic/portfolio/smt_strategic_solver.cpp index 4cf530b1e..7a274a830 100644 --- a/src/tactic/portfolio/smt_strategic_solver.cpp +++ b/src/tactic/portfolio/smt_strategic_solver.cpp @@ -79,6 +79,7 @@ static void init(strategic_solver * s) { s->set_tactic_for(symbol("UFBV"), alloc(ufbv_fct)); s->set_tactic_for(symbol("BV"), alloc(ufbv_fct)); s->set_tactic_for(symbol("QF_FPA"), alloc(qffpa_fct)); + s->set_tactic_for(symbol("QF_FPABV"), alloc(qffpa_fct)); s->set_tactic_for(symbol("HORN"), alloc(horn_fct)); } diff --git a/src/tactic/sls/sls_tactic.cpp b/src/tactic/sls/sls_tactic.cpp index 0ad845095..f49ce8422 100644 --- a/src/tactic/sls/sls_tactic.cpp +++ b/src/tactic/sls/sls_tactic.cpp @@ -1363,16 +1363,16 @@ class sls_tactic : public tactic { static void collect_param_descrs(param_descrs & r) { insert_produce_models(r); - r.insert(":sls-restarts", CPK_UINT, "(default: infty) # of SLS restarts."); - r.insert(":random-seed", CPK_UINT, "(default: 0) random seed."); - r.insert(":plateau-limit", CPK_UINT, "(default: 100) SLS plateau limit."); + r.insert("sls_restarts", CPK_UINT, "(default: infty) # of SLS restarts."); + r.insert("random_seed", CPK_UINT, "(default: 0) random seed."); + r.insert("plateau_limit", CPK_UINT, "(default: 100) SLS plateau limit."); } void updt_params(params_ref const & p) { - m_produce_models = p.get_bool(":produce-models", false); - m_max_restarts = p.get_uint(":sls-restarts", -1); - m_tracker.set_random_seed(p.get_uint(":random-seed", 0)); - m_plateau_limit = p.get_uint(":plateau-limit", 100); + m_produce_models = p.get_bool("produce_models", false); + m_max_restarts = p.get_uint("sls_restarts", -1); + m_tracker.set_random_seed(p.get_uint("random_seed", 0)); + m_plateau_limit = p.get_uint("plateau_limit", 100); } void checkpoint() { @@ -1854,28 +1854,28 @@ tactic * mk_sls_tactic(ast_manager & m, params_ref const & p) { tactic * mk_preamble(ast_manager & m, params_ref const & p) { params_ref main_p; - main_p.set_bool(":elim-and", true); - // main_p.set_bool(":pull-cheap-ite", true); - main_p.set_bool(":push-ite-bv", true); - main_p.set_bool(":blast-distinct", true); - // main_p.set_bool(":udiv2mul", true); - main_p.set_bool(":hi-div0", true); + main_p.set_bool("elim_and", true); + // main_p.set_bool("pull_cheap_ite", true); + main_p.set_bool("push_ite_bv", true); + main_p.set_bool("blast_distinct", true); + // main_p.set_bool("udiv2mul", true); + main_p.set_bool("hi_div0", true); params_ref simp2_p = p; - simp2_p.set_bool(":som", true); - simp2_p.set_bool(":pull-cheap-ite", true); - simp2_p.set_bool(":push-ite-bv", false); - simp2_p.set_bool(":local-ctx", true); - simp2_p.set_uint(":local-ctx-limit", 10000000); + simp2_p.set_bool("som", true); + simp2_p.set_bool("pull_cheap_ite", true); + simp2_p.set_bool("push_ite_bv", false); + simp2_p.set_bool("local_ctx", true); + simp2_p.set_uint("local_ctx_limit", 10000000); params_ref hoist_p; - hoist_p.set_bool(":hoist-mul", true); - // hoist_p.set_bool(":hoist-cmul", true); - hoist_p.set_bool(":som", false); + hoist_p.set_bool("hoist_mul", true); + // hoist_p.set_bool("hoist_cmul", true); + hoist_p.set_bool("som", false); params_ref gaussian_p; // conservative gaussian elimination. - gaussian_p.set_uint(":gaussian-max-occs", 2); + gaussian_p.set_uint("gaussian_max_occs", 2); return and_then(and_then(mk_simplify_tactic(m), mk_propagate_values_tactic(m), @@ -1890,8 +1890,8 @@ tactic * mk_preamble(ast_manager & m, params_ref const & p) { tactic * mk_qfbv_sls_tactic(ast_manager & m, params_ref const & p) { params_ref sls_p(p); - sls_p.set_uint(":sls-restarts", 10000); - sls_p.set_uint(":plateau-limit", 100); + sls_p.set_uint("sls_restarts", 10000); + sls_p.set_uint("plateau_limit", 100); tactic * t = and_then(mk_preamble(m, p), using_params(mk_sls_tactic(m, p), sls_p)); diff --git a/src/tactic/smtlogics/nra_tactic.cpp b/src/tactic/smtlogics/nra_tactic.cpp index 623b7e55e..845b6bfec 100644 --- a/src/tactic/smtlogics/nra_tactic.cpp +++ b/src/tactic/smtlogics/nra_tactic.cpp @@ -27,11 +27,11 @@ Notes: tactic * mk_nra_tactic(ast_manager & m, params_ref const& p) { params_ref p1 = p; - p1.set_uint(":seed", 11); - p1.set_bool(":factor", false); + p1.set_uint("seed", 11); + p1.set_bool("factor", false); params_ref p2 = p; - p2.set_uint(":seed", 13); - p2.set_bool(":factor", false); + p2.set_uint("seed", 13); + p2.set_bool("factor", false); return and_then(mk_simplify_tactic(m, p), mk_nnf_tactic(m, p), diff --git a/src/tactic/smtlogics/qfaufbv_tactic.cpp b/src/tactic/smtlogics/qfaufbv_tactic.cpp index 5f371da0c..cb14fa778 100644 --- a/src/tactic/smtlogics/qfaufbv_tactic.cpp +++ b/src/tactic/smtlogics/qfaufbv_tactic.cpp @@ -29,22 +29,22 @@ Notes: tactic * mk_qfaufbv_tactic(ast_manager & m, params_ref const & p) { params_ref main_p; - main_p.set_bool(":elim-and", true); - main_p.set_bool(":sort-store", true); + main_p.set_bool("elim_and", true); + main_p.set_bool("sort_store", true); params_ref simp2_p = p; - simp2_p.set_bool(":som", true); - simp2_p.set_bool(":pull-cheap-ite", true); - simp2_p.set_bool(":push-ite-bv", false); - simp2_p.set_bool(":local-ctx", true); - simp2_p.set_uint(":local-ctx-limit", 10000000); + simp2_p.set_bool("som", true); + simp2_p.set_bool("pull_cheap_ite", true); + simp2_p.set_bool("push_ite_bv", false); + simp2_p.set_bool("local_ctx", true); + simp2_p.set_uint("local_ctx_limit", 10000000); params_ref ctx_simp_p; - ctx_simp_p.set_uint(":max-depth", 32); - ctx_simp_p.set_uint(":max-steps", 5000000); + ctx_simp_p.set_uint("max_depth", 32); + ctx_simp_p.set_uint("max_steps", 5000000); params_ref solver_p; - solver_p.set_bool(":array-old-simplifier", false); + solver_p.set_bool("array.simplify", false); // disable array simplifications at old_simplify module tactic * preamble_st = and_then(mk_simplify_tactic(m), mk_propagate_values_tactic(m), diff --git a/src/tactic/smtlogics/qfauflia_tactic.cpp b/src/tactic/smtlogics/qfauflia_tactic.cpp index 422be13d5..89f96d354 100644 --- a/src/tactic/smtlogics/qfauflia_tactic.cpp +++ b/src/tactic/smtlogics/qfauflia_tactic.cpp @@ -26,16 +26,16 @@ Notes: tactic * mk_qfauflia_tactic(ast_manager & m, params_ref const & p) { params_ref main_p; - main_p.set_bool(":elim-and", true); - main_p.set_bool(":som", true); - main_p.set_bool(":sort-store", true); + main_p.set_bool("elim_and", true); + main_p.set_bool("som", true); + main_p.set_bool("sort_store", true); params_ref ctx_simp_p; - ctx_simp_p.set_uint(":max-depth", 30); - ctx_simp_p.set_uint(":max-steps", 5000000); + ctx_simp_p.set_uint("max_depth", 30); + ctx_simp_p.set_uint("max_steps", 5000000); params_ref solver_p; - solver_p.set_bool(":array-old-simplifier", false); + solver_p.set_bool("array.simplify", false); // disable array simplifications at old_simplify module tactic * preamble_st = and_then(mk_simplify_tactic(m), mk_propagate_values_tactic(m), diff --git a/src/tactic/smtlogics/qfbv_tactic.cpp b/src/tactic/smtlogics/qfbv_tactic.cpp index 5924c5bdf..51b040332 100644 --- a/src/tactic/smtlogics/qfbv_tactic.cpp +++ b/src/tactic/smtlogics/qfbv_tactic.cpp @@ -33,40 +33,40 @@ Notes: tactic * mk_qfbv_tactic(ast_manager & m, params_ref const & p) { params_ref main_p; - main_p.set_bool(":elim-and", true); - main_p.set_bool(":push-ite-bv", true); - main_p.set_bool(":blast-distinct", true); + main_p.set_bool("elim_and", true); + main_p.set_bool("push_ite_bv", true); + main_p.set_bool("blast_distinct", true); params_ref simp2_p = p; - simp2_p.set_bool(":som", true); - simp2_p.set_bool(":pull-cheap-ite", true); - simp2_p.set_bool(":push-ite-bv", false); - simp2_p.set_bool(":local-ctx", true); - simp2_p.set_uint(":local-ctx-limit", 10000000); + simp2_p.set_bool("som", true); + simp2_p.set_bool("pull_cheap_ite", true); + simp2_p.set_bool("push_ite_bv", false); + simp2_p.set_bool("local_ctx", true); + simp2_p.set_uint("local_ctx_limit", 10000000); params_ref local_ctx_p = p; - local_ctx_p.set_bool(":local-ctx", true); + local_ctx_p.set_bool("local_ctx", true); params_ref solver_p; - solver_p.set_bool(":preprocess", false); // preprocessor of smt::context is not needed. + solver_p.set_bool("preprocess", false); // preprocessor of smt::context is not needed. params_ref no_flat_p; - no_flat_p.set_bool(":flat", false); + no_flat_p.set_bool("flat", false); params_ref ctx_simp_p; - ctx_simp_p.set_uint(":max-depth", 32); - ctx_simp_p.set_uint(":max-steps", 50000000); + ctx_simp_p.set_uint("max_depth", 32); + ctx_simp_p.set_uint("max_steps", 50000000); params_ref hoist_p; - hoist_p.set_bool(":hoist-mul", true); - hoist_p.set_bool(":som", false); + hoist_p.set_bool("hoist_mul", true); + hoist_p.set_bool("som", false); params_ref solve_eq_p; // conservative guassian elimination. - solve_eq_p.set_uint(":solve-eqs-max-occs", 2); + solve_eq_p.set_uint("solve_eqs_max_occs", 2); params_ref big_aig_p; - big_aig_p.set_bool(":aig-per-assertion", false); + big_aig_p.set_bool("aig_per_assertion", false); tactic * preamble_st = and_then(and_then(mk_simplify_tactic(m), mk_propagate_values_tactic(m), @@ -74,7 +74,7 @@ tactic * mk_qfbv_tactic(ast_manager & m, params_ref const & p) { mk_elim_uncnstr_tactic(m), if_no_proofs(if_no_unsat_cores(mk_bv_size_reduction_tactic(m))), using_params(mk_simplify_tactic(m), simp2_p)), - // Z3 can solve a couple of extra benchmarks by using :hoist-mul + // Z3 can solve a couple of extra benchmarks by using hoist_mul // but the timeout in SMT-COMP is too small. // Moreover, it impacted negatively some easy benchmarks. // We should decide later, if we keep it or not. diff --git a/src/tactic/smtlogics/qfidl_tactic.cpp b/src/tactic/smtlogics/qfidl_tactic.cpp index 57aef4991..de05797e8 100644 --- a/src/tactic/smtlogics/qfidl_tactic.cpp +++ b/src/tactic/smtlogics/qfidl_tactic.cpp @@ -37,23 +37,23 @@ Notes: tactic * mk_qfidl_tactic(ast_manager & m, params_ref const & p) { params_ref main_p; - main_p.set_bool(":elim-and", true); - main_p.set_bool(":blast-distinct", true); - main_p.set_bool(":som", true); + main_p.set_bool("elim_and", true); + main_p.set_bool("blast_distinct", true); + main_p.set_bool("som", true); params_ref lhs_p; - lhs_p.set_bool(":arith-lhs", true); + lhs_p.set_bool("arith_lhs", true); params_ref lia2pb_p; - lia2pb_p.set_uint(":lia2pb-max-bits", 4); + lia2pb_p.set_uint("lia2pb_max_bits", 4); params_ref pb2bv_p; - pb2bv_p.set_uint(":pb2bv-all-clauses-limit", 8); + pb2bv_p.set_uint("pb2bv_all_clauses_limit", 8); params_ref pull_ite_p; - pull_ite_p.set_bool(":pull-cheap-ite", true); - pull_ite_p.set_bool(":local-ctx", true); - pull_ite_p.set_uint(":local-ctx-limit", 10000000); + pull_ite_p.set_bool("pull_cheap_ite", true); + pull_ite_p.set_bool("local_ctx", true); + pull_ite_p.set_uint("local_ctx_limit", 10000000); tactic * preamble_st = and_then(and_then(mk_simplify_tactic(m), mk_fix_dl_var_tactic(m), @@ -71,10 +71,10 @@ tactic * mk_qfidl_tactic(ast_manager & m, params_ref const & p) { params_ref bv_solver_p; // The cardinality constraint encoding generates a lot of shared if-then-else's that can be flattened. // Several of them are simplified to and/or. If we flat them, we increase a lot the memory consumption. - bv_solver_p.set_bool(":flat", false); - bv_solver_p.set_bool(":som", false); + bv_solver_p.set_bool("flat", false); + bv_solver_p.set_bool("som", false); // dynamic psm seems to work well. - bv_solver_p.set_sym(":gc-strategy", symbol("dyn-psm")); + bv_solver_p.set_sym("gc", symbol("dyn_psm")); tactic * bv_solver = using_params(and_then(mk_simplify_tactic(m), mk_propagate_values_tactic(m), @@ -93,7 +93,7 @@ tactic * mk_qfidl_tactic(ast_manager & m, params_ref const & p) { bv_solver); params_ref diff_neq_p; - diff_neq_p.set_uint(":diff-neq-max-k", 25); + diff_neq_p.set_uint("diff_neq_max_k", 25); tactic * st = cond(mk_and(mk_lt(mk_num_consts_probe(), mk_const_probe(static_cast(BIG_PROBLEM))), mk_and(mk_not(mk_produce_proofs_probe()), diff --git a/src/tactic/smtlogics/qflia_tactic.cpp b/src/tactic/smtlogics/qflia_tactic.cpp index 1fb30faae..6b05cff96 100644 --- a/src/tactic/smtlogics/qflia_tactic.cpp +++ b/src/tactic/smtlogics/qflia_tactic.cpp @@ -64,17 +64,17 @@ probe * mk_quasi_pb_probe() { // Create SMT solver that does not use cuts static tactic * mk_no_cut_smt_tactic(unsigned rs) { params_ref solver_p; - solver_p.set_uint(":arith-branch-cut-ratio", 10000000); - solver_p.set_uint(":random-seed", rs); + solver_p.set_uint("arith.branch_cut_ratio", 10000000); + solver_p.set_uint("random_seed", rs); return using_params(mk_smt_tactic_using(false), solver_p); } // Create SMT solver that does not use cuts static tactic * mk_no_cut_no_relevancy_smt_tactic(unsigned rs) { params_ref solver_p; - solver_p.set_uint(":arith-branch-cut-ratio", 10000000); - solver_p.set_uint(":random-seed", rs); - solver_p.set_uint(":relevancy", 0); + solver_p.set_uint("arith.branch_cut_ratio", 10000000); + solver_p.set_uint("random_seed", rs); + solver_p.set_uint("relevancy", 0); return using_params(mk_smt_tactic_using(false), solver_p); } @@ -82,10 +82,10 @@ static tactic * mk_bv2sat_tactic(ast_manager & m) { params_ref solver_p; // The cardinality constraint encoding generates a lot of shared if-then-else's that can be flattened. // Several of them are simplified to and/or. If we flat them, we increase a lot the memory consumption. - solver_p.set_bool(":flat", false); - solver_p.set_bool(":som", false); + solver_p.set_bool("flat", false); + solver_p.set_bool("som", false); // dynamic psm seems to work well. - solver_p.set_sym(":gc-strategy", symbol("dyn-psm")); + solver_p.set_sym("gc", symbol("dyn_psm")); return using_params(and_then(mk_simplify_tactic(m), mk_propagate_values_tactic(m), @@ -101,8 +101,8 @@ static tactic * mk_bv2sat_tactic(ast_manager & m) { static tactic * mk_pb_tactic(ast_manager & m) { params_ref pb2bv_p; - pb2bv_p.set_bool(":ite-extra", true); - pb2bv_p.set_uint(":pb2bv-all-clauses-limit", 8); + pb2bv_p.set_bool("ite_extra", true); + pb2bv_p.set_uint("pb2bv_all_clauses_limit", 8); return and_then(fail_if_not(mk_is_pb_probe()), fail_if(mk_produce_proofs_probe()), @@ -119,8 +119,8 @@ static tactic * mk_pb_tactic(ast_manager & m) { static tactic * mk_lia2sat_tactic(ast_manager & m) { params_ref pb2bv_p; - pb2bv_p.set_bool(":ite-extra", true); - pb2bv_p.set_uint(":pb2bv-all-clauses-limit", 8); + pb2bv_p.set_bool("ite_extra", true); + pb2bv_p.set_uint("pb2bv_all_clauses_limit", 8); return and_then(fail_if(mk_is_unbounded_probe()), fail_if(mk_produce_proofs_probe()), @@ -137,11 +137,11 @@ static tactic * mk_lia2sat_tactic(ast_manager & m) { // Fails if the problem is no ILP. static tactic * mk_ilp_model_finder_tactic(ast_manager & m) { params_ref add_bounds_p1; - add_bounds_p1.set_rat(":add-bound-lower", rational(-16)); - add_bounds_p1.set_rat(":add-bound-upper", rational(15)); + add_bounds_p1.set_rat("add_bound_lower", rational(-16)); + add_bounds_p1.set_rat("add_bound_upper", rational(15)); params_ref add_bounds_p2; - add_bounds_p2.set_rat(":add-bound-lower", rational(-32)); - add_bounds_p2.set_rat(":add-bound-upper", rational(31)); + add_bounds_p2.set_rat("add_bound_lower", rational(-32)); + add_bounds_p2.set_rat("add_bound_upper", rational(31)); return and_then(fail_if_not(mk_and(mk_is_ilp_probe(), mk_is_unbounded_probe())), fail_if(mk_produce_proofs_probe()), @@ -170,22 +170,22 @@ static tactic * mk_bounded_tactic(ast_manager & m) { tactic * mk_qflia_tactic(ast_manager & m, params_ref const & p) { params_ref main_p; - main_p.set_bool(":elim-and", true); - main_p.set_bool(":som", true); - // main_p.set_bool(":push-ite-arith", true); + main_p.set_bool("elim_and", true); + main_p.set_bool("som", true); + // main_p.set_bool("push_ite_arith", true); params_ref pull_ite_p; - pull_ite_p.set_bool(":pull-cheap-ite", true); - pull_ite_p.set_bool(":push-ite-arith", false); - pull_ite_p.set_bool(":local-ctx", true); - pull_ite_p.set_uint(":local-ctx-limit", 10000000); + pull_ite_p.set_bool("pull_cheap_ite", true); + pull_ite_p.set_bool("push_ite_arith", false); + pull_ite_p.set_bool("local_ctx", true); + pull_ite_p.set_uint("local_ctx_limit", 10000000); params_ref ctx_simp_p; - ctx_simp_p.set_uint(":max-depth", 30); - ctx_simp_p.set_uint(":max-steps", 5000000); + ctx_simp_p.set_uint("max_depth", 30); + ctx_simp_p.set_uint("max_steps", 5000000); params_ref lhs_p; - lhs_p.set_bool(":arith-lhs", true); + lhs_p.set_bool("arith_lhs", true); tactic * preamble_st = and_then(and_then(mk_simplify_tactic(m), mk_propagate_values_tactic(m), @@ -197,10 +197,10 @@ tactic * mk_qflia_tactic(ast_manager & m, params_ref const & p) { ); params_ref quasi_pb_p; - quasi_pb_p.set_uint(":lia2pb-max-bits", 64); + quasi_pb_p.set_uint("lia2pb_max_bits", 64); params_ref no_cut_p; - no_cut_p.set_uint(":arith-branch-cut-ratio", 10000000); + no_cut_p.set_uint("arith.branch_cut_ratio", 10000000); tactic * st = using_params(and_then(preamble_st, diff --git a/src/tactic/smtlogics/qflra_tactic.cpp b/src/tactic/smtlogics/qflra_tactic.cpp index 42aaa96b7..41f0e16f3 100644 --- a/src/tactic/smtlogics/qflra_tactic.cpp +++ b/src/tactic/smtlogics/qflra_tactic.cpp @@ -29,23 +29,23 @@ Notes: tactic * mk_qflra_tactic(ast_manager & m, params_ref const & p) { params_ref pivot_p; - pivot_p.set_bool(":arith-greatest-error-pivot", true); + pivot_p.set_bool("arith.greatest_error_pivot", true); params_ref main_p = p; - main_p.set_bool(":elim-and", true); - main_p.set_bool(":som", true); - main_p.set_bool(":blast-distinct", true); + main_p.set_bool("elim_and", true); + main_p.set_bool("som", true); + main_p.set_bool("blast_distinct", true); params_ref ctx_simp_p; - ctx_simp_p.set_uint(":max-depth", 30); - ctx_simp_p.set_uint(":max-steps", 5000000); + ctx_simp_p.set_uint("max_depth", 30); + ctx_simp_p.set_uint("max_steps", 5000000); params_ref lhs_p; - lhs_p.set_bool(":arith-lhs", true); - lhs_p.set_bool(":eq2ineq", true); + lhs_p.set_bool("arith_lhs", true); + lhs_p.set_bool("eq2ineq", true); params_ref elim_to_real_p; - elim_to_real_p.set_bool(":elim-to-real", true); + elim_to_real_p.set_bool("elim_to_real", true); #if 0 diff --git a/src/tactic/smtlogics/qfnia_tactic.cpp b/src/tactic/smtlogics/qfnia_tactic.cpp index e87d36503..950291221 100644 --- a/src/tactic/smtlogics/qfnia_tactic.cpp +++ b/src/tactic/smtlogics/qfnia_tactic.cpp @@ -31,14 +31,14 @@ Notes: tactic * mk_qfnia_bv_solver(ast_manager & m, params_ref const & p_ref) { params_ref p = p_ref; - p.set_bool(":flat", false); - p.set_bool(":hi-div0", true); - p.set_bool(":elim-and", true); - p.set_bool(":blast-distinct", true); + p.set_bool("flat", false); + p.set_bool("hi_div0", true); + p.set_bool("elim_and", true); + p.set_bool("blast_distinct", true); params_ref simp2_p = p; - simp2_p.set_bool(":local-ctx", true); - simp2_p.set_uint(":local-ctx-limit", 10000000); + simp2_p.set_bool("local_ctx", true); + simp2_p.set_uint("local_ctx_limit", 10000000); tactic * r = using_params(and_then(mk_simplify_tactic(m), @@ -53,19 +53,19 @@ tactic * mk_qfnia_bv_solver(ast_manager & m, params_ref const & p_ref) { tactic * mk_qfnia_premable(ast_manager & m, params_ref const & p_ref) { params_ref pull_ite_p = p_ref; - pull_ite_p.set_bool(":pull-cheap-ite", true); - pull_ite_p.set_bool(":local-ctx", true); - pull_ite_p.set_uint(":local-ctx-limit", 10000000); + pull_ite_p.set_bool("pull_cheap_ite", true); + pull_ite_p.set_bool("local_ctx", true); + pull_ite_p.set_uint("local_ctx_limit", 10000000); params_ref ctx_simp_p = p_ref; - ctx_simp_p.set_uint(":max-depth", 30); - ctx_simp_p.set_uint(":max-steps", 5000000); + ctx_simp_p.set_uint("max_depth", 30); + ctx_simp_p.set_uint("max_steps", 5000000); params_ref simp_p = p_ref; - simp_p.set_bool(":hoist-mul", true); + simp_p.set_bool("hoist_mul", true); params_ref elim_p = p_ref; - elim_p.set_uint(":max-memory",20); + elim_p.set_uint("max_memory",20); return and_then(mk_simplify_tactic(m), @@ -79,7 +79,7 @@ tactic * mk_qfnia_premable(ast_manager & m, params_ref const & p_ref) { tactic * mk_qfnia_sat_solver(ast_manager & m, params_ref const & p) { params_ref nia2sat_p = p; - nia2sat_p.set_uint(":nla2bv-max-bv-size", 64); + nia2sat_p.set_uint("nla2bv_max_bv_size", 64); return and_then(mk_nla2bv_tactic(m, nia2sat_p), mk_qfnia_bv_solver(m, p), diff --git a/src/tactic/smtlogics/qfnra_tactic.cpp b/src/tactic/smtlogics/qfnra_tactic.cpp index d13d9e198..716b4868b 100644 --- a/src/tactic/smtlogics/qfnra_tactic.cpp +++ b/src/tactic/smtlogics/qfnra_tactic.cpp @@ -25,7 +25,7 @@ Notes: static tactic * mk_qfnra_sat_solver(ast_manager& m, params_ref const& p, unsigned bv_size) { params_ref nra2sat_p = p; - nra2sat_p.set_uint(":nla2bv-max-bv-size", p.get_uint(":nla2bv-max-bv-size", bv_size)); + nra2sat_p.set_uint("nla2bv_max_bv_size", p.get_uint("nla2bv_max_bv_size", bv_size)); return and_then(mk_nla2bv_tactic(m, nra2sat_p), mk_smt_tactic(), @@ -34,11 +34,11 @@ static tactic * mk_qfnra_sat_solver(ast_manager& m, params_ref const& p, unsigne tactic * mk_qfnra_tactic(ast_manager & m, params_ref const& p) { params_ref p1 = p; - p1.set_uint(":seed", 11); - p1.set_bool(":factor", false); + p1.set_uint("seed", 11); + p1.set_bool("factor", false); params_ref p2 = p; - p2.set_uint(":seed", 13); - p2.set_bool(":factor", false); + p2.set_uint("seed", 13); + p2.set_bool("factor", false); return and_then(mk_simplify_tactic(m, p), mk_propagate_values_tactic(m, p), diff --git a/src/tactic/smtlogics/qfuf_tactic.cpp b/src/tactic/smtlogics/qfuf_tactic.cpp index 3acfb8d98..567325f6a 100644 --- a/src/tactic/smtlogics/qfuf_tactic.cpp +++ b/src/tactic/smtlogics/qfuf_tactic.cpp @@ -26,9 +26,9 @@ Notes: tactic * mk_qfuf_tactic(ast_manager & m, params_ref const & p) { params_ref s2_p; - s2_p.set_bool(":pull-cheap-ite", true); - s2_p.set_bool(":local-ctx", true); - s2_p.set_uint(":local-ctx-limit", 10000000); + s2_p.set_bool("pull_cheap_ite", true); + s2_p.set_bool("local_ctx", true); + s2_p.set_uint("local_ctx_limit", 10000000); return and_then(mk_simplify_tactic(m, p), mk_propagate_values_tactic(m, p), mk_solve_eqs_tactic(m, p), diff --git a/src/tactic/smtlogics/qfufbv_tactic.cpp b/src/tactic/smtlogics/qfufbv_tactic.cpp index 400ff9891..d10b7c1b4 100644 --- a/src/tactic/smtlogics/qfufbv_tactic.cpp +++ b/src/tactic/smtlogics/qfufbv_tactic.cpp @@ -28,8 +28,8 @@ Notes: tactic * mk_qfufbv_tactic(ast_manager & m, params_ref const & p) { params_ref main_p; - main_p.set_bool(":elim-and", true); - main_p.set_bool(":blast-distinct", true); + main_p.set_bool("elim_and", true); + main_p.set_bool("blast_distinct", true); tactic * preamble_st = and_then(mk_simplify_tactic(m), mk_propagate_values_tactic(m), diff --git a/src/tactic/smtlogics/quant_tactics.cpp b/src/tactic/smtlogics/quant_tactics.cpp index 157202442..6b5ede813 100644 --- a/src/tactic/smtlogics/quant_tactics.cpp +++ b/src/tactic/smtlogics/quant_tactics.cpp @@ -27,13 +27,13 @@ Revision History: static tactic * mk_quant_preprocessor(ast_manager & m, bool disable_gaussian = false) { params_ref pull_ite_p; - pull_ite_p.set_bool(":pull-cheap-ite", true); - pull_ite_p.set_bool(":local-ctx", true); - pull_ite_p.set_uint(":local-ctx-limit", 10000000); + pull_ite_p.set_bool("pull_cheap_ite", true); + pull_ite_p.set_bool("local_ctx", true); + pull_ite_p.set_uint("local_ctx_limit", 10000000); params_ref ctx_simp_p; - ctx_simp_p.set_uint(":max-depth", 30); - ctx_simp_p.set_uint(":max-steps", 5000000); + ctx_simp_p.set_uint("max_depth", 30); + ctx_simp_p.set_uint("max_steps", 5000000); tactic * solve_eqs; if (disable_gaussian) @@ -71,8 +71,8 @@ tactic * mk_uflra_tactic(ast_manager & m, params_ref const & p) { tactic * mk_auflia_tactic(ast_manager & m, params_ref const & p) { params_ref qi_p; - qi_p.set_str(":qi-cost", "0"); - TRACE("qi_cost", qi_p.display(tout); tout << "\n" << qi_p.get_str(":qi-cost", "") << "\n";); + qi_p.set_str("qi.cost", "0"); + TRACE("qi_cost", qi_p.display(tout); tout << "\n" << qi_p.get_str("qi.cost", "") << "\n";); tactic * st = and_then(mk_no_solve_eq_preprocessor(m), or_else(and_then(fail_if(mk_gt(mk_num_exprs_probe(), mk_const_probe(static_cast(128)))), using_params(mk_smt_tactic(), qi_p), diff --git a/src/tactic/tactic.h b/src/tactic/tactic.h index cb2c3f515..80de1bcd0 100644 --- a/src/tactic/tactic.h +++ b/src/tactic/tactic.h @@ -29,7 +29,6 @@ Notes: #include"tactic_exception.h" #include"lbool.h" -struct front_end_params; class progress_callback; typedef ptr_buffer goal_buffer; @@ -92,7 +91,6 @@ public: virtual void reset() { cleanup(); } // for backward compatibility - virtual void set_front_end_params(front_end_params & p) {} virtual void set_logic(symbol const & l) {} virtual void set_progress_callback(progress_callback * callback) {} diff --git a/src/tactic/tactical.cpp b/src/tactic/tactical.cpp index 30e05bd26..0d61f0916 100644 --- a/src/tactic/tactical.cpp +++ b/src/tactic/tactical.cpp @@ -87,11 +87,6 @@ public: m_t2->reset(); } - virtual void set_front_end_params(front_end_params & p) { - m_t1->set_front_end_params(p); - m_t2->set_front_end_params(p); - } - virtual void set_logic(symbol const & l) { m_t1->set_logic(l); m_t2->set_logic(l); @@ -380,13 +375,6 @@ public: (*it)->reset(); } - virtual void set_front_end_params(front_end_params & p) { - ptr_vector::iterator it = m_ts.begin(); - ptr_vector::iterator end = m_ts.end(); - for (; it != end; ++it) - (*it)->set_front_end_params(p); - } - virtual void set_logic(symbol const & l) { ptr_vector::iterator it = m_ts.begin(); ptr_vector::iterator end = m_ts.end(); @@ -992,7 +980,6 @@ public: virtual void cleanup(void) { m_t->cleanup(); } virtual void collect_statistics(statistics & st) const { m_t->collect_statistics(st); } virtual void reset_statistics() { m_t->reset_statistics(); } - virtual void set_front_end_params(front_end_params & p) { m_t->set_front_end_params(p); } virtual void updt_params(params_ref const & p) { m_t->updt_params(p); } virtual void collect_param_descrs(param_descrs & r) { m_t->collect_param_descrs(r); } virtual void reset() { m_t->reset(); } diff --git a/src/tactic/ufbv/macro_finder_tactic.cpp b/src/tactic/ufbv/macro_finder_tactic.cpp index 3872a3a2e..14a42ec51 100644 --- a/src/tactic/ufbv/macro_finder_tactic.cpp +++ b/src/tactic/ufbv/macro_finder_tactic.cpp @@ -102,7 +102,7 @@ class macro_finder_tactic : public tactic { } void updt_params(params_ref const & p) { - m_elim_and = p.get_bool(":elim-and", false); + m_elim_and = p.get_bool("elim_and", false); } }; @@ -131,7 +131,7 @@ public: insert_max_memory(r); insert_produce_models(r); insert_produce_proofs(r); - r.insert(":elim-and", CPK_BOOL, "(default: false) eliminate conjunctions during (internal) calls to the simplifier."); + r.insert("elim_and", CPK_BOOL, "(default: false) eliminate conjunctions during (internal) calls to the simplifier."); } virtual void operator()(goal_ref const & in, diff --git a/src/tactic/ufbv/ufbv_tactic.cpp b/src/tactic/ufbv/ufbv_tactic.cpp index 85ec506aa..80d403b67 100644 --- a/src/tactic/ufbv/ufbv_tactic.cpp +++ b/src/tactic/ufbv/ufbv_tactic.cpp @@ -37,7 +37,7 @@ tactic * mk_der_fp_tactic(ast_manager & m, params_ref const & p) { tactic * mk_ufbv_preprocessor_tactic(ast_manager & m, params_ref const & p) { params_ref no_elim_and(p); - no_elim_and.set_bool(":elim-and", false); + no_elim_and.set_bool("elim_and", false); return and_then( mk_trace_tactic("ufbv_pre"), @@ -61,10 +61,10 @@ tactic * mk_ufbv_preprocessor_tactic(ast_manager & m, params_ref const & p) { tactic * mk_ufbv_tactic(ast_manager & m, params_ref const & p) { params_ref main_p(p); - main_p.set_bool(":mbqi", true); - main_p.set_uint(":mbqi-max-iterations", -1); - main_p.set_bool(":elim-and", true); - main_p.set_bool(":solver", true); + main_p.set_bool("mbqi", true); + main_p.set_uint("mbqi_max_iterations", -1); + main_p.set_bool("elim_and", true); + main_p.set_bool("solver", true); tactic * t = and_then(repeat(mk_ufbv_preprocessor_tactic(m, main_p), 2), mk_smt_tactic_using(false, main_p)); diff --git a/src/test/arith_simplifier_plugin.cpp b/src/test/arith_simplifier_plugin.cpp index 0ea1c2675..59f4996ce 100644 --- a/src/test/arith_simplifier_plugin.cpp +++ b/src/test/arith_simplifier_plugin.cpp @@ -1,5 +1,5 @@ #include "arith_eq_solver.h" -#include "front_end_params.h" +#include "smt_params.h" typedef rational numeral; typedef vector row; @@ -24,7 +24,7 @@ static void test_solve_integer_equations( } void tst_arith_simplifier_plugin() { - front_end_params params; + smt_params params; ast_manager m; arith_eq_solver asimp(m); diff --git a/src/test/check_assumptions.cpp b/src/test/check_assumptions.cpp index e6a5433e9..872af714c 100644 --- a/src/test/check_assumptions.cpp +++ b/src/test/check_assumptions.cpp @@ -1,5 +1,5 @@ #include "memory_manager.h" -#include "front_end_params.h" +#include "smt_params.h" #include "ast.h" #include "arith_decl_plugin.h" #include "bv_decl_plugin.h" @@ -9,7 +9,7 @@ void tst_check_assumptions() { memory::initialize(0); - front_end_params params; + smt_params params; ast_manager mgr; reg_decl_plugins(mgr); diff --git a/src/test/datalog_parser.cpp b/src/test/datalog_parser.cpp index 2d8a04225..64ee4201e 100644 --- a/src/test/datalog_parser.cpp +++ b/src/test/datalog_parser.cpp @@ -2,7 +2,7 @@ #include "ast_pp.h" #include "arith_decl_plugin.h" #include "dl_context.h" -#include "front_end_params.h" +#include "smt_params.h" #include "reg_decl_plugins.h" using namespace datalog; @@ -10,7 +10,7 @@ using namespace datalog; static void dparse_string(char const* str) { ast_manager m; - front_end_params params; + smt_params params; reg_decl_plugins(m); context ctx(m, params); @@ -37,7 +37,7 @@ static void dparse_string(char const* str) { static void dparse_file(char const* file) { ast_manager m; - front_end_params params; + smt_params params; reg_decl_plugins(m); context ctx(m, params); diff --git a/src/test/dl_context.cpp b/src/test/dl_context.cpp index b2530b9da..d5fcddb71 100644 --- a/src/test/dl_context.cpp +++ b/src/test/dl_context.cpp @@ -2,7 +2,7 @@ #include "ast_pp.h" #include "arith_decl_plugin.h" #include "dl_context.h" -#include "front_end_params.h" +#include "smt_params.h" using namespace datalog; @@ -27,7 +27,7 @@ static void dl_context_simple_query_test(params_ref & params) { ast_manager m; dl_decl_util decl_util(m); - front_end_params fparams; + smt_params fparams; context ctx(m, fparams); ctx.updt_params(params); @@ -49,7 +49,7 @@ static void dl_context_simple_query_test(params_ref & params) { void dl_context_saturate_file(params_ref & params, const char * f) { ast_manager m; dl_decl_util decl_util(m); - front_end_params fparams; + smt_params fparams; context ctx(m, fparams); ctx.updt_params(params); @@ -60,7 +60,7 @@ void dl_context_saturate_file(params_ref & params, const char * f) { } dealloc(parser); std::cerr << "Saturating...\n"; - ctx.dl_saturate(); + ctx.get_rel_context().saturate(); std::cerr << "Done\n"; } @@ -72,9 +72,9 @@ void tst_dl_context() { params_ref params; for(unsigned rel_index=0; rel_index=0; eager_checking--) { - params.set_bool(":eager-emptiness-checking", eager_checking!=0); + params.set_bool("eager_emptiness_checking", eager_checking!=0); std::cerr << "Testing " << relations[rel_index] << "\n"; std::cerr << "Eager emptiness checking " << (eager_checking!=0 ? "on" : "off") << "\n"; diff --git a/src/test/dl_product_relation.cpp b/src/test/dl_product_relation.cpp index 2711f3e00..ef43258ad 100644 --- a/src/test/dl_product_relation.cpp +++ b/src/test/dl_product_relation.cpp @@ -19,14 +19,15 @@ namespace datalog { }; - void test_functional_columns(front_end_params fparams, params_ref& params) { + void test_functional_columns(smt_params fparams, params_ref& params) { ast_manager m; context ctx(m, fparams); + rel_context& rctx = ctx.get_rel_context(); ctx.updt_params(params); - relation_manager & rmgr(ctx.get_rmanager()); + relation_manager & rmgr(rctx.get_rmanager()); sparse_table_plugin & plugin = - static_cast(*ctx.get_rmanager().get_table_plugin(symbol("sparse"))); + static_cast(*rctx.get_rmanager().get_table_plugin(symbol("sparse"))); SASSERT(&plugin); table_signature sig2; sig2.push_back(2); @@ -121,14 +122,14 @@ namespace datalog { } } - void test_finite_product_relation(front_end_params fparams, params_ref& params) { + void test_finite_product_relation(smt_params fparams, params_ref& params) { ast_manager m; context ctx(m, fparams); ctx.updt_params(params); dl_decl_util dl_util(m); - relation_manager & rmgr = ctx.get_rmanager(); + relation_manager & rmgr = ctx.get_rel_context().get_rmanager(); - relation_plugin & rel_plugin = *ctx.get_rmanager().get_relation_plugin(params.get_sym(":default-relation", symbol("sparse"))); + relation_plugin & rel_plugin = *rmgr.get_relation_plugin(params.get_sym("default_relation", symbol("sparse"))); SASSERT(&rel_plugin); finite_product_relation_plugin plg(rel_plugin, rmgr); @@ -338,12 +339,12 @@ namespace datalog { using namespace datalog; void tst_dl_product_relation() { - front_end_params fparams; + smt_params fparams; params_ref params; test_functional_columns(fparams, params); - params.set_sym(":default-relation", symbol("tr_sparse")); + params.set_sym("default_relation", symbol("tr_sparse")); test_finite_product_relation(fparams, params); } diff --git a/src/test/dl_query.cpp b/src/test/dl_query.cpp index 2cca7cce6..4dc770056 100644 --- a/src/test/dl_query.cpp +++ b/src/test/dl_query.cpp @@ -2,7 +2,7 @@ #include "ast_pp.h" #include "dl_table_relation.h" #include "dl_context.h" -#include "front_end_params.h" +#include "smt_params.h" #include "stopwatch.h" #include "reg_decl_plugins.h" @@ -43,21 +43,21 @@ void dl_query_ask_for_last_arg(context & ctx, func_decl * pred, relation_fact & } } -void dl_query_test(ast_manager & m, front_end_params & fparams, params_ref& params, +void dl_query_test(ast_manager & m, smt_params & fparams, params_ref& params, context & ctx_b, char const* problem_file, unsigned test_count, bool use_magic_sets) { dl_decl_util decl_util(m); context ctx_q(m, fparams); - params.set_bool(":magic-sets-for-queries", use_magic_sets); + params.set_bool("magic_sets_for_queries", use_magic_sets); ctx_q.updt_params(params); { parser* p = parser::create(ctx_q,m); TRUSTME( p->parse_file(problem_file) ); dealloc(p); } - relation_manager & rel_mgr_q = ctx_b.get_rmanager(); + relation_manager & rel_mgr_q = ctx_b.get_rel_context().get_rmanager(); decl_set out_preds = ctx_b.get_output_predicates(); decl_set::iterator it = out_preds.begin(); @@ -68,10 +68,10 @@ void dl_query_test(ast_manager & m, front_end_params & fparams, params_ref& para func_decl * pred_q = ctx_q.try_get_predicate_decl(symbol(pred_b->get_name().bare_str())); SASSERT(pred_q); - relation_base & rel_b = ctx_b.get_relation(pred_b); + relation_base & rel_b = ctx_b.get_rel_context().get_relation(pred_b); relation_signature sig_b = rel_b.get_signature(); - relation_signature sig_q = ctx_q.get_relation(pred_q).get_signature(); + relation_signature sig_q = ctx_q.get_rel_context().get_relation(pred_q).get_signature(); SASSERT(sig_b.size()==sig_q.size()); std::cerr << "Queries on random facts...\n"; @@ -124,8 +124,8 @@ void dl_query_test(ast_manager & m, front_end_params & fparams, params_ref& para } } -void dl_query_test_wpa(front_end_params & fparams, params_ref& params) { - params.set_bool(":magic-sets-for-queries", true); +void dl_query_test_wpa(smt_params & fparams, params_ref& params) { + params.set_bool("magic_sets_for_queries", true); ast_manager m; reg_decl_plugins(m); arith_util arith(m); @@ -183,10 +183,10 @@ void dl_query_test_wpa(front_end_params & fparams, params_ref& params) { } void tst_dl_query() { - front_end_params fparams; + smt_params fparams; params_ref params; - params.set_sym(":default-table", symbol("sparse")); - params.set_sym(":default-relation", symbol("tr_sparse")); + params.set_sym("default_table", symbol("sparse")); + params.set_sym("default_relation", symbol("tr_sparse")); //params.m_dl_default_table = symbol("hashtable"); //params.m_dl_default_relation = symbol("tr_hashtable"); @@ -209,12 +209,12 @@ void tst_dl_query() { TRUSTME( p->parse_file(problem_file) ); dealloc(p); } - ctx_base.dl_saturate(); + ctx_base.get_rel_context().saturate(); for(unsigned use_restarts=0; use_restarts<=1; use_restarts++) { - params.set_uint(":initial-restart-timeout", use_restarts ? 100 : 0); + params.set_uint("initial_restart_timeout", use_restarts ? 100 : 0); for(unsigned use_similar=0; use_similar<=1; use_similar++) { - params.set_uint(":similarity-compressor", use_similar != 0); + params.set_uint("similarity_compressor", use_similar != 0); for(unsigned use_magic_sets=0; use_magic_sets<=1; use_magic_sets++) { stopwatch watch; diff --git a/src/test/dl_relation.cpp b/src/test/dl_relation.cpp index 095751cb6..5daf3dc9b 100644 --- a/src/test/dl_relation.cpp +++ b/src/test/dl_relation.cpp @@ -8,11 +8,11 @@ namespace datalog { static void test_interval_relation() { - front_end_params params; + smt_params params; ast_manager ast_m; context ctx(ast_m, params); arith_util autil(ast_m); - relation_manager & m = ctx.get_rmanager(); + relation_manager & m = ctx.get_rel_context().get_rmanager(); m.register_plugin(alloc(interval_relation_plugin, m)); interval_relation_plugin& ip = dynamic_cast(*m.get_relation_plugin(symbol("interval_relation"))); SASSERT(&ip); @@ -111,11 +111,11 @@ namespace datalog { std::cout << "bound relation\n"; - front_end_params params; + smt_params params; ast_manager ast_m; context ctx(ast_m, params); arith_util autil(ast_m); - relation_manager & m = ctx.get_rmanager(); + relation_manager & m = ctx.get_rel_context().get_rmanager(); m.register_plugin(alloc(bound_relation_plugin, m)); bound_relation_plugin& br = dynamic_cast(*m.get_relation_plugin(symbol("bound_relation"))); SASSERT(&br); diff --git a/src/test/dl_smt_relation.cpp b/src/test/dl_smt_relation.cpp deleted file mode 100644 index fa66a89c9..000000000 --- a/src/test/dl_smt_relation.cpp +++ /dev/null @@ -1,234 +0,0 @@ -#include "dl_smt_relation.h" -#include "arith_decl_plugin.h" -#include "dl_context.h" -#include "z3.h" -#include "z3_private.h" -#include "reg_decl_plugins.h" - - -namespace datalog { - - void test_smt_relation_unit() { - ast_manager m; - reg_decl_plugins(m); - arith_util a(m); - sort* int_sort = a.mk_int(); - sort* real_sort = a.mk_real(); - front_end_params params; - context ctx(m, params); - relation_manager & rm = ctx.get_rmanager(); - relation_signature sig1; - sig1.push_back(int_sort); - sig1.push_back(int_sort); - sig1.push_back(real_sort); - - smt_relation_plugin plugin(rm); - - scoped_rel r1 = plugin.mk_empty(sig1); - - // add_fact - relation_fact fact1(m); - fact1.push_back(a.mk_numeral(rational(1), true)); - fact1.push_back(a.mk_numeral(rational(2), true)); - fact1.push_back(a.mk_numeral(rational(3), false)); - - relation_fact fact2(m); - fact2.push_back(a.mk_numeral(rational(2), true)); - fact2.push_back(a.mk_numeral(rational(2), true)); - fact2.push_back(a.mk_numeral(rational(3), false)); - - r1->add_fact(fact1); - r1->display(std::cout << "r1: "); - - - // contains_fact - SASSERT(r1->contains_fact(fact1)); - SASSERT(!r1->contains_fact(fact2)); - - // empty - scoped_rel r2 = plugin.mk_empty(sig1); - SASSERT(!r1->empty()); - SASSERT(r2->empty()); - - // clone - scoped_rel r3 = r1->clone(); - - // complement? - r2->add_fact(fact2); - scoped_rel r4 = dynamic_cast(*r2).complement(0); - r4->display(std::cout << "complement r4: " ); - - // join - unsigned col_cnt = 2; - unsigned cols1[2] = {1, 2}; - unsigned cols2[2] = {0, 2}; - scoped_ptr joinfn = plugin.mk_join_fn(*r1, *r4, col_cnt, cols1, cols2); - scoped_rel r5 = (*joinfn)(*r1, *r4); - r5->display(std::cout<< "join r5: "); - - relation_fact fact3(m); - fact3.push_back(a.mk_numeral(rational(1), true)); - fact3.push_back(a.mk_numeral(rational(2), true)); - fact3.push_back(a.mk_numeral(rational(3), false)); - fact3.push_back(a.mk_numeral(rational(2), true)); - fact3.push_back(a.mk_numeral(rational(2), true)); - fact3.push_back(a.mk_numeral(rational(3), false)); - SASSERT(!r5->contains_fact(fact3)); - fact3[5] = a.mk_numeral(rational(4), false); - SASSERT(!r5->contains_fact(fact3)); - fact3[5] = a.mk_numeral(rational(3), false); - fact3[4] = a.mk_numeral(rational(3), true); - SASSERT(r5->contains_fact(fact3)); - - // project - unsigned removed_cols[2] = { 1, 4 }; - scoped_ptr projfn = plugin.mk_project_fn(*r5, col_cnt, removed_cols); - scoped_rel r6 = (*projfn)(*r5); - r6->display(std::cout<< "project r6: "); - - // rename - unsigned cycle[3] = { 0, 2, 4 }; - unsigned cycle_len = 3; - scoped_rel renamefn = plugin.mk_rename_fn(*r5, cycle_len, cycle); - scoped_rel r7 = (*renamefn)(*r5); - r7->display(std::cout << "rename r7: "); - - // union - // widen - relation_base* delta = 0; - scoped_ptr widenfn = plugin.mk_widen_fn(*r1, *r2, delta); - scoped_ptr unionfn = plugin.mk_union_fn(*r1, *r2, delta); - scoped_rel r8 = r1->clone(); - (*unionfn)(*r8,*r2,0); - r8->display(std::cout << "union r8: "); - - // filter_identical - unsigned identical_cols[2] = { 1, 3 }; - scoped_ptr filti = plugin.mk_filter_identical_fn(*r5, col_cnt, identical_cols); - scoped_rel r9 = r1->clone(); - (*filti)(*r9); - r9->display(std::cout << "filter identical r9: "); - - // filter_equal - app_ref value(m); - value = m.mk_const(symbol("x"), int_sort); - scoped_rel eqn = plugin.mk_filter_equal_fn(*r5, value.get(), 3); - scoped_rel r10 = r1->clone(); - (*eqn)(*r10); - r10->display(std::cout << "filter equal r10: "); - - - // filter_interpreted - app_ref cond(m); - cond = a.mk_lt(m.mk_var(3, int_sort), m.mk_var(4, int_sort)); - scoped_rel filtint = plugin.mk_filter_interpreted_fn(*r5, cond); - scoped_rel r11 = r5->clone(); - (*filtint)(*r11); - r11->display(std::cout << "filter interpreted r11: "); - - } - - void test_smt_relation_api() { - - enable_trace("smt_relation"); - enable_trace("smt_relation2"); - enable_trace("quant_elim"); - Z3_config cfg = Z3_mk_config(); - Z3_set_param_value(cfg, "DL_DEFAULT_RELATION", "smt_relation2"); - Z3_context ctx = Z3_mk_context(cfg); - Z3_fixedpoint dl = Z3_mk_fixedpoint(ctx); - Z3_fixedpoint_inc_ref(ctx,dl); - Z3_del_config(cfg); - - Z3_sort int_sort = Z3_mk_int_sort(ctx); - Z3_sort bool_sort = Z3_mk_bool_sort(ctx); - Z3_func_decl nil_decl, is_nil_decl; - Z3_func_decl cons_decl, is_cons_decl, head_decl, tail_decl; - - Z3_sort list = Z3_mk_list_sort( - ctx, - Z3_mk_string_symbol(ctx, "list"), - int_sort, - &nil_decl, - &is_nil_decl, - &cons_decl, - &is_cons_decl, - &head_decl, - &tail_decl); - - Z3_sort listint[2] = { list, int_sort }; - Z3_symbol p_sym = Z3_mk_string_symbol(ctx, "p"); - Z3_symbol q_sym = Z3_mk_string_symbol(ctx, "q"); - - - Z3_func_decl p = Z3_mk_func_decl(ctx, p_sym, 2, listint, bool_sort); - Z3_func_decl q = Z3_mk_func_decl(ctx, q_sym, 2, listint, bool_sort); - Z3_fixedpoint_register_relation(ctx, dl, p); - Z3_fixedpoint_register_relation(ctx, dl, q); - - - Z3_ast zero = Z3_mk_numeral(ctx, "0", int_sort); - Z3_ast one = Z3_mk_numeral(ctx, "1", int_sort); - Z3_ast two = Z3_mk_numeral(ctx, "2", int_sort); - Z3_ast x = Z3_mk_bound(ctx, 0, list); - Z3_ast y = Z3_mk_bound(ctx, 1, int_sort); - Z3_ast z = Z3_mk_bound(ctx, 2, list); - Z3_ast zero_x[2] = { zero, x }; - Z3_ast fx = Z3_mk_app(ctx, cons_decl, 2, zero_x); - Z3_ast zero_fx[2] = { zero, fx }; - Z3_ast ffx = Z3_mk_app(ctx, cons_decl, 2, zero_fx); - Z3_ast xy[2] = { x, y }; - Z3_ast zy[2] = { z, y }; - // Z3_ast ffxy[2] = { ffx, y }; - // Z3_ast fxy[2] = { fx, y }; - Z3_ast zero_nil[2] = { zero, Z3_mk_app(ctx, nil_decl, 0, 0) }; - Z3_ast f0 = Z3_mk_app(ctx, cons_decl, 2, zero_nil); - Z3_ast zero_f0[2] = { zero, f0 }; - Z3_ast f1 = Z3_mk_app(ctx, cons_decl, 2, zero_f0); - Z3_ast zero_f1[2] = { zero, f1 }; - Z3_ast f2 = Z3_mk_app(ctx, cons_decl, 2, zero_f1); - Z3_ast zero_f2[2] = { zero, f2 }; - Z3_ast f3 = Z3_mk_app(ctx, cons_decl, 2, zero_f2); - Z3_ast zero_f3[2] = { zero, f3 }; - Z3_ast f4 = Z3_mk_app(ctx, cons_decl, 2, zero_f3); - Z3_ast zero_f4[2] = { zero, f4 }; - Z3_ast f5 = Z3_mk_app(ctx, cons_decl, 2, zero_f4); - Z3_ast zero_z[2] = { zero, z }; - Z3_ast fz = Z3_mk_app(ctx, cons_decl, 2, zero_z); - - Z3_ast pxy = Z3_mk_app(ctx, p, 2, xy); - Z3_ast pzy = Z3_mk_app(ctx, p, 2, zy); - Z3_ast qxy = Z3_mk_app(ctx, q, 2, xy); - Z3_ast qzy = Z3_mk_app(ctx, q, 2, zy); - Z3_ast even_y = Z3_mk_eq(ctx, zero, Z3_mk_mod(ctx, y, two)); - Z3_ast odd_y = Z3_mk_eq(ctx, one, Z3_mk_mod(ctx, y, two)); - - - // p(x, y) :- odd(y), p(z,y), f(z) = x . // dead rule. - // q(x, y) :- p(f(f(x)), y). - // p(x, y) :- q(f(x), y) // x decreases - // p(x, y) :- even y, x = f^5(0) // initial condition. - - Z3_ast body1[3] = { pzy, Z3_mk_eq(ctx, fz, x), odd_y }; - Z3_ast body2[2] = { pzy, Z3_mk_eq(ctx, ffx, z) }; - Z3_ast body3[2] = { qzy, Z3_mk_eq(ctx, fx, z) }; - Z3_ast body4[2] = { even_y, Z3_mk_eq(ctx, x, f5) }; - Z3_fixedpoint_add_rule(ctx, dl, Z3_mk_implies(ctx, Z3_mk_and(ctx, 3, body1), pxy), 0); - Z3_fixedpoint_add_rule(ctx, dl, Z3_mk_implies(ctx, Z3_mk_and(ctx, 2, body2), qxy), 0); - Z3_fixedpoint_add_rule(ctx, dl, Z3_mk_implies(ctx, Z3_mk_and(ctx, 2, body3), pxy), 0); - Z3_fixedpoint_add_rule(ctx, dl, Z3_mk_implies(ctx, Z3_mk_and(ctx, 2, body4), pxy), 0); - - Z3_lbool r = Z3_fixedpoint_query(ctx, dl, pxy); - if (r != Z3_L_UNDEF) { - std::cout << Z3_ast_to_string(ctx, Z3_fixedpoint_get_answer(ctx, dl)) << "\n"; - } - - Z3_del_context(ctx); - - } -}; - -void tst_dl_smt_relation() { - datalog::test_smt_relation_api(); - datalog::test_smt_relation_unit(); -} diff --git a/src/test/dl_table.cpp b/src/test/dl_table.cpp index a29ef48d8..0c8afcdc2 100644 --- a/src/test/dl_table.cpp +++ b/src/test/dl_table.cpp @@ -24,12 +24,12 @@ static void test_table(mk_table_fn mk_table) { sig.push_back(4); sig.push_back(8); sig.push_back(4); - front_end_params params; + smt_params params; ast_manager ast_m; datalog::context ctx(ast_m, params); - datalog::relation_manager & m = ctx.get_rmanager(); + datalog::relation_manager & m = ctx.get_rel_context().get_rmanager(); - ctx.get_rmanager().register_plugin(alloc(datalog::bitvector_table_plugin, ctx.get_rmanager())); + m.register_plugin(alloc(datalog::bitvector_table_plugin, m)); datalog::table_base* _tbl = mk_table(m, sig); datalog::table_base& table = *_tbl; diff --git a/src/test/ini_file.cpp b/src/test/ini_file.cpp deleted file mode 100644 index d3114c037..000000000 --- a/src/test/ini_file.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - ini_file.cpp - -Abstract: - - - -Author: - - Leonardo de Moura (leonardo) 2007-05-10. - -Revision History: - ---*/ -#include -#include"ini_file.h" -#include"debug.h" - -static void tst1() { - ini_params p; - int p1; - p.register_int_param("ipar1", 0, 100, p1); - int p2; - p.register_int_param("ipar2", -100, 100, p2); - bool p3; - p.register_bool_param("bpar1", p3); - bool p4; - p.register_bool_param("bpar2", p4); - unsigned p5; - p.register_unsigned_param("upar1", 0, 100, p5); - double p6; - p.register_percentage_param("ppar1", p6); - std::istringstream in("ipar1 = 100 ipar2=-30 bpar1 = true ;; COMMENT\n bpar2 = false upar1=30 ppar1 = 10"); - p.read_ini_file(in); - SASSERT(p1 == 100); - SASSERT(p2 == -30); - SASSERT(p3); - SASSERT(!p4); - SASSERT(p5 == 30); - SASSERT(p6 == 0.1); -} - -void tst_ini_file() { - tst1(); -} - diff --git a/src/test/main.cpp b/src/test/main.cpp index acbea0761..13ade7714 100644 --- a/src/test/main.cpp +++ b/src/test/main.cpp @@ -140,7 +140,6 @@ int main(int argc, char ** argv) { TST(diff_logic); TST(uint_set); TST_ARGV(expr_rand); - TST(ini_file); TST(list); TST(small_object_allocator); TST(timeout); @@ -167,7 +166,6 @@ int main(int argc, char ** argv) { TST(total_order); TST(dl_table); TST(dl_context); - TST(dl_smt_relation); TST(dl_query); TST(dl_util); TST(dl_product_relation); diff --git a/src/test/model_retrieval.cpp b/src/test/model_retrieval.cpp index 0a0b8a0dc..da6c3ddd0 100644 --- a/src/test/model_retrieval.cpp +++ b/src/test/model_retrieval.cpp @@ -1,6 +1,6 @@ #include "ast.h" -#include "front_end_params.h" +#include "smt_params.h" #include "smt_context.h" #include "arith_decl_plugin.h" #include "bv_decl_plugin.h" @@ -11,7 +11,7 @@ void tst_model_retrieval() { memory::initialize(0); - front_end_params params; + smt_params params; params.m_model = true; diff --git a/src/test/quant_elim.cpp b/src/test/quant_elim.cpp index 0f1ddfabd..4e750c34e 100644 --- a/src/test/quant_elim.cpp +++ b/src/test/quant_elim.cpp @@ -1,5 +1,5 @@ #include "ast.h" -#include "front_end_params.h" +#include "smt_params.h" #include "simplifier.h" #include "qe.h" #include "basic_simplifier_plugin.h" @@ -33,7 +33,7 @@ static void test_qe(ast_manager& m, lbool expected_outcome, expr* fml, char cons // enable_trace("bv_bit_prop"); simplifier simp(m); - front_end_params params; + smt_params params; // params.m_quant_elim = true; std::cout << mk_pp(fml, m) << "\n"; diff --git a/src/test/quant_solve.cpp b/src/test/quant_solve.cpp index bae63f129..36b354b44 100644 --- a/src/test/quant_solve.cpp +++ b/src/test/quant_solve.cpp @@ -1,5 +1,5 @@ #include "ast.h" -#include "front_end_params.h" +#include "smt_params.h" #include "qe.h" #include "arith_decl_plugin.h" #include "ast_pp.h" @@ -28,7 +28,7 @@ static void validate_quant_solution(ast_manager& m, expr* fml, expr* guard, qe:: (*rep)(fml1); expr_ref tmp(m); tmp = m.mk_not(m.mk_implies(guard, fml1)); - front_end_params fp; + smt_params fp; smt::kernel solver(m, fp); solver.assert_expr(tmp); lbool res = solver.check(); @@ -63,7 +63,7 @@ static void validate_quant_solutions(app* x, expr* fml, expr_ref_vector& guards) std::cout << mk_pp(fml2, m) << "\n"; tmp = m.mk_not(m.mk_iff(fml2, tmp)); std::cout << mk_pp(tmp, m) << "\n"; - front_end_params fp; + smt_params fp; smt::kernel solver(m, fp); solver.assert_expr(tmp); lbool res = solver.check(); @@ -78,7 +78,7 @@ static void validate_quant_solutions(app* x, expr* fml, expr_ref_vector& guards) static void test_quant_solver(ast_manager& m, unsigned sz, app*const* xs, expr* fml, bool validate) { - front_end_params params; + smt_params params; qe::expr_quant_elim qe(m, params); qe::guarded_defs defs(m); bool success = qe.solve_for_vars(sz, xs, fml, defs); @@ -98,8 +98,7 @@ static void test_quant_solver(ast_manager& m, unsigned sz, app*const* xs, expr* static expr_ref parse_fml(ast_manager& m, char const* str) { expr_ref result(m); - front_end_params fp; - cmd_context ctx(&fp, false, &m); + cmd_context ctx(false, &m); ctx.set_ignore_check(true); std::ostringstream buffer; buffer << "(declare-const x Int)\n" diff --git a/src/test/smt_context.cpp b/src/test/smt_context.cpp index 853bde068..49ada8ebd 100644 --- a/src/test/smt_context.cpp +++ b/src/test/smt_context.cpp @@ -3,7 +3,7 @@ void tst_smt_context() { - front_end_params params; + smt_params params; ast_manager m; reg_decl_plugins(m); diff --git a/src/test/substitution.cpp b/src/test/substitution.cpp index 38f85bb11..889666972 100644 --- a/src/test/substitution.cpp +++ b/src/test/substitution.cpp @@ -1,5 +1,5 @@ #include "expr_substitution.h" -#include "front_end_params.h" +#include "smt_params.h" #include "substitution.h" #include "unifier.h" #include "bv_decl_plugin.h" @@ -10,7 +10,7 @@ void tst_substitution() { memory::initialize(0); - front_end_params params; + smt_params params; params.m_model = true; enable_trace("subst_bug"); diff --git a/src/test/theory_dl.cpp b/src/test/theory_dl.cpp index d07ec34af..9521a8932 100644 --- a/src/test/theory_dl.cpp +++ b/src/test/theory_dl.cpp @@ -6,7 +6,7 @@ void tst_theory_dl() { ast_manager m; - front_end_params params; + smt_params params; params.m_model = true; datalog::dl_decl_util u(m); smt::context ctx(m, params); diff --git a/src/util/cooperate.cpp b/src/util/cooperate.cpp index c941b18e5..cdd91bfdd 100644 --- a/src/util/cooperate.cpp +++ b/src/util/cooperate.cpp @@ -16,10 +16,10 @@ Author: Notes: --*/ -#include"z3_omp.h" #include"cooperate.h" #include"trace.h" #include"debug.h" +#include"z3_omp.h" struct cooperation_lock { omp_nest_lock_t m_lock; diff --git a/src/util/debug.cpp b/src/util/debug.cpp index 41e0a48fc..75ea8586a 100644 --- a/src/util/debug.cpp +++ b/src/util/debug.cpp @@ -22,6 +22,7 @@ Revision History: #endif #include #include"str_hashtable.h" +#include"z3_exception.h" volatile bool g_enable_assertions = true; @@ -73,7 +74,7 @@ void invoke_gdb() { char buffer[1024]; int * x = 0; for (;;) { - std::cerr << "(C)ontinue, (A)bort, (S)top, Invoke (G)DB\n"; + std::cerr << "(C)ontinue, (A)bort, (S)top, (T)hrow exception, Invoke (G)DB\n"; char result; std::cin >> result; switch(result) { @@ -88,6 +89,9 @@ void invoke_gdb() { // force seg fault... *x = 0; return; + case 't': + case 'T': + throw default_exception("assertion violation"); case 'G': case 'g': sprintf(buffer, "gdb -nw /proc/%d/exe %d", getpid(), getpid()); diff --git a/src/util/double_manager.h b/src/util/double_manager.h index a6a72cc6f..5334e60df 100644 --- a/src/util/double_manager.h +++ b/src/util/double_manager.h @@ -40,7 +40,7 @@ public: double_manager(params_ref const & p = params_ref()) { updt_params(p); } void updt_params(params_ref const & p) { - m_zero_tolerance = p.get_double(":zero-tolerance", 0.00000001); + m_zero_tolerance = p.get_double("zero_tolerance", 0.00000001); } static void reset(double & a) { a = 0.0; } diff --git a/src/util/env_params.cpp b/src/util/env_params.cpp new file mode 100644 index 000000000..28d80d92d --- /dev/null +++ b/src/util/env_params.cpp @@ -0,0 +1,38 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + env_params.cpp + +Abstract: + + Goodies for updating environment parameters. + +Author: + + Leonardo (leonardo) 2012-12-01 + +Notes: + +--*/ +#include"env_params.h" +#include"params.h" +#include"gparams.h" +#include"util.h" +#include"memory_manager.h" + +void env_params::updt_params() { + params_ref p = gparams::get(); + set_verbosity_level(p.get_uint("verbose", get_verbosity_level())); + enable_warning_messages(p.get_bool("warning", true)); + memory::set_max_size(p.get_uint("memory_max_size", 0)); + memory::set_high_watermark(p.get_uint("memory_high_watermark", 0)); +} + +void env_params::collect_param_descrs(param_descrs & d) { + d.insert("verbose", CPK_UINT, "be verbose, where the value is the verbosity level", "0"); + d.insert("warning", CPK_BOOL, "enable/disable warning messages", "true"); + d.insert("memory_max_size", CPK_UINT, "set hard upper limit for memory consumption (in megabytes), if 0 then there is no limit", "0"); + d.insert("memory_high_watermark", CPK_UINT, "set high watermark for memory consumption (in megabytes), if 0 then there is no limit", "0"); +} diff --git a/src/util/env_params.h b/src/util/env_params.h new file mode 100644 index 000000000..8b5fa7005 --- /dev/null +++ b/src/util/env_params.h @@ -0,0 +1,32 @@ +/*++ +Copyright (c) 2011 Microsoft Corporation + +Module Name: + + env_params.h + +Abstract: + + Goodies for updating environment parameters. + +Author: + + Leonardo (leonardo) 2012-12-01 + +Notes: + +--*/ +#ifndef _ENV_PARAMS_H_ +#define _ENV_PARAMS_H_ + +class param_descrs; + +struct env_params { + static void updt_params(); + static void collect_param_descrs(param_descrs & p); + /* + REG_PARAMS('env_params::collect_param_descrs') + */ +}; + +#endif diff --git a/src/util/gparams.cpp b/src/util/gparams.cpp new file mode 100644 index 000000000..b81531798 --- /dev/null +++ b/src/util/gparams.cpp @@ -0,0 +1,591 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + gparams.cpp + +Abstract: + + Global parameter management. + +Author: + + Leonardo (leonardo) 2012-11-29 + +Notes: + +--*/ +#include"gparams.h" +#include"dictionary.h" +#include"trace.h" + +extern void gparams_register_modules(); + +char const * g_old_params_names[] = { + "arith_adaptive","arith_adaptive_assertion_threshold","arith_adaptive_gcd","arith_adaptive_propagation_threshold","arith_add_binary_bounds","arith_blands_rule_threshold","arith_branch_cut_ratio","arith_dump_lemmas","arith_eager_eq_axioms","arith_eager_gcd","arith_eq_bounds","arith_euclidean_solver","arith_expand_eqs","arith_force_simplex","arith_gcd_test","arith_ignore_int","arith_lazy_adapter","arith_lazy_pivoting","arith_max_lemma_size","arith_process_all_eqs","arith_propagate_eqs","arith_propagation_mode","arith_propagation_threshold","arith_prop_strategy","arith_random_initial_value","arith_random_lower","arith_random_seed","arith_random_upper","arith_reflect","arith_skip_big_coeffs","arith_small_lemma_size","arith_solver","arith_stronger_lemmas","array_always_prop_upward","array_canonize","array_cg","array_delay_exp_axiom","array_extensional","array_laziness","array_lazy_ieq","array_lazy_ieq_delay","array_solver","array_weak","async_commands","at_labels_cex","auto_config","bb_eager","bb_ext_gates","bb_quantifiers","bin_clauses","bit2int","bv2int_distribute","bv_blast_max_size","bv_cc","bv_enable_int2bv_propagation","bv_lazy_le","bv_max_sharing","bv_reflect","bv_solver","case_split","check_at_labels","check_proof","cnf_factor","cnf_mode","context_simplifier","dack","dack_eq","dack_factor","dack_gc","dack_gc_inv_decay","dack_threshold","default_qid","default_table","default_table_checked","delay_units","delay_units_threshold","der","display_config","display_dot_proof","display_error_for_visual_studio","display_features","display_proof","display_unsat_core","distribute_forall","dt_lazy_splits","dump_goal_as_smt","elim_and","elim_bounds","elim_nlarith_quantifiers","elim_quantifiers","elim_term_ite","ematching","engine","eq_propagation","hi_div0","ignore_bad_patterns","ignore_setparameter","instruction_max","inst_gen","interactive","internalizer_nnf","lemma_gc_factor","lemma_gc_half","lemma_gc_initial","lemma_gc_new_clause_activity","lemma_gc_new_clause_relevancy","lemma_gc_new_old_ratio","lemma_gc_old_clause_activity","lemma_gc_old_clause_relevancy","lemma_gc_strategy","lift_ite","lookahead_diseq","macro_finder","max_conflicts","max_counterexamples","mbqi","mbqi_force_template","mbqi_max_cexs","mbqi_max_cexs_incr","mbqi_max_iterations","mbqi_trace","minimize_lemmas","model","model_compact","model_completion","model_display_arg_sort","model_hide_unused_partitions","model_on_final_check","model_on_timeout","model_partial","model_v1","model_v2","model_validate","new_core2th_eq","ng_lift_ite","nl_arith","nl_arith_branching","nl_arith_gb","nl_arith_gb_eqs","nl_arith_gb_perturbate","nl_arith_gb_threshold","nl_arith_max_degree","nl_arith_rounds","nnf_factor","nnf_ignore_labels","nnf_mode","nnf_sk_hack","order","order_var_weight","order_weights","phase_selection","pi_arith","pi_arith_weight","pi_avoid_skolems","pi_block_looop_patterns","pi_max_multi_patterns","pi_non_nested_arith_weight","pi_nopat_weight","pi_pull_quantifiers","pi_use_database","pi_warnings","pp_bounded","pp_bv_literals","pp_bv_neg","pp_decimal","pp_decimal_precision","pp_fixed_indent","pp_flat_assoc","pp_max_depth","pp_max_indent","pp_max_num_lines","pp_max_ribbon","pp_max_width","pp_min_alias_size","pp_simplify_implies","pp_single_line","precedence","precedence_gen","pre_demodulator","pre_simplifier","pre_simplify_expr","profile_res_sub","progress_sampling_freq","proof_mode","propagate_booleans","propagate_values","pull_cheap_ite_trees","pull_nested_quantifiers","qi_conservative_final_check","qi_cost","qi_eager_threshold","qi_lazy_instantiation","qi_lazy_quick_checker","qi_lazy_threshold","qi_max_eager_multi_patterns","qi_max_instances","qi_max_lazy_multi_pattern_matching","qi_new_gen","qi_profile","qi_profile_freq","qi_promote_unsat","qi_quick_checker","quasi_macros","random_case_split_freq","random_initial_activity","random_seed","recent_lemma_threshold","reduce_args","refine_inj_axiom","relevancy","relevancy_lemma","rel_case_split_order","restart_adaptive","restart_agility_threshold","restart_factor","restart_initial","restart_strategy","restricted_quasi_macros","simplify_clauses","smtlib2_compliant","smtlib_category","smtlib_dump_lemmas","smtlib_logic","smtlib_source_info","smtlib_trace_path","soft_timeout","solver","spc_bs","spc_es","spc_factor_subsumption_index_opt","spc_initial_subsumption_index_opt","spc_max_subsumption_index_features","spc_min_func_freq_subsumption_index","spc_num_iterations","spc_trace","statistics","strong_context_simplifier","tick","trace","trace_file_name","type_check","user_theory_persist_axioms","user_theory_preprocess_axioms","verbose","warning","well_sorted_check","z3_solver_ll_pp","z3_solver_smt_pp", 0 }; + +bool is_old_param_name(symbol const & name) { + char const * const * it = g_old_params_names; + while (*it) { + if (name == *it) + return true; + it++; + } + return false; +} + +char const * g_params_renames[] = { + "proof_mode", "proof", + "soft_timeout", "timeout", + "mbqi", "smt.mbqi", + "relevancy", "smt.relevancy", + "ematching", "smt.ematching", + "macro_finder", "smt.macro_finder", + "delay_units", "smt.delay_units", + "case_split", "smt.case_split", + "phase_selection", "smt.phase_selection", + "restart_strategy", "smt.restart_strategy", + "restart_factor", "smt.restart_factor", + "arith_random_initial_value", "smt.arith.random_initial_value", + "bv_reflect", "smt.bv.reflect", + "qi_cost", "smt.qi.cost", + "qi_eager_threshold", "smt.qi.eager_threshold", + "nl_arith", "smt.arith.nl", + "nnf_sk_hack", "nnf.sk_hack", + "model_v2", "model.v2", + "pi_non_nested_arith_weight", "pi.non_nested_arith_weight", + "pi_warnings", "pi.warnings", + "pp_decimal", "pp.decimal", + "pp_decimal", "pp.decimal_precision", + "pp_bv_literals", "pp.bv_literals", + "pp_bv_neg", "pp.bv_neg", + "pp_max_depth", "pp.max_depth", + "pp_min_alias_size", "pp.min_alias_size", + 0 }; + +char const * get_new_param_name(symbol const & p) { + char const * const * it = g_params_renames; + while (*it) { + if (p == *it) { + it++; + return *it; + } + it += 2; + } + return 0; +} + +struct gparams::imp { + bool m_modules_registered; + dictionary m_module_param_descrs; + dictionary m_module_descrs; + param_descrs m_param_descrs; + dictionary m_module_params; + params_ref m_params; + + void check_registered() { + if (m_modules_registered) + return; + m_modules_registered = true; + gparams_register_modules(); + } + + dictionary & get_module_param_descrs() { check_registered(); return m_module_param_descrs; } + dictionary & get_module_descrs() { check_registered(); return m_module_descrs; } + param_descrs & get_param_descrs() { check_registered(); return m_param_descrs; } + +public: + imp(): + m_modules_registered(false) { + } + + ~imp() { + reset(); + dictionary::iterator it = m_module_param_descrs.begin(); + dictionary::iterator end = m_module_param_descrs.end(); + for (; it != end; ++it) { + dealloc(it->m_value); + } + } + + void reset() { + #pragma omp critical (gparams) + { + m_params.reset(); + dictionary::iterator it = m_module_params.begin(); + dictionary::iterator end = m_module_params.end(); + for (; it != end; ++it) { + dealloc(it->m_value); + } + m_module_params.reset(); + } + } + + // ----------------------------------------------- + // + // Module registration routines. + // They are invoked when descriptions are initialized + // + // ----------------------------------------------- + + void register_global(param_descrs & d) { + // Don't need synchronization here, this method + // is invoked from check_registered that is already protected. + m_param_descrs.copy(d); + } + + void register_module(char const * module_name, param_descrs * d) { + // Don't need synchronization here, this method + // is invoked from check_registered that is already protected. + symbol s(module_name); + param_descrs * old_d; + if (m_module_param_descrs.find(s, old_d)) { + old_d->copy(*d); + dealloc(d); + } + else { + m_module_param_descrs.insert(s, d); + } + } + + void register_module_descr(char const * module_name, char const * descr) { + // Don't need synchronization here, this method + // is invoked from check_registered that is already protected. + m_module_descrs.insert(symbol(module_name), descr); + } + + // ----------------------------------------------- + // + // Parameter setting & retrieval + // + // ----------------------------------------------- + + void normalize(char const * name, /* out */ symbol & mod_name, /* out */ symbol & param_name) { + if (*name == ':') + name++; + std::string tmp = name; + unsigned n = tmp.size(); + for (unsigned i = 0; i < n; i++) { + if (tmp[i] >= 'A' && tmp[i] <= 'Z') + tmp[i] = tmp[i] - 'A' + 'a'; + else if (tmp[i] == '-') + tmp[i] = '_'; + } + for (unsigned i = 0; i < n; i++) { + if (tmp[i] == '.') { + param_name = tmp.substr(i+1).c_str(); + tmp.resize(i); + mod_name = tmp.c_str(); + return; + } + } + param_name = tmp.c_str(); + mod_name = symbol::null; + } + + params_ref & get_params(symbol const & mod_name) { + if (mod_name == symbol::null) { + return m_params; + } + else { + params_ref * p = 0; + if (!m_module_params.find(mod_name, p)) { + p = alloc(params_ref); + m_module_params.insert(mod_name, p); + } + SASSERT(p != 0); + return *p; + } + } + + void throw_unknown_parameter(symbol const & param_name, symbol const & mod_name) { + if (mod_name == symbol::null) { + char const * new_name = get_new_param_name(param_name); + if (new_name) { + throw exception("the parameter '%s' was renamed to '%s', invoke 'z3 -p' to obtain the new parameter list, and 'z3 -pp:%s' for the full description of the parameter", + param_name.bare_str(), new_name, new_name); + } + else if (is_old_param_name(param_name)) { + throw exception("unknown parameter '%s', this is an old parameter name, invoke 'z3 -p' to obtain the new parameter list", + param_name.bare_str()); + } + else { + throw exception("unknown parameter '%s'", param_name.bare_str()); + } + } + else { + throw exception("unknown parameter '%s' at module '%s'", param_name.bare_str(), mod_name.bare_str()); + } + } + + void set(param_descrs const & d, symbol const & param_name, char const * value, symbol const & mod_name) { + param_kind k = d.get_kind(param_name); + params_ref & ps = get_params(mod_name); + if (k == CPK_INVALID) { + throw_unknown_parameter(param_name, mod_name); + } + else if (k == CPK_UINT) { + long val = strtol(value, 0, 10); + ps.set_uint(param_name, static_cast(val)); + } + else if (k == CPK_DOUBLE) { + char * aux; + double val = strtod(value, &aux); + ps.set_double(param_name, val); + } + else if (k == CPK_BOOL) { + if (strcmp(value, "true") == 0) { + ps.set_bool(param_name, true); + } + else if (strcmp(value, "false") == 0) { + ps.set_bool(param_name, false); + } + else { + if (mod_name == symbol::null) + throw exception("invalid value '%s' for Boolean parameter '%s'", value, param_name.bare_str()); + else + throw exception("invalid value '%s' for Boolean parameter '%s' at module '%s'", value, param_name.bare_str(), mod_name.bare_str()); + } + } + else if (k == CPK_SYMBOL) { + ps.set_sym(param_name, symbol(value)); + } + else if (k == CPK_STRING) { + // There is no guarantee that (external) callers will not delete value after invoking gparams::set. + // I see two solutions: + // 1) Modify params_ref to create a copy of set_str parameters. + // This solution is not nice since we create copies and move the params_ref around. + // We would have to keep copying the strings. + // Moreover, when we use params_ref internally, the value is usually a static value. + // So, we would be paying this price for nothing. + // 2) "Copy" value by transforming it into a symbol. + // I'm using this solution for now. + ps.set_str(param_name, symbol(value).bare_str()); + } + else { + if (mod_name == symbol::null) + throw exception("unsupported parameter type '%s'", param_name.bare_str()); + else + throw exception("unsupported parameter type '%s' at module '%s'", param_name.bare_str(), mod_name.bare_str()); + } + } + + void set(char const * name, char const * value) { + bool error = false; + std::string error_msg; + #pragma omp critical (gparams) + { + try { + symbol m, p; + normalize(name, m, p); + if (m == symbol::null) { + set(get_param_descrs(), p, value, m); + } + else { + param_descrs * d; + if (get_module_param_descrs().find(m, d)) { + set(*d, p, value, m); + } + else { + throw exception("invalid parameter, unknown module '%s'", m.bare_str()); + } + } + } + catch (z3_exception & ex) { + // Exception cannot cross critical section boundaries. + error = true; + error_msg = ex.msg(); + } + } + if (error) + throw exception(error_msg); + } + + std::string get_value(params_ref const & ps, symbol const & p) { + std::ostringstream buffer; + ps.display(buffer, p); + return buffer.str(); + } + + std::string get_default(param_descrs const & d, symbol const & p, symbol const & m) { + if (!d.contains(p)) { + throw_unknown_parameter(p, m); + } + char const * r = d.get_default(p); + if (r == 0) + return "default"; + return r; + } + + std::string get_value(char const * name) { + std::string r; + bool error = false; + std::string error_msg; + #pragma omp critical (gparams) + { + try { + symbol m, p; + normalize(name, m, p); + if (m == symbol::null) { + if (m_params.contains(p)) { + r = get_value(m_params, p); + } + else { + r = get_default(get_param_descrs(), p, m); + } + } + else { + params_ref * ps = 0; + if (m_module_params.find(m, ps) && ps->contains(p)) { + r = get_value(*ps, p); + } + else { + param_descrs * d; + if (get_module_param_descrs().find(m, d)) { + r = get_default(*d, p, m); + } + else { + throw exception("unknown module '%s'", m.bare_str()); + } + } + } + } + catch (z3_exception & ex) { + // Exception cannot cross critical section boundaries. + error = true; + error_msg = ex.msg(); + } + } + if (error) + throw exception(error_msg); + return r; + } + + params_ref get_module(symbol const & module_name) { + params_ref result; + params_ref * ps = 0; + #pragma omp critical (gparams) + { + if (m_module_params.find(module_name, ps)) { + result = *ps; + } + } + return result; + } + + params_ref get() { + params_ref result; + TRACE("gparams", tout << "get() m_params: " << m_params << "\n";); + #pragma omp critical (gparams) + { + result = m_params; + } + return result; + } + + // ----------------------------------------------- + // + // Pretty printing + // + // ----------------------------------------------- + + void display(std::ostream & out, unsigned indent, bool smt2_style, bool include_descr) { + #pragma omp critical (gparams) + { + out << "Global parameters\n"; + get_param_descrs().display(out, indent + 4, smt2_style, include_descr); + out << "\n"; + if (!smt2_style) { + out << "To set a module parameter, use .=value\n"; + out << "Example: pp.decimal=true\n"; + out << "\n"; + } + dictionary::iterator it = get_module_param_descrs().begin(); + dictionary::iterator end = get_module_param_descrs().end(); + for (; it != end; ++it) { + out << "[module] " << it->m_key; + char const * descr = 0; + if (get_module_descrs().find(it->m_key, descr)) { + out << ", description: " << descr; + } + out << "\n"; + it->m_value->display(out, indent + 4, smt2_style, include_descr); + } + } + } + + void display_modules(std::ostream & out) { + #pragma omp critical (gparams) + { + dictionary::iterator it = get_module_param_descrs().begin(); + dictionary::iterator end = get_module_param_descrs().end(); + for (; it != end; ++it) { + out << "[module] " << it->m_key; + char const * descr = 0; + if (get_module_descrs().find(it->m_key, descr)) { + out << ", description: " << descr; + } + out << "\n"; + } + } + } + + void display_module(std::ostream & out, symbol const & module_name) { + bool error = false; + std::string error_msg; + #pragma omp critical (gparams) + { + try { + param_descrs * d = 0; + if (!get_module_param_descrs().find(module_name, d)) + throw exception("unknown module '%s'", module_name.bare_str()); + out << "[module] " << module_name; + char const * descr = 0; + if (get_module_descrs().find(module_name, descr)) { + out << ", description: " << descr; + } + out << "\n"; + d->display(out, 4, false); + } + catch (z3_exception & ex) { + // Exception cannot cross critical section boundaries. + error = true; + error_msg = ex.msg(); + } + } + if (error) + throw exception(error_msg); + } + + void display_parameter(std::ostream & out, char const * name) { + bool error = false; + std::string error_msg; + #pragma omp critical (gparams) + { + try { + symbol m, p; + normalize(name, m, p); + std::cout << name << " " << m << " " << p << "\n"; + param_descrs * d; + if (m == symbol::null) { + d = &get_param_descrs(); + } + else { + if (!get_module_param_descrs().find(m, d)) + throw exception("unknown module '%s'", m.bare_str()); + } + if (!d->contains(p)) + throw_unknown_parameter(p, m); + out << " name: " << p << "\n"; + if (m != symbol::null) { + out << " module: " << m << "\n"; + out << " qualified name: " << m << "." << p << "\n"; + } + out << " type: " << d->get_kind(p) << "\n"; + out << " description: " << d->get_descr(p) << "\n"; + out << " default value: " << d->get_default(p) << "\n"; + } + catch (z3_exception & ex) { + // Exception cannot cross critical section boundaries. + error = true; + error_msg = ex.msg(); + } + } + if (error) + throw exception(error_msg); + } +}; + +gparams::imp * gparams::g_imp = 0; + +void gparams::reset() { + SASSERT(g_imp != 0); + g_imp->reset(); +} + +void gparams::set(char const * name, char const * value) { + TRACE("gparams", tout << "setting [" << name << "] <- '" << value << "'\n";); + SASSERT(g_imp != 0); + g_imp->set(name, value); +} + +void gparams::set(symbol const & name, char const * value) { + SASSERT(g_imp != 0); + g_imp->set(name.bare_str(), value); +} + +std::string gparams::get_value(char const * name) { + SASSERT(g_imp != 0); + return g_imp->get_value(name); +} + +std::string gparams::get_value(symbol const & name) { + SASSERT(g_imp != 0); + return g_imp->get_value(name.bare_str()); +} + +void gparams::register_global(param_descrs & d) { + SASSERT(g_imp != 0); + g_imp->register_global(d); +} + +void gparams::register_module(char const * module_name, param_descrs * d) { + SASSERT(g_imp != 0); + g_imp->register_module(module_name, d); +} + +void gparams::register_module_descr(char const * module_name, char const * descr) { + SASSERT(g_imp != 0); + g_imp->register_module_descr(module_name, descr); +} + +params_ref gparams::get_module(char const * module_name) { + return get_module(symbol(module_name)); +} + +params_ref gparams::get_module(symbol const & module_name) { + SASSERT(g_imp != 0); + return g_imp->get_module(module_name); +} + +params_ref gparams::get() { + TRACE("gparams", tout << "gparams::get()\n";); + SASSERT(g_imp != 0); + return g_imp->get(); +} + +void gparams::display(std::ostream & out, unsigned indent, bool smt2_style, bool include_descr) { + SASSERT(g_imp != 0); + g_imp->display(out, indent, smt2_style, include_descr); +} + +void gparams::display_modules(std::ostream & out) { + SASSERT(g_imp != 0); + g_imp->display_modules(out); +} + +void gparams::display_module(std::ostream & out, char const * module_name) { + SASSERT(g_imp != 0); + g_imp->display_module(out, symbol(module_name)); +} + +void gparams::display_parameter(std::ostream & out, char const * name) { + SASSERT(g_imp != 0); + g_imp->display_parameter(out, name); +} + +void gparams::init() { + TRACE("gparams", tout << "gparams::init()\n";); + g_imp = alloc(imp); +} + +void gparams::finalize() { + TRACE("gparams", tout << "gparams::finalize()\n";); + if (g_imp != 0) { + dealloc(g_imp); + g_imp = 0; + } +} + + diff --git a/src/util/gparams.h b/src/util/gparams.h new file mode 100644 index 000000000..a55761830 --- /dev/null +++ b/src/util/gparams.h @@ -0,0 +1,140 @@ +/*++ +Copyright (c) 2012 Microsoft Corporation + +Module Name: + + gparams.h + +Abstract: + + Global parameter management. + +Author: + + Leonardo (leonardo) 2012-11-29 + +Notes: + +--*/ +#ifndef _GPARAMS_H_ +#define _GPARAMS_H_ + +#include"params.h" + +class gparams { + struct imp; + static imp * g_imp; +public: + typedef default_exception exception; + + /** + \brief Reset all global and module parameters. + */ + static void reset(); + + /** + \brief Set a global parameter \c name with \c value. + + The name of parameter can be composed of characters [a-z][A-Z], digits [0-9], '-' and '_'. + The character '.' is a delimiter (more later). + + The parameter names are case-insensitive. The character '-' should be viewed as an "alias" for '_'. + Thus, the following parameter names are considered equivalent: "auto-config" and "AUTO_CONFIG". + + This function can be used to set parameters for a specific Z3 module. + This can be done by using .. + For example: + set_global_param('pp.decimal', 'true') + will set the parameter "decimal" in the module "pp" to true. + + An exception is thrown if the the parameter name is unknown, or if the value is incorrect. + */ + static void set(char const * name, char const * value); + static void set(symbol const & name, char const * value); + + /** + \brief Auxiliary method used to implement get-option in SMT 2.0 front-end. + + If the parameter is not set, then it just returns 'default'. + + An exception is thrown if the the parameter name is unknown. + */ + static std::string get_value(char const * name); + static std::string get_value(symbol const & name); + + /** + \brief Register additional global parameters + + This is an auxiliary function used by our automatic code generator. + Example: the directive REG_PARAMS('collect_param_descrs') + "tells" the automatic code generator how to register the additional global parameters. + */ + static void register_global(param_descrs & d); + + /** + \brief Register parameter descriptions for a Z3 module. + The parameters of a given Z3 module can only be set using #set_global_param if + they are registered in this module using this function. + + This is an auxiliary function used by our automatic code generator. + Each module will contain directives (in comments) such as + Example: the directive REG_MODULE_PARAMS('nlsat', 'nlsat::solver::collect_param_descrs') + "tells" the automatic code generator how to register the parameters for the given + module. + */ + static void register_module(char const * module_name, param_descrs * d); + + /** + \brief Add a (small) description to the given module. + */ + static void register_module_descr(char const * module_name, char const * descr); + + /** + \brief Retrieves the parameters associated with the given module. + + Example: + // The following command sets the parameter "decimal" in the module "pp" to true. + set_global_param("pp.decimal", "true"); + ... + // The following command will return the global parameters that were set for the module "pp". + // In this example "p" will contain "decimal" -> true after executing this function. + params_ref const & p = get_module_params("pp") + */ + static params_ref get_module(char const * module_name); + static params_ref get_module(symbol const & module_name); + + /** + \brief Return the global parameter set (i.e., parameters that are not associated with any particular module). + */ + static params_ref get(); + + /** + \brief Dump information about available parameters in the given output stream. + */ + static void display(std::ostream & out, unsigned indent = 0, bool smt2_style=false, bool include_descr=true); + + // Auxiliary APIs for better command line support + static void display_modules(std::ostream & out); + static void display_module(std::ostream & out, char const * module_name); + static void display_parameter(std::ostream & out, char const * name); + + /** + \brief Initialize the global parameter management module. + + Remark: I set a priority in the initialization, because this module must be initialized + after the core modules such as symbol. + ADD_INITIALIZER('gparams::init();', 1) + */ + static void init(); + + /** + \brief Finalize the global parameter management module. + + ADD_FINALIZER('gparams::finalize();'); + */ + static void finalize(); +}; + + + +#endif diff --git a/src/util/ini_file.cpp b/src/util/ini_file.cpp deleted file mode 100644 index 48279a2ea..000000000 --- a/src/util/ini_file.cpp +++ /dev/null @@ -1,1564 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - ini_file.cpp - -Abstract: - - Configuration file support. - -Author: - - Leonardo de Moura (leonardo) 2007-05-10. - -Revision History: - ---*/ -#include"ini_file.h" -#include"util.h" -#include"trace.h" -#include"str_hashtable.h" -#include"map.h" -#include"string_buffer.h" -#include"symbol_table.h" -#include"error_codes.h" -#include - -template -class value_vector_map { - void * m_owner; - map *, ptr_hash, ptr_eq > m_mapping; - ptr_vector m_domain; - ptr_vector > m_range; - unsigned m_max_size; -public: - value_vector_map(void * owner):m_owner(owner), m_max_size(0) {} - - ~value_vector_map() { - std::for_each(m_range.begin(), m_range.end(), delete_proc >()); - } - - void insert(T * ptr, T const & value) { - SASSERT(reinterpret_cast(ptr) >= reinterpret_cast(m_owner)); - vector * vect; - if (m_mapping.find(ptr, vect)) { - vect->push_back(value); - if (vect->size() > m_max_size) - m_max_size = vect->size(); - return; - } - vect = alloc(vector); - m_range.push_back(vect); - m_domain.push_back(ptr); - vect->push_back(value); - if (m_max_size == 0) - m_max_size = 1; - m_mapping.insert(ptr, vect); - } - - void copy_params(void * curr_owner, unsigned idx) { - typename ptr_vector::iterator it = m_domain.begin(); - typename ptr_vector::iterator end = m_domain.end(); - for (; it != end; ++it) { - T * ptr = *it; - vector * vect = 0; - m_mapping.find(ptr, vect); - SASSERT(vect != 0); - if (idx < vect->size()) { - // BIG HACK - SASSERT(reinterpret_cast(ptr) >= reinterpret_cast(m_owner)); - size_t offset = reinterpret_cast(ptr) - reinterpret_cast(m_owner); - T * curr_ptr = reinterpret_cast(reinterpret_cast(curr_owner) + offset); - *curr_ptr = vect->operator[](idx); - } - } - } - - unsigned size(void) const { return m_max_size; } -}; - -struct param_vector_imp { - value_vector_map m_bool_params; - value_vector_map m_unsigned_params; - value_vector_map m_int_params; - value_vector_map m_double_params; - value_vector_map m_string_params; - value_vector_map m_symbol_params; - value_vector_map > m_symbol_list_params; - value_vector_map > m_symbol_nat_list_params; - - param_vector_imp(void * owner): - m_bool_params(owner), - m_unsigned_params(owner), - m_int_params(owner), - m_double_params(owner), - m_string_params(owner), - m_symbol_params(owner), - m_symbol_list_params(owner), - m_symbol_nat_list_params(owner) { - } - - void insert_bool_param(bool * value_ptr, bool value) { - TRACE("param_vector", tout << "insert: " << value_ptr << " -> " << value << "\n";); - m_bool_params.insert(value_ptr, value); - } - - void insert_unsigned_param(unsigned * value_ptr, unsigned value) { - TRACE("param_vector", tout << "insert: " << value_ptr << " -> " << value << "\n";); - m_unsigned_params.insert(value_ptr, value); - } - - void insert_int_param(int * value_ptr, int value) { - TRACE("param_vector", tout << "insert: " << value_ptr << " -> " << value << "\n";); - m_int_params.insert(value_ptr, value); - } - - void insert_double_param(double * value_ptr, double value) { - TRACE("param_vector", tout << "insert: " << value_ptr << " -> " << value << "\n";); - m_double_params.insert(value_ptr, value); - } - - void insert_string_param(std::string * value_ptr, std::string const & value) { - TRACE("param_vector", tout << "insert: " << value_ptr << " -> " << value << "\n";); - m_string_params.insert(value_ptr, value); - } - - void insert_symbol_param(symbol * value_ptr, symbol const & value) { - TRACE("param_vector", tout << "insert: " << value_ptr << " -> " << value << "\n";); - m_symbol_params.insert(value_ptr, value); - } - - void insert_symbol_list_param(svector * value_ptr, svector const & value) { - TRACE("param_vector", tout << "insert: " << value_ptr << " -> "; display(tout, value.begin(), value.end()); tout << "\n";); - m_symbol_list_params.insert(value_ptr, value); - } - - void insert_symbol_nat_list_param(svector * value_ptr, svector const & value) { - TRACE("param_vector", tout << "insert: " << value_ptr << " -> "; display(tout, value.begin(), value.end()); tout << "\n";); - m_symbol_nat_list_params.insert(value_ptr, value); - } - - void copy_params(void * curr_owner, unsigned idx) { - m_bool_params.copy_params(curr_owner, idx); - m_unsigned_params.copy_params(curr_owner, idx); - m_int_params.copy_params(curr_owner, idx); - m_double_params.copy_params(curr_owner, idx); - m_string_params.copy_params(curr_owner, idx); - m_symbol_params.copy_params(curr_owner, idx); - m_symbol_list_params.copy_params(curr_owner, idx); - m_symbol_nat_list_params.copy_params(curr_owner, idx); - } - - unsigned size(void) const { - unsigned ret = 0; - ret = std::max(ret, m_bool_params.size()); - ret = std::max(ret, m_unsigned_params.size()); - ret = std::max(ret, m_int_params.size()); - ret = std::max(ret, m_double_params.size()); - ret = std::max(ret, m_string_params.size()); - ret = std::max(ret, m_symbol_params.size()); - ret = std::max(ret, m_symbol_list_params.size()); - ret = std::max(ret, m_symbol_nat_list_params.size()); - return ret; - } -}; - - -param_vector::param_vector(void * owner): - m_ref_count(0) { - m_imp = alloc(param_vector_imp, owner); -} - -param_vector::~param_vector() { - dealloc(m_imp); -} - -void param_vector::inc_ref() { - m_ref_count++; -} - -void param_vector::dec_ref() { - SASSERT(m_ref_count > 0); - m_ref_count--; - if (m_ref_count == 0) - dealloc(this); -} - -void param_vector::copy_params(void * curr_owner, unsigned idx) { - m_imp->copy_params(curr_owner, idx); -} - -unsigned param_vector::size(void) const -{ - return m_imp->size(); -} - -enum itoken { - ITK_NULL, ITK_ID, ITK_NUM, ITK_DOUBLE, ITK_STRING, ITK_BAD_STRING, ITK_TRUE, ITK_FALSE, ITK_COMMA, ITK_LP, ITK_RP, ITK_LCB, ITK_RCB, ITK_CLN, ITK_EQ, ITK_BAD_ID, ITK_EOS, ITK_LAST -}; - -class ini_reserved_symbols { - typedef map str2token; - str2token m_str2token; - -public: - ini_reserved_symbols() { - m_str2token.insert("true", ITK_TRUE); - m_str2token.insert("false", ITK_FALSE); - } - - itoken string2itoken(char const * str) { - str2token::entry * e = m_str2token.find_core(const_cast(str)); - if (e) - return e->get_data().m_value; - else - return ITK_ID; - } -}; - -static char const * g_itoken2string[] = { - "", - "", - "", - "", - "", - "", - "true", - "false", - ",", - "(", - ")", - "{", - "}", - ":", - "=", - "", - "" -}; - -COMPILE_TIME_ASSERT(sizeof(g_itoken2string)/sizeof(char const*) == ITK_LAST); - -inline static const char * itoken2string(itoken t) { - return g_itoken2string[t]; -} - -inline itoken string2itoken(ini_reserved_symbols& reserved, char const * str) { - itoken r = reserved.string2itoken(str); - TRACE("token", tout << str << " -> " << itoken2string(r) << "\n";); - return r; -} - -class ini_lexer { - std::istream & m_input; - char m_curr_char; - int m_line; - int m_pos; - int m_tok_pos; - string_buffer<> m_buffer; - ini_reserved_symbols m_ini_reserved; -public: - bool eos() const { - return m_curr_char == EOF; - } - - void next() { - m_curr_char = m_input.get(); - m_pos++; - } - - void save_and_next() { - m_buffer << m_curr_char; - next(); - } - - ini_lexer(std::istream & input): - m_input(input), - m_line(1), - m_pos(0), - m_tok_pos(0), - m_ini_reserved() { - next(); - } - - itoken read_num() { - while (isdigit(m_curr_char)) { - save_and_next(); - } - if (m_curr_char == '.') { - save_and_next(); - while (isdigit(m_curr_char)) { - save_and_next(); - } - if (m_curr_char == 'e' || m_curr_char == 'E' || m_curr_char == 'd' || m_curr_char == 'D') { - save_and_next(); - if (m_curr_char == '-') { - save_and_next(); - } - while (isdigit(m_curr_char)) { - save_and_next(); - } - } - return ITK_DOUBLE; - } - return ITK_NUM; - } - - itoken read_id() { - while (!eos() && (isalpha(m_curr_char) || isdigit(m_curr_char) || m_curr_char == '_')) { - save_and_next(); - } - return string2itoken(m_ini_reserved, m_buffer.c_str()); - } - - itoken read_string() { - m_tok_pos = m_pos; - next(); - while (m_curr_char != '"' && m_curr_char != '\'') { - if (m_input.eof()) { - return ITK_BAD_STRING; - } - if (m_curr_char == '\n') { - return ITK_BAD_STRING; - } - if (m_curr_char == '\\') { - next(); // do not save the '\' - switch (m_curr_char) { - case 't': - m_buffer << '\t'; - next(); - break; - case 'n': - m_buffer << '\n'; - next(); - break; - case '\n': - m_buffer << '\n'; - next(); - break; - default: - if (!isdigit(m_curr_char)) { - save_and_next(); /* handles \\, \", \', and \? */ - } - else { /* \xxx */ - int c = 0; - int i = 0; - do { - c = 10*c + (m_curr_char-'0'); - next(); - } - while (++i<3 && isdigit(m_curr_char)); - if (c > UCHAR_MAX) { - return ITK_BAD_STRING; - } - m_buffer << static_cast(c); - } - } - } - else { - save_and_next(); - } - } - next(); - return ITK_STRING; - } - - itoken next_token() { - for(;;) { - if (eos()) { - return ITK_EOS; - } - - m_buffer.reset(); - switch (m_curr_char) { - case ';': // comment - while (m_curr_char != '\n' && !eos()) { - next(); - } - break; - case '\n': - next(); - m_line++; - break; - case '=': - m_tok_pos = m_pos; - next(); - return ITK_EQ; - case '\'': - case '\"': - return read_string(); - case '{': - m_tok_pos = m_pos; - next(); - return ITK_LCB; - case '}': - m_tok_pos = m_pos; - next(); - return ITK_RCB; - case '(': - m_tok_pos = m_pos; - next(); - return ITK_LP; - case ')': - m_tok_pos = m_pos; - next(); - return ITK_RP; - case ',': - m_tok_pos = m_pos; - next(); - return ITK_COMMA; - case ':': - m_tok_pos = m_pos; - next(); - return ITK_CLN; - default: - if (isspace(m_curr_char)) { - next(); - break; - } - else if (isdigit(m_curr_char)) { - m_tok_pos = m_pos; - save_and_next(); - return read_num(); - } - else { - char old = m_curr_char; - m_tok_pos = m_pos; - save_and_next(); - TRACE("ini_lexer", tout << "old: " << static_cast(old) << " " << old << "\n";); - if (old == '-' && isdigit(m_curr_char)) { - return read_num(); - } - else if (old == '_' || isalpha(old)) { - return read_id(); - } - else { - return ITK_BAD_ID; - } - } - } - } - } - - char const * get_token_data() const { - return m_buffer.c_str(); - } - - unsigned get_token_pos() const { - return m_tok_pos; - } -}; - - -enum ini_param_kind { - IPK_BOOL, - IPK_INT, - IPK_UNSIGNED, - IPK_DOUBLE, - IPK_PERCENTAGE, - IPK_STRING, - IPK_SYMBOL, - IPK_SYMBOL_LIST, - IPK_SYMBOL_NAT_LIST -}; - - -struct ini_param_info { - ini_param_kind m_kind; - bool m_is_mutable; - - char const * m_description; - union { - struct { - int m_int_min; - int m_int_max; - int * m_int_val; - }; - struct { - unsigned m_uint_min; - unsigned m_uint_max; - unsigned * m_uint_val; - }; - bool * m_bool_val; - double * m_double_val; - double * m_perc_val; - symbol * m_sym_val; - std::string * m_str_val; - svector * m_sym_list_val; - svector * m_sym_nat_list_val; - }; - - ini_param_info(char const * descr = 0): - m_kind(IPK_BOOL), - m_is_mutable(false), - m_description(descr), - m_bool_val(0) { - } - - ini_param_info(int min, int max, int * val, char const * descr, bool is_mutable): - m_kind(IPK_INT), - m_is_mutable(is_mutable), - m_description(descr), - m_int_min(min), - m_int_max(max), - m_int_val(val) { - } - - ini_param_info(unsigned min, unsigned max, unsigned * val, char const * descr, bool is_mutable): - m_kind(IPK_UNSIGNED), - m_is_mutable(is_mutable), - m_description(descr), - m_uint_min(min), - m_uint_max(max), - m_uint_val(val) { - } - - ini_param_info(bool * val, char const * descr, bool is_mutable): - m_kind(IPK_BOOL), - m_is_mutable(is_mutable), - m_description(descr), - m_bool_val(val) { - } - - ini_param_info(bool perc, double * val, char const * descr, bool is_mutable): - m_kind(perc ? IPK_PERCENTAGE : IPK_DOUBLE), - m_is_mutable(is_mutable), - m_description(descr), - m_perc_val(val) { - } - - ini_param_info(svector * val, char const * descr, bool is_mutable): - m_kind(IPK_SYMBOL_LIST), - m_is_mutable(is_mutable), - m_description(descr), - m_sym_list_val(val) { - } - - ini_param_info(svector * val, char const * descr, bool is_mutable): - m_kind(IPK_SYMBOL_NAT_LIST), - m_is_mutable(is_mutable), - m_description(descr), - m_sym_nat_list_val(val) { - } - - ini_param_info(symbol * s, char const * descr, bool is_mutable): - m_kind(IPK_SYMBOL), - m_is_mutable(is_mutable), - m_description(descr), - m_sym_val(s) { - } - - ini_param_info(std::string * str, char const * descr, bool is_mutable): - m_kind(IPK_STRING), - m_is_mutable(is_mutable), - m_description(descr), - m_str_val(str) { - } - -}; - -struct ini_params_imp { - bool m_abort_on_error; - ini_reserved_symbols m_ini_reserved; - ref m_param_vector; - symbol_table m_param_info; - bool m_is_frozen; - - ini_params_imp(bool abort_on_error): m_abort_on_error(abort_on_error), m_is_frozen(false) {} - - void freeze(bool f) { m_is_frozen = f; } - - void register_param_vector(param_vector * pv) { - m_param_vector = pv; - } - - void register_bool_param(symbol param_name, bool & value, char const * descr, bool is_mutable) { - SASSERT(!m_param_info.contains(param_name)); - m_param_info.insert(param_name, ini_param_info(&value, descr, is_mutable)); - } - - void register_unsigned_param(symbol param_name, unsigned min, unsigned max, unsigned & value, char const * descr, bool is_mutable) { - SASSERT(!m_param_info.contains(param_name)); - m_param_info.insert(param_name, ini_param_info(min, max, &value, descr, is_mutable)); - } - - void register_int_param(symbol param_name, int min, int max, int & value, char const * descr, bool is_mutable) { - SASSERT(!m_param_info.contains(param_name)); - m_param_info.insert(param_name, ini_param_info(min, max, &value, descr, is_mutable)); - } - - void register_percentage_param(symbol param_name, double & value, char const * descr, bool is_mutable) { - SASSERT(!m_param_info.contains(param_name)); - m_param_info.insert(param_name, ini_param_info(true, &value, descr, is_mutable)); - } - - void register_double_param(symbol param_name, double & value, char const * descr, bool is_mutable) { - SASSERT(!m_param_info.contains(param_name)); - m_param_info.insert(param_name, ini_param_info(false, &value, descr, is_mutable)); - } - - void register_string_param(symbol param_name, std::string & value, char const * descr, bool is_mutable) { - SASSERT(!m_param_info.contains(param_name)); - m_param_info.insert(param_name, ini_param_info(&value, descr, is_mutable)); - } - - void register_symbol_param(symbol param_name, symbol & value, char const * descr, bool is_mutable) { - SASSERT(!m_param_info.contains(param_name)); - m_param_info.insert(param_name, ini_param_info(&value, descr, is_mutable)); - } - - void register_symbol_list_param(symbol param_name, svector & value, char const * descr, bool is_mutable) { - SASSERT(!m_param_info.contains(param_name)); - m_param_info.insert(param_name, ini_param_info(&value, descr, is_mutable)); - } - - void register_symbol_nat_list_param(symbol param_name, svector & value, char const * descr, bool is_mutable) { - SASSERT(!m_param_info.contains(param_name)); - m_param_info.insert(param_name, ini_param_info(&value, descr, is_mutable)); - } - - struct symbol_lt_proc { - bool operator()(const symbol & s1, const symbol & s2) const { - return strcmp(s1.bare_str(), s2.bare_str()) < 0; - } - }; - - void display_param_help(char const* param_id, std::ostream& out) const { - ini_param_info info; - if (m_param_info.find(symbol(param_id), info)) { - display_param_info(out, info); - } - else { - out << "option " << param_id << " does not exist"; - } - } - - void display_param_info(std::ostream& out, ini_param_info& info) const { - switch (info.m_kind) { - case IPK_BOOL: - out << " boolean"; - out << ", default: " << (*info.m_bool_val ? "true" : "false"); - break; - case IPK_INT: - out << " integer"; - if (info.m_int_min > INT_MIN) { - out << ", min: " << info.m_int_min; - } - if (info.m_int_max < INT_MAX) { - out << ", max: " << info.m_int_max; - } - out << ", default: " << *info.m_int_val; - break; - case IPK_UNSIGNED: - out << " unsigned integer"; - if (info.m_uint_min > 0) { - out << ", min: " << info.m_uint_min; - } - if (info.m_uint_max < INT_MAX) { - out << ", max: " << info.m_uint_max; - } - out << ", default: " << *info.m_uint_val; - break; - case IPK_DOUBLE: - out << " double"; - out << ", default: " << *info.m_double_val; - break; - case IPK_PERCENTAGE: - out << " percentage"; - out << ", default: " << *info.m_perc_val; - break; - case IPK_SYMBOL: - out << " symbol"; - out << ", default: " << *info.m_sym_val; - break; - case IPK_STRING: - out << " string"; - out << ", default: " << *info.m_str_val; - break; - case IPK_SYMBOL_LIST: - out << " list of symbols (strings)"; - break; - case IPK_SYMBOL_NAT_LIST: - out << " list of pairs: symbols(strings) x unsigned"; - break; - } - if (info.m_description) { - out << ", " << info.m_description << "."; - } - out << "\n"; - } - - void display_params(std::ostream & out) const { - svector params; - m_param_info.get_dom(params); - std::sort(params.begin(), params.end(), symbol_lt_proc()); - svector::iterator it = params.begin(); - svector::iterator end = params.end(); - for (; it != end; ++it) { - out << *it << ":"; - ini_param_info info; - m_param_info.find(*it, info); - display_param_info(out, info); - } - } - - void display_params_documentation(std::ostream & out) const { - out << "// AUTOMATICALLY GENERATED FILE - DO NOT EDIT\n\n" - << "/**\n" - << " \\page config INI parameters\n\n"; - svector params; - m_param_info.get_dom(params); - std::sort(params.begin(), params.end(), symbol_lt_proc()); - svector::iterator it = params.begin(); - svector::iterator end = params.end(); - for (; it != end; ++it) { - out << "- \\c " << *it << ":"; - ini_param_info info; - m_param_info.find(*it, info); - switch (info.m_kind) { - case IPK_BOOL: - out << " \\em boolean"; - out << ", default: " << (*info.m_bool_val ? "\\c true" : "\\c false"); - break; - case IPK_INT: - out << " \\em integer"; - if (info.m_int_min > INT_MIN) { - out << ", min: \\c " << info.m_int_min; - } - if (info.m_int_max < INT_MAX) { - out << ", max: \\c " << info.m_int_max; - } - out << ", default: \\c " << *info.m_int_val; - break; - case IPK_UNSIGNED: - out << " \\em unsigned \\em integer"; - if (info.m_uint_min > 0) { - out << ", min: \\c " << info.m_uint_min; - } - if (info.m_uint_max < INT_MAX) { - out << ", max: \\c " << info.m_uint_max; - } - out << ", default: \\c " << *info.m_uint_val; - break; - case IPK_DOUBLE: - out << " \\em double"; - out << ", default: \\c " << *info.m_double_val; - break; - case IPK_PERCENTAGE: - out << " \\em percentage"; - out << ", default: \\c " << *info.m_perc_val; - break; - case IPK_STRING: - out << " \\em string"; - out << ", default: " << *info.m_str_val; - break; - case IPK_SYMBOL: - out << " \\em symbol"; - out << ", default: " << *info.m_sym_val; - break; - case IPK_SYMBOL_LIST: - out << " \\em list \\em of \\em symbols \\em (strings)"; - break; - case IPK_SYMBOL_NAT_LIST: - out << " \\em list \\em of \\em pairs: \\em symbols(strings) \\em x \\em unsigned"; - break; - } - if (info.m_description) { - out << ", " << info.m_description << "."; - } - out << "\n\n"; - } - out << "*/\n"; - } - - void error(char const * param_id, char const * msg) { - if (m_abort_on_error) { - verbose_stream() << "Error setting '" << param_id << "', reason: " << msg << "\n"; - throw z3_error(ERR_INI_FILE); - } - else { - throw set_get_param_exception(param_id, msg); - } - } - - symbol trim(char const * param_id) { - string_buffer<> m_buffer; - while (*param_id != 0 && !isspace(*param_id)) { - m_buffer.append(*param_id); - param_id++; - } - return symbol(m_buffer.c_str()); - } - - void set_param_value(char const * param_id, char const * param_value) { - TRACE("param_value", tout << param_id << " " << param_value << "\n";); - if (param_value == 0) { - error(param_id, "invalid (null) option"); - } - symbol s(param_id); - ini_param_info info; - if (!m_param_info.find(s, info)) { - s = trim(param_id); - if (!m_param_info.find(s, info)) - error(param_id, "unknown option."); - } - if (!info.m_is_mutable && m_is_frozen) { - error(param_id, "option value cannot be modified after initialization"); - } - switch (info.m_kind) { - case IPK_BOOL: - parse_bool_param(param_id, info, param_value); - break; - case IPK_INT: - parse_int_param(param_id, info, param_value); - break; - case IPK_UNSIGNED: - parse_uint_param(param_id, info, param_value); - break; - case IPK_DOUBLE: - parse_double_param(param_id, info, param_value); - break; - case IPK_PERCENTAGE: - parse_perc_param(param_id, info, param_value); - break; - case IPK_STRING: - parse_string_param(param_id, info, param_value); - break; - case IPK_SYMBOL: - // TODO: not used so far - *info.m_sym_val = param_value; - break; - case IPK_SYMBOL_LIST: - error(param_id, "this option can only be set in an INI file"); - break; - case IPK_SYMBOL_NAT_LIST: - error(param_id, "this option can only be set in an INI file"); - break; - default: - UNREACHABLE(); - } - } - - - bool get_param_value(char const * param_id, std::string& param_value) { - TRACE("param_value", tout << param_id << "\n";); - std::ostringstream buffer; - symbol s(param_id); - ini_param_info info; - if (!m_param_info.find(s, info)) { - s = trim(param_id); - if (!m_param_info.find(s, info)) { - return false; - } - } - switch (info.m_kind) { - case IPK_BOOL: - buffer << ((*info.m_bool_val)?"true":"false"); - break; - case IPK_INT: - buffer << (*info.m_int_val); - break; - case IPK_UNSIGNED: - buffer << (*info.m_uint_val); - break; - case IPK_DOUBLE: - buffer << (*info.m_double_val); - break; - case IPK_PERCENTAGE: - buffer << (*info.m_perc_val); - break; - case IPK_STRING: - buffer << (*info.m_str_val); - break; - case IPK_SYMBOL: - buffer << (info.m_sym_val->str()); - break; - case IPK_SYMBOL_LIST: - error(param_id, "this option cannot be retrieved"); - break; - case IPK_SYMBOL_NAT_LIST: - error(param_id, "this option cannot be retrieved"); - break; - default: - UNREACHABLE(); - } - param_value = buffer.str(); - return true; - } - - string_buffer<> m_buffer; - - char const * get_token_data() const { - return m_buffer.c_str(); - } - - void save_and_next(char const * & in) { - m_buffer.append(*in); - ++in; - } - - itoken read_num(char const * & in) { - while (isdigit(*in)) { - save_and_next(in); - } - TRACE("read_num", tout << "1. read_num: " << m_buffer.c_str() << ", *in: " << *in << "\n";); - if (*in == '.') { - save_and_next(in); - while (isdigit(*in)) { - save_and_next(in); - } - TRACE("read_num", tout << "2. read_num: " << m_buffer.c_str() << ", *in: " << *in << "\n";); - if (*in == 'e' || *in == 'E' || *in == 'd' || *in == 'D') { - save_and_next(in); - if (*in == '-') { - save_and_next(in); - } - while (isdigit(*in)) { - save_and_next(in); - } - } - return ITK_DOUBLE; - } - return ITK_NUM; - } - - itoken read_id(char const * & in) { - while (!*in == 0 && (isalpha(*in) || isdigit(*in) || *in == '_')) { - save_and_next(in); - } - return string2itoken(m_ini_reserved, m_buffer.c_str()); - } - - itoken read_string(char const * & in) { - ++in; - while (*in != '"' && *in != '\'') { - TRACE("read_string", tout << *in << "\n";); - if (*in == 0) - return ITK_BAD_STRING; - if (*in == '\n') - return ITK_BAD_STRING; - if (*in == '\\') { - ++in; - switch (*in) { - case 't': - m_buffer << '\t'; - ++in; - break; - case 'n': - m_buffer << '\n'; - ++in; - break; - case '\n': - m_buffer << '\n'; - ++in; - break; - default: - if (!isdigit(*in)) { - save_and_next(in); /* handles \\, \", \', and \? */ - } - else { /* \xxx */ - int c = 0; - int i = 0; - do { - c = 10*c + (*in-'0'); - ++in; - } - while (++i<3 && isdigit(*in)); - if (c > UCHAR_MAX) - return ITK_BAD_STRING; - m_buffer << static_cast(c); - } - } - } - else { - save_and_next(in); - } - } - ++in; - return ITK_STRING; - } - - itoken next_token(char const * & in) { - for(;;) { - if (*in == 0) - return ITK_EOS; - m_buffer.reset(); - switch (*in) { - case '{': - in++; - return ITK_LCB; - case '}': - in++; - return ITK_RCB; - case ',': - in++; - return ITK_COMMA; - case '"': - case '\'': - TRACE("read_string", tout << "found \"\n";); - return read_string(in); - default: - if (isspace(*in)) { - in++; - break; - } - else if (isdigit(*in)) { - TRACE("read_num", tout << "found is_digit\n";); - return read_num(in); - } - else { - char old = *in; - save_and_next(in); - if (old == '-' && isdigit(*in)) { - return read_num(in); - } - else if (old == '_' || isalpha(old)) { - return read_id(in); - } - else { - return ITK_BAD_ID; - } - } - } - } - } - - bool end_of_list(char const * param_id, char const * & param_value) { - switch (next_token(param_value)) { - case ITK_COMMA: - return false; - case ITK_RCB: - return true; - default: - error(param_id, "boolean value (true/false) expected"); - } - return false; - } - - void parse_bool_param(char const * param_id, ini_param_info & info, char const * param_value) { - switch (next_token(param_value)) { - case ITK_TRUE: - *info.m_bool_val = true; - break; - case ITK_FALSE: - *info.m_bool_val = false; - break; - default: - error(param_id, "boolean value (true/false) expected"); - } - if (m_param_vector.get() && next_token(param_value) == ITK_LCB) { - for (;;) { - switch (next_token(param_value)) { - case ITK_TRUE: - m_param_vector->m_imp->insert_bool_param(info.m_bool_val, true); - break; - case ITK_FALSE: - m_param_vector->m_imp->insert_bool_param(info.m_bool_val, false); - break; - default: - error(param_id, "boolean value (true/false) expected"); - } - if (end_of_list(param_id, param_value)) - return; - } - } - } - - void parse_int_param(char const * param_id, ini_param_info & info, char const * param_value) { - if (next_token(param_value) != ITK_NUM) - error(param_id, "integer expected"); - int val = strtol(get_token_data(), 0, 10); - if (val < info.m_int_min || val > info.m_int_max) - error(param_id, "integer out of bounds"); - *info.m_int_val = val; - if (m_param_vector.get() && next_token(param_value) == ITK_LCB) { - for (;;) { - if (next_token(param_value) != ITK_NUM) - error(param_id, "integer expected"); - int val = strtol(get_token_data(), 0, 10); - if (val < info.m_int_min || val > info.m_int_max) - error(param_id, "integer out of bounds"); - m_param_vector->m_imp->insert_int_param(info.m_int_val, val); - if (end_of_list(param_id, param_value)) - return; - } - } - } - - void parse_uint_param(char const * param_id, ini_param_info & info, char const * param_value) { - if (next_token(param_value) != ITK_NUM) - error(param_id, "integer expected"); - unsigned val = static_cast(strtol(get_token_data(), 0, 10)); - - if (val < info.m_uint_min || val > info.m_uint_max) - error(param_id, "unsigned out of bounds"); - *info.m_uint_val = val; - if (m_param_vector.get() && next_token(param_value) == ITK_LCB) { - for (;;) { - if (next_token(param_value) != ITK_NUM) - error(param_id, "integer expected"); - unsigned val = static_cast(strtol(get_token_data(), 0, 10)); - if (val < info.m_uint_min || val > info.m_uint_max) - error(param_id, "unsigned out of bounds"); - m_param_vector->m_imp->insert_unsigned_param(info.m_uint_val, val); - if (end_of_list(param_id, param_value)) - return; - } - } - } - - void parse_double_param(char const * param_id, ini_param_info & info, char const * param_value) { - itoken k = next_token(param_value); - if (k != ITK_NUM && k != ITK_DOUBLE) - error(param_id, "float expected"); - char * aux; - *info.m_double_val = strtod(get_token_data(), &aux); - if (m_param_vector.get() && next_token(param_value) == ITK_LCB) { - for (;;) { - k = next_token(param_value); - if (k != ITK_NUM && k != ITK_DOUBLE) - error(param_id, "float expected"); - m_param_vector->m_imp->insert_double_param(info.m_double_val, strtod(get_token_data(), &aux)); - if (end_of_list(param_id, param_value)) - return; - } - } - } - - void parse_perc_param(char const * param_id, ini_param_info & info, char const * param_value) { - if (next_token(param_value) != ITK_NUM) - error(param_id, "integer expected"); - int val = strtol(get_token_data(), 0, 10); - if (val < 0 || val > 100) - error(param_id, "integer between 0 and 100 expected"); - *info.m_perc_val = static_cast(val)/100.0; - if (m_param_vector.get() && next_token(param_value) == ITK_LCB) { - for (;;) { - if (next_token(param_value) != ITK_NUM) - error(param_id, "integer expected"); - int val = strtol(get_token_data(), 0, 10); - if (val < 0 || val > 100) - error(param_id, "integer between 0 and 100 expected"); - m_param_vector->m_imp->insert_double_param(info.m_perc_val, static_cast(val)/100.0); - if (end_of_list(param_id, param_value)) - return; - } - } - } - - void parse_string_param(char const * param_id, ini_param_info & info, char const * param_value) { - if (next_token(param_value) != ITK_STRING) - error(param_id, "string expected"); - *info.m_str_val = get_token_data(); - if (m_param_vector.get() && next_token(param_value) == ITK_LCB) { - for (;;) { - if (next_token(param_value) != ITK_STRING) - error(param_id, "string expected"); - m_param_vector->m_imp->insert_string_param(info.m_str_val, get_token_data()); - if (end_of_list(param_id, param_value)) - return; - } - } - } -}; - -class ini_parser { - ini_lexer m_lexer; - ini_params_imp * m_params; - itoken m_curr_token; - - void error(unsigned pos, char const * msg) { - if (m_params->m_abort_on_error) { - verbose_stream() << "Error INI file [position: " << pos << "]: " << msg << "\n"; - throw z3_error(ERR_INI_FILE); - } - else { - throw ini_parser_exception(pos, msg); - } - } - - void error(char const * msg) { - error(m_lexer.get_token_pos(), msg); - } - - itoken get_curr_token() { - if (m_curr_token == ITK_NULL) { - m_curr_token = m_lexer.next_token(); - } - SASSERT(m_curr_token != ITK_NULL); - return m_curr_token; - } - - void next() { - if (m_curr_token == ITK_NULL) { - m_lexer.next_token(); - } - else { - m_curr_token = ITK_NULL; - } - } - - char const * get_token_data() { - if (m_curr_token == ITK_NULL) { - get_curr_token(); - } - SASSERT(m_curr_token != ITK_NULL); - return m_lexer.get_token_data(); - } - - bool test_next(itoken expected) { - if (get_curr_token() == expected) { - next(); - return true; - } - else { - return false; - } - } - - void check(itoken expected) { - if (!test_next(expected)) { - string_buffer<> msg; - msg << "unexpected token '" << itoken2string(get_curr_token()) - << "', '" << itoken2string(expected) << "' expected."; - error(msg.c_str()); - } - } - -public: - ini_parser(std::istream & in, ini_params_imp * p): - m_lexer(in), - m_params(p), - m_curr_token(ITK_NULL) { - } - - void parse_param() { - symbol s(get_token_data()); - check(ITK_ID); - ini_param_info info; - if (!m_params->m_param_info.find(s, info)) { - error("unknown option."); - } - check(ITK_EQ); - switch (info.m_kind) { - case IPK_BOOL: - parse_bool_param(info); - break; - case IPK_INT: - parse_int_param(info); - break; - case IPK_UNSIGNED: - parse_uint_param(info); - break; - case IPK_DOUBLE: - parse_double_param(info); - break; - case IPK_PERCENTAGE: - parse_perc_param(info); - break; - case IPK_STRING: - parse_string_param(info); - break; - case IPK_SYMBOL: - // TODO: add support for VAL{VAL,...,VAL} - *info.m_sym_val = get_token_data(); - check(ITK_STRING); - break; - case IPK_SYMBOL_NAT_LIST: - parse_symbol_nat_list(info); - break; - case IPK_SYMBOL_LIST: - parse_symbol_list(info); - break; - default: - UNREACHABLE(); - } - } - - bool end_of_list() { - switch (get_curr_token()) { - case ITK_COMMA: - next(); - return false; - case ITK_RCB: - next(); - return true; - default: - error("boolean value expected"); - } - return false; - } - - void parse_bool_param(ini_param_info & info) { - if (get_curr_token() != ITK_TRUE && get_curr_token() != ITK_FALSE) - error("boolean value expected"); - *info.m_bool_val = get_curr_token() == ITK_TRUE; - next(); - if (m_params->m_param_vector.get() && get_curr_token() == ITK_LCB) { - next(); - for (;;) { - if (get_curr_token() != ITK_TRUE && get_curr_token() != ITK_FALSE) - error("boolean value expected"); - m_params->m_param_vector->m_imp->insert_bool_param(info.m_bool_val, get_curr_token() == ITK_TRUE); - next(); - if (end_of_list()) - return; - } - } - } - - void parse_int_param(ini_param_info & info) { - if (get_curr_token() != ITK_NUM) - error("integer expected"); - int val = strtol(get_token_data(), 0, 10); - if (val < info.m_int_min || val > info.m_int_max) - error("integer out of bounds"); - *info.m_int_val = val; - next(); - TRACE("int_param", tout << "val: " << val << "\n";); - if (m_params->m_param_vector.get() && get_curr_token() == ITK_LCB) { - next(); - for (;;) { - if (get_curr_token() != ITK_NUM) - error("integer expected"); - int val = strtol(get_token_data(), 0, 10); - if (val < info.m_int_min || val > info.m_int_max) - error("integer out of bounds"); - m_params->m_param_vector->m_imp->insert_int_param(info.m_int_val, val); - next(); - if (end_of_list()) - return; - } - } - } - - void parse_uint_param(ini_param_info & info) { - if (get_curr_token() != ITK_NUM) - error("integer expected"); - long val = strtol(get_token_data(), 0, 10); - if (val < static_cast(info.m_uint_min) || val > static_cast(info.m_uint_max)) - error("integer out of bounds"); - *info.m_uint_val = val; - next(); - if (m_params->m_param_vector.get() && get_curr_token() == ITK_LCB) { - next(); - for (;;) { - if (get_curr_token() != ITK_NUM) - error("integer expected"); - long val = strtol(get_token_data(), 0, 10); - if (val < static_cast(info.m_uint_min) || val > static_cast(info.m_uint_max)) - error("integer out of bounds"); - m_params->m_param_vector->m_imp->insert_unsigned_param(info.m_uint_val, val); - next(); - if (end_of_list()) - return; - } - } - } - - void parse_double_param(ini_param_info & info) { - if (get_curr_token() != ITK_NUM && get_curr_token() != ITK_DOUBLE) - error("float expected"); - char * aux; - *info.m_double_val = strtod(get_token_data(), &aux); - next(); - if (m_params->m_param_vector.get() && get_curr_token() == ITK_LCB) { - next(); - for (;;) { - if (get_curr_token() != ITK_NUM && get_curr_token() != ITK_DOUBLE) - error("float expected"); - m_params->m_param_vector->m_imp->insert_double_param(info.m_double_val, strtod(get_token_data(), &aux)); - next(); - if (end_of_list()) - return; - } - } - } - - void parse_perc_param(ini_param_info & info) { - if (get_curr_token() != ITK_NUM) - error("integer expected"); - int val = strtol(get_token_data(), 0, 10); - if (val < 0 || val > 100) - error("integer between 0 and 100 expected"); - *info.m_perc_val = static_cast(val)/100.0; - next(); - if (m_params->m_param_vector.get() && get_curr_token() == ITK_LCB) { - next(); - for (;;) { - if (get_curr_token() != ITK_NUM) - error("integer expected"); - int val = strtol(get_token_data(), 0, 10); - if (val < 0 || val > 100) - error("integer between 0 and 100 expected"); - m_params->m_param_vector->m_imp->insert_double_param(info.m_perc_val, static_cast(val)/100.0); - next(); - if (end_of_list()) - return; - } - } - } - - void parse_string_param(ini_param_info & info) { - if (get_curr_token() != ITK_STRING) - error("string expected"); - *info.m_str_val = get_token_data(); - next(); - if (m_params->m_param_vector.get() && get_curr_token() == ITK_LCB) { - next(); - for (;;) { - if (get_curr_token() != ITK_STRING) - error("string expected"); - m_params->m_param_vector->m_imp->insert_string_param(info.m_str_val, get_token_data()); - next(); - if (end_of_list()) - return; - } - } - } - - void parse_s_list(svector & result) { - check(ITK_LP); - for (;;) { - symbol s(get_token_data()); - result.push_back(s); - check(ITK_ID); - if (!test_next(ITK_COMMA)) { - check(ITK_RP); - return; - } - } - } - - void parse_symbol_list(ini_param_info & info) { - parse_s_list(*(info.m_sym_list_val)); - if (m_params->m_param_vector.get() && test_next(ITK_LCB)) { - for (;;) { - svector lst; - parse_s_list(lst); - m_params->m_param_vector->m_imp->insert_symbol_list_param(info.m_sym_list_val, lst); - if (!test_next(ITK_COMMA)) { - check(ITK_RCB); - return; - } - } - } - } - - void parse_sn_list(svector & result) { - check(ITK_LP); - for (;;) { - symbol s(get_token_data()); - check(ITK_ID); - check(ITK_CLN); - unsigned val = strtol(get_token_data(), 0, 10); - check(ITK_NUM); - result.push_back(std::make_pair(s, val)); - if (!test_next(ITK_COMMA)) { - check(ITK_RP); - return; - } - } - } - - void parse_symbol_nat_list(ini_param_info & info) { - parse_sn_list(*(info.m_sym_nat_list_val)); - if (m_params->m_param_vector.get() && test_next(ITK_LCB)) { - for (;;) { - svector lst; - parse_sn_list(lst); - m_params->m_param_vector->m_imp->insert_symbol_nat_list_param(info.m_sym_nat_list_val, lst); - if (!test_next(ITK_COMMA)) { - check(ITK_RCB); - return; - } - } - } - } - - void parse() { - while (get_curr_token() != ITK_EOS) { - parse_param(); - } - } -}; - -ini_params::ini_params(bool abort_on_error) { - m_imp = alloc(ini_params_imp, abort_on_error); -} - -ini_params::~ini_params() { - dealloc(m_imp); -} - -void ini_params::register_bool_param(char const * param_name, bool & value, char const * descr, bool is_mutable) { - m_imp->register_bool_param(symbol(param_name), value, descr, is_mutable); -} - -void ini_params::register_unsigned_param(char const * param_name, unsigned min, unsigned max, unsigned & value, char const * descr, bool is_mutable) { - m_imp->register_unsigned_param(symbol(param_name), min, max, value, descr, is_mutable); -} - -void ini_params::register_int_param(char const * param_name, int min, int max, int & value, char const * descr, bool is_mutable) { - m_imp->register_int_param(symbol(param_name), min, max, value, descr, is_mutable); -} - -void ini_params::register_double_param(char const * param_name, double & value, char const * descr, bool is_mutable) { - m_imp->register_double_param(symbol(param_name), value, descr, is_mutable); -} - -void ini_params::register_percentage_param(char const * param_name, double & value, char const * descr, bool is_mutable) { - m_imp->register_percentage_param(symbol(param_name), value, descr, is_mutable); -} - -void ini_params::register_string_param(char const * param_name, std::string & value, char const * descr, bool is_mutable) { - m_imp->register_string_param(symbol(param_name), value, descr, is_mutable); -} - -void ini_params::register_symbol_param(char const * param_name, symbol & value, char const * descr, bool is_mutable) { - m_imp->register_symbol_param(symbol(param_name), value, descr, is_mutable); -} - -void ini_params::register_symbol_list_param(char const * param_name, svector & value, char const * descr, bool is_mutable) { - m_imp->register_symbol_list_param(symbol(param_name), value, descr, is_mutable); -} - -void ini_params::register_symbol_nat_list_param(char const * param_name, svector & value, char const * descr, bool is_mutable) { - m_imp->register_symbol_nat_list_param(symbol(param_name), value, descr, is_mutable); -} - -void ini_params::register_param_vector(param_vector * pv) { - m_imp->register_param_vector(pv); -} - -void ini_params::read_ini_file(std::istream & in) { - ini_parser p(in, m_imp); - p.parse(); -} - -void ini_params::display_params(std::ostream & out) const { - m_imp->display_params(out); -} - -void ini_params::display_parameter_help(char const* param_id, std::ostream & out) const { - m_imp->display_param_help(param_id, out); -} - -void ini_params::display_params_documentation(std::ostream & out) const { - m_imp->display_params_documentation(out); -} - -void ini_params::set_param_value(char const * param_id, char const * param_value) { - m_imp->set_param_value(param_id, param_value); -} -bool ini_params::get_param_value(char const * param_id, std::string& param_value) { - return m_imp->get_param_value(param_id, param_value); -} - -void ini_params::freeze(bool f) { - m_imp->freeze(f); -} - - - diff --git a/src/util/ini_file.h b/src/util/ini_file.h deleted file mode 100644 index cb884b916..000000000 --- a/src/util/ini_file.h +++ /dev/null @@ -1,117 +0,0 @@ -/*++ -Copyright (c) 2006 Microsoft Corporation - -Module Name: - - ini_file.h - -Abstract: - - Configuration file support. - -Author: - - Leonardo de Moura (leonardo) 2007-05-10. - -Revision History: - ---*/ -#ifndef _INI_FILE_H_ -#define _INI_FILE_H_ - -#include -#include -#include - -#include"symbol.h" -#include"vector.h" -#include"ref.h" - -#ifdef _EXTERNAL_RELEASE -#define PRIVATE_PARAMS(CODE) ((void) 0) -#else -#define PRIVATE_PARAMS(CODE) { CODE } -#endif - -struct param_vector_imp; -struct ini_params_imp; -class ini_parser; - -typedef std::pair symbol_nat_pair; - -inline std::ostream & operator<<(std::ostream & out, symbol_nat_pair const & p) { - out << p.first << ":" << p.second; - return out; -} - -/** - \brief Support for multiple values for a parameter. The values are used to configure - different cores. -*/ -class param_vector { - unsigned m_ref_count; - param_vector_imp * m_imp; - friend struct ini_params_imp; - friend class ini_parser; -public: - // TODO: onwer is a big hack - param_vector(void * owner); - ~param_vector(); - void inc_ref(); - void dec_ref(); - void copy_params(void * curr_owner, unsigned idx); - unsigned size(void) const; -}; - -class set_get_param_exception { - std::string m_id; - std::string m_msg; -public: - set_get_param_exception(char const * id, char const * msg):m_id(id), m_msg(msg) {} - char const * get_param_id() const { return m_id.c_str(); } - char const * get_msg() const { return m_msg.c_str(); } -}; - -class ini_parser_exception { - unsigned m_pos; - std::string m_msg; -public: - ini_parser_exception(unsigned pos, char const * msg):m_pos(pos), m_msg(msg) {} - unsigned get_pos() const { return m_pos; } - char const * get_msg() const { return m_msg.c_str(); } -}; - -class ini_params { - ini_params_imp * m_imp; -public: - ini_params(bool abort_on_error = true); - ~ini_params(); - void freeze(bool f = true); - void register_bool_param(char const * param_name, bool & value, char const * descr = 0, bool is_mutable = false); - void register_unsigned_param(char const * param_name, unsigned min, unsigned max, unsigned & value, char const * descr = 0, bool is_mutable = false); - void register_unsigned_param(char const * param_name, unsigned & value, char const * descr = 0, bool is_mutable = false) { - register_unsigned_param(param_name, 0, INT_MAX, value, descr, is_mutable); - } - void register_int_param(char const * param_name, int min, int max, int & value, char const * descr = 0, bool is_mutable = false); - void register_int_param(char const * param_name, int & value, char const * descr = 0, bool is_mutable = false) { - register_int_param(param_name, INT_MIN, INT_MAX, value, descr, is_mutable); - } - void register_double_param(char const * param_name, double & value, char const * descr = 0,bool is_mutable = false); - void register_percentage_param(char const * param_name, double & value, char const * descr = 0, bool is_mutable = false); - void register_string_param(char const * param_name, std::string & value, char const * descr = 0, bool is_mutable = false); - void register_symbol_param(char const * param_name, symbol & value, char const * descr = 0, bool is_mutable = false); - void register_symbol_list_param(char const * param_name, svector & value, char const * descr = 0, bool is_mutable = false); - void register_symbol_nat_list_param(char const * param_name, svector & value, char const * descr = 0, bool is_mutable = false); - void register_param_vector(param_vector * pv); - - void read_ini_file(std::istream & in); - void display_params(std::ostream & out) const; - void display_parameter_help(char const* param_id, std::ostream & out) const; - void set_param_value(char const * param_id, char const * param_value); - void set_param_mutable(char const * param_id); - bool get_param_value(char const * param_id, std::string& param_value); - void display_params_documentation(std::ostream & out) const; -}; - -#endif /* _INI_FILE_H_ */ - diff --git a/src/util/instruction_count.cpp b/src/util/instruction_count.cpp deleted file mode 100644 index 6dd5bcb85..000000000 --- a/src/util/instruction_count.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#ifdef _WINDOWS -#include -#endif -#include "instruction_count.h" - -#ifdef _WINDOWS -typedef BOOL (WINAPI *QTCP)(HANDLE, PULONG64); -static QTCP QTCP_proc; -BOOL WINAPI dummy_qtcp(HANDLE h, PULONG64 u) -{ - *u = 0; - return 0; -} - -inline void check_handler() -{ - if (!QTCP_proc) { - QTCP_proc = (QTCP) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "QueryThreadCycleTime"); - if (!QTCP_proc) - QTCP_proc = &dummy_qtcp; - } -} -#endif - -void instruction_count::start() { - m_count = 0; -#ifdef _WINDOWS - check_handler(); - QTCP_proc(GetCurrentThread(), &m_count); -#endif -} - -double instruction_count::get_num_instructions() { - unsigned long long current = 0; -#ifdef _WINDOWS - check_handler(); - QTCP_proc(GetCurrentThread(), ¤t); -#endif - return static_cast(current - m_count); -} - diff --git a/src/util/instruction_count.h b/src/util/instruction_count.h deleted file mode 100644 index 29fa0c45b..000000000 --- a/src/util/instruction_count.h +++ /dev/null @@ -1,43 +0,0 @@ -/*++ -Copyright (c) 2009 Microsoft Corporation - -Module Name: - - instruction_count.h - -Abstract: - - - -Author: - - Nikolaj Bjorner (nbjorner) 2009-03-04. - -Revision History: - ---*/ -#ifndef _INSTRUCTION_COUNT_H_ -#define _INSTRUCTION_COUNT_H_ - - -/** - \brief Wrapper for an instruction counter. -*/ -class instruction_count { - unsigned long long m_count; -public: - instruction_count() : m_count(0) {} - - ~instruction_count() {} - - void start(); - - double get_num_instructions(); - - bool is_instruction_maxed(double max_instr) { - return max_instr > 0.0 && get_num_instructions() > max_instr; - } -}; - -#endif /* _INSTRUcTION_COUNT_H_ */ - diff --git a/src/util/memory_manager.cpp b/src/util/memory_manager.cpp index b6eb648d9..de4e760d7 100644 --- a/src/util/memory_manager.cpp +++ b/src/util/memory_manager.cpp @@ -1,9 +1,10 @@ #include #include +#include #include"trace.h" #include"memory_manager.h" #include"error_codes.h" - +#include"z3_omp.h" // The following two function are automatically generated by the mk_make.py script. // The script collects ADD_INITIALIZER and ADD_FINALIZER commands in the .h files. // For example, rational.h contains @@ -27,6 +28,7 @@ out_of_memory_error::out_of_memory_error():z3_error(ERR_MEMOUT) { } volatile bool g_memory_out_of_memory = false; +bool g_memory_initialized = false; long long g_memory_alloc_size = 0; long long g_memory_max_size = 0; long long g_memory_max_used_size = 0; @@ -70,8 +72,20 @@ mem_usage_report g_info; #endif void memory::initialize(size_t max_size) { + bool initialize = false; + #pragma omp critical (z3_memory_manager) + { + // only update the maximum size if max_size != UINT_MAX + if (max_size != UINT_MAX) + g_memory_max_size = max_size; + if (!g_memory_initialized) { + g_memory_initialized = true; + initialize = true; + } + } + if (!initialize) + return; g_memory_out_of_memory = false; - g_memory_max_size = max_size; mem_initialize(); } @@ -108,8 +122,12 @@ void memory::set_max_size(size_t max_size) { static bool g_finalizing = false; void memory::finalize() { - g_finalizing = true; - mem_finalize(); + if (g_memory_initialized) { + g_finalizing = true; + mem_finalize(); + g_memory_initialized = false; + g_finalizing = false; + } } unsigned long long memory::get_allocation_size() { diff --git a/src/util/params.cpp b/src/util/params.cpp index ae7f0c830..f302f7721 100644 --- a/src/util/params.cpp +++ b/src/util/params.cpp @@ -21,33 +21,91 @@ Notes: #include"symbol.h" #include"dictionary.h" +std::string norm_param_name(char const * n) { + if (n == 0) + return "_"; + if (*n == ':') + n++; + std::string r = n; + unsigned sz = r.size(); + if (sz == 0) + return "_"; + for (unsigned i = 0; i < sz; i++) { + char curr = r[i]; + if ('A' <= curr && curr <= 'Z') + r[i] = curr - 'A' + 'a'; + else if (curr == '-' || curr == ':') + r[i] = '_'; + } + return r; +} + +std::string norm_param_name(symbol const & n) { + return norm_param_name(n.bare_str()); +} + struct param_descrs::imp { - typedef std::pair info; + struct info { + param_kind m_kind; + char const * m_descr; + char const * m_default; + + info(param_kind k, char const * descr, char const * def): + m_kind(k), + m_descr(descr), + m_default(def) { + } + + info(): + m_kind(CPK_INVALID), + m_descr(0), + m_default(0) { + } + }; + dictionary m_info; svector m_names; - void insert(symbol const & name, param_kind k, char const * descr) { + void insert(symbol const & name, param_kind k, char const * descr, char const * def) { SASSERT(!name.is_numerical()); info i; if (m_info.find(name, i)) { - SASSERT(i.first == k); + SASSERT(i.m_kind == k); return; } - m_info.insert(name, info(k, descr)); + m_info.insert(name, info(k, descr, def)); m_names.push_back(name); } void erase(symbol const & name) { m_info.erase(name); } + + bool contains(symbol const & name) const { + return m_info.contains(name); + } param_kind get_kind(symbol const & name) const { info i; if (m_info.find(name, i)) - return i.first; + return i.m_kind; return CPK_INVALID; } + char const * get_descr(symbol const & name) const { + info i; + if (m_info.find(name, i)) + return i.m_descr; + return 0; + } + + char const * get_default(symbol const & name) const { + info i; + if (m_info.find(name, i)) + return i.m_default; + return 0; + } + unsigned size() const { return m_names.size(); } @@ -60,7 +118,7 @@ struct param_descrs::imp { bool operator()(symbol const & s1, symbol const & s2) const { return strcmp(s1.bare_str(), s2.bare_str()) < 0; } }; - void display(std::ostream & out, unsigned indent) const { + void display(std::ostream & out, unsigned indent, bool smt2_style, bool include_descr) const { svector names; dictionary::iterator it = m_info.begin(); dictionary::iterator end = m_info.end(); @@ -72,14 +130,40 @@ struct param_descrs::imp { svector::iterator end2 = names.end(); for (; it2 != end2; ++it2) { for (unsigned i = 0; i < indent; i++) out << " "; - out << *it2; + if (smt2_style) + out << ':'; + char const * s = it2->bare_str(); + unsigned n = strlen(s); + for (unsigned i = 0; i < n; i++) { + if (smt2_style && s[i] == '_') + out << '-'; + else if (!smt2_style && s[i] == '-') + out << '_'; + else if (s[i] >= 'A' && s[i] <= 'Z') + out << (s[i] - 'A' + 'a'); + else + out << s[i]; + } info d; - d.second = 0; m_info.find(*it2, d); - SASSERT(d.second); - out << " (" << d.first << ") " << d.second << "\n"; + SASSERT(d.m_descr); + out << " (" << d.m_kind << ")"; + if (include_descr) + out << " " << d.m_descr; + if (d.m_default != 0) + out << " (default: " << d.m_default << ")"; + out << "\n"; } } + + void copy(param_descrs & other) { + dictionary::iterator it = other.m_imp->m_info.begin(); + dictionary::iterator end = other.m_imp->m_info.end(); + for (; it != end; ++it) { + insert(it->m_key, it->m_value.m_kind, it->m_value.m_descr, it->m_value.m_default); + } + } + }; param_descrs::param_descrs() { @@ -90,12 +174,40 @@ param_descrs::~param_descrs() { dealloc(m_imp); } -void param_descrs::insert(symbol const & name, param_kind k, char const * descr) { - m_imp->insert(name, k, descr); +void param_descrs::copy(param_descrs & other) { + m_imp->copy(other); } -void param_descrs::insert(char const * name, param_kind k, char const * descr) { - insert(symbol(name), k, descr); +void param_descrs::insert(symbol const & name, param_kind k, char const * descr, char const * def) { + m_imp->insert(name, k, descr, def); +} + +void param_descrs::insert(char const * name, param_kind k, char const * descr, char const * def) { + insert(symbol(name), k, descr, def); +} + +bool param_descrs::contains(char const * name) const { + return contains(symbol(name)); +} + +bool param_descrs::contains(symbol const & name) const { + return m_imp->contains(name); +} + +char const * param_descrs::get_descr(char const * name) const { + return get_descr(symbol(name)); +} + +char const * param_descrs::get_descr(symbol const & name) const { + return m_imp->get_descr(name); +} + +char const * param_descrs::get_default(char const * name) const { + return get_default(symbol(name)); +} + +char const * param_descrs::get_default(symbol const & name) const { + return m_imp->get_default(name); } void param_descrs::erase(symbol const & name) { @@ -122,28 +234,28 @@ symbol param_descrs::get_param_name(unsigned i) const { return m_imp->get_param_name(i); } -void param_descrs::display(std::ostream & out, unsigned indent) const { - return m_imp->display(out, indent); +void param_descrs::display(std::ostream & out, unsigned indent, bool smt2_style, bool include_descr) const { + return m_imp->display(out, indent, smt2_style, include_descr); } void insert_max_memory(param_descrs & r) { - r.insert(":max-memory", CPK_UINT, "(default: infty) maximum amount of memory in megabytes."); + r.insert("max_memory", CPK_UINT, "(default: infty) maximum amount of memory in megabytes."); } void insert_max_steps(param_descrs & r) { - r.insert(":max-steps", CPK_UINT, "(default: infty) maximum number of steps."); + r.insert("max_steps", CPK_UINT, "(default: infty) maximum number of steps."); } void insert_produce_models(param_descrs & r) { - r.insert(":produce-models", CPK_BOOL, "(default: false) model generation."); + r.insert("produce_models", CPK_BOOL, "(default: false) model generation."); } void insert_produce_proofs(param_descrs & r) { - r.insert(":produce-proofs", CPK_BOOL, "(default: false) proof generation."); + r.insert("produce_proofs", CPK_BOOL, "(default: false) proof generation."); } void insert_timeout(param_descrs & r) { - r.insert(":timeout", CPK_UINT, "(default: infty) timeout in milliseconds."); + r.insert("timeout", CPK_UINT, "(default: infty) timeout in milliseconds."); } class params { @@ -209,6 +321,12 @@ public: symbol get_sym(symbol const & k, symbol const & _default) const; symbol get_sym(char const * k, symbol const & _default) const; + bool get_bool(char const * k, params_ref const & fallback, bool _default) const; + unsigned get_uint(char const * k, params_ref const & fallback, unsigned _default) const; + double get_double(char const * k, params_ref const & fallback, double _default) const; + char const * get_str(char const * k, params_ref const & fallback, char const * _default) const; + symbol get_sym(char const * k, params_ref const & fallback, symbol const & _default) const; + // setters void set_bool(symbol const & k, bool v); void set_bool(char const * k, bool v); @@ -255,6 +373,39 @@ public: } out << ")"; } + + void display(std::ostream & out, symbol const & k) const { + svector::const_iterator it = m_entries.begin(); + svector::const_iterator end = m_entries.end(); + for (; it != end; ++it) { + if (it->first != k) + continue; + switch (it->second.m_kind) { + case CPK_BOOL: + out << (it->second.m_bool_value?"true":"false"); + return; + case CPK_UINT: + out << it->second.m_uint_value; + return; + case CPK_DOUBLE: + out << it->second.m_double_value; + return; + case CPK_NUMERAL: + out << *(it->second.m_rat_value); + return; + case CPK_SYMBOL: + out << symbol::mk_symbol_from_c_ptr(it->second.m_sym_value); + return; + case CPK_STRING: + out << it->second.m_str_value; + return; + default: + out << "internal"; + return; + } + } + out << "default"; + } }; params_ref::~params_ref() { @@ -274,6 +425,17 @@ void params_ref::display(std::ostream & out) const { out << "(params)"; } +void params_ref::display(std::ostream & out, char const * k) const { + display(out, symbol(k)); +} + +void params_ref::display(std::ostream & out, symbol const & k) const { + if (m_params) + m_params->display(out, k); + else + out << "default"; +} + void params_ref::validate(param_descrs const & p) const { if (m_params) m_params->validate(p); @@ -302,7 +464,7 @@ void params_ref::copy_core(params const * src) { return; svector::const_iterator it = src->m_entries.begin(); svector::const_iterator end = src->m_entries.end(); - for (; it != end; ++it) { + for (; it != end; ++it) { switch (it->second.m_kind) { case CPK_BOOL: m_params->set_bool(it->first, it->second.m_bool_value); @@ -370,6 +532,26 @@ symbol params_ref::get_sym(char const * k, symbol const & _default) const { return m_params ? m_params->get_sym(k, _default) : _default; } +bool params_ref::get_bool(char const * k, params_ref const & fallback, bool _default) const { + return m_params ? m_params->get_bool(k, fallback, _default) : fallback.get_bool(k, _default); +} + +unsigned params_ref::get_uint(char const * k, params_ref const & fallback, unsigned _default) const { + return m_params ? m_params->get_uint(k, fallback, _default) : fallback.get_uint(k, _default); +} + +double params_ref::get_double(char const * k, params_ref const & fallback, double _default) const { + return m_params ? m_params->get_double(k, fallback, _default) : fallback.get_double(k, _default); +} + +char const * params_ref::get_str(char const * k, params_ref const & fallback, char const * _default) const { + return m_params ? m_params->get_str(k, fallback, _default) : fallback.get_str(k, _default); +} + +symbol params_ref::get_sym(char const * k, params_ref const & fallback, symbol const & _default) const { + return m_params ? m_params->get_sym(k, fallback, _default) : fallback.get_sym(k, _default); +} + bool params_ref::empty() const { if (!m_params) return true; @@ -614,6 +796,41 @@ symbol params::get_sym(char const * k, symbol const & _default) const { GET_VALUE(return symbol::mk_symbol_from_c_ptr(it->second.m_sym_value);, CPK_SYMBOL); } +#define GET_VALUE2(MATCH_CODE, KIND) { \ + if (!empty()) { \ + TRAVERSE_CONST_ENTRIES(if (it->first == k && it->second.m_kind == KIND) { \ + MATCH_CODE \ + }); \ + } \ +} + +#define GET_SIMPLE_VALUE2(FIELD_NAME, KIND) GET_VALUE2(return it->second.FIELD_NAME;, KIND) + +bool params::get_bool(char const * k, params_ref const & fallback, bool _default) const { + GET_SIMPLE_VALUE2(m_bool_value, CPK_BOOL); + return fallback.get_bool(k, _default); +} + +unsigned params::get_uint(char const * k, params_ref const & fallback, unsigned _default) const { + GET_SIMPLE_VALUE2(m_uint_value, CPK_UINT); + return fallback.get_uint(k, _default); +} + +double params::get_double(char const * k, params_ref const & fallback, double _default) const { + GET_SIMPLE_VALUE2(m_double_value, CPK_DOUBLE); + return fallback.get_double(k, _default); +} + +char const * params::get_str(char const * k, params_ref const & fallback, char const * _default) const { + GET_SIMPLE_VALUE2(m_str_value, CPK_STRING); + return fallback.get_str(k, _default); +} + +symbol params::get_sym(char const * k, params_ref const & fallback, symbol const & _default) const { + GET_VALUE2(return symbol::mk_symbol_from_c_ptr(it->second.m_sym_value);, CPK_SYMBOL); + return fallback.get_sym(k, _default); +} + #define SET_VALUE(MATCH_CODE, ADD_CODE) { \ TRAVERSE_ENTRIES(if (it->first == k) { \ MATCH_CODE \ diff --git a/src/util/params.h b/src/util/params.h index 66c4e7c7a..13850758c 100644 --- a/src/util/params.h +++ b/src/util/params.h @@ -22,6 +22,9 @@ Notes: #include"cmd_context_types.h" #include"vector.h" +std::string norm_param_name(char const * n); +std::string norm_param_name(symbol const & n); + typedef cmd_arg_kind param_kind; class params; @@ -38,10 +41,10 @@ public: params_ref & operator=(params_ref const & p); - // copy params from p + // copy params from src void copy(params_ref const & src); void append(params_ref const & src) { copy(src); } - + bool get_bool(symbol const & k, bool _default) const; bool get_bool(char const * k, bool _default) const; unsigned get_uint(symbol const & k, unsigned _default) const; @@ -55,6 +58,12 @@ public: symbol get_sym(symbol const & k, symbol const & _default) const; symbol get_sym(char const * k, symbol const & _default) const; + bool get_bool(char const * k, params_ref const & fallback, bool _default) const; + unsigned get_uint(char const * k, params_ref const & fallback, unsigned _default) const; + double get_double(char const * k, params_ref const & fallback, double _default) const; + char const * get_str(char const * k, params_ref const & fallback, char const * _default) const; + symbol get_sym(char const * k, params_ref const & fallback, symbol const & _default) const; + bool empty() const; bool contains(symbol const & k) const; bool contains(char const * k) const; @@ -79,6 +88,14 @@ public: void display(std::ostream & out) const; void validate(param_descrs const & p) const; + + /* + \brief Display the value of the given parameter. + + It displays 'default' if k is not in the parameter set. + */ + void display(std::ostream & out, char const * k) const; + void display(std::ostream & out, symbol const & k) const; }; inline std::ostream & operator<<(std::ostream & out, params_ref const & ref) { @@ -92,13 +109,20 @@ class param_descrs { public: param_descrs(); ~param_descrs(); - void insert(char const * name, param_kind k, char const * descr); - void insert(symbol const & name, param_kind k, char const * descr); + void copy(param_descrs & other); + void insert(char const * name, param_kind k, char const * descr, char const * def = 0); + void insert(symbol const & name, param_kind k, char const * descr, char const * def = 0); + bool contains(char const * name) const; + bool contains(symbol const & name) const; void erase(char const * name); void erase(symbol const & name); param_kind get_kind(char const * name) const; param_kind get_kind(symbol const & name) const; - void display(std::ostream & out, unsigned indent = 0) const; + char const * get_descr(char const * name) const; + char const * get_descr(symbol const & name) const; + char const * get_default(char const * name) const; + char const * get_default(symbol const & name) const; + void display(std::ostream & out, unsigned indent = 0, bool smt2_style=false, bool include_descr=true) const; unsigned size() const; symbol get_param_name(unsigned idx) const; }; diff --git a/src/util/scoped_timer.cpp b/src/util/scoped_timer.cpp index 5f9d554f9..4b191505f 100644 --- a/src/util/scoped_timer.cpp +++ b/src/util/scoped_timer.cpp @@ -58,6 +58,7 @@ Revision History: #endif #include"util.h" #include +#include"z3_omp.h" struct scoped_timer::imp { event_handler * m_eh; diff --git a/src/util/timeit.cpp b/src/util/timeit.cpp index 975dd3127..5246beced 100644 --- a/src/util/timeit.cpp +++ b/src/util/timeit.cpp @@ -38,9 +38,9 @@ struct timeit::imp { ~imp() { m_watch.stop(); double end_memory = static_cast(memory::get_allocation_size())/static_cast(1024*1024); - m_out << m_msg << ", time: " << std::fixed << std::setprecision(2) << m_watch.get_seconds() - << " secs, memory: (before " << std::fixed << std::setprecision(2) << m_start_memory - << ", after " << std::fixed << std::setprecision(2) << end_memory << ")" + m_out << "(" << m_msg << " :time " << std::fixed << std::setprecision(2) << m_watch.get_seconds() + << " :before-memory " << std::fixed << std::setprecision(2) << m_start_memory + << " :after-memory " << std::fixed << std::setprecision(2) << end_memory << ")" << std::endl; } }; diff --git a/src/util/timeout.cpp b/src/util/timeout.cpp index b0b914b5c..75621995c 100644 --- a/src/util/timeout.cpp +++ b/src/util/timeout.cpp @@ -19,6 +19,7 @@ Revision History: --*/ #include +#include"z3_omp.h" #include"util.h" #include"timeout.h" #include"error_codes.h" diff --git a/src/util/util.cpp b/src/util/util.cpp index c2795b637..eb9acb385 100644 --- a/src/util/util.cpp +++ b/src/util/util.cpp @@ -18,7 +18,6 @@ Revision History: --*/ #include"util.h" -#include"ini_file.h" unsigned g_verbosity_level = 0; @@ -30,10 +29,6 @@ unsigned get_verbosity_level() { return g_verbosity_level; } -void register_verbosity_level(ini_params & p) { - p.register_unsigned_param("VERBOSE", g_verbosity_level, "be verbose, where the value is the verbosity level", true); -} - static std::ostream* g_verbose_stream = &std::cerr; void set_verbose_stream(std::ostream& str) { diff --git a/src/util/util.h b/src/util/util.h index 5e51d8ef1..945d259f9 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -157,8 +157,6 @@ struct delete_proc { void set_verbosity_level(unsigned lvl); unsigned get_verbosity_level(); -class ini_params; -void register_verbosity_level(ini_params & p); std::ostream& verbose_stream(); void set_verbose_stream(std::ostream& str); diff --git a/src/util/warning.cpp b/src/util/warning.cpp index 4ab54f203..0a1ac9bbc 100644 --- a/src/util/warning.cpp +++ b/src/util/warning.cpp @@ -23,7 +23,6 @@ Revision History: #include "util.h" #include "buffer.h" #include "vector.h" -#include "ini_file.h" #ifdef _WINDOWS #define PRF sprintf_s @@ -83,10 +82,6 @@ void set_warning_stream(std::ostream* strm) { g_warning_stream = strm; } -void register_warning(ini_params & p) { - p.register_bool_param("WARNING", g_warning_msgs, "enable/disable warning messages", true); -} - void disable_error_msg_prefix() { g_show_error_msg_prefix = false; } diff --git a/src/util/warning.h b/src/util/warning.h index 6800c1f95..a556bfb60 100644 --- a/src/util/warning.h +++ b/src/util/warning.h @@ -21,8 +21,6 @@ Revision History: #include #include -class ini_params; - void send_warnings_to_stdout(bool flag); void enable_warning_messages(bool flag); @@ -33,8 +31,6 @@ void set_warning_stream(std::ostream* strm); void warning_msg(const char * msg, ...); -void register_warning(ini_params & p); - void disable_error_msg_prefix(); void format2ostream(std::ostream& out, char const* fmt, va_list args);