mirror of
https://github.com/Z3Prover/z3
synced 2025-04-15 13:28:47 +00:00
Merge branch 'master' of https://github.com/Z3Prover/z3
This commit is contained in:
commit
cae53c3ec2
|
@ -173,6 +173,7 @@ void rewriter_core::elim_reflex_prs(unsigned spos) {
|
||||||
rewriter_core::rewriter_core(ast_manager & m, bool proof_gen):
|
rewriter_core::rewriter_core(ast_manager & m, bool proof_gen):
|
||||||
m_manager(m),
|
m_manager(m),
|
||||||
m_proof_gen(proof_gen),
|
m_proof_gen(proof_gen),
|
||||||
|
m_cancel_check(true),
|
||||||
m_result_stack(m),
|
m_result_stack(m),
|
||||||
m_result_pr_stack(m),
|
m_result_pr_stack(m),
|
||||||
m_num_qvars(0) {
|
m_num_qvars(0) {
|
||||||
|
|
|
@ -48,6 +48,7 @@ protected:
|
||||||
};
|
};
|
||||||
ast_manager & m_manager;
|
ast_manager & m_manager;
|
||||||
bool m_proof_gen;
|
bool m_proof_gen;
|
||||||
|
bool m_cancel_check;
|
||||||
typedef act_cache cache;
|
typedef act_cache cache;
|
||||||
ptr_vector<cache> m_cache_stack;
|
ptr_vector<cache> m_cache_stack;
|
||||||
cache * m_cache; // current cache.
|
cache * m_cache; // current cache.
|
||||||
|
@ -114,6 +115,7 @@ public:
|
||||||
ast_manager & m() const { return m_manager; }
|
ast_manager & m() const { return m_manager; }
|
||||||
void reset();
|
void reset();
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
void set_cancel_check(bool f) { m_cancel_check = f; }
|
||||||
#ifdef _TRACE
|
#ifdef _TRACE
|
||||||
void display_stack(std::ostream & out, unsigned pp_depth);
|
void display_stack(std::ostream & out, unsigned pp_depth);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -595,7 +595,7 @@ void rewriter_tpl<Config>::set_inv_bindings(unsigned num_bindings, expr * const
|
||||||
template<typename Config>
|
template<typename Config>
|
||||||
template<bool ProofGen>
|
template<bool ProofGen>
|
||||||
void rewriter_tpl<Config>::main_loop(expr * t, expr_ref & result, proof_ref & result_pr) {
|
void rewriter_tpl<Config>::main_loop(expr * t, expr_ref & result, proof_ref & result_pr) {
|
||||||
if (m().canceled()) {
|
if (m_cancel_check && m().canceled()) {
|
||||||
throw rewriter_exception(m().limit().get_cancel_msg());
|
throw rewriter_exception(m().limit().get_cancel_msg());
|
||||||
}
|
}
|
||||||
SASSERT(!ProofGen || result_stack().size() == result_pr_stack().size());
|
SASSERT(!ProofGen || result_stack().size() == result_pr_stack().size());
|
||||||
|
@ -629,7 +629,7 @@ template<bool ProofGen>
|
||||||
void rewriter_tpl<Config>::resume_core(expr_ref & result, proof_ref & result_pr) {
|
void rewriter_tpl<Config>::resume_core(expr_ref & result, proof_ref & result_pr) {
|
||||||
SASSERT(!frame_stack().empty());
|
SASSERT(!frame_stack().empty());
|
||||||
while (!frame_stack().empty()) {
|
while (!frame_stack().empty()) {
|
||||||
if (m().canceled()) {
|
if (m_cancel_check && m().canceled()) {
|
||||||
throw rewriter_exception(m().limit().get_cancel_msg());
|
throw rewriter_exception(m().limit().get_cancel_msg());
|
||||||
}
|
}
|
||||||
SASSERT(!ProofGen || result_stack().size() == result_pr_stack().size());
|
SASSERT(!ProofGen || result_stack().size() == result_pr_stack().size());
|
||||||
|
|
|
@ -342,6 +342,7 @@ public:
|
||||||
else
|
else
|
||||||
cls1.push_back(cls2[j]);
|
cls1.push_back(cls2[j]);
|
||||||
}
|
}
|
||||||
|
(void)found_pivot2;
|
||||||
assert(found_pivot2);
|
assert(found_pivot2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -362,6 +362,7 @@ public:
|
||||||
else
|
else
|
||||||
cls1.push_back(cls2[j]);
|
cls1.push_back(cls2[j]);
|
||||||
}
|
}
|
||||||
|
(void)found_pivot2;
|
||||||
assert(found_pivot2);
|
assert(found_pivot2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,6 +249,7 @@ void grobner::update_order() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool grobner::var_lt::operator()(expr * v1, expr * v2) const {
|
bool grobner::var_lt::operator()(expr * v1, expr * v2) const {
|
||||||
|
if (v1 == v2) return false;
|
||||||
int w1 = 0;
|
int w1 = 0;
|
||||||
int w2 = 0;
|
int w2 = 0;
|
||||||
m_var2weight.find(v1, w1);
|
m_var2weight.find(v1, w1);
|
||||||
|
@ -268,6 +269,8 @@ bool grobner::monomial_lt::operator()(monomial * m1, monomial * m2) const {
|
||||||
for (; it1 != end1; ++it1, ++it2) {
|
for (; it1 != end1; ++it1, ++it2) {
|
||||||
expr * v1 = *it1;
|
expr * v1 = *it1;
|
||||||
expr * v2 = *it2;
|
expr * v2 = *it2;
|
||||||
|
if (v1 == v2)
|
||||||
|
continue;
|
||||||
if (m_var_lt(v1, v2))
|
if (m_var_lt(v1, v2))
|
||||||
return true;
|
return true;
|
||||||
if (v1 != v2)
|
if (v1 != v2)
|
||||||
|
|
|
@ -259,6 +259,8 @@ struct evaluator_cfg : public default_rewriter_cfg {
|
||||||
|
|
||||||
|
|
||||||
br_status mk_array_eq(expr* a, expr* b, expr_ref& result) {
|
br_status mk_array_eq(expr* a, expr* b, expr_ref& result) {
|
||||||
|
return BR_FAILED;
|
||||||
|
// disabled until made more efficient
|
||||||
if (a == b) {
|
if (a == b) {
|
||||||
result = m().mk_true();
|
result = m().mk_true();
|
||||||
return BR_DONE;
|
return BR_DONE;
|
||||||
|
@ -271,6 +273,7 @@ struct evaluator_cfg : public default_rewriter_cfg {
|
||||||
conj.push_back(m().mk_eq(else1, else2));
|
conj.push_back(m().mk_eq(else1, else2));
|
||||||
args1.push_back(a);
|
args1.push_back(a);
|
||||||
args2.push_back(b);
|
args2.push_back(b);
|
||||||
|
// TBD: this is too inefficient.
|
||||||
for (unsigned i = 0; i < stores.size(); ++i) {
|
for (unsigned i = 0; i < stores.size(); ++i) {
|
||||||
args1.resize(1); args1.append(stores[i].size() - 1, stores[i].c_ptr());
|
args1.resize(1); args1.append(stores[i].size() - 1, stores[i].c_ptr());
|
||||||
args2.resize(1); args2.append(stores[i].size() - 1, stores[i].c_ptr());
|
args2.resize(1); args2.append(stores[i].size() - 1, stores[i].c_ptr());
|
||||||
|
@ -362,6 +365,7 @@ struct model_evaluator::imp : public rewriter_tpl<evaluator_cfg> {
|
||||||
false, // no proofs for evaluator
|
false, // no proofs for evaluator
|
||||||
m_cfg),
|
m_cfg),
|
||||||
m_cfg(md.get_manager(), md, p) {
|
m_cfg(md.get_manager(), md, p) {
|
||||||
|
set_cancel_check(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -300,6 +300,7 @@ public:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case datalog::OK:
|
case datalog::OK:
|
||||||
|
(void)query_exn;
|
||||||
SASSERT(query_exn);
|
SASSERT(query_exn);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -173,6 +173,7 @@ namespace datalog {
|
||||||
else {
|
else {
|
||||||
processed = false;
|
processed = false;
|
||||||
}
|
}
|
||||||
|
(void)processed;
|
||||||
TRACE("dl", tout << (processed?"+ ":"- ") << mk_pp(e, m) << "\n";
|
TRACE("dl", tout << (processed?"+ ":"- ") << mk_pp(e, m) << "\n";
|
||||||
if (processed) matrix::display_ineq(tout, row, M.b.back(), M.eq.back());
|
if (processed) matrix::display_ineq(tout, row, M.b.back(), M.eq.back());
|
||||||
);
|
);
|
||||||
|
|
|
@ -137,81 +137,12 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class alternate_min_max_cmd : public cmd {
|
|
||||||
app_ref_vector* m_vars;
|
|
||||||
svector<bool> m_is_max;
|
|
||||||
unsigned m_position;
|
|
||||||
|
|
||||||
app_ref_vector& vars(cmd_context& ctx) {
|
|
||||||
if (!m_vars) {
|
|
||||||
m_vars = alloc(app_ref_vector, ctx.m());
|
|
||||||
}
|
|
||||||
return *m_vars;
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
alternate_min_max_cmd():
|
|
||||||
cmd("min-max"),
|
|
||||||
m_vars(0),
|
|
||||||
m_position(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
virtual void reset(cmd_context & ctx) {
|
|
||||||
dealloc(m_vars);
|
|
||||||
m_vars = 0;
|
|
||||||
m_is_max.reset();
|
|
||||||
m_position = 0;
|
|
||||||
}
|
|
||||||
virtual char const * get_usage() const { return "(min | max | var)+ <term>"; }
|
|
||||||
virtual char const * get_descr(cmd_context & ctx) const { return "check sat modulo alternating min-max objectives";}
|
|
||||||
virtual unsigned get_arity() const { return 2; }
|
|
||||||
virtual void prepare(cmd_context & ctx) {}
|
|
||||||
virtual cmd_arg_kind next_arg_kind(cmd_context & ctx) const {
|
|
||||||
switch (m_position) {
|
|
||||||
case 0: return CPK_SYMBOL_LIST;
|
|
||||||
case 1: return CPK_EXPR;
|
|
||||||
default: return CPK_SYMBOL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void set_next_arg(cmd_context & ctx, unsigned num, symbol const * slist) {
|
|
||||||
bool is_max = false;
|
|
||||||
for (unsigned i = 0; i < num; ++i) {
|
|
||||||
if (slist[i] == symbol("max")) {
|
|
||||||
is_max = true;
|
|
||||||
}
|
|
||||||
else if (slist[i] == symbol("min")) {
|
|
||||||
is_max = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_is_max.push_back(is_max);
|
|
||||||
vars(ctx).push_back(ctx.m().mk_const(ctx.find_func_decl(slist[i])));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
++m_position;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void set_next_arg(cmd_context & ctx, expr * t) {
|
|
||||||
if (!is_app(t)) {
|
|
||||||
throw cmd_exception("malformed objective term: it cannot be a quantifier or bound variable");
|
|
||||||
}
|
|
||||||
++m_position;
|
|
||||||
get_opt(ctx).min_max(to_app(t), vars(ctx), m_is_max);
|
|
||||||
reset(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void failure_cleanup(cmd_context & ctx) {
|
|
||||||
reset(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void execute(cmd_context & ctx) { }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void install_opt_cmds(cmd_context & ctx) {
|
void install_opt_cmds(cmd_context & ctx) {
|
||||||
ctx.insert(alloc(assert_soft_cmd));
|
ctx.insert(alloc(assert_soft_cmd));
|
||||||
ctx.insert(alloc(min_maximize_cmd, true));
|
ctx.insert(alloc(min_maximize_cmd, true));
|
||||||
ctx.insert(alloc(min_maximize_cmd, false));
|
ctx.insert(alloc(min_maximize_cmd, false));
|
||||||
ctx.insert(alloc(alternate_min_max_cmd));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -212,18 +212,6 @@ namespace opt {
|
||||||
m_hard_constraints.append(s.m_hard);
|
m_hard_constraints.append(s.m_hard);
|
||||||
}
|
}
|
||||||
|
|
||||||
lbool context::min_max(app* t, app_ref_vector const& vars, svector<bool> const& is_max) {
|
|
||||||
clear_state();
|
|
||||||
init_solver();
|
|
||||||
import_scoped_state();
|
|
||||||
normalize();
|
|
||||||
internalize();
|
|
||||||
qe::max_min_opt max_min(m, m_params);
|
|
||||||
max_min.add(m_hard_constraints);
|
|
||||||
return max_min.check(is_max, vars, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
lbool context::optimize() {
|
lbool context::optimize() {
|
||||||
if (m_pareto) {
|
if (m_pareto) {
|
||||||
return execute_pareto();
|
return execute_pareto();
|
||||||
|
@ -236,12 +224,12 @@ namespace opt {
|
||||||
import_scoped_state();
|
import_scoped_state();
|
||||||
normalize();
|
normalize();
|
||||||
internalize();
|
internalize();
|
||||||
|
update_solver();
|
||||||
#if 0
|
#if 0
|
||||||
if (is_qsat_opt()) {
|
if (is_qsat_opt()) {
|
||||||
return run_qsat_opt();
|
return run_qsat_opt();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
update_solver();
|
|
||||||
solver& s = get_solver();
|
solver& s = get_solver();
|
||||||
s.assert_expr(m_hard_constraints);
|
s.assert_expr(m_hard_constraints);
|
||||||
display_benchmark();
|
display_benchmark();
|
||||||
|
@ -1473,6 +1461,7 @@ namespace opt {
|
||||||
value.neg();
|
value.neg();
|
||||||
}
|
}
|
||||||
if (result != l_undef) {
|
if (result != l_undef) {
|
||||||
|
m_optsmt.setup(*m_opt_solver.get());
|
||||||
m_optsmt.update_lower(obj.m_index, value);
|
m_optsmt.update_lower(obj.m_index, value);
|
||||||
m_optsmt.update_upper(obj.m_index, value);
|
m_optsmt.update_upper(obj.m_index, value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,7 +172,6 @@ namespace opt {
|
||||||
virtual ~context();
|
virtual ~context();
|
||||||
unsigned add_soft_constraint(expr* f, rational const& w, symbol const& id);
|
unsigned add_soft_constraint(expr* f, rational const& w, symbol const& id);
|
||||||
unsigned add_objective(app* t, bool is_max);
|
unsigned add_objective(app* t, bool is_max);
|
||||||
lbool min_max(app* t, app_ref_vector const& vars, svector<bool> const& is_max);
|
|
||||||
void add_hard_constraint(expr* f);
|
void add_hard_constraint(expr* f);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -344,6 +344,10 @@ namespace opt {
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_ref opt_solver::mk_ge(unsigned var, inf_eps const& val) {
|
expr_ref opt_solver::mk_ge(unsigned var, inf_eps const& val) {
|
||||||
|
if (!val.is_finite())
|
||||||
|
{
|
||||||
|
return expr_ref(val.is_pos() ? m.mk_false() : m.mk_true(), m);
|
||||||
|
}
|
||||||
smt::theory_opt& opt = get_optimizer();
|
smt::theory_opt& opt = get_optimizer();
|
||||||
smt::theory_var v = m_objective_vars[var];
|
smt::theory_var v = m_objective_vars[var];
|
||||||
|
|
||||||
|
|
|
@ -24,9 +24,9 @@ Revision History:
|
||||||
#include "ast_util.h"
|
#include "ast_util.h"
|
||||||
#include "arith_decl_plugin.h"
|
#include "arith_decl_plugin.h"
|
||||||
#include "ast_pp.h"
|
#include "ast_pp.h"
|
||||||
|
#include "model_v2_pp.h"
|
||||||
#include "th_rewriter.h"
|
#include "th_rewriter.h"
|
||||||
#include "expr_functors.h"
|
#include "expr_functors.h"
|
||||||
#include "model_v2_pp.h"
|
|
||||||
#include "expr_safe_replace.h"
|
#include "expr_safe_replace.h"
|
||||||
#include "model_based_opt.h"
|
#include "model_based_opt.h"
|
||||||
|
|
||||||
|
@ -103,19 +103,19 @@ namespace qe {
|
||||||
expr_ref t(m);
|
expr_ref t(m);
|
||||||
opt::ineq_type ty = opt::t_le;
|
opt::ineq_type ty = opt::t_le;
|
||||||
expr* e1, *e2;
|
expr* e1, *e2;
|
||||||
|
DEBUG_CODE(expr_ref val(m); VERIFY(model.eval(lit, val) && m.is_true(val)););
|
||||||
|
|
||||||
bool is_not = m.is_not(lit, lit);
|
bool is_not = m.is_not(lit, lit);
|
||||||
if (is_not) {
|
if (is_not) {
|
||||||
mul.neg();
|
mul.neg();
|
||||||
}
|
}
|
||||||
SASSERT(!m.is_not(lit));
|
SASSERT(!m.is_not(lit));
|
||||||
if (a.is_le(lit, e1, e2) || a.is_ge(lit, e2, e1)) {
|
if (a.is_le(lit, e1, e2) || a.is_ge(lit, e2, e1)) {
|
||||||
if (is_not) mul.neg();
|
|
||||||
linearize(mbo, model, mul, e1, c, ts, tids);
|
linearize(mbo, model, mul, e1, c, ts, tids);
|
||||||
linearize(mbo, model, -mul, e2, c, ts, tids);
|
linearize(mbo, model, -mul, e2, c, ts, tids);
|
||||||
ty = is_not ? opt::t_lt : opt::t_le;
|
ty = is_not ? opt::t_lt : opt::t_le;
|
||||||
}
|
}
|
||||||
else if (a.is_lt(lit, e1, e2) || a.is_gt(lit, e2, e1)) {
|
else if (a.is_lt(lit, e1, e2) || a.is_gt(lit, e2, e1)) {
|
||||||
if (is_not) mul.neg();
|
|
||||||
linearize(mbo, model, mul, e1, c, ts, tids);
|
linearize(mbo, model, mul, e1, c, ts, tids);
|
||||||
linearize(mbo, model, -mul, e2, c, ts, tids);
|
linearize(mbo, model, -mul, e2, c, ts, tids);
|
||||||
ty = is_not ? opt::t_le: opt::t_lt;
|
ty = is_not ? opt::t_le: opt::t_lt;
|
||||||
|
|
138
src/qe/qsat.cpp
138
src/qe/qsat.cpp
|
@ -618,7 +618,7 @@ namespace qe {
|
||||||
}
|
}
|
||||||
|
|
||||||
kernel& get_kernel(unsigned j) {
|
kernel& get_kernel(unsigned j) {
|
||||||
if (m_kernel_ex || is_exists(j)) {
|
if (is_exists(j)) {
|
||||||
return m_ex;
|
return m_ex;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -735,11 +735,7 @@ namespace qe {
|
||||||
void display(std::ostream& out) const {
|
void display(std::ostream& out) const {
|
||||||
out << "level: " << m_level << "\n";
|
out << "level: " << m_level << "\n";
|
||||||
for (unsigned i = 0; i < m_vars.size(); ++i) {
|
for (unsigned i = 0; i < m_vars.size(); ++i) {
|
||||||
for (unsigned j = 0; j < m_vars[i].size(); ++j) {
|
out << m_vars[i] << "\n";
|
||||||
expr* v = m_vars[i][j];
|
|
||||||
out << mk_pp(v, m) << " ";
|
|
||||||
}
|
|
||||||
out << "\n";
|
|
||||||
}
|
}
|
||||||
m_pred_abs.display(out);
|
m_pred_abs.display(out);
|
||||||
}
|
}
|
||||||
|
@ -1070,8 +1066,7 @@ namespace qe {
|
||||||
m_level(0),
|
m_level(0),
|
||||||
m_mode(mode),
|
m_mode(mode),
|
||||||
m_avars(m),
|
m_avars(m),
|
||||||
m_free_vars(m),
|
m_free_vars(m)
|
||||||
m_kernel_ex(false)
|
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
@ -1238,90 +1233,6 @@ namespace qe {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool m_kernel_ex;
|
|
||||||
|
|
||||||
lbool max_min(expr_ref_vector const& fmls, svector<bool> const& is_max, app_ref_vector const& vars, app* t) {
|
|
||||||
m_kernel_ex = true;
|
|
||||||
// Assume this is the only call to check.
|
|
||||||
expr_ref_vector defs(m);
|
|
||||||
app_ref_vector free_vars(m), vars1(m);
|
|
||||||
expr_ref fml = mk_and(fmls);
|
|
||||||
m_pred_abs.get_free_vars(fml, free_vars);
|
|
||||||
m_pred_abs.abstract_atoms(fml, defs);
|
|
||||||
fml = m_pred_abs.mk_abstract(fml);
|
|
||||||
get_kernel(0).k().assert_expr(mk_and(defs));
|
|
||||||
get_kernel(0).k().assert_expr(fml);
|
|
||||||
obj_hashtable<app> var_set;
|
|
||||||
for (unsigned i = 0; i < vars.size(); ++i) {
|
|
||||||
var_set.insert(vars[i]);
|
|
||||||
}
|
|
||||||
for (unsigned i = 0; i < free_vars.size(); ++i) {
|
|
||||||
app* v = free_vars[i].get();
|
|
||||||
if (!var_set.contains(v)) {
|
|
||||||
vars1.push_back(v);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// Insert all variables in alternating list of max/min objectives.
|
|
||||||
// By convention, the outer-most level is max.
|
|
||||||
//
|
|
||||||
bool is_m = true;
|
|
||||||
for (unsigned i = 0; i < vars.size(); ++i) {
|
|
||||||
if (is_m != is_max[i]) {
|
|
||||||
m_vars.push_back(vars1);
|
|
||||||
vars1.reset();
|
|
||||||
is_m = is_max[i];
|
|
||||||
}
|
|
||||||
vars1.push_back(vars[i]);
|
|
||||||
}
|
|
||||||
m_vars.push_back(vars1);
|
|
||||||
|
|
||||||
return max_min();
|
|
||||||
}
|
|
||||||
|
|
||||||
lbool max_min() {
|
|
||||||
while (true) {
|
|
||||||
++m_stats.m_num_rounds;
|
|
||||||
check_cancel();
|
|
||||||
expr_ref_vector asms(m_asms);
|
|
||||||
m_pred_abs.get_assumptions(m_model.get(), asms);
|
|
||||||
//
|
|
||||||
// TBD: add bound to asms.
|
|
||||||
//
|
|
||||||
smt::kernel& k = get_kernel(m_level).k();
|
|
||||||
lbool res = k.check(asms);
|
|
||||||
switch (res) {
|
|
||||||
case l_true:
|
|
||||||
k.get_model(m_model);
|
|
||||||
SASSERT(validate_model(asms));
|
|
||||||
TRACE("qe", k.display(tout); display(tout << "\n", *m_model.get()); display(tout, asms); );
|
|
||||||
//
|
|
||||||
// TBD: compute new bound on objective.
|
|
||||||
//
|
|
||||||
push();
|
|
||||||
break;
|
|
||||||
case l_false:
|
|
||||||
switch (m_level) {
|
|
||||||
case 0: return l_false;
|
|
||||||
case 1:
|
|
||||||
// TBD
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (m_model.get()) {
|
|
||||||
project(asms);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pop(1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case l_undef:
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return l_undef;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1331,49 +1242,6 @@ namespace qe {
|
||||||
return qs.maximize(fmls, t, mdl, value);
|
return qs.maximize(fmls, t, mdl, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct max_min_opt::imp {
|
|
||||||
|
|
||||||
expr_ref_vector m_fmls;
|
|
||||||
qsat m_qsat;
|
|
||||||
|
|
||||||
imp(ast_manager& m, params_ref const& p):
|
|
||||||
m_fmls(m),
|
|
||||||
m_qsat(m, p, qsat_maximize)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void add(expr* e) {
|
|
||||||
m_fmls.push_back(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
lbool check(svector<bool> const& is_max, app_ref_vector const& vars, app* t) {
|
|
||||||
return m_qsat.max_min(m_fmls, is_max, vars, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
max_min_opt::max_min_opt(ast_manager& m, params_ref const& p) {
|
|
||||||
m_imp = alloc(imp, m, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
max_min_opt::~max_min_opt() {
|
|
||||||
dealloc(m_imp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void max_min_opt::add(expr* e) {
|
|
||||||
m_imp->add(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
void max_min_opt::add(expr_ref_vector const& fmls) {
|
|
||||||
for (unsigned i = 0; i < fmls.size(); ++i) {
|
|
||||||
add(fmls[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lbool max_min_opt::check(svector<bool> const& is_max, app_ref_vector const& vars, app* t) {
|
|
||||||
return m_imp->check(is_max, vars, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
tactic * mk_qsat_tactic(ast_manager& m, params_ref const& p) {
|
tactic * mk_qsat_tactic(ast_manager& m, params_ref const& p) {
|
||||||
|
|
|
@ -114,17 +114,6 @@ namespace qe {
|
||||||
void collect_statistics(statistics& st) const;
|
void collect_statistics(statistics& st) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class max_min_opt {
|
|
||||||
struct imp;
|
|
||||||
imp* m_imp;
|
|
||||||
public:
|
|
||||||
max_min_opt(ast_manager& m, params_ref const& p = params_ref());
|
|
||||||
~max_min_opt();
|
|
||||||
void add(expr* e);
|
|
||||||
void add(expr_ref_vector const& fmls);
|
|
||||||
lbool check(svector<bool> const& is_max, app_ref_vector const& vars, app* t);
|
|
||||||
};
|
|
||||||
|
|
||||||
lbool maximize(expr_ref_vector const& fmls, app* t, opt::inf_eps& value, model_ref& mdl, params_ref const& p);
|
lbool maximize(expr_ref_vector const& fmls, app* t, opt::inf_eps& value, model_ref& mdl, params_ref const& p);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ namespace sat {
|
||||||
|
|
||||||
bool clause::check_approx() const {
|
bool clause::check_approx() const {
|
||||||
var_approx_set curr = m_approx;
|
var_approx_set curr = m_approx;
|
||||||
|
(void)curr;
|
||||||
const_cast<clause*>(this)->update_approx();
|
const_cast<clause*>(this)->update_approx();
|
||||||
SASSERT(may_eq(curr, m_approx));
|
SASSERT(may_eq(curr, m_approx));
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -159,7 +159,8 @@ namespace sat {
|
||||||
for (unsigned l_idx = 0; it != end; ++it, ++l_idx) {
|
for (unsigned l_idx = 0; it != end; ++it, ++l_idx) {
|
||||||
literal l = ~to_literal(l_idx);
|
literal l = ~to_literal(l_idx);
|
||||||
watch_list const & wlist = *it;
|
watch_list const & wlist = *it;
|
||||||
CTRACE("sat_bug", s.was_eliminated(l.var()) && !wlist.empty(),
|
CTRACE("sat_bug",
|
||||||
|
s.was_eliminated(l.var()) && !wlist.empty(),
|
||||||
tout << "l: " << l << "\n";
|
tout << "l: " << l << "\n";
|
||||||
s.display_watches(tout);
|
s.display_watches(tout);
|
||||||
s.display(tout););
|
s.display(tout););
|
||||||
|
@ -179,7 +180,7 @@ namespace sat {
|
||||||
tout << "\n";
|
tout << "\n";
|
||||||
sat::display(tout, s.m_cls_allocator, s.get_wlist(~(it2->get_literal())));
|
sat::display(tout, s.m_cls_allocator, s.get_wlist(~(it2->get_literal())));
|
||||||
tout << "\n";);
|
tout << "\n";);
|
||||||
SASSERT(s.get_wlist(~(it2->get_literal())).contains(watched(l, it2->is_learned())));
|
SASSERT(s.get_wlist(~(it2->get_literal())).contains(watched(l, it2->is_learned())));
|
||||||
break;
|
break;
|
||||||
case watched::TERNARY:
|
case watched::TERNARY:
|
||||||
SASSERT(!s.was_eliminated(it2->get_literal1().var()));
|
SASSERT(!s.was_eliminated(it2->get_literal1().var()));
|
||||||
|
|
|
@ -739,6 +739,7 @@ public:
|
||||||
if (idx2 < idx1) {
|
if (idx2 < idx1) {
|
||||||
std::swap(idx1,idx2);
|
std::swap(idx1,idx2);
|
||||||
}
|
}
|
||||||
|
(void) max_idx;
|
||||||
SASSERT(idx1 < idx2 && idx2 < edges.size());
|
SASSERT(idx1 < idx2 && idx2 < edges.size());
|
||||||
SASSERT(max_idx < edges.size());
|
SASSERT(max_idx < edges.size());
|
||||||
dst = get_source(edges[idx2]);
|
dst = get_source(edges[idx2]);
|
||||||
|
|
|
@ -1342,6 +1342,7 @@ namespace smt {
|
||||||
tout << "v" << x_i << " ";
|
tout << "v" << x_i << " ";
|
||||||
tout << (has_shared?"shared":"not shared") << "\n";);
|
tout << (has_shared?"shared":"not shared") << "\n";);
|
||||||
|
|
||||||
|
(void) empty_column;
|
||||||
SASSERT(!safe_gain(min_gain, max_gain) ||
|
SASSERT(!safe_gain(min_gain, max_gain) ||
|
||||||
empty_column ||
|
empty_column ||
|
||||||
(unbounded_gain(max_gain) == (x_i == null_theory_var)));
|
(unbounded_gain(max_gain) == (x_i == null_theory_var)));
|
||||||
|
|
|
@ -218,6 +218,7 @@ namespace smt {
|
||||||
SASSERT(r && bv_sz == m_ebits);
|
SASSERT(r && bv_sz == m_ebits);
|
||||||
r = m_bu.is_numeral(values[2], sig_r, bv_sz);
|
r = m_bu.is_numeral(values[2], sig_r, bv_sz);
|
||||||
SASSERT(r && bv_sz == m_sbits - 1);
|
SASSERT(r && bv_sz == m_sbits - 1);
|
||||||
|
(void)r;
|
||||||
|
|
||||||
SASSERT(mpzm.is_one(sgn_r.to_mpq().denominator()));
|
SASSERT(mpzm.is_one(sgn_r.to_mpq().denominator()));
|
||||||
SASSERT(mpzm.is_one(exp_r.to_mpq().denominator()));
|
SASSERT(mpzm.is_one(exp_r.to_mpq().denominator()));
|
||||||
|
|
|
@ -1820,22 +1820,16 @@ bool theory_seq::solve_ne(unsigned idx) {
|
||||||
TRACE("seq", display_disequation(tout << "reduces to false: ", n););
|
TRACE("seq", display_disequation(tout << "reduces to false: ", n););
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (!change) {
|
||||||
|
TRACE("seq", tout << "no change " << n.ls(i) << " " << n.rs(i) << "\n";);
|
||||||
|
if (updated) {
|
||||||
|
new_ls.push_back(n.ls(i));
|
||||||
|
new_rs.push_back(n.rs(i));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
// eliminate ite expressions.
|
|
||||||
reduce_ite(lhs, new_lits, num_undef_lits, change);
|
|
||||||
reduce_ite(rhs, new_lits, num_undef_lits, change);
|
|
||||||
reduce_ite(ls, new_lits, num_undef_lits, change);
|
|
||||||
reduce_ite(rs, new_lits, num_undef_lits, change);
|
|
||||||
|
|
||||||
if (!change) {
|
|
||||||
TRACE("seq", tout << "no change " << n.ls(i) << " " << n.rs(i) << "\n";);
|
|
||||||
if (updated) {
|
|
||||||
new_ls.push_back(n.ls(i));
|
|
||||||
new_rs.push_back(n.rs(i));
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!updated) {
|
if (!updated) {
|
||||||
for (unsigned j = 0; j < i; ++j) {
|
for (unsigned j = 0; j < i; ++j) {
|
||||||
|
@ -1940,32 +1934,6 @@ bool theory_seq::solve_ne(unsigned idx) {
|
||||||
return updated;
|
return updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
void theory_seq::reduce_ite(expr_ref_vector & ls, literal_vector& new_lits, unsigned& num_undef_lits, bool& change) {
|
|
||||||
expr* cond, *th, *el;
|
|
||||||
context& ctx = get_context();
|
|
||||||
for (unsigned i = 0; i < ls.size(); ++i) {
|
|
||||||
expr* e = ls[i].get();
|
|
||||||
if (m.is_ite(e, cond, th, el)) {
|
|
||||||
literal lit(mk_literal(cond));
|
|
||||||
switch (ctx.get_assignment(lit)) {
|
|
||||||
case l_true:
|
|
||||||
change = true;
|
|
||||||
new_lits.push_back(lit);
|
|
||||||
ls[i] = th;
|
|
||||||
break;
|
|
||||||
case l_false:
|
|
||||||
change = true;
|
|
||||||
new_lits.push_back(~lit);
|
|
||||||
ls[i] = el;
|
|
||||||
break;
|
|
||||||
case l_undef:
|
|
||||||
++num_undef_lits;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool theory_seq::solve_nc(unsigned idx) {
|
bool theory_seq::solve_nc(unsigned idx) {
|
||||||
nc const& n = m_ncs[idx];
|
nc const& n = m_ncs[idx];
|
||||||
|
@ -2613,6 +2581,7 @@ expr_ref theory_seq::expand(expr* e0, dependency*& eqs) {
|
||||||
}
|
}
|
||||||
expr* e = m_rep.find(e0, deps);
|
expr* e = m_rep.find(e0, deps);
|
||||||
expr* e1, *e2, *e3;
|
expr* e1, *e2, *e3;
|
||||||
|
context& ctx = get_context();
|
||||||
if (m_util.str.is_concat(e, e1, e2)) {
|
if (m_util.str.is_concat(e, e1, e2)) {
|
||||||
result = mk_concat(expand(e1, deps), expand(e2, deps));
|
result = mk_concat(expand(e1, deps), expand(e2, deps));
|
||||||
}
|
}
|
||||||
|
@ -2637,11 +2606,26 @@ expr_ref theory_seq::expand(expr* e0, dependency*& eqs) {
|
||||||
else if (m_util.str.is_index(e, e1, e2, e3)) {
|
else if (m_util.str.is_index(e, e1, e2, e3)) {
|
||||||
result = m_util.str.mk_index(expand(e1, deps), expand(e2, deps), e3);
|
result = m_util.str.mk_index(expand(e1, deps), expand(e2, deps), e3);
|
||||||
}
|
}
|
||||||
|
else if (m.is_ite(e, e1, e2, e3)) {
|
||||||
|
literal lit(mk_literal(e1));
|
||||||
|
switch (ctx.get_assignment(lit)) {
|
||||||
|
case l_true:
|
||||||
|
deps = m_dm.mk_join(deps, m_dm.mk_leaf(assumption(lit)));
|
||||||
|
result = expand(e2, deps);
|
||||||
|
break;
|
||||||
|
case l_false:
|
||||||
|
deps = m_dm.mk_join(deps, m_dm.mk_leaf(assumption(~lit)));
|
||||||
|
result = expand(e3, deps);
|
||||||
|
break;
|
||||||
|
case l_undef:
|
||||||
|
result = e;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (m_util.str.is_itos(e, e1)) {
|
else if (m_util.str.is_itos(e, e1)) {
|
||||||
rational val;
|
rational val;
|
||||||
if (get_value(e1, val)) {
|
if (get_value(e1, val)) {
|
||||||
expr_ref num(m), res(m);
|
expr_ref num(m), res(m);
|
||||||
context& ctx = get_context();
|
|
||||||
num = m_autil.mk_numeral(val, true);
|
num = m_autil.mk_numeral(val, true);
|
||||||
if (!ctx.e_internalized(num)) {
|
if (!ctx.e_internalized(num)) {
|
||||||
ctx.internalize(num, false);
|
ctx.internalize(num, false);
|
||||||
|
|
|
@ -410,7 +410,6 @@ namespace smt {
|
||||||
bool solve_nqs(unsigned i);
|
bool solve_nqs(unsigned i);
|
||||||
bool solve_ne(unsigned i);
|
bool solve_ne(unsigned i);
|
||||||
bool solve_nc(unsigned i);
|
bool solve_nc(unsigned i);
|
||||||
void reduce_ite(expr_ref_vector& ls, literal_vector& new_lits, unsigned& num_undef_lits, bool& change);
|
|
||||||
|
|
||||||
struct cell {
|
struct cell {
|
||||||
cell* m_parent;
|
cell* m_parent;
|
||||||
|
|
|
@ -156,6 +156,7 @@ class fm_tactic : public tactic {
|
||||||
r = c;
|
r = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
(void)found;
|
||||||
SASSERT(found);
|
SASSERT(found);
|
||||||
return is_lower ? LOWER : UPPER;
|
return is_lower ? LOWER : UPPER;
|
||||||
}
|
}
|
||||||
|
|
|
@ -300,6 +300,7 @@ public:
|
||||||
bool get_sum(expr* x, rational const& mul, expr_ref_vector& conds, expr_ref_vector& args, vector<rational>& coeffs, rational& coeff) {
|
bool get_sum(expr* x, rational const& mul, expr_ref_vector& conds, expr_ref_vector& args, vector<rational>& coeffs, rational& coeff) {
|
||||||
expr *y, *z, *u;
|
expr *y, *z, *u;
|
||||||
rational r, q;
|
rational r, q;
|
||||||
|
if (!is_app(x)) return false;
|
||||||
app* f = to_app(x);
|
app* f = to_app(x);
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
if (a.is_add(x)) {
|
if (a.is_add(x)) {
|
||||||
|
|
|
@ -274,13 +274,12 @@ void mpn_manager::div_unnormalize(mpn_sbuffer & numer, mpn_sbuffer & denom,
|
||||||
|
|
||||||
bool mpn_manager::div_1(mpn_sbuffer & numer, mpn_digit const denom,
|
bool mpn_manager::div_1(mpn_sbuffer & numer, mpn_digit const denom,
|
||||||
mpn_digit * quot) const {
|
mpn_digit * quot) const {
|
||||||
mpn_double_digit q_hat, temp, r_hat, ms;
|
mpn_double_digit q_hat, temp, ms;
|
||||||
mpn_digit borrow;
|
mpn_digit borrow;
|
||||||
|
|
||||||
for (size_t j = numer.size()-1; j > 0; j--) {
|
for (size_t j = numer.size()-1; j > 0; j--) {
|
||||||
temp = (((mpn_double_digit)numer[j]) << DIGIT_BITS) | ((mpn_double_digit)numer[j-1]);
|
temp = (((mpn_double_digit)numer[j]) << DIGIT_BITS) | ((mpn_double_digit)numer[j-1]);
|
||||||
q_hat = temp / (mpn_double_digit) denom;
|
q_hat = temp / (mpn_double_digit) denom;
|
||||||
r_hat = temp % (mpn_double_digit) denom;
|
|
||||||
if (q_hat >= BASE) {
|
if (q_hat >= BASE) {
|
||||||
UNREACHABLE(); // is this reachable with normalized v?
|
UNREACHABLE(); // is this reachable with normalized v?
|
||||||
}
|
}
|
||||||
|
@ -294,11 +293,13 @@ bool mpn_manager::div_1(mpn_sbuffer & numer, mpn_digit const denom,
|
||||||
quot[j-1]--;
|
quot[j-1]--;
|
||||||
numer[j] = numer[j-1] + denom;
|
numer[j] = numer[j-1] + denom;
|
||||||
}
|
}
|
||||||
TRACE("mpn_div1", tout << "j=" << j << " q_hat=" << q_hat << " r_hat=" << r_hat;
|
TRACE("mpn_div1",
|
||||||
tout << " ms=" << ms;
|
mpn_double_digit r_hat = temp % (mpn_double_digit) denom;
|
||||||
tout << " new numer="; display_raw(tout, numer.c_ptr(), numer.size());
|
tout << "j=" << j << " q_hat=" << q_hat << " r_hat=" << r_hat;
|
||||||
tout << " borrow=" << borrow;
|
tout << " ms=" << ms;
|
||||||
tout << std::endl; );
|
tout << " new numer="; display_raw(tout, numer.c_ptr(), numer.size());
|
||||||
|
tout << " borrow=" << borrow;
|
||||||
|
tout << std::endl; );
|
||||||
}
|
}
|
||||||
|
|
||||||
return true; // return rem != 0?
|
return true; // return rem != 0?
|
||||||
|
|
Loading…
Reference in a new issue