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
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #ifndef LISTOBJ_H_JUN_21_2005
00067 #define LISTOBJ_H_JUN_21_2005
00068
00069 #include <string>
00070 #include <list>
00071 #include <ostream>
00072 #include <ext/hash_map>
00073 using namespace __gnu_cxx;
00074 #include "array.h"
00075 #include "hashstring.h"
00076 #include "domain.h"
00077 #include "arraysaccessor.h"
00078
00079 typedef hash_map<const string, int, HashString, EqualString> VarTypeMap;
00080
00081
00082
00083
00084
00085
00086
00087
00088 class ListObj
00089 {
00090 public:
00091 ListObj()
00092 {
00093 str_ = new char[1];
00094 str_[0] = '\0';
00095 }
00096
00097
00098 ListObj(const char* const & str)
00099 {
00100 if (str != NULL)
00101 {
00102 str_ = new char[strlen(str)+1];
00103 strcpy(str_, str);
00104 }
00105 else
00106 {
00107 str_ = new char[1];
00108 str_[0] = '\0';
00109 }
00110 }
00111
00112
00113 ListObj(const ListObj* const & p)
00114 {
00115 for (int i = 0; i < p->size(); i++)
00116 list_.append(new ListObj((*p)[i]));
00117 str_ = new char[strlen(p->str_)+1];
00118 strcpy(str_, p->str_);
00119
00120 assert(p->list_.size() == list_.size());
00121
00122 }
00123
00124
00125 ~ListObj() { delete [] str_; list_.deleteItemsAndClear(); }
00126
00127
00128 void clear() { list_.clear(); delete [] str_; str_=new char[1];str_[0]='\0'; }
00129
00130 void deleteAndClear() { list_.deleteItemsAndClear(); clear(); }
00131
00132 void clearList() { list_.clear(); }
00133
00134 ostream& print(ostream& out) const
00135 {
00136 if (isStr())
00137 out << str_;
00138 else
00139 {
00140 out << "(";
00141 for (int i = 0; i < list_.size(); i++)
00142 {
00143 list_[i]->print(out);
00144 out << ((i<list_.size()-1)? " " : "");
00145 }
00146 out << ")";
00147 }
00148 return out;
00149 }
00150
00151
00152
00153 const Array<ListObj*>& getList() const { return list_; }
00154
00155
00156 const char* getStr() const { return str_; }
00157
00158
00159
00160 void setStrIfStr(const char* str)
00161 {
00162 if (isStr())
00163 {
00164 delete [] str_;
00165 str_ = new char[strlen(str)+1];
00166 strcpy(str_,str);
00167 }
00168 }
00169
00170 bool isStr() const { return (strlen(str_) > 0); }
00171
00172 bool isList() const { return !isStr(); }
00173
00174 void append(ListObj* const & p) { list_.append(p); }
00175
00176 void append(const char* const & s) { list_.append(new ListObj(s)); }
00177
00178 int size() const { return list_.size(); }
00179
00180 ListObj* operator[](const int& index) const { return list_[index]; }
00181
00182
00183 static ListObj* toCNF(const ListObj* const & p, const ListObj* const & vars,
00184 const Domain* const & domain,
00185 const VarTypeMap * const& vtMap, bool& hasExist)
00186 {
00187 ListObj* p1 = eliminateImplication(p);
00188
00189 const char* opp = op(p1)->str_;
00190
00191 if (strcmp(opp, "!")==0)
00192 {
00193 ListObj* p2 = moveNotInwards(arg1(p1));
00194 if (isLiteralClause(p2)) { delete p1; return p2; }
00195
00196 ListObj* ret = toCNF(p2, vars, domain, vtMap, hasExist);
00197 delete p2; delete p1;
00198 return ret;
00199 }
00200
00201 if (strcmp(opp, "^")==0)
00202 {
00203 ListObj* n = NULL;
00204 int numConj = 0;
00205 ListObj* firstConj = NULL;
00206
00207 for (int i = 1; i < p1->size(); i++)
00208 {
00209 ListObj* conj = toCNF((*p1)[i], vars, domain, vtMap, hasExist);
00210
00211 bool isConj = strcmp(op(conj)->str_, "^")==0;
00212 int jbeg = (isConj) ? 1 : 0;
00213 int jmax = (isConj) ? conj->size() : 1;
00214 ListObj* conjj;
00215
00216 for (int j = jbeg; j < jmax; j++)
00217 {
00218 if (isConj) conjj = (*conj)[j];
00219 else conjj = conj;
00220
00221 numConj++;
00222 if (numConj==1) { firstConj = conjj; continue; }
00223 else
00224 if (numConj==2) {n=new ListObj; n->append("^"); n->append(firstConj);}
00225 n->append(conjj);
00226 }
00227
00228 if (isConj) { delete (*conj)[0]; conj->clearList(); delete conj; }
00229
00230 }
00231
00232 delete p1;
00233 if (numConj == 1) { return firstConj; }
00234 return n;
00235 }
00236
00237 if (strcmp(opp, "v")==0)
00238 {
00239 ListObj* n = new ListObj;
00240 for (int i = 1; i < p1->size(); i++)
00241 n->append(toCNF((*p1)[i], vars, domain, vtMap, hasExist));
00242 ListObj* ret = mergeDisjuncts(n, n->size());
00243
00244 delete n; delete p1;
00245 return ret;
00246 }
00247
00248 if (strcmp(opp, "FORALL")==0)
00249 {
00250 const ListObj* arg1var = arg1(p1);
00251
00252 ListObj* newVar = new ListObj;
00253 for (int i = 0; i < arg1var->size(); i++)
00254 newVar->append(newVariable((*arg1var)[i]));
00255 assert(newVar->size() == arg1var->size());
00256
00257 const ListObj* aarg2 = new ListObj(arg2(p1));
00258
00259 for (int i = 0; i < newVar->size(); i++)
00260 for (int j = 0; j < aarg2->size(); j++)
00261 (*aarg2)[j]->sub((*arg1var)[i], (*newVar)[i]);
00262
00263 ListObj* app = new ListObj;
00264 for (int i = 0; i < newVar->size(); i++) app->append((*newVar)[i]);
00265 for (int i = 0; i < vars->size(); i++) app->append((*vars)[i]);
00266
00267 newVar->clearList();
00268 delete newVar;
00269 ListObj* ret = toCNF(aarg2, app, domain, vtMap, hasExist);
00270 delete aarg2; delete app; delete p1;
00271 return ret;
00272 }
00273
00274 if (strcmp(opp, "EXIST")==0)
00275 {
00276 hasExist = true;
00277 const ListObj* a2 = arg2(p1);
00278 const ListObj* a1 = arg1(p1);
00279
00280
00281
00282 if (domain == NULL)
00283 {
00284 ListObj* sk = skolemize(a2, a1, vars);
00285 ListObj* c = toCNF(sk, vars, domain, vtMap, hasExist);
00286 delete sk; delete p1;
00287 return c;
00288 }
00289
00290 Array<string> varNames;
00291 for (int i = 0; i < a1->size(); i++)
00292 varNames.append((*a1)[i]->getStr());
00293
00294 ArraysAccessor<int> arrAccessor;
00295 for (int i = 0; i < varNames.size(); i++)
00296 {
00297 VarTypeMap::const_iterator mit = vtMap->find(varNames[i]);
00298 assert(mit != vtMap->end());
00299 int typeId = (*mit).second;
00300 assert(typeId > 0);
00301 const Array<int>* constArr = domain->getConstantsByType(typeId);
00302 if (constArr->size() == 0)
00303 {
00304 cout << "You must declare constants for type "
00305 << domain->getTypeName(typeId)
00306 << " in order to ground the variable " << varNames[i] << endl;
00307 exit(-1);
00308 }
00309 arrAccessor.appendArray(constArr);
00310 }
00311
00312 if (varNames.size()==0){cout<<"ERROR: EXIST has no vars."<<endl;exit(-1);}
00313
00314 ListObj* newFormula = new ListObj;
00315 newFormula->append("v");
00316 Array<int> constIds;
00317 while (arrAccessor.getNextCombination(constIds))
00318 {
00319 ListObj* replacedFormula = new ListObj(a2);
00320
00321 assert(constIds.size() == varNames.size());
00322 for (int i = 0; i < varNames.size(); i++)
00323 {
00324 const char* constName = domain->getConstantName(constIds[i]);
00325 replace(replacedFormula, varNames[i].c_str(), constName, domain);
00326 }
00327 newFormula->append(replacedFormula);
00328 }
00329
00330
00331 delete p1;
00332 ListObj* c = toCNF(newFormula, vars, domain, vtMap, hasExist);
00333
00334 delete newFormula;
00335 return c;
00336 }
00337
00338 return p1;
00339 }
00340
00341
00342 void replaceAsterisk(const Array<bool>& bArr, int& idx)
00343 {
00344 if (!isStr())
00345 {
00346 const char* opp = op(this)->str_;
00347
00348 if (strcmp(opp, "*")==0)
00349 {
00350 assert(size()==2);
00351
00352
00353 if (!bArr[idx])
00354 (*this)[0]->setStrIfStr("!");
00355 else
00356 {
00357 ListObj* unNegatedFormula = new ListObj((*this)[1]);
00358 assert(!unNegatedFormula->isStr());
00359 deleteAndClear();
00360 for (int i = 0; i < unNegatedFormula->size(); i++)
00361 append((*unNegatedFormula)[i]);
00362 unNegatedFormula->clear();
00363 delete unNegatedFormula;
00364 }
00365 idx++;
00366 if (idx == bArr.size()) return;
00367 }
00368
00369 for (int i = 0; i < size(); i++)
00370 {
00371 (*this)[i]->replaceAsterisk(bArr, idx);
00372 if (idx == bArr.size()) return;
00373 }
00374 }
00375 }
00376
00377
00378
00379 void cleanUpVars()
00380 {
00381 if (isStr())
00382 {
00383 if (str_[0] != '$') return;
00384 char* dot = strrchr(str_, '.');
00385 if (dot==NULL) return;
00386 int numChar = dot-str_-1;
00387 char* tmp = new char[numChar+1];
00388 strncpy(tmp, str_+1, numChar);
00389 tmp[numChar] = '\0';
00390 delete [] str_;
00391 str_ = tmp;
00392 }
00393 else
00394 for (int i = 0; i < list_.size(); i++)
00395 list_[i]->cleanUpVars();
00396 }
00397
00398
00399 void removeRedundantPredicates()
00400 {
00401 const char* opp = op(this)->str_;
00402
00403 if (strcmp(opp,"^")==0)
00404 {
00405 for (int i = 1; i < size(); i++)
00406 removeRedundantPredicates((*this)[i]);
00407 }
00408 else
00409 removeRedundantPredicates(this);
00410 }
00411
00412
00413 void removeRedundantClauses()
00414 {
00415
00416
00417
00418
00419
00420 const char* opp = op(this)->str_;
00421
00422 if (strcmp(opp,"^")==0)
00423 {
00424 for (int i = 1; i < size(); i++)
00425 removeRedundantPredicates((*this)[i]);
00426
00427 Array<ListObj*> clauses, redundantClauses;
00428 for (int i = 1; i < size(); i++)
00429 {
00430 bool keep = true;
00431 for (int j = 1; j < size(); j++)
00432 {
00433 if (i==j) continue;
00434 if (subsetOf((*this)[j],(*this)[i]))
00435 if ((*this)[i]->size() != (*this)[j]->size() || i < j)
00436 { keep = false; break; }
00437 }
00438 if (keep) clauses.append((*this)[i]);
00439 else redundantClauses.append((*this)[i]);
00440 }
00441
00442 ListObj* andOper = (*this)[0];
00443 assert(strcmp(andOper->str_,"^")==0);
00444
00445 for (int i = 0; i < redundantClauses.size(); i++)
00446 delete redundantClauses[i];
00447 clear();
00448 append(andOper);
00449 for (int i = 0; i < clauses.size(); i++) append(clauses[i]);
00450 }
00451 else
00452 removeRedundantPredicates(this);
00453 }
00454
00455
00456 static void replace(const ListObj* const & p, const char* const & varName,
00457 const char* const& constName, const Domain* const& domain)
00458 {
00459 const char* opp = op(p)->str_;
00460
00461
00462
00463 if (strcmp(opp, "EXIST")==0 || strcmp(opp, "FORALL")==0)
00464 if (containsVarName((*p)[1], varName)) return;
00465
00466
00467 const bool isPredFunc = ( domain->isPredicate(opp)
00468 || domain->isFunction(opp));
00469
00470 for (int i = 1; i < p->size(); i++)
00471 {
00472
00473
00474 if (isPredFunc && (*p)[i]->isStr())
00475 {
00476
00477 if (strcmp((*p)[i]->getStr(), varName)==0)
00478 (*p)[i]->setStrIfStr(constName);
00479 }
00480 else
00481 replace((*p)[i], varName, constName, domain);
00482 }
00483 }
00484
00485
00486 void replace(const char* const & oldop, const char* const & newop)
00487 {
00488 for (int i = 0; i < size(); i++)
00489 {
00490 if (strcmp((*this)[i]->getStr(), oldop)==0)
00491 (*this)[i]->setStrIfStr(newop);
00492 else
00493 (*this)[i]->replace(oldop, newop);
00494 }
00495 }
00496
00497
00498 bool hasOrOp()
00499 {
00500 if (!isList()) return false;
00501 return (strcmp(op(this)->str_,"v")==0);
00502 }
00503
00504
00505 bool hasAndOp()
00506 {
00507 if (!isList()) return false;
00508 return (strcmp(op(this)->str_,"^")==0);
00509 }
00510
00511
00512 private:
00513 static bool same(const ListObj* const & lo1, const ListObj* const & lo2)
00514 {
00515 if (lo1->isStr() && lo2->isStr())
00516 {
00517 if (strcmp(lo1->str_, lo2->str_)==0) return true;
00518 return false;
00519 }
00520
00521 if (lo1->isList() && lo2->isList())
00522 {
00523 if (lo1->size() == lo2->size())
00524 {
00525 for (int i = 0; i < lo1->size(); i++)
00526 if (!same((*lo1)[i],(*lo2)[i])) return false;
00527 return true;
00528 }
00529 return false;
00530 }
00531 return false;
00532 }
00533
00534
00535 void sub(const ListObj* const & oldlo, const ListObj* const & newlo)
00536 {
00537 if (isStr())
00538 {
00539 if (same(this, oldlo))
00540 {
00541 if (newlo->isStr())
00542 {
00543 delete [] str_;
00544 str_ = new char[strlen(newlo->str_)+1];
00545 strcpy(str_, newlo->str_);
00546 }
00547 else
00548 {
00549 delete [] str_;
00550 str_ = new char[1];
00551 str_[0] = '\0';
00552 list_.deleteItemsAndClear();
00553
00554 for (int i = 0; i < newlo->size(); i++)
00555 list_.append(new ListObj((*newlo)[i]));
00556 }
00557 }
00558 return;
00559 }
00560
00561 for (int i = 0; i < list_.size(); i++)
00562 {
00563 if (same(list_[i],oldlo)) {delete list_[i]; list_[i]=new ListObj(newlo); }
00564 else list_[i]->sub(oldlo, newlo);
00565 }
00566 }
00567
00568
00569 static const ListObj* op(const ListObj* const & exp)
00570 {
00571 assert(exp->isList());
00572 if (exp->size() == 0) return exp;
00573 return (*exp)[0];
00574 }
00575
00576
00577 static const ListObj* arg1(const ListObj* const & exp)
00578 {
00579 if (exp->isList() && exp->size() > 1) return (*exp)[1];
00580 else return null_;
00581 }
00582
00583
00584 static const ListObj* arg2(const ListObj* const & exp)
00585 {
00586 if (exp->isList() && exp->size() > 2) return (*exp)[2];
00587 else return null_;
00588 }
00589
00590
00591
00592 static bool isConnective(const char* const & c)
00593 {
00594 if (strcmp(c, "^")==0 || strcmp(c, "v")==0 || strcmp(c, "!")==0 ||
00595 strcmp(c, "=>")==0 || strcmp(c, "<=>")==0 )
00596 return true;
00597 return false;
00598 }
00599
00600
00601 static bool isQuantifier(const char* const & q)
00602 {
00603 if (strcmp(q, "FORALL")==0 || strcmp(q, "EXIST")==0)
00604 return true;
00605 return false;
00606 }
00607
00608
00609
00610 static bool isAtomicClause(const ListObj* const & sentence)
00611 {
00612
00613
00614 const char* opp = op(sentence)->str_;
00615 if (!isConnective(opp) && !isQuantifier(opp)) return true;
00616 return false;
00617 }
00618
00619
00620 static bool isNegatedClause(const ListObj* const & sentence)
00621 {
00622 if (strcmp(op(sentence)->str_, "!")==0) return true;
00623 return false;
00624 }
00625
00626
00627 static bool isLiteralClause(const ListObj* const & sentence)
00628 {
00629 if (isAtomicClause(sentence) || (isNegatedClause(sentence)
00630 && isAtomicClause(arg1(sentence))))
00631 return true;
00632 return false;
00633 }
00634
00635
00636 static ListObj* eliminateImplication(const ListObj* const & p)
00637 {
00638 if (isLiteralClause(p)) return new ListObj(p);
00639
00640 const char* opp = op(p)->str_;
00641
00642 if (strcmp(opp, "=>")==0)
00643 {
00644 ListObj* n1 = new ListObj;
00645 n1->append("!"); n1->append(new ListObj(arg1(p)));
00646 ListObj* n = new ListObj;
00647 n->append("v"); n->append(new ListObj(arg2(p))); n->append(n1);
00648 return n;
00649 }
00650 else
00651 if (strcmp(opp, "<=>")==0)
00652 {
00653 ListObj* n1a = new ListObj;
00654 n1a->append("!"); n1a->append(new ListObj(arg1(p)));
00655 ListObj* na = new ListObj;
00656 na->append("v"); na->append(n1a); na->append(new ListObj(arg2(p)));
00657
00658 ListObj* n1b = new ListObj;
00659 n1b->append("!"); n1b->append(new ListObj(arg2(p)));
00660 ListObj* nb = new ListObj;
00661 nb->append("v"); nb->append(new ListObj(arg1(p)));
00662 nb->append(n1b);
00663
00664 ListObj* n = new ListObj; n->append("^"); n->append(nb); n->append(na);
00665 return n;
00666 }
00667 else
00668 {
00669 ListObj* n = new ListObj; n->append(opp);
00670 for (int i = 1; i < p->size(); i++)
00671 n->append(eliminateImplication((*p)[i]));
00672 return n;
00673 }
00674 }
00675
00676
00677 static ListObj* moveNotInwards(const ListObj* const & p)
00678 {
00679 const char* opp = op(p)->str_;
00680
00681 if (strcmp(opp, "!")==0) return new ListObj((*p)[1]);
00682
00683 if (strcmp(opp, "^")==0)
00684 {
00685 ListObj* n = NULL;
00686 int numDisj = 0;
00687 ListObj* firstDisj = NULL;
00688
00689 for (int i = 1; i < p->size(); i++)
00690 {
00691 numDisj++;
00692 if (numDisj == 1) { firstDisj = moveNotInwards((*p)[i]); continue; }
00693 else
00694 if (numDisj == 2) {n=new ListObj; n->append("v"); n->append(firstDisj);}
00695 n->append(moveNotInwards((*p)[i]));
00696 }
00697 if (numDisj == 1) return firstDisj;
00698 return n;
00699 }
00700
00701 if (strcmp(opp, "v")==0)
00702 {
00703 ListObj* n = NULL;
00704 int numConj = 0;
00705 ListObj* firstConj = NULL;
00706
00707 for (int i = 1; i < p->size(); i++)
00708 {
00709 numConj++;
00710 if (numConj == 1) { firstConj = moveNotInwards((*p)[i]); continue; }
00711 else
00712 if (numConj == 2) { n=new ListObj; n->append("^");n->append(firstConj);}
00713 n->append(moveNotInwards((*p)[i]));
00714 }
00715
00716 if (numConj == 1) return firstConj;
00717 return n;
00718 }
00719
00720 if (strcmp(opp, "FORALL")==0)
00721 {
00722 ListObj* n = new ListObj;
00723 n->append("EXIST");
00724 n->append(new ListObj((*p)[1]));
00725 n->append(moveNotInwards((*p)[2]));
00726 return n;
00727 }
00728
00729 if (strcmp(opp, "EXIST")==0)
00730 {
00731 ListObj* n = new ListObj;
00732 n->append("FORALL");
00733 n->append(new ListObj((*p)[1]));
00734 n->append(moveNotInwards((*p)[2]));
00735 return n;
00736 }
00737
00738 ListObj* n = new ListObj; n->append("!"); n->append(new ListObj(p));
00739 return n;
00740 }
00741
00742
00743 static ListObj* disjunctionAndAppend(const ListObj* const & p1,
00744 const ListObj* const & p2)
00745 {
00746 bool p1IsDisjunc = (strcmp(op(p1)->str_, "v")==0);
00747 int ibeg = (p1IsDisjunc) ? 1 : 0;
00748 int iend = (p1IsDisjunc) ? p1->size() : 1;
00749
00750 bool p2IsDisjunc = (strcmp(op(p2)->str_, "v")==0);
00751 int jbeg = (p2IsDisjunc) ? 1 : 0;
00752 int jend = (p2IsDisjunc) ? p2->size() : 1;
00753
00754 ListObj* n = new ListObj();
00755 if (p1->size()+p2->size() > 1) n->append("v");
00756
00757 for (int i = ibeg; i < iend; i++)
00758 {
00759 if (p1IsDisjunc) n->append(new ListObj((*p1)[i]));
00760 else n->append(new ListObj(p1));
00761 }
00762
00763 for (int j = jbeg; j < jend; j++)
00764 {
00765 if (p2IsDisjunc) n->append(new ListObj((*p2)[j]));
00766 else n->append(new ListObj(p2));
00767 }
00768 return n;
00769 }
00770
00771
00772 static ListObj* mergeDisjuncts(const ListObj* const & ddisjuncts,
00773 const int& numDisj)
00774 {
00775 assert(ddisjuncts->size() >= 1);
00776 if (numDisj == 1) return new ListObj((*ddisjuncts)[ ddisjuncts->size()-1 ]);
00777
00778 ListObj* y = mergeDisjuncts(ddisjuncts, numDisj-1);
00779 ListObj* x = new ListObj((*ddisjuncts)[ ddisjuncts->size()-numDisj ]);
00780 int numConj = 0;
00781 ListObj* result = NULL;
00782 ListObj* firstConj = NULL;
00783 ListObj* yj, * xi;
00784
00785 bool yIsConj = strcmp(op(y)->str_, "^")==0;
00786 int jbeg = (yIsConj) ? 1 : 0;
00787 int jmax = (yIsConj) ? y->size() : 1;
00788
00789 bool xIsConj = strcmp(op(x)->str_, "^")==0;
00790 int xbeg = (xIsConj) ? 1 : 0;
00791 int xmax = (xIsConj) ? x->size() : 1;
00792
00793 for (int j = jbeg; j < jmax; j++)
00794 {
00795 if (yIsConj) yj = (*y)[j];
00796 else yj = y;
00797
00798 for (int i = xbeg; i < xmax; i++)
00799 {
00800 if (xIsConj) xi = (*x)[i];
00801 else xi = x;
00802
00803 numConj++;
00804 if (numConj == 1)
00805 {
00806 firstConj = disjunctionAndAppend(xi, yj);
00807 continue;
00808 }
00809 else
00810 if (numConj == 2)
00811 {
00812 result = new ListObj();
00813 result->append("^");
00814 result->append(firstConj);
00815 }
00816
00817 result->append(disjunctionAndAppend(xi, yj));
00818 }
00819 }
00820
00821 delete y; delete x;
00822 if (numConj == 1) return firstConj;
00823 return result;
00824 }
00825
00826
00827 static bool isVariable(const ListObj* const & x)
00828 {
00829 if (strlen(x->str_) == 0) return false;
00830 return ((x->str_)[0] == '$');
00831 }
00832
00833
00834 static ListObj* newVariable(const ListObj* const & var)
00835 {
00836 assert(var->isStr());
00837 string s;
00838 if (!isVariable(var)) s.append("$");
00839 char buf[128];
00840 sprintf(buf, "%d", ++newVarCounter_);
00841 s.append(var->str_).append(".").append(buf);
00842 return new ListObj(s.c_str());
00843 }
00844
00845
00846 static ListObj* skolemConstant(const ListObj* const & name)
00847 {
00848 assert(name->isStr());
00849 char buf[1024];
00850 sprintf(buf, "$%s_%d", name->str_, ++newVarCounter_);
00851 return new ListObj(buf);
00852 }
00853
00854
00855 static ListObj* cons(ListObj* const & p1, const ListObj* const & p2)
00856 {
00857 assert(p2->isList());
00858 ListObj* n = new ListObj;
00859 n->append(p1);
00860 for (int i = 0; i < p2->size(); i++)
00861 n->append(new ListObj((*p2)[i]));
00862 return n;
00863 }
00864
00865
00866 static ListObj* skolemize(const ListObj* const & p,
00867 const ListObj* const & vars,
00868 const ListObj* const & outsideVars)
00869 {
00870 ListObj* pcopy = new ListObj(p);
00871
00872 ListObj* skolemSym = new ListObj;
00873 if (outsideVars->size() == 0)
00874 {
00875 for (int i = 0; i < vars->size(); i++)
00876 skolemSym->append(skolemConstant((*vars)[i]));
00877 }
00878 else
00879 {
00880 for (int i = 0; i < vars->size(); i++)
00881 skolemSym->append( cons(skolemConstant((*vars)[i]),outsideVars) );
00882 }
00883 assert(skolemSym->size() == vars->size());
00884
00885 for (int i = 0; i < pcopy->size(); i++)
00886 for (int j = 0; j < skolemSym->size(); j++)
00887 (*pcopy)[i]->sub((*vars)[j], (*skolemSym)[j]);
00888
00889 delete skolemSym;
00890
00891 return pcopy;
00892 }
00893
00894
00895 static bool containsVarName(const ListObj* const & vars,
00896 const char* const & varName)
00897 {
00898 for (int i = 0; i < vars->size(); i++)
00899 if (strcmp((*vars)[i]->getStr(), varName)==0) return true;
00900 return false;
00901 }
00902
00903
00904
00905 static void removeRedundantPredicates(ListObj* const & p)
00906 {
00907 const char* opp = op(p)->str_;
00908
00909
00910 if (strcmp(opp,"v")!=0) return;
00911
00912 Array<ListObj*> preds, redundantPreds;
00913 for (int i = 1; i < p->size(); i++)
00914 {
00915 bool unique = true;
00916 for (int j = i+1; j < p->size(); j++)
00917 if (same((*p)[i],(*p)[j])) { unique = false; break; }
00918 if (unique) preds.append((*p)[i]);
00919 else redundantPreds.append((*p)[i]);
00920 }
00921
00922 ListObj* orOper = (*p)[0];
00923 assert(strcmp(orOper->str_,"v")==0);
00924 for (int i = 0; i < redundantPreds.size(); i++)
00925 delete redundantPreds[i];
00926 p->clear();
00927 p->append(orOper);
00928 for (int i = 0; i < preds.size(); i++) p->append(preds[i]);
00929 }
00930
00931
00932 static bool subsetOf(const ListObj* const & p, const ListObj* const & q)
00933 {
00934 if (p->size() > q->size()) return false;
00935 for (int i = 0; i < p->size(); i++)
00936 {
00937 bool sameAsOneElt = false;
00938 for (int j = 0; j < q->size(); j++)
00939 if (same((*p)[i],(*q)[j])) { sameAsOneElt = true; break; }
00940 if (!sameAsOneElt) return false;
00941 }
00942 return true;
00943 }
00944
00945
00946 private:
00947
00948
00949
00950
00951
00952 Array<ListObj*> list_;
00953
00954 char* str_;
00955
00956 static int newVarCounter_;
00957 static ListObj* null_;
00958 };
00959
00960
00961 inline
00962 ostream& operator<<(ostream& out, const ListObj& p) { return p.print(out); }
00963
00964
00965 #endif