mirror of
https://github.com/Z3Prover/z3
synced 2025-09-13 13:11:26 +00:00
* Initial plan * Add virtual translate method to solver_factory base class and all implementations Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> * Add documentation for the translate method in solver_factory Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
202 lines
7 KiB
C++
202 lines
7 KiB
C++
/*++
|
|
Copyright (c) 2012 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
smt_strategic_solver.cpp
|
|
|
|
Abstract:
|
|
|
|
Create a strategic solver with tactic for all main logics
|
|
used in SMT.
|
|
|
|
Author:
|
|
|
|
Leonardo (leonardo) 2012-02-19
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
#include "cmd_context/cmd_context.h"
|
|
#include "solver/combined_solver.h"
|
|
#include "solver/tactic2solver.h"
|
|
#include "tactic/tactical.h"
|
|
#include "tactic/smtlogics/qfbv_tactic.h"
|
|
#include "tactic/smtlogics/qflia_tactic.h"
|
|
#include "tactic/smtlogics/qfnia_tactic.h"
|
|
#include "tactic/smtlogics/qfnra_tactic.h"
|
|
#include "tactic/smtlogics/qfuf_tactic.h"
|
|
#include "tactic/smtlogics/qflra_tactic.h"
|
|
#include "tactic/smtlogics/quant_tactics.h"
|
|
#include "tactic/smtlogics/qfauflia_tactic.h"
|
|
#include "tactic/smtlogics/qfaufbv_tactic.h"
|
|
#include "tactic/smtlogics/qfufbv_tactic.h"
|
|
#include "tactic/smtlogics/qfidl_tactic.h"
|
|
#include "tactic/smtlogics/nra_tactic.h"
|
|
#include "tactic/portfolio/default_tactic.h"
|
|
#include "tactic/fd_solver/fd_solver.h"
|
|
#include "tactic/fd_solver/smtfd_solver.h"
|
|
#include "tactic/ufbv/ufbv_tactic.h"
|
|
#include "tactic/fpa/qffp_tactic.h"
|
|
#include "muz/fp/horn_tactic.h"
|
|
#include "smt/smt_solver.h"
|
|
#include "sat/sat_solver/inc_sat_solver.h"
|
|
#include "sat/sat_solver/sat_smt_solver.h"
|
|
#include "ast/rewriter/bv_rewriter.h"
|
|
#include "solver/solver2tactic.h"
|
|
#include "solver/parallel_tactical.h"
|
|
#include "solver/parallel_params.hpp"
|
|
#include "params/tactic_params.hpp"
|
|
#include "parsers/smt2/smt2parser.h"
|
|
#include "params/sat_params.hpp"
|
|
|
|
tactic* mk_tactic_for_logic(ast_manager& m, params_ref const& p, symbol const& logic);
|
|
|
|
|
|
class smt_nested_solver_factory : public solver_factory {
|
|
public:
|
|
solver* operator()(ast_manager& m, params_ref const& p, bool proofs_enabled, bool models_enabled, bool unsat_core_enabled, symbol const& logic) override {
|
|
auto t = mk_tactic_for_logic(m, p, logic);
|
|
auto s = mk_tactic2solver(m, t, p, proofs_enabled, models_enabled, unsat_core_enabled, logic);
|
|
return s;
|
|
}
|
|
|
|
solver_factory* translate(ast_manager& m) override {
|
|
return alloc(smt_nested_solver_factory);
|
|
}
|
|
};
|
|
|
|
tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const & logic) {
|
|
if (logic=="QF_UF")
|
|
return mk_qfuf_tactic(m, p);
|
|
else if (logic=="QF_BV")
|
|
return mk_qfbv_tactic(m, p);
|
|
else if (logic=="QF_IDL")
|
|
return annotate_tactic("qfidl-tactic", mk_qfidl_tactic(m, p));
|
|
else if (logic=="QF_LIA")
|
|
return annotate_tactic("qflia-tactic", mk_qflia_tactic(m, p));
|
|
else if (logic=="QF_LRA")
|
|
return annotate_tactic("qflra-tactic", mk_qflra_tactic(m, p));
|
|
else if (logic=="QF_NIA")
|
|
return annotate_tactic("qfnia-tactic", mk_qfnia_tactic(m, p));
|
|
else if (logic=="QF_NRA")
|
|
return annotate_tactic("qfnra-tactic", mk_qfnra_tactic(m, p));
|
|
else if (logic=="QF_AUFLIA")
|
|
return annotate_tactic("qfauflia-tactic", mk_qfauflia_tactic(m, p));
|
|
else if (logic=="QF_AUFBV")
|
|
return annotate_tactic("qfaufbv-tactic", mk_qfaufbv_tactic(m, p));
|
|
else if (logic=="QF_ABV")
|
|
return annotate_tactic("qfaufbv-tactic", mk_qfaufbv_tactic(m, p));
|
|
else if (logic=="QF_UFBV")
|
|
return annotate_tactic("qfufbv-tactic", mk_qfufbv_tactic(m, p));
|
|
else if (logic=="AUFLIA")
|
|
return annotate_tactic("auflia-tactic", mk_auflia_tactic(m, p));
|
|
else if (logic=="AUFLIRA")
|
|
return annotate_tactic("auflira-tactic", mk_auflira_tactic(m, p));
|
|
else if (logic=="AUFNIRA")
|
|
return mk_aufnira_tactic(m, p);
|
|
else if (logic=="UFNIA")
|
|
return mk_ufnia_tactic(m, p);
|
|
else if (logic=="UFLRA")
|
|
return mk_uflra_tactic(m, p);
|
|
else if (logic=="LRA")
|
|
return mk_lra_tactic(m, p);
|
|
else if (logic=="NRA")
|
|
return mk_nra_tactic(m, p);
|
|
else if (logic=="LIA")
|
|
return mk_lia_tactic(m, p);
|
|
else if (logic=="UFBV")
|
|
return annotate_tactic("ufbv", mk_ufbv_tactic(m, p));
|
|
else if (logic=="BV")
|
|
return mk_ufbv_tactic(m, p);
|
|
else if (logic=="QF_FP")
|
|
return mk_qffp_tactic(m, p);
|
|
else if (logic == "QF_FPBV" || logic == "QF_BVFP")
|
|
return mk_qffpbv_tactic(m, p);
|
|
else if (logic=="HORN")
|
|
return mk_horn_tactic(m, p);
|
|
else if ((logic == "QF_FD" || logic == "SAT") && !m.proofs_enabled())
|
|
return mk_fd_tactic(m, p);
|
|
else
|
|
return mk_default_tactic(m, p);
|
|
}
|
|
|
|
static solver* mk_special_solver_for_logic(ast_manager & m, params_ref const & p, symbol const& logic) {
|
|
parallel_params pp(p);
|
|
if ((logic == "QF_FD" || logic == "SAT") && !m.proofs_enabled() && !pp.enable())
|
|
return mk_fd_solver(m, p);
|
|
if (logic == "SMTFD" && !m.proofs_enabled() && !pp.enable())
|
|
return mk_smtfd_solver(m, p);
|
|
return nullptr;
|
|
}
|
|
|
|
solver* mk_smt2_solver(ast_manager& m, params_ref const& p, symbol const& logic) {
|
|
sat_params sp(p);
|
|
if (sp.smt())
|
|
return mk_sat_smt_solver(m, p);
|
|
if (sp.euf())
|
|
return mk_inc_sat_solver(m, p);
|
|
return mk_smt_solver(m, p, logic);
|
|
}
|
|
|
|
static solver* mk_solver_for_logic(ast_manager & m, params_ref const & p, symbol const& logic) {
|
|
bv_rewriter rw(m);
|
|
solver* s = mk_special_solver_for_logic(m, p, logic);
|
|
tactic_params tp;
|
|
if (!s && logic == "QF_BV" && rw.hi_div0())
|
|
s = mk_inc_sat_solver(m, p);
|
|
if (!s && tp.default_tactic() == "sat")
|
|
s = mk_inc_sat_solver(m, p);
|
|
if (!s)
|
|
s = mk_smt2_solver(m, p, logic);
|
|
return s;
|
|
}
|
|
|
|
class smt_strategic_solver_factory : public solver_factory {
|
|
symbol m_logic;
|
|
public:
|
|
smt_strategic_solver_factory(symbol const & logic):m_logic(logic) {}
|
|
|
|
solver * operator()(ast_manager & m, params_ref const & p, bool proofs_enabled, bool models_enabled, bool unsat_core_enabled, symbol const & logic) override {
|
|
symbol l;
|
|
if (m_logic != symbol::null)
|
|
l = m_logic;
|
|
else
|
|
l = logic;
|
|
|
|
tactic_params tp;
|
|
tactic_ref t;
|
|
if (tp.default_tactic() != symbol::null &&
|
|
!tp.default_tactic().is_numerical() &&
|
|
tp.default_tactic().str()[0]) {
|
|
cmd_context ctx(false, &m, l);
|
|
std::istringstream is(tp.default_tactic().str());
|
|
char const* file_name = "";
|
|
sexpr_ref se = parse_sexpr(ctx, is, p, file_name);
|
|
if (se) {
|
|
t = sexpr2tactic(ctx, se.get());
|
|
}
|
|
}
|
|
|
|
if (!t) {
|
|
solver* s = mk_special_solver_for_logic(m, p, l);
|
|
if (s) return s;
|
|
}
|
|
if (!t) {
|
|
t = mk_tactic_for_logic(m, p, l);
|
|
}
|
|
return mk_combined_solver(mk_tactic2solver(m, t.get(), p, proofs_enabled, models_enabled, unsat_core_enabled, l),
|
|
mk_solver_for_logic(m, p, l),
|
|
p);
|
|
}
|
|
|
|
solver_factory* translate(ast_manager& m) override {
|
|
return alloc(smt_strategic_solver_factory, m_logic);
|
|
}
|
|
};
|
|
|
|
solver_factory * mk_smt_strategic_solver_factory(symbol const & logic) {
|
|
return alloc(smt_strategic_solver_factory, logic);
|
|
}
|
|
|
|
|