CVC3
|
00001 /*****************************************************************************/ 00002 /*! 00003 *\file cnf.cpp 00004 *\brief Implementation of classes used for generic CNF formulas 00005 * 00006 * Author: Clark Barrett 00007 * 00008 * Created: Mon Dec 12 22:16:11 2005 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 "cnf.h" 00023 00024 00025 using namespace std; 00026 using namespace CVC3; 00027 using namespace SAT; 00028 00029 00030 unsigned SAT::Clause::getMaxVar() const 00031 { 00032 unsigned max = 0; 00033 const_iterator i, iend; 00034 for (i = begin(), iend = end(); i != iend; ++i) { 00035 DebugAssert(!(*i).isNull(), "Null literal found in clause"); 00036 if (unsigned((*i).getVar()) > max) max = unsigned((*i).getVar()); 00037 } 00038 return max; 00039 } 00040 00041 00042 void SAT::Clause::print() const 00043 { 00044 if (isSatisfied()) cout << "*"; 00045 const_iterator i, iend; 00046 for (i = begin(), iend = end(); i != iend; ++i) { 00047 if ((*i).isNull()) cout << "NULL"; 00048 else if ((*i).isFalse()) cout << "F"; 00049 else if ((*i).isTrue()) cout << "T"; 00050 else { 00051 if (!(*i).isPositive()) cout << "-"; 00052 cout << (*i).getVar(); 00053 } 00054 cout << " "; 00055 } 00056 cout << endl; 00057 } 00058 00059 00060 void CNF_Formula::copy(const CNF_Formula& cnf) 00061 { 00062 setNumVars(0); 00063 Clause* c = d_current; 00064 // Don't use iterators in case cnf == *this 00065 unsigned i, iend; 00066 Clause::const_iterator j, jend; 00067 for (i = 0, iend = cnf.numClauses(); i != iend; ++i) { 00068 newClause(); 00069 for (j = cnf[i].begin(), jend = cnf[i].end(); j != jend; ++j) { 00070 addLiteral(*j); 00071 } 00072 00073 Clause oldClause = cnf[i]; 00074 // CVC3::Theorem clauseThm = oldClause.getClauseTheorem(); 00075 CVC3::Theorem clauseThm = cnf[i].getClauseTheorem(); 00076 getCurrentClause().setClauseTheorem(clauseThm);//by yeting 00077 00078 if (cnf[i].isUnit()) registerUnit(); 00079 if (&(cnf[i]) == cnf.d_current) c = d_current; 00080 } 00081 d_current = c; 00082 } 00083 00084 00085 void CNF_Formula::print() const 00086 { 00087 const_iterator i, iend; 00088 for (i = begin(), iend = end(); i != iend; ++i) { 00089 (*i).print(); 00090 } 00091 } 00092 00093 00094 const CNF_Formula& CNF_Formula::operator+=(const CNF_Formula& cnf) 00095 { 00096 Clause* c = d_current; 00097 // Don't use iterators in case cnf == *this 00098 unsigned i, iend; 00099 Clause::const_iterator j, jend; 00100 for (i = 0, iend = cnf.numClauses(); i != iend; ++i) { 00101 newClause(); 00102 for (j = cnf[i].begin(), jend = cnf[i].end(); j != jend; ++j) { 00103 addLiteral(*j); 00104 } 00105 00106 Clause oldClause = cnf[i]; 00107 CVC3::Theorem clauseThm = oldClause.getClauseTheorem(); 00108 getCurrentClause().setClauseTheorem(clauseThm);//by yeting 00109 00110 if (cnf[i].isUnit()) registerUnit(); 00111 } 00112 d_current = c; 00113 return *this; 00114 } 00115 00116 00117 const CNF_Formula& CNF_Formula::operator+=(const Clause& c) 00118 { 00119 Clause* cur = d_current; 00120 newClause(); 00121 Clause::const_iterator j, jend; 00122 for (j=c.begin(), jend = c.end(); j != jend; ++j) { 00123 addLiteral(*j); 00124 } 00125 00126 Clause oldClause = c; 00127 CVC3::Theorem clauseThm = oldClause.getClauseTheorem(); 00128 getCurrentClause().setClauseTheorem(clauseThm);//by yeting 00129 00130 00131 if (c.isUnit()) registerUnit(); 00132 d_current = cur; 00133 return *this; 00134 } 00135 00136 00137 void CNF_Formula_Impl::newClause() 00138 { 00139 d_formula.resize(d_formula.size()+1); 00140 d_current = &(d_formula.back()); 00141 } 00142 00143 00144 void CNF_Formula_Impl::registerUnit() 00145 { 00146 DebugAssert(d_current->size()==1,"Expected unit clause"); 00147 d_current->setUnit(); 00148 Lit l = *(d_current->begin()); 00149 d_lits[l.getID()] = true; 00150 } 00151 00152 00153 void CNF_Formula_Impl::simplify() 00154 { 00155 deque<Clause>::iterator i, iend; 00156 Clause::const_iterator j, jend; 00157 for (i = d_formula.begin(), iend = d_formula.end(); i != iend; ++i) { 00158 if ((*i).isUnit()) continue; 00159 for (j=(*i).begin(), jend = (*i).end(); j != jend; ++j) { 00160 if ((*j).isTrue()) { 00161 (*i).setSatisfied(); 00162 break; 00163 } 00164 hash_map<int, bool>::iterator it = d_lits.find((*j).getID()); 00165 if (it != d_lits.end()) { 00166 (*i).setSatisfied(); 00167 break; 00168 } 00169 } 00170 } 00171 } 00172 00173 00174 void CNF_Formula_Impl::reset() 00175 { 00176 d_formula.clear(); 00177 d_lits.clear(); 00178 d_current = NULL; 00179 d_numVars = 0; 00180 } 00181 00182 00183 void CD_CNF_Formula::newClause() 00184 { 00185 //TODO: don't call constructor twice 00186 d_current = &(d_formula.push_back(Clause())); 00187 } 00188 00189 00190 void CD_CNF_Formula::registerUnit() 00191 { 00192 DebugAssert(d_current->size()==1,"Expected unit clause"); 00193 d_current->setUnit(); 00194 } 00195 00196