@@ -6,6 +6,7 @@ import ProjectM36.TupleSet
66import ProjectM36.Base
77import ProjectM36.Error
88import ProjectM36.Atom
9+import ProjectM36.AtomFunction
910import qualified ProjectM36.Attribute as A
1011import qualified Data.Map as M
1112import qualified Data.HashSet as HS
@@ -99,7 +100,7 @@ evalRelationalExpr (Extend tupleExpression relExpr) = do
99100 case tupleExpressionProcessor rel tupleExpression context of
100101 Left err -> return $ Left err
101102 Right (newAttrs, tupProc) -> return $ relMogrify tupProc newAttrs rel
102−
103+
103104emptyDatabaseContext :: DatabaseContext
104105emptyDatabaseContext = DatabaseContext { inclusionDependencies = HS.empty,
105106 relationVariables = M.empty,
@@ -359,7 +360,6 @@ predicateRestrictionFilter context (AttributeEqualityPredicate attrName atomexpr
359360 case evalAtomExpr tupleIn context atomexpr of
360361 Left _ -> False
361362 Right atomCmp -> atomCmp == atomIn
362−
363363
364364tupleExprCheckNewAttrName :: AttributeName -> Relation -> Either RelationalError Relation
365365tupleExprCheckNewAttrName attrName rel = if isRight $ attributeForName attrName rel then
@@ -379,25 +379,19 @@ tupleExpressionProcessor relIn
379379 Left _ -> undefined -- ?!
380380 Right atom -> tupleAtomExtend newAttrName atom tup)
381381
382−basicAtomFunctions :: AtomFunctions
383−basicAtomFunctions = HS.fromList [
384− --match on any relation type
385− AtomFunction "add" [IntAtomType, IntAtomType, IntAtomType] (\(i1:i2:_) -> (\(IntAtom a) (IntAtom b) -> IntAtom (a + b)) i1 i2),
386− AtomFunction { atomFuncName = "id",
387− atomFuncType = [AnyAtomType],
388− atomFunc = (\(x:_) -> x)}
389−
390−-- AtomFunction "count" [RelationAtomType , IntAtom],
391−-- AtomFunction "sum" [RelationAtomType IntAtomType
392− ]
393−
394−atomFunctionForName :: AtomFunctionName -> AtomFunctions -> Either RelationalError AtomFunction
395−atomFunctionForName funcName funcSet = if HS.null foundFunc then
396− Left $ NoSuchTupleExprFunctionError funcName
397− else
398− Right $ head $ HS.toList foundFunc
399− where
400− foundFunc = HS.filter (\(AtomFunction name _ _) -> name == funcName) funcSet
382+evalAtomExpr :: RelationTuple -> DatabaseContext -> AtomExpr -> Either RelationalError Atom
383+evalAtomExpr tupIn _ (AttributeAtomExpr attrName) = atomForAttributeName attrName tupIn
384+evalAtomExpr _ _ (NakedAtomExpr atom) = Right atom
385+evalAtomExpr tupIn context (FunctionAtomExpr funcName arguments) = do
386+ let functions = atomFunctions context
387+ func <- atomFunctionForName funcName functions
388+ argTypes <- mapM (typeFromAtomExpr (tupleAttributes tupIn) context) arguments
389+ _ <- mapM (uncurry atomTypeVerify) $ init (zip (atomFuncType func) argTypes)
390+ evaldArgs <- mapM (evalAtomExpr tupIn context) arguments
391+ return $ (atomFunc func) evaldArgs
392+evalAtomExpr _ context (RelationAtomExpr relExpr) = do
393+ relAtom <- evalState (evalRelationalExpr relExpr) context
394+ return $ RelationAtom relAtom
401395
402396typeFromAtomExpr :: Attributes -> DatabaseContext -> AtomExpr -> Either RelationalError AtomType
403397typeFromAtomExpr attrs _ (AttributeAtomExpr attrName) = A.atomTypeForAttributeName attrName attrs
@@ -409,7 +403,6 @@ typeFromAtomExpr _ context (FunctionAtomExpr funcName _) = do
409403typeFromAtomExpr _ context (RelationAtomExpr relExpr) = do
410404 relType <- evalState (typeForRelationalExpr relExpr) context
411405 return $ RelationAtomType (attributes relType)
412−
413406
414407verifyAtomExprTypes :: Relation -> DatabaseContext -> AtomExpr -> AtomType -> Either RelationalError AtomType
415408verifyAtomExprTypes relIn _ (AttributeAtomExpr attrName) expectedType = do
@@ -433,27 +426,25 @@ verifyAtomExprTypes _ context (RelationAtomExpr relationExpr) expectedType = do
433426 case runState (typeForRelationalExpr relationExpr) context of
434427 (Left err, _) -> Left err
435428 (Right relType, _) -> atomTypeVerify expectedType (RelationAtomType (attributes relType))
436−
437−--determine if two types are equal or compatible
438−atomTypeVerify :: AtomType -> AtomType -> Either RelationalError AtomType
439−atomTypeVerify AnyAtomType x = Right x
440−atomTypeVerify x AnyAtomType = Right x
441−atomTypeVerify x y = if x == y then
442− Right x
443− else
444− Left $ AtomTypeMismatchError x y
445−
446−evalAtomExpr :: RelationTuple -> DatabaseContext -> AtomExpr -> Either RelationalError Atom
447−evalAtomExpr tupIn _ (AttributeAtomExpr attrName) = atomForAttributeName attrName tupIn
448−evalAtomExpr _ _ (NakedAtomExpr atom) = Right atom
449−evalAtomExpr tupIn context (FunctionAtomExpr funcName arguments) = do
450− let functions = atomFunctions context
451− func <- atomFunctionForName funcName functions
452− argTypes <- mapM (typeFromAtomExpr (tupleAttributes tupIn) context) arguments
453− _ <- mapM (uncurry atomTypeVerify) $ init (zip (atomFuncType func) argTypes)
454− evaldArgs <- mapM (evalAtomExpr tupIn context) arguments
455− return $ (atomFunc func) evaldArgs
456−evalAtomExpr _ context (RelationAtomExpr relExpr) = do
457− relAtom <- evalState (evalRelationalExpr relExpr) context
458− return $ RelationAtom relAtom
459−
429+
430+basicAtomFunctions :: AtomFunctions
431+basicAtomFunctions = HS.fromList [
432+ --match on any relation type
433+ AtomFunction "add" [IntAtomType, IntAtomType, IntAtomType] (\(i1:i2:_) -> (\(IntAtom a) (IntAtom b) -> IntAtom (a + b)) i1 i2),
434+ AtomFunction { atomFuncName = "id",
435+ atomFuncType = [AnyAtomType, AnyAtomType],
436+ atomFunc = (\(x:_) -> x)},
437+ AtomFunction { atomFuncName = "sum",
438+ atomFuncType = foldAtomFuncType IntAtomType IntAtomType,
439+ atomFunc = (\((RelationAtom relIn):_) -> relationSum relIn)},
440+ AtomFunction { atomFuncName = "count",
441+ atomFuncType = foldAtomFuncType AnyAtomType IntAtomType,
442+ atomFunc = (\((RelationAtom relIn):_) -> relationCount relIn)},
443+ AtomFunction { atomFuncName = "max",
444+ atomFuncType = foldAtomFuncType IntAtomType IntAtomType,
445+ atomFunc = (\((RelationAtom relIn):_) -> relationMax relIn)},
446+ AtomFunction { atomFuncName = "min",
447+ atomFuncType = foldAtomFuncType IntAtomType IntAtomType,
448+ atomFunc = (\((RelationAtom relIn):_) -> relationMin relIn)}
449+
450+ ]