z3-z3-4.12.6.src.sat.sat_watched.h Maven / Gradle / Ivy
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
sat_watched.h
Abstract:
Element of the SAT solver watchlist.
Author:
Leonardo de Moura (leonardo) 2011-05-21.
Revision History:
--*/
#pragma once
#include "sat/sat_types.h"
#include "util/vector.h"
namespace sat {
/**
A watched element can be:
1) A literal: for watched binary clauses
2) A pair of literals: for watched ternary clauses
3) A pair (literal, clause-offset): for watched clauses, where the first element of the pair is a literal of the clause.
4) A external constraint-idx: for external constraints.
For binary clauses: we use a bit to store whether the binary clause was learned or not.
Remark: there are no clause objects for binary clauses.
*/
class extension;
class watched {
public:
enum kind {
BINARY = 0, CLAUSE, EXT_CONSTRAINT
};
private:
size_t m_val1;
unsigned m_val2;
public:
watched(literal l, bool learned):
m_val1(l.to_uint()),
m_val2(static_cast(BINARY) + (static_cast(learned) << 2)) {
SASSERT(is_binary_clause());
SASSERT(get_literal() == l);
SASSERT(is_learned() == learned);
SASSERT(learned || is_binary_non_learned_clause());
}
unsigned val2() const { return m_val2; }
watched(literal blocked_lit, clause_offset cls_off):
m_val1(cls_off),
m_val2(static_cast(CLAUSE) + (blocked_lit.to_uint() << 2)) {
SASSERT(is_clause());
SASSERT(get_blocked_literal() == blocked_lit);
SASSERT(get_clause_offset() == cls_off);
}
explicit watched(ext_constraint_idx cnstr_idx):
m_val1(cnstr_idx),
m_val2(static_cast(EXT_CONSTRAINT)) {
SASSERT(is_ext_constraint());
SASSERT(get_ext_constraint_idx() == cnstr_idx);
}
kind get_kind() const { return static_cast(m_val2 & 3); }
bool is_binary_clause() const { return get_kind() == BINARY; }
literal get_literal() const { SASSERT(is_binary_clause()); return to_literal(static_cast(m_val1)); }
void set_literal(literal l) { SASSERT(is_binary_clause()); m_val1 = l.to_uint(); }
bool is_learned() const { SASSERT(is_binary_clause()); return ((m_val2 >> 2) & 1) == 1; }
bool is_binary_learned_clause() const { return is_binary_clause() && is_learned(); }
bool is_binary_non_learned_clause() const { return is_binary_clause() && !is_learned(); }
void set_learned(bool l) { if (l) m_val2 |= 4u; else m_val2 &= ~4u; SASSERT(is_learned() == l); }
bool is_clause() const { return get_kind() == CLAUSE; }
clause_offset get_clause_offset() const { SASSERT(is_clause()); return static_cast(m_val1); }
literal get_blocked_literal() const { SASSERT(is_clause()); return to_literal(m_val2 >> 2); }
void set_clause_offset(clause_offset c) { SASSERT(is_clause()); m_val1 = c; }
void set_blocked_literal(literal l) { SASSERT(is_clause()); m_val2 = static_cast(CLAUSE) + (l.to_uint() << 2); }
void set_clause(literal blocked_lit, clause_offset cls_off) {
m_val1 = cls_off;
m_val2 = static_cast(CLAUSE) + (blocked_lit.to_uint() << 2);
}
bool is_ext_constraint() const { return get_kind() == EXT_CONSTRAINT; }
ext_constraint_idx get_ext_constraint_idx() const { SASSERT(is_ext_constraint()); return m_val1; }
bool operator==(watched const & w) const { return m_val1 == w.m_val1 && m_val2 == w.m_val2; }
bool operator!=(watched const & w) const { return !operator==(w); }
};
static_assert(0 <= watched::BINARY && watched::BINARY <= 2, "");
static_assert(0 <= watched::CLAUSE && watched::CLAUSE <= 2, "");
static_assert(0 <= watched::EXT_CONSTRAINT && watched::EXT_CONSTRAINT <= 2, "");
struct watched_lt {
bool operator()(watched const & w1, watched const & w2) const {
if (w2.is_binary_clause()) return false;
if (w1.is_binary_clause()) return true;
return false;
}
};
typedef vector watch_list;
watched* find_binary_watch(watch_list & wlist, literal l);
watched const* find_binary_watch(watch_list const & wlist, literal l);
bool erase_clause_watch(watch_list & wlist, clause_offset c);
class clause_allocator;
std::ostream& display_watch_list(std::ostream & out, clause_allocator const & ca, watch_list const & wlist, extension* ext);
void conflict_cleanup(watch_list::iterator it, watch_list::iterator it2, watch_list& wlist);
};