mirror of
https://github.com/Z3Prover/z3
synced 2025-08-25 04:26:00 +00:00
rename to op-constraint to give space for other operations
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
bc1e44ab71
commit
a2aa1170f9
8 changed files with 77 additions and 54 deletions
130
src/math/polysat/op_constraint.cpp
Normal file
130
src/math/polysat/op_constraint.cpp
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*++
|
||||
Copyright (c) 2021 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
polysat shift right constraint.
|
||||
|
||||
Author:
|
||||
|
||||
Jakob Rath, Nikolaj Bjorner (nbjorner) 2021-12-09
|
||||
|
||||
--*/
|
||||
|
||||
#include "math/polysat/op_constraint.h"
|
||||
#include "math/polysat/solver.h"
|
||||
|
||||
namespace polysat {
|
||||
|
||||
op_constraint::op_constraint(constraint_manager& m, code c, pdd const& p, pdd const& q, pdd const& r):
|
||||
constraint(m, ckind_t::op_t), m_op(c), m_p(p), m_q(q), m_r(r) {
|
||||
m_vars.append(p.free_vars());
|
||||
for (auto v : q.free_vars())
|
||||
if (!m_vars.contains(v))
|
||||
m_vars.push_back(v);
|
||||
for (auto v : r.free_vars())
|
||||
if (!m_vars.contains(v))
|
||||
m_vars.push_back(v);
|
||||
}
|
||||
|
||||
lbool op_constraint::eval(pdd const& p, pdd const& q, pdd const& r) const {
|
||||
switch (m_op) {
|
||||
case code::lshr_op:
|
||||
if (q.is_val() && r.is_val()) {
|
||||
auto& m = p.manager();
|
||||
if (q.val() >= m.power_of_2())
|
||||
return r.is_zero() ? l_true : l_false;
|
||||
if (p.is_val()) {
|
||||
pdd rr = p * m.mk_val(rational::power_of_two(q.val().get_unsigned()));
|
||||
return rr == r ? l_true : l_false;
|
||||
}
|
||||
// other cases when we know lower
|
||||
// bound of q, e.g, q = 2^k*q1 + q2, where q2 is a constant.
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return l_undef;
|
||||
}
|
||||
|
||||
bool op_constraint::is_always_false(bool is_positive, pdd const& p, pdd const& q, pdd const& r) const {
|
||||
switch (eval(p, q, r)) {
|
||||
case l_true: return !is_positive;
|
||||
case l_false: return is_positive;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool op_constraint::is_always_true(bool is_positive, pdd const& p, pdd const& q, pdd const& r) const {
|
||||
switch (eval(p, q, r)) {
|
||||
case l_true: return is_positive;
|
||||
case l_false: return !is_positive;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& op_constraint::display(std::ostream& out, lbool status) const {
|
||||
switch (status) {
|
||||
case l_true: return display(out);
|
||||
case l_false: return display(out << "~");
|
||||
default: return display(out << "?");
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& op_constraint::display(std::ostream& out) const {
|
||||
switch (m_op) {
|
||||
case code::lshr_op:
|
||||
return out << r() << " == " << p() << " << " << q();
|
||||
default:
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
bool op_constraint::is_always_false(bool is_positive) const {
|
||||
return is_always_false(is_positive, p(), q(), r());
|
||||
}
|
||||
|
||||
bool op_constraint::is_currently_false(assignment_t const& a, bool is_positive) const {
|
||||
return is_always_false(is_positive, p().subst_val(a), q().subst_val(a), r().subst_val(a));
|
||||
}
|
||||
|
||||
bool op_constraint::is_currently_true(assignment_t const& a, bool is_positive) const {
|
||||
return is_always_true(is_positive, p().subst_val(a), q().subst_val(a), r().subst_val(a));
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforce basic axioms, such as:
|
||||
*
|
||||
* r = p >> q & q >= k -> r[i] = 0 for i > K - k
|
||||
* r = p >> q & q >= K -> r = 0
|
||||
* r = p >> q & q = k -> r[i] = p[i+k] for k + i < K
|
||||
* r = p >> q & q >= k -> r <= 2^{K-k-1}
|
||||
* r = p >> q => r <= p
|
||||
* r = p >> q & q != 0 => r < p
|
||||
* r = p >> q & q = 0 => r = p
|
||||
*
|
||||
* when q is a constant, several axioms can be enforced at activation time.
|
||||
*
|
||||
* Enforce also inferences and bounds
|
||||
*
|
||||
* We can assume that op_constraint is only asserted positive.
|
||||
*/
|
||||
void op_constraint::narrow(solver& s, bool is_positive) {
|
||||
SASSERT(is_positive);
|
||||
NOT_IMPLEMENTED_YET();
|
||||
}
|
||||
|
||||
unsigned op_constraint::hash() const {
|
||||
return mk_mix(p().hash(), q().hash(), r().hash());
|
||||
}
|
||||
|
||||
bool op_constraint::operator==(constraint const& other) const {
|
||||
if (other.kind() != ckind_t::op_t)
|
||||
return false;
|
||||
auto const& o = other.to_op();
|
||||
return m_op == o.m_op && p() == o.p() && q() == o.q() && r() == o.r();
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue