groundpredicate.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, and Daniel Lowd.
00006  * 
00007  * Copyright [2004-07] Stanley Kok, Parag Singla, Matthew
00008  * Richardson, Pedro Domingos, Marc Sumner, Hoifung
00009  * Poon, and Daniel Lowd. 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, and Daniel Lowd 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 GROUNDPREDICATE_H_JUN_26_2005
00067 #define GROUNDPREDICATE_H_JUN_26_2005
00068 
00069 #include <cmath>
00070 #include "domain.h"
00071 #include "predicate.h"
00072 #include "groundclause.h"
00073 
00074 class GroundPredicate
00075 {
00076  public:
00077   GroundPredicate(Predicate* const & pred)
00078     : negGndClauses_(new Array<GroundClause*>),
00079       posGndClauses_(new Array<GroundClause*>),
00080       gndClauseSet_(new GroundClauseSet),
00081       truthValue_(false), wtWhenFalse_(0), wtWhenTrue_(0)
00082   {
00083     assert(pred->isGrounded());
00084     int numTerms = pred->getNumTerms();    
00085     intArrRep_ = new Array<unsigned int>(numTerms+1);
00086     intArrRep_->growToSize(numTerms+1);
00087     (*intArrRep_)[0] = pred->getId();
00088     assert((*intArrRep_)[0] >= 0);
00089     for (int i = 0; i < numTerms; i++)
00090     {
00091       (*intArrRep_)[i+1] = pred->getTerm(i)->getId();
00092       assert((*intArrRep_)[i+1] >= 0);
00093     }
00094     intArrRep_->compress();
00095     hashCode_ = Hash::hash(*intArrRep_);
00096   }
00097 
00098   
00099   ~GroundPredicate()
00100   { 
00101     if (intArrRep_)    delete intArrRep_; 
00102     if (gndClauseSet_) delete gndClauseSet_;
00103     delete negGndClauses_;
00104     delete posGndClauses_;
00105   }
00106 
00107 
00108   void deleteGndClauseSet() 
00109   { if (gndClauseSet_) delete gndClauseSet_; gndClauseSet_ = NULL; }
00110 
00115   void removeGndClauses() 
00116   {
00117     deleteGndClauseSet();
00118     delete negGndClauses_;
00119     delete posGndClauses_;
00120     negGndClauses_ = new Array<GroundClause*>;
00121     posGndClauses_ = new Array<GroundClause*>;
00122   }
00123 
00128   Predicate* createEquivalentPredicate(const Domain* const & domain) const
00129   {
00130     const PredicateTemplate* pt = domain->getPredicateTemplate(getId());
00131     assert(pt);
00132     Predicate* pred = new Predicate(pt);
00133     for (int j = 0; j < pt->getNumTerms(); j++)
00134       pred->appendTerm(new Term(getTermId(j), (void*)pred, true));
00135     return pred;
00136   }
00137 
00138   unsigned int getId() const { return (*intArrRep_)[0]; }
00139   unsigned int getTermId(const int& idx) const { return (*intArrRep_)[idx+1]; }
00140   unsigned int getNumTerms() const { return intArrRep_->size() - 1; }
00141 
00142   bool getTruthValue() const { return truthValue_; }
00143   void setTruthValue(const bool& tv) { truthValue_ = tv; }
00144 
00145   double getWtWhenFalse() const { return wtWhenFalse_; }
00146   void setWtWhenFalse(const double& wt) {wtWhenFalse_ = wt;}
00147   void addWtWhenFalse(const double& wt) {wtWhenFalse_ += wt;}
00148 
00149   double getWtWhenTrue() const { return wtWhenTrue_; }
00150   void setWtWhenTrue(const double& wt) {wtWhenTrue_ = wt;}
00151   void addWtWhenTrue(const double& wt) {wtWhenTrue_ += wt;}
00152 
00153     // Get the probability that the ground predicate is true
00154   double getProbability()
00155   { return 1.0 / ( 1.0 + exp(wtWhenFalse_ - wtWhenTrue_)); }
00156 
00157 
00158   void compress()
00159   {
00160     negGndClauses_->compress();
00161     posGndClauses_->compress();
00162   }
00163 
00164 
00165   size_t hashCode() { return hashCode_; }
00166   
00167   const Array<unsigned int>* getIntArrRep() const { return intArrRep_; }
00168 
00169     // add a copy of this GroundPredicate's intArrRep_ to rep
00170   void appendIntArrRep(Array<unsigned int>& rep) { rep.append(*intArrRep_); }
00171 
00172 
00173   bool appendGndClause(GroundClause* const & gc, const bool& senseInGndClause) 
00174   { 
00175     if (gndClauseSet_== NULL || gndClauseSet_->find(gc) == gndClauseSet_->end())
00176     {
00177       if (gndClauseSet_) gndClauseSet_->insert(gc);
00178       //gndClauses_->append(gc);
00179       if (senseInGndClause) posGndClauses_->append(gc);
00180       else                  negGndClauses_->append(gc);
00181       //senseInGndClauses_->append(senseInGndClause);
00182       return true;
00183     }
00184     return false;
00185   } 
00186 
00187   const Array<GroundClause*>* getNegGndClauses() const { return negGndClauses_;}
00188   const Array<GroundClause*>* getPosGndClauses() const { return posGndClauses_;}
00189 
00190   int getNumGndClauses() const 
00191   { return negGndClauses_->size() + posGndClauses_->size(); }
00192 
00193 
00194   bool same(const GroundPredicate* const & gp)
00195   {
00196     if (intArrRep_->size() != gp->getIntArrRep()->size()) return false;
00197     return (memcmp(intArrRep_->getItems(), gp->getIntArrRep()->getItems(), 
00198                    intArrRep_->size()*sizeof(unsigned int)) == 0);
00199   }
00200 
00201   string getPredicateStr(const Domain* const& domain)
00202   {
00203           const char* predName = domain->getPredicateName((*intArrRep_)[0]);
00204           string strPredName = predName;
00205           strPredName = strPredName + "(";
00206           int size = intArrRep_->size();
00207           for (int i = 1; i < size; i++)
00208           {
00209                   string name = domain->getConstantName((*intArrRep_)[i]);
00210                   string::size_type at = name.rfind("@");
00211                   if (at != string::npos) name = name.substr(at+1, name.length()-at-1);
00212                   strPredName = strPredName + name;
00213                   if (i < size-1) strPredName = strPredName + ",";
00214                   else strPredName = strPredName + ")";
00215           }     
00216           return strPredName;
00217   }
00218   string getPredName(const Domain* const& domain) 
00219   {
00220           string s = string(domain->getPredicateName((*intArrRep_)[0]));
00221           return s;
00222   }
00223 
00224   string getPredString(const Domain* const & domain)
00225   {
00226           string strPred = string(domain->getPredicateName((*intArrRep_)[0]));
00227           strPred = strPred + "(";
00228           int size = intArrRep_->size();
00229           for (int i = 1; i < size; i++)
00230           {
00231                   string name = domain->getConstantName((*intArrRep_)[i]);
00232                   string::size_type at = name.rfind("@");
00233                   if (at != string::npos) name = name.substr(at+1, name.length()-at-1);
00234                   strPred = strPred + name;
00235                   if (i < size-1) strPred = strPred + ",";
00236                   else            strPred = strPred + ")";
00237           }
00238           
00239          return strPred; 
00240   }
00241 
00242   void print(ostream& out, const Domain* const & domain) const
00243   {
00244     const char* predName = domain->getPredicateName((*intArrRep_)[0]);
00245     out << predName;
00246       // If dealing with a propositional variable
00247     if (strcmp(domain->getConstantName((*intArrRep_)[1]),
00248                Domain::PROPOSITIONAL_CONSTANT) == 0)
00249     {
00250       return;
00251     }    
00252     
00253     out << "(";
00254     int size = intArrRep_->size();
00255     for (int i = 1; i < size; i++)
00256     {
00257       string name = domain->getConstantName((*intArrRep_)[i]);
00258       string::size_type at = name.rfind("@");
00259       if (at != string::npos) name = name.substr(at+1, name.length()-at-1);
00260       out << name;
00261       if (i < size-1) out << ",";
00262       else            out << ")";
00263     }
00264   }
00265 
00266 
00267   void print(ostream& out) const
00268   {
00269     out << (*intArrRep_)[0] << "(";
00270     int size = intArrRep_->size();
00271     for (int i = 1; i < size; i++)
00272     {
00273       out << (*intArrRep_)[i];
00274       if (i < size-1) out << ",";
00275       else            out << ")";
00276     }
00277   }
00278   
00282   double sizeKB()
00283   {
00284     double size = 0;
00285       //intArrRep_
00286     if (intArrRep_)
00287       size += (intArrRep_->size()*sizeof(unsigned int) / 1024.0);
00288       // hashCode_
00289     size += (sizeof(size_t) / 1024.0);
00290 
00291     if (negGndClauses_)
00292     {
00293       for (int i = 0; i < negGndClauses_->size(); i++)
00294         size += ((*negGndClauses_)[i]->sizeKB());
00295     }
00296     if (posGndClauses_)
00297     {
00298       for (int i = 0; i < posGndClauses_->size(); i++)
00299         size += ((*posGndClauses_)[i]->sizeKB());
00300     }
00301 
00302       // truthValue_
00303     size += (sizeof(bool) / 1024.0);
00304       // wtWhenFalse_
00305     size += (sizeof(double) / 1024.0);
00306       // wtWhenTrue_
00307     size += (sizeof(double) / 1024.0);
00308     
00309     return size;
00310   }
00311 
00312  private:
00313     // intArrRep_[0] is the pred id; intArrRep_[i] is the constant id
00314     // where i > 0
00315   Array<unsigned int>* intArrRep_; // 4 bytes + 4*n bytes (n is the arity)
00316   size_t hashCode_; // 4 bytes
00317     // gnd pred is a neg lit in these clauses
00318   Array<GroundClause*>* negGndClauses_; // 4 bytes + 4*n bytes
00319     // gnd pred is a pos lit in these clauses 
00320   Array<GroundClause*>* posGndClauses_; // 4 bytes + 4*n bytes
00321     // Pointers to ground clauses in which this pred occurs
00322   GroundClauseSet* gndClauseSet_; // 4 bytes + 4*n bytes
00323 
00324     // Truth value
00325   bool truthValue_;
00326     // Wt when false
00327   double wtWhenFalse_;
00328     // Wt when true
00329   double wtWhenTrue_;
00330  
00331 };
00332 
00333 
00335 
00336 
00337 class HashGroundPredicate
00338 {
00339  public:
00340   size_t operator()(GroundPredicate* const & gp) const  {return gp->hashCode();}
00341 };
00342 
00343 
00344 class EqualGroundPredicate
00345 {
00346  public:
00347   bool operator()(GroundPredicate* const & p1, GroundPredicate* const& p2) const
00348   { return p1->same(p2); }
00349 };
00350 
00352 
00353 typedef hash_set<GroundPredicate*, HashGroundPredicate, EqualGroundPredicate> 
00354   GroundPredicateSet;
00355 
00356 typedef hash_map<GroundPredicate*, int,HashGroundPredicate,EqualGroundPredicate>
00357   GroundPredicateToIntMap;
00358 
00359 
00360 
00361 #endif

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