/*****************************************************************************/
/*!
*\file cnf.cpp
*\brief Implementation of classes used for generic CNF formulas
*
* Author: Clark Barrett
*
* Created: Mon Dec 12 22:16:11 2005
*
*
*
* License to use, copy, modify, sell and/or distribute this software
* and its documentation for any purpose is hereby granted without
* royalty, subject to the terms and conditions defined in the \ref
* LICENSE file provided with this distribution.
*
*
*/
/*****************************************************************************/
#include "cnf.h"
using namespace std;
using namespace CVC3;
using namespace SAT;
unsigned SAT::Clause::getMaxVar() const
{
unsigned max = 0;
const_iterator i, iend;
for (i = begin(), iend = end(); i != iend; ++i) {
DebugAssert(!(*i).isNull(), "Null literal found in clause");
if (unsigned((*i).getVar()) > max) max = unsigned((*i).getVar());
}
return max;
}
void SAT::Clause::print() const
{
if (isSatisfied()) cout << "*";
const_iterator i, iend;
for (i = begin(), iend = end(); i != iend; ++i) {
if ((*i).isNull()) cout << "NULL";
else if ((*i).isFalse()) cout << "F";
else if ((*i).isTrue()) cout << "T";
else {
if (!(*i).isPositive()) cout << "-";
cout << (*i).getVar();
}
cout << " ";
}
cout << endl;
}
void CNF_Formula::copy(const CNF_Formula& cnf)
{
setNumVars(0);
Clause* c = d_current;
// Don't use iterators in case cnf == *this
unsigned i, iend;
Clause::const_iterator j, jend;
for (i = 0, iend = cnf.numClauses(); i != iend; ++i) {
newClause();
for (j = cnf[i].begin(), jend = cnf[i].end(); j != jend; ++j) {
addLiteral(*j);
}
Clause oldClause = cnf[i];
// CVC3::Theorem clauseThm = oldClause.getClauseTheorem();
CVC3::Theorem clauseThm = cnf[i].getClauseTheorem();
getCurrentClause().setClauseTheorem(clauseThm);//by yeting
if (cnf[i].isUnit()) registerUnit();
if (&(cnf[i]) == cnf.d_current) c = d_current;
}
d_current = c;
}
void CNF_Formula::print() const
{
const_iterator i, iend;
for (i = begin(), iend = end(); i != iend; ++i) {
(*i).print();
}
}
const CNF_Formula& CNF_Formula::operator+=(const CNF_Formula& cnf)
{
Clause* c = d_current;
// Don't use iterators in case cnf == *this
unsigned i, iend;
Clause::const_iterator j, jend;
for (i = 0, iend = cnf.numClauses(); i != iend; ++i) {
newClause();
for (j = cnf[i].begin(), jend = cnf[i].end(); j != jend; ++j) {
addLiteral(*j);
}
Clause oldClause = cnf[i];
CVC3::Theorem clauseThm = oldClause.getClauseTheorem();
getCurrentClause().setClauseTheorem(clauseThm);//by yeting
if (cnf[i].isUnit()) registerUnit();
}
d_current = c;
return *this;
}
const CNF_Formula& CNF_Formula::operator+=(const Clause& c)
{
Clause* cur = d_current;
newClause();
Clause::const_iterator j, jend;
for (j=c.begin(), jend = c.end(); j != jend; ++j) {
addLiteral(*j);
}
Clause oldClause = c;
CVC3::Theorem clauseThm = oldClause.getClauseTheorem();
getCurrentClause().setClauseTheorem(clauseThm);//by yeting
if (c.isUnit()) registerUnit();
d_current = cur;
return *this;
}
void CNF_Formula_Impl::newClause()
{
d_formula.resize(d_formula.size()+1);
d_current = &(d_formula.back());
}
void CNF_Formula_Impl::registerUnit()
{
DebugAssert(d_current->size()==1,"Expected unit clause");
d_current->setUnit();
Lit l = *(d_current->begin());
d_lits[l.getID()] = true;
}
void CNF_Formula_Impl::simplify()
{
deque::iterator i, iend;
Clause::const_iterator j, jend;
for (i = d_formula.begin(), iend = d_formula.end(); i != iend; ++i) {
if ((*i).isUnit()) continue;
for (j=(*i).begin(), jend = (*i).end(); j != jend; ++j) {
if ((*j).isTrue()) {
(*i).setSatisfied();
break;
}
hash_map::iterator it = d_lits.find((*j).getID());
if (it != d_lits.end()) {
(*i).setSatisfied();
break;
}
}
}
}
void CNF_Formula_Impl::reset()
{
d_formula.clear();
d_lits.clear();
d_current = NULL;
d_numVars = 0;
}
void CD_CNF_Formula::newClause()
{
//TODO: don't call constructor twice
d_current = &(d_formula.push_back(Clause()));
}
void CD_CNF_Formula::registerUnit()
{
DebugAssert(d_current->size()==1,"Expected unit clause");
d_current->setUnit();
}