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