mirror of
https://github.com/Z3Prover/z3
synced 2025-07-23 12:48:53 +00:00
comments
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
49b6d5b6fb
commit
78b022491d
3 changed files with 138 additions and 108 deletions
|
@ -107,7 +107,7 @@ namespace dd {
|
||||||
case pdd_add_op:
|
case pdd_add_op:
|
||||||
if (is_zero(a)) return b;
|
if (is_zero(a)) return b;
|
||||||
if (is_zero(b)) return a;
|
if (is_zero(b)) return a;
|
||||||
if (is_val(a) && is_val(b)) return imk_val(m_mod2_semantics ? ((val(a) + val(b)) % rational(2)) : val(a) + val(b));
|
if (is_val(a) && is_val(b)) return imk_val(val(a) + val(b));
|
||||||
if (level(a) < level(b)) std::swap(a, b);
|
if (level(a) < level(b)) std::swap(a, b);
|
||||||
break;
|
break;
|
||||||
case pdd_mul_op:
|
case pdd_mul_op:
|
||||||
|
@ -249,6 +249,7 @@ namespace dd {
|
||||||
}
|
}
|
||||||
|
|
||||||
pdd_manager::PDD pdd_manager::minus_rec(PDD a) {
|
pdd_manager::PDD pdd_manager::minus_rec(PDD a) {
|
||||||
|
SASSERT(!m_mod2_semantics);
|
||||||
if (is_zero(a)) return zero_pdd;
|
if (is_zero(a)) return zero_pdd;
|
||||||
if (is_val(a)) return imk_val(-val(a));
|
if (is_val(a)) return imk_val(-val(a));
|
||||||
op_entry* e1 = pop_entry(a, a, pdd_minus_op);
|
op_entry* e1 = pop_entry(a, a, pdd_minus_op);
|
||||||
|
@ -299,7 +300,7 @@ namespace dd {
|
||||||
if (is_val(p)) {
|
if (is_val(p)) {
|
||||||
if (is_val(q)) {
|
if (is_val(q)) {
|
||||||
SASSERT(!val(p).is_zero());
|
SASSERT(!val(p).is_zero());
|
||||||
return m_mod2_semantics ? imk_val(val(q)) : imk_val(-val(q)/val(p));
|
return imk_val(-val(q)/val(p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (level(p) == level(q)) {
|
else if (level(p) == level(q)) {
|
||||||
|
@ -321,7 +322,7 @@ namespace dd {
|
||||||
pdd r1 = mk_val(qc);
|
pdd r1 = mk_val(qc);
|
||||||
for (unsigned i = q.size(); i-- > 0; ) r1 = mul(mk_var(q[i]), r1);
|
for (unsigned i = q.size(); i-- > 0; ) r1 = mul(mk_var(q[i]), r1);
|
||||||
r1 = mul(a, r1);
|
r1 = mul(a, r1);
|
||||||
pdd r2 = mk_val(m_mod2_semantics ? pc : -pc);
|
pdd r2 = mk_val(-pc);
|
||||||
for (unsigned i = p.size(); i-- > 0; ) r2 = mul(mk_var(p[i]), r2);
|
for (unsigned i = p.size(); i-- > 0; ) r2 = mul(mk_var(p[i]), r2);
|
||||||
r2 = mul(b, r2);
|
r2 = mul(b, r2);
|
||||||
return add(r1, r2);
|
return add(r1, r2);
|
||||||
|
@ -338,6 +339,11 @@ namespace dd {
|
||||||
while (!is_val(x)) p.push_back(var(x)), x = hi(x);
|
while (!is_val(x)) p.push_back(var(x)), x = hi(x);
|
||||||
pc = val(x);
|
pc = val(x);
|
||||||
qc = val(y);
|
qc = val(y);
|
||||||
|
if (!m_mod2_semantics && pc.is_int() && qc.is_int()) {
|
||||||
|
rational g = gcd(pc, qc);
|
||||||
|
pc /= g;
|
||||||
|
qc /= g;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (level(x) == level(y)) {
|
if (level(x) == level(y)) {
|
||||||
|
@ -443,6 +449,7 @@ namespace dd {
|
||||||
pdd_manager::PDD pdd_manager::imk_val(rational const& r) {
|
pdd_manager::PDD pdd_manager::imk_val(rational const& r) {
|
||||||
if (r.is_zero()) return zero_pdd;
|
if (r.is_zero()) return zero_pdd;
|
||||||
if (r.is_one()) return one_pdd;
|
if (r.is_one()) return one_pdd;
|
||||||
|
if (m_mod2_semantics) return imk_val(mod(r, rational(2)));
|
||||||
const_info info;
|
const_info info;
|
||||||
if (!m_mpq_table.find(r, info)) {
|
if (!m_mpq_table.find(r, info)) {
|
||||||
init_value(info, r);
|
init_value(info, r);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
namespace dd {
|
namespace dd {
|
||||||
|
|
||||||
/***
|
/***
|
||||||
The main algorithm maintains two sets (S, A),
|
A simple algorithm maintains two sets (S, A),
|
||||||
where S is m_processed, and A is m_to_simplify.
|
where S is m_processed, and A is m_to_simplify.
|
||||||
Initially S is empty and A contains the initial equations.
|
Initially S is empty and A contains the initial equations.
|
||||||
|
|
||||||
|
@ -29,22 +29,71 @@ namespace dd {
|
||||||
add b to A
|
add b to A
|
||||||
- add a to S
|
- add a to S
|
||||||
- simplify A using a
|
- simplify A using a
|
||||||
|
|
||||||
|
Alternate:
|
||||||
|
|
||||||
|
- Fix a variable ordering x1 > x2 > x3 > ....
|
||||||
|
In each step:
|
||||||
|
- pick a in A with *highest* variable x_i in leading term of *lowest* degree.
|
||||||
|
- simplify a using S
|
||||||
|
- simplify S using a
|
||||||
|
- if a does not contains x_i, put it back into A and pick again (determine whether possible)
|
||||||
|
- for s in S:
|
||||||
|
b = superpose(a, s)
|
||||||
|
if superposition is invertible, then remove s
|
||||||
|
add b to A
|
||||||
|
- add a to S
|
||||||
|
- simplify A using a
|
||||||
|
|
||||||
|
|
||||||
|
Apply a watch list to filter out relevant elements of S
|
||||||
|
Index leading_term_watch: Var -> Equation*
|
||||||
|
Only need to simplify equations that contain eliminated variable.
|
||||||
|
The watch list can be used to index into equations that are useful to simplify.
|
||||||
|
A Bloom filter on leading term could further speed up test whether reduction applies.
|
||||||
|
|
||||||
|
For p in A:
|
||||||
|
populate watch list by maxvar(p) |-> p
|
||||||
|
For p in S:
|
||||||
|
populate watch list by vars(p) |-> p
|
||||||
|
|
||||||
|
- the variable ordering should be chosen from a candidate model M,
|
||||||
|
in a way that is compatible with weights that draw on the number of occurrences
|
||||||
|
in polynomials with violated evaluations and with the maximal slack (degree of freedom).
|
||||||
|
|
||||||
|
weight(x) := < count { p in P | x in p, M(p) != 0 }, min_{p in P | x in p} slack(p,x) >
|
||||||
|
|
||||||
|
slack is computed from interval assignments to variables, and is an interval in which x can possibly move
|
||||||
|
(an over-approximation).
|
||||||
|
|
||||||
|
The alternative version maintains the following invariant:
|
||||||
|
- polynomials not in the watch list cannot be simplified using a
|
||||||
|
Justification:
|
||||||
|
- elements in S have all variables watched
|
||||||
|
- elements in A are always reduced modulo all variables above the current x_i.
|
||||||
|
|
||||||
|
Invertible rules:
|
||||||
|
when p, q are linear in x, e.g., is of the form p = k*x + a, q = l*x + b
|
||||||
|
where k, l are constant and x is maximal, then
|
||||||
|
from l*a - k*b and k*x + a we have the equality lkx+al+kb-al, which is lx+b
|
||||||
|
So we can throw away q after superposition without losing solutions.
|
||||||
|
- this corresponds to triangulating a matrix during Gauss.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
grobner::grobner(reslimit& lim, pdd_manager& m) :
|
grobner::grobner(reslimit& lim, pdd_manager& m) :
|
||||||
m(m),
|
m(m),
|
||||||
m_limit(lim),
|
m_limit(lim),
|
||||||
m_conflict(false)
|
m_conflict(nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
grobner::~grobner() {
|
grobner::~grobner() {
|
||||||
del_equations(0);
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void grobner::compute_basis() {
|
void grobner::saturate() {
|
||||||
try {
|
try {
|
||||||
while (!done() && compute_basis_step()) {
|
while (!done() && step()) {
|
||||||
TRACE("grobner", display(tout););
|
TRACE("grobner", display(tout););
|
||||||
DEBUG_CODE(invariant(););
|
DEBUG_CODE(invariant(););
|
||||||
}
|
}
|
||||||
|
@ -54,7 +103,7 @@ namespace dd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool grobner::compute_basis_step() {
|
bool grobner::step() {
|
||||||
m_stats.m_compute_steps++;
|
m_stats.m_compute_steps++;
|
||||||
equation* e = pick_next();
|
equation* e = pick_next();
|
||||||
if (!e) return false;
|
if (!e) return false;
|
||||||
|
@ -66,7 +115,8 @@ namespace dd {
|
||||||
if (!simplify_using(m_processed, eq)) return false;
|
if (!simplify_using(m_processed, eq)) return false;
|
||||||
TRACE("grobner", tout << "eq = "; display_equation(tout, eq););
|
TRACE("grobner", tout << "eq = "; display_equation(tout, eq););
|
||||||
superpose(eq);
|
superpose(eq);
|
||||||
toggle_processed(eq);
|
eq.set_processed(true);
|
||||||
|
m_processed.push_back(e);
|
||||||
return simplify_using(m_to_simplify, eq);
|
return simplify_using(m_to_simplify, eq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +127,7 @@ namespace dd {
|
||||||
eq = curr;
|
eq = curr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (eq) m_to_simplify.erase(eq);
|
if (eq) pop_equation(eq->idx(), m_to_simplify);
|
||||||
return eq;
|
return eq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +140,7 @@ namespace dd {
|
||||||
/*
|
/*
|
||||||
Use a set of equations to simplify eq
|
Use a set of equations to simplify eq
|
||||||
*/
|
*/
|
||||||
bool grobner::simplify_using(equation& eq, equation_set const& eqs) {
|
bool grobner::simplify_using(equation& eq, equation_vector const& eqs) {
|
||||||
bool simplified, changed_leading_term;
|
bool simplified, changed_leading_term;
|
||||||
TRACE("grobner", tout << "simplifying: "; display_equation(tout, eq); tout << "using equalities of size " << eqs.size() << "\n";);
|
TRACE("grobner", tout << "simplifying: "; display_equation(tout, eq); tout << "using equalities of size " << eqs.size() << "\n";);
|
||||||
do {
|
do {
|
||||||
|
@ -115,31 +165,29 @@ namespace dd {
|
||||||
/*
|
/*
|
||||||
Use the given equation to simplify equations in set
|
Use the given equation to simplify equations in set
|
||||||
*/
|
*/
|
||||||
bool grobner::simplify_using(equation_set& set, equation const& eq) {
|
bool grobner::simplify_using(equation_vector& set, equation const& eq) {
|
||||||
TRACE("grobner", tout << "poly " << eq.poly() << "\n";);
|
TRACE("grobner", tout << "poly " << eq.poly() << "\n";);
|
||||||
ptr_buffer<equation> to_delete;
|
unsigned j = 0, sz = set.size();
|
||||||
ptr_buffer<equation> to_move;
|
for (unsigned i = 0; i < sz; ++i) {
|
||||||
|
equation& target = *set[i];
|
||||||
bool changed_leading_term = false;
|
bool changed_leading_term = false;
|
||||||
for (equation* target : set) {
|
bool simplified = !done() && simplify_source_target(eq, target, changed_leading_term);
|
||||||
if (canceled())
|
if (simplified && (is_trivial(target) || is_too_complex(target))) {
|
||||||
return false;
|
retire(&target);
|
||||||
if (simplify_source_target(eq, *target, changed_leading_term)) {
|
}
|
||||||
if (is_trivial(*target))
|
else if (simplified && !check_conflict(target) && changed_leading_term && target.is_processed()) {
|
||||||
to_delete.push_back(target);
|
target.set_index(m_to_simplify.size());
|
||||||
else if (is_too_complex(*target))
|
target.set_processed(false);
|
||||||
to_delete.push_back(target);
|
m_to_simplify.push_back(&target);
|
||||||
else if (check_conflict(*target))
|
}
|
||||||
return false;
|
else {
|
||||||
else if (changed_leading_term && target->is_processed()) {
|
set[j] = ⌖
|
||||||
to_move.push_back(target);
|
target.set_index(j);
|
||||||
|
++j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
set.shrink(j);
|
||||||
for (equation* eq : to_delete)
|
return !done();
|
||||||
del_equation(eq);
|
|
||||||
for (equation* eq : to_move)
|
|
||||||
toggle_processed(*eq);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -173,62 +221,31 @@ namespace dd {
|
||||||
m_stats.m_superposed++;
|
m_stats.m_superposed++;
|
||||||
if (r.is_zero()) return;
|
if (r.is_zero()) return;
|
||||||
if (is_too_complex(r)) return;
|
if (is_too_complex(r)) return;
|
||||||
equation* eq = alloc(equation, r, m_dep_manager.mk_join(eq1.dep(), eq2.dep()), m_equations.size());
|
add(r, m_dep_manager.mk_join(eq1.dep(), eq2.dep()));
|
||||||
m_equations.push_back(eq);
|
|
||||||
update_stats_max_degree_and_size(*eq);
|
|
||||||
check_conflict(*eq);
|
|
||||||
m_to_simplify.insert(eq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void grobner::toggle_processed(equation& eq) {
|
grobner::equation_vector const& grobner::equations() {
|
||||||
if (eq.is_processed()) {
|
|
||||||
m_to_simplify.insert(&eq);
|
|
||||||
m_processed.erase(&eq);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_processed.insert(&eq);
|
|
||||||
m_to_simplify.erase(&eq);
|
|
||||||
}
|
|
||||||
eq.set_processed(!eq.is_processed());
|
|
||||||
}
|
|
||||||
|
|
||||||
grobner::equation_set const& grobner::equations() {
|
|
||||||
m_all_eqs.reset();
|
m_all_eqs.reset();
|
||||||
for (equation* eq : m_equations) if (eq) m_all_eqs.insert(eq);
|
for (equation* eq : m_to_simplify) m_all_eqs.push_back(eq);
|
||||||
|
for (equation* eq : m_processed) m_all_eqs.push_back(eq);
|
||||||
return m_all_eqs;
|
return m_all_eqs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void grobner::reset() {
|
void grobner::reset() {
|
||||||
del_equations(0);
|
for (equation* e : m_to_simplify) dealloc(e);
|
||||||
SASSERT(m_equations.empty());
|
for (equation* e : m_processed) dealloc(e);
|
||||||
m_processed.reset();
|
m_processed.reset();
|
||||||
m_to_simplify.reset();
|
m_to_simplify.reset();
|
||||||
m_stats.reset();
|
m_stats.reset();
|
||||||
m_conflict = false;
|
m_conflict = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void grobner::add(pdd const& p, u_dependency * dep) {
|
void grobner::add(pdd const& p, u_dependency * dep) {
|
||||||
if (p.is_zero()) return;
|
if (p.is_zero()) return;
|
||||||
if (p.is_val()) set_conflict();
|
equation * eq = alloc(equation, p, dep, m_to_simplify.size());
|
||||||
equation * eq = alloc(equation, p, dep, m_equations.size());
|
m_to_simplify.push_back(eq);
|
||||||
m_equations.push_back(eq);
|
check_conflict(*eq);
|
||||||
m_to_simplify.insert(eq);
|
update_stats_max_degree_and_size(*eq);
|
||||||
}
|
|
||||||
|
|
||||||
void grobner::del_equations(unsigned old_size) {
|
|
||||||
for (unsigned i = m_equations.size(); i-- > old_size; ) {
|
|
||||||
del_equation(m_equations[i]);
|
|
||||||
}
|
|
||||||
m_equations.shrink(old_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void grobner::del_equation(equation* eq) {
|
|
||||||
if (!eq) return;
|
|
||||||
unsigned idx = eq->idx();
|
|
||||||
m_processed.erase(eq);
|
|
||||||
m_to_simplify.erase(eq);
|
|
||||||
dealloc(m_equations[idx]);
|
|
||||||
m_equations[idx] = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool grobner::canceled() {
|
bool grobner::canceled() {
|
||||||
|
@ -236,7 +253,19 @@ namespace dd {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool grobner::done() {
|
bool grobner::done() {
|
||||||
return m_to_simplify.size() + m_processed.size() >= m_config.m_eqs_threshold || canceled() || m_conflict;
|
return m_to_simplify.size() + m_processed.size() >= m_config.m_eqs_threshold || canceled() || m_conflict != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void grobner::del_equation(equation& eq) {
|
||||||
|
pop_equation(eq.idx(), eq.is_processed() ? m_processed : m_to_simplify);
|
||||||
|
retire(&eq);
|
||||||
|
}
|
||||||
|
|
||||||
|
void grobner::pop_equation(unsigned idx, equation_vector& v) {
|
||||||
|
equation* eq2 = v.back();
|
||||||
|
eq2->set_index(idx);
|
||||||
|
v[idx] = eq2;
|
||||||
|
v.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void grobner::update_stats_max_degree_and_size(const equation& e) {
|
void grobner::update_stats_max_degree_and_size(const equation& e) {
|
||||||
|
@ -268,21 +297,18 @@ namespace dd {
|
||||||
}
|
}
|
||||||
|
|
||||||
void grobner::invariant() const {
|
void grobner::invariant() const {
|
||||||
|
unsigned i = 0;
|
||||||
for (auto* e : m_processed) {
|
for (auto* e : m_processed) {
|
||||||
SASSERT(e->is_processed());
|
SASSERT(e->is_processed());
|
||||||
|
SASSERT(e->idx() == i);
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
|
i = 0;
|
||||||
for (auto* e : m_to_simplify) {
|
for (auto* e : m_to_simplify) {
|
||||||
SASSERT(!e->is_processed());
|
SASSERT(!e->is_processed());
|
||||||
}
|
SASSERT(e->idx() == i);
|
||||||
for (auto* e : m_equations) {
|
++i;
|
||||||
if (e) {
|
|
||||||
SASSERT(!e->is_processed() || m_processed.contains(e));
|
|
||||||
SASSERT(e->is_processed() || m_to_simplify.contains(e));
|
|
||||||
SASSERT(!is_trivial(*e));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ public:
|
||||||
private:
|
private:
|
||||||
class equation {
|
class equation {
|
||||||
bool m_processed; //!< state
|
bool m_processed; //!< state
|
||||||
unsigned m_idx; //!< position at m_equations
|
unsigned m_idx; //!< unique index
|
||||||
pdd m_poly; //!< polynomial in pdd form
|
pdd m_poly; //!< polynomial in pdd form
|
||||||
u_dependency * m_dep; //!< justification for the equality
|
u_dependency * m_dep; //!< justification for the equality
|
||||||
public:
|
public:
|
||||||
|
@ -60,15 +60,14 @@ private:
|
||||||
|
|
||||||
const pdd& poly() const { return m_poly; }
|
const pdd& poly() const { return m_poly; }
|
||||||
u_dependency * dep() const { return m_dep; }
|
u_dependency * dep() const { return m_dep; }
|
||||||
unsigned hash() const { return m_idx; }
|
|
||||||
unsigned idx() const { return m_idx; }
|
unsigned idx() const { return m_idx; }
|
||||||
void operator=(pdd& p) { m_poly = p; }
|
void operator=(pdd& p) { m_poly = p; }
|
||||||
void operator=(u_dependency* d) { m_dep = d; }
|
void operator=(u_dependency* d) { m_dep = d; }
|
||||||
bool is_processed() const { return m_processed; }
|
bool is_processed() const { return m_processed; }
|
||||||
void set_processed(bool p) { m_processed = p; }
|
void set_processed(bool p) { m_processed = p; }
|
||||||
|
void set_index(unsigned idx) { m_idx = idx; }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef obj_hashtable<equation> equation_set;
|
|
||||||
typedef ptr_vector<equation> equation_vector;
|
typedef ptr_vector<equation> equation_vector;
|
||||||
typedef std::function<void (u_dependency* d, std::ostream& out)> print_dep_t;
|
typedef std::function<void (u_dependency* d, std::ostream& out)> print_dep_t;
|
||||||
|
|
||||||
|
@ -77,12 +76,11 @@ private:
|
||||||
stats m_stats;
|
stats m_stats;
|
||||||
config m_config;
|
config m_config;
|
||||||
print_dep_t m_print_dep;
|
print_dep_t m_print_dep;
|
||||||
equation_vector m_equations;
|
equation_vector m_processed;
|
||||||
equation_set m_processed;
|
equation_vector m_to_simplify;
|
||||||
equation_set m_to_simplify;
|
|
||||||
mutable u_dependency_manager m_dep_manager;
|
mutable u_dependency_manager m_dep_manager;
|
||||||
equation_set m_all_eqs;
|
equation_vector m_all_eqs;
|
||||||
bool m_conflict;
|
equation const* m_conflict;
|
||||||
public:
|
public:
|
||||||
grobner(reslimit& lim, pdd_manager& m);
|
grobner(reslimit& lim, pdd_manager& m);
|
||||||
~grobner();
|
~grobner();
|
||||||
|
@ -93,9 +91,9 @@ public:
|
||||||
void reset();
|
void reset();
|
||||||
void add(pdd const&, u_dependency * dep);
|
void add(pdd const&, u_dependency * dep);
|
||||||
|
|
||||||
void compute_basis();
|
void saturate();
|
||||||
|
|
||||||
equation_set const& equations();
|
equation_vector const& equations();
|
||||||
u_dependency_manager& dep() const { return m_dep_manager; }
|
u_dependency_manager& dep() const { return m_dep_manager; }
|
||||||
|
|
||||||
void collect_statistics(statistics & st) const;
|
void collect_statistics(statistics & st) const;
|
||||||
|
@ -103,28 +101,27 @@ public:
|
||||||
std::ostream& display(std::ostream& out) const;
|
std::ostream& display(std::ostream& out) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool compute_basis_step();
|
bool step();
|
||||||
equation* pick_next();
|
equation* pick_next();
|
||||||
bool canceled();
|
bool canceled();
|
||||||
bool done();
|
bool done();
|
||||||
void superpose(equation const& eq1, equation const& eq2);
|
void superpose(equation const& eq1, equation const& eq2);
|
||||||
void superpose(equation const& eq);
|
void superpose(equation const& eq);
|
||||||
bool simplify_source_target(equation const& source, equation& target, bool& changed_leading_term);
|
bool simplify_source_target(equation const& source, equation& target, bool& changed_leading_term);
|
||||||
bool simplify_using(equation_set& set, equation const& eq);
|
bool simplify_using(equation_vector& set, equation const& eq);
|
||||||
bool simplify_using(equation& eq, equation_set const& eqs);
|
bool simplify_using(equation& eq, equation_vector const& eqs);
|
||||||
void toggle_processed(equation& eq);
|
|
||||||
|
|
||||||
bool eliminate(equation& eq) { return is_trivial(eq) && (del_equation(&eq), true); }
|
bool eliminate(equation& eq) { return is_trivial(eq) && (del_equation(eq), true); }
|
||||||
bool is_trivial(equation const& eq) const { return eq.poly().is_zero(); }
|
bool is_trivial(equation const& eq) const { return eq.poly().is_zero(); }
|
||||||
bool is_simpler(equation const& eq1, equation const& eq2) { return eq1.poly() < eq2.poly(); }
|
bool is_simpler(equation const& eq1, equation const& eq2) { return eq1.poly() < eq2.poly(); }
|
||||||
bool check_conflict(equation const& eq) { return eq.poly().is_val() && !is_trivial(eq) && (set_conflict(), true); }
|
bool check_conflict(equation const& eq) { return eq.poly().is_val() && !is_trivial(eq) && (set_conflict(eq), true); }
|
||||||
void set_conflict() { m_conflict = true; }
|
void set_conflict(equation const& eq) { m_conflict = &eq; }
|
||||||
bool is_too_complex(const equation& eq) const { return is_too_complex(eq.poly()); }
|
bool is_too_complex(const equation& eq) const { return is_too_complex(eq.poly()); }
|
||||||
bool is_too_complex(const pdd& p) const { return p.tree_size() > m_config.m_expr_size_limit; }
|
bool is_too_complex(const pdd& p) const { return p.tree_size() > m_config.m_expr_size_limit; }
|
||||||
|
|
||||||
|
void del_equation(equation& eq);
|
||||||
void del_equations(unsigned old_size);
|
void retire(equation* eq) { dealloc(eq); }
|
||||||
void del_equation(equation* eq);
|
void pop_equation(unsigned idx, equation_vector& v);
|
||||||
|
|
||||||
void invariant() const;
|
void invariant() const;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue