3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-08 18:31:49 +00:00
z3/lib/smt_clause.h
Leonardo de Moura e9eab22e5c Z3 sources
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
2012-10-02 11:35:25 -07:00

259 lines
7.7 KiB
C++

/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
smt_clause.h
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2008-02-18.
Revision History:
--*/
#ifndef _SMT_CLAUSE_H_
#define _SMT_CLAUSE_H_
#include"ast.h"
#include"smt_literal.h"
#include"tptr.h"
#include"obj_hashtable.h"
#include"smt_justification.h"
namespace smt {
class clause;
/**
\brief Abstract functor: clause deletion event handler.
*/
class clause_del_eh {
public:
virtual ~clause_del_eh() {}
virtual void operator()(ast_manager & m, clause * cls) = 0;
};
enum clause_kind {
CLS_AUX,
CLS_LEARNED,
CLS_AUX_LEMMA
};
/**
\brief A SMT clause.
A clause has several optional fields, I store space for them only if they are actually used.
*/
class clause {
unsigned m_num_literals;
unsigned m_capacity:24; //!< some of the clause literals can be simplified and removed, this field contains the original number of literals (used for GC).
unsigned m_kind:2; //!< kind
unsigned m_reinit:1; //!< true if the clause is in the reinit stack (only for learned clauses and aux_lemmas)
unsigned m_reinternalize_atoms:1; //!< true if atoms must be reinitialized during reinitialization
unsigned m_has_atoms:1; //!< true if the clause has memory space for storing atoms.
unsigned m_has_del_eh:1; //!< true if must notify event handler when deleted.
unsigned m_has_justification:1; //!< true if the clause has a justification attached to it.
unsigned m_deleted:1; //!< true if the clause is marked for deletion by was not deleted yet because it is referenced by some data-structure (e.g., m_lemmas)
literal m_lits[0];
static unsigned get_obj_size(unsigned num_lits, clause_kind k, bool has_atoms, bool has_del_eh, bool has_justification) {
unsigned r = sizeof(clause) + sizeof(literal) * num_lits;
if (k != CLS_AUX)
r += sizeof(unsigned);
if (has_atoms)
r += sizeof(expr*) * num_lits;
if (has_del_eh)
r += sizeof(clause_del_eh *);
if (has_justification)
r += sizeof(justification *);
return r;
}
unsigned const * get_activity_addr() const {
return reinterpret_cast<unsigned const *>(m_lits + m_capacity);
}
unsigned * get_activity_addr() {
return reinterpret_cast<unsigned *>(m_lits + m_capacity);
}
clause_del_eh * const * get_del_eh_addr() const {
unsigned const * addr = get_activity_addr();
if (is_lemma())
addr ++;
return reinterpret_cast<clause_del_eh * const *>(addr);
}
justification * const * get_justification_addr() const {
clause_del_eh * const * addr = get_del_eh_addr();
if (m_has_del_eh)
addr ++;
return reinterpret_cast<justification * const *>(addr);
}
expr * const * get_atoms_addr() const {
justification * const * addr = get_justification_addr();
if (m_has_justification)
addr ++;
return reinterpret_cast<expr * const *>(addr);
}
friend class context;
void swap_lits(unsigned idx1, unsigned idx2) {
literal tmp = get_literal(idx1);
set_literal(idx1, get_literal(idx2));
set_literal(idx2, tmp);
}
bool is_watch(literal l) const {
return m_lits[0] == l || m_lits[1] == l;
}
void set_literal(unsigned idx, literal l) {
m_lits[idx] = l;
}
void set_num_literals(unsigned n) {
SASSERT(n <= m_num_literals);
SASSERT(!m_reinit);
m_num_literals = n;
}
void set_justification(justification * new_js) {
SASSERT(m_has_justification);
SASSERT(!m_reinit);
SASSERT(!is_lemma() || new_js == 0 || !new_js->in_region());
justification ** js_addr = const_cast<justification**>(get_justification_addr());
*js_addr = new_js;
}
void release_atoms(ast_manager & m);
public:
static clause * mk(ast_manager & m, unsigned num_lits, literal * lits, clause_kind k, justification * js = 0,
clause_del_eh * del_eh = 0, bool save_atoms = false, expr * const * bool_var2expr_map = 0);
void deallocate(ast_manager & m);
clause_kind get_kind() const {
return static_cast<clause_kind>(m_kind);
}
bool is_lemma() const {
return get_kind() != CLS_AUX;
}
bool is_learned() const {
return get_kind() == CLS_LEARNED;
}
bool is_aux_lemma() const {
return get_kind() == CLS_AUX_LEMMA;
}
bool in_reinit_stack() const {
return m_reinit;
}
bool reinternalize_atoms() const {
return m_reinternalize_atoms;
}
unsigned get_num_literals() const {
return m_num_literals;
}
literal get_literal(unsigned idx) const {
SASSERT(idx < m_num_literals);
return m_lits[idx];
}
literal & get_literal(unsigned idx) {
SASSERT(idx < m_num_literals);
return m_lits[idx];
}
literal * begin_literals() { return m_lits; }
literal * end_literals() { return m_lits + m_num_literals; }
literal const * begin_literals() const { return m_lits; }
literal const * end_literals() const { return m_lits + m_num_literals; }
unsigned get_activity() const {
SASSERT(is_lemma());
return *(get_activity_addr());
}
void set_activity(unsigned act) {
SASSERT(is_lemma());
*(get_activity_addr()) = act;
}
clause_del_eh * get_del_eh() const {
return m_has_del_eh ? *(get_del_eh_addr()) : 0;
}
justification * get_justification() const {
return m_has_justification ? *(get_justification_addr()) : 0;
}
unsigned get_num_atoms() const {
return m_reinternalize_atoms ? m_num_literals : 0;
}
expr * get_atom(unsigned idx) const {
SASSERT(idx < get_num_atoms());
return UNTAG(expr*, get_atoms_addr()[idx]);
}
bool get_atom_sign(unsigned idx) const {
SASSERT(idx < get_num_atoms());
return GET_TAG(get_atoms_addr()[idx]) == 1;
}
bool erase_atom(unsigned idx);
void inc_clause_activity() {
SASSERT(is_lemma());
set_activity(get_activity() + 1);
}
void display(std::ostream & out, ast_manager & m, expr * const * bool_var2expr_map) const;
void display_compact(std::ostream & out, ast_manager & m, expr * const * bool_var2expr_map) const;
unsigned hash() const {
return get_ptr_hash(this);
}
void mark_as_deleted(ast_manager & m) {
SASSERT(!m_deleted);
m_deleted = true;
clause_del_eh * del_eh = get_del_eh();
if (del_eh) {
(*del_eh)(m, this);
*(const_cast<clause_del_eh **>(get_del_eh_addr())) = 0;
}
}
bool deleted() const {
return m_deleted;
}
};
typedef ptr_vector<clause> clause_vector;
typedef obj_hashtable<clause> clause_set;
};
#endif /* _SMT_CLAUSE_H_ */