predicate.cpp

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 #include "predicate.h"
00067 #include "clause.h"
00068 #include "groundpredicate.h"
00069 
00070 double Predicate::fixedSizeB_ = -1;
00071 
00072 
00073 void Predicate::setDirty() { dirty_ = true; if (parent_) parent_->setDirty(); }
00074 
00075 
00076 void Predicate::setParentDirty() { if (parent_) parent_->setDirty(); }
00077 
00078 
00079 bool Predicate::canBeGroundedAs(const GroundPredicate* const & gndPred)
00080 {
00081   if ( ((unsigned int) template_->getId()) != gndPred->getId()) return false;
00082   if (allTermsAreDiffVars()) return true;
00083     
00084   int varGndings[MAX_VAR];
00085   memset(varGndings, -1, MAX_VAR*sizeof(int));
00086   for (int i = 0; i < terms_->size(); i++) 
00087   {
00088     int termType = (*terms_)[i]->getType();
00089       
00090     if (termType == Term::CONSTANT) 
00091     {
00092       assert((*terms_)[i]->getId() >= 0);
00093       if ( ((unsigned int) (*terms_)[i]->getId()) != gndPred->getTermId(i)) 
00094         return false;
00095     }
00096     else 
00097     if (termType == Term::VARIABLE) 
00098     {
00099       int varId = -(*terms_)[i]->getId();
00100       assert(varId > 0);
00101       assert(varId < MAX_VAR);
00102       if (varGndings[varId] < 0) // if variable has not been grounded
00103         varGndings[varId] = gndPred->getTermId(i);
00104       else 
00105       if (varGndings[varId] != (int) gndPred->getTermId(i))
00106         return false;
00107     }
00108     else
00109     {
00110       assert(false);
00111     }
00112   }
00113   return true;
00114 }
00115 
00116   //Does not consider the sense of the predicate.
00117 bool Predicate::same(const GroundPredicate* const & gp)
00118 {
00119   if ( getId() != (int) gp->getId() ) return false;
00120   if ( terms_->size() != (int) gp->getNumTerms() ) return false;
00121   for (int i = 0; i < terms_->size(); i++)
00122     if ( (*terms_)[i]->getId() != (int) gp->getTermId(i) ) return false;
00123   return true;
00124 }
00125 
00126 double 
00127 Predicate::getNumGroundingsIfAllVarDiff(const Domain* const & domain) const
00128 { 
00129   int numGnd = 1;
00130   for (int i = 0; i < template_->getNumTerms(); i++)
00131     numGnd *= domain->getNumConstantsByType(template_->getTermTypeAsInt(i));
00132   return numGnd;
00133 }
00134 
00135     //Caller is responsible for deleting the Predicate* in returnArray
00136 void Predicate::createAllGroundings(const int& predId, 
00137                                     const Domain* const & domain,
00138                                     Array<Predicate*>& returnArray)
00139 {
00140   const PredicateTemplate* pt = domain->getPredicateTemplate(predId);
00141   if (pt == NULL)
00142   {
00143     cout << "ERROR in Predicate::createAllGroundings: no predicate with id " 
00144          << predId << " in domain" << endl;
00145     return;
00146   }
00147   if (pt->isEqualPredicateTemplate())
00148   {
00149     cout << "ERROR in Predicate::createAllGroundings: cannot create " 
00150          << "groundings for '=' predicate" << endl;
00151     return;      
00152   }
00153   
00154   ArraysAccessor<int> acc;
00155   for (int i = 0; i < pt->getNumTerms(); i++)
00156   {
00157     int typeId = pt->getTermTypeAsInt(i);
00158     assert(typeId >= 0);
00159     const Array<int>* constArr = domain->getConstantsByType(typeId);
00160     assert(constArr->size() > 0);
00161     acc.appendArray(constArr);
00162   }
00163   
00164   
00165   while (acc.hasNextCombination())
00166   {
00167     Predicate* pred = new Predicate(pt);
00168     int constId;
00169     while (acc.nextItemInCombination(constId))
00170       pred->appendTerm(new Term(constId, (void*)pred, true));
00171     returnArray.append(pred);
00172     
00173   }
00174 }
00175 
00176 //get all the groundings unifying with the term given 
00177 //Caller is responsible for deleting the Predicate* in returnArray
00178 void Predicate::createAllGroundingsUnifyingWithTerm(const int& predId, 
00179                                     const Domain* const & domain,
00180                                     Array<Predicate*>& returnArray,
00181                                                                         int termTypeId,int termConstId)
00182 {
00183   Array<int> tmpArr;
00184   const PredicateTemplate* pt = domain->getPredicateTemplate(predId);
00185   if (pt == NULL)
00186   {
00187     cout << "ERROR in Predicate::createAllGroundings: no predicate with id " 
00188          << predId << " in domain" << endl;
00189     return;
00190   }
00191   if (pt->isEqualPredicateTemplate())
00192   {
00193     cout << "ERROR in Predicate::createAllGroundings: cannot create " 
00194          << "groundings for '=' predicate" << endl;
00195     return;      
00196   }
00197   
00198   ArraysAccessor<int> acc;
00199   for (int i = 0; i < pt->getNumTerms(); i++)
00200   {
00201     int typeId = pt->getTermTypeAsInt(i);
00202     assert(typeId >= 0);
00203         const Array<int>* constArr;
00204     if(typeId != termTypeId) {
00205          constArr = domain->getConstantsByType(typeId);
00206         } else {
00207          tmpArr.clear();
00208          tmpArr.append(termConstId);
00209          constArr = &tmpArr;
00210         }
00211         assert(constArr->size() > 0);
00212         acc.appendArray(constArr);
00213   }
00214   
00215   while (acc.hasNextCombination())
00216   {
00217     Predicate* pred = new Predicate(pt);
00218     int constId;
00219     while (acc.nextItemInCombination(constId))
00220       pred->appendTerm(new Term(constId, (void*)pred, true));
00221     returnArray.append(pred);
00222     
00223   }
00224 }
00225 
00226 
00227   //exactly one of  predReturnArray or constReturnArray must be NULL;
00228 void Predicate::createAllGroundings(const Domain* const & domain,
00229                                     Array<Predicate*>* const & predReturnArray,
00230                                     Array<int*>* const & constReturnArray)
00231 {
00232   assert(predReturnArray == NULL || constReturnArray == NULL);
00233 
00234   if (isGrounded())
00235   {
00236     if (predReturnArray)
00237       predReturnArray->append(new Predicate(*this));
00238     else
00239     {
00240       assert(constReturnArray);
00241       int* constArr = new int[terms_->size()];
00242       for (int j = 0; j < terms_->size(); j++) 
00243       {
00244         constArr[j] = (*terms_)[j]->getId();
00245         assert(constArr[j] >= 0);
00246       }
00247       constReturnArray->append(constArr);
00248     }
00249     return;
00250   }
00251 
00252 
00253   Array<VarsGroundedType*> vgtArr;
00254   for (int i = 0; i < terms_->size(); i++)
00255   {
00256     const Term* t = (*terms_)[i];
00257     if (t->getType() == Term::VARIABLE)
00258     {
00259       int id = -(t->getId());
00260       assert(id > 0);
00261       if (id >= vgtArr.size()) vgtArr.growToSize(id+1,NULL);
00262       VarsGroundedType*& vgt = vgtArr[id];
00263       if (vgt == NULL) 
00264       {
00265         vgt = new VarsGroundedType; 
00266         vgt->typeId = getTermTypeAsInt(i);
00267         assert(vgt->typeId >= 0);        
00268       }
00269       assert(getTermTypeAsInt(i) == vgt->typeId);
00270       vgt->vars.append((Term*)t);
00271     }
00272   }
00273 
00274   Array<int> negVarId; 
00275   ArraysAccessor<int> acc;
00276   for (int i = 0; i < vgtArr.size(); i++)
00277   {
00278     if (vgtArr[i] == NULL) continue;
00279     negVarId.append(i);
00280     acc.appendArray(domain->getConstantsByType(vgtArr[i]->typeId));
00281   }
00282 
00283   while (acc.hasNextCombination())
00284   {
00285     int i = 0;
00286     int constId;
00287     while (acc.nextItemInCombination(constId))
00288     {
00289       Array<Term*>& vars = vgtArr[ negVarId[i] ]->vars;
00290       for (int j = 0; j < vars.size(); j++) vars[j]->setId(constId);
00291       i++;
00292     }
00293     
00294     if (predReturnArray) 
00295       predReturnArray->append(new Predicate(*this));
00296     else
00297     {
00298       assert(constReturnArray);
00299       int* constArr = new int[terms_->size()];
00300       for (int j = 0; j < terms_->size(); j++) 
00301       {
00302         constArr[j] = (*terms_)[j]->getId();
00303         assert(constArr[j] >= 0);
00304       }
00305       constReturnArray->append(constArr);
00306     }
00307   }
00308 
00309     //restore
00310   for (int i = 0; i < vgtArr.size(); i++) 
00311   {
00312     if (vgtArr[i] == NULL) continue;
00313     Array<Term*>& vars  = vgtArr[i]->vars;
00314     for (int j = 0; j < vars.size(); j++) vars[j]->setId(-i);
00315     delete vgtArr[i];
00316   }  
00317 }

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