1module ProjectM36.AtomFunctions.Primitive where
3import ProjectM36.Relation (relFold, oneTuple)
5import ProjectM36.AtomFunctionError
6import ProjectM36.AtomFunction
7import qualified Data.HashSet as HS
8import qualified Data.Vector as V
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 AtomFunction { atomFuncName = "int",
48 atomFuncType = [IntegerAtomType, IntAtomType],
49 atomFuncBody = body $ \(IntegerAtom v:_) -> if v < fromIntegral (maxBound :: Int) then
50 pure (IntAtom (fromIntegral v))
52 Left InvalidIntBoundError
57 body = AtomFunctionBody Nothing
59integerAtomFuncLessThan :: Bool -> [Atom] -> Either AtomFunctionError Atom
60integerAtomFuncLessThan equality (IntegerAtom i1:IntegerAtom i2:_) = pure (BoolAtom (i1 `op` i2))
62 op = if equality then (<=) else (<)
63integerAtomFuncLessThan _ _= pure (BoolAtom False)
65boolAtomNot :: Atom -> Either AtomFunctionError Atom
66boolAtomNot (BoolAtom b) = pure (BoolAtom (not b))
67boolAtomNot _ = error "boolAtomNot called on non-Bool atom"
69--used by sum atom function
70relationSum :: Relation -> Either AtomFunctionError Atom
71relationSum relIn = pure (IntegerAtom (relFold (\tupIn acc -> acc + newVal tupIn) 0 relIn))
73 --extract Integer from Atom
74 newVal tupIn = castInteger (tupleAtoms tupIn V.! 0)
76relationCount :: Relation -> Either AtomFunctionError Atom
77relationCount relIn = pure (IntegerAtom (relFold (\_ acc -> acc + 1) (0::Integer) relIn))
79relationMax :: Relation -> Either AtomFunctionError Atom
80relationMax relIn = case oneTuple relIn of
81 Nothing -> Left AtomFunctionEmptyRelationError
82 Just oneTup -> pure (IntegerAtom (relFold (\tupIn acc -> max acc (newVal tupIn)) (newVal oneTup) relIn))
84 newVal tupIn = castInteger (tupleAtoms tupIn V.! 0)
86relationMin :: Relation -> Either AtomFunctionError Atom
87relationMin relIn = case oneTuple relIn of
88 Nothing -> Left AtomFunctionEmptyRelationError
89 Just oneTup -> pure (IntegerAtom (relFold (\tupIn acc -> min acc (newVal tupIn)) (newVal oneTup) relIn))
91 newVal tupIn = castInteger (tupleAtoms tupIn V.! 0)
94castInt (IntAtom i) = i
95castInt _ = error "attempted to cast non-IntAtom to Int"
97castInteger :: Atom -> Integer
98castInteger (IntegerAtom i) = i
99castInteger _ = error "attempted to cast non-IntegerAtom to Int"
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list