mirror of
https://github.com/Z3Prover/z3
synced 2025-04-07 18:05:21 +00:00
Merge branch 'master' of https://github.com/Z3Prover/z3 into jfleisher/devIntellitest
This commit is contained in:
commit
4d1362b6a3
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -91,4 +91,5 @@ examples/**/obj
|
|||
CMakeSettings.json
|
||||
# Editor temp files
|
||||
*.swp
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
dbg/**
|
||||
|
|
|
@ -1178,7 +1178,7 @@ extern "C" {
|
|||
case OP_BSMOD: return Z3_OP_BSMOD;
|
||||
case OP_BSDIV0: return Z3_OP_BSDIV0;
|
||||
case OP_BUDIV0: return Z3_OP_BUDIV0;
|
||||
case OP_BSREM0: return Z3_OP_BUREM0;
|
||||
case OP_BSREM0: return Z3_OP_BSREM0;
|
||||
case OP_BUREM0: return Z3_OP_BUREM0;
|
||||
case OP_BSMOD0: return Z3_OP_BSMOD0;
|
||||
case OP_ULEQ: return Z3_OP_ULEQ;
|
||||
|
|
|
@ -326,7 +326,9 @@ func_decl * array_decl_plugin::mk_array_ext(unsigned arity, sort * const * domai
|
|||
}
|
||||
sort * r = to_sort(s->get_parameter(i).get_ast());
|
||||
parameter param(i);
|
||||
return m_manager->mk_func_decl(m_array_ext_sym, arity, domain, r, func_decl_info(m_family_id, OP_ARRAY_EXT, 1, ¶m));
|
||||
func_decl_info info(func_decl_info(m_family_id, OP_ARRAY_EXT, 1, ¶m));
|
||||
info.set_commutative(true);
|
||||
return m_manager->mk_func_decl(m_array_ext_sym, arity, domain, r, info);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ bool decl_collector::is_bool(sort * s) {
|
|||
}
|
||||
|
||||
void decl_collector::visit_func(func_decl * n) {
|
||||
func_decl* g;
|
||||
if (!m_visited.is_marked(n)) {
|
||||
family_id fid = n->get_family_id();
|
||||
if (fid == null_family_id)
|
||||
|
@ -57,6 +58,8 @@ void decl_collector::visit_func(func_decl * n) {
|
|||
recfun::util u(m());
|
||||
m_todo.push_back(u.get_def(n).get_rhs());
|
||||
}
|
||||
else if (m_ar_util.is_as_array(n, g))
|
||||
m_todo.push_back(g);
|
||||
m_visited.mark(n, true);
|
||||
m_trail.push_back(n);
|
||||
}
|
||||
|
@ -65,7 +68,8 @@ void decl_collector::visit_func(func_decl * n) {
|
|||
decl_collector::decl_collector(ast_manager & m):
|
||||
m_manager(m),
|
||||
m_trail(m),
|
||||
m_dt_util(m) {
|
||||
m_dt_util(m),
|
||||
m_ar_util(m) {
|
||||
m_basic_fid = m_manager.get_basic_family_id();
|
||||
m_dt_fid = m_dt_util.get_family_id();
|
||||
recfun::util rec_util(m);
|
||||
|
@ -156,8 +160,15 @@ void decl_collector::collect_deps(sort* s, sort_set& set) {
|
|||
for (unsigned i = 0; i < num_cnstr; i++) {
|
||||
func_decl * cnstr = m_dt_util.get_datatype_constructors(s)->get(i);
|
||||
set.insert(cnstr->get_range());
|
||||
for (unsigned j = 0; j < cnstr->get_arity(); ++j)
|
||||
set.insert(cnstr->get_domain(j));
|
||||
for (unsigned j = 0; j < cnstr->get_arity(); ++j) {
|
||||
sort* n = cnstr->get_domain(j);
|
||||
set.insert(n);
|
||||
for (unsigned i = n->get_num_parameters(); i-- > 0; ) {
|
||||
parameter const& p = n->get_parameter(i);
|
||||
if (p.is_ast() && is_sort(p.get_ast()))
|
||||
set.insert(to_sort(p.get_ast()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ Revision History:
|
|||
#include "util/lim_vector.h"
|
||||
#include "ast/ast.h"
|
||||
#include "ast/datatype_decl_plugin.h"
|
||||
#include "ast/array_decl_plugin.h"
|
||||
|
||||
class decl_collector {
|
||||
ast_manager & m_manager;
|
||||
|
@ -35,6 +36,7 @@ class decl_collector {
|
|||
family_id m_basic_fid;
|
||||
family_id m_dt_fid;
|
||||
datatype_util m_dt_util;
|
||||
array_util m_ar_util;
|
||||
family_id m_rec_fid;
|
||||
ptr_vector<ast> m_todo;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -30,7 +30,9 @@ namespace opt {
|
|||
t_eq,
|
||||
t_lt,
|
||||
t_le,
|
||||
t_mod
|
||||
t_divides,
|
||||
t_mod,
|
||||
t_div
|
||||
};
|
||||
|
||||
|
||||
|
@ -48,6 +50,14 @@ namespace opt {
|
|||
return x.m_id < y.m_id;
|
||||
}
|
||||
};
|
||||
|
||||
bool operator==(var const& other) const {
|
||||
return m_id == other.m_id && m_coeff == other.m_coeff;
|
||||
}
|
||||
|
||||
bool operator!=(var const& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
struct row {
|
||||
row(): m_type(t_le), m_value(0), m_alive(false) {}
|
||||
|
@ -57,6 +67,7 @@ namespace opt {
|
|||
ineq_type m_type; // inequality type
|
||||
rational m_value; // value of m_vars + m_coeff under interpretation of m_var2value.
|
||||
bool m_alive; // rows can be marked dead if they have been processed.
|
||||
unsigned m_id; // variable defined by row (used for mod_t and div_t)
|
||||
void reset() { m_vars.reset(); m_coeff.reset(); m_value.reset(); }
|
||||
|
||||
row& normalize();
|
||||
|
@ -85,9 +96,9 @@ namespace opt {
|
|||
static const unsigned m_objective_id = 0;
|
||||
vector<unsigned_vector> m_var2row_ids;
|
||||
vector<rational> m_var2value;
|
||||
bool_vector m_var2is_int;
|
||||
bool_vector m_var2is_int;
|
||||
vector<var> m_new_vars;
|
||||
unsigned_vector m_lub, m_glb, m_mod;
|
||||
unsigned_vector m_lub, m_glb, m_divides, m_mod, m_div;
|
||||
unsigned_vector m_above, m_below;
|
||||
unsigned_vector m_retired_rows;
|
||||
|
||||
|
@ -114,7 +125,7 @@ namespace opt {
|
|||
|
||||
void mul_add(bool same_sign, unsigned row_id1, rational const& c, unsigned row_id2);
|
||||
|
||||
void mul_add(unsigned x, rational const& a1, unsigned row_src, rational const& a2, unsigned row_dst);
|
||||
void mul_add(unsigned x, rational a1, unsigned row_src, rational a2, unsigned row_dst);
|
||||
|
||||
void mul(unsigned dst, rational const& c);
|
||||
|
||||
|
@ -122,14 +133,18 @@ namespace opt {
|
|||
|
||||
void sub(unsigned dst, rational const& c);
|
||||
|
||||
void del_var(unsigned dst, unsigned x);
|
||||
void set_row(unsigned row_id, vector<var> const& coeffs, rational const& c, rational const& m, ineq_type rel);
|
||||
|
||||
void set_row(unsigned row_id, vector<var> const& coeffs, rational const& c, rational const& m, ineq_type rel);
|
||||
void add_lower_bound(unsigned x, rational const& lo);
|
||||
|
||||
void add_constraint(vector<var> const& coeffs, rational const& c, rational const& m, ineq_type r);
|
||||
void add_upper_bound(unsigned x, rational const& hi);
|
||||
|
||||
void add_constraint(vector<var> const& coeffs, rational const& c, rational const& m, ineq_type r, unsigned id);
|
||||
|
||||
void replace_var(unsigned row_id, unsigned x, rational const& A, unsigned y, rational const& B);
|
||||
|
||||
void replace_var(unsigned row_id, unsigned x, rational const& A, unsigned y, rational const& B, unsigned z);
|
||||
|
||||
void replace_var(unsigned row_id, unsigned x, rational const& C);
|
||||
|
||||
void normalize(unsigned row_id);
|
||||
|
@ -138,7 +153,7 @@ namespace opt {
|
|||
|
||||
unsigned new_row();
|
||||
|
||||
unsigned copy_row(unsigned row_id);
|
||||
unsigned copy_row(unsigned row_id, unsigned excl = UINT_MAX);
|
||||
|
||||
rational n_sign(rational const& b) const;
|
||||
|
||||
|
@ -150,8 +165,12 @@ namespace opt {
|
|||
|
||||
def solve_for(unsigned row_id, unsigned x, bool compute_def);
|
||||
|
||||
def solve_mod(unsigned x, unsigned_vector const& mod_rows, bool compute_def);
|
||||
|
||||
def solve_divides(unsigned x, unsigned_vector const& divide_rows, bool compute_def);
|
||||
|
||||
def solve_mod(unsigned x, unsigned_vector const& divide_rows, bool compute_def);
|
||||
|
||||
def solve_div(unsigned x, unsigned_vector const& divide_rows, bool compute_def);
|
||||
|
||||
bool is_int(unsigned x) const { return m_var2is_int[x]; }
|
||||
|
||||
void retire_row(unsigned row_id);
|
||||
|
@ -173,6 +192,17 @@ namespace opt {
|
|||
// add a divisibility constraint. The row should divide m.
|
||||
void add_divides(vector<var> const& coeffs, rational const& c, rational const& m);
|
||||
|
||||
|
||||
// add sub-expression for modulus
|
||||
// v = add_mod(coeffs, m) means
|
||||
// v = coeffs mod m
|
||||
unsigned add_mod(vector<var> const& coeffs, rational const& c, rational const& m);
|
||||
|
||||
// add sub-expression for div
|
||||
// v = add_div(coeffs, m) means
|
||||
// v = coeffs div m
|
||||
unsigned add_div(vector<var> const& coeffs, rational const& c, rational const& m);
|
||||
|
||||
// Set the objective function (linear).
|
||||
void set_objective(vector<var> const& coeffs, rational const& c);
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ Revision History:
|
|||
#include "ast/ast_util.h"
|
||||
#include "ast/arith_decl_plugin.h"
|
||||
#include "ast/ast_pp.h"
|
||||
#include "ast/rewriter/th_rewriter.h"
|
||||
#include "ast/expr_functors.h"
|
||||
#include "ast/rewriter/expr_safe_replace.h"
|
||||
#include "math/simplex/model_based_opt.h"
|
||||
|
@ -32,13 +31,13 @@ Revision History:
|
|||
#include "model/model_v2_pp.h"
|
||||
|
||||
namespace mbp {
|
||||
|
||||
|
||||
struct arith_project_plugin::imp {
|
||||
|
||||
ast_manager& m;
|
||||
ast_manager& m;
|
||||
arith_util a;
|
||||
bool m_check_purified { true }; // check that variables are properly pure
|
||||
bool m_apply_projection { false };
|
||||
bool m_check_purified = true; // check that variables are properly pure
|
||||
bool m_apply_projection = false;
|
||||
|
||||
|
||||
imp(ast_manager& m) :
|
||||
|
@ -48,10 +47,10 @@ namespace mbp {
|
|||
|
||||
void insert_mul(expr* x, rational const& v, obj_map<expr, rational>& ts) {
|
||||
rational w;
|
||||
if (ts.find(x, w))
|
||||
ts.insert(x, w + v);
|
||||
else
|
||||
ts.insert(x, v);
|
||||
if (ts.find(x, w))
|
||||
ts.insert(x, w + v);
|
||||
else
|
||||
ts.insert(x, v);
|
||||
}
|
||||
|
||||
|
||||
|
@ -65,15 +64,15 @@ namespace mbp {
|
|||
rational c(0), mul(1);
|
||||
expr_ref t(m);
|
||||
opt::ineq_type ty = opt::t_le;
|
||||
expr* e1, *e2;
|
||||
DEBUG_CODE(expr_ref val(m);
|
||||
eval(lit, val);
|
||||
CTRACE("qe", !m.is_true(val), tout << mk_pp(lit, m) << " := " << val << "\n";);
|
||||
SASSERT(m.limit().is_canceled() || !m.is_false(val)););
|
||||
expr* e1, * e2;
|
||||
DEBUG_CODE(expr_ref val(m);
|
||||
eval(lit, val);
|
||||
CTRACE("qe", !m.is_true(val), tout << mk_pp(lit, m) << " := " << val << "\n";);
|
||||
SASSERT(m.limit().is_canceled() || !m.is_false(val)););
|
||||
|
||||
if (!m.inc())
|
||||
if (!m.inc())
|
||||
return false;
|
||||
|
||||
|
||||
TRACE("opt", tout << mk_pp(lit, m) << " " << a.is_lt(lit) << " " << a.is_gt(lit) << "\n";);
|
||||
bool is_not = m.is_not(lit, lit);
|
||||
if (is_not) {
|
||||
|
@ -86,37 +85,35 @@ namespace mbp {
|
|||
ty = is_not ? opt::t_lt : opt::t_le;
|
||||
}
|
||||
else if ((a.is_lt(lit, e1, e2) || a.is_gt(lit, e2, e1))) {
|
||||
linearize(mbo, eval, mul, e1, c, fmls, ts, tids);
|
||||
linearize(mbo, eval, mul, e1, c, fmls, ts, tids);
|
||||
linearize(mbo, eval, -mul, e2, c, fmls, ts, tids);
|
||||
ty = is_not ? opt::t_le: opt::t_lt;
|
||||
ty = is_not ? opt::t_le : opt::t_lt;
|
||||
}
|
||||
else if (m.is_eq(lit, e1, e2) && !is_not && is_arith(e1)) {
|
||||
linearize(mbo, eval, mul, e1, c, fmls, ts, tids);
|
||||
linearize(mbo, eval, mul, e1, c, fmls, ts, tids);
|
||||
linearize(mbo, eval, -mul, e2, c, fmls, ts, tids);
|
||||
ty = opt::t_eq;
|
||||
}
|
||||
}
|
||||
else if (m.is_eq(lit, e1, e2) && is_not && is_arith(e1)) {
|
||||
|
||||
|
||||
rational r1, r2;
|
||||
expr_ref val1 = eval(e1);
|
||||
expr_ref val1 = eval(e1);
|
||||
expr_ref val2 = eval(e2);
|
||||
//TRACE("qe", tout << mk_pp(e1, m) << " " << val1 << "\n";);
|
||||
//TRACE("qe", tout << mk_pp(e2, m) << " " << val2 << "\n";);
|
||||
if (!a.is_numeral(val1, r1)) return false;
|
||||
if (!a.is_numeral(val2, r2)) return false;
|
||||
SASSERT(r1 != r2);
|
||||
if (r1 < r2) {
|
||||
std::swap(e1, e2);
|
||||
}
|
||||
}
|
||||
ty = opt::t_lt;
|
||||
linearize(mbo, eval, mul, e1, c, fmls, ts, tids);
|
||||
linearize(mbo, eval, -mul, e2, c, fmls, ts, tids);
|
||||
}
|
||||
linearize(mbo, eval, mul, e1, c, fmls, ts, tids);
|
||||
linearize(mbo, eval, -mul, e2, c, fmls, ts, tids);
|
||||
}
|
||||
else if (m.is_distinct(lit) && !is_not && is_arith(to_app(lit)->get_arg(0))) {
|
||||
expr_ref val(m);
|
||||
rational r;
|
||||
app* alit = to_app(lit);
|
||||
vector<std::pair<expr*,rational> > nums;
|
||||
vector<std::pair<expr*, rational> > nums;
|
||||
for (expr* arg : *alit) {
|
||||
val = eval(arg);
|
||||
TRACE("qe", tout << mk_pp(arg, m) << " " << val << "\n";);
|
||||
|
@ -125,8 +122,8 @@ namespace mbp {
|
|||
}
|
||||
std::sort(nums.begin(), nums.end(), compare_second());
|
||||
for (unsigned i = 0; i + 1 < nums.size(); ++i) {
|
||||
SASSERT(nums[i].second < nums[i+1].second);
|
||||
expr_ref fml(a.mk_lt(nums[i].first, nums[i+1].first), m);
|
||||
SASSERT(nums[i].second < nums[i + 1].second);
|
||||
expr_ref fml(a.mk_lt(nums[i].first, nums[i + 1].first), m);
|
||||
if (!linearize(mbo, eval, fml, fmls, tids)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -139,14 +136,14 @@ namespace mbp {
|
|||
map<rational, expr*, rational::hash_proc, rational::eq_proc> values;
|
||||
bool found_eq = false;
|
||||
for (unsigned i = 0; !found_eq && i < to_app(lit)->get_num_args(); ++i) {
|
||||
expr* arg1 = to_app(lit)->get_arg(i), *arg2 = nullptr;
|
||||
expr* arg1 = to_app(lit)->get_arg(i), * arg2 = nullptr;
|
||||
rational r;
|
||||
expr_ref val = eval(arg1);
|
||||
TRACE("qe", tout << mk_pp(arg1, m) << " " << val << "\n";);
|
||||
if (!a.is_numeral(val, r)) return false;
|
||||
if (values.find(r, arg2)) {
|
||||
ty = opt::t_eq;
|
||||
linearize(mbo, eval, mul, arg1, c, fmls, ts, tids);
|
||||
linearize(mbo, eval, mul, arg1, c, fmls, ts, tids);
|
||||
linearize(mbo, eval, -mul, arg2, c, fmls, ts, tids);
|
||||
found_eq = true;
|
||||
}
|
||||
|
@ -169,27 +166,37 @@ namespace mbp {
|
|||
//
|
||||
// convert linear arithmetic term into an inequality for mbo.
|
||||
//
|
||||
void linearize(opt::model_based_opt& mbo, model_evaluator& eval, rational const& mul, expr* t, rational& c,
|
||||
expr_ref_vector& fmls, obj_map<expr, rational>& ts, obj_map<expr, unsigned>& tids) {
|
||||
expr* t1, *t2, *t3;
|
||||
void linearize(opt::model_based_opt& mbo, model_evaluator& eval, rational const& mul, expr* t, rational& c,
|
||||
expr_ref_vector& fmls, obj_map<expr, rational>& ts, obj_map<expr, unsigned>& tids) {
|
||||
expr* t1, * t2, * t3;
|
||||
rational mul1;
|
||||
expr_ref val(m);
|
||||
if (a.is_mul(t, t1, t2) && is_numeral(t1, mul1))
|
||||
linearize(mbo, eval, mul* mul1, t2, c, fmls, ts, tids);
|
||||
else if (a.is_mul(t, t1, t2) && is_numeral(t2, mul1))
|
||||
linearize(mbo, eval, mul* mul1, t1, c, fmls, ts, tids);
|
||||
|
||||
auto add_def = [&](expr* t1, rational const& m, vars& coeffs) {
|
||||
obj_map<expr, rational> ts0;
|
||||
rational mul0(1), c0(0);
|
||||
linearize(mbo, eval, mul0, t1, c0, fmls, ts0, tids);
|
||||
extract_coefficients(mbo, eval, ts0, tids, coeffs);
|
||||
insert_mul(t, mul, ts);
|
||||
return c0;
|
||||
};
|
||||
|
||||
if (a.is_mul(t, t1, t2) && is_numeral(t1, mul1))
|
||||
linearize(mbo, eval, mul * mul1, t2, c, fmls, ts, tids);
|
||||
else if (a.is_mul(t, t1, t2) && is_numeral(t2, mul1))
|
||||
linearize(mbo, eval, mul * mul1, t1, c, fmls, ts, tids);
|
||||
else if (a.is_uminus(t, t1))
|
||||
linearize(mbo, eval, -mul, t1, c, fmls, ts, tids);
|
||||
else if (a.is_numeral(t, mul1))
|
||||
c += mul * mul1;
|
||||
else if (a.is_numeral(t, mul1))
|
||||
c += mul * mul1;
|
||||
else if (a.is_add(t)) {
|
||||
for (expr* arg : *to_app(t))
|
||||
linearize(mbo, eval, mul, arg, c, fmls, ts, tids);
|
||||
for (expr* arg : *to_app(t))
|
||||
linearize(mbo, eval, mul, arg, c, fmls, ts, tids);
|
||||
}
|
||||
else if (a.is_sub(t, t1, t2)) {
|
||||
linearize(mbo, eval, mul, t1, c, fmls, ts, tids);
|
||||
linearize(mbo, eval, mul, t1, c, fmls, ts, tids);
|
||||
linearize(mbo, eval, -mul, t2, c, fmls, ts, tids);
|
||||
}
|
||||
}
|
||||
|
||||
else if (m.is_ite(t, t1, t2, t3)) {
|
||||
val = eval(t1);
|
||||
|
@ -210,21 +217,31 @@ namespace mbp {
|
|||
else if (a.is_mod(t, t1, t2) && is_numeral(t2, mul1) && !mul1.is_zero()) {
|
||||
rational r;
|
||||
val = eval(t);
|
||||
if (!a.is_numeral(val, r)) {
|
||||
if (!a.is_numeral(val, r))
|
||||
throw default_exception("mbp evaluation didn't produce an integer");
|
||||
}
|
||||
c += mul*r;
|
||||
// t1 mod mul1 == r
|
||||
rational c0(-r), mul0(1);
|
||||
obj_map<expr, rational> ts0;
|
||||
linearize(mbo, eval, mul0, t1, c0, fmls, ts0, tids);
|
||||
c += mul * r;
|
||||
|
||||
rational c0(-r), mul0(1);
|
||||
obj_map<expr, rational> ts0;
|
||||
linearize(mbo, eval, mul0, t1, c0, fmls, ts0, tids);
|
||||
vars coeffs;
|
||||
extract_coefficients(mbo, eval, ts0, tids, coeffs);
|
||||
mbo.add_divides(coeffs, c0, mul1);
|
||||
}
|
||||
else if (false && a.is_mod(t, t1, t2) && is_numeral(t2, mul1) && mul1 > 0) {
|
||||
// v = t1 mod mul1
|
||||
vars coeffs;
|
||||
extract_coefficients(mbo, eval, ts0, tids, coeffs);
|
||||
mbo.add_divides(coeffs, c0, mul1);
|
||||
rational c0 = add_def(t1, mul1, coeffs);
|
||||
tids.insert(t, mbo.add_mod(coeffs, c0, mul1));
|
||||
}
|
||||
else {
|
||||
else if (false && a.is_idiv(t, t1, t2) && is_numeral(t2, mul1) && mul1 > 0) {
|
||||
// v = t1 div mul1
|
||||
vars coeffs;
|
||||
rational c0 = add_def(t1, mul1, coeffs);
|
||||
tids.insert(t, mbo.add_div(coeffs, c0, mul1));
|
||||
}
|
||||
else
|
||||
insert_mul(t, mul, ts);
|
||||
}
|
||||
}
|
||||
|
||||
bool is_numeral(expr* t, rational& r) {
|
||||
|
@ -232,8 +249,8 @@ namespace mbp {
|
|||
}
|
||||
|
||||
struct compare_second {
|
||||
bool operator()(std::pair<expr*, rational> const& a,
|
||||
std::pair<expr*, rational> const& b) const {
|
||||
bool operator()(std::pair<expr*, rational> const& a,
|
||||
std::pair<expr*, rational> const& b) const {
|
||||
return a.second < b.second;
|
||||
}
|
||||
};
|
||||
|
@ -243,14 +260,14 @@ namespace mbp {
|
|||
}
|
||||
|
||||
rational n_sign(rational const& b) {
|
||||
return rational(b.is_pos()?-1:1);
|
||||
return rational(b.is_pos() ? -1 : 1);
|
||||
}
|
||||
|
||||
bool operator()(model& model, app* v, app_ref_vector& vars, expr_ref_vector& lits) {
|
||||
app_ref_vector vs(m);
|
||||
vs.push_back(v);
|
||||
vector<def> defs;
|
||||
return project(model, vs, lits, defs, false) && vs.empty();
|
||||
return project(model, vs, lits, defs, false) && vs.empty();
|
||||
}
|
||||
|
||||
typedef opt::model_based_opt::var var;
|
||||
|
@ -267,10 +284,10 @@ namespace mbp {
|
|||
|
||||
bool project(model& model, app_ref_vector& vars, expr_ref_vector& fmls, vector<def>& result, bool compute_def) {
|
||||
bool has_arith = false;
|
||||
for (expr* v : vars)
|
||||
has_arith |= is_arith(v);
|
||||
if (!has_arith)
|
||||
return true;
|
||||
for (expr* v : vars)
|
||||
has_arith |= is_arith(v);
|
||||
if (!has_arith)
|
||||
return true;
|
||||
model_evaluator eval(model);
|
||||
TRACE("qe", tout << model;);
|
||||
eval.set_model_completion(true);
|
||||
|
@ -281,7 +298,7 @@ namespace mbp {
|
|||
expr_ref_vector pinned(m);
|
||||
unsigned j = 0;
|
||||
TRACE("qe", tout << "vars: " << vars << "\n";
|
||||
for (expr* f : fmls) tout << mk_pp(f, m) << " := " << model(f) << "\n";);
|
||||
for (expr* f : fmls) tout << mk_pp(f, m) << " := " << model(f) << "\n";);
|
||||
for (unsigned i = 0; i < fmls.size(); ++i) {
|
||||
expr* fml = fmls.get(i);
|
||||
if (!linearize(mbo, eval, fml, fmls, tids)) {
|
||||
|
@ -294,8 +311,8 @@ namespace mbp {
|
|||
}
|
||||
fmls.shrink(j);
|
||||
TRACE("qe", tout << "formulas\n" << fmls << "\n";
|
||||
for (auto const& [e, id] : tids)
|
||||
tout << mk_pp(e, m) << " -> " << id << "\n";);
|
||||
for (auto const& [e, id] : tids)
|
||||
tout << mk_pp(e, m) << " -> " << id << "\n";);
|
||||
|
||||
// fmls holds residue,
|
||||
// mbo holds linear inequalities that are in scope
|
||||
|
@ -306,7 +323,7 @@ namespace mbp {
|
|||
// return those to fmls.
|
||||
|
||||
expr_mark var_mark, fmls_mark;
|
||||
for (app * v : vars) {
|
||||
for (app* v : vars) {
|
||||
var_mark.mark(v);
|
||||
if (is_arith(v) && !tids.contains(v)) {
|
||||
rational r;
|
||||
|
@ -321,60 +338,70 @@ namespace mbp {
|
|||
}
|
||||
|
||||
// bail on variables in non-linear sub-terms
|
||||
auto is_pure = [&](expr* e) {
|
||||
expr* x, * y;
|
||||
rational r;
|
||||
if (a.is_mod(e, x, y) && a.is_numeral(y))
|
||||
return true;
|
||||
if (a.is_idiv(e, x, y) && a.is_numeral(y, r) && r > 0)
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
for (auto& kv : tids) {
|
||||
expr* e = kv.m_key;
|
||||
if (is_arith(e) && !var_mark.is_marked(e))
|
||||
mark_rec(fmls_mark, e);
|
||||
if (is_arith(e) && !is_pure(e) && !var_mark.is_marked(e))
|
||||
mark_rec(fmls_mark, e);
|
||||
}
|
||||
if (m_check_purified) {
|
||||
for (expr* fml : fmls)
|
||||
mark_rec(fmls_mark, fml);
|
||||
for (expr* fml : fmls)
|
||||
mark_rec(fmls_mark, fml);
|
||||
for (auto& kv : tids) {
|
||||
expr* e = kv.m_key;
|
||||
if (!var_mark.is_marked(e))
|
||||
mark_rec(fmls_mark, e);
|
||||
if (!var_mark.is_marked(e) && !is_pure(e))
|
||||
mark_rec(fmls_mark, e);
|
||||
}
|
||||
}
|
||||
|
||||
ptr_vector<expr> index2expr;
|
||||
for (auto& kv : tids)
|
||||
index2expr.setx(kv.m_value, kv.m_key, nullptr);
|
||||
for (auto& kv : tids)
|
||||
index2expr.setx(kv.m_value, kv.m_key, nullptr);
|
||||
|
||||
j = 0;
|
||||
unsigned_vector real_vars;
|
||||
for (app* v : vars) {
|
||||
if (is_arith(v) && !fmls_mark.is_marked(v))
|
||||
real_vars.push_back(tids.find(v));
|
||||
else
|
||||
vars[j++] = v;
|
||||
if (is_arith(v) && !fmls_mark.is_marked(v))
|
||||
real_vars.push_back(tids.find(v));
|
||||
else
|
||||
vars[j++] = v;
|
||||
}
|
||||
vars.shrink(j);
|
||||
|
||||
TRACE("qe", tout << "remaining vars: " << vars << "\n";
|
||||
for (unsigned v : real_vars) tout << "v" << v << " " << mk_pp(index2expr[v], m) << "\n";
|
||||
mbo.display(tout););
|
||||
|
||||
TRACE("qe", tout << "remaining vars: " << vars << "\n";
|
||||
for (unsigned v : real_vars) tout << "v" << v << " " << mk_pp(index2expr[v], m) << "\n";
|
||||
mbo.display(tout););
|
||||
vector<opt::model_based_opt::def> defs = mbo.project(real_vars.size(), real_vars.data(), compute_def);
|
||||
|
||||
vector<row> rows;
|
||||
mbo.get_live_rows(rows);
|
||||
rows2fmls(rows, index2expr, fmls);
|
||||
TRACE("qe", mbo.display(tout << "mbo result\n");
|
||||
for (auto const& d : defs) tout << "def: " << d << "\n";
|
||||
tout << fmls << "\n";);
|
||||
|
||||
if (compute_def)
|
||||
optdefs2mbpdef(defs, index2expr, real_vars, result);
|
||||
for (auto const& d : defs) tout << "def: " << d << "\n";
|
||||
tout << fmls << "\n";);
|
||||
|
||||
if (compute_def)
|
||||
optdefs2mbpdef(defs, index2expr, real_vars, result);
|
||||
if (m_apply_projection && !apply_projection(eval, result, fmls))
|
||||
return false;
|
||||
|
||||
TRACE("qe",
|
||||
for (auto const& [v, t] : result)
|
||||
tout << v << " := " << t << "\n";
|
||||
for (auto* f : fmls)
|
||||
tout << mk_pp(f, m) << " := " << eval(f) << "\n";
|
||||
tout << "fmls:" << fmls << "\n";);
|
||||
for (auto* f : fmls)
|
||||
tout << mk_pp(f, m) << " := " << eval(f) << "\n";
|
||||
tout << "fmls:" << fmls << "\n";);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void optdefs2mbpdef(vector<opt::model_based_opt::def> const& defs, ptr_vector<expr> const& index2expr, unsigned_vector const& real_vars, vector<def>& result) {
|
||||
SASSERT(defs.size() == real_vars.size());
|
||||
|
@ -384,31 +411,92 @@ namespace mbp {
|
|||
bool is_int = a.is_int(x);
|
||||
expr_ref_vector ts(m);
|
||||
expr_ref t(m);
|
||||
for (var const& v : d.m_vars)
|
||||
ts.push_back(var2expr(index2expr, v));
|
||||
for (var const& v : d.m_vars)
|
||||
ts.push_back(var2expr(index2expr, v));
|
||||
if (!d.m_coeff.is_zero())
|
||||
ts.push_back(a.mk_numeral(d.m_coeff, is_int));
|
||||
if (ts.empty())
|
||||
ts.push_back(a.mk_numeral(rational(0), is_int));
|
||||
t = mk_add(ts);
|
||||
if (!d.m_div.is_one() && is_int)
|
||||
t = a.mk_idiv(t, a.mk_numeral(d.m_div, is_int));
|
||||
else if (!d.m_div.is_one() && !is_int)
|
||||
t = a.mk_div(t, a.mk_numeral(d.m_div, is_int));
|
||||
if (!d.m_div.is_one() && is_int)
|
||||
t = a.mk_idiv(t, a.mk_numeral(d.m_div, is_int));
|
||||
else if (!d.m_div.is_one() && !is_int)
|
||||
t = a.mk_div(t, a.mk_numeral(d.m_div, is_int));
|
||||
result.push_back(def(expr_ref(x, m), t));
|
||||
}
|
||||
}
|
||||
|
||||
void rows2fmls(vector<row> const& rows, ptr_vector<expr> const& index2expr, expr_ref_vector& fmls) {
|
||||
for (row const& r : rows) {
|
||||
expr_ref_vector ts(m);
|
||||
expr_ref t(m), s(m), val(m);
|
||||
if (r.m_vars.empty()) {
|
||||
expr_ref id2expr(u_map<row> const& def_vars, ptr_vector<expr> const& index2expr, unsigned id) {
|
||||
row r;
|
||||
if (def_vars.find(id, r))
|
||||
return row2expr(def_vars, index2expr, r);
|
||||
return expr_ref(index2expr[id], m);
|
||||
}
|
||||
|
||||
expr_ref row2expr(u_map<row> const& def_vars, ptr_vector<expr> const& index2expr, row const& r) {
|
||||
expr_ref_vector ts(m);
|
||||
expr_ref t(m);
|
||||
rational n;
|
||||
for (var const& v : r.m_vars) {
|
||||
t = id2expr(def_vars, index2expr, v.m_id);
|
||||
if (a.is_numeral(t, n) && n == 0)
|
||||
continue;
|
||||
else if (a.is_numeral(t, n))
|
||||
t = a.mk_numeral(v.m_coeff * n, a.is_int(t));
|
||||
else if (!v.m_coeff.is_one())
|
||||
t = a.mk_mul(a.mk_numeral(v.m_coeff, a.is_int(t)), t);
|
||||
ts.push_back(t);
|
||||
}
|
||||
switch (r.m_type) {
|
||||
case opt::t_mod:
|
||||
if (ts.empty()) {
|
||||
t = a.mk_int(mod(r.m_coeff, r.m_mod));
|
||||
return t;
|
||||
}
|
||||
if (r.m_vars.size() == 1 && r.m_vars[0].m_coeff.is_neg() && r.m_type != opt::t_mod) {
|
||||
ts.push_back(a.mk_int(r.m_coeff));
|
||||
t = mk_add(ts);
|
||||
t = a.mk_mod(t, a.mk_int(r.m_mod));
|
||||
return t;
|
||||
case opt::t_div:
|
||||
if (ts.empty()) {
|
||||
t = a.mk_int(div(r.m_coeff, r.m_mod));
|
||||
return t;
|
||||
}
|
||||
ts.push_back(a.mk_int(r.m_coeff));
|
||||
t = mk_add(ts);
|
||||
t = a.mk_idiv(t, a.mk_int(r.m_mod));
|
||||
return t;
|
||||
case opt::t_divides:
|
||||
ts.push_back(a.mk_int(r.m_coeff));
|
||||
return mk_add(ts);
|
||||
default:
|
||||
return mk_add(ts);
|
||||
}
|
||||
}
|
||||
|
||||
void rows2fmls(vector<row> const& rows, ptr_vector<expr> const& index2expr, expr_ref_vector& fmls) {
|
||||
|
||||
u_map<row> def_vars;
|
||||
for (row const& r : rows) {
|
||||
if (r.m_type == opt::t_mod)
|
||||
def_vars.insert(r.m_id, r);
|
||||
else if (r.m_type == opt::t_div)
|
||||
def_vars.insert(r.m_id, r);
|
||||
}
|
||||
|
||||
for (row const& r : rows) {
|
||||
expr_ref t(m), s(m), val(m);
|
||||
|
||||
if (r.m_vars.empty())
|
||||
continue;
|
||||
if (r.m_type == opt::t_mod)
|
||||
continue;
|
||||
if (r.m_type == opt::t_div)
|
||||
continue;
|
||||
|
||||
if (r.m_vars.size() == 1 && r.m_vars[0].m_coeff.is_neg() && r.m_type != opt::t_divides) {
|
||||
var const& v = r.m_vars[0];
|
||||
t = index2expr[v.m_id];
|
||||
t = id2expr(def_vars, index2expr, v.m_id);
|
||||
if (!v.m_coeff.is_minus_one()) {
|
||||
t = a.mk_mul(a.mk_numeral(-v.m_coeff, a.is_int(t)), t);
|
||||
}
|
||||
|
@ -422,24 +510,14 @@ namespace mbp {
|
|||
fmls.push_back(t);
|
||||
continue;
|
||||
}
|
||||
for (var const& v : r.m_vars) {
|
||||
t = index2expr[v.m_id];
|
||||
if (!v.m_coeff.is_one()) {
|
||||
t = a.mk_mul(a.mk_numeral(v.m_coeff, a.is_int(t)), t);
|
||||
}
|
||||
ts.push_back(t);
|
||||
}
|
||||
t = mk_add(ts);
|
||||
t = row2expr(def_vars, index2expr, r);
|
||||
s = a.mk_numeral(-r.m_coeff, r.m_coeff.is_int() && a.is_int(t));
|
||||
switch (r.m_type) {
|
||||
case opt::t_lt: t = a.mk_lt(t, s); break;
|
||||
case opt::t_le: t = a.mk_le(t, s); break;
|
||||
case opt::t_eq: t = a.mk_eq(t, s); break;
|
||||
case opt::t_mod:
|
||||
if (!r.m_coeff.is_zero()) {
|
||||
t = a.mk_sub(t, s);
|
||||
}
|
||||
t = a.mk_eq(a.mk_mod(t, a.mk_numeral(r.m_mod, true)), a.mk_int(0));
|
||||
case opt::t_divides:
|
||||
t = a.mk_eq(a.mk_mod(t, a.mk_int(r.m_mod)), a.mk_int(0));
|
||||
break;
|
||||
}
|
||||
fmls.push_back(t);
|
||||
|
@ -468,11 +546,11 @@ namespace mbp {
|
|||
SASSERT(validate_model(eval, fmls0));
|
||||
|
||||
// extract linear constraints
|
||||
|
||||
for (expr * fml : fmls) {
|
||||
|
||||
for (expr* fml : fmls) {
|
||||
linearize(mbo, eval, fml, fmls, tids);
|
||||
}
|
||||
|
||||
|
||||
// find optimal value
|
||||
value = mbo.maximize();
|
||||
|
||||
|
@ -543,7 +621,7 @@ namespace mbp {
|
|||
}
|
||||
CTRACE("qe", kv.m_value.is_zero(), tout << mk_pp(v, m) << " has coefficeint 0\n";);
|
||||
if (!kv.m_value.is_zero()) {
|
||||
coeffs.push_back(var(id, kv.m_value));
|
||||
coeffs.push_back(var(id, kv.m_value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -571,7 +649,7 @@ namespace mbp {
|
|||
|
||||
};
|
||||
|
||||
arith_project_plugin::arith_project_plugin(ast_manager& m):project_plugin(m) {
|
||||
arith_project_plugin::arith_project_plugin(ast_manager& m) :project_plugin(m) {
|
||||
m_imp = alloc(imp, m);
|
||||
}
|
||||
|
||||
|
|
|
@ -241,9 +241,8 @@ namespace qe {
|
|||
while (sz0 != todo.size()) {
|
||||
app* a = to_app(todo.back());
|
||||
todo.pop_back();
|
||||
if (mark.is_marked(a)) {
|
||||
if (mark.is_marked(a))
|
||||
continue;
|
||||
}
|
||||
|
||||
mark.mark(a);
|
||||
if (m_lit2pred.find(a, p)) {
|
||||
|
@ -284,9 +283,8 @@ namespace qe {
|
|||
m_elevel.insert(r, l);
|
||||
eq = m.mk_eq(r, a);
|
||||
defs.push_back(eq);
|
||||
if (!is_predicate(a, l.max())) {
|
||||
if (!is_predicate(a, l.max()))
|
||||
insert(r, l);
|
||||
}
|
||||
level.merge(l);
|
||||
}
|
||||
}
|
||||
|
@ -637,57 +635,55 @@ namespace qe {
|
|||
check_cancel();
|
||||
expr_ref_vector asms(m_asms);
|
||||
m_pred_abs.get_assumptions(m_model.get(), asms);
|
||||
if (m_model.get()) {
|
||||
if (m_model.get())
|
||||
validate_assumptions(*m_model.get(), asms);
|
||||
}
|
||||
TRACE("qe", tout << asms << "\n";);
|
||||
solver& s = get_kernel(m_level).s();
|
||||
lbool res = s.check_sat(asms);
|
||||
switch (res) {
|
||||
case l_true:
|
||||
s.get_model(m_model);
|
||||
CTRACE("qe", !m_model, tout << "no model\n");
|
||||
if (!m_model)
|
||||
return l_undef;
|
||||
SASSERT(validate_defs("check_sat"));
|
||||
SASSERT(!m_model.get() || validate_assumptions(*m_model.get(), asms));
|
||||
SASSERT(validate_model(asms));
|
||||
TRACE("qe", s.display(tout); display(tout << "\n", *m_model.get()); display(tout, asms); );
|
||||
if (m_level == 0) {
|
||||
if (m_level == 0)
|
||||
m_model_save = m_model;
|
||||
}
|
||||
push();
|
||||
if (m_level == 1 && m_mode == qsat_maximize) {
|
||||
if (m_level == 1 && m_mode == qsat_maximize)
|
||||
maximize_model();
|
||||
}
|
||||
break;
|
||||
case l_false:
|
||||
switch (m_level) {
|
||||
case 0:
|
||||
return l_false;
|
||||
case 1:
|
||||
if (m_mode == qsat_sat) {
|
||||
if (m_mode == qsat_sat)
|
||||
return l_true;
|
||||
}
|
||||
|
||||
if (m_model.get()) {
|
||||
SASSERT(validate_assumptions(*m_model.get(), asms));
|
||||
if (!project_qe(asms)) return l_undef;
|
||||
if (!project_qe(asms))
|
||||
return l_undef;
|
||||
}
|
||||
else {
|
||||
else
|
||||
pop(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (m_model.get()) {
|
||||
if (!project(asms)) return l_undef;
|
||||
if (!project(asms))
|
||||
return l_undef;
|
||||
}
|
||||
else {
|
||||
else
|
||||
pop(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case l_undef:
|
||||
TRACE("qe", tout << "check-sat is undef\n");
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
@ -833,11 +829,10 @@ namespace qe {
|
|||
}
|
||||
}
|
||||
|
||||
bool get_core(expr_ref_vector& core, unsigned level) {
|
||||
void get_core(expr_ref_vector& core, unsigned level) {
|
||||
SASSERT(validate_defs("get_core"));
|
||||
get_kernel(level).get_core(core);
|
||||
m_pred_abs.pred2lit(core);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool minimize_core(expr_ref_vector& core, unsigned level) {
|
||||
|
@ -905,9 +900,7 @@ namespace qe {
|
|||
SASSERT(m_level == 1);
|
||||
expr_ref fml(m);
|
||||
model& mdl = *m_model.get();
|
||||
if (!get_core(core, m_level)) {
|
||||
return false;
|
||||
}
|
||||
get_core(core, m_level);
|
||||
SASSERT(validate_core(mdl, core));
|
||||
get_vars(m_level);
|
||||
SASSERT(validate_assumptions(mdl, core));
|
||||
|
@ -927,7 +920,7 @@ namespace qe {
|
|||
}
|
||||
|
||||
bool project(expr_ref_vector& core) {
|
||||
if (!get_core(core, m_level)) return false;
|
||||
get_core(core, m_level);
|
||||
TRACE("qe", display(tout); display(tout << "core\n", core););
|
||||
SASSERT(m_level >= 2);
|
||||
expr_ref fml(m);
|
||||
|
@ -950,14 +943,17 @@ namespace qe {
|
|||
if (level.max() == UINT_MAX) {
|
||||
num_scopes = 2*(m_level/2);
|
||||
}
|
||||
else if (level.max() + 2 > m_level) {
|
||||
// fishy - this can happen.
|
||||
TRACE("qe", tout << "max-level: " << level.max() << " level: " << m_level << "\n");
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
if (level.max() + 2 > m_level) return false;
|
||||
SASSERT(level.max() + 2 <= m_level);
|
||||
num_scopes = m_level - level.max();
|
||||
SASSERT(num_scopes >= 2);
|
||||
if ((num_scopes % 2) != 0) {
|
||||
if ((num_scopes % 2) != 0)
|
||||
--num_scopes;
|
||||
}
|
||||
}
|
||||
|
||||
pop(num_scopes);
|
||||
|
|
79
src/sat/smt/xor_solver.cpp
Normal file
79
src/sat/smt/xor_solver.cpp
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*++
|
||||
Copyright (c) 2014 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
xor_solver.h
|
||||
|
||||
Abstract:
|
||||
|
||||
XOR solver.
|
||||
Interface outline.
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
#include "sat/smt/xor_solver.h"
|
||||
#include "sat/sat_simplifier_params.hpp"
|
||||
#include "sat/sat_xor_finder.h"
|
||||
|
||||
namespace xr {
|
||||
|
||||
solver::solver(euf::solver& ctx):
|
||||
th_solver(ctx.get_manager(), symbol("xor-solver"), ctx.get_manager().get_family_id("xor-solver"))
|
||||
{}
|
||||
|
||||
euf::th_solver* solver::clone(euf::solver& ctx) {
|
||||
// and relevant copy internal state
|
||||
return alloc(solver, ctx);
|
||||
}
|
||||
|
||||
void solver::asserted(sat::literal l) {
|
||||
|
||||
}
|
||||
|
||||
bool solver::unit_propagate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void solver::get_antecedents(sat::literal l, sat::ext_justification_idx idx,
|
||||
sat::literal_vector & r, bool probing) {
|
||||
|
||||
}
|
||||
|
||||
sat::check_result solver::check() {
|
||||
return sat::check_result::CR_DONE;
|
||||
}
|
||||
|
||||
void solver::push() {
|
||||
}
|
||||
|
||||
void solver::pop(unsigned n) {
|
||||
}
|
||||
|
||||
// inprocessing
|
||||
// pre_simplify: decompile all xor constraints to allow other in-processing.
|
||||
// simplify: recompile clauses to xor constraints
|
||||
// literals that get added to xor constraints are tagged with the theory.
|
||||
void solver::pre_simplify() {
|
||||
|
||||
}
|
||||
|
||||
void solver::simplify() {
|
||||
|
||||
}
|
||||
|
||||
std::ostream& solver::display(std::ostream& out) const {
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream& solver::display_justification(std::ostream& out, sat::ext_justification_idx idx) const {
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream& solver::display_constraint(std::ostream& out, sat::ext_constraint_idx idx) const {
|
||||
return out;
|
||||
}
|
||||
|
||||
}
|
||||
|
48
src/sat/smt/xor_solver.h
Normal file
48
src/sat/smt/xor_solver.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*++
|
||||
Copyright (c) 2014 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
xor_solver.h
|
||||
|
||||
Abstract:
|
||||
|
||||
XOR solver.
|
||||
Interface outline.
|
||||
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sat/smt/euf_solver.h"
|
||||
|
||||
namespace xr {
|
||||
class solver : public euf::th_solver {
|
||||
public:
|
||||
solver(euf::solver& ctx);
|
||||
|
||||
th_solver* clone(euf::solver& ctx) override;
|
||||
|
||||
sat::literal internalize(expr* e, bool sign, bool root, bool redundant) override { UNREACHABLE(); return sat::null_literal; }
|
||||
|
||||
void internalize(expr* e, bool redundant) override { UNREACHABLE(); }
|
||||
|
||||
|
||||
void asserted(sat::literal l) override;
|
||||
bool unit_propagate() override;
|
||||
void get_antecedents(sat::literal l, sat::ext_justification_idx idx, sat::literal_vector & r, bool probing) override;
|
||||
|
||||
void pre_simplify() override;
|
||||
void simplify() override;
|
||||
|
||||
sat::check_result check() override;
|
||||
void push() override;
|
||||
void pop(unsigned n) override;
|
||||
|
||||
std::ostream& display(std::ostream& out) const override;
|
||||
std::ostream& display_justification(std::ostream& out, sat::ext_justification_idx idx) const override;
|
||||
std::ostream& display_constraint(std::ostream& out, sat::ext_constraint_idx idx) const override;
|
||||
|
||||
};
|
||||
|
||||
}
|
|
@ -23,6 +23,7 @@ Revision History:
|
|||
#include "ast/rewriter/var_subst.h"
|
||||
#include "smt/smt_context.h"
|
||||
#include "smt/qi_queue.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace smt {
|
||||
|
||||
|
@ -228,15 +229,12 @@ namespace smt {
|
|||
|
||||
|
||||
TRACE("qi_queue", tout << "new instance:\n" << mk_pp(instance, m) << "\n";);
|
||||
TRACE("qi_queue_instance", tout << "new instance:\n" << mk_pp(instance, m) << "\n";);
|
||||
expr_ref s_instance(m);
|
||||
proof_ref pr(m);
|
||||
m_context.get_rewriter()(instance, s_instance, pr);
|
||||
|
||||
TRACE("qi_queue_bug", tout << "new instance after simplification:\n" << s_instance << "\n";);
|
||||
if (m.is_true(s_instance)) {
|
||||
TRACE("checker", tout << "reduced to true, before:\n" << mk_ll_pp(instance, m););
|
||||
|
||||
STRACE("instance", tout << "Instance reduced to true\n";);
|
||||
stat -> inc_num_instances_simplify_true();
|
||||
if (m.has_trace_stream()) {
|
||||
|
@ -250,9 +248,11 @@ namespace smt {
|
|||
std::cout << "instantiate\n";
|
||||
enode_vector _bindings(num_bindings, bindings);
|
||||
for (auto * b : _bindings)
|
||||
std::cout << enode_pp(b, m_context) << " ";
|
||||
std::cout << mk_pp(b->get_expr(), m) << " ";
|
||||
std::cout << "\n";
|
||||
std::cout << mk_pp(q, m) << "\n";
|
||||
std::cout << "instance\n";
|
||||
std::cout << instance << "\n";
|
||||
#endif
|
||||
|
||||
TRACE("qi_queue", tout << "simplified instance:\n" << s_instance << "\n";);
|
||||
|
|
|
@ -218,7 +218,7 @@ namespace smt {
|
|||
TRACE("model_checker", tout << "Got some value " << sk_value << "\n";);
|
||||
|
||||
if (use_inv) {
|
||||
unsigned sk_term_gen = 0;
|
||||
unsigned sk_term_gen = 0;
|
||||
expr * sk_term = m_model_finder.get_inv(q, i, sk_value, sk_term_gen);
|
||||
if (sk_term != nullptr) {
|
||||
TRACE("model_checker", tout << "Found inverse " << mk_pp(sk_term, m) << "\n";);
|
||||
|
@ -243,6 +243,8 @@ namespace smt {
|
|||
func_decl * f = nullptr;
|
||||
if (autil.is_as_array(sk_value, f) && cex->get_func_interp(f) && cex->get_func_interp(f)->get_interp()) {
|
||||
expr_ref body(cex->get_func_interp(f)->get_interp(), m);
|
||||
if (contains_model_value(body))
|
||||
return false;
|
||||
ptr_vector<sort> sorts(f->get_arity(), f->get_domain());
|
||||
svector<symbol> names;
|
||||
for (unsigned i = 0; i < f->get_arity(); ++i) {
|
||||
|
|
|
@ -3507,16 +3507,15 @@ public:
|
|||
case lp::lp_status::OPTIMAL: {
|
||||
init_variable_values();
|
||||
TRACE("arith", display(tout << st << " v" << v << " vi: " << vi << "\n"););
|
||||
inf_rational val = get_value(v);
|
||||
// inf_rational val(term_max.x, term_max.y);
|
||||
auto val = value(v);
|
||||
blocker = mk_gt(v);
|
||||
return inf_eps(rational::zero(), val);
|
||||
return val;
|
||||
}
|
||||
case lp::lp_status::FEASIBLE: {
|
||||
inf_rational val = get_value(v);
|
||||
auto val = value(v);
|
||||
TRACE("arith", display(tout << st << " v" << v << " vi: " << vi << "\n"););
|
||||
blocker = mk_gt(v);
|
||||
return inf_eps(rational::zero(), val);
|
||||
return val;
|
||||
}
|
||||
default:
|
||||
SASSERT(st == lp::lp_status::UNBOUNDED);
|
||||
|
@ -3533,23 +3532,19 @@ public:
|
|||
rational r = val.x;
|
||||
expr_ref e(m);
|
||||
if (a.is_int(obj->get_sort())) {
|
||||
if (r.is_int()) {
|
||||
if (r.is_int())
|
||||
r += rational::one();
|
||||
}
|
||||
else {
|
||||
else
|
||||
r = ceil(r);
|
||||
}
|
||||
e = a.mk_numeral(r, obj->get_sort());
|
||||
e = a.mk_ge(obj, e);
|
||||
}
|
||||
else {
|
||||
e = a.mk_numeral(r, obj->get_sort());
|
||||
if (val.y.is_neg()) {
|
||||
if (val.y.is_neg())
|
||||
e = a.mk_ge(obj, e);
|
||||
}
|
||||
else {
|
||||
else
|
||||
e = a.mk_gt(obj, e);
|
||||
}
|
||||
}
|
||||
TRACE("opt", tout << "v" << v << " " << val << " " << r << " " << e << "\n";);
|
||||
return e;
|
||||
|
|
Loading…
Reference in a new issue