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 CLAUSEFACTORY_H_NOV_10_2005
00067 #define CLAUSEFACTORY_H_NOV_10_2005
00068
00069 #include <climits>
00070 #include "clause.h"
00071 #include "domain.h"
00072
00073
00074 class ClauseFactory
00075 {
00076 public:
00077 ClauseFactory() : maxNumVars_(INT_MAX), maxNumPredicates_(INT_MAX),
00078 domain_(NULL) {}
00079 ClauseFactory(const int& maxNumVars, const int& maxNumPredicates,
00080 const Domain* const & domain)
00081 : maxNumVars_(maxNumVars), maxNumPredicates_(maxNumPredicates),
00082 domain_(domain) {}
00083 ~ClauseFactory() {}
00084
00085
00086
00087
00088 void addPredicateToClause(const Array<Predicate*>& preds,
00089 Clause* const & clause,
00090 const int& op, const int& removeClauseIdx,
00091 const bool& clauseHasBeenCanonicalized,
00092 ClauseOpHashArray& newClauses,
00093 const bool& addTruePredOnly)
00094 {
00095 if (!clauseHasBeenCanonicalized) clause->canonicalize();
00096
00097 int smallestVarId;
00098 Array<Array<int>*>* typeIdToVarIds
00099 = clause->getTypeIdToVarIdsMapAndSmallestVarId(smallestVarId);
00100
00101 for (int i = 0; i < preds.size(); i++)
00102 {
00103 bool truePredOnly =
00104 (preds[i]->isEqualPred() || preds[i]->isInternalPred()) ? true : addTruePredOnly;
00105
00106 addPredicateToClause(preds[i], clause, op, removeClauseIdx, newClauses,
00107 typeIdToVarIds, smallestVarId, truePredOnly, NULL);
00108 }
00109
00110 typeIdToVarIds->deleteItemsAndClear();
00111 delete typeIdToVarIds;
00112 }
00113
00114
00115
00116 void addPredicateToClause(const Predicate* const & pred,
00117 Clause* const & clause,
00118 const int& op, const int& removeClauseIdx,
00119 const bool& clauseHasBeenCanonicalized,
00120 ClauseOpHashArray& newClauses,
00121 const bool& addTruePredOnly)
00122 {
00123 Array<Predicate*> arr;
00124 arr.append((Predicate*)pred);
00125 bool truePredOnly =
00126 (pred->isEqualPred() || pred->isInternalPred()) ? true : addTruePredOnly;
00127
00128 addPredicateToClause(arr, clause, op, removeClauseIdx,
00129 clauseHasBeenCanonicalized, newClauses, truePredOnly);
00130 }
00131
00132
00133
00134 void removePredicateFromClause(const int& predIdx,
00135 const Clause* const & clause,
00136 const int& op, const int& removeClauseIdx,
00137 ClauseOpHashArray& newClauses)
00138 {
00139 if (clause->getNumPredicates() == 1) return;
00140 Clause* newClause = new Clause(*clause);
00141 Predicate* p = newClause->removePredicate(predIdx);
00142 if (p == NULL) return;
00143
00144 string prevClauseStr, addPredStr;
00145 if (domain_)
00146 {
00147 ostringstream oss1, oss2;
00148 clause->printWithoutWtWithStrVar(oss1, domain_); prevClauseStr=oss1.str();
00149 p->printWithStrVar(oss2, domain_); addPredStr = oss2.str();
00150 }
00151
00152 delete p;
00153 newClause->canonicalize();
00154
00155 if (newClause->getNumVariablesAssumeCanonicalized() > maxNumVars_ ||
00156 newClause->getNumPredicates() > maxNumPredicates_)
00157 { delete newClause; return; }
00158 if (!newClause->checkPredsAreConnected()) { delete newClause; return; }
00159 if (!validClause(newClause)) { delete newClause; return; }
00160
00161 newClause->setAuxClauseData(new AuxClauseData(0, op, removeClauseIdx,
00162 prevClauseStr, addPredStr,
00163 predIdx));
00164 if (((Clause*)clause)->containsConstants()) newClause->trackConstants();
00165 if (newClauses.append(newClause) < 0) { delete newClause; return; }
00166 newClause->compress();
00167 }
00168
00169
00170
00171 void removePredicateFromClause(const Clause* const & clause,
00172 const int& op, const int& removeClauseIdx,
00173 ClauseOpHashArray& newClauses)
00174 {
00175 for (int i = 0; i < clause->getNumPredicates(); i++)
00176 removePredicateFromClause(i, clause, op, removeClauseIdx, newClauses);
00177 }
00178
00179
00180 void flipSensesInClause(const Clause* const & clause, const int& op,
00181 const int& removeClauseIdx,
00182 ClauseOpHashArray& newClauses,
00183 const bool& canonicalizeNewClauses)
00184 {
00185 Array<Array<bool>*> newedArrays;
00186
00187 ArraysAccessor<bool> acc;
00188 for (int i = 0; i < clause->getNumPredicates(); i++)
00189 {
00190 Array<bool>* bArr = new Array<bool>(2);
00191 bArr->append(false); bArr->append(true);
00192 newedArrays.append(bArr);
00193 acc.appendArray(bArr);
00194 }
00195
00196 Array<bool> bArr;
00197 while (acc.getNextCombination(bArr))
00198 {
00199 assert(bArr.size() == clause->getNumPredicates());
00200 Clause* newClause = new Clause(*clause);
00201 for (int i = 0; i < bArr.size(); i++)
00202 {
00203 Predicate* pred = (Predicate*) newClause->getPredicate(i);
00204 pred->setSense(bArr[i]);
00205 }
00206
00207 int numVarsInNewClause;
00208 if (canonicalizeNewClauses)
00209 {
00210 newClause->canonicalize();
00211 numVarsInNewClause = newClause->getNumVariablesAssumeCanonicalized();
00212 }
00213 else
00214 numVarsInNewClause = newClause->getNumVariables();
00215
00216 if (numVarsInNewClause > maxNumVars_ ||
00217 newClause->getNumPredicates() > maxNumPredicates_)
00218 { delete newClause; continue; }
00219 if (!validClause(newClause)) { delete newClause; continue; }
00220
00221 string prevClauseStr;
00222 if (domain_)
00223 {
00224 ostringstream oss;
00225 clause->printWithoutWtWithStrVar(oss, domain_);
00226 prevClauseStr = oss.str();
00227 }
00228
00229
00230 newClause->setAuxClauseData(new AuxClauseData(0, op, removeClauseIdx,
00231 prevClauseStr, "", -1));
00232 if (((Clause*)clause)->containsConstants()) newClause->trackConstants();
00233 if (newClauses.append(newClause) < 0) { delete newClause; continue; }
00234 newClause->compress();
00235 }
00236
00237 for (int i = 0; i < newedArrays.size(); i++) delete newedArrays[i];
00238 }
00239
00240
00241
00242 static Clause* createUnitClause(const Predicate* const & predicate,
00243 const bool& allowEqualPred)
00244 {
00245 if (!allowEqualPred &&
00246 (predicate->isEqualPred() || predicate->isInternalPred()))
00247 return NULL;
00248 Clause* clause = new Clause();
00249 Predicate* pred = new Predicate(*predicate);
00250 pred->setSense(true);
00251 pred->setParent(clause);
00252 clause->appendPredicate(pred);
00253 clause->canonicalize();
00254 return clause;
00255 }
00256
00257
00258
00259 static void createUnitClauses(Array<Clause*>& unitClauses,
00260 Array<Predicate*>& preds,
00261 const bool& allowEqualPred)
00262 {
00263 for (int i = 0; i < preds.size(); i++)
00264 {
00265 Clause* uclause = createUnitClause(preds[i], allowEqualPred);
00266 if (uclause) unitClauses.append(uclause);
00267 }
00268 }
00269
00270
00271
00272 void createUnitClausesWithDiffCombOfVar(const Predicate* const & pred,
00273 const int& op,
00274 const int& removeClauseIdx,
00275 ClauseOpHashArray& newClauses)
00276 {
00277 Clause* unitClause = createUnitClause(pred, true);
00278
00279 Array<Predicate*> newPreds;
00280 int smallestVarId;
00281 Array<Array<int>*>* typeIdToVarIds
00282 = unitClause->getTypeIdToVarIdsMapAndSmallestVarId(smallestVarId);
00283 ClauseOpHashArray unused;
00284 addPredicateToClause(pred, unitClause, OP_ADD, -1, unused, typeIdToVarIds,
00285 smallestVarId, true, &newPreds);
00286 typeIdToVarIds->deleteItemsAndClear();
00287 delete typeIdToVarIds;
00288 delete unitClause;
00289
00290 for (int i = 0; i < newPreds.size(); i++)
00291 {
00292 Clause* uclause = createUnitClause(newPreds[i], true);
00293 delete newPreds[i];
00294 if (uclause == NULL) continue;
00295 if (uclause->getNumVariablesAssumeCanonicalized() > maxNumVars_ ||
00296 uclause->getNumPredicates() > maxNumPredicates_)
00297 { delete uclause; continue; }
00298
00299 uclause->setAuxClauseData(new AuxClauseData(0, op, removeClauseIdx));
00300 uclause->trackConstants();
00301 if (newClauses.append(uclause) < 0) { delete uclause; continue;}
00302 uclause->compress();
00303
00304 }
00305 }
00306
00307
00308 void createUnitClausesWithDiffCombOfVar(const Array<Predicate*>& preds,
00309 const int& op,
00310 const int& removeClauseIdx,
00311 ClauseOpHashArray& newClauses)
00312 {
00313 for (int i = 0; i < preds.size(); i++)
00314 createUnitClausesWithDiffCombOfVar(preds[i], op, removeClauseIdx,
00315 newClauses);
00316 }
00317
00318
00319
00320 bool validClause(const Clause* const & c)
00321 {
00322 if (hasEqualPredWithFreeVar(c)) return false;
00323 if (hasRedundantEqualPreds(c)) return false;
00324 if (c->getNumPredicates() > maxNumPredicates_) return false;
00325
00326
00327
00328
00329
00330 return true;
00331 }
00332
00333
00334 private:
00335
00336
00337 Predicate* createPredicate(const Predicate* const pred,
00338 const Array<int>& termIds)
00339 {
00340 Predicate* newPred = new Predicate(*pred);
00341 assert(newPred->getNumTerms() == termIds.size());
00342 for (int i = 0; i < termIds.size(); i++)
00343 ((Term*) newPred->getTerm(i))->setId(termIds[i]);
00344 newPred->setSense(true);
00345 return newPred;
00346 }
00347
00348
00349 bool allNewVars(const Array<int>& termIds, const int& smallestVarId)
00350 {
00351 for (int i = 0; i < termIds.size(); i++)
00352 if (termIds[i] >= smallestVarId) return false;
00353 return true;
00354 }
00355
00356
00357 void addPredicateToClause(const Predicate* const & pred,
00358 const Clause* const & clause,
00359 const int& op, const int& removeClauseIdx,
00360 ClauseOpHashArray& newClauses,
00361 const Array<Array<int>*>* const & typeIdToVarIds,
00362 const int& smallestVarId,
00363 const bool& addTruePredOnly,
00364 Array<Predicate*>* const returnNewPredOnly)
00365 {
00366 Array<Array<int>*> newedArrays;
00367
00368 int newVarId = smallestVarId;
00369 Array<int>* intArr;
00370 ArraysAccessor<int> acc;
00371 for (int i = 0; i < pred->getNumTerms(); i++)
00372 {
00373 if (pred->getTerm(i)->getType() == Term::VARIABLE)
00374 {
00375 int typeId = pred->getTermTypeAsInt(i);
00376 if (typeId < typeIdToVarIds->size() && (*typeIdToVarIds)[typeId])
00377 intArr = new Array<int>( *((*typeIdToVarIds)[typeId]) );
00378 else
00379 intArr = new Array<int>;
00380 newedArrays.append(intArr);
00381 intArr->append(--newVarId);
00382 acc.appendArray(intArr);
00383 }
00384 else
00385 {
00386 assert(pred->getTerm(i)->getType() == Term::CONSTANT);
00387 intArr = new Array<int>;
00388 newedArrays.append(intArr);
00389 intArr->append(pred->getTerm(i)->getId());
00390 acc.appendArray(intArr);
00391 }
00392 }
00393
00394 int numComb = acc.numCombinations();
00395 int comb = 0;
00396 Array<int> termIds;
00397 while(acc.getNextCombination(termIds))
00398 {
00399
00400 if (pred->isEqualPred() && termIds[0] <= termIds[1]) continue;
00401
00402
00403 if (++comb==numComb) {assert(allNewVars(termIds,smallestVarId));continue;}
00404
00405 Predicate* newPred = createPredicate(pred, termIds);
00406 if (returnNewPredOnly) { returnNewPredOnly->append(newPred); continue; }
00407
00408 Predicate* fnewPred = new Predicate(*newPred);
00409
00410
00411 if (clause->containsPredicate(newPred))
00412 { delete newPred; delete fnewPred; continue; }
00413 Clause* newClause = new Clause(*clause);
00414 newClause->appendPredicate(newPred);
00415 newPred->setParent(newClause);
00416 newClause->canonicalize();
00417
00418 if (newClause->getNumVariablesAssumeCanonicalized() > maxNumVars_ ||
00419 newClause->getNumPredicates() > maxNumPredicates_)
00420 { delete newClause; delete fnewPred; continue; }
00421
00422 if (!validClause(newClause)) { delete newClause;delete fnewPred;continue;}
00423
00424 string prevClauseStr, addPredStr;
00425 if (domain_)
00426 {
00427 ostringstream oss1, oss2;
00428 clause->printWithoutWtWithStrVar(oss1, domain_);
00429 prevClauseStr = oss1.str();
00430 pred->printWithStrVar(oss2, domain_);
00431 addPredStr = oss2.str();
00432 }
00433
00434
00435 newClause->setAuxClauseData(new AuxClauseData(0, op, removeClauseIdx,
00436 prevClauseStr, addPredStr,
00437 -1));
00438 if (((Clause*)clause)->containsConstants()) newClause->trackConstants();
00439 if (newClauses.append(newClause) < 0) { delete newClause; }
00440 else { newClause->compress(); }
00441
00442 if (addTruePredOnly) { delete fnewPred; continue; }
00443
00444
00445 fnewPred->setSense(false);
00446 newClause = new Clause(*clause);
00447 newClause->appendPredicate(fnewPred);
00448 fnewPred->setParent(newClause);
00449 newClause->canonicalize();
00450
00451 newClause->setAuxClauseData(new AuxClauseData(0, op, removeClauseIdx,
00452 prevClauseStr, addPredStr,
00453 -1));
00454 if (((Clause*)clause)->containsConstants()) newClause->trackConstants();
00455 if (newClauses.append(newClause) < 0) { delete newClause; }
00456 else { newClause->compress(); }
00457 }
00458
00459 newedArrays.deleteItemsAndClear();
00460 }
00461
00462
00463 private:
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 bool hasEqualPredWithFreeVar(const Clause* const & c)
00505 {
00506 for (int i = 0; i < c->getNumPredicates(); i++)
00507 {
00508 const Predicate* p = c->getPredicate(i);
00509 if (p->isEqualPred())
00510 {
00511 for (int j = 0; j < p->getNumTerms(); j++)
00512 {
00513 int tid = p->getTerm(j)->getId();
00514 bool bound = false;
00515 for (int k = 0; k < c->getNumPredicates(); k++)
00516 {
00517 if (i == k) continue;
00518 const Predicate* pp = c->getPredicate(k);
00519 for (int l = 0; l < pp->getNumTerms(); l++)
00520 if (pp->getTerm(l)->getId() == tid) { bound = true; break; }
00521 if (bound) break;
00522 }
00523 if (!bound) return true;
00524 }
00525 }
00526 }
00527 return false;
00528 }
00529
00530
00531
00532
00533 bool hasRedundantEqualPreds(const Clause* const & c)
00534 {
00535 for (int i = 0; i < c->getNumPredicates(); i++)
00536 {
00537 const Predicate* p = c->getPredicate(i);
00538 if (p->isEqualPred())
00539 {
00540 for (int j = i+1; j < c->getNumPredicates(); j++)
00541 {
00542 const Predicate* pp = c->getPredicate(j);
00543 if (p->getId() == pp->getId() &&
00544 p->getTerm(0)->getId() == pp->getTerm(1)->getId() &&
00545 p->getTerm(1)->getId() == pp->getTerm(0)->getId()) return true;
00546 }
00547 }
00548 }
00549 return false;
00550 }
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560 bool hasSamePredWithFreeVarSameVarWrongOrderVar(const Clause* const & c)
00561 {
00562 for (int i = 0; i < c->getNumPredicates(); i++)
00563 {
00564 const Predicate* p = c->getPredicate(i);
00565 const char* predName = domain_->getPredicateName(p->getId());
00566 if (strncmp(predName, "same", 4) == 0)
00567 {
00568 if (p->getTerm(0)->getId() >= p->getTerm(1)->getId()) return true;
00569
00570 for (int j = 0; j < p->getNumTerms(); j++)
00571 {
00572 int tid = p->getTerm(j)->getId();
00573 bool bound = false;
00574 for (int k = 0; k < c->getNumPredicates(); k++)
00575 {
00576 if (i == k) continue;
00577 const Predicate* pp = c->getPredicate(k);
00578 for (int l = 0; l < pp->getNumTerms(); l++)
00579 if (pp->getTerm(l)->getId() == tid) { bound = true; break; }
00580 if (bound) break;
00581 }
00582 if (!bound) return true;
00583 }
00584 }
00585 }
00586 return false;
00587 }
00588
00589
00590
00591
00592
00593
00594 bool hasRedundantSamePreds(const Clause* const & c)
00595 {
00596 for (int i = 0; i < c->getNumPredicates(); i++)
00597 {
00598 const Predicate* p = c->getPredicate(i);
00599 if (p->isEqualPred())
00600 {
00601 for (int j = i+1; j < c->getNumPredicates(); j++)
00602 {
00603 const Predicate* pp = c->getPredicate(j);
00604 if (p->getId() == pp->getId())
00605 {
00606 if (p->getTerm(0)->getId() == pp->getTerm(1)->getId() &&
00607 p->getTerm(1)->getId() == pp->getTerm(0)->getId()) return true;
00608 }
00609 else
00610 {
00611 const char* predName = domain_->getPredicateName(pp->getId());
00612 if (strncmp(predName, "same", 4) == 0)
00613 {
00614 if ( (p->getTerm(0)->getId() == pp->getTerm(0)->getId() &&
00615 p->getTerm(1)->getId() == pp->getTerm(1)->getId()) ||
00616 (p->getTerm(0)->getId() == pp->getTerm(1)->getId() &&
00617 p->getTerm(1)->getId() == pp->getTerm(0)->getId()) )
00618 return true;
00619 }
00620 }
00621 }
00622 }
00623 else
00624 {
00625 const char* predName = domain_->getPredicateName(p->getId());
00626 if (strncmp(predName, "same", 4) == 0)
00627 {
00628 for (int j = i+1; j < c->getNumPredicates(); j++)
00629 {
00630 const Predicate* pp = c->getPredicate(j);
00631 if (p->getId() == pp->getId())
00632 {
00633 if (p->getTerm(0)->getId() == pp->getTerm(1)->getId() &&
00634 p->getTerm(1)->getId() == pp->getTerm(0)->getId())return true;
00635 }
00636 else
00637 if (pp->isEqualPred())
00638 {
00639 if ( (p->getTerm(0)->getId() == pp->getTerm(0)->getId() &&
00640 p->getTerm(1)->getId() == pp->getTerm(1)->getId()) ||
00641 (p->getTerm(0)->getId() == pp->getTerm(1)->getId() &&
00642 p->getTerm(1)->getId() == pp->getTerm(0)->getId()) )
00643 return true;
00644 }
00645 }
00646 }
00647 }
00648 }
00649 return false;
00650 }
00651
00652
00653 private:
00654 int maxNumVars_;
00655 int maxNumPredicates_;
00656 const Domain* domain_;
00657
00658 };
00659
00660
00661 #endif