folhelper.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 FOLHELPER_H_JUL_21_2005
00068 #define FOLHELPER_H_JUN_21_2005
00069 
00070 // dl library used for dynamically loading linked-in functions
00071 #include <dlfcn.h>
00072 #include <stdio.h>
00073 #include <stdlib.h>
00074 #include <assert.h>
00075 #include <signal.h>
00076 #include <ext/hash_set>
00077 #include <stack>
00078 #include <iostream>
00079 #include <fstream>
00080 #include <sstream>
00081 #include "strfifolist.h"
00082 #include "predicate.h"
00083 #include "function.h"
00084 #include "clause.h"
00085 #include "clausefactory.h"
00086 #include "hashstring.h"
00087 #include "database.h"
00088 #include "listobj.h"
00089 #include "timer.h"
00090 #include "internals.h"
00091 
00092 //NOTE: When a variable is added, please init it in zzinit() and destroy it 
00093 //      in zzcleanUp(). Add it in zzreset() if it has to be reinitialized before
00094 //      a new clause is parsed.
00095 
00096 
00097   //Each hard clause derived from a hard formula is given a weight that is twice
00098   //that of the maximum soft clause weight. You can change this value by setting
00099   //HARD_WEIGHT_MULTIPLIER below. If you wish to set the hard clause weight to
00100   //a specific value, you can set HARD_WEIGHT below. 
00101   //If HARD_WEIGHT is DBL_MIN, HARD_WEIGHT_MULTIPLIER is used instead of 
00102   //HARD_WEIGHT; otherwise the latter is used.
00103 const double HARD_WEIGHT_MULTIPLIER = 200000;
00104 const double HARD_WEIGHT = DBL_MIN;
00105 
00106   // If the variables are assigned some initial values, ensure they are are
00107   // similarly assigned in zzinit(). Also set any data structure to its initial 
00108   // state in zzinit()
00109 const int ZZ_MAX_ERRORS = 50;
00110 
00111 // Start of variable names generated by replacement of functions
00112 const char* ZZ_FUNCVAR_PREFIX = "funcVar";
00113 
00114 // Name of shared object file for linked-in functions
00115 const char* ZZ_FUNCTION_SO_FILE = "functions.so";
00116 
00117   // a copy of the user-specified MLN file is created & appended with this str
00118 const char* ZZ_TMP_FILE_POSTFIX = "_tmpalchemy.mln";
00119 
00120   // prepend to a file containing query predicates
00121 const char* zzdefaultPredName = "SKPRED";
00122 const char* zzdefaultFuncName = "SKFUNC";
00123 const char* zzdefaultTypeName = "SKTYPE";
00124 const char* zzdefaultVarName  = "SKVAR";
00125 
00126 bool zzstoreGroundPreds = false; //set to true for testing only
00127   //constants must be declared before being used
00128 bool zzconstantMustBeDeclared = false;
00129   // read weight that is specified for a hard formula
00130 bool zzreadHardClauseWts = false;
00131   //used in follex.y to allow predicate definitions to be on the same line
00132 bool zzafterRtParen;
00133 
00134 bool zzisParsing; //indicates whether a file is currently being parsed
00135 double zzdefaultWt; // default wt of a formula if no wt or . is specified
00136   //a formula must begin with a weight or end with full stop
00137 bool zzmustHaveWtOrFullStop;
00138   // indicates whether weights should be flipped when a clause is flipped.
00139   // This should be true for inference and false for learning.
00140 bool zzflipWtsOfFlippedClause;
00141 bool zzwarnDuplicates;
00142 string zzinFileName;
00143 char zzerrMsg[1024];
00144 
00145 int zzcount;  // to be appended to names of default pred, type etc.
00146 int zzline, zzcolumn;
00147 int zznumCharRead;
00148 int zznumErrors;
00149 bool zzok;
00150 MLN* zzmln;
00151 Domain* zzdomain;
00152 int zznumEofSeen; // num of times EOF seen
00153 StrFifoList zztokenList;
00154 
00155 char* zztypeName;
00156 PredicateTemplate* zzpredTemplate;
00157 FunctionTemplate* zzfuncTemplate;
00158 Predicate* zzpred;
00159 Function* zzfunc;
00160 stack<Function*> zzfuncStack;
00161 stack<ListObj*> zzfuncConjStack;
00162 double* zzwt;
00163 bool zzisNegated;
00164 bool zzisAsterisk;
00165 bool zzisPlus;
00166 bool zzhasFullStop;
00167 bool zzinIndivisible;
00168 int zznumAsterisk;
00169 char zztrueFalseUnknown;
00170 string zzformulaStr;
00171 string zzfuncConjStr;
00172 bool zzparseGroundPred;
00173 stack<ListObj*> zzformulaListObjs;  //used by formulas with connectives
00174 stack<ListObj*> zzpredFuncListObjs; // used by predicates and functions
00175 hash_map<int, PredicateHashArray*> zzpredIdToGndPredMap;
00176 
00177 // Used to check if there is a function definition
00178 int zzfdnumPreds;
00179 int zzfdnumFuncs;
00180 int zzfdnumVars;
00181 int zzfuncVarCounter = 0;
00182 //bool zzfdisEqualPred;
00183 string zzfdfuncName;
00184 Array<string> zzfdfuncConstants;
00185 string zzfdconstName;
00186 // Used in function definitions to store the return value and type
00187 char* zztmpReturnConstant;
00188 bool zztmpReturnNum;
00189 
00190 // Used to store first number in numeric declarations
00191 int zzinitialNumDeclaration;
00192 
00193 // Set to true if using linked-in predicates
00194 bool zzusingLinkedPredicates;
00195 // Set to true if using linked-in functions
00196 bool zzusingLinkedFunctions;
00197 
00198 // Needed to hold list object information while function is replaced
00199 ListObj* zzoldFuncLo; 
00200 Timer zztimer;
00201 
00202 // Holds the internally implemented predicates and their types (see zzinit())
00203 Array<Array<const char*> > zzinternalPredicates;
00204 // Holds the internally implemented functions and their types (see zzinit())
00205 Array<Array<const char*> > zzinternalFunctions;
00206 
00207 // If an infix predicate is encountered then the name of it is stored here
00208 char* zzinfixPredName;
00209 // If an infix function is encountered then the name of it is stored here
00210 char* zzinfixFuncName;
00211 
00213 struct ZZUnknownEqPredInfo
00214 {
00215   ZZUnknownEqPredInfo(const string& name, const string& lhs, const string& rhs)
00216     :name_(name), lhs_(lhs), rhs_(rhs) {}
00217 
00218   string name_; //e.g. SK_EQUAL_1
00219     // variable name on left and right hand side  
00220   string lhs_;
00221   string rhs_; 
00222 };
00223 
00225 struct ZZUnknownIntPredInfo
00226 {
00227   ZZUnknownIntPredInfo(const string& name, const string& lhs, const string& rhs)
00228     :name_(name), lhs_(lhs), rhs_(rhs) {}
00229 
00230   string name_; //e.g. greaterThan_1
00231     // variable name on left and right hand side  
00232   string lhs_;
00233   string rhs_; 
00234 };
00235 
00237 struct ZZUnknownIntFuncInfo
00238 {
00239   ZZUnknownIntFuncInfo(const string& name, const Array<string>& vnames)
00240     :name_(name), vnames_(vnames) {}
00241 
00242   string name_; //e.g. plus_1
00243     // variable names
00244   Array<string> vnames_;
00245 };
00246 
00247   // counts the number of '=' predicates for which both LHS and RHS are unknown
00248 int zzeqTypeCounter; 
00249   // counts the number of internal predicates for which both LHS and RHS are
00250   // unknown
00251 int zzintPredTypeCounter; 
00252   // counts the number of internal functions for which at least one term type is
00253   // unknown
00254 int zzintFuncTypeCounter; 
00255 
00256   // list of '=' predicates for which both LHS and RHS are unknown
00257 list<ZZUnknownEqPredInfo> zzeqPredList;
00258   // list of internal predicates for which both LHS and RHS are unknown
00259 list<ZZUnknownIntPredInfo> zzintPredList;
00260   // list of internal functions for which at least one term type is unknown
00261 list<ZZUnknownIntFuncInfo> zzintFuncList;
00262 
00263   
00265 
00266 struct ZZFileState
00267 {
00268   ZZFileState(FILE* const & file, const string& inFileName, 
00269               const int& numCharRead, const int& line, const int& column) 
00270     : file_(file), inFileName_(inFileName), numCharRead_(numCharRead), 
00271       line_(line), column_(column) {}
00272 
00273   FILE* file_;
00274   string inFileName_;
00275   int numCharRead_;
00276   int line_;
00277   int column_;
00278 };
00279 
00280 stack<ZZFileState> zzinStack; 
00281 
00283 
00284 int zzvarCounter;
00285 int zzanyTypeId;
00286 
00287 struct ZZVarIdType
00288 {
00289   ZZVarIdType() : id_(0), typeId_(0) {}
00290 
00291   ZZVarIdType(const ZZVarIdType& varIdType)
00292     : id_(varIdType.id_), typeId_(varIdType.typeId_) {}
00293  
00294   ZZVarIdType(const int& varId, const int& typeId) 
00295     : id_(varId), typeId_(typeId) {}
00296 
00297   int id_;
00298   int typeId_;
00299 };
00300 
00301 
00302   // contains variables names
00303 typedef hash_map<const string, ZZVarIdType, HashString, EqualString> 
00304   ZZVarNameToIdMap;
00305 
00306 ZZVarNameToIdMap zzvarNameToIdMap;
00307 
00308   // contains mappings of functions to funcVars which replace them
00309 typedef hash_map<Function*, string, HashFunction, EqualFunction> 
00310   ZZFuncToFuncVarMap;
00311   
00312 ZZFuncToFuncVarMap zzfuncToFuncVarMap;
00313 
00314 
00315   // maps a variable name to a new one that has its scope number appended
00316 typedef hash_map<string, string, HashString, EqualString> StringToStringMap;
00317 
00318 int zzscopeCounter; // identifies a scope
00319 
00320   // using a list so that we can iterate through the elements in the stack
00321   // the front and back correspond to the the top and bottom of a stack
00322 typedef list< pair<StringToStringMap*,int> > ZZOldNewVarList;
00323 ZZOldNewVarList zzoldNewVarList;
00324 
00325 
00326   // since plus variables e.g. x in P(+x,y) cannot be explicitly 
00327   // universally/existentially quantified, they must exist within the scope of
00328   // the entire formula
00329 typedef hash_map<string, int, HashString, EqualString> StringToIntMap;
00330 StringToIntMap zzplusVarMap;
00331 
00332 
00334 struct ZZFormulaInfo
00335 {
00336   ZZFormulaInfo(const ListObj* const & fformula, const string& fformulaStr,
00337                 const int& nnumPreds, const double* const & wwt, 
00338                 const double& ddefaultWt, const Domain* const& ddomain, 
00339                 MLN* const & mmln, const ZZVarNameToIdMap& vvarNameToIdMap,
00340                 const StringToIntMap& pplusVarMap, const int& nnumAsterisk,
00341                 const bool& hhasFullStop, 
00342                 const bool& rreadHardClauseWts,
00343                 const bool& mmustHaveWtOrFullStop,
00344                 const bool& iisIndivisible)
00345     : formula(fformula), formulaStr(fformulaStr), numPreds(nnumPreds), 
00346       defaultWt(ddefaultWt), domain(ddomain), mln(mmln), 
00347       numAsterisk(nnumAsterisk), hasFullStop(hhasFullStop), 
00348       readHardClauseWts(rreadHardClauseWts),
00349       mustHaveWtOrFullStop(mmustHaveWtOrFullStop),
00350       isIndivisible(iisIndivisible)
00351   {
00352     wt = (wwt) ? new double(*wwt) : NULL;
00353     
00354     ZZVarNameToIdMap::const_iterator it = vvarNameToIdMap.begin();
00355     for (; it != vvarNameToIdMap.end(); it++)
00356       varNameToIdMap[(*it).first] = ZZVarIdType((*it).second);
00357 
00358     StringToIntMap::const_iterator itt = pplusVarMap.begin();
00359     for (; itt != pplusVarMap.end(); itt++)
00360       plusVarMap[(*itt).first] = (*itt).second;
00361   }
00362 
00363   ~ZZFormulaInfo() { if (wt) delete wt; }
00364 
00365   const ListObj* formula;
00366   const string formulaStr;
00367   const int numPreds;
00368   const double* wt;
00369   const double defaultWt;
00370   const Domain* domain;
00371   MLN* mln;
00372   ZZVarNameToIdMap varNameToIdMap;
00373   StringToIntMap plusVarMap;
00374   const int numAsterisk;
00375   const bool hasFullStop;
00376   const bool readHardClauseWts;
00377   const bool mustHaveWtOrFullStop;
00378   const bool isIndivisible;
00379 };
00380 
00381 Array<ZZFormulaInfo*> zzformulaInfos;
00382 
00383 
00385 
00386 string rmTmpPostfix(const string& filename)
00387 {
00388   unsigned int postfixLen = strlen(ZZ_TMP_FILE_POSTFIX);
00389   if (filename.length() < postfixLen) return filename;
00390   if (filename.compare(filename.length() - postfixLen, postfixLen, 
00391                        ZZ_TMP_FILE_POSTFIX, postfixLen)==0)
00392     return filename.substr(0, filename.length() - postfixLen); 
00393   else
00394     return filename;
00395 }
00396 
00397 
00398 void yyerror(char const * err) 
00399 {
00400   string errStr = err;
00401   if (strncmp(err,"parse error, unexpected '(', expecting '='",42)==0)
00402     errStr.append("Have you declared the predicate/function preceding '('");
00403 
00404   if (zzisParsing)
00405     printf("ERROR in %s: line %d, col %d: %s\n", 
00406            rmTmpPostfix(zzinFileName).c_str(),zzline, zzcolumn, errStr.c_str());
00407   else
00408     printf("ERROR occurs after parsing %s: %s\n", 
00409            rmTmpPostfix(zzinFileName).c_str(), errStr.c_str());
00410 
00411   zzok=false;
00412   if (++zznumErrors == ZZ_MAX_ERRORS)
00413   {
00414     cout << "Num of errors = " << zznumErrors 
00415          << ". Exceeded maximum number of errors." << endl;
00416     exit(-1);
00417   }
00418 }
00419 
00420 
00421 void zzerr(const char* const & str) { yyerror(str); }
00422 
00423 
00424 void zzerr(const char* const & str, const char* const & token)
00425 {
00426   sprintf(zzerrMsg, str, token);
00427   yyerror(zzerrMsg);
00428 }
00429 
00430 
00431 void zzerr(const char* const & str, const char* const & token1, 
00432            const char* const & token2)
00433 {
00434   sprintf(zzerrMsg, str, token1, token2);
00435   yyerror(zzerrMsg);
00436 }
00437 
00438 
00439 void zzerr(const char* const & str, const char* const & token1, 
00440            const char* const & token2, const char* const & token3)
00441 {
00442   sprintf(zzerrMsg, str, token1, token2, token3);
00443   yyerror(zzerrMsg);
00444 }
00445 
00446 
00447 void zzerr(const char* const & str, const char* const & token1, 
00448            const int& token2, const int& token3)
00449 {
00450   sprintf(zzerrMsg, str, token1, token2, token3);
00451   yyerror(zzerrMsg);
00452 }
00453 
00454 
00455 void zzwarn(const char* const & str)
00456 {
00457   if (zzisParsing)
00458     printf("WARNING in %s: line %d, col %d: %s\n", 
00459            rmTmpPostfix(zzinFileName).c_str(), zzline, zzcolumn, str);
00460   else
00461     printf("WARNING after parsing %s: %s\n", 
00462            rmTmpPostfix(zzinFileName).c_str(), str);
00463 }
00464 
00465 
00466 void zzwarn(const char* const & str, const char* const & token)
00467 {
00468   sprintf(zzerrMsg, str, token);
00469   zzwarn(zzerrMsg);
00470 }
00471 
00472 
00473 void zzexit(const char* const & str)
00474 {
00475   zzerr(str);
00476   exit(-1);
00477 }
00478 
00479 
00480 void zzexit(const char* const & str, const char* const & token)
00481 {
00482   zzerr(str,token);
00483   exit(-1);
00484 }
00485 
00486 
00487 void zzassert(const bool& condn, const char* const & str)
00488 {
00489   string s("assertion failed! ");
00490   s.append(str);
00491   if (!condn) zzexit(s.c_str()); 
00492 }
00493 
00494 
00495 void zzmsg(const char* const & str)
00496 {
00497   if (zzisParsing)
00498     printf("in %s: line %d, col %d: %s\n", 
00499            rmTmpPostfix(zzinFileName).c_str(), zzline, zzcolumn, str);
00500   else
00501     printf("after parsing %s: %s\n", rmTmpPostfix(zzinFileName).c_str(), str);
00502 }
00503 
00504 
00505 void zzmsg(const char* const & str, const char* const & token)
00506 {
00507   sprintf(zzerrMsg, str, token);
00508   zzmsg(zzerrMsg);
00509 }
00510 
00511 
00513 
00514 string zzgetNewVarName(const char* const & varName)
00515 {
00516   ZZOldNewVarList::iterator it = zzoldNewVarList.begin();
00517   for (; it != zzoldNewVarList.end(); it++)
00518   {
00519     StringToStringMap* oldNewVarMap = (*it).first;
00520     StringToStringMap::iterator mit;
00521     if ((mit = oldNewVarMap->find(varName)) != oldNewVarMap->end())
00522       return (*mit).second;
00523   }
00524   return string(varName);
00525 }
00526 
00527 
00528   // returns var id (negative number) or 0 if varName is of wrong type
00529 int zzgetVarId(const char* const& varName, const int& varTypeId,
00530                int& expectedTypeId)
00531 {
00532   string vname = varName;
00533 
00534     // search last element (which corresponds to the scope of the entire formula
00535   ZZVarNameToIdMap::iterator mit;
00536   if ((mit = zzvarNameToIdMap.find(vname)) == zzvarNameToIdMap.end())
00537   {
00538     ZZVarIdType v(--zzvarCounter, varTypeId);
00539     zzvarNameToIdMap[vname] = v;
00540     return v.id_;
00541   }
00542 
00543   ZZVarIdType& varIdType = (*mit).second;
00544   int typeId = varTypeId; //avoid confusion later
00545 
00546   if (varIdType.typeId_ == zzanyTypeId)
00547   {
00548     varIdType.typeId_ = typeId;
00549     expectedTypeId = varIdType.typeId_;
00550     return varIdType.id_;
00551   }
00552 
00553 //  if (typeId != zzanyTypeId && typeId != varIdType.typeId_) 
00554 //  {
00555 //    expectedTypeId = varIdType.typeId_;
00556 //    return 0;
00557 //  }
00558   return varIdType.id_;  
00559 }
00560 
00561 
00562 int zzgetVarTypeId(const char* const& varName)
00563 {
00564   ZZVarNameToIdMap::iterator mit;
00565   if ((mit = zzvarNameToIdMap.find(string(varName))) != zzvarNameToIdMap.end())
00566     return (*mit).second.typeId_;
00567   return -1;
00568 }
00569 
00570 
00571 void zzcheckVarNameToIdMap()
00572 {
00573   ZZVarNameToIdMap::iterator it = zzvarNameToIdMap.begin();
00574   for (;it != zzvarNameToIdMap.end(); it++)
00575     if ((*it).second.typeId_ == zzanyTypeId)
00576       zzerr("Variable %s has unknown type.", (*it).first.c_str()); 
00577 }
00578 
00579 
00580   // returns var id (negative number) or 0 if varName is of wrong type
00581 bool zzvarIsQuantified(const char* const& varName)
00582 {
00583   ZZOldNewVarList::iterator it = zzoldNewVarList.begin();
00584   for (; it != zzoldNewVarList.end(); it++)
00585   {
00586     StringToStringMap* oldNewVarMap = (*it).first;
00587     StringToStringMap::iterator mit;
00588     if ((mit = oldNewVarMap->find(varName)) != oldNewVarMap->end())
00589       return true;
00590   }
00591   return false;
00592 }
00593 
00594 
00595    // Caller must delete the returned VarTypeMap
00596 VarTypeMap* zzcreateVarTypeMap(const ZZVarNameToIdMap& map)
00597 {
00598   VarTypeMap* vtMap = new VarTypeMap;
00599   ZZVarNameToIdMap::const_iterator it = map.begin();
00600   for (; it != map.end(); it++)
00601     (*vtMap)[(*it).first] =(*it).second.typeId_;
00602   return vtMap;
00603 }
00604 
00605 
00606 void zzsetPlusVarTypeId()
00607 {
00608   StringToIntMap::iterator mit = zzplusVarMap.begin();
00609   for (; mit != zzplusVarMap.end(); mit++)
00610   {
00611     string plusVarName = (*mit).first;
00612     ZZVarNameToIdMap::iterator typeIt = zzvarNameToIdMap.find(plusVarName);
00613     zzassert(typeIt != zzvarNameToIdMap.end(),
00614              "expect typeIt != zzvarNameToIdMap.end()");
00615     //commented out: done in zzcheckVarNameToIdMap()
00616     //zzassert((*mit).second.typeId_ > 0,"expect typedId > 0");
00617     (*mit).second = (*typeIt).second.typeId_;
00618   }
00619 }
00620 
00621 
00623 
00624 
00632 bool zzisInternalFunction(const char* funcname)
00633 {
00634   for (int i = 0; i < zzinternalFunctions.size(); i++)
00635         if (strcmp(funcname, zzinternalFunctions[i][0]) == 0)
00636           return true;
00637 
00638   return false;
00639 }
00640 
00641 // Returns the index of internal function with name funcname if found,
00642 // otherwise 0
00643 int zzfindInternalFunction(const char* funcname)
00644 {
00645   for (int i = 0; i < zzinternalFunctions.size(); i++)
00646     if (strcmp(funcname, zzinternalFunctions[i][0]) == 0)
00647       return i;
00648   return -1;
00649 }
00650 
00658 bool zzisInternalPredicate(const char* predname)
00659 {
00660   for (int i = 0; i < zzinternalPredicates.size(); i++)
00661         if (strcmp(predname, zzinternalPredicates[i][0]) == 0)
00662           return true;
00663 
00664   return false;
00665 }
00666 
00667 // Returns the index of internal predicate with name predname if found,
00668 // otherwise 0
00669 int zzfindInternalPredicate(const char* predname)
00670 {
00671   for (int i = 0; i < zzinternalPredicates.size(); i++)
00672     if (strcmp(predname, zzinternalPredicates[i][0]) == 0)
00673       return i;
00674   return -1;
00675 }
00676 
00685 bool zzisLinkedFunction(const char* funcname, void* handle)
00686 {
00687   char *error;
00688 
00689   dlerror();    // Clear any existing error
00690   dlsym(handle, funcname);
00691   if ((error = dlerror()) != NULL) return false;
00692 
00693   return true;
00694 }
00695 
00704 bool zzisLinkedPredicate(const char* predname, void* handle)
00705 {
00706   char *error;
00707 
00708   dlerror();    // Clear any existing error
00709   dlsym(handle, predname);
00710   if ((error = dlerror()) != NULL) return false;
00711 
00712   return true;
00713 }       
00714 
00715 void zzsetEqPredTypeName(const int& typeId)
00716 {  
00717   const char * typeName = zzdomain->getTypeName(typeId);
00718   string eqPredName = PredicateTemplate::createEqualPredTypeName(typeName);
00719   const PredicateTemplate* t =
00720     zzdomain->getPredicateTemplate(eqPredName.c_str());
00721   zzpred->setTemplate((PredicateTemplate*)t);
00722   zzassert(t != NULL,
00723            "expect equal pred template != NULL");
00724   ListObj* predlo = zzpredFuncListObjs.top(); 
00725   predlo->replace(PredicateTemplate::EQUAL_NAME, eqPredName.c_str());
00726 }
00727 
00728 int zzgetTypeId(const Term* const & t, const char* const & varName)
00729 {
00730   int termType = t->getType();
00731   if (termType == Term::FUNCTION) 
00732     return t->getFunction()->getRetTypeId();
00733  
00734     // Constants could potentially be of any type
00735   if (termType == Term::CONSTANT) 
00736     return -1;
00737 
00738   if (termType == Term::VARIABLE) 
00739   {
00740     ZZVarNameToIdMap::iterator mit = zzvarNameToIdMap.find(varName);
00741     if (mit != zzvarNameToIdMap.end()) return (*mit).second.typeId_;
00742     return zzanyTypeId;
00743   }
00744   zzassert(false, "expect FUNCTION, VARIABLE, CONSTANT");
00745   return -1;
00746 }
00747 
00748 
00749 void zzdetermineEqPredTypes(ListObj* const & formula)
00750 {
00751   unsigned int prevSize = 0;
00752   while (zzeqPredList.size() != prevSize)
00753   {
00754     prevSize = zzeqPredList.size();
00755     list<ZZUnknownEqPredInfo>::iterator lit, remIt ;
00756     for (lit = zzeqPredList.begin(); lit != zzeqPredList.end(); lit++)
00757     {
00758       ZZUnknownEqPredInfo& uepi = (*lit);
00759       string lvarName = uepi.lhs_;
00760       string rvarName = uepi.rhs_;
00761       int lTypeId = zzgetVarTypeId(lvarName.c_str());
00762       int rTypeId = zzgetVarTypeId(rvarName.c_str());
00763 
00764       if (lTypeId > 0 && rTypeId > 0) //if both types are known
00765       {
00766         if (lTypeId != rTypeId)
00767           zzerr("The types of %s and %s on the left and right of "
00768                 "'=' must match.", lvarName.c_str(), rvarName.c_str());
00769         const char * typeName = zzdomain->getTypeName(lTypeId);
00770         string eqPredName 
00771           = PredicateTemplate::createEqualPredTypeName(typeName);
00772         formula->replace(uepi.name_.c_str(), eqPredName.c_str());
00773         remIt = lit; lit++; zzeqPredList.erase(remIt);
00774         
00775       }
00776       else  // if only one type is known
00777       if ( (lTypeId<=0 && rTypeId>0) || (lTypeId>0 && rTypeId<=0) )
00778       {
00779         int knownTypeId = (lTypeId>0) ? lTypeId : rTypeId;
00780         const char * typeName = zzdomain->getTypeName(knownTypeId);
00781         string eqPredName 
00782           = PredicateTemplate::createEqualPredTypeName(typeName);
00783         formula->replace(uepi.name_.c_str(), eqPredName.c_str());
00784         const char* unknowVarName = (lTypeId>0) ?  rvarName.c_str() : 
00785                                                    lvarName.c_str();
00786         zzvarNameToIdMap[unknowVarName].typeId_ = knownTypeId;
00787         remIt = lit; lit++; zzeqPredList.erase(remIt);  
00788       }
00789     }
00790   }
00791   if (zzeqPredList.size() > 0)
00792   {
00793     zzerr("The following variables used with the '=' operator have "
00794          "unknown types");
00795     list<ZZUnknownEqPredInfo>::iterator lit; 
00796     for (lit = zzeqPredList.begin(); lit != zzeqPredList.end(); lit++)
00797       cout << (*lit).lhs_ << " " << (*lit).rhs_ << " ";
00798     cout << endl;
00799   }
00800 }
00801 
00802 void zzdetermineIntPredTypes(ListObj* const & formula)
00803 {
00804   unsigned int prevSize = 0;
00805   while (zzintPredList.size() != prevSize)
00806   {
00807     prevSize = zzintPredList.size();
00808     list<ZZUnknownIntPredInfo>::iterator lit, remIt ;
00809     for (lit = zzintPredList.begin(); lit != zzintPredList.end(); lit++)
00810     {
00811       ZZUnknownIntPredInfo& uipi = (*lit);
00812       string lvarName = uipi.lhs_;
00813       string rvarName = uipi.rhs_;
00814           string baseName = uipi.name_.substr(0, uipi.name_.find_last_of("_"));
00815       int lTypeId = zzgetVarTypeId(lvarName.c_str());
00816       int rTypeId = zzgetVarTypeId(rvarName.c_str());
00817 
00818       if (lTypeId > 0 && rTypeId > 0) //if both types are known
00819       {
00820         if (lTypeId != rTypeId)
00821           zzerr("The types of %s and %s on the left and right of "
00822                 "an internal opreator must match.",
00823                 lvarName.c_str(), rvarName.c_str());
00824         const char * typeName = zzdomain->getTypeName(lTypeId);
00825         string intPredName 
00826           = PredicateTemplate::createInternalPredTypeName(baseName.c_str(),
00827                                                           typeName);
00828         formula->replace(uipi.name_.c_str(), intPredName.c_str());
00829         remIt = lit; lit++; zzintPredList.erase(remIt);        
00830       }
00831       else  // if only one type is known
00832       if ( (lTypeId<=0 && rTypeId>0) || (lTypeId>0 && rTypeId<=0) )
00833       {
00834         int knownTypeId = (lTypeId>0) ? lTypeId : rTypeId;
00835         const char * typeName = zzdomain->getTypeName(knownTypeId);
00836         string intPredName 
00837           = PredicateTemplate::createInternalPredTypeName(baseName.c_str(),
00838                                                           typeName);
00839         formula->replace(uipi.name_.c_str(), intPredName.c_str());
00840         const char* unknowVarName = (lTypeId>0) ?  rvarName.c_str() : 
00841                                                    lvarName.c_str();
00842         zzvarNameToIdMap[unknowVarName].typeId_ = knownTypeId;
00843         remIt = lit; lit++; zzintPredList.erase(remIt);  
00844       }
00845     }
00846   }
00847   if (zzintPredList.size() > 0)
00848   {
00849     zzerr("The following variables used with an internal operator have "
00850          "unknown types");
00851     list<ZZUnknownIntPredInfo>::iterator lit; 
00852     for (lit = zzintPredList.begin(); lit != zzintPredList.end(); lit++)
00853       cout << (*lit).lhs_ << " " << (*lit).rhs_ << " ";
00854     cout << endl;
00855   }
00856 }
00857 
00858 void zzdetermineIntFuncTypes(ListObj* const & formula)
00859 {
00860   unsigned int prevSize = 0;
00861   while (zzintFuncList.size() != prevSize)
00862   {
00863     prevSize = zzintFuncList.size();
00864     list<ZZUnknownIntFuncInfo>::iterator lit, remIt ;
00865     for (lit = zzintFuncList.begin(); lit != zzintFuncList.end(); lit++)
00866     {
00867       ZZUnknownIntFuncInfo& uifi = (*lit);
00868       Array<string> varNames = uifi.vnames_;
00869           string baseName = uifi.name_.substr(0, uifi.name_.find_last_of("_"));
00870 
00871           bool unknownTypes = false;
00872       Array<int> typeIds;
00873       for  (int i = 0; i < varNames.size(); i++)
00874       {
00875         int typeId = zzgetVarTypeId(varNames[i].c_str());
00876         typeIds.append(typeId);
00877                 if (typeId <= 0)
00878                 {
00879                   unknownTypes = true;
00880                 }
00881       }
00882 
00883       if (!unknownTypes) //if both types are known
00884       {
00885         Array<string> typeNames;
00886         for (int i = 0; i < typeIds.size(); i++)
00887         {
00888           string typeName = zzdomain->getTypeName(typeIds[i]);
00889           typeNames.append(typeName);
00890         }
00891         string intPredFromFuncName 
00892           = FunctionTemplate::createInternalFuncTypeName(baseName.c_str(),
00893                                                          typeNames);
00894         formula->replace(uifi.name_.c_str(), intPredFromFuncName.c_str());
00895         remIt = lit; lit++; zzintFuncList.erase(remIt);
00896       }
00897     }
00898   }
00899   if (zzintFuncList.size() > 0)
00900   {
00901     zzerr("The following variables used with an internal function have "
00902          "unknown types");
00903     list<ZZUnknownIntFuncInfo>::iterator lit; 
00904     for (lit = zzintFuncList.begin(); lit != zzintFuncList.end(); lit++)
00905     {
00906       for (int i = 1; i < (*lit).vnames_.size(); i++)
00907         cout << (*lit).vnames_[i] << " ";
00908     }
00909     cout << endl;
00910   }
00911 }
00912 
00913 
00914 bool zzcheckRightTypeAndGetVarId(const int& typeId, const char* const& varName,
00915                                  int& varId)
00916 {
00917     // check that the variable is of the right type
00918   int expectedTypeId = -1;
00919   varId = zzgetVarId(varName, typeId, expectedTypeId);
00920   if (varId == 0)
00921   {
00922     const char* expName = zzdomain->getTypeName(typeId);
00923     const char* unexpName = zzdomain->getTypeName(expectedTypeId);
00924     zzerr("Variable %s is of the wrong type. Expected %s but given %s", 
00925           varName, expName, unexpName);
00926     return false;
00927   }
00928   return true;
00929 }
00930 
00931 void zzaddType(const char* const& typeName, 
00932                PredicateTemplate* const& predTemplate, 
00933                FunctionTemplate* const& funcTemplate,
00934                bool isUnique, const Domain* const & domain)
00935 {
00936   if (isUnique && funcTemplate != NULL)
00937   {
00938     zzerr("Function parameter (%s) cannot be existentially and uniquely "
00939           "quantified",typeName);
00940     isUnique = false;
00941   }
00942 
00943   if (predTemplate != NULL)
00944   { 
00945     bool ok = predTemplate->appendTermType(typeName, isUnique, domain);
00946     if(!ok) zzexit("Term type %s should have been declared.", typeName);
00947   }
00948   else 
00949   if (funcTemplate != NULL) 
00950   {
00951     bool ok = funcTemplate->appendTermType(typeName, isUnique, domain);
00952     if (!ok) zzexit("Term type %s should have been declared.", typeName);
00953   }
00954 }
00955 
00956 
00957 int zzaddTypeToDomain(Domain* const & domain, const char* const & typeName)
00958 {
00959   int typeId = domain->addType(typeName);
00960   
00961   if (typeName != PredicateTemplate::ANY_TYPE_NAME)
00962   {
00963       // create a PredicateTemplate to represent '=' (equality pred) for type
00964     string ptName = PredicateTemplate::createEqualPredTypeName(typeName);
00965     if (domain->getPredicateTemplate(ptName.c_str()) == NULL)
00966     {
00967       PredicateTemplate* pt = new PredicateTemplate();
00968       pt->setName(ptName.c_str());
00969       pt->appendTermType(typeName, false, domain);
00970       pt->appendTermType(typeName, false, domain);
00971       int id = domain->addPredicateTemplate(pt);
00972       zzassert(id >= 0, "expect pred template id >= 0");
00973       pt->setId(id);
00974     }
00975     
00976       // create a PredicateTemplate for each internal pred. for this type
00977 /*
00978     Array<string> ptNames =
00979       PredicateTemplate::createInternalPredTypeNames(typeName);
00980         for (int i = 0; i < ptNames.size(); i++)
00981         {
00982           string ptName = ptNames[i];
00983           if (domain->getPredicateTemplate(ptName.c_str()) == NULL)
00984       {
00985         PredicateTemplate* pt = new PredicateTemplate();
00986         pt->setName(ptName.c_str());
00987         pt->appendTermType(typeName, false, domain);
00988         pt->appendTermType(typeName, false, domain);
00989         int id = domain->addPredicateTemplate(pt);
00990         zzassert(id >= 0, "expect pred template id >= 0");
00991         pt->setId(id);
00992       }
00993         }
00994 */
00995   }
00996 
00997   return typeId;
00998 }
00999 
01000 void zzcreatePred(Predicate*& pred, const char* const & predName)
01001 {
01002   const PredicateTemplate* t = zzdomain->getPredicateTemplate(predName);
01003   if (t==NULL)
01004   {
01005         int index = zzfindInternalPredicate(predName);
01006         // Internal predicates are declared on the fly
01007     if (index >= 0)
01008     {
01009       zzassert(zzdomain->getFunctionId(predName) < 0, 
01010                "not expecting pred name to be declared as a function name");
01011           PredicateTemplate* ptemplate = new PredicateTemplate();
01012           ptemplate->setName(predName);
01013         
01014           // Add types
01015           for (int j = 1; j < zzinternalPredicates[index].size(); j++)
01016           {
01017             int id;
01018             const char* ttype = zzinternalPredicates[index][j];
01019             if (!zzdomain->isType(ttype))
01020             {
01021                   id = zzaddTypeToDomain(zzdomain, ttype);
01022                   zzassert(id >= 0, "expecting var id >= 0");
01023             }
01024             zzaddType(ttype, ptemplate, NULL, false, zzdomain);
01025             //delete [] ttype;
01026           }
01027         
01028           // Add template to domain
01029           zzassert(ptemplate, "not expecting ptemplate==NULL");
01030           int id = zzdomain->addPredicateTemplate(ptemplate);
01031           zzassert(id >= 0, "expecting pred template id >= 0");
01032           ptemplate->setId(id);
01033           zzassert(pred == NULL, "expect pred == NULL");
01034           pred = new Predicate(ptemplate);
01035           return; 
01036     }
01037     else
01038           zzexit("Predicate %s should have been declared.", predName);
01039   }
01040     // commented out because when zzcreatePred is called predicate has already 
01041     // been declared
01042   //if (t == NULL) 
01043   //{
01044   //  zzerr("Failed to find predicate %s. Have you declared it?", predName);
01045   //    // create a fake predicate template and attempt to recover
01046   //  char buf[32];
01047   //  sprintf(buf, "%s%d", zzdefaultPredName, zzcount++); 
01048   //  zzpredTemplate = new PredicateTemplate();
01049   //  zzpredTemplate->setDomain(zzdomain);
01050   //  zzpredTemplate->setName(buf);
01051   //  int id = zzdomain->addPredicateTemplate(zzpredTemplate);
01052   //  zzassert(id >= 0, "expect id >= 0");
01053   //  zzpredTemplate->setId(id);
01054   //  for (int i = 0; i < 20; i++)
01055   //  {
01056   //    sprintf(buf, "%s%d",zzdefaultTypeName, zzcount++); 
01057   //    bool ok = zzpredTemplate->appendTermType(buf, false, zzdomain);
01058   //    if(!ok) zzexit("");
01059   //  }
01060   //  t = zzpredTemplate;
01061   //  zzpredTemplate = NULL;
01062   //}
01063 
01064   zzassert(pred == NULL, "expect pred == NULL");
01065   pred = new Predicate(t); 
01066 }
01067 
01068 
01069 
01070 void zzcheckPredNumTerm(Predicate*& pred)
01071 {
01072   int exp, unexp;
01073   if ((unexp=pred->getNumTerms()) != (exp=pred->getTemplate()->getNumTerms()))
01074   {
01075     zzerr("Wrong number of terms for predicate %s. Expected %d but given %d", 
01076           pred->getName(), exp, unexp);
01077   
01078     char buf[128];
01079       // try to recover
01080     for (int i = unexp; i < exp; i++)
01081     {
01082       sprintf(buf, "%s%d", zzdefaultVarName, zzcount++); 
01083       int typeId = pred->getTermTypeAsInt(i);
01084       int varId;
01085       bool rightType = zzcheckRightTypeAndGetVarId(typeId, buf, varId);
01086       if (!rightType) zzexit("");
01087       pred->appendTerm(new Term(varId, (void*)pred, true));
01088     }
01089   }
01090 }
01091 
01092 
01093 void zzpredAppendConstant(Predicate* const& pred, const int& constId,
01094                           const char* const & constName)
01095 {    
01096     // if exceeded the number of terms
01097   int exp, unexp;
01098   if ((unexp=pred->getNumTerms()) == (exp=pred->getTemplate()->getNumTerms()))
01099   {
01100     zzerr("Wrong number of terms for predicate %s. Expected %d but given >%d", 
01101           pred->getName(), exp, unexp);
01102     return;
01103   }
01104 /*
01105     // if this is not '=' predicate with unknown types
01106   if (!(strcmp(pred->getName(),PredicateTemplate::EQUAL_NAME) == 0) &&
01107           !(strcmp(pred->getTermTypeAsStr(pred->getNumTerms()),
01108                PredicateTemplate::ANY_TYPE_NAME) == 0))
01109   {
01110       // Check that constant has same type as that of predicate term
01111     int typeId = pred->getTermTypeAsInt(pred->getNumTerms());
01112     int unexpId; 
01113     if (typeId != (unexpId=zzdomain->getConstantTypeId(constId)))
01114     {
01115       const char* expName = zzdomain->getTypeName(typeId);
01116       const char* unexpName = zzdomain->getTypeName(unexpId);
01117       zzerr("Constant %s is of the wrong type. Expected %s but "
01118             "given %s", constName, expName, unexpName);
01119       return;
01120     }
01121   }
01122 */  
01123     // at this point, we have the right num of terms and right constant types
01124   if (pred != NULL) pred->appendTerm(new Term(constId, (void*)pred, true));
01125 }
01126 
01127 
01129 
01130 void zzconsumeToken(StrFifoList& tokenList, const char* c)
01131 {
01132   const char* tok = tokenList.removeLast();
01133   if (strcmp(tok, c)!=0)
01134   {
01135     cout << "token = '" << tok << "', '" << c << "'" << endl;
01136     zzassert(strcmp(tok, c)==0, "expect strcmp(tok,c)==0");
01137   }
01138   delete [] tok;
01139 }
01140 
01141 
01142 void zzcreateFunc(Function*& func, const char* const & funcName)
01143 {
01144   const FunctionTemplate* t = zzdomain->getFunctionTemplate(funcName);
01145   if (t==NULL)
01146   {
01147         // Internal functions are declared on the fly
01148     int index;
01149         if ((index = zzfindInternalFunction(funcName)) >= 0)
01150         {
01151       zzassert(zzfuncTemplate==NULL, "expecting zzfuncTemplate==NULL");
01152           zzfuncTemplate = new FunctionTemplate();
01153 
01154           // We are creating a new predicate as well
01155           zzassert(zzpredTemplate==NULL,"expecting zzpredTemplate==NULL");
01156           zzpredTemplate = new PredicateTemplate();
01157 
01158           zzassert(zzdomain->getPredicateId(funcName) < 0, 
01159                "not expecting func name to be declared as pred name");
01160           zzassert(zzfuncTemplate,"expecting zzfuncTemplate!=NULL");
01161           zzfuncTemplate->setName(funcName);
01162 
01163           // Predicate name is PredicateTemplate::ZZ_RETURN_PREFIX + function name
01164           char* predName;
01165           predName = (char *)malloc((strlen(PredicateTemplate::ZZ_RETURN_PREFIX) +
01166                                                         strlen(funcName) + 1)*sizeof(char));
01167           strcpy(predName, PredicateTemplate::ZZ_RETURN_PREFIX);
01168           strcat(predName, funcName);
01169         
01170           // Check that predicate has not been declared a function
01171           zzassert(zzdomain->getFunctionId(predName) < 0, 
01172                        "not expecting pred name to be declared as a function name");
01173           zzassert(zzpredTemplate,"expecting zzpredTemplate!=NULL");
01174           zzpredTemplate->setName(predName);
01175           delete [] predName;  
01176         
01177           // Add return type
01178           const char* retTypeName = zzinternalFunctions[index][1];
01179 
01180           if (!zzdomain->isType(retTypeName))
01181           {
01182             int id = zzaddTypeToDomain(zzdomain, retTypeName);
01183         zzassert(id >= 0, "expecting retTypeName's id >= 0");
01184           }
01185 
01186           zzfuncTemplate->setRetTypeName(retTypeName,zzdomain);
01187           // We are creating a new predicate as well
01188           zzaddType(retTypeName, zzpredTemplate, NULL, false, zzdomain);
01189   
01190           // Add types
01191           for (int j = 2; j < zzinternalFunctions[index].size(); j++)
01192           {
01193             int id;
01194             const char* ttype = zzinternalFunctions[index][j];
01195             if (!zzdomain->isType(ttype))
01196             {
01197                   id = zzaddTypeToDomain(zzdomain, ttype);
01198                   zzassert(id >= 0, "expecting var id >= 0");
01199             }
01200             zzaddType(ttype, zzpredTemplate, NULL, false, zzdomain);
01201             // Add the type to the function too
01202             zzaddType(ttype, NULL, zzfuncTemplate, false, zzdomain);
01203           }
01204 
01205           // Add templates to domain
01206           zzassert(zzfuncTemplate, "expecting zzfuncTemplate != NULL");
01207           int id = zzdomain->addFunctionTemplate(zzfuncTemplate);
01208           zzassert(id >= 0, "expecting function template's id >= 0");
01209           zzfuncTemplate->setId(id);
01210 
01211           zzassert(zzpredTemplate, "not expecting zzpredTemplate==NULL");
01212           int predId = zzdomain->addPredicateTemplate(zzpredTemplate);
01213           zzassert(predId >= 0, "expecting pred template id >= 0");
01214           zzpredTemplate->setId(predId);
01215 
01216           zzassert(func == NULL, "expect func == NULL");
01217           func = new Function(zzfuncTemplate);
01218           zzfuncTemplate = NULL;
01219           zzpredTemplate = NULL;
01220           return;
01221         }
01222         else
01223         zzexit("Function %s should have been declared.", funcName);
01224   }
01225   //if (t == NULL) 
01226   //{
01227   //  zzerr("Failed to find function %s. Have you declared it?", funcName);
01228   //    // create a fake predicate template and attempt to recover
01229   //  char buf[32];
01230   //  sprintf(buf, "%s%d", zzdefaultFuncName, zzcount++); 
01231   //  zzfuncTemplate = new FunctionTemplate();
01232   //  zzfuncTemplate->setDomain(zzdomain);
01233   //  zzfuncTemplate->setRetTypeName(PredicateTemplate::ANY_TYPE_NAME);
01234   //  zzfuncTemplate->setName(buf);
01235   //  int id = zzdomain->addFunctionTemplate(zzfuncTemplate);
01236   //  zzassert(id >= 0, "expect id >= 0");
01237   //  zzfuncTemplate->setId(id);
01238   //  for (int i = 0; i < 20; i++)
01239   //  {
01240   //    sprintf(buf, "%s%d",zzdefaultTypeName, zzcount++); 
01241   //    bool ok = zzfuncTemplate->appendTermType(buf, false, zzdomain);
01242   //    if(!ok) zzexit("");
01243   //  }
01244   //  t = zzfuncTemplate;
01245   //  zzfuncTemplate = NULL;
01246   //}
01247 
01248   zzassert(func == NULL, "expect func == NULL");
01249   func = new Function(t);
01250 }
01251 
01252 
01253 void zzcheckFuncNumTerm(Function*& func)
01254 {
01255   int exp, unexp;
01256   if ((unexp=func->getNumTerms()) != (exp=func->getTemplate()->getNumTerms()))
01257   {
01258     zzerr("Wrong number of terms for func %s. Expected %d but given %d", 
01259           func->getName(), exp, unexp);
01260   
01261     char buf[128];
01262       // try to recover
01263     for (int i = unexp; i < exp; i++)
01264     {
01265       sprintf(buf, "%s%d", zzdefaultVarName, zzcount++); 
01266       int typeId = func->getTermTypeAsInt(i);
01267       int varId;
01268       bool rightType = zzcheckRightTypeAndGetVarId(typeId, buf, varId);
01269       if (!rightType) zzexit("");
01270       func->appendTerm(new Term(varId, (void*)func, false));
01271     }
01272   }
01273 }
01274 
01275 
01276 void zzfuncAppendConstant(Function* const& func, const int& constId,
01277                           const char* const & constName)
01278 {    
01279     // if exceeded the number of terms
01280   int exp, unexp;
01281   if ((unexp=func->getNumTerms()) == (exp=func->getTemplate()->getNumTerms()))
01282   {
01283     zzerr("Wrong number of terms for function %s. Expected %d but given > %d", 
01284           func->getName(), exp, unexp);
01285     return;
01286   }
01287 /*
01288   if (!(strcmp(func->getTermTypeAsStr(func->getNumTerms()),
01289                PredicateTemplate::ANY_TYPE_NAME)==0))
01290   {
01291           // Check that constant has same type as that of predicate term
01292         int typeId = func->getTermTypeAsInt(func->getNumTerms());
01293         int unexpId; 
01294         if (typeId != (unexpId=zzdomain->getConstantTypeId(constId)))
01295         {
01296       const char* expName = zzdomain->getTypeName(typeId);
01297       const char* unexpName = zzdomain->getTypeName(unexpId);
01298       zzerr("Constant %s is of the wrong type. Expected %s but given %s", 
01299             constName, expName, unexpName);
01300       return;
01301         }
01302   }
01303 */
01304     // at this point, we have the right num of term and right constant type
01305   if (func != NULL) func->appendTerm(new Term(constId, (void*)func, false));
01306 }
01307 
01308 
01310 
01311 void zzpermuteAsteriskedPreds(const int& numAsterisk, 
01312                               const ListObj* const & formula,
01313                               const string& formulaStr,
01314                               Array<ListObj*>& clauses,
01315                               Array<string>& formulaStrs)
01316 {
01317   clauses.clear();
01318   formulaStrs.clear();
01319   if (numAsterisk == 0) 
01320   { 
01321     clauses.append( new ListObj(formula)); 
01322     formulaStrs.append(formulaStr);
01323     return; 
01324   }
01325 
01326   Array<int> astIdxs;
01327   for (unsigned int i = 0; i < formulaStr.length(); i++)
01328     if (formulaStr.at(i) == '*') astIdxs.append(i);
01329   assert(astIdxs.size() == numAsterisk);
01330 
01331     // add numAsterisk number of [false][true] to ArraysAccessor
01332   ArraysAccessor<bool> acc;
01333   for (int i = 0; i < numAsterisk; i++)
01334   {
01335     Array<bool>* a = new Array<bool>(2); 
01336     a->append(false); a->append(true);
01337     acc.appendArray(a);
01338   }
01339 
01340   Array<bool> bArr;
01341   while (acc.getNextCombination(bArr))
01342   {
01343       // create a copy of the formula
01344     clauses.append(new ListObj(formula));
01345     int idx = 0;    
01346     clauses[clauses.size()-1]->replaceAsterisk(bArr, idx);
01347 
01348     string s = formulaStr;
01349     assert(bArr.size() == astIdxs.size());
01350     for (int j = 0; j < bArr.size(); j++)
01351       s.at(astIdxs[j]) = (bArr[j]) ? ' ' : '!';
01352 
01353     formulaStrs.append(s);
01354   }
01355 
01356   acc.deleteArraysAndClear();
01357 }
01358 
01359 
01360 void zzgetDisjunctions(const ListObj* const & lo, Array<ListObj*>& clauses)
01361 {
01362   const Array<ListObj*>& lobjs = lo->getList();
01363   
01364   if ((lobjs[0]->getStr())[0] != '^')
01365   {
01366     clauses.append((ListObj*)lo);
01367     return;
01368   }
01369   
01370   for (int i = 1; i < lobjs.size(); i++)
01371     clauses.append(lobjs[i]);
01372 }
01373 
01374   // Checks if name starts with upper case or " (string constant)
01375 const bool zzisConstant(const char* const & name)
01376 {
01377   return (isupper(name[0]) || name[0] == '"');
01378 }
01379 
01380 Function* zzcreateFunc(const ListObj* const & lo)
01381 {
01382   const Array<ListObj*>& termlo = lo->getList();
01383   const char* funcName = termlo[0]->getStr();
01384   Function* func = NULL;
01385   zzcreateFunc(func, funcName);
01386   for (int i = 1; i < termlo.size(); i++)
01387   {
01388     if (termlo[i]->isStr())  // if is a constant or variable
01389     {
01390       const char* name = termlo[i]->getStr();
01391       //if (isupper(name[0]))  // if is a constant
01392       if (zzisConstant(name))  // if is a constant
01393       {
01394         int constId = zzdomain->getConstantId(name);
01395         if (constId < 0) 
01396           zzexit("zzcreateFunc(): failed to find constant %s. "
01397                  "Have you declared it?", name);
01398         zzfuncAppendConstant(func, constId, name);
01399       }
01400       else  // is a variable
01401       {
01402         if (func->getNumTerms() == func->getTemplate()->getNumTerms())
01403           zzexit("zzcreateFunc(): Function %s has too many terms", 
01404                  func->getName());
01405 
01406           // check the type of the term that is to be added
01407         int typeId = func->getTermTypeAsInt(func->getNumTerms());
01408         int expectedTypeId; 
01409         int varId = zzgetVarId(name, typeId, expectedTypeId);
01410 
01411         if (varId==0) 
01412           zzexit("zzcreateFunc(): failed to create term, variable %s has wrong "
01413                  "type", name);
01414         func->appendTerm(new Term(varId, (void*)func, false));        
01415       }
01416     }
01417     else // is a function
01418     {
01419         //push onto stack
01420       Function* termFunc = zzcreateFunc(termlo[i]);    
01421       Term* newTerm = new Term(termFunc, (void*)func, false);
01422       termFunc->setParent(newTerm);
01423       func->appendTerm(newTerm);
01424     }
01425   }
01426   
01427   zzcheckFuncNumTerm(func);
01428   return func;
01429 } 
01430 
01431 
01432 Predicate* zzcreatePred(const ListObj* const & lo)
01433 {
01434   const Array<ListObj*>& termlo = lo->getList();
01435   const char* predName = termlo[0]->getStr();
01436   Predicate* pred = NULL;
01437   zzcreatePred(pred, predName);
01438   for (int i = 1; i < termlo.size(); i++)
01439   {
01440     if (termlo[i]->isStr())  // if is a constant or variable
01441     {
01442       const char* name = termlo[i]->getStr();
01443       //if (isupper(name[0]))  // if is a constant
01444       if (zzisConstant(name))  // if is a constant
01445       {
01446         int constId = zzdomain->getConstantId(name);
01447         if (constId < 0) 
01448           zzexit("zzcreatePred(): failed to find constant %s. "
01449                  "Have you declared it?", name);
01450         zzpredAppendConstant(pred, constId, name);
01451       }
01452       else  // is a variable
01453       {
01454         if (pred->getNumTerms() == pred->getTemplate()->getNumTerms())
01455           zzexit("zzcreatePred(): Predicate %s has too many terms", 
01456                  pred->getName());
01457 
01458           // check the type of the term that is to be added
01459         int typeId = pred->getTermTypeAsInt(pred->getNumTerms());
01460         int expectedTypeId;
01461         int varId = zzgetVarId(name, typeId, expectedTypeId);
01462 
01463         if (varId==0) 
01464           zzexit("zzcreatePred(): failed to create term, variable %s has wrong "
01465                  "type", name);
01466         pred->appendTerm(new Term(varId, (void*)pred, true));        
01467       }
01468     }
01469     else // is a function
01470     {
01471       Function* func = zzcreateFunc(termlo[i]);
01472       Term* newTerm = new Term(func, (void*)pred, true);
01473       func->setParent(newTerm);
01474       pred->appendTerm(newTerm);
01475     }
01476   }
01477   
01478   zzcheckPredNumTerm(pred);
01479   return pred;
01480 } 
01481 
01482 
01483 void zzcreateClause(const ListObj* const & lo, Clause* const & clause)
01484 {
01485   zzvarCounter = 0;
01486   zzvarNameToIdMap.clear();
01487 
01488   const Array<ListObj*>& clauselo = lo->getList();
01489   if (strcmp(clauselo[0]->getStr(), "v")==0)
01490   {
01491     for (int i = 1; i < clauselo.size(); i++)
01492     {
01493       const Array<ListObj*>& predlo = clauselo[i]->getList();
01494       Predicate* pred;
01495 
01496       if ((predlo[0]->getStr())[0] == '!')
01497       {
01498         pred = zzcreatePred(predlo[1]);
01499         pred->setSense(false);
01500       }
01501       else
01502         pred = zzcreatePred(clauselo[i]);
01503       pred->setParent(clause);
01504       clause->appendPredicate(pred);
01505     }
01506   }
01507   else
01508   {
01509     Predicate* pred;
01510     if (((*lo)[0]->getStr())[0] == '!')
01511     {
01512       pred = zzcreatePred((*lo)[1]);
01513       pred->setSense(false);
01514     }
01515     else
01516       pred = zzcreatePred(lo);
01517     pred->setParent(clause);
01518     clause->appendPredicate(pred);
01519   }
01520 
01521   zzcheckVarNameToIdMap();
01522 }
01523 
01524 
01525   // clauses are those that occur together in CNF
01526 void zzcreateClauses(const ListObj* const & lo, Array<Clause*>& clauses,
01527                      Clause*& flippedClause)
01528 {
01529   flippedClause = NULL;
01530     // clauseOfUnitPreds contains the predicates of unit clauses
01531     // e.g if the cnf formula is P(x) ^ Q(x) ^ (P(y) v Q(y))
01532     // then clauseOfUnitPreds is !P(x) v !Q(x)
01533   Clause* clauseOfUnitPreds = new Clause;
01534   ListObj* unitPreds = new ListObj; ListObj orr("v"); unitPreds->append(&orr);
01535   Array<ListObj*> disjunctions;
01536   zzgetDisjunctions(lo, disjunctions);
01537   for (int i = 0; i < disjunctions.size(); i++)
01538   {
01539     Clause* clause = new Clause();
01540     zzcreateClause(disjunctions[i], clause);
01541     if (clause->getNumPredicates() > 1)
01542       clauses.append(clause);
01543     else
01544     {
01545       unitPreds->append(disjunctions[i]);
01546       delete clause;
01547     }
01548   }
01549 
01550   if (unitPreds->size() > 1) zzcreateClause(unitPreds, clauseOfUnitPreds);
01551   unitPreds->clear();
01552   delete unitPreds;
01553 
01554   if (clauseOfUnitPreds->getNumPredicates() > 1)
01555   {
01556     for (int i = 0; i < clauseOfUnitPreds->getNumPredicates(); i++)
01557       ((Predicate*)clauseOfUnitPreds->getPredicate(i))->invertSense();
01558     clauses.append(clauseOfUnitPreds);
01559     flippedClause = clauseOfUnitPreds;
01560   }
01561   else
01562   if (clauseOfUnitPreds->getNumPredicates() == 1) 
01563   {
01564       //if these is only one unit pred, then don't invert its sense
01565     clauses.append(clauseOfUnitPreds);
01566   }
01567   else
01568     delete clauseOfUnitPreds;
01569 }
01570 
01571 
01581 int zzcreateBlocks(const Domain* const & domain)
01582 {
01583   int totalNumPreds = 0;
01584   int numFOPreds = domain->getNumPredicates();
01585   for (int p = 0; p < numFOPreds; p++)
01586   {
01587     const PredicateTemplate* pt = domain->getPredicateTemplate(p);
01588     const Array<int>* uniqueVarIndexes = pt->getUniqueVarIndexes();
01589       // If predicate has no blocked vars, then continue
01590     if (uniqueVarIndexes->size() == 0) continue;
01591 
01592     Predicate* pred = domain->createPredicate(p, false);
01593       // Save variable ids, set unique vars to dummy id, ground pred to generate
01594       // blocks, then set var ids back to original and add as block to domain
01595     Array<int> uniqueVarIds;
01596       // Save var ids
01597     for (int i = 0; i < pred->getNumTerms(); i++)
01598     {
01599       if (uniqueVarIndexes->contains(i))
01600         uniqueVarIds.append(pred->getTerm(i)->getId());
01601     }
01602       // Set dummy id
01603     for (int i = 0; i < uniqueVarIndexes->size(); i++)
01604     {
01605       ((Term*)pred->getTerm((*uniqueVarIndexes)[i]))->setId(0);
01606     }
01607       // Ground pred to generate blocks 
01608     Array<Predicate*> predArr;
01609     pred->createAllGroundings(domain, predArr);
01610     int numPreds = predArr.size();
01611     totalNumPreds += numPreds;
01612 
01613     for (int i = 0; i < numPreds; i++)
01614     {
01615       Predicate* newPred = predArr[i];
01616         // Set var ids back to original
01617       for (int j = 0; j < uniqueVarIndexes->size(); j++)
01618       {
01619         Term* t = (Term*)newPred->getTerm((*uniqueVarIndexes)[j]);
01620         t->setId(uniqueVarIds[j]);
01621       }
01622         // Add as block to domain
01623       int blockIdx = domain->addPredBlock(newPred);
01624 
01625       bool trueOne = false;
01626         // If groundings of this pred occur, then make sure exactly one is true
01627         // and tell this to the domain
01628       if ((zzpredIdToGndPredMap.find(pred->getId())) != 
01629           zzpredIdToGndPredMap.end())
01630       {
01631         PredicateHashArray* pha = zzpredIdToGndPredMap[pred->getId()];
01632         for (int j = 0; j < pha->size(); j++)
01633         {
01634           Predicate* gndPred = (*pha)[j];
01635             // Only one atom in a block can be true
01636           if (gndPred->getTruthValue() == TRUE &&
01637               newPred->canBeGroundedAs(gndPred))
01638           {
01639             if (domain->getBlockEvidence(blockIdx))
01640               zzexit("More than one true atom found for mutually "
01641                      "exclusive and exhaustive variables");
01642             domain->setBlockEvidence(blockIdx, true);
01643             domain->setTruePredInBlock(blockIdx, new Predicate(*gndPred));
01644             trueOne = true;
01645           }
01646         }
01647       }
01648         // Query pred: There does not have to be a true one
01649       else
01650         trueOne = true;
01651       
01652         // One pred has to be true
01653       if (!trueOne)
01654       {
01655         // This assumes that all groundings of predicate are either query or
01656         // evidence. It doesn't work when some groundings are query, some are
01657         // evidence.
01658         //cout << "Problem with predicate ";
01659         //newPred->print(cout, domain); 
01660         //cout << endl;
01661         //zzexit(": No true atom was found for mutually "
01662         //       "exclusive and exhaustive variables");
01663       }
01664     }
01665     delete pred;
01666   }
01667   return totalNumPreds;
01668 }
01669 
01670 
01672 
01673 void zzgroundPlusVar(const ListObj* const & formula, const string& formulaStr,
01674                      const StringToIntMap& varNameToTypeIdMap, 
01675                      Array<ListObj*>& formulas, Array<string>& formulaStrs,
01676                      const Domain* const & domain,const Domain* const & domain0)
01677 {
01678   formulas.clear();
01679   formulaStrs.clear();
01680   if (varNameToTypeIdMap.size()==0) 
01681   {
01682     formulas.append(new ListObj(formula));
01683     formulaStrs.append(formulaStr);
01684     return; 
01685   }
01686 
01687   Array<Array<int>*> cleanUp;
01688   ArraysAccessor<int> acc;
01689   Array<string> varNames;
01690   StringToIntMap::const_iterator mit = varNameToTypeIdMap.begin();
01691   for (; mit != varNameToTypeIdMap.end(); mit++)
01692   {
01693     int typeId = (*mit).second;
01694     zzassert(typeId > 0, "expect typeId > 0");
01695 
01696     Array<int>* constArr;
01697     constArr = (Array<int>*) domain->getConstantsByType(typeId);
01698 
01699     acc.appendArray(constArr);
01700     varNames.append((*mit).first);
01701   }
01702 
01703   Array<int> constIds;
01704   while (acc.getNextCombination(constIds))
01705   {
01706     ListObj* gndFormula = new ListObj(formula);
01707     string s = formulaStr;
01708 
01709     zzassert(constIds.size() == varNames.size(),
01710              "expect constIds.size() == varNames.size()");
01711     for (int i = 0; i < varNames.size(); i++)
01712     {
01713       const char* constName = domain->getConstantName(constIds[i]);
01714       ListObj::replace(gndFormula, varNames[i].c_str(), constName, domain);
01715       unsigned int a = s.find("+" + varNames[i]);
01716       assert(a != string::npos);
01717       s.replace(a, varNames[i].length() + 1, constName);
01718     }
01719     formulas.append(gndFormula);
01720     formulaStrs.append(s);
01721   }
01722   //acc.deleteArraysAndClear();
01723 
01724   if (domain0) cleanUp.deleteItemsAndClear();
01725 }
01726 
01728 
01729 
01730 void zzcreateListObjFromTop(stack<ListObj*>& stack, const char* const & op)
01731 {
01732   //zzassert(zzformulaListObjs.size()>=1, "expect zzformulaListObjs.size()>=1");  
01733   zzassert(stack.size() >= 1, "expect stack.size()>=1");  
01734   ListObj* lo1 = stack.top(); stack.pop();
01735   ListObj* lo = new ListObj; lo->append(op); lo->append(lo1);
01736   stack.push(lo);
01737 }
01738 
01739 
01740 void zzcreateListObjFromTopTwo(stack<ListObj*>& stack, const char* const & op)
01741 {
01742   //zzassert(zzformulaListObjs.size()>=2,"expect zzformulaListObjs.size()>=2");  
01743   zzassert(stack.size()>=2,"expect stack.size()>=2");  
01744   ListObj* lo1 = stack.top(); stack.pop();
01745   ListObj* lo2 = stack.top(); stack.pop();
01746 
01747   if ((strcmp(op,"v")==0 && lo2->hasOrOp()) || 
01748       (strcmp(op,"^")==0 && lo2->hasAndOp()))
01749   {
01750     lo2->append(lo1);
01751     stack.push(lo2);
01752   }
01753   else
01754   {
01755     ListObj* lo = new ListObj; lo->append(op); lo->append(lo2); lo->append(lo1);
01756     stack.push(lo);
01757   }
01758 }
01759 
01760 
01761 void zzcreateListObjFromTopThree(stack<ListObj*>& stack)
01762 {
01763   //zzassert(zzformulaListObjs.size()>=3, "expect zzformulaListObjs.size()>=3");  
01764   zzassert(stack.size()>=3, "expect stack.size()>=3");  
01765   ListObj* lo1 = stack.top(); stack.pop();
01766   ListObj* lo2 = stack.top(); stack.pop();
01767   ListObj* lo3 = stack.top(); stack.pop();
01768   ListObj* lo = new ListObj; lo->append(lo3); lo->append(lo2); lo->append(lo1);
01769   stack.push(lo);
01770 }
01771 
01772 
01773 void zzcreateIntConstant(char* const & buf, const char* const & typeName, 
01774                        const int& i)
01775 { sprintf(buf, "C@%s@%d", typeName, i); }
01776 
01777   // Checks all types of domain if C@type@intStr is in domain
01778 bool isIntConstant(const int& i, const Domain* const & domain)
01779 {
01780   const Array<const char*>* typeNames = domain->getTypeNames();
01781   for (int j = 0; j < typeNames->size(); j++)
01782   {
01783         char constName[100];
01784         zzcreateIntConstant(constName, (*typeNames)[j], i);
01785         if (domain->isConstant(constName)) 
01786         {
01787           return true;
01788         }
01789   }
01790   return false;
01791 }
01792 
01793   // Returns the first type found to have C@type@intStr as a constant
01794 const char* getIntConstantTypeName(const int& i, const Domain* const & domain)
01795 { 
01796   const Array<const char*>* typeNames = domain->getTypeNames();
01797   for (int j = 0; j < typeNames->size(); j++)
01798   {
01799         char constName[100];
01800         zzcreateIntConstant(constName, (*typeNames)[j], i);
01801         if (domain->getConstantId(constName) >= 0) return (*typeNames)[j];
01802   }
01803   return NULL;
01804 }
01805 
01806 void zzcreateAndCheckNumConstant(const char* const & intStr,
01807                                  const Function* const & func,
01808                                  const Predicate* const & pred,
01809                                  const Domain* const & domain,
01810                                  char* constName)
01811 {
01812   double d = atof(intStr); int i = int(d);
01813   //if (d!=i) zzerr("%s cannot be a term. Only integer terms are allowed",intStr);
01814   
01815   const char* typeName = NULL;
01816   if (func) typeName = func->getTermTypeAsStr(func->getNumTerms());
01817   else      typeName = pred->getTermTypeAsStr(pred->getNumTerms());
01818 
01819   if (typeName == NULL) 
01820   { zzerr("Too many terms for predicate/function"); constName = NULL; return;}
01821 
01822         // If type name is still open, then try to determine it
01823   if (strcmp(typeName, PredicateTemplate::ANY_TYPE_NAME)==0)
01824   {
01825           // Constant may have been previously declared
01826         if (isIntConstant(i, domain))
01827           typeName = getIntConstantTypeName(i, domain);
01828   }
01829 
01830   zzcreateIntConstant(constName, typeName, i);
01831 
01832   char buf[30]; sprintf(buf,"%f",d);
01833   if (zzconstantMustBeDeclared && domain->getConstantId(constName) < 0)
01834     zzerr("Constant %s must be declared before it is used", buf);
01835 }
01836 
01837 
01838   //ASSUMPTION: users don't define truth values of '=' ground preds e.g. A=A
01839 void zzaddGndPredsToDb(Database* const & db)
01840 {
01841     // Add explicit evidence to db
01842   int numPreds = zzdomain->getNumPredicates();
01843   hash_map<int, PredicateHashArray*>::iterator it;
01844   for (int i = 0; i < numPreds; i++)
01845   {
01846     if ((it = zzpredIdToGndPredMap.find(i)) != zzpredIdToGndPredMap.end())
01847     {
01848       PredicateHashArray* predHashArray = (*it).second;
01849       for (int j = 0; j < predHashArray->size(); j++)
01850         db->addEvidenceGroundPredicate((*predHashArray)[j]);
01851 
01852       predHashArray->deleteItemsAndClear();
01853     }
01854     else
01855     {
01856       //  '=' predicates are handled specially by database
01857     }
01858   }
01859 
01860     // If the predicate occurs in the mln with a non-evidence atom, then add
01861     // it to the index in DB
01862     
01863     // Keep track of preds already indexed
01864   Array<Predicate*> indexedPreds;
01865   
01866   for (int i = 0; i < zzmln->getNumClauses(); i++)
01867   {
01868     const Clause* clause = zzmln->getClause(i);
01869       // First check if non-evid. pred is in clause
01870     Array<bool> nonEvidPred(clause->getNumPredicates(), false);
01871     bool oneNonEvidPred = false;
01872     for (int j = 0; j < clause->getNumPredicates(); j++)
01873     {
01874       Predicate* pred = clause->getPredicate(j);
01875       if (!db->isClosedWorld(pred->getId()))
01876       {
01877         nonEvidPred[j] = true;
01878         oneNonEvidPred = true;
01879       }
01880     }
01881 
01882       // If at least one pred is non-evid., then create index for evidence
01883     if (oneNonEvidPred)
01884     {
01885       for (int j = 0; j < clause->getNumPredicates(); j++)
01886       {
01887         if (!nonEvidPred[j])
01888         {
01889           Predicate* pred = clause->getPredicate(j);
01890           if (pred->isEqualPred()) continue;
01891             // Neg. literal means true groundings are added to index which
01892             // already happened above in addEvidenceGroundPredicate
01893           if (!pred->getSense())
01894             continue;
01895 
01896           for (int k = 0; k < indexedPreds.size(); k++)
01897           {
01898             if (indexedPreds[k]->canBeGroundedAs(pred))
01899               continue;
01900           }
01901             // Add all groundings to index
01902           indexedPreds.append(pred);
01903             // Generate groundings to add to index
01904           Array<Predicate*> predArr;
01905           pred->createAllGroundings(zzdomain, predArr);
01906           int numPreds = predArr.size();
01907           for (int l = 0; l < numPreds; l++)
01908           {
01909             Predicate* newPred = predArr[l];
01910             db->addPredToEvidenceIndex(newPred, pred->getSense());
01911             delete newPred;
01912           }
01913         }
01914       }
01915     }
01916   }
01917 
01918   for (unsigned int i = 0; i < zzpredIdToGndPredMap.size(); i++)
01919     delete zzpredIdToGndPredMap[i]; 
01920 }
01921 
01922 
01923 void zzcreateBoolArr(int idx, Array<bool>*& curArray,
01924                      Array<Array<bool>*>& boolArrays)
01925 {  
01926   --idx;
01927 
01928   Array<bool>* copyArray = new Array<bool>(*curArray);
01929 
01930   curArray->append(true);
01931   copyArray->append(false);
01932 
01933   if (idx == 0) 
01934   {
01935     boolArrays.append(curArray);
01936     boolArrays.append(copyArray);
01937   }
01938   else
01939   {
01940     zzcreateBoolArr(idx, curArray, boolArrays);
01941     zzcreateBoolArr(idx, copyArray, boolArrays);
01942   }
01943 }
01944 
01945 
01946   // vs (variable or string) is the name of the constant
01947 void zzaddConstantToDomain(const char* const & vs, const char* const & typeName)
01948 {
01949   //if it is not a string and it does not begin with an uppercase char
01950   //if (vs[0] != '"' && !isupper(vs[0]))
01951   if (!zzisConstant(vs))
01952   {
01953     zzerr("Constant %s must begin in uppercase char or be a \"string\".", vs);
01954     return;
01955   }
01956 
01957   zzassert(typeName != NULL, "expect typeName != NULL");
01958   zzdomain->addConstant(vs, typeName);
01959   //if (id < 0) zzerr("Failed to add constant %s", vs);
01960 }
01961 
01962 
01963 void zzaddConstantToPredFunc(const char* const & constName)
01964 {
01965     //commented out because a constant can be declared with its first appearance
01966   //int constId = zzcheckConstantAndGetId(constName);
01967  
01968   const char* typeName = NULL;
01969   if (zzfunc) typeName = zzfunc->getTermTypeAsStr(zzfunc->getNumTerms());
01970   else
01971   if (zzpred) typeName = zzpred->getTermTypeAsStr(zzpred->getNumTerms());
01972 
01973     // May be continuing after a parse error
01974   if (typeName == NULL) 
01975   {
01976     zzwarn("Wrong number of terms.");
01977     typeName = PredicateTemplate::ANY_TYPE_NAME;
01978   }
01979 
01980   zzaddConstantToDomain(constName, typeName);
01981   int constId = zzdomain->getConstantId(constName);
01982   if (zzfunc) zzfuncAppendConstant(zzfunc, constId, constName);
01983   else if (zzpred) zzpredAppendConstant(zzpred, constId, constName);
01984   else zzexit("No predicate or function is defined.");
01985 }
01986 
01987 
01988 void zztermIsConstant(const char* const & constName,
01989                       const char* const & constStr, const bool& appendToFormula)
01990 {
01991   int constId = zzdomain->getConstantId(constName);
01992     //commented out because a constant can be declared with its first appearance
01993   //if (constId < 0) zzexit("Failed to find constant %s. Have you declared it?",
01994   //                        constName);
01995   if (constId < 0) 
01996   {
01997     const char* typeName = NULL;
01998     if (zzfunc) typeName = zzfunc->getTermTypeAsStr(zzfunc->getNumTerms());
01999     else
02000     if (zzpred) typeName = zzpred->getTermTypeAsStr(zzpred->getNumTerms());
02001 
02002       // May be continuing after a parse error
02003     if (typeName==NULL) 
02004     {
02005       zzwarn("Wrong number of terms.");
02006       typeName=PredicateTemplate::ANY_TYPE_NAME;
02007     }
02008 
02009     zzaddConstantToDomain(constName, typeName);
02010     constId = zzdomain->getConstantId(constName);
02011   }
02012 
02013     //always check zzfunc first, as a function can be found inside a predicate
02014   if (zzfunc != NULL)      
02015   {
02016     zzfuncAppendConstant(zzfunc, constId, constName);
02017     zzpredFuncListObjs.top()->append(constName);
02018   }
02019   else 
02020   if (zzpred != NULL) 
02021   {
02022     zzpredAppendConstant(zzpred, constId, constName);
02023     zzassert(zzpredFuncListObjs.size()==1, 
02024              "expect zzpredFuncListObjs.size()==1");
02025     zzpredFuncListObjs.top()->append(constName);
02026     if (appendToFormula) zzformulaStr.append(constStr);
02027   }
02028   else 
02029     zzexit("No function or predicate to hold constant %s", constName);
02030 }
02031 
02032 
02038 void zzputVariableInPred(const char* varName, const bool& folDbg)
02039 {
02040   if (folDbg >= 1) printf("v_%s ", varName); 
02041 
02042   ++zzfdnumVars;
02043   string newVarName = zzgetNewVarName(varName);
02044       
02045   if (zzpred != NULL) 
02046   {
02047     bool rightNumTerms = true;
02048     bool rightType = true;
02049     int exp, unexp;
02050       
02051       // check that we have not exceeded the number of terms
02052     if ((unexp = zzpred->getNumTerms()) ==
02053         (exp = zzpred->getTemplate()->getNumTerms()))
02054     {
02055       rightNumTerms = false;
02056       zzerr("Wrong number of terms for predicate %s. "
02057             "Expected %d but given %d", zzpred->getName(), exp, unexp+1);
02058     }
02059         
02060     int varId = -1;
02061     if (rightNumTerms)
02062     {
02063         // check that the variable is of the right type
02064       int typeId = zzpred->getTermTypeAsInt(zzpred->getNumTerms());
02065       rightType = zzcheckRightTypeAndGetVarId(typeId, newVarName.c_str(), varId);
02066     }
02067       
02068     if (rightNumTerms && rightType)
02069     {
02070       zzpred->appendTerm(new Term(varId, (void*)zzpred, true));
02071       zzpredFuncListObjs.top()->append(newVarName.c_str());
02072       //zzformulaStr.append(varName);
02073     }
02074   }
02075   else 
02076     zzexit("No function or predicate to hold variable %s",varName);
02077 }
02078         
02079 
02080 void zztermIsVariable(const bool& folDbg)
02081 {
02082   const char* varName = zztokenList.removeLast();
02083   
02084     // if it is a constant (starts in uppercase or a string)
02085   if (zzisConstant(varName)) 
02086   {
02087     if (folDbg >= 1) printf("c2_%s ", varName); 
02088     
02089     if (zzconstantMustBeDeclared)
02090       zzerr("Constant %s must be declared before it is used", varName);
02091     zztermIsConstant(varName, varName, true);
02092     delete [] varName;
02093   }
02094   else
02095   {   //we are dealing with a variable that begins in lowercase    
02096     if (folDbg >= 1) printf("v_%s ", varName); 
02097     
02098     ++zzfdnumVars;
02099     string newVarName = zzgetNewVarName(varName);
02100     
02101       //always check zzfunc first, as a function can be found inside a predicate
02102     if (zzfunc != NULL)      
02103     {
02104       bool rightNumTerms = true;
02105       bool rightType = true;
02106       int exp, unexp;
02107       
02108         // check that we have not exceeded the number of terms
02109       if ((unexp = zzfunc->getNumTerms()) ==
02110           (exp = zzfunc->getTemplate()->getNumTerms()))
02111       {
02112         rightNumTerms = false;
02113         zzerr("Wrong number of terms for function %s. "
02114               "Expected %d but given %d", zzfunc->getName(), exp, unexp+1);
02115       }
02116       
02117       int varId = -1;      
02118       if (rightNumTerms)
02119       {
02120           // check that the variable is of the right type
02121         int typeId = zzfunc->getTermTypeAsInt(zzfunc->getNumTerms());
02122         rightType = zzcheckRightTypeAndGetVarId(typeId, newVarName.c_str(),
02123                                                 varId);
02124       }
02125 
02126       if (rightNumTerms && rightType)
02127       {
02128         zzfunc->appendTerm(new Term(varId, (void*)zzfunc, false));
02129         zzpredFuncListObjs.top()->append(newVarName.c_str());
02130         //zzformulaStr.append(varName);
02131       }
02132     }
02133     else 
02134     if (zzpred != NULL) 
02135     {
02136       bool rightNumTerms = true;
02137       bool rightType = true;
02138       int exp, unexp;
02139       
02140         // check that we have not exceeded the number of terms
02141       if ((unexp = zzpred->getNumTerms()) ==
02142           (exp = zzpred->getTemplate()->getNumTerms()))
02143       {
02144         rightNumTerms = false;
02145         zzerr("Wrong number of terms for predicate %s. "
02146               "Expected %d but given %d", zzpred->getName(), exp, unexp+1);
02147       }
02148       
02149       int varId = -1;
02150       if (rightNumTerms)
02151       {         
02152           // check that the variable is of the right type
02153         int typeId = zzpred->getTermTypeAsInt(zzpred->getNumTerms());
02154         rightType = zzcheckRightTypeAndGetVarId(typeId, newVarName.c_str(),
02155                                                 varId);
02156       }
02157       
02158       if (rightNumTerms && rightType)
02159       {
02160         zzpred->appendTerm(new Term(varId, (void*)zzpred, true));
02161         if (zzpredFuncListObjs.size() != 1) 
02162           zzerr("There may be a parse error. Have you declared all the "
02163                 "predicates and functions?");
02164         zzpredFuncListObjs.top()->append(newVarName.c_str());
02165         zzformulaStr.append(varName);
02166       }
02167     }
02168     else 
02169       zzexit("No function or predicate to hold variable %s",varName);
02170 
02171 
02172     if (zzisPlus) 
02173     {
02174       //zzisPlus = false; //commented out: set to false in not: rule
02175         // if variable is explicitly universally/existentially quantified
02176       if (!zzvarIsQuantified(varName)) // use the old var name
02177       {
02178           // we'll set it to the actual type when the entire formula is seen
02179         zzplusVarMap[newVarName] =  zzanyTypeId;
02180       }
02181       else
02182         zzerr("the '+' operator cannot be applied to variable %s that is "
02183               "explicitly universally/existentially quantified", varName);
02184     }
02185     delete [] varName;
02186   } //else we are dealing with a variable that begins in lowercase
02187 }
02188 
02189 
02190 
02191 void zzcleanUp()
02192 {
02193   zzeqPredList.clear();
02194   zzintPredList.clear();
02195   zzintFuncList.clear();
02196   while (!zzinStack.empty()) zzinStack.pop(); 
02197   zzvarNameToIdMap.clear();
02198   zzfuncToFuncVarMap.clear();
02199   zzoldNewVarList.clear();
02200   zzplusVarMap.clear();
02201   zztokenList.deleteContentsAndClear();
02202   while (!zzfuncStack.empty()) zzfuncStack.pop();
02203   while (!zzfuncConjStack.empty()) zzfuncConjStack.pop();
02204   while (!zzformulaListObjs.empty()) 
02205   {
02206     ListObj* top = zzformulaListObjs.top();
02207     zzformulaListObjs.pop();
02208     delete top;
02209   }
02210   while (!zzpredFuncListObjs.empty()) 
02211   {
02212     ListObj* top = zzpredFuncListObjs.top();
02213     zzpredFuncListObjs.pop();
02214     delete top;
02215   }
02216     //PredicateHashArray and contents deleted in zzaddGndPredsToDb()
02217   zzpredIdToGndPredMap.clear();
02218   zzformulaInfos.clear();
02219 }
02220 
02221 
02222 void zzinit()
02223 {
02224   zzafterRtParen = false;
02225   zzcount = 0;
02226   zzline = 0;
02227   zzcolumn = -1;
02228   zznumCharRead = 0;
02229   zznumErrors = 0;
02230   zzok = true;
02231   zzmln = NULL;
02232   zzdomain = NULL;
02233   zznumEofSeen = 0;
02234   zzeqTypeCounter = 0;
02235   zzintPredTypeCounter = 0;
02236   zzintFuncTypeCounter = 0;
02237   zzanyTypeId = -1;
02238   zzerrMsg[0] = '\0';
02239   zzfdfuncConstants.clear();
02240   zzusingLinkedFunctions = false;
02241   zztmpReturnNum = false;
02242   
02243   // Add internal predicates
02244   Array<const char*>* pred;
02245   pred = new Array<const char*>;
02246   pred->append("greaterThan");
02247   //pred->append("int");
02248   //pred->append("int");
02249   pred->append(PredicateTemplate::ANY_TYPE_NAME);
02250   pred->append(PredicateTemplate::ANY_TYPE_NAME);
02251   zzinternalPredicates.append(*pred);
02252   delete pred;
02253   
02254   pred = new Array<const char*>;
02255   pred->append("lessThan");
02256   //pred->append("int");
02257   //pred->append("int");
02258   pred->append(PredicateTemplate::ANY_TYPE_NAME);
02259   pred->append(PredicateTemplate::ANY_TYPE_NAME);
02260   zzinternalPredicates.append(*pred);
02261   delete pred;
02262 
02263   pred = new Array<const char*>;
02264   pred->append("greaterThanEq");
02265   //pred->append("int");
02266   //pred->append("int");
02267   pred->append(PredicateTemplate::ANY_TYPE_NAME);
02268   pred->append(PredicateTemplate::ANY_TYPE_NAME);
02269   zzinternalPredicates.append(*pred);
02270   delete pred;
02271   
02272   pred = new Array<const char*>;
02273   pred->append("lessThanEq");
02274   //pred->append("int");
02275   //pred->append("int");
02276   pred->append(PredicateTemplate::ANY_TYPE_NAME);
02277   pred->append(PredicateTemplate::ANY_TYPE_NAME);
02278   zzinternalPredicates.append(*pred);
02279   delete pred;
02280 
02281   pred = new Array<const char*>;
02282   pred->append("substr");
02283   //pred->append("string");
02284   //pred->append("string");
02285   pred->append(PredicateTemplate::ANY_TYPE_NAME);
02286   pred->append(PredicateTemplate::ANY_TYPE_NAME);
02287   zzinternalPredicates.append(*pred);
02288   delete pred;
02289 
02290   // Add internal functions
02291   Array<const char*>* func;
02292 
02293   func = new Array<const char*>;
02294   func->append("succ");
02295   //func->append("int"); //return type
02296   //func->append("int");
02297   func->append(PredicateTemplate::ANY_TYPE_NAME);
02298   func->append(PredicateTemplate::ANY_TYPE_NAME);
02299   zzinternalFunctions.append(*func);
02300   delete func;
02301   
02302   func = new Array<const char*>;
02303   func->append("plus");
02304   //func->append("int"); //return type
02305   //func->append("int");
02306   //func->append("int");
02307     // return type
02308   func->append(PredicateTemplate::ANY_TYPE_NAME);
02309   func->append(PredicateTemplate::ANY_TYPE_NAME);
02310   func->append(PredicateTemplate::ANY_TYPE_NAME);
02311   zzinternalFunctions.append(*func);
02312   delete func;
02313 
02314   func = new Array<const char*>;
02315   func->append("minus");
02316   //func->append("int"); //return type
02317   //func->append("int");
02318   //func->append("int");
02319     // return type
02320   func->append(PredicateTemplate::ANY_TYPE_NAME);
02321   func->append(PredicateTemplate::ANY_TYPE_NAME);
02322   func->append(PredicateTemplate::ANY_TYPE_NAME);
02323   zzinternalFunctions.append(*func);
02324   delete func;
02325 
02326   func = new Array<const char*>;
02327   func->append("times");
02328   //func->append("int"); //return type
02329   //func->append("int");
02330   //func->append("int");
02331     // return type
02332   func->append(PredicateTemplate::ANY_TYPE_NAME);
02333   func->append(PredicateTemplate::ANY_TYPE_NAME);
02334   func->append(PredicateTemplate::ANY_TYPE_NAME);
02335   zzinternalFunctions.append(*func);
02336   delete func;
02337 
02338   func = new Array<const char*>;
02339   func->append("dividedBy");
02340   //func->append("int"); //return type
02341   //func->append("int");
02342   //func->append("int");
02343     // return type
02344   func->append(PredicateTemplate::ANY_TYPE_NAME);
02345   func->append(PredicateTemplate::ANY_TYPE_NAME);
02346   func->append(PredicateTemplate::ANY_TYPE_NAME);
02347   zzinternalFunctions.append(*func);
02348   delete func;
02349 
02350   func = new Array<const char*>;
02351   func->append("mod");
02352   //func->append("int"); //return type
02353   //func->append("int");
02354   //func->append("int");
02355     // return type
02356   func->append(PredicateTemplate::ANY_TYPE_NAME);
02357   func->append(PredicateTemplate::ANY_TYPE_NAME);
02358   func->append(PredicateTemplate::ANY_TYPE_NAME);
02359   zzinternalFunctions.append(*func);
02360   delete func;
02361 
02362   func = new Array<const char*>;
02363   func->append("concat");
02364   //func->append("string"); //return type
02365   //func->append("string");
02366   //func->append("string");
02367     // return type
02368   func->append(PredicateTemplate::ANY_TYPE_NAME);
02369   func->append(PredicateTemplate::ANY_TYPE_NAME);
02370   func->append(PredicateTemplate::ANY_TYPE_NAME);
02371   zzinternalFunctions.append(*func);
02372   delete func;
02373 }
02374 
02375 
02376 void zzreset()
02377 {
02378   zzvarCounter = 0;
02379   zzscopeCounter = 0;
02380   zzoldNewVarList.clear();
02381   zzvarNameToIdMap.clear();
02382   zzfuncToFuncVarMap.clear();
02383   zzplusVarMap.clear();
02384   zzeqPredList.clear();
02385   zzintPredList.clear();
02386   zzintFuncList.clear();
02387 
02388   zztypeName = NULL;
02389   zzpredTemplate = NULL;
02390   zzfuncTemplate = NULL;
02391   zzpred = NULL;
02392   zzfunc = NULL;
02393   while (!zzfuncStack.empty()) zzfuncStack.pop();
02394   while (!zzfuncConjStack.empty()) zzfuncConjStack.pop();
02395   if (zzwt) { delete zzwt; zzwt = NULL; }
02396   zzisNegated = false;
02397   zzisAsterisk = false;
02398   zzisPlus = false;
02399   zzhasFullStop = false;
02400   zzinIndivisible = false;
02401   zznumAsterisk = 0;
02402   zztrueFalseUnknown = 't';
02403   zzformulaStr.clear();
02404   zzfuncConjStr.clear();
02405   zzparseGroundPred = false;
02406   while (!zzformulaListObjs.empty()) 
02407   {
02408     ListObj* top = zzformulaListObjs.top();
02409     zzformulaListObjs.pop();
02410     delete top;
02411   }
02412   while (!zzpredFuncListObjs.empty()) 
02413   {
02414     ListObj* top = zzpredFuncListObjs.top();
02415     zzpredFuncListObjs.pop();
02416     delete top;
02417   }
02418   while (!zzfuncStack.empty()) zzfuncStack.pop();
02419   while (!zzfuncConjStack.empty()) zzfuncConjStack.pop();
02420 
02421   zzfdnumPreds = 0;
02422   zzfdnumFuncs = 0;
02423   zzfdnumVars = 0;
02424 //  zzfdisEqualPred = false;
02425   zzfdfuncName.clear();
02426   zzfdfuncConstants.clear();
02427   zzfdconstName.clear();
02428   zztmpReturnNum = false;
02429   zzinfixPredName = NULL;
02430   zzinfixFuncName = NULL;
02431 }
02432 
02433 
02434 string zzappend(const char* const & s, const int& i)
02435 {
02436   char buf[16];
02437   sprintf(buf,"%d",i);
02438   string str;
02439   return str.append(s).append(buf);
02440 }
02441 
02442 string zzappendWithUnderscore(const char* const & s, const int& i)
02443 {
02444   char buf[16];
02445   sprintf(buf,"%d",i);
02446   string str;
02447   return str.append(s).append("_").append(buf);
02448 }
02449 
02450 void zzcheckAllTypesHaveConstants(const Domain* const & domain)
02451 {
02452   const Array<const char*>* types = domain->getTypeNames();
02453   for (int i = 0; i < types->size(); i++)
02454   {
02455     if (strcmp((*types)[i],PredicateTemplate::ANY_TYPE_NAME)==0) continue;
02456     if (strcmp((*types)[i],PredicateTemplate::INT_TYPE_NAME)==0) continue;
02457     if (strcmp((*types)[i],PredicateTemplate::STRING_TYPE_NAME)==0) continue;
02458     if (domain->getNumConstantsByType((*types)[i]) <= 0)
02459       zzerr("type %s has no constant. A type must have at least one constant",
02460             (*types)[i]);
02461   }
02462 }
02463 
02464 
02465 void zzfillClosedWorldArray(Array<bool>& isClosedWorldArr,
02466                             const bool& allPredsExceptQueriesAreClosedWorld,
02467                             const StringHashArray* const & openWorldPredNames,
02468                             const StringHashArray* const & closedWorldPredNames,
02469                             const StringHashArray* const & queryPredNames)
02470 {
02471   if (queryPredNames)
02472   {
02473     for (int i = 0; i < queryPredNames->size(); i++) 
02474     {
02475       const char* predName = (*queryPredNames)[i].c_str();
02476       const PredicateTemplate* pt = zzdomain->getPredicateTemplate(predName);
02477       if (pt == NULL) 
02478       {
02479         zzerr("Query predicate %s is not found. Please declare it. "
02480               "Note that '!' and '?' should not be used with query predicates.",
02481               predName);
02482         continue;
02483       }
02484       if (pt->isEqualPredicateTemplate())
02485       {
02486         zzerr("'=' predicate cannot be a query predicate()");
02487         exit(-1);
02488       }
02489     }
02490   }
02491 
02492   int numPreds = zzdomain->getNumPredicates();
02493   isClosedWorldArr.growToSize(numPreds, true);
02494   if (!allPredsExceptQueriesAreClosedWorld)
02495   {
02496       // If a predicate has no evidence atoms, it is open-world (unless it's in
02497       // cwPredNames), if it has evidence atoms, it is closed-world (unless it's
02498       // in owPredNames).
02499     for (int i = 0; i < numPreds; i++)
02500     {
02501       hash_map<int, PredicateHashArray*>::iterator it;
02502       for (int i = 0; i < numPreds; i++)
02503       {
02504         if ((it = zzpredIdToGndPredMap.find(i)) != zzpredIdToGndPredMap.end())
02505         {
02506             // At least one evidence grounding is present
02507           isClosedWorldArr[i] = true;
02508         }
02509         else
02510         {
02511             // equality and internal predicates are handled specially by
02512             // database
02513           const PredicateTemplate* pt = zzdomain->getPredicateTemplate(i);          
02514           if (!pt->isEqualPredicateTemplate() &&
02515               !pt->isInternalPredicateTemplate())
02516             isClosedWorldArr[i] = false;
02517           else
02518             isClosedWorldArr[i] = true;
02519         }
02520       }
02521     }  
02522   }
02523   
02524     // Force these to be open-world
02525   if (openWorldPredNames)
02526   {
02527     for (int i = 0; i < openWorldPredNames->size(); i++) 
02528     {
02529       const char* predName = (*openWorldPredNames)[i].c_str();
02530       int predId = zzdomain->getPredicateId(predName);
02531       isClosedWorldArr[predId] = false;
02532     }
02533   }
02534     // Force these to be closed-world
02535   if (closedWorldPredNames)
02536   {
02537     for (int i = 0; i < closedWorldPredNames->size(); i++) 
02538     {
02539       const char* predName = (*closedWorldPredNames)[i].c_str();
02540       int predId = zzdomain->getPredicateId(predName);
02541       isClosedWorldArr[predId] = true;
02542     }
02543   } 
02544     // Queries are always open-world
02545   if (queryPredNames)
02546   {
02547     for (int i = 0; i < queryPredNames->size(); i++) 
02548     {
02549       const char* predName = (*queryPredNames)[i].c_str();
02550       int predId = zzdomain->getPredicateId(predName);
02551       isClosedWorldArr[predId] = false;
02552     }
02553   }
02554 }
02555 
02556 
02557 void zzappendUnitClausesToMLN(const Domain* const & domain, MLN* const & mln,
02558                               const double& defaultWt )
02559 {
02560   for (int i = 0; i < domain->getNumPredicates(); i++)
02561   {
02562     Predicate* pred = domain->createPredicate(i, false);
02563     if (pred == NULL) continue;
02564     Clause* clause = ClauseFactory::createUnitClause(pred, false);
02565     delete pred;
02566 
02567     if (clause == NULL) continue;
02568     if (mln->containsClause(clause)) { delete clause; continue; }
02569 
02570     int idx;
02571     ostringstream oss;
02572     clause->getPredicate(0)->getTemplate()->printWithStrVar(oss);
02573     bool app = mln->appendClause(oss.str(), false, clause, defaultWt, false,
02574                                  idx, false);
02575     if (app)
02576     {
02577       mln->setFormulaNumPreds(oss.str(), 1);
02578       mln->setFormulaIsHard(oss.str(), false);
02579       mln->setFormulaPriorMean(oss.str(), defaultWt);
02580     }
02581   }
02582 }
02583 
02584 
02585 void zzappendFormulaClausesToMLN(const ListObj* const & formula,
02586                                  const string& formulaStr, 
02587                                  const int& numPreds,
02588                                  const double* const & wt,
02589                                  const double& defaultWt,
02590                                  const Domain* const & domain,
02591                                  MLN* const & mln,
02592                                  const ZZVarNameToIdMap& varNameToIdMap,
02593                                  const StringToIntMap& plusVarMap,
02594                                  const int& numAsterisk,
02595                                  const bool& hasFullStop,
02596                                  const bool& readHardClauseWts,
02597                                  const bool& mustHaveWtOrFullStop,
02598                                  const bool& isIndivisible,
02599                                  Array<int>& hardClauseIdxs,
02600                                  Array<string>& hardFormulas,
02601                                  Clause*& flippedClause,
02602                                  const Domain* const & domain0)
02603 {
02604   //cout << "orig formula = " << endl << "\t: " << formulaStr << endl;    
02605   //cout << "formula      = " << endl << "\t: " << *formula << endl;
02606 
02607   VarTypeMap* vtMap = zzcreateVarTypeMap(varNameToIdMap);
02608   Array<ListObj*> formulas;
02609   Array<string> formulaStrs;
02610   zzgroundPlusVar(formula, formulaStr, plusVarMap, formulas, formulaStrs, 
02611                   domain, domain0);
02612   delete formula;
02613 
02614   for (int f = 0; f < formulas.size(); f++)
02615   {
02616     //cout<<"formula (after gnding '+')= "<<endl<<"\t: "<< *(formulas[f])<<endl;
02617 
02618     Array<ListObj*> formulas2;
02619     Array<string> formulaStrs2;
02620     zzpermuteAsteriskedPreds(numAsterisk, formulas[f], formulaStrs[f], 
02621                              formulas2, formulaStrs2);
02622     delete formulas[f];    
02623 
02624     for (int g = 0; g < formulas2.size(); g++)
02625     {
02626       string formStr = formulaStrs2[g];
02627 
02628       //cout << "formula (after *) " << endl << "\t: " << *(formulas2[g])<<endl;
02629       ListObj* vars = new ListObj;
02630       bool hasExist = false;
02631       ListObj* cnf = ListObj::toCNF(formulas2[g], vars, domain, vtMap, hasExist);
02632       delete formulas2[g];
02633       //cout << "cnf = " << endl << "\t: " << *cnf << endl;
02634 
02635       cnf->cleanUpVars();
02636       //cout << "cnf (after cleanUp) = " << endl << "\t: " << *cnf << endl;
02637       
02638       //commented out: not likely for there to be redundant clauses and is slow
02639       //replaced with removeRedundantPredicates()
02640       //cnf->removeRedundantClauses();
02641 
02642       cnf->removeRedundantPredicates();
02643       //cout << "cnf (removed redundant preds) = " <<endl<<"\t: "<<*cnf<<endl;
02644 
02645       Array<Clause*> clauses;
02646       zzcreateClauses(cnf, clauses, flippedClause);
02647 
02648         // Output message of cnf size only if more than one
02649       if (clauses.size() > 1)
02650         cout << "\tCNF has  " << clauses.size() << " clauses" << endl;
02651 
02652       delete cnf; delete vars;
02653 
02654       double perClauseWt = 0;
02655       double formulaWt = 0;
02656       bool setHardWtLater = false;
02657 
02658       if (hasFullStop) // if this is a hard clause/formula
02659       {
02660         assert(wt == NULL);
02661         if (readHardClauseWts)
02662         {
02663           if (wt) 
02664           { perClauseWt = (*wt)/clauses.size(); formulaWt = (*wt); }
02665           else    
02666           {   //set weight later to twice of max soft clause wt
02667             perClauseWt = 1; formulaWt = 1; 
02668             hardFormulas.append(formStr);
02669             setHardWtLater = true;
02670           }                   
02671         }
02672         else
02673         {   //set later to twice of max soft clause wt         
02674           perClauseWt = 1; formulaWt = 1;
02675           hardFormulas.append(formStr);
02676           setHardWtLater = true;
02677         }
02678       }
02679       else
02680       if (wt)
02681       { perClauseWt = (*wt)/clauses.size(); formulaWt = *wt; }
02682       else
02683       {
02684         if (mustHaveWtOrFullStop)
02685           zzerr("a weight or full stop must be specified for:\n%s",
02686                 formStr.c_str());
02687         perClauseWt = defaultWt/clauses.size();
02688         formulaWt = defaultWt;
02689       }
02690 
02691       
02692       for (int i = 0; i < clauses.size(); i++)
02693       {
02700         double clauseWt = perClauseWt;
02701         if (flippedClause && flippedClause == clauses[i] 
02702             && zzflipWtsOfFlippedClause)
02703           clauseWt = -clauseWt;
02704 
02705         int prevIdx;
02706         bool ok = mln->appendClause(formStr, hasExist, clauses[i], 
02707                                     clauseWt, hasFullStop, prevIdx,
02708                                     isIndivisible);
02709 
02710         if (!ok)
02711         {
02712           cout << "\tsame clause (derived from another formula) has been added "
02713                << "to MLN:\n\t"; 
02714           const Clause* cl = mln->getClause(prevIdx);          
02715           cl->printWithoutWt(cout,domain); cout << endl;
02716           //cout << " derived from current formula:\n\t" << formStr << endl;
02717         }
02718 
02719         if (setHardWtLater) hardClauseIdxs.append(prevIdx);
02720       }
02721 
02722       mln->setFormulaNumPreds(formStr, numPreds);
02723       mln->setFormulaPriorMean(formStr, formulaWt);
02724       mln->setFormulaWt(formStr, formulaWt);
02725       mln->setFormulaIsHard(formStr, hasFullStop);      
02726 
02727     } //for (int g = 0; g < formulas2.size(); g++)
02728   }//for (int f = 0; f < formulas.size(); f++)
02729   delete vtMap;
02730 }
02731 
02732 
02733 void zzappendFormulasToMLN(Array<ZZFormulaInfo*>& formulaInfos, 
02734                            MLN* const & mln, const Domain* const & domain0)
02735 {
02736   cout << "converting to CNF:" << endl;
02737 
02738   Array<int> hardClauseIdxs;
02739   Array<string> hardFormulas;
02740   Clause* flippedClause = NULL;
02741 
02742   for (int i = 0; i < formulaInfos.size(); i++)
02743   {
02744     double startSec = zztimer.time();
02745     ZZFormulaInfo* epfi = formulaInfos[i];
02746     cout << "formula " << i << ": " << epfi->formulaStr << endl;
02747     assert(mln == epfi->mln);
02748     zzappendFormulaClausesToMLN(epfi->formula, epfi->formulaStr, epfi->numPreds,
02749                                 epfi->wt, epfi->defaultWt, epfi->domain,
02750                                 epfi->mln, epfi->varNameToIdMap,
02751                                 epfi->plusVarMap, epfi->numAsterisk,
02752                                 epfi->hasFullStop,
02753                                 epfi->readHardClauseWts,
02754                                 epfi->mustHaveWtOrFullStop,
02755                                 epfi->isIndivisible,
02756                                 hardClauseIdxs, hardFormulas, 
02757                                 flippedClause, domain0);
02758     delete epfi;
02759     cout<<"CNF conversion took ";Timer::printTime(cout,zztimer.time()-startSec);
02760     cout<<endl;
02761   }
02762   formulaInfos.clear();
02763 
02764   //set the weights of hard clauses
02765   double maxSoftWt = mln->getMaxAbsSoftWt();
02766   if (maxSoftWt == 0) maxSoftWt = 1;
02767 
02768   double hardWt = (HARD_WEIGHT==DBL_MIN) ?  HARD_WEIGHT_MULTIPLIER * maxSoftWt 
02769                                           : HARD_WEIGHT;
02770 
02771   for (int i = 0; i < hardClauseIdxs.size(); i++)
02772   {
02779     double hhardWt = hardWt;
02780     /*
02781     if (flippedClause && 
02782         //flippedClause->same( (Clause*)mln->getClause(hardClauseIdxs[i]) )
02783         flippedClause == (Clause*)mln->getClause(hardClauseIdxs[i])
02784         && zzflipWtsOfFlippedClause)
02785       hhardWt = -hhardWt;
02786     */
02787     
02788       // Weight has been flipped when added to mln. So, if weight
02789       // is neg. and marked as hard, then need to flip hard weight
02790     if (zzflipWtsOfFlippedClause &&
02791         ((Clause*)mln->getClause(hardClauseIdxs[i]))->getWt() < 0)
02792       hhardWt = -hhardWt;
02793           
02794     ((Clause*)mln->getClause(hardClauseIdxs[i]))->setWt(hhardWt);
02795   }
02796 
02797   for (int i = 0; i < hardFormulas.size(); i++)
02798   {
02799     mln->setFormulaWt(hardFormulas[i], hardWt);
02800     mln->setFormulaPriorMean(hardFormulas[i], hardWt);
02801   }
02802 }
02803 
02804 
02805 void zzsigHandler(int signo)
02806 {
02807   if (zznumErrors > 0) printf("Num of errors detected = %d\n", zznumErrors);
02808   if (zzisParsing)
02809     printf("UNRECOVERABLE ERROR in %s: line %d, col %d\n", 
02810            rmTmpPostfix(zzinFileName).c_str(), zzline, zzcolumn);
02811   else
02812     printf("UNRECOVERABLE ERROR after parsing %s\n", 
02813            rmTmpPostfix(zzinFileName).c_str());
02814 
02815   zzok = false;
02816   signal(signo,SIG_DFL);
02817 }
02818 
02827 void zzcompileFunctions(const char* fileName)
02828 {
02829   ifstream infs;
02830   ofstream outfs;
02831 
02832   // First remove any old .so file
02833   char* removeso;
02834   removeso = (char *)malloc((strlen("rm -f ") +
02835                                                         strlen(ZZ_FUNCTION_SO_FILE) + 1)*sizeof(char));
02836   strcpy(removeso, "rm -f ");
02837   strcat(removeso, ZZ_FUNCTION_SO_FILE);
02838   system(removeso);
02839 
02840   // If .so file is still there, then exit  
02841   infs.open(ZZ_FUNCTION_SO_FILE, ifstream::in);
02842   infs.close();
02843   if(!infs.fail())
02844   {
02845         infs.clear(ios::failbit);
02846         cout << "Unable to remove " << ZZ_FUNCTION_SO_FILE << endl;
02847         exit(-1);
02848   }
02849   
02850   // Compile the file
02851   char* systemcall;
02852   systemcall = (char *)malloc((strlen("g++ -fPIC -shared -o ") +
02853                                                                 strlen(ZZ_FUNCTION_SO_FILE) +
02854                                                                 strlen(" ") +
02855                                                                 strlen(fileName) + 1)*sizeof(char));
02856   strcpy(systemcall, "g++ -fPIC -shared -o ");
02857   strcat(systemcall, ZZ_FUNCTION_SO_FILE);
02858   strcat(systemcall, " ");
02859   strcat(systemcall, fileName);
02860   system(systemcall);
02861   
02862   // If .so file is not there, then exit  
02863   infs.open(ZZ_FUNCTION_SO_FILE, ifstream::in);
02864   infs.close();
02865   if(infs.fail())
02866   {
02867         infs.clear(ios::failbit);
02868         cout << "Could not compile function file " << fileName << endl;
02869         exit(-1);
02870   }
02871   return;
02872 }
02873 
02874 
02892 void zzinsertPermutationOfLinkedFunction(const Domain* const & domain,
02893                                          void* funccall,
02894                                          const FunctionTemplate* ftemplate,
02895                                          int numTerms,
02896                                          Array<int>* currentConstants)
02897 {
02898   string retString;
02899   string arguments[numTerms];
02900   string argumentsAsNum[numTerms];
02901   
02902   // Find the arguments for the function according to currentConstants
02903   for (int i = 0; i < numTerms; i++)
02904   {
02905     const Array<int>* constantsByType =
02906       domain->getConstantsByType(ftemplate->getTermTypeAsInt(i));
02907 
02908     arguments[i] =
02909       domain->getConstantName((*constantsByType)[((*currentConstants)[i])]);
02910         // If constant is a number, then we have to cut it out of the string
02911     // C@Type@Number
02912     unsigned int at = arguments[i].rfind("@");
02913     if (at != string::npos)
02914       argumentsAsNum[i] = arguments[i].substr(at+1, arguments[i].length()-at-1);
02915     else argumentsAsNum[i] = arguments[i];
02916   }
02917   
02918   // Make the function call (max. 5 arguments)
02919   switch (numTerms)
02920   {
02921     case 0:
02922       retString = (*(string (*)())(funccall))();
02923       break;
02924     case 1:
02925       retString = (*(string (*)(string))(funccall))(argumentsAsNum[0]);
02926       break;
02927     case 2:
02928       retString = (*(string (*)(string, string))(funccall))
02929                     (argumentsAsNum[0], argumentsAsNum[1]);
02930       break;
02931     case 3:
02932       retString = (*(string (*)(string, string, string))(funccall))
02933                     (argumentsAsNum[0], argumentsAsNum[1], argumentsAsNum[2]);
02934       break;
02935     case 4:
02936       retString = (*(string (*)(string, string, string, string))(funccall))
02937                     (argumentsAsNum[0], argumentsAsNum[1], argumentsAsNum[2],
02938                      argumentsAsNum[3]);
02939       break;
02940     case 5:
02941       retString = (*(string (*)(string, string, string, string, string))
02942                     (funccall))
02943                     (argumentsAsNum[0], argumentsAsNum[1], argumentsAsNum[2],
02944                      argumentsAsNum[3], argumentsAsNum[4]);
02945       break;
02946     default:
02947       cout << "Linked-in functions can take max. 5 arguments\n" << endl;
02948       return;    
02949   }
02950 
02951   // If a number is returned, then we have to make a constant out of it
02952   int i;
02953   istringstream iss(retString);
02954   char constName[1000];
02955   if (iss>>i) // We are dealing with an integer
02956     zzcreateIntConstant(constName, ftemplate->getRetTypeName(), i);
02957   else
02958     strcpy(constName, retString.c_str());
02959 
02960   // The return value has to be an existing constant of the return type
02961   int constantId = domain->getConstantId(constName);
02962   const Array<int>* returnConstants =
02963     domain->getConstantsByType(ftemplate->getRetTypeId());
02964   
02965   if (returnConstants->contains(constantId))
02966   {
02967       // Insert the function definition just created  
02968       // Predicate name is PredicateTemplate::ZZ_RETURN_PREFIX + function name
02969     char* predName;
02970     predName = (char *)malloc((strlen(PredicateTemplate::ZZ_RETURN_PREFIX) +
02971                                strlen(ftemplate->getName()) + 1)*sizeof(char));
02972     strcpy(predName, PredicateTemplate::ZZ_RETURN_PREFIX);
02973     strcat(predName, ftemplate->getName());
02974     zzcreatePred(zzpred, predName);
02975     zzpred->setTruthValue(TRUE);
02976 
02977       //Add return constant to predicate
02978     zzpredAppendConstant(zzpred, constantId, constName);
02979       //Add constant terms to predicate
02980     for (int i = 0; i < numTerms; i++)
02981     {
02982       const char* term = arguments[i].c_str();
02983       int constId = domain->getConstantId(term);
02984       zzpredAppendConstant(zzpred, constId, term);
02985     }
02986         
02987     zzcheckPredNumTerm(zzpred);
02988     int predId = zzpred->getId();
02989 
02990       // Insert mapping of grounding
02991     hash_map<int,PredicateHashArray*>::iterator it;
02992     if ((it=zzpredIdToGndPredMap.find(predId)) == zzpredIdToGndPredMap.end())
02993       zzpredIdToGndPredMap[predId] = new PredicateHashArray;
02994 
02995 //cout << "Mapping " << endl;
02996 //zzpred->printWithStrVar(cout, zzdomain);
02997 //cout << " " << zzpred->getTruthValue() << endl;
02998   
02999     PredicateHashArray* pha = zzpredIdToGndPredMap[predId];
03000     if (pha->append(zzpred) < 0)
03001     {
03002       int a = pha->find(zzpred);
03003       zzassert(a >= 0, "expecting ground predicate to be found");
03004       string origTvStr = (*pha)[a]->getTruthValueAsStr();
03005       (*pha)[a]->setTruthValue(zzpred->getTruthValue());
03006       string newTvStr = (*pha)[a]->getTruthValueAsStr();
03007 
03008       if (zzwarnDuplicates)
03009       {
03010         ostringstream oss;
03011         oss << "Duplicate ground predicate "; zzpred->print(oss, zzdomain); 
03012         oss << " found. ";
03013         if (origTvStr.compare(newTvStr) != 0)
03014           oss << "Changed its truthValue from " << origTvStr << " to "
03015               << newTvStr << endl;
03016         zzwarn(oss.str().c_str());
03017       }
03018           delete zzpred;
03019     }
03020 
03021     delete [] predName;
03022     zzpred = NULL;
03023   }
03024   //delete returnConstants;
03025 }
03026 
03046 void zzinsertPermutationsOfLinkedFunction(const Domain* const & domain,
03047                                           void* funccall,
03048                                           const FunctionTemplate* ftemplate,
03049                                           int numTerms, int currentTerm,
03050                                           Array<int>* currentConstants)
03051 {
03052   const Array<int>* constants =
03053     domain->getConstantsByType(ftemplate->getTermTypeAsInt(currentTerm));
03054 
03055     // Base case: at the last term
03056   if (currentTerm == numTerms - 1)
03057   {
03058     for (int i = 0; i < constants->size(); i++)
03059     {
03060       (*currentConstants)[currentTerm] = i;
03061       zzinsertPermutationOfLinkedFunction(domain, funccall, ftemplate, numTerms,
03062                                           currentConstants);
03063     }
03064     return;
03065   }
03066   
03067     // Not yet at last term
03068   zzinsertPermutationsOfLinkedFunction(domain, funccall, ftemplate, numTerms,
03069                                        currentTerm + 1, currentConstants);
03070   
03071   if (++(*currentConstants)[currentTerm] < constants->size())
03072     zzinsertPermutationsOfLinkedFunction(domain, funccall, ftemplate, numTerms,
03073                                          currentTerm, currentConstants);
03074 
03075   (*currentConstants)[currentTerm] = 0;
03076   return;
03077 }
03078 
03091 void zzgenerateGroundingsFromLinkedFunction(const Domain* const & domain,
03092                                                                                     const char* funcname,
03093                                                                                     void* handle)
03094 {
03095   char* error;
03096   void* funccall;
03097   
03098     // Obtain functioncall from dynamic library
03099   dlerror();    // Clear any existing error
03100   funccall = dlsym(handle, funcname);
03101   if ((error = dlerror()) != NULL)
03102   {
03103     printf("Error while evaluating function %s\n", funcname);
03104     fprintf (stderr, "dlerror: %s\n", error);
03105     return;
03106   }
03107 
03108     // Find number of terms for function
03109   const FunctionTemplate* ftemplate = domain->getFunctionTemplate(funcname);
03110   int numTerms = ftemplate->getNumTerms();
03111 
03112     // Insert all possible permutations of constants
03113   const Array<int>* termTypes = ftemplate->getTermTypesAsInt();
03114   zzassert(numTerms == termTypes->size(),
03115            "Number of terms and term types in function don't match");
03116   Array<int>* currentConstants = new Array<int>;
03117   for (int i = 0; i < numTerms; i++) currentConstants->append(0);
03118   zzinsertPermutationsOfLinkedFunction(domain, funccall, ftemplate, numTerms, 0,
03119                                        currentConstants);
03120 
03121   return;
03122 }
03123 
03134 void zzgenerateGroundingsFromLinkedFunctions(const Domain* const & domain)
03135 {
03136     // First check if a file with functions exists
03137   void *handle;
03138   char* openFileName;
03139   openFileName = (char *)malloc((strlen("./") +
03140                                  strlen(ZZ_FUNCTION_SO_FILE) + 1)*sizeof(char));
03141   strcpy(openFileName, "./");
03142   strcat(openFileName, ZZ_FUNCTION_SO_FILE);
03143   handle = dlopen(openFileName, RTLD_LAZY);
03144   if (!handle)
03145   {
03146       // Can not open file, so no linked-in functions
03147     printf("No file for linked-in functions found.\n");
03148     fprintf (stderr, "%s\n", dlerror());
03149     dlclose(handle);
03150     return;
03151   }
03152 
03153     // Look at each function
03154   const Array<const char*>* fnames = domain->getFunctionNames();
03155   for (int i = 0; i < fnames->size(); i++)
03156   {
03157       // If it is a linked-in function,
03158       // then generate groundings for each permutation of the given types
03159     if (!zzisInternalFunction((*fnames)[i]) &&
03160         zzisLinkedFunction((*fnames)[i], handle))
03161     {
03162       cout << "Found linked-in function: " << (*fnames)[i] << endl;
03163       zzgenerateGroundingsFromLinkedFunction(domain, (*fnames)[i], handle);
03164     }
03165   }
03166   dlclose(handle);
03167   return;
03168 }
03169 
03170 
03188 void zzinsertPermutationOfLinkedPredicate(const Domain* const & domain,
03189                                           void* funccall,
03190                                           const PredicateTemplate* ptemplate,
03191                                           int numTerms,
03192                                           Array<int>* currentConstants)
03193 {
03194   bool retBool = false;
03195   string arguments[numTerms];
03196   string argumentsAsNum[numTerms];
03197   
03198     // Find the arguments for the predicate according to currentConstants
03199   for (int i = 0; i < numTerms; i++)
03200   {
03201     const Array<int>* constantsByType =
03202       domain->getConstantsByType(ptemplate->getTermTypeAsInt(i));
03203 
03204     arguments[i] =
03205       domain->getConstantName((*constantsByType)[((*currentConstants)[i])]);
03206       // If constant is a number, then we have to cut it out of the string
03207       // C@Type@Number
03208     unsigned int at = arguments[i].rfind("@");
03209     if (at != string::npos)
03210       argumentsAsNum[i] = arguments[i].substr(at+1, arguments[i].length()-at-1);
03211     else argumentsAsNum[i] = arguments[i];
03212   }
03213   
03214     // Make the function call (max. 5 arguments)
03215   switch (numTerms)
03216   {
03217     case 0:
03218       retBool = (*(bool (*)())(funccall))();
03219       break;
03220     case 1:
03221       retBool = (*(bool (*)(string))(funccall))(argumentsAsNum[0]);
03222       break;
03223     case 2:
03224       retBool = (*(bool (*)(string, string))(funccall))
03225                     (argumentsAsNum[0], argumentsAsNum[1]);
03226       break;
03227     case 3:
03228       retBool = (*(bool (*)(string, string, string))(funccall))
03229                     (argumentsAsNum[0], argumentsAsNum[1], argumentsAsNum[2]);
03230       break;
03231     case 4:
03232       retBool = (*(bool (*)(string, string, string, string))(funccall))
03233                     (argumentsAsNum[0], argumentsAsNum[1], argumentsAsNum[2],
03234                      argumentsAsNum[3]);
03235       break;
03236     case 5:
03237       retBool = (*(bool (*)(string, string, string, string, string))(funccall))
03238                     (argumentsAsNum[0], argumentsAsNum[1], argumentsAsNum[2],
03239                      argumentsAsNum[3], argumentsAsNum[4]);
03240       break;
03241     default:
03242       cout << "Linked-in predicates can take max. 5 arguments\n" << endl;
03243       return;    
03244   }
03245   
03246     // Insert the predicate definition just created  
03247   const char* predName;
03248   predName = ptemplate->getName();
03249   //for (int i = 0; i < currentConstants->size(); i++)
03250     //printf("%d ", (*currentConstants)[i]);
03251   zzcreatePred(zzpred, predName);
03252   if (retBool) zzpred->setTruthValue(TRUE);
03253   else zzpred->setTruthValue(FALSE);
03254   
03255     // Add constant terms to predicate
03256   for (int i = 0; i < numTerms; i++)
03257   {
03258     const char* term = arguments[i].c_str();
03259     int constId = domain->getConstantId(term);
03260     zzpredAppendConstant(zzpred, constId, term);
03261   }
03262         
03263   zzcheckPredNumTerm(zzpred);
03264   int predId = zzpred->getId();
03265 
03266     // Insert mapping of grounding
03267   hash_map<int,PredicateHashArray*>::iterator it;
03268   if ((it=zzpredIdToGndPredMap.find(predId)) == zzpredIdToGndPredMap.end())
03269         zzpredIdToGndPredMap[predId] = new PredicateHashArray;
03270   
03271 //cout << "Mapping " << endl;
03272 //zzpred->printWithStrVar(cout, zzdomain);
03273 //cout << " " << zzpred->getTruthValue() << endl;
03274 
03275   PredicateHashArray* pha = zzpredIdToGndPredMap[predId];
03276   if (pha->append(zzpred) < 0)
03277   {
03278     int a = pha->find(zzpred);
03279     zzassert(a >= 0, "expecting ground predicate to be found");
03280     string origTvStr = (*pha)[a]->getTruthValueAsStr();
03281     (*pha)[a]->setTruthValue(zzpred->getTruthValue());
03282     string newTvStr = (*pha)[a]->getTruthValueAsStr();
03283 
03284     if (zzwarnDuplicates)
03285     {
03286       ostringstream oss;
03287       oss << "Duplicate ground predicate "; zzpred->print(oss, zzdomain); 
03288       oss << " found. ";
03289       if (origTvStr.compare(newTvStr) != 0)
03290         oss << "Changed its truthValue from " << origTvStr << " to " << newTvStr
03291             << endl;
03292       zzwarn(oss.str().c_str());
03293     }
03294     delete zzpred;
03295   }
03296   zzpred = NULL;
03297 }
03298 
03318 void zzinsertPermutationsOfLinkedPredicate(const Domain* const & domain,
03319                                            void* funccall,
03320                                            const PredicateTemplate* ptemplate,
03321                                            int numTerms, int currentTerm,
03322                                            Array<int>* currentConstants)
03323 {
03324   const Array<int>* constants =
03325     domain->getConstantsByType(ptemplate->getTermTypeAsInt(currentTerm));
03326 
03327     // Base case: at the last term
03328   if (currentTerm == numTerms - 1)
03329   {
03330     for (int i = 0; i < constants->size(); i++)
03331     {
03332       (*currentConstants)[currentTerm] = i;
03333       zzinsertPermutationOfLinkedPredicate(domain, funccall, ptemplate,
03334                                            numTerms, currentConstants);
03335     }
03336     return;
03337   }
03338   
03339     // Not yet at last term
03340   zzinsertPermutationsOfLinkedPredicate(domain, funccall, ptemplate, numTerms,
03341                                         currentTerm + 1, currentConstants);
03342   
03343   if (++(*currentConstants)[currentTerm] < constants->size())
03344     zzinsertPermutationsOfLinkedPredicate(domain, funccall, ptemplate, numTerms,
03345                                           currentTerm, currentConstants);
03346 
03347   (*currentConstants)[currentTerm] = 0;
03348   return;
03349 }
03350 
03363 void zzgenerateGroundingsFromLinkedPredicate(const Domain* const & domain,
03364                                                                                      const char* predname,
03365                                                                                      void* handle)
03366 {
03367   char* error;
03368   void* funccall;
03369   
03370     // Obtain functioncall from dynamic library
03371   dlerror();    // Clear any existing error
03372   funccall = dlsym(handle, predname);
03373   if ((error = dlerror()) != NULL)
03374   {
03375     printf("Error while evaluating predicate %s\n", predname);
03376     fprintf (stderr, "dlerror: %s\n", error);
03377     return;
03378   }
03379 
03380     // Find number of terms for predicate
03381   const PredicateTemplate* ptemplate = domain->getPredicateTemplate(predname);
03382   int numTerms = ptemplate->getNumTerms();
03383 
03384     // Insert all possible permutations of constants
03385   const Array<int>* termTypes = ptemplate->getTermTypesAsInt();
03386   zzassert(numTerms == termTypes->size(),
03387            "Number of terms and term types in function don't match");
03388   Array<int>* currentConstants = new Array<int>;
03389   for (int i = 0; i < numTerms; i++) currentConstants->append(0);
03390   zzinsertPermutationsOfLinkedPredicate(domain, funccall, ptemplate, numTerms,
03391                                         0, currentConstants);
03392 
03393   return;
03394 }
03395 
03406 void zzgenerateGroundingsFromLinkedPredicates(const Domain* const & domain)
03407 {
03408     // First check if a file with predicates exists
03409   void *handle;
03410   char* openFileName;
03411   openFileName = (char *)malloc((strlen("./") +
03412                                  strlen(ZZ_FUNCTION_SO_FILE) + 1)*sizeof(char));
03413   strcpy(openFileName, "./");
03414   strcat(openFileName, ZZ_FUNCTION_SO_FILE);
03415   handle = dlopen(openFileName, RTLD_LAZY);
03416   if (!handle)
03417   {
03418       // Can not open file, so no linked-in predicates
03419     printf("No file for linked-in predicates found.\n");
03420     fprintf (stderr, "%s\n", dlerror());
03421     dlclose(handle);
03422     return;
03423   }
03424 
03425     // Look at each predicate
03426   const Array<const char*>* pnames = domain->getPredicateNames();
03427   for (int i = 0; i < pnames->size(); i++)
03428   {
03429       // If it is a linked-in predicate,
03430       // then generate groundings for each permutation of the given types
03431     if (!zzisInternalPredicate((*pnames)[i]) &&
03432         zzisLinkedPredicate((*pnames)[i], handle))
03433     {
03434       cout << "Found linked-in predicate: " << (*pnames)[i] << endl;
03435       zzgenerateGroundingsFromLinkedPredicate(domain, (*pnames)[i], handle);
03436     }
03437   }
03438   dlclose(handle);
03439   return;
03440 }
03441 
03447 /*
03448 void zzdeclareInternalPredicatesAndFunctions()
03449 {
03450   // Predicates
03451   for (int i = 0; i < zzinternalPredicates.size(); i++)
03452   {
03453         const char* predName = zzinternalPredicates[i][0];
03454           //predicate has not been declared a function
03455         zzassert(zzdomain->getFunctionId(predName) < 0, 
03456                "not expecting pred name to be declared as a function name");
03457         zzassert(zzpredTemplate==NULL,"expecting zzpredTemplate==NULL");
03458         zzpredTemplate = new PredicateTemplate();
03459         zzpredTemplate->setName(predName);
03460         
03461         // Add types
03462         for (int j = 1; j < zzinternalPredicates[i].size(); j++)
03463         {
03464           int id;
03465           const char* ttype = zzinternalPredicates[i][j];
03466           if (!zzdomain->isType(ttype))
03467           {
03468                 id = zzaddTypeToDomain(zzdomain, ttype);
03469                 zzassert(id >= 0, "expecting var id >= 0");
03470           }
03471           zzaddType(ttype, zzpredTemplate, NULL, false, zzdomain);
03472           //delete [] ttype;
03473         }
03474         
03475         // Add template to domain
03476         zzassert(zzpredTemplate, "not expecting zzpredTemplate==NULL");
03477         int id = zzdomain->addPredicateTemplate(zzpredTemplate);
03478         zzassert(id >= 0, "expecting pred template id >= 0");
03479         zzpredTemplate->setId(id);
03480         zzpredTemplate = NULL;
03481   }
03482   
03483   
03484   // Functions
03485   for (int i = 0; i < zzinternalFunctions.size(); i++)
03486   {
03487         zzassert(zzfuncTemplate==NULL, "expecting zzfuncTemplate==NULL");
03488         zzfuncTemplate = new FunctionTemplate();
03489 
03490         // We are creating a new predicate as well
03491         zzassert(zzpredTemplate==NULL,"expecting zzpredTemplate==NULL");
03492         zzpredTemplate = new PredicateTemplate();
03493 
03494         const char* funcName = zzinternalFunctions[i][0];
03495 
03496         zzassert(zzdomain->getPredicateId(funcName) < 0, 
03497              "not expecting func name to be declared as pred name");
03498         zzassert(zzfuncTemplate,"expecting zzfuncTemplate!=NULL");
03499         zzfuncTemplate->setName(funcName);
03500 
03501         // Predicate name is PredicateTemplate::ZZ_RETURN_PREFIX + function name
03502         char* predName;
03503         predName = (char *)malloc((strlen(PredicateTemplate::ZZ_RETURN_PREFIX) +
03504                                                         strlen(funcName) + 1)*sizeof(char));
03505         strcpy(predName, PredicateTemplate::ZZ_RETURN_PREFIX);
03506         strcat(predName, funcName);
03507         
03508         // Check that predicate has not been declared a function
03509         zzassert(zzdomain->getFunctionId(predName) < 0, 
03510                      "not expecting pred name to be declared as a function name");
03511         zzassert(zzpredTemplate,"expecting zzpredTemplate!=NULL");
03512         zzpredTemplate->setName(predName);
03513         delete [] predName;  
03514         
03515         // Add return type
03516         const char* retTypeName = zzinternalFunctions[i][1];
03517 
03518         if (!zzdomain->isType(retTypeName))
03519         {
03520           int id = zzaddTypeToDomain(zzdomain, retTypeName);
03521       zzassert(id >= 0, "expecting retTypeName's id >= 0");
03522         }
03523 
03524         zzfuncTemplate->setRetTypeName(retTypeName,zzdomain);
03525         // We are creating a new predicate as well
03526         zzaddType(retTypeName, zzpredTemplate, NULL, false, zzdomain);
03527   
03528         // Add types
03529         for (int j = 2; j < zzinternalFunctions[i].size(); j++)
03530         {
03531           int id;
03532           const char* ttype = zzinternalFunctions[i][j];
03533           if (!zzdomain->isType(ttype))
03534           {
03535                 id = zzaddTypeToDomain(zzdomain, ttype);
03536                 zzassert(id >= 0, "expecting var id >= 0");
03537           }
03538           zzaddType(ttype, zzpredTemplate, NULL, false, zzdomain);
03539           // Add the type to the function too
03540           zzaddType(ttype, NULL, zzfuncTemplate, false, zzdomain);
03541         }
03542 
03543   // Add templates to domain
03544   zzassert(zzfuncTemplate, "expecting zzfuncTemplate != NULL");
03545   int id = zzdomain->addFunctionTemplate(zzfuncTemplate);
03546   zzassert(id >= 0, "expecting function template's id >= 0");
03547   zzfuncTemplate->setId(id);
03548   zzfuncTemplate = NULL;
03549 
03550   zzassert(zzpredTemplate, "not expecting zzpredTemplate==NULL");
03551   int predId = zzdomain->addPredicateTemplate(zzpredTemplate);
03552   zzassert(predId >= 0, "expecting pred template id >= 0");
03553   zzpredTemplate->setId(predId);
03554   zzpredTemplate = NULL;
03555   }
03556   
03557   return;
03558 }
03559 */
03560 
03576 void zzinsertPermutationOfInternalPredicate(int index,
03577                                       const PredicateTemplate* const& ptemplate,
03578                                             int numTerms,
03579                                             Array<int>* currentConstants)
03580 {
03581   bool retBool = false;
03582   string arguments[numTerms];
03583   string argumentsAsNum[numTerms];
03584   
03585     // Find the arguments for the predicate according to currentConstants
03586   for (int i = 0; i < numTerms; i++)
03587   {
03588     const Array<int>* constantsByType =
03589       zzdomain->getConstantsByType(ptemplate->getTermTypeAsInt(i));
03590 
03591     arguments[i] =
03592       zzdomain->getConstantName((*constantsByType)[((*currentConstants)[i])]);
03593       // If constant is a number, then we have to cut it out of the string
03594       // C@Type@Number
03595     unsigned int at = arguments[i].rfind("@");
03596     if (at != string::npos)
03597       argumentsAsNum[i] = arguments[i].substr(at+1, arguments[i].length()-at-1);
03598     else
03599     {
03600       argumentsAsNum[i] = arguments[i];
03601         // Remove " from constants
03602       string::size_type loc = argumentsAsNum[i].find("\"", 0);
03603       while (loc != string::npos)
03604       {
03605         argumentsAsNum[i].erase(loc, 1);
03606         loc = argumentsAsNum[i].find("\"", 0);
03607       }
03608     }
03609   }
03610   
03611     // Make the function call
03612   int a, b;
03613   switch(index)
03614   {
03615     case 0:
03616       Internals::stringToInt(argumentsAsNum[0], a);
03617       Internals::stringToInt(argumentsAsNum[1], b);
03618       retBool = Internals::greaterThan(a, b);
03619       break;
03620     case 1:
03621       Internals::stringToInt(argumentsAsNum[0], a);
03622       Internals::stringToInt(argumentsAsNum[1], b);
03623       retBool = Internals::lessThan(a, b);
03624       break;
03625     case 2:
03626       Internals::stringToInt(argumentsAsNum[0], a);
03627       Internals::stringToInt(argumentsAsNum[1], b);
03628       retBool = Internals::greaterThanEq(a, b);
03629       break;
03630     case 3:
03631       Internals::stringToInt(argumentsAsNum[0], a);
03632       Internals::stringToInt(argumentsAsNum[1], b);
03633       retBool = Internals::lessThanEq(a, b);
03634       break;
03635     case 4:
03636       retBool = Internals::substr(argumentsAsNum[0], argumentsAsNum[1]);
03637       break;
03638   }
03639     
03640     // Insert the predicate definition just created  
03641   const char* predName;
03642   predName = ptemplate->getName();
03643   zzcreatePred(zzpred, predName);
03644   if (retBool) zzpred->setTruthValue(TRUE);
03645   else zzpred->setTruthValue(FALSE);
03646   
03647     // Add constant terms to predicate
03648   for (int i = 0; i < numTerms; i++)
03649   {
03650     const char* term = arguments[i].c_str();
03651     int constId = zzdomain->getConstantId(term);
03652     zzpredAppendConstant(zzpred, constId, term);
03653   }
03654 
03655   zzcheckPredNumTerm(zzpred);
03656   int predId = zzpred->getId();
03657 
03658     // Insert mapping of grounding
03659   hash_map<int,PredicateHashArray*>::iterator it;
03660   if ((it=zzpredIdToGndPredMap.find(predId)) == zzpredIdToGndPredMap.end())
03661     zzpredIdToGndPredMap[predId] = new PredicateHashArray;
03662   
03663 //cout << "Mapping " << endl;
03664 //zzpred->printWithStrVar(cout, zzdomain);
03665 //cout << " " << zzpred->getTruthValue() << endl;
03666 
03667   PredicateHashArray* pha = zzpredIdToGndPredMap[predId];
03668   if (pha->append(zzpred) < 0)
03669   {
03670     int a = pha->find(zzpred);
03671     zzassert(a >= 0, "expecting ground predicate to be found");
03672     string origTvStr = (*pha)[a]->getTruthValueAsStr();
03673     (*pha)[a]->setTruthValue(zzpred->getTruthValue());
03674     string newTvStr = (*pha)[a]->getTruthValueAsStr();
03675 
03676     if (zzwarnDuplicates)
03677     {
03678       ostringstream oss;
03679       oss << "Duplicate ground predicate "; zzpred->print(oss, zzdomain); 
03680       oss << " found. ";
03681       if (origTvStr.compare(newTvStr) != 0)
03682         oss << "Changed its truthValue from " << origTvStr << " to " << newTvStr
03683             << endl;
03684       zzwarn(oss.str().c_str());
03685     }
03686     delete zzpred;
03687   }
03688 
03689   zzpred = NULL;
03690 }
03691 
03708 void zzinsertPermutationOfInternalFunction(int index,
03709                                            const FunctionTemplate* ftemplate,
03710                                            int numTerms,
03711                                            Array<int>* currentConstants)
03712 {
03713   char constName[1000];
03714   string arguments[numTerms];
03715   string argumentsAsNum[numTerms];
03716   
03717     // Find the arguments for the predicate according to currentConstants
03718   for (int i = 0; i < numTerms; i++)
03719   {
03720     const Array<int>* constantsByType =
03721       zzdomain->getConstantsByType(ftemplate->getTermTypeAsInt(i));
03722 
03723     arguments[i] =
03724       zzdomain->getConstantName((*constantsByType)[((*currentConstants)[i])]);
03725       // If constant is a number, then we have to cut it out of the string
03726       // C@Type@Number
03727     unsigned int at = arguments[i].rfind("@");
03728     if (at != string::npos)
03729       argumentsAsNum[i] = arguments[i].substr(at+1, arguments[i].length()-at-1);
03730     else argumentsAsNum[i] = arguments[i];
03731   }
03732   
03733     // Make the function call
03734   int a, b;
03735   switch(index)
03736   {
03737     case 0:
03738       Internals::stringToInt(argumentsAsNum[0], a);
03739       zzcreateIntConstant(constName, ftemplate->getRetTypeName(),
03740                           Internals::succ(a));
03741       break;
03742     case 1:
03743       Internals::stringToInt(argumentsAsNum[0], a);
03744       Internals::stringToInt(argumentsAsNum[1], b);
03745       zzcreateIntConstant(constName, ftemplate->getRetTypeName(),
03746                           Internals::plus(a, b));
03747       break;
03748     case 2:
03749       Internals::stringToInt(argumentsAsNum[0], a);
03750       Internals::stringToInt(argumentsAsNum[1], b);
03751       zzcreateIntConstant(constName, ftemplate->getRetTypeName(),
03752                           Internals::minus(a, b));
03753       break;
03754     case 3:
03755       Internals::stringToInt(argumentsAsNum[0], a);
03756       Internals::stringToInt(argumentsAsNum[1], b);
03757       zzcreateIntConstant(constName, ftemplate->getRetTypeName(),
03758                           Internals::times(a, b));
03759       break;
03760     case 4:
03761       Internals::stringToInt(argumentsAsNum[0], a);
03762       Internals::stringToInt(argumentsAsNum[1], b);
03763       zzcreateIntConstant(constName, ftemplate->getRetTypeName(),
03764                           Internals::dividedBy(a, b));
03765       break;
03766     case 5:
03767       Internals::stringToInt(argumentsAsNum[0], a);
03768       Internals::stringToInt(argumentsAsNum[1], b);
03769       zzcreateIntConstant(constName, ftemplate->getRetTypeName(),
03770                           Internals::mod(a, b));
03771       break;
03772     case 6:
03773       strcpy(constName,
03774              Internals::concat(argumentsAsNum[0], argumentsAsNum[1]).c_str());
03775   }
03776   
03777     // The return value has to be an existing constant of the return type
03778   int constantId = zzdomain->getConstantId(constName);
03779   const Array<int>* returnConstants =
03780     zzdomain->getConstantsByType(ftemplate->getRetTypeId());
03781   
03782   if (returnConstants->contains(constantId))
03783   {
03784       // Insert the function definition just created  
03785       // Predicate name is PredicateTemplate::ZZ_RETURN_PREFIX + function name
03786     char* predName;
03787     predName = (char *)malloc((strlen(PredicateTemplate::ZZ_RETURN_PREFIX) +
03788                                strlen(ftemplate->getName()) + 1)*sizeof(char));
03789     strcpy(predName, PredicateTemplate::ZZ_RETURN_PREFIX);
03790     strcat(predName, ftemplate->getName());
03791     zzcreatePred(zzpred, predName);
03792     zzpred->setTruthValue(TRUE);
03793 
03794       // Add return constant to predicate
03795     zzpredAppendConstant(zzpred, constantId, constName);
03796       // Add constant terms to predicate
03797     for (int i = 0; i < numTerms; i++)
03798     {
03799       const char* term = arguments[i].c_str();
03800       int constId = zzdomain->getConstantId(term);
03801       zzpredAppendConstant(zzpred, constId, term);
03802     }
03803     
03804     zzcheckPredNumTerm(zzpred);
03805     int predId = zzpred->getId();
03806       // Insert mapping of grounding
03807     hash_map<int,PredicateHashArray*>::iterator it;
03808     if ((it=zzpredIdToGndPredMap.find(predId)) == zzpredIdToGndPredMap.end())
03809       zzpredIdToGndPredMap[predId] = new PredicateHashArray;
03810 
03811 //cout << "Mapping " << endl;
03812 //zzpred->printWithStrVar(cout, zzdomain);
03813 //cout << " " << zzpred->getTruthValue() << endl;
03814   
03815     PredicateHashArray* pha = zzpredIdToGndPredMap[predId];
03816     if (pha->append(zzpred) < 0)
03817     {
03818       int a = pha->find(zzpred);
03819       zzassert(a >= 0, "expecting ground predicate to be found");
03820       string origTvStr = (*pha)[a]->getTruthValueAsStr();
03821       (*pha)[a]->setTruthValue(zzpred->getTruthValue());
03822       string newTvStr = (*pha)[a]->getTruthValueAsStr();
03823 
03824       if (zzwarnDuplicates)
03825       {
03826         ostringstream oss;
03827         oss << "Duplicate ground predicate "; zzpred->print(oss, zzdomain); 
03828         oss << " found. ";
03829         if (origTvStr.compare(newTvStr) != 0)
03830           oss << "Changed its truthValue from " << origTvStr << " to "
03831               << newTvStr << endl;
03832         zzwarn(oss.str().c_str());
03833       }
03834       delete zzpred;
03835     }
03836 
03837     free(predName);
03838     zzpred = NULL;
03839   }
03840   //delete returnConstants;
03841 }
03842 
03860 void zzinsertPermutationsOfInternalPredicate(int index,
03861                                       const PredicateTemplate* const& ptemplate,
03862                                              int numTerms, int currentTerm,
03863                                              Array<int>* currentConstants)
03864 {
03865   const Array<int>* constants =
03866     zzdomain->getConstantsByType(ptemplate->getTermTypeAsInt(currentTerm));
03867 
03868     // Base case: at the last term
03869   if (currentTerm == numTerms - 1)
03870   {
03871     for (int i = 0; i < constants->size(); i++)
03872     {
03873       (*currentConstants)[currentTerm] = i;
03874       zzinsertPermutationOfInternalPredicate(index, ptemplate, numTerms,
03875                                              currentConstants);
03876     }
03877     return;
03878   }
03879   
03880     // Not yet at last term
03881   zzinsertPermutationsOfInternalPredicate(index, ptemplate, numTerms,
03882                                           currentTerm + 1, currentConstants);
03883   
03884   if (++(*currentConstants)[currentTerm] < constants->size())
03885     zzinsertPermutationsOfInternalPredicate(index, ptemplate, numTerms,
03886                                             currentTerm, currentConstants);
03887 
03888   (*currentConstants)[currentTerm] = 0;
03889   return;
03890 }
03891 
03892 
03910 void zzinsertPermutationsOfInternalFunction(int index,
03911                                        const FunctionTemplate* const& ftemplate,
03912                                        int numTerms, int currentTerm,
03913                                        Array<int>* currentConstants)
03914 {
03915   const Array<int>* constants =
03916     zzdomain->getConstantsByType(ftemplate->getTermTypeAsInt(currentTerm));
03917 
03918     // Base case: at the last term
03919   if (currentTerm == numTerms - 1)
03920   {
03921     for (int i = 0; i < constants->size(); i++)
03922     {
03923       (*currentConstants)[currentTerm] = i;
03924       zzinsertPermutationOfInternalFunction(index, ftemplate, numTerms,
03925                                             currentConstants);
03926     }
03927     return;
03928   }
03929   
03930     // Not yet at last term
03931   zzinsertPermutationsOfInternalFunction(index, ftemplate, numTerms,
03932                                          currentTerm + 1, currentConstants);
03933   
03934   if (++(*currentConstants)[currentTerm] < constants->size())
03935     zzinsertPermutationsOfInternalFunction(index, ftemplate, numTerms,
03936                                            currentTerm, currentConstants);
03937 
03938   (*currentConstants)[currentTerm] = 0;
03939   return;
03940 }
03941 
03947 void zzgenerateGroundingsFromInternalPredicate(int index,
03948                                       const PredicateTemplate* const& ptemplate)
03949 {
03950     // Find number of terms for predicate
03951   if (ptemplate != NULL)
03952   {
03953     int numTerms = ptemplate->getNumTerms();
03954 
03955       // Insert all possible permutations of constants
03956     const Array<int>* termTypes = ptemplate->getTermTypesAsInt();
03957     zzassert(numTerms == termTypes->size(),
03958              "Number of terms and term types in predicate don't match");
03959     Array<int>* currentConstants = new Array<int>;
03960     for (int i = 0; i < numTerms; i++) currentConstants->append(0);
03961     zzinsertPermutationsOfInternalPredicate(index, ptemplate, numTerms, 0,
03962                                             currentConstants);
03963     delete currentConstants;
03964   }
03965   return;
03966 }
03967 
03973 void zzgenerateGroundingsFromInternalFunction(int index,
03974                                        const FunctionTemplate* const& ftemplate)
03975 {
03976   // Find number of terms for function
03977   if (ftemplate != NULL)
03978   {
03979     int numTerms = ftemplate->getNumTerms();
03980 
03981       // Insert all possible permutations of constants
03982     const Array<int>* termTypes = ftemplate->getTermTypesAsInt();
03983     zzassert(numTerms == termTypes->size(),
03984              "Number of terms and term types in predicate don't match");
03985     Array<int>* currentConstants = new Array<int>;
03986     for (int i = 0; i < numTerms; i++) currentConstants->append(0);
03987     zzinsertPermutationsOfInternalFunction(index, ftemplate, numTerms, 0,
03988                                            currentConstants);
03989     delete currentConstants;
03990   }
03991   return;
03992 }
03993 
04002 void zzgenerateGroundingsFromInternalPredicatesAndFunctions()
04003 {
04004     // Look at each predicate
04005   for (int i = 0; i < zzdomain->getNumPredicates(); i++)
04006   {
04007     const PredicateTemplate* ptemplate = zzdomain->getPredicateTemplate(i);
04008     if (ptemplate->isInternalPredicateTemplate())
04009     {
04010       cout << "Found internal predicate: " << ptemplate->getName() << endl;
04011       for (int j = 0; j < zzinternalPredicates.size(); j++)
04012       {
04013 cout << "h1" << endl;
04014         if (strncmp(ptemplate->getName(), zzinternalPredicates[j][0],
04015                     strlen(zzinternalPredicates[j][0])) == 0)
04016         {
04017 cout << "h2" << endl;
04018           zzgenerateGroundingsFromInternalPredicate(j, ptemplate);
04019 cout << "h3" << endl;
04020           break;
04021         }
04022 cout << "h4" << endl;
04023       }
04024     }
04025   }
04026 
04027     // Look at each function
04028   for (int i = 0; i < zzdomain->getNumFunctions(); i++)
04029   {
04030     const FunctionTemplate* ftemplate = zzdomain->getFunctionTemplate(i);
04031     if (ftemplate->isInternalFunctionTemplate())
04032     {
04033       cout << "Found internal function: " << ftemplate->getName() << endl;
04034       for (int j = 0; j < zzinternalFunctions.size(); j++)
04035       {
04036         if (strncmp(ftemplate->getName(), zzinternalFunctions[j][0],
04037                     strlen(zzinternalFunctions[j][0])) == 0)
04038         {
04039           zzgenerateGroundingsFromInternalFunction(j, ftemplate);
04040           break;
04041         }
04042       }
04043     }
04044   }
04045 
04046   return;
04047 }
04048 
04049 void zzcreateInternalPredTemplate(const string& predName,
04050                                   const char* const & ttype)
04051 {
04052     // If already declared then return
04053   if (zzdomain->getPredicateId(predName.c_str()) >= 0) return;
04054   int index;
04055   string baseName = predName.substr(0, predName.find_last_of("_"));
04056   
04057   if ((index = zzfindInternalPredicate(baseName.c_str())) >= 0)
04058   {
04059     zzassert(zzdomain->getFunctionId(predName.c_str()) < 0, 
04060              "not expecting pred name to be declared as a function name");
04061     PredicateTemplate* ptemplate = new PredicateTemplate();
04062     ptemplate->setName(predName.c_str());
04063         
04064       // Add types
04065     for (int j = 1; j < zzinternalPredicates[index].size(); j++)
04066     {
04067       int id;
04068       if (!zzdomain->isType(ttype))
04069       {
04070         id = zzaddTypeToDomain(zzdomain, ttype);
04071         zzassert(id >= 0, "expecting var id >= 0");
04072       }
04073       zzaddType(ttype, ptemplate, NULL, false, zzdomain);
04074     }
04075 
04076       // Add template to domain
04077     zzassert(ptemplate, "not expecting ptemplate==NULL");
04078     int id = zzdomain->addPredicateTemplate(ptemplate);
04079     zzassert(id >= 0, "expecting pred template id >= 0");
04080     ptemplate->setId(id);
04081   }
04082   else
04083     zzexit("Predicate %s is not an internal predicate.", predName.c_str());
04084 }
04085 
04086 void zzsetInternalPredTypeName(const char* const & predName, const int& typeId)
04087 {
04088   const char * typeName = zzdomain->getTypeName(typeId);
04089   string intPredName =
04090     PredicateTemplate::createInternalPredTypeName(predName, typeName);
04091   zzcreateInternalPredTemplate(intPredName, typeName);
04092   const PredicateTemplate* t =
04093     zzdomain->getPredicateTemplate(intPredName.c_str());
04094   zzpred->setTemplate((PredicateTemplate*)t);
04095   zzassert(zzdomain->getPredicateTemplate(intPredName.c_str()) != NULL,
04096            "expect internal pred template != NULL");
04097   ListObj* predlo = zzpredFuncListObjs.top();
04098   predlo->replace(predName, intPredName.c_str());
04099 }
04100 
04101 void zzcreateInternalFuncTemplate(const string & funcName,
04102                                                                   const Array<string>& typeNames)
04103 {
04104     // If already declared then return
04105   if (zzdomain->getFunctionId(funcName.c_str()) >= 0) return;
04106   int index;
04107   string baseName = funcName.substr(0, funcName.find_first_of("_"));
04108 
04109   if ((index = zzfindInternalFunction(baseName.c_str())) >= 0)
04110   {
04111     zzassert(zzfuncTemplate==NULL, "expecting zzfuncTemplate==NULL");
04112     zzfuncTemplate = new FunctionTemplate();
04113 
04114       // We are creating a new predicate as well
04115     zzassert(zzpredTemplate==NULL,"expecting zzpredTemplate==NULL");
04116     zzpredTemplate = new PredicateTemplate();
04117 
04118     zzassert(zzdomain->getPredicateId(funcName.c_str()) < 0, 
04119              "not expecting func name to be declared as pred name");
04120     zzassert(zzfuncTemplate,"expecting zzfuncTemplate!=NULL");
04121     zzfuncTemplate->setName(funcName.c_str());
04122 
04123       // Predicate name is PredicateTemplate::ZZ_RETURN_PREFIX + function name
04124     char* predName;
04125     predName = (char *)malloc((strlen(PredicateTemplate::ZZ_RETURN_PREFIX) +
04126                                strlen(funcName.c_str()) + 1)*sizeof(char));
04127     strcpy(predName, PredicateTemplate::ZZ_RETURN_PREFIX);
04128     strcat(predName, funcName.c_str());
04129 
04130       // Check that predicate has not been declared a function
04131     zzassert(zzdomain->getFunctionId(predName) < 0, 
04132              "not expecting pred name to be declared as a function name");
04133     zzassert(zzpredTemplate,"expecting zzpredTemplate!=NULL");
04134     zzpredTemplate->setName(predName);
04135     free(predName);  
04136     
04137       // Add return type
04138     const char* retTypeName = typeNames[0].c_str();
04139 
04140     if (!zzdomain->isType(retTypeName))
04141     {
04142       int id = zzaddTypeToDomain(zzdomain, retTypeName);
04143       zzassert(id >= 0, "expecting retTypeName's id >= 0");
04144     }
04145 
04146     zzfuncTemplate->setRetTypeName(retTypeName, zzdomain);
04147       // We are creating a new predicate as well
04148     zzaddType(retTypeName, zzpredTemplate, NULL, false, zzdomain);
04149   
04150       // Add types
04151     for (int j = 1; j < typeNames.size(); j++)
04152     {
04153       int id;
04154       const char* ttype = typeNames[j].c_str();
04155       if (!zzdomain->isType(ttype))
04156       {
04157         id = zzaddTypeToDomain(zzdomain, ttype);
04158         zzassert(id >= 0, "expecting var id >= 0");
04159       }
04160       zzaddType(ttype, zzpredTemplate, NULL, false, zzdomain);
04161         // Add the type to the function too
04162       zzaddType(ttype, NULL, zzfuncTemplate, false, zzdomain);
04163     }
04164 
04165       // Add templates to domain
04166     zzassert(zzfuncTemplate, "expecting zzfuncTemplate != NULL");
04167     int id = zzdomain->addFunctionTemplate(zzfuncTemplate);
04168     zzassert(id >= 0, "expecting function template's id >= 0");
04169     zzfuncTemplate->setId(id);
04170     zzfuncTemplate = NULL;
04171 
04172     zzassert(zzpredTemplate, "not expecting zzpredTemplate==NULL");
04173     int predId = zzdomain->addPredicateTemplate(zzpredTemplate);
04174     zzassert(predId >= 0, "expecting pred template id >= 0");
04175     zzpredTemplate->setId(predId);
04176     zzpredTemplate = NULL;      
04177   }
04178   else
04179     zzexit("Function %s is not an internal function.", funcName.c_str());
04180 }
04181 
04182 void zzsetInternalFuncTypeName(const char* const & funcName,
04183                                const Array<int>& typeIds)
04184 {
04185   Array<string> typeNames(typeIds.size());
04186   for (int i = 0; i < typeIds.size(); i++)
04187     typeNames.append(zzdomain->getTypeName(typeIds[i]));
04188   string intFuncName =
04189     FunctionTemplate::createInternalFuncTypeName(funcName, typeNames);
04190   zzcreateInternalFuncTemplate(intFuncName, typeNames);
04191   
04192   const FunctionTemplate* t =
04193     zzdomain->getFunctionTemplate(intFuncName.c_str());
04194   zzfunc->setTemplate((FunctionTemplate*)t);
04195   zzassert(zzdomain->getFunctionTemplate(intFuncName.c_str()) != NULL,
04196            "expect internal func template != NULL");
04197   ListObj* funclo = zzpredFuncListObjs.top();
04198   funclo->replace(funcName, intFuncName.c_str());
04199 }
04200 
04201 const FunctionTemplate* zzgetGenericInternalFunctionTemplate(
04202                                                    const char* const & funcName)
04203 {
04204   zzassert(FunctionTemplate::isInternalFunctionTemplateName(funcName),
04205            "expect internal function name");
04206   int index = zzfindInternalFunction(funcName);
04207   FunctionTemplate* funcTemplate = new FunctionTemplate();
04208   funcTemplate->setName(funcName);
04209         
04210     // Add return type
04211   funcTemplate->setRetTypeName(PredicateTemplate::ANY_TYPE_NAME, zzdomain);
04212   
04213     // Add types
04214   for (int j = 2; j < zzinternalFunctions[index].size(); j++)
04215   {
04216       // Add the type to the function
04217     zzaddType(PredicateTemplate::ANY_TYPE_NAME, NULL, funcTemplate, false,
04218               zzdomain);
04219   }
04220   return funcTemplate;
04221 }
04222 
04229 void moveTermToInfixFunction()
04230 {
04231     // top in zzpredFuncListObjs must be infix function, second to top is pred /
04232     // func in which it is nested
04233 
04234   Term* term = NULL;
04235     // In a function
04236   if (!zzfuncStack.empty())
04237   {
04238     Function* prevFunc = zzfuncStack.top();
04239     term = prevFunc->removeLastTerm();
04240   }
04241     // Not in a function
04242   else
04243   {
04244     zzassert(zzpred, "expecting to be in a predicate");
04245     term = zzpred->removeLastTerm();
04246   }
04247   term->setParent(zzfunc, false);
04248   zzfunc->appendTerm(term);
04249   ListObj* lo = zzpredFuncListObjs.top();
04250   zzpredFuncListObjs.pop();
04251   lo->append((zzpredFuncListObjs.top())->removeLast());
04252   zzpredFuncListObjs.push(lo);
04253 }
04254 
04255 #endif

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