mirror of
https://github.com/Z3Prover/z3
synced 2025-07-19 10:52:02 +00:00
na
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
d247289606
commit
52d37f131d
3 changed files with 109 additions and 80 deletions
|
@ -81,8 +81,9 @@ namespace polysat {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
solver::solver(trail_stack& s):
|
solver::solver(trail_stack& s, reslimit& lim):
|
||||||
m_trail(s),
|
m_trail(s),
|
||||||
|
m_lim(lim),
|
||||||
m_bdd(1000),
|
m_bdd(1000),
|
||||||
m_dep_manager(m_value_manager, m_alloc),
|
m_dep_manager(m_value_manager, m_alloc),
|
||||||
m_conflict_dep(nullptr, m_dep_manager),
|
m_conflict_dep(nullptr, m_dep_manager),
|
||||||
|
@ -92,7 +93,7 @@ namespace polysat {
|
||||||
solver::~solver() {}
|
solver::~solver() {}
|
||||||
|
|
||||||
lbool solver::check_sat() {
|
lbool solver::check_sat() {
|
||||||
while (true) {
|
while (m_lim.inc()) {
|
||||||
if (is_conflict() && at_base_level()) return l_false;
|
if (is_conflict() && at_base_level()) return l_false;
|
||||||
else if (is_conflict()) resolve_conflict();
|
else if (is_conflict()) resolve_conflict();
|
||||||
else if (can_propagate()) propagate();
|
else if (can_propagate()) propagate();
|
||||||
|
@ -167,13 +168,19 @@ namespace polysat {
|
||||||
|
|
||||||
void solver::assign(unsigned var, unsigned index, bool value, unsigned dep) {
|
void solver::assign(unsigned var, unsigned index, bool value, unsigned dep) {
|
||||||
m_viable[var] &= value ? m_bdd.mk_var(index) : m_bdd.mk_nvar(index);
|
m_viable[var] &= value ? m_bdd.mk_var(index) : m_bdd.mk_nvar(index);
|
||||||
m_trail.push(vector_value_trail<p_dependency*, false>(m_vdeps, var));
|
add_viable_dep(var, mk_dep(dep));
|
||||||
m_vdeps[var] = m_dep_manager.mk_join(m_vdeps[var], m_dep_manager.mk_leaf(dep));
|
|
||||||
if (m_viable[var].is_false()) {
|
if (m_viable[var].is_false()) {
|
||||||
// TBD: set conflict
|
// TBD: set conflict
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void solver::add_viable_dep(unsigned var, p_dependency* dep) {
|
||||||
|
if (!dep)
|
||||||
|
return;
|
||||||
|
m_trail.push(vector_value_trail<p_dependency*, false>(m_vdeps, var));
|
||||||
|
m_vdeps[var] = m_dep_manager.mk_join(m_vdeps[var], dep);
|
||||||
|
}
|
||||||
|
|
||||||
bool solver::can_propagate() {
|
bool solver::can_propagate() {
|
||||||
return m_qhead < m_search.size() && !is_conflict();
|
return m_qhead < m_search.size() && !is_conflict();
|
||||||
}
|
}
|
||||||
|
@ -280,9 +287,11 @@ namespace polysat {
|
||||||
|
|
||||||
void solver::push_level() {
|
void solver::push_level() {
|
||||||
++m_level;
|
++m_level;
|
||||||
|
m_trail.push_scope();
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::pop_levels(unsigned num_levels) {
|
void solver::pop_levels(unsigned num_levels) {
|
||||||
|
m_trail.pop_scope(num_levels);
|
||||||
m_level -= num_levels;
|
m_level -= num_levels;
|
||||||
pop_constraints(m_constraints);
|
pop_constraints(m_constraints);
|
||||||
pop_constraints(m_redundant);
|
pop_constraints(m_redundant);
|
||||||
|
@ -304,12 +313,16 @@ namespace polysat {
|
||||||
void solver::pop_assignment() {
|
void solver::pop_assignment() {
|
||||||
while (!m_search.empty() && m_justification[m_search.back()].level() > m_level) {
|
while (!m_search.empty() && m_justification[m_search.back()].level() > m_level) {
|
||||||
auto v = m_search.back();
|
auto v = m_search.back();
|
||||||
|
undo_var(m_search.back());
|
||||||
|
m_search.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void solver::undo_var(unsigned v) {
|
||||||
m_justification[v] = justification::unassigned();
|
m_justification[v] = justification::unassigned();
|
||||||
m_free_vars.unassign_var_eh(v);
|
m_free_vars.unassign_var_eh(v);
|
||||||
m_cjust[v].reset();
|
m_cjust[v].reset();
|
||||||
m_viable[v] = m_bdd.mk_true();
|
m_viable[v] = m_bdd.mk_true();
|
||||||
m_search.pop_back();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::add_watch(constraint& c) {
|
void solver::add_watch(constraint& c) {
|
||||||
|
@ -343,20 +356,21 @@ namespace polysat {
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::decide() {
|
void solver::decide() {
|
||||||
m_trail.push_scope();
|
|
||||||
rational val;
|
rational val;
|
||||||
unsigned var;
|
|
||||||
decide(val, var);
|
|
||||||
}
|
|
||||||
|
|
||||||
void solver::decide(rational & val, unsigned& var) {
|
|
||||||
SASSERT(can_decide());
|
SASSERT(can_decide());
|
||||||
|
unsigned var = m_free_vars.next_var();
|
||||||
|
switch (find_viable(var, val)) {
|
||||||
|
case l_false:
|
||||||
|
set_conflict(m_cjust[var]);
|
||||||
|
break;
|
||||||
|
case l_true:
|
||||||
|
assign_core(var, val, justification::propagation(m_level));
|
||||||
|
break;
|
||||||
|
case l_undef:
|
||||||
push_level();
|
push_level();
|
||||||
var = m_free_vars.next_var();
|
|
||||||
auto viable = m_viable[var];
|
|
||||||
SASSERT(!viable.is_false());
|
|
||||||
// TBD, choose some value from viable and construct val.
|
|
||||||
assign_core(var, val, justification::decision(m_level));
|
assign_core(var, val, justification::decision(m_level));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::assign_core(unsigned var, rational const& val, justification const& j) {
|
void solver::assign_core(unsigned var, rational const& val, justification const& j) {
|
||||||
|
@ -368,7 +382,7 @@ namespace polysat {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Conflict resolution.
|
* Conflict resolution.
|
||||||
* - m_conflict is a constraint infeasible in the current assignment.
|
* - m_conflict are constraints that are infeasible in the current assignment.
|
||||||
* 1. walk m_search from top down until last variable in m_conflict.
|
* 1. walk m_search from top down until last variable in m_conflict.
|
||||||
* 2. resolve constraints in m_cjust to isolate lowest degree polynomials
|
* 2. resolve constraints in m_cjust to isolate lowest degree polynomials
|
||||||
* using variable.
|
* using variable.
|
||||||
|
@ -385,23 +399,7 @@ namespace polysat {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void solver::resolve_conflict() {
|
void solver::resolve_conflict() {
|
||||||
SASSERT(!m_conflict.empty());
|
vector<pdd> ps = init_conflict();
|
||||||
reset_marks();
|
|
||||||
m_conflict_level = 0;
|
|
||||||
m_conflict_dep = nullptr;
|
|
||||||
pdd p = m_conflict[0]->p();
|
|
||||||
for (constraint* c : m_conflict) {
|
|
||||||
for (auto v : c->vars())
|
|
||||||
set_mark(v);
|
|
||||||
pdd p = c->p();
|
|
||||||
m_conflict_level = std::max(m_conflict_level, c->level());
|
|
||||||
m_conflict_dep = m_dep_manager.mk_join(m_conflict_dep, c->dep());
|
|
||||||
}
|
|
||||||
// TBD: deal with case of multiple constaints
|
|
||||||
// to obtain single p or delay extracting p until resolution.
|
|
||||||
//
|
|
||||||
m_conflict.reset();
|
|
||||||
unsigned new_lemma_level = 0;
|
|
||||||
unsigned v = UINT_MAX;
|
unsigned v = UINT_MAX;
|
||||||
unsigned i = m_search.size();
|
unsigned i = m_search.size();
|
||||||
vector<std::pair<unsigned, rational>> sub;
|
vector<std::pair<unsigned, rational>> sub;
|
||||||
|
@ -418,11 +416,12 @@ namespace polysat {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (j.is_decision()) {
|
if (j.is_decision()) {
|
||||||
learn_lemma(v, p);
|
if (ps.size() == 1)
|
||||||
|
learn_lemma(v, ps[0]);
|
||||||
revert_decision(i);
|
revert_decision(i);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pdd r = resolve(v, p, new_lemma_level);
|
pdd r = resolve(v, ps);
|
||||||
pdd rval = r.subst_val(sub);
|
pdd rval = r.subst_val(sub);
|
||||||
if (r.is_val() && rval.is_non_zero()) {
|
if (r.is_val() && rval.is_non_zero()) {
|
||||||
report_unsat();
|
report_unsat();
|
||||||
|
@ -436,12 +435,29 @@ namespace polysat {
|
||||||
reset_marks();
|
reset_marks();
|
||||||
for (auto w : r.free_vars())
|
for (auto w : r.free_vars())
|
||||||
set_mark(w);
|
set_mark(w);
|
||||||
p = r;
|
ps.shrink(1);
|
||||||
m_conflict_level = new_lemma_level;
|
ps[0] = r;
|
||||||
}
|
}
|
||||||
report_unsat();
|
report_unsat();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<pdd> solver::init_conflict() {
|
||||||
|
SASSERT(!m_conflict.empty());
|
||||||
|
vector<pdd> ps;
|
||||||
|
reset_marks();
|
||||||
|
m_conflict_level = 0;
|
||||||
|
m_conflict_dep = nullptr;
|
||||||
|
for (auto* c : m_conflict) {
|
||||||
|
for (auto v : c->vars())
|
||||||
|
set_mark(v);
|
||||||
|
ps.push_back(c->p());
|
||||||
|
m_conflict_level = std::max(m_conflict_level, c->level());
|
||||||
|
m_conflict_dep = m_dep_manager.mk_join(m_conflict_dep, c->dep());
|
||||||
|
}
|
||||||
|
m_conflict.reset();
|
||||||
|
return ps;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TBD: m_conflict_dep is a justification that m_value[v] is not viable.
|
* TBD: m_conflict_dep is a justification that m_value[v] is not viable.
|
||||||
* it is currently not yet being accounted for.
|
* it is currently not yet being accounted for.
|
||||||
|
@ -498,14 +514,20 @@ namespace polysat {
|
||||||
void solver::revert_decision(unsigned i) {
|
void solver::revert_decision(unsigned i) {
|
||||||
auto v = m_search[i];
|
auto v = m_search[i];
|
||||||
SASSERT(m_justification[v].is_decision());
|
SASSERT(m_justification[v].is_decision());
|
||||||
add_non_viable(v, m_value[v]);
|
|
||||||
|
|
||||||
// TBD how much to backjump to be clarified
|
|
||||||
// everything before v is reverted, but not assignment
|
|
||||||
// to v. This is different from propositional CDCL
|
|
||||||
// where decision on v is also reverted.
|
|
||||||
unsigned new_level = m_justification[v].level();
|
unsigned new_level = m_justification[v].level();
|
||||||
backjump(new_level);
|
if (new_level < m_level)
|
||||||
|
backjump(new_level + 1);
|
||||||
|
while (m_search.back() != v) {
|
||||||
|
undo_var(m_search.back());
|
||||||
|
m_search.pop_back();
|
||||||
|
}
|
||||||
|
SASSERT(!m_search.empty());
|
||||||
|
SASSERT(m_search.back() == v);
|
||||||
|
m_search.pop_back();
|
||||||
|
add_non_viable(v, m_value[v]);
|
||||||
|
add_viable_dep(v, m_conflict_dep);
|
||||||
|
m_qhead = m_search.size();
|
||||||
rational value;
|
rational value;
|
||||||
m_conflict_dep = nullptr;
|
m_conflict_dep = nullptr;
|
||||||
switch (find_viable(v, value)) {
|
switch (find_viable(v, value)) {
|
||||||
|
@ -523,10 +545,8 @@ namespace polysat {
|
||||||
|
|
||||||
void solver::backjump(unsigned new_level) {
|
void solver::backjump(unsigned new_level) {
|
||||||
unsigned num_levels = m_level - new_level;
|
unsigned num_levels = m_level - new_level;
|
||||||
if (num_levels > 0) {
|
if (num_levels > 0)
|
||||||
pop_levels(num_levels);
|
pop_levels(num_levels);
|
||||||
m_trail.pop_scope(num_levels);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -534,12 +554,9 @@ namespace polysat {
|
||||||
* producing polynomial that isolates v to lowest degree
|
* producing polynomial that isolates v to lowest degree
|
||||||
* and lowest power of 2.
|
* and lowest power of 2.
|
||||||
*/
|
*/
|
||||||
pdd solver::isolate(unsigned v) {
|
pdd solver::isolate(unsigned v, vector<pdd> const& ps) {
|
||||||
if (m_cjust[v].empty())
|
pdd p = ps[0];
|
||||||
return sz2pdd(m_size[v]).zero();
|
for (unsigned i = ps.size(); i-- > 1; ) {
|
||||||
auto const& cs = m_cjust[v];
|
|
||||||
pdd p = cs[0]->p();
|
|
||||||
for (unsigned i = cs.size(); i-- > 1; ) {
|
|
||||||
// TBD reduce with respect to v
|
// TBD reduce with respect to v
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
|
@ -548,18 +565,17 @@ namespace polysat {
|
||||||
/**
|
/**
|
||||||
* Return residue of superposing p and q with respect to v.
|
* Return residue of superposing p and q with respect to v.
|
||||||
*/
|
*/
|
||||||
pdd solver::resolve(unsigned v, pdd const& p, unsigned& resolve_level) {
|
pdd solver::resolve(unsigned v, vector<pdd> const& ps) {
|
||||||
resolve_level = 0;
|
|
||||||
auto degree = p.degree(v);
|
|
||||||
auto const& cs = m_cjust[v];
|
auto const& cs = m_cjust[v];
|
||||||
pdd r = p;
|
pdd r = isolate(v, ps);
|
||||||
|
auto degree = r.degree(v);
|
||||||
while (degree > 0) {
|
while (degree > 0) {
|
||||||
for (auto * c : cs) {
|
for (auto * c : cs) {
|
||||||
if (degree >= c->p().degree(v)) {
|
if (degree >= c->p().degree(v)) {
|
||||||
// TODO binary resolve, update r using result
|
// TODO binary resolve, update r using result
|
||||||
// add parity condition to presere falsification
|
// add parity condition to presere falsification
|
||||||
degree = r.degree(v);
|
degree = r.degree(v);
|
||||||
resolve_level = std::max(resolve_level, c->level());
|
m_conflict_level = std::max(m_conflict_level, c->level());
|
||||||
m_conflict_dep = m_dep_manager.mk_join(m_conflict_dep.get(), c->dep());
|
m_conflict_dep = m_dep_manager.mk_join(m_conflict_dep.get(), c->dep());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -591,11 +607,11 @@ namespace polysat {
|
||||||
|
|
||||||
void solver::push() {
|
void solver::push() {
|
||||||
push_level();
|
push_level();
|
||||||
m_scopes.push_back(m_level);
|
m_base_levels.push_back(m_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::pop(unsigned num_scopes) {
|
void solver::pop(unsigned num_scopes) {
|
||||||
unsigned base_level = m_scopes[m_scopes.size() - num_scopes];
|
unsigned base_level = m_base_levels[m_base_levels.size() - num_scopes];
|
||||||
pop_levels(m_level - base_level - 1);
|
pop_levels(m_level - base_level - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -604,7 +620,7 @@ namespace polysat {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned solver::base_level() const {
|
unsigned solver::base_level() const {
|
||||||
return m_scopes.empty() ? 0 : m_scopes.back();
|
return m_base_levels.empty() ? 0 : m_base_levels.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& solver::display(std::ostream& out) const {
|
std::ostream& solver::display(std::ostream& out) const {
|
||||||
|
|
|
@ -19,6 +19,7 @@ Author:
|
||||||
#include "util/dependency.h"
|
#include "util/dependency.h"
|
||||||
#include "util/trail.h"
|
#include "util/trail.h"
|
||||||
#include "util/lbool.h"
|
#include "util/lbool.h"
|
||||||
|
#include "util/rlimit.h"
|
||||||
#include "util/scoped_ptr_vector.h"
|
#include "util/scoped_ptr_vector.h"
|
||||||
#include "util/var_queue.h"
|
#include "util/var_queue.h"
|
||||||
#include "math/dd/dd_pdd.h"
|
#include "math/dd/dd_pdd.h"
|
||||||
|
@ -114,6 +115,7 @@ namespace polysat {
|
||||||
typedef ptr_vector<constraint> constraints;
|
typedef ptr_vector<constraint> constraints;
|
||||||
|
|
||||||
trail_stack& m_trail;
|
trail_stack& m_trail;
|
||||||
|
reslimit& m_lim;
|
||||||
scoped_ptr_vector<dd::pdd_manager> m_pdd;
|
scoped_ptr_vector<dd::pdd_manager> m_pdd;
|
||||||
dd::bdd_manager m_bdd;
|
dd::bdd_manager m_bdd;
|
||||||
dep_value_manager m_value_manager;
|
dep_value_manager m_value_manager;
|
||||||
|
@ -142,7 +144,7 @@ namespace polysat {
|
||||||
unsigned m_qhead { 0 };
|
unsigned m_qhead { 0 };
|
||||||
unsigned m_level { 0 };
|
unsigned m_level { 0 };
|
||||||
|
|
||||||
unsigned_vector m_scopes; // user-scopes. External clients can push/pop scope.
|
unsigned_vector m_base_levels; // External clients can push/pop scope.
|
||||||
|
|
||||||
|
|
||||||
// conflict state
|
// conflict state
|
||||||
|
@ -159,6 +161,11 @@ namespace polysat {
|
||||||
*/
|
*/
|
||||||
void add_non_viable(unsigned var, rational const& val);
|
void add_non_viable(unsigned var, rational const& val);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add dependency for variable viable range.
|
||||||
|
*/
|
||||||
|
void add_viable_dep(unsigned var, p_dependency* dep);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a next viable value for varible.
|
* Find a next viable value for varible.
|
||||||
|
@ -206,8 +213,10 @@ namespace polysat {
|
||||||
|
|
||||||
unsigned m_conflict_level { 0 };
|
unsigned m_conflict_level { 0 };
|
||||||
|
|
||||||
pdd isolate(unsigned v);
|
pdd isolate(unsigned v, vector<pdd> const& ps);
|
||||||
pdd resolve(unsigned v, pdd const& p, unsigned& resolve_level);
|
pdd resolve(unsigned v, vector<pdd> const& ps);
|
||||||
|
|
||||||
|
bool can_decide() const { return !m_free_vars.empty(); }
|
||||||
void decide();
|
void decide();
|
||||||
|
|
||||||
p_dependency* mk_dep(unsigned dep) { return dep == null_dependency ? nullptr : m_dep_manager.mk_leaf(dep); }
|
p_dependency* mk_dep(unsigned dep) { return dep == null_dependency ? nullptr : m_dep_manager.mk_leaf(dep); }
|
||||||
|
@ -216,16 +225,16 @@ namespace polysat {
|
||||||
bool at_base_level() const;
|
bool at_base_level() const;
|
||||||
unsigned base_level() const;
|
unsigned base_level() const;
|
||||||
|
|
||||||
|
vector<pdd> init_conflict();
|
||||||
void resolve_conflict();
|
void resolve_conflict();
|
||||||
void backtrack(unsigned i);
|
void backtrack(unsigned i);
|
||||||
void report_unsat();
|
void report_unsat();
|
||||||
void revert_decision(unsigned i);
|
void revert_decision(unsigned i);
|
||||||
void learn_lemma(unsigned v, pdd const& p);
|
void learn_lemma(unsigned v, pdd const& p);
|
||||||
void backjump(unsigned new_level);
|
void backjump(unsigned new_level);
|
||||||
|
void undo_var(unsigned v);
|
||||||
void add_lemma(constraint* c);
|
void add_lemma(constraint* c);
|
||||||
|
|
||||||
bool can_decide() const { return !m_free_vars.empty(); }
|
|
||||||
void decide(rational & val, unsigned& var);
|
|
||||||
|
|
||||||
|
|
||||||
bool invariant();
|
bool invariant();
|
||||||
|
@ -238,7 +247,7 @@ namespace polysat {
|
||||||
* every update to the solver is going to be retractable
|
* every update to the solver is going to be retractable
|
||||||
* by pushing an undo action on the trail stack.
|
* by pushing an undo action on the trail stack.
|
||||||
*/
|
*/
|
||||||
solver(trail_stack& s);
|
solver(trail_stack& s, reslimit& lim);
|
||||||
|
|
||||||
~solver();
|
~solver();
|
||||||
|
|
||||||
|
|
|
@ -5,14 +5,21 @@ namespace polysat {
|
||||||
// test resolve, factoring routines
|
// test resolve, factoring routines
|
||||||
// auxiliary
|
// auxiliary
|
||||||
|
|
||||||
|
struct solver_scope {
|
||||||
|
reslimit lim;
|
||||||
|
trail_stack stack;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct scoped_solver : public solver_scope, public solver {
|
||||||
|
scoped_solver(): solver(stack, lim) {}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This one is unsat because a*a*(a*a - 1)
|
* This one is unsat because a*a*(a*a - 1)
|
||||||
* is 0 for all values of a.
|
* is 0 for all values of a.
|
||||||
*/
|
*/
|
||||||
static void test_eq1() {
|
static void test_eq1() {
|
||||||
trail_stack stack;
|
scoped_solver s;
|
||||||
solver s(stack);
|
|
||||||
auto a = s.var(s.add_var(2));
|
auto a = s.var(s.add_var(2));
|
||||||
auto p = a*a*(a*a - 1) + 1;
|
auto p = a*a*(a*a - 1) + 1;
|
||||||
s.add_eq(p);
|
s.add_eq(p);
|
||||||
|
@ -23,8 +30,7 @@ namespace polysat {
|
||||||
* has solution a = 3
|
* has solution a = 3
|
||||||
*/
|
*/
|
||||||
static void test_eq2() {
|
static void test_eq2() {
|
||||||
trail_stack stack;
|
scoped_solver s;
|
||||||
solver s(stack);
|
|
||||||
auto a = s.var(s.add_var(2));
|
auto a = s.var(s.add_var(2));
|
||||||
auto p = a*(a-1) + 2;
|
auto p = a*(a-1) + 2;
|
||||||
s.add_eq(p);
|
s.add_eq(p);
|
||||||
|
@ -38,8 +44,7 @@ namespace polysat {
|
||||||
* v*q > u
|
* v*q > u
|
||||||
*/
|
*/
|
||||||
static void test_ineq1() {
|
static void test_ineq1() {
|
||||||
trail_stack stack;
|
scoped_solver s;
|
||||||
solver s(stack);
|
|
||||||
auto u = s.var(s.add_var(5));
|
auto u = s.var(s.add_var(5));
|
||||||
auto v = s.var(s.add_var(5));
|
auto v = s.var(s.add_var(5));
|
||||||
auto q = s.var(s.add_var(5));
|
auto q = s.var(s.add_var(5));
|
||||||
|
@ -57,8 +62,7 @@ namespace polysat {
|
||||||
* n > r2 > 0
|
* n > r2 > 0
|
||||||
*/
|
*/
|
||||||
static void test_ineq2() {
|
static void test_ineq2() {
|
||||||
trail_stack stack;
|
scoped_solver s;
|
||||||
solver s(stack);
|
|
||||||
auto n = s.var(s.add_var(5));
|
auto n = s.var(s.add_var(5));
|
||||||
auto q1 = s.var(s.add_var(5));
|
auto q1 = s.var(s.add_var(5));
|
||||||
auto a = s.var(s.add_var(5));
|
auto a = s.var(s.add_var(5));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue