3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-05-04 14:25:46 +00:00

add some of the SMT2.5 features

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2015-12-02 18:41:10 -08:00
parent 6580f1daf3
commit e2565d8d82
4 changed files with 256 additions and 27 deletions

View file

@ -165,26 +165,39 @@ ATOMIC_CMD(get_proof_cmd, "get-proof", "retrieve proof", {
ctx.regular_stream() << std::endl;
});
#define PRINT_CORE() \
ptr_vector<expr> core; \
ctx.get_check_sat_result()->get_unsat_core(core); \
ctx.regular_stream() << "("; \
ptr_vector<expr>::const_iterator it = core.begin(); \
ptr_vector<expr>::const_iterator end = core.end(); \
for (bool first = true; it != end; ++it) { \
if (first) \
first = false; \
else \
ctx.regular_stream() << " "; \
ctx.regular_stream() << mk_ismt2_pp(*it, ctx.m()); \
} \
ctx.regular_stream() << ")" << std::endl; \
ATOMIC_CMD(get_unsat_core_cmd, "get-unsat-core", "retrieve unsat core", {
if (!ctx.produce_unsat_cores())
throw cmd_exception("unsat core construction is not enabled, use command (set-option :produce-unsat-cores true)");
if (!ctx.has_manager() ||
ctx.cs_state() != cmd_context::css_unsat)
throw cmd_exception("unsat core is not available");
ptr_vector<expr> core;
ctx.get_check_sat_result()->get_unsat_core(core);
ctx.regular_stream() << "(";
ptr_vector<expr>::const_iterator it = core.begin();
ptr_vector<expr>::const_iterator end = core.end();
for (bool first = true; it != end; ++it) {
if (first)
first = false;
else
ctx.regular_stream() << " ";
ctx.regular_stream() << mk_ismt2_pp(*it, ctx.m());
}
ctx.regular_stream() << ")" << std::endl;
});
if (!ctx.produce_unsat_cores())
throw cmd_exception("unsat core construction is not enabled, use command (set-option :produce-unsat-cores true)");
if (!ctx.has_manager() ||
ctx.cs_state() != cmd_context::css_unsat)
throw cmd_exception("unsat core is not available");
PRINT_CORE();
});
ATOMIC_CMD(get_unsat_assumptions_cmd, "get-unsat-assumptions", "retrieve subset of assumptions sufficient for unsatisfiability", {
if (!ctx.produce_unsat_assumptions())
throw cmd_exception("unsat assumptions construction is not enabled, use command (set-option :produce-unsat-assumptions true)");
if (!ctx.has_manager() || ctx.cs_state() != cmd_context::css_unsat) {
throw cmd_exception("unsat assumptions is not available");
}
PRINT_CORE();
});
ATOMIC_CMD(labels_cmd, "labels", "retrieve Simplify-like labels", {
if (!ctx.has_manager() ||
@ -201,6 +214,11 @@ ATOMIC_CMD(labels_cmd, "labels", "retrieve Simplify-like labels", {
ATOMIC_CMD(get_assertions_cmd, "get-assertions", "retrieve asserted terms when in interactive mode", ctx.display_assertions(););
ATOMIC_CMD(reset_assertions_cmd, "reset-assertions", "reset all asserted formulas (but retain definitions and declarations)", ctx.reset_assertions(););
UNARY_CMD(set_logic_cmd, "set-logic", "<symbol>", "set the background logic.", CPK_SYMBOL, symbol const &,
if (ctx.set_logic(arg))
ctx.print_success();
@ -226,6 +244,7 @@ protected:
symbol m_interactive_mode;
symbol m_produce_proofs;
symbol m_produce_unsat_cores;
symbol m_produce_unsat_assumptions;
symbol m_produce_models;
symbol m_produce_assignments;
symbol m_produce_interpolants;
@ -241,9 +260,9 @@ protected:
bool is_builtin_option(symbol const & s) const {
return
s == m_print_success || s == m_print_warning || s == m_expand_definitions ||
s == m_interactive_mode || s == m_produce_proofs || s == m_produce_unsat_cores ||
s == m_interactive_mode || s == m_produce_proofs || s == m_produce_unsat_cores || s == m_produce_unsat_assumptions ||
s == m_produce_models || s == m_produce_assignments || s == m_produce_interpolants ||
s == m_regular_output_channel || s == m_diagnostic_output_channel ||
s == m_regular_output_channel || s == m_diagnostic_output_channel ||
s == m_random_seed || s == m_verbosity || s == m_global_decls;
}
@ -258,6 +277,7 @@ public:
m_interactive_mode(":interactive-mode"),
m_produce_proofs(":produce-proofs"),
m_produce_unsat_cores(":produce-unsat-cores"),
m_produce_unsat_assumptions(":produce-unsat-assumptions"),
m_produce_models(":produce-models"),
m_produce_assignments(":produce-assignments"),
m_produce_interpolants(":produce-interpolants"),
@ -336,6 +356,10 @@ class set_option_cmd : public set_get_option_cmd {
check_not_initialized(ctx, m_produce_unsat_cores);
ctx.set_produce_unsat_cores(to_bool(value));
}
else if (m_option == m_produce_unsat_assumptions) {
check_not_initialized(ctx, m_produce_unsat_assumptions);
ctx.set_produce_unsat_assumptions(to_bool(value));
}
else if (m_option == m_produce_models) {
ctx.set_produce_models(to_bool(value));
}
@ -737,8 +761,15 @@ void install_basic_cmds(cmd_context & ctx) {
ctx.insert(alloc(builtin_cmd, "declare-fun", "<symbol> (<sort>*) <sort>", "declare a new function/constant."));
ctx.insert(alloc(builtin_cmd, "declare-const", "<symbol> <sort>", "declare a new constant."));
ctx.insert(alloc(builtin_cmd, "declare-datatypes", "(<symbol>*) (<datatype-declaration>+)", "declare mutually recursive datatypes.\n<datatype-declaration> ::= (<symbol> <constructor-decl>+)\n<constructor-decl> ::= (<symbol> <accessor-decl>*)\n<accessor-decl> ::= (<symbol> <sort>)\nexample: (declare-datatypes (T) ((BinTree (leaf (value T)) (node (left BinTree) (right BinTree)))))"));
ctx.insert(alloc(builtin_cmd, "check-sat-asuming", "( hprop_literali* )", "check sat assuming a collection of literals"));
// ctx.insert(alloc(builtin_cmd, "define-fun-rec", "hfun-defi", "define a function satisfying recursive equations"));
// ctx.insert(alloc(builtin_cmd, "define-funs-rec", "( hfun_decin+1 ) ( htermin+1 )", "define multiple mutually recursive functions"));
// ctx.insert(alloc(get_unsat_assumptions_cmd));
ctx.insert(alloc(reset_assertions_cmd));
}
void install_ext_basic_cmds(cmd_context & ctx) {
ctx.insert(alloc(help_cmd));
ctx.insert(alloc(pp_cmd));

View file

@ -313,6 +313,7 @@ cmd_context::cmd_context(bool main_ctx, ast_manager * m, symbol const & l):
m_print_success(m_params.m_smtlib2_compliant),
m_random_seed(0),
m_produce_unsat_cores(false),
m_produce_unsat_assumptions(false),
m_produce_assignments(false),
m_status(UNKNOWN),
m_numeral_as_real(false),
@ -831,6 +832,17 @@ void cmd_context::insert(symbol const & s, object_ref * r) {
m_object_refs.insert(s, r);
}
void cmd_context::insert_rec_fun(func_decl* f, expr_ref_vector const& binding, svector<symbol> const& ids, expr* e) {
expr_ref eq(m()), lhs(m());
lhs = m().mk_app(f, binding.size(), binding.c_ptr());
eq = m().mk_eq(lhs, e);
if (!ids.empty()) {
eq = m().mk_forall(ids.size(), f->get_domain(), ids.c_ptr(), eq);
}
warning_msg("recursive functions are currently only partially supported: they are translated into recursive equations without special handling");
// TBD: basic implementation asserts axiom. Life-time of recursive equation follows scopes (unlikely to be what SMT-LIB 2.5 wants).
assert_expr(eq);
}
func_decl * cmd_context::find_func_decl(symbol const & s) const {
builtin_decl d;
@ -1480,6 +1492,24 @@ void cmd_context::check_sat(unsigned num_assumptions, expr * const * assumptions
}
}
void cmd_context::reset_assertions() {
if (m_opt) {
m_opt = 0;
}
if (m_solver) {
m_solver = 0;
mk_solver();
}
restore_assertions(0);
svector<scope>::iterator it = m_scopes.begin();
svector<scope>::iterator end = m_scopes.end();
for (; it != end; ++it) {
it->m_assertions_lim = 0;
if (m_solver) m_solver->push();
}
}
void cmd_context::display_model(model_ref& mdl) {
if (mdl) {
model_params p;
@ -1672,6 +1702,7 @@ void cmd_context::display_statistics(bool show_total_time, double total_time) {
st.display_smt2(regular_stream());
}
void cmd_context::display_assertions() {
if (!m_interactive_mode)
throw cmd_exception("command is only available in interactive mode, use command (set-option :interactive-mode true)");

View file

@ -156,6 +156,7 @@ protected:
bool m_print_success;
unsigned m_random_seed;
bool m_produce_unsat_cores;
bool m_produce_unsat_assumptions;
bool m_produce_assignments;
status m_status;
bool m_numeral_as_real;
@ -308,7 +309,9 @@ public:
void set_produce_unsat_cores(bool flag);
void set_produce_proofs(bool flag);
void set_produce_interpolants(bool flag);
void set_produce_unsat_assumptions(bool flag) { m_produce_unsat_assumptions = flag; }
bool produce_assignments() const { return m_produce_assignments; }
bool produce_unsat_assumptions() const { return m_produce_unsat_assumptions; }
void set_produce_assignments(bool flag) { m_produce_assignments = flag; }
void set_status(status st) { m_status = st; }
status get_status() const { return m_status; }
@ -342,6 +345,7 @@ public:
void insert(probe_info * p) { tactic_manager::insert(p); }
void insert_user_tactic(symbol const & s, sexpr * d);
void insert_aux_pdecl(pdecl * p);
void insert_rec_fun(func_decl* f, expr_ref_vector const& binding, svector<symbol> const& ids, expr* e);
func_decl * find_func_decl(symbol const & s) const;
func_decl * find_func_decl(symbol const & s, unsigned num_indices, unsigned const * indices,
unsigned arity, sort * const * domain, sort * range) const;
@ -390,6 +394,7 @@ public:
void push(unsigned n);
void pop(unsigned n);
void check_sat(unsigned num_assumptions, expr * const * assumptions);
void reset_assertions();
// display the result produced by a check-sat or check-sat-using commands in the regular stream
void display_sat_result(lbool r);
// check if result produced by check-sat or check-sat-using matches the known status