00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef _relExpression_h
00032 #define _relExpression_h
00033
00034 #include "bddRelation.h"
00035 #include "relTerm.h"
00036
00037 #include <string>
00038 #include <fstream>
00039 #include <iterator>
00040 #include <regex.h>
00041
00043 extern string unsigned2string(unsigned pUnsigned);
00044 extern string double2string(double pNum);
00045 extern double elapsed();
00046
00048 extern map<string, relDataType*> gVariables;
00049 extern const unsigned gAttributeNum;
00050 extern const char gAttributePrefix;
00051 extern bddSymTab* gSymTab;
00052 extern bool gPrintWarnings;
00053
00054
00056 class relExpression : public relObject
00057 {
00058 public:
00059 virtual set<string>
00060 collectFreeAttrs() = 0;
00061
00062 virtual bddRelation
00063 interpret(bddSymTab* pSymTab) = 0;
00064 };
00065
00067 class relExprRelVar : public relExpression
00068 {
00069 private:
00070 string* mRelVar;
00071 vector<relTerm*>* mTermList;
00072
00073 public:
00074 relExprRelVar(string* pRelVar, vector<relTerm*>* pTermList)
00075 : mRelVar(pRelVar),
00076 mTermList(pTermList)
00077 {}
00078
00079 ~relExprRelVar()
00080 {
00081 delete mRelVar;
00082 for( vector<relTerm*>::iterator
00083 lIt = mTermList->begin();
00084 lIt != mTermList->end();
00085 ++lIt)
00086 {
00087 delete *lIt;
00088 }
00089 delete mTermList;
00090 }
00091
00092 virtual set<string>
00093 collectFreeAttrs()
00094 {
00095 set<string> result;
00096 for( vector<relTerm*>::iterator
00097 lIt = mTermList->begin();
00098 lIt != mTermList->end();
00099 ++lIt)
00100 {
00101 if (dynamic_cast<relTermAttribute*>(*lIt) != NULL) {
00102 result.insert((*lIt)->interpret(gSymTab));
00103 }
00104 }
00105 return result;
00106 }
00107
00108 virtual bddRelation
00109 interpret(bddSymTab* pSymTab)
00110 {
00111
00112
00113 for(unsigned i = 0; i < mTermList->size(); ++i) {
00114
00115 if (dynamic_cast<relTermAttribute*>((*mTermList)[i]) != NULL)
00116 {
00117 pSymTab->addAttribute( (*mTermList)[i]->interpret(pSymTab) );
00118 }
00119 }
00120
00121
00122 for(unsigned i = 0; i < mTermList->size(); ++i) {
00123 if ( (dynamic_cast<relTermStrExpr*>((*mTermList)[i]) != NULL) &&
00124 (!pSymTab->isValueGood((*mTermList)[i]->interpret(pSymTab))) ) {
00125 if (gPrintWarnings) {
00126 cerr << "Warning: String '" << (*mTermList)[i]->interpret(pSymTab)
00127 << "' is not in universe." << endl;
00128 }
00129
00130 return bddRelation(pSymTab, false);
00131 }
00132 }
00133
00134
00135 string lRelVar = *mRelVar;
00136 vector<relTerm*> lTermList = *mTermList;
00137 map<string, relDataType*>::const_iterator lVarIt = gVariables.find(lRelVar);
00138 assert(lVarIt != gVariables.end());
00139 assert(lVarIt->second != NULL);
00140 if (dynamic_cast<bddRelationConst*>(lVarIt->second) != NULL) {
00141
00142 if (lRelVar == "=" || lRelVar == "!=" ||
00143 lRelVar == "<" || lRelVar == "<=" ||
00144 lRelVar == ">" || lRelVar == ">=") {
00145
00146 assert(lTermList.size() == 2);
00147
00148 if (dynamic_cast<relTermStrExpr*>(lTermList[0]) == NULL &&
00149 dynamic_cast<relTermStrExpr*>(lTermList[1]) != NULL) {
00150 relTerm* lTermTmp = lTermList[0];
00151 lTermList[0] = lTermList[1];
00152 lTermList[1] = lTermTmp;
00153 if (lRelVar == "<") {
00154 lRelVar = ">";
00155 } else if (lRelVar == "<=") {
00156 lRelVar = ">=";
00157 } else if (lRelVar == ">") {
00158 lRelVar = "<";
00159 } else if (lRelVar == ">=") {
00160 lRelVar = "<=";
00161 }
00162 lVarIt = gVariables.find(lRelVar);
00163 assert(lVarIt != gVariables.end());
00164 assert(lVarIt->second != NULL);
00165 }
00166 }
00167 }
00168 bddRelation* lResult = dynamic_cast<bddRelation*>(lVarIt->second);
00169 assert(lResult != NULL);
00170
00171 bddRelation result = *lResult;
00172
00173
00174 if ( lResult->mArity != -1
00175 && lResult->mArity != mTermList->size() )
00176 {
00177 if (gPrintWarnings) {
00178 cerr << "Warning: Arity mismatch. '"
00179 << *mRelVar << "' is of arity " << lResult->mArity
00180 << " but is now used for arity " << mTermList->size() << "." << endl;
00181 }
00182 }
00183
00184
00185
00186 for(int i = lTermList.size()-1; i >= 0; --i)
00187 {
00188 string lTerm = lTermList[i]->interpret(pSymTab);
00189 if (dynamic_cast<relTermExists*>(lTermList[i]) != NULL)
00190 {
00191
00192 result.exists(gAttributePrefix + unsigned2string(i));
00193 }
00194 else if (dynamic_cast<relTermStrExpr*>(lTermList[i]) != NULL)
00195 {
00196
00197 result.intersect(bddRelation::mkAttributeValue(
00198 pSymTab,
00199 gAttributePrefix + unsigned2string(i),
00200 lTerm)
00201 );
00202 result.exists(gAttributePrefix + unsigned2string(i));
00203 }
00204 }
00205
00206
00207
00208 for(int i = lTermList.size()-1; i >= 0; --i)
00209 {
00210 string lTerm = lTermList[i]->interpret(pSymTab);
00211 if (dynamic_cast<relTermAttribute*>(lTermList[i]) != NULL)
00212 {
00213
00214
00215 result.rename(gAttributePrefix + unsigned2string(i), lTerm);
00216 }
00217 }
00218
00219
00220
00221 if ( result.testVars(gAttributePrefix + unsigned2string(0),
00222 gAttributePrefix + unsigned2string(gAttributeNum-1)) ) {
00223 cerr << "Error: The arity of relation '" << *mRelVar
00224 << "' is greater than the number of terms." << endl;
00225 exit(EXIT_FAILURE);
00226 }
00227
00228 return result;
00229 }
00230 };
00231
00233 class relExprRelNumCmp : public relExpression
00234 {
00235 private:
00236 string* mRelSym;
00237 relNumExpr* mNumExpr1;
00238 relNumExpr* mNumExpr2;
00239
00240 public:
00241 relExprRelNumCmp(string* pRelSym, relNumExpr* pNumExpr1, relNumExpr* pNumExpr2)
00242 : mRelSym(pRelSym),
00243 mNumExpr1(pNumExpr1),
00244 mNumExpr2(pNumExpr2)
00245 {}
00246
00247 ~relExprRelNumCmp()
00248 {
00249 delete mRelSym;
00250 delete mNumExpr1;
00251 delete mNumExpr2;
00252 }
00253
00254 virtual set<string>
00255 collectFreeAttrs()
00256 {
00257 set<string> result;
00258 return result;
00259 }
00260
00261 virtual bddRelation
00262 interpret(bddSymTab* pSymTab)
00263 {
00264 double lNum1 = mNumExpr1->interpret(pSymTab).getValue();
00265 double lNum2 = mNumExpr2->interpret(pSymTab).getValue();
00266 bool result = false;
00267 if (*mRelSym == "=") result = (lNum1 == lNum2);
00268 else if (*mRelSym == "!=") result = (lNum1 != lNum2);
00269 else if (*mRelSym == "<") result = (lNum1 < lNum2);
00270 else if (*mRelSym == "<=") result = (lNum1 <= lNum2);
00271 else if (*mRelSym == ">") result = (lNum1 > lNum2);
00272 else if (*mRelSym == ">=") result = (lNum1 >= lNum2);
00273 else {
00274 cerr << "Internal error: Unknown operator in numerical comparison: '"
00275 << *mRelSym << "'." << endl;
00276 abort();
00277 }
00278 return bddRelation(pSymTab, result);
00279 }
00280 };
00281
00283 class relExprExists : public relExpression
00284 {
00285 private:
00286 vector<relTerm*>* mTermList;
00287 relExpression* mExpr;
00288
00289 public:
00290 relExprExists(vector<relTerm*>* pTermList, relExpression* pExpr)
00291 : mTermList(pTermList),
00292 mExpr(pExpr)
00293 {}
00294
00295 ~relExprExists()
00296 {
00297 for( vector<relTerm*>::iterator
00298 lIt = mTermList->begin();
00299 lIt != mTermList->end();
00300 ++lIt)
00301 {
00302 delete *lIt;
00303 }
00304 delete mTermList;
00305 delete mExpr;
00306 }
00307
00308 virtual set<string>
00309 collectFreeAttrs()
00310 {
00311 set<string> result = mExpr->collectFreeAttrs();
00312 for( vector<relTerm*>::iterator
00313 lIt = mTermList->begin();
00314 lIt != mTermList->end();
00315 ++lIt)
00316 {
00317 if (dynamic_cast<relTermAttribute*>(*lIt) != NULL) {
00318 result.erase((*lIt)->interpret(gSymTab));
00319 }
00320 }
00321 return result;
00322 }
00323
00324 virtual bddRelation
00325 interpret(bddSymTab* pSymTab)
00326 {
00327 bddRelation result( mExpr->interpret(pSymTab) );
00328 const set<string> lFree = mExpr->collectFreeAttrs();
00329 for( vector<relTerm*>::iterator
00330 lIt = mTermList->begin();
00331 lIt != mTermList->end();
00332 ++lIt)
00333 {
00334 const string lAttr = (*lIt)->interpret(pSymTab);
00335 if (dynamic_cast<relTermAttribute*>(*lIt) == NULL) {
00336 cerr << "Error: Only attributes allowed for quantification." << endl;
00337 } else if (lFree.find(lAttr) == lFree.end()) {
00338 cerr << "Error: Only free attributes allowed for quantification."
00339 << endl
00340 << "Attribute '" << lAttr
00341 << "' does not occur free in the expression." << endl;
00342 } else {
00343 result.exists(lAttr);
00344 }
00345 }
00346 return result;
00347 }
00348 };
00349
00351 class relExprNot : public relExpression
00352 {
00353 private:
00354 relExpression* mExpr;
00355
00356 public:
00357 relExprNot( relExpression* pExpr)
00358 : mExpr(pExpr)
00359 {}
00360
00361 ~relExprNot()
00362 {
00363 delete mExpr;
00364 }
00365
00366 virtual set<string>
00367 collectFreeAttrs()
00368 {
00369 return mExpr->collectFreeAttrs();
00370 }
00371
00372 virtual bddRelation
00373 interpret(bddSymTab* pSymTab)
00374 {
00375 bddRelation result = mExpr->interpret(pSymTab);
00376 result.complement();
00377 return result;
00378 }
00379 };
00380
00382 class relExprAnd : public relExpression
00383 {
00384 private:
00385 relExpression* mExpr1;
00386 relExpression* mExpr2;
00387
00388 public:
00389 relExprAnd(relExpression* pExpr1, relExpression* pExpr2)
00390 : mExpr1(pExpr1),
00391 mExpr2(pExpr2)
00392 {}
00393
00394 ~relExprAnd()
00395 {
00396 delete mExpr1;
00397 delete mExpr2;
00398 }
00399
00400 virtual set<string>
00401 collectFreeAttrs()
00402 {
00403 set<string> result = mExpr1->collectFreeAttrs();
00404 set<string> tmp = mExpr2->collectFreeAttrs();
00405 result.insert(tmp.begin(), tmp.end());
00406 return result;
00407 }
00408
00409 virtual bddRelation
00410 interpret(bddSymTab* pSymTab)
00411 {
00412 bddRelation result( mExpr1->interpret(pSymTab) );
00413 result.intersect( mExpr2->interpret(pSymTab) );
00414 return result;
00415 }
00416 };
00417
00419 class relExprOr : public relExpression
00420 {
00421 private:
00422 relExpression* mExpr1;
00423 relExpression* mExpr2;
00424
00425 public:
00426 relExprOr(relExpression* pExpr1, relExpression* pExpr2)
00427 : mExpr1(pExpr1),
00428 mExpr2(pExpr2)
00429 {}
00430
00431 ~relExprOr()
00432 {
00433 delete mExpr1;
00434 delete mExpr2;
00435 }
00436
00437 virtual set<string>
00438 collectFreeAttrs()
00439 {
00440 set<string> result = mExpr1->collectFreeAttrs();
00441 set<string> tmp = mExpr2->collectFreeAttrs();
00442 result.insert(tmp.begin(), tmp.end());
00443 return result;
00444 }
00445
00446 virtual bddRelation
00447 interpret(bddSymTab* pSymTab)
00448 {
00449 bddRelation result( mExpr1->interpret(pSymTab) );
00450 result.unite( mExpr2->interpret(pSymTab) );
00451 return result;
00452 }
00453 };
00454
00456 class relExprEquiv : public relExpression
00457 {
00458 private:
00459 relExpression* mExpr1;
00460 relExpression* mExpr2;
00461
00462 public:
00463 relExprEquiv(relExpression* pExpr1, relExpression* pExpr2)
00464 : mExpr1(pExpr1),
00465 mExpr2(pExpr2)
00466 {}
00467
00468 ~relExprEquiv()
00469 {
00470 delete mExpr1;
00471 delete mExpr2;
00472 }
00473
00474 virtual set<string>
00475 collectFreeAttrs()
00476 {
00477 set<string> result = mExpr1->collectFreeAttrs();
00478 set<string> tmp = mExpr2->collectFreeAttrs();
00479 result.insert(tmp.begin(), tmp.end());
00480 return result;
00481 }
00482
00483 virtual bddRelation
00484 interpret(bddSymTab* pSymTab)
00485 {
00486
00487 bddRelation lExpr1 = mExpr1->interpret(pSymTab);
00488 bddRelation lExpr2 = mExpr2->interpret(pSymTab);
00489 bddRelation lIntersect = lExpr1;
00490 lIntersect.intersect(lExpr2);
00491 bddRelation result = lExpr1;
00492 result.unite(lExpr2);
00493 result.complement();
00494 result.unite(lIntersect);
00495 return result;
00496 }
00497 };
00498
00500 class relExprClosure : public relExpression
00501 {
00502 public:
00503 typedef enum {EXPTRAVERS, WARSHALLII} relTCAlg;
00504
00505 private:
00506 relExpression* mExpr;
00507 relTCAlg mAlg;
00508
00509 public:
00510 relExprClosure(relExpression* pExpr,
00511 relTCAlg pAlg)
00512 : mExpr(pExpr),
00513 mAlg(pAlg)
00514 {}
00515
00516 ~relExprClosure()
00517 {
00518 delete mExpr;
00519 }
00520
00521 virtual set<string>
00522 collectFreeAttrs()
00523 {
00524 return mExpr->collectFreeAttrs();
00525 }
00526
00527
00528 virtual bddRelation
00529 interpret(bddSymTab* pSymTab)
00530 {
00531
00532 bddRelation result( mExpr->interpret(pSymTab) );
00533
00534 const set<string> lFree = mExpr->collectFreeAttrs();
00535 if(lFree.size() != 2) {
00536 cerr << "Error: Transitive closure requires two free attributes." << endl;
00537 exit(EXIT_FAILURE);
00538 }
00539 const map<unsigned,string> lVarOrd = pSymTab->computeVariableOrder(lFree);
00540 assert(lVarOrd.size() == 2);
00541 const string lAttributeX = lVarOrd.begin()->second;
00542 const string lAttributeY = (++lVarOrd.begin())->second;
00543
00544
00545 string tmpAttr = ".INTERNAL_TMPATTR.";
00546
00547 pSymTab->addAttribute(tmpAttr);
00548
00549
00550 if (mAlg == EXPTRAVERS) {
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629 {
00630
00631
00632 bddRelation lPrevRel(pSymTab, false);
00633 while( ! lPrevRel.setEqual(result) )
00634 {
00635 lPrevRel = result;
00636
00637
00638 bddRelation lTmpRel(result);
00639 lTmpRel.rename(lAttributeY, tmpAttr);
00640 lTmpRel.rename(lAttributeX, lAttributeY);
00641
00642
00643 result.intersect(lTmpRel);
00644 result.exists(lAttributeY);
00645 result.rename(tmpAttr, lAttributeY);
00646
00647 result.unite( lPrevRel );
00648 }
00649 }
00650
00651 }
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715 if (mAlg == WARSHALLII) {
00716
00717
00718
00719
00720
00721
00722 bddRelation lInvResult(result);
00723 lInvResult.rename(lAttributeY, tmpAttr);
00724 lInvResult.rename(lAttributeX, lAttributeY);
00725 lInvResult.rename(tmpAttr, lAttributeX);
00726
00727
00728 bddRelation lValuesX(result);
00729 lValuesX.exists(lAttributeY);
00730 bddRelation lValuesY(result);
00731 lValuesY.exists(lAttributeX);
00732 lValuesY.rename(lAttributeY, lAttributeX);
00733 lValuesX.intersect(lValuesY);
00734 const unsigned lVarId = pSymTab->getAttributePos(lAttributeX);
00735
00736 while (!lValuesX.isEmpty()) {
00737
00738 string lValue = lValuesX.getElement(lVarId);
00739
00740 bddRelation lCurrentValue( bddRelation::mkAttributeValue(pSymTab, lAttributeX, lValue) );
00741
00742
00743 bddRelation lStartNodesY(lInvResult);
00744 lStartNodesY.intersect(lCurrentValue);
00745 lStartNodesY.exists(lAttributeX);
00746 bddRelation lStartNodesX(lStartNodesY);
00747 lStartNodesX.rename(lAttributeY, lAttributeX);
00748
00749 bddRelation lEndNodesY(result);
00750 lEndNodesY.intersect(lCurrentValue);
00751 lEndNodesY.exists(lAttributeX);
00752 bddRelation lEndNodesX(lEndNodesY);
00753 lEndNodesX.rename(lAttributeY, lAttributeX);
00754
00755 lStartNodesX.intersect(lEndNodesY);
00756 lEndNodesX.intersect(lStartNodesY);
00757
00758 result.unite(lStartNodesX);
00759 lInvResult.unite(lEndNodesX);
00760
00761
00762
00763 lCurrentValue.complement();
00764 lValuesX.intersect(lCurrentValue);
00765 }
00766 }
00767
00768 pSymTab->removeAttribute(tmpAttr);
00769 return result;
00770 }
00771 };
00772
00774 class relExprRelOp : public relExpression
00775 {
00776 private:
00777 relExpression* mExpr1;
00778 string* mRelOp;
00779 relExpression* mExpr2;
00780
00781 public:
00782 relExprRelOp( relExpression* pExpr1,
00783 string* pRelOp,
00784 relExpression* pExpr2)
00785 : mExpr1(pExpr1),
00786 mRelOp(pRelOp),
00787 mExpr2(pExpr2)
00788 {}
00789
00790 ~relExprRelOp()
00791 {
00792 delete mExpr1;
00793 delete mRelOp;
00794 delete mExpr2;
00795 }
00796
00797 virtual set<string>
00798 collectFreeAttrs()
00799 {
00800 set<string> result;
00801 return result;
00802 }
00803
00804 virtual bddRelation
00805 interpret(bddSymTab* pSymTab)
00806 {
00807 bool result = false;
00808 bddRelation lExpr1 = mExpr1->interpret(pSymTab);
00809 bddRelation lExpr2 = mExpr2->interpret(pSymTab);
00810
00811 if (*mRelOp == "=") result = lExpr1.setEqual(lExpr2);
00812 else if (*mRelOp == "!=") result = ! lExpr1.setEqual(lExpr2);
00813 else if (*mRelOp == ">") result = lExpr1.setContains(lExpr2) && ! lExpr1.setEqual(lExpr2);
00814 else if (*mRelOp == ">=") result = lExpr1.setContains(lExpr2);
00815 else if (*mRelOp == "<") result = lExpr2.setContains(lExpr1) && ! lExpr1.setEqual(lExpr2);
00816 else if (*mRelOp == "<=") result = lExpr2.setContains(lExpr1);
00817 else {
00818 cerr << "Internal error: Unknown operator (relExprRelOp)." << endl;
00819 abort();
00820 }
00821 return bddRelation(pSymTab, result);
00822 }
00823 };
00824
00829 class relExprRegExTerm : public relExpression
00830 {
00831 private:
00832 relStrExpr* mRegExString;
00833 relTerm* mTerm;
00834
00835 public:
00836 relExprRegExTerm( relStrExpr* pRegExString,
00837 relTerm* pTerm)
00838 : mRegExString(pRegExString),
00839 mTerm(pTerm)
00840 {}
00841
00842 ~relExprRegExTerm()
00843 {
00844 delete mRegExString;
00845 delete mTerm;
00846 }
00847
00848 virtual set<string>
00849 collectFreeAttrs()
00850 {
00851 set<string> result;
00852 if (dynamic_cast<relTermAttribute*>(mTerm) != NULL) {
00853 result.insert(mTerm->interpret(gSymTab));
00854 }
00855 return result;
00856 }
00857
00859 void
00860 errorproc(int pErrorCode,
00861 regex_t* pRegExCompiled,
00862 const char* pRegEx,
00863 const char* pString)
00864 {
00865 size_t lLength = regerror(pErrorCode, pRegExCompiled, NULL, 0);
00866 char* lErrorMsg = (char*) malloc(lLength);
00867 if (lErrorMsg == NULL) {
00868 cerr << "Error: Virtual memory exhausted." << endl;
00869 exit(EXIT_FAILURE);
00870 }
00871 (void) regerror(pErrorCode, pRegExCompiled, lErrorMsg, lLength);
00872 cerr << "Error: Cannot apply regular expression '" << pRegEx
00873 << "' to string '" << pString << "': " << lErrorMsg << endl;
00874 delete lErrorMsg;
00875 }
00876
00878 bool
00879 regexmatch(regex_t* pRegExCompiled,
00880 const char* pRegEx,
00881 const char* pString)
00882 {
00883 int lErrorCode = regexec(pRegExCompiled, pString, 0, NULL, 0);
00884 if (lErrorCode == 0) {
00885 return true;
00886 }
00887 if (lErrorCode == REG_NOMATCH) {
00888 return false;
00889 }
00890
00891 errorproc(lErrorCode, pRegExCompiled, pRegEx, pString);
00892 regfree(pRegExCompiled);
00893 exit(EXIT_FAILURE);
00894 }
00895
00896 virtual bddRelation
00897 interpret(bddSymTab* pSymTab)
00898 {
00899 const char* lTerm = mTerm->interpret(pSymTab).c_str();
00900 const char* lRegExStr
00901 = mRegExString->interpret(pSymTab).getValue().c_str();
00902
00903 regex_t lRegExCompiled;
00904 int lErrorCode
00905 = regcomp(&lRegExCompiled, lRegExStr, REG_EXTENDED | REG_NOSUB);
00906 if (lErrorCode != 0) {
00907 errorproc(lErrorCode, &lRegExCompiled, lRegExStr, lTerm);
00908 regfree(&lRegExCompiled);
00909 exit(EXIT_FAILURE);
00910 }
00911
00912
00913 if (dynamic_cast<relTermStrExpr*>(mTerm) != NULL)
00914 {
00915 if (!pSymTab->isValueGood(string(lTerm))) {
00916 if (gPrintWarnings) {
00917 cerr << "Warning: String '" << lTerm
00918 << "' is not in universe." << endl;
00919 }
00920
00921 regfree(&lRegExCompiled);
00922 return bddRelation(pSymTab, false);
00923 }
00924
00925 bool result = regexmatch(&lRegExCompiled,
00926 lRegExStr,
00927 lTerm);
00928 regfree(&lRegExCompiled);
00929 return bddRelation(pSymTab, result);
00930 }
00931
00932 if (dynamic_cast<relTermExists*>(mTerm) != NULL)
00933 {
00934 for (reprNUMBER i = 0; i < pSymTab->getUniverseSize(); ++i)
00935 {
00936
00937 bool result = regexmatch(&lRegExCompiled,
00938 lRegExStr,
00939 lTerm);
00940 if (result) {
00941 regfree(&lRegExCompiled);
00942 return bddRelation(pSymTab, true);
00943 }
00944 }
00945 regfree(&lRegExCompiled);
00946 return bddRelation(pSymTab, false);
00947 }
00948
00949
00950 assert(dynamic_cast<relTermAttribute*>(mTerm) != NULL);
00951
00952
00953
00954 pSymTab->addAttribute(mTerm->interpret(pSymTab));
00955
00956 bddRelation result(pSymTab, false);
00957 const unsigned lVarId = pSymTab->getAttributePos(lTerm);
00958 for (reprNUMBER i = 0; i < pSymTab->getUniverseSize(); ++i)
00959 {
00960 const string lValue = pSymTab->getAttributeValue(i);
00961
00962 if (regexmatch(&lRegExCompiled,
00963 lRegExStr,
00964 lValue.c_str())) {
00965 result.unite( bddRelation::mkEqual(pSymTab, lVarId, i) );
00966 }
00967 }
00968 regfree(&lRegExCompiled);
00969 return result;
00970 }
00971 };
00972
00973
00976 class relExprTupleOf : public relExpression
00977 {
00978 private:
00979 relExpression* mExpr;
00980
00981 public:
00982 relExprTupleOf(relExpression* pExpr)
00983 : mExpr(pExpr)
00984 {}
00985
00986 ~relExprTupleOf()
00987 {
00988 delete mExpr;
00989 }
00990
00991 virtual set<string>
00992 collectFreeAttrs()
00993 {
00994 return mExpr->collectFreeAttrs();
00995 }
00996
00997 virtual bddRelation
00998 interpret(bddSymTab* pSymTab)
00999 {
01000
01001 bddRelation lRel = mExpr->interpret(pSymTab);
01002 const set<string> lFree = mExpr->collectFreeAttrs();
01003 const map<unsigned,string> lVarOrd = pSymTab->computeVariableOrder(lFree);
01004 if( lRel.isEmpty() ) {
01005 cerr << "Error: TUPLEOF requires a non-empty relation as parameter."
01006 << endl;
01007 exit(EXIT_FAILURE);
01008 }
01009 return lRel.getTupleOf(lVarOrd);
01010 }
01011 };
01012
01013 #endif
01014