/*****************************************************************************/
/*!
* \file clause.cpp
* \brief Implementation of class Clause
*
* Author: Sergey Berezin
*
* Created: Mon Apr 28 17:20:23 2003
*
*
*
* 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 "clause.h"
#include "theory_core.h"
using namespace std;
namespace CVC3 {
////////////////////////////////////////////////////////////////////////
// class ClauseValue methods
////////////////////////////////////////////////////////////////////////
// Constructor: takes the main clause theorem which must be a
// disjunction of literals and have no assumptions.
ClauseValue::ClauseValue(TheoryCore* core, VariableManager* vm,
const Theorem& clause, int scope)
: d_refcount(0), d_refcountOwner(0), d_thm(clause), d_scope(scope),
// This backtrackable member is initialized in the first scope
// (which is #0)
d_sat(core->getCM()->getCurrentContext(), false, 0),
d_deleted(false) {
// Check the clause
DebugAssert(clause.getExpr().isOr(), "Clause(): bad clause given: "
+ clause.toString());
// DebugAssert(clause.getExpr().arity()>0, "Clause(): empty clause: "
// + clause.toString());
// Initialize watched literals to the edges with directions
// pointing outwards
d_wp[0]=0; d_dir[0]=-1;
d_wp[1] = clause.getExpr().arity()-1; d_dir[1]=1;
// Initialize the literals
Expr c(clause.getExpr());
d_literals.reserve(c.arity());
for(Expr::iterator i=c.begin(), iend=c.end(); i!=iend; ++i) {
int val(i->isNot()? -1 : 1);
Variable v(vm, (val < 0)? (*i)[0] : (*i));
Literal l(v, val > 0);
d_literals.push_back(l);
// Update the literal's count for splitter heuristics
l.count()++;
}
IF_DEBUG(d_sat.setName("CDO[Clause.d_sat]"));
}
ClauseValue::~ClauseValue() {
TRACE_MSG("search literals", "~ClauseValue() {");
FatalAssert(d_refcount == 0, "~ClauseValue: non-zero refcount: "
+ int2string(d_refcount));
if(!d_deleted) { // Update the literal counts for splitter heuristics
for(vector::iterator i=d_literals.begin(),
iend=d_literals.end(); i!=iend; ++i) {
i->count()--;
IF_DEBUG(if(i->count() == 0)
TRACE("search literals", "Null count for ", *i, ""));
}
}
TRACE_MSG("search literals", "~ClauseValue() => }");
}
////////////////////////////////////////////////////////////////////////
// class Clause methods
////////////////////////////////////////////////////////////////////////
// Destructor
Clause::~Clause() {
if(d_clause != NULL) {
FatalAssert(d_clause->d_refcount > 0,
"~Clause: non-positive refcount: "
+ int2string(d_clause->d_refcount));
if(--(d_clause->d_refcount) == 0) delete d_clause;
}
}
void
Clause::markDeleted() const {
TRACE("search literals", "Clause::markDeleted(",
CompactClause(*this), ") {");
DebugAssert(!isNull(), "Clause::markDeleted()");
if(!d_clause->d_deleted) {
d_clause->d_deleted = true;
// Update the literal counts for splitter heuristics
for(vector::iterator i=d_clause->d_literals.begin(),
iend=d_clause->d_literals.end(); i!=iend; ++i) {
i->count()--;
IF_DEBUG(if(i->count() == 0)
TRACE("search literals", "Null count for ", *i, ""));
}
}
TRACE_MSG("search literals", "Clause::markDeleted => }");
}
// Assignment operator
Clause& Clause::operator=(const Clause& c) {
if(&c == this) return *this; // Self-assignment
if(d_clause != NULL) {
DebugAssert(d_clause->d_refcount > 0,
"Clause::operator=: non-positive refcount: "
+ int2string(d_clause->d_refcount));
if(--(d_clause->d_refcount) == 0) delete d_clause;
}
d_clause = c.d_clause;
if(d_clause != NULL) d_clause->d_refcount++;
return *this;
}
// Printing
string Clause::toString() const {
std::ostringstream ss;
ss << *this;
return ss.str();
}
ostream& operator<<(ostream& os, const Clause& c) {
if(c.isNull()) return os << "Clause[Null]";
os << "Clause[";
if(c.deleted()) os << "DELETED ";
os << c.id();
IF_DEBUG(if(c.getFile() != "")
os << ", " << c.getFile() << ":" << c.getLine());
os << "](" << c.getTheorem()
<< ";\n";
if(c.wp(0) == c.wp(1)) os << "WARNING: wp[0] = wp[1]\n";
for(unsigned i=0; i 0)? "=>" : "<=") << " ";
else if(c.wp(1) == i)
os << "wp[1]" << ((c.dir(1) > 0)? "=>" : "<=") << " ";
else
os << " ";
os << c[i] << ";\n";
}
return os << ((c.sat())? "Clause is SAT" : "") << ")";
}
static void printLit(ostream& os, const Literal& l) {
if(l.isNegative()) os << "!";
os << l.getVar().getExpr();
int val(l.getValue());
if(val != 0) os << "=" << val << "@" << l.getScope();
}
ostream& operator<<(std::ostream& os, const CompactClause& c) {
const vector& lits = c.d_clause.getLiterals();
int wp0(c.d_clause.wp(0)), wp1(c.d_clause.wp(1));
int i=0, iend=c.d_clause.size();
os << "Clause[";
if(c.d_clause.deleted()) os << "*DELETED* ";
if(c.d_clause.owners() > 0) os << "owned(" << c.d_clause.owners() << ") ";
if(i!=iend) {
if(i==wp0 || i==wp1) os << "*";
printLit(os, lits[i]); ++i;
}
for(; i!=iend; ++i) {
os << ", ";
if(i==wp0 || i==wp1) os << "*";
printLit(os, lits[i]);
}
os << "]";
return os;
}
string CompactClause::toString() const {
ostringstream ss;
ss << (*this);
return ss.str();
}
#ifdef DEBUG
bool CVC3::Clause::wpCheck() const
{
if (sat(true))
return true;
return (getLiteral(wp(0)).getValue() == 0 && getLiteral(wp(1)).getValue() == 0);
}
#endif
} // end of namespace CVC3