relNumExpr.cpp

Go to the documentation of this file.
00001 /*
00002  * CrocoPat is a tool for relational programming.
00003  * This file is part of CrocoPat. 
00004  *
00005  * Copyright (C) 2002-2008  Dirk Beyer
00006  *
00007  * CrocoPat is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License
00009  * as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * CrocoPat is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public License
00018  * along with CrocoPat; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  *
00021  * Please find the GNU Lesser General Public License in file
00022  * License_LGPL.txt or at http://www.gnu.org/licenses/lgpl.txt
00023  *
00024  * Author:
00025  * Dirk Beyer (firstname.lastname@sfu.ca)
00026  * Simon Fraser University
00027  *
00028  * With contributions of: Andreas Noack, Michael Vogel
00029  */
00030 
00031 #include "relNumExpr.h"
00032 #include "relExpression.h"
00033 #include "relStrExpr.h"
00034 
00035 #include <cfloat>
00036 
00037 extern double string2double(string pStr);
00038 
00040 relNumExprUnOp::~relNumExprUnOp()
00041 {
00042   delete mExpr;
00043 }
00044 
00045 relNumber
00046 relNumExprUnOp::interpret(bddSymTab* pSymTab)
00047 {
00048   // First evaluate, to set variables in the variable ordering.
00049   bddRelation lRel = mExpr->interpret(pSymTab);
00050   const set<string> lFree = mExpr->collectFreeAttrs();
00051   relNumber result(0);
00052 
00053   // Cardinality.
00054   if (mOp == CARD) {
00055     result.setValue( lRel.getTupleNr(lFree) );
00056     return result;
00057   }
00058 
00059   // Min, Max, Sum.
00060   if(lFree.size() != 1) {
00061     cerr << "Error: MIN, MAX, SUM, or AVG requires expression with one free attribute (i.e. a set)." 
00062          << endl;
00063     exit(EXIT_FAILURE);
00064   }
00065   const unsigned lVarId = pSymTab->getAttributePos(*lFree.begin());
00066 
00067   if (lRel.isEmpty()) {
00068     if (mOp == SUM) {
00069       result.setValue(0);
00070       return result;
00071     }
00072     cerr << "Error: MIN, MAX, or AVG applied to empty set." << endl;
00073     exit(EXIT_FAILURE);
00074   }
00075   double lSum  = 0;
00076   double lCard = 0;
00077   double lMin  = DBL_MAX;
00078   double lMax  = -DBL_MAX;
00079   // For all elements of the set (all values for attribute lAttribute).
00080   while (!lRel.isEmpty()) {
00081     // Get next value of the attribute.
00082     string lValue = lRel.getElement(lVarId);
00083     double lNumValue = string2double(lValue);
00084     lSum += lNumValue;
00085     ++lCard;
00086     lMin = min(lMin, lNumValue);
00087     lMax = max(lMax, lNumValue);
00088     
00089     // Compute cofactor for current value in (lTmpRel).
00090     bddRelation lCurrentValue( 
00091                   bddRelation::mkEqual(pSymTab, 
00092                                        lVarId, 
00093                                        pSymTab->getValueNum(lValue)) );
00094     // Delete current element from set.
00095     lCurrentValue.complement();  
00096     lRel.intersect(lCurrentValue);
00097   }
00098 
00099   if (mOp == MIN)       result.setValue( lMin );
00100   else if (mOp == MAX)  result.setValue( lMax );
00101   else if (mOp == SUM)  result.setValue( lSum );
00102   else if (mOp == AVG)  result.setValue( lSum / lCard );
00103   else { 
00104     cerr << "Internal error: Unknown operator in relNumExprUnOp::interpret." 
00105          << endl;
00106     abort();
00107   }
00108   return result;
00109 }
00110 
00112 relNumExprStr::~relNumExprStr()
00113 {
00114   delete mExpr;
00115 }
00116 
00117 relNumber
00118 relNumExprStr::interpret(bddSymTab* pSymTab)
00119 {
00120   return relNumber( string2double(mExpr->interpret(pSymTab).getValue()) );
00121 }

Generated on Fri Jun 6 22:21:09 2008 for CrocoPat by  doxygen 1.5.1