on 18f736a help sign in
91 lines 4.4 kB history raw
1module ProjectM36.AtomFunctions.Primitive where
2import ProjectM36.Base
3import ProjectM36.Relation (relFold, oneTuple)
4import ProjectM36.Tuple
5import ProjectM36.AtomFunctionError
6import ProjectM36.AtomFunction
7import qualified Data.HashSet as HS
8import qualified Data.Vector as V
9import Control.Monad
11primitiveAtomFunctions :: AtomFunctions
12primitiveAtomFunctions = HS.fromList [
13 --match on any relation type
14 AtomFunction { atomFuncName = "add",
15 atomFuncType = [IntegerAtomType, IntegerAtomType, IntegerAtomType],
16 atomFuncBody = body (\(IntegerAtom i1:IntegerAtom i2:_) -> pure (IntegerAtom (i1 + i2)))},
17 AtomFunction { atomFuncName = "id",
18 atomFuncType = [TypeVariableType "a", TypeVariableType "a"],
19 atomFuncBody = body (\(x:_) -> pure x)},
20 AtomFunction { atomFuncName = "sum",
21 atomFuncType = foldAtomFuncType IntegerAtomType IntegerAtomType,
22 atomFuncBody = body (\(RelationAtom rel:_) -> relationSum rel)},
23 AtomFunction { atomFuncName = "count",
24 atomFuncType = foldAtomFuncType (TypeVariableType "a") IntegerAtomType,
25 atomFuncBody = body (\(RelationAtom relIn:_) -> relationCount relIn)},
26 AtomFunction { atomFuncName = "max",
27 atomFuncType = foldAtomFuncType IntegerAtomType IntegerAtomType,
28 atomFuncBody = body (\(RelationAtom relIn:_) -> relationMax relIn)},
29 AtomFunction { atomFuncName = "min",
30 atomFuncType = foldAtomFuncType IntegerAtomType IntegerAtomType,
31 atomFuncBody = body (\(RelationAtom relIn:_) -> relationMin relIn)},
32 AtomFunction { atomFuncName = "lt",
33 atomFuncType = [IntegerAtomType, IntegerAtomType, BoolAtomType],
34 atomFuncBody = body $ integerAtomFuncLessThan False},
35 AtomFunction { atomFuncName = "lte",
36 atomFuncType = [IntegerAtomType, IntegerAtomType, BoolAtomType],
37 atomFuncBody = body $ integerAtomFuncLessThan True},
38 AtomFunction { atomFuncName = "gte",
39 atomFuncType = [IntegerAtomType, IntegerAtomType, BoolAtomType],
40 atomFuncBody = body $ integerAtomFuncLessThan False >=> boolAtomNot},
41 AtomFunction { atomFuncName = "gt",
42 atomFuncType = [IntegerAtomType, IntegerAtomType, BoolAtomType],
43 atomFuncBody = body $ integerAtomFuncLessThan True >=> boolAtomNot},
44 AtomFunction { atomFuncName = "not",
45 atomFuncType = [BoolAtomType, BoolAtomType],
46 atomFuncBody = body $ \(b:_) -> boolAtomNot b }
47 ]
48 where
49 body = AtomFunctionBody Nothing
51integerAtomFuncLessThan :: Bool -> [Atom] -> Either AtomFunctionError Atom
52integerAtomFuncLessThan equality (IntegerAtom i1:IntegerAtom i2:_) = pure (BoolAtom (i1 `op` i2))
53 where
54 op = if equality then (<=) else (<)
55integerAtomFuncLessThan _ _= pure (BoolAtom False)
57boolAtomNot :: Atom -> Either AtomFunctionError Atom
58boolAtomNot (BoolAtom b) = pure (BoolAtom (not b))
59boolAtomNot _ = error "boolAtomNot called on non-Bool atom"
61--used by sum atom function
62relationSum :: Relation -> Either AtomFunctionError Atom
63relationSum relIn = pure (IntegerAtom (relFold (\tupIn acc -> acc + newVal tupIn) 0 relIn))
64 where
65 --extract Integer from Atom
66 newVal tupIn = castInteger (tupleAtoms tupIn V.! 0)
68relationCount :: Relation -> Either AtomFunctionError Atom
69relationCount relIn = pure (IntegerAtom (relFold (\_ acc -> acc + 1) (0::Integer) relIn))
71relationMax :: Relation -> Either AtomFunctionError Atom
72relationMax relIn = case oneTuple relIn of
73 Nothing -> Left AtomFunctionEmptyRelationError
74 Just oneTup -> pure (IntegerAtom (relFold (\tupIn acc -> max acc (newVal tupIn)) (newVal oneTup) relIn))
75 where
76 newVal tupIn = castInteger (tupleAtoms tupIn V.! 0)
78relationMin :: Relation -> Either AtomFunctionError Atom
79relationMin relIn = case oneTuple relIn of
80 Nothing -> Left AtomFunctionEmptyRelationError
81 Just oneTup -> pure (IntegerAtom (relFold (\tupIn acc -> min acc (newVal tupIn)) (newVal oneTup) relIn))
82 where
83 newVal tupIn = castInteger (tupleAtoms tupIn V.! 0)
85castInt :: Atom -> Int
86castInt (IntAtom i) = i
87castInt _ = error "attempted to cast non-IntAtom to Int"
89castInteger :: Atom -> Integer
90castInteger (IntegerAtom i) = i
91castInteger _ = error "attempted to cast non-IntegerAtom to Int"