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

added facility to persist model transformations

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2017-11-02 00:05:52 -05:00
commit fd49a0c89c
195 changed files with 3601 additions and 2139 deletions

View file

@ -20,6 +20,7 @@ Notes:
#include "util/version.h"
#include "ast/ast_smt_pp.h"
#include "ast/ast_smt2_pp.h"
#include "ast/ast_pp_dot.h"
#include "ast/ast_pp.h"
#include "ast/array_decl_plugin.h"
#include "ast/pp.h"
@ -202,6 +203,26 @@ ATOMIC_CMD(get_proof_cmd, "get-proof", "retrieve proof", {
}
});
ATOMIC_CMD(get_proof_graph_cmd, "get-proof-graph", "retrieve proof and print it in graphviz", {
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)
throw cmd_exception("proof is not available");
proof_ref pr(ctx.m());
pr = ctx.get_check_sat_result()->get_proof();
if (pr == 0)
throw cmd_exception("proof is not available");
if (ctx.well_sorted_check_enabled() && !is_well_sorted(ctx.m(), pr)) {
throw cmd_exception("proof is not well sorted");
}
context_params& params = ctx.params();
const std::string& file = params.m_dot_proof_file;
std::ofstream out(file);
out << ast_pp_dot(pr) << std::endl;
});
static void print_core(cmd_context& ctx) {
ptr_vector<expr> core;
ctx.get_check_sat_result()->get_unsat_core(core);
@ -840,6 +861,7 @@ void install_basic_cmds(cmd_context & ctx) {
ctx.insert(alloc(get_assignment_cmd));
ctx.insert(alloc(get_assertions_cmd));
ctx.insert(alloc(get_proof_cmd));
ctx.insert(alloc(get_proof_graph_cmd));
ctx.insert(alloc(get_unsat_core_cmd));
ctx.insert(alloc(set_option_cmd));
ctx.insert(alloc(get_option_cmd));

View file

@ -492,6 +492,7 @@ cmd_context::~cmd_context() {
finalize_tactic_cmds();
finalize_probes();
reset(true);
m_mc0 = 0;
m_solver = 0;
m_check_sat_result = 0;
}
@ -775,7 +776,6 @@ bool cmd_context::is_func_decl(symbol const & s) const {
}
void cmd_context::insert(symbol const & s, func_decl * f) {
m_check_sat_result = 0;
if (!m_check_logic(f)) {
throw cmd_exception(m_check_logic.get_last_error());
}
@ -806,7 +806,6 @@ void cmd_context::insert(symbol const & s, func_decl * f) {
}
void cmd_context::insert(symbol const & s, psort_decl * p) {
m_check_sat_result = 0;
if (m_psort_decls.contains(s)) {
throw cmd_exception("sort already defined ", s);
}
@ -820,7 +819,6 @@ void cmd_context::insert(symbol const & s, psort_decl * p) {
void cmd_context::insert(symbol const & s, unsigned arity, sort *const* domain, expr * t) {
expr_ref _t(t, m());
m_check_sat_result = 0;
if (m_builtin_decls.contains(s)) {
throw cmd_exception("invalid macro/named expression, builtin symbol ", s);
}
@ -1081,16 +1079,31 @@ void cmd_context::mk_app(symbol const & s, unsigned num_args, expr * const * arg
if (fs.more_than_one())
throw cmd_exception("ambiguous constant reference, more than one constant with the same sort, use a qualified expression (as <symbol> <sort>) to disumbiguate ", s);
func_decl * f = fs.first();
if (f == 0)
if (f == 0) {
throw cmd_exception("unknown constant ", s);
}
if (f->get_arity() != 0)
throw cmd_exception("invalid function application, missing arguments ", s);
result = m().mk_const(f);
}
else {
func_decl * f = fs.find(m(), num_args, args, range);
if (f == 0)
throw cmd_exception("unknown constant ", s);
if (f == 0) {
std::ostringstream buffer;
buffer << "unknown constant " << s << " ";
buffer << " (";
bool first = true;
for (unsigned i = 0; i < num_args; ++i, first = false) {
if (!first) buffer << " ";
buffer << mk_pp(m().get_sort(args[i]), m());
}
buffer << ") ";
if (range) buffer << mk_pp(range, m()) << " ";
for (unsigned i = 0; i < fs.get_num_entries(); ++i) {
buffer << "\ndeclared: " << mk_pp(fs.get_entry(i), m()) << " ";
}
throw cmd_exception(buffer.str().c_str());
}
if (well_sorted_check_enabled())
m().check_sort(f, num_args, args);
result = m().mk_app(f, num_args, args);
@ -1250,8 +1263,8 @@ void cmd_context::reset(bool finalize) {
reset_macros();
reset_func_decls();
restore_assertions(0);
if (m_solver)
m_solver = 0;
m_solver = 0;
m_mc0 = 0;
m_scopes.reset();
m_opt = 0;
m_pp_env = 0;
@ -1624,7 +1637,9 @@ void cmd_context::validate_check_sat_result(lbool r) {
throw cmd_exception("check annotation that says unsat");
#else
diagnostic_stream() << "BUG: incompleteness" << std::endl;
exit(ERR_INCOMPLETENESS);
// WORKAROUND: `exit()` causes LSan to be invoked and produce
// many false positives.
_Exit(ERR_INCOMPLETENESS);
#endif
}
break;
@ -1634,7 +1649,9 @@ void cmd_context::validate_check_sat_result(lbool r) {
throw cmd_exception("check annotation that says sat");
#else
diagnostic_stream() << "BUG: unsoundness" << std::endl;
exit(ERR_UNSOUNDNESS);
// WORKAROUND: `exit()` causes LSan to be invoked and produce
// many false positives.
_Exit(ERR_UNSOUNDNESS);
#endif
}
break;

View file

@ -194,6 +194,7 @@ protected:
static std::ostringstream g_error_stream;
generic_model_converter_ref m_mc0;
ast_manager * m_manager;
bool m_own_manager;
bool m_manager_initialized;
@ -304,7 +305,6 @@ protected:
void erase_macro(symbol const& s);
bool macros_find(symbol const& s, unsigned n, expr*const* args, expr*& t) const;
generic_model_converter_ref m_mc0;
public:
cmd_context(bool main_ctx = true, ast_manager * m = 0, symbol const & l = symbol::null);

View file

@ -111,6 +111,9 @@ void context_params::set(char const * param, char const * value) {
else if (p == "trace_file_name") {
m_trace_file_name = value;
}
else if (p == "dot_proof_file") {
m_dot_proof_file = value;
}
else if (p == "unsat_core") {
set_bool(m_unsat_core, param, value);
}
@ -146,6 +149,7 @@ void context_params::updt_params(params_ref const & p) {
m_dump_models = p.get_bool("dump_models", m_dump_models);
m_trace = p.get_bool("trace", m_trace);
m_trace_file_name = p.get_str("trace_file_name", "z3.log");
m_dot_proof_file = p.get_str("dot_proof_file", "proof.dot");
m_unsat_core = p.get_bool("unsat_core", m_unsat_core);
m_debug_ref_count = p.get_bool("debug_ref_count", m_debug_ref_count);
m_smtlib2_compliant = p.get_bool("smtlib2_compliant", m_smtlib2_compliant);
@ -161,6 +165,7 @@ void context_params::collect_param_descrs(param_descrs & d) {
d.insert("dump_models", CPK_BOOL, "dump models whenever check-sat returns sat", "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("dot_proof_file", CPK_STRING, "file in which to output graphical proofs", "proof.dot");
d.insert("debug_ref_count", CPK_BOOL, "debug support for AST reference counting", "false");
d.insert("smtlib2_compliant", CPK_BOOL, "enable/disable SMT-LIB 2.0 compliance", "false");
collect_solver_param_descrs(d);
@ -192,7 +197,7 @@ void context_params::get_solver_params(ast_manager const & m, params_ref & p, bo
ast_manager * context_params::mk_ast_manager() {
ast_manager * r = alloc(ast_manager,
m_proof ? PGM_FINE : PGM_DISABLED,
m_proof ? PGM_ENABLED : PGM_DISABLED,
m_trace ? m_trace_file_name.c_str() : 0);
if (m_smtlib2_compliant)
r->enable_int_real_coercions(false);

View file

@ -30,6 +30,7 @@ class context_params {
public:
bool m_auto_config;
bool m_proof;
std::string m_dot_proof_file;
bool m_interpolants;
bool m_debug_ref_count;
bool m_trace;

View file

@ -147,7 +147,7 @@ static void compute_interpolant_and_maybe_check(cmd_context & ctx, expr * t, par
ast_manager &_m = ctx.m();
// TODO: the following is a HACK to enable proofs in the old smt solver
// When we stop using that solver, this hack can be removed
scoped_proof_mode spm(_m,PGM_FINE);
scoped_proof_mode spm(_m,PGM_ENABLED);
ctx.params().get_solver_params(_m, p, proofs_enabled, models_enabled, unsat_core_enabled);
p.set_bool("proof", true);
scoped_ptr<solver> sp = (ctx.get_interpolating_solver_factory())(_m, p, true, models_enabled, false, ctx.get_logic());