clausefactory.h

00001 /*
00002  * All of the documentation and software included in the
00003  * Alchemy Software is copyrighted by Stanley Kok, Parag
00004  * Singla, Matthew Richardson, Pedro Domingos, Marc
00005  * Sumner and Hoifung Poon.
00006  * 
00007  * Copyright [2004-07] Stanley Kok, Parag Singla, Matthew
00008  * Richardson, Pedro Domingos, Marc Sumner and Hoifung
00009  * Poon. All rights reserved.
00010  * 
00011  * Contact: Pedro Domingos, University of Washington
00012  * (pedrod@cs.washington.edu).
00013  * 
00014  * Redistribution and use in source and binary forms, with
00015  * or without modification, are permitted provided that
00016  * the following conditions are met:
00017  * 
00018  * 1. Redistributions of source code must retain the above
00019  * copyright notice, this list of conditions and the
00020  * following disclaimer.
00021  * 
00022  * 2. Redistributions in binary form must reproduce the
00023  * above copyright notice, this list of conditions and the
00024  * following disclaimer in the documentation and/or other
00025  * materials provided with the distribution.
00026  * 
00027  * 3. All advertising materials mentioning features or use
00028  * of this software must display the following
00029  * acknowledgment: "This product includes software
00030  * developed by Stanley Kok, Parag Singla, Matthew
00031  * Richardson, Pedro Domingos, Marc Sumner and Hoifung
00032  * Poon in the Department of Computer Science and
00033  * Engineering at the University of Washington".
00034  * 
00035  * 4. Your publications acknowledge the use or
00036  * contribution made by the Software to your research
00037  * using the following citation(s): 
00038  * Stanley Kok, Parag Singla, Matthew Richardson and
00039  * Pedro Domingos (2005). "The Alchemy System for
00040  * Statistical Relational AI", Technical Report,
00041  * Department of Computer Science and Engineering,
00042  * University of Washington, Seattle, WA.
00043  * http://www.cs.washington.edu/ai/alchemy.
00044  * 
00045  * 5. Neither the name of the University of Washington nor
00046  * the names of its contributors may be used to endorse or
00047  * promote products derived from this software without
00048  * specific prior written permission.
00049  * 
00050  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF WASHINGTON
00051  * AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
00052  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00053  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00054  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY
00055  * OF WASHINGTON OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
00056  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00057  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00058  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00059  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00060  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00061  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00062  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00063  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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     //Caller is responsible for deleting preds (and its contents), clause, and
00087     //the contents of newClauses.
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     //Caller is responsible for deleting pred, clause and newClauses' contents.
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     //Caller is responsible for deleting clause, and the contents of newClauses
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     //Caller is responsible for deleting clause, and the contents of newClauses
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; // for clean up later
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     // Caller is responsible for deleting the returned clause and ppred 
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     //Caller is responsible for deleting the contents of unitClauses and preds
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     //Caller is responsible for deleting pred and the contents of newClauses
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     //NOTE: add code to filter out clauses here
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       //for testing UW-CSE domain
00327     //if (hasSamePredWithFreeVarSameVarWrongOrderVar(c)) return false; 
00328     //if (hasRedundantSamePreds(c)) return false;
00329     
00330     return true;
00331   }
00332 
00333 
00334  private:
00335     // If the returned predicate is added to a clause, its parent should be set
00336     // as the clause
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; //for clean up later
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         //prevent creating both P(a,b) v a = b and P(a,b) v b = a
00400       if (pred->isEqualPred() && termIds[0] <= termIds[1]) continue;
00401 
00402         //in last combination, pred contains all new variables, so ignore it
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         //check newPred is not in clause
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       //Predicate* fnewPred = new Predicate(*newPred);
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   //commented out: the problem of same var and wrong order is taken care of 
00465   //               in addPredicateToClause().
00466   /*
00467     // returns true if clause c contains an '=' pred with the same 
00468     // variable/constant (e.g., a = a), with a free var 
00469     // (e.g., person(a) v same(a,b)), or with the vars in the wrong order 
00470     // (e.g. advisedBy(a1,a2) v a2=a1). The last check prevents us from 
00471     // creating duplicate clauses like advisedBy(a1,a2) v a1=a2  and
00472     // advisedBy(a1,a2) v a2=a1.
00473   bool hasEqualPredWithFreeVarSameVarWrongOrderVar(const Clause* const & c)
00474   {
00475     for (int i = 0; i < c->getNumPredicates(); i++)
00476     {
00477       const Predicate* p = c->getPredicate(i);
00478       if (p->isEqualPred())
00479       {
00480         if (p->getTerm(0)->getId() >= p->getTerm(1)->getId()) return true;
00481 
00482         for (int j = 0; j < p->getNumTerms(); j++)
00483         {
00484           int tid = p->getTerm(j)->getId();
00485           bool bound = false;
00486           for (int k = 0; k < c->getNumPredicates(); k++)
00487           {
00488             if (i == k) continue;
00489             const Predicate* pp = c->getPredicate(k);
00490             for (int l = 0; l < pp->getNumTerms(); l++)
00491               if (pp->getTerm(l)->getId() == tid) { bound = true; break; }
00492             if (bound) break;
00493           }
00494           if (!bound) return true;
00495         }
00496       }
00497     }
00498     return false;
00499   }
00500   */
00501 
00502     // returns true if clause c contains an '=' pred with a free var 
00503     // (e.g., person(a) v a = b).
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     //returns true if clause c contains two predicates of the form
00532     //(a = b) v (b = a)
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     //for testing UW-CSE domain. 
00554     // returns true if clause c contains an 'same' pred with the same 
00555     // variable/constant (e.g., samePerson(a,a) or a pred with a free var 
00556     // (e.g., person(a) v samePerson(a,b)), or with the vars in the wrong order 
00557     // (e.g. advisedBy(a1,a2) v same(a2,a1)). The last check prevents us from 
00558     // creating duplicate clauses like advisedBy(a1,a2) v same(a1,a2)  and
00559     // advisedBy(a1,a2) v same(a2,a1).
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     //for testing UW-CSE domain.  
00591     //returns true if clause c contains two predicates of the form
00592     //samePerson(a,b) v (a = b),  samePerson(a,b) v (b = a), 
00593     //samePerson(a,b) v samePerson(b,a), (a = b) v (b = a),
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_; //not owned by this object, do not delete
00657 
00658 };
00659 
00660 
00661 #endif

Generated on Tue Jan 16 05:30:04 2007 for Alchemy by  doxygen 1.5.1