clause.cpp

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  * \file clause.cpp
00004  * \brief Implementation of class Clause
00005  * 
00006  * Author: Sergey Berezin
00007  * 
00008  * Created: Mon Apr 28 17:20:23 2003
00009  *
00010  * <hr>
00011  * Copyright (C) 2003 by the Board of Trustees of Leland Stanford
00012  * Junior University and by New York University. 
00013  *
00014  * License to use, copy, modify, sell and/or distribute this software
00015  * and its documentation for any purpose is hereby granted without
00016  * royalty, subject to the terms and conditions defined in the \ref
00017  * LICENSE file provided with this distribution.  In particular:
00018  *
00019  * - The above copyright notice and this permission notice must appear
00020  * in all copies of the software and related documentation.
00021  *
00022  * - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,
00023  * EXPRESSED OR IMPLIED.  USE IT AT YOUR OWN RISK.
00024  * 
00025  * <hr>
00026  * 
00027  */
00028 /*****************************************************************************/
00029 
00030 #include "clause.h"
00031 #include "theory_core.h"
00032 
00033 using namespace std;
00034 
00035 namespace CVCL {
00036 
00037 ////////////////////////////////////////////////////////////////////////
00038 //  class ClauseValue methods
00039 ////////////////////////////////////////////////////////////////////////
00040 
00041 // Constructor: takes the main clause theorem which must be a
00042 // disjunction of literals and have no assumptions.
00043 ClauseValue::ClauseValue(TheoryCore* core, VariableManager* vm,
00044                          const Theorem& clause, int scope)
00045   : d_refcount(0), d_refcountOwner(0), d_thm(clause), d_scope(scope),
00046     // This backtrackable member is initialized in the first scope
00047     // (which is #0)
00048     d_sat(core->getCM()->getCurrentContext(), false, 0),
00049     d_deleted(false) {
00050   // Check the clause
00051   DebugAssert(clause.getExpr().isOr(), "Clause(): bad clause given: "
00052               + clause.toString());
00053 //   DebugAssert(clause.getExpr().arity()>0, "Clause(): empty clause: "
00054 //            + clause.toString());
00055   // Initialize watched literals to the edges with directions
00056   // pointing outwards
00057   d_wp[0]=0; d_dir[0]=-1;
00058   d_wp[1] = clause.getExpr().arity()-1; d_dir[1]=1;
00059   // Initialize the literals
00060   Expr c(clause.getExpr());
00061   d_literals.reserve(c.arity());
00062   for(Expr::iterator i=c.begin(), iend=c.end(); i!=iend; ++i) {
00063     int val(i->isNot()? -1 : 1);
00064     Variable v(vm, (val < 0)? (*i)[0] : (*i));
00065     Literal l(v, val > 0);
00066     d_literals.push_back(l);
00067     // Update the literal's count for splitter heuristics
00068     l.count()++;
00069   }
00070   IF_DEBUG(d_sat.setName("CDO[Clause.d_sat]"));
00071 }
00072 
00073 ClauseValue::~ClauseValue() {
00074   TRACE_MSG("search literals", "~ClauseValue() {");
00075   FatalAssert(d_refcount == 0, "~ClauseValue: non-zero refcount: "
00076                + int2string(d_refcount));
00077   if(!d_deleted) { // Update the literal counts for splitter heuristics
00078     for(vector<Literal>::iterator i=d_literals.begin(),
00079           iend=d_literals.end(); i!=iend; ++i) {
00080       i->count()--;
00081       IF_DEBUG(if(i->count() == 0)
00082                TRACE("search literals", "Null count for ", *i, ""));
00083     }
00084   }
00085   TRACE_MSG("search literals", "~ClauseValue() => }");
00086 }
00087   
00088 ////////////////////////////////////////////////////////////////////////
00089 //  class Clause methods
00090 ////////////////////////////////////////////////////////////////////////
00091 
00092 // Destructor
00093 Clause::~Clause() {
00094   if(d_clause != NULL) {
00095     DebugAssert(d_clause->d_refcount > 0,
00096                 "~Clause: non-positive refcount: "
00097                 + int2string(d_clause->d_refcount));
00098     if(--(d_clause->d_refcount) == 0) delete d_clause;
00099   }
00100 }
00101 
00102 
00103 void
00104 Clause::markDeleted() const {
00105   TRACE("search literals", "Clause::markDeleted(",
00106         CompactClause(*this), ") {");
00107   DebugAssert(!isNull(), "Clause::markDeleted()");
00108   if(!d_clause->d_deleted) {
00109     d_clause->d_deleted = true;
00110     // Update the literal counts for splitter heuristics
00111     for(vector<Literal>::iterator i=d_clause->d_literals.begin(),
00112           iend=d_clause->d_literals.end(); i!=iend; ++i) {
00113       i->count()--;
00114       IF_DEBUG(if(i->count() == 0)
00115                TRACE("search literals", "Null count for ", *i, ""));
00116     }
00117   }
00118   TRACE_MSG("search literals", "Clause::markDeleted => }");
00119 }
00120 
00121 
00122 // Assignment operator
00123 Clause& Clause::operator=(const Clause& c) {
00124   if(&c == this) return *this; // Self-assignment
00125   if(d_clause != NULL) {
00126     DebugAssert(d_clause->d_refcount > 0,
00127                 "Clause::operator=: non-positive refcount: "
00128                 + int2string(d_clause->d_refcount));
00129     if(--(d_clause->d_refcount) == 0) delete d_clause;
00130   }
00131   d_clause = c.d_clause;
00132   if(d_clause != NULL) d_clause->d_refcount++;
00133   return *this;
00134 }
00135 
00136 // Printing
00137 string Clause::toString() const {
00138   std::ostringstream ss;
00139   ss << *this;
00140   return ss.str();
00141 }
00142 
00143 ostream& operator<<(ostream& os, const Clause& c) {
00144   if(c.isNull()) return os << "Clause[Null]";
00145   os << "Clause[";
00146   if(c.deleted()) os << "DELETED ";
00147   os << c.id();
00148   IF_DEBUG(if(c.getFile() != "")
00149            os << ", " << c.getFile() << ":" << c.getLine());
00150   os << "](" << c.getTheorem()
00151      << ";\n";
00152   if(c.wp(0) == c.wp(1)) os << "WARNING: wp[0] = wp[1]\n";
00153   for(unsigned i=0; i<c.size(); ++i) {
00154     if(c.wp(0) == i)
00155       os << "wp[0]" << ((c.dir(0) > 0)? "=>" : "<=") << " ";
00156     else if(c.wp(1) == i)
00157       os << "wp[1]" << ((c.dir(1) > 0)? "=>" : "<=") << " ";
00158     else
00159       os << "        ";
00160     os << c[i] << ";\n";
00161   }
00162   return os << ((c.sat())? "Clause is SAT" : "") << ")";
00163 }
00164   
00165   static void printLit(ostream& os, const Literal& l) {
00166     if(l.isNegative()) os << "!";
00167     os << l.getVar().getExpr();
00168     int val(l.getValue());
00169     if(val != 0) os << "=" << val << "@" << l.getScope();
00170   }
00171 
00172 ostream& operator<<(std::ostream& os, const CompactClause& c) {
00173   const vector<Literal>& lits = c.d_clause.getLiterals();
00174   int wp0(c.d_clause.wp(0)), wp1(c.d_clause.wp(1));
00175   int i=0, iend=c.d_clause.size();
00176   os << "Clause[";
00177   if(c.d_clause.deleted()) os << "*DELETED* ";
00178   if(c.d_clause.owners() > 0) os << "owned(" << c.d_clause.owners() << ") ";
00179   if(i!=iend) {
00180     if(i==wp0 || i==wp1) os << "*";
00181     printLit(os, lits[i]);  ++i; 
00182   }
00183   for(; i!=iend; ++i) {
00184     os << ", ";
00185     if(i==wp0 || i==wp1) os << "*";
00186     printLit(os, lits[i]);
00187   }
00188   os << "]";
00189   return os;
00190 }
00191 
00192 string CompactClause::toString() const {
00193   ostringstream ss;
00194   ss << (*this);
00195   return ss.str();
00196 }
00197 
00198 #ifdef DEBUG
00199 bool Clause::wpCheck() const
00200 {
00201   if (sat(true))
00202     return true;
00203   return (getLiteral(wp(0)).getValue() == 0 && getLiteral(wp(1)).getValue() == 0);
00204 }
00205 #endif
00206 
00207 } // end of namespace CVCL

Generated on Thu Apr 13 16:57:29 2006 for CVC Lite by  doxygen 1.4.4