tactic * mk_qflra_tactic(ast_manager & m, params_ref const & p) { params_ref pivot_p; 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); params_ref ctx_simp_p; 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); params_ref elim_to_real_p; elim_to_real_p.set_bool("elim_to_real", true); #if 0 tactic * mip = and_then(fail_if(mk_produce_proofs_probe()), fail_if(mk_produce_unsat_cores_probe()), using_params(and_then(and_then(mk_simplify_tactic(m), mk_recover_01_tactic(m), using_params(mk_simplify_tactic(m), elim_to_real_p), mk_propagate_values_tactic(m)), using_params(mk_ctx_simplify_tactic(m), ctx_simp_p), mk_elim_uncnstr_tactic(m), mk_solve_eqs_tactic(m), using_params(mk_simplify_tactic(m), lhs_p), using_params(mk_simplify_tactic(m), elim_to_real_p) ), main_p), fail_if(mk_not(mk_is_mip_probe())), try_for(mk_mip_tactic(m), 30000), mk_fail_if_undecided_tactic()); #endif // return using_params(or_else(mip, // using_params(mk_smt_tactic(m), pivot_p)), // p); #if 0 params_ref simplex_0, simplex_1, simplex_2; simplex_0.set_uint("lp.simplex_strategy", 0); simplex_1.set_uint("lp.simplex_strategy", 1); simplex_2.set_uint("lp.simplex_strategy", 2); return par(using_params(mk_smt_tactic(), simplex_0), using_params(mk_smt_tactic(), simplex_1), using_params(mk_smt_tactic(), simplex_2)); #else return using_params(using_params(mk_smt_tactic(m), pivot_p), p); #endif }
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); return and_then(fail_if(mk_is_unbounded_probe()), fail_if(mk_produce_proofs_probe()), fail_if(mk_produce_unsat_cores_probe()), mk_propagate_ineqs_tactic(m), mk_normalize_bounds_tactic(m), mk_lia2pb_tactic(m), using_params(mk_pb2bv_tactic(m), pb2bv_p), fail_if_not(mk_is_qfbv_probe()), mk_bv2sat_tactic(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); return and_then(fail_if_not(mk_is_pb_probe()), fail_if(mk_produce_proofs_probe()), fail_if(mk_produce_unsat_cores_probe()), or_else(and_then(fail_if(mk_ge(mk_num_exprs_probe(), mk_const_probe(SMALL_SIZE))), fail_if_not(mk_is_ilp_probe()), // try_for(mk_mip_tactic(m), 8000), mk_fail_if_undecided_tactic()), and_then(using_params(mk_pb2bv_tactic(m), pb2bv_p), fail_if_not(mk_is_qfbv_probe()), mk_bv2sat_tactic(m)))); }
tactic * mk_qffp_approx_tactic(ast_manager & m, params_ref const & p) { params_ref simp_p = p; simp_p.set_bool("arith_lhs", true); simp_p.set_bool("elim_and", true); tactic * st = and_then(mk_simplify_tactic(m, simp_p), mk_propagate_values_tactic(m, p), using_params(mk_simplify_tactic(m, p), simp_p), cond(mk_or(mk_produce_proofs_probe(), mk_produce_unsat_cores_probe()), mk_smt_tactic(), cond(mk_is_qffp_probe(), mk_fpa2bv_approx_tactic(m, p), mk_qfnra_tactic(m, p))), mk_fail_if_undecided_tactic()); st->updt_params(p); return st; }
tactic * mk_qfbv_tactic(ast_manager& m, params_ref const & p, tactic* sat, tactic* smt) { params_ref local_ctx_p = p; 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. params_ref no_flat_p; 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); params_ref big_aig_p; big_aig_p.set_bool("aig_per_assertion", false); tactic* preamble_st = mk_qfbv_preamble(m, p); tactic * st = main_p(and_then(preamble_st, // If the user sets HI_DIV0=false, then the formula may contain uninterpreted function // symbols. In this case, we should not use the `sat', but instead `smt'. Alternatively, // the UFs can be eliminated by eager ackermannization in the preamble. cond(mk_is_qfbv_eq_probe(), and_then(mk_bv1_blaster_tactic(m), using_params(smt, solver_p)), cond(mk_is_qfbv_probe(), and_then(mk_bit_blaster_tactic(m), when(mk_lt(mk_memory_probe(), mk_const_probe(MEMLIMIT)), and_then(using_params(and_then(mk_simplify_tactic(m), mk_solve_eqs_tactic(m)), local_ctx_p), if_no_proofs(cond(mk_produce_unsat_cores_probe(), mk_aig_tactic(), using_params(mk_aig_tactic(), big_aig_p))))), sat), smt)))); st->updt_params(p); return st; }
// Try to find a model for an unbounded ILP problem. // 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)); 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)); return and_then(fail_if_not(mk_and(mk_is_ilp_probe(), mk_is_unbounded_probe())), fail_if(mk_produce_proofs_probe()), fail_if(mk_produce_unsat_cores_probe()), mk_propagate_ineqs_tactic(m), or_else(try_for(mk_mip_tactic(m), 5000), try_for(mk_no_cut_smt_tactic(100), 2000), and_then(using_params(mk_add_bounds_tactic(m), add_bounds_p1), try_for(mk_lia2sat_tactic(m), 5000)), try_for(mk_no_cut_smt_tactic(200), 5000), and_then(using_params(mk_add_bounds_tactic(m), add_bounds_p2), try_for(mk_lia2sat_tactic(m), 10000)), mk_mip_tactic(m)), mk_fail_if_undecided_tactic()); }
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); params_ref lhs_p; lhs_p.set_bool("arith_lhs", true); params_ref lia2pb_p; lia2pb_p.set_uint("lia2pb_max_bits", 4); params_ref pb2bv_p; 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); tactic * preamble_st = and_then(and_then(mk_simplify_tactic(m), mk_fix_dl_var_tactic(m), mk_propagate_values_tactic(m), mk_elim_uncnstr_tactic(m) ), and_then(mk_solve_eqs_tactic(m), using_params(mk_simplify_tactic(m), lhs_p), mk_propagate_values_tactic(m), mk_normalize_bounds_tactic(m), mk_solve_eqs_tactic(m))); 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); // dynamic psm seems to work well. 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), mk_solve_eqs_tactic(m), mk_max_bv_sharing_tactic(m), mk_bit_blaster_tactic(m), mk_aig_tactic(), mk_sat_tactic(m)), bv_solver_p); tactic * try2bv = and_then(using_params(mk_lia2pb_tactic(m), lia2pb_p), mk_propagate_ineqs_tactic(m), using_params(mk_pb2bv_tactic(m), pb2bv_p), fail_if(mk_not(mk_is_qfbv_probe())), bv_solver); params_ref diff_neq_p; 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<double>(BIG_PROBLEM))), mk_and(mk_not(mk_produce_proofs_probe()), mk_not(mk_produce_unsat_cores_probe()))), using_params(and_then(preamble_st, or_else(using_params(mk_diff_neq_tactic(m), diff_neq_p), try2bv, mk_smt_tactic())), main_p), mk_smt_tactic()); st->updt_params(p); return st; }
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); 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("flat", true); // required by som simp2_p.set_bool("hoist_mul", false); // required by som params_ref local_ctx_p = p; 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. params_ref no_flat_p; 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); params_ref hoist_p; 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); params_ref big_aig_p; 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), using_params(mk_solve_eqs_tactic(m), solve_eq_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 // 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. using_params(mk_simplify_tactic(m), hoist_p), mk_max_bv_sharing_tactic(m)); #ifdef USE_OLD_SAT_SOLVER tactic * new_sat = and_then(mk_simplify_tactic(m), mk_smt_tactic()); #else tactic * new_sat = cond(mk_or(mk_produce_proofs_probe(), mk_produce_unsat_cores_probe()), and_then(mk_simplify_tactic(m), mk_smt_tactic()), mk_sat_tactic(m)); #endif tactic * st = using_params(and_then(preamble_st, // If the user sets HI_DIV0=false, then the formula may contain uninterpreted function // symbols. In this case, we should not use cond(mk_is_qfbv_probe(), cond(mk_is_qfbv_eq_probe(), and_then(mk_bv1_blaster_tactic(m), using_params(mk_smt_tactic(), solver_p)), and_then(mk_bit_blaster_tactic(m), when(mk_lt(mk_memory_probe(), mk_const_probe(MEMLIMIT)), and_then(using_params(and_then(mk_simplify_tactic(m), mk_solve_eqs_tactic(m)), local_ctx_p), if_no_proofs(cond(mk_produce_unsat_cores_probe(), mk_aig_tactic(), using_params(mk_aig_tactic(), big_aig_p))))), new_sat)), mk_smt_tactic())), main_p); st->updt_params(p); return st; }