mirror of
https://github.com/Z3Prover/z3
synced 2025-05-03 22:05:45 +00:00
working on smt2 and api
This commit is contained in:
parent
2b93537366
commit
78848f3ddd
30 changed files with 1307 additions and 94 deletions
|
@ -240,6 +240,8 @@ protected:
|
|||
symbol m_produce_unsat_cores;
|
||||
symbol m_produce_models;
|
||||
symbol m_produce_assignments;
|
||||
symbol m_produce_interpolants;
|
||||
symbol m_check_interpolants;
|
||||
symbol m_regular_output_channel;
|
||||
symbol m_diagnostic_output_channel;
|
||||
symbol m_random_seed;
|
||||
|
@ -253,7 +255,9 @@ protected:
|
|||
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_produce_models || s == m_produce_assignments || s == m_regular_output_channel || s == m_diagnostic_output_channel ||
|
||||
s == m_produce_models || s == m_produce_assignments || s == m_produce_interpolants ||
|
||||
s == m_check_interpolants ||
|
||||
s == m_regular_output_channel || s == m_diagnostic_output_channel ||
|
||||
s == m_random_seed || s == m_verbosity || s == m_global_decls;
|
||||
}
|
||||
|
||||
|
@ -270,6 +274,8 @@ public:
|
|||
m_produce_unsat_cores(":produce-unsat-cores"),
|
||||
m_produce_models(":produce-models"),
|
||||
m_produce_assignments(":produce-assignments"),
|
||||
m_produce_interpolants(":produce-interpolants"),
|
||||
m_check_interpolants(":check-interpolants"),
|
||||
m_regular_output_channel(":regular-output-channel"),
|
||||
m_diagnostic_output_channel(":diagnostic-output-channel"),
|
||||
m_random_seed(":random-seed"),
|
||||
|
@ -337,6 +343,13 @@ class set_option_cmd : public set_get_option_cmd {
|
|||
check_not_initialized(ctx, m_produce_proofs);
|
||||
ctx.set_produce_proofs(to_bool(value));
|
||||
}
|
||||
else if (m_option == m_produce_interpolants) {
|
||||
check_not_initialized(ctx, m_produce_interpolants);
|
||||
ctx.set_produce_interpolants(to_bool(value));
|
||||
}
|
||||
else if (m_option == m_check_interpolants) {
|
||||
ctx.set_check_interpolants(to_bool(value));
|
||||
}
|
||||
else if (m_option == m_produce_unsat_cores) {
|
||||
check_not_initialized(ctx, m_produce_unsat_cores);
|
||||
ctx.set_produce_unsat_cores(to_bool(value));
|
||||
|
@ -485,6 +498,9 @@ public:
|
|||
else if (opt == m_produce_proofs) {
|
||||
print_bool(ctx, ctx.produce_proofs());
|
||||
}
|
||||
else if (opt == m_produce_interpolants) {
|
||||
print_bool(ctx, ctx.produce_interpolants());
|
||||
}
|
||||
else if (opt == m_produce_unsat_cores) {
|
||||
print_bool(ctx, ctx.produce_unsat_cores());
|
||||
}
|
||||
|
|
|
@ -38,6 +38,9 @@ Notes:
|
|||
#include"model_evaluator.h"
|
||||
#include"for_each_expr.h"
|
||||
#include"scoped_timer.h"
|
||||
#include"interpolant_cmds.h"
|
||||
//FIXME Does this break modularity?
|
||||
// #include"smt_solver.h"
|
||||
|
||||
func_decls::func_decls(ast_manager & m, func_decl * f):
|
||||
m_decls(TAG(func_decl*, f, 0)) {
|
||||
|
@ -323,6 +326,7 @@ cmd_context::cmd_context(bool main_ctx, ast_manager * m, symbol const & l):
|
|||
install_basic_cmds(*this);
|
||||
install_ext_basic_cmds(*this);
|
||||
install_core_tactic_cmds(*this);
|
||||
install_interpolant_cmds(*this);
|
||||
SASSERT(m != 0 || !has_manager());
|
||||
if (m)
|
||||
init_external_manager();
|
||||
|
@ -380,6 +384,19 @@ void cmd_context::set_produce_proofs(bool f) {
|
|||
m_params.m_proof = f;
|
||||
}
|
||||
|
||||
void cmd_context::set_produce_interpolants(bool f) {
|
||||
// can only be set before initialization
|
||||
// FIXME currently synonym for produce_proofs
|
||||
// also sets the default solver to be simple smt
|
||||
SASSERT(!has_manager());
|
||||
m_params.m_proof = f;
|
||||
// set_solver_factory(mk_smt_solver_factory());
|
||||
}
|
||||
|
||||
void cmd_context::set_check_interpolants(bool f) {
|
||||
m_params.m_check_interpolants = f;
|
||||
}
|
||||
|
||||
bool cmd_context::produce_models() const {
|
||||
return m_params.m_model;
|
||||
}
|
||||
|
@ -388,6 +405,15 @@ bool cmd_context::produce_proofs() const {
|
|||
return m_params.m_proof;
|
||||
}
|
||||
|
||||
bool cmd_context::produce_interpolants() const {
|
||||
// FIXME currently synonym for produce_proofs
|
||||
return m_params.m_proof;
|
||||
}
|
||||
|
||||
bool cmd_context::check_interpolants() const {
|
||||
return m_params.m_check_interpolants;
|
||||
}
|
||||
|
||||
bool cmd_context::produce_unsat_cores() const {
|
||||
return m_params.m_unsat_core;
|
||||
}
|
||||
|
@ -1456,11 +1482,27 @@ void cmd_context::validate_model() {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME: really interpolants_enabled ought to be a parameter to the solver factory,
|
||||
// but this is a global change, so for now, we use an alternate solver factory
|
||||
// for interpolation
|
||||
|
||||
void cmd_context::mk_solver() {
|
||||
bool proofs_enabled, models_enabled, unsat_core_enabled;
|
||||
params_ref p;
|
||||
m_params.get_solver_params(m(), p, proofs_enabled, models_enabled, unsat_core_enabled);
|
||||
m_solver = (*m_solver_factory)(m(), p, proofs_enabled, models_enabled, unsat_core_enabled, m_logic);
|
||||
if(produce_interpolants()){
|
||||
SASSERT(m_interpolating_solver_factory);
|
||||
m_solver = (*m_interpolating_solver_factory)(m(), p, true /* must have proofs */, models_enabled, unsat_core_enabled, m_logic);
|
||||
}
|
||||
else
|
||||
m_solver = (*m_solver_factory)(m(), p, proofs_enabled, models_enabled, unsat_core_enabled, m_logic);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void cmd_context::set_interpolating_solver_factory(solver_factory * f) {
|
||||
SASSERT(!has_manager());
|
||||
m_interpolating_solver_factory = f;
|
||||
}
|
||||
|
||||
void cmd_context::set_solver_factory(solver_factory * f) {
|
||||
|
|
|
@ -186,6 +186,7 @@ protected:
|
|||
|
||||
svector<scope> m_scopes;
|
||||
scoped_ptr<solver_factory> m_solver_factory;
|
||||
scoped_ptr<solver_factory> m_interpolating_solver_factory;
|
||||
ref<solver> m_solver;
|
||||
ref<check_sat_result> m_check_sat_result;
|
||||
|
||||
|
@ -253,6 +254,7 @@ public:
|
|||
void cancel() { set_cancel(true); }
|
||||
void reset_cancel() { set_cancel(false); }
|
||||
context_params & params() { return m_params; }
|
||||
solver_factory &get_solver_factory() { return *m_solver_factory; }
|
||||
void global_params_updated(); // this method should be invoked when global (and module) params are updated.
|
||||
bool set_logic(symbol const & s);
|
||||
bool has_logic() const { return m_logic != symbol::null; }
|
||||
|
@ -275,12 +277,16 @@ public:
|
|||
void set_random_seed(unsigned s) { m_random_seed = s; }
|
||||
bool produce_models() const;
|
||||
bool produce_proofs() const;
|
||||
bool produce_interpolants() const;
|
||||
bool check_interpolants() const;
|
||||
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);
|
||||
void set_produce_interpolants(bool flag);
|
||||
void set_check_interpolants(bool flag);
|
||||
bool produce_assignments() const { return m_produce_assignments; }
|
||||
void set_produce_assignments(bool flag) { m_produce_assignments = flag; }
|
||||
void set_status(status st) { m_status = st; }
|
||||
|
@ -294,6 +300,7 @@ public:
|
|||
sexpr_manager & sm() const { if (!m_sexpr_manager) const_cast<cmd_context*>(this)->m_sexpr_manager = alloc(sexpr_manager); return *m_sexpr_manager; }
|
||||
|
||||
void set_solver_factory(solver_factory * s);
|
||||
void set_interpolating_solver_factory(solver_factory * s);
|
||||
void set_check_sat_result(check_sat_result * r) { m_check_sat_result = r; }
|
||||
check_sat_result * get_check_sat_result() const { return m_check_sat_result.get(); }
|
||||
check_sat_state cs_state() const;
|
||||
|
|
|
@ -61,6 +61,9 @@ void context_params::set(char const * param, char const * value) {
|
|||
else if (p == "proof") {
|
||||
set_bool(m_proof, param, value);
|
||||
}
|
||||
else if (p == "check_interpolants") {
|
||||
set_bool(m_check_interpolants, param, value);
|
||||
}
|
||||
else if (p == "model") {
|
||||
set_bool(m_model, param, value);
|
||||
}
|
||||
|
@ -96,6 +99,7 @@ void context_params::updt_params(params_ref const & p) {
|
|||
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_check_interpolants = p.get_bool("check_interpolants", false);
|
||||
m_model = p.get_bool("model", true);
|
||||
m_model_validate = p.get_bool("model_validate", false);
|
||||
m_trace = p.get_bool("trace", false);
|
||||
|
@ -111,6 +115,7 @@ void context_params::collect_param_descrs(param_descrs & d) {
|
|||
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("check_interpolants", CPK_BOOL, "check correctness of interpolants", "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");
|
||||
|
|
|
@ -29,6 +29,8 @@ class context_params {
|
|||
public:
|
||||
bool m_auto_config;
|
||||
bool m_proof;
|
||||
bool m_interpolants;
|
||||
bool m_check_interpolants;
|
||||
bool m_debug_ref_count;
|
||||
bool m_trace;
|
||||
std::string m_trace_file_name;
|
||||
|
|
120
src/cmd_context/interpolant_cmds.cpp
Normal file
120
src/cmd_context/interpolant_cmds.cpp
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*++
|
||||
Copyright (c) 2013 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
interpolant_cmds.cpp
|
||||
|
||||
Abstract:
|
||||
Commands for interpolation.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-12-23
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include<sstream>
|
||||
#include"cmd_context.h"
|
||||
#include"cmd_util.h"
|
||||
#include"scoped_timer.h"
|
||||
#include"scoped_ctrl_c.h"
|
||||
#include"cancel_eh.h"
|
||||
#include"ast_pp.h"
|
||||
#include"ast_smt_pp.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
#include"parametric_cmd.h"
|
||||
#include"mpq.h"
|
||||
#include"expr2var.h"
|
||||
#include"pp.h"
|
||||
#include"pp_params.hpp"
|
||||
#include"iz3interp.h"
|
||||
#include"iz3checker.h"
|
||||
|
||||
static void get_interpolant_and_maybe_check(cmd_context & ctx, expr * t, bool check) {
|
||||
|
||||
// get the proof, if there is one
|
||||
|
||||
if (!ctx.produce_interpolants())
|
||||
throw cmd_exception("interpolation is not enabled, use command (set-option :produce-interpolants true)");
|
||||
if (!ctx.has_manager() ||
|
||||
ctx.cs_state() != cmd_context::css_unsat)
|
||||
throw cmd_exception("proof is not available");
|
||||
expr_ref pr(ctx.m());
|
||||
pr = ctx.get_check_sat_result()->get_proof();
|
||||
if (pr == 0)
|
||||
throw cmd_exception("proof is not available");
|
||||
|
||||
// get the assertions
|
||||
|
||||
ptr_vector<expr>::const_iterator it = ctx.begin_assertions();
|
||||
ptr_vector<expr>::const_iterator end = ctx.end_assertions();
|
||||
ptr_vector<ast> cnsts(end - it);
|
||||
for (int i = 0; it != end; ++it, ++i)
|
||||
cnsts[i] = *it;
|
||||
|
||||
// compute an interpolant
|
||||
|
||||
ptr_vector<ast> interps;
|
||||
|
||||
try {
|
||||
iz3interpolate(ctx.m(),pr.get(),cnsts,t,interps,0);
|
||||
}
|
||||
catch (iz3_bad_tree &) {
|
||||
throw cmd_exception("interpolation pattern contains non-asserted formula");
|
||||
}
|
||||
catch (iz3_incompleteness &) {
|
||||
throw cmd_exception("incompleteness in interpolator");
|
||||
}
|
||||
|
||||
|
||||
// if we lived, print it out
|
||||
for(unsigned i = 0; i < interps.size(); i++){
|
||||
ctx.regular_stream() << mk_pp(interps[i], ctx.m()) << std::endl;
|
||||
#if 0
|
||||
ast_smt_pp pp(ctx.m());
|
||||
pp.set_logic(ctx.get_logic().str().c_str());
|
||||
pp.display_smt2(ctx.regular_stream(), to_expr(interps[i]));
|
||||
ctx.regular_stream() << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
// verify, for the paranoid...
|
||||
if(check || ctx.check_interpolants()){
|
||||
std::ostringstream err;
|
||||
ast_manager &_m = ctx.m();
|
||||
|
||||
// need a solver -- make one here FIXME is this right?
|
||||
bool proofs_enabled, models_enabled, unsat_core_enabled;
|
||||
params_ref p;
|
||||
ctx.params().get_solver_params(_m, p, proofs_enabled, models_enabled, unsat_core_enabled);
|
||||
scoped_ptr<solver> sp = (ctx.get_solver_factory())(_m, p, false, true, false, ctx.get_logic());
|
||||
|
||||
if(iz3check(_m,sp.get(),err,cnsts,t,interps))
|
||||
ctx.regular_stream() << "correct\n";
|
||||
else
|
||||
ctx.regular_stream() << "incorrect: " << err.str().c_str() << "\n";
|
||||
}
|
||||
|
||||
for(unsigned i = 0; i < interps.size(); i++){
|
||||
ctx.m().dec_ref(interps[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void get_interpolant(cmd_context & ctx, expr * t) {
|
||||
get_interpolant_and_maybe_check(ctx,t,false);
|
||||
}
|
||||
|
||||
static void get_and_check_interpolant(cmd_context & ctx, expr * t) {
|
||||
get_interpolant_and_maybe_check(ctx,t,true);
|
||||
}
|
||||
|
||||
UNARY_CMD(get_interpolant_cmd, "get-interpolant", "<fmla>", "get interpolant for marked positions in fmla", CPK_EXPR, expr *, get_interpolant(ctx, arg););
|
||||
|
||||
// UNARY_CMD(get_and_check_interpolant_cmd, "get-and-check-interpolant", "<fmla>", "get and check interpolant for marked positions in fmla", CPK_EXPR, expr *, get_and_check_interpolant(ctx, arg););
|
||||
|
||||
void install_interpolant_cmds(cmd_context & ctx) {
|
||||
ctx.insert(alloc(get_interpolant_cmd));
|
||||
// ctx.insert(alloc(get_and_check_interpolant_cmd));
|
||||
}
|
24
src/cmd_context/interpolant_cmds.h
Normal file
24
src/cmd_context/interpolant_cmds.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
interpolant_cmds.h
|
||||
|
||||
Abstract:
|
||||
Commands for interpolation.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-12-23
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _INTERPOLANT_CMDS_H_
|
||||
#define _INTERPOLANT_CMDS_H_
|
||||
|
||||
class cmd_context;
|
||||
void install_interpolant_cmds(cmd_context & ctx);
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue