groundclause.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 GROUNDCLAUSE_H_JUN_26_2005
00067 #define GROUNDCLAUSE_H_JUN_26_2005
00068 
00069 #include <cfloat>
00070 #include <ext/hash_set>
00071 using namespace __gnu_cxx;
00072 #include "hasharray.h"
00073 #include "array.h"
00074 #include "hash.h"
00075 #include <map>
00076 #include <cstring>
00077 
00078 using namespace std;
00079 
00080 // containers    /////////////////////////////////////////////
00081 typedef map<int, pair<int,bool> > IntBoolPair;
00082 typedef IntBoolPair::iterator IntBoolPairItr;  
00084 
00085 // Constants
00086 const double HARD_GROUNDCLAUSE_WT = DBL_MAX;
00087 const bool gcdebug = false;
00088 
00089 // Forward declarations
00090 class MLN;
00091 class Domain;
00092 class Clause;
00093 class GroundPredicate;
00094 class HashGroundPredicate;
00095 class EqualGroundPredicate;
00096 
00097 // Typedefs
00098 typedef HashArray<GroundPredicate*, HashGroundPredicate, EqualGroundPredicate> 
00099  GroundPredicateHashArray;
00100 
00104 class GroundClause
00105 {
00106  public:
00107   GroundClause(const Clause* const & c, 
00108                GroundPredicateHashArray* const & gndPredHashArray);
00109 
00110   ~GroundClause() 
00111   { 
00112     if (gndPredIndexes_) delete gndPredIndexes_;
00113     if (foClauseFrequencies_) delete foClauseFrequencies_;
00114   }
00115 
00116   void deleteFoClauseFrequencies()
00117   { 
00118     if (foClauseFrequencies_) delete foClauseFrequencies_;
00119     foClauseFrequencies_ = NULL;
00120   }
00121 
00122   void addWt(const double& wt) 
00123   { if (wt_ == HARD_GROUNDCLAUSE_WT) return; wt_ += wt; }
00124 
00125   void setWt(const double& wt) 
00126   { if (wt_ == HARD_GROUNDCLAUSE_WT) return; wt_ = wt; }
00127 
00128   double getWt() const { return wt_; }
00129 
00130   void setWtToHardWt() { wt_ = HARD_GROUNDCLAUSE_WT; }
00131   bool isHardClause() const { return (wt_ == HARD_GROUNDCLAUSE_WT); }
00132 
00133   int getNumGroundPredicates() const { return gndPredIndexes_->size(); }
00134 
00135   const GroundPredicate* getGroundPredicate(const int& i,
00136                       GroundPredicateHashArray* const & gndPredHashArray) const 
00137   { 
00138     return (*gndPredHashArray)[abs((*gndPredIndexes_)[i]) - 1];
00139   }
00140 
00147   void appendToGndPreds(GroundPredicateHashArray* const & gndPredHashArray);
00148 
00149   bool getGroundPredicateSense(const int& i) const 
00150   { return ((*gndPredIndexes_)[i] > 0); }
00151 
00152   void setGroundPredicateSense(const int& i, const bool& sense)
00153   {
00154       // Already the sense being set to, then return
00155     if (sense && (*gndPredIndexes_)[i] > 0 ||
00156         !sense && (*gndPredIndexes_)[i] < 0)
00157       return;
00158     
00159     (*gndPredIndexes_)[i] = -(*gndPredIndexes_)[i];
00160     rehash();
00161   }
00162 
00163   void setGroundPredicateIndex(const int& i, const int& gndPredIdx) 
00164   { (*gndPredIndexes_)[i] = gndPredIdx; }
00165 
00166   int getGroundPredicateIndex(const int& i) const 
00167   { return (*gndPredIndexes_)[i]; }
00168 
00169   const Array<int>* getGndPredIndexes() const
00170   {
00171     return gndPredIndexes_;
00172   }
00173 
00181   void setWtToSumOfParentWts(const MLN* const & mln);
00182   
00183   IntBoolPair *getClauseFrequencies()
00184   {
00185     return foClauseFrequencies_;
00186   }
00187 
00188   int getClauseFrequency(int clauseno)
00189   {
00190         if (!foClauseFrequencies_) return 0;
00191         IntBoolPairItr itr = foClauseFrequencies_->find(clauseno);
00192         if (itr == foClauseFrequencies_->end()) 
00193           return 0;
00194         else
00195           return itr->second.first;
00196   }
00197   
00198   void incrementClauseFrequency(int clauseno, int increment, bool invertWt)
00199   {
00200         if (!foClauseFrequencies_)
00201       foClauseFrequencies_ = new IntBoolPair;
00202         IntBoolPairItr itr = foClauseFrequencies_->find(clauseno);
00203         if (itr == foClauseFrequencies_->end()) 
00204           foClauseFrequencies_->
00205         insert(make_pair(clauseno, make_pair(increment, invertWt)));
00206         else
00207           itr->second.first += increment;
00208   }
00209 
00216   void removeGndPred(const int& gndPred)
00217   {
00218     for (int i = 0; i < gndPredIndexes_->size(); i++)
00219     {
00220       if (gndPred == (*gndPredIndexes_)[i])
00221       {
00222         gndPredIndexes_->removeItem(i);
00223         gndPredIndexes_->compress();
00224         rehash();
00225         break;
00226       }
00227     }
00228   }
00229 
00237   void changeGndPredIndex(const int& oldIdx, const int& newIdx)
00238   {
00239     for (int i = 0; i < gndPredIndexes_->size(); i++)
00240     {
00241       if (oldIdx == (*gndPredIndexes_)[i])
00242       {
00243         (*gndPredIndexes_)[i] = newIdx;
00244         rehash();
00245         break;
00246       }
00247     }    
00248   }
00249 
00250   size_t hashCode() { return hashCode_; }
00251   
00252   bool same(const GroundClause* const & gc)
00253   {
00254     if (this == gc) return true;
00255     if (gndPredIndexes_->size() != gc->getGndPredIndexes()->size())
00256     {
00257       return false;
00258     }
00259     return (memcmp(gndPredIndexes_->getItems(),
00260                    gc->getGndPredIndexes()->getItems(), 
00261                    (gndPredIndexes_->size())*sizeof(int)) == 0);
00262   }
00263 
00264   void printWithoutWt(ostream& out) const;
00265   void print(ostream& out) const;
00266 
00267   ostream& print(ostream& out, const Domain* const& domain, 
00268                  const bool& withWt, const bool& asInt, 
00269                  const bool& withStrVar,
00270                  const GroundPredicateHashArray* const & predHashArray) const;
00271 
00272   ostream& printWithoutWt(ostream& out, const Domain* const & domain,
00273                   const GroundPredicateHashArray* const & predHashArray) const;
00274 
00275   ostream& 
00276   printWithoutWtWithStrVar(ostream& out, const Domain* const & domain,
00277                   const GroundPredicateHashArray* const & predHashArray) const;
00278 
00279   ostream& printWithWtAndStrVar(ostream& out, const Domain* const& domain,
00280                   const GroundPredicateHashArray* const & predHashArray) const;
00281 
00282   ostream& print(ostream& out, const Domain* const& domain,
00283                  const GroundPredicateHashArray* const & predHashArray) const;
00284     
00285   ostream& printWithoutWtWithStrVarAndPeriod(ostream& out, 
00286                                              const Domain* const& domain,
00287                   const GroundPredicateHashArray* const & predHashArray) const;
00288 
00289   double sizeKB();
00290 
00291  private:
00292   
00296   void rehash()
00297   {
00298     Array<unsigned int>* intArrRep = new Array<unsigned int>;
00299 
00300       // For each predicate
00301     for (int i = 0; i < gndPredIndexes_->size(); i++)
00302     {
00303         // For each pred 1 (if pos.) or 0 (if neg.) is appended to intArrRep
00304       if ((*gndPredIndexes_)[i] > 0)
00305         intArrRep->append(1);
00306       else
00307         intArrRep->append((unsigned int)0);
00308       intArrRep->append(abs((*gndPredIndexes_)[i]));
00309     }
00310   
00311     hashCode_ = Hash::hash(*intArrRep);
00312     delete intArrRep;    
00313   }
00314 
00315  private:
00316     // Hash code of this ground clause
00317   size_t hashCode_;
00318   Array<int>* gndPredIndexes_; // 4 + 4*n bytes (n is no. of preds)
00319 
00320     // overloaded to indicate whether this is a hard clause
00321     // if this is a hard clause, wt_ is set to HARD_GROUNDCLAUSE_WT
00322   double wt_; // 8 bytes
00323 
00324     // Number of first-order clauses this clause corresponds to. Also stores
00325     // if the weight has been flipped from each parent clause
00326   IntBoolPair* foClauseFrequencies_;
00327 
00328 };
00329 
00330 
00332 
00333 
00334 class HashGroundClause
00335 {
00336  public: 
00337   size_t operator()(GroundClause* const & gc) const  { return gc->hashCode(); }
00338 };
00339 
00340 
00341 class EqualGroundClause
00342 {
00343  public:
00344   bool operator()(GroundClause* const & c1, GroundClause* const & c2) const
00345     { return c1->same(c2); }
00346 };
00347 
00348 
00350 
00351 typedef HashArray<GroundClause*, HashGroundClause, EqualGroundClause> 
00352   GroundClauseHashArray;
00353 
00354 typedef hash_set<GroundClause*, HashGroundClause, EqualGroundClause> 
00355   GroundClauseSet;
00356 
00357   
00358 #endif

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