z3-z3-4.12.6.src.util.sat_literal.h Maven / Gradle / Ivy
/*++
Copyright (c) 2011 Microsoft Corporation
Module Name:
sat_literal.h
Abstract:
Literal datatype
Author:
Leonardo de Moura (leonardo) 2011-05-21.
--*/
#pragma once
#include "util/lbool.h"
#include "util/approx_set.h"
#include "util/vector.h"
#include "util/uint_set.h"
namespace sat {
/**
\brief A boolean variable is just an integer.
*/
typedef unsigned bool_var;
typedef svector bool_var_vector;
inline constexpr bool_var null_bool_var = UINT_MAX >> 1;
/**
\brief The literal b is represented by the value 2*b, and
the literal (not b) by the value 2*b + 1
*/
class literal {
unsigned m_val;
public:
constexpr literal(): m_val(null_bool_var << 1) { }
explicit literal(bool_var v, bool _sign = false):
m_val((v << 1) + static_cast(_sign)) {
SASSERT(var() == v);
SASSERT(sign() == _sign);
}
constexpr bool_var var() const {
return m_val >> 1;
}
constexpr bool sign() const {
return m_val & 1ul;
}
literal unsign() const {
literal l;
l.m_val = m_val & ~1;
return l;
}
unsigned index() const {
return m_val;
}
void neg() {
m_val = m_val ^ 1;
}
friend literal operator~(literal l) {
l.m_val = l.m_val ^1;
return l;
}
unsigned to_uint() const { return m_val; }
unsigned hash() const { return to_uint(); }
friend literal to_literal(unsigned x);
friend bool operator<(literal const & l1, literal const & l2);
friend bool operator==(literal const & l1, literal const & l2);
friend bool operator!=(literal const & l1, literal const & l2);
};
inline constexpr literal null_literal;
static_assert(null_literal.var() == null_bool_var);
static_assert(!null_literal.sign());
using literal_hash = obj_hash;
inline literal to_literal(unsigned x) { literal l; l.m_val = x; return l; }
inline bool operator<(literal const & l1, literal const & l2) { return l1.m_val < l2.m_val; }
inline bool operator==(literal const & l1, literal const & l2) { return l1.m_val == l2.m_val; }
inline bool operator!=(literal const & l1, literal const & l2) { return l1.m_val != l2.m_val; }
inline std::ostream & operator<<(std::ostream & out, sat::literal l) { if (l == sat::null_literal) out << "null"; else out << (l.sign() ? "-" : "") << l.var(); return out; }
typedef svector literal_vector;
typedef std::pair literal_pair;
struct literal2unsigned { unsigned operator()(literal l) const { return l.to_uint(); } };
typedef approx_set_tpl literal_approx_set;
typedef approx_set_tpl var_approx_set;
inline void negate(literal_vector& ls) { for (unsigned i = 0; i < ls.size(); ++i) ls[i].neg(); }
typedef tracked_uint_set bool_var_set;
class literal_set {
tracked_uint_set m_set;
public:
literal_set(literal_vector const& v) {
for (unsigned i = 0; i < v.size(); ++i) insert(v[i]);
}
literal_set() {}
literal_vector to_vector() const {
literal_vector result;
for (literal lit : *this) result.push_back(lit);
return result;
}
literal_set& operator=(literal_vector const& v) {
reset();
for (unsigned i = 0; i < v.size(); ++i) insert(v[i]);
return *this;
}
void insert(literal l) { m_set.insert(l.index()); }
void remove(literal l) { m_set.remove(l.index()); }
literal pop() { return to_literal(m_set.erase()); }
bool contains(literal l) const { return m_set.contains(l.index()); }
bool empty() const { return m_set.empty(); }
unsigned size() const { return m_set.size(); }
void reset() { m_set.reset(); }
void finalize() { m_set.finalize(); }
class iterator {
tracked_uint_set::iterator m_it;
public:
iterator(tracked_uint_set::iterator it):m_it(it) {}
literal operator*() const { return to_literal(*m_it); }
iterator& operator++() { ++m_it; return *this; }
iterator operator++(int) { iterator tmp = *this; ++m_it; return tmp; }
bool operator==(iterator const& it) const { return m_it == it.m_it; }
bool operator!=(iterator const& it) const { return m_it != it.m_it; }
};
iterator begin() const { return iterator(m_set.begin()); }
iterator end() const { return iterator(m_set.end()); }
literal_set& operator&=(literal_set const& other) {
m_set &= other.m_set;
return *this;
}
literal_set& operator|=(literal_set const& other) {
m_set |= other.m_set;
return *this;
}
};
struct dimacs_lit {
literal m_lit;
explicit dimacs_lit(literal l):m_lit(l) {}
};
inline std::ostream & operator<<(std::ostream & out, dimacs_lit const & dl) {
literal l = dl.m_lit;
if (l.sign()) out << "-" << (l.var() + 1);
else out << (l.var() + 1);
return out;
}
struct mk_lits_pp {
unsigned m_num;
literal const * m_lits;
mk_lits_pp(unsigned num, literal const * ls):m_num(num), m_lits(ls) {}
};
inline std::ostream & operator<<(std::ostream & out, mk_lits_pp const & ls) {
for (unsigned i = 0; i < ls.m_num; i++) {
if (i > 0) out << " ";
out << ls.m_lits[i];
}
return out;
}
inline std::ostream & operator<<(std::ostream & out, literal_vector const & ls) {
return out << mk_lits_pp(ls.size(), ls.data());
}
};
namespace std {
inline std::string to_string(sat::literal l) {
if (l.sign()) return "-" + to_string(l.var());
return to_string(l.var());
}
};