superpred.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-08] 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 _SUPERPRED_H_DEC_2007
00067 #define _SUPERPRED_H_DEC_2007
00068 
00069 #include "superclause.h"
00070 
00071 /******************************************************************************/
00072 // Clause Counter
00073 /******************************************************************************/
00074 
00075 //used in the following class
00076 typedef hash_map<int, int, HashInt, EqualInt> IntToIntMap;
00077 
00078 //this class is for maintaining the counts of for an indexed set of
00079 //clauses (where each entity has a unique id)
00080 class ClauseCounter
00081 {
00082  public:
00083   ClauseCounter()
00084   {
00085     idToIndex_ = new IntToIntMap();
00086     clauseIds_ = new Array<int>;
00087     clauseCntsArr_ = new Array<Array<double>*>;
00088     dirty_ = true;
00089   }
00090 
00091   ~ClauseCounter()
00092   {
00093     delete idToIndex_;
00094     delete clauseIds_;
00095     for (int i = 0; i < clauseCntsArr_->size(); i++)
00096     {
00097       delete (*clauseCntsArr_)[i];
00098     }
00099     delete clauseCntsArr_;
00100   }
00101 
00102   int getNumClauses() { return clauseIds_->size();}
00103 
00104   const Array<int>* getClauseIds() const { return clauseIds_;}
00105 
00106   const Array<double>* getClauseCounts(int index) const
00107   {
00108     return (*clauseCntsArr_)[index];
00109   }
00110 
00111   int  getClauseId(int index) { return (*clauseIds_)[index];}
00112 
00113   void incrementCount(int clauseId, int predId, int clausePredCnt, double cnt)
00114   {
00115     int index;
00116     int id = clauseId;
00117     Array<double> *clauseCnts;
00118     IntToIntMap::iterator itr;
00119     itr = idToIndex_->find(id);
00120 
00121     if (itr == idToIndex_->end())
00122     {
00123       index = clauseIds_->size();
00124       (*idToIndex_)[id] = index;
00125       clauseIds_->append(id);
00126 
00127       clauseCnts = new Array<double>();
00128       clauseCnts->growToSize(clausePredCnt, 0);
00129       clauseCntsArr_->append(clauseCnts);
00130     }
00131     else
00132     {
00133       index = (*idToIndex_)[id];
00134     }
00135 
00136       //increment the count for this clauseId/predId combination
00137     clauseCnts = (*clauseCntsArr_)[index];
00138     (*clauseCnts)[predId] += cnt;
00139     dirty_ = true;
00140   }
00141 
00142   size_t getHashCode()
00143   {
00144     if (!dirty_)
00145       return hashCode_;
00146     IntToIntMap::iterator itr;
00147     Array<double> * clauseCnts;
00148     int code = 1;
00149     for (int index = 0; index < clauseIds_->size(); index++)
00150     {
00151       code = 31*code + (*clauseIds_)[index];
00152       clauseCnts = (*clauseCntsArr_)[index];
00153       for (int predId = 0; predId < clauseCnts->size(); predId++)
00154       {
00155         code = 31*code + (int)(*clauseCnts)[predId];
00156       }
00157     }
00158     dirty_ = false;
00159     hashCode_ = (size_t)code;
00160     return hashCode_;
00161   }
00162 
00163   ostream & print(ostream & out)
00164   {
00165     for (int index = 0; index < clauseIds_->size(); index++)
00166     {
00167       out<<(*clauseIds_)[index]<<" : ";
00168       printArray(*(*clauseCntsArr_)[index], out);
00169       out<<" ** ";
00170     }
00171     return out;
00172   }
00173 
00174  private:
00175   IntToIntMap *idToIndex_;
00176 
00177   //NOTE: Assumes that clauseIds_ are stored in a pre-defined order for
00178   //all the ClauseCounter instances. This is critical for making
00179   //sure that hashCode/Equal functions on two instances of this
00180   //class work as expected
00181 
00182   Array<int> * clauseIds_;
00183   Array<Array<double>*> * clauseCntsArr_;
00184   bool dirty_;
00185   size_t hashCode_;
00186 };
00187 
00188 class PredicateConstantsInfo
00189 {
00190  public:
00191   PredicateConstantsInfo(ClauseCounter * const & cc, int superPredId)
00192   {
00193     cc_ = cc;
00194     superPredId_ = superPredId;
00195   }
00196 
00197   ~PredicateConstantsInfo()
00198   {
00199     delete cc_;
00200   }
00201 
00202   int getSuperPredId() { return superPredId_;}
00203   ClauseCounter * getClauseCounter() {return cc_;}
00204 
00205  private:
00206   int superPredId_;
00207   ClauseCounter *cc_;
00208 };
00209 
00210 
00211 class SuperPred;
00212 typedef hash_map<Array<int>*, SuperPred*, HashIntArray, EqualIntArray>
00213   IntArrayToSuperPredMap;
00214 
00215 //extern function defined in superpred.cpp
00216 extern void createSuperPreds(
00217                            Array<Array<SuperClause*>*>* const & superClausesArr,
00218                              Domain * const & domain);
00219 
00220 class SuperPred
00221 {
00222  public:
00223   SuperPred(int & predId, ClauseCounter* const & clauseCounter,
00224             int parentSuperPredId)
00225   {
00226     constantTuples_ = new Array<Array<int>*>;
00227     predId_ = predId;
00228 
00229       //find the id of this superpred - this is simply the
00230       //current cnt of the superpreds for this predId
00231     Array<SuperPred *> * superPreds = (*(SuperPred::superPredsArr_))[predId];
00232     superPredId_ = superPreds->size();
00233     superPreds->append(this);
00234     clauseCounter_ = clauseCounter;
00235     parentSuperPredId_ = parentSuperPredId;
00236   }
00237 
00238     //not responsible for deleting the constants
00239   ~SuperPred()
00240   {
00241     delete constantTuples_;
00242       //note: though, clauseCounter is allocated memory somewhere outside,
00243       //it is delete here
00244     delete clauseCounter_;
00245   }
00246 
00247   int getPredId() {return predId_;}
00248 
00249   Array<int> * getConstantTuple(int tindex) {return (*constantTuples_)[tindex];}
00250 
00251   int getSuperPredId() {return superPredId_;}
00252 
00253   int getParentSuperPredId() {return parentSuperPredId_;}
00254 
00255   int getNumTuples() { return constantTuples_->size();}
00256  
00257   const ClauseCounter * getClauseCounter() { return clauseCounter_;}
00258 
00259   void addConstantTuple(Array<int> * constants, int predId)
00260   {
00261     constantTuples_->append(constants);
00262     IntArrayToSuperPredMap * constantsToSuperPred;
00263     constantsToSuperPred = (*(SuperPred::constantsToSuperPredArr_))[predId];
00264     (*constantsToSuperPred)[constants] = this;
00265   }
00266 
00267                   //static functions
00268   static int getSuperPredCount(int predId)
00269   {
00270     return (*superPredsArr_)[predId]->size();
00271   }
00272 
00273     //get all the superpreds for the given predId
00274   static Array<SuperPred*>* getSuperPreds(int predId)
00275   {
00276     return (*superPredsArr_)[predId];
00277   }
00278 
00279   static void clear(int predCnt)
00280   {
00281       //if first time access then, need to allocate memory
00282     if (isFirstAccessForStaticVars_)
00283     {
00284       superPredsArr_ = new Array<Array<SuperPred *>*>();
00285       constantsToSuperPredArr_ = new Array<IntArrayToSuperPredMap *>();
00286       for (int predId = 0; predId < predCnt; predId++)
00287       {
00288         constantsToSuperPredArr_->append(new IntArrayToSuperPredMap());
00289         superPredsArr_->append(new Array<SuperPred *>());
00290       }
00291       isFirstAccessForStaticVars_ = false;
00292     }
00293     else
00294     {
00295         //this is not the first time access - need to clean up
00296       Array<SuperPred *> *superPreds;
00297       IntArrayToSuperPredMap * constantsToSuperPred;
00298       IntArrayToSuperPredMap::iterator iaToSpItr;
00299       for (int predId = 0; predId < predCnt; predId++)
00300       {
00301           //first delete super preds     
00302         superPreds = (*superPredsArr_)[predId];
00303         for (int i = 0; i < superPreds->size(); i++)
00304         {
00305           delete (*superPreds)[i];
00306         }
00307 
00308           //now delete the constants
00309         Array<Array<int> *> keysArr;
00310         constantsToSuperPred = (*constantsToSuperPredArr_)[predId];
00311         keysArr.clear();
00312         for (iaToSpItr = constantsToSuperPred->begin();
00313              iaToSpItr != constantsToSuperPred->end();
00314              iaToSpItr++)
00315         {
00316           keysArr.append(iaToSpItr->first);
00317         }
00318         for (int i = 0; i < keysArr.size(); i++)
00319         {
00320           delete keysArr[i];
00321         }
00322 
00323           //reinitialize
00324         superPreds->clear();
00325         constantsToSuperPred->clear();
00326       }
00327     }
00328   }
00329 
00330   static int getSuperPredId(Array<int> * constants, int & predId)
00331   {
00332     IntArrayToSuperPredMap * constantsToSuperPred;
00333     IntArrayToSuperPredMap::iterator iaToSpItr;
00334     if (isFirstAccessForStaticVars_)
00335       return -1;
00336     assert(constantsToSuperPredArr_);
00337     constantsToSuperPred = (*constantsToSuperPredArr_)[predId];
00338     iaToSpItr = constantsToSuperPred->find(constants); 
00339     SuperPred *superPred = iaToSpItr->second;
00340     return superPred->getSuperPredId();
00341   }
00342 
00343  private:
00344   int predId_;
00345   int superPredId_;
00346   int parentSuperPredId_;
00347   Array<Array<int> *> *constantTuples_;
00348   ClauseCounter *clauseCounter_;
00349 
00350   static bool isFirstAccessForStaticVars_;
00351   static Array<IntArrayToSuperPredMap*>* constantsToSuperPredArr_;
00352   static Array<Array<SuperPred *>*>* superPredsArr_;
00353 };
00354 
00355 
00356 class HashClauseCounter
00357 {
00358  public:
00359   size_t operator()(ClauseCounter *cc) const
00360   {
00361     return cc->getHashCode();
00362   }
00363 };
00364 
00365 
00366 class EqualClauseCounter
00367 {
00368  public:
00369   bool operator()(ClauseCounter* const & cc1, ClauseCounter* const & cc2) const
00370   {
00371     bool same;
00372     const int *items1, *items2;
00373     const Array<double> *cnts1, *cnts2;
00374 
00375     int size1, size2;
00376 
00377     size1 = cc1->getNumClauses();
00378     size2 = cc2->getNumClauses();
00379 
00380     if (size1 != size2) return false;
00381 
00382       //first check if the clause ids match
00383     items1 = (cc1->getClauseIds())->getItems();
00384     items2 = (cc2->getClauseIds())->getItems();
00385 
00386     same = memcmp(items1, items2, size1*sizeof(int))==0;
00387     if (!same)
00388       return same;
00389 
00390     double epsilon = 1e-6;
00391       //now check if the clause cnts match for each of the indices 
00392       //(no need check the index sizes again - they must be same at this point)
00393     for (int index = 0; index < size1; index++)
00394     {
00395       cnts1 = cc1->getClauseCounts(index);
00396       cnts2 = cc2->getClauseCounts(index);
00397       for (int i = 0;i < cnts1->size(); i++)
00398       {
00399         if(((*cnts1)[i] + epsilon < (*cnts2)[i]) || 
00400            ((*cnts1)[i] - epsilon > (*cnts2)[i]))
00401           return false;
00402       }
00403     }
00404     return true;
00405   }
00406 };
00407 
00408 typedef hash_map<Array<int>*, PredicateConstantsInfo*, HashIntArray,
00409                  EqualIntArray> IntArrayToPredicateConstantsInfoMap;
00410 typedef hash_map<ClauseCounter*, SuperPred*, HashClauseCounter,
00411                  EqualClauseCounter> ClauseCounterToSuperPredMap;
00412 
00413 #endif

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