mirror of
https://github.com/Z3Prover/z3
synced 2025-04-12 04:03:39 +00:00
binspr
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
e212159f4e
commit
e818b8d06f
|
@ -5,6 +5,7 @@ z3_add_component(sat
|
||||||
sat_asymm_branch.cpp
|
sat_asymm_branch.cpp
|
||||||
sat_bdd.cpp
|
sat_bdd.cpp
|
||||||
sat_big.cpp
|
sat_big.cpp
|
||||||
|
sat_binspr.cpp
|
||||||
sat_clause.cpp
|
sat_clause.cpp
|
||||||
sat_clause_set.cpp
|
sat_clause_set.cpp
|
||||||
sat_clause_use_list.cpp
|
sat_clause_use_list.cpp
|
||||||
|
|
463
src/sat/sat_binspr.cpp
Normal file
463
src/sat/sat_binspr.cpp
Normal file
|
@ -0,0 +1,463 @@
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2019 Microsoft Corporation
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
sat_binspr.cpp
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Inprocessing step for creating SPR binary clauses.
|
||||||
|
|
||||||
|
Author:
|
||||||
|
|
||||||
|
Nikolaj Bjorner, Marijn Heule 2019-4-29
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
|
||||||
|
L = { lit1, lit2 }
|
||||||
|
G := { touched_L(C) | C in F and C intersects with L, and not F|L |-_unit untouch_L(C) }
|
||||||
|
G & ~L is satisfiable
|
||||||
|
------------
|
||||||
|
Learn ~lit1 or ~lit2
|
||||||
|
|
||||||
|
|
||||||
|
Marijn's version:
|
||||||
|
|
||||||
|
L = { lit1, lit2 }
|
||||||
|
alpha = L + units in F|L
|
||||||
|
G := { touched_alpha(C) | C in F and C intersects with L, and not F|L |-_unit untouch_alpha(C) }
|
||||||
|
G & ~L is satisfiable
|
||||||
|
---------------------
|
||||||
|
Learn ~L
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Alternative:
|
||||||
|
|
||||||
|
for p in literals:
|
||||||
|
push(1)
|
||||||
|
propagate(p)
|
||||||
|
candidates = literals \ units
|
||||||
|
for (C or p) in use(p) and candidates != empty:
|
||||||
|
push(1)
|
||||||
|
propagate(~C)
|
||||||
|
if inconsistent():
|
||||||
|
learn C (subsumes C or p)
|
||||||
|
else:
|
||||||
|
candidates' := C union ~(consequencs of propagate(~C))
|
||||||
|
candidates := candidates' intersect candidates
|
||||||
|
pop(1)
|
||||||
|
for q in candidates:
|
||||||
|
add (~q or ~p)
|
||||||
|
pop(1)
|
||||||
|
|
||||||
|
The idea is that all clauses using p must satisfy
|
||||||
|
q in C or F|pq |-1 untouched(C)
|
||||||
|
The clauses that contain q are not restricted: We directly create G := (~p or ~q) & q, which is satisfiable
|
||||||
|
Let pqM |= F, we claim then that ~pqM |= F
|
||||||
|
|
||||||
|
- every clause (C or q) that contains q is satisfied by ~pqM
|
||||||
|
- every clause (C or p) that does not contain q positively, but contains p satisfies F|pq |-1 untouched(C)
|
||||||
|
Therefore pqM |= untouched(C) and therefore already M |= untouched(C)
|
||||||
|
- all other clauses are satisfied by pqM, but contain neither p, nor q,
|
||||||
|
so it is already the case that M satisfies the clause.
|
||||||
|
|
||||||
|
Alternative:
|
||||||
|
|
||||||
|
for p in literals:
|
||||||
|
push(1)
|
||||||
|
propagate(p)
|
||||||
|
candidates = {}
|
||||||
|
for (C or p) in use(p):
|
||||||
|
push(1)
|
||||||
|
propagate(~C)
|
||||||
|
if inconsistent():
|
||||||
|
learn C (subsumes C or p)
|
||||||
|
else:
|
||||||
|
candidates := candicates union C union ~(consequencs of propagate(~C))
|
||||||
|
pop(1)
|
||||||
|
for q in candidates:
|
||||||
|
push(1)
|
||||||
|
propagate(q)
|
||||||
|
incons := true
|
||||||
|
for (C or p) in use(p) and incons:
|
||||||
|
push(1)
|
||||||
|
propagate(~C)
|
||||||
|
incons := inconsistent()
|
||||||
|
pop(1)
|
||||||
|
pop(1)
|
||||||
|
if incons:
|
||||||
|
add (~p or ~q)
|
||||||
|
pop(1)
|
||||||
|
|
||||||
|
The idea is similar to the previous alternative, but it allows a candidate to
|
||||||
|
not be directly unit derivable in all clauses C or p, but could be a failed literal
|
||||||
|
under the assumption ~C.
|
||||||
|
The motivation for this variant is that it is unlikely that we need failed literals to
|
||||||
|
close both (C_1 or p),..., (C_n or p) for all clauses containing p.
|
||||||
|
|
||||||
|
Alternative:
|
||||||
|
|
||||||
|
|
||||||
|
1. extract BIG
|
||||||
|
Use BIG to limit cone enumeration
|
||||||
|
2. for each literal lit:
|
||||||
|
enumerate k1 in cone of lit
|
||||||
|
enumerate lit2 in use(~k1)
|
||||||
|
check if cone of lit2 contains k2 such that lit1 in use(~k2)
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include "sat/sat_binspr.h"
|
||||||
|
#include "sat/sat_solver.h"
|
||||||
|
#include "sat/sat_big.h"
|
||||||
|
|
||||||
|
namespace sat {
|
||||||
|
|
||||||
|
struct binspr::report {
|
||||||
|
binspr& m_binspr;
|
||||||
|
stopwatch m_watch;
|
||||||
|
report(binspr& b):
|
||||||
|
m_binspr(b) {
|
||||||
|
m_watch.start();
|
||||||
|
}
|
||||||
|
~report() {
|
||||||
|
m_watch.stop();
|
||||||
|
unsigned nb = m_binspr.m_bin_clauses;
|
||||||
|
IF_VERBOSE(2, verbose_stream() << " (sat-binspr :binary " << nb << m_watch << ")\n");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void binspr::operator()() {
|
||||||
|
unsigned num = s.num_vars();
|
||||||
|
m_bin_clauses = 0;
|
||||||
|
|
||||||
|
report _rep(*this);
|
||||||
|
m_use_list.reset();
|
||||||
|
m_use_list.reserve(num*2);
|
||||||
|
for (clause* c : s.m_clauses) {
|
||||||
|
if (!c->frozen() && !c->was_removed()) {
|
||||||
|
for (literal lit : *c) {
|
||||||
|
m_use_list[lit.index()].push_back(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TRACE("sat", s.display(tout););
|
||||||
|
algorithm2();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
F, p |- ~u,
|
||||||
|
F, p, q |- ~v,
|
||||||
|
{ p, v } u C in F
|
||||||
|
{ q, u } u D in F
|
||||||
|
|
||||||
|
Then use { p, ~u, q, ~v } as alpha, L = { p, q }
|
||||||
|
|
||||||
|
for u in ~consequences of p:
|
||||||
|
for (u u D) in use(u):
|
||||||
|
for q in D, unassigned:
|
||||||
|
for v in ~consequences(q) | ({p, v} u C) in use(v):
|
||||||
|
check_spr(p, q, u, v)
|
||||||
|
*/
|
||||||
|
|
||||||
|
void binspr::algorithm2() {
|
||||||
|
mk_masks();
|
||||||
|
unsigned num_lits = 2 * s.num_vars();
|
||||||
|
for (unsigned l_idx = 0; l_idx < num_lits && !s.inconsistent(); ++l_idx) {
|
||||||
|
s.checkpoint();
|
||||||
|
literal p = to_literal(l_idx);
|
||||||
|
TRACE("sat", tout << "p " << p << " " << s.value(p) << "\n";);
|
||||||
|
if (is_used(p) && s.value(p) == l_undef) {
|
||||||
|
s.push();
|
||||||
|
s.assign_scoped(p);
|
||||||
|
unsigned sz_p = s.m_trail.size();
|
||||||
|
s.propagate(false);
|
||||||
|
if (s.inconsistent()) {
|
||||||
|
s.pop(1);
|
||||||
|
s.assign_unit(~p);
|
||||||
|
s.propagate(false);
|
||||||
|
TRACE("sat", s.display(tout << "unit\n"););
|
||||||
|
IF_VERBOSE(0, verbose_stream() << "unit " << (~p) << "\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (unsigned i = sz_p; !s.inconsistent() && i < s.m_trail.size(); ++i) {
|
||||||
|
literal u = ~s.m_trail[i];
|
||||||
|
TRACE("sat", tout << "p " << p << " u " << u << "\n";);
|
||||||
|
for (clause* cp : m_use_list[u.index()]) {
|
||||||
|
for (literal q : *cp) {
|
||||||
|
if (s.inconsistent())
|
||||||
|
break;
|
||||||
|
if (s.value(q) != l_undef)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
s.push();
|
||||||
|
s.assign_scoped(q);
|
||||||
|
unsigned sz_q = s.m_trail.size();
|
||||||
|
s.propagate(false);
|
||||||
|
if (s.inconsistent()) {
|
||||||
|
// learn ~p or ~q
|
||||||
|
s.pop(1);
|
||||||
|
block_binary(p, q, true);
|
||||||
|
s.propagate(false);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
bool found = false;
|
||||||
|
for (unsigned j = sz_q; !found && j < s.m_trail.size(); ++j) {
|
||||||
|
literal v = ~s.m_trail[j];
|
||||||
|
for (clause* cp2 : m_use_list[v.index()]) {
|
||||||
|
if (cp2->contains(p)) {
|
||||||
|
if (check_spr(p, q, u, v)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.pop(1);
|
||||||
|
if (found) {
|
||||||
|
block_binary(p, q, false);
|
||||||
|
s.propagate(false);
|
||||||
|
TRACE("sat", s.display(tout););
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.pop(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool binspr::is_used(literal lit) const {
|
||||||
|
return !m_use_list[lit.index()].empty() || !s.get_wlist(~lit).empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool binspr::check_spr(literal p, literal q, literal u, literal v) {
|
||||||
|
SASSERT(s.value(p) == l_true);
|
||||||
|
SASSERT(s.value(q) == l_true);
|
||||||
|
SASSERT(s.value(u) == l_false);
|
||||||
|
SASSERT(s.value(v) == l_false);
|
||||||
|
init_g(p, q, u, v);
|
||||||
|
literal lits[4] = { p, q, ~u, ~v };
|
||||||
|
for (unsigned i = 0; g_is_sat() && i < 4; ++i) {
|
||||||
|
binary_are_unit_implied(lits[i]);
|
||||||
|
clauses_are_unit_implied(lits[i]);
|
||||||
|
}
|
||||||
|
TRACE("sat", tout << p << " " << q << " " << u << " " << v << " " << g_is_sat() << "\n";);
|
||||||
|
return g_is_sat();
|
||||||
|
}
|
||||||
|
|
||||||
|
void binspr::binary_are_unit_implied(literal p) {
|
||||||
|
for (watched const& w : s.get_wlist(~p)) {
|
||||||
|
if (!g_is_sat()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!w.is_binary_non_learned_clause()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_alpha();
|
||||||
|
VERIFY(touch(p));
|
||||||
|
literal lit = w.get_literal();
|
||||||
|
SASSERT(lit != p);
|
||||||
|
|
||||||
|
if (touch(lit)) {
|
||||||
|
add_touched();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool inconsistent = (s.value(lit) == l_true);
|
||||||
|
if (s.value(lit) == l_undef) {
|
||||||
|
s.push();
|
||||||
|
s.assign_scoped(~lit);
|
||||||
|
s.propagate(false);
|
||||||
|
inconsistent = s.inconsistent();
|
||||||
|
s.pop(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inconsistent) {
|
||||||
|
TRACE("sat", tout << "not implied: " << p << " " << lit << "\n";);
|
||||||
|
m_state = 0;
|
||||||
|
add_touched();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void binspr::clauses_are_unit_implied(literal p) {
|
||||||
|
for (clause* cp : m_use_list[p.index()]) {
|
||||||
|
if (!g_is_sat()) break;
|
||||||
|
clause_is_unit_implied(*cp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void binspr::clause_is_unit_implied(clause const& c) {
|
||||||
|
s.push();
|
||||||
|
clear_alpha();
|
||||||
|
for (literal lit : c) {
|
||||||
|
if (touch(lit)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (s.value(lit) == l_true) {
|
||||||
|
s.pop(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (s.value(lit) != l_false) {
|
||||||
|
s.assign_scoped(~lit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.propagate(false);
|
||||||
|
bool inconsistent = s.inconsistent();
|
||||||
|
s.pop(1);
|
||||||
|
if (!inconsistent) {
|
||||||
|
add_touched();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void binspr::block_binary(literal lit1, literal lit2, bool learned) {
|
||||||
|
IF_VERBOSE(2, verbose_stream() << "SPR: " << learned << " " << ~lit1 << " " << ~lit2 << "\n");
|
||||||
|
TRACE("sat", tout << "SPR: " << learned << " " << ~lit1 << " " << ~lit2 << "\n";);
|
||||||
|
s.mk_clause(~lit1, ~lit2, learned);
|
||||||
|
++m_bin_clauses;
|
||||||
|
}
|
||||||
|
|
||||||
|
void binspr::g_add_unit(literal lit1, literal lit2) {
|
||||||
|
if (lit1.var() < lit2.var()) {
|
||||||
|
m_state &= 0x2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_state &= 0x4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void binspr::g_add_binary(literal lit1, literal lit2, bool flip2) {
|
||||||
|
bool flip1 = false;
|
||||||
|
if (lit1.var() > lit2.var()) { std::swap(flip1, flip2); }
|
||||||
|
m_state &= ((flip1?0x5:0xA) | (flip2?0x3:0xC));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0 -> 10
|
||||||
|
// 1 -> 01
|
||||||
|
// * -> 11
|
||||||
|
// 00 -> 1000
|
||||||
|
// 10 -> 0100
|
||||||
|
// 01 -> 0010
|
||||||
|
// 11 -> 0001
|
||||||
|
// *1 -> 00110011
|
||||||
|
// *0 -> 11001100
|
||||||
|
// 0* -> 10101010
|
||||||
|
// 1* -> 01010101
|
||||||
|
// **1 -> 00001111
|
||||||
|
// **0 -> 11110000
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief create masks (lsb is left)
|
||||||
|
i = 0: 1010101010101010
|
||||||
|
i = 1: 1100110011001100
|
||||||
|
i = 2: 1111000011110000
|
||||||
|
*/
|
||||||
|
unsigned binspr::mk_mask(unsigned i) {
|
||||||
|
// variable number i is false.
|
||||||
|
unsigned mask0 = (1 << (1 << i)) - 1; // 2^i bits of ones
|
||||||
|
unsigned pos = 1 << (i+1); // how many bits in mask
|
||||||
|
|
||||||
|
unsigned mask = mask0;
|
||||||
|
while (pos < 32) {
|
||||||
|
mask |= (mask0 << pos);
|
||||||
|
pos += 1 << (i + 1);
|
||||||
|
}
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void binspr::mk_masks() {
|
||||||
|
for (unsigned i = 0; i < max_lits; ++i) {
|
||||||
|
m_false[i] = mk_mask(i);
|
||||||
|
m_true[i] = m_false[i] << (1 << i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief create Boolean function table
|
||||||
|
corresponding to disjunction of literals
|
||||||
|
*/
|
||||||
|
|
||||||
|
void binspr::add_touched() {
|
||||||
|
|
||||||
|
unsigned mask = 0;
|
||||||
|
for (unsigned i = 0; i < 4; ++i) {
|
||||||
|
switch (m_vals[i]) {
|
||||||
|
case l_true:
|
||||||
|
mask |= m_true[i];
|
||||||
|
break;
|
||||||
|
case l_false:
|
||||||
|
mask |= m_false[i];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool first = m_state == ~0;
|
||||||
|
m_state &= mask;
|
||||||
|
TRACE("sat",
|
||||||
|
{
|
||||||
|
bool_var vars[4];
|
||||||
|
vars[0] = m_p; vars[1] = m_q; vars[2] = m_u; vars[3] = m_v;
|
||||||
|
tout << "touched: ";
|
||||||
|
for (unsigned i = 0; i < 4; ++i) {
|
||||||
|
switch (m_vals[i]) {
|
||||||
|
case l_true:
|
||||||
|
tout << literal(vars[i], false) << " ";
|
||||||
|
break;
|
||||||
|
case l_false:
|
||||||
|
tout << literal(vars[i], true) << " ";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
display_mask(tout << " ", m_state);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void binspr::init_g(literal p, literal q, literal u, literal v) {
|
||||||
|
m_p = p.var();
|
||||||
|
m_q = q.var();
|
||||||
|
m_u = u.var();
|
||||||
|
m_v = v.var();
|
||||||
|
m_state = ~0;
|
||||||
|
clear_alpha();
|
||||||
|
VERIFY(touch(~p));
|
||||||
|
VERIFY(touch(~q));
|
||||||
|
add_touched();
|
||||||
|
}
|
||||||
|
|
||||||
|
void binspr::clear_alpha() {
|
||||||
|
m_vals[0] = m_vals[1] = m_vals[2] = m_vals[3] = l_undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool binspr::touch(literal p) {
|
||||||
|
bool_var v = p.var();
|
||||||
|
if (v == m_p) m_vals[0] = to_lbool(!p.sign());
|
||||||
|
else if (v == m_q) m_vals[1] = to_lbool(!p.sign());
|
||||||
|
else if (v == m_u) m_vals[2] = to_lbool(!p.sign());
|
||||||
|
else if (v == m_v) m_vals[3] = to_lbool(!p.sign());
|
||||||
|
else return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& binspr::display_mask(std::ostream& out, unsigned mask) const {
|
||||||
|
for (unsigned i = 0; i < 4; ++i) {
|
||||||
|
out << m_vals[i] << " ";
|
||||||
|
}
|
||||||
|
out << " - ";
|
||||||
|
for (unsigned i = 0; i < 32; ++i) {
|
||||||
|
out << (0 != (mask & (1 << i)) ? 1 : 0);
|
||||||
|
}
|
||||||
|
return out << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
108
src/sat/sat_binspr.h
Normal file
108
src/sat/sat_binspr.h
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
/*++
|
||||||
|
Copyright (c) 2019 Microsoft Corporation
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
sat_binspr.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
Inprocessing step for creating SPR binary clauses.
|
||||||
|
|
||||||
|
Author:
|
||||||
|
|
||||||
|
Nikolaj Bjorner, Marijn Heule 2019-4-29
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
|
||||||
|
--*/
|
||||||
|
#ifndef _SAT_BINSPR_
|
||||||
|
#define _SAT_BINSPR_
|
||||||
|
|
||||||
|
#include "util/params.h"
|
||||||
|
#include "util/statistics.h"
|
||||||
|
#include "sat/sat_clause.h"
|
||||||
|
#include "sat/sat_types.h"
|
||||||
|
|
||||||
|
namespace sat {
|
||||||
|
class solver;
|
||||||
|
|
||||||
|
class binspr {
|
||||||
|
enum states {
|
||||||
|
unit = 0xA, // 1010
|
||||||
|
unit_or_other_nunit = 0xB, // 1011
|
||||||
|
either = 0xE, // 1110
|
||||||
|
nand = 0x7, // 0111
|
||||||
|
not_pr = 0x0
|
||||||
|
};
|
||||||
|
|
||||||
|
solver& s;
|
||||||
|
unsigned m_bin_clauses;
|
||||||
|
unsigned m_stopped_at;
|
||||||
|
vector<clause_vector> m_use_list;
|
||||||
|
unsigned m_limit1, m_limit2;
|
||||||
|
svector<bool> m_mark, m_mark2;
|
||||||
|
literal_vector m_must_candidates, m_may_candidates;
|
||||||
|
unsigned m_state;
|
||||||
|
|
||||||
|
void init_g() { m_state = 0x7; }
|
||||||
|
void g_add_binary(literal l1, literal l2, bool flip2);
|
||||||
|
void g_add_unit(literal l1, literal l2); // l1 is a unit
|
||||||
|
bool g_is_sat() { return m_state != 0; }
|
||||||
|
|
||||||
|
void init_g(literal p, literal q, literal u, literal v);
|
||||||
|
|
||||||
|
|
||||||
|
struct report;
|
||||||
|
|
||||||
|
void block_binary(literal lit1, literal lit2, bool learned);
|
||||||
|
void double_lookahead();
|
||||||
|
|
||||||
|
void check_spr_single_lookahead(literal lit);
|
||||||
|
void check_spr(literal lit1);
|
||||||
|
void check_spr(literal lit1, literal lit2);
|
||||||
|
bool check_spr(literal p, literal q, literal s, literal r);
|
||||||
|
void binary_are_unit_implied(literal lit1, literal lit2);
|
||||||
|
void clauses_are_unit_implied(literal lit1, literal lit2);
|
||||||
|
void clause_is_unit_implied(literal lit1, literal lit2, clause& c);
|
||||||
|
bool is_used(literal lit) const;
|
||||||
|
void update_candidates(bool& first, unsigned sz1);
|
||||||
|
void collect_candidates(literal lit, literal const* begin, literal const* end);
|
||||||
|
void strengthen_clause(literal lit, literal const* begin, literal const* end);
|
||||||
|
|
||||||
|
bool_var m_p, m_q, m_u, m_v;
|
||||||
|
lbool m_vals[4];
|
||||||
|
|
||||||
|
void algorithm2();
|
||||||
|
void algorithm2(literal lit, clause const& c);
|
||||||
|
void clear_alpha();
|
||||||
|
void add_touched();
|
||||||
|
bool touch(literal p);
|
||||||
|
void binary_are_unit_implied(literal p);
|
||||||
|
void clauses_are_unit_implied(literal p);
|
||||||
|
void clause_is_unit_implied(clause const& c);
|
||||||
|
static const unsigned max_lits = 5; // = log(32)
|
||||||
|
unsigned m_true[max_lits], m_false[max_lits];
|
||||||
|
unsigned mk_function(svector<lbool> const& lits);
|
||||||
|
void mk_masks();
|
||||||
|
unsigned mk_mask(unsigned i);
|
||||||
|
|
||||||
|
std::ostream& display_mask(std::ostream& out, unsigned mask) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
binspr(solver& s, params_ref const& p): s(s), m_stopped_at(0), m_limit1(1000), m_limit2(300) {}
|
||||||
|
|
||||||
|
~binspr() {}
|
||||||
|
|
||||||
|
void operator()();
|
||||||
|
|
||||||
|
void updt_params(params_ref const& p) {}
|
||||||
|
|
||||||
|
void collect_statistics(statistics& st) const {}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue