mirror of
https://github.com/Z3Prover/z3
synced 2025-04-22 16:45:31 +00:00
Reorganizing the code
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
d8cd3fc3ab
commit
6bdb009c3e
74 changed files with 67 additions and 27 deletions
|
@ -1,774 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
basic_cmds.cpp
|
||||
|
||||
Abstract:
|
||||
Basic commands for SMT2 front end.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-03-30
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"cmd_context.h"
|
||||
#include"version.h"
|
||||
#include"ast_smt_pp.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
#include"ast_pp.h"
|
||||
#include"model_smt2_pp.h"
|
||||
#include"model_v2_pp.h"
|
||||
#include"array_decl_plugin.h"
|
||||
#include"pp.h"
|
||||
#include"cmd_util.h"
|
||||
#include"simplify_cmd.h"
|
||||
#include"eval_cmd.h"
|
||||
#include"qe_cmd.h"
|
||||
|
||||
class help_cmd : public cmd {
|
||||
svector<symbol> m_cmds;
|
||||
void display_cmd(cmd_context & ctx, symbol const & s, cmd * c) {
|
||||
char const * usage = c->get_usage();
|
||||
char const * descr = c->get_descr(ctx);
|
||||
ctx.regular_stream() << " (" << s;
|
||||
if (usage)
|
||||
ctx.regular_stream() << " " << escaped(usage, true) << ")\n";
|
||||
else
|
||||
ctx.regular_stream() << ")\n";
|
||||
if (descr) {
|
||||
ctx.regular_stream() << " " << escaped(descr, true, 4) << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
help_cmd():cmd("help") {}
|
||||
virtual char const * get_usage() const { return "<symbol>*"; }
|
||||
virtual char const * get_descr(cmd_context & ctx) const { return "print this help."; }
|
||||
virtual unsigned get_arity() const { return VAR_ARITY; }
|
||||
virtual void prepare(cmd_context & ctx) { m_cmds.reset(); }
|
||||
virtual cmd_arg_kind next_arg_kind(cmd_context & ctx) const { return CPK_SYMBOL; }
|
||||
virtual void set_next_arg(cmd_context & ctx, symbol const & s) {
|
||||
cmd * c = ctx.find_cmd(s);
|
||||
if (c == 0) {
|
||||
std::string err_msg("unknown command '");
|
||||
err_msg = err_msg + s.bare_str() + "'";
|
||||
throw cmd_exception(err_msg);
|
||||
}
|
||||
m_cmds.push_back(s);
|
||||
}
|
||||
|
||||
typedef std::pair<symbol, cmd*> named_cmd;
|
||||
struct named_cmd_lt {
|
||||
bool operator()(named_cmd const & c1, named_cmd const & c2) const { return c1.first.str() < c2.first.str(); }
|
||||
};
|
||||
|
||||
virtual void execute(cmd_context & ctx) {
|
||||
ctx.regular_stream() << "\"";
|
||||
if (m_cmds.empty()) {
|
||||
vector<named_cmd> cmds;
|
||||
cmd_context::cmd_iterator it = ctx.begin_cmds();
|
||||
cmd_context::cmd_iterator end = ctx.end_cmds();
|
||||
for (; it != end; ++it) {
|
||||
cmds.push_back(named_cmd((*it).m_key, (*it).m_value));
|
||||
}
|
||||
// named_cmd_lt is not a total order for commands, but this is irrelevant for Linux x Windows behavior
|
||||
std::sort(cmds.begin(), cmds.end(), named_cmd_lt());
|
||||
vector<named_cmd>::const_iterator it2 = cmds.begin();
|
||||
vector<named_cmd>::const_iterator end2 = cmds.end();
|
||||
for (; it2 != end2; ++it2) {
|
||||
display_cmd(ctx, it2->first, it2->second);
|
||||
}
|
||||
}
|
||||
else {
|
||||
svector<symbol>::const_iterator it = m_cmds.begin();
|
||||
svector<symbol>::const_iterator end = m_cmds.end();
|
||||
for (; it != end; ++it) {
|
||||
cmd * c = ctx.find_cmd(*it);
|
||||
SASSERT(c);
|
||||
display_cmd(ctx, *it, c);
|
||||
}
|
||||
}
|
||||
ctx.regular_stream() << "\"\n";
|
||||
}
|
||||
};
|
||||
|
||||
ATOMIC_CMD(exit_cmd, "exit", "exit.", ctx.print_success(); throw stop_parser_exception(););
|
||||
|
||||
ATOMIC_CMD(get_model_cmd, "get-model", "retrieve model for the last check-sat command", {
|
||||
if (!ctx.is_model_available() || ctx.get_check_sat_result() == 0)
|
||||
throw cmd_exception("model is not available");
|
||||
model_ref m;
|
||||
ctx.get_check_sat_result()->get_model(m);
|
||||
if (ctx.params().m_model_v1_pp || ctx.params().m_model_v2_pp) {
|
||||
std::ostringstream buffer;
|
||||
model_v2_pp(buffer, *m, ctx.params().m_model_partial);
|
||||
ctx.regular_stream() << "\"" << escaped(buffer.str().c_str(), true) << "\"" << std::endl;
|
||||
} else {
|
||||
ctx.regular_stream() << "(model " << std::endl;
|
||||
model_smt2_pp(ctx.regular_stream(), ctx, *(m.get()), 2);
|
||||
// m->display(ctx.regular_stream());
|
||||
ctx.regular_stream() << ")" << std::endl;
|
||||
}
|
||||
});
|
||||
|
||||
ATOMIC_CMD(get_assignment_cmd, "get-assignment", "retrieve assignment", {
|
||||
if (!ctx.is_model_available() || ctx.get_check_sat_result() == 0)
|
||||
throw cmd_exception("model is not available");
|
||||
model_ref m;
|
||||
ctx.get_check_sat_result()->get_model(m);
|
||||
ctx.regular_stream() << "(";
|
||||
dictionary<cmd_context::macro> const & macros = ctx.get_macros();
|
||||
dictionary<cmd_context::macro>::iterator it = macros.begin();
|
||||
dictionary<cmd_context::macro>::iterator end = macros.end();
|
||||
for (bool first = true; it != end; ++it) {
|
||||
symbol const & name = (*it).m_key;
|
||||
cmd_context::macro const & _m = (*it).m_value;
|
||||
if (_m.first == 0 && ctx.m().is_bool(_m.second)) {
|
||||
expr_ref val(ctx.m());
|
||||
m->eval(_m.second, val, true);
|
||||
if (ctx.m().is_true(val) || ctx.m().is_false(val)) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
ctx.regular_stream() << " ";
|
||||
ctx.regular_stream() << "(" << name << " " << (ctx.m().is_true(val) ? "true" : "false") << ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx.regular_stream() << ")" << std::endl;
|
||||
});
|
||||
|
||||
class cmd_is_declared : public ast_smt_pp::is_declared {
|
||||
cmd_context& m_ctx;
|
||||
public:
|
||||
cmd_is_declared(cmd_context& ctx): m_ctx(ctx) {}
|
||||
|
||||
virtual bool operator()(func_decl* d) const {
|
||||
return m_ctx.is_func_decl(d->get_name());
|
||||
}
|
||||
virtual bool operator()(sort* s) const {
|
||||
return m_ctx.is_sort_decl(s->get_name());
|
||||
}
|
||||
};
|
||||
|
||||
ATOMIC_CMD(get_proof_cmd, "get-proof", "retrieve proof", {
|
||||
if (ctx.params().m_proof_mode == PGM_DISABLED)
|
||||
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");
|
||||
expr_ref pr(ctx.m());
|
||||
pr = ctx.get_check_sat_result()->get_proof();
|
||||
if (pr == 0)
|
||||
throw cmd_exception("proof is not available");
|
||||
// TODO: reimplement a new SMT2 pretty printer
|
||||
ast_smt_pp pp(ctx.m());
|
||||
cmd_is_declared isd(ctx);
|
||||
pp.set_is_declared(&isd);
|
||||
pp.set_logic(ctx.get_logic().str().c_str());
|
||||
pp.display_smt2(ctx.regular_stream(), pr);
|
||||
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;
|
||||
});
|
||||
|
||||
ATOMIC_CMD(labels_cmd, "labels", "retrieve Simplify-like labels", {
|
||||
if (!ctx.has_manager() ||
|
||||
(ctx.cs_state() != cmd_context::css_sat && ctx.cs_state() != cmd_context::css_unknown))
|
||||
throw cmd_exception("labels are not available");
|
||||
svector<symbol> labels;
|
||||
ctx.get_check_sat_result()->get_labels(labels);
|
||||
ctx.regular_stream() << "(labels";
|
||||
for (unsigned i = 0; i < labels.size(); i++) {
|
||||
ctx.regular_stream() << " " << labels[i];
|
||||
}
|
||||
ctx.regular_stream() << ")" << std::endl;
|
||||
});
|
||||
|
||||
ATOMIC_CMD(get_assertions_cmd, "get-assertions", "retrieve asserted terms when in interactive mode", ctx.display_assertions(););
|
||||
|
||||
UNARY_CMD(set_logic_cmd, "set-logic", "<symbol>", "set the background logic.", CPK_SYMBOL, symbol const &, ctx.set_logic(arg); ctx.print_success(););
|
||||
|
||||
UNARY_CMD(pp_cmd, "display", "<term>", "display the given term.", CPK_EXPR, expr *, {
|
||||
ctx.display(ctx.regular_stream(), arg);
|
||||
ctx.regular_stream() << std::endl;
|
||||
});
|
||||
|
||||
UNARY_CMD(echo_cmd, "echo", "<string>", "display the given string", CPK_STRING, char const *, ctx.regular_stream() << arg << std::endl;);
|
||||
|
||||
/**
|
||||
\brief Convert a keyword into an internal Z3 option name
|
||||
*/
|
||||
std::string smt_keyword2opt_name(symbol const & opt) {
|
||||
std::string r;
|
||||
SASSERT(opt.bare_str()[0] == ':');
|
||||
r = opt.bare_str() + 1;
|
||||
unsigned sz = static_cast<unsigned>(r.size());
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
char curr = r[i];
|
||||
if ('a' <= curr && curr <= 'z')
|
||||
r[i] = 'A' + (curr - 'a');
|
||||
else if (curr == '-')
|
||||
r[i] = '_';
|
||||
}
|
||||
TRACE("smt2_opt_name", tout << opt << " -> '" << r << "'\n";);
|
||||
return r;
|
||||
}
|
||||
|
||||
class set_get_option_cmd : public cmd {
|
||||
protected:
|
||||
symbol m_true;
|
||||
symbol m_false;
|
||||
|
||||
symbol m_print_success;
|
||||
symbol m_print_warning;
|
||||
symbol m_expand_definitions;
|
||||
symbol m_interactive_mode;
|
||||
symbol m_produce_proofs;
|
||||
symbol m_produce_unsat_cores;
|
||||
symbol m_produce_models;
|
||||
symbol m_produce_assignments;
|
||||
symbol m_regular_output_channel;
|
||||
symbol m_diagnostic_output_channel;
|
||||
symbol m_random_seed;
|
||||
symbol m_verbosity;
|
||||
symbol m_global_decls;
|
||||
symbol m_numeral_as_real;
|
||||
symbol m_error_behavior;
|
||||
symbol m_int_real_coercions;
|
||||
ini_params m_ini;
|
||||
|
||||
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_produce_models || s == m_produce_assignments || s == m_regular_output_channel || s == m_diagnostic_output_channel ||
|
||||
s == m_random_seed || s == m_verbosity || s == m_global_decls;
|
||||
}
|
||||
|
||||
public:
|
||||
set_get_option_cmd(char const * name, front_end_params & params):
|
||||
cmd(name),
|
||||
m_true("true"),
|
||||
m_false("false"),
|
||||
m_print_success(":print-success"),
|
||||
m_print_warning(":print-warning"),
|
||||
m_expand_definitions(":expand-definitions"),
|
||||
m_interactive_mode(":interactive-mode"),
|
||||
m_produce_proofs(":produce-proofs"),
|
||||
m_produce_unsat_cores(":produce-unsat-cores"),
|
||||
m_produce_models(":produce-models"),
|
||||
m_produce_assignments(":produce-assignments"),
|
||||
m_regular_output_channel(":regular-output-channel"),
|
||||
m_diagnostic_output_channel(":diagnostic-output-channel"),
|
||||
m_random_seed(":random-seed"),
|
||||
m_verbosity(":verbosity"),
|
||||
m_global_decls(":global-decls"),
|
||||
m_numeral_as_real(":numeral-as-real"),
|
||||
m_error_behavior(":error-behavior"),
|
||||
m_int_real_coercions(":int-real-coercions"),
|
||||
m_ini(false) {
|
||||
params.register_params(m_ini);
|
||||
register_pp_params(m_ini);
|
||||
}
|
||||
virtual ~set_get_option_cmd() {}
|
||||
|
||||
};
|
||||
|
||||
class set_option_cmd : public set_get_option_cmd {
|
||||
bool m_unsupported;
|
||||
symbol m_option;
|
||||
|
||||
bool to_bool(symbol const & value) const {
|
||||
if (value != m_true && value != m_false)
|
||||
throw cmd_exception("invalid option value, true/false expected");
|
||||
return value == m_true;
|
||||
}
|
||||
|
||||
static unsigned to_unsigned(rational const & val) {
|
||||
if (!val.is_unsigned())
|
||||
throw cmd_exception("option value is too big to fit in a machine integer.");
|
||||
return val.get_unsigned();
|
||||
}
|
||||
|
||||
static void check_not_initialized(cmd_context & ctx, symbol const & opt_name) {
|
||||
if (ctx.has_manager()) {
|
||||
std::string msg = "error setting '";
|
||||
msg += opt_name.str();
|
||||
msg += "', option value cannot be modified after initialization";
|
||||
throw cmd_exception(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void set_param(cmd_context & ctx, char const * value) {
|
||||
m_ini.freeze(ctx.has_manager());
|
||||
std::string internal_opt = smt_keyword2opt_name(m_option);
|
||||
try {
|
||||
std::string old_value;
|
||||
if (!m_ini.get_param_value(internal_opt.c_str(), old_value)) {
|
||||
m_unsupported = true;
|
||||
return;
|
||||
}
|
||||
m_ini.set_param_value(internal_opt.c_str(), value);
|
||||
}
|
||||
catch (set_get_param_exception ex) {
|
||||
std::string msg = "error setting '";
|
||||
msg += m_option.str();
|
||||
msg += "', ";
|
||||
msg += ex.get_msg();
|
||||
throw cmd_exception(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void set_symbol(cmd_context & ctx, symbol const & value) {
|
||||
if (m_option == m_print_success) {
|
||||
ctx.set_print_success(to_bool(value));
|
||||
}
|
||||
else if (m_option == m_print_warning) {
|
||||
enable_warning_messages(to_bool(value));
|
||||
}
|
||||
else if (m_option == m_expand_definitions) {
|
||||
m_unsupported = true;
|
||||
}
|
||||
else if (m_option == m_interactive_mode) {
|
||||
check_not_initialized(ctx, m_interactive_mode);
|
||||
ctx.set_interactive_mode(to_bool(value));
|
||||
}
|
||||
else if (m_option == m_produce_proofs) {
|
||||
check_not_initialized(ctx, m_produce_proofs);
|
||||
ctx.params().m_proof_mode = to_bool(value) ? PGM_FINE : PGM_DISABLED;
|
||||
}
|
||||
else if (m_option == m_produce_unsat_cores) {
|
||||
check_not_initialized(ctx, m_produce_unsat_cores);
|
||||
ctx.set_produce_unsat_cores(to_bool(value));
|
||||
}
|
||||
else if (m_option == m_produce_models) {
|
||||
ctx.params().m_model = to_bool(value);
|
||||
}
|
||||
else if (m_option == m_produce_assignments) {
|
||||
ctx.set_produce_assignments(to_bool(value));
|
||||
}
|
||||
else if (m_option == m_global_decls) {
|
||||
check_not_initialized(ctx, m_global_decls);
|
||||
ctx.set_global_decls(to_bool(value));
|
||||
}
|
||||
else if (m_option == m_numeral_as_real) {
|
||||
ctx.set_numeral_as_real(to_bool(value));
|
||||
}
|
||||
else if (m_option == m_int_real_coercions) {
|
||||
ctx.m().enable_int_real_coercions(to_bool(value));
|
||||
}
|
||||
#ifdef Z3DEBUG
|
||||
else if (m_option == ":enable-assertions") {
|
||||
enable_assertions(to_bool(value));
|
||||
}
|
||||
#endif
|
||||
else if (m_option == m_error_behavior) {
|
||||
if (value == "immediate-exit") {
|
||||
ctx.set_exit_on_error(true);
|
||||
}
|
||||
else if (value == "continued-execution") {
|
||||
ctx.set_exit_on_error(false);
|
||||
}
|
||||
else {
|
||||
throw cmd_exception("error setting :error-behavior, 'immediate-execution' or 'continued-execution' expected");
|
||||
}
|
||||
}
|
||||
else if (is_builtin_option(m_option)) {
|
||||
throw cmd_exception("option value is not a symbol");
|
||||
}
|
||||
else {
|
||||
set_param(ctx, value.bare_str());
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
set_option_cmd(front_end_params & params):
|
||||
set_get_option_cmd("set-option", params),
|
||||
m_unsupported(false) {
|
||||
}
|
||||
|
||||
virtual char const * get_usage() const { return "<keyword> <value>"; }
|
||||
|
||||
virtual char const * get_descr(cmd_context & ctx) const { return "set configuration option."; }
|
||||
|
||||
virtual unsigned get_arity() const { return 2; }
|
||||
|
||||
virtual void prepare(cmd_context & ctx) { m_unsupported = false; m_option = symbol::null; }
|
||||
|
||||
virtual cmd_arg_kind next_arg_kind(cmd_context & ctx) const {
|
||||
return m_option == symbol::null ? CPK_KEYWORD : CPK_OPTION_VALUE;
|
||||
}
|
||||
|
||||
virtual void set_next_arg(cmd_context & ctx, symbol const & opt) {
|
||||
if (m_option == symbol::null) {
|
||||
m_option = opt;
|
||||
}
|
||||
else {
|
||||
set_symbol(ctx, opt);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void set_next_arg(cmd_context & ctx, rational const & val) {
|
||||
if (m_option == m_random_seed) {
|
||||
ctx.set_random_seed(to_unsigned(val));
|
||||
}
|
||||
else if (m_option == m_verbosity) {
|
||||
set_verbosity_level(to_unsigned(val));
|
||||
}
|
||||
else if (is_builtin_option(m_option)) {
|
||||
throw cmd_exception("option value is not a numeral");
|
||||
}
|
||||
else {
|
||||
std::string str = val.to_string();
|
||||
set_param(ctx, str.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
virtual void set_next_arg(cmd_context & ctx, char const * value) {
|
||||
if (m_option == m_regular_output_channel) {
|
||||
ctx.set_regular_stream(value);
|
||||
}
|
||||
else if (m_option == m_diagnostic_output_channel) {
|
||||
ctx.set_diagnostic_stream(value);
|
||||
}
|
||||
else if (is_builtin_option(m_option)) {
|
||||
throw cmd_exception("option value is not a string");
|
||||
}
|
||||
else {
|
||||
set_param(ctx, value);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void execute(cmd_context & ctx) {
|
||||
if (m_unsupported)
|
||||
ctx.print_unsupported(m_option);
|
||||
else
|
||||
ctx.print_success();
|
||||
}
|
||||
};
|
||||
|
||||
class get_option_cmd : public set_get_option_cmd {
|
||||
static void print_bool(cmd_context & ctx, bool b) {
|
||||
ctx.regular_stream() << (b ? "true" : "false") << std::endl;
|
||||
}
|
||||
|
||||
static void print_unsigned(cmd_context & ctx, unsigned v) {
|
||||
ctx.regular_stream() << v << std::endl;
|
||||
}
|
||||
|
||||
static void print_string(cmd_context & ctx, char const * str) {
|
||||
ctx.regular_stream() << str << std::endl;
|
||||
}
|
||||
|
||||
public:
|
||||
get_option_cmd(front_end_params & params):
|
||||
set_get_option_cmd("get-option", params) {
|
||||
}
|
||||
virtual char const * get_usage() const { return "<keyword>"; }
|
||||
virtual char const * get_descr(cmd_context & ctx) const { return "get configuration option."; }
|
||||
virtual unsigned get_arity() const { return 1; }
|
||||
virtual cmd_arg_kind next_arg_kind(cmd_context & ctx) const { return CPK_KEYWORD; }
|
||||
virtual void set_next_arg(cmd_context & ctx, symbol const & opt) {
|
||||
if (opt == m_print_success) {
|
||||
print_bool(ctx, ctx.print_success_enabled());
|
||||
}
|
||||
// TODO:
|
||||
// else if (opt == m_print_warning) {
|
||||
// print_bool(ctx, );
|
||||
// }
|
||||
else if (opt == m_expand_definitions) {
|
||||
ctx.print_unsupported(m_expand_definitions);
|
||||
}
|
||||
else if (opt == m_interactive_mode) {
|
||||
print_bool(ctx, ctx.interactive_mode());
|
||||
}
|
||||
else if (opt == m_produce_proofs) {
|
||||
print_bool(ctx, ctx.params().m_proof_mode != PGM_DISABLED);
|
||||
}
|
||||
else if (opt == m_produce_unsat_cores) {
|
||||
print_bool(ctx, ctx.produce_unsat_cores());
|
||||
}
|
||||
else if (opt == m_produce_models) {
|
||||
print_bool(ctx, ctx.params().m_model);
|
||||
}
|
||||
else if (opt == m_produce_assignments) {
|
||||
print_bool(ctx, ctx.produce_assignments());
|
||||
}
|
||||
else if (opt == m_global_decls) {
|
||||
print_bool(ctx, ctx.global_decls());
|
||||
}
|
||||
else if (opt == m_random_seed) {
|
||||
print_unsigned(ctx, ctx.random_seed());
|
||||
}
|
||||
else if (opt == m_verbosity) {
|
||||
print_unsigned(ctx, get_verbosity_level());
|
||||
}
|
||||
else if (opt == m_regular_output_channel) {
|
||||
print_string(ctx, ctx.get_regular_stream_name());
|
||||
}
|
||||
else if (opt == m_diagnostic_output_channel) {
|
||||
print_string(ctx, ctx.get_diagnostic_stream_name());
|
||||
}
|
||||
else if (opt == m_error_behavior) {
|
||||
if (ctx.exit_on_error()) {
|
||||
print_string(ctx, "immediate-exit");
|
||||
}
|
||||
else {
|
||||
print_string(ctx, "continued-execution");
|
||||
}
|
||||
}
|
||||
else if (opt == m_int_real_coercions) {
|
||||
print_bool(ctx, ctx.m().int_real_coercions());
|
||||
}
|
||||
else {
|
||||
std::string iopt = smt_keyword2opt_name(opt);
|
||||
std::string r;
|
||||
if (m_ini.get_param_value(iopt.c_str(), r)) {
|
||||
ctx.regular_stream() << r << std::endl;
|
||||
}
|
||||
else {
|
||||
ctx.print_unsupported(opt);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class get_info_cmd : public cmd {
|
||||
symbol m_error_behavior;
|
||||
symbol m_name;
|
||||
symbol m_authors;
|
||||
symbol m_version;
|
||||
symbol m_status;
|
||||
symbol m_reason_unknown;
|
||||
symbol m_all_statistics;
|
||||
public:
|
||||
get_info_cmd():
|
||||
cmd("get-info"),
|
||||
m_error_behavior(":error-behavior"),
|
||||
m_name(":name"),
|
||||
m_authors(":authors"),
|
||||
m_version(":version"),
|
||||
m_status(":status"),
|
||||
m_reason_unknown(":reason-unknown"),
|
||||
m_all_statistics(":all-statistics") {
|
||||
}
|
||||
virtual char const * get_usage() const { return "<keyword>"; }
|
||||
virtual char const * get_descr(cmd_context & ctx) const { return "get information."; }
|
||||
virtual unsigned get_arity() const { return 1; }
|
||||
virtual cmd_arg_kind next_arg_kind(cmd_context & ctx) const { return CPK_KEYWORD; }
|
||||
virtual void set_next_arg(cmd_context & ctx, symbol const & opt) {
|
||||
if (opt == m_error_behavior) {
|
||||
if (ctx.exit_on_error())
|
||||
ctx.regular_stream() << "(:error-behavior immediate-exit)" << std::endl;
|
||||
else
|
||||
ctx.regular_stream() << "(:error-behavior continued-execution)" << std::endl;
|
||||
}
|
||||
else if (opt == m_name) {
|
||||
ctx.regular_stream() << "(:name \"Z3\")" << std::endl;
|
||||
}
|
||||
else if (opt == m_authors) {
|
||||
ctx.regular_stream() << "(:authors \"Leonardo de Moura and Nikolaj Bjorner\")" << std::endl;
|
||||
}
|
||||
else if (opt == m_version) {
|
||||
ctx.regular_stream() << "(:version \"" << Z3_MAJOR_VERSION << "." << Z3_MINOR_VERSION << "\")" << std::endl;
|
||||
}
|
||||
else if (opt == m_status) {
|
||||
ctx.regular_stream() << "(:status " << ctx.get_status() << ")" << std::endl;
|
||||
}
|
||||
else if (opt == m_reason_unknown) {
|
||||
ctx.regular_stream() << "(:reason-unknown " << ctx.reason_unknown() << ")" << std::endl;
|
||||
}
|
||||
else if (opt == m_all_statistics) {
|
||||
ctx.display_statistics();
|
||||
}
|
||||
else {
|
||||
ctx.print_unsupported(opt);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class set_info_cmd : public cmd {
|
||||
symbol m_info;
|
||||
symbol m_status;
|
||||
symbol m_unsat;
|
||||
symbol m_sat;
|
||||
symbol m_unknown;
|
||||
public:
|
||||
set_info_cmd():
|
||||
cmd("set-info"),
|
||||
m_status(":status"),
|
||||
m_unsat("unsat"),
|
||||
m_sat("sat"),
|
||||
m_unknown("unknown") {
|
||||
}
|
||||
virtual char const * get_usage() const { return "<keyword> <value>"; }
|
||||
virtual char const * get_descr(cmd_context & ctx) const { return "set information."; }
|
||||
virtual unsigned get_arity() const { return 2; }
|
||||
virtual void prepare(cmd_context & ctx) { m_info = symbol::null; }
|
||||
virtual cmd_arg_kind next_arg_kind(cmd_context & ctx) const {
|
||||
return m_info == symbol::null ? CPK_KEYWORD : CPK_OPTION_VALUE;
|
||||
}
|
||||
virtual void set_next_arg(cmd_context & ctx, rational const & val) {}
|
||||
virtual void set_next_arg(cmd_context & ctx, char const * val) {}
|
||||
virtual void set_next_arg(cmd_context & ctx, symbol const & s) {
|
||||
if (m_info == symbol::null) {
|
||||
m_info = s;
|
||||
}
|
||||
else {
|
||||
if (m_info == m_status) {
|
||||
if (s == m_unsat) {
|
||||
ctx.set_status(cmd_context::UNSAT);
|
||||
}
|
||||
else if (s == m_sat) {
|
||||
ctx.set_status(cmd_context::SAT);
|
||||
}
|
||||
else if (s == m_unknown) {
|
||||
ctx.set_status(cmd_context::UNKNOWN);
|
||||
}
|
||||
else {
|
||||
throw cmd_exception("invalid ':status' attribute");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void execute(cmd_context & ctx) {
|
||||
ctx.print_success();
|
||||
}
|
||||
};
|
||||
|
||||
class declare_map_cmd : public cmd {
|
||||
symbol m_array_sort;
|
||||
symbol m_name;
|
||||
ptr_vector<sort> m_domain;
|
||||
func_decl * m_f;
|
||||
family_id m_array_fid;
|
||||
public:
|
||||
declare_map_cmd():
|
||||
cmd("declare-map"),
|
||||
m_array_sort("Array"),
|
||||
m_array_fid(null_family_id) {}
|
||||
|
||||
family_id get_array_fid(cmd_context & ctx) {
|
||||
if (m_array_fid == null_family_id) {
|
||||
m_array_fid = ctx.m().get_family_id("array");
|
||||
}
|
||||
return m_array_fid;
|
||||
}
|
||||
virtual char const * get_usage() const { return "<symbol> (<sort>+) <func-decl-ref>"; }
|
||||
virtual char const * get_descr(cmd_context & ctx) const { return "declare a new array map operator with name <symbol> using the given function declaration.\n<func-decl-ref> ::= <symbol>\n | (<symbol> (<sort>*) <sort>)\n | ((_ <symbol> <numeral>+) (<sort>*) <sort>)\nThe last two cases are used to disumbiguate between declarations with the same name and/or select (indexed) builtin declarations.\nFor more details about the the array map operator, see 'Generalized and Efficient Array Decision Procedures' (FMCAD 2009).\nExample: (declare-map set-union (Int) (or (Bool Bool) Bool))\nDeclares a new function (declare-fun set-union ((Array Int Bool) (Array Int Bool)) (Array Int Bool)).\nThe instance of the map axiom for this new declaration is:\n(forall ((a1 (Array Int Bool)) (a2 (Array Int Bool)) (i Int)) (= (select (set-union a1 a2) i) (or (select a1 i) (select a2 i))))"; }
|
||||
virtual unsigned get_arity() const { return 3; }
|
||||
virtual void prepare(cmd_context & ctx) { m_name = symbol::null; m_domain.reset(); }
|
||||
virtual cmd_arg_kind next_arg_kind(cmd_context & ctx) const {
|
||||
if (m_name == symbol::null) return CPK_SYMBOL;
|
||||
if (m_domain.empty()) return CPK_SORT_LIST;
|
||||
return CPK_FUNC_DECL;
|
||||
}
|
||||
virtual void set_next_arg(cmd_context & ctx, symbol const & s) { m_name = s; }
|
||||
virtual void set_next_arg(cmd_context & ctx, unsigned num, sort * const * slist) {
|
||||
if (num == 0)
|
||||
throw cmd_exception("invalid map declaration, empty sort list");
|
||||
m_domain.append(num, slist);
|
||||
}
|
||||
virtual void set_next_arg(cmd_context & ctx, func_decl * f) {
|
||||
m_f = f;
|
||||
if (m_f->get_arity() == 0)
|
||||
throw cmd_exception("invalid map declaration, function declaration must have arity > 0");
|
||||
}
|
||||
virtual void reset(cmd_context & ctx) {
|
||||
m_array_fid = null_family_id;
|
||||
}
|
||||
virtual void execute(cmd_context & ctx) {
|
||||
psort_decl * array_sort = ctx.find_psort_decl(m_array_sort);
|
||||
if (array_sort == 0)
|
||||
throw cmd_exception("Array sort is not available");
|
||||
ptr_vector<sort> & array_sort_args = m_domain;
|
||||
sort_ref_buffer domain(ctx.m());
|
||||
unsigned arity = m_f->get_arity();
|
||||
for (unsigned i = 0; i < arity; i++) {
|
||||
array_sort_args.push_back(m_f->get_domain(i));
|
||||
domain.push_back(array_sort->instantiate(ctx.pm(), array_sort_args.size(), array_sort_args.c_ptr()));
|
||||
array_sort_args.pop_back();
|
||||
}
|
||||
sort_ref range(ctx.m());
|
||||
array_sort_args.push_back(m_f->get_range());
|
||||
range = array_sort->instantiate(ctx.pm(), array_sort_args.size(), array_sort_args.c_ptr());
|
||||
parameter p[1] = { parameter(m_f) };
|
||||
func_decl_ref new_map(ctx.m());
|
||||
new_map = ctx.m().mk_func_decl(get_array_fid(ctx), OP_ARRAY_MAP, 1, p, domain.size(), domain.c_ptr(), range.get());
|
||||
if (new_map == 0)
|
||||
throw cmd_exception("invalid array map operator");
|
||||
ctx.insert(m_name, new_map);
|
||||
}
|
||||
};
|
||||
|
||||
// provides "help" for builtin cmds
|
||||
class builtin_cmd : public cmd {
|
||||
char const * m_usage;
|
||||
char const * m_descr;
|
||||
public:
|
||||
builtin_cmd(char const * name, char const * usage, char const * descr):
|
||||
cmd(name), m_usage(usage), m_descr(descr) {}
|
||||
virtual char const * get_usage() const { return m_usage; }
|
||||
virtual char const * get_descr(cmd_context & ctx) const { return m_descr; }
|
||||
};
|
||||
|
||||
|
||||
void install_basic_cmds(cmd_context & ctx) {
|
||||
ctx.insert(alloc(set_logic_cmd));
|
||||
ctx.insert(alloc(exit_cmd));
|
||||
ctx.insert(alloc(get_assignment_cmd));
|
||||
ctx.insert(alloc(get_assertions_cmd));
|
||||
ctx.insert(alloc(get_proof_cmd));
|
||||
ctx.insert(alloc(get_unsat_core_cmd));
|
||||
ctx.insert(alloc(set_option_cmd, ctx.params()));
|
||||
ctx.insert(alloc(get_option_cmd, ctx.params()));
|
||||
ctx.insert(alloc(get_info_cmd));
|
||||
ctx.insert(alloc(set_info_cmd));
|
||||
ctx.insert(alloc(builtin_cmd, "assert", "<term>", "assert term."));
|
||||
ctx.insert(alloc(builtin_cmd, "check-sat", "<boolean-constants>*", "check if the current context is satisfiable. If a list of boolean constants B is provided, then check if the current context is consistent with assigning every constant in B to true."));
|
||||
ctx.insert(alloc(builtin_cmd, "push", "<number>?", "push 1 (or <number>) scopes."));
|
||||
ctx.insert(alloc(builtin_cmd, "pop", "<number>?", "pop 1 (or <number>) scopes."));
|
||||
ctx.insert(alloc(builtin_cmd, "get-value", "(<term>+)", "evaluate the given terms in the current model."));
|
||||
ctx.insert(alloc(builtin_cmd, "declare-sort", "<symbol> <numeral>?", "declare a new uninterpreted sort of arity <numeral>, if arity is not provided, then it is assumed to be 0."));
|
||||
ctx.insert(alloc(builtin_cmd, "define-sort", "<symbol> (<symbol>*) <sort>", "define a new sort."));
|
||||
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)))))"));
|
||||
}
|
||||
|
||||
void install_ext_basic_cmds(cmd_context & ctx) {
|
||||
ctx.insert(alloc(help_cmd));
|
||||
ctx.insert(alloc(pp_cmd));
|
||||
ctx.insert(alloc(get_model_cmd));
|
||||
ctx.insert(alloc(echo_cmd));
|
||||
ctx.insert(alloc(labels_cmd));
|
||||
ctx.insert(alloc(declare_map_cmd));
|
||||
ctx.insert(alloc(builtin_cmd, "reset", 0, "reset the shell (all declarations and assertions will be erased)"));
|
||||
install_simplify_cmd(ctx);
|
||||
install_eval_cmd(ctx);
|
||||
install_qe_cmd(ctx);
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
basic_cmds.h
|
||||
|
||||
Abstract:
|
||||
Basic commands for SMT2 front end.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-03-30
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _BASIC_CMDS_H_
|
||||
#define _BASIC_CMDS_H_
|
||||
|
||||
class cmd_context;
|
||||
|
||||
void install_basic_cmds(cmd_context & ctx);
|
||||
void install_ext_basic_cmds(cmd_context & ctx);
|
||||
|
||||
#endif
|
|
@ -1,41 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
bit_blaster_params.h
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-10-02.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _BIT_BLASTER_PARAMS_H_
|
||||
#define _BIT_BLASTER_PARAMS_H_
|
||||
|
||||
#include"ini_file.h"
|
||||
|
||||
struct bit_blaster_params {
|
||||
bool m_bb_eager;
|
||||
bool m_bb_ext_gates;
|
||||
bool m_bb_quantifiers;
|
||||
bit_blaster_params():
|
||||
m_bb_eager(false),
|
||||
m_bb_ext_gates(false),
|
||||
m_bb_quantifiers(false) {
|
||||
}
|
||||
void register_params(ini_params & p) {
|
||||
p.register_bool_param("BB_EAGER", m_bb_eager, "eager bit blasting");
|
||||
p.register_bool_param("BB_EXT_GATES", m_bb_ext_gates, "use extended gates during bit-blasting");
|
||||
p.register_bool_param("BB_QUANTIFIERS", m_bb_quantifiers, "convert bit-vectors to Booleans in quantifiers");
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _BIT_BLASTER_PARAMS_H_ */
|
||||
|
|
@ -1,495 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
check_logic.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Check whether a given assertion is in the correct logic or not
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2011-08-11.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"check_logic.h"
|
||||
#include"arith_decl_plugin.h"
|
||||
#include"array_decl_plugin.h"
|
||||
#include"bv_decl_plugin.h"
|
||||
#include"ast_pp.h"
|
||||
|
||||
struct check_logic::imp {
|
||||
ast_manager & m;
|
||||
symbol m_logic;
|
||||
arith_util m_a_util;
|
||||
bv_util m_bv_util;
|
||||
array_util m_ar_util;
|
||||
bool m_uf; // true if the logic supports uninterpreted functions
|
||||
bool m_arrays; // true if the logic supports arbitrary arrays
|
||||
bool m_bv_arrays; // true if the logic supports only bv arrays
|
||||
bool m_reals; // true if the logic supports reals
|
||||
bool m_ints; // true if the logic supports integers
|
||||
bool m_diff; // true if the logic supports difference logic only
|
||||
bool m_nonlinear; // true if the logic supports nonlinear arithmetic
|
||||
bool m_bvs; // true if the logic supports bit-vectors
|
||||
bool m_quantifiers; // true if the logic supports quantifiers
|
||||
bool m_unknown_logic;
|
||||
|
||||
imp(ast_manager & _m):m(_m), m_a_util(m), m_bv_util(m), m_ar_util(m) {
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
m_uf = false;
|
||||
m_arrays = false;
|
||||
m_bv_arrays = false;
|
||||
m_reals = false;
|
||||
m_ints = false;
|
||||
m_diff = false;
|
||||
m_nonlinear = false;
|
||||
m_bvs = false;
|
||||
m_quantifiers = false;
|
||||
m_unknown_logic = true;
|
||||
}
|
||||
|
||||
void set_logic(symbol const & logic) {
|
||||
reset();
|
||||
m_unknown_logic = false;
|
||||
if (logic == "AUFLIA") {
|
||||
m_uf = true;
|
||||
m_arrays = true;
|
||||
m_ints = true;
|
||||
m_quantifiers = true;
|
||||
}
|
||||
else if (logic == "AUFLIRA") {
|
||||
m_uf = true;
|
||||
m_arrays = true;
|
||||
m_reals = true;
|
||||
m_ints = true;
|
||||
m_quantifiers = true;
|
||||
}
|
||||
else if (logic == "AUFNIRA") {
|
||||
m_uf = true;
|
||||
m_arrays = true;
|
||||
m_reals = true;
|
||||
m_ints = true;
|
||||
m_nonlinear = true;
|
||||
m_quantifiers = true;
|
||||
}
|
||||
else if (logic == "LRA") {
|
||||
m_reals = true;
|
||||
m_quantifiers = true;
|
||||
}
|
||||
else if (logic == "QF_ABV") {
|
||||
m_bv_arrays = true;
|
||||
m_bvs = true;
|
||||
}
|
||||
else if (logic == "QF_AUFBV") {
|
||||
m_uf = true;
|
||||
m_bv_arrays = true;
|
||||
m_bvs = true;
|
||||
}
|
||||
else if (logic == "QF_UFBV") {
|
||||
m_uf = true;
|
||||
m_bvs = true;
|
||||
}
|
||||
else if (logic == "QF_AUFLIA") {
|
||||
m_uf = true;
|
||||
m_arrays = true;
|
||||
m_ints = true;
|
||||
}
|
||||
else if (logic == "QF_AX") {
|
||||
m_arrays = true;
|
||||
}
|
||||
else if (logic == "QF_BV") {
|
||||
m_bvs = true;
|
||||
}
|
||||
else if (logic == "QF_IDL") {
|
||||
m_ints = true;
|
||||
m_diff = true;
|
||||
}
|
||||
else if (logic == "QF_RDL") {
|
||||
m_reals = true;
|
||||
m_diff = true;
|
||||
}
|
||||
else if (logic == "QF_LIA") {
|
||||
m_ints = true;
|
||||
}
|
||||
else if (logic == "QF_LRA") {
|
||||
m_reals = true;
|
||||
}
|
||||
else if (logic == "QF_NIA") {
|
||||
m_ints = true;
|
||||
m_nonlinear = true;
|
||||
}
|
||||
else if (logic == "QF_NRA") {
|
||||
m_reals = true;
|
||||
m_nonlinear = true;
|
||||
}
|
||||
else if (logic == "QF_UF") {
|
||||
m_uf = true;
|
||||
}
|
||||
else if (logic == "QF_UFIDL") {
|
||||
m_uf = true;
|
||||
m_ints = true;
|
||||
m_diff = true;
|
||||
}
|
||||
else if (logic == "QF_UFLIA") {
|
||||
m_uf = true;
|
||||
m_ints = true;
|
||||
}
|
||||
else if (logic == "QF_UFLRA") {
|
||||
m_uf = true;
|
||||
m_reals = true;
|
||||
}
|
||||
else if (logic == "QF_UFNRA") {
|
||||
m_uf = true;
|
||||
m_reals = true;
|
||||
m_nonlinear = true;
|
||||
}
|
||||
else if (logic == "UFLRA") {
|
||||
m_uf = true;
|
||||
m_reals = true;
|
||||
m_quantifiers = true;
|
||||
}
|
||||
else if (logic == "UFNIA") {
|
||||
m_uf = true;
|
||||
m_ints = true;
|
||||
m_quantifiers = true;
|
||||
m_nonlinear = true;
|
||||
}
|
||||
else if (logic == "UFBV") {
|
||||
m_uf = true;
|
||||
m_bvs = true;
|
||||
m_quantifiers = true;
|
||||
}
|
||||
else {
|
||||
m_unknown_logic = true;
|
||||
}
|
||||
|
||||
m_logic = logic;
|
||||
}
|
||||
|
||||
struct failed {};
|
||||
std::string m_last_error;
|
||||
|
||||
void fail(char const * msg) {
|
||||
m_last_error = msg;
|
||||
throw failed();
|
||||
}
|
||||
|
||||
void check_sort(sort * s) {
|
||||
if (s->get_family_id() == null_family_id) {
|
||||
if (!m_uf)
|
||||
fail("logic does not support uninterpreted sorts");
|
||||
}
|
||||
else if (m.is_bool(s)) {
|
||||
return;
|
||||
}
|
||||
else if (m_a_util.is_int(s)) {
|
||||
if (!m_ints)
|
||||
fail("logic does not support integers");
|
||||
}
|
||||
else if (m_a_util.is_real(s)) {
|
||||
if (!m_reals)
|
||||
fail("logic does not support reals");
|
||||
}
|
||||
else if (m_bv_util.is_bv_sort(s)) {
|
||||
if (!m_bvs)
|
||||
fail("logic does not support bitvectors");
|
||||
}
|
||||
else if (m_ar_util.is_array(s)) {
|
||||
if (m_arrays) {
|
||||
return;
|
||||
}
|
||||
else if (m_bv_arrays) {
|
||||
if (get_array_arity(s) != 1)
|
||||
fail("logic supports only unidimensional arrays");
|
||||
if (!m_bv_util.is_bv_sort(get_array_range(s)) || !m_bv_util.is_bv_sort(get_array_domain(s, 0)))
|
||||
fail("logic supports only arrays from bitvectors to bitvectors");
|
||||
}
|
||||
else {
|
||||
fail("logic does not support arrays");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(var * n) {
|
||||
if (!m_quantifiers)
|
||||
fail("logic does not support quantifiers");
|
||||
check_sort(m.get_sort(n));
|
||||
}
|
||||
|
||||
bool is_int(expr * t) {
|
||||
if (m_a_util.is_uminus(t))
|
||||
t = to_app(t)->get_arg(0);
|
||||
return m_a_util.is_numeral(t);
|
||||
}
|
||||
|
||||
bool is_numeral(expr * t) {
|
||||
if (m_a_util.is_uminus(t))
|
||||
t = to_app(t)->get_arg(0);
|
||||
// c
|
||||
if (is_int(t))
|
||||
return true;
|
||||
// c1/c2
|
||||
if (m_a_util.is_div(t) && is_int(to_app(t)->get_arg(0)) && is_int(to_app(t)->get_arg(1)))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if n has at most one argument that is not numeral.
|
||||
void check_mul(app * n) {
|
||||
if (m_nonlinear)
|
||||
return; // nothing to check
|
||||
unsigned num_args = n->get_num_args();
|
||||
bool found_non_numeral = false;
|
||||
for (unsigned i = 0; i < num_args; i++) {
|
||||
if (!is_numeral(n->get_arg(i))) {
|
||||
if (found_non_numeral)
|
||||
fail("logic does not support nonlinear arithmetic");
|
||||
else
|
||||
found_non_numeral = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check if the divisor is a numeral
|
||||
void check_div(app * n) {
|
||||
SASSERT(n->get_num_args() == 2);
|
||||
if (!m_nonlinear && !is_numeral(n->get_arg(1)))
|
||||
fail("logic does not support nonlinear arithmetic");
|
||||
}
|
||||
|
||||
bool is_diff_var(expr * t) const {
|
||||
if (is_app(t) && to_app(t)->get_decl()->get_family_id() == null_family_id)
|
||||
return true;
|
||||
if (m.is_ite(t))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void fail_non_diff(expr * t) {
|
||||
TRACE("check_logic", tout << mk_pp(t, m) << "\n";);
|
||||
fail("logic only supports difference arithmetic");
|
||||
}
|
||||
|
||||
bool same_args(app * t) {
|
||||
unsigned num_args = t->get_num_args();
|
||||
if (num_args == 0)
|
||||
return false;
|
||||
expr * arg = t->get_arg(0);
|
||||
for (unsigned i = 1; i < num_args; i++) {
|
||||
if (t->get_arg(i) != arg)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_arith(expr * t) const {
|
||||
return m.get_sort(t)->get_family_id() == m_a_util.get_family_id();
|
||||
}
|
||||
|
||||
bool is_offset(app * t) {
|
||||
while (true) {
|
||||
expr * non_numeral = 0;
|
||||
unsigned num_args = t->get_num_args();
|
||||
for (unsigned i = 0; i < num_args; i++) {
|
||||
expr * arg = t->get_arg(i);
|
||||
if (is_numeral(arg))
|
||||
continue;
|
||||
if (non_numeral != 0)
|
||||
return false;
|
||||
non_numeral = arg;
|
||||
}
|
||||
if (is_diff_var(non_numeral))
|
||||
return true;
|
||||
if (!m_a_util.is_add(non_numeral) && !m_a_util.is_sub(non_numeral))
|
||||
return false;
|
||||
t = to_app(non_numeral);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_diff_arg(expr * t) {
|
||||
if (is_diff_var(t))
|
||||
return true;
|
||||
if (is_numeral(t))
|
||||
return true;
|
||||
if (m_a_util.is_add(t) || m_a_util.is_sub(t))
|
||||
return is_offset(to_app(t));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if n is a diff logic predicate
|
||||
void check_diff_predicate(app * n) {
|
||||
expr * lhs = n->get_arg(0);
|
||||
expr * rhs = n->get_arg(1);
|
||||
if (!is_arith(lhs))
|
||||
return; // formula is not in arithmetic
|
||||
if (is_diff_arg(lhs) && is_diff_arg(rhs))
|
||||
return;
|
||||
if (is_numeral(lhs))
|
||||
std::swap(lhs, rhs);
|
||||
if (!is_numeral(rhs))
|
||||
fail_non_diff(n);
|
||||
if (!m_a_util.is_sub(lhs) || to_app(lhs)->get_num_args() != 2)
|
||||
fail_non_diff(n);
|
||||
expr * t1 = to_app(lhs)->get_arg(0);
|
||||
expr * t2 = to_app(lhs)->get_arg(1);
|
||||
if (is_diff_var(t1) && is_diff_var(t2))
|
||||
return;
|
||||
if (m_a_util.is_add(t1) && m_a_util.is_add(t2)) {
|
||||
// QF_RDL supports (<= (- (+ x ... x) (+ y ... y)) c)
|
||||
if (to_app(t1)->get_num_args() != to_app(t2)->get_num_args())
|
||||
fail_non_diff(n);
|
||||
if (!same_args(to_app(t1)) || !same_args(to_app(t2)))
|
||||
fail_non_diff(n);
|
||||
return;
|
||||
}
|
||||
fail_non_diff(n);
|
||||
}
|
||||
|
||||
void check_diff_arg(expr * t) {
|
||||
if (!is_diff_arg(t))
|
||||
fail_non_diff(t);
|
||||
}
|
||||
|
||||
// Check if the arith args of n are of the form (t + k) where k is a numeral.
|
||||
void check_diff_args(app * n) {
|
||||
unsigned num_args = n->get_num_args();
|
||||
for (unsigned i = 0; i < num_args; i++) {
|
||||
if (is_arith(n))
|
||||
check_diff_arg(n);
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(app * n) {
|
||||
sort * s = m.get_sort(n);
|
||||
check_sort(s);
|
||||
func_decl * f = n->get_decl();
|
||||
family_id fid = f->get_family_id();
|
||||
if (fid == null_family_id) {
|
||||
if (!m_uf && f->get_arity() > 0)
|
||||
fail("logic does not support uninterpreted functions");
|
||||
if (m_diff)
|
||||
check_diff_args(n);
|
||||
}
|
||||
else if (fid == m_a_util.get_family_id()) {
|
||||
if (m_a_util.is_mul(n))
|
||||
check_mul(n);
|
||||
else if (m_a_util.is_div(n) || m_a_util.is_idiv(n) || m_a_util.is_rem(n) || m_a_util.is_mod(n))
|
||||
check_div(n);
|
||||
if (m_diff) {
|
||||
if (m_a_util.is_le(n) || m_a_util.is_lt(n) || m_a_util.is_ge(n) || m_a_util.is_gt(n))
|
||||
check_diff_predicate(n);
|
||||
}
|
||||
if (!m_ints || !m_reals) {
|
||||
if (m_a_util.is_to_real(n) || m_a_util.is_to_int(n))
|
||||
fail("logic does not support casting operators");
|
||||
}
|
||||
}
|
||||
else if (fid == m_bv_util.get_family_id()) {
|
||||
// nothing to check...
|
||||
}
|
||||
else if (fid == m_ar_util.get_family_id()) {
|
||||
// nothing to check...
|
||||
if (m_diff)
|
||||
check_diff_args(n);
|
||||
}
|
||||
else if (fid == m.get_basic_family_id()) {
|
||||
// nothing to check...
|
||||
if (m_diff) {
|
||||
if (m.is_eq(n))
|
||||
check_diff_predicate(n);
|
||||
else if (m.is_distinct(n) || m.is_ite(n))
|
||||
check_diff_args(n);
|
||||
}
|
||||
}
|
||||
else if (m.is_builtin_family_id(fid)) {
|
||||
// nothing to check
|
||||
}
|
||||
else {
|
||||
fail("logic does not support theory");
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(quantifier * n) {
|
||||
if (!m_quantifiers)
|
||||
fail("logic does not support quantifiers");
|
||||
}
|
||||
|
||||
bool operator()(expr * n) {
|
||||
if (m_unknown_logic)
|
||||
return true;
|
||||
try {
|
||||
quick_for_each_expr(*this, n);
|
||||
return true;
|
||||
}
|
||||
catch (failed) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator()(func_decl * f) {
|
||||
if (m_unknown_logic)
|
||||
return true;
|
||||
try {
|
||||
unsigned arity = f->get_arity();
|
||||
if (arity > 0) {
|
||||
if (!m_uf)
|
||||
fail("logic does not support uninterpreted functions");
|
||||
for (unsigned i = 0; i < arity; i++)
|
||||
check_sort(f->get_domain(i));
|
||||
}
|
||||
check_sort(f->get_range());
|
||||
return true;
|
||||
}
|
||||
catch (failed) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
check_logic::check_logic() {
|
||||
m_imp = 0;
|
||||
}
|
||||
|
||||
check_logic::~check_logic() {
|
||||
if (m_imp)
|
||||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
void check_logic::reset() {
|
||||
if (m_imp)
|
||||
dealloc(m_imp);
|
||||
m_imp = 0;
|
||||
}
|
||||
|
||||
void check_logic::set_logic(ast_manager & m, symbol const & logic) {
|
||||
reset();
|
||||
m_imp = alloc(imp, m);
|
||||
m_imp->set_logic(logic);
|
||||
}
|
||||
|
||||
bool check_logic::operator()(expr * n) {
|
||||
if (m_imp)
|
||||
return m_imp->operator()(n);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool check_logic::operator()(func_decl * f) {
|
||||
if (m_imp)
|
||||
return m_imp->operator()(f);
|
||||
return true;
|
||||
}
|
||||
|
||||
char const * check_logic::get_last_error() const {
|
||||
if (m_imp)
|
||||
return m_imp->m_last_error.c_str();
|
||||
return "";
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
check_logic.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Check whether a given assertion is in the correct logic or not
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2011-08-11.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _CHECK_LOGIC_H_
|
||||
#define _CHECK_LOGIC_H_
|
||||
|
||||
#include"assertion_set.h"
|
||||
|
||||
class check_logic {
|
||||
struct imp;
|
||||
imp * m_imp;
|
||||
public:
|
||||
check_logic();
|
||||
~check_logic();
|
||||
void reset();
|
||||
void set_logic(ast_manager & m, symbol const & logic);
|
||||
bool operator()(expr * n);
|
||||
bool operator()(func_decl * f);
|
||||
char const * get_last_error() const;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,69 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
check_sat_result.h
|
||||
|
||||
Abstract:
|
||||
Abstract interface for storing the result produced by
|
||||
a check_sat like command
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2012-01-23
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _CHECK_SAT_RESULT_H_
|
||||
#define _CHECK_SAT_RESULT_H_
|
||||
|
||||
#include"model.h"
|
||||
#include"lbool.h"
|
||||
#include"statistics.h"
|
||||
|
||||
class check_sat_result {
|
||||
protected:
|
||||
unsigned m_ref_count;
|
||||
lbool m_status;
|
||||
public:
|
||||
check_sat_result():m_ref_count(0), m_status(l_undef) {}
|
||||
virtual ~check_sat_result() {}
|
||||
void inc_ref() { m_ref_count++; }
|
||||
void dec_ref() { SASSERT(m_ref_count > 0); m_ref_count--; if (m_ref_count == 0) dealloc(this); }
|
||||
void set_status(lbool r) { m_status = r; }
|
||||
lbool status() const { return m_status; }
|
||||
virtual void collect_statistics(statistics & st) const = 0;
|
||||
virtual void get_unsat_core(ptr_vector<expr> & r) = 0;
|
||||
virtual void get_model(model_ref & m) = 0;
|
||||
virtual proof * get_proof() = 0;
|
||||
virtual std::string reason_unknown() const = 0;
|
||||
virtual void get_labels(svector<symbol> & r) = 0;
|
||||
};
|
||||
|
||||
struct simple_check_sat_result : public check_sat_result {
|
||||
statistics m_stats;
|
||||
model_ref m_model;
|
||||
expr_ref_vector m_core;
|
||||
proof_ref m_proof;
|
||||
std::string m_unknown;
|
||||
|
||||
simple_check_sat_result(ast_manager & m):
|
||||
m_core(m),
|
||||
m_proof(m) {
|
||||
}
|
||||
virtual ~simple_check_sat_result() {}
|
||||
virtual void collect_statistics(statistics & st) const { st.copy(m_stats); }
|
||||
virtual void get_unsat_core(ptr_vector<expr> & r) { if (m_status == l_false) r.append(m_core.size(), m_core.c_ptr()); }
|
||||
virtual void get_model(model_ref & m) {
|
||||
if (m_status != l_false) m = m_model; else m = 0;
|
||||
}
|
||||
virtual proof * get_proof() { return m_status == l_false ? m_proof.get() : 0; }
|
||||
virtual std::string reason_unknown() const {
|
||||
return m_unknown;
|
||||
}
|
||||
virtual void get_labels(svector<symbol> & r) {}
|
||||
};
|
||||
|
||||
#endif
|
1601
lib/cmd_context.cpp
1601
lib/cmd_context.cpp
File diff suppressed because it is too large
Load diff
|
@ -1,405 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
cmd_context.h
|
||||
|
||||
Abstract:
|
||||
Ultra-light command context.
|
||||
It provides a generic command pluging infrastructure.
|
||||
A command context also provides names (aka symbols) to Z3 objects.
|
||||
These names are used to reference Z3 objects in commands.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-03-01
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _CMD_CONTEXT_H_
|
||||
#define _CMD_CONTEXT_H_
|
||||
|
||||
#include<sstream>
|
||||
#include"ast.h"
|
||||
#include"pdecl.h"
|
||||
#include"front_end_params.h"
|
||||
#include"dictionary.h"
|
||||
#include"solver.h"
|
||||
#include"datatype_decl_plugin.h"
|
||||
#include"stopwatch.h"
|
||||
#include"cmd_context_types.h"
|
||||
#include"event_handler.h"
|
||||
#include"sexpr.h"
|
||||
#include"tactic_manager.h"
|
||||
#include"check_logic.h"
|
||||
#include"progress_callback.h"
|
||||
#include"scoped_ptr_vector.h"
|
||||
|
||||
class func_decls {
|
||||
func_decl * m_decls;
|
||||
public:
|
||||
func_decls():m_decls(0) {}
|
||||
func_decls(ast_manager & m, func_decl * f);
|
||||
void finalize(ast_manager & m);
|
||||
bool contains(func_decl * f) const;
|
||||
bool insert(ast_manager & m, func_decl * f);
|
||||
void erase(ast_manager & m, func_decl * f);
|
||||
bool more_than_one() const;
|
||||
bool clash(func_decl * f) const;
|
||||
bool empty() const { return m_decls == 0; }
|
||||
func_decl * first() const;
|
||||
func_decl * find(unsigned arity, sort * const * domain, sort * range) const;
|
||||
func_decl * find(ast_manager & m, unsigned num_args, expr * const * args, sort * range) const;
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Generic wrapper.
|
||||
*/
|
||||
class object_ref {
|
||||
unsigned m_ref_count;
|
||||
public:
|
||||
object_ref():m_ref_count(0) {}
|
||||
virtual ~object_ref() {}
|
||||
virtual void finalize(cmd_context & ctx) = 0;
|
||||
void inc_ref(cmd_context & ctx) {
|
||||
m_ref_count++;
|
||||
}
|
||||
void dec_ref(cmd_context & ctx) {
|
||||
SASSERT(m_ref_count > 0);
|
||||
m_ref_count--;
|
||||
if (m_ref_count == 0) {
|
||||
finalize(ctx);
|
||||
dealloc(this);
|
||||
}
|
||||
}
|
||||
virtual char const * kind() const = 0;
|
||||
};
|
||||
|
||||
class ast_object_ref : public object_ref {
|
||||
ast * m_ast;
|
||||
public:
|
||||
ast_object_ref(cmd_context & ctx, ast * a);
|
||||
virtual void finalize(cmd_context & ctx);
|
||||
ast * get_ast() const { return m_ast; }
|
||||
static char const * cls_kind() { return "AST"; }
|
||||
virtual char const * kind() const { return cls_kind(); }
|
||||
};
|
||||
|
||||
class stream_ref {
|
||||
std::string m_default_name;
|
||||
std::ostream & m_default;
|
||||
std::string m_name;
|
||||
std::ostream * m_stream;
|
||||
bool m_owner;
|
||||
public:
|
||||
stream_ref(std::string n, std::ostream & d):m_default_name(n), m_default(d), m_name(n), m_stream(&d), m_owner(false) {}
|
||||
~stream_ref() { reset(); }
|
||||
void set(char const * name);
|
||||
void reset();
|
||||
std::ostream & operator*() { return *m_stream; }
|
||||
char const * name() const { return m_name.c_str(); }
|
||||
};
|
||||
|
||||
struct builtin_decl {
|
||||
family_id m_fid;
|
||||
decl_kind m_decl;
|
||||
builtin_decl * m_next;
|
||||
builtin_decl():m_fid(null_family_id), m_decl(0), m_next(0) {}
|
||||
builtin_decl(family_id fid, decl_kind k, builtin_decl * n = 0):m_fid(fid), m_decl(k), m_next(n) {}
|
||||
};
|
||||
|
||||
class cmd_context : public progress_callback, public tactic_manager {
|
||||
public:
|
||||
enum status {
|
||||
UNSAT, SAT, UNKNOWN
|
||||
};
|
||||
|
||||
enum check_sat_state {
|
||||
css_unsat, css_sat, css_unknown, css_clear
|
||||
};
|
||||
|
||||
typedef std::pair<unsigned, expr*> macro;
|
||||
|
||||
struct scoped_watch {
|
||||
cmd_context & m_ctx;
|
||||
public:
|
||||
scoped_watch(cmd_context & ctx):m_ctx(ctx) { m_ctx.m_watch.reset(); m_ctx.m_watch.start(); }
|
||||
~scoped_watch() { m_ctx.m_watch.stop(); }
|
||||
};
|
||||
|
||||
protected:
|
||||
bool m_main_ctx;
|
||||
front_end_params & m_params;
|
||||
symbol m_logic;
|
||||
bool m_interactive_mode;
|
||||
bool m_global_decls;
|
||||
bool m_print_success;
|
||||
unsigned m_random_seed;
|
||||
bool m_produce_unsat_cores;
|
||||
bool m_produce_assignments;
|
||||
status m_status;
|
||||
bool m_numeral_as_real;
|
||||
bool m_ignore_check; // used by the API to disable check-sat() commands when parsing SMT 2.0 files.
|
||||
bool m_exit_on_error;
|
||||
|
||||
static std::ostringstream g_error_stream;
|
||||
|
||||
ast_manager * m_manager;
|
||||
bool m_own_manager;
|
||||
pdecl_manager * m_pmanager;
|
||||
sexpr_manager * m_sexpr_manager;
|
||||
check_logic m_check_logic;
|
||||
stream_ref m_regular;
|
||||
stream_ref m_diagnostic;
|
||||
dictionary<cmd*> m_cmds;
|
||||
dictionary<builtin_decl> m_builtin_decls;
|
||||
scoped_ptr_vector<builtin_decl> m_extra_builtin_decls; // make sure that dynamically allocated builtin_decls are deleted
|
||||
dictionary<object_ref*> m_object_refs; // anything that can be named.
|
||||
dictionary<sexpr*> m_user_tactic_decls;
|
||||
|
||||
dictionary<func_decls> m_func_decls;
|
||||
obj_map<func_decl, symbol> m_func_decl2alias;
|
||||
dictionary<psort_decl*> m_psort_decls;
|
||||
dictionary<macro> m_macros;
|
||||
// the following fields m_func_decls_stack, m_psort_decls_stack and m_exprs_stack are used when m_global_decls == false
|
||||
typedef std::pair<symbol, func_decl *> sf_pair;
|
||||
svector<sf_pair> m_func_decls_stack;
|
||||
svector<symbol> m_psort_decls_stack;
|
||||
svector<symbol> m_macros_stack;
|
||||
//
|
||||
ptr_vector<pdecl> m_aux_pdecls;
|
||||
ptr_vector<expr> m_assertions;
|
||||
vector<std::string> m_assertion_strings;
|
||||
ptr_vector<expr> m_assumptions; // for unsat-core extraction
|
||||
|
||||
struct scope {
|
||||
unsigned m_func_decls_stack_lim;
|
||||
unsigned m_psort_decls_stack_lim;
|
||||
unsigned m_macros_stack_lim;
|
||||
unsigned m_aux_pdecls_lim;
|
||||
// only m_assertions_lim and m_assumptions_lim are relevant when m_global_decls = true
|
||||
unsigned m_assertions_lim;
|
||||
unsigned m_assumptions_lim;
|
||||
};
|
||||
|
||||
svector<scope> m_scopes;
|
||||
ref<solver> m_solver;
|
||||
ref<check_sat_result> m_check_sat_result;
|
||||
|
||||
stopwatch m_watch;
|
||||
|
||||
class dt_eh : public new_datatype_eh {
|
||||
cmd_context & m_owner;
|
||||
datatype_util m_dt_util;
|
||||
public:
|
||||
dt_eh(cmd_context & owner);
|
||||
virtual ~dt_eh();
|
||||
virtual void operator()(sort * dt);
|
||||
};
|
||||
|
||||
friend class dt_eh;
|
||||
scoped_ptr<dt_eh> m_dt_eh;
|
||||
|
||||
class pp_env;
|
||||
friend class pp_env;
|
||||
|
||||
scoped_ptr<pp_env> m_pp_env;
|
||||
pp_env & get_pp_env() const;
|
||||
|
||||
void register_builtin_sorts(decl_plugin * p);
|
||||
void register_builtin_ops(decl_plugin * p);
|
||||
void register_plugin(symbol const & name, decl_plugin * p, bool install_names);
|
||||
void init_manager_core(bool new_manager);
|
||||
void init_manager();
|
||||
void init_external_manager();
|
||||
void reset_cmds();
|
||||
void finalize_cmds();
|
||||
|
||||
void restore_func_decls(unsigned old_sz);
|
||||
void restore_psort_decls(unsigned old_sz);
|
||||
void restore_macros(unsigned old_sz);
|
||||
void restore_aux_pdecls(unsigned old_sz);
|
||||
void restore_assertions(unsigned old_sz);
|
||||
void restore_assumptions(unsigned old_sz);
|
||||
|
||||
void erase_func_decl_core(symbol const & s, func_decl * f);
|
||||
void erase_psort_decl_core(symbol const & s);
|
||||
void erase_macro_core(symbol const & s);
|
||||
|
||||
bool logic_has_arith_core(symbol const & s) const;
|
||||
bool logic_has_bv_core(symbol const & s) const;
|
||||
bool logic_has_array_core(symbol const & s) const;
|
||||
bool logic_has_seq_core(symbol const & s) const;
|
||||
bool logic_has_arith() const;
|
||||
bool logic_has_bv() const;
|
||||
bool logic_has_seq() const;
|
||||
bool logic_has_array() const;
|
||||
bool logic_has_datatype() const;
|
||||
bool logic_has_floats() const;
|
||||
bool supported_logic(symbol const & s) const;
|
||||
|
||||
void print_unsupported_msg() { regular_stream() << "unsupported" << std::endl; }
|
||||
void print_unsupported_info(symbol const& s) { if (s != symbol::null) diagnostic_stream() << "; " << s << std::endl;}
|
||||
|
||||
public:
|
||||
cmd_context(front_end_params & params, bool main_ctx = true, ast_manager * m = 0, symbol const & l = symbol::null);
|
||||
~cmd_context();
|
||||
bool is_smtlib2_compliant() const { return m_params.m_smtlib2_compliant; }
|
||||
void set_logic(symbol const & s);
|
||||
bool has_logic() const { return m_logic != symbol::null; }
|
||||
symbol const & get_logic() const { return m_logic; }
|
||||
bool is_logic(char const * l_name) const { return has_logic() && strcmp(m_logic.bare_str(), l_name) == 0; }
|
||||
bool numeral_as_real() const { return m_numeral_as_real; }
|
||||
void set_numeral_as_real(bool f) { m_numeral_as_real = f; }
|
||||
void set_interactive_mode(bool flag) { m_interactive_mode = flag; }
|
||||
void set_ignore_check(bool flag) { m_ignore_check = flag; }
|
||||
void set_exit_on_error(bool flag) { m_exit_on_error = flag; }
|
||||
bool exit_on_error() const { return m_exit_on_error; }
|
||||
bool interactive_mode() const { return m_interactive_mode; }
|
||||
void set_print_success(bool flag) { m_print_success = flag; }
|
||||
bool print_success_enabled() const { return m_print_success; }
|
||||
void print_success() { if (print_success_enabled()) regular_stream() << "success" << std::endl; }
|
||||
void print_unsupported(symbol const & s) { print_unsupported_msg(); print_unsupported_info(s); }
|
||||
bool global_decls() const { return m_global_decls; }
|
||||
void set_global_decls(bool flag) { SASSERT(!has_manager()); m_global_decls = flag; }
|
||||
unsigned random_seed() const { return m_random_seed; }
|
||||
void set_random_seed(unsigned s) { m_random_seed = s; }
|
||||
bool produce_models() const { return m_params.m_model; }
|
||||
bool produce_proofs() const { return m_params.m_proof_mode != PGM_DISABLED; }
|
||||
bool produce_unsat_cores() const { return m_produce_unsat_cores; }
|
||||
void set_produce_unsat_cores(bool flag) { m_produce_unsat_cores = 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; }
|
||||
status get_status() const { return m_status; }
|
||||
std::string reason_unknown() const;
|
||||
|
||||
bool has_manager() const { return m_manager != 0; }
|
||||
ast_manager & m() const { if (!m_manager) const_cast<cmd_context*>(this)->init_manager(); return *m_manager; }
|
||||
pdecl_manager & pm() const { if (!m_pmanager) const_cast<cmd_context*>(this)->init_manager(); return *m_pmanager; }
|
||||
sexpr_manager & sm() const { if (!m_sexpr_manager) const_cast<cmd_context*>(this)->m_sexpr_manager = alloc(sexpr_manager); return *m_sexpr_manager; }
|
||||
front_end_params & params() const { return m_params; }
|
||||
|
||||
void set_solver(solver * s);
|
||||
solver * get_solver() const { return m_solver.get(); }
|
||||
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;
|
||||
void validate_model();
|
||||
|
||||
bool is_func_decl(symbol const & s) const;
|
||||
bool is_sort_decl(symbol const& s) const { return m_psort_decls.contains(s); }
|
||||
void insert(cmd * c);
|
||||
void insert(symbol const & s, func_decl * f);
|
||||
void insert(func_decl * f) { insert(f->get_name(), f); }
|
||||
void insert(symbol const & s, psort_decl * p);
|
||||
void insert(psort_decl * p) { insert(p->get_name(), p); }
|
||||
void insert(symbol const & s, unsigned arity, expr * t);
|
||||
void insert(symbol const & s, object_ref *);
|
||||
void insert(tactic_cmd * c) { tactic_manager::insert(c); }
|
||||
void insert(probe_info * p) { tactic_manager::insert(p); }
|
||||
void insert_user_tactic(symbol const & s, sexpr * d);
|
||||
void insert_aux_pdecl(pdecl * p);
|
||||
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;
|
||||
psort_decl * find_psort_decl(symbol const & s) const;
|
||||
macro find_macro(symbol const & s) const;
|
||||
cmd * find_cmd(symbol const & s) const;
|
||||
sexpr * find_user_tactic(symbol const & s) const;
|
||||
object_ref * find_object_ref(symbol const & s) const;
|
||||
void mk_const(symbol const & s, expr_ref & result) const;
|
||||
void mk_app(symbol const & s, unsigned num_args, expr * const * args, unsigned num_indices, parameter const * indices, sort * range,
|
||||
expr_ref & r) const;
|
||||
void erase_cmd(symbol const & s);
|
||||
void erase_func_decl(symbol const & s);
|
||||
void erase_func_decl(symbol const & s, func_decl * f);
|
||||
void erase_func_decl(func_decl * f) { erase_func_decl(f->get_name(), f); }
|
||||
void erase_psort_decl(symbol const & s);
|
||||
void erase_macro(symbol const & s);
|
||||
void erase_object_ref(symbol const & s);
|
||||
void erase_user_tactic(symbol const & s);
|
||||
void reset_func_decls();
|
||||
void reset_psort_decls();
|
||||
void reset_macros();
|
||||
void reset_object_refs();
|
||||
void reset_user_tactics();
|
||||
void set_regular_stream(char const * name) { m_regular.set(name); }
|
||||
void set_diagnostic_stream(char const * name);
|
||||
std::ostream & regular_stream() { return *m_regular; }
|
||||
std::ostream & diagnostic_stream() { return *m_diagnostic; }
|
||||
char const * get_regular_stream_name() const { return m_regular.name(); }
|
||||
char const * get_diagnostic_stream_name() const { return m_diagnostic.name(); }
|
||||
typedef dictionary<cmd*>::iterator cmd_iterator;
|
||||
cmd_iterator begin_cmds() const { return m_cmds.begin(); }
|
||||
cmd_iterator end_cmds() const { return m_cmds.end(); }
|
||||
|
||||
typedef dictionary<sexpr*>::iterator user_tactic_iterator;
|
||||
user_tactic_iterator begin_user_tactics() const { return m_user_tactic_decls.begin(); }
|
||||
user_tactic_iterator end_user_tactics() const { return m_user_tactic_decls.end(); }
|
||||
|
||||
void display_assertions();
|
||||
void display_statistics(bool show_total_time = false, double total_time = 0.0);
|
||||
void reset(bool finalize = false);
|
||||
void assert_expr(expr * t);
|
||||
void assert_expr(symbol const & name, expr * t);
|
||||
void push_assert_string(std::string const & s) { SASSERT(m_interactive_mode); m_assertion_strings.push_back(s); }
|
||||
void push();
|
||||
void push(unsigned n);
|
||||
void pop(unsigned n);
|
||||
void check_sat(unsigned num_assumptions, expr * const * assumptions);
|
||||
// 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
|
||||
void validate_check_sat_result(lbool r);
|
||||
unsigned num_scopes() const { return m_scopes.size(); }
|
||||
|
||||
dictionary<macro> const & get_macros() const { return m_macros; }
|
||||
|
||||
bool is_model_available() const;
|
||||
|
||||
double get_seconds() const { return m_watch.get_seconds(); }
|
||||
|
||||
ptr_vector<expr>::const_iterator begin_assertions() const { return m_assertions.begin(); }
|
||||
ptr_vector<expr>::const_iterator end_assertions() const { return m_assertions.end(); }
|
||||
|
||||
ptr_vector<expr>::const_iterator begin_assumptions() const { return m_assumptions.begin(); }
|
||||
ptr_vector<expr>::const_iterator end_assumptions() const { return m_assumptions.end(); }
|
||||
|
||||
/**
|
||||
\brief Hack: consume assertions if there are no scopes.
|
||||
This method is useful for reducing memory consumption in huge benchmarks were incrementality is not an issue.
|
||||
*/
|
||||
bool consume_assertions() {
|
||||
if (num_scopes() > 0)
|
||||
return false;
|
||||
restore_assertions(0);
|
||||
restore_assumptions(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
format_ns::format * pp(sort * s) const;
|
||||
void pp(func_decl * f, format_ns::format_ref & r) const;
|
||||
void pp(expr * n, unsigned num_vars, char const * var_prefix, format_ns::format_ref & r, sbuffer<symbol> & var_names) const;
|
||||
void pp(expr * n, format_ns::format_ref & r) const;
|
||||
void display(std::ostream & out, sort * s, unsigned indent = 0) const;
|
||||
void display(std::ostream & out, expr * n, unsigned indent, unsigned num_vars, char const * var_prefix, sbuffer<symbol> & var_names) const;
|
||||
void display(std::ostream & out, expr * n, unsigned indent = 0) const;
|
||||
void display(std::ostream & out, func_decl * f, unsigned indent = 0) const;
|
||||
|
||||
// dump assertions in out using the pretty printer.
|
||||
void dump_assertions(std::ostream & out) const;
|
||||
|
||||
// display assertions as a SMT2 benchmark.
|
||||
void display_smt2_benchmark(std::ostream & out, unsigned num, expr * const * assertions, symbol const & logic = symbol::null) const;
|
||||
|
||||
|
||||
virtual void slow_progress_sample();
|
||||
virtual void fast_progress_sample();
|
||||
};
|
||||
|
||||
std::ostream & operator<<(std::ostream & out, cmd_context::status st);
|
||||
|
||||
#endif
|
|
@ -1,38 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
cmd_util.cpp
|
||||
|
||||
Abstract:
|
||||
Macros for definining new SMT2 front-end cmds.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-04-01
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"cmd_context.h"
|
||||
|
||||
ast * get_ast_ref(cmd_context & ctx, symbol const & v) {
|
||||
object_ref * r = ctx.find_object_ref(v);
|
||||
SASSERT(r != 0);
|
||||
if (r->kind() != ast_object_ref::cls_kind())
|
||||
throw cmd_exception("global variable does not reference an AST");
|
||||
return static_cast<ast_object_ref*>(r)->get_ast();
|
||||
}
|
||||
|
||||
expr * get_expr_ref(cmd_context & ctx, symbol const & v) {
|
||||
ast * r = get_ast_ref(ctx, v);
|
||||
if (!is_expr(r))
|
||||
throw cmd_exception("global variable does not reference a term");
|
||||
return to_expr(r);
|
||||
}
|
||||
|
||||
void store_expr_ref(cmd_context & ctx, symbol const & v, expr * t) {
|
||||
ctx.insert(v, alloc(ast_object_ref, ctx, t));
|
||||
}
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
cmd_util.h
|
||||
|
||||
Abstract:
|
||||
Macros for definining new SMT2 front-end cmds.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-04-01
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _CMD_UTIL_H_
|
||||
#define _CMD_UTIL_H_
|
||||
|
||||
#define ATOMIC_CMD(CLS_NAME, NAME, DESCR, ACTION) \
|
||||
class CLS_NAME : public cmd { \
|
||||
public: \
|
||||
CLS_NAME():cmd(NAME) {} \
|
||||
virtual char const * get_usage() const { return 0; } \
|
||||
virtual char const * get_descr(cmd_context & ctx) const { return DESCR; } \
|
||||
virtual unsigned get_arity() const { return 0; } \
|
||||
virtual void execute(cmd_context & ctx) { ACTION } \
|
||||
};
|
||||
|
||||
#define UNARY_CMD(CLS_NAME, NAME, USAGE, DESCR, ARG_KIND, ARG_TYPE, ACTION) \
|
||||
class CLS_NAME : public cmd { \
|
||||
public: \
|
||||
CLS_NAME():cmd(NAME) {} \
|
||||
virtual char const * get_usage() const { return USAGE; } \
|
||||
virtual char const * get_descr(cmd_context & ctx) const { return DESCR; } \
|
||||
virtual unsigned get_arity() const { return 1; } \
|
||||
virtual cmd_arg_kind next_arg_kind(cmd_context & ctx) const { return ARG_KIND; } \
|
||||
virtual void set_next_arg(cmd_context & ctx, ARG_TYPE arg) { ACTION } \
|
||||
}
|
||||
|
||||
// Macro for creating commands where the first argument is a symbol
|
||||
// The second argument cannot be a symbol
|
||||
#define BINARY_SYM_CMD(CLS_NAME, NAME, USAGE, DESCR, ARG_KIND, ARG_TYPE, ACTION) \
|
||||
class CLS_NAME : public cmd { \
|
||||
symbol m_sym; \
|
||||
public: \
|
||||
CLS_NAME():cmd(NAME) {} \
|
||||
virtual char const * get_usage() const { return USAGE; } \
|
||||
virtual char const * get_descr(cmd_context & ctx) const { return DESCR; } \
|
||||
virtual unsigned get_arity() const { return 2; } \
|
||||
virtual void prepare(cmd_context & ctx) { m_sym = symbol::null; } \
|
||||
virtual cmd_arg_kind next_arg_kind(cmd_context & ctx) const { \
|
||||
return m_sym == symbol::null ? CPK_SYMBOL : ARG_KIND; \
|
||||
} \
|
||||
virtual void set_next_arg(cmd_context & ctx, symbol const & s) { m_sym = s; } \
|
||||
virtual void set_next_arg(cmd_context & ctx, ARG_TYPE arg) { ACTION } \
|
||||
};
|
||||
|
||||
|
||||
class ast;
|
||||
class expr;
|
||||
class symbol;
|
||||
class cmd_context;
|
||||
|
||||
/**
|
||||
\brief Return the AST that is referenced by the global variable v in the given command context.
|
||||
*/
|
||||
ast * get_ast_ref(cmd_context & ctx, symbol const & v);
|
||||
/**
|
||||
\brief Return the expression that is referenced by the global variable v in the given command context.
|
||||
*/
|
||||
expr * get_expr_ref(cmd_context & ctx, symbol const & v);
|
||||
|
||||
/**
|
||||
\brief Store t in the global variable v.
|
||||
*/
|
||||
void store_expr_ref(cmd_context & ctx, symbol const & v, expr * t);
|
||||
|
||||
#endif
|
|
@ -1,26 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
cnf_params.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-01-23.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include"cnf_params.h"
|
||||
|
||||
void cnf_params::register_params(ini_params & p) {
|
||||
p.register_unsigned_param("CNF_FACTOR", m_cnf_factor, "the maximum number of clauses that can be created when converting a subformula");
|
||||
p.register_int_param("CNF_MODE", 0, 3, reinterpret_cast<int&>(m_cnf_mode), "CNF translation mode: 0 - disabled, 1 - quantifiers in CNF, 2 - 0 + opportunistic, 3 - full");
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
cnf_params.h
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-01-23.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _CNF_PARAMS_H_
|
||||
#define _CNF_PARAMS_H_
|
||||
|
||||
#include"ini_file.h"
|
||||
|
||||
/**
|
||||
\brief CNF translation mode. The cheapest mode is CNF_QUANT, and
|
||||
the most expensive is CNF_FULL.
|
||||
*/
|
||||
enum cnf_mode {
|
||||
CNF_DISABLED, /* CNF translator is disabled.
|
||||
This mode is sufficient when using E-matching.
|
||||
*/
|
||||
CNF_QUANT, /* A subformula is put into CNF if it is inside of a
|
||||
quantifier.
|
||||
|
||||
This mode is sufficient when using Superposition
|
||||
Calculus.
|
||||
*/
|
||||
CNF_OPPORTUNISTIC, /* a subformula is also put in CNF if it is cheap. */
|
||||
CNF_FULL /* Everything is put into CNF, new names are introduced
|
||||
if it is too expensive. */
|
||||
};
|
||||
|
||||
struct cnf_params {
|
||||
cnf_mode m_cnf_mode;
|
||||
unsigned m_cnf_factor;
|
||||
cnf_params():
|
||||
m_cnf_mode(CNF_DISABLED),
|
||||
m_cnf_factor(4) {
|
||||
}
|
||||
|
||||
void register_params(ini_params & p);
|
||||
};
|
||||
|
||||
|
||||
#endif /* _CNF_PARAMS_H_ */
|
||||
|
142
lib/converter.h
142
lib/converter.h
|
@ -1,142 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
converter.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Abstract class and templates for proof and model converters.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-11-14
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _CONVERTER_H_
|
||||
#define _CONVERTER_H_
|
||||
|
||||
#include"vector.h"
|
||||
#include"ref.h"
|
||||
#include"ast_translation.h"
|
||||
|
||||
class converter {
|
||||
unsigned m_ref_count;
|
||||
public:
|
||||
converter():m_ref_count(0) {}
|
||||
virtual ~converter() {}
|
||||
|
||||
void inc_ref() { ++m_ref_count; }
|
||||
void dec_ref() {
|
||||
--m_ref_count;
|
||||
if (m_ref_count == 0)
|
||||
dealloc(this);
|
||||
}
|
||||
|
||||
virtual void cancel() {}
|
||||
|
||||
// for debugging purposes
|
||||
virtual void display(std::ostream & out) {}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class concat_converter : public T {
|
||||
protected:
|
||||
ref<T> m_c1;
|
||||
ref<T> m_c2;
|
||||
|
||||
template<typename T2>
|
||||
T * translate_core(ast_translation & translator) {
|
||||
T * t1 = m_c1->translate(translator);
|
||||
T * t2 = m_c2->translate(translator);
|
||||
return alloc(T2, t1, t2);
|
||||
}
|
||||
|
||||
public:
|
||||
concat_converter(T * c1, T * c2):m_c1(c1), m_c2(c2) {}
|
||||
|
||||
virtual ~concat_converter() {}
|
||||
|
||||
virtual void cancel() {
|
||||
m_c2->cancel();
|
||||
m_c1->cancel();
|
||||
}
|
||||
|
||||
virtual char const * get_name() const = 0;
|
||||
|
||||
virtual void display(std::ostream & out) {
|
||||
out << "(" << get_name() << "\n";
|
||||
m_c1->display(out);
|
||||
m_c2->display(out);
|
||||
out << ")\n";
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class concat_star_converter : public T {
|
||||
protected:
|
||||
ref<T> m_c1;
|
||||
ptr_vector<T> m_c2s;
|
||||
unsigned_vector m_szs;
|
||||
|
||||
template<typename T2>
|
||||
T * translate_core(ast_translation & translator) {
|
||||
T * t1 = m_c1 ? m_c1->translate(translator) : 0;
|
||||
ptr_buffer<T> t2s;
|
||||
unsigned num = m_c2s.size();
|
||||
for (unsigned i = 0; i < num; i++)
|
||||
t2s.push_back(m_c2s[i] ? m_c2s[i]->translate(translator) : 0);
|
||||
return alloc(T2, t1, num, t2s.c_ptr(), m_szs.c_ptr());
|
||||
}
|
||||
|
||||
public:
|
||||
concat_star_converter(T * c1, unsigned num, T * const * c2s, unsigned * szs):
|
||||
m_c1(c1) {
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
T * c2 = c2s[i];
|
||||
if (c2)
|
||||
c2->inc_ref();
|
||||
m_c2s.push_back(c2);
|
||||
m_szs.push_back(szs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~concat_star_converter() {
|
||||
unsigned sz = m_c2s.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
T * c2 = m_c2s[i];
|
||||
if (c2)
|
||||
c2->dec_ref();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void cancel() {
|
||||
if (m_c1)
|
||||
m_c1->cancel();
|
||||
unsigned num = m_c2s.size();
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
if (m_c2s[i])
|
||||
m_c2s[i]->cancel();
|
||||
}
|
||||
}
|
||||
|
||||
virtual char const * get_name() const = 0;
|
||||
|
||||
virtual void display(std::ostream & out) {
|
||||
out << "(" << get_name() << "\n";
|
||||
if (m_c1)
|
||||
m_c1->display(out);
|
||||
out << "(\n";
|
||||
unsigned num = m_c2s.size();
|
||||
for (unsigned i = 0; i < num; i++)
|
||||
if (m_c2s[i])
|
||||
m_c2s[i]->display(out);
|
||||
out << "))\n";
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
dyn_ack_params.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2007-05-18.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"dyn_ack_params.h"
|
||||
|
||||
void dyn_ack_params::register_params(ini_params & p) {
|
||||
p.register_int_param("DACK", 0, 2, reinterpret_cast<int&>(m_dack),
|
||||
"0 - disable dynamic ackermannization, 1 - expand Leibniz's axiom if a congruence is the root of a conflict, 2 - expand Leibniz's axiom if a congruence is used during conflict resolution.");
|
||||
p.register_bool_param("DACK_EQ", m_dack_eq, "enable dynamic ackermannization for transtivity of equalities");
|
||||
p.register_unsigned_param("DACK_THRESHOLD", m_dack_threshold, "number of times the congruence rule must be used before Leibniz's axiom is expanded");
|
||||
p.register_double_param("DACK_FACTOR", m_dack_factor, "number of instance per conflict");
|
||||
p.register_unsigned_param("DACK_GC", m_dack_gc, "Dynamic ackermannization garbage collection frequency (per conflict).");
|
||||
p.register_double_param("DACK_GC_INV_DECAY", m_dack_gc_inv_decay);
|
||||
}
|
||||
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
dyn_ack_params.h
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2007-05-18.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _DYN_ACK_PARAMS_H_
|
||||
#define _DYN_ACK_PARAMS_H_
|
||||
|
||||
#include"ini_file.h"
|
||||
|
||||
enum dyn_ack_strategy {
|
||||
DACK_DISABLED,
|
||||
DACK_ROOT, // congruence is the root of the conflict
|
||||
DACK_CR // congruence used during conflict resolution
|
||||
};
|
||||
|
||||
struct dyn_ack_params {
|
||||
dyn_ack_strategy m_dack;
|
||||
bool m_dack_eq;
|
||||
double m_dack_factor;
|
||||
unsigned m_dack_threshold;
|
||||
unsigned m_dack_gc;
|
||||
double m_dack_gc_inv_decay;
|
||||
|
||||
public:
|
||||
dyn_ack_params():
|
||||
m_dack(DACK_ROOT),
|
||||
m_dack_eq(false),
|
||||
m_dack_factor(0.1),
|
||||
m_dack_threshold(10),
|
||||
m_dack_gc(2000),
|
||||
m_dack_gc_inv_decay(0.8) {
|
||||
}
|
||||
|
||||
void register_params(ini_params & p);
|
||||
};
|
||||
|
||||
|
||||
#endif /* _DYN_ACK_PARAMS_H_ */
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
eval_cmd.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
eval_cmd
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-04-30
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"cmd_context.h"
|
||||
#include"model_evaluator.h"
|
||||
#include"parametric_cmd.h"
|
||||
#include"scoped_timer.h"
|
||||
#include"scoped_ctrl_c.h"
|
||||
#include"cancel_eh.h"
|
||||
|
||||
class eval_cmd : public parametric_cmd {
|
||||
expr * m_target;
|
||||
symbol m_last;
|
||||
public:
|
||||
eval_cmd():parametric_cmd("eval") {}
|
||||
|
||||
virtual char const * get_usage() const { return "<term> (<keyword> <value>)*"; }
|
||||
|
||||
virtual char const * get_main_descr() const {
|
||||
return "evaluate the given term in the current model.";
|
||||
}
|
||||
|
||||
virtual void init_pdescrs(cmd_context & ctx, param_descrs & p) {
|
||||
model_evaluator::get_param_descrs(p);
|
||||
insert_timeout(p);
|
||||
}
|
||||
|
||||
virtual void prepare(cmd_context & ctx) {
|
||||
parametric_cmd::prepare(ctx);
|
||||
m_target = 0;
|
||||
}
|
||||
|
||||
virtual cmd_arg_kind next_arg_kind(cmd_context & ctx) const {
|
||||
if (m_target == 0) return CPK_EXPR;
|
||||
return parametric_cmd::next_arg_kind(ctx);
|
||||
}
|
||||
|
||||
virtual void set_next_arg(cmd_context & ctx, expr * arg) {
|
||||
m_target = arg;
|
||||
}
|
||||
|
||||
virtual void execute(cmd_context & ctx) {
|
||||
if (!ctx.is_model_available())
|
||||
throw cmd_exception("model is not available");
|
||||
model_ref md;
|
||||
check_sat_result * last_result = ctx.get_check_sat_result();
|
||||
SASSERT(last_result);
|
||||
last_result->get_model(md);
|
||||
expr_ref r(ctx.m());
|
||||
unsigned timeout = m_params.get_uint(":timeout", UINT_MAX);
|
||||
model_evaluator ev(*(md.get()), m_params);
|
||||
cancel_eh<model_evaluator> eh(ev);
|
||||
{
|
||||
scoped_ctrl_c ctrlc(eh);
|
||||
scoped_timer timer(timeout, &eh);
|
||||
cmd_context::scoped_watch sw(ctx);
|
||||
try {
|
||||
ev(m_target, r);
|
||||
}
|
||||
catch (model_evaluator_exception & ex) {
|
||||
ctx.regular_stream() << "(error \"evaluator failed: " << ex.msg() << "\")" << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
ctx.display(ctx.regular_stream(), r.get());
|
||||
ctx.regular_stream() << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
void install_eval_cmd(cmd_context & ctx) {
|
||||
ctx.insert(alloc(eval_cmd));
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
eval_cmd.h
|
||||
|
||||
Abstract:
|
||||
|
||||
eval_cmd
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-04-30
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _EVAL_CMD_H_
|
||||
#define _EVAL_CMD_H_
|
||||
|
||||
class cmd_context;
|
||||
|
||||
void install_eval_cmd(cmd_context & ctx);
|
||||
|
||||
#endif
|
|
@ -1,108 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
front_end_params.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2007-05-10.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"front_end_params.h"
|
||||
|
||||
void front_end_params::register_params(ini_params & p) {
|
||||
p.register_param_vector(m_param_vector.get());
|
||||
preprocessor_params::register_params(p);
|
||||
spc_params::register_params(p);
|
||||
smt_params::register_params(p);
|
||||
parser_params::register_params(p);
|
||||
arith_simplifier_params::register_params(p);
|
||||
p.register_int_param("ENGINE", 0, 2, reinterpret_cast<int&>(m_engine), "0: SMT solver, 1: Superposition prover, 2: EPR solver, true");
|
||||
z3_solver_params::register_params(p);
|
||||
model_params::register_params(p);
|
||||
p.register_unsigned_param("MAX_COUNTEREXAMPLES", m_max_num_cex,
|
||||
"set the maximum number of counterexamples when using Simplify front end");
|
||||
p.register_bool_param("AT_LABELS_CEX", m_at_labels_cex,
|
||||
"only use labels that contain '@' when building multiple counterexamples");
|
||||
p.register_bool_param("CHECK_AT_LABELS", m_check_at_labels,
|
||||
"check that labels containing '@' are used correctly to only produce unique counter examples");
|
||||
p.register_bool_param("DEFAULT_QID", m_default_qid, "create a default quantifier id based on its position, the id is used to report profiling information (see QI_PROFILE)");
|
||||
|
||||
p.register_bool_param("TYPE_CHECK", m_well_sorted_check, "enable/disable type checker");
|
||||
p.register_bool_param("WELL_SORTED_CHECK", m_well_sorted_check, "enable/disable type checker");
|
||||
p.register_bool_param("INTERACTIVE", m_interactive, "enable interactive mode using Simplify input format");
|
||||
p.register_unsigned_param("SOFT_TIMEOUT", m_soft_timeout, "set approximate timeout for each solver query (milliseconds), the value 0 represents no timeout", true);
|
||||
p.register_double_param("INSTRUCTION_MAX", m_instr_out, "set the (approximate) maximal number of instructions per invocation of check", true);
|
||||
p.register_bool_param("AUTO_CONFIG", m_auto_config, "use heuristics to set Z3 configuration parameters, it is only available for the SMT-LIB input format");
|
||||
p.register_int_param("PROOF_MODE", 0, 2, reinterpret_cast<int&>(m_proof_mode), "select proof generation mode: 0 - disabled, 1 - coarse grain, 2 - fine grain");
|
||||
p.register_bool_param("TRACE", m_trace, "enable tracing for the Axiom Profiler tool");
|
||||
p.register_string_param("TRACE_FILE_NAME", m_trace_file_name, "tracing file name");
|
||||
p.register_bool_param("IGNORE_SETPARAMETER", m_ignore_setparameter, "ignore (SETPARAMETER ...) commands in Simplify format input");
|
||||
p.register_bool_param("ASYNC_COMMANDS", m_async_commands, "enable/disable support for asynchronous commands in the Simplify front-end.");
|
||||
p.register_bool_param("DISPLAY_CONFIG", m_display_config, "display configuration used by Z3");
|
||||
|
||||
#ifdef _WINDOWS
|
||||
// The non-windows memory manager does not have access to memory sizes.
|
||||
p.register_unsigned_param("MEMORY_HIGH_WATERMARK", m_memory_high_watermark,
|
||||
"set high watermark for memory consumption (in megabytes)");
|
||||
p.register_unsigned_param("MEMORY_MAX_SIZE", m_memory_max_size,
|
||||
"set hard upper limit for memory consumption (in megabytes)");
|
||||
#endif
|
||||
|
||||
#ifndef _EXTERNAL_RELEASE
|
||||
// external users should not have access to it.
|
||||
p.register_bool_param("PREPROCESS", m_preprocess);
|
||||
#endif
|
||||
|
||||
p.register_bool_param("USER_THEORY_PREPROCESS_AXIOMS",
|
||||
m_user_theory_preprocess_axioms,
|
||||
"Apply full pre-processing to user theory axioms",
|
||||
true);
|
||||
|
||||
p.register_bool_param("USER_THEORY_PERSIST_AXIOMS",
|
||||
m_user_theory_persist_axioms,
|
||||
"Persist user axioms to the base level",
|
||||
true);
|
||||
|
||||
p.register_bool_param("SMTLIB2_COMPLIANT", m_smtlib2_compliant);
|
||||
|
||||
p.register_bool_param("IGNORE_BAD_PATTERNS", m_ignore_bad_patterns);
|
||||
|
||||
PRIVATE_PARAMS({
|
||||
p.register_bool_param("IGNORE_CHECKSAT", m_ignore_checksat);
|
||||
p.register_bool_param("DEBUG_REF_COUNT", m_debug_ref_count);
|
||||
p.register_bool_param("IGNORE_USER_PATTERNS", m_ignore_user_patterns);
|
||||
p.register_bool_param("INCREMENTAL_CORE_ASSERT", m_incremental_core_assert);
|
||||
DEBUG_CODE(p.register_int_param("COPY_PARAMS", m_copy_params););
|
||||
});
|
||||
|
||||
// temporary hack until strategic_solver is ported to new tactic framework
|
||||
PRIVATE_PARAMS({
|
||||
p.register_bool_param("NLSAT", m_nlsat);
|
||||
});
|
||||
}
|
||||
|
||||
void front_end_params::open_trace_file() {
|
||||
if (m_trace) {
|
||||
m_trace_stream = alloc(std::fstream, m_trace_file_name.c_str(), std::ios_base::out);
|
||||
}
|
||||
}
|
||||
|
||||
void front_end_params::close_trace_file() {
|
||||
if (m_trace_stream != NULL) {
|
||||
std::fstream &tmp = *m_trace_stream;
|
||||
m_trace_stream = NULL;
|
||||
tmp << "[eof]\n";
|
||||
tmp.close();
|
||||
// do not delete it, this might be called from a Ctrl-C signal handler
|
||||
// and there might be someone writing to it
|
||||
}
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
front_end_params.h
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2007-05-10.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _FRONT_END_PARAMS_H_
|
||||
#define _FRONT_END_PARAMS_H_
|
||||
|
||||
#include"ini_file.h"
|
||||
#include"ast.h"
|
||||
#include"preprocessor_params.h"
|
||||
#include"spc_params.h"
|
||||
#include"smt_params.h"
|
||||
#include"pp_params.h"
|
||||
#include"parser_params.h"
|
||||
#include"arith_simplifier_params.h"
|
||||
#include"z3_solver_params.h"
|
||||
#include"model_params.h"
|
||||
|
||||
enum engine {
|
||||
ENG_SMT,
|
||||
ENG_SPC,
|
||||
ENG_EPR
|
||||
};
|
||||
|
||||
struct front_end_params : public preprocessor_params, public spc_params, public smt_params, public parser_params,
|
||||
public arith_simplifier_params, public z3_solver_params, public model_params
|
||||
{
|
||||
ref<param_vector> m_param_vector;
|
||||
engine m_engine;
|
||||
unsigned m_max_num_cex; // maximum number of counterexamples
|
||||
bool m_at_labels_cex; // only use labels which contains the @ symbol when building multiple counterexamples.
|
||||
bool m_check_at_labels; // check that @ labels are inserted to generate unique counter-examples.
|
||||
bool m_default_qid;
|
||||
bool m_interactive;
|
||||
bool m_well_sorted_check;
|
||||
bool m_ignore_bad_patterns;
|
||||
bool m_ignore_user_patterns;
|
||||
bool m_incremental_core_assert; // assert conditions to the core incrementally
|
||||
unsigned m_soft_timeout;
|
||||
double m_instr_out;
|
||||
unsigned m_memory_high_watermark;
|
||||
unsigned m_memory_max_size;
|
||||
proof_gen_mode m_proof_mode;
|
||||
bool m_auto_config;
|
||||
bool m_smtlib2_compliant;
|
||||
#ifdef Z3DEBUG
|
||||
int m_copy_params; // used for testing copy params... Invoke method copy_params(m_copy_params) in main.cpp when diff -1.
|
||||
#endif
|
||||
bool m_preprocess; // temporary hack for disabling all preprocessing..
|
||||
bool m_ignore_checksat; // abort before checksat... for internal debugging
|
||||
bool m_debug_ref_count;
|
||||
bool m_trace;
|
||||
std::string m_trace_file_name;
|
||||
std::fstream* m_trace_stream;
|
||||
bool m_ignore_setparameter;
|
||||
bool m_async_commands;
|
||||
bool m_display_config;
|
||||
bool m_user_theory_preprocess_axioms;
|
||||
bool m_user_theory_persist_axioms;
|
||||
bool m_nlsat; // temporary hack until strategic_solver is ported to new tactic framework
|
||||
|
||||
front_end_params():
|
||||
m_param_vector(alloc(param_vector, this)),
|
||||
m_engine(ENG_SMT),
|
||||
m_max_num_cex(1),
|
||||
m_at_labels_cex(false),
|
||||
m_check_at_labels(false),
|
||||
m_default_qid(false),
|
||||
m_interactive(false),
|
||||
m_well_sorted_check(true),
|
||||
m_ignore_bad_patterns(true),
|
||||
m_ignore_user_patterns(false),
|
||||
m_incremental_core_assert(true),
|
||||
m_soft_timeout(0),
|
||||
m_instr_out(0.0),
|
||||
m_memory_high_watermark(0),
|
||||
m_memory_max_size(0),
|
||||
m_proof_mode(PGM_DISABLED),
|
||||
#if defined(SMTCOMP) || defined(_EXTERNAL_RELEASE)
|
||||
m_auto_config(true),
|
||||
#else
|
||||
m_auto_config(false),
|
||||
#endif
|
||||
#if 0
|
||||
m_smtlib2_compliant(true),
|
||||
#else
|
||||
m_smtlib2_compliant(false),
|
||||
#endif
|
||||
#ifdef Z3DEBUG
|
||||
m_copy_params(-1),
|
||||
#endif
|
||||
m_preprocess(true), // temporary hack for disabling all preprocessing..
|
||||
m_ignore_checksat(false),
|
||||
m_debug_ref_count(false),
|
||||
m_trace(false),
|
||||
m_trace_file_name("z3.log"),
|
||||
m_trace_stream(NULL),
|
||||
m_ignore_setparameter(false),
|
||||
m_async_commands(true),
|
||||
m_display_config(false),
|
||||
m_user_theory_preprocess_axioms(false),
|
||||
m_user_theory_persist_axioms(false),
|
||||
m_nlsat(false) {
|
||||
}
|
||||
|
||||
void register_params(ini_params & p);
|
||||
|
||||
void open_trace_file();
|
||||
|
||||
void close_trace_file();
|
||||
|
||||
void copy_params(unsigned idx) {
|
||||
m_param_vector->copy_params(this, idx);
|
||||
}
|
||||
|
||||
bool has_auto_config(unsigned idx) { return m_auto_config; }
|
||||
|
||||
private:
|
||||
|
||||
front_end_params& operator=(front_end_params const& other);
|
||||
};
|
||||
|
||||
#endif /* _FRONT_END_PARAMS_H_ */
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
goal_util.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
goal goodies.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-01-03.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"goal_util.h"
|
||||
#include"goal.h"
|
||||
|
||||
struct has_term_ite_functor {
|
||||
struct found {};
|
||||
ast_manager & m;
|
||||
has_term_ite_functor(ast_manager & _m):m(_m) {}
|
||||
void operator()(var *) {}
|
||||
void operator()(quantifier *) {}
|
||||
void operator()(app * n) { if (m.is_term_ite(n)) throw found(); }
|
||||
};
|
||||
|
||||
bool has_term_ite(goal const & g) {
|
||||
return test<has_term_ite_functor>(g);
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
goal_util.h
|
||||
|
||||
Abstract:
|
||||
|
||||
goal goodies.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-01-03.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _GOAL_UTIL_H_
|
||||
#define _GOAL_UTIL_H_
|
||||
|
||||
class goal;
|
||||
bool has_term_ite(goal const & g);
|
||||
|
||||
#endif
|
|
@ -1,150 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
model_converter.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Abstract interface for converting models.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-04-21
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"model_converter.h"
|
||||
#include"model_v2_pp.h"
|
||||
|
||||
class concat_model_converter : public concat_converter<model_converter> {
|
||||
public:
|
||||
concat_model_converter(model_converter * mc1, model_converter * mc2):concat_converter<model_converter>(mc1, mc2) {}
|
||||
|
||||
virtual void operator()(model_ref & m) {
|
||||
this->m_c2->operator()(m);
|
||||
this->m_c1->operator()(m);
|
||||
}
|
||||
|
||||
virtual void operator()(model_ref & m, unsigned goal_idx) {
|
||||
this->m_c2->operator()(m, goal_idx);
|
||||
this->m_c1->operator()(m, 0);
|
||||
}
|
||||
|
||||
virtual char const * get_name() const { return "concat-model-converter"; }
|
||||
|
||||
virtual model_converter * translate(ast_translation & translator) {
|
||||
return this->translate_core<concat_model_converter>(translator);
|
||||
}
|
||||
};
|
||||
|
||||
model_converter * concat(model_converter * mc1, model_converter * mc2) {
|
||||
if (mc1 == 0)
|
||||
return mc2;
|
||||
if (mc2 == 0)
|
||||
return mc1;
|
||||
return alloc(concat_model_converter, mc1, mc2);
|
||||
}
|
||||
|
||||
class concat_star_model_converter : public concat_star_converter<model_converter> {
|
||||
public:
|
||||
concat_star_model_converter(model_converter * mc1, unsigned num, model_converter * const * mc2s, unsigned * szs):
|
||||
concat_star_converter<model_converter>(mc1, num, mc2s, szs) {
|
||||
}
|
||||
|
||||
virtual void operator()(model_ref & m) {
|
||||
// TODO: delete method after conversion is complete
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
virtual void operator()(model_ref & m, unsigned goal_idx) {
|
||||
unsigned num = this->m_c2s.size();
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
if (goal_idx < this->m_szs[i]) {
|
||||
// found the model converter that should be used
|
||||
model_converter * c2 = this->m_c2s[i];
|
||||
if (c2)
|
||||
c2->operator()(m, goal_idx);
|
||||
if (m_c1)
|
||||
this->m_c1->operator()(m, i);
|
||||
return;
|
||||
}
|
||||
// invalid goal
|
||||
goal_idx -= this->m_szs[i];
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
virtual char const * get_name() const { return "concat-star-model-converter"; }
|
||||
|
||||
virtual model_converter * translate(ast_translation & translator) {
|
||||
return this->translate_core<concat_star_model_converter>(translator);
|
||||
}
|
||||
};
|
||||
|
||||
model_converter * concat(model_converter * mc1, unsigned num, model_converter * const * mc2s, unsigned * szs) {
|
||||
SASSERT(num > 0);
|
||||
if (num == 1)
|
||||
return concat(mc1, mc2s[0]);
|
||||
unsigned i;
|
||||
for (i = 0; i < num; i++) {
|
||||
if (mc2s[i] != 0)
|
||||
break;
|
||||
}
|
||||
if (i == num) {
|
||||
// all mc2s are 0
|
||||
return mc1;
|
||||
}
|
||||
return alloc(concat_star_model_converter, mc1, num, mc2s, szs);
|
||||
}
|
||||
|
||||
class model2mc : public model_converter {
|
||||
model_ref m_model;
|
||||
public:
|
||||
model2mc(model * m):m_model(m) {}
|
||||
virtual ~model2mc() {}
|
||||
|
||||
virtual void operator()(model_ref & m) {
|
||||
m = m_model;
|
||||
}
|
||||
|
||||
virtual void operator()(model_ref & m, unsigned goal_idx) {
|
||||
m = m_model;
|
||||
}
|
||||
|
||||
virtual void cancel() {
|
||||
}
|
||||
|
||||
virtual void display(std::ostream & out) {
|
||||
out << "(model->model-converter-wrapper\n";
|
||||
model_v2_pp(out, *m_model);
|
||||
out << ")\n";
|
||||
}
|
||||
|
||||
virtual model_converter * translate(ast_translation & translator) {
|
||||
model * m = m_model->translate(translator);
|
||||
return alloc(model2mc, m);
|
||||
}
|
||||
};
|
||||
|
||||
model_converter * model2model_converter(model * m) {
|
||||
if (m == 0)
|
||||
return 0;
|
||||
return alloc(model2mc, m);
|
||||
}
|
||||
|
||||
void model_converter2model(ast_manager & mng, model_converter * mc, model_ref & m) {
|
||||
if (mc) {
|
||||
m = alloc(model, mng);
|
||||
(*mc)(m, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void apply(model_converter_ref & mc, model_ref & m, unsigned gidx) {
|
||||
if (mc) {
|
||||
(*mc)(m, gidx);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
model_converter.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Abstract interface for converting models.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-04-21
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _MODEL_CONVERTER_H_
|
||||
#define _MODEL_CONVERTER_H_
|
||||
|
||||
#include"model.h"
|
||||
#include"converter.h"
|
||||
#include"ref.h"
|
||||
|
||||
class model_converter : public converter {
|
||||
public:
|
||||
virtual void operator()(model_ref & m) {} // TODO: delete
|
||||
|
||||
virtual void operator()(model_ref & m, unsigned goal_idx) {
|
||||
// TODO: make it virtual after the transition to goal/tactic/tactical is complete
|
||||
SASSERT(goal_idx == 0);
|
||||
operator()(m);
|
||||
}
|
||||
|
||||
virtual model_converter * translate(ast_translation & translator) = 0;
|
||||
};
|
||||
|
||||
typedef ref<model_converter> model_converter_ref;
|
||||
|
||||
model_converter * concat(model_converter * mc1, model_converter * mc2);
|
||||
|
||||
/**
|
||||
\brief \c mc1 is the model converter for a sequence of subgoals of size \c num.
|
||||
Given an i in [0, num), mc2s[i] is the model converter for subgoal i,
|
||||
and num_subgoals[i] is the number of subgoals of subgoals[i].
|
||||
*/
|
||||
model_converter * concat(model_converter * mc1, unsigned num, model_converter * const * mc2s, unsigned * num_subgoals);
|
||||
|
||||
model_converter * model2model_converter(model * m);
|
||||
|
||||
void model_converter2model(ast_manager & mng, model_converter * mc, model_ref & m);
|
||||
|
||||
void apply(model_converter_ref & mc, model_ref & m, unsigned gidx);
|
||||
|
||||
typedef sref_vector<model_converter> model_converter_ref_vector;
|
||||
typedef sref_buffer<model_converter> model_converter_ref_buffer;
|
||||
|
||||
#endif
|
|
@ -1,26 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
nnf_params.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-01-14.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"nnf_params.h"
|
||||
|
||||
void nnf_params::register_params(ini_params & p) {
|
||||
p.register_unsigned_param("NNF_FACTOR", m_nnf_factor, "the maximum growth factor during NNF translation (auxiliary definitions are introduced if the threshold is reached)");
|
||||
p.register_int_param("NNF_MODE", 0, 3, reinterpret_cast<int&>(m_nnf_mode), "NNF translation mode: 0 - skolem normal form, 1 - 0 + quantifiers in NNF, 2 - 1 + opportunistic, 3 - full");
|
||||
p.register_bool_param("NNF_IGNORE_LABELS", m_nnf_ignore_labels, "remove/ignore labels in the input formula, this option is ignored if proofs are enabled");
|
||||
p.register_bool_param("NNF_SK_HACK", m_nnf_sk_hack, "hack for VCC");
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
nnf_params.h
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-01-14.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _NNF_PARAMS_H_
|
||||
#define _NNF_PARAMS_H_
|
||||
|
||||
#include"ini_file.h"
|
||||
|
||||
/**
|
||||
\brief NNF translation mode. The cheapest mode is NNF_SKOLEM, and
|
||||
the most expensive is NNF_FULL.
|
||||
*/
|
||||
enum nnf_mode {
|
||||
NNF_SKOLEM, /* A subformula is put into NNF only if it contains
|
||||
quantifiers or labels. The result of the
|
||||
transformation will be in skolem normal form.
|
||||
If a formula is too expensive to be put into NNF,
|
||||
then nested quantifiers and labels are renamed.
|
||||
|
||||
This mode is sufficient when using E-matching.
|
||||
*/
|
||||
NNF_QUANT, /* A subformula is put into NNF if it contains
|
||||
quantifiers, labels, or is in the scope of a
|
||||
quantifier. The result of the transformation will be
|
||||
in skolem normal form, and the body of quantifiers
|
||||
will be in NNF. If a ground formula is too expensive to
|
||||
be put into NNF, then nested quantifiers and labels
|
||||
are renamed.
|
||||
|
||||
This mode is sufficient when using Superposition
|
||||
Calculus.
|
||||
|
||||
Remark: If the problem does not contain quantifiers,
|
||||
then NNF_QUANT is identical to NNF_SKOLEM.
|
||||
*/
|
||||
NNF_OPPORTUNISTIC, /* Similar to NNF_QUANT, but a subformula is
|
||||
also put into NNF, if it is
|
||||
cheap. Otherwise, the nested quantifiers and
|
||||
labels are renamed. */
|
||||
NNF_FULL /* Everything is put into NNF. */
|
||||
};
|
||||
|
||||
struct nnf_params {
|
||||
nnf_mode m_nnf_mode;
|
||||
unsigned m_nnf_factor;
|
||||
bool m_nnf_ignore_labels;
|
||||
bool m_nnf_sk_hack;
|
||||
nnf_params():
|
||||
m_nnf_mode(NNF_SKOLEM),
|
||||
m_nnf_factor(4),
|
||||
m_nnf_ignore_labels(false),
|
||||
m_nnf_sk_hack(false) {
|
||||
}
|
||||
|
||||
void register_params(ini_params & p);
|
||||
};
|
||||
|
||||
#endif /* _NNF_PARAMS_H_ */
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
order_params.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Term ordering parameters.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-01-28.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"order_params.h"
|
||||
|
||||
void order_params::register_params(ini_params & p) {
|
||||
p.register_symbol_list_param("PRECEDENCE", m_order_precedence, "describe a (partial) precedence for the term ordering used in the Superposition Calculus module. The precedence is lists of function symbols. Example: PRECEDENCE=\"(f, g, h)\"");
|
||||
p.register_symbol_list_param("PRECEDENCE_GEN", m_order_precedence_gen, "describe how a total precedence order is generated. The generator is a sequence of simple (partial) orders with an optional '-' (indicating the next (partial) order should be inverted). The available simple (partial) orders are: user (the order specified by precedence); arity; interpreted (interpreted function symbols are considered smaller); definition (defined function symbols are considered bigger); frequency; arbitrary (total arbitrary order generated by Z3). Example: PRECEDENCE_GEN=\"user interpreted - arity arbitraty\"");
|
||||
p.register_symbol_nat_list_param("ORDER_WEIGHTS", m_order_weights, "describe a (partial) assignment of weights to function symbols for term orderings (e.g., KBO). The assigment is a list of pairs of the form f:n where f is a string and n is a natural. Example: WEIGHTS=\"(f:1, g:2, h:3)\"");
|
||||
p.register_unsigned_param("ORDER_VAR_WEIGHT", m_order_var_weight, "weight of variables in term orderings (e.g., KBO)");
|
||||
p.register_int_param("ORDER", 0, 1, reinterpret_cast<int&>(m_order_kind), "Term ordering: 0 - KBO, 1 - LPO");
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
order_params.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Term ordering parameters.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-01-28.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _ORDER_PARAMS_H_
|
||||
#define _ORDER_PARAMS_H_
|
||||
|
||||
#include"ini_file.h"
|
||||
|
||||
enum order_kind {
|
||||
ORD_KBO,
|
||||
ORD_LPO
|
||||
};
|
||||
|
||||
struct order_params {
|
||||
svector<symbol> m_order_precedence;
|
||||
svector<symbol> m_order_precedence_gen;
|
||||
svector<symbol_nat_pair> m_order_weights;
|
||||
unsigned m_order_var_weight;
|
||||
order_kind m_order_kind;
|
||||
|
||||
order_params():
|
||||
m_order_var_weight(1),
|
||||
m_order_kind(ORD_KBO) {
|
||||
}
|
||||
|
||||
void register_params(ini_params & p);
|
||||
};
|
||||
|
||||
#endif /* _ORDER_PARAMS_H_ */
|
|
@ -1,64 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
parametric_cmd.h
|
||||
|
||||
Abstract:
|
||||
A generic parametric cmd.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-04-22
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include<sstream>
|
||||
#include"parametric_cmd.h"
|
||||
|
||||
char const * parametric_cmd::get_descr(cmd_context & ctx) const {
|
||||
if (m_descr == 0) {
|
||||
const_cast<parametric_cmd*>(this)->m_descr = alloc(string_buffer<>);
|
||||
m_descr->append(get_main_descr());
|
||||
m_descr->append("\nThe following options are available:\n");
|
||||
std::ostringstream buf;
|
||||
pdescrs(ctx).display(buf, 2);
|
||||
m_descr->append(buf.str().c_str());
|
||||
}
|
||||
return m_descr->c_str();
|
||||
}
|
||||
|
||||
cmd_arg_kind parametric_cmd::next_arg_kind(cmd_context & ctx) const {
|
||||
if (m_last == symbol::null) return CPK_KEYWORD;
|
||||
return pdescrs(ctx).get_kind(m_last);
|
||||
}
|
||||
|
||||
void parametric_cmd::set_next_arg(cmd_context & ctx, symbol const & s) {
|
||||
if (m_last == symbol::null) {
|
||||
m_last = s;
|
||||
if (pdescrs(ctx).get_kind(m_last.bare_str()) == CPK_INVALID)
|
||||
throw cmd_exception("invalid keyword argument");
|
||||
return;
|
||||
}
|
||||
m_params.set_sym(m_last.bare_str(), s);
|
||||
m_last = symbol::null;
|
||||
}
|
||||
|
||||
param_descrs const & parametric_cmd::pdescrs(cmd_context & ctx) const {
|
||||
if (!m_pdescrs) {
|
||||
parametric_cmd * _this = const_cast<parametric_cmd*>(this);
|
||||
_this->m_pdescrs = alloc(param_descrs);
|
||||
_this->init_pdescrs(ctx, *(_this->m_pdescrs));
|
||||
}
|
||||
return *m_pdescrs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
parametric_cmd.h
|
||||
|
||||
Abstract:
|
||||
A generic parametric cmd.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-04-22
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _PARAMETRIC_CMD_H_
|
||||
#define _PARAMETRIC_CMD_H_
|
||||
|
||||
#include"params.h"
|
||||
#include"symbol.h"
|
||||
#include"string_buffer.h"
|
||||
#include"cmd_context_types.h"
|
||||
|
||||
class parametric_cmd : public cmd {
|
||||
public:
|
||||
symbol m_last;
|
||||
string_buffer<> * m_descr;
|
||||
params_ref m_params;
|
||||
scoped_ptr<param_descrs> m_pdescrs;
|
||||
public:
|
||||
parametric_cmd(char const * name):cmd(name), m_descr(0) {}
|
||||
virtual ~parametric_cmd() { if (m_descr) dealloc(m_descr); }
|
||||
virtual void init_pdescrs(cmd_context & ctx, param_descrs & d) = 0;
|
||||
param_descrs const & pdescrs(cmd_context & ctx) const;
|
||||
params_ref const & ps() const { return m_params; }
|
||||
virtual char const * get_main_descr() const = 0;
|
||||
virtual char const * get_descr(cmd_context & ctx) const;
|
||||
virtual unsigned get_arity() const { return VAR_ARITY; }
|
||||
virtual void prepare(cmd_context & ctx) { m_last = symbol::null; m_params.reset(); }
|
||||
virtual cmd_arg_kind next_arg_kind(cmd_context & ctx) const;
|
||||
virtual void set_next_arg(cmd_context & ctx, symbol const & s);
|
||||
virtual void set_next_arg(cmd_context & ctx, unsigned val) {
|
||||
m_params.set_uint(m_last, val);
|
||||
m_last = symbol::null;
|
||||
}
|
||||
virtual void set_next_arg(cmd_context & ctx, bool val) {
|
||||
m_params.set_bool(m_last, val);
|
||||
m_last = symbol::null;
|
||||
}
|
||||
virtual void set_next_arg(cmd_context & ctx, rational const & val) {
|
||||
m_params.set_rat(m_last, val);
|
||||
m_last = symbol::null;
|
||||
}
|
||||
virtual void set_next_arg(cmd_context & ctx, char const * val) {
|
||||
m_params.set_str(m_last, val);
|
||||
m_last = symbol::null;
|
||||
}
|
||||
virtual void set_next_arg(cmd_context & ctx, sort * s) {
|
||||
m_params.set_sort(m_last, s);
|
||||
m_last = symbol::null;
|
||||
}
|
||||
virtual void set_next_arg(cmd_context & ctx, expr * t) {
|
||||
m_params.set_expr(m_last, t);
|
||||
m_last = symbol::null;
|
||||
}
|
||||
virtual void set_next_arg(cmd_context & ctx, func_decl * f) {
|
||||
m_params.set_func_decl(m_last, f);
|
||||
m_last = symbol::null;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
params2front_end_params.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Backward compatibility utilities for parameter setting
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2011-05-19.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"front_end_params.h"
|
||||
#include"params.h"
|
||||
|
||||
/**
|
||||
Update front_end_params using s.
|
||||
Only the most frequently used options are updated.
|
||||
|
||||
This function is mainly used to allow smt::context to be used in
|
||||
the new strategy framework.
|
||||
*/
|
||||
void params2front_end_params(params_ref const & s, front_end_params & t) {
|
||||
t.m_quant_elim = s.get_bool(":elim-quant", t.m_quant_elim);
|
||||
t.m_relevancy_lvl = s.get_uint(":relevancy", t.m_relevancy_lvl);
|
||||
TRACE("qi_cost", s.display(tout); tout << "\n";);
|
||||
t.m_qi_cost = s.get_str(":qi-cost", t.m_qi_cost.c_str());
|
||||
t.m_mbqi = s.get_bool(":mbqi", t.m_mbqi);
|
||||
t.m_mbqi_max_iterations = s.get_uint(":mbqi-max-iterations", t.m_mbqi_max_iterations);
|
||||
t.m_random_seed = s.get_uint(":random-seed", t.m_random_seed);
|
||||
t.m_model = s.get_bool(":produce-models", t.m_model);
|
||||
if (s.get_bool(":produce-proofs", false))
|
||||
t.m_proof_mode = PGM_FINE;
|
||||
t.m_well_sorted_check = s.get_bool(":check-sorts", t.m_well_sorted_check);
|
||||
t.m_qi_eager_threshold = s.get_double(":qi-eager-threshold", t.m_qi_eager_threshold);
|
||||
t.m_qi_lazy_threshold = s.get_double(":qi-lazy-threshold", t.m_qi_lazy_threshold);
|
||||
t.m_solver = s.get_bool(":solver", t.m_solver);
|
||||
t.m_preprocess = s.get_bool(":preprocess", t.m_preprocess);
|
||||
t.m_hi_div0 = s.get_bool(":hi-div0", t.m_hi_div0);
|
||||
t.m_auto_config = s.get_bool(":auto-config", t.m_auto_config);
|
||||
t.m_array_simplify = s.get_bool(":array-old-simplifier", t.m_array_simplify);
|
||||
t.m_arith_branch_cut_ratio = s.get_uint(":arith-branch-cut-ratio", t.m_arith_branch_cut_ratio);
|
||||
t.m_arith_expand_eqs = s.get_bool(":arith-expand-eqs", t.m_arith_expand_eqs);
|
||||
|
||||
if (s.get_bool(":arith-greatest-error-pivot", false))
|
||||
t.m_arith_pivot_strategy = ARITH_PIVOT_GREATEST_ERROR;
|
||||
else if (s.get_bool(":arith-least-error-pivot", false))
|
||||
t.m_arith_pivot_strategy = ARITH_PIVOT_LEAST_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Copy parameters (from s) that affect the semantics of Z3 (e.g., HI_DIV0).
|
||||
It also copies the model construction parameter. Thus, model construction
|
||||
can be enabled at the command line.
|
||||
*/
|
||||
void front_end_params2params(front_end_params const & s, params_ref & t) {
|
||||
if (s.m_model)
|
||||
t.set_bool(":produce-models", true);
|
||||
if (!s.m_hi_div0)
|
||||
t.set_bool(":hi-div0", false);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Bridge for using params_ref with smt::context.
|
||||
*/
|
||||
void solver_front_end_params_descrs(param_descrs & r) {
|
||||
r.insert(":hi-div0", CPK_BOOL, "(default: true) if true, then Z3 uses the usual hardware interpretation for division (rem, mod) by zero. Otherwise, these operations are considered uninterpreted");
|
||||
r.insert(":relevancy", CPK_UINT, "relevancy propagation heuristic: 0 - disabled, 1 - relevancy is tracked by only affects quantifier instantiation, 2 - relevancy is tracked, and an atom is only asserted if it is relevant");
|
||||
r.insert(":mbqi", CPK_BOOL, "model based quantifier instantiation (MBQI)");
|
||||
r.insert(":mbqi-max-iterations", CPK_UINT, "maximum number of rounds of MBQI");
|
||||
r.insert(":random-seed", CPK_UINT, "random seed for smt solver");
|
||||
r.insert(":qi-eager-threshold", CPK_DOUBLE, "threshold for eager quantifier instantiation");
|
||||
r.insert(":qi-lazy-threshold", CPK_DOUBLE, "threshold for lazy quantifier instantiation");
|
||||
r.insert(":auto_config", CPK_BOOL, "use heuristics to automatically configure smt solver");
|
||||
r.insert(":arith-branch-cut-ratio", CPK_UINT, "branch&bound / gomory cut ratio");
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
params2front_end_params.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Backward compatibility utilities for parameter setting
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2011-05-19.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _PARAMS2FRONT_END_PARAMS_H_
|
||||
#define _PARAMS2FRONT_END_PARAMS_H_
|
||||
|
||||
class params_ref;
|
||||
struct front_end_params;
|
||||
|
||||
void params2front_end_params(params_ref const & s, front_end_params & t);
|
||||
|
||||
void front_end_params2params(front_end_params const & s, params_ref & t);
|
||||
|
||||
void solver_front_end_params_descrs(param_descrs & r);
|
||||
|
||||
#endif
|
|
@ -1,14 +0,0 @@
|
|||
#include "parser_params.h"
|
||||
|
||||
parser_params::parser_params() :
|
||||
m_dump_goal_as_smt(false),
|
||||
m_display_error_for_vs(false) {
|
||||
}
|
||||
|
||||
void parser_params::register_params(ini_params & p) {
|
||||
p.register_bool_param("DUMP_GOAL_AS_SMT", m_dump_goal_as_smt, "write goal back to output in SMT format");
|
||||
p.register_bool_param("DISPLAY_ERROR_FOR_VISUAL_STUDIO", m_display_error_for_vs, "display error messages in Visual Studio format");
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2008 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
parser_params.h
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2008-04-21.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _PARSER_PARAMS_H_
|
||||
#define _PARSER_PARAMS_H_
|
||||
|
||||
#include"ini_file.h"
|
||||
|
||||
struct parser_params {
|
||||
bool m_dump_goal_as_smt; // re-print goal as SMT benchmark.
|
||||
bool m_display_error_for_vs; // print error in vs format.
|
||||
|
||||
parser_params();
|
||||
void register_params(ini_params & p);
|
||||
};
|
||||
|
||||
#endif /* _PARSER_PARAMS_H_ */
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
pattern_inference_params.h
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-03-24.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _PATTERN_INFERENCE_PARAMS_H_
|
||||
#define _PATTERN_INFERENCE_PARAMS_H_
|
||||
|
||||
#include"ini_file.h"
|
||||
|
||||
enum arith_pattern_inference_kind {
|
||||
AP_NO, // do not infer patterns with arithmetic terms
|
||||
AP_CONSERVATIVE, // only infer patterns with arithmetic terms if there is no other option
|
||||
AP_FULL // always use patterns with arithmetic terms
|
||||
};
|
||||
|
||||
struct pattern_inference_params {
|
||||
unsigned m_pi_max_multi_patterns;
|
||||
bool m_pi_block_loop_patterns;
|
||||
arith_pattern_inference_kind m_pi_arith;
|
||||
bool m_pi_use_database;
|
||||
unsigned m_pi_arith_weight;
|
||||
unsigned m_pi_non_nested_arith_weight;
|
||||
bool m_pi_pull_quantifiers;
|
||||
int m_pi_nopat_weight;
|
||||
bool m_pi_avoid_skolems;
|
||||
bool m_pi_warnings;
|
||||
|
||||
pattern_inference_params():
|
||||
m_pi_max_multi_patterns(0),
|
||||
m_pi_block_loop_patterns(true),
|
||||
m_pi_arith(AP_CONSERVATIVE),
|
||||
m_pi_use_database(false),
|
||||
m_pi_arith_weight(5),
|
||||
m_pi_non_nested_arith_weight(10),
|
||||
m_pi_pull_quantifiers(true),
|
||||
m_pi_nopat_weight(-1),
|
||||
m_pi_avoid_skolems(true),
|
||||
m_pi_warnings(false) {
|
||||
}
|
||||
|
||||
void register_params(ini_params & p);
|
||||
};
|
||||
|
||||
#endif /* _PATTERN_INFERENCE_PARAMS_H_ */
|
||||
|
958
lib/pdecl.cpp
958
lib/pdecl.cpp
|
@ -1,958 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
pdecl.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Parametric declarations for SMT-LIB 2.0 + inductive data-types.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2011-03-02.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"pdecl.h"
|
||||
#include"datatype_decl_plugin.h"
|
||||
using namespace format_ns;
|
||||
|
||||
class psort_inst_cache {
|
||||
unsigned m_num_params;
|
||||
sort * m_const;
|
||||
obj_map<sort, void *> m_map; // if m_num_params == 1 value is a sort, otherwise it is a reference to another inst_cache
|
||||
public:
|
||||
psort_inst_cache(unsigned num_params):m_num_params(num_params), m_const(0) {
|
||||
}
|
||||
|
||||
~psort_inst_cache() { SASSERT(m_map.empty()); SASSERT(m_const == 0); }
|
||||
|
||||
void finalize(pdecl_manager & m) {
|
||||
if (m_num_params == 0) {
|
||||
SASSERT(m_map.empty());
|
||||
if (m_const)
|
||||
m.m().dec_ref(m_const);
|
||||
m_const = 0;
|
||||
}
|
||||
else {
|
||||
SASSERT(m_const == 0);
|
||||
obj_map<sort, void *>::iterator it = m_map.begin();
|
||||
obj_map<sort, void *>::iterator end = m_map.end();
|
||||
for (; it != end; ++it) {
|
||||
m.m().dec_ref((*it).m_key);
|
||||
if (m_num_params == 1) {
|
||||
m.m().dec_ref(static_cast<sort*>((*it).m_value));
|
||||
}
|
||||
else {
|
||||
psort_inst_cache * child = static_cast<psort_inst_cache*>((*it).m_value);
|
||||
child->finalize(m);
|
||||
child->~psort_inst_cache();
|
||||
m.a().deallocate(sizeof(psort_inst_cache), child);
|
||||
}
|
||||
}
|
||||
m_map.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void insert(pdecl_manager & m, sort * const * s, sort * r) {
|
||||
if (m_num_params == 0) {
|
||||
SASSERT(m_const == 0);
|
||||
m.m().inc_ref(r);
|
||||
m_const = r;
|
||||
return;
|
||||
}
|
||||
psort_inst_cache * curr = this;
|
||||
while (true) {
|
||||
if (curr->m_num_params == 1) {
|
||||
SASSERT(!curr->m_map.contains(*s));
|
||||
curr->m_map.insert(*s, r);
|
||||
m.m().inc_ref(*s);
|
||||
m.m().inc_ref(r);
|
||||
return;
|
||||
}
|
||||
void * next = 0;
|
||||
if (!curr->m_map.find(*s, next)) {
|
||||
next = new (m.a().allocate(sizeof(psort_inst_cache))) psort_inst_cache(curr->m_num_params-1);
|
||||
curr->m_map.insert(*s, next);
|
||||
m.m().inc_ref(*s);
|
||||
}
|
||||
SASSERT(next != 0);
|
||||
SASSERT(curr->m_num_params == static_cast<psort_inst_cache*>(next)->m_num_params + 1);
|
||||
s++;
|
||||
curr = static_cast<psort_inst_cache*>(next);
|
||||
}
|
||||
}
|
||||
|
||||
sort * find(sort * const * s) const {
|
||||
if (m_num_params == 0)
|
||||
return m_const;
|
||||
psort_inst_cache const * curr = this;
|
||||
while (true) {
|
||||
if (curr->m_num_params == 1) {
|
||||
void * r = 0;
|
||||
curr->m_map.find(*s, r);
|
||||
return static_cast<sort*>(r);
|
||||
}
|
||||
else {
|
||||
void * next = 0;
|
||||
curr->m_map.find(*s, next);
|
||||
if (next == 0)
|
||||
return 0;
|
||||
s++;
|
||||
curr = static_cast<psort_inst_cache*>(next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool empty() const { return m_num_params == 0 ? m_const == 0 : m_map.empty(); }
|
||||
};
|
||||
|
||||
void psort::cache(pdecl_manager & m, sort * const * s, sort * r) {
|
||||
if (!m_inst_cache)
|
||||
m_inst_cache = m.mk_inst_cache(m_num_params);
|
||||
m_inst_cache->insert(m, s, r);
|
||||
}
|
||||
|
||||
sort * psort::find(sort * const * s) const {
|
||||
if (!m_inst_cache)
|
||||
return 0;
|
||||
return m_inst_cache->find(s);
|
||||
}
|
||||
|
||||
void psort::finalize(pdecl_manager & m) {
|
||||
m.del_inst_cache(m_inst_cache);
|
||||
m_inst_cache = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief wrapper for sorts.
|
||||
*/
|
||||
class psort_sort : public psort {
|
||||
friend class pdecl_manager;
|
||||
sort * m_sort;
|
||||
psort_sort(unsigned id, pdecl_manager & m, sort * s):psort(id, 0), m_sort(s) { m.m().inc_ref(m_sort); }
|
||||
virtual void finalize(pdecl_manager & m) {
|
||||
m.m().dec_ref(m_sort);
|
||||
psort::finalize(m);
|
||||
}
|
||||
virtual bool check_num_params(pdecl * other) const { return true; }
|
||||
virtual size_t obj_size() const { return sizeof(psort_sort); }
|
||||
sort * get_sort() const { return m_sort; }
|
||||
virtual sort * instantiate(pdecl_manager & m, sort * const * s) { return m_sort; }
|
||||
public:
|
||||
virtual ~psort_sort() {}
|
||||
virtual bool is_sort_wrapper() const { return true; }
|
||||
virtual char const * hcons_kind() const { return "psort_sort"; }
|
||||
virtual unsigned hcons_hash() const { return m_sort->get_id(); }
|
||||
virtual bool hcons_eq(psort const * other) const {
|
||||
if (other->hcons_kind() != hcons_kind())
|
||||
return false;
|
||||
return m_sort == static_cast<psort_sort const *>(other)->m_sort;
|
||||
}
|
||||
virtual void display(std::ostream & out) const {
|
||||
out << m_sort->get_name();
|
||||
}
|
||||
};
|
||||
|
||||
class psort_var : public psort {
|
||||
friend class pdecl_manager;
|
||||
unsigned m_idx;
|
||||
psort_var(unsigned id, unsigned num_params, unsigned idx):psort(id, num_params), m_idx(idx) { SASSERT(idx < num_params); }
|
||||
virtual sort * instantiate(pdecl_manager & m, sort * const * s) { return s[m_idx]; }
|
||||
virtual size_t obj_size() const { return sizeof(psort_var); }
|
||||
public:
|
||||
virtual ~psort_var() {}
|
||||
virtual char const * hcons_kind() const { return "psort_var"; }
|
||||
virtual unsigned hcons_hash() const { return hash_u_u(m_num_params, m_idx); }
|
||||
virtual bool hcons_eq(psort const * other) const {
|
||||
if (other->hcons_kind() != hcons_kind())
|
||||
return false;
|
||||
return get_num_params() == other->get_num_params() && m_idx == static_cast<psort_var const *>(other)->m_idx;
|
||||
}
|
||||
virtual void display(std::ostream & out) const {
|
||||
out << "s_" << m_idx;
|
||||
}
|
||||
};
|
||||
|
||||
class psort_app : public psort {
|
||||
friend class pdecl_manager;
|
||||
psort_decl * m_decl;
|
||||
ptr_vector<psort> m_args;
|
||||
|
||||
psort_app(unsigned id, unsigned num_params, pdecl_manager & m, psort_decl * d, unsigned num_args, psort * const * args):
|
||||
psort(id, num_params),
|
||||
m_decl(d),
|
||||
m_args(num_args, args) {
|
||||
m.inc_ref(d);
|
||||
m.inc_ref(num_args, args);
|
||||
SASSERT(num_args == m_decl->get_num_params() || m_decl->has_var_params());
|
||||
DEBUG_CODE(for (unsigned i = 0; i < num_params; i++) args[i]->check_num_params(this););
|
||||
}
|
||||
|
||||
virtual void finalize(pdecl_manager & m) {
|
||||
m.lazy_dec_ref(m_decl);
|
||||
m.lazy_dec_ref(m_args.size(), m_args.c_ptr());
|
||||
psort::finalize(m);
|
||||
}
|
||||
|
||||
virtual size_t obj_size() const { return sizeof(psort_app); }
|
||||
|
||||
struct khasher {
|
||||
unsigned operator()(psort_app const * d) const { return d->m_decl->hash(); }
|
||||
};
|
||||
|
||||
struct chasher {
|
||||
unsigned operator()(psort_app const * d, unsigned idx) const { return d->m_args[idx]->hash(); }
|
||||
};
|
||||
|
||||
virtual sort * instantiate(pdecl_manager & m, sort * const * s) {
|
||||
sort * r = find(s);
|
||||
if (r)
|
||||
return r;
|
||||
sort_ref_buffer args_i(m.m());
|
||||
unsigned sz = m_args.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
sort * a = m_args[i]->instantiate(m, s);
|
||||
args_i.push_back(a);
|
||||
}
|
||||
r = m_decl->instantiate(m, args_i.size(), args_i.c_ptr());
|
||||
cache(m, s, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~psort_app() {}
|
||||
virtual char const * hcons_kind() const { return "psort_app"; }
|
||||
virtual unsigned hcons_hash() const {
|
||||
return get_composite_hash<psort_app*, khasher, chasher>(const_cast<psort_app*>(this), m_args.size());
|
||||
}
|
||||
virtual bool hcons_eq(psort const * other) const {
|
||||
if (other->hcons_kind() != hcons_kind())
|
||||
return false;
|
||||
if (get_num_params() != other->get_num_params())
|
||||
return false;
|
||||
psort_app const * _other = static_cast<psort_app const *>(other);
|
||||
if (m_decl != _other->m_decl)
|
||||
return false;
|
||||
SASSERT(m_args.size() == _other->m_args.size());
|
||||
unsigned sz = m_args.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
if (m_args[i] != _other->m_args[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
virtual void display(std::ostream & out) const {
|
||||
if (m_args.empty()) {
|
||||
out << m_decl->get_name();
|
||||
}
|
||||
else {
|
||||
out << "(" << m_decl->get_name();
|
||||
unsigned sz = m_args.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
out << " ";
|
||||
m_args[i]->display(out);
|
||||
}
|
||||
out << ")";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
psort_decl::psort_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n):
|
||||
pdecl(id, num_params),
|
||||
m_name(n),
|
||||
m_inst_cache(0) {
|
||||
}
|
||||
|
||||
void psort_decl::finalize(pdecl_manager & m) {
|
||||
m.del_inst_cache(m_inst_cache);
|
||||
m_inst_cache = 0;
|
||||
}
|
||||
|
||||
void psort_decl::cache(pdecl_manager & m, sort * const * s, sort * r) {
|
||||
if (!m_inst_cache)
|
||||
m_inst_cache = m.mk_inst_cache(m_num_params);
|
||||
m_inst_cache->insert(m, s, r);
|
||||
}
|
||||
|
||||
sort * psort_decl::find(sort * const * s) {
|
||||
if (!m_inst_cache)
|
||||
return 0;
|
||||
return m_inst_cache->find(s);
|
||||
}
|
||||
|
||||
psort_user_decl::psort_user_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n, psort * p):
|
||||
psort_decl(id, num_params, m, n),
|
||||
m_def(p) {
|
||||
m.inc_ref(p);
|
||||
SASSERT(p == 0 || num_params == p->get_num_params());
|
||||
}
|
||||
|
||||
void psort_user_decl::finalize(pdecl_manager & m) {
|
||||
m.dec_ref(m_def);
|
||||
m_def = 0;
|
||||
psort_decl::finalize(m);
|
||||
}
|
||||
|
||||
sort * psort_user_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * s) {
|
||||
SASSERT(n == m_num_params);
|
||||
sort * r = find(s);
|
||||
if (r)
|
||||
return r;
|
||||
if (m_def == 0) {
|
||||
user_sort_plugin * plugin = m.m().get_user_sort_plugin();
|
||||
buffer<parameter> ps;
|
||||
for (unsigned i = 0; i < n; i++)
|
||||
ps.push_back(parameter(s[i]));
|
||||
decl_kind kind = plugin->register_name(m_name);
|
||||
r = plugin->mk_sort(kind, ps.size(), ps.c_ptr());
|
||||
}
|
||||
else {
|
||||
r = m_def->instantiate(m, s);
|
||||
}
|
||||
cache(m, s, r);
|
||||
m.save_info(r, this, n, s);
|
||||
return r;
|
||||
}
|
||||
|
||||
void display_sort_args(std::ostream & out, unsigned num_params) {
|
||||
if (num_params > 0)
|
||||
out << " (";
|
||||
for (unsigned i = 0; i < num_params; i++) {
|
||||
if (i > 0) out << " ";
|
||||
out << "s_" << i;
|
||||
}
|
||||
if (num_params > 0)
|
||||
out << ") ";
|
||||
}
|
||||
|
||||
void psort_user_decl::display(std::ostream & out) const {
|
||||
out << "(declare-sort " << m_name;
|
||||
display_sort_args(out, m_num_params);
|
||||
if (m_def)
|
||||
m_def->display(out);
|
||||
out << ")";
|
||||
}
|
||||
|
||||
psort_builtin_decl::psort_builtin_decl(unsigned id, pdecl_manager & m, symbol const & n, family_id fid, decl_kind k):
|
||||
psort_decl(id, PSORT_DECL_VAR_PARAMS, m, n),
|
||||
m_fid(fid),
|
||||
m_kind(k) {
|
||||
}
|
||||
|
||||
sort * psort_builtin_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * s) {
|
||||
if (n == 0) {
|
||||
sort * r = m.m().mk_sort(m_fid, m_kind);
|
||||
m.save_info(r, this, 0, s);
|
||||
return r;
|
||||
}
|
||||
else {
|
||||
buffer<parameter> params;
|
||||
for (unsigned i = 0; i < n; i++)
|
||||
params.push_back(parameter(s[i]));
|
||||
sort * r = m.m().mk_sort(m_fid, m_kind, n, params.c_ptr());
|
||||
m.save_info(r, this, n, s);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
sort * psort_builtin_decl::instantiate(pdecl_manager & m, unsigned n, unsigned const * s) {
|
||||
if (n == 0) {
|
||||
sort * r = m.m().mk_sort(m_fid, m_kind);
|
||||
m.save_info(r, this, 0, s);
|
||||
return r;
|
||||
}
|
||||
else {
|
||||
buffer<parameter> params;
|
||||
for (unsigned i = 0; i < n; i++)
|
||||
params.push_back(parameter(s[i]));
|
||||
sort * r = m.m().mk_sort(m_fid, m_kind, n, params.c_ptr());
|
||||
m.save_info(r, this, n, s);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
void psort_builtin_decl::display(std::ostream & out) const {
|
||||
out << "(declare-builtin-sort " << m_name << ")";
|
||||
}
|
||||
|
||||
void ptype::display(std::ostream & out, pdatatype_decl const * const * dts) const {
|
||||
switch (kind()) {
|
||||
case PTR_PSORT: get_psort()->display(out); break;
|
||||
case PTR_REC_REF: out << dts[get_idx()]->get_name(); break;
|
||||
case PTR_MISSING_REF: out << get_missing_ref(); break;
|
||||
}
|
||||
}
|
||||
|
||||
paccessor_decl::paccessor_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n, ptype const & r):
|
||||
pdecl(id, num_params),
|
||||
m_name(n),
|
||||
m_type(r) {
|
||||
if (m_type.kind() == PTR_PSORT)
|
||||
m.inc_ref(r.get_psort());
|
||||
}
|
||||
|
||||
void paccessor_decl::finalize(pdecl_manager & m) {
|
||||
if (m_type.kind() == PTR_PSORT)
|
||||
m.lazy_dec_ref(m_type.get_psort());
|
||||
}
|
||||
|
||||
bool paccessor_decl::has_missing_refs(symbol & missing) const {
|
||||
if (m_type.kind() == PTR_MISSING_REF) {
|
||||
missing = m_type.get_missing_ref();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool paccessor_decl::fix_missing_refs(dictionary<int> const & symbol2idx, symbol & missing) {
|
||||
TRACE("fix_missing_refs", tout << "m_type.kind(): " << m_type.kind() << "\n";
|
||||
if (m_type.kind() == PTR_MISSING_REF) tout << m_type.get_missing_ref() << "\n";);
|
||||
if (m_type.kind() != PTR_MISSING_REF)
|
||||
return true;
|
||||
int idx;
|
||||
if (symbol2idx.find(m_type.get_missing_ref(), idx)) {
|
||||
m_type = ptype(idx);
|
||||
SASSERT(m_type.kind() == PTR_REC_REF);
|
||||
return true;
|
||||
}
|
||||
missing = m_type.get_missing_ref();
|
||||
return false;
|
||||
}
|
||||
|
||||
accessor_decl * paccessor_decl::instantiate_decl(pdecl_manager & m, sort * const * s) {
|
||||
switch (m_type.kind()) {
|
||||
case PTR_REC_REF: return mk_accessor_decl(m_name, type_ref(m_type.get_idx()));
|
||||
case PTR_PSORT: return mk_accessor_decl(m_name, type_ref(m_type.get_psort()->instantiate(m, s)));
|
||||
default:
|
||||
// missing refs must have been eliminated.
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void paccessor_decl::display(std::ostream & out, pdatatype_decl const * const * dts) const {
|
||||
out << "(" << m_name << " ";
|
||||
m_type.display(out, dts);
|
||||
out << ")";
|
||||
}
|
||||
|
||||
pconstructor_decl::pconstructor_decl(unsigned id, unsigned num_params, pdecl_manager & m,
|
||||
symbol const & n, symbol const & r, unsigned num_accessors, paccessor_decl * const * accessors):
|
||||
pdecl(id, num_params),
|
||||
m_name(n),
|
||||
m_recogniser_name(r),
|
||||
m_accessors(num_accessors, accessors) {
|
||||
m.inc_ref(num_accessors, accessors);
|
||||
TRACE("pconstructor_decl", tout << "name: " << n << ", recognizer: " << r << "\n";);
|
||||
}
|
||||
|
||||
void pconstructor_decl::finalize(pdecl_manager & m) {
|
||||
m.lazy_dec_ref(m_accessors.size(), m_accessors.c_ptr());
|
||||
}
|
||||
|
||||
bool pconstructor_decl::has_missing_refs(symbol & missing) const {
|
||||
ptr_vector<paccessor_decl>::const_iterator it = m_accessors.begin();
|
||||
ptr_vector<paccessor_decl>::const_iterator end = m_accessors.end();
|
||||
for (; it != end; ++it) {
|
||||
if ((*it)->has_missing_refs(missing))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool pconstructor_decl::fix_missing_refs(dictionary<int> const & symbol2idx, symbol & missing) {
|
||||
ptr_vector<paccessor_decl>::iterator it = m_accessors.begin();
|
||||
ptr_vector<paccessor_decl>::iterator end = m_accessors.end();
|
||||
for (; it != end; ++it) {
|
||||
if (!(*it)->fix_missing_refs(symbol2idx, missing))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
constructor_decl * pconstructor_decl::instantiate_decl(pdecl_manager & m, sort * const * s) {
|
||||
ptr_buffer<accessor_decl> as;
|
||||
ptr_vector<paccessor_decl>::iterator it = m_accessors.begin();
|
||||
ptr_vector<paccessor_decl>::iterator end = m_accessors.end();
|
||||
for (; it != end; ++it)
|
||||
as.push_back((*it)->instantiate_decl(m, s));
|
||||
return mk_constructor_decl(m_name, m_recogniser_name, as.size(), as.c_ptr());
|
||||
}
|
||||
|
||||
void pconstructor_decl::display(std::ostream & out, pdatatype_decl const * const * dts) const {
|
||||
out << "(" << m_name;
|
||||
ptr_vector<paccessor_decl>::const_iterator it = m_accessors.begin();
|
||||
ptr_vector<paccessor_decl>::const_iterator end = m_accessors.end();
|
||||
for (; it != end; ++it) {
|
||||
out << " ";
|
||||
(*it)->display(out, dts);
|
||||
}
|
||||
out << ")";
|
||||
}
|
||||
|
||||
pdatatype_decl::pdatatype_decl(unsigned id, unsigned num_params, pdecl_manager & m,
|
||||
symbol const & n, unsigned num_constructors, pconstructor_decl * const * constructors):
|
||||
psort_decl(id, num_params, m, n),
|
||||
m_constructors(num_constructors, constructors),
|
||||
m_parent(0) {
|
||||
m.inc_ref(num_constructors, constructors);
|
||||
}
|
||||
|
||||
void pdatatype_decl::finalize(pdecl_manager & m) {
|
||||
m.lazy_dec_ref(m_constructors.size(), m_constructors.c_ptr());
|
||||
psort_decl::finalize(m);
|
||||
}
|
||||
|
||||
bool pdatatype_decl::has_missing_refs(symbol & missing) const {
|
||||
ptr_vector<pconstructor_decl>::const_iterator it = m_constructors.begin();
|
||||
ptr_vector<pconstructor_decl>::const_iterator end = m_constructors.end();
|
||||
for (; it != end; ++it) {
|
||||
if ((*it)->has_missing_refs(missing))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool pdatatype_decl::fix_missing_refs(dictionary<int> const & symbol2idx, symbol & missing) {
|
||||
ptr_vector<pconstructor_decl>::iterator it = m_constructors.begin();
|
||||
ptr_vector<pconstructor_decl>::iterator end = m_constructors.end();
|
||||
for (; it != end; ++it) {
|
||||
if (!(*it)->fix_missing_refs(symbol2idx, missing))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
datatype_decl * pdatatype_decl::instantiate_decl(pdecl_manager & m, sort * const * s) {
|
||||
ptr_buffer<constructor_decl> cs;
|
||||
ptr_vector<pconstructor_decl>::iterator it = m_constructors.begin();
|
||||
ptr_vector<pconstructor_decl>::iterator end = m_constructors.end();
|
||||
for (; it != end; ++it) {
|
||||
cs.push_back((*it)->instantiate_decl(m, s));
|
||||
}
|
||||
return mk_datatype_decl(m_name, cs.size(), cs.c_ptr());
|
||||
}
|
||||
|
||||
struct datatype_decl_buffer {
|
||||
ptr_buffer<datatype_decl> m_buffer;
|
||||
~datatype_decl_buffer() { del_datatype_decls(m_buffer.size(), m_buffer.c_ptr()); }
|
||||
};
|
||||
|
||||
sort * pdatatype_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * s) {
|
||||
SASSERT(m_num_params == n);
|
||||
sort * r = find(s);
|
||||
if (r)
|
||||
return r;
|
||||
if (m_parent != 0) {
|
||||
if (m_parent->instantiate(m, s)) {
|
||||
r = find(s);
|
||||
SASSERT(r);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
else {
|
||||
datatype_decl_buffer dts;
|
||||
dts.m_buffer.push_back(instantiate_decl(m, s));
|
||||
datatype_decl * d_ptr = dts.m_buffer[0];
|
||||
sort_ref_vector sorts(m.m());
|
||||
bool is_ok = m.get_dt_plugin()->mk_datatypes(1, &d_ptr, sorts);
|
||||
TRACE("pdatatype_decl", tout << "instantiating " << m_name << " is_ok: " << is_ok << "\n";);
|
||||
if (is_ok) {
|
||||
r = sorts.get(0);
|
||||
cache(m, s, r);
|
||||
m.save_info(r, this, n, s);
|
||||
m.notify_new_dt(r);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pdatatype_decl::display(std::ostream & out) const {
|
||||
out << "(declare-datatype " << m_name;
|
||||
display_sort_args(out, m_num_params);
|
||||
ptr_vector<pconstructor_decl>::const_iterator it = m_constructors.begin();
|
||||
ptr_vector<pconstructor_decl>::const_iterator end = m_constructors.end();
|
||||
for (bool first = true; it != end; ++it) {
|
||||
if (!first)
|
||||
out << " ";
|
||||
if (m_parent) {
|
||||
(*it)->display(out, m_parent->children());
|
||||
}
|
||||
else {
|
||||
pdatatype_decl const * dts[1] = { this };
|
||||
(*it)->display(out, dts);
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
out << ")";
|
||||
}
|
||||
|
||||
pdatatypes_decl::pdatatypes_decl(unsigned id, unsigned num_params, pdecl_manager & m,
|
||||
unsigned num_datatypes, pdatatype_decl * const * dts):
|
||||
pdecl(id, num_params),
|
||||
m_datatypes(num_datatypes, dts) {
|
||||
m.inc_ref(num_datatypes, dts);
|
||||
|
||||
ptr_vector<pdatatype_decl>::iterator it = m_datatypes.begin();
|
||||
ptr_vector<pdatatype_decl>::iterator end = m_datatypes.end();
|
||||
for (; it != end; ++it) {
|
||||
SASSERT((*it)->m_parent == 0);
|
||||
(*it)->m_parent = this;
|
||||
}
|
||||
}
|
||||
|
||||
void pdatatypes_decl::finalize(pdecl_manager & m) {
|
||||
m.lazy_dec_ref(m_datatypes.size(), m_datatypes.c_ptr());
|
||||
}
|
||||
|
||||
bool pdatatypes_decl::fix_missing_refs(symbol & missing) {
|
||||
TRACE("fix_missing_refs", tout << "pdatatypes_decl::fix_missing_refs\n";);
|
||||
dictionary<int> symbol2idx;
|
||||
ptr_vector<pdatatype_decl>::iterator it = m_datatypes.begin();
|
||||
ptr_vector<pdatatype_decl>::iterator end = m_datatypes.end();
|
||||
for (unsigned idx = 0; it != end; ++it, ++idx)
|
||||
symbol2idx.insert((*it)->get_name(), idx);
|
||||
|
||||
it = m_datatypes.begin();
|
||||
for (unsigned idx = 0; it != end; ++it, ++idx) {
|
||||
if (!(*it)->fix_missing_refs(symbol2idx, missing))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pdatatypes_decl::instantiate(pdecl_manager & m, sort * const * s) {
|
||||
datatype_decl_buffer dts;
|
||||
ptr_vector<pdatatype_decl>::iterator it = m_datatypes.begin();
|
||||
ptr_vector<pdatatype_decl>::iterator end = m_datatypes.end();
|
||||
for (; it != end; ++it) {
|
||||
dts.m_buffer.push_back((*it)->instantiate_decl(m, s));
|
||||
}
|
||||
sort_ref_vector sorts(m.m());
|
||||
bool is_ok = m.get_dt_plugin()->mk_datatypes(dts.m_buffer.size(), dts.m_buffer.c_ptr(), sorts);
|
||||
if (!is_ok)
|
||||
return false;
|
||||
it = m_datatypes.begin();
|
||||
for (unsigned i = 0; it != end; ++it, ++i) {
|
||||
sort * new_dt = sorts.get(i);
|
||||
(*it)->cache(m, s, new_dt);
|
||||
m.save_info(new_dt, *it, m_num_params, s);
|
||||
m.notify_new_dt(new_dt);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
struct pdecl_manager::sort_info {
|
||||
psort_decl * m_decl;
|
||||
|
||||
sort_info(pdecl_manager & m, psort_decl * d):
|
||||
m_decl(d) {
|
||||
m.inc_ref(d);
|
||||
}
|
||||
virtual ~sort_info() {}
|
||||
virtual unsigned obj_size() const { return sizeof(sort_info); }
|
||||
virtual void finalize(pdecl_manager & m) {
|
||||
m.dec_ref(m_decl);
|
||||
}
|
||||
virtual void display(std::ostream & out, pdecl_manager const & m) const = 0;
|
||||
virtual format * pp(pdecl_manager const & m) const = 0;
|
||||
};
|
||||
|
||||
struct pdecl_manager::app_sort_info : public pdecl_manager::sort_info {
|
||||
ptr_vector<sort> m_args;
|
||||
|
||||
app_sort_info(pdecl_manager & m, psort_decl * d, unsigned n, sort * const * s):
|
||||
sort_info(m, d),
|
||||
m_args(n, s) {
|
||||
m.m().inc_array_ref(n, s);
|
||||
}
|
||||
|
||||
virtual ~app_sort_info() {}
|
||||
|
||||
virtual unsigned obj_size() const { return sizeof(app_sort_info); }
|
||||
|
||||
virtual void finalize(pdecl_manager & m) {
|
||||
sort_info::finalize(m);
|
||||
m.m().dec_array_ref(m_args.size(), m_args.c_ptr());
|
||||
}
|
||||
|
||||
virtual void display(std::ostream & out, pdecl_manager const & m) const {
|
||||
if (m_args.empty()) {
|
||||
out << m_decl->get_name();
|
||||
}
|
||||
else {
|
||||
out << "(" << m_decl->get_name();
|
||||
for (unsigned i = 0; i < m_args.size(); i++) {
|
||||
out << " ";
|
||||
m.display(out, m_args[i]);
|
||||
}
|
||||
out << ")";
|
||||
}
|
||||
}
|
||||
|
||||
virtual format * pp(pdecl_manager const & m) const {
|
||||
if (m_args.empty()) {
|
||||
return mk_string(m.m(), m_decl->get_name().str().c_str());
|
||||
}
|
||||
else {
|
||||
ptr_buffer<format> b;
|
||||
for (unsigned i = 0; i < m_args.size(); i++)
|
||||
b.push_back(m.pp(m_args[i]));
|
||||
return mk_seq1(m.m(), b.begin(), b.end(), f2f(), m_decl->get_name().str().c_str());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct pdecl_manager::indexed_sort_info : public pdecl_manager::sort_info {
|
||||
svector<unsigned> m_indices;
|
||||
|
||||
indexed_sort_info(pdecl_manager & m, psort_decl * d, unsigned n, unsigned const * s):
|
||||
sort_info(m, d),
|
||||
m_indices(n, s) {
|
||||
}
|
||||
|
||||
virtual ~indexed_sort_info() {}
|
||||
|
||||
virtual unsigned obj_size() const { return sizeof(indexed_sort_info); }
|
||||
|
||||
virtual void display(std::ostream & out, pdecl_manager const & m) const {
|
||||
if (m_indices.empty()) {
|
||||
out << m_decl->get_name();
|
||||
}
|
||||
else {
|
||||
out << "(_ " << m_decl->get_name();
|
||||
for (unsigned i = 0; i < m_indices.size(); i++) {
|
||||
out << " " << m_indices[i];
|
||||
}
|
||||
out << ")";
|
||||
}
|
||||
}
|
||||
|
||||
virtual format * pp(pdecl_manager const & m) const {
|
||||
if (m_indices.empty()) {
|
||||
return mk_string(m.m(), m_decl->get_name().str().c_str());
|
||||
}
|
||||
else {
|
||||
ptr_buffer<format> b;
|
||||
b.push_back(mk_string(m.m(), m_decl->get_name().str().c_str()));
|
||||
for (unsigned i = 0; i < m_indices.size(); i++)
|
||||
b.push_back(mk_unsigned(m.m(), m_indices[i]));
|
||||
return mk_seq1(m.m(), b.begin(), b.end(), f2f(), "_");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void pdecl_manager::init_list() {
|
||||
SASSERT(m_list == 0);
|
||||
psort * v = mk_psort_var(1, 0);
|
||||
ptype T(v);
|
||||
ptype ListT(0);
|
||||
paccessor_decl * as[2] = { mk_paccessor_decl(1, symbol("head"), T),
|
||||
mk_paccessor_decl(1, symbol("tail"), ListT) };
|
||||
pconstructor_decl * cs[2] = { mk_pconstructor_decl(1, symbol("nil"), symbol("is-nil"), 0, 0),
|
||||
mk_pconstructor_decl(1, symbol("insert"), symbol("is-insert"), 2, as) };
|
||||
m_list = mk_pdatatype_decl(1, symbol("List"), 2, cs);
|
||||
inc_ref(m_list);
|
||||
}
|
||||
|
||||
pdecl_manager::pdecl_manager(ast_manager & m):
|
||||
m_manager(m),
|
||||
m_allocator(m.get_allocator()),
|
||||
m_new_dt_eh(0) {
|
||||
m_list = 0;
|
||||
m_datatype_fid = m.get_family_id("datatype");
|
||||
}
|
||||
|
||||
pdecl_manager::~pdecl_manager() {
|
||||
dec_ref(m_list);
|
||||
reset_sort_info();
|
||||
SASSERT(m_sort2psort.empty());
|
||||
SASSERT(m_table.empty());
|
||||
}
|
||||
|
||||
psort * pdecl_manager::mk_psort_cnst(sort * s) {
|
||||
psort * r = 0;
|
||||
if (m_sort2psort.find(s, r))
|
||||
return r;
|
||||
r = new (a().allocate(sizeof(psort_sort))) psort_sort(m_id_gen.mk(), *this, s);
|
||||
m_sort2psort.insert(s, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
psort * pdecl_manager::register_psort(psort * n) {
|
||||
psort * r = m_table.insert_if_not_there(n);
|
||||
if (r != n) {
|
||||
del_decl_core(n);
|
||||
return r;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
psort * pdecl_manager::mk_psort_var(unsigned num_params, unsigned vidx) {
|
||||
psort_var * n = new (a().allocate(sizeof(psort_var))) psort_var(m_id_gen.mk(), num_params, vidx);
|
||||
return register_psort(n);
|
||||
}
|
||||
|
||||
paccessor_decl * pdecl_manager::mk_paccessor_decl(unsigned num_params, symbol const & s, ptype const & p) {
|
||||
return new (a().allocate(sizeof(paccessor_decl))) paccessor_decl(m_id_gen.mk(), num_params, *this, s, p);
|
||||
}
|
||||
|
||||
pconstructor_decl * pdecl_manager::mk_pconstructor_decl(unsigned num_params,
|
||||
symbol const & s, symbol const & r, unsigned num, paccessor_decl * const * as) {
|
||||
return new (a().allocate(sizeof(pconstructor_decl))) pconstructor_decl(m_id_gen.mk(), num_params, *this,
|
||||
s, r, num, as);
|
||||
}
|
||||
|
||||
pdatatype_decl * pdecl_manager::mk_pdatatype_decl(unsigned num_params, symbol const & s, unsigned num, pconstructor_decl * const * cs) {
|
||||
return new (a().allocate(sizeof(pdatatype_decl))) pdatatype_decl(m_id_gen.mk(), num_params, *this,
|
||||
s, num, cs);
|
||||
}
|
||||
|
||||
pdatatypes_decl * pdecl_manager::mk_pdatatypes_decl(unsigned num_params, unsigned num, pdatatype_decl * const * dts) {
|
||||
return new (a().allocate(sizeof(pdatatypes_decl))) pdatatypes_decl(m_id_gen.mk(), num_params, *this,
|
||||
num, dts);
|
||||
}
|
||||
|
||||
psort * pdecl_manager::mk_psort_app(unsigned num_params, psort_decl * d, unsigned num_args, psort * const * args) {
|
||||
psort * n = new (a().allocate(sizeof(psort_app))) psort_app(m_id_gen.mk(), num_params, *this, d, num_args, args);
|
||||
return register_psort(n);
|
||||
}
|
||||
|
||||
psort * pdecl_manager::mk_psort_app(psort_decl * d) {
|
||||
SASSERT(d->get_num_params() == 0 || d->get_num_params() == PSORT_DECL_VAR_PARAMS);
|
||||
sort * s = d->instantiate(*this, 0, static_cast<sort*const*>(0));
|
||||
if (s == 0)
|
||||
return 0;
|
||||
return mk_psort_cnst(s);
|
||||
}
|
||||
|
||||
psort_decl * pdecl_manager::mk_psort_user_decl(unsigned num_params, symbol const & n, psort * def) {
|
||||
return new (a().allocate(sizeof(psort_user_decl))) psort_user_decl(m_id_gen.mk(), num_params, *this, n, def);
|
||||
}
|
||||
|
||||
psort_decl * pdecl_manager::mk_psort_builtin_decl(symbol const & n, family_id fid, decl_kind k) {
|
||||
return new (a().allocate(sizeof(psort_builtin_decl))) psort_builtin_decl(m_id_gen.mk(), *this, n, fid, k);
|
||||
}
|
||||
|
||||
sort * pdecl_manager::instantiate(psort * p, unsigned num, sort * const * args) {
|
||||
// ignoring stack overflows... sorts are not deeply nested
|
||||
return p->instantiate(*this, args);
|
||||
}
|
||||
|
||||
void pdecl_manager::del_decl_core(pdecl * p) {
|
||||
TRACE("pdecl_manager",
|
||||
tout << "del_decl_core:\n";
|
||||
if (p->is_psort()) static_cast<psort*>(p)->display(tout);
|
||||
else static_cast<psort_decl*>(p)->display(tout);
|
||||
tout << "\n";);
|
||||
size_t sz = p->obj_size();
|
||||
m_id_gen.recycle(p->get_id());
|
||||
p->finalize(*this);
|
||||
p->~pdecl();
|
||||
m_allocator.deallocate(sz, p);
|
||||
}
|
||||
|
||||
void pdecl_manager::del_decl(pdecl * p) {
|
||||
if (p->is_psort()) {
|
||||
psort * _p = static_cast<psort*>(p);
|
||||
if (_p->is_sort_wrapper())
|
||||
m_sort2psort.erase(static_cast<psort_sort*>(_p)->get_sort());
|
||||
else
|
||||
m_table.erase(_p);
|
||||
}
|
||||
del_decl_core(p);
|
||||
}
|
||||
|
||||
void pdecl_manager::del_decls() {
|
||||
while (!m_to_delete.empty()) {
|
||||
pdecl * p = m_to_delete.back();
|
||||
m_to_delete.pop_back();
|
||||
del_decl(p);
|
||||
}
|
||||
}
|
||||
|
||||
psort_inst_cache * pdecl_manager::mk_inst_cache(unsigned num_params) {
|
||||
return new (a().allocate(sizeof(psort_inst_cache))) psort_inst_cache(num_params);
|
||||
}
|
||||
|
||||
void pdecl_manager::del_inst_cache(psort_inst_cache * c) {
|
||||
if (c) {
|
||||
c->finalize(*this);
|
||||
c->~psort_inst_cache();
|
||||
a().deallocate(sizeof(psort_inst_cache), c);
|
||||
}
|
||||
}
|
||||
|
||||
datatype_decl_plugin * pdecl_manager::get_dt_plugin() const {
|
||||
return static_cast<datatype_decl_plugin*>(m().get_plugin(m_datatype_fid));
|
||||
}
|
||||
|
||||
void pdecl_manager::save_info(sort * s, psort_decl * d, unsigned num_args, sort * const * args) {
|
||||
if (m_sort2info.contains(s))
|
||||
return;
|
||||
sort_info * info = new (a().allocate(sizeof(app_sort_info))) app_sort_info(*this, d, num_args, args);
|
||||
m().inc_ref(s);
|
||||
m_sort2info.insert(s, info);
|
||||
}
|
||||
|
||||
void pdecl_manager::save_info(sort * s, psort_decl * d, unsigned num_indices, unsigned const * indices) {
|
||||
if (m_sort2info.contains(s))
|
||||
return;
|
||||
sort_info * info = new (a().allocate(sizeof(indexed_sort_info))) indexed_sort_info(*this, d, num_indices, indices);
|
||||
m().inc_ref(s);
|
||||
m_sort2info.insert(s, info);
|
||||
}
|
||||
|
||||
void pdecl_manager::reset_sort_info() {
|
||||
obj_map<sort, sort_info *>::iterator it = m_sort2info.begin();
|
||||
obj_map<sort, sort_info *>::iterator end = m_sort2info.end();
|
||||
for (; it != end; ++it) {
|
||||
sort * s = (*it).m_key;
|
||||
sort_info * info = (*it).m_value;
|
||||
m().dec_ref(s);
|
||||
unsigned sz = info->obj_size();
|
||||
info->finalize(*this);
|
||||
info->~sort_info();
|
||||
m_allocator.deallocate(sz, info);
|
||||
}
|
||||
m_sort2info.reset();
|
||||
}
|
||||
|
||||
void pdecl_manager::display(std::ostream & out, sort * s) const {
|
||||
sort_info * info = 0;
|
||||
if (m_sort2info.find(s, info)) {
|
||||
info->display(out, *this);
|
||||
return;
|
||||
}
|
||||
out << s->get_name();
|
||||
}
|
||||
|
||||
format * pdecl_manager::pp(sort * s) const {
|
||||
sort_info * info = 0;
|
||||
if (m_sort2info.find(s, info)) {
|
||||
return info->pp(*this);
|
||||
}
|
||||
unsigned num_params = s->get_num_parameters();
|
||||
if (s->get_family_id() != null_family_id && num_params > 0) {
|
||||
// Small hack to display FP and BitVec sorts that were not explicitly referenced by the user.
|
||||
unsigned i = 0;
|
||||
for (i = 0; i < num_params; i++) {
|
||||
if (!s->get_parameter(i).is_int())
|
||||
break;
|
||||
}
|
||||
if (i == num_params) {
|
||||
// all parameters are integer
|
||||
ptr_buffer<format> b;
|
||||
b.push_back(mk_string(m(), s->get_name().str().c_str()));
|
||||
for (unsigned i = 0; i < num_params; i++)
|
||||
b.push_back(mk_unsigned(m(), s->get_parameter(i).get_int()));
|
||||
return mk_seq1(m(), b.begin(), b.end(), f2f(), "_");
|
||||
}
|
||||
}
|
||||
return mk_string(m(), s->get_name().str().c_str());
|
||||
}
|
329
lib/pdecl.h
329
lib/pdecl.h
|
@ -1,329 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
pdecl.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Parametric declarations for SMT-LIB 2.0 + inductive data-types.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2011-03-02.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _PDECL_H_
|
||||
#define _PDECL_H_
|
||||
|
||||
#include"ast.h"
|
||||
#include"obj_hashtable.h"
|
||||
#include"dictionary.h"
|
||||
#include"format.h"
|
||||
|
||||
class pdecl_manager;
|
||||
|
||||
class pdecl {
|
||||
protected:
|
||||
friend class pdecl_manager;
|
||||
unsigned m_id;
|
||||
unsigned m_num_params;
|
||||
unsigned m_ref_count;
|
||||
void inc_ref() { m_ref_count++; }
|
||||
void dec_ref() { SASSERT(m_ref_count > 0); --m_ref_count; }
|
||||
virtual bool is_psort() const { return false; }
|
||||
virtual size_t obj_size() const = 0;
|
||||
pdecl(unsigned id, unsigned num_params):m_id(id), m_num_params(num_params), m_ref_count(0) {}
|
||||
virtual void finalize(pdecl_manager & m) {}
|
||||
virtual ~pdecl() {}
|
||||
public:
|
||||
virtual bool check_num_params(pdecl * other) const { return m_num_params == other->m_num_params; }
|
||||
unsigned get_num_params() const { return m_num_params; }
|
||||
unsigned get_id() const { return m_id; }
|
||||
unsigned get_ref_count() const { return m_ref_count; }
|
||||
unsigned hash() const { return m_id; }
|
||||
virtual void display(std::ostream & out) const {}
|
||||
};
|
||||
|
||||
class psort_inst_cache;
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
// CMW: for some unknown reason, llvm on OSX does not like the name `psort'
|
||||
#define psort Z3_psort
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief Parametric sorts.
|
||||
*/
|
||||
class psort : public pdecl {
|
||||
protected:
|
||||
psort_inst_cache * m_inst_cache;
|
||||
friend class pdecl_manager;
|
||||
psort(unsigned id, unsigned num_params):pdecl(id, num_params), m_inst_cache(0) {}
|
||||
virtual bool is_psort() const { return true; }
|
||||
virtual void finalize(pdecl_manager & m);
|
||||
virtual ~psort() {}
|
||||
virtual void cache(pdecl_manager & m, sort * const * s, sort * r);
|
||||
virtual sort * find(sort * const * s) const;
|
||||
public:
|
||||
virtual bool is_sort_wrapper() const { return false; }
|
||||
virtual sort * instantiate(pdecl_manager & m, sort * const * s) { return 0; }
|
||||
// we use hash-consing for psorts.
|
||||
virtual char const * hcons_kind() const = 0;
|
||||
virtual unsigned hcons_hash() const = 0;
|
||||
virtual bool hcons_eq(psort const * other) const = 0;
|
||||
};
|
||||
|
||||
// for hash consing
|
||||
struct psort_hash_proc { unsigned operator()(psort * p) const { return p->hcons_hash(); } };
|
||||
struct psort_eq_proc { bool operator()(psort * p1, psort * p2) const { return p1->hcons_eq(p2); } };
|
||||
typedef ptr_hashtable<psort, psort_hash_proc, psort_eq_proc> psort_table;
|
||||
|
||||
#define PSORT_DECL_VAR_PARAMS UINT_MAX
|
||||
|
||||
class psort_decl : public pdecl {
|
||||
protected:
|
||||
friend class pdecl_manager;
|
||||
symbol m_name;
|
||||
psort_inst_cache * m_inst_cache;
|
||||
void cache(pdecl_manager & m, sort * const * s, sort * r);
|
||||
sort * find(sort * const * s);
|
||||
psort_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n);
|
||||
virtual void finalize(pdecl_manager & m);
|
||||
virtual ~psort_decl() {}
|
||||
public:
|
||||
virtual sort * instantiate(pdecl_manager & m, unsigned n, sort * const * s) = 0;
|
||||
virtual sort * instantiate(pdecl_manager & m, unsigned n, unsigned const * s) { return 0; }
|
||||
virtual sort * instantiate(pdecl_manager & m) { return instantiate(m, 0, static_cast<sort*const*>(0)); }
|
||||
// return true if the declaration accepts a variable number of parameters.
|
||||
// Only builtin declarations can have a variable number of parameters.
|
||||
bool has_var_params() const { return m_num_params == PSORT_DECL_VAR_PARAMS; }
|
||||
symbol const & get_name() const { return m_name; }
|
||||
};
|
||||
|
||||
class psort_user_decl : public psort_decl {
|
||||
protected:
|
||||
friend class pdecl_manager;
|
||||
psort * m_def;
|
||||
psort_user_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n, psort * p);
|
||||
virtual size_t obj_size() const { return sizeof(psort_user_decl); }
|
||||
virtual void finalize(pdecl_manager & m);
|
||||
virtual ~psort_user_decl() {}
|
||||
public:
|
||||
virtual sort * instantiate(pdecl_manager & m, unsigned n, sort * const * s);
|
||||
virtual void display(std::ostream & out) const;
|
||||
};
|
||||
|
||||
class psort_builtin_decl : public psort_decl {
|
||||
protected:
|
||||
friend class pdecl_manager;
|
||||
family_id m_fid;
|
||||
decl_kind m_kind;
|
||||
psort_builtin_decl(unsigned id, pdecl_manager & m, symbol const & n, family_id fid, decl_kind k);
|
||||
virtual size_t obj_size() const { return sizeof(psort_builtin_decl); }
|
||||
virtual ~psort_builtin_decl() {}
|
||||
public:
|
||||
virtual sort * instantiate(pdecl_manager & m, unsigned n, sort * const * s);
|
||||
virtual sort * instantiate(pdecl_manager & m, unsigned n, unsigned const * s);
|
||||
virtual void display(std::ostream & out) const;
|
||||
};
|
||||
|
||||
class datatype_decl_plugin;
|
||||
class datatype_decl;
|
||||
class constructor_decl;
|
||||
class accessor_decl;
|
||||
|
||||
class pdatatypes_decl;
|
||||
class pdatatype_decl;
|
||||
class pconstructor_decl;
|
||||
class paccessor_decl;
|
||||
|
||||
enum ptype_kind {
|
||||
PTR_PSORT, // psort
|
||||
PTR_REC_REF, // recursive reference
|
||||
PTR_MISSING_REF // a symbol, it is useful for building parsers.
|
||||
};
|
||||
|
||||
class ptype {
|
||||
ptype_kind m_kind;
|
||||
union {
|
||||
psort * m_sort;
|
||||
int m_idx;
|
||||
};
|
||||
symbol m_missing_ref;
|
||||
public:
|
||||
ptype():m_kind(PTR_PSORT), m_sort(0) {}
|
||||
ptype(int idx):m_kind(PTR_REC_REF), m_idx(idx) {}
|
||||
ptype(psort * s):m_kind(PTR_PSORT), m_sort(s) {}
|
||||
ptype(symbol const & s):m_kind(PTR_MISSING_REF), m_missing_ref(s) {}
|
||||
ptype_kind kind() const { return m_kind; }
|
||||
psort * get_psort() const { SASSERT(kind() == PTR_PSORT); return m_sort; }
|
||||
int get_idx() const { SASSERT(kind() == PTR_REC_REF); return m_idx; }
|
||||
symbol const & get_missing_ref() const { SASSERT(kind() == PTR_MISSING_REF); return m_missing_ref; }
|
||||
void display(std::ostream & out, pdatatype_decl const * const * dts) const;
|
||||
};
|
||||
|
||||
class paccessor_decl : public pdecl {
|
||||
friend class pdecl_manager;
|
||||
friend class pconstructor_decl;
|
||||
symbol m_name;
|
||||
ptype m_type;
|
||||
paccessor_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n, ptype const & r);
|
||||
virtual void finalize(pdecl_manager & m);
|
||||
virtual size_t obj_size() const { return sizeof(paccessor_decl); }
|
||||
bool has_missing_refs(symbol & missing) const;
|
||||
bool fix_missing_refs(dictionary<int> const & symbol2idx, symbol & missing);
|
||||
accessor_decl * instantiate_decl(pdecl_manager & m, sort * const * s);
|
||||
symbol const & get_name() const { return m_name; }
|
||||
ptype const & get_type() const { return m_type; }
|
||||
virtual ~paccessor_decl() {}
|
||||
public:
|
||||
void display(std::ostream & out, pdatatype_decl const * const * dts) const;
|
||||
};
|
||||
|
||||
class pconstructor_decl : public pdecl {
|
||||
friend class pdecl_manager;
|
||||
friend class pdatatype_decl;
|
||||
symbol m_name;
|
||||
symbol m_recogniser_name;
|
||||
ptr_vector<paccessor_decl> m_accessors;
|
||||
pconstructor_decl(unsigned id, unsigned num_params, pdecl_manager & m,
|
||||
symbol const & n, symbol const & r, unsigned num_accessors, paccessor_decl * const * accessors);
|
||||
virtual void finalize(pdecl_manager & m);
|
||||
virtual size_t obj_size() const { return sizeof(pconstructor_decl); }
|
||||
bool has_missing_refs(symbol & missing) const;
|
||||
bool fix_missing_refs(dictionary<int> const & symbol2idx, symbol & missing);
|
||||
symbol const & get_name() const { return m_name; }
|
||||
symbol const & get_recognizer_name() const { return m_recogniser_name; }
|
||||
constructor_decl * instantiate_decl(pdecl_manager & m, sort * const * s);
|
||||
virtual ~pconstructor_decl() {}
|
||||
public:
|
||||
void display(std::ostream & out, pdatatype_decl const * const * dts) const;
|
||||
};
|
||||
|
||||
class pdatatype_decl : public psort_decl {
|
||||
friend class pdecl_manager;
|
||||
friend class pdatatypes_decl;
|
||||
ptr_vector<pconstructor_decl> m_constructors;
|
||||
pdatatypes_decl * m_parent;
|
||||
pdatatype_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n,
|
||||
unsigned num_constructors, pconstructor_decl * const * constructors);
|
||||
virtual void finalize(pdecl_manager & m);
|
||||
virtual size_t obj_size() const { return sizeof(pdatatype_decl); }
|
||||
bool fix_missing_refs(dictionary<int> const & symbol2idx, symbol & missing);
|
||||
datatype_decl * instantiate_decl(pdecl_manager & m, sort * const * s);
|
||||
virtual ~pdatatype_decl() {}
|
||||
public:
|
||||
sort * instantiate(pdecl_manager & m, unsigned n, sort * const * s);
|
||||
virtual void display(std::ostream & out) const;
|
||||
bool has_missing_refs(symbol & missing) const;
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Represents a set of parametric mutually recursive inductive data-types.
|
||||
*/
|
||||
class pdatatypes_decl : public pdecl {
|
||||
friend class pdecl_manager;
|
||||
friend class pdatatype_decl;
|
||||
ptr_vector<pdatatype_decl> m_datatypes;
|
||||
pdatatypes_decl(unsigned id, unsigned num_params, pdecl_manager & m, unsigned num_datatypes, pdatatype_decl * const * dts);
|
||||
virtual void finalize(pdecl_manager & m);
|
||||
virtual size_t obj_size() const { return sizeof(pdatatypes_decl); }
|
||||
bool fix_missing_refs(symbol & missing);
|
||||
bool instantiate(pdecl_manager & m, sort * const * s);
|
||||
virtual ~pdatatypes_decl() {}
|
||||
public:
|
||||
pdatatype_decl const * const * children() const { return m_datatypes.c_ptr(); }
|
||||
};
|
||||
|
||||
class new_datatype_eh {
|
||||
public:
|
||||
virtual ~new_datatype_eh() {}
|
||||
virtual void operator()(sort * dt) = 0;
|
||||
};
|
||||
|
||||
class pdecl_manager {
|
||||
ast_manager & m_manager;
|
||||
small_object_allocator & m_allocator;
|
||||
id_gen m_id_gen;
|
||||
obj_map<sort, psort *> m_sort2psort;
|
||||
psort_table m_table;
|
||||
ptr_vector<pdecl> m_to_delete;
|
||||
pdatatype_decl * m_list;
|
||||
family_id m_datatype_fid;
|
||||
new_datatype_eh * m_new_dt_eh;
|
||||
|
||||
struct sort_info;
|
||||
struct app_sort_info;
|
||||
struct indexed_sort_info;
|
||||
|
||||
obj_map<sort, sort_info *> m_sort2info; // for pretty printing sorts
|
||||
|
||||
void init_list();
|
||||
void del_decl_core(pdecl * p);
|
||||
void del_decl(pdecl * p);
|
||||
void del_decls();
|
||||
psort * register_psort(psort * n);
|
||||
void reset_sort_info();
|
||||
public:
|
||||
pdecl_manager(ast_manager & m);
|
||||
~pdecl_manager();
|
||||
ast_manager & m() const { return m_manager; }
|
||||
small_object_allocator & a() const { return m_allocator; }
|
||||
family_id get_datatype_fid() const { return m_datatype_fid; }
|
||||
void set_new_datatype_eh(new_datatype_eh * eh) { m_new_dt_eh = eh; }
|
||||
psort * mk_psort_cnst(sort * s);
|
||||
psort * mk_psort_var(unsigned num_params, unsigned vidx);
|
||||
psort * mk_psort_app(unsigned num_params, psort_decl * d, unsigned num_args, psort * const * args);
|
||||
psort * mk_psort_app(psort_decl * d);
|
||||
psort_decl * mk_psort_user_decl(unsigned num_params, symbol const & n, psort * def);
|
||||
psort_decl * mk_psort_builtin_decl(symbol const & n, family_id fid, decl_kind k);
|
||||
paccessor_decl * mk_paccessor_decl(unsigned num_params, symbol const & s, ptype const & p);
|
||||
pconstructor_decl * mk_pconstructor_decl(unsigned num_params, symbol const & s, symbol const & r, unsigned num, paccessor_decl * const * as);
|
||||
pdatatype_decl * mk_pdatatype_decl(unsigned num_params, symbol const & s, unsigned num, pconstructor_decl * const * cs);
|
||||
pdatatypes_decl * mk_pdatatypes_decl(unsigned num_params, unsigned num, pdatatype_decl * const * dts);
|
||||
pdatatype_decl * mk_plist_decl() { if (!m_list) init_list(); return m_list; }
|
||||
bool fix_missing_refs(pdatatypes_decl * s, symbol & missing) { return s->fix_missing_refs(missing); }
|
||||
sort * instantiate(psort * s, unsigned num, sort * const * args);
|
||||
|
||||
void lazy_dec_ref(pdecl * p) { p->dec_ref(); if (p->get_ref_count() == 0) m_to_delete.push_back(p); }
|
||||
template<typename T>
|
||||
void lazy_dec_ref(unsigned num, T * const * ps) { for (unsigned i = 0; i < num; i++) lazy_dec_ref(ps[i]); }
|
||||
void inc_ref(pdecl * p) { if (p) { p->inc_ref(); } }
|
||||
void dec_ref(pdecl * p) { if (p) { lazy_dec_ref(p); del_decls(); } }
|
||||
template<typename T>
|
||||
void inc_ref(unsigned num, T * const * ps) { for (unsigned i = 0; i < num; i++) inc_ref(ps[i]); }
|
||||
template<typename T>
|
||||
void dec_ref(unsigned num, T * const * ps) { lazy_dec_ref(num, ps); del_decls(); }
|
||||
psort_inst_cache * mk_inst_cache(unsigned num_params);
|
||||
void del_inst_cache(psort_inst_cache * c);
|
||||
void notify_new_dt(sort * dt) { if (m_new_dt_eh) (*m_new_dt_eh)(dt); }
|
||||
datatype_decl_plugin * get_dt_plugin() const;
|
||||
|
||||
void save_info(sort * s, psort_decl * d, unsigned num_args, sort * const * args);
|
||||
void save_info(sort * s, psort_decl * d, unsigned num_indices, unsigned const * indices);
|
||||
void display(std::ostream & out, sort * s) const;
|
||||
format_ns::format * pp(sort * s) const;
|
||||
};
|
||||
|
||||
|
||||
typedef obj_ref<pdecl, pdecl_manager> pdecl_ref;
|
||||
typedef obj_ref<psort, pdecl_manager> psort_ref;
|
||||
typedef obj_ref<paccessor_decl, pdecl_manager> paccessor_decl_ref;
|
||||
typedef obj_ref<pconstructor_decl, pdecl_manager> pconstructor_decl_ref;
|
||||
typedef obj_ref<pdatatype_decl, pdecl_manager> pdatatype_decl_ref;
|
||||
typedef obj_ref<pdatatypes_decl, pdecl_manager> pdatatypes_decl_ref;
|
||||
|
||||
typedef ref_vector<pdecl, pdecl_manager> pdecl_ref_vector;
|
||||
typedef ref_vector<psort_decl, pdecl_manager> psort_decl_ref_vector;
|
||||
typedef ref_vector<psort, pdecl_manager> psort_ref_vector;
|
||||
|
||||
typedef ref_buffer<paccessor_decl, pdecl_manager> paccessor_decl_ref_buffer;
|
||||
typedef ref_buffer<pconstructor_decl, pdecl_manager> pconstructor_decl_ref_buffer;
|
||||
typedef ref_buffer<pdatatype_decl, pdecl_manager> pdatatype_decl_ref_buffer;
|
||||
typedef ref_buffer<pdatatypes_decl, pdecl_manager> pdatatypes_decl_ref_buffer;
|
||||
|
||||
#endif
|
|
@ -1,140 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
preprocessor_params.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Preprocess AST before adding them to the logical context
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-01-17.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _PREPROCESSOR_PARAMS_H_
|
||||
#define _PREPROCESSOR_PARAMS_H_
|
||||
|
||||
#include"nnf_params.h"
|
||||
#include"cnf_params.h"
|
||||
#include"pattern_inference_params.h"
|
||||
#include"bit_blaster_params.h"
|
||||
#include"bv_simplifier_params.h"
|
||||
|
||||
enum lift_ite_kind {
|
||||
LI_NONE,
|
||||
LI_CONSERVATIVE,
|
||||
LI_FULL
|
||||
};
|
||||
|
||||
enum q_arith_kind {
|
||||
QA_NONE,
|
||||
QA_COOPER,
|
||||
QA_OMEGA,
|
||||
QA_ALTERNATE
|
||||
};
|
||||
|
||||
struct preprocessor_params : public nnf_params, public cnf_params, public pattern_inference_params,
|
||||
public bit_blaster_params, public bv_simplifier_params {
|
||||
lift_ite_kind m_lift_ite;
|
||||
lift_ite_kind m_ng_lift_ite; // lift ite for non ground terms
|
||||
bool m_pull_cheap_ite_trees;
|
||||
bool m_pull_nested_quantifiers;
|
||||
bool m_eliminate_term_ite;
|
||||
bool m_eliminate_and; // represent (and a b) as (not (or (not a) (not b)))
|
||||
bool m_reverse_implies; // translate (implies a b) into (or b (not a))
|
||||
bool m_macro_finder;
|
||||
bool m_solver;
|
||||
bool m_propagate_values;
|
||||
bool m_propagate_booleans;
|
||||
bool m_context_simplifier;
|
||||
bool m_strong_context_simplifier;
|
||||
bool m_refine_inj_axiom;
|
||||
bool m_eliminate_bounds;
|
||||
bool m_quant_elim;
|
||||
bool m_nlquant_elim;
|
||||
bool m_der;
|
||||
bool m_simplify_bit2int;
|
||||
bool m_nnf_cnf;
|
||||
bool m_distribute_forall;
|
||||
bool m_reduce_args;
|
||||
bool m_pre_demod;
|
||||
bool m_quasi_macros;
|
||||
bool m_restricted_quasi_macros;
|
||||
bool m_max_bv_sharing;
|
||||
bool m_pre_simplifier;
|
||||
|
||||
public:
|
||||
preprocessor_params():
|
||||
m_lift_ite(LI_NONE),
|
||||
m_ng_lift_ite(LI_NONE),
|
||||
m_pull_cheap_ite_trees(false),
|
||||
m_pull_nested_quantifiers(false),
|
||||
m_eliminate_term_ite(false),
|
||||
m_eliminate_and(true),
|
||||
m_macro_finder(false),
|
||||
m_solver(false),
|
||||
m_propagate_values(true),
|
||||
m_propagate_booleans(false), // TODO << check peformance
|
||||
m_context_simplifier(false),
|
||||
m_strong_context_simplifier(false),
|
||||
m_refine_inj_axiom(true),
|
||||
m_eliminate_bounds(false),
|
||||
m_quant_elim(false),
|
||||
m_nlquant_elim(false),
|
||||
m_der(false),
|
||||
m_simplify_bit2int(false),
|
||||
m_nnf_cnf(true),
|
||||
m_distribute_forall(false),
|
||||
m_reduce_args(false),
|
||||
m_pre_demod(false),
|
||||
m_quasi_macros(false),
|
||||
m_restricted_quasi_macros(false),
|
||||
m_max_bv_sharing(true),
|
||||
m_pre_simplifier(true) {
|
||||
}
|
||||
|
||||
void register_params(ini_params & p) {
|
||||
nnf_params::register_params(p);
|
||||
cnf_params::register_params(p);
|
||||
pattern_inference_params::register_params(p);
|
||||
bit_blaster_params::register_params(p);
|
||||
bv_simplifier_params::register_params(p);
|
||||
p.register_int_param("LIFT_ITE", 0, 2, reinterpret_cast<int&>(m_lift_ite), "ite term lifting: 0 - no lifting, 1 - conservative, 2 - full");
|
||||
p.register_int_param("NG_LIFT_ITE", 0, 2, reinterpret_cast<int&>(m_ng_lift_ite), "ite (non-ground) term lifting: 0 - no lifting, 1 - conservative, 2 - full");
|
||||
p.register_bool_param("ELIM_TERM_ITE", m_eliminate_term_ite, "eliminate term if-then-else in the preprocessor");
|
||||
p.register_bool_param("ELIM_AND", m_eliminate_and, "represent (and a b) as (not (or (not a) (not b)))");
|
||||
p.register_bool_param("MACRO_FINDER", m_macro_finder, "try to find universally quantified formulas that can be viewed as macros");
|
||||
p.register_bool_param("SOLVER", m_solver, "enable solver during preprocessing step", true);
|
||||
p.register_bool_param("PROPAGATE_VALUES", m_propagate_values, "propagate values during preprocessing step");
|
||||
p.register_bool_param("PROPAGATE_BOOLEANS", m_propagate_booleans, "propagate boolean values during preprocessing step");
|
||||
p.register_bool_param("PULL_CHEAP_ITE_TREES", m_pull_cheap_ite_trees);
|
||||
p.register_bool_param("PULL_NESTED_QUANTIFIERS", m_pull_nested_quantifiers, "eliminate nested quantifiers by moving nested quantified variables to the outermost quantifier, it is unnecessary if the formula is converted into CNF");
|
||||
p.register_bool_param("CONTEXT_SIMPLIFIER", m_context_simplifier,
|
||||
"Simplify Boolean sub-expressions if they already appear in context", true);
|
||||
p.register_bool_param("STRONG_CONTEXT_SIMPLIFIER", m_strong_context_simplifier,
|
||||
"Simplify Boolean sub-expressions by using full satisfiability queries", true);
|
||||
p.register_bool_param("REFINE_INJ_AXIOM", m_refine_inj_axiom);
|
||||
p.register_bool_param("ELIM_BOUNDS", m_eliminate_bounds, "cheap Fourier-Motzkin");
|
||||
|
||||
p.register_bool_param("ELIM_QUANTIFIERS", m_quant_elim,
|
||||
"Use quantifier elimination procedures on Boolean, Bit-vector, Arithmetic and Array variables", true);
|
||||
p.register_bool_param("ELIM_NLARITH_QUANTIFIERS", m_nlquant_elim,
|
||||
"Eliminate non-linear quantifiers", true);
|
||||
p.register_bool_param("DER", m_der);
|
||||
p.register_bool_param("BIT2INT", m_simplify_bit2int, "hoist bit2int conversions over arithmetical expressions");
|
||||
p.register_bool_param("DISTRIBUTE_FORALL", m_distribute_forall);
|
||||
p.register_bool_param("REDUCE_ARGS", m_reduce_args);
|
||||
p.register_bool_param("PRE_DEMODULATOR", m_pre_demod, "apply demodulators during preprocessing step");
|
||||
p.register_bool_param("QUASI_MACROS", m_quasi_macros);
|
||||
p.register_bool_param("RESTRICTED_QUASI_MACROS", m_restricted_quasi_macros);
|
||||
p.register_bool_param("BV_MAX_SHARING", m_max_bv_sharing);
|
||||
p.register_bool_param("PRE_SIMPLIFIER", m_pre_simplifier);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _PREPROCESSOR_PARAMS_H_ */
|
449
lib/probe.cpp
449
lib/probe.cpp
|
@ -1,449 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
probe.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Evaluates/Probes a goal.
|
||||
|
||||
A probe is used to build tactics (aka strategies) that
|
||||
makes decisions based on the structure of a goal.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2011-10-13.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"probe.h"
|
||||
#include"arith_decl_plugin.h"
|
||||
#include"bv_decl_plugin.h"
|
||||
#include"goal_util.h"
|
||||
|
||||
class memory_probe : public probe {
|
||||
public:
|
||||
virtual result operator()(goal const & g) {
|
||||
return result(static_cast<double>(memory::get_allocation_size())/static_cast<double>(1024*1024));
|
||||
}
|
||||
};
|
||||
|
||||
probe * mk_memory_probe() {
|
||||
return alloc(memory_probe);
|
||||
}
|
||||
|
||||
class depth_probe : public probe {
|
||||
public:
|
||||
virtual result operator()(goal const & g) {
|
||||
return result(g.depth());
|
||||
}
|
||||
};
|
||||
|
||||
class size_probe : public probe {
|
||||
public:
|
||||
virtual result operator()(goal const & g) {
|
||||
return result(g.size());
|
||||
}
|
||||
};
|
||||
|
||||
class num_exprs_probe : public probe {
|
||||
public:
|
||||
virtual result operator()(goal const & g) {
|
||||
return result(g.num_exprs());
|
||||
}
|
||||
};
|
||||
|
||||
probe * mk_depth_probe() {
|
||||
return alloc(depth_probe);
|
||||
}
|
||||
|
||||
probe * mk_size_probe() {
|
||||
return alloc(size_probe);
|
||||
}
|
||||
|
||||
probe * mk_num_exprs_probe() {
|
||||
return alloc(num_exprs_probe);
|
||||
}
|
||||
|
||||
class unary_probe : public probe {
|
||||
protected:
|
||||
probe * m_p;
|
||||
public:
|
||||
unary_probe(probe * p):
|
||||
m_p(p) {
|
||||
SASSERT(p);
|
||||
p->inc_ref();
|
||||
}
|
||||
|
||||
~unary_probe() {
|
||||
m_p->dec_ref();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class bin_probe : public probe {
|
||||
protected:
|
||||
probe * m_p1;
|
||||
probe * m_p2;
|
||||
public:
|
||||
bin_probe(probe * p1, probe * p2):
|
||||
m_p1(p1),
|
||||
m_p2(p2) {
|
||||
SASSERT(p1);
|
||||
SASSERT(p2);
|
||||
p1->inc_ref();
|
||||
p2->inc_ref();
|
||||
}
|
||||
|
||||
~bin_probe() {
|
||||
m_p1->dec_ref();
|
||||
m_p2->dec_ref();
|
||||
}
|
||||
};
|
||||
|
||||
class not_probe : public unary_probe {
|
||||
public:
|
||||
not_probe(probe * p):unary_probe(p) {}
|
||||
virtual result operator()(goal const & g) {
|
||||
return result(!m_p->operator()(g).is_true());
|
||||
}
|
||||
};
|
||||
|
||||
class and_probe : public bin_probe {
|
||||
public:
|
||||
and_probe(probe * p1, probe * p2):bin_probe(p1, p2) {}
|
||||
virtual result operator()(goal const & g) {
|
||||
return result(m_p1->operator()(g).is_true() && m_p2->operator()(g).is_true());
|
||||
}
|
||||
};
|
||||
|
||||
class or_probe : public bin_probe {
|
||||
public:
|
||||
or_probe(probe * p1, probe * p2):bin_probe(p1, p2) {}
|
||||
virtual result operator()(goal const & g) {
|
||||
return result(m_p1->operator()(g).is_true() || m_p2->operator()(g).is_true());
|
||||
}
|
||||
};
|
||||
|
||||
class eq_probe : public bin_probe {
|
||||
public:
|
||||
eq_probe(probe * p1, probe * p2):bin_probe(p1, p2) {}
|
||||
virtual result operator()(goal const & g) {
|
||||
return result(m_p1->operator()(g).get_value() == m_p2->operator()(g).get_value());
|
||||
}
|
||||
};
|
||||
|
||||
class le_probe : public bin_probe {
|
||||
public:
|
||||
le_probe(probe * p1, probe * p2):bin_probe(p1, p2) {}
|
||||
virtual result operator()(goal const & g) {
|
||||
return result(m_p1->operator()(g).get_value() <= m_p2->operator()(g).get_value());
|
||||
}
|
||||
};
|
||||
|
||||
class add_probe : public bin_probe {
|
||||
public:
|
||||
add_probe(probe * p1, probe * p2):bin_probe(p1, p2) {}
|
||||
virtual result operator()(goal const & g) {
|
||||
return result(m_p1->operator()(g).get_value() + m_p2->operator()(g).get_value());
|
||||
}
|
||||
};
|
||||
|
||||
class sub_probe : public bin_probe {
|
||||
public:
|
||||
sub_probe(probe * p1, probe * p2):bin_probe(p1, p2) {}
|
||||
virtual result operator()(goal const & g) {
|
||||
return result(m_p1->operator()(g).get_value() - m_p2->operator()(g).get_value());
|
||||
}
|
||||
};
|
||||
|
||||
class mul_probe : public bin_probe {
|
||||
public:
|
||||
mul_probe(probe * p1, probe * p2):bin_probe(p1, p2) {}
|
||||
virtual result operator()(goal const & g) {
|
||||
return result(m_p1->operator()(g).get_value() * m_p2->operator()(g).get_value());
|
||||
}
|
||||
};
|
||||
|
||||
class div_probe : public bin_probe {
|
||||
public:
|
||||
div_probe(probe * p1, probe * p2):bin_probe(p1, p2) {}
|
||||
virtual result operator()(goal const & g) {
|
||||
return result(m_p1->operator()(g).get_value() / m_p2->operator()(g).get_value());
|
||||
}
|
||||
};
|
||||
|
||||
class const_probe : public probe {
|
||||
double m_val;
|
||||
public:
|
||||
const_probe(double v):m_val(v) {}
|
||||
|
||||
virtual result operator()(goal const & g) {
|
||||
return result(m_val);
|
||||
}
|
||||
};
|
||||
|
||||
probe * mk_const_probe(double v) {
|
||||
return alloc(const_probe, v);
|
||||
}
|
||||
|
||||
probe * mk_not(probe * p) {
|
||||
return alloc(not_probe, p);
|
||||
}
|
||||
|
||||
probe * mk_and(probe * p1, probe * p2) {
|
||||
return alloc(and_probe, p1, p2);
|
||||
}
|
||||
|
||||
probe * mk_or(probe * p1, probe * p2) {
|
||||
return alloc(or_probe, p1, p2);
|
||||
}
|
||||
|
||||
probe * mk_implies(probe * p1, probe * p2) {
|
||||
return mk_or(mk_not(p1), p2);
|
||||
}
|
||||
|
||||
probe * mk_eq(probe * p1, probe * p2) {
|
||||
return alloc(eq_probe, p1, p2);
|
||||
}
|
||||
|
||||
probe * mk_neq(probe * p1, probe * p2) {
|
||||
return mk_not(mk_eq(p1, p2));
|
||||
}
|
||||
|
||||
probe * mk_le(probe * p1, probe * p2) {
|
||||
return alloc(le_probe, p1, p2);
|
||||
}
|
||||
|
||||
probe * mk_ge(probe * p1, probe * p2) {
|
||||
return mk_le(p2, p1);
|
||||
}
|
||||
|
||||
probe * mk_lt(probe * p1, probe * p2) {
|
||||
return mk_not(mk_ge(p1, p2));
|
||||
}
|
||||
|
||||
probe * mk_gt(probe * p1, probe * p2) {
|
||||
return mk_lt(p2, p1);
|
||||
}
|
||||
|
||||
probe * mk_add(probe * p1, probe * p2) {
|
||||
return alloc(add_probe, p1, p2);
|
||||
}
|
||||
|
||||
probe * mk_mul(probe * p1, probe * p2) {
|
||||
return alloc(mul_probe, p1, p2);
|
||||
}
|
||||
|
||||
probe * mk_sub(probe * p1, probe * p2) {
|
||||
return alloc(sub_probe, p1, p2);
|
||||
}
|
||||
|
||||
probe * mk_div(probe * p1, probe * p2) {
|
||||
return alloc(div_probe, p1, p2);
|
||||
}
|
||||
|
||||
struct is_non_propositional_predicate {
|
||||
struct found {};
|
||||
ast_manager & m;
|
||||
|
||||
is_non_propositional_predicate(ast_manager & _m):m(_m) {}
|
||||
void operator()(var *) { throw found(); }
|
||||
void operator()(quantifier *) { throw found(); }
|
||||
void operator()(app * n) {
|
||||
if (!m.is_bool(n))
|
||||
throw found();
|
||||
|
||||
family_id fid = n->get_family_id();
|
||||
if (fid == m.get_basic_family_id())
|
||||
return;
|
||||
|
||||
if (is_uninterp_const(n))
|
||||
return;
|
||||
|
||||
throw found();
|
||||
}
|
||||
};
|
||||
|
||||
struct is_non_qfbv_predicate {
|
||||
struct found {};
|
||||
ast_manager & m;
|
||||
bv_util u;
|
||||
|
||||
is_non_qfbv_predicate(ast_manager & _m):m(_m), u(m) {}
|
||||
|
||||
void operator()(var *) { throw found(); }
|
||||
|
||||
void operator()(quantifier *) { throw found(); }
|
||||
|
||||
void operator()(app * n) {
|
||||
if (!m.is_bool(n) && !u.is_bv(n))
|
||||
throw found();
|
||||
family_id fid = n->get_family_id();
|
||||
if (fid == m.get_basic_family_id())
|
||||
return;
|
||||
if (fid == u.get_family_id())
|
||||
return;
|
||||
if (is_uninterp_const(n))
|
||||
return;
|
||||
|
||||
throw found();
|
||||
}
|
||||
};
|
||||
|
||||
class is_propositional_probe : public probe {
|
||||
public:
|
||||
virtual result operator()(goal const & g) {
|
||||
return !test<is_non_propositional_predicate>(g);
|
||||
}
|
||||
};
|
||||
|
||||
class is_qfbv_probe : public probe {
|
||||
public:
|
||||
virtual result operator()(goal const & g) {
|
||||
return !test<is_non_qfbv_predicate>(g);
|
||||
}
|
||||
};
|
||||
|
||||
probe * mk_is_propositional_probe() {
|
||||
return alloc(is_propositional_probe);
|
||||
}
|
||||
|
||||
probe * mk_is_qfbv_probe() {
|
||||
return alloc(is_qfbv_probe);
|
||||
}
|
||||
|
||||
class num_consts_probe : public probe {
|
||||
bool m_bool; // If true, track only boolean constants. Otherwise, track only non boolean constants.
|
||||
char const * m_family; // (Ignored if m_bool == true), if != 0 and m_bool == true, then track only constants of the given family.
|
||||
struct proc {
|
||||
ast_manager & m;
|
||||
bool m_bool;
|
||||
family_id m_fid;
|
||||
unsigned m_counter;
|
||||
proc(ast_manager & _m, bool b, char const * family):m(_m), m_bool(b), m_counter(0) {
|
||||
if (family != 0)
|
||||
m_fid = m.get_family_id(family);
|
||||
else
|
||||
m_fid = null_family_id;
|
||||
}
|
||||
void operator()(quantifier *) {}
|
||||
void operator()(var *) {}
|
||||
void operator()(app * n) {
|
||||
if (n->get_num_args() == 0 && !m.is_value(n)) {
|
||||
if (m_bool) {
|
||||
if (m.is_bool(n))
|
||||
m_counter++;
|
||||
}
|
||||
else {
|
||||
if (m_fid == null_family_id) {
|
||||
if (!m.is_bool(n))
|
||||
m_counter++;
|
||||
}
|
||||
else {
|
||||
if (m.get_sort(n)->get_family_id() == m_fid)
|
||||
m_counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
num_consts_probe(bool b, char const * f):
|
||||
m_bool(b), m_family(f) {
|
||||
}
|
||||
virtual result operator()(goal const & g) {
|
||||
proc p(g.m(), m_bool, m_family);
|
||||
unsigned sz = g.size();
|
||||
expr_fast_mark1 visited;
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
for_each_expr_core<proc, expr_fast_mark1, true, true>(p, visited, g.form(i));
|
||||
}
|
||||
return result(p.m_counter);
|
||||
}
|
||||
};
|
||||
|
||||
probe * mk_num_consts_probe() {
|
||||
return alloc(num_consts_probe, false, 0);
|
||||
}
|
||||
|
||||
probe * mk_num_bool_consts_probe() {
|
||||
return alloc(num_consts_probe, true, 0);
|
||||
}
|
||||
|
||||
probe * mk_num_arith_consts_probe() {
|
||||
return alloc(num_consts_probe, false, "arith");
|
||||
}
|
||||
|
||||
probe * mk_num_bv_consts_probe() {
|
||||
return alloc(num_consts_probe, false, "bv");
|
||||
}
|
||||
|
||||
class produce_proofs_probe : public probe {
|
||||
public:
|
||||
virtual result operator()(goal const & g) {
|
||||
return g.proofs_enabled();
|
||||
}
|
||||
};
|
||||
|
||||
class produce_models_probe : public probe {
|
||||
public:
|
||||
virtual result operator()(goal const & g) {
|
||||
return g.models_enabled();
|
||||
}
|
||||
};
|
||||
|
||||
class produce_unsat_cores_probe : public probe {
|
||||
public:
|
||||
virtual result operator()(goal const & g) {
|
||||
return g.unsat_core_enabled();
|
||||
}
|
||||
};
|
||||
|
||||
probe * mk_produce_proofs_probe() {
|
||||
return alloc(produce_proofs_probe);
|
||||
}
|
||||
|
||||
probe * mk_produce_models_probe() {
|
||||
return alloc(produce_models_probe);
|
||||
}
|
||||
|
||||
probe * mk_produce_unsat_cores_probe() {
|
||||
return alloc(produce_unsat_cores_probe);
|
||||
}
|
||||
|
||||
struct has_pattern_probe : public probe {
|
||||
struct found {};
|
||||
|
||||
struct proc {
|
||||
void operator()(var * n) {}
|
||||
void operator()(app * n) {}
|
||||
void operator()(quantifier * n) {
|
||||
if (n->get_num_patterns() > 0 || n->get_num_no_patterns() > 0)
|
||||
throw found();
|
||||
}
|
||||
};
|
||||
public:
|
||||
virtual result operator()(goal const & g) {
|
||||
try {
|
||||
expr_fast_mark1 visited;
|
||||
proc p;
|
||||
unsigned sz = g.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
quick_for_each_expr(p, visited, g.form(i));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
catch (found) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
probe * mk_has_pattern_probe() {
|
||||
return alloc(has_pattern_probe);
|
||||
}
|
91
lib/probe.h
91
lib/probe.h
|
@ -1,91 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
probe.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Evaluates/Probes a goal.
|
||||
|
||||
A probe is used to build tactics (aka strategies) that
|
||||
makes decisions based on the structure of a goal.
|
||||
|
||||
The current implementation is very simple.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2011-10-13.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _PROBE_H_
|
||||
#define _PROBE_H_
|
||||
|
||||
#include"goal.h"
|
||||
|
||||
class probe {
|
||||
public:
|
||||
class result {
|
||||
double m_value;
|
||||
public:
|
||||
result(double v = 0.0):m_value(v) {}
|
||||
result(unsigned v):m_value(static_cast<double>(v)) {}
|
||||
result(int v):m_value(static_cast<double>(v)) {}
|
||||
result(bool b):m_value(b ? 1.0 : 0.0) {}
|
||||
|
||||
bool is_true() const { return m_value != 0.0; }
|
||||
double get_value() const { return m_value; }
|
||||
};
|
||||
|
||||
private:
|
||||
unsigned m_ref_count;
|
||||
|
||||
public:
|
||||
probe():m_ref_count(0) {}
|
||||
virtual ~probe() {}
|
||||
|
||||
void inc_ref() { ++m_ref_count; }
|
||||
void dec_ref() { SASSERT(m_ref_count > 0); --m_ref_count; if (m_ref_count == 0) dealloc(this); }
|
||||
|
||||
virtual result operator()(goal const & g) = 0;
|
||||
};
|
||||
|
||||
typedef ref<probe> probe_ref;
|
||||
|
||||
probe * mk_memory_probe();
|
||||
probe * mk_depth_probe();
|
||||
probe * mk_size_probe();
|
||||
probe * mk_num_exprs_probe();
|
||||
probe * mk_const_probe(double val);
|
||||
probe * mk_num_consts_probe();
|
||||
probe * mk_num_bool_consts_probe();
|
||||
probe * mk_num_arith_consts_probe();
|
||||
probe * mk_num_bv_consts_probe();
|
||||
probe * mk_produce_proofs_probe();
|
||||
probe * mk_produce_models_probe();
|
||||
probe * mk_produce_unsat_cores_probe();
|
||||
probe * mk_has_pattern_probe();
|
||||
|
||||
// Some basic combinators for probes
|
||||
probe * mk_not(probe * p1);
|
||||
probe * mk_and(probe * p1, probe * p2);
|
||||
probe * mk_or(probe * p1, probe * p2);
|
||||
probe * mk_implies(probe * p1, probe * p2);
|
||||
probe * mk_eq(probe * p1, probe * p2);
|
||||
probe * mk_neq(probe * p1, probe * p2);
|
||||
probe * mk_le(probe * p1, probe * p2);
|
||||
probe * mk_lt(probe * p1, probe * p2);
|
||||
probe * mk_ge(probe * p1, probe * p2);
|
||||
probe * mk_gt(probe * p1, probe * p2);
|
||||
probe * mk_add(probe * p1, probe * p2);
|
||||
probe * mk_sub(probe * p1, probe * p2);
|
||||
probe * mk_mul(probe * p1, probe * p2);
|
||||
probe * mk_div(probe * p1, probe * p2);
|
||||
|
||||
probe * mk_is_propositional_probe();
|
||||
probe * mk_is_qfbv_probe();
|
||||
|
||||
#endif
|
|
@ -1,33 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2008 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
progress_callback.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Virtual callback for reporting progress.
|
||||
|
||||
Author:
|
||||
|
||||
Michal Moskal (micmo) 2009-02-17.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _PROGRESS_CALLBACK_H_
|
||||
#define _PROGRESS_CALLBACK_H_
|
||||
|
||||
class progress_callback {
|
||||
public:
|
||||
virtual ~progress_callback() {}
|
||||
|
||||
// Called approx. every m_progress_sampling_freq miliseconds
|
||||
virtual void slow_progress_sample() { }
|
||||
|
||||
// Called on every check for reqsource limit exceeded (mach more frequent).
|
||||
virtual void fast_progress_sample() { }
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,162 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
proof_converter.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Abstract interface for converting proofs, and basic combinators
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-11-14
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"proof_converter.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
|
||||
class concat_proof_converter : public concat_converter<proof_converter> {
|
||||
public:
|
||||
concat_proof_converter(proof_converter * pc1, proof_converter * pc2):concat_converter<proof_converter>(pc1, pc2) {}
|
||||
|
||||
virtual char const * get_name() const { return "concat-proof-converter"; }
|
||||
|
||||
virtual void operator()(ast_manager & m, unsigned num_source, proof * const * source, proof_ref & result) {
|
||||
proof_ref tmp(m);
|
||||
this->m_c2->operator()(m, num_source, source, tmp);
|
||||
proof * new_source = tmp.get();
|
||||
this->m_c1->operator()(m, 1, &new_source, result);
|
||||
}
|
||||
|
||||
virtual proof_converter * translate(ast_translation & translator) {
|
||||
return this->translate_core<concat_proof_converter>(translator);
|
||||
}
|
||||
};
|
||||
|
||||
proof_converter * concat(proof_converter * pc1, proof_converter * pc2) {
|
||||
if (pc1 == 0)
|
||||
return pc2;
|
||||
if (pc2 == 0)
|
||||
return pc1;
|
||||
return alloc(concat_proof_converter, pc1, pc2);
|
||||
}
|
||||
|
||||
class concat_star_proof_converter : public concat_star_converter<proof_converter> {
|
||||
public:
|
||||
concat_star_proof_converter(proof_converter * pc1, unsigned num, proof_converter * const * pc2s, unsigned * szs):
|
||||
concat_star_converter<proof_converter>(pc1, num, pc2s, szs) {
|
||||
}
|
||||
|
||||
virtual char const * get_name() const { return "concat-star-proof-converter"; }
|
||||
|
||||
virtual void operator()(ast_manager & m, unsigned num_source, proof * const * source, proof_ref & result) {
|
||||
unsigned num = this->m_szs.size();
|
||||
#ifdef Z3DEBUG
|
||||
unsigned sum = 0;
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
sum += this->m_szs[i];
|
||||
}
|
||||
SASSERT(sum == num_source);
|
||||
#endif
|
||||
proof_ref_buffer tmp_prs(m);
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
unsigned sz = m_szs[i];
|
||||
proof_converter * c2 = m_c2s[i];
|
||||
proof_ref pr(m);
|
||||
if (c2) {
|
||||
(*c2)(m, sz, source, pr);
|
||||
}
|
||||
else {
|
||||
SASSERT(sz == 1);
|
||||
pr = *source;
|
||||
}
|
||||
source += sz;
|
||||
tmp_prs.push_back(pr.get());
|
||||
}
|
||||
if (m_c1) {
|
||||
(*m_c1)(m, tmp_prs.size(), tmp_prs.c_ptr(), result);
|
||||
}
|
||||
else {
|
||||
SASSERT(tmp_prs.size() == 1);
|
||||
result = tmp_prs[0];
|
||||
}
|
||||
}
|
||||
|
||||
virtual proof_converter * translate(ast_translation & translator) {
|
||||
return this->translate_core<concat_star_proof_converter>(translator);
|
||||
}
|
||||
};
|
||||
|
||||
proof_converter * concat(proof_converter * pc1, unsigned num, proof_converter * const * pc2s, unsigned * szs) {
|
||||
SASSERT(num > 0);
|
||||
if (num == 1)
|
||||
return concat(pc1, pc2s[0]);
|
||||
unsigned i;
|
||||
for (i = 0; i < num; i++) {
|
||||
if (pc2s[i] != 0)
|
||||
break;
|
||||
}
|
||||
if (i == num) {
|
||||
// all pc2s are 0
|
||||
return pc1;
|
||||
}
|
||||
return alloc(concat_star_proof_converter, pc1, num, pc2s, szs);
|
||||
}
|
||||
|
||||
class proof2pc : public proof_converter {
|
||||
proof_ref m_pr;
|
||||
public:
|
||||
proof2pc(ast_manager & m, proof * pr):m_pr(pr, m) {}
|
||||
virtual ~proof2pc() {}
|
||||
|
||||
virtual void operator()(ast_manager & m, unsigned num_source, proof * const * source, proof_ref & result) {
|
||||
SASSERT(num_source == 0);
|
||||
result = m_pr;
|
||||
}
|
||||
|
||||
virtual proof_converter * translate(ast_translation & translator) {
|
||||
return alloc(proof2pc, translator.to(), translator(m_pr.get()));
|
||||
}
|
||||
|
||||
virtual void display(std::ostream & out) {
|
||||
out << "(proof->proof-converter-wrapper\n" << mk_ismt2_pp(m_pr.get(), m_pr.get_manager()) << ")\n";
|
||||
}
|
||||
};
|
||||
|
||||
proof_converter * proof2proof_converter(ast_manager & m, proof * pr) {
|
||||
if (pr == 0)
|
||||
return 0;
|
||||
return alloc(proof2pc, m, pr);
|
||||
}
|
||||
|
||||
void apply(ast_manager & m, proof_converter * pc, proof_ref & pr) {
|
||||
if (pc) {
|
||||
proof * _pr = pr.get();
|
||||
(*pc)(m, 1, &_pr, pr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Let pc2s be a buffer of proof converters that are wrappers for proofs.
|
||||
That is, they are functors of the form: unit -> Proof
|
||||
Then, this function applies pc1 to the proofs produced by pc2s's and store
|
||||
the resultant proof in result.
|
||||
|
||||
pc1 and pc2s must be different from 0.
|
||||
*/
|
||||
void apply(ast_manager & m, proof_converter_ref & pc1, proof_converter_ref_buffer & pc2s, proof_ref & result) {
|
||||
SASSERT(pc1);
|
||||
proof_ref_buffer prs(m);
|
||||
unsigned sz = pc2s.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
proof_ref pr(m);
|
||||
SASSERT(pc2s[i]); // proof production is enabled
|
||||
pc2s[i]->operator()(m, 0, 0, pr);
|
||||
prs.push_back(pr);
|
||||
}
|
||||
(*pc1)(m, sz, prs.c_ptr(), result);
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
proof_converter.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Abstract interface for converting proofs, and basic combinators.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-04-26
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _PROOF_CONVERTER_H_
|
||||
#define _PROOF_CONVERTER_H_
|
||||
|
||||
#include"ast.h"
|
||||
#include"converter.h"
|
||||
#include"ref.h"
|
||||
|
||||
class proof_converter : public converter {
|
||||
public:
|
||||
virtual ~proof_converter() { }
|
||||
virtual void operator()(ast_manager & m, unsigned num_source, proof * const * source, proof_ref & result) = 0;
|
||||
virtual proof_converter * translate(ast_translation & translator) = 0;
|
||||
};
|
||||
|
||||
typedef ref<proof_converter> proof_converter_ref;
|
||||
|
||||
proof_converter * concat(proof_converter * pc1, proof_converter * pc2);
|
||||
|
||||
/**
|
||||
\brief \c pc1 is the proof converter for a sequence of subgoals of size \c num.
|
||||
Given an i in [0, num), pc2s[i] is the proof converter for subgoal i,
|
||||
and num_subgoals[i] is the number of subgoals of subgoals[i].
|
||||
*/
|
||||
proof_converter * concat(proof_converter * pc1, unsigned num, proof_converter * const * pc2s, unsigned * num_subgoals);
|
||||
|
||||
proof_converter * proof2proof_converter(ast_manager & m, proof * pr);
|
||||
|
||||
typedef sref_vector<proof_converter> proof_converter_ref_vector;
|
||||
typedef sref_buffer<proof_converter> proof_converter_ref_buffer;
|
||||
|
||||
void apply(ast_manager & m, proof_converter_ref & pc1, proof_converter_ref_buffer & pc2s, proof_ref & result);
|
||||
void apply(ast_manager & m, proof_converter * pc, proof_ref & pr);
|
||||
|
||||
#endif
|
139
lib/qi_params.h
139
lib/qi_params.h
|
@ -1,139 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
qi_params.h
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-06-15.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _QI_PARAMS_H_
|
||||
#define _QI_PARAMS_H_
|
||||
|
||||
#include"ini_file.h"
|
||||
|
||||
enum quick_checker_mode {
|
||||
MC_NO, // do not use (cheap) model checking based instantiation
|
||||
MC_UNSAT, // instantiate unsatisfied instances
|
||||
MC_NO_SAT // instantiate unsatisfied and not-satisfied instances
|
||||
};
|
||||
|
||||
struct qi_params {
|
||||
bool m_qi_ematching;
|
||||
std::string m_qi_cost;
|
||||
std::string m_qi_new_gen;
|
||||
double m_qi_eager_threshold;
|
||||
double m_qi_lazy_threshold;
|
||||
unsigned m_qi_max_eager_multipatterns;
|
||||
unsigned m_qi_max_lazy_multipattern_matching;
|
||||
bool m_qi_profile;
|
||||
unsigned m_qi_profile_freq;
|
||||
quick_checker_mode m_qi_quick_checker;
|
||||
bool m_qi_lazy_quick_checker;
|
||||
bool m_qi_promote_unsat;
|
||||
unsigned m_qi_max_instances;
|
||||
bool m_qi_lazy_instantiation;
|
||||
bool m_qi_conservative_final_check;
|
||||
|
||||
bool m_mbqi;
|
||||
unsigned m_mbqi_max_cexs;
|
||||
unsigned m_mbqi_max_cexs_incr;
|
||||
unsigned m_mbqi_max_iterations;
|
||||
bool m_mbqi_trace;
|
||||
unsigned m_mbqi_force_template;
|
||||
|
||||
bool m_instgen;
|
||||
|
||||
qi_params():
|
||||
/*
|
||||
The "weight 0" performance bug
|
||||
------------------------------
|
||||
|
||||
The parameters m_qi_cost and m_qi_new_gen influence quantifier instantiation.
|
||||
- m_qi_cost: specify the cost of a quantifier instantiation. Z3 will block instantiations using m_qi_eager_threshold and m_qi_lazy_threshold.
|
||||
- m_qi_new_gen: specify how the "generation" tag of an enode created by quantifier instantiation is set.
|
||||
|
||||
Enodes in the input problem have generation 0.
|
||||
|
||||
Some combinations of m_qi_cost and m_qi_new_gen will prevent Z3 from breaking matching loops.
|
||||
For example, the "Weight 0" peformace bug was triggered by the following combination:
|
||||
- m_qi_cost: (+ weight generation)
|
||||
- m_qi_new_gen: cost
|
||||
If a quantifier has weight 0, then the cost of instantiating it with a term in the input problem has cost 0.
|
||||
The new enodes created during the instantiation will be tagged with generation = const = 0. So, every enode
|
||||
will have generation 0, and consequently every quantifier instantiation will have cost 0.
|
||||
|
||||
Although dangerous, this feature was requested by the Boogie team. In their case, the patterns are carefully constructred,
|
||||
and there are no matching loops. Moreover, the tag some quantifiers with weight 0 to instruct Z3 to never block their instances.
|
||||
An example is the select-store axiom. They need this feature to be able to analyze code that contains very long execution paths.
|
||||
|
||||
So, unless requested by the user, the default weight must be > 0. Otherwise, Z3 will execute without any
|
||||
matching loop detection.
|
||||
*/
|
||||
m_qi_cost("(+ weight generation)"),
|
||||
m_qi_new_gen("cost"),
|
||||
m_qi_eager_threshold(10.0),
|
||||
m_qi_lazy_threshold(20.0), // reduced to give a chance to MBQI
|
||||
m_qi_max_eager_multipatterns(0),
|
||||
m_qi_max_lazy_multipattern_matching(2),
|
||||
m_qi_profile(false),
|
||||
m_qi_profile_freq(UINT_MAX),
|
||||
m_qi_quick_checker(MC_NO),
|
||||
m_qi_lazy_quick_checker(true),
|
||||
m_qi_promote_unsat(true),
|
||||
m_qi_max_instances(UINT_MAX),
|
||||
m_qi_lazy_instantiation(false),
|
||||
m_qi_conservative_final_check(false),
|
||||
#ifdef _EXTERNAL_RELEASE
|
||||
m_mbqi(true), // enabled by default
|
||||
#else
|
||||
m_mbqi(false), // to avoid Rustan whining that the models are not partial anymore.
|
||||
#endif
|
||||
m_mbqi_max_cexs(1),
|
||||
m_mbqi_max_cexs_incr(1),
|
||||
m_mbqi_max_iterations(1000),
|
||||
m_mbqi_trace(false),
|
||||
m_mbqi_force_template(10),
|
||||
m_instgen(false) {
|
||||
}
|
||||
|
||||
void register_params(ini_params & p) {
|
||||
p.register_unsigned_param("QI_MAX_EAGER_MULTI_PATTERNS", m_qi_max_eager_multipatterns,
|
||||
"Specify the number of extra multi patterns that are processed eagerly. By default, the prover use at most one multi-pattern eagerly when there is no unary pattern. This value should be smaller than or equal to PI_MAX_MULTI_PATTERNS");
|
||||
p.register_unsigned_param("QI_MAX_LAZY_MULTI_PATTERN_MATCHING", m_qi_max_lazy_multipattern_matching, "Maximum number of rounds of matching in a branch for delayed multipatterns. A multipattern is delayed based on the value of QI_MAX_EAGER_MULTI_PATTERNS");
|
||||
p.register_string_param("QI_COST", m_qi_cost, "The cost function for quantifier instantiation");
|
||||
p.register_string_param("QI_NEW_GEN", m_qi_new_gen, "The function for calculating the generation of newly constructed terms");
|
||||
p.register_double_param("QI_EAGER_THRESHOLD", m_qi_eager_threshold, "Threshold for eager quantifier instantiation");
|
||||
p.register_double_param("QI_LAZY_THRESHOLD", m_qi_lazy_threshold, "Threshold for lazy quantifier instantiation");
|
||||
p.register_bool_param("QI_PROFILE", m_qi_profile);
|
||||
p.register_unsigned_param("QI_PROFILE_FREQ", m_qi_profile_freq);
|
||||
p.register_int_param("QI_QUICK_CHECKER", 0, 2, reinterpret_cast<int&>(m_qi_quick_checker), "0 - do not use (cheap) model checker, 1 - instantiate instances unsatisfied by current model, 2 - 1 + instantiate instances not satisfied by current model");
|
||||
p.register_bool_param("QI_LAZY_QUICK_CHECKER", m_qi_lazy_quick_checker);
|
||||
p.register_bool_param("QI_PROMOTE_UNSAT", m_qi_promote_unsat);
|
||||
p.register_unsigned_param("QI_MAX_INSTANCES", m_qi_max_instances);
|
||||
p.register_bool_param("QI_LAZY_INSTANTIATION", m_qi_lazy_instantiation);
|
||||
p.register_bool_param("QI_CONSERVATIVE_FINAL_CHECK", m_qi_conservative_final_check);
|
||||
|
||||
|
||||
p.register_bool_param("MBQI", m_mbqi, "Model Based Quantifier Instantiation (MBQI)");
|
||||
p.register_unsigned_param("MBQI_MAX_CEXS", m_mbqi_max_cexs, "Initial maximal number of counterexamples used in MBQI, each counterexample generates a quantifier instantiation", true);
|
||||
p.register_unsigned_param("MBQI_MAX_CEXS_INCR", m_mbqi_max_cexs_incr, "Increment for MBQI_MAX_CEXS, the increment is performed after each round of MBQI", true);
|
||||
p.register_unsigned_param("MBQI_MAX_ITERATIONS", m_mbqi_max_iterations, "Maximum number of rounds of MBQI", true);
|
||||
p.register_bool_param("MBQI_TRACE", m_mbqi_trace, "Generate tracing messages for Model Based Quantifier Instantiation (MBQI). It will display a message before every round of MBQI, and the quantifiers that were not satisfied.", true);
|
||||
p.register_unsigned_param("MBQI_FORCE_TEMPLATE", m_mbqi_force_template, "Some quantifiers can be used as templates for building interpretations for functions. Z3 uses heuristics to decide whether a quantifier will be used as a template or not. Quantifiers with weight >= MBQI_FORCE_TEMPLATE are forced to be used as a template", true);
|
||||
|
||||
p.register_bool_param("INST_GEN", m_instgen, "Enable Instantiation Generation solver (disables other quantifier reasoning)", false);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _QI_PARAMS_H_ */
|
||||
|
|
@ -1,128 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
simplify_cmd.cpp
|
||||
|
||||
Abstract:
|
||||
SMT2 front-end 'simplify' command.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-04-20
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"cmd_context.h"
|
||||
#include"th_rewriter.h"
|
||||
#include"shared_occs.h"
|
||||
#include"ast_smt_pp.h"
|
||||
#include"for_each_expr.h"
|
||||
#include"parametric_cmd.h"
|
||||
#include"scoped_timer.h"
|
||||
#include"scoped_ctrl_c.h"
|
||||
#include"cancel_eh.h"
|
||||
#include<iomanip>
|
||||
|
||||
class simplify_cmd : public parametric_cmd {
|
||||
expr * m_target;
|
||||
public:
|
||||
simplify_cmd(char const * name = "simplify"):parametric_cmd(name) {}
|
||||
|
||||
virtual char const * get_usage() const { return "<term> (<keyword> <value>)*"; }
|
||||
|
||||
virtual char const * get_main_descr() const {
|
||||
return "simplify the given term using builtin theory simplification rules.";
|
||||
}
|
||||
|
||||
virtual void init_pdescrs(cmd_context & ctx, param_descrs & p) {
|
||||
th_rewriter::get_param_descrs(p);
|
||||
insert_timeout(p);
|
||||
p.insert(":print", CPK_BOOL, "(default: true) print the simplified term.");
|
||||
p.insert(":print-proofs", CPK_BOOL, "(default: false) print a proof showing the original term is equal to the resultant one.");
|
||||
p.insert(":print-statistics", CPK_BOOL, "(default: false) print statistics.");
|
||||
}
|
||||
|
||||
virtual ~simplify_cmd() {
|
||||
}
|
||||
|
||||
virtual void prepare(cmd_context & ctx) {
|
||||
parametric_cmd::prepare(ctx);
|
||||
m_target = 0;
|
||||
}
|
||||
|
||||
virtual cmd_arg_kind next_arg_kind(cmd_context & ctx) const {
|
||||
if (m_target == 0) return CPK_EXPR;
|
||||
return parametric_cmd::next_arg_kind(ctx);
|
||||
}
|
||||
|
||||
virtual void set_next_arg(cmd_context & ctx, expr * arg) {
|
||||
m_target = arg;
|
||||
}
|
||||
|
||||
virtual void execute(cmd_context & ctx) {
|
||||
if (m_target == 0)
|
||||
throw cmd_exception("invalid simplify command, argument expected");
|
||||
expr_ref r(ctx.m());
|
||||
proof_ref pr(ctx.m());
|
||||
if (m_params.get_bool(":som", false))
|
||||
m_params.set_bool(":flat", true);
|
||||
th_rewriter s(ctx.m(), m_params);
|
||||
unsigned cache_sz;
|
||||
unsigned num_steps = 0;
|
||||
unsigned timeout = m_params.get_uint(":timeout", UINT_MAX);
|
||||
bool failed = false;
|
||||
cancel_eh<th_rewriter> eh(s);
|
||||
{
|
||||
scoped_ctrl_c ctrlc(eh);
|
||||
scoped_timer timer(timeout, &eh);
|
||||
cmd_context::scoped_watch sw(ctx);
|
||||
try {
|
||||
s(m_target, r, pr);
|
||||
}
|
||||
catch (z3_error & ex) {
|
||||
throw ex;
|
||||
}
|
||||
catch (z3_exception & ex) {
|
||||
ctx.regular_stream() << "(error \"simplifier failed: " << ex.msg() << "\")" << std::endl;
|
||||
failed = true;
|
||||
r = m_target;
|
||||
}
|
||||
cache_sz = s.get_cache_size();
|
||||
num_steps = s.get_num_steps();
|
||||
s.cleanup();
|
||||
}
|
||||
if (m_params.get_bool(":print", true)) {
|
||||
ctx.display(ctx.regular_stream(), r);
|
||||
ctx.regular_stream() << std::endl;
|
||||
}
|
||||
if (!failed && m_params.get_bool(":print-proofs", false)) {
|
||||
ast_smt_pp pp(ctx.m());
|
||||
pp.set_logic(ctx.get_logic().str().c_str());
|
||||
pp.display_expr_smt2(ctx.regular_stream(), pr.get());
|
||||
ctx.regular_stream() << std::endl;
|
||||
}
|
||||
if (m_params.get_bool(":print-statistics", false)) {
|
||||
shared_occs s1(ctx.m());
|
||||
if (!failed)
|
||||
s1(r);
|
||||
unsigned long long max_mem = memory::get_max_used_memory();
|
||||
unsigned long long mem = memory::get_allocation_size();
|
||||
ctx.regular_stream() << "(:time " << std::fixed << std::setprecision(2) << ctx.get_seconds() << " :num-steps " << num_steps
|
||||
<< " :memory " << std::fixed << std::setprecision(2) << static_cast<double>(mem)/static_cast<double>(1024*1024)
|
||||
<< " :max-memory " << std::fixed << std::setprecision(2) << static_cast<double>(max_mem)/static_cast<double>(1024*1024)
|
||||
<< " :cache-size: " << cache_sz
|
||||
<< " :num-nodes-before " << get_num_exprs(m_target);
|
||||
if (!failed)
|
||||
ctx.regular_stream() << " :num-shared " << s1.num_shared() << " :num-nodes " << get_num_exprs(r);
|
||||
ctx.regular_stream() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void install_simplify_cmd(cmd_context & ctx, char const * cmd_name) {
|
||||
ctx.insert(alloc(simplify_cmd, cmd_name));
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
simplify_cmd.h
|
||||
|
||||
Abstract:
|
||||
SMT2 front-end 'simplify' command.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-04-20
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _SIMPLIFY_CMD_H_
|
||||
#define _SIMPLIFY_CMD_H_
|
||||
|
||||
class cmd_context;
|
||||
|
||||
void install_simplify_cmd(cmd_context & ctx, char const * cmd_name = "simplify");
|
||||
|
||||
#endif
|
|
@ -1,108 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
smt_params.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-02-20.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"smt_params.h"
|
||||
#include"trace.h"
|
||||
|
||||
void smt_params::register_params(ini_params & p) {
|
||||
dyn_ack_params::register_params(p);
|
||||
qi_params::register_params(p);
|
||||
theory_arith_params::register_params(p);
|
||||
theory_array_params::register_params(p);
|
||||
theory_bv_params::register_params(p);
|
||||
theory_datatype_params::register_params(p);
|
||||
|
||||
p.register_bool_param("CHECK_PROOF", m_check_proof);
|
||||
p.register_bool_param("DISPLAY_PROOF", m_display_proof);
|
||||
p.register_bool_param("DISPLAY_DOT_PROOF", m_display_dot_proof);
|
||||
p.register_bool_param("DISPLAY_UNSAT_CORE", m_display_unsat_core);
|
||||
p.register_bool_param("INTERNALIZER_NNF", m_internalizer_nnf);
|
||||
p.register_bool_param("EQ_PROPAGATION", m_eq_propagation);
|
||||
p.register_bool_param("BIN_CLAUSES", m_binary_clause_opt);
|
||||
p.register_unsigned_param("RELEVANCY", m_relevancy_lvl, "relevancy propagation heuristic: 0 - disabled, 1 - relevancy is tracked by only affects quantifier instantiation, 2 - relevancy is tracked, and an atom is only asserted if it is relevant", true);
|
||||
p.register_bool_param("RELEVANCY_LEMMA", m_relevancy_lemma, "true if lemmas are used to propagate relevancy");
|
||||
p.register_unsigned_param("RANDOM_SEED", m_random_seed, "random seed for Z3");
|
||||
p.register_percentage_param("RANDOM_CASE_SPLIT_FREQ", m_random_var_freq, "frequency of random case splits");
|
||||
p.register_int_param("PHASE_SELECTION", 0, 6, reinterpret_cast<int&>(m_phase_selection), "phase selection heuristic: 0 - always false, 1 - always true, 2 - phase caching, 3 - phase caching conservative, 4 - phase caching conservative 2, 5 - random, 6 - number of occurrences");
|
||||
p.register_bool_param("MINIMIZE_LEMMAS", m_minimize_lemmas, "enable/disable lemma minimization algorithm");
|
||||
p.register_unsigned_param("MAX_CONFLICTS", m_max_conflicts, "maximum number of conflicts");
|
||||
|
||||
p.register_unsigned_param("RECENT_LEMMA_THRESHOLD", m_recent_lemmas_size);
|
||||
p.register_unsigned_param("TICK", m_tick);
|
||||
|
||||
PRIVATE_PARAMS({
|
||||
p.register_bool_param("THEORY_RESOLVE", m_theory_resolve, "Apply theory resolution to produce auxiliary conflict clauses", true);
|
||||
});
|
||||
|
||||
p.register_int_param("RESTART_STRATEGY", 0, 4, reinterpret_cast<int&>(m_restart_strategy), "0 - geometric, 1 - inner-outer-geometric, 2 - luby, 3 - fixed, 4 - arithmetic");
|
||||
p.register_unsigned_param("RESTART_INITIAL", m_restart_initial,
|
||||
"inital restart frequency in number of conflicts, it is also the unit for the luby sequence");
|
||||
p.register_double_param("RESTART_FACTOR", m_restart_factor, "when using geometric (or inner-outer-geometric) progression of restarts, it specifies the constant used to multiply the currect restart threshold");
|
||||
p.register_bool_param("RESTART_ADAPTIVE", m_restart_adaptive, "disable restarts based on the search 'agility'");
|
||||
p.register_percentage_param("RESTART_AGILITY_THRESHOLD", m_restart_agility_threshold);
|
||||
|
||||
p.register_int_param("LEMMA_GC_STRATEGY", 0, 2, reinterpret_cast<int&>(m_lemma_gc_strategy), "0 - fixed, 1 - geometric, 2 - at every restart");
|
||||
p.register_bool_param("LEMMA_GC_HALF", m_lemma_gc_half, "true for simple gc algorithm (delete approx. half of the clauses)");
|
||||
p.register_unsigned_param("LEMMA_GC_INITIAL", m_lemma_gc_initial, "lemma initial gc frequency (in number of conflicts), used by fixed or geometric strategies");
|
||||
p.register_double_param("LEMMA_GC_FACTOR", m_lemma_gc_factor, "used by geometric strategy");
|
||||
p.register_unsigned_param("LEMMA_GC_NEW_OLD_RATIO", m_new_old_ratio);
|
||||
p.register_unsigned_param("LEMMA_GC_NEW_CLAUSE_ACTIVITY", m_new_clause_activity);
|
||||
p.register_unsigned_param("LEMMA_GC_OLD_CLAUSE_ACTIVITY", m_old_clause_activity);
|
||||
p.register_unsigned_param("LEMMA_GC_NEW_CLAUSE_RELEVANCY", m_new_clause_relevancy);
|
||||
p.register_unsigned_param("LEMMA_GC_OLD_CLAUSE_RELEVANCY", m_old_clause_activity);
|
||||
|
||||
p.register_bool_param("SIMPLIFY_CLAUSES", m_simplify_clauses);
|
||||
|
||||
p.register_int_param("RANDOM_INITIAL_ACTIVITY", 0, 2, reinterpret_cast<int&>(m_random_initial_activity));
|
||||
|
||||
PRIVATE_PARAMS({
|
||||
|
||||
p.register_double_param("INV_DECAY", m_inv_decay);
|
||||
p.register_unsigned_param("PHASE_CACHING_ON_DURATION", m_phase_caching_on);
|
||||
p.register_unsigned_param("PHASE_CACHING_OFF_DURATION", m_phase_caching_off);
|
||||
});
|
||||
|
||||
p.register_bool_param("SMTLIB_DUMP_LEMMAS", m_smtlib_dump_lemmas);
|
||||
p.register_string_param("SMTLIB_LOGIC", m_smtlib_logic, "Name used for the :logic field when generating SMT-LIB benchmarks");
|
||||
p.register_bool_param("DISPLAY_FEATURES", m_display_features);
|
||||
|
||||
p.register_bool_param("NEW_CORE2TH_EQ", m_new_core2th_eq);
|
||||
p.register_bool_param("EMATCHING", m_ematching, "E-Matching based quantifier instantiation");
|
||||
|
||||
p.register_bool_param("PROFILE_RES_SUB", m_profile_res_sub);
|
||||
#ifndef _EXTERNAL_RELEASE
|
||||
p.register_bool_param("DISPLAY_BOOL_VAR2EXPR", m_display_bool_var2expr);
|
||||
p.register_bool_param("DISPLAY_LL_BOOL_VAR2EXPR", m_display_ll_bool_var2expr);
|
||||
p.register_bool_param("ABORT_AFTER_PREPROC", m_abort_after_preproc, "abort after preprocessing step, this flag is only useful for debugging purposes");
|
||||
p.register_bool_param("DISPLAY_INSTALLED_THEORIES", m_display_installed_theories, "display theories installed at smt::context", true);
|
||||
#endif
|
||||
p.register_int_param("CASE_SPLIT", 0, 5, reinterpret_cast<int&>(m_case_split_strategy), "0 - case split based on variable activity, 1 - similar to 0, but delay case splits created during the search, 2 - similar to 0, but cache the relevancy, 3 - case split based on relevancy (structural splitting), 4 - case split on relevancy and activity, 5 - case split on relevancy and current goal");
|
||||
p.register_unsigned_param("REL_CASE_SPLIT_ORDER", 0, 2, m_rel_case_split_order, "structural (relevancy) splitting order: 0 - left-to-right (default), 1 - random, 2 - right-to-left");
|
||||
p.register_bool_param("LOOKAHEAD_DISEQ", m_lookahead_diseq);
|
||||
|
||||
p.register_bool_param("DELAY_UNITS", m_delay_units);
|
||||
p.register_unsigned_param("DELAY_UNITS_THRESHOLD", m_delay_units_threshold);
|
||||
|
||||
p.register_bool_param("MODEL", m_model, "enable/disable model construction", true);
|
||||
p.register_bool_param("MODEL_VALIDATE", m_model_validate, "validate the model", true);
|
||||
p.register_bool_param("MODEL_ON_TIMEOUT", m_model_on_timeout, "after hitting soft-timeout or memory high watermark, generate a candidate model", true);
|
||||
p.register_bool_param("MODEL_ON_FINAL_CHECK", m_model_on_final_check, "display candidate model (in the standard output) whenever Z3 hits a final check", true);
|
||||
|
||||
p.register_unsigned_param("PROGRESS_SAMPLING_FREQ", m_progress_sampling_freq, "frequency for progress output in miliseconds");
|
||||
}
|
||||
|
257
lib/smt_params.h
257
lib/smt_params.h
|
@ -1,257 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
smt_params.h
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-02-20.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _SMT_PARAMS_H_
|
||||
#define _SMT_PARAMS_H_
|
||||
|
||||
#include"ini_file.h"
|
||||
#include"dyn_ack_params.h"
|
||||
#include"qi_params.h"
|
||||
#include"theory_arith_params.h"
|
||||
#include"theory_array_params.h"
|
||||
#include"theory_bv_params.h"
|
||||
#include"theory_datatype_params.h"
|
||||
|
||||
enum phase_selection {
|
||||
PS_ALWAYS_FALSE,
|
||||
PS_ALWAYS_TRUE,
|
||||
PS_CACHING,
|
||||
PS_CACHING_CONSERVATIVE,
|
||||
PS_CACHING_CONSERVATIVE2, // similar to the previous one, but alternated default config from time to time.
|
||||
PS_RANDOM,
|
||||
PS_OCCURRENCE
|
||||
};
|
||||
|
||||
enum restart_strategy {
|
||||
RS_GEOMETRIC,
|
||||
RS_IN_OUT_GEOMETRIC,
|
||||
RS_LUBY,
|
||||
RS_FIXED,
|
||||
RS_ARITHMETIC
|
||||
};
|
||||
|
||||
enum lemma_gc_strategy {
|
||||
LGC_FIXED,
|
||||
LGC_GEOMETRIC,
|
||||
LGC_AT_RESTART
|
||||
};
|
||||
|
||||
enum initial_activity {
|
||||
IA_ZERO, // initialized with 0
|
||||
IA_RANDOM_WHEN_SEARCHING, // random when searching
|
||||
IA_RANDOM // always random
|
||||
};
|
||||
|
||||
enum case_split_strategy {
|
||||
CS_ACTIVITY, // case split based on activity
|
||||
CS_ACTIVITY_DELAY_NEW, // case split based on activity but delay new case splits created during the search
|
||||
CS_ACTIVITY_WITH_CACHE, // case split based on activity and cache the activity
|
||||
CS_RELEVANCY, // case split based on relevancy
|
||||
CS_RELEVANCY_ACTIVITY, // case split based on relevancy and activity
|
||||
CS_RELEVANCY_GOAL, // based on relevancy and the current goal
|
||||
};
|
||||
|
||||
struct smt_params : public dyn_ack_params, public qi_params, public theory_arith_params, public theory_array_params, public theory_bv_params,
|
||||
public theory_datatype_params {
|
||||
bool m_display_proof;
|
||||
bool m_display_dot_proof;
|
||||
bool m_display_unsat_core;
|
||||
bool m_check_proof;
|
||||
bool m_internalizer_nnf;
|
||||
bool m_eq_propagation;
|
||||
bool m_binary_clause_opt;
|
||||
unsigned m_relevancy_lvl;
|
||||
bool m_relevancy_lemma;
|
||||
unsigned m_random_seed;
|
||||
double m_random_var_freq;
|
||||
double m_inv_decay;
|
||||
unsigned m_clause_decay;
|
||||
initial_activity m_random_initial_activity;
|
||||
phase_selection m_phase_selection;
|
||||
unsigned m_phase_caching_on;
|
||||
unsigned m_phase_caching_off;
|
||||
bool m_minimize_lemmas;
|
||||
unsigned m_max_conflicts;
|
||||
bool m_simplify_clauses;
|
||||
unsigned m_tick;
|
||||
bool m_display_features;
|
||||
bool m_new_core2th_eq;
|
||||
bool m_ematching;
|
||||
|
||||
// -----------------------------------
|
||||
//
|
||||
// Case split strategy
|
||||
//
|
||||
// -----------------------------------
|
||||
case_split_strategy m_case_split_strategy;
|
||||
unsigned m_rel_case_split_order;
|
||||
bool m_lookahead_diseq;
|
||||
|
||||
// -----------------------------------
|
||||
//
|
||||
// Delay units...
|
||||
//
|
||||
// -----------------------------------
|
||||
bool m_delay_units;
|
||||
unsigned m_delay_units_threshold;
|
||||
|
||||
// -----------------------------------
|
||||
//
|
||||
// Conflict resolution
|
||||
//
|
||||
// -----------------------------------
|
||||
bool m_theory_resolve;
|
||||
|
||||
// -----------------------------------
|
||||
//
|
||||
// Restart
|
||||
//
|
||||
// -----------------------------------
|
||||
restart_strategy m_restart_strategy;
|
||||
unsigned m_restart_initial;
|
||||
double m_restart_factor;
|
||||
bool m_restart_adaptive;
|
||||
double m_agility_factor;
|
||||
double m_restart_agility_threshold;
|
||||
|
||||
// -----------------------------------
|
||||
//
|
||||
// Lemma garbage collection
|
||||
//
|
||||
// -----------------------------------
|
||||
lemma_gc_strategy m_lemma_gc_strategy;
|
||||
bool m_lemma_gc_half;
|
||||
unsigned m_recent_lemmas_size;
|
||||
unsigned m_lemma_gc_initial;
|
||||
double m_lemma_gc_factor;
|
||||
unsigned m_new_old_ratio; //!< the ratio of new and old clauses.
|
||||
unsigned m_new_clause_activity;
|
||||
unsigned m_old_clause_activity;
|
||||
unsigned m_new_clause_relevancy; //!< Max. number of unassigned literals to be considered relevant.
|
||||
unsigned m_old_clause_relevancy; //!< Max. number of unassigned literals to be considered relevant.
|
||||
double m_inv_clause_decay; //!< clause activity decay
|
||||
|
||||
// -----------------------------------
|
||||
//
|
||||
// SMT-LIB (debug) pretty printer
|
||||
//
|
||||
// -----------------------------------
|
||||
bool m_smtlib_dump_lemmas;
|
||||
std::string m_smtlib_logic;
|
||||
|
||||
// -----------------------------------
|
||||
//
|
||||
// Statistics for Profiling
|
||||
//
|
||||
// -----------------------------------
|
||||
bool m_profile_res_sub;
|
||||
bool m_display_bool_var2expr;
|
||||
bool m_display_ll_bool_var2expr;
|
||||
bool m_abort_after_preproc;
|
||||
|
||||
// -----------------------------------
|
||||
//
|
||||
// Model generation
|
||||
//
|
||||
// -----------------------------------
|
||||
bool m_model;
|
||||
bool m_model_validate;
|
||||
bool m_model_on_timeout;
|
||||
bool m_model_on_final_check;
|
||||
|
||||
// -----------------------------------
|
||||
//
|
||||
// Progress sampling
|
||||
//
|
||||
// -----------------------------------
|
||||
unsigned m_progress_sampling_freq;
|
||||
|
||||
// -----------------------------------
|
||||
//
|
||||
// Debugging goodies
|
||||
//
|
||||
// -----------------------------------
|
||||
bool m_display_installed_theories;
|
||||
|
||||
smt_params():
|
||||
m_display_proof(false),
|
||||
m_display_dot_proof(false),
|
||||
m_display_unsat_core(false),
|
||||
m_check_proof(false),
|
||||
m_internalizer_nnf(false),
|
||||
m_eq_propagation(true),
|
||||
m_binary_clause_opt(true),
|
||||
m_relevancy_lvl(2),
|
||||
m_relevancy_lemma(false),
|
||||
m_random_seed(0),
|
||||
m_random_var_freq(0.01),
|
||||
m_inv_decay(1.052),
|
||||
m_clause_decay(1),
|
||||
m_random_initial_activity(IA_RANDOM_WHEN_SEARCHING),
|
||||
m_phase_selection(PS_CACHING_CONSERVATIVE),
|
||||
m_phase_caching_on(400),
|
||||
m_phase_caching_off(100),
|
||||
m_minimize_lemmas(true),
|
||||
m_max_conflicts(UINT_MAX),
|
||||
m_simplify_clauses(true),
|
||||
m_tick(1000),
|
||||
m_display_features(false),
|
||||
m_new_core2th_eq(true),
|
||||
m_ematching(true),
|
||||
m_case_split_strategy(CS_ACTIVITY_DELAY_NEW),
|
||||
m_rel_case_split_order(0),
|
||||
m_lookahead_diseq(false),
|
||||
m_delay_units(false),
|
||||
m_delay_units_threshold(32),
|
||||
m_theory_resolve(false),
|
||||
m_restart_strategy(RS_IN_OUT_GEOMETRIC),
|
||||
m_restart_initial(100),
|
||||
m_restart_factor(1.1),
|
||||
m_restart_adaptive(true),
|
||||
m_agility_factor(0.9999),
|
||||
m_restart_agility_threshold(0.18),
|
||||
m_lemma_gc_strategy(LGC_FIXED),
|
||||
m_lemma_gc_half(false),
|
||||
m_recent_lemmas_size(100),
|
||||
m_lemma_gc_initial(5000),
|
||||
m_lemma_gc_factor(1.1),
|
||||
m_new_old_ratio(16),
|
||||
m_new_clause_activity(10),
|
||||
m_old_clause_activity(500),
|
||||
m_new_clause_relevancy(45),
|
||||
m_old_clause_relevancy(6),
|
||||
m_inv_clause_decay(1),
|
||||
m_smtlib_dump_lemmas(false),
|
||||
m_smtlib_logic("AUFLIA"),
|
||||
m_profile_res_sub(false),
|
||||
m_display_bool_var2expr(false),
|
||||
m_display_ll_bool_var2expr(false),
|
||||
m_abort_after_preproc(false),
|
||||
m_model(true),
|
||||
m_model_validate(false),
|
||||
m_model_on_timeout(false),
|
||||
m_model_on_final_check(false),
|
||||
m_progress_sampling_freq(0),
|
||||
m_display_installed_theories(false) {
|
||||
}
|
||||
|
||||
void register_params(ini_params & p);
|
||||
};
|
||||
|
||||
#endif /* _SMT_PARAMS_H_ */
|
||||
|
|
@ -1,353 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
smt_solver.h
|
||||
|
||||
Abstract:
|
||||
|
||||
New frontend for the incremental solver.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-02-09.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"smt_solver.h"
|
||||
#include"smt_context.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
#include"params2front_end_params.h"
|
||||
|
||||
namespace smt {
|
||||
|
||||
struct solver::imp {
|
||||
smt::context m_kernel;
|
||||
params_ref m_params;
|
||||
|
||||
imp(ast_manager & m, front_end_params & fp, params_ref const & p):
|
||||
m_kernel(m, fp, p),
|
||||
m_params(p) {
|
||||
}
|
||||
|
||||
front_end_params & fparams() {
|
||||
return m_kernel.get_fparams();
|
||||
}
|
||||
|
||||
params_ref const & params() {
|
||||
return m_params;
|
||||
}
|
||||
|
||||
ast_manager & m() const {
|
||||
return m_kernel.get_manager();
|
||||
}
|
||||
|
||||
bool set_logic(symbol logic) {
|
||||
return m_kernel.set_logic(logic);
|
||||
}
|
||||
|
||||
void set_progress_callback(progress_callback * callback) {
|
||||
return m_kernel.set_progress_callback(callback);
|
||||
}
|
||||
|
||||
void assert_expr(expr * e) {
|
||||
TRACE("smt_solver", tout << "assert:\n" << mk_ismt2_pp(e, m()) << "\n";);
|
||||
m_kernel.assert_expr(e);
|
||||
}
|
||||
|
||||
void assert_expr(expr * e, proof * pr) {
|
||||
m_kernel.assert_expr(e, pr);
|
||||
}
|
||||
|
||||
unsigned size() const {
|
||||
return m_kernel.get_num_asserted_formulas();
|
||||
}
|
||||
|
||||
expr * const * get_formulas() const {
|
||||
return m_kernel.get_asserted_formulas();
|
||||
}
|
||||
|
||||
bool reduce() {
|
||||
return m_kernel.reduce_assertions();
|
||||
}
|
||||
|
||||
void push() {
|
||||
TRACE("smt_solver", tout << "push()\n";);
|
||||
m_kernel.push();
|
||||
}
|
||||
|
||||
void pop(unsigned num_scopes) {
|
||||
TRACE("smt_solver", tout << "pop()\n";);
|
||||
m_kernel.pop(num_scopes);
|
||||
}
|
||||
|
||||
unsigned get_scope_level() const {
|
||||
return m_kernel.get_scope_level();
|
||||
}
|
||||
|
||||
lbool setup_and_check() {
|
||||
return m_kernel.setup_and_check();
|
||||
}
|
||||
|
||||
bool inconsistent() {
|
||||
return m_kernel.inconsistent();
|
||||
}
|
||||
|
||||
lbool check(unsigned num_assumptions, expr * const * assumptions) {
|
||||
return m_kernel.check(num_assumptions, assumptions);
|
||||
}
|
||||
|
||||
void get_model(model_ref & m) const {
|
||||
m_kernel.get_model(m);
|
||||
}
|
||||
|
||||
proof * get_proof() {
|
||||
return m_kernel.get_proof();
|
||||
}
|
||||
|
||||
unsigned get_unsat_core_size() const {
|
||||
return m_kernel.get_unsat_core_size();
|
||||
}
|
||||
|
||||
expr * get_unsat_core_expr(unsigned idx) const {
|
||||
return m_kernel.get_unsat_core_expr(idx);
|
||||
}
|
||||
|
||||
failure last_failure() const {
|
||||
return m_kernel.get_last_search_failure();
|
||||
}
|
||||
|
||||
std::string last_failure_as_string() const {
|
||||
return m_kernel.last_failure_as_string();
|
||||
}
|
||||
|
||||
void get_assignments(expr_ref_vector & result) {
|
||||
m_kernel.get_assignments(result);
|
||||
}
|
||||
|
||||
void get_relevant_labels(expr * cnstr, buffer<symbol> & result) {
|
||||
m_kernel.get_relevant_labels(cnstr, result);
|
||||
}
|
||||
|
||||
void get_relevant_labeled_literals(bool at_lbls, expr_ref_vector & result) {
|
||||
m_kernel.get_relevant_labeled_literals(at_lbls, result);
|
||||
}
|
||||
|
||||
void get_relevant_literals(expr_ref_vector & result) {
|
||||
m_kernel.get_relevant_literals(result);
|
||||
}
|
||||
|
||||
void get_guessed_literals(expr_ref_vector & result) {
|
||||
m_kernel.get_guessed_literals(result);
|
||||
}
|
||||
|
||||
void display(std::ostream & out) const {
|
||||
// m_kernel.display(out); <<< for external users it is just junk
|
||||
// TODO: it will be replaced with assertion_stack.display
|
||||
unsigned num = m_kernel.get_num_asserted_formulas();
|
||||
expr * const * fms = m_kernel.get_asserted_formulas();
|
||||
out << "(solver";
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
out << "\n " << mk_ismt2_pp(fms[i], m(), 2);
|
||||
}
|
||||
out << ")";
|
||||
}
|
||||
|
||||
void collect_statistics(::statistics & st) const {
|
||||
m_kernel.collect_statistics(st);
|
||||
}
|
||||
|
||||
void reset_statistics() {
|
||||
}
|
||||
|
||||
void display_statistics(std::ostream & out) const {
|
||||
m_kernel.display_statistics(out);
|
||||
}
|
||||
|
||||
void display_istatistics(std::ostream & out) const {
|
||||
m_kernel.display_istatistics(out);
|
||||
}
|
||||
|
||||
void set_cancel(bool f) {
|
||||
m_kernel.set_cancel_flag(f);
|
||||
}
|
||||
|
||||
bool canceled() {
|
||||
return m_kernel.get_cancel_flag();
|
||||
}
|
||||
|
||||
void updt_params(params_ref const & p) {
|
||||
params2front_end_params(p, fparams());
|
||||
}
|
||||
};
|
||||
|
||||
solver::solver(ast_manager & m, front_end_params & fp, params_ref const & p) {
|
||||
m_imp = alloc(imp, m, fp, p);
|
||||
}
|
||||
|
||||
solver::~solver() {
|
||||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
ast_manager & solver::m() const {
|
||||
return m_imp->m();
|
||||
}
|
||||
|
||||
bool solver::set_logic(symbol logic) {
|
||||
return m_imp->set_logic(logic);
|
||||
}
|
||||
|
||||
void solver::set_progress_callback(progress_callback * callback) {
|
||||
m_imp->set_progress_callback(callback);
|
||||
}
|
||||
|
||||
void solver::assert_expr(expr * e) {
|
||||
m_imp->assert_expr(e);
|
||||
}
|
||||
|
||||
void solver::assert_expr(expr * e, proof * pr) {
|
||||
m_imp->assert_expr(e, pr);
|
||||
}
|
||||
|
||||
unsigned solver::size() const {
|
||||
return m_imp->size();
|
||||
}
|
||||
|
||||
expr * const * solver::get_formulas() const {
|
||||
return m_imp->get_formulas();
|
||||
}
|
||||
|
||||
bool solver::reduce() {
|
||||
return m_imp->reduce();
|
||||
}
|
||||
|
||||
void solver::push() {
|
||||
m_imp->push();
|
||||
}
|
||||
|
||||
void solver::pop(unsigned num_scopes) {
|
||||
m_imp->pop(num_scopes);
|
||||
}
|
||||
|
||||
unsigned solver::get_scope_level() const {
|
||||
return m_imp->get_scope_level();
|
||||
}
|
||||
|
||||
void solver::reset() {
|
||||
ast_manager & _m = m();
|
||||
front_end_params & fps = m_imp->fparams();
|
||||
params_ref ps = m_imp->params();
|
||||
#pragma omp critical (smt_solver)
|
||||
{
|
||||
dealloc(m_imp);
|
||||
m_imp = alloc(imp, _m, fps, ps);
|
||||
}
|
||||
}
|
||||
|
||||
bool solver::inconsistent() {
|
||||
return m_imp->inconsistent();
|
||||
}
|
||||
|
||||
lbool solver::setup_and_check() {
|
||||
set_cancel(false);
|
||||
return m_imp->setup_and_check();
|
||||
}
|
||||
|
||||
lbool solver::check(unsigned num_assumptions, expr * const * assumptions) {
|
||||
set_cancel(false);
|
||||
lbool r = m_imp->check(num_assumptions, assumptions);
|
||||
TRACE("smt_solver", tout << "check result: " << r << "\n";);
|
||||
return r;
|
||||
}
|
||||
|
||||
void solver::get_model(model_ref & m) const {
|
||||
m_imp->get_model(m);
|
||||
}
|
||||
|
||||
proof * solver::get_proof() {
|
||||
return m_imp->get_proof();
|
||||
}
|
||||
|
||||
unsigned solver::get_unsat_core_size() const {
|
||||
return m_imp->get_unsat_core_size();
|
||||
}
|
||||
|
||||
expr * solver::get_unsat_core_expr(unsigned idx) const {
|
||||
return m_imp->get_unsat_core_expr(idx);
|
||||
}
|
||||
|
||||
failure solver::last_failure() const {
|
||||
return m_imp->last_failure();
|
||||
}
|
||||
|
||||
std::string solver::last_failure_as_string() const {
|
||||
return m_imp->last_failure_as_string();
|
||||
}
|
||||
|
||||
void solver::get_assignments(expr_ref_vector & result) {
|
||||
m_imp->get_assignments(result);
|
||||
}
|
||||
|
||||
void solver::get_relevant_labels(expr * cnstr, buffer<symbol> & result) {
|
||||
m_imp->get_relevant_labels(cnstr, result);
|
||||
}
|
||||
|
||||
void solver::get_relevant_labeled_literals(bool at_lbls, expr_ref_vector & result) {
|
||||
m_imp->get_relevant_labeled_literals(at_lbls, result);
|
||||
}
|
||||
|
||||
void solver::get_relevant_literals(expr_ref_vector & result) {
|
||||
m_imp->get_relevant_literals(result);
|
||||
}
|
||||
|
||||
void solver::get_guessed_literals(expr_ref_vector & result) {
|
||||
m_imp->get_guessed_literals(result);
|
||||
}
|
||||
|
||||
void solver::display(std::ostream & out) const {
|
||||
m_imp->display(out);
|
||||
}
|
||||
|
||||
void solver::collect_statistics(::statistics & st) const {
|
||||
m_imp->collect_statistics(st);
|
||||
}
|
||||
|
||||
void solver::reset_statistics() {
|
||||
m_imp->reset_statistics();
|
||||
}
|
||||
|
||||
void solver::display_statistics(std::ostream & out) const {
|
||||
m_imp->display_statistics(out);
|
||||
}
|
||||
|
||||
void solver::display_istatistics(std::ostream & out) const {
|
||||
m_imp->display_istatistics(out);
|
||||
}
|
||||
|
||||
void solver::set_cancel(bool f) {
|
||||
#pragma omp critical (smt_solver)
|
||||
{
|
||||
if (m_imp)
|
||||
m_imp->set_cancel(f);
|
||||
}
|
||||
}
|
||||
|
||||
bool solver::canceled() const {
|
||||
return m_imp->canceled();
|
||||
}
|
||||
|
||||
void solver::updt_params(params_ref const & p) {
|
||||
return m_imp->updt_params(p);
|
||||
}
|
||||
|
||||
void solver::collect_param_descrs(param_descrs & d) {
|
||||
solver_front_end_params_descrs(d);
|
||||
}
|
||||
|
||||
context & solver::kernel() {
|
||||
return m_imp->m_kernel;
|
||||
}
|
||||
|
||||
};
|
247
lib/smt_solver.h
247
lib/smt_solver.h
|
@ -1,247 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
smt_solver.h
|
||||
|
||||
Abstract:
|
||||
|
||||
New frontend for the incremental solver.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-02-09.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _SMT_SOLVER_H_
|
||||
#define _SMT_SOLVER_H_
|
||||
|
||||
#include"ast.h"
|
||||
#include"params.h"
|
||||
#include"model.h"
|
||||
#include"lbool.h"
|
||||
#include"statistics.h"
|
||||
#include"smt_failure.h"
|
||||
|
||||
struct front_end_params;
|
||||
class progress_callback;
|
||||
|
||||
namespace smt {
|
||||
|
||||
class enode;
|
||||
class context;
|
||||
|
||||
class solver {
|
||||
struct imp;
|
||||
imp * m_imp;
|
||||
public:
|
||||
solver(ast_manager & m, front_end_params & fp, params_ref const & p = params_ref());
|
||||
|
||||
~solver();
|
||||
|
||||
ast_manager & m() const;
|
||||
|
||||
/**
|
||||
\brief Set logic. It must be invoked before any assertions.
|
||||
Return true if succeeded.
|
||||
*/
|
||||
bool set_logic(symbol logic);
|
||||
|
||||
/**
|
||||
brief Set progress meter. Solver will invoke the callback from time to time.
|
||||
*/
|
||||
void set_progress_callback(progress_callback * callback);
|
||||
|
||||
/**
|
||||
\brief Assert the given assetion into the logical context.
|
||||
This method uses the "asserted" proof as a justification for e.
|
||||
*/
|
||||
void assert_expr(expr * e);
|
||||
|
||||
/**
|
||||
\brief Assert the given assertion with the given proof as a justification.
|
||||
*/
|
||||
void assert_expr(expr * e, proof * pr);
|
||||
|
||||
/**
|
||||
\brief Return the number of asserted formulas in the solver.
|
||||
*/
|
||||
unsigned size() const;
|
||||
|
||||
/**
|
||||
\brief Return the array of asserted formulas.
|
||||
*/
|
||||
expr * const * get_formulas() const;
|
||||
|
||||
/**
|
||||
\brief Reduce the set of asserted formulas using preprocessors.
|
||||
Return true if an inconsistency is detected.
|
||||
|
||||
\remark This is mainly used by dl_smt_relation. This method
|
||||
seens to be misplaced. This is not the right place.
|
||||
*/
|
||||
bool reduce();
|
||||
|
||||
/**
|
||||
\brief Create a backtracking point (aka scope level).
|
||||
*/
|
||||
void push();
|
||||
|
||||
/**
|
||||
\brief Backtrack the given number of scope levels.
|
||||
*/
|
||||
void pop(unsigned num_scopes);
|
||||
|
||||
/**
|
||||
\brief Return the number of backtracking points.
|
||||
*/
|
||||
unsigned get_scope_level() const;
|
||||
|
||||
/**
|
||||
\brief Reset the solver.
|
||||
All assertions are erased.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
\brief Return true if the set of asserted formulas is known to be inconsistent.
|
||||
*/
|
||||
bool inconsistent();
|
||||
|
||||
/**
|
||||
\brief Setup the logical context and invoke check.
|
||||
*/
|
||||
lbool setup_and_check();
|
||||
|
||||
/**
|
||||
\brief Satisfiability check.
|
||||
*/
|
||||
lbool check(unsigned num_assumptions = 0, expr * const * assumptions = 0);
|
||||
|
||||
/**
|
||||
\brief Return the model associated with the last check command.
|
||||
*/
|
||||
void get_model(model_ref & m) const;
|
||||
|
||||
/**
|
||||
\brief Return the proof of unsatisfiability associated with the last check command.
|
||||
*/
|
||||
proof * get_proof();
|
||||
|
||||
/**
|
||||
\brief Return the size of the unsat core associated with the last check command.
|
||||
*/
|
||||
unsigned get_unsat_core_size() const;
|
||||
|
||||
/**
|
||||
\brief Return the i-th expression in the unsat core associated with the last check command.
|
||||
|
||||
\pre i < get_unsat_core_size()
|
||||
*/
|
||||
expr * get_unsat_core_expr(unsigned i) const;
|
||||
|
||||
/**
|
||||
\brief Return the reason for failure for the last check command.
|
||||
Failure means, it returned l_undef
|
||||
*/
|
||||
failure last_failure() const;
|
||||
|
||||
/**
|
||||
\brief Return a string describing the failure.
|
||||
*/
|
||||
std::string last_failure_as_string() const;
|
||||
|
||||
/**
|
||||
\brief Return the set of formulas assigned by the solver.
|
||||
*/
|
||||
void get_assignments(expr_ref_vector & result);
|
||||
|
||||
/**
|
||||
\brief Return the set of relevant labels in the last check command.
|
||||
*/
|
||||
void get_relevant_labels(expr * cnstr, buffer<symbol> & result);
|
||||
|
||||
/**
|
||||
\brief Return the relevant labeled_literals in the last check command.
|
||||
*/
|
||||
void get_relevant_labeled_literals(bool at_lbls, expr_ref_vector & result);
|
||||
|
||||
/**
|
||||
\brief Return the relevant literals in the last check command.
|
||||
*/
|
||||
void get_relevant_literals(expr_ref_vector & result);
|
||||
|
||||
/**
|
||||
\brief Return the set of guessed literals (decisions) performed in the last check command.
|
||||
*/
|
||||
void get_guessed_literals(expr_ref_vector & result);
|
||||
|
||||
/**
|
||||
\brief (For debubbing purposes) Prints the state of the solver
|
||||
*/
|
||||
void display(std::ostream & out) const;
|
||||
|
||||
/**
|
||||
\brief Collect runtime statistics.
|
||||
*/
|
||||
void collect_statistics(::statistics & st) const;
|
||||
|
||||
/**
|
||||
\brief Reset solver statistics.
|
||||
*/
|
||||
void reset_statistics();
|
||||
|
||||
/**
|
||||
\brief Display statistics.
|
||||
*/
|
||||
void display_statistics(std::ostream & out) const;
|
||||
|
||||
/**
|
||||
\brief Display statistics in low level format.
|
||||
*/
|
||||
void display_istatistics(std::ostream & out) const;
|
||||
|
||||
/**
|
||||
\brief Interrupt the solver.
|
||||
*/
|
||||
void set_cancel(bool f = true);
|
||||
void cancel() { set_cancel(true); }
|
||||
|
||||
/**
|
||||
\brief Reset interruption.
|
||||
*/
|
||||
void reset_cancel() { set_cancel(false); }
|
||||
|
||||
/**
|
||||
\brief Return true if the solver was interrupted.
|
||||
*/
|
||||
bool canceled() const;
|
||||
|
||||
/**
|
||||
\brief Update configuration parameters.
|
||||
*/
|
||||
void updt_params(params_ref const & p);
|
||||
|
||||
/**
|
||||
\brief Collect a description of the configuration parameters.
|
||||
*/
|
||||
static void collect_param_descrs(param_descrs & d);
|
||||
|
||||
/**
|
||||
\brief Return a reference to the kernel.
|
||||
This is a temporary hack to support user theories.
|
||||
TODO: remove this hack.
|
||||
We need to revamp user theories too.
|
||||
|
||||
This method breaks the abstraction barrier.
|
||||
|
||||
\warning We should not use this method
|
||||
*/
|
||||
context & kernel();
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
193
lib/solver.cpp
193
lib/solver.cpp
|
@ -1,193 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
solver.h
|
||||
|
||||
Abstract:
|
||||
|
||||
abstract solver interface
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-03-19
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"solver.h"
|
||||
#include"smt_solver.h"
|
||||
|
||||
unsigned solver::get_num_assertions() const {
|
||||
NOT_IMPLEMENTED_YET();
|
||||
return 0;
|
||||
}
|
||||
|
||||
expr * solver::get_assertion(unsigned idx) const {
|
||||
NOT_IMPLEMENTED_YET();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void solver::display(std::ostream & out) const {
|
||||
out << "(solver)";
|
||||
}
|
||||
|
||||
class default_solver : public solver {
|
||||
front_end_params * m_params;
|
||||
smt::solver * m_context;
|
||||
public:
|
||||
default_solver():m_params(0), m_context(0) {}
|
||||
|
||||
virtual ~default_solver() {
|
||||
if (m_context != 0)
|
||||
dealloc(m_context);
|
||||
}
|
||||
|
||||
virtual void set_front_end_params(front_end_params & p) {
|
||||
m_params = &p;
|
||||
}
|
||||
|
||||
virtual void updt_params(params_ref const & p) {
|
||||
if (m_context == 0)
|
||||
return;
|
||||
m_context->updt_params(p);
|
||||
}
|
||||
|
||||
virtual void collect_param_descrs(param_descrs & r) {
|
||||
if (m_context == 0) {
|
||||
ast_manager m;
|
||||
m.register_decl_plugins();
|
||||
front_end_params p;
|
||||
smt::solver s(m, p);
|
||||
s.collect_param_descrs(r);
|
||||
}
|
||||
else {
|
||||
m_context->collect_param_descrs(r);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void init(ast_manager & m, symbol const & logic) {
|
||||
SASSERT(m_params);
|
||||
reset();
|
||||
#pragma omp critical (solver)
|
||||
{
|
||||
m_context = alloc(smt::solver, m, *m_params);
|
||||
}
|
||||
if (logic != symbol::null)
|
||||
m_context->set_logic(logic);
|
||||
}
|
||||
|
||||
virtual void collect_statistics(statistics & st) const {
|
||||
if (m_context == 0) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
m_context->collect_statistics(st);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void reset() {
|
||||
if (m_context != 0) {
|
||||
#pragma omp critical (solver)
|
||||
{
|
||||
dealloc(m_context);
|
||||
m_context = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void assert_expr(expr * t) {
|
||||
SASSERT(m_context);
|
||||
m_context->assert_expr(t);
|
||||
}
|
||||
|
||||
virtual void push() {
|
||||
SASSERT(m_context);
|
||||
m_context->push();
|
||||
}
|
||||
|
||||
virtual void pop(unsigned n) {
|
||||
SASSERT(m_context);
|
||||
m_context->pop(n);
|
||||
}
|
||||
|
||||
virtual unsigned get_scope_level() const {
|
||||
if (m_context)
|
||||
return m_context->get_scope_level();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual lbool check_sat(unsigned num_assumptions, expr * const * assumptions) {
|
||||
SASSERT(m_context);
|
||||
return m_context->check(num_assumptions, assumptions);
|
||||
}
|
||||
|
||||
virtual void get_unsat_core(ptr_vector<expr> & r) {
|
||||
SASSERT(m_context);
|
||||
unsigned sz = m_context->get_unsat_core_size();
|
||||
for (unsigned i = 0; i < sz; i++)
|
||||
r.push_back(m_context->get_unsat_core_expr(i));
|
||||
}
|
||||
|
||||
virtual void get_model(model_ref & m) {
|
||||
SASSERT(m_context);
|
||||
m_context->get_model(m);
|
||||
}
|
||||
|
||||
virtual proof * get_proof() {
|
||||
SASSERT(m_context);
|
||||
return m_context->get_proof();
|
||||
}
|
||||
|
||||
virtual std::string reason_unknown() const {
|
||||
SASSERT(m_context);
|
||||
return m_context->last_failure_as_string();
|
||||
}
|
||||
|
||||
virtual void get_labels(svector<symbol> & r) {
|
||||
SASSERT(m_context);
|
||||
buffer<symbol> tmp;
|
||||
m_context->get_relevant_labels(0, tmp);
|
||||
r.append(tmp.size(), tmp.c_ptr());
|
||||
}
|
||||
|
||||
virtual void set_cancel(bool f) {
|
||||
#pragma omp critical (solver)
|
||||
{
|
||||
if (m_context)
|
||||
m_context->set_cancel(f);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void set_progress_callback(progress_callback * callback) {
|
||||
SASSERT(m_context);
|
||||
m_context->set_progress_callback(callback);
|
||||
}
|
||||
|
||||
virtual unsigned get_num_assertions() const {
|
||||
if (m_context)
|
||||
return m_context->size();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual expr * get_assertion(unsigned idx) const {
|
||||
SASSERT(m_context);
|
||||
SASSERT(idx < get_num_assertions());
|
||||
return m_context->get_formulas()[idx];
|
||||
}
|
||||
|
||||
virtual void display(std::ostream & out) const {
|
||||
if (m_context)
|
||||
m_context->display(out);
|
||||
else
|
||||
out << "(solver)";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
solver * mk_default_solver() {
|
||||
return alloc(default_solver);
|
||||
}
|
63
lib/solver.h
63
lib/solver.h
|
@ -1,63 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
solver.h
|
||||
|
||||
Abstract:
|
||||
|
||||
abstract solver interface
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-03-19
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _SOLVER_H_
|
||||
#define _SOLVER_H_
|
||||
|
||||
#include"check_sat_result.h"
|
||||
#include"front_end_params.h"
|
||||
#include"progress_callback.h"
|
||||
#include"params.h"
|
||||
|
||||
class solver : public check_sat_result {
|
||||
public:
|
||||
virtual ~solver() {}
|
||||
|
||||
// for backward compatibility
|
||||
virtual void set_front_end_params(front_end_params & p) {}
|
||||
|
||||
virtual void updt_params(params_ref const & p) {}
|
||||
virtual void collect_param_descrs(param_descrs & r) {}
|
||||
|
||||
virtual void set_produce_proofs(bool f) {}
|
||||
virtual void set_produce_models(bool f) {}
|
||||
virtual void set_produce_unsat_cores(bool f) {}
|
||||
|
||||
virtual void init(ast_manager & m, symbol const & logic) = 0;
|
||||
virtual void reset() = 0;
|
||||
virtual void assert_expr(expr * t) = 0;
|
||||
virtual void push() = 0;
|
||||
virtual void pop(unsigned n) = 0;
|
||||
virtual unsigned get_scope_level() const = 0;
|
||||
virtual lbool check_sat(unsigned num_assumptions, expr * const * assumptions) = 0;
|
||||
|
||||
virtual void set_cancel(bool f) {}
|
||||
void cancel() { set_cancel(true); }
|
||||
void reset_cancel() { set_cancel(false); }
|
||||
|
||||
virtual void set_progress_callback(progress_callback * callback) = 0;
|
||||
|
||||
virtual unsigned get_num_assertions() const;
|
||||
virtual expr * get_assertion(unsigned idx) const;
|
||||
|
||||
virtual void display(std::ostream & out) const;
|
||||
};
|
||||
|
||||
solver * mk_default_solver();
|
||||
|
||||
#endif
|
|
@ -1,37 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
spc_params.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-02-08.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"spc_params.h"
|
||||
|
||||
void spc_params::register_params(ini_params & p) {
|
||||
order_params::register_params(p);
|
||||
p.register_unsigned_param("SPC_MIN_FUNC_FREQ_SUBSUMPTION_INDEX",m_min_func_freq_subsumption_index,
|
||||
"minimal number of occurrences (in clauses) for a function symbol to be considered for subsumption indexing.");
|
||||
p.register_unsigned_param("SPC_MAX_SUBSUMPTION_INDEX_FEATURES", m_max_subsumption_index_features,
|
||||
"maximum number of features to be used for subsumption index.");
|
||||
p.register_unsigned_param("SPC_INITIAL_SUBSUMPTION_INDEX_OPT", m_initial_subsumption_index_opt,
|
||||
"after how many processed clauses the subsumption index is optimized.");
|
||||
p.register_double_param("SPC_FACTOR_SUBSUMPTION_INDEX_OPT", m_factor_subsumption_index_opt,
|
||||
"after each optimization the threshold for optimization is increased by this factor. See INITIAL_SUBSUMPTION_INDEX_OPT.");
|
||||
p.register_bool_param("SPC_BS", m_backward_subsumption, "Enable/disable backward subsumption in the superposition engine");
|
||||
p.register_bool_param("SPC_ES", m_equality_subsumption, "Enable/disable equality resolution in the superposition engine");
|
||||
p.register_unsigned_param("SPC_NUM_ITERATIONS", m_spc_num_iterations);
|
||||
p.register_bool_param("SPC_TRACE", m_spc_trace);
|
||||
}
|
||||
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
spc_params.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Parameters for the Superposition Calculus Engine
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-02-08.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _SPC_PARAMS_H_
|
||||
#define _SPC_PARAMS_H_
|
||||
|
||||
#include"order_params.h"
|
||||
|
||||
struct spc_params : public order_params {
|
||||
unsigned m_min_func_freq_subsumption_index;
|
||||
unsigned m_max_subsumption_index_features;
|
||||
unsigned m_initial_subsumption_index_opt;
|
||||
double m_factor_subsumption_index_opt;
|
||||
bool m_backward_subsumption;
|
||||
bool m_equality_subsumption;
|
||||
unsigned m_spc_num_iterations;
|
||||
bool m_spc_trace;
|
||||
|
||||
spc_params():
|
||||
m_min_func_freq_subsumption_index(100),
|
||||
m_max_subsumption_index_features(32),
|
||||
m_initial_subsumption_index_opt(1000),
|
||||
m_factor_subsumption_index_opt(1.5),
|
||||
m_backward_subsumption(true),
|
||||
m_equality_subsumption(true),
|
||||
m_spc_num_iterations(1000),
|
||||
m_spc_trace(false) {
|
||||
}
|
||||
|
||||
void register_params(ini_params & p);
|
||||
};
|
||||
|
||||
#endif /* _SPC_PARAMS_H_ */
|
||||
|
331
lib/tactic.cpp
331
lib/tactic.cpp
|
@ -1,331 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
tactic.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Abstract tactic object.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-10-13
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include<iomanip>
|
||||
#include"tactic.h"
|
||||
#include"probe.h"
|
||||
#include"stopwatch.h"
|
||||
#include"model_v2_pp.h"
|
||||
#include"cmd_context.h"
|
||||
|
||||
void tactic::cancel() {
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
set_cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
void tactic::reset_cancel() {
|
||||
#pragma omp critical (tactic_cancel)
|
||||
{
|
||||
set_cancel(false);
|
||||
}
|
||||
}
|
||||
|
||||
struct tactic_report::imp {
|
||||
char const * m_id;
|
||||
goal const & m_goal;
|
||||
stopwatch m_watch;
|
||||
double m_start_memory;
|
||||
|
||||
imp(char const * id, goal const & g):
|
||||
m_id(id),
|
||||
m_goal(g),
|
||||
m_start_memory(static_cast<double>(memory::get_allocation_size())/static_cast<double>(1024*1024)) {
|
||||
m_watch.start();
|
||||
}
|
||||
|
||||
~imp() {
|
||||
m_watch.stop();
|
||||
double end_memory = static_cast<double>(memory::get_allocation_size())/static_cast<double>(1024*1024);
|
||||
verbose_stream() << "(" << m_id
|
||||
<< " :num-exprs " << m_goal.num_exprs()
|
||||
<< " :num-asts " << m_goal.m().get_num_asts()
|
||||
<< " :time " << std::fixed << std::setprecision(2) << m_watch.get_seconds()
|
||||
<< " :before-memory " << std::fixed << std::setprecision(2) << m_start_memory
|
||||
<< " :after-memory " << std::fixed << std::setprecision(2) << end_memory
|
||||
<< ")" << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
tactic_report::tactic_report(char const * id, goal const & g) {
|
||||
if (get_verbosity_level() >= TACTIC_VERBOSITY_LVL)
|
||||
m_imp = alloc(imp, id, g);
|
||||
else
|
||||
m_imp = 0;
|
||||
}
|
||||
|
||||
tactic_report::~tactic_report() {
|
||||
if (m_imp)
|
||||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
void report_tactic_progress(char const * id, unsigned val) {
|
||||
if (val > 0) {
|
||||
IF_VERBOSE(TACTIC_VERBOSITY_LVL, verbose_stream() << "(" << id << " " << val << ")" << std::endl;);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class skip_tactic : public tactic {
|
||||
public:
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
result.reset();
|
||||
result.push_back(in.get());
|
||||
mc = 0;
|
||||
pc = 0;
|
||||
core = 0;
|
||||
}
|
||||
|
||||
virtual void cleanup() {}
|
||||
|
||||
virtual tactic * translate(ast_manager & m) { return this; }
|
||||
};
|
||||
|
||||
tactic * mk_skip_tactic() {
|
||||
return alloc(skip_tactic);
|
||||
}
|
||||
|
||||
class fail_tactic : public tactic {
|
||||
public:
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
throw tactic_exception("fail tactic");
|
||||
}
|
||||
|
||||
virtual void cleanup() {}
|
||||
|
||||
virtual tactic * translate(ast_manager & m) { return this; }
|
||||
};
|
||||
|
||||
tactic * mk_fail_tactic() {
|
||||
return alloc(fail_tactic);
|
||||
}
|
||||
|
||||
class report_verbose_tactic : public skip_tactic {
|
||||
char const * m_msg;
|
||||
unsigned m_lvl;
|
||||
public:
|
||||
report_verbose_tactic(char const * msg, unsigned lvl) : m_msg(msg), m_lvl(lvl) {}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
IF_VERBOSE(m_lvl, verbose_stream() << m_msg << "\n";);
|
||||
skip_tactic::operator()(in, result, mc, pc, core);
|
||||
}
|
||||
};
|
||||
|
||||
tactic * mk_report_verbose_tactic(char const * msg, unsigned lvl) {
|
||||
return alloc(report_verbose_tactic, msg, lvl);
|
||||
}
|
||||
|
||||
class trace_tactic : public skip_tactic {
|
||||
char const * m_tag;
|
||||
public:
|
||||
trace_tactic(char const * tag):m_tag(tag) {}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
TRACE(m_tag, in->display(tout););
|
||||
skip_tactic::operator()(in, result, mc, pc, core);
|
||||
}
|
||||
};
|
||||
|
||||
tactic * mk_trace_tactic(char const * tag) {
|
||||
return alloc(trace_tactic, tag);
|
||||
}
|
||||
|
||||
class echo_tactic : public skip_tactic {
|
||||
cmd_context & m_ctx;
|
||||
char const * m_msg;
|
||||
bool m_newline;
|
||||
public:
|
||||
echo_tactic(cmd_context & ctx, char const * msg, bool newline):m_ctx(ctx), m_msg(msg), m_newline(newline) {}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
#pragma omp critical (echo_tactic)
|
||||
{
|
||||
m_ctx.diagnostic_stream() << m_msg;
|
||||
if (m_newline)
|
||||
m_ctx.diagnostic_stream() << std::endl;
|
||||
}
|
||||
skip_tactic::operator()(in, result, mc, pc, core);
|
||||
}
|
||||
};
|
||||
|
||||
tactic * mk_echo_tactic(cmd_context & ctx, char const * msg, bool newline) {
|
||||
return alloc(echo_tactic, ctx, msg, newline);
|
||||
}
|
||||
|
||||
class probe_value_tactic : public skip_tactic {
|
||||
cmd_context & m_ctx;
|
||||
char const * m_msg;
|
||||
probe * m_p;
|
||||
bool m_newline;
|
||||
public:
|
||||
probe_value_tactic(cmd_context & ctx, char const * msg, probe * p, bool newline):m_ctx(ctx), m_msg(msg), m_p(p), m_newline(newline) {
|
||||
SASSERT(m_p);
|
||||
m_p->inc_ref();
|
||||
}
|
||||
|
||||
~probe_value_tactic() {
|
||||
m_p->dec_ref();
|
||||
}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
double val = (*m_p)(*(in.get())).get_value();
|
||||
#pragma omp critical (probe_value_tactic)
|
||||
{
|
||||
if (m_msg)
|
||||
m_ctx.diagnostic_stream() << m_msg << " ";
|
||||
m_ctx.diagnostic_stream() << val;
|
||||
if (m_newline)
|
||||
m_ctx.diagnostic_stream() << std::endl;
|
||||
}
|
||||
skip_tactic::operator()(in, result, mc, pc, core);
|
||||
}
|
||||
};
|
||||
|
||||
tactic * mk_probe_value_tactic(cmd_context & ctx, char const * msg, probe * p, bool newline) {
|
||||
return alloc(probe_value_tactic, ctx, msg, p, newline);
|
||||
}
|
||||
|
||||
class fail_if_undecided_tactic : public skip_tactic {
|
||||
public:
|
||||
fail_if_undecided_tactic() {}
|
||||
|
||||
virtual void operator()(goal_ref const & in,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
if (!in->is_decided())
|
||||
throw tactic_exception("undecided");
|
||||
skip_tactic::operator()(in, result, mc, pc, core);
|
||||
}
|
||||
};
|
||||
|
||||
tactic * mk_fail_if_undecided_tactic() {
|
||||
return alloc(fail_if_undecided_tactic);
|
||||
}
|
||||
|
||||
void exec(tactic & t, goal_ref const & in, goal_ref_buffer & result, model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) {
|
||||
t.reset_statistics();
|
||||
t.reset_cancel();
|
||||
try {
|
||||
t(in, result, mc, pc, core);
|
||||
t.cleanup();
|
||||
}
|
||||
catch (tactic_exception & ex) {
|
||||
IF_VERBOSE(TACTIC_VERBOSITY_LVL, verbose_stream() << "(tactic-exception \"" << escaped(ex.msg()) << "\")" << std::endl;);
|
||||
t.cleanup();
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
lbool check_sat(tactic & t, goal_ref & g, model_ref & md, proof_ref & pr, expr_dependency_ref & core, std::string & reason_unknown) {
|
||||
bool models_enabled = g->models_enabled();
|
||||
bool proofs_enabled = g->proofs_enabled();
|
||||
bool cores_enabled = g->unsat_core_enabled();
|
||||
md = 0;
|
||||
pr = 0;
|
||||
core = 0;
|
||||
ast_manager & m = g->m();
|
||||
goal_ref_buffer r;
|
||||
model_converter_ref mc;
|
||||
proof_converter_ref pc;
|
||||
try {
|
||||
exec(t, g, r, mc, pc, core);
|
||||
}
|
||||
catch (tactic_exception & ex) {
|
||||
reason_unknown = ex.msg();
|
||||
return l_undef;
|
||||
}
|
||||
TRACE("tactic_mc", mc->display(tout););
|
||||
TRACE("tactic_check_sat",
|
||||
tout << "r.size(): " << r.size() << "\n";
|
||||
for (unsigned i = 0; i < r.size(); i++) r[0]->display(tout););
|
||||
|
||||
if (is_decided_sat(r)) {
|
||||
if (models_enabled) {
|
||||
model_converter2model(m, mc.get(), md);
|
||||
if (!md) {
|
||||
// create empty model.
|
||||
md = alloc(model, m);
|
||||
}
|
||||
}
|
||||
return l_true;
|
||||
}
|
||||
else if (is_decided_unsat(r)) {
|
||||
goal * final = r[0];
|
||||
SASSERT(m.is_false(final->form(0)));
|
||||
if (proofs_enabled) pr = final->pr(0);
|
||||
if (cores_enabled) core = final->dep(0);
|
||||
return l_false;
|
||||
}
|
||||
else {
|
||||
if (models_enabled) model_converter2model(m, mc.get(), md);
|
||||
reason_unknown = "incomplete";
|
||||
return l_undef;
|
||||
}
|
||||
}
|
||||
|
||||
void fail_if_proof_generation(char const * tactic_name, goal_ref const & in) {
|
||||
if (in->proofs_enabled()) {
|
||||
std::string msg = tactic_name;
|
||||
msg += " does not support proof production";
|
||||
throw tactic_exception(msg.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void fail_if_unsat_core_generation(char const * tactic_name, goal_ref const & in) {
|
||||
if (in->unsat_core_enabled()) {
|
||||
std::string msg = tactic_name;
|
||||
msg += " does not support unsat core production";
|
||||
throw tactic_exception(msg.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void fail_if_model_generation(char const * tactic_name, goal_ref const & in) {
|
||||
if (in->models_enabled()) {
|
||||
std::string msg = tactic_name;
|
||||
msg += " does not generate models";
|
||||
throw tactic_exception(msg.c_str());
|
||||
}
|
||||
}
|
155
lib/tactic.h
155
lib/tactic.h
|
@ -1,155 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
tactic.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Abstract tactic object.
|
||||
It used to be called assertion_set_strategy.
|
||||
The main improvement is the support for multiple subgoals.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-10-13
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _TACTIC_H_
|
||||
#define _TACTIC_H_
|
||||
|
||||
#include"goal.h"
|
||||
#include"params.h"
|
||||
#include"statistics.h"
|
||||
#include"model_converter.h"
|
||||
#include"proof_converter.h"
|
||||
#include"tactic_exception.h"
|
||||
#include"lbool.h"
|
||||
|
||||
struct front_end_params;
|
||||
class progress_callback;
|
||||
|
||||
typedef ptr_buffer<goal> goal_buffer;
|
||||
|
||||
class tactic {
|
||||
unsigned m_ref_count;
|
||||
public:
|
||||
tactic():m_ref_count(0) {}
|
||||
virtual ~tactic() {}
|
||||
|
||||
void inc_ref() { m_ref_count++; }
|
||||
void dec_ref() { SASSERT(m_ref_count > 0); m_ref_count--; if (m_ref_count == 0) dealloc(this); }
|
||||
|
||||
virtual void updt_params(params_ref const & p) {}
|
||||
virtual void collect_param_descrs(param_descrs & r) {}
|
||||
|
||||
void cancel();
|
||||
void reset_cancel();
|
||||
virtual void set_cancel(bool f) {}
|
||||
|
||||
/**
|
||||
\brief Apply tactic to goal \c in.
|
||||
|
||||
The list of resultant subgoals is stored in \c result.
|
||||
The content of \c in may be destroyed during the operation.
|
||||
|
||||
The resultant model converter \c mc can be used to convert a model for one of the returned subgoals
|
||||
into a model for \in. If mc == 0, then model construction is disabled or any model for a subgoal
|
||||
of \c in is also a model for \c in.
|
||||
If \c result is decided_sat (i.e., it contains a single empty subgoal), then
|
||||
the model converter is just wrapping the model.
|
||||
|
||||
The resultant proof converter \c pc can be used to convert proofs for each subgoal in \c result
|
||||
into a proof for \c in. If pc == 0, then one of the following conditions should hold:
|
||||
1- proof construction is disabled,
|
||||
2- result contains a single subgoal, and any proof of unsatisfiability for this subgoal is a proof for \c in.
|
||||
3- result is an decided_unsat (i.e., it contains a single unsat subgoal). The actual proof can be extracted from this goal.
|
||||
|
||||
The output parameter \c core is used to accumulate the unsat core of closed subgoals.
|
||||
It must be 0 if dependency tracking is disabled, or the result is decided unsat, or
|
||||
no tagged assertions were used to close any subgoal.
|
||||
|
||||
Note that, this signature is not compatible with the one described in the paper:
|
||||
"The Strategy Challenge in SMT Solving".
|
||||
The approach in the paper is conceptually simpler, but (for historical reasons) it would
|
||||
require a lot of re-engineering in the Z3 code. In Z3, we keep a proof/justification for every formula
|
||||
in a goal.
|
||||
|
||||
Therefore, in most cases, pc == 0 and core == 0 for non-branching tactics.
|
||||
*/
|
||||
virtual void operator()(/* in */ goal_ref const & in,
|
||||
/* out */ goal_ref_buffer & result,
|
||||
/* out */ model_converter_ref & mc,
|
||||
/* out */ proof_converter_ref & pc,
|
||||
/* out */ expr_dependency_ref & core) = 0;
|
||||
|
||||
virtual void collect_statistics(statistics & st) const {}
|
||||
virtual void reset_statistics() {}
|
||||
virtual void cleanup() = 0;
|
||||
virtual void reset() { cleanup(); }
|
||||
|
||||
// for backward compatibility
|
||||
virtual void set_front_end_params(front_end_params & p) {}
|
||||
virtual void set_logic(symbol const & l) {}
|
||||
virtual void set_progress_callback(progress_callback * callback) {}
|
||||
|
||||
// translate tactic to the given manager
|
||||
virtual tactic * translate(ast_manager & m) = 0;
|
||||
};
|
||||
|
||||
typedef ref<tactic> tactic_ref;
|
||||
typedef sref_vector<tactic> tactic_ref_vector;
|
||||
typedef sref_buffer<tactic> tactic_ref_buffer;
|
||||
|
||||
// minimum verbosity level for tactics
|
||||
#define TACTIC_VERBOSITY_LVL 10
|
||||
|
||||
class tactic_report {
|
||||
struct imp;
|
||||
imp * m_imp;
|
||||
public:
|
||||
tactic_report(char const * id, goal const & g);
|
||||
~tactic_report();
|
||||
};
|
||||
|
||||
void report_tactic_progress(char const * id, unsigned val);
|
||||
|
||||
tactic * mk_skip_tactic();
|
||||
tactic * mk_fail_tactic();
|
||||
tactic * mk_fail_if_undecided_tactic();
|
||||
|
||||
tactic * mk_report_verbose_tactic(char const * msg, unsigned lvl);
|
||||
tactic * mk_trace_tactic(char const * tag);
|
||||
tactic * mk_echo_tactic(cmd_context & ctx, char const * msg, bool newline = true);
|
||||
// Display the value returned by p in the diagnostic_stream
|
||||
class probe;
|
||||
tactic * mk_probe_value_tactic(cmd_context & ctx, char const * msg, probe * p, bool newline = true);
|
||||
|
||||
|
||||
class tactic_factory {
|
||||
public:
|
||||
virtual ~tactic_factory() {}
|
||||
virtual tactic * operator()(ast_manager & m, params_ref const & p) = 0;
|
||||
};
|
||||
|
||||
#define MK_TACTIC_FACTORY(NAME, CODE) \
|
||||
class NAME : public tactic_factory { \
|
||||
public: \
|
||||
virtual ~NAME() {} \
|
||||
virtual tactic * operator()(ast_manager & m, params_ref const & p) { CODE } \
|
||||
};
|
||||
|
||||
#define MK_SIMPLE_TACTIC_FACTORY(NAME, ST) MK_TACTIC_FACTORY(NAME, return ST;)
|
||||
|
||||
void exec(tactic & t, goal_ref const & in, goal_ref_buffer & result, model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core);
|
||||
lbool check_sat(tactic & t, goal_ref & g, model_ref & md, proof_ref & pr, expr_dependency_ref & core, std::string & reason_unknown);
|
||||
|
||||
// Throws an exception if goal \c in requires proof generation.
|
||||
void fail_if_proof_generation(char const * tactic_name, goal_ref const & in);
|
||||
void fail_if_unsat_core_generation(char const * tactic_name, goal_ref const & in);
|
||||
void fail_if_model_generation(char const * tactic_name, goal_ref const & in);
|
||||
|
||||
#endif
|
|
@ -1,814 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
tactic_cmds.cpp
|
||||
|
||||
Abstract:
|
||||
Support for tactics in SMT 2.0 frontend.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-10-20
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include<sstream>
|
||||
#include"tactic_cmds.h"
|
||||
#include"cmd_context.h"
|
||||
#include"cmd_util.h"
|
||||
#include"parametric_cmd.h"
|
||||
#include"install_tactics.h"
|
||||
#include"scoped_timer.h"
|
||||
#include"scoped_ctrl_c.h"
|
||||
#include"cancel_eh.h"
|
||||
#include"model_smt2_pp.h"
|
||||
#include"params2front_end_params.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
#include"tactic.h"
|
||||
#include"tactical.h"
|
||||
#include"probe.h"
|
||||
#include"check_sat_result.h"
|
||||
|
||||
tactic_cmd::~tactic_cmd() {
|
||||
dealloc(m_factory);
|
||||
}
|
||||
|
||||
tactic * tactic_cmd::mk(ast_manager & m) {
|
||||
return (*m_factory)(m, params_ref());
|
||||
}
|
||||
|
||||
probe_info::probe_info(symbol const & n, char const * d, probe * p):
|
||||
m_name(n),
|
||||
m_descr(d),
|
||||
m_probe(p) {
|
||||
}
|
||||
|
||||
probe_info::~probe_info() {
|
||||
}
|
||||
|
||||
class declare_tactic_cmd : public cmd {
|
||||
symbol m_name;
|
||||
sexpr * m_decl;
|
||||
public:
|
||||
declare_tactic_cmd():
|
||||
cmd("declare-tactic"),
|
||||
m_decl(0) {
|
||||
}
|
||||
|
||||
virtual char const * get_usage() const { return "<symbol> <tactic>"; }
|
||||
virtual char const * get_descr(cmd_context & ctx) const { return "declare a new tactic, use (help-tactic) for the tactic language syntax."; }
|
||||
virtual unsigned get_arity() const { return 2; }
|
||||
virtual void prepare(cmd_context & ctx) { m_name = symbol::null; m_decl = 0; }
|
||||
virtual cmd_arg_kind next_arg_kind(cmd_context & ctx) const {
|
||||
if (m_name == symbol::null) return CPK_SYMBOL;
|
||||
return CPK_SEXPR;
|
||||
}
|
||||
virtual void set_next_arg(cmd_context & ctx, symbol const & s) { m_name = s; }
|
||||
virtual void set_next_arg(cmd_context & ctx, sexpr * n) { m_decl = n; }
|
||||
virtual void execute(cmd_context & ctx) {
|
||||
tactic_ref t = sexpr2tactic(ctx, m_decl); // make sure the tactic is well formed.
|
||||
ctx.insert_user_tactic(m_name, m_decl);
|
||||
}
|
||||
};
|
||||
|
||||
ATOMIC_CMD(get_user_tactics_cmd, "get-user-tactics", "display tactics defined using the declare-tactic command.", {
|
||||
ctx.regular_stream() << "(";
|
||||
std::ostringstream buf;
|
||||
cmd_context::user_tactic_iterator it = ctx.begin_user_tactics();
|
||||
cmd_context::user_tactic_iterator end = ctx.end_user_tactics();
|
||||
for (bool first = true; it != end; ++it) {
|
||||
if (first) first = false; else buf << "\n ";
|
||||
buf << "(declare-tactic " << it->m_key << " ";
|
||||
it->m_value->display(buf);
|
||||
buf << ")";
|
||||
}
|
||||
std::string r = buf.str();
|
||||
ctx.regular_stream() << escaped(r.c_str());
|
||||
ctx.regular_stream() << ")\n";
|
||||
});
|
||||
|
||||
void help_tactic(cmd_context & ctx) {
|
||||
std::ostringstream buf;
|
||||
buf << "combinators:\n";
|
||||
buf << "- (and-then <tactic>+) executes the given tactics sequencially.\n";
|
||||
buf << "- (or-else <tactic>+) tries the given tactics in sequence until one of them succeeds.\n";
|
||||
buf << "- (par-or <tactic>+) executes the given tactics in parallel until one of them succeeds.\n";
|
||||
buf << "- (par-then <tactic1> <tactic2>) executes tactic1 and then tactic2 to every subgoal produced by tactic1. All subgoals are processed in parallel.\n";
|
||||
buf << "- (try-for <tactic> <num>) excutes the given tactic for at most <num> milliseconds, it fails if the execution takes more than <num> milliseconds.\n";
|
||||
buf << "- (if <probe> <tactic> <tactic>) if <probe> evaluates to true, then execute the first tactic. Otherwise execute the second.\n";
|
||||
buf << "- (when <probe> <tactic>) shorthand for (if <probe> <tactic> skip).\n";
|
||||
buf << "- (fail-if <probe>) fail if <probe> evaluates to true.\n";
|
||||
buf << "- (using-params <tactic> <attribute>*) executes the given tactic using the given attributes, where <attribute> ::= <keyword> <value>. ! is a syntax sugar for using-params.\n";
|
||||
buf << "builtin tactics:\n";
|
||||
cmd_context::tactic_cmd_iterator it = ctx.begin_tactic_cmds();
|
||||
cmd_context::tactic_cmd_iterator end = ctx.end_tactic_cmds();
|
||||
for (; it != end; ++it) {
|
||||
tactic_cmd * cmd = *it;
|
||||
buf << "- " << cmd->get_name() << " " << cmd->get_descr() << "\n";
|
||||
tactic_ref t = cmd->mk(ctx.m());
|
||||
param_descrs descrs;
|
||||
t->collect_param_descrs(descrs);
|
||||
descrs.display(buf, 4);
|
||||
}
|
||||
buf << "builtin probes:\n";
|
||||
cmd_context::probe_iterator it2 = ctx.begin_probes();
|
||||
cmd_context::probe_iterator end2 = ctx.end_probes();
|
||||
for (; it2 != end2; ++it2) {
|
||||
probe_info * pinfo = *it2;
|
||||
buf << "- " << pinfo->get_name() << " " << pinfo->get_descr() << "\n";
|
||||
}
|
||||
ctx.regular_stream() << "\"" << escaped(buf.str().c_str()) << "\"\n";
|
||||
}
|
||||
|
||||
ATOMIC_CMD(help_tactic_cmd, "help-tactic", "display the tactic combinators and primitives.", help_tactic(ctx););
|
||||
|
||||
class exec_given_tactic_cmd : public parametric_cmd {
|
||||
protected:
|
||||
sexpr * m_tactic;
|
||||
public:
|
||||
exec_given_tactic_cmd(char const * name):
|
||||
parametric_cmd(name) {
|
||||
}
|
||||
|
||||
virtual char const * get_usage() const { return "<tactic> (<keyword> <value>)*"; }
|
||||
|
||||
virtual void prepare(cmd_context & ctx) {
|
||||
parametric_cmd::prepare(ctx);
|
||||
m_tactic = 0;
|
||||
}
|
||||
|
||||
virtual cmd_arg_kind next_arg_kind(cmd_context & ctx) const {
|
||||
if (m_tactic == 0) return CPK_SEXPR;
|
||||
return parametric_cmd::next_arg_kind(ctx);
|
||||
}
|
||||
|
||||
virtual void set_next_arg(cmd_context & ctx, sexpr * arg) {
|
||||
m_tactic = arg;
|
||||
}
|
||||
|
||||
virtual void init_pdescrs(cmd_context & ctx, param_descrs & p) {
|
||||
insert_timeout(p);
|
||||
insert_max_memory(p);
|
||||
p.insert(":print-statistics", CPK_BOOL, "(default: false) print statistics.");
|
||||
}
|
||||
|
||||
void display_statistics(cmd_context & ctx, tactic * t) {
|
||||
statistics stats;
|
||||
unsigned long long max_mem = memory::get_max_used_memory();
|
||||
unsigned long long mem = memory::get_allocation_size();
|
||||
stats.update("time", ctx.get_seconds());
|
||||
stats.update("memory", static_cast<double>(mem)/static_cast<double>(1024*1024));
|
||||
stats.update("max memory", static_cast<double>(max_mem)/static_cast<double>(1024*1024));
|
||||
t->collect_statistics(stats);
|
||||
stats.display_smt2(ctx.regular_stream());
|
||||
}
|
||||
};
|
||||
|
||||
typedef simple_check_sat_result check_sat_tactic_result;
|
||||
|
||||
class check_sat_using_tactict_cmd : public exec_given_tactic_cmd {
|
||||
public:
|
||||
check_sat_using_tactict_cmd():
|
||||
exec_given_tactic_cmd("check-sat-using") {
|
||||
}
|
||||
|
||||
virtual char const * get_main_descr() const { return "check if the current context is satisfiable using the given tactic, use (help-tactic) for the tactic language syntax."; }
|
||||
|
||||
virtual void init_pdescrs(cmd_context & ctx, param_descrs & p) {
|
||||
exec_given_tactic_cmd::init_pdescrs(ctx, p);
|
||||
p.insert(":print-unsat-core", CPK_BOOL, "(default: false) print unsatisfiable core.");
|
||||
p.insert(":print-proof", CPK_BOOL, "(default: false) print proof.");
|
||||
p.insert(":print-model", CPK_BOOL, "(default: false) print model.");
|
||||
}
|
||||
|
||||
virtual void execute(cmd_context & ctx) {
|
||||
params_ref p = ps();
|
||||
front_end_params2params(ctx.params(), p);
|
||||
tactic_ref tref = using_params(sexpr2tactic(ctx, m_tactic), p);
|
||||
tref->set_front_end_params(ctx.params());
|
||||
tref->set_logic(ctx.get_logic());
|
||||
ast_manager & m = ctx.m();
|
||||
unsigned timeout = p.get_uint(":timeout", UINT_MAX);
|
||||
goal_ref g = alloc(goal, m, ctx.produce_proofs(), ctx.produce_models(), ctx.produce_unsat_cores());
|
||||
assert_exprs_from(ctx, *g);
|
||||
TRACE("check_sat_using", g->display(tout););
|
||||
model_ref md;
|
||||
proof_ref pr(m);
|
||||
expr_dependency_ref core(m);
|
||||
std::string reason_unknown;
|
||||
ref<check_sat_tactic_result> result = alloc(check_sat_tactic_result, m);
|
||||
ctx.set_check_sat_result(result.get());
|
||||
{
|
||||
tactic & t = *tref;
|
||||
cancel_eh<tactic> eh(t);
|
||||
{
|
||||
scoped_ctrl_c ctrlc(eh);
|
||||
scoped_timer timer(timeout, &eh);
|
||||
cmd_context::scoped_watch sw(ctx);
|
||||
lbool r = l_undef;
|
||||
try {
|
||||
r = check_sat(t, g, md, pr, core, reason_unknown);
|
||||
ctx.display_sat_result(r);
|
||||
result->set_status(r);
|
||||
if (r == l_undef) {
|
||||
if (reason_unknown != "") {
|
||||
result->m_unknown = reason_unknown;
|
||||
// ctx.diagnostic_stream() << "\"" << escaped(reason_unknown.c_str(), true) << "\"" << std::endl;
|
||||
}
|
||||
else {
|
||||
result->m_unknown = "unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (z3_error & ex) {
|
||||
throw ex;
|
||||
}
|
||||
catch (z3_exception & ex) {
|
||||
result->set_status(l_undef);
|
||||
result->m_unknown = ex.msg();
|
||||
ctx.regular_stream() << "(error \"tactic failed: " << ex.msg() << "\")" << std::endl;
|
||||
}
|
||||
ctx.validate_check_sat_result(r);
|
||||
}
|
||||
t.collect_statistics(result->m_stats);
|
||||
}
|
||||
|
||||
if (ctx.produce_unsat_cores()) {
|
||||
ptr_vector<expr> core_elems;
|
||||
m.linearize(core, core_elems);
|
||||
result->m_core.append(core_elems.size(), core_elems.c_ptr());
|
||||
if (p.get_bool(":print-unsat-core", false)) {
|
||||
ctx.regular_stream() << "(unsat-core";
|
||||
ptr_vector<expr>::const_iterator it = core_elems.begin();
|
||||
ptr_vector<expr>::const_iterator end = core_elems.end();
|
||||
for (; it != end; ++it) {
|
||||
ctx.regular_stream() << " ";
|
||||
ctx.display(ctx.regular_stream(), *it);
|
||||
}
|
||||
ctx.regular_stream() << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx.produce_models() && md) {
|
||||
result->m_model = md;
|
||||
if (p.get_bool(":print-model", false)) {
|
||||
ctx.regular_stream() << "(model " << std::endl;
|
||||
model_smt2_pp(ctx.regular_stream(), ctx, *md, 2);
|
||||
ctx.regular_stream() << ")" << std::endl;
|
||||
}
|
||||
if (result->status() == l_true)
|
||||
ctx.validate_model();
|
||||
}
|
||||
|
||||
if (ctx.produce_proofs() && pr) {
|
||||
result->m_proof = pr;
|
||||
if (p.get_bool(":print-proof", false)) {
|
||||
ctx.regular_stream() << mk_ismt2_pp(pr, m) << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (p.get_bool(":print-statistics", false))
|
||||
display_statistics(ctx, tref.get());
|
||||
}
|
||||
};
|
||||
|
||||
class apply_tactic_cmd : public exec_given_tactic_cmd {
|
||||
public:
|
||||
apply_tactic_cmd():
|
||||
exec_given_tactic_cmd("apply") {
|
||||
}
|
||||
|
||||
virtual char const * get_main_descr() const { return "apply the given tactic to the current context, and print the resultant set of goals."; }
|
||||
|
||||
virtual void init_pdescrs(cmd_context & ctx, param_descrs & p) {
|
||||
p.insert(":print", CPK_BOOL, "(default: true) print resultant goals.");
|
||||
#ifndef _EXTERNAL_RELEASE
|
||||
p.insert(":print-proof", CPK_BOOL, "(default: false) print proof associated with each assertion.");
|
||||
#endif
|
||||
p.insert(":print-model-converter", CPK_BOOL, "(default: false) print model converter.");
|
||||
p.insert(":print-benchmark", CPK_BOOL, "(default: false) display resultant goals as a SMT2 benchmark.");
|
||||
#ifndef _EXTERNAL_RELEASE
|
||||
p.insert(":print-dependencies", CPK_BOOL, "(default: false) print dependencies when displaying the resultant set of goals.");
|
||||
#endif
|
||||
exec_given_tactic_cmd::init_pdescrs(ctx, p);
|
||||
}
|
||||
|
||||
virtual void execute(cmd_context & ctx) {
|
||||
params_ref p = ps();
|
||||
front_end_params2params(ctx.params(), p);
|
||||
tactic_ref tref = using_params(sexpr2tactic(ctx, m_tactic), p);
|
||||
{
|
||||
tactic & t = *(tref.get());
|
||||
ast_manager & m = ctx.m();
|
||||
goal_ref g = alloc(goal, m, ctx.produce_proofs(), ctx.produce_models(), ctx.produce_unsat_cores());
|
||||
assert_exprs_from(ctx, *g);
|
||||
|
||||
unsigned timeout = p.get_uint(":timeout", UINT_MAX);
|
||||
|
||||
goal_ref_buffer result_goals;
|
||||
model_converter_ref mc;
|
||||
proof_converter_ref pc;
|
||||
expr_dependency_ref core(m);
|
||||
|
||||
std::string reason_unknown;
|
||||
bool failed = false;
|
||||
cancel_eh<tactic> eh(t);
|
||||
{
|
||||
scoped_ctrl_c ctrlc(eh);
|
||||
scoped_timer timer(timeout, &eh);
|
||||
cmd_context::scoped_watch sw(ctx);
|
||||
try {
|
||||
exec(t, g, result_goals, mc, pc, core);
|
||||
}
|
||||
catch (tactic_exception & ex) {
|
||||
ctx.regular_stream() << "(error \"tactic failed: " << ex.msg() << "\")" << std::endl;
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!failed && p.get_bool(":print", true)) {
|
||||
bool print_dependencies = p.get_bool(":print-dependencies", false);
|
||||
ctx.regular_stream() << "(goals\n";
|
||||
unsigned sz = result_goals.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
if (print_dependencies)
|
||||
result_goals[i]->display_with_dependencies(ctx);
|
||||
else
|
||||
result_goals[i]->display(ctx);
|
||||
}
|
||||
ctx.regular_stream() << ")\n";
|
||||
}
|
||||
|
||||
#ifndef _EXTERNAL_RELEASE
|
||||
if (!failed && ctx.produce_proofs() && p.get_bool(":print-proof", false)) {
|
||||
// TODO
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!failed && p.get_bool(":print-benchmark", false)) {
|
||||
unsigned num_goals = result_goals.size();
|
||||
SASSERT(num_goals > 0);
|
||||
if (num_goals == 1) {
|
||||
// easy case
|
||||
goal * fg = result_goals[0];
|
||||
unsigned sz = fg->size();
|
||||
ptr_buffer<expr> assertions;
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
assertions.push_back(fg->form(i));
|
||||
}
|
||||
ctx.display_smt2_benchmark(ctx.regular_stream(), assertions.size(), assertions.c_ptr());
|
||||
}
|
||||
else {
|
||||
// create a big OR
|
||||
expr_ref_buffer or_args(m);
|
||||
ptr_vector<expr> formulas;
|
||||
for (unsigned i = 0; i < num_goals; i++) {
|
||||
formulas.reset();
|
||||
result_goals[i]->get_formulas(formulas);
|
||||
if (formulas.size() == 1)
|
||||
or_args.push_back(formulas[0]);
|
||||
else
|
||||
or_args.push_back(m.mk_and(formulas.size(), formulas.c_ptr()));
|
||||
}
|
||||
expr_ref assertion_ref(m);
|
||||
assertion_ref = m.mk_or(or_args.size(), or_args.c_ptr());
|
||||
expr * assertions[1] = { assertion_ref.get() };
|
||||
ctx.display_smt2_benchmark(ctx.regular_stream(), 1, assertions);
|
||||
}
|
||||
}
|
||||
|
||||
if (!failed && mc && p.get_bool(":print-model-converter", false))
|
||||
mc->display(ctx.regular_stream());
|
||||
|
||||
if (p.get_bool(":print-statistics", false))
|
||||
display_statistics(ctx, tref.get());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void install_tactic_cmds(cmd_context & ctx) {
|
||||
ctx.insert(alloc(declare_tactic_cmd));
|
||||
ctx.insert(alloc(get_user_tactics_cmd));
|
||||
ctx.insert(alloc(help_tactic_cmd));
|
||||
ctx.insert(alloc(check_sat_using_tactict_cmd));
|
||||
ctx.insert(alloc(apply_tactic_cmd));
|
||||
install_tactics(ctx);
|
||||
}
|
||||
|
||||
static tactic * mk_and_then(cmd_context & ctx, sexpr * n) {
|
||||
SASSERT(n->is_composite());
|
||||
unsigned num_children = n->get_num_children();
|
||||
if (num_children < 2)
|
||||
throw cmd_exception("invalid and-then combinator, at least one argument expected", n->get_line(), n->get_pos());
|
||||
if (num_children == 2)
|
||||
return sexpr2tactic(ctx, n->get_child(1));
|
||||
tactic_ref_buffer args;
|
||||
for (unsigned i = 1; i < num_children; i++)
|
||||
args.push_back(sexpr2tactic(ctx, n->get_child(i)));
|
||||
return and_then(args.size(), args.c_ptr());
|
||||
}
|
||||
|
||||
static tactic * mk_or_else(cmd_context & ctx, sexpr * n) {
|
||||
SASSERT(n->is_composite());
|
||||
unsigned num_children = n->get_num_children();
|
||||
if (num_children < 2)
|
||||
throw cmd_exception("invalid or-else combinator, at least one argument expected", n->get_line(), n->get_pos());
|
||||
if (num_children == 2)
|
||||
return sexpr2tactic(ctx, n->get_child(1));
|
||||
tactic_ref_buffer args;
|
||||
for (unsigned i = 1; i < num_children; i++)
|
||||
args.push_back(sexpr2tactic(ctx, n->get_child(i)));
|
||||
return or_else(args.size(), args.c_ptr());
|
||||
}
|
||||
|
||||
static tactic * mk_par(cmd_context & ctx, sexpr * n) {
|
||||
SASSERT(n->is_composite());
|
||||
unsigned num_children = n->get_num_children();
|
||||
if (num_children < 2)
|
||||
throw cmd_exception("invalid par-or combinator, at least one argument expected", n->get_line(), n->get_pos());
|
||||
if (num_children == 2)
|
||||
return sexpr2tactic(ctx, n->get_child(1));
|
||||
tactic_ref_buffer args;
|
||||
for (unsigned i = 1; i < num_children; i++)
|
||||
args.push_back(sexpr2tactic(ctx, n->get_child(i)));
|
||||
return par(args.size(), args.c_ptr());
|
||||
}
|
||||
|
||||
static tactic * mk_par_then(cmd_context & ctx, sexpr * n) {
|
||||
SASSERT(n->is_composite());
|
||||
unsigned num_children = n->get_num_children();
|
||||
if (num_children < 2)
|
||||
throw cmd_exception("invalid par-then combinator, at least one argument expected", n->get_line(), n->get_pos());
|
||||
if (num_children == 2)
|
||||
return sexpr2tactic(ctx, n->get_child(1));
|
||||
tactic_ref_buffer args;
|
||||
for (unsigned i = 1; i < num_children; i++)
|
||||
args.push_back(sexpr2tactic(ctx, n->get_child(i)));
|
||||
return par_and_then(args.size(), args.c_ptr());
|
||||
}
|
||||
|
||||
static tactic * mk_try_for(cmd_context & ctx, sexpr * n) {
|
||||
SASSERT(n->is_composite());
|
||||
unsigned num_children = n->get_num_children();
|
||||
if (num_children != 3)
|
||||
throw cmd_exception("invalid try-for combinator, two arguments expected", n->get_line(), n->get_pos());
|
||||
if (!n->get_child(2)->is_numeral() || !n->get_child(2)->get_numeral().is_unsigned())
|
||||
throw cmd_exception("invalid try-for combinator, second argument must be an unsigned integer", n->get_line(), n->get_pos());
|
||||
tactic * t = sexpr2tactic(ctx, n->get_child(1));
|
||||
unsigned timeout = n->get_child(2)->get_numeral().get_unsigned();
|
||||
return try_for(t, timeout);
|
||||
}
|
||||
|
||||
static tactic * mk_repeat(cmd_context & ctx, sexpr * n) {
|
||||
SASSERT(n->is_composite());
|
||||
unsigned num_children = n->get_num_children();
|
||||
if (num_children != 3 && num_children != 2)
|
||||
throw cmd_exception("invalid repeat combinator, one or two arguments expected", n->get_line(), n->get_pos());
|
||||
unsigned max = UINT_MAX;
|
||||
if (num_children == 3) {
|
||||
if (!n->get_child(2)->is_numeral() || !n->get_child(2)->get_numeral().is_unsigned())
|
||||
throw cmd_exception("invalid repeat combinator, second argument must be an unsigned integer", n->get_line(), n->get_pos());
|
||||
max = n->get_child(2)->get_numeral().get_unsigned();
|
||||
}
|
||||
tactic * t = sexpr2tactic(ctx, n->get_child(1));
|
||||
return repeat(t, max);
|
||||
}
|
||||
|
||||
static tactic * mk_using_params(cmd_context & ctx, sexpr * n) {
|
||||
SASSERT(n->is_composite());
|
||||
unsigned num_children = n->get_num_children();
|
||||
if (num_children < 2)
|
||||
throw cmd_exception("invalid using-params combinator, at least one argument expected", n->get_line(), n->get_pos());
|
||||
if (num_children == 2)
|
||||
return sexpr2tactic(ctx, n->get_child(1));
|
||||
tactic_ref t = sexpr2tactic(ctx, n->get_child(1));
|
||||
param_descrs descrs;
|
||||
t->collect_param_descrs(descrs);
|
||||
params_ref p;
|
||||
unsigned i = 2;
|
||||
while (i < num_children) {
|
||||
sexpr * c = n->get_child(i);
|
||||
i++;
|
||||
if (!c->is_keyword())
|
||||
throw cmd_exception("invalid using-params combinator, keyword expected", c->get_line(), c->get_pos());
|
||||
if (i == num_children)
|
||||
throw cmd_exception("invalid using-params combinator, parameter value expected", c->get_line(), c->get_pos());
|
||||
symbol param_name = c->get_symbol();
|
||||
c = n->get_child(i);
|
||||
i++;
|
||||
switch (descrs.get_kind(param_name)) {
|
||||
case CPK_INVALID:
|
||||
throw cmd_exception("invalid using-params combinator, unknown parameter ", param_name, c->get_line(), c->get_pos());
|
||||
case CPK_BOOL:
|
||||
if (!c->is_symbol() || (c->get_symbol() != "true" && c->get_symbol() != "false"))
|
||||
throw cmd_exception("invalid parameter value, true or false expected", c->get_line(), c->get_pos());
|
||||
p.set_bool(param_name, c->get_symbol() == "true");
|
||||
break;
|
||||
case CPK_UINT:
|
||||
if (!c->is_numeral() || !c->get_numeral().is_unsigned())
|
||||
throw cmd_exception("invalid parameter value, unsigned integer expected", c->get_line(), c->get_pos());
|
||||
p.set_uint(param_name, c->get_numeral().get_unsigned());
|
||||
break;
|
||||
case CPK_NUMERAL:
|
||||
if (!c->is_numeral())
|
||||
throw cmd_exception("invalid parameter value, numeral expected", c->get_line(), c->get_pos());
|
||||
p.set_rat(param_name, c->get_numeral());
|
||||
break;
|
||||
case CPK_SYMBOL:
|
||||
if (!c->is_symbol())
|
||||
throw cmd_exception("invalid parameter value, symbol expected", c->get_line(), c->get_pos());
|
||||
p.set_sym(param_name, c->get_symbol());
|
||||
break;
|
||||
case CPK_DOUBLE:
|
||||
if (!c->is_numeral())
|
||||
throw cmd_exception("invalid parameter value, numeral expected", c->get_line(), c->get_pos());
|
||||
p.set_double(param_name, c->get_numeral().get_double());
|
||||
break;
|
||||
default:
|
||||
throw cmd_exception("invalid using-params combinator, unsupported parameter kind");
|
||||
}
|
||||
}
|
||||
return using_params(t.get(), p);
|
||||
}
|
||||
|
||||
static tactic * mk_if(cmd_context & ctx, sexpr * n) {
|
||||
SASSERT(n->is_composite());
|
||||
unsigned num_children = n->get_num_children();
|
||||
if (num_children != 4)
|
||||
throw cmd_exception("invalid if/conditional combinator, three arguments expected", n->get_line(), n->get_pos());
|
||||
probe_ref c = sexpr2probe(ctx, n->get_child(1));
|
||||
tactic_ref t = sexpr2tactic(ctx, n->get_child(2));
|
||||
tactic_ref e = sexpr2tactic(ctx, n->get_child(3));
|
||||
return cond(c.get(), t.get(), e.get());
|
||||
}
|
||||
|
||||
static tactic * mk_fail_if(cmd_context & ctx, sexpr * n) {
|
||||
SASSERT(n->is_composite());
|
||||
unsigned num_children = n->get_num_children();
|
||||
if (num_children != 2)
|
||||
throw cmd_exception("invalid fail-if tactic, one argument expected", n->get_line(), n->get_pos());
|
||||
probe_ref c = sexpr2probe(ctx, n->get_child(1));
|
||||
return fail_if(c.get());
|
||||
}
|
||||
|
||||
static tactic * mk_when(cmd_context & ctx, sexpr * n) {
|
||||
SASSERT(n->is_composite());
|
||||
unsigned num_children = n->get_num_children();
|
||||
if (num_children != 3)
|
||||
throw cmd_exception("invalid when combinator, two arguments expected", n->get_line(), n->get_pos());
|
||||
probe_ref c = sexpr2probe(ctx, n->get_child(1));
|
||||
tactic_ref t = sexpr2tactic(ctx, n->get_child(2));
|
||||
return cond(c.get(), t.get(), mk_skip_tactic());
|
||||
}
|
||||
|
||||
static tactic * mk_echo(cmd_context & ctx, sexpr * n) {
|
||||
SASSERT(n->is_composite());
|
||||
unsigned num_children = n->get_num_children();
|
||||
if (num_children < 2)
|
||||
throw cmd_exception("invalid echo tactic, must have at least one argument", n->get_line(), n->get_pos());
|
||||
tactic_ref res;
|
||||
for (unsigned i = 1; i < num_children; i++) {
|
||||
sexpr * curr = n->get_child(i);
|
||||
bool last = (i == num_children - 1);
|
||||
tactic * t;
|
||||
if (curr->is_string())
|
||||
t = mk_echo_tactic(ctx, curr->get_string().c_str(), last);
|
||||
else
|
||||
t = mk_probe_value_tactic(ctx, 0, sexpr2probe(ctx, curr), last);
|
||||
tactic * new_res;
|
||||
if (res.get() == 0)
|
||||
new_res = t;
|
||||
else
|
||||
new_res = and_then(res.get(), t);
|
||||
if (last)
|
||||
return new_res;
|
||||
res = new_res;
|
||||
}
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static tactic * mk_fail_if_branching(cmd_context & ctx, sexpr * n) {
|
||||
SASSERT(n->is_composite());
|
||||
unsigned num_children = n->get_num_children();
|
||||
if (num_children != 3 && num_children != 2)
|
||||
throw cmd_exception("invalid fail-if-branching combinator, one or two arguments expected", n->get_line(), n->get_pos());
|
||||
unsigned threshold = 1;
|
||||
if (num_children == 3) {
|
||||
if (!n->get_child(2)->is_numeral() || !n->get_child(2)->get_numeral().is_unsigned())
|
||||
throw cmd_exception("invalid fail-if-branching combinator, second argument must be an unsigned integer", n->get_line(), n->get_pos());
|
||||
threshold = n->get_child(2)->get_numeral().get_unsigned();
|
||||
}
|
||||
tactic * t = sexpr2tactic(ctx, n->get_child(1));
|
||||
return fail_if_branching(t, threshold);
|
||||
}
|
||||
|
||||
static tactic * mk_if_no_proofs(cmd_context & ctx, sexpr * n) {
|
||||
SASSERT(n->is_composite());
|
||||
unsigned num_children = n->get_num_children();
|
||||
if (num_children != 2)
|
||||
throw cmd_exception("invalid if-no-proofs combinator, one argument expected", n->get_line(), n->get_pos());
|
||||
tactic * t = sexpr2tactic(ctx, n->get_child(1));
|
||||
return if_no_proofs(t);
|
||||
}
|
||||
|
||||
static tactic * mk_if_no_models(cmd_context & ctx, sexpr * n) {
|
||||
SASSERT(n->is_composite());
|
||||
unsigned num_children = n->get_num_children();
|
||||
if (num_children != 2)
|
||||
throw cmd_exception("invalid if-no-models combinator, one argument expected", n->get_line(), n->get_pos());
|
||||
tactic * t = sexpr2tactic(ctx, n->get_child(1));
|
||||
return if_no_models(t);
|
||||
}
|
||||
|
||||
static tactic * mk_if_no_unsat_cores(cmd_context & ctx, sexpr * n) {
|
||||
SASSERT(n->is_composite());
|
||||
unsigned num_children = n->get_num_children();
|
||||
if (num_children != 2)
|
||||
throw cmd_exception("invalid if-no-unsat-cores combinator, one argument expected", n->get_line(), n->get_pos());
|
||||
tactic * t = sexpr2tactic(ctx, n->get_child(1));
|
||||
return if_no_unsat_cores(t);
|
||||
}
|
||||
|
||||
static tactic * mk_skip_if_failed(cmd_context & ctx, sexpr * n) {
|
||||
SASSERT(n->is_composite());
|
||||
unsigned num_children = n->get_num_children();
|
||||
if (num_children != 2)
|
||||
throw cmd_exception("invalid skip-if-failed combinator, one argument expected", n->get_line(), n->get_pos());
|
||||
tactic * t = sexpr2tactic(ctx, n->get_child(1));
|
||||
return skip_if_failed(t);
|
||||
}
|
||||
|
||||
tactic * sexpr2tactic(cmd_context & ctx, sexpr * n) {
|
||||
if (n->is_symbol()) {
|
||||
tactic_cmd * cmd = ctx.find_tactic_cmd(n->get_symbol());
|
||||
if (cmd != 0)
|
||||
return cmd->mk(ctx.m());
|
||||
sexpr * decl = ctx.find_user_tactic(n->get_symbol());
|
||||
if (decl != 0)
|
||||
return sexpr2tactic(ctx, decl);
|
||||
throw cmd_exception("invalid tactic, unknown tactic ", n->get_symbol(), n->get_line(), n->get_pos());
|
||||
}
|
||||
else if (n->is_composite()) {
|
||||
unsigned num_children = n->get_num_children();
|
||||
if (num_children == 0)
|
||||
throw cmd_exception("invalid tactic, arguments expected", n->get_line(), n->get_pos());
|
||||
sexpr * head = n->get_child(0);
|
||||
if (!head->is_symbol())
|
||||
throw cmd_exception("invalid tactic, symbol expected", n->get_line(), n->get_pos());
|
||||
symbol const & cmd_name = head->get_symbol();
|
||||
if (cmd_name == "and-then" || cmd_name == "then")
|
||||
return mk_and_then(ctx, n);
|
||||
else if (cmd_name == "or-else")
|
||||
return mk_or_else(ctx, n);
|
||||
else if (cmd_name == "par")
|
||||
return mk_par(ctx, n);
|
||||
else if (cmd_name == "par-or")
|
||||
return mk_par(ctx, n);
|
||||
else if (cmd_name == "par-then")
|
||||
return mk_par_then(ctx, n);
|
||||
else if (cmd_name == "try-for")
|
||||
return mk_try_for(ctx, n);
|
||||
else if (cmd_name == "repeat")
|
||||
return mk_repeat(ctx, n);
|
||||
else if (cmd_name == "if" || cmd_name == "ite" || cmd_name == "cond")
|
||||
return mk_if(ctx, n);
|
||||
else if (cmd_name == "fail-if")
|
||||
return mk_fail_if(ctx, n);
|
||||
else if (cmd_name == "fail-if-branching")
|
||||
return mk_fail_if_branching(ctx, n);
|
||||
else if (cmd_name == "when")
|
||||
return mk_when(ctx, n);
|
||||
else if (cmd_name == "!" || cmd_name == "using-params" || cmd_name == "with")
|
||||
return mk_using_params(ctx, n);
|
||||
else if (cmd_name == "echo")
|
||||
return mk_echo(ctx, n);
|
||||
else if (cmd_name == "if-no-proofs")
|
||||
return mk_if_no_proofs(ctx, n);
|
||||
else if (cmd_name == "if-no-models")
|
||||
return mk_if_no_models(ctx, n);
|
||||
else if (cmd_name == "if-no-unsat-cores")
|
||||
return mk_if_no_unsat_cores(ctx, n);
|
||||
else if (cmd_name == "skip-if-failed")
|
||||
return mk_skip_if_failed(ctx, n);
|
||||
else
|
||||
throw cmd_exception("invalid tactic, unknown tactic combinator ", cmd_name, n->get_line(), n->get_pos());
|
||||
}
|
||||
else {
|
||||
throw cmd_exception("invalid tactic, unexpected input", n->get_line(), n->get_pos());
|
||||
}
|
||||
}
|
||||
|
||||
static probe * mk_not_probe (cmd_context & ctx, sexpr * n) {
|
||||
SASSERT(n->is_composite());
|
||||
unsigned num_children = n->get_num_children();
|
||||
if (num_children != 2)
|
||||
throw cmd_exception("invalid probe expression, one argument expected", n->get_line(), n->get_pos());
|
||||
return mk_not(sexpr2probe(ctx, n->get_child(1)));
|
||||
}
|
||||
|
||||
#define MK_BIN_PROBE(NAME) \
|
||||
static probe * NAME ## _probe (cmd_context & ctx, sexpr * n) { \
|
||||
SASSERT(n->is_composite()); \
|
||||
unsigned num_children = n->get_num_children(); \
|
||||
if (num_children != 3) \
|
||||
throw cmd_exception("invalid probe expression, two arguments expected", n->get_line(), n->get_pos()); \
|
||||
ref<probe> p1 = sexpr2probe(ctx, n->get_child(1)); \
|
||||
ref<probe> p2 = sexpr2probe(ctx, n->get_child(2)); \
|
||||
return NAME(p1.get(), p2.get()); \
|
||||
}
|
||||
|
||||
MK_BIN_PROBE(mk_eq);
|
||||
MK_BIN_PROBE(mk_le);
|
||||
MK_BIN_PROBE(mk_lt);
|
||||
MK_BIN_PROBE(mk_ge);
|
||||
MK_BIN_PROBE(mk_gt);
|
||||
MK_BIN_PROBE(mk_implies);
|
||||
MK_BIN_PROBE(mk_div);
|
||||
MK_BIN_PROBE(mk_sub);
|
||||
|
||||
#define MK_NARY_PROBE(NAME) \
|
||||
static probe * NAME ## _probe(cmd_context & ctx, sexpr * n) { \
|
||||
SASSERT(n->is_composite()); \
|
||||
unsigned num_children = n->get_num_children(); \
|
||||
if (num_children < 2) \
|
||||
throw cmd_exception("invalid probe, at least one argument expected", n->get_line(), n->get_pos()); \
|
||||
probe * r = sexpr2probe(ctx, n->get_child(1)); \
|
||||
if (num_children == 2) \
|
||||
return r; \
|
||||
ref<probe> prev = r; \
|
||||
unsigned i = 1; \
|
||||
while (true) { \
|
||||
r = NAME(prev.get(), sexpr2probe(ctx, n->get_child(i))); \
|
||||
if (i == num_children - 1) \
|
||||
return r; \
|
||||
i++; \
|
||||
prev = r; \
|
||||
} \
|
||||
}
|
||||
|
||||
MK_NARY_PROBE(mk_and);
|
||||
MK_NARY_PROBE(mk_or);
|
||||
MK_NARY_PROBE(mk_add);
|
||||
MK_NARY_PROBE(mk_mul);
|
||||
|
||||
probe * sexpr2probe(cmd_context & ctx, sexpr * n) {
|
||||
if (n->is_symbol()) {
|
||||
probe_info * pinfo = ctx.find_probe(n->get_symbol());
|
||||
if (pinfo != 0)
|
||||
return pinfo->get();
|
||||
throw cmd_exception("invalid probe, unknown builtin probe ", n->get_symbol(), n->get_line(), n->get_pos());
|
||||
}
|
||||
else if (n->is_numeral()) {
|
||||
rational const & v = n->get_numeral();
|
||||
if (!v.is_int32())
|
||||
throw cmd_exception("invalid probe, constant is too big to fit in a fixed size integer", n->get_line(), n->get_pos());
|
||||
return mk_const_probe(static_cast<int>(v.get_int64()));
|
||||
}
|
||||
else if (n->is_composite()) {
|
||||
unsigned num_children = n->get_num_children();
|
||||
if (num_children == 0)
|
||||
throw cmd_exception("invalid probe, arguments expected", n->get_line(), n->get_pos());
|
||||
sexpr * head = n->get_child(0);
|
||||
if (!head->is_symbol())
|
||||
throw cmd_exception("invalid probe, symbol expected", n->get_line(), n->get_pos());
|
||||
symbol const & p_name = head->get_symbol();
|
||||
|
||||
if (p_name == "=")
|
||||
return mk_eq_probe(ctx, n);
|
||||
else if (p_name == "<=")
|
||||
return mk_le_probe(ctx, n);
|
||||
else if (p_name == ">=")
|
||||
return mk_ge_probe(ctx, n);
|
||||
else if (p_name == "<")
|
||||
return mk_lt_probe(ctx, n);
|
||||
else if (p_name == ">")
|
||||
return mk_gt_probe(ctx, n);
|
||||
else if (p_name == "and")
|
||||
return mk_and_probe(ctx, n);
|
||||
else if (p_name == "or")
|
||||
return mk_or_probe(ctx, n);
|
||||
else if (p_name == "=>" || p_name == "implies")
|
||||
return mk_implies_probe(ctx, n);
|
||||
else if (p_name == "not")
|
||||
return mk_not_probe(ctx, n);
|
||||
else if (p_name == "*")
|
||||
return mk_mul_probe(ctx, n);
|
||||
else if (p_name == "+")
|
||||
return mk_add_probe(ctx, n);
|
||||
else if (p_name == "-")
|
||||
return mk_sub_probe(ctx, n);
|
||||
else if (p_name == "/")
|
||||
return mk_div_probe(ctx, n);
|
||||
else
|
||||
throw cmd_exception("invalid probe, unknown probe expression ", p_name, n->get_line(), n->get_pos());
|
||||
}
|
||||
else {
|
||||
throw cmd_exception("invalid probe, unexpected input", n->get_line(), n->get_pos());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
tactic_cmds.h
|
||||
|
||||
Abstract:
|
||||
Support for tactics in SMT 2.0 frontend.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-11-20
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _TACTIC_CMDS_H_
|
||||
#define _TACTIC_CMDS_H_
|
||||
|
||||
#include"ast.h"
|
||||
#include"cmd_context_types.h"
|
||||
#include"ref.h"
|
||||
|
||||
class tactic;
|
||||
class probe;
|
||||
class tactic_factory;
|
||||
|
||||
class tactic_cmd {
|
||||
symbol m_name;
|
||||
char const * m_descr;
|
||||
tactic_factory * m_factory;
|
||||
public:
|
||||
tactic_cmd(symbol const & n, char const * d, tactic_factory * f):
|
||||
m_name(n), m_descr(d), m_factory(f) {
|
||||
SASSERT(m_factory);
|
||||
}
|
||||
|
||||
~tactic_cmd();
|
||||
|
||||
symbol get_name() const { return m_name; }
|
||||
|
||||
char const * get_descr() const { return m_descr; }
|
||||
|
||||
tactic * mk(ast_manager & m);
|
||||
};
|
||||
|
||||
void install_tactic_cmds(cmd_context & ctx);
|
||||
tactic * sexpr2tactic(cmd_context & ctx, sexpr * n);
|
||||
|
||||
class probe_info {
|
||||
symbol m_name;
|
||||
char const * m_descr;
|
||||
ref<probe> m_probe;
|
||||
public:
|
||||
probe_info(symbol const & n, char const * d, probe * p);
|
||||
~probe_info();
|
||||
|
||||
symbol get_name() const { return m_name; }
|
||||
char const * get_descr() const { return m_descr; }
|
||||
|
||||
probe * get() const { return m_probe.get(); }
|
||||
};
|
||||
|
||||
probe * sexpr2probe(cmd_context & ctx, sexpr * n);
|
||||
|
||||
#endif
|
|
@ -1,62 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
tactic_manager.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Collection of tactics & probes
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2012-03-06
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"tactic_manager.h"
|
||||
|
||||
tactic_manager::~tactic_manager() {
|
||||
finalize_tactic_cmds();
|
||||
finalize_probes();
|
||||
}
|
||||
|
||||
void tactic_manager::insert(tactic_cmd * c) {
|
||||
symbol const & s = c->get_name();
|
||||
SASSERT(!m_name2tactic.contains(s));
|
||||
m_name2tactic.insert(s, c);
|
||||
m_tactics.push_back(c);
|
||||
}
|
||||
|
||||
void tactic_manager::insert(probe_info * p) {
|
||||
symbol const & s = p->get_name();
|
||||
SASSERT(!m_name2probe.contains(s));
|
||||
m_name2probe.insert(s, p);
|
||||
m_probes.push_back(p);
|
||||
}
|
||||
|
||||
tactic_cmd * tactic_manager::find_tactic_cmd(symbol const & s) const {
|
||||
tactic_cmd * c = 0;
|
||||
m_name2tactic.find(s, c);
|
||||
return c;
|
||||
}
|
||||
|
||||
probe_info * tactic_manager::find_probe(symbol const & s) const {
|
||||
probe_info * p = 0;
|
||||
m_name2probe.find(s, p);
|
||||
return p;
|
||||
}
|
||||
|
||||
void tactic_manager::finalize_tactic_cmds() {
|
||||
std::for_each(m_tactics.begin(), m_tactics.end(), delete_proc<tactic_cmd>());
|
||||
m_tactics.reset();
|
||||
m_name2tactic.reset();
|
||||
}
|
||||
|
||||
void tactic_manager::finalize_probes() {
|
||||
std::for_each(m_probes.begin(), m_probes.end(), delete_proc<probe_info>());
|
||||
m_probes.reset();
|
||||
m_name2probe.reset();
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
tactic_manager.h
|
||||
|
||||
Abstract:
|
||||
Collection of tactics & probes
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2012-03-06
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _TACTIC_MANAGER_H_
|
||||
#define _TACTIC_MANAGER_H_
|
||||
|
||||
#include"tactic_cmds.h"
|
||||
#include"dictionary.h"
|
||||
|
||||
class tactic_manager {
|
||||
protected:
|
||||
dictionary<tactic_cmd*> m_name2tactic;
|
||||
dictionary<probe_info*> m_name2probe;
|
||||
ptr_vector<tactic_cmd> m_tactics;
|
||||
ptr_vector<probe_info> m_probes;
|
||||
void finalize_tactic_cmds();
|
||||
void finalize_probes();
|
||||
public:
|
||||
~tactic_manager();
|
||||
|
||||
void insert(tactic_cmd * c);
|
||||
void insert(probe_info * p);
|
||||
tactic_cmd * find_tactic_cmd(symbol const & s) const;
|
||||
probe_info * find_probe(symbol const & s) const;
|
||||
|
||||
unsigned num_tactics() const { return m_tactics.size(); }
|
||||
unsigned num_probes() const { return m_probes.size(); }
|
||||
tactic_cmd * get_tactic(unsigned i) const { return m_tactics[i]; }
|
||||
probe_info * get_probe(unsigned i) const { return m_probes[i]; }
|
||||
|
||||
typedef ptr_vector<tactic_cmd>::const_iterator tactic_cmd_iterator;
|
||||
tactic_cmd_iterator begin_tactic_cmds() const { return m_tactics.begin(); }
|
||||
tactic_cmd_iterator end_tactic_cmds() const { return m_tactics.end(); }
|
||||
|
||||
typedef ptr_vector<probe_info>::const_iterator probe_iterator;
|
||||
probe_iterator begin_probes() const { return m_probes.begin(); }
|
||||
probe_iterator end_probes() const { return m_probes.end(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
1434
lib/tactical.cpp
1434
lib/tactical.cpp
File diff suppressed because it is too large
Load diff
|
@ -1,83 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
tactical.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Basic combinators
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-10-13
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _TACTICAL_H_
|
||||
#define _TACTICAL_H_
|
||||
|
||||
#include"tactic.h"
|
||||
#include"probe.h"
|
||||
|
||||
tactic * and_then(unsigned num, tactic * const * ts);
|
||||
tactic * and_then(tactic * t1, tactic * t2);
|
||||
tactic * and_then(tactic * t1, tactic * t2, tactic * t3);
|
||||
tactic * and_then(tactic * t1, tactic * t2, tactic * t3, tactic * t4);
|
||||
tactic * and_then(tactic * t1, tactic * t2, tactic * t3, tactic * t4, tactic * t5);
|
||||
tactic * and_then(tactic * t1, tactic * t2, tactic * t3, tactic * t4, tactic * t5, tactic * t6);
|
||||
tactic * and_then(tactic * t1, tactic * t2, tactic * t3, tactic * t4, tactic * t5, tactic * t6, tactic * t7);
|
||||
tactic * and_then(tactic * t1, tactic * t2, tactic * t3, tactic * t4, tactic * t5, tactic * t6, tactic * t7, tactic * t8);
|
||||
tactic * and_then(tactic * t1, tactic * t2, tactic * t3, tactic * t4, tactic * t5, tactic * t6, tactic * t7, tactic * t8, tactic * t9);
|
||||
tactic * and_then(tactic * t1, tactic * t2, tactic * t3, tactic * t4, tactic * t5, tactic * t6, tactic * t7, tactic * t8, tactic * t9, tactic * t10);
|
||||
|
||||
tactic * or_else(unsigned num, tactic * const * ts);
|
||||
tactic * or_else(tactic * t1, tactic * t2);
|
||||
tactic * or_else(tactic * t1, tactic * t2, tactic * t3);
|
||||
tactic * or_else(tactic * t1, tactic * t2, tactic * t3, tactic * t4);
|
||||
tactic * or_else(tactic * t1, tactic * t2, tactic * t3, tactic * t4, tactic * t5);
|
||||
tactic * or_else(tactic * t1, tactic * t2, tactic * t3, tactic * t4, tactic * t5, tactic * t6);
|
||||
tactic * or_else(tactic * t1, tactic * t2, tactic * t3, tactic * t4, tactic * t5, tactic * t6, tactic * t7);
|
||||
tactic * or_else(tactic * t1, tactic * t2, tactic * t3, tactic * t4, tactic * t5, tactic * t6, tactic * t7, tactic * t8);
|
||||
tactic * or_else(tactic * t1, tactic * t2, tactic * t3, tactic * t4, tactic * t5, tactic * t6, tactic * t7, tactic * t8, tactic * t9);
|
||||
tactic * or_else(tactic * t1, tactic * t2, tactic * t3, tactic * t4, tactic * t5, tactic * t6, tactic * t7, tactic * t8, tactic * t9, tactic * t10);
|
||||
|
||||
tactic * repeat(tactic * t, unsigned max = UINT_MAX);
|
||||
/**
|
||||
\brief Fails if \c t produeces more than \c threshold subgoals.
|
||||
Otherwise, it behabes like \c t.
|
||||
*/
|
||||
tactic * fail_if_branching(tactic * t, unsigned threshold = 1);
|
||||
|
||||
tactic * par(unsigned num, tactic * const * ts);
|
||||
tactic * par(tactic * t1, tactic * t2);
|
||||
tactic * par(tactic * t1, tactic * t2, tactic * t3);
|
||||
tactic * par(tactic * t1, tactic * t2, tactic * t3, tactic * t4);
|
||||
|
||||
tactic * par_and_then(unsigned num, tactic * const * ts);
|
||||
tactic * par_and_then(tactic * t1, tactic * t2);
|
||||
|
||||
tactic * try_for(tactic * t, unsigned msecs);
|
||||
tactic * clean(tactic * t);
|
||||
tactic * using_params(tactic * t, params_ref const & p);
|
||||
|
||||
// Create a tactic that fails if the result returned by probe p is true.
|
||||
tactic * fail_if(probe * p);
|
||||
tactic * fail_if_not(probe * p);
|
||||
// Execute t1 if p returns true, and t2 otherwise
|
||||
tactic * cond(probe * p, tactic * t1, tactic * t2);
|
||||
// Alias for cond(p, t, mk_skip_tactic())
|
||||
tactic * when(probe * p, tactic * t);
|
||||
|
||||
// alias for (or-else t skip)
|
||||
tactic * skip_if_failed(tactic * t);
|
||||
|
||||
// Execute the given tactic only if proof production is not enabled.
|
||||
// If proof production is enabled it is a skip
|
||||
tactic * if_no_proofs(tactic * t);
|
||||
tactic * if_no_unsat_cores(tactic * t);
|
||||
tactic * if_no_models(tactic * t);
|
||||
|
||||
#endif
|
|
@ -1,76 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
theory_arith_params.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-05-06.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include"theory_arith_params.h"
|
||||
|
||||
void theory_arith_params::register_params(ini_params & p) {
|
||||
#ifdef _EXTERNAL_RELEASE
|
||||
p.register_int_param("ARITH_SOLVER", 0, 3, reinterpret_cast<int&>(m_arith_mode), "select arithmetic solver: 0 - no solver, 1 - bellman-ford based solver (diff. logic only), 2 - simplex based solver, 3 - floyd-warshall based solver (diff. logic only) and no theory combination");
|
||||
#else
|
||||
p.register_int_param("ARITH_SOLVER", 0, 4, reinterpret_cast<int&>(m_arith_mode), "select arithmetic solver: 0 - no solver, 1 - bellman-ford based solver (diff. logic only), 2 - simplex based solver, 3 - floyd-warshall based solver (diff. logic only) and no theory combination, 4 - model guided arith_solver");
|
||||
#endif
|
||||
p.register_bool_param("ARITH_FORCE_SIMPLEX", m_arith_auto_config_simplex, "force Z3 to use simplex solver.");
|
||||
p.register_unsigned_param("ARITH_BLANDS_RULE_THRESHOLD", m_arith_blands_rule_threshold);
|
||||
p.register_bool_param("ARITH_PROPAGATE_EQS", m_arith_propagate_eqs);
|
||||
p.register_int_param("ARITH_PROPAGATION_MODE", 0, 2, reinterpret_cast<int&>(m_arith_bound_prop));
|
||||
p.register_bool_param("ARITH_STRONGER_LEMMAS", m_arith_stronger_lemmas);
|
||||
p.register_bool_param("ARITH_SKIP_BIG_COEFFS", m_arith_skip_rows_with_big_coeffs);
|
||||
p.register_unsigned_param("ARITH_MAX_LEMMA_SIZE", m_arith_max_lemma_size);
|
||||
p.register_unsigned_param("ARITH_SMALL_LEMMA_SIZE", m_arith_small_lemma_size);
|
||||
p.register_bool_param("ARITH_REFLECT", m_arith_reflect);
|
||||
p.register_bool_param("ARITH_IGNORE_INT", m_arith_ignore_int);
|
||||
p.register_unsigned_param("ARITH_LAZY_PIVOTING", m_arith_lazy_pivoting_lvl);
|
||||
p.register_unsigned_param("ARITH_RANDOM_SEED", m_arith_random_seed);
|
||||
p.register_bool_param("ARITH_RANDOM_INITIAL_VALUE", m_arith_random_initial_value);
|
||||
p.register_int_param("ARITH_RANDOM_LOWER", m_arith_random_lower);
|
||||
p.register_int_param("ARITH_RANDOM_UPPER", m_arith_random_upper);
|
||||
p.register_bool_param("ARITH_ADAPTIVE", m_arith_adaptive);
|
||||
p.register_double_param("ARITH_ADAPTIVE_ASSERTION_THRESHOLD", m_arith_adaptive_assertion_threshold, "Delay arithmetic atoms if the num-arith-conflicts/total-conflicts < threshold");
|
||||
p.register_double_param("ARITH_ADAPTIVE_PROPAGATION_THRESHOLD", m_arith_adaptive_propagation_threshold, "Disable arithmetic theory propagation if the num-arith-conflicts/total-conflicts < threshold");
|
||||
p.register_bool_param("ARITH_DUMP_LEMMAS", m_arith_dump_lemmas);
|
||||
p.register_bool_param("ARITH_EAGER_EQ_AXIOMS", m_arith_eager_eq_axioms);
|
||||
p.register_unsigned_param("ARITH_BRANCH_CUT_RATIO", m_arith_branch_cut_ratio);
|
||||
|
||||
p.register_bool_param("ARITH_ADD_BINARY_BOUNDS", m_arith_add_binary_bounds);
|
||||
p.register_unsigned_param("ARITH_PROP_STRATEGY", 0, 1, reinterpret_cast<unsigned&>(m_arith_propagation_strategy), "Propagation strategy: 0 - use agility measures based on ration of theory conflicts, 1 - propagate proportional to ratio of theory conflicts (default)");
|
||||
|
||||
p.register_bool_param("ARITH_EQ_BOUNDS", m_arith_eq_bounds);
|
||||
p.register_bool_param("ARITH_LAZY_ADAPTER", m_arith_lazy_adapter);
|
||||
p.register_bool_param("ARITH_GCD_TEST", m_arith_gcd_test);
|
||||
p.register_bool_param("ARITH_EAGER_GCD", m_arith_eager_gcd);
|
||||
p.register_bool_param("ARITH_ADAPTIVE_GCD", m_arith_adaptive_gcd);
|
||||
p.register_unsigned_param("ARITH_PROPAGATION_THRESHOLD", m_arith_propagation_threshold);
|
||||
|
||||
p.register_bool_param("NL_ARITH", m_nl_arith, "enable/disable non linear arithmetic support. This option is ignored when ARITH_SOLVER != 2.");
|
||||
p.register_bool_param("NL_ARITH_GB", m_nl_arith_gb, "enable/disable Grobner Basis computation. This option is ignored when NL_ARITH=false");
|
||||
p.register_bool_param("NL_ARITH_GB_EQS", m_nl_arith_gb_eqs, "enable/disable equations in the Grobner Basis to be copied to the Simplex tableau.");
|
||||
p.register_bool_param("NL_ARITH_GB_PERTURBATE", m_nl_arith_gb_perturbate, "enable/disable perturbation of the variable order in GB when searching for new polynomials.");
|
||||
p.register_unsigned_param("NL_ARITH_GB_THRESHOLD", m_nl_arith_gb_threshold, "Grobner basis computation can be very expensive. This is a threshold on the number of new equalities that can be generated.");
|
||||
p.register_bool_param("NL_ARITH_BRANCHING", m_nl_arith_branching, "enable/disable branching on integer variables in non linear clusters");
|
||||
p.register_unsigned_param("NL_ARITH_ROUNDS", m_nl_arith_rounds, "threshold for number of (nested) final checks for non linear arithmetic.");
|
||||
p.register_unsigned_param("NL_ARITH_MAX_DEGREE", m_nl_arith_max_degree, "max degree for internalizing new monomials.");
|
||||
PRIVATE_PARAMS({
|
||||
p.register_bool_param("ARITH_FIXNUM", m_arith_fixnum);
|
||||
p.register_bool_param("ARITH_INT_ONLY", m_arith_int_only);
|
||||
p.register_bool_param("ARITH_ENUM_CONST_MOD", m_arith_enum_const_mod, "Create axioms for the finite set of equalities for (mod x k) where k is a positive numeral constant");
|
||||
p.register_bool_param("ARITH_INT_EQ_BRANCHING", m_arith_int_eq_branching, "Determine branch predicates based on integer equation solving");
|
||||
});
|
||||
p.register_bool_param("ARITH_EUCLIDEAN_SOLVER", m_arith_euclidean_solver, "");
|
||||
}
|
||||
|
|
@ -1,158 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
theory_arith_params.h
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-05-06.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _THEORY_ARITH_PARAMS_H_
|
||||
#define _THEORY_ARITH_PARAMS_H_
|
||||
|
||||
#include"ini_file.h"
|
||||
|
||||
enum arith_solver_id {
|
||||
AS_NO_ARITH,
|
||||
AS_DIFF_LOGIC,
|
||||
AS_ARITH,
|
||||
AS_DENSE_DIFF_LOGIC
|
||||
};
|
||||
|
||||
enum bound_prop_mode {
|
||||
BP_NONE,
|
||||
BP_SIMPLE, // only used for implying literals
|
||||
BP_REFINE // refine known bounds
|
||||
};
|
||||
|
||||
enum arith_prop_strategy {
|
||||
ARITH_PROP_AGILITY,
|
||||
ARITH_PROP_PROPORTIONAL
|
||||
};
|
||||
|
||||
enum arith_pivot_strategy {
|
||||
ARITH_PIVOT_SMALLEST,
|
||||
ARITH_PIVOT_GREATEST_ERROR,
|
||||
ARITH_PIVOT_LEAST_ERROR
|
||||
};
|
||||
|
||||
struct theory_arith_params {
|
||||
arith_solver_id m_arith_mode;
|
||||
bool m_arith_auto_config_simplex; //!< force simplex solver in auto_config
|
||||
unsigned m_arith_blands_rule_threshold;
|
||||
bool m_arith_propagate_eqs;
|
||||
bound_prop_mode m_arith_bound_prop;
|
||||
bool m_arith_stronger_lemmas;
|
||||
bool m_arith_skip_rows_with_big_coeffs;
|
||||
unsigned m_arith_max_lemma_size;
|
||||
unsigned m_arith_small_lemma_size;
|
||||
bool m_arith_reflect;
|
||||
bool m_arith_ignore_int;
|
||||
unsigned m_arith_lazy_pivoting_lvl;
|
||||
unsigned m_arith_random_seed;
|
||||
bool m_arith_random_initial_value;
|
||||
int m_arith_random_lower;
|
||||
int m_arith_random_upper;
|
||||
bool m_arith_adaptive;
|
||||
double m_arith_adaptive_assertion_threshold;
|
||||
double m_arith_adaptive_propagation_threshold;
|
||||
bool m_arith_dump_lemmas;
|
||||
bool m_arith_eager_eq_axioms;
|
||||
unsigned m_arith_branch_cut_ratio;
|
||||
bool m_arith_int_eq_branching;
|
||||
bool m_arith_enum_const_mod;
|
||||
|
||||
bool m_arith_gcd_test;
|
||||
bool m_arith_eager_gcd;
|
||||
bool m_arith_adaptive_gcd;
|
||||
unsigned m_arith_propagation_threshold;
|
||||
|
||||
arith_pivot_strategy m_arith_pivot_strategy;
|
||||
|
||||
// used in diff-logic
|
||||
bool m_arith_add_binary_bounds;
|
||||
arith_prop_strategy m_arith_propagation_strategy;
|
||||
|
||||
// used arith_eq_adapter
|
||||
bool m_arith_eq_bounds;
|
||||
bool m_arith_lazy_adapter;
|
||||
|
||||
// performance debugging flags
|
||||
bool m_arith_fixnum;
|
||||
bool m_arith_int_only;
|
||||
|
||||
// non linear support
|
||||
bool m_nl_arith;
|
||||
bool m_nl_arith_gb;
|
||||
unsigned m_nl_arith_gb_threshold;
|
||||
bool m_nl_arith_gb_eqs;
|
||||
bool m_nl_arith_gb_perturbate;
|
||||
unsigned m_nl_arith_max_degree;
|
||||
bool m_nl_arith_branching;
|
||||
unsigned m_nl_arith_rounds;
|
||||
|
||||
// euclidean solver for tighting bounds
|
||||
bool m_arith_euclidean_solver;
|
||||
|
||||
|
||||
theory_arith_params():
|
||||
m_arith_mode(AS_ARITH),
|
||||
m_arith_auto_config_simplex(false),
|
||||
m_arith_blands_rule_threshold(1000),
|
||||
m_arith_propagate_eqs(true),
|
||||
m_arith_bound_prop(BP_REFINE),
|
||||
m_arith_stronger_lemmas(true),
|
||||
m_arith_skip_rows_with_big_coeffs(true),
|
||||
m_arith_max_lemma_size(128),
|
||||
m_arith_small_lemma_size(16),
|
||||
m_arith_reflect(true),
|
||||
m_arith_ignore_int(false),
|
||||
m_arith_lazy_pivoting_lvl(0),
|
||||
m_arith_random_seed(0),
|
||||
m_arith_random_initial_value(false),
|
||||
m_arith_random_lower(-1000),
|
||||
m_arith_random_upper(1000),
|
||||
m_arith_adaptive(false),
|
||||
m_arith_adaptive_assertion_threshold(0.2),
|
||||
m_arith_adaptive_propagation_threshold(0.4),
|
||||
m_arith_dump_lemmas(false),
|
||||
m_arith_eager_eq_axioms(true),
|
||||
m_arith_branch_cut_ratio(2),
|
||||
m_arith_int_eq_branching(false),
|
||||
m_arith_enum_const_mod(false),
|
||||
m_arith_gcd_test(true),
|
||||
m_arith_eager_gcd(false),
|
||||
m_arith_adaptive_gcd(false),
|
||||
m_arith_propagation_threshold(UINT_MAX),
|
||||
m_arith_pivot_strategy(ARITH_PIVOT_SMALLEST),
|
||||
m_arith_add_binary_bounds(false),
|
||||
m_arith_propagation_strategy(ARITH_PROP_PROPORTIONAL),
|
||||
m_arith_eq_bounds(false),
|
||||
m_arith_lazy_adapter(false),
|
||||
m_arith_fixnum(false),
|
||||
m_arith_int_only(false),
|
||||
m_nl_arith(true),
|
||||
m_nl_arith_gb(true),
|
||||
m_nl_arith_gb_threshold(512),
|
||||
m_nl_arith_gb_eqs(false),
|
||||
m_nl_arith_gb_perturbate(true),
|
||||
m_nl_arith_max_degree(6),
|
||||
m_nl_arith_branching(true),
|
||||
m_nl_arith_rounds(1024),
|
||||
m_arith_euclidean_solver(false) {
|
||||
}
|
||||
|
||||
void register_params(ini_params & p);
|
||||
};
|
||||
|
||||
#endif /* _THEORY_ARITH_PARAMS_H_ */
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
theory_array_params.h
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-06-01.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _THEORY_ARRAY_PARAMS_H_
|
||||
#define _THEORY_ARRAY_PARAMS_H_
|
||||
|
||||
#include"ini_file.h"
|
||||
|
||||
enum array_solver_id {
|
||||
AR_NO_ARRAY,
|
||||
AR_SIMPLE,
|
||||
AR_MODEL_BASED,
|
||||
AR_FULL
|
||||
};
|
||||
|
||||
struct theory_array_params {
|
||||
array_solver_id m_array_mode;
|
||||
bool m_array_weak;
|
||||
bool m_array_extensional;
|
||||
unsigned m_array_laziness;
|
||||
bool m_array_delay_exp_axiom;
|
||||
bool m_array_cg;
|
||||
bool m_array_always_prop_upward;
|
||||
bool m_array_lazy_ieq;
|
||||
unsigned m_array_lazy_ieq_delay;
|
||||
bool m_array_canonize_simplify;
|
||||
bool m_array_simplify; // temporary hack for disabling array simplifier plugin.
|
||||
|
||||
theory_array_params():
|
||||
m_array_mode(AR_FULL),
|
||||
m_array_weak(false),
|
||||
m_array_extensional(true),
|
||||
m_array_laziness(1),
|
||||
m_array_delay_exp_axiom(true),
|
||||
m_array_cg(false),
|
||||
m_array_always_prop_upward(true), // UPWARDs filter is broken... TODO: fix it
|
||||
m_array_lazy_ieq(false),
|
||||
m_array_lazy_ieq_delay(10),
|
||||
m_array_canonize_simplify(false),
|
||||
m_array_simplify(true) {
|
||||
}
|
||||
|
||||
void register_params(ini_params & p) {
|
||||
p.register_int_param("ARRAY_SOLVER", 0, 3, reinterpret_cast<int&>(m_array_mode), "0 - no array, 1 - simple, 2 - model based, 3 - full");
|
||||
p.register_bool_param("ARRAY_WEAK", m_array_weak);
|
||||
p.register_bool_param("ARRAY_EXTENSIONAL", m_array_extensional);
|
||||
p.register_unsigned_param("ARRAY_LAZINESS", m_array_laziness);
|
||||
p.register_bool_param("ARRAY_DELAY_EXP_AXIOM", m_array_delay_exp_axiom);
|
||||
p.register_bool_param("ARRAY_CG", m_array_cg);
|
||||
p.register_bool_param("ARRAY_ALWAYS_PROP_UPWARD", m_array_always_prop_upward,
|
||||
"Disable the built-in filter upwards propagation");
|
||||
p.register_bool_param("ARRAY_LAZY_IEQ", m_array_lazy_ieq);
|
||||
p.register_unsigned_param("ARRAY_LAZY_IEQ_DELAY", m_array_lazy_ieq_delay);
|
||||
p.register_bool_param("ARRAY_CANONIZE", m_array_canonize_simplify,
|
||||
"Normalize arrays into normal form during simplification");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif /* _THEORY_ARRAY_PARAMS_H_ */
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
theory_bv_params.h
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-06-06.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _THEORY_BV_PARAMS_H_
|
||||
#define _THEORY_BV_PARAMS_H_
|
||||
|
||||
#include"ini_file.h"
|
||||
|
||||
enum bv_solver_id {
|
||||
BS_NO_BV,
|
||||
BS_BLASTER
|
||||
};
|
||||
|
||||
struct theory_bv_params {
|
||||
bv_solver_id m_bv_mode;
|
||||
bool m_bv_reflect;
|
||||
bool m_bv_lazy_le;
|
||||
bool m_bv_cc;
|
||||
unsigned m_bv_blast_max_size;
|
||||
bool m_bv_enable_int2bv2int;
|
||||
theory_bv_params():
|
||||
m_bv_mode(BS_BLASTER),
|
||||
m_bv_reflect(true),
|
||||
m_bv_lazy_le(false),
|
||||
m_bv_cc(false),
|
||||
m_bv_blast_max_size(INT_MAX),
|
||||
m_bv_enable_int2bv2int(false) {}
|
||||
void register_params(ini_params & p) {
|
||||
p.register_int_param("BV_SOLVER", 0, 2, reinterpret_cast<int&>(m_bv_mode), "0 - no bv, 1 - simple");
|
||||
p.register_unsigned_param("BV_BLAST_MAX_SIZE", m_bv_blast_max_size, "Maximal size for bit-vectors to blast");
|
||||
p.register_bool_param("BV_REFLECT", m_bv_reflect);
|
||||
p.register_bool_param("BV_LAZY_LE", m_bv_lazy_le);
|
||||
p.register_bool_param("BV_CC", m_bv_cc, "enable congruence closure for BV operators");
|
||||
p.register_bool_param("BV_ENABLE_INT2BV_PROPAGATION", m_bv_enable_int2bv2int,
|
||||
"enable full (potentially expensive) propagation for int2bv and bv2int");
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _THEORY_BV_PARAMS_H_ */
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
theory_datatype_params.h
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-11-04.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _THEORY_DATATYPE_PARAMS_H_
|
||||
#define _THEORY_DATATYPE_PARAMS_H_
|
||||
|
||||
#include"ini_file.h"
|
||||
|
||||
struct theory_datatype_params {
|
||||
unsigned m_dt_lazy_splits;
|
||||
|
||||
theory_datatype_params():
|
||||
m_dt_lazy_splits(1) {
|
||||
}
|
||||
|
||||
void register_params(ini_params & p) {
|
||||
p.register_unsigned_param("DT_LAZY_SPLITS", m_dt_lazy_splits, "How lazy datatype splits are performed: 0- eager, 1- lazy for infinite types, 2- lazy");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif /* _THEORY_DATATYPE_PARAMS_H_ */
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
z3_solver_params.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2007-06-11.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include"z3_solver_params.h"
|
||||
|
||||
void z3_solver_params::register_params(ini_params & p) {
|
||||
p.register_bool_param("Z3_SOLVER_LL_PP", m_ast_ll_pp, "pretty print asserted constraints using low-level printer (Z3 input format specific)");
|
||||
p.register_bool_param("Z3_SOLVER_SMT_PP", m_ast_smt_pp, "pretty print asserted constraints using SMT printer (Z3 input format specific)");
|
||||
p.register_bool_param("PRE_SIMPLIFY_EXPR", m_pre_simplify_expr, "pre-simplify expressions when created over the API (example: -x -> (* -1 x))");
|
||||
p.register_string_param("SMTLIB_TRACE_PATH", m_smtlib_trace_path, "path for converting Z3 formulas to SMTLIB benchmarks");
|
||||
p.register_string_param("SMTLIB_SOURCE_INFO", m_smtlib_source_info, "additional source info to add to SMTLIB benchmark");
|
||||
p.register_string_param("SMTLIB_CATEGORY", m_smtlib_category, "additional category info to add to SMTLIB benchmark");
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
z3_solver_params.h
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2007-06-11.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _Z3_SOLVER_PARAMS_H_
|
||||
#define _Z3_SOLVER_PARAMS_H_
|
||||
|
||||
#include"ini_file.h"
|
||||
|
||||
struct z3_solver_params {
|
||||
bool m_ast_ll_pp;
|
||||
bool m_ast_smt_pp;
|
||||
bool m_pre_simplify_expr;
|
||||
std::string m_smtlib_trace_path;
|
||||
std::string m_smtlib_source_info;
|
||||
std::string m_smtlib_category;
|
||||
|
||||
z3_solver_params():
|
||||
m_ast_ll_pp(false),
|
||||
m_ast_smt_pp(false),
|
||||
m_pre_simplify_expr(false),
|
||||
m_smtlib_trace_path(""),
|
||||
m_smtlib_source_info(""),
|
||||
m_smtlib_category("")
|
||||
{}
|
||||
void register_params(ini_params & p);
|
||||
};
|
||||
|
||||
#endif /* _Z3_SOLVER_PARAMS_H_ */
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue