Skip to content

Commit

Permalink
add template haskell parsers for RelationalExpr and DatabaseContextExpr
Browse files Browse the repository at this point in the history
resolves #288
  • Loading branch information
agentm committed Dec 6, 2021
1 parent 08bab65 commit a890f50
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 34 deletions.
10 changes: 6 additions & 4 deletions project-m36.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Flag haskell-scripting
Default: True

Library
Build-Depends: base>=4.8 && < 4.15, ghc-paths, mtl, containers, unordered-containers, hashable, haskeline, directory, MonadRandom, random-shuffle, uuid >= 1.3.12, cassava >= 0.4.5.1 && < 0.6, text, bytestring, deepseq, deepseq-generics, vector, parallel, monad-parallel, exceptions, transformers, gnuplot, filepath, zlib, directory, temporary, stm, time, hashable-time, old-locale, rset, attoparsec, either, base64-bytestring, data-interval, extended-reals, aeson >= 1.1, path-pieces, conduit, resourcet, http-api-data, semigroups, QuickCheck, quickcheck-instances, list-t, stm-containers >= 0.2.15, foldl, optparse-applicative, Glob, cryptohash-sha256, text-manipulate >= 0.2.0.1 && < 0.4, winery, curryer-rpc, network, async, vector-instances, recursion-schemes, streamly >= 0.7.2, convertible
Build-Depends: base>=4.8 && < 4.15, ghc-paths, mtl, containers, unordered-containers, hashable, haskeline, directory, MonadRandom, random-shuffle, uuid >= 1.3.12, cassava >= 0.4.5.1 && < 0.6, text, bytestring, deepseq, deepseq-generics, vector, parallel, monad-parallel, exceptions, transformers, gnuplot, filepath, zlib, directory, temporary, stm, time, hashable-time, old-locale, rset, attoparsec, either, base64-bytestring, data-interval, extended-reals, aeson >= 1.1, path-pieces, conduit, resourcet, http-api-data, semigroups, QuickCheck, quickcheck-instances, list-t, stm-containers >= 0.2.15, foldl, optparse-applicative, Glob, cryptohash-sha256, text-manipulate >= 0.2.0.1 && < 0.4, winery, curryer-rpc, network, async, vector-instances, recursion-schemes, streamly >= 0.7.2, convertible, template-haskell, th-lift-instances
if flag(haskell-scripting)
Build-Depends: ghc >= 8.2 && < 8.11
CPP-Options: -DPM36_HASKELL_SCRIPTING
Expand Down Expand Up @@ -192,7 +192,8 @@ Executable tutd
base16-bytestring >= 1.0.0.0,
http-conduit,
modern-uri,
http-types
http-types,
template-haskell
Other-Modules: TutorialD.Interpreter,
TutorialD.Interpreter.Base,
TutorialD.Interpreter.DatabaseContextExpr,
Expand All @@ -212,6 +213,7 @@ Executable tutd
TutorialD.Interpreter.TransGraphRelationalOperator,
TutorialD.Interpreter.SchemaOperator
TutorialD.Printer
TutorialD.Interpreter.TH
main-is: TutorialD/tutd.hs
CC-Options: -fPIC
if os(windows)
Expand Down Expand Up @@ -310,8 +312,8 @@ Test-Suite test-tutoriald
import: commontest
type: exitcode-stdio-1.0
main-is: TutorialD/InterpreterTest.hs
Other-Modules: TutorialD.Interpreter, TutorialD.Interpreter.Base, TutorialD.Interpreter.Export.Base, TutorialD.Interpreter.Export.CSV, TutorialD.Interpreter.Import.Base, TutorialD.Interpreter.Import.CSV, TutorialD.Interpreter.Import.TutorialD, TutorialD.Interpreter.RODatabaseContextOperator, TutorialD.Interpreter.RelationalExpr, TutorialD.Interpreter.TransactionGraphOperator, TutorialD.Interpreter.Types, TutorialD.Interpreter.DatabaseContextExpr, TutorialD.Interpreter.InformationOperator, TutorialD.Interpreter.Import.BasicExamples, TutorialD.Interpreter.DatabaseContextIOOperator, TutorialD.Interpreter.TestBase, TutorialD.Interpreter.TransGraphRelationalOperator, TutorialD.Interpreter.SchemaOperator, TutorialD.Printer
Build-Depends: base, HUnit, Cabal, containers, hashable, unordered-containers, mtl, vector, time, hashable-time, bytestring, uuid, stm, deepseq, deepseq-generics, parallel, cassava, attoparsec, gnuplot, directory, temporary, haskeline, megaparsec, text, base64-bytestring, data-interval, filepath, stm-containers, list-t, project-m36, random, MonadRandom, semigroups, parser-combinators, prettyprinter
Other-Modules: TutorialD.Interpreter, TutorialD.Interpreter.Base, TutorialD.Interpreter.Export.Base, TutorialD.Interpreter.Export.CSV, TutorialD.Interpreter.Import.Base, TutorialD.Interpreter.Import.CSV, TutorialD.Interpreter.Import.TutorialD, TutorialD.Interpreter.RODatabaseContextOperator, TutorialD.Interpreter.RelationalExpr, TutorialD.Interpreter.TransactionGraphOperator, TutorialD.Interpreter.Types, TutorialD.Interpreter.DatabaseContextExpr, TutorialD.Interpreter.InformationOperator, TutorialD.Interpreter.Import.BasicExamples, TutorialD.Interpreter.DatabaseContextIOOperator, TutorialD.Interpreter.TestBase, TutorialD.Interpreter.TransGraphRelationalOperator, TutorialD.Interpreter.SchemaOperator, TutorialD.Printer, TutorialD.Interpreter.TH
Build-Depends: base, HUnit, Cabal, containers, hashable, unordered-containers, mtl, vector, time, hashable-time, bytestring, uuid, stm, deepseq, deepseq-generics, parallel, cassava, attoparsec, gnuplot, directory, temporary, haskeline, megaparsec, text, base64-bytestring, data-interval, filepath, stm-containers, list-t, project-m36, random, MonadRandom, semigroups, parser-combinators, prettyprinter, template-haskell

Test-Suite test-tutoriald-atomfunctionscript
import: commontest
Expand Down
78 changes: 49 additions & 29 deletions src/lib/ProjectM36/Base.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{-# LANGUAGE ExistentialQuantification,DeriveGeneric,DeriveAnyClass,FlexibleInstances,OverloadedStrings, DeriveTraversable, DerivingVia, TemplateHaskell, TypeFamilies #-}
{-# LANGUAGE ExistentialQuantification,DeriveGeneric,DeriveAnyClass,FlexibleInstances,OverloadedStrings, DeriveTraversable, DerivingVia, TemplateHaskell, TypeFamilies, DeriveLift #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

module ProjectM36.Base where
Expand Down Expand Up @@ -26,6 +26,8 @@ import Data.Typeable
import Data.ByteString (ByteString)
import qualified Data.List.NonEmpty as NE
import Data.Vector.Instances ()
import Language.Haskell.TH.Syntax (Lift(..), Exp(..), mkName, unsafeTExpCoerce)
import Instances.TH.Lift ()

type StringType = Text

Expand Down Expand Up @@ -56,7 +58,24 @@ data Atom = IntegerAtom Integer |
RelationAtom Relation |
RelationalExprAtom RelationalExpr | --used for returning inc deps
ConstructedAtom DataConstructorName AtomType [Atom]
deriving (Eq, Show, Typeable, NFData, Generic, Read)
deriving (Eq, Show, Typeable, NFData, Generic, Read, Lift)

-- lift instances missing from th-lift-instances
instance Lift UTCTime where
lift (UTCTime x y) = do
x' <- lift x
y' <- lift y
return $ AppE (AppE (ConE (mkName "UTCTime")) x') y'
liftTyped = unsafeTExpCoerce . lift


instance Lift Day where
lift x = [|toEnum $(lift (fromEnum x))|]
liftTyped = unsafeTExpCoerce . lift

instance Lift DiffTime where
lift x = [|toEnum $(lift (fromEnum x))|]
liftTyped = unsafeTExpCoerce . lift

instance Hashable Atom where
hashWithSalt salt (ConstructedAtom dConsName _ atoms) = salt `hashWithSalt` atoms
Expand Down Expand Up @@ -89,7 +108,7 @@ data AtomType = IntAtomType |
RelationalExprAtomType |
TypeVariableType TypeVarName
--wildcard used in Atom Functions and tuples for data constructors which don't provide all arguments to the type constructor
deriving (Eq, NFData, Generic, Show, Read, Hashable)
deriving (Eq, NFData, Generic, Show, Read, Hashable, Lift)

instance Ord AtomType where
compare = undefined
Expand All @@ -106,7 +125,7 @@ isRelationAtomType _ = False
type AttributeName = StringType

-- | A relation's type is composed of attribute names and types.
data Attribute = Attribute AttributeName AtomType deriving (Eq, Show, Read, Generic, NFData)
data Attribute = Attribute AttributeName AtomType deriving (Eq, Show, Read, Generic, NFData, Lift)

instance Hashable Attribute where
hashWithSalt salt (Attribute attrName _) = hashWithSalt salt attrName
Expand All @@ -118,7 +137,7 @@ newtype Attributes = Attributes {
attributesVec :: V.Vector Attribute
--,attributesSet :: HS.HashSet Attribute --compare with this generated in heap profile and benchmarks
}
deriving (NFData, Read, Hashable, Generic)
deriving (NFData, Read, Hashable, Generic, Lift)

attributesSet :: Attributes -> HS.HashSet Attribute
attributesSet = HS.fromList . V.toList . attributesVec
Expand All @@ -136,7 +155,7 @@ sortedAttributesIndices :: Attributes -> [(Int, Attribute)]
sortedAttributesIndices attrs = L.sortBy (\(_, Attribute name1 _) (_,Attribute name2 _) -> compare name1 name2) $ V.toList (V.indexed (attributesVec attrs))

-- | The relation's tuple set is the body of the relation.
newtype RelationTupleSet = RelationTupleSet { asList :: [RelationTuple] } deriving (Hashable, Show, Generic, Read)
newtype RelationTupleSet = RelationTupleSet { asList :: [RelationTuple] } deriving (Hashable, Show, Generic, Read, Lift)

instance Read Relation where
readsPrec = error "relation read not supported"
Expand Down Expand Up @@ -164,7 +183,7 @@ instance Hashable RelationTuple where
sortedTupVec = V.map (\(index, _) -> tupVec V.! index) $ V.fromList sortedAttrsIndices

-- | A tuple is a set of attributes mapped to their 'Atom' values.
data RelationTuple = RelationTuple Attributes (V.Vector Atom) deriving (Show, Read, Generic)
data RelationTuple = RelationTuple Attributes (V.Vector Atom) deriving (Show, Read, Generic, Lift)

instance Eq RelationTuple where
tuple1@(RelationTuple attrs1 _) == tuple2@(RelationTuple attrs2 _) =
Expand All @@ -177,7 +196,7 @@ instance Eq RelationTuple where

instance NFData RelationTuple where rnf = genericRnf

data Relation = Relation Attributes RelationTupleSet deriving (Show, Generic,Typeable)
data Relation = Relation Attributes RelationTupleSet deriving (Show, Generic, Typeable, Lift)

instance Eq Relation where
Relation attrs1 tupSet1 == Relation attrs2 tupSet2 = attrs1 == attrs2 && tupSet1 == tupSet2
Expand Down Expand Up @@ -235,12 +254,12 @@ data RelationalExprBase a =
--Summarize :: AtomExpr -> AttributeName -> RelationalExpr -> RelationalExpr -> RelationalExpr -- a special case of Extend
--Evaluate relationalExpr with scoped views
With [(WithNameExprBase a, RelationalExprBase a)] (RelationalExprBase a)
deriving (Show, Read, Eq, Generic, NFData, Foldable, Functor, Traversable)
deriving (Show, Read, Eq, Generic, NFData, Foldable, Functor, Traversable, Lift)

instance Hashable RelationalExpr

data WithNameExprBase a = WithNameExpr RelVarName a
deriving (Show, Read, Eq, Generic, NFData, Foldable, Functor, Traversable, Hashable)
deriving (Show, Read, Eq, Generic, NFData, Foldable, Functor, Traversable, Hashable, Lift)

type WithNameExpr = WithNameExprBase ()

Expand All @@ -262,15 +281,15 @@ type TypeVarName = StringType
-- | Metadata definition for type constructors such as @data Either a b@.
data TypeConstructorDef = ADTypeConstructorDef TypeConstructorName [TypeVarName] |
PrimitiveTypeConstructorDef TypeConstructorName AtomType
deriving (Show, Generic, Eq, NFData, Hashable, Read)
deriving (Show, Generic, Eq, NFData, Hashable, Read, Lift)

-- | Found in data constructors and type declarations: Left (Either Int Text) | Right Int
type TypeConstructor = TypeConstructorBase ()
data TypeConstructorBase a = ADTypeConstructor TypeConstructorName [TypeConstructor] |
PrimitiveTypeConstructor TypeConstructorName AtomType |
RelationAtomTypeConstructor [AttributeExprBase a] |
TypeVariable TypeVarName
deriving (Show, Generic, Eq, NFData, Hashable, Read)
deriving (Show, Generic, Eq, NFData, Hashable, Read, Lift)

type TypeConstructorMapping = [(TypeConstructorDef, DataConstructorDefs)]

Expand All @@ -280,13 +299,13 @@ type DataConstructorName = StringType
type AtomTypeName = StringType

-- | Used to define a data constructor in a type constructor context such as @Left a | Right b@
data DataConstructorDef = DataConstructorDef DataConstructorName [DataConstructorDefArg] deriving (Eq, Show, Generic, NFData, Hashable, Read)
data DataConstructorDef = DataConstructorDef DataConstructorName [DataConstructorDefArg] deriving (Eq, Show, Generic, NFData, Hashable, Read, Lift)

type DataConstructorDefs = [DataConstructorDef]

data DataConstructorDefArg = DataConstructorDefTypeConstructorArg TypeConstructor |
DataConstructorDefTypeVarNameArg TypeVarName
deriving (Show, Generic, Eq, NFData, Hashable, Read)
deriving (Show, Generic, Eq, NFData, Hashable, Read, Lift)

type InclusionDependencies = M.Map IncDepName InclusionDependency
type RelationVariables = M.Map RelVarName GraphRefRelationalExpr
Expand Down Expand Up @@ -331,7 +350,7 @@ data DatabaseContext = DatabaseContext {
type IncDepName = StringType

-- | Inclusion dependencies represent every possible database constraint. Constraints enforce specific, arbitrarily-complex rules to which the database context's relation variables must adhere unconditionally.
data InclusionDependency = InclusionDependency RelationalExpr RelationalExpr deriving (Show, Eq, Generic, NFData, Hashable, Read)
data InclusionDependency = InclusionDependency RelationalExpr RelationalExpr deriving (Show, Eq, Generic, NFData, Hashable, Read, Lift)

type AttributeNameAtomExprMap = M.Map AttributeName AtomExpr

Expand Down Expand Up @@ -371,7 +390,7 @@ data DatabaseContextExprBase a =
ExecuteDatabaseContextFunction FunctionName [AtomExprBase a] |

MultipleExpr [DatabaseContextExprBase a]
deriving (Show, Read, Eq, Generic, NFData)
deriving (Show, Read, Eq, Generic, NFData, Lift)

type ObjModuleName = StringType
type ObjFunctionName = StringType
Expand Down Expand Up @@ -404,7 +423,7 @@ data RestrictionPredicateExprBase a =
RelationalExprPredicate (RelationalExprBase a) | --type must be same as true and false relations (no attributes)
AtomExprPredicate (AtomExprBase a) | --atom must evaluate to boolean
AttributeEqualityPredicate AttributeName (AtomExprBase a) -- relationalexpr must result in relation with single tuple
deriving (Show, Read, Eq, Generic, NFData, Foldable, Functor, Traversable)
deriving (Show, Read, Eq, Generic, NFData, Foldable, Functor, Traversable, Lift)

-- child + parent links
-- | A transaction graph's head name references the leaves of the transaction graph and can be used during session creation to indicate at which point in the graph commits should persist.
Expand Down Expand Up @@ -475,11 +494,11 @@ data AtomExprBase a = AttributeAtomExpr AttributeName |
FunctionAtomExpr FunctionName [AtomExprBase a] a |
RelationAtomExpr (RelationalExprBase a) |
ConstructedAtomExpr DataConstructorName [AtomExprBase a] a
deriving (Eq, Show, Read, Generic, NFData, Foldable, Functor, Traversable)
deriving (Eq, Show, Read, Generic, NFData, Foldable, Functor, Traversable, Lift)

-- | Used in tuple creation when creating a relation.
data ExtendTupleExprBase a = AttributeExtendTupleExpr AttributeName (AtomExprBase a)
deriving (Show, Read, Eq, Generic, NFData, Foldable, Functor, Traversable)
deriving (Show, Read, Eq, Generic, NFData, Foldable, Functor, Traversable, Lift)

type ExtendTupleExpr = ExtendTupleExprBase ()

Expand All @@ -504,7 +523,7 @@ data AttributeNamesBase a = AttributeNames (S.Set AttributeName) |
UnionAttributeNames (AttributeNamesBase a) (AttributeNamesBase a) |
IntersectAttributeNames (AttributeNamesBase a) (AttributeNamesBase a) |
RelationalExprAttributeNames (RelationalExprBase a) -- use attribute names from the relational expression's type
deriving (Eq, Show, Read, Generic, NFData, Foldable, Functor, Traversable)
deriving (Eq, Show, Read, Generic, NFData, Foldable, Functor, Traversable, Lift)

type AttributeNames = AttributeNamesBase ()

Expand All @@ -529,11 +548,11 @@ type GraphRefAttributeExpr = AttributeExprBase GraphRefTransactionMarker
-- | Create attributes dynamically.
data AttributeExprBase a = AttributeAndTypeNameExpr AttributeName TypeConstructor a |
NakedAttributeExpr Attribute
deriving (Eq, Show, Read, Generic, NFData, Foldable, Functor, Traversable, Hashable)
deriving (Eq, Show, Read, Generic, NFData, Foldable, Functor, Traversable, Hashable, Lift)

-- | Dynamically create a tuple from attribute names and 'AtomExpr's.
newtype TupleExprBase a = TupleExpr (M.Map AttributeName (AtomExprBase a))
deriving (Eq, Show, Read, Generic, NFData, Foldable, Functor, Traversable)
deriving (Eq, Show, Read, Generic, NFData, Foldable, Functor, Traversable, Lift)

instance Hashable TupleExpr

Expand All @@ -542,7 +561,7 @@ type TupleExpr = TupleExprBase ()
type GraphRefTupleExpr = TupleExprBase GraphRefTransactionMarker

data TupleExprsBase a = TupleExprs a [TupleExprBase a]
deriving (Eq, Show, Read, Generic, NFData, Foldable, Functor, Traversable)
deriving (Eq, Show, Read, Generic, NFData, Foldable, Functor, Traversable, Lift)

instance Hashable TupleExprs

Expand Down Expand Up @@ -579,19 +598,20 @@ instance Eq (Function a) where
f1 == f2 = funcName f1 == funcName f2

instance Hashable (Function a) where
hashWithSalt salt func = salt `hashWithSalt` funcName func `hashWithSalt` funcType func `hashWithSalt` funcBody func
hashWithSalt salt func = salt `hashWithSalt` funcName func `hashWithSalt` funcType func `hashWithSalt` hashfuncbody
where
hashfuncbody =
case funcBody func of
(FunctionScriptBody script _) -> salt `hashWithSalt` script
(FunctionBuiltInBody _) -> salt
(FunctionObjectLoadedBody fp modName entryFunc _) -> salt `hashWithSalt` (fp, modName, entryFunc)

data FunctionBody a =
FunctionScriptBody FunctionBodyScript a |
FunctionBuiltInBody a |
FunctionObjectLoadedBody FilePath ObjectModuleName ObjectFileEntryFunctionName a
deriving Generic

instance Hashable (FunctionBody a) where
salt `hashWithSalt` (FunctionScriptBody script _) = salt `hashWithSalt` script
salt `hashWithSalt` (FunctionBuiltInBody _) = salt
salt `hashWithSalt` (FunctionObjectLoadedBody fp modName entryFunc _) = salt `hashWithSalt` (fp, modName, entryFunc)

instance NFData a => NFData (FunctionBody a) where
rnf (FunctionScriptBody script _) = rnf script
rnf (FunctionBuiltInBody _) = rnf ()
Expand Down
Loading

0 comments on commit a890f50

Please sign in to comment.