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 and Hoifung Poon.
00006  * 
00007  * Copyright [2004-07] Stanley Kok, Parag Singla, Matthew
00008  * Richardson, Pedro Domingos, Marc Sumner and Hoifung
00009  * Poon. All rights reserved.
00010  * 
00011  * Contact: Pedro Domingos, University of Washington
00012  * (pedrod@cs.washington.edu).
00013  * 
00014  * Redistribution and use in source and binary forms, with
00015  * or without modification, are permitted provided that
00016  * the following conditions are met:
00017  * 
00018  * 1. Redistributions of source code must retain the above
00019  * copyright notice, this list of conditions and the
00020  * following disclaimer.
00021  * 
00022  * 2. Redistributions in binary form must reproduce the
00023  * above copyright notice, this list of conditions and the
00024  * following disclaimer in the documentation and/or other
00025  * materials provided with the distribution.
00026  * 
00027  * 3. All advertising materials mentioning features or use
00028  * of this software must display the following
00029  * acknowledgment: "This product includes software
00030  * developed by Stanley Kok, Parag Singla, Matthew
00031  * Richardson, Pedro Domingos, Marc Sumner and Hoifung
00032  * Poon in the Department of Computer Science and
00033  * Engineering at the University of Washington".
00034  * 
00035  * 4. Your publications acknowledge the use or
00036  * contribution made by the Software to your research
00037  * using the following citation(s): 
00038  * Stanley Kok, Parag Singla, Matthew Richardson and
00039  * Pedro Domingos (2005). "The Alchemy System for
00040  * Statistical Relational AI", Technical Report,
00041  * Department of Computer Science and Engineering,
00042  * University of Washington, Seattle, WA.
00043  * http://www.cs.washington.edu/ai/alchemy.
00044  * 
00045  * 5. Neither the name of the University of Washington nor
00046  * the names of its contributors may be used to endorse or
00047  * promote products derived from this software without
00048  * specific prior written permission.
00049  * 
00050  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF WASHINGTON
00051  * AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
00052  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00053  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00054  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY
00055  * OF WASHINGTON OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
00056  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00057  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00058  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00059  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00060  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00061  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00062  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00063  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00064  * 
00065  */
00066 #ifndef FOLHELPER_H_JUL_21_2005
00067 #define FOLHELPER_H_JUN_21_2005
00068 
00069 // dl library used for dynamically loading linked-in functions
00070 #include <dlfcn.h>
00071 #include <stdio.h>
00072 #include <stdlib.h>
00073 #include <assert.h>
00074 #include <signal.h>
00075 #include <ext/hash_set>
00076 #include <stack>
00077 #include <iostream>
00078 #include <fstream>
00079 #include <sstream>
00080 #include "strfifolist.h"
00081 #include "predicate.h"
00082 #include "function.h"
00083 #include "clause.h"
00084 #include "clausefactory.h"
00085 #include "hashstring.h"
00086 #include "database.h"
00087 #include "listobj.h"
00088 #include "timer.h"
00089 #include "internals.h"
00090 
00091 //NOTE: When a variable is added, please init it in zzinit() and destroy it 
00092 //      in zzcleanUp(). Add it in zzreset() if it has to be reinitialized before
00093 //      a new clause is parsed.
00094 
00095 
00096   //Each hard clause derived from a hard formula is given a weight that is twice
00097   //that of the maximum soft clause weight. You can change this value by setting
00098   //HARD_WEIGHT_MULTIPLIER below. If you wish to set the hard clause weight to
00099   //a specific value, you can set HARD_WEIGHT below. 
00100   //If HARD_WEIGHT is DBL_MIN, HARD_WEIGHT_MULTIPLIER is used instead of 
00101   //HARD_WEIGHT; otherwise the latter is used.
00102 const double HARD_WEIGHT_MULTIPLIER = 2;
00103 const double HARD_WEIGHT = DBL_MIN;
00104 
00105   //Each clause derived from a unit formula with mutually exclusive and 
00106   //exhaustive variables is given a weight that is 1.5 times
00107   //that of the maximum soft clause weight. You can change this value by setting
00108   //EXIST_UNIQUE_WEIGHT_MULTIPLIER below. If you wish to set the clause weight 
00109   //to a specific value, you can set EXIST_UNIQUE_WEIGHT to that value below. 
00110   //If EXIST_UNIQUE_WEIGHT is DBL_MIN, EXIST_UNIQUE_WEIGHT_MULTIPLIER is used 
00111   //instead of EXIST_UNIQUE_WEIGHT; otherwise the latter is used.
00112 const double EXIST_UNIQUE_WEIGHT_MULTIPLIER = 1.5;
00113 const double EXIST_UNIQUE_WEIGHT = DBL_MIN;
00114 
00115   // If the variables are assigned some initial values, ensure they are are
00116   // similarly assigned in zzinit(). Also set any data structure to its initial 
00117   // state in zzinit()
00118 const int ZZ_MAX_ERRORS = 50;
00119 
00120 // Start of variable names generated by replacement of functions
00121 const char* ZZ_FUNCVAR_PREFIX = "funcVar";
00122 
00123 // Name of shared object file for linked-in functions
00124 const char* ZZ_FUNCTION_SO_FILE = "functions.so";
00125 
00126   // a copy of the user-specified MLN file is created & appended with this str
00127 const char* ZZ_TMP_FILE_POSTFIX = "_tmpalchemy.mln";
00128 
00129   // prepend to a file containing query predicates
00130 const char* zzdefaultPredName = "SKPRED";
00131 const char* zzdefaultFuncName = "SKFUNC";
00132 const char* zzdefaultTypeName = "SKTYPE";
00133 const char* zzdefaultVarName  = "SKVAR";
00134 
00135 bool zzstoreGroundPreds = false; //set to true for testing only
00136   //constants must be declared before being used
00137 bool zzconstantMustBeDeclared = false;
00138   // read weight that is specified for a hard formula
00139 bool zzreadHardClauseWts = false;
00140   //used in follex.y to allow predicate definitions to be on the same line
00141 bool zzafterRtParen;
00142 
00143 bool zzisParsing; //indicates whether a file is currently being parsed
00144 double zzdefaultWt; // default wt of a formula if no wt or . is specified
00145   //a formula must begin with a weight or end with full stop
00146 bool zzmustHaveWtOrFullStop;
00147   // indicates whether weights should be flipped when a clause is flipped.
00148   // This should be true for inference and false for learning.
00149 bool zzflipWtsOfFlippedClause;
00150 bool zzwarnDuplicates;
00151 string zzinFileName;
00152 char zzerrMsg[1024];
00153 
00154 int zzcount;  // to be appended to names of default pred, type etc.
00155 int zzline, zzcolumn;
00156 int zznumCharRead;
00157 int zznumErrors;
00158 bool zzok;
00159 MLN* zzmln;
00160 Domain* zzdomain;
00161 int zznumEofSeen; // num of times EOF seen
00162 StrFifoList zztokenList;
00163 
00164 char* zztypeName;
00165 PredicateTemplate* zzpredTemplate;
00166 FunctionTemplate* zzfuncTemplate;
00167 Predicate* zzpred;
00168 Function* zzfunc;
00169 stack<Function*> zzfuncStack;
00170 stack<ListObj*> zzfuncConjStack;
00171 double* zzwt;
00172 bool zzisNegated;
00173 bool zzisAsterisk;
00174 bool zzisPlus;
00175 bool zzhasFullStop;
00176 int zznumAsterisk;
00177 char zztrueFalseUnknown;
00178 string zzformulaStr;
00179 string zzfuncConjStr;
00180 bool zzparseGroundPred;
00181 Array<int> zzuniqueVarIndexes; // index of unique variable in unit clause
00182 stack<ListObj*> zzformulaListObjs;  //used by formulas with connectives
00183 stack<ListObj*> zzpredFuncListObjs; // used by predicates and functions
00184 hash_map<int, PredicateHashArray*> zzpredIdToGndPredMap;
00185 
00186 // Used to check if there is a function definition
00187 int zzfdnumPreds;
00188 int zzfdnumFuncs;
00189 int zzfdnumVars;
00190 int zzfuncVarCounter = 0;
00191 //bool zzfdisEqualPred;
00192 string zzfdfuncName;
00193 Array<string> zzfdfuncConstants;
00194 string zzfdconstName;
00195 // Used in function definitions to store the return value and type
00196 char* zztmpReturnConstant;
00197 bool zztmpReturnNum;
00198 
00199 // Used to store first number in numeric declarations
00200 int zzinitialNumDeclaration;
00201 
00202 // Set to true if using linked-in predicates
00203 bool zzusingLinkedPredicates;
00204 // Set to true if using linked-in functions
00205 bool zzusingLinkedFunctions;
00206 
00207 // Needed to hold list object information while function is replaced
00208 ListObj* zzoldFuncLo; 
00209 Timer zztimer;
00210 
00211 // Holds the internally implemented predicates and their types (see zzinit())
00212 Array<Array<const char*> > zzinternalPredicates;
00213 // Holds the internally implemented functions and their types (see zzinit())
00214 Array<Array<const char*> > zzinternalFunctions;
00215 
00216 // If an infix predicate is encountered then the name of it is stored here
00217 char* zzinfixPredName;
00218 // If an infix function is encountered then the name of it is stored here
00219 char* zzinfixFuncName;
00220 
00222 struct ZZUnknownEqPredInfo
00223 {
00224   ZZUnknownEqPredInfo(const string& name, const string& lhs, const string& rhs)
00225     :name_(name), lhs_(lhs), rhs_(rhs) {}
00226 
00227   string name_; //e.g. SK_EQUAL_1
00228     // variable name on left and right hand side  
00229   string lhs_;
00230   string rhs_; 
00231 };
00232 
00234 struct ZZUnknownIntPredInfo
00235 {
00236   ZZUnknownIntPredInfo(const string& name, const string& lhs, const string& rhs)
00237     :name_(name), lhs_(lhs), rhs_(rhs) {}
00238 
00239   string name_; //e.g. greaterThan_1
00240     // variable name on left and right hand side  
00241   string lhs_;
00242   string rhs_; 
00243 };
00244 
00246 struct ZZUnknownIntFuncInfo
00247 {
00248   ZZUnknownIntFuncInfo(const string& name, const Array<string>& vnames)
00249     :name_(name), vnames_(vnames) {}
00250 
00251   string name_; //e.g. plus_1
00252     // variable names
00253   Array<string> vnames_;
00254 };
00255 
00256   // counts the number of '=' predicates for which both LHS and RHS are unknown
00257 int zzeqTypeCounter; 
00258   // counts the number of internal predicates for which both LHS and RHS are unknown
00259 int zzintPredTypeCounter; 
00260   // counts the number of internal functions for which at least one term type is unknown
00261 int zzintFuncTypeCounter; 
00262 
00263   // list of '=' predicates for which both LHS and RHS are unknown
00264 list<ZZUnknownEqPredInfo> zzeqPredList;
00265   // list of internal predicates for which both LHS and RHS are unknown
00266 list<ZZUnknownIntPredInfo> zzintPredList;
00267   // list of internal functions for which at least one term type is unknown
00268 list<ZZUnknownIntFuncInfo> zzintFuncList;
00269 
00270   
00272 
00273 struct ZZFileState
00274 {
00275   ZZFileState(FILE* const & file, const string& inFileName, 
00276               const int& numCharRead, const int& line, const int& column) 
00277     : file_(file), inFileName_(inFileName), numCharRead_(numCharRead), 
00278       line_(line), column_(column) {}
00279 
00280   FILE* file_;
00281   string inFileName_;
00282   int numCharRead_;
00283   int line_;
00284   int column_;
00285 };
00286 
00287 stack<ZZFileState> zzinStack; 
00288 
00290 
00291 int zzvarCounter;
00292 int zzanyTypeId;
00293 
00294 struct ZZVarIdType
00295 {
00296   ZZVarIdType() : id_(0), typeId_(0) {}
00297 
00298   ZZVarIdType(const ZZVarIdType& varIdType)
00299     : id_(varIdType.id_), typeId_(varIdType.typeId_) {}
00300  
00301   ZZVarIdType(const int& varId, const int& typeId) 
00302     : id_(varId), typeId_(typeId) {}
00303 
00304   int id_;
00305   int typeId_;
00306 };
00307 
00308 
00309   // contains variables names
00310 typedef hash_map<const string, ZZVarIdType, HashString, EqualString> 
00311   ZZVarNameToIdMap;
00312 
00313 ZZVarNameToIdMap zzvarNameToIdMap;
00314 
00315   // contains mappings of functions to funcVars which replace them
00316 typedef hash_map<Function*, string, HashFunction, EqualFunction> 
00317   ZZFuncToFuncVarMap;
00318   
00319 ZZFuncToFuncVarMap zzfuncToFuncVarMap;
00320 
00321 
00322   // maps a variable name to a new one that has its scope number appended
00323 typedef hash_map<string, string, HashString, EqualString> StringToStringMap;
00324 
00325 int zzscopeCounter; // identifies a scope
00326 
00327   // using a list so that we can iterate through the elements in the stack
00328   // the front and back correspond to the the top and bottom of a stack
00329 typedef list< pair<StringToStringMap*,int> > ZZOldNewVarList;
00330 ZZOldNewVarList zzoldNewVarList;
00331 
00332 
00333   // since plus variables e.g. x in P(+x,y) cannot be explicitly 
00334   // universally/existentially quantified, they must exist within the scope of
00335   // the entire formula
00336 typedef hash_map<string, int, HashString, EqualString> StringToIntMap;
00337 StringToIntMap zzplusVarMap;
00338 
00339 
00341 struct ZZFormulaInfo
00342 {
00343   ZZFormulaInfo(const ListObj* const & fformula, const string& fformulaStr,
00344                 const int& nnumPreds, const double* const & wwt, 
00345                 const double& ddefaultWt, const Domain* const& ddomain, 
00346                 MLN* const & mmln, const ZZVarNameToIdMap& vvarNameToIdMap,
00347                 const StringToIntMap& pplusVarMap, const int& nnumAsterisk,
00348                 const Array<int>& uuniqueVarIndexes, const bool& hhasFullStop, 
00349                 const bool& rreadHardClauseWts,
00350                 const bool& mmustHaveWtOrFullStop)
00351     : formula(fformula), formulaStr(fformulaStr), numPreds(nnumPreds), 
00352       defaultWt(ddefaultWt), domain(ddomain), mln(mmln), 
00353       numAsterisk(nnumAsterisk), hasFullStop(hhasFullStop), 
00354       readHardClauseWts(rreadHardClauseWts),
00355       mustHaveWtOrFullStop(mmustHaveWtOrFullStop)
00356 
00357   {
00358     wt = (wwt) ? new double(*wwt) : NULL;
00359     
00360     ZZVarNameToIdMap::const_iterator it = vvarNameToIdMap.begin();
00361     for (; it != vvarNameToIdMap.end(); it++)
00362       varNameToIdMap[(*it).first] = ZZVarIdType((*it).second);
00363 
00364     StringToIntMap::const_iterator itt = pplusVarMap.begin();
00365     for (; itt != pplusVarMap.end(); itt++)
00366       plusVarMap[(*itt).first] = (*itt).second;
00367 
00368     uniqueVarIndexes.append(uuniqueVarIndexes);
00369   }
00370 
00371   ~ZZFormulaInfo() { if (wt) delete wt; }
00372 
00373   const ListObj* formula;
00374   const string formulaStr;
00375   const int numPreds;
00376   const double* wt;
00377   const double defaultWt;
00378   const Domain* domain;
00379   MLN* mln;
00380   ZZVarNameToIdMap varNameToIdMap;
00381   StringToIntMap plusVarMap;
00382   const int numAsterisk;
00383   Array<int> uniqueVarIndexes;
00384   const bool hasFullStop;
00385   const bool readHardClauseWts;
00386   const bool mustHaveWtOrFullStop;
00387 };
00388 
00389 Array<ZZFormulaInfo*> zzformulaInfos;
00390 
00391 
00393 
00394 string rmTmpPostfix(const string& filename)
00395 {
00396   unsigned int postfixLen = strlen(ZZ_TMP_FILE_POSTFIX);
00397   if (filename.length() < postfixLen) return filename;
00398   if (filename.compare(filename.length() - postfixLen, postfixLen, 
00399                        ZZ_TMP_FILE_POSTFIX, postfixLen)==0)
00400     return filename.substr(0, filename.length() - postfixLen); 
00401   else
00402     return filename;
00403 }
00404 
00405 
00406 void yyerror(char const * err) 
00407 {
00408   string errStr = err;
00409   if (strncmp(err,"parse error, unexpected '(', expecting '='",42)==0)
00410     errStr.append("Have you declared the predicate/function preceding '('");
00411 
00412   if (zzisParsing)
00413     printf("ERROR in %s: line %d, col %d: %s\n", 
00414            rmTmpPostfix(zzinFileName).c_str(),zzline, zzcolumn, errStr.c_str());
00415   else
00416     printf("ERROR occurs after parsing %s: %s\n", 
00417            rmTmpPostfix(zzinFileName).c_str(), errStr.c_str());
00418 
00419   zzok=false;
00420   if (++zznumErrors == ZZ_MAX_ERRORS)
00421   {
00422     cout << "Num of errors = " << zznumErrors 
00423          << ". Exceeded maximum number of errors." << endl;
00424     exit(-1);
00425   }
00426 }
00427 
00428 
00429 void zzerr(const char* const & str) { yyerror(str); }
00430 
00431 
00432 void zzerr(const char* const & str, const char* const & token)
00433 {
00434   sprintf(zzerrMsg, str, token);
00435   yyerror(zzerrMsg);
00436 }
00437 
00438 
00439 void zzerr(const char* const & str, const char* const & token1, 
00440            const char* const & token2)
00441 {
00442   sprintf(zzerrMsg, str, token1, token2);
00443   yyerror(zzerrMsg);
00444 }
00445 
00446 
00447 void zzerr(const char* const & str, const char* const & token1, 
00448            const char* const & token2, const char* const & token3)
00449 {
00450   sprintf(zzerrMsg, str, token1, token2, token3);
00451   yyerror(zzerrMsg);
00452 }
00453 
00454 
00455 void zzerr(const char* const & str, const char* const & token1, 
00456            const int& token2, const int& token3)
00457 {
00458   sprintf(zzerrMsg, str, token1, token2, token3);
00459   yyerror(zzerrMsg);
00460 }
00461 
00462 
00463 void zzwarn(const char* const & str)
00464 {
00465   if (zzisParsing)
00466     printf("WARNING in %s: line %d, col %d: %s\n", 
00467            rmTmpPostfix(zzinFileName).c_str(), zzline, zzcolumn, str);
00468   else
00469     printf("WARNING after parsing %s: %s\n", 
00470            rmTmpPostfix(zzinFileName).c_str(), str);
00471 }
00472 
00473 
00474 void zzwarn(const char* const & str, const char* const & token)
00475 {
00476   sprintf(zzerrMsg, str, token);
00477   zzwarn(zzerrMsg);
00478 }
00479 
00480 
00481 void zzexit(const char* const & str)
00482 {
00483   zzerr(str);
00484   exit(-1);
00485 }
00486 
00487 
00488 void zzexit(const char* const & str, const char* const & token)
00489 {
00490   zzerr(str,token);
00491   exit(-1);
00492 }
00493 
00494 
00495 void zzassert(const bool& condn, const char* const & str)
00496 {
00497   string s("assertion failed! ");
00498   s.append(str);
00499   if (!condn) zzexit(s.c_str()); 
00500 }
00501 
00502 
00503 void zzmsg(const char* const & str)
00504 {
00505   if (zzisParsing)
00506     printf("in %s: line %d, col %d: %s\n", 
00507            rmTmpPostfix(zzinFileName).c_str(), zzline, zzcolumn, str);
00508   else
00509     printf("after parsing %s: %s\n", rmTmpPostfix(zzinFileName).c_str(), str);
00510 }
00511 
00512 
00513 void zzmsg(const char* const & str, const char* const & token)
00514 {
00515   sprintf(zzerrMsg, str, token);
00516   zzmsg(zzerrMsg);
00517 }
00518 
00519 
00521 
00522 string zzgetNewVarName(const char* const & varName)
00523 {
00524   ZZOldNewVarList::iterator it = zzoldNewVarList.begin();
00525   for (; it != zzoldNewVarList.end(); it++)
00526   {
00527     StringToStringMap* oldNewVarMap = (*it).first;
00528     StringToStringMap::iterator mit;
00529     if ((mit = oldNewVarMap->find(varName)) != oldNewVarMap->end())
00530       return (*mit).second;
00531   }
00532   return string(varName);
00533 }
00534 
00535 
00536   // returns var id (negative number) or 0 if varName is of wrong type
00537 int zzgetVarId(const char* const& varName, const int& varTypeId,
00538                int& expectedTypeId)
00539 {
00540   string vname = varName;
00541 
00542     // search last element (which corresponds to the scope of the entire formula
00543   ZZVarNameToIdMap::iterator mit;
00544   if ((mit=zzvarNameToIdMap.find(vname)) == zzvarNameToIdMap.end())
00545   {
00546     ZZVarIdType v(--zzvarCounter, varTypeId);
00547     zzvarNameToIdMap[vname] = v;
00548     return v.id_;
00549   }
00550 
00551   ZZVarIdType& varIdType = (*mit).second;
00552   int typeId = varTypeId; //avoid confusion later
00553 
00554   if (varIdType.typeId_ == zzanyTypeId)
00555   {
00556     varIdType.typeId_ = typeId;
00557     expectedTypeId = varIdType.typeId_;
00558     return varIdType.id_;
00559   }
00560 
00561   if (typeId != zzanyTypeId && typeId != varIdType.typeId_) 
00562   {
00563     expectedTypeId = varIdType.typeId_;
00564     return 0;
00565   }
00566   return varIdType.id_;  
00567 }
00568 
00569 
00570 int zzgetVarTypeId(const char* const& varName)
00571 {
00572   ZZVarNameToIdMap::iterator mit;
00573   if ((mit=zzvarNameToIdMap.find(string(varName))) != zzvarNameToIdMap.end())
00574     return (*mit).second.typeId_;
00575   return -1;
00576 }
00577 
00578 
00579 void zzcheckVarNameToIdMap()
00580 {
00581   ZZVarNameToIdMap::iterator it = zzvarNameToIdMap.begin();
00582   for (;it != zzvarNameToIdMap.end(); it++)
00583     if ((*it).second.typeId_ == zzanyTypeId)
00584       zzerr("Variable %s has unknown type.", (*it).first.c_str()); 
00585 }
00586 
00587 
00588   // returns var id (negative number) or 0 if varName is of wrong type
00589 bool zzvarIsQuantified(const char* const& varName)
00590 {
00591   ZZOldNewVarList::iterator it = zzoldNewVarList.begin();
00592   for (; it != zzoldNewVarList.end(); it++)
00593   {
00594     StringToStringMap* oldNewVarMap = (*it).first;
00595     StringToStringMap::iterator mit;
00596     if ((mit = oldNewVarMap->find(varName)) != oldNewVarMap->end())
00597       return true;
00598   }
00599   return false;
00600 }
00601 
00602 
00603    // Caller must delete the returned VarTypeMap
00604 VarTypeMap* zzcreateVarTypeMap(const ZZVarNameToIdMap& map)
00605 {
00606   VarTypeMap* vtMap = new VarTypeMap;
00607   ZZVarNameToIdMap::const_iterator it = map.begin();
00608   for (; it != map.end(); it++)
00609     (*vtMap)[(*it).first] =(*it).second.typeId_;
00610   return vtMap;
00611 }
00612 
00613 
00614 void zzsetPlusVarTypeId()
00615 {
00616   StringToIntMap::iterator mit = zzplusVarMap.begin();
00617   for (; mit != zzplusVarMap.end(); mit++)
00618   {
00619     string plusVarName = (*mit).first;
00620     ZZVarNameToIdMap::iterator typeIt = zzvarNameToIdMap.find(plusVarName);
00621     zzassert(typeIt != zzvarNameToIdMap.end(),
00622              "expect typeIt != zzvarNameToIdMap.end()");
00623     //commented out: done in zzcheckVarNameToIdMap()
00624     //zzassert((*mit).second.typeId_ > 0,"expect typedId > 0");
00625     (*mit).second = (*typeIt).second.typeId_;
00626   }
00627 }
00628 
00629 
00631 
00632 
00640 bool zzisInternalFunction(const char* funcname)
00641 {
00642   for (int i = 0; i < zzinternalFunctions.size(); i++)
00643         if (strcmp(funcname, zzinternalFunctions[i][0]) == 0)
00644           return true;
00645 
00646   return false;
00647 }
00648 
00649 // Returns the index of internal function with name funcname if found, otherwise 0
00650 int zzfindInternalFunction(const char* funcname)
00651 {
00652   for (int i = 0; i < zzinternalFunctions.size(); i++)
00653     if (strcmp(funcname, zzinternalFunctions[i][0]) == 0)
00654       return i;
00655   return -1;
00656 }
00657 
00665 bool zzisInternalPredicate(const char* predname)
00666 {
00667   for (int i = 0; i < zzinternalPredicates.size(); i++)
00668         if (strcmp(predname, zzinternalPredicates[i][0]) == 0)
00669           return true;
00670 
00671   return false;
00672 }
00673 
00674 // Returns the index of internal predicate with name predname if found, otherwise 0
00675 int zzfindInternalPredicate(const char* predname)
00676 {
00677   for (int i = 0; i < zzinternalPredicates.size(); i++)
00678     if (strcmp(predname, zzinternalPredicates[i][0]) == 0)
00679       return i;
00680   return -1;
00681 }
00682 
00691 bool zzisLinkedFunction(const char* funcname, void* handle)
00692 {
00693   string (*funccall)(string);
00694   char *error;
00695 
00696   dlerror();    // Clear any existing error
00697   *(void **) (&funccall) = dlsym(handle, funcname);
00698   if ((error = dlerror()) != NULL) return false;
00699 
00700   return true;
00701 }
00702 
00711 bool zzisLinkedPredicate(const char* predname, void* handle)
00712 {
00713   bool (*funccall)(string);
00714   char *error;
00715 
00716   dlerror();    // Clear any existing error
00717   *(void **) (&funccall) = dlsym(handle, predname);
00718   if ((error = dlerror()) != NULL) return false;
00719 
00720   return true;
00721 }       
00722 
00723 void zzsetEqPredTypeName(const int& typeId)
00724 {  
00725   const char * typeName = zzdomain->getTypeName(typeId);
00726   string eqPredName = PredicateTemplate::createEqualPredTypeName(typeName);
00727   const PredicateTemplate* t = zzdomain->getPredicateTemplate(eqPredName.c_str());
00728   zzpred->setTemplate((PredicateTemplate*)t);
00729   zzassert(t != NULL,
00730            "expect equal pred template != NULL");
00731   ListObj* predlo = zzpredFuncListObjs.top(); 
00732   predlo->replace(PredicateTemplate::EQUAL_NAME, eqPredName.c_str());
00733 }
00734 
00735 
00736 int zzgetTypeId(const Term* const & t, const char* const & varName)
00737 {
00738   int termType = t->getType();
00739   if (termType == Term::FUNCTION) 
00740     return t->getFunction()->getRetTypeId();
00741  
00742   if (termType == Term::CONSTANT) 
00743     return zzdomain->getConstantTypeId(t->getId());
00744 
00745   if (termType == Term::VARIABLE) 
00746   {
00747     ZZVarNameToIdMap::iterator mit = zzvarNameToIdMap.find(varName);
00748     if (mit != zzvarNameToIdMap.end()) return (*mit).second.typeId_;
00749     return zzanyTypeId;
00750   }
00751   zzassert(false, "expect FUNCTION, VARIABLE, CONSTANT");
00752   return -1;
00753 }
00754 
00755 
00756 void zzdetermineEqPredTypes(ListObj* const & formula)
00757 {
00758   unsigned int prevSize = 0;
00759   while (zzeqPredList.size() != prevSize)
00760   {
00761     prevSize = zzeqPredList.size();
00762     list<ZZUnknownEqPredInfo>::iterator lit, remIt ;
00763     for (lit = zzeqPredList.begin(); lit != zzeqPredList.end(); lit++)
00764     {
00765       ZZUnknownEqPredInfo& uepi = (*lit);
00766       string lvarName = uepi.lhs_;
00767       string rvarName = uepi.rhs_;
00768       int lTypeId = zzgetVarTypeId(lvarName.c_str());
00769       int rTypeId = zzgetVarTypeId(rvarName.c_str());
00770 
00771       if (lTypeId > 0 && rTypeId > 0) //if both types are known
00772       {
00773         if (lTypeId != rTypeId)
00774           zzerr("The types of %s and %s on the left and right of "
00775                 "'=' must match.", lvarName.c_str(), rvarName.c_str());
00776         const char * typeName = zzdomain->getTypeName(lTypeId);
00777         string eqPredName 
00778           = PredicateTemplate::createEqualPredTypeName(typeName);
00779         formula->replace(uepi.name_.c_str(), eqPredName.c_str());
00780         remIt = lit; lit++; zzeqPredList.erase(remIt);
00781         
00782       }
00783       else  // if only one type is known
00784       if ( (lTypeId<=0 && rTypeId>0) || (lTypeId>0 && rTypeId<=0) )
00785       {
00786         int knownTypeId = (lTypeId>0) ? lTypeId : rTypeId;
00787         const char * typeName = zzdomain->getTypeName(knownTypeId);
00788         string eqPredName 
00789           = PredicateTemplate::createEqualPredTypeName(typeName);
00790         formula->replace(uepi.name_.c_str(), eqPredName.c_str());
00791         const char* unknowVarName = (lTypeId>0) ?  rvarName.c_str() : 
00792                                                    lvarName.c_str();
00793         zzvarNameToIdMap[unknowVarName].typeId_ = knownTypeId;
00794         remIt = lit; lit++; zzeqPredList.erase(remIt);  
00795       }
00796     }
00797   }
00798   if (zzeqPredList.size() > 0)
00799   {
00800     zzerr("The following variables used with the '=' operator have "
00801          "unknown types");
00802     list<ZZUnknownEqPredInfo>::iterator lit; 
00803     for (lit = zzeqPredList.begin(); lit != zzeqPredList.end(); lit++)
00804       cout << (*lit).lhs_ << " " << (*lit).rhs_ << " ";
00805     cout << endl;
00806   }
00807 }
00808 
00809 void zzdetermineIntPredTypes(ListObj* const & formula)
00810 {
00811   unsigned int prevSize = 0;
00812   while (zzintPredList.size() != prevSize)
00813   {
00814     prevSize = zzintPredList.size();
00815     list<ZZUnknownIntPredInfo>::iterator lit, remIt ;
00816     for (lit = zzintPredList.begin(); lit != zzintPredList.end(); lit++)
00817     {
00818       ZZUnknownIntPredInfo& uipi = (*lit);
00819       string lvarName = uipi.lhs_;
00820       string rvarName = uipi.rhs_;
00821           string baseName = uipi.name_.substr(0, uipi.name_.find_last_of("_"));
00822       int lTypeId = zzgetVarTypeId(lvarName.c_str());
00823       int rTypeId = zzgetVarTypeId(rvarName.c_str());
00824 
00825       if (lTypeId > 0 && rTypeId > 0) //if both types are known
00826       {
00827         if (lTypeId != rTypeId)
00828           zzerr("The types of %s and %s on the left and right of "
00829                 "an internal opreator must match.",
00830                 lvarName.c_str(), rvarName.c_str());
00831         const char * typeName = zzdomain->getTypeName(lTypeId);
00832         string intPredName 
00833           = PredicateTemplate::createInternalPredTypeName(baseName.c_str(), typeName);
00834         formula->replace(uipi.name_.c_str(), intPredName.c_str());
00835         remIt = lit; lit++; zzintPredList.erase(remIt);        
00836       }
00837       else  // if only one type is known
00838       if ( (lTypeId<=0 && rTypeId>0) || (lTypeId>0 && rTypeId<=0) )
00839       {
00840         int knownTypeId = (lTypeId>0) ? lTypeId : rTypeId;
00841         const char * typeName = zzdomain->getTypeName(knownTypeId);
00842         string intPredName 
00843           = PredicateTemplate::createInternalPredTypeName(baseName.c_str(), typeName);
00844         formula->replace(uipi.name_.c_str(), intPredName.c_str());
00845         const char* unknowVarName = (lTypeId>0) ?  rvarName.c_str() : 
00846                                                    lvarName.c_str();
00847         zzvarNameToIdMap[unknowVarName].typeId_ = knownTypeId;
00848         remIt = lit; lit++; zzintPredList.erase(remIt);  
00849       }
00850     }
00851   }
00852   if (zzintPredList.size() > 0)
00853   {
00854     zzerr("The following variables used with an internal operator have "
00855          "unknown types");
00856     list<ZZUnknownIntPredInfo>::iterator lit; 
00857     for (lit = zzintPredList.begin(); lit != zzintPredList.end(); lit++)
00858       cout << (*lit).lhs_ << " " << (*lit).rhs_ << " ";
00859     cout << endl;
00860   }
00861 }
00862 
00863 void zzdetermineIntFuncTypes(ListObj* const & formula)
00864 {
00865   unsigned int prevSize = 0;
00866   while (zzintFuncList.size() != prevSize)
00867   {
00868     prevSize = zzintFuncList.size();
00869     list<ZZUnknownIntFuncInfo>::iterator lit, remIt ;
00870     for (lit = zzintFuncList.begin(); lit != zzintFuncList.end(); lit++)
00871     {
00872       ZZUnknownIntFuncInfo& uifi = (*lit);
00873       Array<string> varNames = uifi.vnames_;
00874           string baseName = uifi.name_.substr(0, uifi.name_.find_last_of("_"));
00875 
00876           bool unknownTypes = false;
00877       Array<int> typeIds;
00878       for  (int i = 0; i < varNames.size(); i++)
00879       {
00880         int typeId = zzgetVarTypeId(varNames[i].c_str());
00881         typeIds.append(typeId);
00882                 if (typeId <= 0)
00883                 {
00884                   unknownTypes = true;
00885                 }
00886       }
00887 
00888       if (!unknownTypes) //if both types are known
00889       {
00890         Array<string> typeNames;
00891         for (int i = 0; i < typeIds.size(); i++)
00892         {
00893           string typeName = zzdomain->getTypeName(typeIds[i]);
00894           typeNames.append(typeName);
00895         }
00896         string intPredFromFuncName 
00897           = FunctionTemplate::createInternalFuncTypeName(baseName.c_str(), typeNames);
00898         formula->replace(uifi.name_.c_str(), intPredFromFuncName.c_str());
00899         remIt = lit; lit++; zzintFuncList.erase(remIt);
00900       }
00901     }
00902   }
00903   if (zzintFuncList.size() > 0)
00904   {
00905     zzerr("The following variables used with an internal function have "
00906          "unknown types");
00907     list<ZZUnknownIntFuncInfo>::iterator lit; 
00908     for (lit = zzintFuncList.begin(); lit != zzintFuncList.end(); lit++)
00909     {
00910       for (int i = 1; i < (*lit).vnames_.size(); i++)
00911         cout << (*lit).vnames_[i] << " ";
00912     }
00913     cout << endl;
00914   }
00915 }
00916 
00917 
00918 bool zzcheckRightTypeAndGetVarId(const int& typeId, const char* const& varName,
00919                                  int& varId)
00920 {
00921   // check that the variable is of the right type
00922   int expectedTypeId = -1;
00923   varId = zzgetVarId(varName,typeId,expectedTypeId);
00924   if (varId==0) 
00925   {
00926     const char* expName = zzdomain->getTypeName(typeId);
00927     const char* unexpName = zzdomain->getTypeName(expectedTypeId);
00928     zzerr("Variable %s is of the wrong type. Expected %s but given %s", 
00929           varName, expName, unexpName);
00930     return false;
00931   }
00932   return true;
00933 }
00934 
00935 void zzaddType(const char* const& typeName, 
00936                PredicateTemplate* const& predTemplate, 
00937                FunctionTemplate* const& funcTemplate,
00938                bool isUnique, const Domain* const & domain)
00939 {
00940   if (isUnique && funcTemplate != NULL)
00941   {
00942     zzerr("Function parameter (%s) cannot be existentially and uniquely "
00943           "quantified",typeName);
00944     isUnique = false;
00945   }
00946 
00947   if (predTemplate != NULL)
00948   { 
00949     bool ok = predTemplate->appendTermType(typeName, isUnique, domain);
00950     if(!ok) zzexit("Term type %s should have been declared.", typeName);
00951   }
00952   else 
00953   if (funcTemplate != NULL) 
00954   {
00955     bool ok = funcTemplate->appendTermType(typeName, isUnique, domain);
00956     if (!ok) zzexit("Term type %s should have been declared.", typeName);
00957   }
00958 }
00959 
00960 
00961 int zzaddTypeToDomain(Domain* const & domain, const char* const & typeName)
00962 {
00963   int typeId = domain->addType(typeName);
00964   
00965   if (typeName != PredicateTemplate::ANY_TYPE_NAME)
00966   {
00967       // create a PredicateTemplate to represent '=' (equality pred) for type
00968     string ptName = PredicateTemplate::createEqualPredTypeName(typeName);
00969     if (domain->getPredicateTemplate(ptName.c_str()) == NULL)
00970     {
00971       PredicateTemplate* pt = new PredicateTemplate();
00972       pt->setName(ptName.c_str());
00973       pt->appendTermType(typeName, false, domain);
00974       pt->appendTermType(typeName, false, domain);
00975       int id = domain->addPredicateTemplate(pt);
00976       zzassert(id >= 0, "expect pred template id >= 0");
00977       pt->setId(id);
00978     }
00979     
00980       // create a PredicateTemplate for each internal pred. for this type
00981 /*
00982     Array<string> ptNames = PredicateTemplate::createInternalPredTypeNames(typeName);
00983         for (int i = 0; i < ptNames.size(); i++)
00984         {
00985           string ptName = ptNames[i];
00986           if (domain->getPredicateTemplate(ptName.c_str()) == NULL)
00987       {
00988         PredicateTemplate* pt = new PredicateTemplate();
00989         pt->setName(ptName.c_str());
00990         pt->appendTermType(typeName, false, domain);
00991         pt->appendTermType(typeName, false, domain);
00992         int id = domain->addPredicateTemplate(pt);
00993         zzassert(id >= 0, "expect pred template id >= 0");
00994         pt->setId(id);
00995       }
00996         }
00997 */
00998   }
00999 
01000   return typeId;
01001 }
01002 
01003 void zzcreatePred(Predicate*& pred, const char* const & predName)
01004 {
01005   const PredicateTemplate* t = zzdomain->getPredicateTemplate(predName);
01006   if (t==NULL)
01007   {
01008         int index = zzfindInternalPredicate(predName);
01009         // Internal predicates are declared on the fly
01010     if (index >= 0)
01011     {
01012       zzassert(zzdomain->getFunctionId(predName) < 0, 
01013                "not expecting pred name to be declared as a function name");
01014           PredicateTemplate* ptemplate = new PredicateTemplate();
01015           ptemplate->setName(predName);
01016         
01017           // Add types
01018           for (int j = 1; j < zzinternalPredicates[index].size(); j++)
01019           {
01020             int id;
01021             const char* ttype = zzinternalPredicates[index][j];
01022             if (!zzdomain->isType(ttype))
01023             {
01024                   id = zzaddTypeToDomain(zzdomain, ttype);
01025                   zzassert(id >= 0, "expecting var id >= 0");
01026             }
01027             zzaddType(ttype, ptemplate, NULL, false, zzdomain);
01028             //delete [] ttype;
01029           }
01030         
01031           // Add template to domain
01032           zzassert(ptemplate, "not expecting ptemplate==NULL");
01033           int id = zzdomain->addPredicateTemplate(ptemplate);
01034           zzassert(id >= 0, "expecting pred template id >= 0");
01035           ptemplate->setId(id);
01036           zzassert(pred == NULL, "expect pred == NULL");
01037           pred = new Predicate(ptemplate);
01038           return; 
01039     }
01040     else
01041           zzexit("Predicate %s should have been declared.", predName);
01042   }
01043     // commented out because when zzcreatePred is called predicate has already 
01044     // been declared
01045   //if (t == NULL) 
01046   //{
01047   //  zzerr("Failed to find predicate %s. Have you declared it?", predName);
01048   //    // create a fake predicate template and attempt to recover
01049   //  char buf[32];
01050   //  sprintf(buf, "%s%d", zzdefaultPredName, zzcount++); 
01051   //  zzpredTemplate = new PredicateTemplate();
01052   //  zzpredTemplate->setDomain(zzdomain);
01053   //  zzpredTemplate->setName(buf);
01054   //  int id = zzdomain->addPredicateTemplate(zzpredTemplate);
01055   //  zzassert(id >= 0, "expect id >= 0");
01056   //  zzpredTemplate->setId(id);
01057   //  for (int i = 0; i < 20; i++)
01058   //  {
01059   //    sprintf(buf, "%s%d",zzdefaultTypeName, zzcount++); 
01060   //    bool ok = zzpredTemplate->appendTermType(buf, false, zzdomain);
01061   //    if(!ok) zzexit("");
01062   //  }
01063   //  t = zzpredTemplate;
01064   //  zzpredTemplate = NULL;
01065   //}
01066 
01067   zzassert(pred == NULL, "expect pred == NULL");
01068   pred = new Predicate(t); 
01069 }
01070 
01071 
01072 
01073 void zzcheckPredNumTerm(Predicate*& pred)
01074 {
01075   int exp, unexp;
01076   if ((unexp=pred->getNumTerms()) != (exp=pred->getTemplate()->getNumTerms()))
01077   {
01078     zzerr("Wrong number of terms for predicate %s. Expected %d but given %d", 
01079           pred->getName(), exp, unexp);
01080   
01081     char buf[128];
01082       // try to recover
01083     for (int i = unexp; i < exp; i++)
01084     {
01085       sprintf(buf, "%s%d", zzdefaultVarName, zzcount++); 
01086       int typeId = pred->getTermTypeAsInt(i);
01087       int varId;
01088       bool rightType = zzcheckRightTypeAndGetVarId(typeId, buf, varId);
01089       if (!rightType) zzexit("");
01090       pred->appendTerm(new Term(varId, (void*)pred, true));
01091     }
01092   }
01093 }
01094 
01095 
01096 void zzpredAppendConstant(Predicate* const& pred, const int& constId,
01097                           const char* const & constName)
01098 {    
01099     // if exceeded the number of terms
01100   int exp, unexp;
01101   if ((unexp=pred->getNumTerms()) == (exp=pred->getTemplate()->getNumTerms()))
01102   {
01103     zzerr("Wrong number of terms for predicate %s. Expected %d but given >%d", 
01104           pred->getName(), exp, unexp);
01105     return;
01106   }
01107 
01108     // if this is not '=' predicate with unknown types
01109   if (!(strcmp(pred->getName(),PredicateTemplate::EQUAL_NAME)==0) &&
01110           !(strcmp(pred->getTermTypeAsStr(pred->getNumTerms()),PredicateTemplate::ANY_TYPE_NAME)==0))
01111   {
01112       // Check that constant has same type as that of predicate term
01113     int typeId = pred->getTermTypeAsInt(pred->getNumTerms());
01114     int unexpId; 
01115     if (typeId != (unexpId=zzdomain->getConstantTypeId(constId)))
01116     {
01117       const char* expName = zzdomain->getTypeName(typeId);
01118       const char* unexpName = zzdomain->getTypeName(unexpId);
01119       zzerr("Constant %s is of the wrong type. Expected %s but "
01120             "given %s", constName, expName, unexpName);
01121       return;
01122     }
01123   }
01124   
01125     // at this point, we have the right num of terms and right constant types
01126   if (pred != NULL) pred->appendTerm(new Term(constId, (void*)pred, true));
01127 }
01128 
01129 
01131 
01132 void zzconsumeToken(StrFifoList& tokenList, const char* c)
01133 {
01134   const char* tok = tokenList.removeLast();
01135   if (strcmp(tok, c)!=0)
01136   {
01137     cout << "token = '" << tok << "', '" << c << "'" << endl;
01138     zzassert(strcmp(tok, c)==0, "expect strcmp(tok,c)==0");
01139   }
01140   delete [] tok;
01141 }
01142 
01143 
01144 void zzcreateFunc(Function*& func, const char* const & funcName)
01145 {
01146   const FunctionTemplate* t = zzdomain->getFunctionTemplate(funcName);
01147   if (t==NULL)
01148   {
01149         // Internal functions are declared on the fly
01150     int index;
01151         if ((index = zzfindInternalFunction(funcName)) >= 0)
01152         {
01153       zzassert(zzfuncTemplate==NULL, "expecting zzfuncTemplate==NULL");
01154           zzfuncTemplate = new FunctionTemplate();
01155 
01156           // We are creating a new predicate as well
01157           zzassert(zzpredTemplate==NULL,"expecting zzpredTemplate==NULL");
01158           zzpredTemplate = new PredicateTemplate();
01159 
01160           zzassert(zzdomain->getPredicateId(funcName) < 0, 
01161                "not expecting func name to be declared as pred name");
01162           zzassert(zzfuncTemplate,"expecting zzfuncTemplate!=NULL");
01163           zzfuncTemplate->setName(funcName);
01164 
01165           // Predicate name is PredicateTemplate::ZZ_RETURN_PREFIX + function name
01166           char* predName;
01167           predName = (char *)malloc((strlen(PredicateTemplate::ZZ_RETURN_PREFIX) +
01168                                                         strlen(funcName) + 1)*sizeof(char));
01169           strcpy(predName, PredicateTemplate::ZZ_RETURN_PREFIX);
01170           strcat(predName, funcName);
01171         
01172           // Check that predicate has not been declared a function
01173           zzassert(zzdomain->getFunctionId(predName) < 0, 
01174                        "not expecting pred name to be declared as a function name");
01175           zzassert(zzpredTemplate,"expecting zzpredTemplate!=NULL");
01176           zzpredTemplate->setName(predName);
01177           delete [] predName;  
01178         
01179           // Add return type
01180           const char* retTypeName = zzinternalFunctions[index][1];
01181 
01182           if (!zzdomain->isType(retTypeName))
01183           {
01184             int id = zzaddTypeToDomain(zzdomain, retTypeName);
01185         zzassert(id >= 0, "expecting retTypeName's id >= 0");
01186           }
01187 
01188           zzfuncTemplate->setRetTypeName(retTypeName,zzdomain);
01189           // We are creating a new predicate as well
01190           zzaddType(retTypeName, zzpredTemplate, NULL, false, zzdomain);
01191   
01192           // Add types
01193           for (int j = 2; j < zzinternalFunctions[index].size(); j++)
01194           {
01195             int id;
01196             const char* ttype = zzinternalFunctions[index][j];
01197             if (!zzdomain->isType(ttype))
01198             {
01199                   id = zzaddTypeToDomain(zzdomain, ttype);
01200                   zzassert(id >= 0, "expecting var id >= 0");
01201             }
01202             zzaddType(ttype, zzpredTemplate, NULL, false, zzdomain);
01203             // Add the type to the function too
01204             zzaddType(ttype, NULL, zzfuncTemplate, false, zzdomain);
01205           }
01206 
01207           // Add templates to domain
01208           zzassert(zzfuncTemplate, "expecting zzfuncTemplate != NULL");
01209           int id = zzdomain->addFunctionTemplate(zzfuncTemplate);
01210           zzassert(id >= 0, "expecting function template's id >= 0");
01211           zzfuncTemplate->setId(id);
01212 
01213           zzassert(zzpredTemplate, "not expecting zzpredTemplate==NULL");
01214           int predId = zzdomain->addPredicateTemplate(zzpredTemplate);
01215           zzassert(predId >= 0, "expecting pred template id >= 0");
01216           zzpredTemplate->setId(predId);
01217 
01218           zzassert(func == NULL, "expect func == NULL");
01219           func = new Function(zzfuncTemplate);
01220           zzfuncTemplate = NULL;
01221           zzpredTemplate = NULL;
01222           return;
01223         }
01224         else
01225         zzexit("Function %s should have been declared.", funcName);
01226   }
01227   //if (t == NULL) 
01228   //{
01229   //  zzerr("Failed to find function %s. Have you declared it?", funcName);
01230   //    // create a fake predicate template and attempt to recover
01231   //  char buf[32];
01232   //  sprintf(buf, "%s%d", zzdefaultFuncName, zzcount++); 
01233   //  zzfuncTemplate = new FunctionTemplate();
01234   //  zzfuncTemplate->setDomain(zzdomain);
01235   //  zzfuncTemplate->setRetTypeName(PredicateTemplate::ANY_TYPE_NAME);
01236   //  zzfuncTemplate->setName(buf);
01237   //  int id = zzdomain->addFunctionTemplate(zzfuncTemplate);
01238   //  zzassert(id >= 0, "expect id >= 0");
01239   //  zzfuncTemplate->setId(id);
01240   //  for (int i = 0; i < 20; i++)
01241   //  {
01242   //    sprintf(buf, "%s%d",zzdefaultTypeName, zzcount++); 
01243   //    bool ok = zzfuncTemplate->appendTermType(buf, false, zzdomain);
01244   //    if(!ok) zzexit("");
01245   //  }
01246   //  t = zzfuncTemplate;
01247   //  zzfuncTemplate = NULL;
01248   //}
01249 
01250   zzassert(func == NULL, "expect func == NULL");
01251   func = new Function(t);
01252 }
01253 
01254 
01255 void zzcheckFuncNumTerm(Function*& func)
01256 {
01257   int exp, unexp;
01258   if ((unexp=func->getNumTerms()) != (exp=func->getTemplate()->getNumTerms()))
01259   {
01260     zzerr("Wrong number of terms for func %s. Expected %d but given %d", 
01261           func->getName(), exp, unexp);
01262   
01263     char buf[128];
01264       // try to recover
01265     for (int i = unexp; i < exp; i++)
01266     {
01267       sprintf(buf, "%s%d", zzdefaultVarName, zzcount++); 
01268       int typeId = func->getTermTypeAsInt(i);
01269       int varId;
01270       bool rightType = zzcheckRightTypeAndGetVarId(typeId, buf, varId);
01271       if (!rightType) zzexit("");
01272       func->appendTerm(new Term(varId, (void*)func, false));
01273     }
01274   }
01275 }
01276 
01277 
01278 void zzfuncAppendConstant(Function* const& func, const int& constId,
01279                           const char* const & constName)
01280 {    
01281     // if exceeded the number of terms
01282   int exp, unexp;
01283   if ((unexp=func->getNumTerms()) == (exp=func->getTemplate()->getNumTerms()))
01284   {
01285     zzerr("Wrong number of terms for function %s. Expected %d but given > %d", 
01286           func->getName(), exp, unexp);
01287     return;
01288   }
01289 
01290   if (!(strcmp(func->getTermTypeAsStr(func->getNumTerms()),PredicateTemplate::ANY_TYPE_NAME)==0))
01291   {
01292           // Check that constant has same type as that of predicate term
01293         int typeId = func->getTermTypeAsInt(func->getNumTerms());
01294         int unexpId; 
01295         if (typeId != (unexpId=zzdomain->getConstantTypeId(constId)))
01296         {
01297       const char* expName = zzdomain->getTypeName(typeId);
01298       const char* unexpName = zzdomain->getTypeName(unexpId);
01299       zzerr("Constant %s is of the wrong type. Expected %s but given %s", 
01300             constName, expName, unexpName);
01301       return;
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 ((clauselo[0]->getStr())[0] == 'v')
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 
01572   //create clauses from an existentially and uniquely quantified variables
01573 int zzcreateExistUniqueClauses(Array<Clause*>& clauses, 
01574                                const Array<int>& uniqueVarIndexes,
01575                                const Domain* const & domain)
01576 {
01577   if (clauses.size() != 1 || uniqueVarIndexes.size() <= 0)
01578     zzexit("ERROR: in zzcreateExistUniqueClauses. "
01579            "clauses.size() != 1 || uniqueVarIndexes.size() <= 0");
01580 
01581     //c has been canonicalized
01582   Clause* c = clauses[0];
01583   clauses.clear();
01584   Predicate* pred = (Predicate*) c->getPredicate(0); 
01585  
01586   Array<int> nonUniqVarIndexes, nonUniqVarIds;
01587   for (int i = 0; i < pred->getNumTerms(); i++)
01588   {
01589     if (uniqueVarIndexes.contains(i)) continue;
01590     nonUniqVarIndexes.append(i);
01591     nonUniqVarIds.append(pred->getTerm(i)->getId());
01592   }
01593 
01594   for (int i = 0; i < nonUniqVarIndexes.size(); i++)
01595     ((Term*)pred->getTerm(nonUniqVarIndexes[i]))->setId(1);
01596  
01597   Array<Predicate*> predArr;
01598   pred->createAllGroundings(domain, &predArr, NULL);
01599   int numPreds = predArr.size();
01600 
01601   for (int i = 0; i < numPreds; i++)
01602   {
01603     Predicate* newPred = predArr[i];
01604     for (int j = 0; j < nonUniqVarIndexes.size(); j++)
01605     {
01606       Term* t = (Term*)newPred->getTerm(nonUniqVarIndexes[j]);
01607       t->setId(nonUniqVarIds[j]);
01608     }
01609   }
01610 
01611     // Commented out: Mut. excl. and exh. variables are handled
01612     // internally by the learning and inference algorithms
01613 /*      
01614     // At-least-one (ALO) clause
01615   Clause* cc = new Clause;
01616   for (int i = 0; i < numPreds; i++)
01617   {
01618     Predicate* newPred = new Predicate(*(predArr[i]));
01619     newPred->setParent(cc);
01620     cc->appendPredicate(newPred);
01621   }
01622   clauses.append(cc);
01623 
01624     // At-most-one (AMO) clauses
01625   for (int i = 0; i < numPreds; i++)
01626     for (int j = i+1; j < numPreds; j++)
01627     {
01628       Clause* cc = new Clause;
01629       Predicate* newPred = new Predicate(*(predArr[i]));
01630       newPred->setParent(cc);
01631       newPred->setSense(false);
01632       cc->appendPredicate(newPred);
01633 
01634       Predicate* newPred2 = new Predicate(*(predArr[j]));
01635       newPred2->setParent(cc);
01636       newPred2->setSense(false);
01637       cc->appendPredicate(newPred2);
01638       clauses.append(cc);
01639     }
01640 */
01641     // Add predicates to blocks
01642   Array<Array<Predicate*>*>* predBlocks = new Array<Array<Predicate*>*>;
01643   
01644     // # blocks = (# const. of nonUniqVar 1) * (# const. of nonUniqVar 2) ...
01645   int numBlocks = 1;
01646   for (int i = 0; i < nonUniqVarIndexes.size(); i++)
01647   {
01648     int typeId = pred->getTermTypeAsInt(nonUniqVarIndexes[i]);
01649     numBlocks *= domain->getNumConstantsByType(typeId);
01650   }
01651   predBlocks->growToSize(numBlocks);
01652 
01653   for (int i = 0; i < numBlocks; i++)
01654   {
01655     Array<Predicate*>* predBlock = new Array<Predicate*>;
01656     (*predBlocks)[i] = predBlock;
01657   }
01658   
01659   for (int i = 0; i < numPreds; i++)
01660   {
01661     Predicate* newPred = new Predicate(*(predArr[i]));
01662     Array<Predicate*> predGndings;
01663     newPred->createAllGroundings(domain, &predGndings, NULL);
01664 
01665     for (int j = 0; j < predGndings.size(); j++)
01666     {
01667       Predicate* predGnding = new Predicate(*(predGndings[j]));
01668       (*predBlocks)[j]->append(predGnding);
01669     }
01670     predGndings.deleteItemsAndClear();
01671     delete newPred;
01672   }
01673 
01674   for (int i = 0; i < numBlocks; i++)
01675   {
01676     Array<Predicate*>* predBlock = (*predBlocks)[i];
01677     int blockIdx = domain->addPredBlock(predBlock);
01678     
01679     for (int j = 0; j < predBlock->size(); j++)
01680     {
01681       Predicate* p = (*predBlock)[j];
01682 
01683         // If groundings of this pred occur
01684       if ((zzpredIdToGndPredMap.find(pred->getId())) != 
01685            zzpredIdToGndPredMap.end())
01686       {
01687         PredicateHashArray* pha = zzpredIdToGndPredMap[pred->getId()];
01688         int a = pha->find(p);
01689       
01690           // Only one atom in a block can be true
01691         if (a >= 0 && (*pha)[a]->getTruthValue() == TRUE)
01692         {
01693           zzassert(!domain->getBlockEvidence(blockIdx),
01694                    "More than one true atom found for mutually "
01695                    "exclusive and exhaustive variables");
01696           domain->setBlockEvidence(blockIdx, true);
01697         }
01698       }
01699     }
01700   }
01701   delete predBlocks;
01702 
01703   predArr.deleteItemsAndClear();
01704   delete c;  
01705   return numPreds;
01706 }
01707 
01709 
01710 bool zzcheckPlusTypes(const char* const & typeName,
01711                       const Domain* const & dom, const Domain* const & domain0)
01712 {
01713   if (domain0 == NULL) return true;
01714 
01715   const Array<int>* c = dom->getConstantsByType(typeName);
01716   assert(c);
01717   
01718   const Array<int>* cc = domain0->getConstantsByType(typeName);
01719   
01720   if (cc == NULL || (c->size() != cc->size())) 
01721   {
01722     zzerr("the type (\"%s\") of variables to which '+' is applied must have "
01723           "the same constants across all databases.", typeName);
01724     return false;
01725   }
01726   
01727   for (int k = 0; k < c->size(); k++)
01728   {
01729     const char* constName = dom->getConstantName((*c)[k]);      
01730     int cconstId = domain0->getConstantId(constName);
01731     const char* ttypeName = domain0->getConstantTypeName(cconstId);
01732     
01733     if (cconstId < 0 || strcmp(typeName,ttypeName) != 0)
01734     {
01735       zzerr("the type (\"%s\") of variables to which '+' is applied must have"
01736             " the same constants across all databases.", typeName);
01737       zzerr("constant %s not found or is of the wrong type", constName);
01738       return false;
01739     }
01740   }
01741   return true;
01742 }
01743 
01744 
01745 void zzgroundPlusVar(const ListObj* const & formula, const string& formulaStr,
01746                      const StringToIntMap& varNameToTypeIdMap, 
01747                      Array<ListObj*>& formulas, Array<string>& formulaStrs,
01748                      const Domain* const & domain,const Domain* const & domain0)
01749 {
01750   formulas.clear();
01751   formulaStrs.clear();
01752   if (varNameToTypeIdMap.size()==0) 
01753   {
01754     formulas.append(new ListObj(formula));
01755     formulaStrs.append(formulaStr);
01756     return; 
01757   }
01758 
01759   Array<Array<int>*> cleanUp;
01760   ArraysAccessor<int> acc;
01761   Array<string> varNames;
01762   StringToIntMap::const_iterator mit = varNameToTypeIdMap.begin();
01763   for (; mit != varNameToTypeIdMap.end(); mit++)
01764   {
01765     int typeId = (*mit).second;
01766     zzassert(typeId > 0, "expect typeId > 0");
01767 
01768     const char* typeName = domain->getTypeName(typeId);
01769     if (domain0 && !zzcheckPlusTypes(typeName, domain, domain0)) return;
01770 
01771     Array<int>* constArr;
01772     if (domain0) 
01773     {
01774       constArr = new Array<int>;
01775       cleanUp.append(constArr);
01776       const Array<int>* carr = domain0->getConstantsByType(typeName);
01777       constArr->growToSize(carr->size());
01778       for (int i = 0; i < carr->size(); i++)
01779       {
01780         const char* constName = domain0->getConstantName((*carr)[i]);
01781         int constId = domain->getConstantId(constName);
01782         zzassert(constId >= 0, "failed to find constant in zzgroundPlusVar");
01783         (*constArr)[i] = constId;
01784       }
01785     }
01786     else         
01787       constArr = (Array<int>*) domain->getConstantsByType(typeId);
01788 
01789     acc.appendArray(constArr);
01790     varNames.append((*mit).first);
01791   }
01792 
01793   Array<int> constIds;
01794   while (acc.getNextCombination(constIds))
01795   {
01796     ListObj* gndFormula = new ListObj(formula);
01797 
01798     zzassert(constIds.size() == varNames.size(),
01799              "expect constIds.size() == varNames.size()");
01800     for (int i = 0; i < varNames.size(); i++)
01801     {
01802       const char* constName = domain->getConstantName(constIds[i]);
01803       ListObj::replace(gndFormula, varNames[i].c_str(), constName, domain);
01804     }
01805     formulas.append(gndFormula);
01806 
01807     string s = formulaStr;
01808     for (int i = 0; i < constIds.size(); i++)
01809     {
01810       unsigned int a = s.find("+");
01811       assert(a != string::npos);
01812       unsigned int b = a+1;
01813       while(s.at(b) != ',' && s.at(b) != ')') b++;
01814       string front = s.substr(0, a);
01815       string back = s.substr(b, s.length()-b);
01816       s = front; 
01817       s.append(domain->getConstantName(constIds[i]));
01818       s.append(back);
01819     }
01820 
01821     formulaStrs.append(s);
01822   }
01823 
01824   if (domain0) cleanUp.deleteItemsAndClear();
01825 }
01826 
01828 
01829 
01830 void zzcreateListObjFromTop(stack<ListObj*>& stack, const char* const & op)
01831 {
01832   zzassert(zzformulaListObjs.size()>=1, "expect zzformulaListObjs.size()>=1");  
01833   ListObj* lo1 = stack.top(); stack.pop();
01834   ListObj* lo = new ListObj; lo->append(op); lo->append(lo1);
01835   stack.push(lo);
01836 }
01837 
01838 
01839 void zzcreateListObjFromTopTwo(stack<ListObj*>& stack, const char* const & op)
01840 {
01841   zzassert(zzformulaListObjs.size()>=2,"expect zzformulaListObjs.size()>=2");  
01842   ListObj* lo1 = stack.top(); stack.pop();
01843   ListObj* lo2 = stack.top(); stack.pop();
01844 
01845   if ((strcmp(op,"v")==0 && lo2->hasOrOp()) || 
01846       (strcmp(op,"^")==0 && lo2->hasAndOp()))
01847   {
01848     lo2->append(lo1);
01849     stack.push(lo2);
01850   }
01851   else
01852   {
01853     ListObj* lo = new ListObj; lo->append(op); lo->append(lo2); lo->append(lo1);
01854     stack.push(lo);
01855   }
01856 }
01857 
01858 
01859 void zzcreateListObjFromTopThree(stack<ListObj*>& stack)
01860 {
01861   zzassert(zzformulaListObjs.size()>=3, "expect zzformulaListObjs.size()>=3");  
01862   ListObj* lo1 = stack.top(); stack.pop();
01863   ListObj* lo2 = stack.top(); stack.pop();
01864   ListObj* lo3 = stack.top(); stack.pop();
01865   ListObj* lo = new ListObj; lo->append(lo3); lo->append(lo2); lo->append(lo1);
01866   stack.push(lo);
01867 }
01868 
01869 
01870 void zzcreateIntConstant(char* const & buf, const char* const & typeName, 
01871                        const int& i)
01872 { sprintf(buf, "C@%s@%d", typeName, i); }
01873 
01874   // Checks all types of domain if C@type@intStr is in domain
01875 bool isIntConstant(const int& i, const Domain* const & domain)
01876 {
01877   const Array<const char*>* typeNames = domain->getTypeNames();
01878   for (int j = 0; j < typeNames->size(); j++)
01879   {
01880         char constName[100];
01881         zzcreateIntConstant(constName, (*typeNames)[j], i);
01882         if (domain->isConstant(constName)) 
01883         {
01884           return true;
01885         }
01886   }
01887   return false;
01888 }
01889 
01890   // Returns the first type found to have C@type@intStr as a constant
01891 const char* getIntConstantTypeName(const int& i, const Domain* const & domain)
01892 { 
01893   const Array<const char*>* typeNames = domain->getTypeNames();
01894   for (int j = 0; j < typeNames->size(); j++)
01895   {
01896         char constName[100];
01897         zzcreateIntConstant(constName, (*typeNames)[j], i);
01898         if (domain->getConstantId(constName) >= 0) return (*typeNames)[j];
01899   }
01900   return NULL;
01901 }
01902 
01903 void zzcreateAndCheckIntConstant(const char* const & intStr,
01904                                  const Function* const & func,
01905                                  const Predicate* const & pred,
01906                                  const Domain* const & domain,
01907                                  char* constName)
01908 {
01909   double d = atof(intStr); int i = int(d);
01910   if (d!=i) zzerr("%s cannot be a term. Only integer terms are allowed",intStr);
01911   
01912   const char* typeName = NULL;
01913   if (func) typeName = func->getTermTypeAsStr(func->getNumTerms());
01914   else      typeName = pred->getTermTypeAsStr(pred->getNumTerms());
01915 
01916   if (typeName == NULL) 
01917   { zzerr("Too many terms for predicate/function"); constName = NULL; return;}
01918 
01919         // If type name is still open, then try to determine it
01920   if (strcmp(typeName, PredicateTemplate::ANY_TYPE_NAME)==0)
01921   {
01922           // Constant may have been previously declared
01923         if (isIntConstant(i, domain))
01924           typeName = getIntConstantTypeName(i, domain);
01925   }
01926 
01927   zzcreateIntConstant(constName, typeName, i);
01928 
01929   char buf[30]; sprintf(buf,"%f",d);
01930   if (zzconstantMustBeDeclared && domain->getConstantId(constName) < 0)
01931     zzerr("Constant %s must be declared before it is used", buf);
01932 }
01933 
01934 
01935   //ASSUMPTION: users don't define truth values of '=' ground preds e.g. A=A
01936 void zzaddGndPredsToDb(Database* const & db)
01937 {
01938   int numPreds = zzdomain->getNumPredicates();
01939   hash_map<int, PredicateHashArray*>::iterator it;
01940   for (int i = 0; i < numPreds; i++)
01941   {
01942     if ((it=zzpredIdToGndPredMap.find(i)) != zzpredIdToGndPredMap.end())
01943     {
01944       PredicateHashArray* predHashArray = (*it).second;
01945       for (int j = 0; j < predHashArray->size(); j++)
01946           {
01947         db->addEvidenceGroundPredicate((*predHashArray)[j]);
01948           }
01949       predHashArray->deleteItemsAndClear();
01950     }
01951     else
01952     {
01953       //  '=' predicates are handled specially by database
01954     }
01955   }
01956 
01957   //if (db->storeGroundPreds()) db->addAllGroundings();
01958 
01959   for (unsigned int i = 0; i < zzpredIdToGndPredMap.size(); i++)
01960     delete zzpredIdToGndPredMap[i]; 
01961 
01962 }
01963 
01964 
01965 void zzcreateBoolArr(int idx, Array<bool>*& curArray,
01966                      Array<Array<bool>*>& boolArrays)
01967 {  
01968   --idx;
01969 
01970   Array<bool>* copyArray = new Array<bool>(*curArray);
01971 
01972   curArray->append(true);
01973   copyArray->append(false);
01974 
01975   if (idx == 0) 
01976   {
01977     boolArrays.append(curArray);
01978     boolArrays.append(copyArray);
01979   }
01980   else
01981   {
01982     zzcreateBoolArr(idx, curArray, boolArrays);
01983     zzcreateBoolArr(idx, copyArray, boolArrays);
01984   }
01985 }
01986 
01987 
01988   // vs (variable or string) is the name of the constant
01989 void zzaddConstantToDomain(const char* const & vs,const char* const & typeName)
01990 {
01991   //if it is not a string and it does not begin with an uppercase char
01992   //if (vs[0] != '"' && !isupper(vs[0]))
01993   if (!zzisConstant(vs))
01994   {
01995     zzerr("Constant %s must begin in uppercase char or be a \"string\".", vs);
01996     return;
01997   }
01998 
01999   zzassert(typeName != NULL, "expect typeName != NULL");
02000   int id = zzdomain->addConstant(vs, typeName);
02001   if (id < 0) zzerr("Failed to add constant %s", vs);
02002 }
02003 
02004 
02005 void zzaddConstantToPredFunc(const char* const & constName)
02006 {
02007     //commented out because a constant can be declared with its first appearance
02008   //int constId = zzcheckConstantAndGetId(constName);
02009  
02010   int constId = zzdomain->getConstantId(constName);
02011   if (constId < 0) 
02012   {
02013     const char* typeName = NULL;
02014     if (zzfunc) typeName = zzfunc->getTermTypeAsStr(zzfunc->getNumTerms());
02015     else
02016     if (zzpred) typeName = zzpred->getTermTypeAsStr(zzpred->getNumTerms());
02017 
02018       // May be continuing after a parse error
02019     if (typeName==NULL) 
02020     {
02021       zzwarn("Wrong number of terms.");
02022       typeName=PredicateTemplate::ANY_TYPE_NAME;
02023     }
02024 
02025     zzaddConstantToDomain(constName, typeName);
02026     constId = zzdomain->getConstantId(constName);
02027   }
02028   if (zzfunc) zzfuncAppendConstant(zzfunc, constId, constName);
02029   else if (zzpred) zzpredAppendConstant(zzpred, constId, constName);
02030   else zzexit("No predicate or function is defined.");
02031 }
02032 
02033 
02034 void zztermIsConstant(const char* const & constName)
02035 {  
02036   int constId = zzdomain->getConstantId(constName);
02037     //commented out because a constant can be declared with its first appearance
02038   //if (constId < 0) zzexit("Failed to find constant %s. Have you declared it?",
02039   //                        constName);
02040   if (constId < 0) 
02041   {
02042     const char* typeName = NULL;
02043     if (zzfunc) typeName = zzfunc->getTermTypeAsStr(zzfunc->getNumTerms());
02044     else
02045     if (zzpred) typeName = zzpred->getTermTypeAsStr(zzpred->getNumTerms());
02046 
02047       // May be continuing after a parse error
02048     if (typeName==NULL) 
02049     {
02050       zzwarn("Wrong number of terms.");
02051       typeName=PredicateTemplate::ANY_TYPE_NAME;
02052     }
02053 
02054     zzaddConstantToDomain(constName, typeName);
02055     constId = zzdomain->getConstantId(constName);
02056   }
02057 
02058     //always check zzfunc first, as a function can be found inside a predicate
02059   if (zzfunc != NULL)      
02060   {
02061     zzfuncAppendConstant(zzfunc, constId, constName);
02062     zzpredFuncListObjs.top()->append(constName);
02063   }
02064   else 
02065   if (zzpred != NULL) 
02066   {
02067     zzpredAppendConstant(zzpred, constId, constName);
02068     zzassert(zzpredFuncListObjs.size()==1, 
02069              "expect zzpredFuncListObjs.size()==1");
02070     zzpredFuncListObjs.top()->append(constName);
02071     zzformulaStr.append(constName);
02072   }
02073   else 
02074     zzexit("No function or predicate to hold constant %s", constName);
02075 }
02076 
02077 
02083 void zzputVariableInPred(const char* varName, const bool& folDbg)
02084 {
02085   if (folDbg >= 1) printf("v_%s ", varName); 
02086     
02087   ++zzfdnumVars;
02088   string newVarName = zzgetNewVarName(varName);
02089       
02090   if (zzpred != NULL) 
02091   {
02092     bool rightNumTerms = true;
02093     bool rightType = true;
02094     int exp, unexp;
02095       
02096       // check that we have not exceeded the number of terms
02097     if ((unexp=zzpred->getNumTerms()) ==
02098         (exp=zzpred->getTemplate()->getNumTerms()))
02099     {
02100       rightNumTerms = false;
02101       zzerr("Wrong number of terms for predicate %s. "
02102             "Expected %d but given %d", zzpred->getName(), exp, unexp+1);
02103     }
02104         
02105     int varId = -1;
02106     if (rightNumTerms)
02107     {
02108         // check that the variable is of the right type
02109       int typeId = zzpred->getTermTypeAsInt(zzpred->getNumTerms());
02110       rightType = zzcheckRightTypeAndGetVarId(typeId, newVarName.c_str(),
02111                                                                                   varId);
02112     }
02113       
02114     if (rightNumTerms && rightType)
02115     {
02116       zzpred->appendTerm(new Term(varId, (void*)zzpred, true));
02117       zzpredFuncListObjs.top()->append(newVarName.c_str());
02118       //zzformulaStr.append(varName);
02119     }
02120   }
02121   else 
02122     zzexit("No function or predicate to hold variable %s",varName);
02123 }
02124         
02125 
02126 void zztermIsVariable(const bool& folDbg)
02127 {
02128   const char* varName = zztokenList.removeLast();
02129   
02130   // if it is a constant (starts in uppercase or a string)
02131   //if (isupper(varName[0])) 
02132   if (zzisConstant(varName)) 
02133   {
02134     if (folDbg >= 1) printf("c2_%s ", varName); 
02135     
02136     if (zzconstantMustBeDeclared)
02137       zzerr("Constant %s must be declared before it is used", varName);
02138     zztermIsConstant(varName); 
02139     delete [] varName;
02140   }
02141   else
02142   {   //we are dealing with a variable that begins in lowercase    
02143     if (folDbg >= 1) printf("v_%s ", varName); 
02144     
02145     ++zzfdnumVars;
02146     string newVarName = zzgetNewVarName(varName);
02147     
02148       //always check zzfunc first, as a function can be found inside a predicate
02149     if (zzfunc != NULL)      
02150     {
02151       bool rightNumTerms = true;
02152       bool rightType = true;
02153       int exp, unexp;
02154       
02155         // check that we have not exceeded the number of terms
02156       if ((unexp=zzfunc->getNumTerms()) ==
02157           (exp=zzfunc->getTemplate()->getNumTerms()))
02158       {
02159         rightNumTerms = false;
02160         zzerr("Wrong number of terms for function %s. "
02161               "Expected %d but given %d", zzfunc->getName(), exp, unexp+1);
02162       }
02163       
02164       int varId = -1;      
02165       if (rightNumTerms)
02166       {
02167           // check that the variable is of the right type
02168         int typeId = zzfunc->getTermTypeAsInt(zzfunc->getNumTerms());
02169         rightType = zzcheckRightTypeAndGetVarId(typeId, newVarName.c_str(),
02170                                                 varId);
02171       }
02172 
02173       if (rightNumTerms && rightType)
02174       {
02175         zzfunc->appendTerm(new Term(varId, (void*)zzfunc, false));
02176         zzpredFuncListObjs.top()->append(newVarName.c_str());
02177         //zzformulaStr.append(varName);
02178       }
02179     }
02180     else 
02181     if (zzpred != NULL) 
02182     {
02183       bool rightNumTerms = true;
02184       bool rightType = true;
02185       int exp, unexp;
02186       
02187         // check that we have not exceeded the number of terms
02188       if ((unexp=zzpred->getNumTerms()) ==
02189           (exp=zzpred->getTemplate()->getNumTerms()))
02190       {
02191         rightNumTerms = false;
02192         zzerr("Wrong number of terms for predicate %s. "
02193               "Expected %d but given %d", zzpred->getName(), exp, unexp+1);
02194       }
02195       
02196       int varId = -1;
02197       if (rightNumTerms)
02198       {         
02199           // check that the variable is of the right type
02200         int typeId = zzpred->getTermTypeAsInt(zzpred->getNumTerms());
02201         rightType = zzcheckRightTypeAndGetVarId(typeId, newVarName.c_str(),
02202                                                 varId);
02203       }
02204       
02205       if (rightNumTerms && rightType)
02206       {
02207         zzpred->appendTerm(new Term(varId, (void*)zzpred, true));
02208         if (zzpredFuncListObjs.size() != 1) 
02209           zzerr("There may be a parse error. Have you declared all the "
02210                 "predicates and functions?");
02211         zzpredFuncListObjs.top()->append(newVarName.c_str());
02212         zzformulaStr.append(varName);
02213       }
02214     }
02215     else 
02216       zzexit("No function or predicate to hold variable %s",varName);
02217 
02218 
02219     if (zzisPlus) 
02220     {
02221       //zzisPlus = false; //commented out: set to false in not: rule
02222         // if variable is explicitly universally/existentially quantified
02223       if (!zzvarIsQuantified(varName)) // use the old var name
02224       {
02225           // we'll set it to the actual type when the entire formula is seen
02226         zzplusVarMap[newVarName] =  zzanyTypeId;
02227       }
02228       else
02229         zzerr("the '+' operator cannot be applied to variable %s that is "
02230               "explicitly universally/existentially quantified", varName);
02231     }
02232     delete [] varName;
02233   } //else we are dealing with a variable that begins in lowercase
02234 }
02235 
02236 
02237 
02238 void zzcleanUp()
02239 {
02240   zzeqPredList.clear();
02241   zzintPredList.clear();
02242   zzintFuncList.clear();
02243   while (!zzinStack.empty()) zzinStack.pop(); 
02244   zzvarNameToIdMap.clear();
02245   zzfuncToFuncVarMap.clear();
02246   zzoldNewVarList.clear();
02247   zzplusVarMap.clear();
02248   zztokenList.deleteContentsAndClear();
02249   while (!zzfuncStack.empty()) zzfuncStack.pop();
02250   while (!zzfuncConjStack.empty()) zzfuncConjStack.pop();
02251   zzuniqueVarIndexes.clear();
02252   while (!zzformulaListObjs.empty()) 
02253   {
02254     ListObj* top = zzformulaListObjs.top();
02255     zzformulaListObjs.pop();
02256     delete top;
02257   }
02258   while (!zzpredFuncListObjs.empty()) 
02259   {
02260     ListObj* top = zzpredFuncListObjs.top();
02261     zzpredFuncListObjs.pop();
02262     delete top;
02263   }
02264     //PredicateHashArray and contents deleted in zzaddGndPredsToDb()
02265   zzpredIdToGndPredMap.clear();
02266   zzformulaInfos.clear();
02267 }
02268 
02269 
02270 void zzinit()
02271 {
02272   zzafterRtParen = false;
02273   zzcount = 0;
02274   zzline = 0;
02275   zzcolumn = -1;
02276   zznumCharRead = 0;
02277   zznumErrors = 0;
02278   zzok = true;
02279   zzmln = NULL;
02280   zzdomain = NULL;
02281   zznumEofSeen = 0;
02282   zzeqTypeCounter = 0;
02283   zzintPredTypeCounter = 0;
02284   zzintFuncTypeCounter = 0;
02285   zzanyTypeId = -1;
02286   zzerrMsg[0] = '\0';
02287   zzfdfuncConstants.clear();
02288   zzusingLinkedFunctions = false;
02289   zztmpReturnNum = false;
02290   
02291   // Add internal predicates
02292   Array<const char*>* pred;
02293   pred = new Array<const char*>;
02294   pred->append("greaterThan");
02295   //pred->append("int");
02296   //pred->append("int");
02297   pred->append(PredicateTemplate::ANY_TYPE_NAME);
02298   pred->append(PredicateTemplate::ANY_TYPE_NAME);
02299   zzinternalPredicates.append(*pred);
02300   delete pred;
02301   
02302   pred = new Array<const char*>;
02303   pred->append("lessThan");
02304   //pred->append("int");
02305   //pred->append("int");
02306   pred->append(PredicateTemplate::ANY_TYPE_NAME);
02307   pred->append(PredicateTemplate::ANY_TYPE_NAME);
02308   zzinternalPredicates.append(*pred);
02309   delete pred;
02310 
02311   pred = new Array<const char*>;
02312   pred->append("greaterThanEq");
02313   //pred->append("int");
02314   //pred->append("int");
02315   pred->append(PredicateTemplate::ANY_TYPE_NAME);
02316   pred->append(PredicateTemplate::ANY_TYPE_NAME);
02317   zzinternalPredicates.append(*pred);
02318   delete pred;
02319   
02320   pred = new Array<const char*>;
02321   pred->append("lessThanEq");
02322   //pred->append("int");
02323   //pred->append("int");
02324   pred->append(PredicateTemplate::ANY_TYPE_NAME);
02325   pred->append(PredicateTemplate::ANY_TYPE_NAME);
02326   zzinternalPredicates.append(*pred);
02327   delete pred;
02328 
02329   pred = new Array<const char*>;
02330   pred->append("substr");
02331   //pred->append("string");
02332   //pred->append("string");
02333   pred->append(PredicateTemplate::ANY_TYPE_NAME);
02334   pred->append(PredicateTemplate::ANY_TYPE_NAME);
02335   zzinternalPredicates.append(*pred);
02336   delete pred;
02337 
02338   // Add internal functions
02339   Array<const char*>* func;
02340 
02341   func = new Array<const char*>;
02342   func->append("succ");
02343   //func->append("int"); //return type
02344   //func->append("int");
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("plus");
02352   //func->append("int"); //return type
02353   //func->append("int");
02354   //func->append("int");
02355   func->append(PredicateTemplate::ANY_TYPE_NAME);
02356   func->append(PredicateTemplate::ANY_TYPE_NAME);
02357   func->append(PredicateTemplate::ANY_TYPE_NAME);
02358   zzinternalFunctions.append(*func);
02359   delete func;
02360 
02361   func = new Array<const char*>;
02362   func->append("minus");
02363   //func->append("int"); //return type
02364   //func->append("int");
02365   //func->append("int");
02366   func->append(PredicateTemplate::ANY_TYPE_NAME);
02367   func->append(PredicateTemplate::ANY_TYPE_NAME);
02368   func->append(PredicateTemplate::ANY_TYPE_NAME);
02369   zzinternalFunctions.append(*func);
02370   delete func;
02371 
02372   func = new Array<const char*>;
02373   func->append("times");
02374   //func->append("int"); //return type
02375   //func->append("int");
02376   //func->append("int");
02377   func->append(PredicateTemplate::ANY_TYPE_NAME);
02378   func->append(PredicateTemplate::ANY_TYPE_NAME);
02379   func->append(PredicateTemplate::ANY_TYPE_NAME);
02380   zzinternalFunctions.append(*func);
02381   delete func;
02382 
02383   func = new Array<const char*>;
02384   func->append("dividedBy");
02385   //func->append("int"); //return type
02386   //func->append("int");
02387   //func->append("int");
02388   func->append(PredicateTemplate::ANY_TYPE_NAME);
02389   func->append(PredicateTemplate::ANY_TYPE_NAME);
02390   func->append(PredicateTemplate::ANY_TYPE_NAME);
02391   zzinternalFunctions.append(*func);
02392   delete func;
02393 
02394   func = new Array<const char*>;
02395   func->append("mod");
02396   //func->append("int"); //return type
02397   //func->append("int");
02398   //func->append("int");
02399   func->append(PredicateTemplate::ANY_TYPE_NAME);
02400   func->append(PredicateTemplate::ANY_TYPE_NAME);
02401   func->append(PredicateTemplate::ANY_TYPE_NAME);
02402   zzinternalFunctions.append(*func);
02403   delete func;
02404 
02405   func = new Array<const char*>;
02406   func->append("concat");
02407   //func->append("string"); //return type
02408   //func->append("string");
02409   //func->append("string");
02410   func->append(PredicateTemplate::ANY_TYPE_NAME);
02411   func->append(PredicateTemplate::ANY_TYPE_NAME);
02412   func->append(PredicateTemplate::ANY_TYPE_NAME);
02413   zzinternalFunctions.append(*func);
02414   delete func;
02415 }
02416 
02417 
02418 void zzreset()
02419 {
02420   zzvarCounter = 0;
02421   zzscopeCounter = 0;
02422   zzoldNewVarList.clear();
02423   zzvarNameToIdMap.clear();
02424   zzfuncToFuncVarMap.clear();
02425   zzplusVarMap.clear();
02426   zzeqPredList.clear();
02427   zzintPredList.clear();
02428   zzintFuncList.clear();
02429 
02430   zztypeName = NULL;
02431   zzpredTemplate = NULL;
02432   zzfuncTemplate = NULL;
02433   zzpred = NULL;
02434   zzfunc = NULL;
02435   while (!zzfuncStack.empty()) zzfuncStack.pop();
02436   while (!zzfuncConjStack.empty()) zzfuncConjStack.pop();
02437   if (zzwt) { delete zzwt; zzwt = NULL; }
02438   zzisNegated = false;
02439   zzisAsterisk = false;
02440   zzisPlus = false;
02441   zzhasFullStop = false;
02442   zznumAsterisk = 0;
02443   zztrueFalseUnknown = 't';
02444   zzformulaStr.clear();
02445   zzfuncConjStr.clear();
02446   zzparseGroundPred = false;
02447   zzuniqueVarIndexes.clear();
02448   while (!zzformulaListObjs.empty()) 
02449   {
02450     ListObj* top = zzformulaListObjs.top();
02451     zzformulaListObjs.pop();
02452     delete top;
02453   }
02454   while (!zzpredFuncListObjs.empty()) 
02455   {
02456     ListObj* top = zzpredFuncListObjs.top();
02457     zzpredFuncListObjs.pop();
02458     delete top;
02459   }
02460   while (!zzfuncStack.empty()) zzfuncStack.pop();
02461   while (!zzfuncConjStack.empty()) zzfuncConjStack.pop();
02462 
02463   zzfdnumPreds = 0;
02464   zzfdnumFuncs = 0;
02465   zzfdnumVars = 0;
02466 //  zzfdisEqualPred = false;
02467   zzfdfuncName.clear();
02468   zzfdfuncConstants.clear();
02469   zzfdconstName.clear();
02470   zztmpReturnNum = false;
02471   zzinfixPredName = NULL;
02472   zzinfixFuncName = NULL;
02473 }
02474 
02475 
02476 string zzappend(const char* const & s, const int& i)
02477 {
02478   char buf[16];
02479   sprintf(buf,"%d",i);
02480   string str;
02481   return str.append(s).append(buf);
02482 }
02483 
02484 string zzappendWithUnderscore(const char* const & s, const int& i)
02485 {
02486   char buf[16];
02487   sprintf(buf,"%d",i);
02488   string str;
02489   return str.append(s).append("_").append(buf);
02490 }
02491 
02492 void zzcheckAllTypesHaveConstants(const Domain* const & domain)
02493 {
02494   const Array<const char*>* types = domain->getTypeNames();
02495   for (int i = 0; i < types->size(); i++)
02496   {
02497     if (strcmp((*types)[i],PredicateTemplate::ANY_TYPE_NAME)==0) continue;
02498     if (strcmp((*types)[i],PredicateTemplate::INT_TYPE_NAME)==0) continue;
02499     if (strcmp((*types)[i],PredicateTemplate::STRING_TYPE_NAME)==0) continue;
02500     if (domain->getNumConstantsByType((*types)[i]) <= 0)
02501       zzerr("type %s has no constant. A type must have at least one constant",
02502             (*types)[i]);
02503   }
02504 }
02505 
02506 
02507 void zzfillClosedWorldArray(Array<bool>& isClosedWorldArr,
02508                             const bool& allPredsExceptQueriesAreClosedWorld,
02509                             const StringHashArray* const & openWorldPredNames,
02510                             const StringHashArray* const & queryPredNames)
02511 {
02512   if (queryPredNames)
02513   {
02514     for (int i = 0; i < queryPredNames->size(); i++) 
02515     {
02516       const char* predName = (*queryPredNames)[i].c_str();
02517       const PredicateTemplate* pt = zzdomain->getPredicateTemplate(predName);
02518       if (pt == NULL) 
02519       {
02520         zzerr("Query predicate %s is not found. Please declare it. "
02521               "Note that '!' and '?' should not be used with query predicates.",
02522               predName);
02523         continue;
02524       }
02525       if (pt->isEqualPredicateTemplate())
02526       {
02527         zzerr("'=' predicate cannot be a query predicate()");
02528         exit(-1);
02529       }
02530     }
02531   }
02532   
02533 
02534   if (allPredsExceptQueriesAreClosedWorld)
02535   {
02536     isClosedWorldArr.growToSize(zzdomain->getNumPredicates(), true);
02537     if (queryPredNames)
02538     {
02539       for (int i = 0; i < queryPredNames->size(); i++) 
02540       {
02541         const char* predName = (*queryPredNames)[i].c_str();
02542         int predId = zzdomain->getPredicateId(predName);
02543         isClosedWorldArr[predId] = false;
02544       }
02545     }
02546   }
02547   else
02548   {   // some or all predicates are open world
02549     isClosedWorldArr.growToSize(zzdomain->getNumPredicates(), true);
02550  
02551     // '=' predicates are always closed world
02552 
02553     Array<string> owPredNames;
02554       // if no open world predicates are specified then all are open world
02555     if (openWorldPredNames == NULL || openWorldPredNames->empty())
02556       zzdomain->getNonEqualPredicateNames(owPredNames);
02557     else
02558       for (int i = 0; i < openWorldPredNames->size(); i++) 
02559         owPredNames.append((*openWorldPredNames)[i]);
02560 
02561     for (int i = 0; i < owPredNames.size(); i++) 
02562     {
02563       const char* predName = owPredNames[i].c_str();
02564       int predId = zzdomain->getPredicateId(predName);
02565       if (predId < 0)
02566       {
02567         zzerr("predicate %s is not declared. Please declare it.", predName);
02568         continue;
02569       }
02570       
02571       isClosedWorldArr[predId] = false;
02572     }
02573 
02574     for (int i = 0; i < queryPredNames->size(); i++) 
02575     {
02576       const char* predName = (*queryPredNames)[i].c_str();
02577       int predId = zzdomain->getPredicateId(predName);
02578       isClosedWorldArr[predId] = false;
02579     }
02580   }
02581 }
02582 
02583 
02584 void zzappendUnitClausesToMLN(const Domain* const & domain, MLN* const & mln,
02585                               const double& defaultWt )
02586 {
02587   for (int i = 0; i < domain->getNumPredicates(); i++)
02588   {
02589     Predicate* pred = domain->createPredicate(i, false);
02590     if (pred == NULL) continue;
02591     Clause* clause = ClauseFactory::createUnitClause(pred, false);
02592     delete pred;
02593 
02594     if (clause == NULL) continue;
02595     if (mln->containsClause(clause)) { delete clause; continue; }
02596 
02597     int idx;
02598     ostringstream oss;
02599     clause->getPredicate(0)->getTemplate()->printWithStrVar(oss);
02600     bool app = mln->appendClause(oss.str(), false, clause, defaultWt,false,idx);
02601     if (app)
02602     {
02603       mln->setFormulaNumPreds(oss.str(), 1);
02604       mln->setFormulaIsHard(oss.str(), false);
02605       mln->setFormulaPriorMean(oss.str(), defaultWt);
02606     }
02607   }
02608 }
02609 
02610 
02611 void zzappendFormulaClausesToMLN(const ListObj* const & formula,
02612                                  const string& formulaStr, 
02613                                  const int& numPreds,
02614                                  const double* const & wt,
02615                                  const double& defaultWt,
02616                                  const Domain* const & domain,
02617                                  MLN* const & mln,
02618                                  const ZZVarNameToIdMap& varNameToIdMap,
02619                                  const StringToIntMap& plusVarMap,
02620                                  const int& numAsterisk,
02621                                  const Array<int>& uniqueVarIndexes,
02622                                  const bool& hasFullStop,
02623                                  const bool& readHardClauseWts,
02624                                  const bool& mustHaveWtOrFullStop,
02625                                  Array<int>& hardClauseIdxs,
02626                                  Array<string>& hardFormulas,
02627                                  Array<int>& existUniqueClauseIdxs,
02628                                  Array<string>& existUniqueFormulas,
02629                                  Clause*& flippedClause,
02630                                  const Domain* const & domain0)
02631 {
02632   //cout << "orig formula = " << endl << "\t: " << formulaStr << endl;    
02633   //cout << "formula      = " << endl << "\t: " << *formula << endl;
02634 
02635   bool isExistUnique = (uniqueVarIndexes.size() > 0);
02636 
02637   VarTypeMap* vtMap = zzcreateVarTypeMap(varNameToIdMap);
02638   Array<ListObj*> formulas;
02639   Array<string> formulaStrs;
02640   zzgroundPlusVar(formula, formulaStr, plusVarMap, formulas, formulaStrs, 
02641                   domain, domain0);
02642   delete formula;
02643 
02644   for (int f = 0; f < formulas.size(); f++)
02645   {
02646     //cout<<"formula (after gnding '+')= "<<endl<<"\t: "<< *(formulas[f])<<endl;
02647 
02648     Array<ListObj*> formulas2;
02649     Array<string> formulaStrs2;
02650     zzpermuteAsteriskedPreds(numAsterisk, formulas[f], formulaStrs[f], 
02651                              formulas2, formulaStrs2);
02652     delete formulas[f];    
02653 
02654     for (int g = 0; g < formulas2.size(); g++)
02655     {
02656       string formStr = formulaStrs2[g];
02657 
02658       //cout << "formula (after *) " << endl << "\t: " << *(formulas2[g])<<endl;
02659       ListObj* vars = new ListObj;
02660       bool hasExist = false;
02661       ListObj* cnf = ListObj::toCNF(formulas2[g], vars, domain, vtMap,hasExist);
02662       delete formulas2[g];
02663       //cout << "cnf = " << endl << "\t: " << *cnf << endl;
02664           
02665       cnf->cleanUpVars();
02666       //cout << "cnf (after cleanUp) = " << endl << "\t: " << *cnf << endl;
02667       
02668       //commented out: not likely for there to be redundant clauses and is slow
02669       //replaced with removeRedundantPredicates()
02670       //cnf->removeRedundantClauses();
02671 
02672       cnf->removeRedundantPredicates();
02673       //cout << "cnf (removed redundant preds) = " <<endl<<"\t: "<<*cnf<<endl;
02674 
02675         //if the '!' operator is used
02676       if (isExistUnique)
02677       {
02678         assert(formulas.size() == 1); // no '+' is used
02679         assert(formulas2.size() == 1); //no '*' is used
02680       }
02681       Array<Clause*> clauses;
02682       zzcreateClauses(cnf, clauses, flippedClause);
02683       int numEPreds = 0;
02684       if (isExistUnique) 
02685         numEPreds=zzcreateExistUniqueClauses(clauses,uniqueVarIndexes,zzdomain);
02686 
02687       cout << "\tCNF has  " << clauses.size() << " clause"
02688            << ((clauses.size()>1)?"s":"") << endl;
02689       delete cnf; delete vars;
02690 
02691       double perClauseWt = 0;
02692       double formulaWt = 0;
02693       bool setHardWtLater = false;
02694       bool setExistUniqueWtLater = false;
02695 
02696       if (hasFullStop) // if this is a hard clause/formula
02697       {
02698         assert(wt == NULL);
02699         if (readHardClauseWts)
02700         {
02701           if (wt) 
02702           { perClauseWt = (*wt)/clauses.size(); formulaWt = (*wt); }
02703           else    
02704           {   //set weight later to twice of max soft clause wt
02705             perClauseWt = 1; formulaWt = 1; 
02706             hardFormulas.append(formStr);
02707             setHardWtLater = true;
02708           }                   
02709         }
02710         else
02711         {   //set later to twice of max soft clause wt         
02712           perClauseWt = 1; formulaWt = 1;
02713           hardFormulas.append(formStr);
02714           setHardWtLater = true;
02715         }
02716         if (isExistUnique) numEPreds = 0;
02717       }
02718       else
02719       if (wt)
02720       { perClauseWt = (*wt)/clauses.size(); formulaWt = *wt; }
02721       else
02722       {
02723         if (mustHaveWtOrFullStop && !isExistUnique)
02724           zzerr("a weight or full stop must be specified for:\n%s",
02725                 formStr.c_str());
02726         perClauseWt = defaultWt/clauses.size();
02727         formulaWt = defaultWt;
02728 
02729         if (isExistUnique) 
02730         { 
02731           perClauseWt = 0; formulaWt = 0; 
02732           existUniqueFormulas.append(formStr);
02733           setExistUniqueWtLater = true;
02734           numEPreds = 0;
02735         }
02736       }
02737 
02738       
02739       for (int i = 0; i < clauses.size(); i++)
02740       {
02741           //if this clause belongs to the CNF of  an exist. & unique. quant. 
02742           //formula and a prior mean was explicitly specified
02743         if (isExistUnique && numEPreds > 0) 
02744         { 
02745           double n = numEPreds;
02746           if (i == 0) perClauseWt = (n > 1) ? formulaWt/(n+1) : formulaWt;
02747           else        perClauseWt = 2*formulaWt/(n*n-1);
02748         }
02749 
02756         double clauseWt = perClauseWt;
02757         if (flippedClause && flippedClause == clauses[i] 
02758             && zzflipWtsOfFlippedClause)
02759           clauseWt = -clauseWt;
02760 
02761         int prevIdx;
02762         bool ok = mln->appendClause(formStr, hasExist, clauses[i], 
02763                                     clauseWt, hasFullStop, prevIdx);
02764 
02765         if (!ok)
02766         {
02767           cout << "\tsame clause (derived from another formula) has been added "
02768                << "to MLN:\n\t"; 
02769           const Clause* cl = mln->getClause(prevIdx);          
02770           cl->printWithoutWt(cout,domain); cout << endl;
02771           //cout << " derived from current formula:\n\t" << formStr << endl;
02772         }
02773 
02774         if (setHardWtLater) hardClauseIdxs.append(prevIdx);
02775         else if (setExistUniqueWtLater) existUniqueClauseIdxs.append(prevIdx);
02776       }
02777 
02778       mln->setFormulaNumPreds(formStr, numPreds);
02779       mln->setFormulaPriorMean(formStr, formulaWt);
02780       mln->setFormulaWt(formStr, formulaWt);
02781       mln->setFormulaIsExistUnique(formStr, isExistUnique);
02782       mln->setFormulaIsHard(formStr, hasFullStop);      
02783 
02784     } //for (int g = 0; g < formulas2.size(); g++)
02785   }//for (int f = 0; f < formulas.size(); f++)
02786   delete vtMap;
02787 }
02788 
02789 
02790 void zzappendFormulasToMLN(Array<ZZFormulaInfo*>& formulaInfos, 
02791                            MLN* const & mln, const Domain* const & domain0)
02792 {
02793   cout << "converting to CNF:" << endl;
02794 
02795   Array<int> hardClauseIdxs, existUniqueClauseIdxs;
02796   Array<string> hardFormulas, existUniqueFormulas;
02797   Clause* flippedClause = NULL;
02798 
02799   for (int i = 0; i < formulaInfos.size(); i++)
02800   {
02801     double startSec = zztimer.time();
02802     ZZFormulaInfo* epfi = formulaInfos[i];
02803     cout << "formula " << i << ": " << epfi->formulaStr << endl;
02804     assert(mln == epfi->mln);
02805     zzappendFormulaClausesToMLN(epfi->formula, epfi->formulaStr, epfi->numPreds,
02806                                 epfi->wt, epfi->defaultWt, epfi->domain, epfi->mln,
02807                                 epfi->varNameToIdMap, epfi->plusVarMap,
02808                                 epfi->numAsterisk, epfi->uniqueVarIndexes,
02809                                 epfi->hasFullStop, epfi->readHardClauseWts,
02810                                 epfi->mustHaveWtOrFullStop, 
02811                                 hardClauseIdxs, hardFormulas, 
02812                                 existUniqueClauseIdxs, existUniqueFormulas,
02813                                 flippedClause, domain0);
02814     delete epfi;
02815     cout<<"CNF conversion took ";Timer::printTime(cout,zztimer.time()-startSec);
02816     cout<<endl;
02817   }
02818   formulaInfos.clear();
02819 
02820   //set the weights of hard clauses and those derived from 
02821   //existentially & uniquely quant formulas
02822 
02823   double maxSoftWt = mln->getMaxAbsSoftWt();
02824   if (maxSoftWt == 0) maxSoftWt = 1;
02825 
02826   double hardWt = (HARD_WEIGHT==DBL_MIN) ?  HARD_WEIGHT_MULTIPLIER * maxSoftWt 
02827                                           : HARD_WEIGHT;
02828   double existUniqueWt = (EXIST_UNIQUE_WEIGHT==DBL_MIN) ? 
02829                          EXIST_UNIQUE_WEIGHT_MULTIPLIER *maxSoftWt 
02830                        : EXIST_UNIQUE_WEIGHT; 
02831 
02832   for (int i = 0; i < existUniqueClauseIdxs.size(); i++)
02833     ((Clause*)mln->getClause(existUniqueClauseIdxs[i]))->setWt(existUniqueWt);
02834 
02835   for (int i = 0; i < existUniqueFormulas.size(); i++)
02836   {
02837     mln->setFormulaWt(existUniqueFormulas[i], existUniqueWt);
02838     mln->setFormulaPriorMean(existUniqueFormulas[i], existUniqueWt);
02839   }
02840 
02841   for (int i = 0; i < hardClauseIdxs.size(); i++)
02842   {
02849     double hhardWt = hardWt;
02850     /*
02851     if (flippedClause && 
02852         //flippedClause->same( (Clause*)mln->getClause(hardClauseIdxs[i]) )
02853         flippedClause == (Clause*)mln->getClause(hardClauseIdxs[i])
02854         && zzflipWtsOfFlippedClause)
02855       hhardWt = -hhardWt;
02856     */
02857     
02858       // Weight has been flipped when added to mln. So, if weight
02859       // is neg. and marked as hard, then need to flip hard weight
02860     if (zzflipWtsOfFlippedClause &&
02861         ((Clause*)mln->getClause(hardClauseIdxs[i]))->getWt() < 0)
02862       hhardWt = -hhardWt;
02863           
02864     ((Clause*)mln->getClause(hardClauseIdxs[i]))->setWt(hhardWt);
02865   }
02866 
02867   for (int i = 0; i < hardFormulas.size(); i++)
02868   {
02869     mln->setFormulaWt(hardFormulas[i], hardWt);
02870     mln->setFormulaPriorMean(hardFormulas[i], hardWt);
02871   }
02872 }
02873 
02874 
02875 void zzsigHandler(int signo)
02876 {
02877   if (zznumErrors > 0) printf("Num of errors detected = %d\n", zznumErrors);
02878   if (zzisParsing)
02879     printf("UNRECOVERABLE ERROR in %s: line %d, col %d\n", 
02880            rmTmpPostfix(zzinFileName).c_str(), zzline, zzcolumn);
02881   else
02882     printf("UNRECOVERABLE ERROR after parsing %s\n", 
02883            rmTmpPostfix(zzinFileName).c_str());
02884 
02885   zzok = false;
02886   signal(signo,SIG_DFL);
02887 }
02888 
02897 void zzcompileFunctions(const char* fileName)
02898 {
02899   ifstream infs;
02900   ofstream outfs;
02901 
02902   // First remove any old .so file
02903   char* removeso;
02904   removeso = (char *)malloc((strlen("rm -f ") +
02905                                                         strlen(ZZ_FUNCTION_SO_FILE) + 1)*sizeof(char));
02906   strcpy(removeso, "rm -f ");
02907   strcat(removeso, ZZ_FUNCTION_SO_FILE);
02908   system(removeso);
02909 
02910   // If .so file is still there, then exit  
02911   infs.open(ZZ_FUNCTION_SO_FILE, ifstream::in);
02912   infs.close();
02913   if(!infs.fail())
02914   {
02915         infs.clear(ios::failbit);
02916         cout << "Unable to remove " << ZZ_FUNCTION_SO_FILE << endl;
02917         exit(-1);
02918   }
02919   
02920   // Compile the file
02921   char* systemcall;
02922   systemcall = (char *)malloc((strlen("g++ -fPIC -shared -o ") +
02923                                                                 strlen(ZZ_FUNCTION_SO_FILE) +
02924                                                                 strlen(" ") +
02925                                                                 strlen(fileName) + 1)*sizeof(char));
02926   strcpy(systemcall, "g++ -fPIC -shared -o ");
02927   strcat(systemcall, ZZ_FUNCTION_SO_FILE);
02928   strcat(systemcall, " ");
02929   strcat(systemcall, fileName);
02930   system(systemcall);
02931   
02932   // If .so file is not there, then exit  
02933   infs.open(ZZ_FUNCTION_SO_FILE, ifstream::in);
02934   infs.close();
02935   if(infs.fail())
02936   {
02937         infs.clear(ios::failbit);
02938         cout << "Could not compile function file " << fileName << endl;
02939         exit(-1);
02940   }
02941   return;
02942 }
02943 
02944 
02962 void zzinsertPermutationOfLinkedFunction(const Domain* const & domain, void* funccall,
02963                                                                                  const FunctionTemplate* ftemplate, int numTerms,
02964                                                                                  Array<int>* currentConstants)
02965 {
02966   string retString;
02967   string arguments[numTerms];
02968   string argumentsAsNum[numTerms];
02969   
02970   // Find the arguments for the function according to currentConstants
02971   for (int i = 0; i < numTerms; i++)
02972   {
02973         const Array<int>* constantsByType =
02974                 domain->getConstantsByType(ftemplate->getTermTypeAsInt(i));
02975 
02976         arguments[i] = domain->getConstantName((*constantsByType)[((*currentConstants)[i])]);
02977         // If constant is a number, then we have to cut it out of the string C@Type@Number
02978         unsigned int at = arguments[i].rfind("@");
02979         if (at != string::npos)
02980           argumentsAsNum[i] = arguments[i].substr(at+1, arguments[i].length()-at-1);
02981         else argumentsAsNum[i] = arguments[i];
02982   }
02983   
02984   // Make the function call (max. 5 arguments)
02985   switch (numTerms)
02986   {
02987     case 0:
02988       retString = (*(string (*)())(funccall))();
02989       break;
02990     case 1:
02991       retString = (*(string (*)(string))(funccall))(argumentsAsNum[0]);
02992       break;
02993     case 2:
02994       retString = (*(string (*)(string, string))(funccall))
02995                                 (argumentsAsNum[0], argumentsAsNum[1]);
02996       break;
02997     case 3:
02998       retString = (*(string (*)(string, string, string))(funccall))
02999                                 (argumentsAsNum[0], argumentsAsNum[1], argumentsAsNum[2]);
03000       break;
03001     case 4:
03002       retString = (*(string (*)(string, string, string, string))(funccall))
03003                                 (argumentsAsNum[0], argumentsAsNum[1], argumentsAsNum[2],
03004                                  argumentsAsNum[3]);
03005       break;
03006     case 5:
03007       retString = (*(string (*)(string, string, string, string, string))(funccall))
03008                                 (argumentsAsNum[0], argumentsAsNum[1], argumentsAsNum[2],
03009                                  argumentsAsNum[3], argumentsAsNum[4]);
03010       break;
03011     default:
03012       cout << "Linked-in functions can take max. 5 arguments\n" << endl;
03013       return;    
03014   }
03015 
03016 
03017   // If a number is returned, then we have to make a constant out of it
03018   int i;
03019   istringstream iss(retString);
03020   char constName[1000];
03021   if (iss>>i) // We are dealing with an integer
03022     zzcreateIntConstant(constName, ftemplate->getRetTypeName(), i);
03023   else
03024         strcpy(constName, retString.c_str());
03025 
03026   // The return value has to be an existing constant of the return type
03027   int constantId = domain->getConstantId(constName);
03028   const Array<int>* returnConstants =
03029                 domain->getConstantsByType(ftemplate->getRetTypeId());
03030   
03031   if (returnConstants->contains(constantId)) {
03032         // Insert the function definition just created  
03033         // Predicate name is PredicateTemplate::ZZ_RETURN_PREFIX + function name
03034         char* predName;
03035         predName = (char *)malloc((strlen(PredicateTemplate::ZZ_RETURN_PREFIX) +
03036                                                            strlen(ftemplate->getName()) + 1)*sizeof(char));
03037         strcpy(predName, PredicateTemplate::ZZ_RETURN_PREFIX);
03038         strcat(predName, ftemplate->getName());
03039         zzcreatePred(zzpred, predName);
03040         zzpred->setTruthValue(TRUE);
03041 
03042         //Add return constant to predicate
03043         zzpredAppendConstant(zzpred, constantId, constName);
03044         //Add constant terms to predicate
03045         for (int i = 0; i < numTerms; i++)
03046         {
03047           const char* term = arguments[i].c_str();
03048           int constId = domain->getConstantId(term);
03049           zzpredAppendConstant(zzpred, constId, term);
03050         }
03051         
03052         zzcheckPredNumTerm(zzpred);
03053         int predId = zzpred->getId();
03054 
03055         // Insert mapping of grounding
03056         hash_map<int,PredicateHashArray*>::iterator it;
03057         if ((it=zzpredIdToGndPredMap.find(predId)) == zzpredIdToGndPredMap.end())
03058         zzpredIdToGndPredMap[predId] = new PredicateHashArray;
03059 
03060 //cout << "Mapping " << endl;
03061 //zzpred->printWithStrVar(cout, zzdomain);
03062 //cout << " " << zzpred->getTruthValue() << endl;
03063   
03064         PredicateHashArray* pha = zzpredIdToGndPredMap[predId];
03065         if (pha->append(zzpred) < 0)
03066         {
03067       int a = pha->find(zzpred);
03068       zzassert(a >= 0, "expecting ground predicate to be found");
03069       string origTvStr = (*pha)[a]->getTruthValueAsStr();
03070       (*pha)[a]->setTruthValue(zzpred->getTruthValue());
03071       string newTvStr = (*pha)[a]->getTruthValueAsStr();
03072 
03073       if (zzwarnDuplicates)
03074       {
03075         ostringstream oss;
03076         oss << "Duplicate ground predicate "; zzpred->print(oss, zzdomain); 
03077         oss << " found. ";
03078         if (origTvStr.compare(newTvStr) != 0)
03079           oss << "Changed its truthValue from " << origTvStr << " to " <<newTvStr 
03080               << endl;
03081         zzwarn(oss.str().c_str());
03082       }
03083           delete zzpred;
03084     }
03085 
03086     delete [] predName;
03087         zzpred = NULL;
03088   }
03089 }
03090 
03110 void zzinsertPermutationsOfLinkedFunction(const Domain* const & domain, void* funccall,
03111                                                                           const FunctionTemplate* ftemplate, int numTerms,
03112                                                                                   int currentTerm, Array<int>* currentConstants)
03113 {
03114   const Array<int>* constants =
03115         domain->getConstantsByType(ftemplate->getTermTypeAsInt(currentTerm));
03116 
03117   // Base case: at the last term
03118   if (currentTerm == numTerms - 1)
03119   {
03120         for (int i = 0; i < constants->size(); i++)
03121         {
03122           (*currentConstants)[currentTerm] = i;
03123           zzinsertPermutationOfLinkedFunction(domain, funccall, ftemplate,
03124                                                                           numTerms, currentConstants);
03125         }
03126         return;
03127   }
03128   
03129   // Not yet at last term
03130   zzinsertPermutationsOfLinkedFunction(domain, funccall, ftemplate,
03131                                                                            numTerms, currentTerm + 1, currentConstants);
03132   
03133   if (++(*currentConstants)[currentTerm] < constants->size())
03134         zzinsertPermutationsOfLinkedFunction(domain, funccall, ftemplate,
03135                                                                              numTerms, currentTerm, currentConstants);
03136 
03137   (*currentConstants)[currentTerm] = 0;
03138   return;
03139 }
03140 
03153 void zzgenerateGroundingsFromLinkedFunction(const Domain* const & domain,
03154                                                                                     const char* funcname,
03155                                                                                     void* handle)
03156 {
03157   char* error;
03158   void* funccall;
03159   
03160   // Obtain functioncall from dynamic library
03161   dlerror();    // Clear any existing error
03162   funccall = dlsym(handle, funcname);
03163   if ((error = dlerror()) != NULL)
03164   {
03165         printf("Error while evaluating function %s\n", funcname);
03166     fprintf (stderr, "dlerror: %s\n", error);
03167         return;
03168   }
03169 
03170   // Find number of terms for function
03171   const FunctionTemplate* ftemplate = domain->getFunctionTemplate(funcname);
03172   int numTerms = ftemplate->getNumTerms();
03173 
03174   // Insert all possible permutations of constants
03175   const Array<int>* termTypes = ftemplate->getTermTypesAsInt();
03176   zzassert(numTerms == termTypes->size(),
03177                    "Number of terms and term types in function don't match");
03178   Array<int>* currentConstants = new Array<int>;
03179   for (int i = 0; i < numTerms; i++) currentConstants->append(0);
03180   zzinsertPermutationsOfLinkedFunction(domain, funccall, ftemplate, numTerms, 0, currentConstants);
03181 
03182   return;
03183 }
03184 
03195 void zzgenerateGroundingsFromLinkedFunctions(const Domain* const & domain)
03196 {
03197   // First check if a file with functions exists
03198   void *handle;
03199   char* openFileName;
03200   openFileName = (char *)malloc((strlen("./") +
03201                                                                 strlen(ZZ_FUNCTION_SO_FILE) + 1)*sizeof(char));
03202   strcpy(openFileName, "./");
03203   strcat(openFileName, ZZ_FUNCTION_SO_FILE);
03204   handle = dlopen(openFileName, RTLD_LAZY);
03205   if (!handle)
03206   {
03207         // Can not open file, so no linked-in functions
03208     printf("No file for linked-in functions found.\n");
03209     fprintf (stderr, "%s\n", dlerror());
03210     dlclose(handle);
03211     return;
03212   }
03213 
03214   // Look at each function
03215   const Array<const char*>* fnames = domain->getFunctionNames();
03216   for (int i = 0; i < fnames->size(); i++)
03217   {
03218         // If it is a linked-in function,
03219         // then generate groundings for each permutation of the given types
03220         if (!zzisInternalFunction((*fnames)[i]) &&
03221                 zzisLinkedFunction((*fnames)[i], handle))
03222         {
03223           cout << "Found linked-in function: " << (*fnames)[i] << endl;
03224           zzgenerateGroundingsFromLinkedFunction(domain, (*fnames)[i], handle);
03225         }
03226   }
03227   dlclose(handle);
03228   return;
03229 }
03230 
03231 
03249 void zzinsertPermutationOfLinkedPredicate(const Domain* const & domain, void* funccall,
03250                                                                                   const PredicateTemplate* ptemplate, int numTerms,
03251                                                                                   Array<int>* currentConstants)
03252 {
03253   bool retBool = false;
03254   string arguments[numTerms];
03255   string argumentsAsNum[numTerms];
03256   
03257   // Find the arguments for the predicate according to currentConstants
03258   for (int i = 0; i < numTerms; i++)
03259   {
03260         const Array<int>* constantsByType =
03261                 domain->getConstantsByType(ptemplate->getTermTypeAsInt(i));
03262 
03263         arguments[i] = domain->getConstantName((*constantsByType)[((*currentConstants)[i])]);
03264         // If constant is a number, then we have to cut it out of the string C@Type@Number
03265         unsigned int at = arguments[i].rfind("@");
03266         if (at != string::npos)
03267           argumentsAsNum[i] = arguments[i].substr(at+1, arguments[i].length()-at-1);
03268         else argumentsAsNum[i] = arguments[i];
03269   }
03270   
03271   // Make the function call (max. 5 arguments)
03272   switch (numTerms)
03273   {
03274     case 0:
03275       retBool = (*(bool (*)())(funccall))();
03276       break;
03277     case 1:
03278       retBool = (*(bool (*)(string))(funccall))(argumentsAsNum[0]);
03279       break;
03280     case 2:
03281       retBool = (*(bool (*)(string, string))(funccall))
03282                                 (argumentsAsNum[0], argumentsAsNum[1]);
03283       break;
03284     case 3:
03285       retBool = (*(bool (*)(string, string, string))(funccall))
03286                                 (argumentsAsNum[0], argumentsAsNum[1], argumentsAsNum[2]);
03287       break;
03288     case 4:
03289       retBool = (*(bool (*)(string, string, string, string))(funccall))
03290                                 (argumentsAsNum[0], argumentsAsNum[1], argumentsAsNum[2],
03291                                  argumentsAsNum[3]);
03292       break;
03293     case 5:
03294       retBool = (*(bool (*)(string, string, string, string, string))(funccall))
03295                                 (argumentsAsNum[0], argumentsAsNum[1], argumentsAsNum[2],
03296                                  argumentsAsNum[3], argumentsAsNum[4]);
03297       break;
03298     default:
03299       cout << "Linked-in predicates can take max. 5 arguments\n" << endl;
03300       return;    
03301   }
03302   
03303   // Insert the predicate definition just created  
03304   const char* predName;
03305         predName = ptemplate->getName();
03306   //for (int i = 0; i < currentConstants->size(); i++)
03307     //printf("%d ", (*currentConstants)[i]);
03308   zzcreatePred(zzpred, predName);
03309   if (retBool) zzpred->setTruthValue(TRUE);
03310   else zzpred->setTruthValue(FALSE);
03311   
03312   //Add constant terms to predicate
03313   for (int i = 0; i < numTerms; i++)
03314   {
03315         const char* term = arguments[i].c_str();
03316         int constId = domain->getConstantId(term);
03317         zzpredAppendConstant(zzpred, constId, term);
03318   }
03319         
03320   zzcheckPredNumTerm(zzpred);
03321   int predId = zzpred->getId();
03322 
03323   // Insert mapping of grounding
03324   hash_map<int,PredicateHashArray*>::iterator it;
03325   if ((it=zzpredIdToGndPredMap.find(predId)) == zzpredIdToGndPredMap.end())
03326         zzpredIdToGndPredMap[predId] = new PredicateHashArray;
03327   
03328 //cout << "Mapping " << endl;
03329 //zzpred->printWithStrVar(cout, zzdomain);
03330 //cout << " " << zzpred->getTruthValue() << endl;
03331 
03332   PredicateHashArray* pha = zzpredIdToGndPredMap[predId];
03333   if (pha->append(zzpred) < 0)
03334   {
03335     int a = pha->find(zzpred);
03336     zzassert(a >= 0, "expecting ground predicate to be found");
03337     string origTvStr = (*pha)[a]->getTruthValueAsStr();
03338     (*pha)[a]->setTruthValue(zzpred->getTruthValue());
03339     string newTvStr = (*pha)[a]->getTruthValueAsStr();
03340 
03341     if (zzwarnDuplicates)
03342     {
03343       ostringstream oss;
03344       oss << "Duplicate ground predicate "; zzpred->print(oss, zzdomain); 
03345       oss << " found. ";
03346       if (origTvStr.compare(newTvStr) != 0)
03347         oss << "Changed its truthValue from " << origTvStr << " to " <<newTvStr 
03348             << endl;
03349       zzwarn(oss.str().c_str());
03350     }
03351     delete zzpred;
03352   }
03353 
03354   zzpred = NULL;
03355 }
03356 
03376 void zzinsertPermutationsOfLinkedPredicate(const Domain* const & domain, void* funccall,
03377                                                                                    const PredicateTemplate* ptemplate, int numTerms,
03378                                                                                    int currentTerm, Array<int>* currentConstants)
03379 {
03380   const Array<int>* constants =
03381         domain->getConstantsByType(ptemplate->getTermTypeAsInt(currentTerm));
03382 
03383   // Base case: at the last term
03384   if (currentTerm == numTerms - 1)
03385   {
03386         for (int i = 0; i < constants->size(); i++)
03387         {
03388           (*currentConstants)[currentTerm] = i;
03389           zzinsertPermutationOfLinkedPredicate(domain, funccall, ptemplate,
03390                                                                                    numTerms, currentConstants);
03391         }
03392         return;
03393   }
03394   
03395   // Not yet at last term
03396   zzinsertPermutationsOfLinkedPredicate(domain, funccall, ptemplate,
03397                                                                             numTerms, currentTerm + 1, currentConstants);
03398   
03399   if (++(*currentConstants)[currentTerm] < constants->size())
03400         zzinsertPermutationsOfLinkedPredicate(domain, funccall, ptemplate,
03401                                                                               numTerms, currentTerm, currentConstants);
03402 
03403   (*currentConstants)[currentTerm] = 0;
03404   return;
03405 }
03406 
03419 void zzgenerateGroundingsFromLinkedPredicate(const Domain* const & domain,
03420                                                                                      const char* predname,
03421                                                                                      void* handle)
03422 {
03423   char* error;
03424   void* funccall;
03425   
03426   // Obtain functioncall from dynamic library
03427   dlerror();    // Clear any existing error
03428   funccall = dlsym(handle, predname);
03429   if ((error = dlerror()) != NULL)
03430   {
03431         printf("Error while evaluating predicate %s\n", predname);
03432     fprintf (stderr, "dlerror: %s\n", error);
03433         return;
03434   }
03435 
03436   // Find number of terms for predicate
03437   const PredicateTemplate* ptemplate = domain->getPredicateTemplate(predname);
03438   int numTerms = ptemplate->getNumTerms();
03439 
03440   // Insert all possible permutations of constants
03441   const Array<int>* termTypes = ptemplate->getTermTypesAsInt();
03442   zzassert(numTerms == termTypes->size(),
03443                    "Number of terms and term types in function don't match");
03444   Array<int>* currentConstants = new Array<int>;
03445   for (int i = 0; i < numTerms; i++) currentConstants->append(0);
03446   zzinsertPermutationsOfLinkedPredicate(domain, funccall, ptemplate, numTerms, 0, currentConstants);
03447 
03448   return;
03449 }
03450 
03461 void zzgenerateGroundingsFromLinkedPredicates(const Domain* const & domain)
03462 {
03463   // First check if a file with predicates exists
03464   void *handle;
03465   char* openFileName;
03466   openFileName = (char *)malloc((strlen("./") +
03467                                                                 strlen(ZZ_FUNCTION_SO_FILE) + 1)*sizeof(char));
03468   strcpy(openFileName, "./");
03469   strcat(openFileName, ZZ_FUNCTION_SO_FILE);
03470   handle = dlopen(openFileName, RTLD_LAZY);
03471   if (!handle)
03472   {
03473         // Can not open file, so no linked-in predicates
03474     printf("No file for linked-in predicates found.\n");
03475     fprintf (stderr, "%s\n", dlerror());
03476     dlclose(handle);
03477     return;
03478   }
03479 
03480   // Look at each predicate
03481   const Array<const char*>* pnames = domain->getPredicateNames();
03482   for (int i = 0; i < pnames->size(); i++)
03483   {
03484         // If it is a linked-in predicate,
03485         // then generate groundings for each permutation of the given types
03486         if (!zzisInternalPredicate((*pnames)[i]) &&
03487                 zzisLinkedPredicate((*pnames)[i], handle))
03488         {
03489           cout << "Found linked-in predicate: " << (*pnames)[i] << endl;
03490           zzgenerateGroundingsFromLinkedPredicate(domain, (*pnames)[i], handle);
03491         }
03492   }
03493   dlclose(handle);
03494   return;
03495 }
03496 
03502 /*
03503 void zzdeclareInternalPredicatesAndFunctions()
03504 {
03505   // Predicates
03506   for (int i = 0; i < zzinternalPredicates.size(); i++)
03507   {
03508         const char* predName = zzinternalPredicates[i][0];
03509           //predicate has not been declared a function
03510         zzassert(zzdomain->getFunctionId(predName) < 0, 
03511                "not expecting pred name to be declared as a function name");
03512         zzassert(zzpredTemplate==NULL,"expecting zzpredTemplate==NULL");
03513         zzpredTemplate = new PredicateTemplate();
03514         zzpredTemplate->setName(predName);
03515         
03516         // Add types
03517         for (int j = 1; j < zzinternalPredicates[i].size(); j++)
03518         {
03519           int id;
03520           const char* ttype = zzinternalPredicates[i][j];
03521           if (!zzdomain->isType(ttype))
03522           {
03523                 id = zzaddTypeToDomain(zzdomain, ttype);
03524                 zzassert(id >= 0, "expecting var id >= 0");
03525           }
03526           zzaddType(ttype, zzpredTemplate, NULL, false, zzdomain);
03527           //delete [] ttype;
03528         }
03529         
03530         // Add template to domain
03531         zzassert(zzpredTemplate, "not expecting zzpredTemplate==NULL");
03532         int id = zzdomain->addPredicateTemplate(zzpredTemplate);
03533         zzassert(id >= 0, "expecting pred template id >= 0");
03534         zzpredTemplate->setId(id);
03535         zzpredTemplate = NULL;
03536   }
03537   
03538   
03539   // Functions
03540   for (int i = 0; i < zzinternalFunctions.size(); i++)
03541   {
03542         zzassert(zzfuncTemplate==NULL, "expecting zzfuncTemplate==NULL");
03543         zzfuncTemplate = new FunctionTemplate();
03544 
03545         // We are creating a new predicate as well
03546         zzassert(zzpredTemplate==NULL,"expecting zzpredTemplate==NULL");
03547         zzpredTemplate = new PredicateTemplate();
03548 
03549         const char* funcName = zzinternalFunctions[i][0];
03550 
03551         zzassert(zzdomain->getPredicateId(funcName) < 0, 
03552              "not expecting func name to be declared as pred name");
03553         zzassert(zzfuncTemplate,"expecting zzfuncTemplate!=NULL");
03554         zzfuncTemplate->setName(funcName);
03555 
03556         // Predicate name is PredicateTemplate::ZZ_RETURN_PREFIX + function name
03557         char* predName;
03558         predName = (char *)malloc((strlen(PredicateTemplate::ZZ_RETURN_PREFIX) +
03559                                                         strlen(funcName) + 1)*sizeof(char));
03560         strcpy(predName, PredicateTemplate::ZZ_RETURN_PREFIX);
03561         strcat(predName, funcName);
03562         
03563         // Check that predicate has not been declared a function
03564         zzassert(zzdomain->getFunctionId(predName) < 0, 
03565                      "not expecting pred name to be declared as a function name");
03566         zzassert(zzpredTemplate,"expecting zzpredTemplate!=NULL");
03567         zzpredTemplate->setName(predName);
03568         delete [] predName;  
03569         
03570         // Add return type
03571         const char* retTypeName = zzinternalFunctions[i][1];
03572 
03573         if (!zzdomain->isType(retTypeName))
03574         {
03575           int id = zzaddTypeToDomain(zzdomain, retTypeName);
03576       zzassert(id >= 0, "expecting retTypeName's id >= 0");
03577         }
03578 
03579         zzfuncTemplate->setRetTypeName(retTypeName,zzdomain);
03580         // We are creating a new predicate as well
03581         zzaddType(retTypeName, zzpredTemplate, NULL, false, zzdomain);
03582   
03583         // Add types
03584         for (int j = 2; j < zzinternalFunctions[i].size(); j++)
03585         {
03586           int id;
03587           const char* ttype = zzinternalFunctions[i][j];
03588           if (!zzdomain->isType(ttype))
03589           {
03590                 id = zzaddTypeToDomain(zzdomain, ttype);
03591                 zzassert(id >= 0, "expecting var id >= 0");
03592           }
03593           zzaddType(ttype, zzpredTemplate, NULL, false, zzdomain);
03594           // Add the type to the function too
03595           zzaddType(ttype, NULL, zzfuncTemplate, false, zzdomain);
03596         }
03597 
03598   // Add templates to domain
03599   zzassert(zzfuncTemplate, "expecting zzfuncTemplate != NULL");
03600   int id = zzdomain->addFunctionTemplate(zzfuncTemplate);
03601   zzassert(id >= 0, "expecting function template's id >= 0");
03602   zzfuncTemplate->setId(id);
03603   zzfuncTemplate = NULL;
03604 
03605   zzassert(zzpredTemplate, "not expecting zzpredTemplate==NULL");
03606   int predId = zzdomain->addPredicateTemplate(zzpredTemplate);
03607   zzassert(predId >= 0, "expecting pred template id >= 0");
03608   zzpredTemplate->setId(predId);
03609   zzpredTemplate = NULL;
03610   }
03611   
03612   return;
03613 }
03614 */
03615 
03631 void zzinsertPermutationOfInternalPredicate(int index,
03632                                                                                         const PredicateTemplate* const& ptemplate,
03633                                                                                     int numTerms, Array<int>* currentConstants)
03634 {
03635   bool retBool = false;
03636   string arguments[numTerms];
03637   string argumentsAsNum[numTerms];
03638   
03639   // Find the arguments for the predicate according to currentConstants
03640   for (int i = 0; i < numTerms; i++)
03641   {
03642         const Array<int>* constantsByType =
03643                 zzdomain->getConstantsByType(ptemplate->getTermTypeAsInt(i));
03644 
03645         arguments[i] = zzdomain->getConstantName((*constantsByType)[((*currentConstants)[i])]);
03646         // If constant is a number, then we have to cut it out of the string C@Type@Number
03647         unsigned int at = arguments[i].rfind("@");
03648         if (at != string::npos)
03649           argumentsAsNum[i] = arguments[i].substr(at+1, arguments[i].length()-at-1);
03650         else
03651         {
03652           argumentsAsNum[i] = arguments[i];
03653                 // Remove " from constants
03654           string::size_type loc = argumentsAsNum[i].find("\"", 0);
03655           while (loc != string::npos)
03656           {
03657                 argumentsAsNum[i].erase(loc, 1);
03658                 loc = argumentsAsNum[i].find("\"", 0);
03659           }
03660         }
03661   }
03662   
03663   // Make the function call
03664   int a, b;
03665   switch(index)
03666   {
03667         case 0:
03668           Internals::stringToInt(argumentsAsNum[0], a);
03669           Internals::stringToInt(argumentsAsNum[1], b);
03670       retBool = Internals::greaterThan(a, b);
03671       break;
03672     case 1:
03673           Internals::stringToInt(argumentsAsNum[0], a);
03674           Internals::stringToInt(argumentsAsNum[1], b);
03675       retBool = Internals::lessThan(a, b);
03676       break;
03677     case 2:
03678           Internals::stringToInt(argumentsAsNum[0], a);
03679           Internals::stringToInt(argumentsAsNum[1], b);
03680       retBool = Internals::greaterThanEq(a, b);
03681       break;
03682     case 3:
03683           Internals::stringToInt(argumentsAsNum[0], a);
03684           Internals::stringToInt(argumentsAsNum[1], b);
03685       retBool = Internals::lessThanEq(a, b);
03686       break;
03687     case 4:
03688       retBool = Internals::substr(argumentsAsNum[0], argumentsAsNum[1]);
03689       break;
03690   }
03691     
03692   // Insert the predicate definition just created  
03693   const char* predName;
03694   predName = ptemplate->getName();
03695   zzcreatePred(zzpred, predName);
03696   if (retBool) zzpred->setTruthValue(TRUE);
03697   else zzpred->setTruthValue(FALSE);
03698   
03699   //Add constant terms to predicate
03700   for (int i = 0; i < numTerms; i++)
03701   {
03702         const char* term = arguments[i].c_str();
03703         int constId = zzdomain->getConstantId(term);
03704         zzpredAppendConstant(zzpred, constId, term);
03705   }
03706         
03707   zzcheckPredNumTerm(zzpred);
03708   int predId = zzpred->getId();
03709 
03710   // Insert mapping of grounding
03711   hash_map<int,PredicateHashArray*>::iterator it;
03712   if ((it=zzpredIdToGndPredMap.find(predId)) == zzpredIdToGndPredMap.end())
03713         zzpredIdToGndPredMap[predId] = new PredicateHashArray;
03714   
03715 //cout << "Mapping " << endl;
03716 //zzpred->printWithStrVar(cout, zzdomain);
03717 //cout << " " << zzpred->getTruthValue() << endl;
03718 
03719   PredicateHashArray* pha = zzpredIdToGndPredMap[predId];
03720   if (pha->append(zzpred) < 0)
03721   {
03722     int a = pha->find(zzpred);
03723     zzassert(a >= 0, "expecting ground predicate to be found");
03724     string origTvStr = (*pha)[a]->getTruthValueAsStr();
03725     (*pha)[a]->setTruthValue(zzpred->getTruthValue());
03726     string newTvStr = (*pha)[a]->getTruthValueAsStr();
03727 
03728     if (zzwarnDuplicates)
03729     {
03730       ostringstream oss;
03731       oss << "Duplicate ground predicate "; zzpred->print(oss, zzdomain); 
03732       oss << " found. ";
03733       if (origTvStr.compare(newTvStr) != 0)
03734         oss << "Changed its truthValue from " << origTvStr << " to " <<newTvStr 
03735             << endl;
03736       zzwarn(oss.str().c_str());
03737     }
03738     delete zzpred;
03739   }
03740 
03741   zzpred = NULL;
03742 }
03743 
03760 void zzinsertPermutationOfInternalFunction(int index, const FunctionTemplate* ftemplate,
03761                                                                                    int numTerms, Array<int>* currentConstants)
03762 {
03763   char constName[1000];
03764   string arguments[numTerms];
03765   string argumentsAsNum[numTerms];
03766   
03767   // Find the arguments for the predicate according to currentConstants
03768   for (int i = 0; i < numTerms; i++)
03769   {
03770         const Array<int>* constantsByType =
03771                 zzdomain->getConstantsByType(ftemplate->getTermTypeAsInt(i));
03772 
03773         arguments[i] = zzdomain->getConstantName((*constantsByType)[((*currentConstants)[i])]);
03774         // If constant is a number, then we have to cut it out of the string C@Type@Number
03775         unsigned int at = arguments[i].rfind("@");
03776         if (at != string::npos)
03777           argumentsAsNum[i] = arguments[i].substr(at+1, arguments[i].length()-at-1);
03778         else argumentsAsNum[i] = arguments[i];
03779   }
03780   
03781   // Make the function call
03782   int a, b;
03783   switch(index)
03784   {
03785         case 0:
03786           Internals::stringToInt(argumentsAsNum[0], a);
03787           zzcreateIntConstant(constName, ftemplate->getRetTypeName(), Internals::succ(a));
03788       break;
03789     case 1:
03790           Internals::stringToInt(argumentsAsNum[0], a);
03791           Internals::stringToInt(argumentsAsNum[1], b);
03792           zzcreateIntConstant(constName, ftemplate->getRetTypeName(), Internals::plus(a, b));
03793       break;
03794     case 2:
03795           Internals::stringToInt(argumentsAsNum[0], a);
03796           Internals::stringToInt(argumentsAsNum[1], b);
03797           zzcreateIntConstant(constName, ftemplate->getRetTypeName(), Internals::minus(a, b));
03798       break;
03799     case 3:
03800           Internals::stringToInt(argumentsAsNum[0], a);
03801           Internals::stringToInt(argumentsAsNum[1], b);
03802           zzcreateIntConstant(constName, ftemplate->getRetTypeName(), Internals::times(a, b));
03803       break;
03804     case 4:
03805           Internals::stringToInt(argumentsAsNum[0], a);
03806           Internals::stringToInt(argumentsAsNum[1], b);
03807           zzcreateIntConstant(constName, ftemplate->getRetTypeName(), Internals::dividedBy(a, b));
03808       break;
03809     case 5:
03810           Internals::stringToInt(argumentsAsNum[0], a);
03811           Internals::stringToInt(argumentsAsNum[1], b);
03812           zzcreateIntConstant(constName, ftemplate->getRetTypeName(), Internals::mod(a, b));
03813       break;
03814     case 6:
03815       strcpy(constName, Internals::concat(argumentsAsNum[0], argumentsAsNum[1]).c_str());
03816   }
03817   
03818   // The return value has to be an existing constant of the return type
03819   int constantId = zzdomain->getConstantId(constName);
03820   const Array<int>* returnConstants =
03821                 zzdomain->getConstantsByType(ftemplate->getRetTypeId());
03822   
03823   if (returnConstants->contains(constantId))
03824   {
03825         // Insert the function definition just created  
03826         // Predicate name is PredicateTemplate::ZZ_RETURN_PREFIX + function name
03827         char* predName;
03828         predName = (char *)malloc((strlen(PredicateTemplate::ZZ_RETURN_PREFIX) +
03829                                                            strlen(ftemplate->getName()) + 1)*sizeof(char));
03830         strcpy(predName, PredicateTemplate::ZZ_RETURN_PREFIX);
03831         strcat(predName, ftemplate->getName());
03832         zzcreatePred(zzpred, predName);
03833         zzpred->setTruthValue(TRUE);
03834 
03835         //Add return constant to predicate
03836         zzpredAppendConstant(zzpred, constantId, constName);
03837         //Add constant terms to predicate
03838         for (int i = 0; i < numTerms; i++)
03839         {
03840           const char* term = arguments[i].c_str();
03841           int constId = zzdomain->getConstantId(term);
03842           zzpredAppendConstant(zzpred, constId, term);
03843         }
03844         
03845         zzcheckPredNumTerm(zzpred);
03846         int predId = zzpred->getId();
03847         // Insert mapping of grounding
03848         hash_map<int,PredicateHashArray*>::iterator it;
03849         if ((it=zzpredIdToGndPredMap.find(predId)) == zzpredIdToGndPredMap.end())
03850         zzpredIdToGndPredMap[predId] = new PredicateHashArray;
03851 
03852 //cout << "Mapping " << endl;
03853 //zzpred->printWithStrVar(cout, zzdomain);
03854 //cout << " " << zzpred->getTruthValue() << endl;
03855   
03856         PredicateHashArray* pha = zzpredIdToGndPredMap[predId];
03857         if (pha->append(zzpred) < 0)
03858         {
03859       int a = pha->find(zzpred);
03860       zzassert(a >= 0, "expecting ground predicate to be found");
03861       string origTvStr = (*pha)[a]->getTruthValueAsStr();
03862       (*pha)[a]->setTruthValue(zzpred->getTruthValue());
03863       string newTvStr = (*pha)[a]->getTruthValueAsStr();
03864 
03865       if (zzwarnDuplicates)
03866       {
03867         ostringstream oss;
03868         oss << "Duplicate ground predicate "; zzpred->print(oss, zzdomain); 
03869         oss << " found. ";
03870         if (origTvStr.compare(newTvStr) != 0)
03871           oss << "Changed its truthValue from " << origTvStr << " to " <<newTvStr 
03872               << endl;
03873         zzwarn(oss.str().c_str());
03874       }
03875           delete zzpred;
03876     }
03877 
03878     free(predName);
03879         zzpred = NULL;
03880   }
03881   
03882 }
03883 
03901 void zzinsertPermutationsOfInternalPredicate(int index,
03902                                                                                          const PredicateTemplate* const& ptemplate,
03903                                                                                      int numTerms, int currentTerm,
03904                                                                                      Array<int>* currentConstants)
03905 {
03906   const Array<int>* constants =
03907         zzdomain->getConstantsByType(ptemplate->getTermTypeAsInt(currentTerm));
03908 
03909   // Base case: at the last term
03910   if (currentTerm == numTerms - 1)
03911   {
03912         for (int i = 0; i < constants->size(); i++)
03913         {
03914           (*currentConstants)[currentTerm] = i;
03915           zzinsertPermutationOfInternalPredicate(index, ptemplate,
03916                                                                                      numTerms, currentConstants);
03917         }
03918         return;
03919   }
03920   
03921   // Not yet at last term
03922   zzinsertPermutationsOfInternalPredicate(index, ptemplate,
03923                                                                                   numTerms, currentTerm + 1, currentConstants);
03924   
03925   if (++(*currentConstants)[currentTerm] < constants->size())
03926         zzinsertPermutationsOfInternalPredicate(index, ptemplate,
03927                                                                                 numTerms, currentTerm, currentConstants);
03928 
03929   (*currentConstants)[currentTerm] = 0;
03930   return;
03931 }
03932 
03933 
03951 void zzinsertPermutationsOfInternalFunction(int index,
03952                                                                                         const FunctionTemplate* const& ftemplate,
03953                                                                                     int numTerms, int currentTerm,
03954                                                                                     Array<int>* currentConstants)
03955 {
03956   const Array<int>* constants =
03957         zzdomain->getConstantsByType(ftemplate->getTermTypeAsInt(currentTerm));
03958 
03959   // Base case: at the last term
03960   if (currentTerm == numTerms - 1)
03961   {
03962         for (int i = 0; i < constants->size(); i++)
03963         {
03964           (*currentConstants)[currentTerm] = i;
03965           zzinsertPermutationOfInternalFunction(index, ftemplate,
03966                                                                                     numTerms, currentConstants);
03967         }
03968         return;
03969   }
03970   
03971   // Not yet at last term
03972   zzinsertPermutationsOfInternalFunction(index, ftemplate,
03973                                                                              numTerms, currentTerm + 1, currentConstants);
03974   
03975   if (++(*currentConstants)[currentTerm] < constants->size())
03976         zzinsertPermutationsOfInternalFunction(index, ftemplate,
03977                                                                                numTerms, currentTerm, currentConstants);
03978 
03979   (*currentConstants)[currentTerm] = 0;
03980   return;
03981 }
03982 
03988 void zzgenerateGroundingsFromInternalPredicate(int index,
03989                                                                                            const PredicateTemplate* const& ptemplate)
03990 {
03991   // Find number of terms for predicate
03992   //const PredicateTemplate* ptemplate =
03993   //    zzdomain->getPredicateTemplate(zzinternalPredicates[index][0]);
03994 
03995   if (ptemplate != NULL)
03996   {
03997     int numTerms = ptemplate->getNumTerms();
03998 
03999     // Insert all possible permutations of constants
04000     const Array<int>* termTypes = ptemplate->getTermTypesAsInt();
04001     zzassert(numTerms == termTypes->size(),
04002                  "Number of terms and term types in predicate don't match");
04003     Array<int>* currentConstants = new Array<int>;
04004     for (int i = 0; i < numTerms; i++) currentConstants->append(0);
04005     zzinsertPermutationsOfInternalPredicate(index, ptemplate, numTerms, 0, currentConstants);
04006     delete currentConstants;
04007   }
04008   return;
04009 }
04010 
04016 void zzgenerateGroundingsFromInternalFunction(int index,
04017                                                                                           const FunctionTemplate* const& ftemplate)
04018 {
04019   // Find number of terms for function
04020   //const FunctionTemplate* ftemplate =
04021         //zzdomain->getFunctionTemplate(zzinternalFunctions[index][0]);
04022         
04023   if (ftemplate != NULL)
04024   {
04025     int numTerms = ftemplate->getNumTerms();
04026 
04027     // Insert all possible permutations of constants
04028     const Array<int>* termTypes = ftemplate->getTermTypesAsInt();
04029     zzassert(numTerms == termTypes->size(),
04030                    "Number of terms and term types in predicate don't match");
04031     Array<int>* currentConstants = new Array<int>;
04032     for (int i = 0; i < numTerms; i++) currentConstants->append(0);
04033     zzinsertPermutationsOfInternalFunction(index, ftemplate, numTerms, 0, currentConstants);
04034     delete currentConstants;
04035   }
04036   return;
04037 }
04038 
04047 void zzgenerateGroundingsFromInternalPredicatesAndFunctions()
04048 {
04049   // Look at each predicate
04050   //for (int i = 0; i < zzinternalPredicates.size(); i++)
04051   //{
04052         //const char* predName = zzinternalPredicates[i][0];
04053         //if (zzdomain->getPredicateId(predName) >= 0)
04054         //{
04055           //cout << "Found internal predicate: " << zzinternalPredicates[i][0] << endl;
04056           //zzgenerateGroundingsFromInternalPredicate(i);
04057         //}
04058   //}
04059 
04060   // Look at each predicate
04061   for (int i = 0; i < zzdomain->getNumPredicates(); i++)
04062   {
04063         const PredicateTemplate* ptemplate = zzdomain->getPredicateTemplate(i);
04064         if (ptemplate->isInternalPredicateTemplate())
04065         {
04066           cout << "Found internal predicate: " << ptemplate->getName() << endl;
04067           for (int j = 0; j < zzinternalPredicates.size(); j++)
04068           {
04069                 if (strncmp(ptemplate->getName(), zzinternalPredicates[j][0],
04070                                         strlen(zzinternalPredicates[j][0])) == 0)
04071                 {
04072                   zzgenerateGroundingsFromInternalPredicate(j, ptemplate);
04073                   break;
04074                 }
04075           }
04076         }
04077   }
04078 
04079   // Look at each function
04080   //for (int i = 0; i < zzinternalFunctions.size(); i++)
04081   //{
04082         //const char* funcName = zzinternalFunctions[i][0];
04083         //if (zzdomain->getFunctionId(funcName) >= 0)
04084         //{
04085           //cout << "Found internal function: " << zzinternalFunctions[i][0] << endl;
04086           //zzgenerateGroundingsFromInternalFunction(i);
04087         //}
04088   //}
04089 
04090   // Look at each function
04091   for (int i = 0; i < zzdomain->getNumFunctions(); i++)
04092   {
04093         const FunctionTemplate* ftemplate = zzdomain->getFunctionTemplate(i);
04094         if (ftemplate->isInternalFunctionTemplate())
04095         {
04096           cout << "Found internal function: " << ftemplate->getName() << endl;
04097           for (int j = 0; j < zzinternalFunctions.size(); j++)
04098           {
04099                 if (strncmp(ftemplate->getName(), zzinternalFunctions[j][0],
04100                                         strlen(zzinternalFunctions[j][0])) == 0)
04101                 {
04102                   zzgenerateGroundingsFromInternalFunction(j, ftemplate);
04103                   break;
04104                 }
04105           }
04106         }
04107   }
04108 
04109   return;
04110 }
04111 
04112 void zzcreateInternalPredTemplate(const string& predName, const char* const & ttype)
04113 {
04114   // If already declared then return
04115   if (zzdomain->getPredicateId(predName.c_str()) >= 0) return;
04116   int index;
04117   string baseName = predName.substr(0, predName.find_last_of("_"));
04118   
04119   if ((index = zzfindInternalPredicate(baseName.c_str())) >= 0)
04120   {
04121     zzassert(zzdomain->getFunctionId(predName.c_str()) < 0, 
04122                "not expecting pred name to be declared as a function name");
04123     PredicateTemplate* ptemplate = new PredicateTemplate();
04124         ptemplate->setName(predName.c_str());
04125         
04126         // Add types
04127         for (int j = 1; j < zzinternalPredicates[index].size(); j++)
04128         {
04129           int id;
04130           //const char* ttype = zzinternalPredicates[index][j];
04131           if (!zzdomain->isType(ttype))
04132           {
04133                 id = zzaddTypeToDomain(zzdomain, ttype);
04134                 zzassert(id >= 0, "expecting var id >= 0");
04135           }
04136           zzaddType(ttype, ptemplate, NULL, false, zzdomain);
04137           //delete [] ttype;
04138         }
04139         
04140         // Add template to domain
04141         zzassert(ptemplate, "not expecting ptemplate==NULL");
04142         int id = zzdomain->addPredicateTemplate(ptemplate);
04143         zzassert(id >= 0, "expecting pred template id >= 0");
04144         ptemplate->setId(id);
04145   }
04146   else
04147     zzexit("Predicate %s is not an internal predicate.", predName.c_str());
04148 }
04149 
04150 void zzsetInternalPredTypeName(const char* const & predName, const int& typeId)
04151 {
04152   const char * typeName = zzdomain->getTypeName(typeId);
04153   string intPredName = PredicateTemplate::createInternalPredTypeName(predName, typeName);
04154   zzcreateInternalPredTemplate(intPredName, typeName);
04155   const PredicateTemplate* t = zzdomain->getPredicateTemplate(intPredName.c_str());
04156   zzpred->setTemplate((PredicateTemplate*)t);
04157   zzassert(zzdomain->getPredicateTemplate(intPredName.c_str()) != NULL,
04158            "expect internal pred template != NULL");
04159   ListObj* predlo = zzpredFuncListObjs.top();
04160   predlo->replace(predName, intPredName.c_str());
04161 }
04162 
04163 void zzcreateInternalFuncTemplate(const string & funcName,
04164                                                                   const Array<string>& typeNames)
04165 {
04166   // If already declared then return
04167   if (zzdomain->getFunctionId(funcName.c_str()) >= 0) return;
04168   int index;
04169   string baseName = funcName.substr(0, funcName.find_first_of("_"));
04170 
04171   if ((index = zzfindInternalFunction(baseName.c_str())) >= 0)
04172   {
04173     zzassert(zzfuncTemplate==NULL, "expecting zzfuncTemplate==NULL");
04174         zzfuncTemplate = new FunctionTemplate();
04175 
04176         // We are creating a new predicate as well
04177         zzassert(zzpredTemplate==NULL,"expecting zzpredTemplate==NULL");
04178         zzpredTemplate = new PredicateTemplate();
04179 
04180         zzassert(zzdomain->getPredicateId(funcName.c_str()) < 0, 
04181              "not expecting func name to be declared as pred name");
04182         zzassert(zzfuncTemplate,"expecting zzfuncTemplate!=NULL");
04183         zzfuncTemplate->setName(funcName.c_str());
04184 
04185         // Predicate name is PredicateTemplate::ZZ_RETURN_PREFIX + function name
04186         char* predName;
04187         predName = (char *)malloc((strlen(PredicateTemplate::ZZ_RETURN_PREFIX) +
04188                                                         strlen(funcName.c_str()) + 1)*sizeof(char));
04189         strcpy(predName, PredicateTemplate::ZZ_RETURN_PREFIX);
04190         strcat(predName, funcName.c_str());
04191         
04192         // Check that predicate has not been declared a function
04193         zzassert(zzdomain->getFunctionId(predName) < 0, 
04194                      "not expecting pred name to be declared as a function name");
04195         zzassert(zzpredTemplate,"expecting zzpredTemplate!=NULL");
04196         zzpredTemplate->setName(predName);
04197         free(predName);  
04198         
04199         // Add return type
04200         //const char* retTypeName = zzinternalFunctions[index][1];
04201         const char* retTypeName = typeNames[0].c_str();
04202 
04203         if (!zzdomain->isType(retTypeName))
04204         {
04205           int id = zzaddTypeToDomain(zzdomain, retTypeName);
04206       zzassert(id >= 0, "expecting retTypeName's id >= 0");
04207         }
04208 
04209         zzfuncTemplate->setRetTypeName(retTypeName, zzdomain);
04210         // We are creating a new predicate as well
04211         zzaddType(retTypeName, zzpredTemplate, NULL, false, zzdomain);
04212   
04213         // Add types
04214         //for (int j = 2; j < zzinternalFunctions[index].size(); j++)
04215         for (int j = 1; j < typeNames.size(); j++)
04216         {
04217           int id;
04218           //const char* ttype = zzinternalFunctions[index][j];
04219           const char* ttype = typeNames[j].c_str();
04220           if (!zzdomain->isType(ttype))
04221           {
04222                 id = zzaddTypeToDomain(zzdomain, ttype);
04223                 zzassert(id >= 0, "expecting var id >= 0");
04224           }
04225           zzaddType(ttype, zzpredTemplate, NULL, false, zzdomain);
04226           // Add the type to the function too
04227           zzaddType(ttype, NULL, zzfuncTemplate, false, zzdomain);
04228         }
04229 
04230         // Add templates to domain
04231         zzassert(zzfuncTemplate, "expecting zzfuncTemplate != NULL");
04232         int id = zzdomain->addFunctionTemplate(zzfuncTemplate);
04233         zzassert(id >= 0, "expecting function template's id >= 0");
04234         zzfuncTemplate->setId(id);
04235         zzfuncTemplate = NULL;
04236 
04237         zzassert(zzpredTemplate, "not expecting zzpredTemplate==NULL");
04238         int predId = zzdomain->addPredicateTemplate(zzpredTemplate);
04239         zzassert(predId >= 0, "expecting pred template id >= 0");
04240         zzpredTemplate->setId(predId);
04241         zzpredTemplate = NULL;          
04242   }
04243   else
04244     zzexit("Function %s is not an internal function.", funcName.c_str());
04245 }
04246 
04247 void zzsetInternalFuncTypeName(const char* const & funcName, const Array<int>& typeIds)
04248 {
04249   Array<string> typeNames(typeIds.size());
04250   for (int i = 0; i < typeIds.size(); i++)
04251     typeNames.append(zzdomain->getTypeName(typeIds[i]));
04252   string intFuncName = FunctionTemplate::createInternalFuncTypeName(funcName, typeNames);
04253   zzcreateInternalFuncTemplate(intFuncName, typeNames);
04254   
04255   const FunctionTemplate* t = zzdomain->getFunctionTemplate(intFuncName.c_str());
04256   zzfunc->setTemplate((FunctionTemplate*)t);
04257   zzassert(zzdomain->getFunctionTemplate(intFuncName.c_str()) != NULL,
04258            "expect internal func template != NULL");
04259   ListObj* funclo = zzpredFuncListObjs.top();
04260   funclo->replace(funcName, intFuncName.c_str());
04261 }
04262 
04263 const FunctionTemplate* zzgetGenericInternalFunctionTemplate(const char* const & funcName)
04264 {
04265   zzassert(FunctionTemplate::isInternalFunctionTemplateName(funcName),
04266                    "expect internal function name");
04267   int index = zzfindInternalFunction(funcName);
04268   FunctionTemplate* funcTemplate = new FunctionTemplate();
04269   funcTemplate->setName(funcName);
04270         
04271         // Add return type
04272   funcTemplate->setRetTypeName(PredicateTemplate::ANY_TYPE_NAME, zzdomain);
04273   
04274         // Add types
04275   for (int j = 2; j < zzinternalFunctions[index].size(); j++)
04276   {
04277           // Add the type to the function
04278         zzaddType(PredicateTemplate::ANY_TYPE_NAME, NULL, funcTemplate, false, zzdomain);
04279   }
04280   return funcTemplate;
04281 }
04282 
04283 #endif

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