3
0
Fork 0
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:
Leonardo de Moura 2012-10-20 20:42:28 -07:00
parent d8cd3fc3ab
commit 6bdb009c3e
74 changed files with 67 additions and 27 deletions

View file

@ -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);
}

View file

@ -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

View file

@ -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_ */

View file

@ -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 "";
}

View file

@ -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

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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));
}

View file

@ -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

View file

@ -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");
}

View file

@ -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_ */

View file

@ -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

View file

@ -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);
}

View file

@ -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_ */

View file

@ -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));
}

View file

@ -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

View file

@ -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
}
}

View file

@ -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_ */

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -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

View file

@ -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");
}

View file

@ -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_ */

View file

@ -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");
}

View file

@ -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_ */

View file

@ -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;
}

View file

@ -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

View file

@ -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");
}

View file

@ -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

View file

@ -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");
}

View file

@ -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_ */

View file

@ -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_ */

View file

@ -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());
}

View file

@ -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

View file

@ -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_ */

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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_ */

View file

@ -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));
}

View file

@ -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

View file

@ -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");
}

View file

@ -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_ */

View file

@ -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;
}
};

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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_ */

View file

@ -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());
}
}

View file

@ -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

View file

@ -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());
}
}

View file

@ -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

View file

@ -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();
}

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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, "");
}

View file

@ -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_ */

View file

@ -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_ */

View file

@ -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_ */

View file

@ -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_ */

View file

@ -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");
}

View file

@ -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_ */