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:
commit
cfda8e9e03
25 changed files with 313 additions and 228 deletions
|
@ -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:
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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];
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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]; }
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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; );
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue