truefalsegroundingsstore.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 and Hoifung Poon.
00006  * 
00007  * Copyright [2004-07] Stanley Kok, Parag Singla, Matthew
00008  * Richardson, Pedro Domingos, Marc Sumner and Hoifung
00009  * Poon. 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 and Hoifung
00032  * Poon 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 TRUEFALSEGROUNDINGSSTORE_H_NOV_16_2005
00067 #define TRUEFALSEGROUNDINGSSTORE_H_NOV_16_2005
00068 
00069 #include <ext/hash_map>
00070 using namespace __gnu_cxx;
00071 #include "random.h"
00072 #include "domain.h"
00073 
00074 
00075 struct TrueFalseGndings 
00076 {
00077   TrueFalseGndings() {}
00078   ~TrueFalseGndings() 
00079   {
00080     for (int i = 0; i < trueGndings.size(); i++) delete [] trueGndings[i];
00081     for (int i = 0; i < falseGndings.size(); i++) delete [] falseGndings[i];
00082   }
00083 
00084   Array<int*> trueGndings; 
00085   Array<int*> falseGndings; 
00086 };
00087 
00088 
00089 typedef hash_map<Predicate*, TrueFalseGndings*, HashPredicate,EqualPredicate>
00090   PredToGndingsMap;
00091 
00092 
00093 
00094 class TrueFalseGroundingsStore
00095 {
00096  public:
00097   TrueFalseGroundingsStore(const Domain* const & domain) : domain_(domain) 
00098   {
00099     predToGndingsMaps_.growToSize(domain_->getNumPredicates(), NULL);
00100     random_.init(-1);
00101   }
00102 
00103 
00104   ~TrueFalseGroundingsStore() 
00105   {
00106     for (int i = 0; i < predToGndingsMaps_.size(); i++)
00107     {
00108       PredToGndingsMap* ptgMap = predToGndingsMaps_[i];
00109       if (ptgMap == NULL) continue;
00110       Array<Predicate*> toBeDeleted;      
00111       for (PredToGndingsMap::iterator it=ptgMap->begin();it!=ptgMap->end();it++)
00112       {
00113         toBeDeleted.append((*it).first);
00114         delete (*it).second;
00115       }
00116       delete ptgMap;
00117       toBeDeleted.deleteItemsAndClear();
00118     }
00119   }
00120 
00121 
00122     //Caller is responsible for deleting returned predicate
00123   int getNumTrueLiteralGroundings(const Predicate* const & pred,
00124                                   const Predicate* const & flippedGndPred)
00125   {
00126     if (((Predicate*)pred)->isGrounded())
00127     {
00128       TruthValue tv = domain_->getDB()->getValue(pred);
00129       if (Database::sameTruthValueAndSense(tv, pred->getSense())) return 1;
00130       return 0;
00131     }
00132 
00133     TrueFalseGndings* tfGndings = getTrueFalseGndings(pred, flippedGndPred);
00134     bool sense = pred->getSense();
00135     int n = (sense) ?  tfGndings->trueGndings.size() 
00136                      : tfGndings->falseGndings.size();
00137 
00138       // check whether flippedGndPred should be included in numGndings
00139     if (flippedGndPred && 
00140         ((Predicate*)pred)->canBeGroundedAs((Predicate*)flippedGndPred))
00141     {
00142       TruthValue flippedtv = domain_->getDB()->getValue(flippedGndPred);
00143       TruthValue tv = FALSE;
00144       if (flippedtv == TRUE)       tv = FALSE;
00145       else if (flippedtv == FALSE) tv = TRUE;
00146       else assert(false);
00147       if (Database::sameTruthValueAndSense(tv, pred->getSense())) n--;
00148     }
00149     return n;
00150   }
00151 
00152 
00153     //Caller is responsible for deleting returned predicate and the input params
00154   Predicate* getRandomTrueLiteralGrounding(const Predicate* const & pred,
00155                                            const Predicate* const & flippedPred)
00156   {
00157     if (((Predicate*)pred)->isGrounded())
00158     {
00159       TruthValue tv = domain_->getDB()->getValue(pred);
00160       if (Database::sameTruthValueAndSense(tv, pred->getSense())) 
00161         return new Predicate(*pred);
00162       return NULL;
00163     }
00164 
00165 
00166     TrueFalseGndings* tfGndings = getTrueFalseGndings(pred, flippedPred);
00167     Predicate* randPred = new Predicate(*pred);
00168 
00169     bool sense = pred->getSense();
00170     bool firstTry = true;
00171     if (sense)
00172     {
00173       int numGndings = tfGndings->trueGndings.size();
00174       while (firstTry || 
00175              (flippedPred && randPred->same((Predicate*)flippedPred)))
00176       {
00177         firstTry = false;
00178         int* constIds=tfGndings->trueGndings[ random_.randomOneOf(numGndings) ];
00179         for (int i = 0; i < randPred->getNumTerms(); i++)
00180           ((Term*)randPred->getTerm(i))->setId( constIds[i] );
00181       }
00182       return randPred;
00183     }
00184     else       
00185     {
00186       int numGndings = tfGndings->falseGndings.size();
00187       while (firstTry || 
00188              (flippedPred && randPred->same((Predicate*)flippedPred)))
00189       {
00190         firstTry = false;
00191         int* constIds=tfGndings->falseGndings[ random_.randomOneOf(numGndings)];
00192         for (int i = 0; i < randPred->getNumTerms(); i++)
00193           ((Term*)randPred->getTerm(i))->setId( constIds[i] );
00194       }
00195       return randPred;
00196     }
00197   }
00198 
00199 
00200  private:
00201   void fillInTrueFalseGndings(const Predicate* const & pred, 
00202                               TrueFalseGndings* const & tfGndings,
00203                               const Predicate* const & flippedPred)
00204   {
00205     bool flip = false;
00206     if (flippedPred && 
00207         ((Predicate*)pred)->canBeGroundedAs((Predicate*)flippedPred))
00208     { flip = true; domain_->getDB()->flipValue((Predicate*)flippedPred); }
00209 
00210     Predicate* tmpPred = new Predicate(*pred);
00211     Array<int*> constArrays;
00212     tmpPred->createAllGroundings(domain_, constArrays);
00213     for (int i = 0; i < constArrays.size(); i++)
00214     {
00215       int* constIds = constArrays[i];
00216       for (int j = 0; j < tmpPred->getNumTerms(); j++)
00217         ((Term*)tmpPred->getTerm(j))->setId(constIds[j]);
00218 
00219       TruthValue tv = domain_->getDB()->getValue(tmpPred); 
00220       if (tv == TRUE) tfGndings->trueGndings.append(constIds);
00221       else if (tv == FALSE) tfGndings->falseGndings.append(constIds);
00222     }
00223     tfGndings->trueGndings.compress();
00224     tfGndings->falseGndings.compress();
00225     delete tmpPred;
00226 
00227     if (flip) domain_->getDB()->flipValue((Predicate*)flippedPred);
00228   }
00229 
00230 
00231     //Caller is responsible for deleting pred
00232   TrueFalseGndings* newEntryInPredToGndingsMaps(const Predicate* const & pred,
00233                                          const Predicate* const & flippedPred)
00234   {
00235     PredToGndingsMap* ptgMap = predToGndingsMaps_[pred->getId()];
00236     TrueFalseGndings* tfGndings = new TrueFalseGndings;
00237     Predicate* newPred = new Predicate(*pred);
00238     (*ptgMap)[newPred] = tfGndings;
00239     fillInTrueFalseGndings(newPred, tfGndings, flippedPred);
00240     return tfGndings;
00241   }
00242 
00243 
00244   TrueFalseGndings* getTrueFalseGndings(const Predicate* const & pred,
00245                                         const Predicate* const & flippedPred)
00246   {
00247     int predId = pred->getId();
00248     if (predToGndingsMaps_[predId] == NULL) 
00249       predToGndingsMaps_[predId] = new PredToGndingsMap;
00250     PredToGndingsMap* ptgMap = predToGndingsMaps_[predId];
00251 
00252     PredToGndingsMap::iterator it;
00253     if ((it=ptgMap->find((Predicate*)pred)) == ptgMap->end())
00254       return newEntryInPredToGndingsMaps(pred, flippedPred);
00255     return (*it).second;
00256   }
00257 
00258   
00259  private:
00260   const Domain* domain_; // not owned by TrueFalseGroundingsStore; don't delete
00261 
00262     //PredToGndingsMaps[p] is the PredToGndingsMap of predicate with id p
00263   Array<PredToGndingsMap*> predToGndingsMaps_;
00264   Random random_;
00265 
00266 };
00267 
00268 #endif

Generated on Tue Jan 16 05:30:04 2007 for Alchemy by  doxygen 1.5.1