mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 17:15:31 +00:00
add anf
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
bd5670a30b
commit
40a4326ad4
20 changed files with 860 additions and 465 deletions
|
@ -105,6 +105,19 @@ namespace dd {
|
|||
pdd pdd_manager::mk_xor(pdd const& p, pdd const& q) { return (p*q*2) - p - q; }
|
||||
pdd pdd_manager::mk_not(pdd const& p) { return 1 - p; }
|
||||
|
||||
pdd pdd_manager::subst_val(pdd const& p, vector<std::pair<unsigned, rational>> const& _s) {
|
||||
typedef std::pair<unsigned, rational> pr;
|
||||
vector<pr> s(_s);
|
||||
std::function<bool (pr const&, pr const&)> compare_level =
|
||||
[&](pr const& a, pr const& b) { return m_var2level[a.first] < m_var2level[b.first]; };
|
||||
std::sort(s.begin(), s.end(), compare_level);
|
||||
pdd r(one());
|
||||
for (auto const& q : s) {
|
||||
r = (r*mk_var(q.first)) + q.second;
|
||||
}
|
||||
return pdd(apply(p.root, r.root, pdd_subst_val_op), this);
|
||||
}
|
||||
|
||||
pdd_manager::PDD pdd_manager::apply(PDD arg1, PDD arg2, pdd_op op) {
|
||||
bool first = true;
|
||||
SASSERT(well_formed());
|
||||
|
@ -166,6 +179,14 @@ namespace dd {
|
|||
if (is_val(p)) return p;
|
||||
if (!is_val(q) && level(p) < level(q)) return p;
|
||||
break;
|
||||
case pdd_subst_val_op:
|
||||
while (!is_val(q) && !is_val(p)) {
|
||||
if (level(p) == level(q)) break;
|
||||
if (level(p) < level(q)) q = lo(q);
|
||||
else p = lo(p);
|
||||
}
|
||||
if (is_val(p) || is_val(q)) return p;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
@ -298,6 +319,16 @@ namespace dd {
|
|||
npop = 0;
|
||||
}
|
||||
break;
|
||||
case pdd_subst_val_op:
|
||||
SASSERT(!is_val(p));
|
||||
SASSERT(!is_val(q));
|
||||
SASSERT(level_p = level_q);
|
||||
push(apply_rec(lo(p), hi(q), pdd_subst_val_op)); // lo := subst(lo(p), s)
|
||||
push(apply_rec(hi(p), hi(q), pdd_subst_val_op)); // hi := subst(hi(p), s)
|
||||
push(apply_rec(lo(q), read(1), pdd_mul_op)); // hi := hi*s[var(p)]
|
||||
r = apply_rec(read(1), read(3), pdd_add_op); // r := hi + lo := subst(lo(p),s) + s[var(p)]*subst(hi(p),s)
|
||||
npop = 3;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
|
|
@ -62,7 +62,8 @@ namespace dd {
|
|||
pdd_minus_op = 4,
|
||||
pdd_mul_op = 5,
|
||||
pdd_reduce_op = 6,
|
||||
pdd_no_op = 7
|
||||
pdd_subst_val_op = 7,
|
||||
pdd_no_op = 8
|
||||
};
|
||||
|
||||
struct node {
|
||||
|
@ -264,6 +265,7 @@ namespace dd {
|
|||
pdd mk_xor(pdd const& p, pdd const& q);
|
||||
pdd mk_not(pdd const& p);
|
||||
pdd reduce(pdd const& a, pdd const& b);
|
||||
pdd subst_val(pdd const& a, vector<std::pair<unsigned, rational>> const& s);
|
||||
|
||||
bool is_linear(PDD p);
|
||||
bool is_linear(pdd const& p);
|
||||
|
@ -330,11 +332,15 @@ namespace dd {
|
|||
pdd reduce(pdd const& other) const { return m.reduce(*this, other); }
|
||||
bool different_leading_term(pdd const& other) const { return m.different_leading_term(*this, other); }
|
||||
|
||||
pdd subst_val(vector<std::pair<unsigned, rational>> const& s) const { return m.subst_val(*this, s); }
|
||||
|
||||
std::ostream& display(std::ostream& out) const { return m.display(out, *this); }
|
||||
bool operator==(pdd const& other) const { return root == other.root; }
|
||||
bool operator!=(pdd const& other) const { return root != other.root; }
|
||||
bool operator<(pdd const& other) const { return m.lt(*this, other); }
|
||||
|
||||
|
||||
|
||||
unsigned dag_size() const { return m.dag_size(*this); }
|
||||
double tree_size() const { return m.tree_size(*this); }
|
||||
unsigned degree() const { return m.degree(*this); }
|
||||
|
|
|
@ -105,8 +105,10 @@ public:
|
|||
solver(reslimit& lim, pdd_manager& m);
|
||||
~solver();
|
||||
|
||||
void operator=(print_dep_t& pd) { m_print_dep = pd; }
|
||||
void operator=(config const& c) { m_config = c; }
|
||||
pdd_manager& get_manager() { return m; }
|
||||
|
||||
void set(print_dep_t& pd) { m_print_dep = pd; }
|
||||
void set(config const& c) { m_config = c; }
|
||||
|
||||
void reset();
|
||||
void add(pdd const& p) { add(p, nullptr); }
|
||||
|
|
|
@ -91,3 +91,28 @@ std::ostream& bit_matrix::display(std::ostream& out) {
|
|||
return out;
|
||||
}
|
||||
|
||||
/*
|
||||
produce a sequence of bits forming a Gray code.
|
||||
- All 2^n bit-sequences are covered.
|
||||
- The Hamming distance between two entries it one.
|
||||
*/
|
||||
unsigned_vector bit_matrix::gray(unsigned n) {
|
||||
SASSERT(n < 32);
|
||||
if (n == 0) {
|
||||
return unsigned_vector();
|
||||
}
|
||||
else if (n == 1) {
|
||||
unsigned_vector v;
|
||||
v.push_back(0);
|
||||
v.push_back(1);
|
||||
return v;
|
||||
}
|
||||
else {
|
||||
auto v = gray(n-1);
|
||||
auto w = v;
|
||||
w.reverse();
|
||||
for (auto & u : v) u |= (1 << (n-1));
|
||||
v.append(w);
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ public:
|
|||
|
||||
private:
|
||||
void basic_solve();
|
||||
unsigned_vector gray(unsigned n);
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, bit_matrix& m) { return m.display(out); }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue