predicate.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, Hoifung Poon, Daniel Lowd, and Jue Wang.
00006  * 
00007  * Copyright [2004-09] Stanley Kok, Parag Singla, Matthew
00008  * Richardson, Pedro Domingos, Marc Sumner, Hoifung
00009  * Poon, Daniel Lowd, and Jue Wang. 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, Hoifung
00032  * Poon, Daniel Lowd, and Jue Wang in the Department of
00033  * Computer Science and Engineering at the University of
00034  * Washington".
00035  * 
00036  * 4. Your publications acknowledge the use or
00037  * contribution made by the Software to your research
00038  * using the following citation(s): 
00039  * Stanley Kok, Parag Singla, Matthew Richardson and
00040  * Pedro Domingos (2005). "The Alchemy System for
00041  * Statistical Relational AI", Technical Report,
00042  * Department of Computer Science and Engineering,
00043  * University of Washington, Seattle, WA.
00044  * http://alchemy.cs.washington.edu.
00045  * 
00046  * 5. Neither the name of the University of Washington nor
00047  * the names of its contributors may be used to endorse or
00048  * promote products derived from this software without
00049  * specific prior written permission.
00050  * 
00051  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF WASHINGTON
00052  * AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
00053  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00054  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00055  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY
00056  * OF WASHINGTON OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
00057  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00058  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00059  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00060  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00061  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00062  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00063  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00064  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00065  * 
00066  */
00067 #ifndef PREDICATE_H_JUN_26_2005
00068 #define PREDICATE_H_JUN_26_2005
00069 
00070 #include <ext/hash_set>
00071 using namespace __gnu_cxx;
00072 #include "predicatetemplate.h"
00073 #include "term.h"
00074 #include "hash.h"
00075 #include "hasharray.h"
00076 #include "function.h"
00077 
00078 const int MAX_VAR = 10;
00079 enum TruthValue { FALSE = 0, TRUE = 1, UNKNOWN = 2 };
00080 
00081 struct VarsTypeId { Array<Term*> vars; int typeId; }; 
00082 
00083 class Clause;
00084 class GroundPredicate;
00085 class Domain;
00086 
00087   //Ensure that the dirty_ bit is consistently updated.
00088 class Predicate
00089 {
00090  public:
00091   Predicate(const PredicateTemplate* const & pt) 
00092     : template_(pt), terms_(new Array<Term*>), sense_(true), 
00093       truthValue_(UNKNOWN), allTermsAreDiffVars_(false), isGrounded_(false), 
00094       intArrRep_(NULL), hashCode_(0), dirty_(true), parent_(NULL) {}
00095 
00096   Predicate(const PredicateTemplate* const & pt, Clause* const & parent)
00097     : template_(pt), terms_(new Array<Term*>), sense_(true), 
00098       truthValue_(UNKNOWN), allTermsAreDiffVars_(false), isGrounded_(false), 
00099       intArrRep_(NULL), hashCode_(0), dirty_(true), parent_(parent) {}
00100 
00101   Predicate(const Predicate& p)  { parent_ = NULL; copy(p); }
00102   Predicate(const Predicate& p,  Clause* const & par) { parent_= par; copy(p); }
00103 
00104   
00105   ~Predicate()
00106   {
00107     for (int i = 0; i < terms_->size(); i++)  delete (*terms_)[i];
00108     delete terms_;
00109     if (intArrRep_) delete intArrRep_;
00110   }
00111 
00112 
00113   double sizeMB() const
00114   {
00115     double sizeMB = (fixedSizeB_ + intArrRep_->size()*sizeof(int) +
00116                      terms_->size()*sizeof(Term*))/1000000.0;
00117     for (int i = 0; i < terms_->size(); i++) sizeMB += (*terms_)[i]->sizeMB();
00118     return sizeMB;
00119   }
00120 
00121 
00122   static void computeFixedSizeB()
00123   { fixedSizeB_ = (sizeof(Predicate)+sizeof(Array<Term*>)+sizeof(Array<int>)); }
00124 
00125 
00126   void compress() 
00127   { 
00128     for (int i = 0; i < terms_->size(); i++)  (*terms_)[i]->compress();
00129     terms_->compress(); 
00130     intArrRep_->compress(); 
00131   }
00132 
00133 
00134     //returns true if this predicate represents "="
00135   bool isEqualPred() const  { return template_->isEqualPred(); }
00136   
00137   bool isEqualPredWithType() const  { return template_->isEqualPredWithType(); }
00138 
00139     //returns true if this predicate is empty predicate
00140   bool isEmptyPred() const  { return template_->isEmptyPredicateTemplate(); }
00141  
00142      //returns true if this predicate is an internal predicate
00143   bool isInternalPred() const  { return template_->isInternalPredicateTemplate(); }
00144   
00145   bool isInternalPredWithoutType() const
00146   { return template_->isInternalPredicateTemplateWithoutType(); }
00147 
00148   void canonicalize()
00149   {
00150     Array<int> varIdToNewVarId;
00151     int newVarId = 0;
00152     for (int i = 0; i < terms_->size(); i++)
00153     {
00154       if ((*terms_)[i]->getType() == Term::VARIABLE)
00155       {
00156         int id = -((*terms_)[i]->getId());
00157         assert(id > 0);
00158         if (id >= varIdToNewVarId.size()) varIdToNewVarId.growToSize(id+1,0);
00159           //if a new var id has not been assigned to old var id
00160         if (varIdToNewVarId[id] >= 0) varIdToNewVarId[id] = --newVarId;
00161         (*terms_)[i]->setId(varIdToNewVarId[id]);
00162       }
00163       assert((*terms_)[i]->getType() != Term::FUNCTION);
00164     }
00165   }
00166 
00167 
00168     //term is owned by Predicate. Caller should not delete it
00169   void appendTerm(Term* const & term)
00170   {
00171     if (template_->getNumTerms() == terms_->size()) 
00172     {
00173       cout << "Error: In Predicate::appendTerm. Tried to add more terms than "
00174            << "the declared num of " << template_->getNumTerms() << endl;
00175       exit(-1);
00176     }
00177     terms_->append(term);
00178     setDirty();
00179   }
00180 
00186   Term* removeLastTerm()
00187   {
00188     Term* term = terms_->removeLastItem();
00189     terms_->compress();
00190     setDirty();
00191     return term;
00192   }
00193 
00194   
00195   bool getSense() const { return sense_; }
00196   void setSense(const bool& s) { sense_ = s; setDirty();}
00197   void invertSense() { sense_ = (sense_) ? false : true; setDirty(); }
00198 
00199     //get and set the definitive truth value of the predicate
00200   TruthValue getTruthValue() const { return truthValue_; }
00201   void setTruthValue(const TruthValue& tv) { truthValue_ = tv; }
00202   string getTruthValueAsStr() const 
00203   {
00204     if (truthValue_ == TRUE)    return "TRUE";
00205     if (truthValue_ == FALSE)   return "FALSE";
00206     if (truthValue_ == UNKNOWN) return "UNKNOWN";
00207     assert(false); 
00208     return "UNKNOWN"; //avoid compilation warning
00209   }
00210 
00211 
00212   double getNumGroundingsIfAllVarDiff(const Domain* const & domain) const;
00213  
00214   
00215     //Caller is responsible for deleting the Predicate* in returnArray
00216   static void createAllGroundings(const int& predId, 
00217                                   const Domain* const & domain,
00218                                   Array<Predicate*>& returnArray);
00219 
00220   
00221   //Caller is responsible for deleting the Predicate* in returnArray
00222   static void createAllGroundingsUnifyingWithTerm(const int& predId, 
00223                                   const Domain* const & domain,
00224                                   Array<Predicate*>& returnArray,
00225                                   int termTypeId, int termVal);
00226 
00227 
00228   void createAllGroundingsIfAllVarDiff(const Domain* const & domain,
00229                                        Array<Predicate*>& returnArray)
00230   { createAllGroundings(getId(), domain, returnArray); }
00231 
00232      //create groundings of predicate, taking into account vars may be shared
00233   void createAllGroundings(const Domain* const & domain,
00234                            Array<Predicate*>& returnArray)
00235   { createAllGroundings(domain, &returnArray, NULL, -1); }
00236 
00237 
00238     //create groundings of predicate, taking into account vars may be shared
00239   void createAllGroundings(const Domain* const & domain,
00240                            Array<int*>& returnArray)
00241   { createAllGroundings(domain, NULL, &returnArray, -1); }
00242 
00252   void getGroundingNumber(const Domain* const & domain,
00253                           Array<Predicate*>& returnArray, const int& grounding)
00254   { createAllGroundings(domain, &returnArray, NULL, grounding); }
00255 
00256   int getNumTerms() const { return terms_->size(); }
00257 
00258   const Term* getTerm(const int& idx) const { return (*terms_)[idx]; }
00259 
00260 
00261   void setTermToConstant(const int& termNum, const int& constId)
00262   {
00263     assert(termNum < template_->getNumTerms());
00264     assert(constId >= 0);
00265     if (termNum >= terms_->size()) terms_->growToSize(termNum+1,NULL);
00266     if ((*terms_)[termNum]) delete (*terms_)[termNum];
00267     (*terms_)[termNum] = new Term(constId, (void*)this, true);
00268     setDirty();
00269   }
00270 
00271   
00272   bool containsConstant(const int& constId) const
00273   {
00274     assert(constId >= 0);
00275     for (int i = 0; i < terms_->size(); i++)
00276     {
00277       Term* t = (*terms_)[i];
00278       if (t->getType() == Term::CONSTANT && t->getId() == constId) return true;
00279     }
00280     return false;
00281   }
00282 
00288   bool containsConstants() const
00289   {
00290     for (int i = 0; i < terms_->size(); i++)
00291     {
00292       Term* t = (*terms_)[i];
00293       if (t->getType() == Term::CONSTANT) return true;
00294     }
00295     return false;    
00296   }
00297 
00298   void setTemplate(PredicateTemplate* const & t) { template_ = t; }
00299 
00300   const PredicateTemplate* getTemplate() const { return template_; }
00301 
00302 
00303     // Caller should not delete the returned const char* 
00304   const char* getName() const { return template_->getName(); }
00305 
00306   int getId() const { return template_->getId(); }
00307   
00308 
00309     // Caller should not delete the returned const char* nor modify its
00310     // contents. Returns NULL if idx is larger than the possible number of 
00311     // terms
00312   const char* getTermTypeAsStr(const int& idx) const 
00313   {
00314     if (idx >= template_->getNumTerms()) return NULL;
00315     return template_->getTermTypeAsStr(idx); 
00316   }
00317 
00318     // Returns -1 if idx is larger than the possible number of terms
00319   int getTermTypeAsInt(const int& idx) const 
00320   {
00321     if (idx >= template_->getNumTerms()) return -1;
00322     return template_->getTermTypeAsInt(idx); 
00323   }
00324 
00325 
00326   bool allTermsAreDiffVars()
00327   {
00328     if (dirty_) computeAndStoreIntArrRep();
00329     return allTermsAreDiffVars_;
00330   }
00331   
00332 
00333   bool checkAllTermsAreDiffVars()
00334   {
00335     Array<int> vars;
00336     allTermsAreDiffVars_ = true;
00337     for (int i = 0; i < terms_->size(); i++)
00338     {
00339       if ((*terms_)[i]->getType() == Term::VARIABLE)
00340       {
00341         int tid = (*terms_)[i]->getId();
00342         if (vars.contains(tid)) { allTermsAreDiffVars_ = false; return false;}
00343         else                    vars.append(tid);
00344       }
00345       else
00346       { 
00347         assert((*terms_)[i]->getType() != Term::FUNCTION);
00348           //is a constant
00349         allTermsAreDiffVars_ = false;
00350         return false;
00351       }
00352     }
00353     return true;
00354   }
00355 
00356 
00357   bool isGrounded()
00358   {
00359     if (dirty_) computeAndStoreIntArrRep();
00360     return isGrounded_;    
00361   }
00362 
00363 
00372   bool canBeGroundedAs(Predicate* const & partGndPred)
00373   {
00374     //assert(partGndPred->isGrounded());
00375     if (template_->getId() != partGndPred->getId()) return false;
00376     if (allTermsAreDiffVars()) return true;
00377     if (isGrounded() && partGndPred->isGrounded()) return same(partGndPred);
00378     
00379     int varGndings[MAX_VAR];
00380     memset(varGndings, -1, MAX_VAR*sizeof(int));
00381     for (int i = 0; i < terms_->size(); i++) 
00382     {
00383       int termType = (*terms_)[i]->getType();
00384       
00385       if (termType == Term::CONSTANT) 
00386       {
00387         if ((*terms_)[i]->getId() != partGndPred->getTerm(i)->getId()) 
00388           return false;
00389       }
00390       else 
00391       if (termType == Term::VARIABLE) 
00392       {
00393         int varId = -(*terms_)[i]->getId();
00394         assert(varId > 0);
00395         assert(varId < MAX_VAR);
00396         if (varGndings[varId] < 0) // if variable has not been grounded
00397           varGndings[varId] = partGndPred->getTerm(i)->getId();
00398         else 
00399           if (varGndings[varId] != partGndPred->getTerm(i)->getId())
00400             return false;
00401       }
00402       else
00403       {
00404         assert(false);
00405       }
00406     }
00407     return true;
00408   }
00409 
00410 
00411   bool canBeGroundedAs(const GroundPredicate* const & gndPred);
00412 
00413   Array<int> * getPredicateConstants(Array<int> * const & constants)
00414   {
00415     Array<int> * pconstants = new Array<int>();
00416     for (int termno = 0; termno < getNumTerms(); termno++)
00417     {
00418       const Term *term = getTerm(termno);
00419       int id = term->getId();
00420       assert(id < 0);
00421       pconstants->append((*constants)[-id]);
00422     }
00423     return pconstants;
00424   }
00425 
00426   Array<int> * getPredicateConstants()
00427   {
00428     Array<int> * pconstants = new Array<int>();
00429     for (int termno = 0; termno < getNumTerms(); termno++)
00430     {
00431       const Term *term = getTerm(termno);
00432       int id = term->getId();
00433       assert(id >= 0);
00434       pconstants->append(id);
00435     }
00436     return pconstants;
00437   }
00438 
00439   void setDirty();
00440   bool isDirty() const { return dirty_; }
00441 
00442   void setParent(Clause* const & parent) { parent_ = parent; setDirty(); }
00443   Clause* getParent() const { return parent_; }
00444 
00445         // True, if the predicate can be used in the inverted index
00446     // If in pos. clause, then it must be negated
00447     // If in neg. clause, then the inverted index can not be used
00448   bool isIndexable(bool posClause)
00449   {
00450       // At most one of the two terms is grounded
00451       // and equality pred is never indexed
00452     //if (isGrounded() || isEqualPred()) return false;
00453     if (isEqualPred()) return false;
00454     
00455     //return (!getSense());
00456     return true;
00457   }
00458 
00459   void createVarsTypeIdArr(Array<VarsTypeId*>*& varsTypeIdArr)
00460   {
00461     if (varsTypeIdArr == NULL) varsTypeIdArr = new Array<VarsTypeId*>;
00462 
00463       //for each variable of the predicate
00464     for (int j = 0; j < terms_->size(); j++)
00465     {
00466       Term* t = (*terms_)[j];
00467       if (t->getType() == Term::VARIABLE)
00468       {
00469         int id = -(t->getId());
00470         assert(id > 0);
00471         if (id >= varsTypeIdArr->size()) varsTypeIdArr->growToSize(id+1, NULL);
00472         VarsTypeId*& vti = (*varsTypeIdArr)[id];
00473         if (vti == NULL) 
00474         {
00475           vti = new VarsTypeId;
00476           vti->typeId = getTermTypeAsInt(j);
00477           assert(vti->typeId >= 0);
00478         }
00479         assert(getTermTypeAsInt(j) == vti->typeId);
00480         vti->vars.append(t);
00481       }
00482       assert(t->getType() != Term::FUNCTION);
00483     }// for each variable of the predicate
00484   }
00485 
00486 
00487   void deleteVarsTypeIdArr(Array<VarsTypeId*>*& varsTypeIdArr)
00488   {
00489     for (int i = 0; i < varsTypeIdArr->size(); i++)
00490       if ((*varsTypeIdArr)[i]) delete (*varsTypeIdArr)[i];
00491     delete varsTypeIdArr;
00492     varsTypeIdArr = NULL; 
00493   }
00494 
00495 
00496     //Does not consider the sense of the predicate.
00497   bool same(Predicate* const & p)
00498   {
00499     if (this == p)  return true;
00500     const Array<int>* pArr  = p->getIntArrRep();
00501     const Array<int>* myArr = getIntArrRep();
00502     if (myArr->size() != pArr->size()) return false;
00503     const int* pItems  = p->getIntArrRep()->getItems();
00504     const int* myItems = getIntArrRep()->getItems();
00505     return (memcmp(myItems, pItems, myArr->size()*sizeof(int))==0);
00506   }
00507 
00508 
00509   bool same(const GroundPredicate* const & gp);
00510 
00511   
00512     // represent function as an Array<int> and append it to rep
00513   void appendIntArrRep(Array<int>& rep) 
00514   {
00515     if (dirty_) computeAndStoreIntArrRep();
00516     rep.append(*intArrRep_);
00517   }
00518 
00519 
00520   size_t hashCode()
00521   {
00522     if (dirty_) computeAndStoreIntArrRep();
00523     return hashCode_;
00524   }
00525 
00526 
00527   ostream& printAsInt(ostream& out) const
00528   {
00529     if(isEqualPred()) return printAsIntEqualPred(out);
00530     if(isInternalPred()) return printAsIntInternalPred(out);
00531 
00532     if (!sense_) out << "!";
00533     out << template_->getId() << "(";
00534     for (int i = 0; i < terms_->size(); i++)
00535     {
00536       (*terms_)[i]->printAsInt(out); 
00537       out << ((i!=terms_->size()-1)?",":")");
00538     }
00539     return out;
00540   }
00541 
00542   ostream& printWithStrVar(ostream& out, const Domain* const & domain) const;
00543 
00544   ostream& print(ostream& out, const Domain* const & domain) const;
00545 
00546 
00547  private:
00548  
00564   void createAllGroundings(const Domain* const & domain,
00565                            Array<Predicate*>* const & predReturnArray,
00566                            Array<int*>* const & constReturnArray,
00567                            const int& grounding);
00568  
00569   void copy(const Predicate& p)
00570   {
00571     template_ = p.template_;
00572 
00573     terms_ = new Array<Term*>;
00574     Array<Term*>* tterms = p.terms_;
00575     for (int i = 0; i < tterms->size(); i++)
00576     {
00577       Term* t = (*tterms)[i];
00578       terms_->append(new Term(*t, (void*)this, true));      
00579     }
00580     dirty_ = p.dirty_;
00581 
00582     if (!dirty_) { assert(noDirtyTerms()); }
00583 
00584     sense_ = p.sense_;
00585     truthValue_ = p.truthValue_;
00586     allTermsAreDiffVars_ = p.allTermsAreDiffVars_;
00587     isGrounded_ = p.isGrounded_;
00588     
00589     if (p.intArrRep_)  intArrRep_ = new Array<int>(*(p.intArrRep_));
00590     else               intArrRep_ = NULL;    
00591 
00592     hashCode_ = p.hashCode_;
00593 
00594     setParentDirty();
00595   }
00596 
00597 
00598   void setParentDirty();
00599 
00600   bool noDirtyTerms()
00601   {
00602     for (int i = 0; i < terms_->size(); i++)
00603       if ((*terms_)[i]->isDirty()) return false;
00604     return true;
00605   }
00606 
00607 
00608   const Array<int>* getIntArrRep() 
00609   { if (dirty_) computeAndStoreIntArrRep(); return intArrRep_; }
00610 
00611 
00612     //Also finds out whether all of its terms are variables/constants.
00613   void computeAndStoreIntArrRep()
00614   {
00615     dirty_ = false;
00616     if (intArrRep_ == NULL) intArrRep_ = new Array<int>;
00617     else                    intArrRep_->clear();
00618       //commented out: predicate comparison ignores sense
00619     //intArrRep_->append(sense_?1:0);
00620     intArrRep_->append(template_->getId());
00621     int numTerms = terms_->size();
00622     Array<int> vars(numTerms);
00623     allTermsAreDiffVars_ = true;
00624     isGrounded_ = true;
00625     for (int i = 0; i < numTerms; i++)
00626     {
00627       (*terms_)[i]->appendIntArrRep(*intArrRep_);
00628       int termType = (*terms_)[i]->getType();
00629       
00630       if (termType == Term::VARIABLE)
00631       {
00632         if (allTermsAreDiffVars_)
00633         {
00634           int tid = (*terms_)[i]->getId();
00635           if (vars.contains(tid)) allTermsAreDiffVars_ = false;
00636           else                    vars.append(tid);
00637         }
00638         isGrounded_ = false;
00639       }
00640       else
00641       if (termType == Term::CONSTANT)
00642       {
00643         allTermsAreDiffVars_ = false;
00644         if ((*terms_)[i]->getType() != Term::CONSTANT) isGrounded_ = false;
00645       }
00646       else
00647       {
00648         assert(false);
00649       }
00650     }
00651     hashCode_ = Hash::hash(*intArrRep_);
00652   }
00653 
00654 
00655   ostream& printAsIntEqualPred(ostream& out) const
00656   {
00657     assert(isEqualPred());
00658     assert(terms_->size()==2);
00659     if (!sense_) out << "!(";
00660     (*terms_)[0]->printAsInt(out); 
00661     out << " = ";
00662     (*terms_)[1]->printAsInt(out); 
00663     if (!sense_) out << ")";
00664     return out;
00665   }
00666 
00667 
00668   ostream& printEqualPred(ostream& out, const Domain* const & domain) const
00669   {
00670     assert(isEqualPred());
00671     assert(terms_->size()==2);
00672     if (!sense_) out << "!(";
00673     (*terms_)[0]->print(out, domain); 
00674     out << " = ";
00675     (*terms_)[1]->print(out, domain); 
00676     if (!sense_) out << ")";
00677     return out;
00678   }
00679 
00680 
00681   ostream& 
00682   printEqualPredWithStrVar(ostream& out, const Domain* const & domain) const
00683   {
00684     assert(isEqualPred());
00685     assert(terms_->size()==2);
00686     if (!sense_) out << "!(";
00687     (*terms_)[0]->printWithStrVar(out, domain); 
00688     out << " = ";
00689     (*terms_)[1]->printWithStrVar(out, domain); 
00690     if (!sense_) out << ")";
00691     return out;
00692   }
00693     
00694     
00695   ostream& printAsIntInternalPred(ostream& out) const
00696   {
00697     assert(isInternalPred());
00698     assert(terms_->size()==2);
00699     
00700       //No infix
00701         if (strncmp(getName(), PredicateTemplate::SUBSTR_NAME,
00702                                 strlen(PredicateTemplate::SUBSTR_NAME)) == 0)
00703         {
00704           if (!sense_) out << "!";
00705       out << template_->getId() << "(";
00706       for (int i = 0; i < terms_->size(); i++)
00707       {
00708         (*terms_)[i]->printAsInt(out); 
00709         out << ((i!=terms_->size()-1)?",":")");
00710       }
00711       return out; 
00712         }
00713         else // Infix
00714         {
00715       if (!sense_) out << "!(";
00716       (*terms_)[0]->printAsInt(out); 
00717           
00718           if (strncmp(getName(), PredicateTemplate::GT_NAME,
00719                                   strlen(PredicateTemplate::GT_NAME)) == 0)
00720         out << " > ";
00721       else
00722           if (strncmp(getName(), PredicateTemplate::LT_NAME,
00723                                   strlen(PredicateTemplate::LT_NAME)) == 0)
00724         out << " < ";
00725       else
00726       if (strncmp(getName(), PredicateTemplate::GTEQ_NAME,
00727                                   strlen(PredicateTemplate::GTEQ_NAME)) == 0)
00728         out << " >= ";
00729       else
00730           if (strncmp(getName(), PredicateTemplate::LTEQ_NAME,
00731                                   strlen(PredicateTemplate::LTEQ_NAME)) == 0)
00732         out << " <= ";
00733       
00734       (*terms_)[1]->printAsInt(out); 
00735       if (!sense_) out << ")";
00736       return out;
00737         }
00738   }
00739 
00740 
00741   ostream& printInternalPred(ostream& out, const Domain* const & domain) const
00742   {
00743     assert(isInternalPred());
00744     assert(terms_->size()==2);
00745 
00746           //No infix
00747         if (strncmp(getName(), PredicateTemplate::SUBSTR_NAME,
00748                                 strlen(PredicateTemplate::SUBSTR_NAME)) == 0)
00749         {
00750       if (!sense_) out << "!";
00751       out << PredicateTemplate::SUBSTR_NAME << "(";
00752       for (int i = 0; i < terms_->size(); i++)
00753       {
00754         (*terms_)[i]->print(out, domain); 
00755         out << ((i!=terms_->size()-1)?",":")");
00756       }
00757       return out;
00758         }
00759         else // Infix
00760         {
00761           if (!sense_) out << "!(";
00762       (*terms_)[0]->print(out, domain); 
00763           
00764           if (strncmp(getName(), PredicateTemplate::GT_NAME,
00765                                   strlen(PredicateTemplate::GT_NAME)) == 0)
00766         out << " > ";
00767       else
00768           if (strncmp(getName(), PredicateTemplate::LT_NAME,
00769                                   strlen(PredicateTemplate::LT_NAME)) == 0)
00770         out << " < ";
00771       else
00772       if (strncmp(getName(), PredicateTemplate::GTEQ_NAME,
00773                                   strlen(PredicateTemplate::GTEQ_NAME)) == 0)
00774         out << " >= ";
00775       else
00776           if (strncmp(getName(), PredicateTemplate::LTEQ_NAME,
00777                                   strlen(PredicateTemplate::LTEQ_NAME)) == 0)
00778         out << " <= ";
00779       
00780       (*terms_)[1]->print(out, domain); 
00781       if (!sense_) out << ")";
00782       return out;
00783         }
00784   }
00785 
00786 
00787   ostream& 
00788   printInternalPredWithStrVar(ostream& out, const Domain* const & domain) const
00789   {
00790     assert(isInternalPred());
00791     assert(terms_->size()==2);
00792 
00793           //No infix
00794         if (strncmp(getName(), PredicateTemplate::SUBSTR_NAME,
00795                                 strlen(PredicateTemplate::SUBSTR_NAME)) == 0)
00796         {
00797       if (!sense_) out << "!";
00798       out << PredicateTemplate::SUBSTR_NAME << "(";
00799       for (int i = 0; i < terms_->size(); i++)
00800       {
00801         (*terms_)[i]->printWithStrVar(out, domain); 
00802         out << ((i!=terms_->size()-1)?",":")");
00803       }
00804       return out;
00805         }
00806         else // Infix
00807         {
00808       if (!sense_) out << "!(";
00809       (*terms_)[0]->printWithStrVar(out, domain);
00810           
00811           if (strncmp(getName(), PredicateTemplate::GT_NAME,
00812                                   strlen(PredicateTemplate::GT_NAME)) == 0)
00813         out << " > ";
00814       else
00815           if (strncmp(getName(), PredicateTemplate::LT_NAME,
00816                                   strlen(PredicateTemplate::LT_NAME)) == 0)
00817         out << " < ";
00818       else
00819       if (strncmp(getName(), PredicateTemplate::GTEQ_NAME,
00820                                   strlen(PredicateTemplate::GTEQ_NAME)) == 0)
00821         out << " >= ";
00822       else
00823           if (strncmp(getName(), PredicateTemplate::LTEQ_NAME,
00824                                   strlen(PredicateTemplate::LTEQ_NAME)) == 0)
00825         out << " <= ";
00826       
00827       (*terms_)[1]->printWithStrVar(out, domain); 
00828       if (!sense_) out << ")";
00829       return out;
00830         }
00831   }
00832   
00833    
00834  private:
00835   const PredicateTemplate* template_; // not owned by Predicate
00836   Array<Term*>* terms_;
00837   bool sense_; // indicate whether the predicate is non-negated/negated
00838   TruthValue truthValue_;
00839 
00840   bool allTermsAreDiffVars_; // all of its terms are different variables
00841   bool isGrounded_;
00842 
00843   Array<int>* intArrRep_;
00844   size_t hashCode_;
00845   bool dirty_;
00846   Clause* parent_; //not owned by Predicate, so no deleted in destructor
00847 
00848   static double fixedSizeB_;
00849 };
00850 
00851 inline
00852 ostream& operator<<(ostream& out, const Predicate& p){return p.printAsInt(out);}
00853 
00854 
00856 
00857 class HashPredicate
00858 {
00859  public:
00860   size_t operator()(Predicate* const & p) const  { return p->hashCode(); }
00861 };
00862 
00863 
00864 class EqualPredicate
00865 {
00866  public:
00867   bool operator()(Predicate* const & p1, Predicate* const & p2) 
00868     const { return p1->same(p2); }
00869 };
00870 
00872 
00873 typedef hash_set<Predicate*, HashPredicate, EqualPredicate> PredicateSet;
00874 
00875 typedef HashArray<Predicate*, HashPredicate, EqualPredicate> PredicateHashArray;
00876 
00877 #endif

Generated on Sun Jun 7 11:55:17 2009 for Alchemy by  doxygen 1.5.1