3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-30 12:25:51 +00:00
z3/src/math/polysat/eq_constraint.cpp
Nikolaj Bjorner 146d107961 na
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2021-09-07 17:04:32 +02:00

108 lines
2.9 KiB
C++

/*++
Copyright (c) 2021 Microsoft Corporation
Module Name:
polysat eq_constraints
Author:
Nikolaj Bjorner (nbjorner) 2021-03-19
Jakob Rath 2021-04-6
--*/
#include "math/polysat/constraint.h"
#include "math/polysat/solver.h"
#include "math/polysat/log.h"
namespace polysat {
std::ostream& eq_constraint::display(std::ostream& out, lbool status) const {
out << p();
if (status == l_true) out << " == 0";
else if (status == l_false) out << " != 0";
else out << " ==/!= 0";
return display_extra(out, status);
}
void eq_constraint::narrow(solver& s, bool is_positive) {
LOG("Assignment: " << assignments_pp(s));
auto q = p().subst_val(s.assignment());
LOG("Substituted: " << p() << " := " << q);
if (q.is_zero()) {
if (!is_positive) {
LOG("Conflict (zero under current assignment)");
s.set_conflict({this, is_positive});
}
return;
}
if (q.is_never_zero()) {
if (is_positive) {
LOG("Conflict (never zero under current assignment)");
s.set_conflict({this, is_positive});
}
return;
}
if (q.is_unilinear()) {
// a*x + b == 0
pvar v = q.var();
s.push_cjust(v, {this, is_positive});
rational a = q.hi().val();
rational b = q.lo().val();
s.m_viable.intersect_eq(a, v, b, is_positive);
rational val;
if (s.m_viable.find_viable(v, val) == dd::find_t::singleton)
s.propagate(v, val, {this, is_positive});
return;
}
// TODO: what other constraints can be extracted cheaply?
}
bool eq_constraint::is_always_false(bool is_positive) {
if (is_positive)
return p().is_never_zero();
else
return p().is_zero();
}
bool eq_constraint::is_currently_false(solver& s, bool is_positive) {
pdd r = p().subst_val(s.assignment());
if (is_positive)
return r.is_never_zero();
else
return r.is_zero();
}
bool eq_constraint::is_currently_true(solver& s, bool is_positive) {
pdd r = p().subst_val(s.assignment());
if (is_positive)
return r.is_zero();
else
return r.is_never_zero();
}
inequality eq_constraint::as_inequality(bool is_positive) const {
pdd zero = p() - p();
if (is_positive)
// p <= 0
return inequality(p(), zero, false, this);
else
// 0 < p
return inequality(zero, p(), true, this);
}
unsigned eq_constraint::hash() const {
return p().hash();
}
bool eq_constraint::operator==(constraint const& other) const {
return other.is_eq() && p() == other.to_eq().p();
}
}