mirror of
https://github.com/Z3Prover/z3
synced 2025-08-22 11:07:51 +00:00
rename polysat files to exclude namespace
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
a2d64e8441
commit
561d3e8eb9
21 changed files with 60 additions and 49 deletions
|
@ -1,224 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2021 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
polysat intervals
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2021-03-19
|
||||
Jakob Rath 2021-04-6
|
||||
|
||||
--*/
|
||||
#pragma once
|
||||
#include "sat/smt/polysat/polysat_types.h"
|
||||
#include <optional>
|
||||
|
||||
namespace polysat {
|
||||
|
||||
struct pdd_bounds {
|
||||
pdd lo; ///< lower bound, inclusive
|
||||
pdd hi; ///< upper bound, exclusive
|
||||
};
|
||||
|
||||
/**
|
||||
* An interval is either [lo; hi[ (excl. upper bound) or the full domain Z_{2^w}.
|
||||
* If lo > hi, the interval wraps around, i.e., represents the union of [lo; 2^w[ and [0; hi[.
|
||||
* Membership test t \in [lo; hi[ is equivalent to t - lo < hi - lo.
|
||||
*/
|
||||
class interval {
|
||||
std::optional<pdd_bounds> m_bounds = std::nullopt;
|
||||
|
||||
interval() = default;
|
||||
interval(pdd const& lo, pdd const& hi): m_bounds({lo, hi}) {}
|
||||
public:
|
||||
static interval empty(dd::pdd_manager& m) { return proper(m.zero(), m.zero()); }
|
||||
static interval full() { return {}; }
|
||||
static interval proper(pdd const& lo, pdd const& hi) { return {lo, hi}; }
|
||||
|
||||
interval(interval const&) = default;
|
||||
interval(interval&&) = default;
|
||||
interval& operator=(interval const& other) {
|
||||
m_bounds = std::nullopt; // clear pdds first to allow changing pdd_manager (probably should change the PDD assignment operator; but for now I want to be able to detect manager confusions)
|
||||
m_bounds = other.m_bounds;
|
||||
return *this;
|
||||
}
|
||||
interval& operator=(interval&& other) {
|
||||
m_bounds = std::nullopt; // clear pdds first to allow changing pdd_manager
|
||||
m_bounds = std::move(other.m_bounds);
|
||||
return *this;
|
||||
}
|
||||
~interval() = default;
|
||||
|
||||
bool is_full() const { return !m_bounds; }
|
||||
bool is_proper() const { return !!m_bounds; }
|
||||
bool is_always_empty() const { return is_proper() && lo() == hi(); }
|
||||
pdd const& lo() const { SASSERT(is_proper()); return m_bounds->lo; }
|
||||
pdd const& hi() const { SASSERT(is_proper()); return m_bounds->hi; }
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, interval const& i) {
|
||||
if (i.is_full())
|
||||
return os << "full";
|
||||
else
|
||||
return os << "[" << i.lo() << " ; " << i.hi() << "[";
|
||||
}
|
||||
|
||||
// distance from a to b, wrapping around at mod_value.
|
||||
// basically mod(b - a, mod_value), but distance(0, mod_value, mod_value) = mod_value.
|
||||
inline rational distance(rational const& a, rational const& b, rational const& mod_value) {
|
||||
SASSERT(mod_value.is_power_of_two());
|
||||
SASSERT(0 <= a && a < mod_value);
|
||||
SASSERT(0 <= b && b <= mod_value);
|
||||
rational x = b - a;
|
||||
if (x.is_neg())
|
||||
x += mod_value;
|
||||
return x;
|
||||
}
|
||||
|
||||
class r_interval {
|
||||
rational m_lo;
|
||||
rational m_hi;
|
||||
|
||||
r_interval(rational lo, rational hi)
|
||||
: m_lo(std::move(lo)), m_hi(std::move(hi))
|
||||
{}
|
||||
|
||||
public:
|
||||
|
||||
static r_interval empty() {
|
||||
return {rational::zero(), rational::zero()};
|
||||
}
|
||||
|
||||
static r_interval full() {
|
||||
return {rational(-1), rational::zero()};
|
||||
}
|
||||
|
||||
static r_interval proper(rational lo, rational hi) {
|
||||
SASSERT(0 <= lo);
|
||||
SASSERT(0 <= hi);
|
||||
return {std::move(lo), std::move(hi)};
|
||||
}
|
||||
|
||||
bool is_full() const { return m_lo.is_neg(); }
|
||||
bool is_proper() const { return !is_full(); }
|
||||
bool is_empty() const { return is_proper() && lo() == hi(); }
|
||||
rational const& lo() const { SASSERT(is_proper()); return m_lo; }
|
||||
rational const& hi() const { SASSERT(is_proper()); return m_hi; }
|
||||
|
||||
// this one also supports representing full intervals as [lo;mod_value[
|
||||
static rational len(rational const& lo, rational const& hi, rational const& mod_value) {
|
||||
SASSERT(mod_value.is_power_of_two());
|
||||
SASSERT(0 <= lo && lo < mod_value);
|
||||
SASSERT(0 <= hi && hi <= mod_value);
|
||||
SASSERT(hi != mod_value || lo == 0); // hi == mod_value only allowed when lo == 0
|
||||
rational len = hi - lo;
|
||||
if (len.is_neg())
|
||||
len += mod_value;
|
||||
return len;
|
||||
}
|
||||
|
||||
rational len(rational const& mod_value) const {
|
||||
SASSERT(is_proper());
|
||||
return len(lo(), hi(), mod_value);
|
||||
}
|
||||
|
||||
// deals only with proper intervals
|
||||
// but works with full intervals represented as [0;mod_value[ -- maybe we should just change representation of full intervals to this always
|
||||
static bool contains(rational const& lo, rational const& hi, rational const& val) {
|
||||
if (lo <= hi)
|
||||
return lo <= val && val < hi;
|
||||
else
|
||||
return val < hi || val >= lo;
|
||||
}
|
||||
|
||||
bool contains(rational const& val) const {
|
||||
if (is_full())
|
||||
return true;
|
||||
else
|
||||
return contains(lo(), hi(), val);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class eval_interval {
|
||||
interval m_symbolic;
|
||||
rational m_concrete_lo;
|
||||
rational m_concrete_hi;
|
||||
|
||||
eval_interval(interval&& i, rational const& lo_val, rational const& hi_val):
|
||||
m_symbolic(std::move(i)), m_concrete_lo(lo_val), m_concrete_hi(hi_val) {}
|
||||
public:
|
||||
static eval_interval empty(dd::pdd_manager& m) {
|
||||
return {interval::empty(m), rational::zero(), rational::zero()};
|
||||
}
|
||||
|
||||
static eval_interval full() {
|
||||
return {interval::full(), rational::zero(), rational::zero()};
|
||||
}
|
||||
|
||||
static eval_interval proper(pdd const& lo, rational const& lo_val, pdd const& hi, rational const& hi_val) {
|
||||
SASSERT(0 <= lo_val && lo_val <= lo.manager().max_value());
|
||||
SASSERT(0 <= hi_val && hi_val <= hi.manager().max_value());
|
||||
return {interval::proper(lo, hi), lo_val, hi_val};
|
||||
}
|
||||
|
||||
bool is_full() const { return m_symbolic.is_full(); }
|
||||
bool is_proper() const { return m_symbolic.is_proper(); }
|
||||
bool is_always_empty() const { return m_symbolic.is_always_empty(); }
|
||||
bool is_currently_empty() const { return is_proper() && lo_val() == hi_val(); }
|
||||
interval const& symbolic() const { return m_symbolic; }
|
||||
pdd const& lo() const { return m_symbolic.lo(); }
|
||||
pdd const& hi() const { return m_symbolic.hi(); }
|
||||
rational const& lo_val() const { SASSERT(is_proper()); return m_concrete_lo; }
|
||||
rational const& hi_val() const { SASSERT(is_proper()); return m_concrete_hi; }
|
||||
|
||||
rational current_len() const {
|
||||
SASSERT(is_proper());
|
||||
return mod(hi_val() - lo_val(), lo().manager().two_to_N());
|
||||
}
|
||||
|
||||
bool currently_contains(rational const& val) const {
|
||||
if (is_full())
|
||||
return true;
|
||||
else if (lo_val() <= hi_val())
|
||||
return lo_val() <= val && val < hi_val();
|
||||
else
|
||||
return val < hi_val() || val >= lo_val();
|
||||
}
|
||||
|
||||
bool currently_contains(eval_interval const& other) const {
|
||||
if (is_full())
|
||||
return true;
|
||||
if (other.is_full())
|
||||
return false;
|
||||
// lo <= lo' <= hi' <= hi'
|
||||
if (lo_val() <= other.lo_val() && other.lo_val() <= other.hi_val() && other.hi_val() <= hi_val())
|
||||
return true;
|
||||
if (lo_val() <= hi_val())
|
||||
return false;
|
||||
// hi < lo <= lo' <= hi'
|
||||
if (lo_val() <= other.lo_val() && other.lo_val() <= other.hi_val())
|
||||
return true;
|
||||
// lo' <= hi' <= hi < lo
|
||||
if (other.lo_val() <= other.hi_val() && other.hi_val() <= hi_val())
|
||||
return true;
|
||||
// hi' <= hi < lo <= lo'
|
||||
if (other.hi_val() <= hi_val() && lo_val() <= other.lo_val())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
}; // class eval_interval
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, eval_interval const& i) {
|
||||
if (i.is_full())
|
||||
return os << "full";
|
||||
else {
|
||||
auto& m = i.hi().manager();
|
||||
return os << i.symbolic() << " := [" << m.normalize(i.lo_val()) << ";" << m.normalize(i.hi_val()) << "[";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue