on master help sign in
compilation checkpoint for new functional dependency generator
commit6560e46e8508cf88466d3b2bd4fb5fb5be9e9728 authorAgentM <agentm@themactionfaction.com> dateTue 29 Nov 2016, 15:26 (10 years ago) parent3e0d0c1
6 files changed+52−9
project-m36.cabal+1 src/bin/TutorialD/Interpreter/DatabaseContextExpr.hs+16 src/lib/ProjectM36/AttributeNames.hs+11−7 src/lib/ProjectM36/Base.hs+2−1 src/lib/ProjectM36/FunctionalDependency.hs+19 src/lib/ProjectM36/StaticOptimizer.hs+3−1
project-m36.cabal+1
@@ -85,6 +85,7 @@ Library
8585 ProjectM36.Atom,
8686 ProjectM36.AtomFunction,
8787 ProjectM36.Key,
88+ ProjectM36.FunctionalDependency,
8889 ProjectM36.DatabaseContext,
8990 ProjectM36.DateExamples,
9091 ProjectM36.DisconnectedTransaction,
src/bin/TutorialD/Interpreter/DatabaseContextExpr.hs+16
@@ -13,6 +13,7 @@ import qualified ProjectM36.Error as PM36E
1313import ProjectM36.Error
1414import ProjectM36.RelationalExpression
1515import ProjectM36.Key
16+import ProjectM36.FunctionalDependency
1617import Data.Monoid
1718
1819--parsers which create "database expressions" which modify the database context (such as relvar assignment)
@@ -23,6 +24,7 @@ databaseContextExprP = choice [insertP,
2324 updateP,
2425 addConstraintP,
2526 keyP,
27+ funcDepP,
2628 defineP,
2729 undefineP,
2830 assignP,
@@ -121,6 +123,20 @@ keyP = do
121123 let newIncDep = inclusionDependencyForKey uniquenessAttrNames uniquenessExpr
122124 pure $ AddInclusionDependency keyName newIncDep
123125
126+funcDepP :: Parser DatabaseContextExpr
127+funcDepP = do
128+ reserved "funcdep"
129+ keyName <- identifier
130+ source <- parens attributeListP
131+ dependents <- parens attributeListP
132+ expr <- relExprP
133+ let newIncDeps = inclusionDependenciesForFunctionalDependency funcDep
134+ funcDep = FunctionalDependency source dependents expr
135+ nameA = keyName <> "_A"
136+ nameB = keyName <> "_B"
137+ pure (MultipleExpr [AddInclusionDependency nameA (fst newIncDeps),
138+ AddInclusionDependency nameB (snd newIncDeps)])
139+
124140attributeAssignmentP :: Parser (AttributeName, AtomExpr)
125141attributeAssignmentP = do
126142 attrName <- identifier
src/lib/ProjectM36/AttributeNames.hs+11−7
@@ -8,6 +8,9 @@ import qualified Data.Set as S
88empty :: AttributeNames
99empty = AttributeNames S.empty
1010
11+all :: AttributeNames
12+all = InvertedAttributeNames S.empty
13+
1114--check that the attribute names are actually in the attributes
1215projectionAttributesForAttributeNames :: Attributes -> AttributeNames -> Either RelationalError Attributes
1316projectionAttributesForAttributeNames attrs (AttributeNames attrNameSet) = do
@@ -21,12 +24,13 @@ projectionAttributesForAttributeNames attrs (InvertedAttributeNames unselectedAt
2124 if not $ S.null nonExistentAttributeNames then
2225 Left $ AttributeNamesMismatchError nonExistentAttributeNames
2326 else
24− return $ A.attributesForNames (A.nonMatchingAttributeNameSet unselectedAttrNameSet (A.attributeNameSet attrs)) attrs
25−
26−attributeNameSet :: AttributeNames -> S.Set AttributeName
27−attributeNameSet (AttributeNames nameSet) = nameSet
28−attributeNameSet (InvertedAttributeNames nameSet) = nameSet
29−
27+ return $ A.attributesForNames (A.nonMatchingAttributeNameSet unselectedAttrNameSet (A.attributeNameSet attrs)) attrs
28+projectionAttributesForAttributeNames attrs (UnionAttributeNames namesA namesB) = do
29+ attrsA <- projectionAttributesForAttributeNames attrs namesA
30+ attrsB <- projectionAttributesForAttributeNames attrs namesB
31+ pure (A.union attrsA attrsB)
32+
3033invertAttributeNames :: AttributeNames -> AttributeNames
3134invertAttributeNames (AttributeNames names) = InvertedAttributeNames names
32−invertAttributeNames (InvertedAttributeNames names) = AttributeNames names
35+invertAttributeNames (InvertedAttributeNames names) = AttributeNames names
36+invertAttributeNames (UnionAttributeNames namesA namesB) = UnionAttributeNames (invertAttributeNames namesA) (invertAttributeNames namesB)
src/lib/ProjectM36/Base.hs+2−1
@@ -453,7 +453,8 @@ instance Show AtomFunction where
453453
454454-- | The 'AttributeNames' structure represents a set of attribute names or the same set of names but inverted in the context of a relational expression. For example, if a relational expression has attributes named "a", "b", and "c", the 'InvertedAttributeNames' of ("a","c") is ("b").
455455data AttributeNames = AttributeNames (S.Set AttributeName) |
456− InvertedAttributeNames (S.Set AttributeName)
456+ InvertedAttributeNames (S.Set AttributeName) |
457+ UnionAttributeNames AttributeNames AttributeNames
457458 deriving (Eq, Show, Generic)
458459
459460instance Binary AttributeNames
src/lib/ProjectM36/FunctionalDependency.hsnew file+19
@@ -0,0 +1,19 @@
1+module ProjectM36.FunctionalDependency where
2+import ProjectM36.Base
3+import qualified Data.Set as S
4+
5+data FunctionalDependency = FunctionalDependency AttributeNames AttributeNames RelationalExpr
6+
7+--(s{city} group ({city} as x) : {z:=count(@x)}) {z}
8+-- as defined in Relational Algebra and All That Jazz page 21
9+inclusionDependenciesForFunctionalDependency :: FunctionalDependency -> (InclusionDependency, InclusionDependency)
10+inclusionDependenciesForFunctionalDependency (FunctionalDependency attrNamesSource attrNamesDependent relExpr) = (InclusionDependency countSource countDep,
11+ InclusionDependency countDep countSource)
12+ where
13+ countSource = relExprCount relExpr attrNamesSource
14+ countDep = relExprCount relExpr (UnionAttributeNames attrNamesSource attrNamesDependent)
15+ projectZName = Project (AttributeNames (S.singleton "z"))
16+ zCount = FunctionAtomExpr "count" [AttributeAtomExpr "x"] ()
17+ extendZName = Extend (AttributeExtendTupleExpr "z" zCount)
18+ relExprCount expr projectionAttrNames = projectZName (extendZName
19+ (Group projectionAttrNames "x" (Project projectionAttrNames expr)))
src/lib/ProjectM36/StaticOptimizer.hs+3−1
@@ -26,7 +26,9 @@ applyStaticRelationalOptimization (Project attrNameSet expr) = do
2626 relType <- typeForRelationalExpr expr
2727 case relType of
2828 Left err -> return $ Left err
29− Right relType2 -> if attributeNames relType2 == AS.attributeNameSet attrNameSet then
29+ Right relType2 -> if AS.all == attrNameSet then
30+ applyStaticRelationalOptimization expr
31+ else if AttributeNames (attributeNames relType2) == attrNameSet then
3032 applyStaticRelationalOptimization expr
3133 else do
3234 optimizedSubExpression <- applyStaticRelationalOptimization expr