3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-12 20:18:18 +00:00

introduce globally visible macro for controlling use of ternary, turn them off

This commit is contained in:
Nikolaj Bjorner 2022-10-25 10:30:18 -07:00
parent c62c5e9d23
commit 154fed7783
7 changed files with 55 additions and 6 deletions

View file

@ -445,8 +445,10 @@ namespace sat {
return false; return false;
case justification::BINARY: case justification::BINARY:
return contains(c, j.get_literal()); return contains(c, j.get_literal());
#if ENABLE_TERNARY
case justification::TERNARY: case justification::TERNARY:
return contains(c, j.get_literal1(), j.get_literal2()); return contains(c, j.get_literal1(), j.get_literal2());
#endif
case justification::CLAUSE: case justification::CLAUSE:
return contains(s.get_clause(j)); return contains(s.get_clause(j));
default: default:

View file

@ -20,8 +20,6 @@ Revision History:
#include "sat/sat_solver.h" #include "sat/sat_solver.h"
#define ENABLE_TERNARY true
namespace sat { namespace sat {
// ----------------------- // -----------------------
@ -180,6 +178,7 @@ namespace sat {
IF_VERBOSE(SAT_VB_LVL, verbose_stream() << "(sat-gc :strategy " << st_name << " :deleted " << (sz - new_sz) << ")\n";); IF_VERBOSE(SAT_VB_LVL, verbose_stream() << "(sat-gc :strategy " << st_name << " :deleted " << (sz - new_sz) << ")\n";);
} }
#if ENABLE_TERNARY
bool solver::can_delete3(literal l1, literal l2, literal l3) const { bool solver::can_delete3(literal l1, literal l2, literal l3) const {
if (value(l1) == l_true && if (value(l1) == l_true &&
value(l2) == l_false && value(l2) == l_false &&
@ -193,16 +192,19 @@ namespace sat {
} }
return true; return true;
} }
#endif
bool solver::can_delete(clause const & c) const { bool solver::can_delete(clause const & c) const {
if (c.on_reinit_stack()) if (c.on_reinit_stack())
return false; return false;
#if ENABLE_TERNARY
if (ENABLE_TERNARY && c.size() == 3) { if (ENABLE_TERNARY && c.size() == 3) {
return return
can_delete3(c[0],c[1],c[2]) && can_delete3(c[0],c[1],c[2]) &&
can_delete3(c[1],c[0],c[2]) && can_delete3(c[1],c[0],c[2]) &&
can_delete3(c[2],c[0],c[1]); can_delete3(c[2],c[0],c[1]);
} }
#endif
literal l0 = c[0]; literal l0 = c[0];
if (value(l0) != l_true) if (value(l0) != l_true)
return true; return true;

View file

@ -22,7 +22,11 @@ namespace sat {
class justification { class justification {
public: public:
enum kind { NONE = 0, BINARY = 1, TERNARY = 2, CLAUSE = 3, EXT_JUSTIFICATION = 4}; enum kind { NONE = 0, BINARY = 1,
#if ENABLE_TERNARY
TERNARY = 2,
#endif
CLAUSE = 3, EXT_JUSTIFICATION = 4};
private: private:
unsigned m_level; unsigned m_level;
size_t m_val1; size_t m_val1;
@ -32,7 +36,9 @@ namespace sat {
public: public:
justification(unsigned lvl):m_level(lvl), m_val1(0), m_val2(NONE) {} justification(unsigned lvl):m_level(lvl), m_val1(0), m_val2(NONE) {}
explicit justification(unsigned lvl, literal l):m_level(lvl), m_val1(l.to_uint()), m_val2(BINARY) {} explicit justification(unsigned lvl, literal l):m_level(lvl), m_val1(l.to_uint()), m_val2(BINARY) {}
#if ENABLE_TERNARY
justification(unsigned lvl, literal l1, literal l2):m_level(lvl), m_val1(l1.to_uint()), m_val2(TERNARY + (l2.to_uint() << 3)) {} justification(unsigned lvl, literal l1, literal l2):m_level(lvl), m_val1(l1.to_uint()), m_val2(TERNARY + (l2.to_uint() << 3)) {}
#endif
explicit justification(unsigned lvl, clause_offset cls_off):m_level(lvl), m_val1(cls_off), m_val2(CLAUSE) {} explicit justification(unsigned lvl, clause_offset cls_off):m_level(lvl), m_val1(cls_off), m_val2(CLAUSE) {}
static justification mk_ext_justification(unsigned lvl, ext_justification_idx idx) { return justification(lvl, idx, EXT_JUSTIFICATION); } static justification mk_ext_justification(unsigned lvl, ext_justification_idx idx) { return justification(lvl, idx, EXT_JUSTIFICATION); }
@ -45,9 +51,11 @@ namespace sat {
bool is_binary_clause() const { return m_val2 == BINARY; } bool is_binary_clause() const { return m_val2 == BINARY; }
literal get_literal() const { SASSERT(is_binary_clause()); return to_literal(val1()); } literal get_literal() const { SASSERT(is_binary_clause()); return to_literal(val1()); }
#if ENABLE_TERNARY
bool is_ternary_clause() const { return get_kind() == TERNARY; } bool is_ternary_clause() const { return get_kind() == TERNARY; }
literal get_literal1() const { SASSERT(is_ternary_clause()); return to_literal(val1()); } literal get_literal1() const { SASSERT(is_ternary_clause()); return to_literal(val1()); }
literal get_literal2() const { SASSERT(is_ternary_clause()); return to_literal(m_val2 >> 3); } literal get_literal2() const { SASSERT(is_ternary_clause()); return to_literal(m_val2 >> 3); }
#endif
bool is_clause() const { return m_val2 == CLAUSE; } bool is_clause() const { return m_val2 == CLAUSE; }
clause_offset get_clause_offset() const { return m_val1; } clause_offset get_clause_offset() const { return m_val1; }
@ -65,9 +73,11 @@ namespace sat {
case justification::BINARY: case justification::BINARY:
out << "binary " << j.get_literal(); out << "binary " << j.get_literal();
break; break;
#if ENABLE_TERNARY
case justification::TERNARY: case justification::TERNARY:
out << "ternary " << j.get_literal1() << " " << j.get_literal2(); out << "ternary " << j.get_literal1() << " " << j.get_literal2();
break; break;
#endif
case justification::CLAUSE: case justification::CLAUSE:
out << "clause"; out << "clause";
break; break;

View file

@ -125,8 +125,10 @@ namespace sat {
in_coi |= m_in_coi.contains(lit.index()); in_coi |= m_in_coi.contains(lit.index());
else if (js.is_binary_clause()) else if (js.is_binary_clause())
in_coi = m_in_coi.contains(js.get_literal().index()); in_coi = m_in_coi.contains(js.get_literal().index());
#if ENABLE_TERNARY
else if (js.is_ternary_clause()) else if (js.is_ternary_clause())
in_coi = m_in_coi.contains(js.get_literal1().index()) || m_in_coi.contains(js.get_literal2().index()); in_coi = m_in_coi.contains(js.get_literal1().index()) || m_in_coi.contains(js.get_literal2().index());
#endif
else else
UNREACHABLE(); // approach does not work for external justifications UNREACHABLE(); // approach does not work for external justifications
@ -224,10 +226,12 @@ namespace sat {
case justification::BINARY: case justification::BINARY:
add_dependency(j.get_literal()); add_dependency(j.get_literal());
break; break;
#if ENABLE_TERNARY
case justification::TERNARY: case justification::TERNARY:
add_dependency(j.get_literal1()); add_dependency(j.get_literal1());
add_dependency(j.get_literal2()); add_dependency(j.get_literal2());
break; break;
#endif
case justification::CLAUSE: case justification::CLAUSE:
for (auto lit : s.get_clause(j)) for (auto lit : s.get_clause(j))
if (s.value(lit) == l_false) if (s.value(lit) == l_false)
@ -258,11 +262,13 @@ namespace sat {
m_clause.push_back(l); m_clause.push_back(l);
m_clause.push_back(j.get_literal()); m_clause.push_back(j.get_literal());
break; break;
#if ENABLE_TERNARY
case justification::TERNARY: case justification::TERNARY:
m_clause.push_back(l); m_clause.push_back(l);
m_clause.push_back(j.get_literal1()); m_clause.push_back(j.get_literal1());
m_clause.push_back(j.get_literal2()); m_clause.push_back(j.get_literal2());
break; break;
#endif
case justification::CLAUSE: case justification::CLAUSE:
s.get_clause(j).mark_used(); s.get_clause(j).mark_used();
IF_VERBOSE(3, verbose_stream() << "add core " << s.get_clause(j) << "\n"); IF_VERBOSE(3, verbose_stream() << "add core " << s.get_clause(j) << "\n");

View file

@ -37,7 +37,6 @@ Revision History:
# include <xmmintrin.h> # include <xmmintrin.h>
#endif #endif
#define ENABLE_TERNARY true
namespace sat { namespace sat {
@ -576,6 +575,7 @@ namespace sat {
return reinit; return reinit;
} }
#if ENABLE_TERNARY
bool solver::propagate_ter_clause(clause& c) { bool solver::propagate_ter_clause(clause& c) {
bool reinit = false; bool reinit = false;
if (value(c[1]) == l_false && value(c[2]) == l_false) { if (value(c[1]) == l_false && value(c[2]) == l_false) {
@ -595,6 +595,7 @@ namespace sat {
} }
return reinit; return reinit;
} }
#endif
clause * solver::mk_nary_clause(unsigned num_lits, literal * lits, sat::status st) { clause * solver::mk_nary_clause(unsigned num_lits, literal * lits, sat::status st) {
m_stats.m_mk_clause++; m_stats.m_mk_clause++;
@ -1061,7 +1062,7 @@ namespace sat {
bool solver::propagate_literal(literal l, bool update) { bool solver::propagate_literal(literal l, bool update) {
literal l1, l2; literal l1, l2;
lbool val1, val2;
bool keep; bool keep;
unsigned curr_level = lvl(l); unsigned curr_level = lvl(l);
TRACE("sat_propagate", tout << "propagating: " << l << "@" << curr_level << " " << m_justification[l.var()] << "\n"; ); TRACE("sat_propagate", tout << "propagating: " << l << "@" << curr_level << " " << m_justification[l.var()] << "\n"; );
@ -1099,7 +1100,9 @@ namespace sat {
*it2 = *it; *it2 = *it;
it2++; it2++;
break; break;
case watched::TERNARY: #if ENABLE_TERNARY
case watched::TERNARY: {
lbool val1, val2;
l1 = it->get_literal1(); l1 = it->get_literal1();
l2 = it->get_literal2(); l2 = it->get_literal2();
val1 = value(l1); val1 = value(l1);
@ -1120,6 +1123,8 @@ namespace sat {
*it2 = *it; *it2 = *it;
it2++; it2++;
break; break;
}
#endif
case watched::CLAUSE: { case watched::CLAUSE: {
if (value(it->get_blocked_literal()) == l_true) { if (value(it->get_blocked_literal()) == l_true) {
TRACE("propagate_clause_bug", tout << "blocked literal " << it->get_blocked_literal() << "\n"; TRACE("propagate_clause_bug", tout << "blocked literal " << it->get_blocked_literal() << "\n";
@ -2497,10 +2502,12 @@ namespace sat {
case justification::BINARY: case justification::BINARY:
process_antecedent(~(js.get_literal()), num_marks); process_antecedent(~(js.get_literal()), num_marks);
break; break;
#if ENABLE_TERNARY
case justification::TERNARY: case justification::TERNARY:
process_antecedent(~(js.get_literal1()), num_marks); process_antecedent(~(js.get_literal1()), num_marks);
process_antecedent(~(js.get_literal2()), num_marks); process_antecedent(~(js.get_literal2()), num_marks);
break; break;
#endif
case justification::CLAUSE: { case justification::CLAUSE: {
clause & c = get_clause(js); clause & c = get_clause(js);
unsigned i = 0; unsigned i = 0;
@ -2679,11 +2686,13 @@ namespace sat {
SASSERT(consequent != null_literal); SASSERT(consequent != null_literal);
process_antecedent_for_unsat_core(~(js.get_literal())); process_antecedent_for_unsat_core(~(js.get_literal()));
break; break;
#if ENABLE_TERNARY
case justification::TERNARY: case justification::TERNARY:
SASSERT(consequent != null_literal); SASSERT(consequent != null_literal);
process_antecedent_for_unsat_core(~(js.get_literal1())); process_antecedent_for_unsat_core(~(js.get_literal1()));
process_antecedent_for_unsat_core(~(js.get_literal2())); process_antecedent_for_unsat_core(~(js.get_literal2()));
break; break;
#endif
case justification::CLAUSE: { case justification::CLAUSE: {
clause & c = get_clause(js); clause & c = get_clause(js);
unsigned i = 0; unsigned i = 0;
@ -2820,10 +2829,12 @@ namespace sat {
case justification::BINARY: case justification::BINARY:
level = update_max_level(js.get_literal(), level, unique_max); level = update_max_level(js.get_literal(), level, unique_max);
return level; return level;
#if ENABLE_TERNARY
case justification::TERNARY: case justification::TERNARY:
level = update_max_level(js.get_literal1(), level, unique_max); level = update_max_level(js.get_literal1(), level, unique_max);
level = update_max_level(js.get_literal2(), level, unique_max); level = update_max_level(js.get_literal2(), level, unique_max);
return level; return level;
#endif
case justification::CLAUSE: case justification::CLAUSE:
for (literal l : get_clause(js)) for (literal l : get_clause(js))
level = update_max_level(l, level, unique_max); level = update_max_level(l, level, unique_max);
@ -3175,6 +3186,7 @@ namespace sat {
return false; return false;
} }
break; break;
#if ENABLE_TERNARY
case justification::TERNARY: case justification::TERNARY:
if (!process_antecedent_for_minimization(~(js.get_literal1())) || if (!process_antecedent_for_minimization(~(js.get_literal1())) ||
!process_antecedent_for_minimization(~(js.get_literal2()))) { !process_antecedent_for_minimization(~(js.get_literal2()))) {
@ -3182,6 +3194,7 @@ namespace sat {
return false; return false;
} }
break; break;
#endif
case justification::CLAUSE: { case justification::CLAUSE: {
clause & c = get_clause(js); clause & c = get_clause(js);
unsigned i = 0; unsigned i = 0;
@ -3337,10 +3350,12 @@ namespace sat {
case justification::BINARY: case justification::BINARY:
update_lrb_reasoned(js.get_literal()); update_lrb_reasoned(js.get_literal());
break; break;
#if ENABLE_TERNARY
case justification::TERNARY: case justification::TERNARY:
update_lrb_reasoned(js.get_literal1()); update_lrb_reasoned(js.get_literal1());
update_lrb_reasoned(js.get_literal2()); update_lrb_reasoned(js.get_literal2());
break; break;
#endif
case justification::CLAUSE: { case justification::CLAUSE: {
clause & c = get_clause(js); clause & c = get_clause(js);
for (literal l : c) { for (literal l : c) {
@ -3686,6 +3701,7 @@ namespace sat {
} }
else { else {
clause & c = *(cw.get_clause()); clause & c = *(cw.get_clause());
#if ENABLE_TERNARY
if (ENABLE_TERNARY && c.size() == 3) { if (ENABLE_TERNARY && c.size() == 3) {
if (propagate_ter_clause(c) && !at_base_lvl()) if (propagate_ter_clause(c) && !at_base_lvl())
m_clauses_to_reinit[j++] = cw; m_clauses_to_reinit[j++] = cw;
@ -3695,6 +3711,7 @@ namespace sat {
c.set_reinit_stack(false); c.set_reinit_stack(false);
continue; continue;
} }
#endif
detach_clause(c); detach_clause(c);
attach_clause(c, reinit); attach_clause(c, reinit);
if (reinit && !at_base_lvl()) if (reinit && !at_base_lvl())
@ -3961,10 +3978,12 @@ namespace sat {
case justification::BINARY: case justification::BINARY:
out << "binary " << js.get_literal() << "@" << lvl(js.get_literal()); out << "binary " << js.get_literal() << "@" << lvl(js.get_literal());
break; break;
#if ENABLE_TERNARY
case justification::TERNARY: case justification::TERNARY:
out << "ternary " << js.get_literal1() << "@" << lvl(js.get_literal1()) << " "; out << "ternary " << js.get_literal1() << "@" << lvl(js.get_literal1()) << " ";
out << js.get_literal2() << "@" << lvl(js.get_literal2()); out << js.get_literal2() << "@" << lvl(js.get_literal2());
break; break;
#endif
case justification::CLAUSE: { case justification::CLAUSE: {
out << "("; out << "(";
bool first = true; bool first = true;
@ -4624,12 +4643,14 @@ namespace sat {
if (!check_domain(lit, ~js.get_literal())) return false; if (!check_domain(lit, ~js.get_literal())) return false;
s |= m_antecedents.find(js.get_literal().var()); s |= m_antecedents.find(js.get_literal().var());
break; break;
#if ENABLE_TERNARY
case justification::TERNARY: case justification::TERNARY:
if (!check_domain(lit, ~js.get_literal1()) || if (!check_domain(lit, ~js.get_literal1()) ||
!check_domain(lit, ~js.get_literal2())) return false; !check_domain(lit, ~js.get_literal2())) return false;
s |= m_antecedents.find(js.get_literal1().var()); s |= m_antecedents.find(js.get_literal1().var());
s |= m_antecedents.find(js.get_literal2().var()); s |= m_antecedents.find(js.get_literal2().var());
break; break;
#endif
case justification::CLAUSE: { case justification::CLAUSE: {
clause & c = get_clause(js); clause & c = get_clause(js);
for (literal l : c) { for (literal l : c) {

View file

@ -34,6 +34,8 @@ class params_ref;
class reslimit; class reslimit;
class statistics; class statistics;
#define ENABLE_TERNARY false
namespace sat { namespace sat {
#define SAT_VB_LVL 10 #define SAT_VB_LVL 10

View file

@ -690,6 +690,7 @@ namespace pb {
inc_coeff(consequent, offset); inc_coeff(consequent, offset);
process_antecedent(js.get_literal(), offset); process_antecedent(js.get_literal(), offset);
break; break;
#if ENABLE_TERNARY
case sat::justification::TERNARY: case sat::justification::TERNARY:
inc_bound(offset); inc_bound(offset);
SASSERT (consequent != sat::null_literal); SASSERT (consequent != sat::null_literal);
@ -697,6 +698,7 @@ namespace pb {
process_antecedent(js.get_literal1(), offset); process_antecedent(js.get_literal1(), offset);
process_antecedent(js.get_literal2(), offset); process_antecedent(js.get_literal2(), offset);
break; break;
#endif
case sat::justification::CLAUSE: { case sat::justification::CLAUSE: {
inc_bound(offset); inc_bound(offset);
sat::clause & c = s().get_clause(js); sat::clause & c = s().get_clause(js);
@ -1017,6 +1019,7 @@ namespace pb {
inc_coeff(consequent, 1); inc_coeff(consequent, 1);
process_antecedent(js.get_literal()); process_antecedent(js.get_literal());
break; break;
#if ENABLE_TERNARY
case sat::justification::TERNARY: case sat::justification::TERNARY:
SASSERT(consequent != sat::null_literal); SASSERT(consequent != sat::null_literal);
round_to_one(consequent.var()); round_to_one(consequent.var());
@ -1025,6 +1028,7 @@ namespace pb {
process_antecedent(js.get_literal1()); process_antecedent(js.get_literal1());
process_antecedent(js.get_literal2()); process_antecedent(js.get_literal2());
break; break;
#endif
case sat::justification::CLAUSE: { case sat::justification::CLAUSE: {
sat::clause & c = s().get_clause(js); sat::clause & c = s().get_clause(js);
unsigned i = 0; unsigned i = 0;
@ -3472,6 +3476,7 @@ namespace pb {
ineq.push(lit, offset); ineq.push(lit, offset);
ineq.push(js.get_literal(), offset); ineq.push(js.get_literal(), offset);
break; break;
#if ENABLE_TERNARY
case sat::justification::TERNARY: case sat::justification::TERNARY:
SASSERT(lit != sat::null_literal); SASSERT(lit != sat::null_literal);
ineq.reset(offset); ineq.reset(offset);
@ -3479,6 +3484,7 @@ namespace pb {
ineq.push(js.get_literal1(), offset); ineq.push(js.get_literal1(), offset);
ineq.push(js.get_literal2(), offset); ineq.push(js.get_literal2(), offset);
break; break;
#endif
case sat::justification::CLAUSE: { case sat::justification::CLAUSE: {
ineq.reset(offset); ineq.reset(offset);
sat::clause & c = s().get_clause(js); sat::clause & c = s().get_clause(js);