superclause.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 SUPERCLAUSE_H_NOV_2007
00068 #define SUPERCLAUSE_H_NOV_2007
00069 
00070 #include "util.h"
00071 #include "mrf.h"
00072 #include "array.h"
00073 #include "hashint.h"
00074 #include <ext/hash_set>
00075 #include "variable.h"
00076 
00077 using namespace std;
00078 using namespace __gnu_cxx;
00079 
00080 class SuperClause
00081 {
00082  public:
00083 
00084   SuperClause(Clause * const & clause, Array<Variable *> * const & eqVars,
00085               Array<int> * const & varIdToCanonicalVarId, bool useImplicit,
00086               double outputWt)
00087   {
00088     int parentSuperClauseId = -1;
00089     outputWt_ = outputWt;
00090     init(clause, eqVars, varIdToCanonicalVarId, useImplicit,
00091          parentSuperClauseId);
00092   }
00093 
00094   SuperClause(Clause * const & clause, Array<Variable *> * const & eqVars,
00095               Array<int> * const & varIdToCanonicalVarId, bool useImplicit,
00096               int parentSuperClauseId, double outputWt)
00097   {
00098     outputWt_ = outputWt;
00099     init(clause, eqVars, varIdToCanonicalVarId, useImplicit,
00100          parentSuperClauseId);
00101   }
00102 
00103   void init(Clause * const & clause, Array<Variable *> * const & eqVars,
00104             Array<int> * const & varIdToCanonicalVarId, bool useImplicit,
00105             int parentSuperClauseId)
00106   {
00107     clause_ = clause;
00108     constantTuples_ = new IntArrayHashArray();
00109     tupleCnts_ = new Array<double>();
00110     implicitTupleFlags_ = new Array<bool>();
00111     eqVars_ = new Array<Variable *>(*eqVars);
00112     varIdToCanonicalVarId_ = new Array<int>(*varIdToCanonicalVarId);
00113     useImplicit_ = useImplicit;
00114     superClauseId_ = superClauseIndex__++; 
00115     parentSuperClauseId_ = parentSuperClauseId;
00116   }
00117                     
00118   ~SuperClause()
00119   {
00120     delete constantTuples_;
00121     delete tupleCnts_;
00122     delete implicitTupleFlags_;
00123     delete eqVars_;
00124   }
00125           
00126   SuperClause * createSuperClauseFromTemplate()
00127   {
00128     return new SuperClause(clause_, eqVars_, varIdToCanonicalVarId_,
00129                            useImplicit_, superClauseId_, outputWt_);
00130   }
00131 
00132   int getSuperClauseId() { return superClauseId_;}
00133 
00134   int getParentSuperClauseId() { return parentSuperClauseId_;}
00135 
00136   Clause * getClause() { return clause_;}
00137 
00138   double getTupleCount(int index) {return (*tupleCnts_)[index];}
00139 
00140   int getNumTuples(){ return constantTuples_->size();}
00141 
00142   int getTupleIndex(Array<int> * const & constants)
00143   {
00144     return constantTuples_->find(constants);
00145   }
00146 
00147   Array<int> * getConstantTuple(int tindex) {return (*constantTuples_)[tindex];}
00148 
00149   Array<int> * getVarIdToCanonicalVarId() { return varIdToCanonicalVarId_;}
00150 
00151   bool isUseImplicit() { return useImplicit_;}
00152 
00153   bool checkIfImplicit(Array<int> * const & constants)
00154   {
00155     bool isImplicit = false;
00156     for (int i = 0; i < constants->size(); i++)
00157     {
00158       if ((*eqVars_)[i] == NULL)
00159         continue;
00160       if ((*eqVars_)[i]->isImplicit((*constants)[i]))
00161       {
00162         isImplicit = true;
00163         break;
00164       }
00165     }
00166     return isImplicit;
00167   }
00168 
00169     //increments the count of the given constant tuple. Assumes that
00170     //tuple is already present
00171   void incrementTupleCount(Array<int> * const & constants, double cnt)
00172   {
00173     int index = constantTuples_->find(constants);
00174     (*tupleCnts_)[index] += cnt;
00175   }
00176 
00177     //add the constant tuple - returns true if the addition was
00178     //successful i.e. if the tuple was not already present
00179   bool addConstantTuple(Array<int> * const & constants)
00180   {
00181     bool isImplicit; 
00182     int index = constantTuples_->find(constants);
00183       //this tuple does not exist already then add it
00184     if (index < 0)
00185     {
00186       constantTuples_->append(constants);
00187       tupleCnts_->append(0.0);
00188       if (useImplicit_)
00189         isImplicit = checkIfImplicit(constants);
00190       else
00191         isImplicit = false;
00192       implicitTupleFlags_->append(isImplicit);
00193       return true;
00194     }
00195     else
00196     {
00197       return false;
00198     }
00199   }
00200 
00201     //add a copy of the constants (after replacing the non existent vars by
00202     //their var ids) and increment the count. 
00203   void addNewConstantsAndIncrementCount(Array<int> * const & constants,
00204                                         double cnt)
00205   {
00206     bool addedNew = false;
00207     Array<int>* newConstants = new Array<int>(*constants);
00208       //add this constant tuple to the superclause
00209     addedNew = addConstantTuple(newConstants);   
00210     incrementTupleCount(newConstants,cnt);
00211       //delete this newly created tuple if it was already present
00212     if (!addedNew)
00213       delete newConstants;
00214   }
00215 
00216     //get the constants corresponding to this predicate in the given tuple id
00217   Array<int> * getPredicateConstants(int tindex, Predicate *pred)
00218   {
00219     bool isImplicitTuple = useImplicit_ && (*implicitTupleFlags_)[tindex];
00220     Array<Variable*> *pvars = new Array<Variable *>();
00221     Array<int> * pconstants = new Array<int>;
00222     Array<int> * constants = (*constantTuples_)[tindex];
00223     for (int i = 0; i < pred->getNumTerms(); i++)
00224     {
00225       const Term *term = pred->getTerm(i);
00226       int id = term->getId();
00227       assert(id < 0);
00228       pconstants->append((*constants)[-id]);
00229         //need to do this only if implicit representation
00230       if (isImplicitTuple)
00231         pvars->append((*eqVars_)[-id]);
00232     }
00233 
00234     if (!isImplicitTuple)
00235     {
00236       delete pvars;
00237       return pconstants;
00238     }
00239 
00240       //to make sure this is not used below
00241     constants = NULL;
00242                
00243       //now standardize the implicit constants
00244     Array<bool> *seenIds = new Array<bool>(pconstants->size(), false);
00245     IntHashArray *pconstantsForVar = new IntHashArray();
00246     for (int i = 0; i < pconstants->size(); i++)
00247     {
00248       if (!(*pvars)[i]->isImplicit((*pconstants)[i]) || (*seenIds)[i])
00249         continue;
00250       pconstantsForVar->clear();
00251       for (int j = i; j < pconstants->size(); j++)
00252       {
00253         if(!(*pvars)[j]->isImplicit((*pconstants)[j]))
00254           continue;
00255         if((*pvars)[i] != (*pvars)[j])
00256           continue;
00257         pconstantsForVar->append((*pconstants)[j]);
00258         (*seenIds)[j] = true;
00259       }
00260                    
00261       for (int j = i; j < pconstants->size(); j++)
00262       {
00263         if(!(*pvars)[j]->isImplicit((*pconstants)[j]))
00264           continue;
00265         if((*pvars)[i] != (*pvars)[j])
00266           continue;
00267         int index = pconstantsForVar->find((*pconstants)[j]);
00268         (*pconstants)[j] = (*pvars)[i]->getImplicitConstant(index);
00269       }
00270     }
00271 
00272     delete pvars;
00273     delete seenIds;
00274     delete pconstantsForVar;
00275     return pconstants;
00276   }
00277 
00278   int getImplicitCount(Array<int> * const & constants,
00279                        Array<bool> * const & relevantIds,
00280                        Array<bool> * const & predIds)
00281   {
00282     if(!useImplicit_) return 1;
00283     int cnt = 1;
00284     bool print = false;
00285     Array<bool> *seenIds = new Array<bool>(constants->size(),false);
00286     IntHashArray *constantsForVar = new IntHashArray();
00287     IntHashArray *predConstantsForVar = new IntHashArray();
00288     if (print)
00289     {
00290       cout<<"Constants : ";
00291       printArray(*constants,1,cout);
00292       cout<<endl;
00293     }
00294     for (int i = 0; i < constants->size(); i++)
00295     {
00296       if (!(*relevantIds)[i] || (*seenIds)[i])
00297         continue;
00298       constantsForVar->clear();
00299       predConstantsForVar->clear();
00300       for (int j = i; j < constants->size(); j++)
00301       {
00302         if (!(*relevantIds)[j])
00303           continue;
00304         if ((*eqVars_)[i] != (*eqVars_)[j])
00305           continue;
00306                       
00307           //take a note of this if it appears in the predicate
00308         if (predIds && (*predIds)[j])
00309           predConstantsForVar->append((*constants)[j]);
00310         constantsForVar->append((*constants)[j]);
00311         (*seenIds)[j] = true;
00312       }
00313       int numImplicitConstants = (*eqVars_)[i]->getNumImplicitConstants();
00314       int constantsForVarSize = constantsForVar->size();
00315       int predConstantsForVarSize = predConstantsForVar->size();
00316       assert(predConstantsForVarSize <= constantsForVarSize);
00317                    
00318       if (print)
00319       {
00320         cout<<"numImplicitConstants = "<<numImplicitConstants;
00321         cout<<", constantsForVarSize = "<<constantsForVarSize<<endl;
00322         cout<<", predConstantsForVarSize = "<<predConstantsForVarSize<<endl;
00323       }
00324       cnt = cnt * Util::permute(numImplicitConstants - predConstantsForVarSize,
00325                                 constantsForVarSize - predConstantsForVarSize);
00326     }
00327 
00328     delete seenIds;
00329     delete constantsForVar;
00330     delete predConstantsForVar;
00331 
00332     return cnt;
00333   }
00334 
00335     //get the count of implicit constants (partial tuples) joining with this
00336     //predicate in the given tuple 
00337   int getImplicitCountJoiningWithPred(int tindex, Predicate *pred)
00338   {
00339       //count is 1 if we are not using implicit representation
00340     bool isImplicitTuple = useImplicit_ && (*implicitTupleFlags_)[tindex];
00341     if (!isImplicitTuple)
00342       return 1;
00343 
00344     Array<int> *constants = (*constantTuples_)[tindex];
00345     Array<bool> *relevantIds = new Array<bool>(constants->size(),true);
00346 
00347     for (int i = 0; i < constants->size(); i++)
00348     {
00349       int constantId = (*constants)[i];
00350       if (!(*eqVars_)[i] || !((*eqVars_)[i]->isImplicit(constantId)))
00351       {
00352         (*relevantIds)[i] = false;
00353       }
00354     }
00355 
00356     Array<bool> *predIds = new Array<bool>(constants->size(), false);
00357       //those appearing in this predicate should also be ignored
00358       //(made irrelevant)
00359     for (int i = 0; i < pred->getNumTerms(); i++)
00360     {
00361       const Term *term = pred->getTerm(i);
00362       int id = term->getId();
00363       assert(id < 0);
00364       (*predIds)[-id] = true;
00365     }
00366 
00367     int cnt = getImplicitCount(constants, relevantIds, predIds);
00368     delete relevantIds;
00369     delete predIds;
00370     return cnt;
00371   }
00372           
00373     //get the total number of implicit tuples which are represented by the
00374     //tuple at given index
00375   int getNumImplicitTuples(int tindex)
00376   {
00377       //count is 1 if we are not using implicit representation
00378     bool isImplicitTuple = useImplicit_ && (*implicitTupleFlags_)[tindex];
00379     if (!isImplicitTuple)
00380       return 1;
00381     Array<int> *constants;
00382     constants = (*constantTuples_)[tindex];
00383     Array<bool> *relevantIds = new Array<bool>(constants->size(), true);
00384     for (int i = 0; i < constants->size(); i++)
00385     {
00386       int constantId = (*constants)[i];
00387       if (!(*eqVars_)[i] || !((*eqVars_)[i]->isImplicit(constantId)))
00388       {
00389         (*relevantIds)[i] = false;
00390       }
00391     }
00392     Array<bool> * predIds = NULL;
00393     int cnt = getImplicitCount(constants, relevantIds, predIds);
00394     delete relevantIds;
00395     return cnt;
00396   }
00397           
00398   int getNumTuplesIncludingImplicit()
00399   {
00400     int num = 0;
00401     for (int index = 0; index < constantTuples_->size(); index++)
00402     {
00403       num = num + getNumImplicitTuples(index);
00404     }
00405     return num;
00406   }
00407 
00408   double getOutputWt()
00409   {
00410     return outputWt_;
00411   }
00412 
00413   void addOutputWt(const double& outputWt)
00414   {
00415     outputWt_ += outputWt;
00416   }
00417 
00418     //print the tuples  
00419   ostream& print(ostream& out)
00420   {
00421     int beginIndex = 1;
00422     for (int i = 0; i < constantTuples_->size(); i++)
00423     {
00424       printArray(*((*constantTuples_)[i]), beginIndex, out);
00425       out << endl;
00426     }
00427     return out;
00428   }
00429 
00430     //static function
00431   void static resetIndex() { superClauseIndex__ = 0;}
00432 
00433  private:
00434   Clause* clause_;
00435   double wtScale_;
00436   IntArrayHashArray *constantTuples_;
00437   Array<bool> * implicitTupleFlags_;
00438   Array<double> * tupleCnts_;
00439   Array<Variable *> * eqVars_;
00440   Array<int> * varIdToCanonicalVarId_;
00441   bool useImplicit_;
00442   int superClauseId_;
00443   int parentSuperClauseId_;
00444   double outputWt_;
00445           
00446   static int superClauseIndex__;
00447 };
00448 
00449 //extern function defined in superpred.cpp
00450 extern void createSuperClauses(
00451                            Array<Array<SuperClause*>*>* const & superClausesArr,
00452                                Domain * const & domain);
00453 
00454 typedef hash_map<Array<int>*, SuperClause*, HashIntArray, EqualIntArray>
00455   IntArrayToSuperClause;
00456 
00457 #endif

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