mirror of
https://github.com/Z3Prover/z3
synced 2025-09-04 09:07:40 +00:00
fix box
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
commit
ce18421a7a
51 changed files with 1663 additions and 1117 deletions
|
@ -19,10 +19,11 @@ Revision History:
|
|||
#include"smt_params.h"
|
||||
#include"smt_params_helper.hpp"
|
||||
#include"model_params.hpp"
|
||||
#include"gparams.h"
|
||||
|
||||
void smt_params::updt_local_params(params_ref const & _p) {
|
||||
smt_params_helper p(_p);
|
||||
m_auto_config = p.auto_config();
|
||||
m_auto_config = p.auto_config() && gparams::get_value("auto_config") == "true"; // auto-config is not scoped by smt in gparams.
|
||||
m_random_seed = p.random_seed();
|
||||
m_relevancy_lvl = p.relevancy();
|
||||
m_ematching = p.ematching();
|
||||
|
|
|
@ -1017,6 +1017,7 @@ namespace smt {
|
|||
//
|
||||
// -----------------------------------
|
||||
virtual inf_eps_rational<inf_rational> maximize(theory_var v, expr_ref& blocker);
|
||||
virtual inf_eps_rational<inf_rational> value(theory_var v);
|
||||
virtual theory_var add_objective(app* term);
|
||||
virtual expr* mk_ge(filter_model_converter& fm, theory_var v, inf_numeral const& val);
|
||||
void enable_record_conflict(expr* bound);
|
||||
|
|
|
@ -1059,7 +1059,6 @@ namespace smt {
|
|||
theory_var theory_arith<Ext>::add_objective(app* term) {
|
||||
theory_var v = internalize_term_core(term);
|
||||
TRACE("opt", tout << mk_pp(term, get_manager()) << " |-> v" << v << "\n";);
|
||||
TRACE("opt", tout << "data-size: " << m_data.size() << "\n";);
|
||||
SASSERT(!is_quasi_base(v));
|
||||
if (!is_linear(get_manager(), term)) {
|
||||
v = null_theory_var;
|
||||
|
@ -1067,6 +1066,11 @@ namespace smt {
|
|||
return v;
|
||||
}
|
||||
|
||||
template<typename Ext>
|
||||
inf_eps_rational<inf_rational> theory_arith<Ext>::value(theory_var v) {
|
||||
return inf_eps_rational<inf_rational>(get_value(v));
|
||||
}
|
||||
|
||||
template<typename Ext>
|
||||
inf_eps_rational<inf_rational> theory_arith<Ext>::maximize(theory_var v, expr_ref& blocker) {
|
||||
TRACE("bound_bug", display_var(tout, v); display(tout););
|
||||
|
@ -1533,12 +1537,14 @@ namespace smt {
|
|||
*/
|
||||
template<typename Ext>
|
||||
typename theory_arith<Ext>::max_min_t theory_arith<Ext>::max_min(theory_var v, bool max) {
|
||||
TRACE("opt", tout << (max ? "maximizing" : "minimizing") << " v" << v << "...\n";);
|
||||
expr* e = get_enode(v)->get_owner();
|
||||
SASSERT(valid_row_assignment());
|
||||
SASSERT(satisfy_bounds());
|
||||
SASSERT(!is_quasi_base(v));
|
||||
if ((max && at_upper(v)) || (!max && at_lower(v)))
|
||||
if ((max && at_upper(v)) || (!max && at_lower(v))) {
|
||||
TRACE("opt", tout << "At bound: " << mk_pp(e, get_manager()) << "...\n";);
|
||||
return AT_BOUND; // nothing to be done...
|
||||
}
|
||||
m_tmp_row.reset();
|
||||
if (is_non_base(v)) {
|
||||
add_tmp_row_entry<false>(m_tmp_row, numeral(1), v);
|
||||
|
@ -1554,11 +1560,16 @@ namespace smt {
|
|||
}
|
||||
max_min_t r = max_min(m_tmp_row, max);
|
||||
if (r == OPTIMIZED) {
|
||||
TRACE("opt", tout << "v" << v << " " << (max ? "max" : "min") << " value is: " << get_value(v) << "\n";
|
||||
TRACE("opt", tout << mk_pp(e, get_manager()) << " " << (max ? "max" : "min") << " value is: " << get_value(v) << "\n";
|
||||
display_row(tout, m_tmp_row, true); display_row_info(tout, m_tmp_row););
|
||||
|
||||
mk_bound_from_row(v, get_value(v), max ? B_UPPER : B_LOWER, m_tmp_row);
|
||||
|
||||
mk_bound_from_row(v, get_value(v), max ? B_UPPER : B_LOWER, m_tmp_row);
|
||||
}
|
||||
else if (r == UNBOUNDED) {
|
||||
TRACE("opt", tout << "unbounded: " << mk_pp(e, get_manager()) << "...\n";);
|
||||
}
|
||||
else {
|
||||
TRACE("opt", tout << "not optimized: " << mk_pp(e, get_manager()) << "...\n";);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ namespace smt {
|
|||
unsigned bv_size = get_bv_size(n);
|
||||
context & ctx = get_context();
|
||||
literal_vector & bits = m_bits[v];
|
||||
bits.reset();
|
||||
for (unsigned i = 0; i < bv_size; i++) {
|
||||
app * bit = mk_bit2bool(owner, i);
|
||||
ctx.internalize(bit, true);
|
||||
|
@ -75,12 +76,14 @@ namespace smt {
|
|||
void theory_bv::mk_bit2bool(app * n) {
|
||||
context & ctx = get_context();
|
||||
SASSERT(!ctx.b_internalized(n));
|
||||
if (!ctx.e_internalized(n->get_arg(0))) {
|
||||
|
||||
expr* first_arg = n->get_arg(0);
|
||||
|
||||
if (!ctx.e_internalized(first_arg)) {
|
||||
// This may happen if bit2bool(x) is in a conflict
|
||||
// clause that is being reinitialized, and x was not reinitialized
|
||||
// yet.
|
||||
// So, we internalize x (i.e., n->get_arg(0))
|
||||
expr * first_arg = n->get_arg(0);
|
||||
// So, we internalize x (i.e., arg)
|
||||
ctx.internalize(first_arg, false);
|
||||
SASSERT(ctx.e_internalized(first_arg));
|
||||
// In most cases, when x is internalized, its bits are created.
|
||||
|
@ -91,10 +94,27 @@ namespace smt {
|
|||
// This will also force the creation of all bits for x.
|
||||
enode * first_arg_enode = ctx.get_enode(first_arg);
|
||||
get_var(first_arg_enode);
|
||||
SASSERT(ctx.b_internalized(n));
|
||||
// numerals are not blasted into bit2bool, so we do this directly.
|
||||
if (!ctx.b_internalized(n)) {
|
||||
rational val;
|
||||
unsigned sz;
|
||||
VERIFY(m_util.is_numeral(first_arg, val, sz));
|
||||
theory_var v = first_arg_enode->get_th_var(get_id());
|
||||
app* owner = first_arg_enode->get_owner();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
ctx.internalize(mk_bit2bool(owner, i), true);
|
||||
}
|
||||
m_bits[v].reset();
|
||||
rational bit;
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
div(val, rational::power_of_two(i), bit);
|
||||
mod(bit, rational(2), bit);
|
||||
m_bits[v].push_back(bit.is_zero()?false_literal:true_literal);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
enode * arg = ctx.get_enode(n->get_arg(0));
|
||||
enode * arg = ctx.get_enode(first_arg);
|
||||
// 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.
|
||||
// See comment in the then-branch.
|
||||
|
@ -1041,6 +1061,7 @@ namespace smt {
|
|||
|
||||
void theory_bv::new_diseq_eh(theory_var v1, theory_var v2) {
|
||||
if (is_bv(v1)) {
|
||||
SASSERT(m_bits[v1].size() == m_bits[v2].size());
|
||||
expand_diseq(v1, v2);
|
||||
}
|
||||
}
|
||||
|
@ -1381,6 +1402,7 @@ namespace smt {
|
|||
if (v1 != null_theory_var) {
|
||||
// conflict was detected ... v1 and v2 have complementary bits
|
||||
SASSERT(m_bits[v1][it->m_idx] == ~(m_bits[v2][it->m_idx]));
|
||||
SASSERT(m_bits[v1].size() == m_bits[v2].size());
|
||||
mk_new_diseq_axiom(v1, v2, it->m_idx);
|
||||
RESET_MERGET_AUX();
|
||||
return false;
|
||||
|
|
|
@ -267,6 +267,7 @@ namespace smt {
|
|||
// -----------------------------------
|
||||
|
||||
virtual inf_eps_rational<inf_rational> maximize(theory_var v, expr_ref& blocker);
|
||||
virtual inf_eps_rational<inf_rational> value(theory_var v);
|
||||
virtual theory_var add_objective(app* term);
|
||||
virtual expr_ref mk_gt(theory_var v, inf_rational const& val);
|
||||
virtual expr* mk_ge(theory_var v, inf_rational const& val) { return 0; }
|
||||
|
|
|
@ -875,6 +875,19 @@ namespace smt {
|
|||
return true;
|
||||
}
|
||||
|
||||
template<typename Ext>
|
||||
inf_eps_rational<inf_rational> theory_dense_diff_logic<Ext>::value(theory_var v) {
|
||||
objective_term const& objective = m_objectives[v];
|
||||
inf_eps r = inf_eps(m_objective_consts[v]);
|
||||
for (unsigned i = 0; i < objective.size(); ++i) {
|
||||
numeral n = m_assignment[v];
|
||||
rational r1 = n.get_rational().to_rational();
|
||||
rational r2 = n.get_infinitesimal().to_rational();
|
||||
r += objective[i].second * inf_eps(rational(0), inf_rational(r1, r2));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
template<typename Ext>
|
||||
inf_eps_rational<inf_rational> theory_dense_diff_logic<Ext>::maximize(theory_var v, expr_ref& blocker) {
|
||||
typedef simplex::simplex<simplex::mpq_ext> Simplex;
|
||||
|
|
|
@ -65,6 +65,7 @@ namespace smt {
|
|||
|
||||
typedef typename Ext::numeral numeral;
|
||||
typedef simplex::simplex<simplex::mpq_ext> Simplex;
|
||||
typedef inf_eps_rational<inf_rational> inf_eps;
|
||||
|
||||
class atom {
|
||||
bool_var m_bvar;
|
||||
|
@ -319,7 +320,8 @@ namespace smt {
|
|||
//
|
||||
// -----------------------------------
|
||||
|
||||
virtual inf_eps_rational<inf_rational> maximize(theory_var v, expr_ref& blocker);
|
||||
virtual inf_eps maximize(theory_var v, expr_ref& blocker);
|
||||
virtual inf_eps value(theory_var v);
|
||||
virtual theory_var add_objective(app* term);
|
||||
virtual expr_ref mk_gt(theory_var v, inf_rational const& val);
|
||||
virtual expr* mk_ge(theory_var v, inf_rational const& val) { return 0; }
|
||||
|
|
|
@ -1078,43 +1078,32 @@ void theory_diff_logic<Ext>::get_implied_bound_antecedents(edge_id bridge_edge,
|
|||
|
||||
template<typename Ext>
|
||||
unsigned theory_diff_logic<Ext>::node2simplex(unsigned v) {
|
||||
//return v;
|
||||
return m_objectives.size() + 2*v + 1;
|
||||
}
|
||||
template<typename Ext>
|
||||
unsigned theory_diff_logic<Ext>::edge2simplex(unsigned e) {
|
||||
//return m_graph.get_num_nodes() + e;
|
||||
return m_objectives.size() + 2*e;
|
||||
}
|
||||
template<typename Ext>
|
||||
unsigned theory_diff_logic<Ext>::obj2simplex(unsigned e) {
|
||||
//return m_graph.get_num_nodes() + m_graph.get_num_edges() + e;
|
||||
return e;
|
||||
}
|
||||
|
||||
template<typename Ext>
|
||||
unsigned theory_diff_logic<Ext>::num_simplex_vars() {
|
||||
//return m_graph.get_num_nodes() + m_graph.get_num_edges() + m_objectives.size();
|
||||
return m_objectives.size() + std::max(2*m_graph.get_num_edges(),2*m_graph.get_num_nodes()+1);
|
||||
}
|
||||
|
||||
template<typename Ext>
|
||||
bool theory_diff_logic<Ext>::is_simplex_edge(unsigned e) {
|
||||
#if 0
|
||||
return
|
||||
m_graph.get_num_nodes() <= e &&
|
||||
e < m_graph.get_num_nodes() + m_graph.get_num_edges();
|
||||
#else
|
||||
if (e < m_objectives.size()) return false;
|
||||
e -= m_objectives.size();
|
||||
return (0 == (e & 0x1));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename Ext>
|
||||
unsigned theory_diff_logic<Ext>::simplex2edge(unsigned e) {
|
||||
SASSERT(is_simplex_edge(e));
|
||||
//return e - m_graph.get_num_nodes();
|
||||
return (e - m_objectives.size())/2;
|
||||
}
|
||||
|
||||
|
@ -1184,7 +1173,21 @@ void theory_diff_logic<Ext>::update_simplex(Simplex& S) {
|
|||
}
|
||||
|
||||
template<typename Ext>
|
||||
inf_eps_rational<inf_rational> theory_diff_logic<Ext>::maximize(theory_var v, expr_ref& blocker) {
|
||||
typename theory_diff_logic<Ext>::inf_eps theory_diff_logic<Ext>::value(theory_var v) {
|
||||
objective_term const& objective = m_objectives[v];
|
||||
inf_eps r = inf_eps(m_objective_consts[v]);
|
||||
for (unsigned i = 0; i < objective.size(); ++i) {
|
||||
numeral n = m_graph.get_assignment(v);
|
||||
rational r1 = n.get_rational().to_rational();
|
||||
rational r2 = n.get_infinitesimal().to_rational();
|
||||
r += objective[i].second * inf_eps(rational(0), inf_rational(r1, r2));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
template<typename Ext>
|
||||
typename theory_diff_logic<Ext>::inf_eps
|
||||
theory_diff_logic<Ext>::maximize(theory_var v, expr_ref& blocker) {
|
||||
|
||||
Simplex& S = m_S;
|
||||
ast_manager& m = get_manager();
|
||||
|
@ -1206,7 +1209,7 @@ inf_eps_rational<inf_rational> theory_diff_logic<Ext>::maximize(theory_var v, ex
|
|||
lbool is_sat = S.make_feasible();
|
||||
if (is_sat == l_undef) {
|
||||
blocker = m.mk_false();
|
||||
return inf_eps_rational<inf_rational>::infinity();
|
||||
return inf_eps::infinity();
|
||||
}
|
||||
TRACE("opt", S.display(tout); );
|
||||
SASSERT(is_sat != l_false);
|
||||
|
@ -1233,12 +1236,12 @@ inf_eps_rational<inf_rational> theory_diff_logic<Ext>::maximize(theory_var v, ex
|
|||
}
|
||||
}
|
||||
blocker = mk_gt(v, r);
|
||||
return inf_eps_rational<inf_rational>(rational(0), r);
|
||||
return inf_eps(rational(0), r);
|
||||
}
|
||||
default:
|
||||
TRACE("opt", tout << "unbounded\n"; );
|
||||
blocker = m.mk_false();
|
||||
return inf_eps_rational<inf_rational>::infinity();
|
||||
return inf_eps::infinity();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace smt {
|
|||
class theory_opt {
|
||||
public:
|
||||
typedef inf_eps_rational<inf_rational> inf_eps;
|
||||
virtual inf_eps value(theory_var) = 0;
|
||||
virtual inf_eps maximize(theory_var v, expr_ref& blocker) = 0;
|
||||
virtual theory_var add_objective(app* term) = 0;
|
||||
virtual expr* mk_ge(filter_model_converter& fm, theory_var v, inf_eps const& val) { UNREACHABLE(); return 0; }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue