predicatetemplate.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 PREDICATETEMPLATE_JUN_22_2005
00067 #define PREDICATETEMPLATE_JUN_22_2005
00068 
00069 #include <ctype.h>
00070 #include "array.h"
00071 #include <cstring>
00072 
00073 class Domain;
00074 
00075 
00076 class PredicateTemplate
00077 {
00078  public:
00079   static const char* EMPTY_NAME; // name of empty template
00080   //Internal predicate names
00081   static const char* EQUAL_NAME; // name of template representing '='
00082   static const char* GT_NAME; // name of template representing '>'
00083   static const char* LT_NAME; // name of template representing '<'
00084   static const char* GTEQ_NAME; // name of template representing '>='
00085   static const char* LTEQ_NAME; // name of template representing '<='
00086   static const char* SUBSTR_NAME; // name of template representing 'substring'
00087   static const char* ANY_TYPE_NAME;   // name of any type
00088   static const char* INT_TYPE_NAME;   // name of type representing integers
00089   static const char* STRING_TYPE_NAME;   // name of type representing strings
00090   // Start of the predicate name used for replacing functions
00091   static const char* ZZ_RETURN_PREFIX;
00092   
00093   // Internal function names
00094   static const char* SUCC_NAME; // name of template representing 'succ'
00095   static const char* PLUS_NAME; // name of template representing '+'
00096   static const char* MINUS_NAME; // name of template representing '-'
00097   static const char* TIMES_NAME; // name of template representing '*'
00098   static const char* DIVIDEDBY_NAME; // name of template representing '/'
00099   static const char* MOD_NAME; // name of template representing '%'
00100   static const char* CONCAT_NAME; // name of template representing 'concat'
00101  private:
00102   enum { NONE = 0, EQUAL_PRED = 1, EQUAL_PRED_WITH_TYPE = 2 };
00103   enum { INT_PRED = 1, INT_PRED_WITH_TYPE = 2 };
00104 
00105  public:
00106   PredicateTemplate() : id_(-1), name_(NULL), termTypesAsInt_(new Array<int>), 
00107                         termTypesAsStr_(new Array<const char*>),
00108                         termsUnique_(new Array<bool>), numGnd_(-1.0), 
00109                         uniqueVarIndexes_(new Array<int>),
00110                         equalPred_(NONE), intPred_(NONE)
00111   {}
00112   
00113   virtual ~PredicateTemplate() 
00114   { 
00115     delete [] name_;
00116     for (int i = 0; i < termTypesAsStr_->size(); i++)
00117       delete [] (*termTypesAsStr_)[i];
00118     delete termTypesAsInt_; 
00119     delete termTypesAsStr_; 
00120     delete termsUnique_;
00121     delete uniqueVarIndexes_;
00122   }
00123 
00124 
00125     // returns EQUAL_NAME append with _typeName
00126   static string createEqualPredTypeName(const char* const & typeName)
00127   {
00128     string ptName;
00129     ptName.append(PredicateTemplate::EQUAL_NAME).append("_").append(typeName);
00130     return ptName;
00131   }
00132 
00133     // returns predName append with _typeName
00134   static string createInternalPredTypeName(const char* const & predName,
00135                                                                                    const char* const & typeName)
00136   {
00137     string ptName;
00138     ptName.append(predName).append("_").append(typeName);
00139     return ptName;
00140   }
00141   
00142         // returns array with internal predicate names appended with _typeName
00143   static Array<string> createInternalPredTypeNames(const char* const & typeName)
00144   {
00145         Array<string> predTypeNames;
00146         
00147         string gtName;
00148         gtName.append(PredicateTemplate::GT_NAME).append("_").append(typeName);
00149         predTypeNames.append(gtName);
00150         
00151         string ltName;
00152         ltName.append(PredicateTemplate::LT_NAME).append("_").append(typeName);
00153         predTypeNames.append(ltName);
00154         
00155         string gteqName;
00156         gteqName.append(PredicateTemplate::GTEQ_NAME).append("_").append(typeName);
00157         predTypeNames.append(gteqName);
00158         
00159         string lteqName;
00160         lteqName.append(PredicateTemplate::LTEQ_NAME).append("_").append(typeName);
00161         predTypeNames.append(lteqName);
00162         
00163         string substrName;
00164         substrName.append(PredicateTemplate::SUBSTR_NAME).append("_").append(typeName);
00165         predTypeNames.append(substrName);
00166         
00167         return predTypeNames;
00168   }
00169 
00170   static bool isEqualPredName(const char* predName)
00171   { return (strncmp(predName, EQUAL_NAME, strlen(EQUAL_NAME))==0); }
00172 
00173   static bool isInternalPredicateTemplateName(const char* predName)
00174   { 
00175         return (strncmp(predName, GT_NAME, strlen(GT_NAME)) == 0 || 
00176                         strncmp(predName, LT_NAME, strlen(LT_NAME)) == 0 ||
00177                         strncmp(predName, GTEQ_NAME, strlen(GTEQ_NAME)) == 0 ||
00178                         strncmp(predName, LTEQ_NAME, strlen(LTEQ_NAME)) == 0 ||
00179                         strncmp(predName, SUBSTR_NAME, strlen(SUBSTR_NAME)) == 0);
00180   }
00181 
00182 
00183   bool isEqualPredicateTemplate() const 
00184   { return (equalPred_ == EQUAL_PRED || equalPred_ == EQUAL_PRED_WITH_TYPE); }
00185 
00186   bool isEmptyPredicateTemplate() const 
00187   { return (strcmp(name_, EMPTY_NAME) == 0); }
00188 
00189   bool isInternalPredicateTemplate() const 
00190   { 
00191         return (strncmp(name_, GT_NAME, strlen(GT_NAME)) == 0 || 
00192                         strncmp(name_, LT_NAME, strlen(LT_NAME)) == 0 ||
00193                         strncmp(name_, GTEQ_NAME, strlen(GTEQ_NAME)) == 0 ||
00194                         strncmp(name_, LTEQ_NAME, strlen(LTEQ_NAME)) == 0 ||
00195                         strncmp(name_, SUBSTR_NAME, strlen(SUBSTR_NAME)) == 0);
00196   }
00197 
00198   bool isInternalPredicateTemplateWithoutType() const 
00199   { 
00200         return (strcmp(name_, GT_NAME) == 0 || 
00201                         strcmp(name_, LT_NAME) == 0 ||
00202                         strcmp(name_, GTEQ_NAME) == 0 ||
00203                         strcmp(name_, LTEQ_NAME) == 0 ||
00204                         strcmp(name_, SUBSTR_NAME) == 0);
00205   }
00206 
00207   bool isPredicateTemplateFromInternalFunction() const
00208   {
00209         return (strcmp(name_, string(ZZ_RETURN_PREFIX).append(string(SUCC_NAME)).c_str()) == 0 ||
00210                         strcmp(name_, string(ZZ_RETURN_PREFIX).append(string(PLUS_NAME)).c_str()) == 0 ||
00211                         strcmp(name_, string(ZZ_RETURN_PREFIX).append(string(MINUS_NAME)).c_str()) == 0 ||
00212                         strcmp(name_, string(ZZ_RETURN_PREFIX).append(string(TIMES_NAME)).c_str()) == 0 ||
00213                         strcmp(name_, string(ZZ_RETURN_PREFIX).append(string(DIVIDEDBY_NAME)).c_str()) == 0 ||
00214                         strcmp(name_, string(ZZ_RETURN_PREFIX).append(string(MOD_NAME)).c_str()) == 0 ||
00215                         strcmp(name_, string(ZZ_RETURN_PREFIX).append(string(CONCAT_NAME)).c_str()) == 0);
00216   }
00217   
00218   bool isPredicateTemplateFromFunction() const
00219   {
00220         if (strlen(name_) > strlen(ZZ_RETURN_PREFIX))
00221           return (strncmp(name_, ZZ_RETURN_PREFIX, strlen(ZZ_RETURN_PREFIX)) == 0);
00222         return false;
00223   }
00224   
00225   static string translateEqualPredicateName(const string& eqPredName)
00226   {
00227     if (strncmp(eqPredName.c_str(), "same", 4) != 0) return "";
00228     string typeStr = eqPredName.substr(4, eqPredName.length()-4);
00229     string newName = PredicateTemplate::EQUAL_NAME;
00230     newName.append("_").append(typeStr);
00231     return newName;
00232   }
00233 
00234 
00235   void setId(const int& id)  { id_ = id; }
00236 
00237   int getId() const { return id_; }
00238 
00239 
00240     // Caller is responsible for deleting name if required.
00241   void setName(const char* const & name) 
00242   { 
00243     if (name_) delete [] name_;
00244     name_ = new char[strlen(name)+1]; 
00245     strcpy(name_, name);
00246 
00247     unsigned int len = strlen(EQUAL_NAME);
00248     if (strncmp(name_, EQUAL_NAME, len)==0 && strlen(name_) > len)
00249       equalPred_ = EQUAL_PRED_WITH_TYPE;
00250     else
00251     if (strncmp(name_,EQUAL_NAME, len)==0) 
00252       equalPred_ = EQUAL_PRED;
00253     else 
00254       equalPred_ = NONE;
00255   }
00256 
00257   
00258   bool isEqualPred() const 
00259   { return (equalPred_ == EQUAL_PRED || equalPred_ == EQUAL_PRED_WITH_TYPE); }
00260 
00261 
00262   bool isEqualPredWithType() const
00263   { return (equalPred_ == EQUAL_PRED_WITH_TYPE); }
00264 
00265     // Caller should not delete returned const char*.
00266   const char* const getName() const { return name_; }
00267 
00268 
00269   int getNumTerms() const 
00270   {
00271     assert(termTypesAsStr_->size() == termTypesAsInt_->size());
00272     return termTypesAsInt_->size(); 
00273   }
00274 
00275 
00276     // Caller is responsible for deleting typeName if required.
00277     // returns true if termType is successfully added; false otherwise
00278   bool appendTermType(const char* const & typeName, const bool& isUnique,
00279                       const Domain* const & domain);
00280 
00281     // returns true if termType is successfully added; false otherwise
00282   bool appendTermType(const int& typeId, const bool& isUnique, 
00283                       const Domain* const & domain);
00284                       
00285 
00286     // Caller should not delete the returned Array<const char&>* nor modify its
00287     // contents.
00288   const Array<const char*>* getTermTypesAsStr() const 
00289   { return termTypesAsStr_; }
00290 
00291 
00292     // Caller should not delete the returned const char* nor modify its
00293     // contents.
00294   const char* getTermTypeAsStr(const int& idx) const 
00295   { return (*termTypesAsStr_)[idx]; }
00296 
00297 
00298     // Caller should not delete the returned Array<int>* nor modify its
00299     // contents.
00300   const Array<int>* getTermTypesAsInt() const 
00301   { return termTypesAsInt_; }
00302 
00303 
00304   int getTermTypeAsInt(const int& idx) const 
00305   { return (*termTypesAsInt_)[idx]; }
00306   
00307 
00308     // Caller should not delete the returned Array<bool>* nor modify its
00309     // contents.
00310   const Array<bool>* getTermsUnique() const { return termsUnique_; }
00311 
00312 
00313   const bool termIsUnique(const int& idx) const 
00314   { return (*termsUnique_)[idx]; }
00315 
00316     // Caller should not delete the returned Array<bool>* nor modify its
00317     // contents.
00318   const Array<int>* getUniqueVarIndexes() const { return uniqueVarIndexes_; }
00319 
00325   void addUniqueVarIndex(const int& idx) const 
00326   {
00327     assert(idx < getNumTerms());
00328     uniqueVarIndexes_->append(idx);
00329   }
00330 
00331   virtual ostream& print(ostream& out) const
00332   {
00333     out << name_ << "(";
00334     for (int i = 0; i < termTypesAsStr_->size(); i++)
00335     {
00336       out << (*termTypesAsStr_)[i];
00337       if (uniqueVarIndexes_->contains(i))
00338         out << "!";
00339       out << ((i!=termTypesAsStr_->size()-1)?",":")");
00340     }
00341     return out;
00342   }
00343 
00344 
00345   virtual ostream& printWithStrVar(ostream& out) const
00346   {
00347     out << name_;
00348       // If dealing with a propositional variable
00349     if (strcmp(getTermTypeAsStr(0), "AlchemyPropositionalType") == 0)
00350     {
00351       return out;
00352     }
00353     
00354     out << "(";
00355     for (int i = 0; i < termTypesAsStr_->size(); i++)
00356     {
00357       out << "a" << i+1; 
00358       if (uniqueVarIndexes_->contains(i))
00359         out << "!";
00360       out << ((i != termTypesAsStr_->size() - 1) ? "," : ")");
00361     }
00362     return out;
00363   }
00364 
00365 
00366  protected:
00367   int id_;     // id of predicate
00368   char* name_; // name of predicate
00369   Array<int>* termTypesAsInt_;
00370   Array<const char*>* termTypesAsStr_;
00371   Array<bool>* termsUnique_;
00372   double numGnd_;
00373     // Indices of blocked variables
00374   Array<int>* uniqueVarIndexes_;
00375   
00376  private:
00377   int equalPred_;
00378   int intPred_;
00379 };
00380 
00381 
00382 inline
00383 ostream& operator<<(ostream& o, const PredicateTemplate& p) {return p.print(o);}
00384 
00385 
00386 #endif

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