3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-09-04 09:07:40 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2014-10-15 14:29:39 -07:00
commit ce18421a7a
51 changed files with 1663 additions and 1117 deletions

View file

@ -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();

View file

@ -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);

View file

@ -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;
}

View file

@ -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;

View file

@ -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; }

View file

@ -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;

View file

@ -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; }

View file

@ -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();
}
}

View file

@ -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; }