/*++ Copyright (c) 2006 Microsoft Corporation Module Name: smt_clause.cpp Abstract: Author: Leonardo de Moura (leonardo) 2008-02-19. Revision History: --*/ #include"smt_clause.h" #include"smt_justification.h" #include"ast_ll_pp.h" namespace smt { /** \brief Create a new clause. bool_var2expr_map is a mapping from bool_var -> expr, it is only used if save_atoms == true. */ clause * clause::mk(ast_manager & m, unsigned num_lits, literal * lits, clause_kind k, justification * js, clause_del_eh * del_eh, bool save_atoms, expr * const * bool_var2expr_map) { SASSERT(k == CLS_AUX || js == 0 || !js->in_region()); SASSERT(num_lits >= 2); unsigned sz = get_obj_size(num_lits, k, save_atoms, del_eh != 0, js != 0); void * mem = m.get_allocator().allocate(sz); clause * cls = new (mem) clause(); cls->m_num_literals = num_lits; cls->m_capacity = num_lits; cls->m_kind = k; cls->m_reinit = save_atoms; cls->m_reinternalize_atoms = save_atoms; cls->m_has_atoms = save_atoms; cls->m_has_del_eh = del_eh != 0; cls->m_has_justification = js != 0; cls->m_deleted = false; SASSERT(!m.proofs_enabled() || js != 0); memcpy(cls->m_lits, lits, sizeof(literal) * num_lits); if (cls->is_lemma()) cls->set_activity(1); if (del_eh) *(const_cast(cls->get_del_eh_addr())) = del_eh; if (js) *(const_cast(cls->get_justification_addr())) = js; if (save_atoms) { for (unsigned i = 0; i < num_lits; i++) { expr * atom = bool_var2expr_map[lits[i].var()]; m.inc_ref(atom); const_cast(cls->get_atoms_addr())[i] = TAG(expr*, atom, lits[i].sign()); } } DEBUG_CODE({ SASSERT(!cls->is_lemma() || cls->get_activity() == 1); SASSERT(cls->get_del_eh() == del_eh); SASSERT(cls->get_justification() == js); for (unsigned i = 0; i < num_lits; i++) { SASSERT(cls->get_literal(i) == lits[i]); SASSERT(!save_atoms || cls->get_atom(i) == bool_var2expr_map[lits[i].var()]); }}); return cls; } void clause::deallocate(ast_manager & m) { clause_del_eh * del_eh = get_del_eh(); if (del_eh) (*del_eh)(m, this); if (is_lemma() && m_has_justification) { justification * js = get_justification(); if (js) { SASSERT(!js->in_region()); js->del_eh(m); dealloc(js); } } unsigned num_atoms = get_num_atoms(); for (unsigned i = 0; i < num_atoms; i++) { SASSERT(m_reinit || get_atom(i) == 0); m.dec_ref(get_atom(i)); } m.get_allocator().deallocate(get_obj_size(m_capacity, get_kind(), m_has_atoms, m_has_del_eh, m_has_justification), this); } void clause::release_atoms(ast_manager & m) { unsigned num_atoms = get_num_atoms(); for (unsigned i = 0; i < num_atoms; i++) { m.dec_ref(get_atom(i)); const_cast(get_atoms_addr())[i] = 0; } } void clause::display(std::ostream & out, ast_manager & m, expr * const * bool_var2expr_map) const { out << "(clause"; for (unsigned i = 0; i < m_num_literals; i++) { out << " "; m_lits[i].display(out, m, bool_var2expr_map); } out << ")"; } void clause::display_compact(std::ostream & out, ast_manager & m, expr * const * bool_var2expr_map) const { out << "(clause"; for (unsigned i = 0; i < m_num_literals; i++) { out << " "; m_lits[i].display_compact(out, bool_var2expr_map); } out << ")"; } };