00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "cnf_manager.h"
00031 #include "cnf_rules.h"
00032 #include "common_proof_rules.h"
00033 #include "theorem_manager.h"
00034
00035
00036 using namespace std;
00037 using namespace CVCL;
00038 using namespace SAT;
00039
00040
00041 CNF_Manager::CNF_Manager(TheoremManager* tm)
00042 : d_commonRules(tm->getRules()),
00043 d_theorems(tm->getCM()->getCurrentContext()),
00044 d_clauseIdNext(0),
00045
00046 d_bottomScope(-1)
00047 {
00048 d_rules = createProofRules(tm);
00049
00050 Varinfo v;
00051 d_varInfo.push_back(v);
00052 }
00053
00054
00055 CNF_Manager::~CNF_Manager()
00056 {
00057 delete d_rules;
00058 }
00059
00060
00061 Theorem CNF_Manager::replaceITErec(const Expr& e, Var v, bool translateOnly)
00062 {
00063
00064 if (e.isAtomic()) return d_commonRules->reflexivityRule(e);
00065
00066
00067 Theorem thm;
00068 bool foundInCache = false;
00069 ExprMap<Theorem>::iterator iMap = d_iteMap.find(e);
00070 if (iMap != d_iteMap.end()) {
00071 thm = (*iMap).second;
00072 foundInCache = true;
00073 }
00074
00075 if (e.getKind() == ITE) {
00076
00077 DebugAssert(!e.getType().isBool(), "Expected non-Bool ITE");
00078
00079 if (!foundInCache) thm = d_commonRules->varIntroSkolem(e);
00080 Theorem thm2 = d_commonRules->symmetryRule(thm);
00081 thm2 = d_commonRules->iffMP(thm2, d_rules->ifLiftRule(thm2.getExpr(), 1));
00082 d_translateQueueVars.push_back(v);
00083 d_translateQueueThms.push_back(thm2);
00084 d_translateQueueFlags.push_back(translateOnly);
00085 }
00086 else {
00087
00088 vector<Theorem> thms;
00089 vector<unsigned> changed;
00090 unsigned index = 0;
00091 Expr::iterator i, iend;
00092 if (foundInCache) {
00093 for(i = e.begin(), iend = e.end(); i!=iend; ++i, ++index) {
00094 replaceITErec(*i, v, translateOnly);
00095 }
00096 }
00097 else {
00098 for(i = e.begin(), iend = e.end(); i!=iend; ++i, ++index) {
00099 thm = replaceITErec(*i, v, translateOnly);
00100 if(thm.getLHS() != thm.getRHS()) {
00101 thms.push_back(thm);
00102 changed.push_back(index);
00103 }
00104 }
00105 if(changed.size() > 0) {
00106 thm = d_commonRules->substitutivityRule(e, changed, thms);
00107 }
00108 else thm = d_commonRules->reflexivityRule(e);
00109 }
00110 }
00111
00112
00113 if (!foundInCache) d_iteMap[e] = thm;
00114 return thm;
00115 }
00116
00117
00118 Lit CNF_Manager::translateExprRec(const Expr& e, CNF_Formula& cnf)
00119 {
00120 if (e.isFalse()) return Lit::getFalse();
00121 if (e.isTrue()) return Lit::getTrue();
00122 if (e.isNot()) return !translateExprRec(e[0], cnf);
00123
00124 ExprMap<Var>::iterator iMap = d_cnfVars.find(e);
00125
00126 if (e.isTranslated()) {
00127 DebugAssert(iMap != d_cnfVars.end(), "Translated expr should be in map");
00128 return Lit((*iMap).second);
00129 }
00130 else e.setTranslated(d_bottomScope);
00131
00132 Var v(int(d_varInfo.size()));
00133 bool translateOnly = false;
00134
00135 if (iMap != d_cnfVars.end()) {
00136 v = (*iMap).second;
00137 translateOnly = true;
00138 d_varInfo[v].fanouts.clear();
00139 }
00140 else {
00141 d_varInfo.resize(v+1);
00142 d_varInfo.back().expr = e;
00143 d_cnfVars[e] = v;
00144 }
00145
00146 Expr::iterator i, iend;
00147
00148 bool isAnd = false;
00149 switch (e.getKind()) {
00150 case AND:
00151 isAnd = true;
00152 case OR: {
00153 vector<Lit> lits;
00154 unsigned idx;
00155 for (i = e.begin(), iend = e.end(); i != iend; ++i) {
00156 lits.push_back(translateExprRec(*i, cnf));
00157 }
00158 for (idx = 0; idx < lits.size(); ++idx) {
00159 cnf.newClause();
00160 cnf.addLiteral(v,isAnd);
00161 cnf.addLiteral(lits[idx], !isAnd);
00162 }
00163 cnf.newClause();
00164 cnf.addLiteral(v,!isAnd);
00165 for (idx = 0; idx < lits.size(); ++idx) {
00166 cnf.addLiteral(lits[idx], isAnd);
00167 }
00168 break;
00169 }
00170 case IMPLIES: {
00171 Lit arg0 = translateExprRec(e[0], cnf);
00172 Lit arg1 = translateExprRec(e[1], cnf);
00173
00174 cnf.newClause();
00175 cnf.addLiteral(v);
00176 cnf.addLiteral(arg0);
00177
00178 cnf.newClause();
00179 cnf.addLiteral(v);
00180 cnf.addLiteral(arg1,true);
00181
00182 cnf.newClause();
00183 cnf.addLiteral(v,true);
00184 cnf.addLiteral(arg0,true);
00185 cnf.addLiteral(arg1);
00186 break;
00187 }
00188 case IFF: {
00189 Lit arg0 = translateExprRec(e[0], cnf);
00190 Lit arg1 = translateExprRec(e[1], cnf);
00191
00192 cnf.newClause();
00193 cnf.addLiteral(v);
00194 cnf.addLiteral(arg0);
00195 cnf.addLiteral(arg1);
00196
00197 cnf.newClause();
00198 cnf.addLiteral(v);
00199 cnf.addLiteral(arg0,true);
00200 cnf.addLiteral(arg1,true);
00201
00202 cnf.newClause();
00203 cnf.addLiteral(v,true);
00204 cnf.addLiteral(arg0,true);
00205 cnf.addLiteral(arg1);
00206
00207 cnf.newClause();
00208 cnf.addLiteral(v,true);
00209 cnf.addLiteral(arg0);
00210 cnf.addLiteral(arg1,true);
00211 break;
00212 }
00213 case XOR: {
00214 Lit arg0 = translateExprRec(e[0], cnf);
00215 Lit arg1 = translateExprRec(e[1], cnf);
00216
00217 cnf.newClause();
00218 cnf.addLiteral(v,true);
00219 cnf.addLiteral(arg0);
00220 cnf.addLiteral(arg1);
00221
00222 cnf.newClause();
00223 cnf.addLiteral(v,true);
00224 cnf.addLiteral(arg0,true);
00225 cnf.addLiteral(arg1,true);
00226
00227 cnf.newClause();
00228 cnf.addLiteral(v);
00229 cnf.addLiteral(arg0,true);
00230 cnf.addLiteral(arg1);
00231
00232 cnf.newClause();
00233 cnf.addLiteral(v);
00234 cnf.addLiteral(arg0);
00235 cnf.addLiteral(arg1,true);
00236 break;
00237 }
00238 case ITE:
00239 {
00240 Lit arg0 = translateExprRec(e[0], cnf);
00241 Lit arg1 = translateExprRec(e[1], cnf);
00242 Lit arg2 = translateExprRec(e[2], cnf);
00243
00244 cnf.newClause();
00245 cnf.addLiteral(v,true);
00246 cnf.addLiteral(arg0);
00247 cnf.addLiteral(arg2);
00248
00249 cnf.newClause();
00250 cnf.addLiteral(v);
00251 cnf.addLiteral(arg0);
00252 cnf.addLiteral(arg2,true);
00253
00254 cnf.newClause();
00255 cnf.addLiteral(v);
00256 cnf.addLiteral(arg0,true);
00257 cnf.addLiteral(arg1,true);
00258
00259 cnf.newClause();
00260 cnf.addLiteral(v,true);
00261 cnf.addLiteral(arg0,true);
00262 cnf.addLiteral(arg1);
00263
00264 cnf.newClause();
00265 cnf.addLiteral(v);
00266 cnf.addLiteral(arg1,true);
00267 cnf.addLiteral(arg2,true);
00268
00269 cnf.newClause();
00270 cnf.addLiteral(v,true);
00271 cnf.addLiteral(arg1);
00272 cnf.addLiteral(arg2);
00273 break;
00274 }
00275 default:
00276 DebugAssert(!e.isAbsAtomicFormula() || d_varInfo[v].expr == e,
00277 "Corrupted Varinfo");
00278 if (e.isAbsAtomicFormula()) return v;
00279 Theorem thm = replaceITErec(e, v, translateOnly);
00280 const Expr& e2 = thm.getRHS();
00281 DebugAssert(e2.isAbsAtomicFormula(), "Expected AbsAtomicFormula");
00282 if (e2.isTranslated()) {
00283
00284
00285
00286 DebugAssert(!translateOnly, "Expected translateOnly = false");
00287 d_varInfo.resize(v-1);
00288 while (d_translateQueueVars.back() == v) {
00289 d_translateQueueVars.pop_back();
00290 }
00291 DebugAssert(d_cnfVars.find(e2) != d_cnfVars.end(),
00292 "Expected existing literal");
00293 v = d_cnfVars[e2];
00294 while (d_translateQueueVars.size() < d_translateQueueThms.size()) {
00295 d_translateQueueVars.push_back(v);
00296 }
00297 }
00298 else {
00299 e2.setTranslated(d_bottomScope);
00300 if (!translateOnly) {
00301 DebugAssert(d_cnfVars.find(e2) == d_cnfVars.end(),
00302 "Expected new literal");
00303 d_varInfo[v].expr = e2;
00304 d_cnfVars[e2] = v;
00305 }
00306 }
00307 return v;
00308 }
00309
00310
00311 Lit l;
00312 for (i = e.begin(), iend = e.end(); i != iend; ++i) {
00313 l = getCNFLit(*i);
00314 DebugAssert(!l.isNull(), "Expected non-null literal");
00315 if (!translateOnly) d_varInfo[v].fanins.push_back(l);
00316 if (l.isVar()) d_varInfo[l.getVar()].fanouts.push_back(v);
00317 }
00318 return v;
00319 }
00320
00321
00322 Lit CNF_Manager::translateExpr(const Expr& e, CNF_Formula& cnf)
00323 {
00324 Lit l;
00325 Var v;
00326 Theorem thm;
00327 bool translateOnly;
00328
00329 Lit ret = translateExprRec(e, cnf);
00330
00331 while (d_translateQueueVars.size()) {
00332 v = d_translateQueueVars.front();
00333 d_translateQueueVars.pop_front();
00334 thm = d_translateQueueThms.front();
00335 d_translateQueueThms.pop_front();
00336 translateOnly = d_translateQueueFlags.front();
00337 d_translateQueueFlags.pop_front();
00338 l = translateExprRec(thm.getExpr(), cnf);
00339 cnf.newClause();
00340 cnf.addLiteral(l);
00341 cnf.registerUnit();
00342 d_theorems.insert(d_clauseIdNext, thm);
00343 cnf.getCurrentClause().setId(d_clauseIdNext++);
00344 FatalAssert(d_clauseIdNext != 0, "Overflow of clause id's");
00345 if (!translateOnly) d_varInfo[v].fanins.push_back(l);
00346 d_varInfo[l.getVar()].fanouts.push_back(v);
00347 }
00348 return ret;
00349 }
00350
00351
00352 void CNF_Manager::convertLemma(const Theorem& thm, Clause& c)
00353 {
00354 DebugAssert(c.size() == 0, "Expected empty clause");
00355 Theorem clause = d_rules->learnedClause(thm);
00356
00357 const Expr& e = clause.getExpr();
00358 if (!e.isOr()) {
00359 DebugAssert(!getCNFLit(e).isNull(), "Unknown literal");
00360 c.addLiteral(getCNFLit(e));
00361 }
00362 else {
00363 Expr::iterator iend = e.end();
00364 for (Expr::iterator i = e.begin(); i != iend; ++i) {
00365 DebugAssert(!getCNFLit(*i).isNull(), "Unknown literal");
00366 c.addLiteral(getCNFLit(*i));
00367 }
00368 }
00369 if (c.size() == 1) c.setUnit();
00370
00371 d_theorems.insert(d_clauseIdNext, clause);
00372 c.setId(d_clauseIdNext++);
00373 FatalAssert(d_clauseIdNext != 0, "Overflow of clause id's");
00374 }
00375
00376
00377 Lit CNF_Manager::addAssumption(const Theorem& thm, CNF_Formula& cnf)
00378 {
00379 Lit l = translateExpr(thm.getExpr(), cnf);
00380 cnf.newClause();
00381 cnf.addLiteral(l);
00382 cnf.registerUnit();
00383
00384 d_theorems[d_clauseIdNext] = thm;
00385 cnf.getCurrentClause().setId(d_clauseIdNext++);
00386 FatalAssert(d_clauseIdNext != 0, "Overflow of clause id's");
00387
00388 return l;
00389 }
00390
00391
00392 Lit CNF_Manager::addLemma(const Theorem& thm, CNF_Formula& cnf)
00393 {
00394 Theorem clause = d_rules->learnedClause(thm);
00395
00396 Lit l = translateExpr(clause.getExpr(), cnf);
00397 cnf.newClause();
00398 cnf.addLiteral(l);
00399 cnf.registerUnit();
00400
00401 d_theorems.insert(d_clauseIdNext, clause);
00402 cnf.getCurrentClause().setId(d_clauseIdNext++);
00403 FatalAssert(d_clauseIdNext != 0, "Overflow of clause id's");
00404
00405 return l;
00406 }