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 }
1.5.1