3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-10 08:03:25 +00:00

Merge branch 'master' of https://github.com/Z3Prover/z3 into new-ml-api

This commit is contained in:
Christoph M. Wintersteiger 2016-03-08 14:32:30 +00:00
commit cfda8e9e03
25 changed files with 313 additions and 228 deletions

View file

@ -1612,14 +1612,27 @@ def generate_files(api_files,
java_package_name=None, java_package_name=None,
ml_output_dir=None): ml_output_dir=None):
""" """
Scan the api files in ``api_files`` and emit Scan the api files in ``api_files`` and emit the relevant API files into
the relevant ``api_*.h`` and ``api_*.cpp`` files the output directories specified. If an output directory is set to ``None``
for the api modules into the ``api_output_dir`` then the files for that language binding or module are not emitted.
directory.
For the remaining arguments, if said argument is The reason for this function interface is:
not ``None`` the relevant files for that language
binding will be emitted to the specified directory. * The CMake build system needs to control where
files are emitted.
* The CMake build system needs to be able to choose
which API files are emitted.
* This function should be as decoupled from the Python
build system as much as possible but it must be possible
for the Python build system code to use this function.
Therefore we:
* Do not use the ``mk_util.is_*_enabled()`` functions
to determine if certain files should be or should not be emitted.
* Do not use the components declared in the Python build system
to determine the output directory paths.
""" """
# FIXME: These should not be global # FIXME: These should not be global
global log_h, log_c, exe_c, core_py global log_h, log_c, exe_c, core_py
@ -1677,16 +1690,32 @@ def generate_files(api_files,
def main(args): def main(args):
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
parser = argparse.ArgumentParser(description=__doc__) parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("api_files", nargs="+", parser.add_argument("api_files",
nargs="+",
help="API header files to generate files from") help="API header files to generate files from")
parser.add_argument("--api_output_dir", parser.add_argument("--api_output_dir",
help="Directory to emit files for api module", default=None,
default=None) help="Directory to emit files for api module. If not specified no files are emitted.")
parser.add_argument("--z3py-output-dir", dest="z3py_output_dir", default=None) parser.add_argument("--z3py-output-dir",
parser.add_argument("--dotnet-output-dir", dest="dotnet_output_dir", default=None) dest="z3py_output_dir",
parser.add_argument("--java-output-dir", dest="java_output_dir", default=None) default=None,
parser.add_argument("--java-package-name", dest="java_package_name", default=None) help="Directory to emit z3py files. If not specified no files are emitted.")
parser.add_argument("--ml-output-dir", dest="ml_output_dir", default=None) parser.add_argument("--dotnet-output-dir",
dest="dotnet_output_dir",
default=None,
help="Directory to emit dotnet files. If not specified no files are emitted.")
parser.add_argument("--java-output-dir",
dest="java_output_dir",
default=None,
help="Directory to emit Java files. If not specified no files are emitted.")
parser.add_argument("--java-package-name",
dest="java_package_name",
default=None,
help="Name to give the Java package (e.g. ``com.microsoft.z3``).")
parser.add_argument("--ml-output-dir",
dest="ml_output_dir",
default=None,
help="Directory to emit OCaml files. If not specified no files are emitted.")
pargs = parser.parse_args(args) pargs = parser.parse_args(args)
if pargs.java_output_dir: if pargs.java_output_dir:

View file

@ -1454,6 +1454,7 @@ void cmd_context::check_sat(unsigned num_assumptions, expr * const * assumptions
throw ex; throw ex;
} }
catch (z3_exception & ex) { catch (z3_exception & ex) {
get_opt()->display_assignment(regular_stream());
throw cmd_exception(ex.msg()); throw cmd_exception(ex.msg());
} }
if (was_pareto && r == l_false) { if (was_pareto && r == l_false) {

View file

@ -23,6 +23,7 @@ Revision History:
#include "ast.h" #include "ast.h"
#include "map.h" #include "map.h"
#include "vector.h" #include "vector.h"
#include <vector>
class model_core; class model_core;
@ -46,7 +47,7 @@ private:
mutable unsigned m_next_sym_suffix_idx; mutable unsigned m_next_sym_suffix_idx;
mutable symbols m_used_suffixes; mutable symbols m_used_suffixes;
/** Here we have default suffixes for each of the variants */ /** Here we have default suffixes for each of the variants */
vector<std::string> m_suffixes; std::vector<std::string> m_suffixes;
/** /**

View file

@ -233,8 +233,7 @@ namespace opt {
new_assignment.reset(); new_assignment.reset();
s().get_model(model); s().get_model(model);
for (unsigned i = 0; i < m_soft.size(); ++i) { for (unsigned i = 0; i < m_soft.size(); ++i) {
VERIFY(model->eval(m_soft[i], val)); new_assignment.push_back(model->eval(m_soft[i], val) && m.is_true(val));
new_assignment.push_back(m.is_true(val));
if (!new_assignment[i]) { if (!new_assignment[i]) {
new_upper += m_weights[i]; new_upper += m_weights[i];
} }

View file

@ -204,7 +204,7 @@ namespace opt {
m_assignment.reset(); m_assignment.reset();
for (unsigned i = 0; i < m_soft.size(); ++i) { for (unsigned i = 0; i < m_soft.size(); ++i) {
expr_ref val(m); expr_ref val(m);
VERIFY(m_model->eval(m_soft[i], val)); if (!m_model->eval(m_soft[i], val)) return l_undef;
TRACE("opt", tout << val << "\n";); TRACE("opt", tout << val << "\n";);
m_assignment.push_back(m.is_true(val)); m_assignment.push_back(m.is_true(val));
} }

View file

@ -530,8 +530,7 @@ namespace opt {
bool is_true(model_ref& mdl, expr* e) { bool is_true(model_ref& mdl, expr* e) {
expr_ref val(m); expr_ref val(m);
VERIFY(mdl->eval(e, val)); return mdl->eval(e, val) && m.is_true(val);
return m.is_true(val);
} }
bool is_active(unsigned i) const { bool is_active(unsigned i) const {

View file

@ -82,6 +82,7 @@ private:
memset(this, 0, sizeof(*this)); memset(this, 0, sizeof(*this));
} }
}; };
unsigned m_index;
stats m_stats; stats m_stats;
expr_ref_vector m_B; expr_ref_vector m_B;
expr_ref_vector m_asms; expr_ref_vector m_asms;
@ -112,10 +113,11 @@ private:
typedef ptr_vector<expr> exprs; typedef ptr_vector<expr> exprs;
public: public:
maxres(maxsat_context& c, maxres(maxsat_context& c, unsigned index,
weights_t& ws, expr_ref_vector const& soft, weights_t& ws, expr_ref_vector const& soft,
strategy_t st): strategy_t st):
maxsmt_solver_base(c, ws, soft), maxsmt_solver_base(c, ws, soft),
m_index(index),
m_B(m), m_asms(m), m_defs(m), m_B(m), m_asms(m), m_defs(m),
m_mus(c.get_solver(), m), m_mus(c.get_solver(), m),
m_mss(c.get_solver(), m), m_mss(c.get_solver(), m),
@ -189,7 +191,7 @@ public:
lbool mus_solver() { lbool mus_solver() {
lbool is_sat = l_true; lbool is_sat = l_true;
init(); if (!init()) return l_undef;
init_local(); init_local();
trace(); trace();
while (m_lower < m_upper) { while (m_lower < m_upper) {
@ -227,7 +229,7 @@ public:
} }
lbool primal_dual_solver() { lbool primal_dual_solver() {
init(); if (!init()) return l_undef;
init_local(); init_local();
trace(); trace();
exprs cs; exprs cs;
@ -483,8 +485,9 @@ public:
if (m_csmodel) { if (m_csmodel) {
expr_ref val(m); expr_ref val(m);
SASSERT(m_csmodel.get()); SASSERT(m_csmodel.get());
VERIFY(m_csmodel->eval(value, val)); if (m_csmodel->eval(value, val, true)) {
m_csmodel->register_decl(to_app(def)->get_decl(), val); m_csmodel->register_decl(to_app(def)->get_decl(), val);
}
} }
} }
@ -724,17 +727,26 @@ public:
if (upper >= m_upper) { if (upper >= m_upper) {
return; return;
} }
if (!m_c.verify_model(m_index, mdl, upper)) {
return;
}
m_model = mdl; m_model = mdl;
for (unsigned i = 0; i < m_soft.size(); ++i) { for (unsigned i = 0; i < m_soft.size(); ++i) {
m_assignment[i] = is_true(m_soft[i]); m_assignment[i] = is_true(m_soft[i]);
} }
DEBUG_CODE(verify_assignment();); DEBUG_CODE(verify_assignment(););
m_upper = upper; m_upper = upper;
trace(); trace();
add_upper_bound_block(); add_upper_bound_block();
} }
void add_upper_bound_block() { void add_upper_bound_block() {
@ -751,14 +763,12 @@ public:
bool is_true(model* mdl, expr* e) { bool is_true(model* mdl, expr* e) {
expr_ref tmp(m); expr_ref tmp(m);
VERIFY(mdl->eval(e, tmp)); return mdl->eval(e, tmp, true) && m.is_true(tmp);
return m.is_true(tmp);
} }
bool is_false(model* mdl, expr* e) { bool is_false(model* mdl, expr* e) {
expr_ref tmp(m); expr_ref tmp(m);
VERIFY(mdl->eval(e, tmp)); return mdl->eval(e, tmp, true) && m.is_false(tmp);
return m.is_false(tmp);
} }
bool is_true(expr* e) { bool is_true(expr* e) {
@ -870,12 +880,12 @@ public:
}; };
opt::maxsmt_solver_base* opt::mk_maxres( opt::maxsmt_solver_base* opt::mk_maxres(
maxsat_context& c, weights_t& ws, expr_ref_vector const& soft) { maxsat_context& c, unsigned id, weights_t& ws, expr_ref_vector const& soft) {
return alloc(maxres, c, ws, soft, maxres::s_primal); return alloc(maxres, c, id, ws, soft, maxres::s_primal);
} }
opt::maxsmt_solver_base* opt::mk_primal_dual_maxres( opt::maxsmt_solver_base* opt::mk_primal_dual_maxres(
maxsat_context& c, weights_t& ws, expr_ref_vector const& soft) { maxsat_context& c, unsigned id, weights_t& ws, expr_ref_vector const& soft) {
return alloc(maxres, c, ws, soft, maxres::s_primal_dual); return alloc(maxres, c, id, ws, soft, maxres::s_primal_dual);
} }

View file

@ -22,9 +22,9 @@ Notes:
namespace opt { namespace opt {
maxsmt_solver_base* mk_maxres(maxsat_context& c, weights_t & ws, expr_ref_vector const& soft); maxsmt_solver_base* mk_maxres(maxsat_context& c, unsigned id, weights_t & ws, expr_ref_vector const& soft);
maxsmt_solver_base* mk_primal_dual_maxres(maxsat_context& c, weights_t & ws, expr_ref_vector const& soft); maxsmt_solver_base* mk_primal_dual_maxres(maxsat_context& c, unsigned id, weights_t & ws, expr_ref_vector const& soft);
}; };

View file

@ -69,13 +69,13 @@ namespace opt {
s().assert_expr(tmp); s().assert_expr(tmp);
} }
void maxsmt_solver_base::init() { bool maxsmt_solver_base::init() {
m_lower.reset(); m_lower.reset();
m_upper.reset(); m_upper.reset();
m_assignment.reset(); m_assignment.reset();
for (unsigned i = 0; i < m_weights.size(); ++i) { for (unsigned i = 0; i < m_weights.size(); ++i) {
expr_ref val(m); expr_ref val(m);
VERIFY(m_model->eval(m_soft[i], val)); if (!m_model->eval(m_soft[i], val)) return false;
m_assignment.push_back(m.is_true(val)); m_assignment.push_back(m.is_true(val));
if (!m_assignment.back()) { if (!m_assignment.back()) {
m_upper += m_weights[i]; m_upper += m_weights[i];
@ -88,6 +88,7 @@ namespace opt {
tout << (m_assignment[i]?"T":"F"); tout << (m_assignment[i]?"T":"F");
} }
tout << "\n";); tout << "\n";);
return true;
} }
void maxsmt_solver_base::set_mus(bool f) { void maxsmt_solver_base::set_mus(bool f) {
@ -137,7 +138,8 @@ namespace opt {
//m_wth->reset_local(); //m_wth->reset_local();
} }
smt::theory_wmaxsat& maxsmt_solver_base::scoped_ensure_theory::operator()() { return *m_wth; } smt::theory_wmaxsat& maxsmt_solver_base::scoped_ensure_theory::operator()() { return *m_wth; }
void maxsmt_solver_base::trace_bounds(char const * solver) { void maxsmt_solver_base::trace_bounds(char const * solver) {
IF_VERBOSE(1, IF_VERBOSE(1,
rational l = m_adjust_value(m_lower); rational l = m_adjust_value(m_lower);
@ -148,8 +150,8 @@ namespace opt {
maxsmt::maxsmt(maxsat_context& c): maxsmt::maxsmt(maxsat_context& c, unsigned index):
m(c.get_manager()), m_c(c), m(c.get_manager()), m_c(c), m_index(index),
m_soft_constraints(m), m_answer(m) {} m_soft_constraints(m), m_answer(m) {}
lbool maxsmt::operator()() { lbool maxsmt::operator()() {
@ -159,10 +161,10 @@ namespace opt {
IF_VERBOSE(1, verbose_stream() << "(maxsmt)\n";); IF_VERBOSE(1, verbose_stream() << "(maxsmt)\n";);
TRACE("opt", tout << "maxsmt\n";); TRACE("opt", tout << "maxsmt\n";);
if (m_soft_constraints.empty() || maxsat_engine == symbol("maxres")) { if (m_soft_constraints.empty() || maxsat_engine == symbol("maxres")) {
m_msolver = mk_maxres(m_c, m_weights, m_soft_constraints); m_msolver = mk_maxres(m_c, m_index, m_weights, m_soft_constraints);
} }
else if (maxsat_engine == symbol("pd-maxres")) { else if (maxsat_engine == symbol("pd-maxres")) {
m_msolver = mk_primal_dual_maxres(m_c, m_weights, m_soft_constraints); m_msolver = mk_primal_dual_maxres(m_c, m_index, m_weights, m_soft_constraints);
} }
else if (maxsat_engine == symbol("bcd2")) { else if (maxsat_engine == symbol("bcd2")) {
m_msolver = mk_bcd2(m_c, m_weights, m_soft_constraints); m_msolver = mk_bcd2(m_c, m_weights, m_soft_constraints);
@ -188,7 +190,13 @@ namespace opt {
if (m_msolver) { if (m_msolver) {
m_msolver->updt_params(m_params); m_msolver->updt_params(m_params);
m_msolver->set_adjust_value(m_adjust_value); m_msolver->set_adjust_value(m_adjust_value);
is_sat = (*m_msolver)(); is_sat = l_undef;
try {
is_sat = (*m_msolver)();
}
catch (z3_exception&) {
is_sat = l_undef;
}
if (is_sat != l_false) { if (is_sat != l_false) {
m_msolver->get_model(m_model, m_labels); m_msolver->get_model(m_model, m_labels);
} }
@ -205,6 +213,14 @@ namespace opt {
return is_sat; return is_sat;
} }
void maxsmt::set_adjust_value(adjust_value& adj) {
m_adjust_value = adj;
if (m_msolver) {
m_msolver->set_adjust_value(m_adjust_value);
}
}
void maxsmt::verify_assignment() { void maxsmt::verify_assignment() {
// TBD: have to use a different solver // TBD: have to use a different solver
// because we don't push local scope any longer. // because we don't push local scope any longer.
@ -233,7 +249,7 @@ namespace opt {
rational r = m_upper; rational r = m_upper;
if (m_msolver) { if (m_msolver) {
rational q = m_msolver->get_upper(); rational q = m_msolver->get_upper();
if (q < r) r = q; if (q < r) r = q;
} }
return m_adjust_value(r); return m_adjust_value(r);
} }

View file

@ -82,7 +82,7 @@ namespace opt {
void set_model() { s().get_model(m_model); s().get_labels(m_labels); } void set_model() { s().get_model(m_model); s().get_labels(m_labels); }
virtual void updt_params(params_ref& p); virtual void updt_params(params_ref& p);
solver& s(); solver& s();
void init(); bool init();
void set_mus(bool f); void set_mus(bool f);
app* mk_fresh_bool(char const* name); app* mk_fresh_bool(char const* name);
@ -111,6 +111,7 @@ namespace opt {
class maxsmt { class maxsmt {
ast_manager& m; ast_manager& m;
maxsat_context& m_c; maxsat_context& m_c;
unsigned m_index;
scoped_ptr<maxsmt_solver_base> m_msolver; scoped_ptr<maxsmt_solver_base> m_msolver;
expr_ref_vector m_soft_constraints; expr_ref_vector m_soft_constraints;
expr_ref_vector m_answer; expr_ref_vector m_answer;
@ -122,11 +123,11 @@ namespace opt {
svector<symbol> m_labels; svector<symbol> m_labels;
params_ref m_params; params_ref m_params;
public: public:
maxsmt(maxsat_context& c); maxsmt(maxsat_context& c, unsigned id);
lbool operator()(); lbool operator()();
void updt_params(params_ref& p); void updt_params(params_ref& p);
void add(expr* f, rational const& w); void add(expr* f, rational const& w);
void set_adjust_value(adjust_value& adj) { m_adjust_value = adj; } void set_adjust_value(adjust_value& adj);
unsigned size() const { return m_soft_constraints.size(); } unsigned size() const { return m_soft_constraints.size(); }
expr* operator[](unsigned idx) const { return m_soft_constraints[idx]; } expr* operator[](unsigned idx) const { return m_soft_constraints[idx]; }
rational weight(unsigned idx) const { return m_weights[idx]; } rational weight(unsigned idx) const { return m_weights[idx]; }

View file

@ -73,8 +73,7 @@ namespace opt {
expr* n = core[j]; expr* n = core[j];
if (!core_lits.contains(n)) { if (!core_lits.contains(n)) {
core_lits.insert(n); core_lits.insert(n);
VERIFY(m_model->eval(n, tmp)); if (m_model->eval(n, tmp) && m.is_true(tmp)) {
if (m.is_true(tmp)) {
add_mss(n); add_mss(n);
} }
else { else {
@ -86,8 +85,7 @@ namespace opt {
for (unsigned i = 0; i < literals.size(); ++i) { for (unsigned i = 0; i < literals.size(); ++i) {
expr* n = literals[i]; expr* n = literals[i];
if (!core_lits.contains(n)) { if (!core_lits.contains(n)) {
VERIFY(m_model->eval(n, tmp)); if (m_model->eval(n, tmp) && m.is_true(tmp)) {
if (m.is_true(tmp)) {
m_mss.push_back(n); m_mss.push_back(n);
} }
else { else {
@ -130,8 +128,7 @@ namespace opt {
if (m_mcs.contains(n)) { if (m_mcs.contains(n)) {
continue; // remove from cores. continue; // remove from cores.
} }
VERIFY(m_model->eval(n, tmp)); if (m_model->eval(n, tmp) && m.is_true(tmp)) {
if (m.is_true(tmp)) {
add_mss(n); add_mss(n);
} }
else { else {
@ -275,7 +272,7 @@ namespace opt {
expr_ref tmp(m); expr_ref tmp(m);
for (unsigned i = 0; i < m_mss.size(); ++i) { for (unsigned i = 0; i < m_mss.size(); ++i) {
expr* n = m_mss[i]; expr* n = m_mss[i];
VERIFY(m_model->eval(n, tmp)); if (!m_model->eval(n, tmp)) return true;
CTRACE("opt", !m.is_true(tmp), tout << mk_pp(n, m) << " |-> " << mk_pp(tmp, m) << "\n";); CTRACE("opt", !m.is_true(tmp), tout << mk_pp(n, m) << " |-> " << mk_pp(tmp, m) << "\n";);
SASSERT(!m.is_false(tmp)); SASSERT(!m.is_false(tmp));
} }

View file

@ -203,7 +203,7 @@ namespace opt {
objective& obj = s.m_objectives[i]; objective& obj = s.m_objectives[i];
m_objectives.push_back(obj); m_objectives.push_back(obj);
if (obj.m_type == O_MAXSMT) { if (obj.m_type == O_MAXSMT) {
add_maxsmt(obj.m_id); add_maxsmt(obj.m_id, i);
} }
} }
m_hard_constraints.append(s.m_hard); m_hard_constraints.append(s.m_hard);
@ -311,7 +311,9 @@ namespace opt {
maxsmt& ms = *m_maxsmts.find(id); maxsmt& ms = *m_maxsmts.find(id);
if (scoped) get_solver().push(); if (scoped) get_solver().push();
lbool result = ms(); lbool result = ms();
if (result != l_false && (ms.get_model(tmp, m_labels), tmp.get())) ms.get_model(m_model, m_labels); if (result != l_false && (ms.get_model(tmp, m_labels), tmp.get())) {
ms.get_model(m_model, m_labels);
}
if (scoped) get_solver().pop(1); if (scoped) get_solver().pop(1);
if (result == l_true && committed) ms.commit_assignment(); if (result == l_true && committed) ms.commit_assignment();
return result; return result;
@ -414,12 +416,16 @@ namespace opt {
case O_MINIMIZE: case O_MINIMIZE:
is_ge = !is_ge; is_ge = !is_ge;
case O_MAXIMIZE: case O_MAXIMIZE:
VERIFY(mdl->eval(obj.m_term, val) && is_numeral(val, k)); if (mdl->eval(obj.m_term, val) && is_numeral(val, k)) {
if (is_ge) { if (is_ge) {
result = mk_ge(obj.m_term, val); result = mk_ge(obj.m_term, val);
}
else {
result = mk_ge(val, obj.m_term);
}
} }
else { else {
result = mk_ge(val, obj.m_term); result = m.mk_true();
} }
break; break;
case O_MAXSMT: { case O_MAXSMT: {
@ -430,8 +436,7 @@ namespace opt {
for (unsigned i = 0; i < sz; ++i) { for (unsigned i = 0; i < sz; ++i) {
terms.push_back(obj.m_terms[i]); terms.push_back(obj.m_terms[i]);
coeffs.push_back(obj.m_weights[i]); coeffs.push_back(obj.m_weights[i]);
VERIFY(mdl->eval(obj.m_terms[i], val)); if (mdl->eval(obj.m_terms[i], val) && m.is_true(val)) {
if (m.is_true(val)) {
k += obj.m_weights[i]; k += obj.m_weights[i];
} }
} }
@ -469,8 +474,7 @@ namespace opt {
update_bound(false); update_bound(false);
} }
lbool context::execute_pareto() { lbool context::execute_pareto() {
if (!m_pareto) { if (!m_pareto) {
set_pareto(alloc(gia_pareto, m, *this, m_solver.get(), m_params)); set_pareto(alloc(gia_pareto, m, *this, m_solver.get(), m_params));
} }
@ -642,8 +646,8 @@ namespace opt {
} }
void context::add_maxsmt(symbol const& id) { void context::add_maxsmt(symbol const& id, unsigned index) {
maxsmt* ms = alloc(maxsmt, *this); maxsmt* ms = alloc(maxsmt, *this, index);
ms->updt_params(m_params); ms->updt_params(m_params);
#pragma omp critical (opt_context) #pragma omp critical (opt_context)
{ {
@ -708,7 +712,7 @@ namespace opt {
} }
} }
bool context::is_maximize(expr* fml, app_ref& term, expr*& orig_term, unsigned& index) { bool context::is_maximize(expr* fml, app_ref& term, expr_ref& orig_term, unsigned& index) {
if (is_app(fml) && m_objective_fns.find(to_app(fml)->get_decl(), index) && if (is_app(fml) && m_objective_fns.find(to_app(fml)->get_decl(), index) &&
m_objectives[index].m_type == O_MAXIMIZE) { m_objectives[index].m_type == O_MAXIMIZE) {
term = to_app(to_app(fml)->get_arg(0)); term = to_app(to_app(fml)->get_arg(0));
@ -718,7 +722,7 @@ namespace opt {
return false; return false;
} }
bool context::is_minimize(expr* fml, app_ref& term, expr*& orig_term, unsigned& index) { bool context::is_minimize(expr* fml, app_ref& term, expr_ref& orig_term, unsigned& index) {
if (is_app(fml) && m_objective_fns.find(to_app(fml)->get_decl(), index) && if (is_app(fml) && m_objective_fns.find(to_app(fml)->get_decl(), index) &&
m_objectives[index].m_type == O_MINIMIZE) { m_objectives[index].m_type == O_MINIMIZE) {
term = to_app(to_app(fml)->get_arg(0)); term = to_app(to_app(fml)->get_arg(0));
@ -730,7 +734,7 @@ namespace opt {
bool context::is_maxsat(expr* fml, expr_ref_vector& terms, bool context::is_maxsat(expr* fml, expr_ref_vector& terms,
vector<rational>& weights, rational& offset, vector<rational>& weights, rational& offset,
bool& neg, symbol& id, unsigned& index) { bool& neg, symbol& id, expr_ref& orig_term, unsigned& index) {
if (!is_app(fml)) return false; if (!is_app(fml)) return false;
neg = false; neg = false;
app* a = to_app(fml); app* a = to_app(fml);
@ -752,7 +756,6 @@ namespace opt {
return true; return true;
} }
app_ref term(m); app_ref term(m);
expr* orig_term;
offset = rational::zero(); offset = rational::zero();
bool is_max = is_maximize(fml, term, orig_term, index); bool is_max = is_maximize(fml, term, orig_term, index);
bool is_min = !is_max && is_minimize(fml, term, orig_term, index); bool is_min = !is_max && is_minimize(fml, term, orig_term, index);
@ -773,7 +776,7 @@ namespace opt {
} }
} }
TRACE("opt", TRACE("opt",
tout << "Convert minimization " << mk_pp(orig_term, m) << "\n"; tout << "Convert minimization " << orig_term << "\n";
tout << "to maxsat: " << term << "\n"; tout << "to maxsat: " << term << "\n";
for (unsigned i = 0; i < weights.size(); ++i) { for (unsigned i = 0; i < weights.size(); ++i) {
tout << mk_pp(terms[i].get(), m) << ": " << weights[i] << "\n"; tout << mk_pp(terms[i].get(), m) << ": " << weights[i] << "\n";
@ -781,7 +784,7 @@ namespace opt {
tout << "offset: " << offset << "\n"; tout << "offset: " << offset << "\n";
); );
std::ostringstream out; std::ostringstream out;
out << mk_pp(orig_term, m) << ":" << index; out << orig_term << ":" << index;
id = symbol(out.str().c_str()); id = symbol(out.str().c_str());
return true; return true;
} }
@ -804,7 +807,7 @@ namespace opt {
} }
neg = true; neg = true;
std::ostringstream out; std::ostringstream out;
out << mk_pp(orig_term, m) << ":" << index; out << orig_term << ":" << index;
id = symbol(out.str().c_str()); id = symbol(out.str().c_str());
return true; return true;
} }
@ -823,7 +826,7 @@ namespace opt {
} }
neg = is_max; neg = is_max;
std::ostringstream out; std::ostringstream out;
out << mk_pp(orig_term, m) << ":" << index; out << orig_term << ":" << index;
id = symbol(out.str().c_str()); id = symbol(out.str().c_str());
return true; return true;
} }
@ -871,7 +874,7 @@ namespace opt {
tout << mk_pp(fmls[i], m) << "\n"; tout << mk_pp(fmls[i], m) << "\n";
}); });
m_hard_constraints.reset(); m_hard_constraints.reset();
expr* orig_term; expr_ref orig_term(m);
for (unsigned i = 0; i < fmls.size(); ++i) { for (unsigned i = 0; i < fmls.size(); ++i) {
expr* fml = fmls[i]; expr* fml = fmls[i];
app_ref tr(m); app_ref tr(m);
@ -881,7 +884,7 @@ namespace opt {
unsigned index; unsigned index;
symbol id; symbol id;
bool neg; bool neg;
if (is_maxsat(fml, terms, weights, offset, neg, id, index)) { if (is_maxsat(fml, terms, weights, offset, neg, id, orig_term, index)) {
objective& obj = m_objectives[index]; objective& obj = m_objectives[index];
if (obj.m_type != O_MAXSMT) { if (obj.m_type != O_MAXSMT) {
@ -889,10 +892,11 @@ namespace opt {
obj.m_id = id; obj.m_id = id;
obj.m_type = O_MAXSMT; obj.m_type = O_MAXSMT;
SASSERT(!m_maxsmts.contains(id)); SASSERT(!m_maxsmts.contains(id));
add_maxsmt(id); add_maxsmt(id, index);
} }
mk_atomic(terms); mk_atomic(terms);
SASSERT(obj.m_id == id); SASSERT(obj.m_id == id);
obj.m_term = to_app(orig_term);
obj.m_terms.reset(); obj.m_terms.reset();
obj.m_terms.append(terms); obj.m_terms.append(terms);
obj.m_weights.reset(); obj.m_weights.reset();
@ -933,6 +937,32 @@ namespace opt {
} }
} }
bool context::verify_model(unsigned index, model* md, rational const& _v) {
rational r;
app_ref term = m_objectives[index].m_term;
rational v = m_objectives[index].m_adjust_value(_v);
expr_ref val(m);
model_ref mdl = md;
fix_model(mdl);
if (!mdl->eval(term, val)) {
TRACE("opt", tout << "Term does not evaluate " << term << "\n";);
return false;
}
if (!m_arith.is_numeral(val, r)) {
TRACE("opt", tout << "model does not evaluate objective to a value\n";);
return false;
}
if (r != v) {
TRACE("opt", tout << "Out of bounds: " << term << " " << val << " != " << v << "\n";);
return false;
}
else {
TRACE("opt", tout << "validated: " << term << " = " << val << "\n";);
}
return true;
}
void context::purify(app_ref& term) { void context::purify(app_ref& term) {
filter_model_converter_ref fm; filter_model_converter_ref fm;
if (m_arith.is_add(term)) { if (m_arith.is_add(term)) {
@ -1395,8 +1425,8 @@ namespace opt {
case O_MAXSMT: { case O_MAXSMT: {
rational value(0); rational value(0);
for (unsigned i = 0; i < obj.m_terms.size(); ++i) { for (unsigned i = 0; i < obj.m_terms.size(); ++i) {
VERIFY(m_model->eval(obj.m_terms[i], val)); bool evaluated = m_model->eval(obj.m_terms[i], val);
if (!m.is_true(val)) { if (evaluated && !m.is_true(val)) {
value += obj.m_weights[i]; value += obj.m_weights[i];
} }
// TBD: check that optimal was not changed. // TBD: check that optimal was not changed.

View file

@ -55,6 +55,8 @@ namespace opt {
virtual void get_base_model(model_ref& _m) = 0; // retrieve model from initial satisfiability call. virtual void get_base_model(model_ref& _m) = 0; // retrieve model from initial satisfiability call.
virtual smt::context& smt_context() = 0; // access SMT context for SMT based MaxSMT solver (wmax requires SMT core) virtual smt::context& smt_context() = 0; // access SMT context for SMT based MaxSMT solver (wmax requires SMT core)
virtual unsigned num_objectives() = 0; virtual unsigned num_objectives() = 0;
virtual bool verify_model(unsigned id, model* mdl, rational const& v) = 0;
virtual void set_model(model_ref& _m) = 0;
}; };
/** /**
@ -132,6 +134,7 @@ namespace opt {
bool set(ptr_vector<expr> & hard); bool set(ptr_vector<expr> & hard);
unsigned add(expr* soft, rational const& weight, symbol const& id); unsigned add(expr* soft, rational const& weight, symbol const& id);
unsigned add(app* obj, bool is_max); unsigned add(app* obj, bool is_max);
unsigned get_index(symbol const& id) { return m_indices[id]; }
}; };
ast_manager& m; ast_manager& m;
@ -178,6 +181,7 @@ namespace opt {
virtual void set_hard_constraints(ptr_vector<expr> & hard); virtual void set_hard_constraints(ptr_vector<expr> & hard);
virtual lbool optimize(); virtual lbool optimize();
virtual bool print_model() const; virtual bool print_model() const;
virtual void set_model(model_ref& _m) { m_model = _m; }
virtual void get_model(model_ref& _m); virtual void get_model(model_ref& _m);
virtual void fix_model(model_ref& _m); virtual void fix_model(model_ref& _m);
virtual void collect_statistics(statistics& stats) const; virtual void collect_statistics(statistics& stats) const;
@ -219,6 +223,8 @@ namespace opt {
virtual void get_base_model(model_ref& _m); virtual void get_base_model(model_ref& _m);
virtual bool verify_model(unsigned id, model* mdl, rational const& v);
private: private:
void validate_feasibility(maxsmt& ms); void validate_feasibility(maxsmt& ms);
@ -236,11 +242,11 @@ namespace opt {
void import_scoped_state(); void import_scoped_state();
void normalize(); void normalize();
void internalize(); void internalize();
bool is_maximize(expr* fml, app_ref& term, expr*& orig_term, unsigned& index); bool is_maximize(expr* fml, app_ref& term, expr_ref& orig_term, unsigned& index);
bool is_minimize(expr* fml, app_ref& term, expr*& orig_term, unsigned& index); bool is_minimize(expr* fml, app_ref& term, expr_ref& orig_term, unsigned& index);
bool is_maxsat(expr* fml, expr_ref_vector& terms, bool is_maxsat(expr* fml, expr_ref_vector& terms,
vector<rational>& weights, rational& offset, bool& neg, vector<rational>& weights, rational& offset, bool& neg,
symbol& id, unsigned& index); symbol& id, expr_ref& orig_term, unsigned& index);
void purify(app_ref& term); void purify(app_ref& term);
app* purify(filter_model_converter_ref& fm, expr* e); app* purify(filter_model_converter_ref& fm, expr* e);
bool is_mul_const(expr* e); bool is_mul_const(expr* e);
@ -269,7 +275,7 @@ namespace opt {
void init_solver(); void init_solver();
void update_solver(); void update_solver();
void setup_arith_solver(); void setup_arith_solver();
void add_maxsmt(symbol const& id); void add_maxsmt(symbol const& id, unsigned index);
void set_simplify(tactic *simplify); void set_simplify(tactic *simplify);
void set_pareto(pareto_base* p); void set_pareto(pareto_base* p);
void clear_state(); void clear_state();

View file

@ -156,8 +156,7 @@ namespace opt {
m_s->get_labels(m_labels); m_s->get_labels(m_labels);
for (unsigned i = 0; i < ors.size(); ++i) { for (unsigned i = 0; i < ors.size(); ++i) {
expr_ref tmp(m); expr_ref tmp(m);
m_model->eval(ors[i].get(), tmp); if (m_model->eval(ors[i].get(), tmp) && m.is_true(tmp)) {
if (m.is_true(tmp)) {
m_lower[i] = m_upper[i]; m_lower[i] = m_upper[i];
ors[i] = m.mk_false(); ors[i] = m.mk_false();
disj[i] = m.mk_false(); disj[i] = m.mk_false();

View file

@ -139,8 +139,7 @@ namespace smt {
m_orig_model = mdl; m_orig_model = mdl;
for (unsigned i = 0; i < m_var2decl.size(); ++i) { for (unsigned i = 0; i < m_var2decl.size(); ++i) {
expr_ref tmp(m); expr_ref tmp(m);
VERIFY(mdl->eval(m_var2decl[i], tmp)); m_assignment[i] = mdl->eval(m_var2decl[i], tmp) && m.is_true(tmp);
m_assignment[i] = m.is_true(tmp);
} }
} }
@ -305,7 +304,9 @@ namespace smt {
if (!eval(m_clauses[i])) { if (!eval(m_clauses[i])) {
m_hard_false.insert(i); m_hard_false.insert(i);
expr_ref tmp(m); expr_ref tmp(m);
VERIFY(m_orig_model->eval(m_orig_clauses[i].get(), tmp)); if (!m_orig_model->eval(m_orig_clauses[i].get(), tmp)) {
return;
}
IF_VERBOSE(0, IF_VERBOSE(0,
verbose_stream() << "original evaluation: " << tmp << "\n"; verbose_stream() << "original evaluation: " << tmp << "\n";
verbose_stream() << mk_pp(m_orig_clauses[i].get(), m) << "\n"; verbose_stream() << mk_pp(m_orig_clauses[i].get(), m) << "\n";
@ -487,8 +488,7 @@ namespace smt {
SASSERT(m_soft_occ.size() == var); SASSERT(m_soft_occ.size() == var);
m_hard_occ.push_back(unsigned_vector()); m_hard_occ.push_back(unsigned_vector());
m_soft_occ.push_back(unsigned_vector()); m_soft_occ.push_back(unsigned_vector());
VERIFY(m_orig_model->eval(f, tmp)); m_assignment.push_back(m_orig_model->eval(f, tmp) && m.is_true(tmp));
m_assignment.push_back(m.is_true(tmp));
m_decl2var.insert(f, var); m_decl2var.insert(f, var);
m_var2decl.push_back(f); m_var2decl.push_back(f);
} }

View file

@ -97,7 +97,7 @@ namespace sat {
break; break;
} }
if (s.m_config.m_minimize_core_partial && s.m_stats.m_restart - m_restart > m_max_restarts) { if (s.m_config.m_minimize_core_partial && s.m_stats.m_restart - m_restart > m_max_restarts) {
IF_VERBOSE(1, verbose_stream() << "restart budget exceeded\n";); IF_VERBOSE(1, verbose_stream() << "(sat restart budget exceeded)\n";);
set_core(); set_core();
return l_true; return l_true;
} }
@ -173,7 +173,7 @@ namespace sat {
lbool mus::qx(literal_set& assignment, literal_set& support, bool has_support) { lbool mus::qx(literal_set& assignment, literal_set& support, bool has_support) {
lbool is_sat = l_true; lbool is_sat = l_true;
if (s.m_config.m_minimize_core_partial && s.m_stats.m_restart - m_restart > m_max_restarts) { if (s.m_config.m_minimize_core_partial && s.m_stats.m_restart - m_restart > m_max_restarts) {
IF_VERBOSE(1, verbose_stream() << "restart budget exceeded\n";); IF_VERBOSE(1, verbose_stream() << "(sat restart budget exceeded)\n";);
return l_true; return l_true;
} }
if (has_support) { if (has_support) {

View file

@ -50,14 +50,14 @@ class inc_sat_solver : public solver {
expr_ref_vector m_core; expr_ref_vector m_core;
atom2bool_var m_map; atom2bool_var m_map;
model_ref m_model; model_ref m_model;
model_converter_ref m_mc; scoped_ptr<bit_blaster_rewriter> m_bb_rewriter;
bit_blaster_rewriter m_bb_rewriter;
tactic_ref m_preprocess; tactic_ref m_preprocess;
unsigned m_num_scopes; unsigned m_num_scopes;
sat::literal_vector m_asms; sat::literal_vector m_asms;
goal_ref_buffer m_subgoals; goal_ref_buffer m_subgoals;
proof_converter_ref m_pc; proof_converter_ref m_pc;
model_converter_ref m_mc2; model_converter_ref m_mc;
model_converter_ref m_mc0;
expr_dependency_ref m_dep_core; expr_dependency_ref m_dep_core;
svector<double> m_weights; svector<double> m_weights;
std::string m_unknown; std::string m_unknown;
@ -72,29 +72,13 @@ public:
m_asmsf(m), m_asmsf(m),
m_fmls_head(0), m_fmls_head(0),
m_core(m), m_core(m),
m_map(m), m_map(m),
m_bb_rewriter(m, p),
m_num_scopes(0), m_num_scopes(0),
m_dep_core(m), m_dep_core(m),
m_unknown("no reason given") { m_unknown("no reason given") {
m_params.set_bool("elim_vars", false); m_params.set_bool("elim_vars", false);
m_solver.updt_params(m_params); m_solver.updt_params(m_params);
params_ref simp2_p = p; init_preprocess();
simp2_p.set_bool("som", true);
simp2_p.set_bool("pull_cheap_ite", true);
simp2_p.set_bool("push_ite_bv", false);
simp2_p.set_bool("local_ctx", true);
simp2_p.set_uint("local_ctx_limit", 10000000);
simp2_p.set_bool("flat", true); // required by som
simp2_p.set_bool("hoist_mul", false); // required by som
simp2_p.set_bool("elim_and", true);
m_preprocess =
and_then(mk_card2bv_tactic(m, m_params),
using_params(mk_simplify_tactic(m), simp2_p),
mk_max_bv_sharing_tactic(m),
mk_bit_blaster_tactic(m, &m_bb_rewriter),
//mk_aig_tactic(),
using_params(mk_simplify_tactic(m), simp2_p));
} }
virtual ~inc_sat_solver() {} virtual ~inc_sat_solver() {}
@ -179,14 +163,14 @@ public:
m_fmls_lim.push_back(m_fmls.size()); m_fmls_lim.push_back(m_fmls.size());
m_asms_lim.push_back(m_asmsf.size()); m_asms_lim.push_back(m_asmsf.size());
m_fmls_head_lim.push_back(m_fmls_head); m_fmls_head_lim.push_back(m_fmls_head);
m_bb_rewriter.push(); m_bb_rewriter->push();
m_map.push(); m_map.push();
} }
virtual void pop(unsigned n) { virtual void pop(unsigned n) {
if (n > m_num_scopes) { // allow inc_sat_solver to if (n > m_num_scopes) { // allow inc_sat_solver to
n = m_num_scopes; // take over for another solver. n = m_num_scopes; // take over for another solver.
} }
m_bb_rewriter.pop(n); m_bb_rewriter->pop(n);
m_map.pop(n); m_map.pop(n);
SASSERT(n <= m_num_scopes); SASSERT(n <= m_num_scopes);
m_solver.user_pop(n); m_solver.user_pop(n);
@ -269,30 +253,58 @@ public:
return m_asmsf[idx]; return m_asmsf[idx];
} }
void init_preprocess() {
if (m_preprocess) {
m_preprocess->reset();
}
params_ref simp2_p = m_params;
m_bb_rewriter = alloc(bit_blaster_rewriter, m, m_params);
simp2_p.set_bool("som", true);
simp2_p.set_bool("pull_cheap_ite", true);
simp2_p.set_bool("push_ite_bv", false);
simp2_p.set_bool("local_ctx", true);
simp2_p.set_uint("local_ctx_limit", 10000000);
simp2_p.set_bool("flat", true); // required by som
simp2_p.set_bool("hoist_mul", false); // required by som
simp2_p.set_bool("elim_and", true);
m_preprocess =
and_then(mk_card2bv_tactic(m, m_params),
using_params(mk_simplify_tactic(m), simp2_p),
mk_max_bv_sharing_tactic(m),
mk_bit_blaster_tactic(m, m_bb_rewriter.get()),
//mk_aig_tactic(),
using_params(mk_simplify_tactic(m), simp2_p));
for (unsigned i = 0; i < m_num_scopes; ++i) {
m_bb_rewriter->push();
}
m_preprocess->reset();
}
private: private:
lbool internalize_goal(goal_ref& g, dep2asm_t& dep2asm) { lbool internalize_goal(goal_ref& g, dep2asm_t& dep2asm) {
m_mc2.reset(); m_mc.reset();
m_pc.reset(); m_pc.reset();
m_dep_core.reset(); m_dep_core.reset();
m_subgoals.reset(); m_subgoals.reset();
m_preprocess->reset(); init_preprocess();
SASSERT(g->models_enabled()); SASSERT(g->models_enabled());
SASSERT(!g->proofs_enabled()); SASSERT(!g->proofs_enabled());
TRACE("sat", g->display(tout);); TRACE("sat", g->display(tout););
try { try {
(*m_preprocess)(g, m_subgoals, m_mc2, m_pc, m_dep_core); (*m_preprocess)(g, m_subgoals, m_mc, m_pc, m_dep_core);
} }
catch (tactic_exception & ex) { catch (tactic_exception & ex) {
IF_VERBOSE(0, verbose_stream() << "exception in tactic " << ex.msg() << "\n";); IF_VERBOSE(0, verbose_stream() << "exception in tactic " << ex.msg() << "\n";);
m_preprocess = 0;
m_bb_rewriter = 0;
return l_undef; return l_undef;
} }
if (m_subgoals.size() != 1) { if (m_subgoals.size() != 1) {
IF_VERBOSE(0, verbose_stream() << "size of subgoals is not 1, it is: " << m_subgoals.size() << "\n";); IF_VERBOSE(0, verbose_stream() << "size of subgoals is not 1, it is: " << m_subgoals.size() << "\n";);
return l_undef; return l_undef;
} }
CTRACE("sat", m_mc.get(), m_mc->display(tout); );
g = m_subgoals[0]; g = m_subgoals[0];
TRACE("sat", g->display_with_dependencies(tout);); TRACE("sat", g->display_with_dependencies(tout););
m_goal2sat(*g, m_params, m_solver, m_map, dep2asm, true); m_goal2sat(*g, m_params, m_solver, m_map, dep2asm, true);
@ -416,24 +428,25 @@ private:
} }
} }
m_model = md; m_model = md;
if (m_mc || !m_bb_rewriter.const2bits().empty()) {
model_converter_ref mc = m_mc; if (!m_bb_rewriter->const2bits().empty()) {
if (!m_bb_rewriter.const2bits().empty()) { m_mc0 = concat(m_mc0.get(), mk_bit_blaster_model_converter(m, m_bb_rewriter->const2bits()));
mc = concat(mc.get(), mk_bit_blaster_model_converter(m, m_bb_rewriter.const2bits())); }
} if (m_mc0) {
(*mc)(m_model); (*m_mc0)(m_model);
} }
SASSERT(m_model); SASSERT(m_model);
DEBUG_CODE( DEBUG_CODE(
for (unsigned i = 0; i < m_fmls.size(); ++i) { for (unsigned i = 0; i < m_fmls.size(); ++i) {
expr_ref tmp(m); expr_ref tmp(m);
VERIFY(m_model->eval(m_fmls[i].get(), tmp, true)); if (m_model->eval(m_fmls[i].get(), tmp, true)) {
CTRACE("sat", !m.is_true(tmp), CTRACE("sat", !m.is_true(tmp),
tout << "Evaluation failed: " << mk_pp(m_fmls[i].get(), m) tout << "Evaluation failed: " << mk_pp(m_fmls[i].get(), m)
<< " to " << tmp << "\n"; << " to " << tmp << "\n";
model_smt2_pp(tout, m, *(m_model.get()), 0);); model_smt2_pp(tout, m, *(m_model.get()), 0););
SASSERT(m.is_true(tmp)); SASSERT(m.is_true(tmp));
}
}); });
} }
}; };

View file

@ -99,7 +99,7 @@ public:
m_ctx(0), m_ctx(0),
m_callback(0) { m_callback(0) {
updt_params_core(p); updt_params_core(p);
TRACE("smt_tactic", tout << this << "\np: " << p << "\n";); TRACE("smt_tactic", tout << "p: " << p << "\n";);
} }
virtual tactic * translate(ast_manager & m) { virtual tactic * translate(ast_manager & m) {
@ -120,13 +120,12 @@ public:
} }
virtual void updt_params(params_ref const & p) { virtual void updt_params(params_ref const & p) {
TRACE("smt_tactic", tout << this << "\nupdt_params: " << p << "\n";); TRACE("smt_tactic", tout << "updt_params: " << p << "\n";);
updt_params_core(p); updt_params_core(p);
fparams().updt_params(p); fparams().updt_params(p);
symbol logic = p.get_sym(symbol("logic"), symbol::null); m_logic = p.get_sym(symbol("logic"), m_logic);
if (logic != symbol::null) { if (m_logic != symbol::null && m_ctx) {
if (m_ctx) m_ctx->set_logic(logic); m_ctx->set_logic(m_logic);
m_logic = logic;
} }
SASSERT(p.get_bool("auto_config", fparams().m_auto_config) == fparams().m_auto_config); SASSERT(p.get_bool("auto_config", fparams().m_auto_config) == fparams().m_auto_config);
} }

View file

@ -95,10 +95,9 @@ namespace smt {
enode * first_arg_enode = ctx.get_enode(first_arg); enode * first_arg_enode = ctx.get_enode(first_arg);
get_var(first_arg_enode); get_var(first_arg_enode);
// numerals are not blasted into bit2bool, so we do this directly. // numerals are not blasted into bit2bool, so we do this directly.
if (!ctx.b_internalized(n)) { rational val;
rational val; unsigned sz;
unsigned sz; if (!ctx.b_internalized(n) && m_util.is_numeral(first_arg, val, sz)) {
VERIFY(m_util.is_numeral(first_arg, val, sz));
theory_var v = first_arg_enode->get_th_var(get_id()); theory_var v = first_arg_enode->get_th_var(get_id());
app* owner = first_arg_enode->get_owner(); app* owner = first_arg_enode->get_owner();
for (unsigned i = 0; i < sz; ++i) { for (unsigned i = 0; i < sz; ++i) {
@ -113,29 +112,28 @@ namespace smt {
} }
} }
} }
else {
enode * arg = ctx.get_enode(first_arg); enode * arg = ctx.get_enode(first_arg);
// The argument was already internalized, but it may not have a theory variable associated with it. // The argument was already internalized, but it may not have a theory variable associated with it.
// For example, for ite-terms the method apply_sort_cnstr is not invoked. // For example, for ite-terms the method apply_sort_cnstr is not invoked.
// See comment in the then-branch. // See comment in the then-branch.
theory_var v_arg = arg->get_th_var(get_id()); theory_var v_arg = arg->get_th_var(get_id());
if (v_arg == null_theory_var) { if (v_arg == null_theory_var) {
// The method get_var will create a theory variable for arg. // The method get_var will create a theory variable for arg.
// As a side-effect the bits for arg will also be created. // As a side-effect the bits for arg will also be created.
get_var(arg); get_var(arg);
SASSERT(ctx.b_internalized(n)); SASSERT(ctx.b_internalized(n));
} }
else { else if (!ctx.b_internalized(n)) {
SASSERT(v_arg != null_theory_var); SASSERT(v_arg != null_theory_var);
bool_var bv = ctx.mk_bool_var(n); bool_var bv = ctx.mk_bool_var(n);
ctx.set_var_theory(bv, get_id()); ctx.set_var_theory(bv, get_id());
bit_atom * a = new (get_region()) bit_atom(); bit_atom * a = new (get_region()) bit_atom();
insert_bv2a(bv, a); insert_bv2a(bv, a);
m_trail_stack.push(mk_atom_trail(bv)); m_trail_stack.push(mk_atom_trail(bv));
unsigned idx = n->get_decl()->get_parameter(0).get_int(); unsigned idx = n->get_decl()->get_parameter(0).get_int();
SASSERT(a->m_occs == 0); SASSERT(a->m_occs == 0);
a->m_occs = new (get_region()) var_pos_occ(v_arg, idx); a->m_occs = new (get_region()) var_pos_occ(v_arg, idx);
}
} }
} }

View file

@ -128,8 +128,8 @@ lbool tactic2solver::check_sat_core(unsigned num_assumptions, expr * const * ass
ast_manager & m = m_assertions.m(); ast_manager & m = m_assertions.m();
m_result = alloc(simple_check_sat_result, m); m_result = alloc(simple_check_sat_result, m);
m_tactic->cleanup(); m_tactic->cleanup();
m_tactic->updt_params(m_params);
m_tactic->set_logic(m_logic); m_tactic->set_logic(m_logic);
m_tactic->updt_params(m_params); // parameters are allowed to overwrite logic.
goal_ref g = alloc(goal, m, m_produce_proofs, m_produce_models, m_produce_unsat_cores); goal_ref g = alloc(goal, m, m_produce_proofs, m_produce_models, m_produce_unsat_cores);
unsigned sz = m_assertions.size(); unsigned sz = m_assertions.size();

View file

@ -272,8 +272,9 @@ class lia2pb_tactic : public tactic {
} }
TRACE("lia2pb", tout << mk_ismt2_pp(x, m) << " -> " << dep << "\n";); TRACE("lia2pb", tout << mk_ismt2_pp(x, m) << " -> " << dep << "\n";);
subst.insert(x, def, 0, dep); subst.insert(x, def, 0, dep);
if (m_produce_models) if (m_produce_models) {
mc1->insert(to_app(x)->get_decl(), def); mc1->insert(to_app(x)->get_decl(), def);
}
} }
} }

View file

@ -25,25 +25,6 @@ Notes:
extension_model_converter::~extension_model_converter() { extension_model_converter::~extension_model_converter() {
} }
struct extension_model_converter::set_eval {
extension_model_converter * m_owner;
model_evaluator * m_old;
set_eval(extension_model_converter * owner, model_evaluator * ev) {
m_owner = owner;
m_old = owner->m_eval;
#pragma omp critical (extension_model_converter)
{
owner->m_eval = ev;
}
}
~set_eval() {
#pragma omp critical (extension_model_converter)
{
m_owner->m_eval = m_old;
}
}
};
static void display_decls_info(std::ostream & out, model_ref & md) { static void display_decls_info(std::ostream & out, model_ref & md) {
ast_manager & m = md->get_manager(); ast_manager & m = md->get_manager();
@ -68,36 +49,38 @@ void extension_model_converter::operator()(model_ref & md, unsigned goal_idx) {
model_evaluator ev(*(md.get())); model_evaluator ev(*(md.get()));
ev.set_model_completion(true); ev.set_model_completion(true);
expr_ref val(m()); expr_ref val(m());
{ unsigned i = m_vars.size();
set_eval setter(this, &ev); while (i > 0) {
unsigned i = m_vars.size(); --i;
while (i > 0) { expr * def = m_defs.get(i);
--i; ev(def, val);
expr * def = m_defs.get(i); TRACE("extension_mc", tout << m_vars.get(i)->get_name() << " ->\n" << mk_ismt2_pp(def, m()) << "\n==>\n" << mk_ismt2_pp(val, m()) << "\n";);
ev(def, val); func_decl * f = m_vars.get(i);
TRACE("extension_mc", tout << m_vars.get(i)->get_name() << " ->\n" << mk_ismt2_pp(def, m()) << "\n==>\n" << mk_ismt2_pp(val, m()) << "\n";); unsigned arity = f->get_arity();
func_decl * f = m_vars.get(i); if (arity == 0) {
unsigned arity = f->get_arity(); md->register_decl(f, val);
if (arity == 0) { }
md->register_decl(f, val); else {
} func_interp * new_fi = alloc(func_interp, m(), arity);
else { new_fi->set_else(val);
func_interp * new_fi = alloc(func_interp, m(), arity); md->register_decl(f, new_fi);
new_fi->set_else(val);
md->register_decl(f, new_fi);
}
} }
} }
TRACE("extension_mc", model_v2_pp(tout, *md); display_decls_info(tout, md);); TRACE("extension_mc", model_v2_pp(tout, *md); display_decls_info(tout, md););
} }
void extension_model_converter::insert(func_decl * v, expr * def) {
m_vars.push_back(v);
m_defs.push_back(def);
}
void extension_model_converter::display(std::ostream & out) { void extension_model_converter::display(std::ostream & out) {
ast_manager & m = m_vars.get_manager();
out << "(extension-model-converter"; out << "(extension-model-converter";
for (unsigned i = 0; i < m_vars.size(); i++) { for (unsigned i = 0; i < m_vars.size(); i++) {
out << "\n (" << m_vars.get(i)->get_name() << " "; out << "\n (" << m_vars.get(i)->get_name() << " ";
unsigned indent = m_vars.get(i)->get_name().size() + 4; unsigned indent = m_vars.get(i)->get_name().size() + 4;
out << mk_ismt2_pp(m_defs.get(i), m, indent) << ")"; out << mk_ismt2_pp(m_defs.get(i), m(), indent) << ")";
} }
out << ")" << std::endl; out << ")" << std::endl;
} }
@ -108,6 +91,5 @@ model_converter * extension_model_converter::translate(ast_translation & transla
res->m_vars.push_back(translator(m_vars[i].get())); res->m_vars.push_back(translator(m_vars[i].get()));
for (unsigned i = 0; i < m_defs.size(); i++) for (unsigned i = 0; i < m_defs.size(); i++)
res->m_defs.push_back(translator(m_defs[i].get())); res->m_defs.push_back(translator(m_defs[i].get()));
// m_eval is a transient object. So, it doesn't need to be translated.
return res; return res;
} }

View file

@ -23,15 +23,12 @@ Notes:
#include"ast.h" #include"ast.h"
#include"model_converter.h" #include"model_converter.h"
class model_evaluator;
class extension_model_converter : public model_converter { class extension_model_converter : public model_converter {
func_decl_ref_vector m_vars; func_decl_ref_vector m_vars;
expr_ref_vector m_defs; expr_ref_vector m_defs;
model_evaluator * m_eval;
struct set_eval;
public: public:
extension_model_converter(ast_manager & m):m_vars(m), m_defs(m), m_eval(0) { extension_model_converter(ast_manager & m):m_vars(m), m_defs(m) {
} }
virtual ~extension_model_converter(); virtual ~extension_model_converter();
@ -43,10 +40,7 @@ public:
virtual void display(std::ostream & out); virtual void display(std::ostream & out);
// register a variable that was eliminated // register a variable that was eliminated
void insert(func_decl * v, expr * def) { void insert(func_decl * v, expr * def);
m_vars.push_back(v);
m_defs.push_back(def);
}
virtual model_converter * translate(ast_translation & translator); virtual model_converter * translate(ast_translation & translator);
}; };

View file

@ -26,13 +26,19 @@ void tst_model_evaluator() {
expr_ref vB0(m.mk_var(0, m.mk_bool_sort()), m); expr_ref vB0(m.mk_var(0, m.mk_bool_sort()), m);
expr_ref vB1(m.mk_var(1, m.mk_bool_sort()), m); expr_ref vB1(m.mk_var(1, m.mk_bool_sort()), m);
expr_ref vB2(m.mk_var(2, m.mk_bool_sort()), m); expr_ref vB2(m.mk_var(2, m.mk_bool_sort()), m);
expr_ref f01(m.mk_app(f, vI0, vB1), m); expr* vI0p = vI0.get();
expr_ref g01(m.mk_app(g, vI0, vB1), m); expr* vI1p = vI1.get();
expr_ref h01(m.mk_app(h, vI0, vB1), m); expr* vB0p = vB0.get();
expr* vB1p = vB1.get();
expr* vB2p = vB2.get();
expr_ref f01(m.mk_app(f, vI0p, vB1p), m);
expr_ref g01(m.mk_app(g, vI0p, vB1p), m);
expr_ref h01(m.mk_app(h, vI0p, vB1p), m);
func_interp* fi = alloc(func_interp, m, 2); func_interp* fi = alloc(func_interp, m, 2);
func_interp* gi = alloc(func_interp, m, 2); func_interp* gi = alloc(func_interp, m, 2);
func_interp* hi = alloc(func_interp, m, 2); func_interp* hi = alloc(func_interp, m, 2);
hi->set_else(m.mk_ite(vB1, m.mk_app(f, vI0, vB1), m.mk_app(g, vI0, vB1))); hi->set_else(m.mk_ite(vB1p, m.mk_app(f, vI0p, vB1p), m.mk_app(g, vI0p, vB1p)));
mdl.register_decl(h, hi); mdl.register_decl(h, hi);
@ -42,23 +48,23 @@ void tst_model_evaluator() {
{ {
symbol nI("N"); symbol nI("N");
fi->set_else(m.mk_ite(m.mk_exists(1, &sI, &nI, a.mk_le(vI0, m.mk_app(F, vI1, vB2))), vI0, a.mk_int(1))); fi->set_else(m.mk_ite(m.mk_exists(1, &sI, &nI, a.mk_le(vI0p, m.mk_app(F, vI1p, vB2p))), vI0p, a.mk_int(1)));
gi->set_else(m.mk_ite(m.mk_exists(1, &sI, &nI, a.mk_le(vI0, m.mk_app(G, vI1, vB2))), a.mk_int(2), vI0)); gi->set_else(m.mk_ite(m.mk_exists(1, &sI, &nI, a.mk_le(vI0p, m.mk_app(G, vI1p, vB2p))), a.mk_int(2), vI0p));
mdl.register_decl(g, gi); mdl.register_decl(g, gi);
mdl.register_decl(f, fi); mdl.register_decl(f, fi);
model_pp(std::cout, mdl); model_pp(std::cout, mdl);
e = m.mk_app(h, vI0, vB1); e = m.mk_app(h, vI0p, vB1p);
eval(e, v); eval(e, v);
std::cout << e << " " << v << "\n"; std::cout << e << " " << v << "\n";
} }
{ {
fi->set_else(m.mk_app(F, vI0, vB1)); fi->set_else(m.mk_app(F, vI0p, vB1p));
gi->set_else(m.mk_app(G, vI0, vB1)); gi->set_else(m.mk_app(G, vI0p, vB1p));
mdl.register_decl(g, gi); mdl.register_decl(g, gi);
mdl.register_decl(h, hi); mdl.register_decl(h, hi);
model_pp(std::cout, mdl); model_pp(std::cout, mdl);
e = m.mk_app(h, vI0, vB1); e = m.mk_app(h, vI0p, vB1p);
eval(e, v); eval(e, v);
std::cout << e << " " << v << "\n"; std::cout << e << " " << v << "\n";
} }

View file

@ -226,7 +226,7 @@ size_t mpn_manager::div_normalize(mpn_digit const * numer, size_t const lnum,
mpn_sbuffer & n_denom) const mpn_sbuffer & n_denom) const
{ {
size_t d = 0; size_t d = 0;
while (((denom[lden-1] << d) & MASK_FIRST) == 0) d++; while (lden > 0 && ((denom[lden-1] << d) & MASK_FIRST) == 0) d++;
SASSERT(d < DIGIT_BITS); SASSERT(d < DIGIT_BITS);
n_numer.resize(lnum+1); n_numer.resize(lnum+1);
@ -239,7 +239,8 @@ size_t mpn_manager::div_normalize(mpn_digit const * numer, size_t const lnum,
for (size_t i = 0; i < lden; i++) for (size_t i = 0; i < lden; i++)
n_denom[i] = denom[i]; n_denom[i] = denom[i];
} }
else { else if (lnum != 0) {
SASSERT(lden > 0);
mpn_digit q = FIRST_BITS(d, numer[lnum-1]); mpn_digit q = FIRST_BITS(d, numer[lnum-1]);
n_numer[lnum] = q; n_numer[lnum] = q;
for (size_t i = lnum-1; i > 0; i--) for (size_t i = lnum-1; i > 0; i--)
@ -249,6 +250,9 @@ size_t mpn_manager::div_normalize(mpn_digit const * numer, size_t const lnum,
n_denom[i] = denom[i] << d | FIRST_BITS(d, denom[i-1]); n_denom[i] = denom[i] << d | FIRST_BITS(d, denom[i-1]);
n_denom[0] = denom[0] << d; n_denom[0] = denom[0] << d;
} }
else {
d = 0;
}
TRACE("mpn_norm", tout << "Normalized: n_numer="; display_raw(tout, n_numer.c_ptr(), n_numer.size()); TRACE("mpn_norm", tout << "Normalized: n_numer="; display_raw(tout, n_numer.c_ptr(), n_numer.size());
tout << " n_denom="; display_raw(tout, n_denom.c_ptr(), n_denom.size()); tout << std::endl; ); tout << " n_denom="; display_raw(tout, n_denom.c_ptr(), n_denom.size()); tout << std::endl; );