#pragma once
#include "sat/sat_types.h"
#include "util/ref_vector.h"
namespace sat {
class solver;
static unsigned counter = 0;
class model_converter {
public:
typedef svector<std::pair<unsigned, literal>> elim_stackv;
class elim_stack {
unsigned m_counter;
unsigned m_refcount;
elim_stackv m_stack;
public:
elim_stack(elim_stack const&) = delete;
elim_stack(elim_stackv && stack):
m_counter(0),
m_refcount(0),
m_stack(std::move(stack)) {
m_counter = ++counter;
}
void inc_ref() { ++m_refcount; }
void dec_ref() { if (0 == --m_refcount) { dealloc(this); } }
elim_stackv const& stack() const { return m_stack; }
unsigned ref_count() const { return m_refcount; }
};
enum kind { ELIM_VAR = 0, BCE, CCE, ACCE, ABCE, ATE };
class entry {
friend class model_converter;
bool_var m_var;
kind m_kind;
literal_vector m_clauses; literal_vector m_clause; sref_vector<elim_stack> m_elim_stack;
entry(kind k, bool_var v): m_var(v), m_kind(k) {}
public:
bool_var var() const { return m_var; }
kind get_kind() const { return m_kind; }
};
private:
vector<entry> m_entries; unsigned m_exposed_lim = 0; bool_vector m_mark; solver const* m_solver = nullptr;
elim_stackv m_elim_stack;
void process_stack(model & m, literal_vector const& clause, elim_stackv const& stack) const;
std::ostream& display(std::ostream & out, entry const& entry) const;
bool legal_to_flip(bool_var v) const;
void swap(bool_var v, unsigned sz, literal_vector& clause) noexcept;
void add_elim_stack(entry & e);
public:
void set_solver(solver const* s) { m_solver = s; }
void operator()(model & m) const;
model_converter& operator=(model_converter const& other);
elim_stackv& stackv() { return m_elim_stack; }
entry & mk(kind k, bool_var v);
void insert(entry & e, clause const & c);
void insert(entry & e, literal l1, literal l2);
void insert(entry & e, clause_wrapper const & c);
void insert(entry & c, literal_vector const& covered_clause);
void set_clause(entry & e, literal l1, literal l2);
void set_clause(entry & e, clause const & c);
void add_ate(literal_vector const& lits);
void add_ate(literal l1, literal l2);
void add_ate(clause const& c);
bool empty() const { return m_entries.empty(); }
unsigned size() const { return m_entries.size(); }
void init_search(solver& s);
void add_clause(unsigned n, literal const* lits);
bool check_invariant(unsigned num_vars) const;
void display(std::ostream & out) const;
bool check_model(model const & m) const;
void copy(model_converter const & src);
void flush(model_converter& src);
void collect_vars(bool_var_set & s) const;
unsigned max_var(unsigned min) const;
void expand(literal_vector& update_stack);
};
inline std::ostream& operator<<(std::ostream& out, model_converter::kind k) {
switch (k) {
case model_converter::ELIM_VAR: out << "elim"; break;
case model_converter::BCE: out << "bce"; break;
case model_converter::CCE: out << "cce"; break;
case model_converter::ACCE: out << "acce"; break;
case model_converter::ABCE: out << "abce"; break;
case model_converter::ATE: out << "ate"; break;
}
return out;
}
};