on master help sign in
add arbitrary ConstructedAtomType
commit827ba56d3326ce21169e1b633427a85d9ddaa5d4 authorJohnny Liao <dycan0716@gmail.com> dateTue 29 May 2018, 18:30 (8 years ago) parent8911ef7
4 files changed+148−96
project-m36.cabal+2−2 src/lib/ProjectM36/Arbitrary.hs+135 src/lib/ProjectM36/Base.hs+2−90 src/lib/ProjectM36/RelationalExpression.hs+9−4
project-m36.cabal+2−2
@@ -73,7 +73,6 @@ Library
7373 ,http-api-data
7474 -- used for arbitrary tuples
7575 ,QuickCheck
76− ,quickcheck-arbitrary-adt
7776--needed for remote access
7877 ,distributed-process-client-server >= 0.2.3
7978 ,distributed-process >= 0.6.6
@@ -155,7 +154,8 @@ Library
155154 ProjectM36.TypeConstructor,
156155 ProjectM36.TypeConstructorDef,
157156 ProjectM36.FileLock,
158− ProjectM36.FSType
157+ ProjectM36.FSType,
158+ ProjectM36.Arbitrary
159159 GHC-Options: -Wall -rdynamic
160160 if os(windows)
161161 Build-Depends: Win32 >= 2.3
src/lib/ProjectM36/Arbitrary.hsnew file+135
@@ -0,0 +1,135 @@
1+{-# LANGUAGE ExistentialQuantification,DeriveGeneric,DeriveAnyClass,TypeSynonymInstances,FlexibleInstances,OverloadedStrings #-}
2+{-# OPTIONS_GHC -fno-warn-orphans #-}
3+
4+module ProjectM36.Arbitrary where
5+import ProjectM36.Base
6+import ProjectM36.Error
7+import ProjectM36.AtomType
8+import ProjectM36.Attribute (atomType)
9+import ProjectM36.DataConstructorDef as DCD
10+import qualified Data.Map as M
11+import qualified Data.Set as S
12+import qualified Data.Vector as V
13+import qualified Data.List as L
14+import Data.Text (Text,unpack,pack)
15+import Test.QuickCheck
16+import Test.QuickCheck.Gen
17+import Test.QuickCheck.Random
18+import Test.QuickCheck.Arbitrary
19+import qualified Data.ByteString.Char8 as B
20+import Data.Time
21+import Data.Time.Clock
22+import Debug.Trace
23+import Control.Monad.Reader
24+import Data.Either
25+import Data.Either.Combinators
26+
27+arbitrary' :: AtomType -> WithTCMap Gen (Either RelationalError Atom)
28+arbitrary' IntegerAtomType = do
29+ i <- lift (arbitrary :: Gen Integer)
30+ pure $ Right $ IntegerAtom i
31+
32+arbitrary' (RelationAtomType attrs) = do
33+ tcMap <-ask
34+ maybeRel <- lift $ runReaderT (arbitraryRelation attrs (0,5)) tcMap
35+ case maybeRel of
36+ Left err -> pure $ Left err
37+ Right rel -> pure $ Right $ RelationAtom rel
38+
39+arbitrary' IntAtomType = do
40+ i <- lift (arbitrary :: Gen Int)
41+ pure $ Right $ IntAtom i
42+
43+arbitrary' DoubleAtomType = do
44+ i <- lift (arbitrary :: Gen Double)
45+ pure $ Right $ DoubleAtom i
46+
47+arbitrary' TextAtomType = do
48+ i <- lift (arbitrary :: Gen Text)
49+ pure $ Right $ TextAtom i
50+
51+arbitrary' DayAtomType = do
52+ i <- lift (arbitrary :: Gen Day)
53+ pure $ Right $ DayAtom i
54+
55+arbitrary' DateTimeAtomType = do
56+ i <- lift (arbitrary :: Gen UTCTime)
57+ pure $ Right $ DateTimeAtom i
58+
59+arbitrary' BoolAtomType = do
60+ i <- lift (arbitrary :: Gen Bool)
61+ pure $ Right $ BoolAtom i
62+
63+arbitrary' (IntervalAtomType atomTy) = do
64+ tcMap <- ask
65+ eitherAtomType <- lift $ runReaderT (arbitrary' atomTy) tcMap
66+ case eitherAtomType of
67+ Left err -> pure $ Left err
68+ Right atomType -> do
69+ a <- lift $ (arbitrary :: Gen Bool)
70+ b <- lift $ (arbitrary :: Gen Bool)
71+ pure $ Right $ IntervalAtom atomType atomType a b
72+
73+arbitrary' constructedAtomType@(ConstructedAtomType tcName tvMap) = do
74+ tcMap <- ask
75+ let maybeTCons = findTypeConstructor tcName tcMap
76+ let eitherTCons = maybeToRight (NoSuchTypeConstructorName tcName) maybeTCons
77+ let eitherDCDefs = snd <$> eitherTCons
78+ let eitherGenDCDef = elements <$> eitherDCDefs
79+ case eitherGenDCDef of
80+ Left err -> pure $ Left err
81+ Right genDCDef -> do
82+ dcDef <- lift $ genDCDef
83+ case resolvedAtomTypesForDataConstructorDefArgs tcMap tvMap dcDef of
84+ Left err -> pure $ Left err
85+ Right atomTypes -> do
86+ let genListOfEitherAtom = mapM (\aTy->runReaderT (arbitrary' aTy) tcMap) atomTypes
87+ listOfEitherAtom <- lift genListOfEitherAtom
88+ let eitherListOfAtom = sequence listOfEitherAtom
89+ case eitherListOfAtom of
90+ Left err -> pure $ Left err
91+ Right listOfAtom -> pure $ Right $ ConstructedAtom (DCD.name dcDef) constructedAtomType listOfAtom
92+arbitrary' (TypeVariableType tvName) = undefined
93+
94+maybeToRight :: b -> Maybe a -> Either b a
95+maybeToRight _ (Just x) = Right x
96+maybeToRight y Nothing = Left y
97+
98+instance Arbitrary Text where
99+ arbitrary = pack <$> elements ["Mary", "Johnny", "Sunny", "Ted"]
100+
101+instance Arbitrary Day where
102+ arbitrary = ModifiedJulianDay <$> (arbitrary :: Gen Integer)
103+
104+instance Arbitrary UTCTime where
105+ arbitrary = UTCTime <$> arbitrary <*> (secondsToDiffTime <$> choose(0,86400))
106+
107+instance Arbitrary B.ByteString where
108+ arbitrary = B.pack <$> (arbitrary :: Gen String)
109+
110+arbitraryRelationTuple :: Attributes -> WithTCMap Gen (Either RelationalError RelationTuple)
111+arbitraryRelationTuple attris = do
112+ tcMap <- ask
113+ listOfMaybeAType <- lift $ sequence $ map ((\aTy -> runReaderT (arbitrary' aTy) tcMap) . atomType) (V.toList attris)
114+ case sequence listOfMaybeAType of
115+ Left err -> pure $ Left err
116+ Right listOfAttr -> do
117+ let vectorOfAttr = V.fromList listOfAttr
118+ pure $ Right $ RelationTuple attris vectorOfAttr
119+
120+arbitraryWithRange :: Gen (Either RelationalError RelationTuple) -> Range -> Gen [Either RelationalError RelationTuple]
121+arbitraryWithRange genEitherTuple range = do
122+ num <- choose range
123+ vectorOf num genEitherTuple
124+
125+arbitraryRelation :: Attributes -> Range -> WithTCMap Gen (Either RelationalError Relation)
126+arbitraryRelation attris range = do
127+ tcMap <- ask
128+ let genEitherTuple = runReaderT (arbitraryRelationTuple attris) tcMap
129+ listOfEitherTuple <- lift $ arbitraryWithRange genEitherTuple range
130+ let eitherTupleList = sequence listOfEitherTuple
131+ case eitherTupleList of
132+ Left err -> pure $ Left err
133+ Right tupleList -> pure $ Right $ Relation attris $ RelationTupleSet tupleList
134+
135+type WithTCMap a = ReaderT TypeConstructorMapping a
src/lib/ProjectM36/Base.hs+2−90
@@ -15,7 +15,7 @@ import Control.DeepSeq.Generics (genericRnf)
1515import GHC.Generics (Generic)
1616import qualified Data.Vector as V
1717import qualified Data.List as L
18−import Data.Text (Text,unpack,pack)
18+import Data.Text (Text,unpack)
1919import Data.Binary
2020import Data.Vector.Binary()
2121import Data.Time.Clock
@@ -24,15 +24,6 @@ import Data.Time.Calendar (Day,toGregorian,fromGregorian)
2424import Data.Hashable.Time ()
2525import Data.Typeable
2626import Data.ByteString (ByteString)
27−--for generating arbitrary tuples
28−import Test.QuickCheck
29−import Test.QuickCheck.Gen
30−import Test.QuickCheck.Random
31−import Test.QuickCheck.Arbitrary.ADT
32−import qualified Data.ByteString.Char8 as B
33−import Data.Time
34−import Data.Time.Clock
35−
3627type StringType = Text
3728
3829-- | Database atoms are the smallest, undecomposable units of a tuple. Common examples are integers, text, or unique identity keys.
@@ -579,83 +570,4 @@ atomTypeVars (RelationAtomType attrs) = S.unions (map attrTypeVars (V.toList att
579570atomTypeVars (ConstructedAtomType _ tvMap) = M.keysSet tvMap
580571atomTypeVars (TypeVariableType nam) = S.singleton nam
581572
582−-- for creating arbitrary relations
583−
584−arbitrary' :: AtomType -> Gen Atom
585−arbitrary' IntegerAtomType = IntegerAtom <$> (arbitrary :: Gen Integer)
586−arbitrary' IntAtomType = IntAtom <$> (arbitrary :: Gen Int)
587−arbitrary' DoubleAtomType = DoubleAtom <$> (arbitrary :: Gen Double)
588−arbitrary' TextAtomType = TextAtom <$> (arbitrary :: Gen Text)
589−arbitrary' DayAtomType = DayAtom <$> (arbitrary :: Gen Day)
590−arbitrary' DateTimeAtomType = DateTimeAtom <$> (arbitrary :: Gen UTCTime)
591−arbitrary' BoolAtomType = BoolAtom <$> (arbitrary :: Gen Bool)
592−arbitrary' (IntervalAtomType atomTy) = IntervalAtom <$> (arbitrary' atomTy) <*> (arbitrary' atomTy) <*> arbitrary <*> arbitrary
593−arbitrary' (RelationAtomType attrs) = arbitraryRel attrs (0,10)
594−arbitrary' (ConstructedAtomType tcname tvmap) = undefined -- ConstructedAtom DataConstructorName AtomType [Atom]
595−--arbitrary' (ConstructedAtomType tcname tvmap) = do
596−arbitrary' (TypeVariableType tvname) = undefined
597−
598−instance Arbitrary Text where
599− arbitrary = pack <$> elements ["Mary", "Johnny", "Sunny", "Ted"]
600−
601−instance Arbitrary Day where
602− arbitrary = ModifiedJulianDay <$> (arbitrary :: Gen Integer)
603−
604−instance Arbitrary Attribute where
605− arbitrary = genericArbitrary
606−
607−instance (Arbitrary a) => Arbitrary (V.Vector a) where
608− arbitrary = do
609− maxbound <- choose (0,5)
610− V.fromList <$> vectorOf maxbound arbitrary
611−
612−--not sure what's use on this one
613−instance {-# OVERLAPPING #-} Arbitrary TypeVarMap where
614− arbitrary = undefined
615−
616−instance Arbitrary UTCTime where
617− arbitrary = UTCTime <$> arbitrary <*> (secondsToDiffTime <$> choose(0,86400))
618−
619−instance Arbitrary B.ByteString where
620− arbitrary = B.pack <$> (arbitrary :: Gen String)
621−
622−defAttributeNames = ["Number","People","Time","Thing"]
623−defAtomtypes = [IntAtomType, TextAtomType, DayAtomType, TextAtomType]
624−defAttributes = V.fromList $ zipWith Attribute defAttributeNames defAtomtypes
625−
626−{-
627−instance Arbitrary RelationTuple where
628− arbitrary = do
629− a <- IntAtom <$> (arbitrary :: Gen Int)
630− b <- TextAtom <$> (arbitrary :: Gen Text)
631− c <- DayAtom <$> (arbitrary :: Gen Day)
632− d <- TextAtom <$> (arbitrary :: Gen Text)
633− let sample = V.fromList [a,b,c,d]
634− return $ RelationTuple defAttributes sample
635−
636−instance Arbitrary Relation where
637− arbitrary = do
638− list <- listOf (arbitrary :: Gen RelationTuple)
639− return $ Relation defAttributes (RelationTupleSet list)
640−-}
641−
642−arbitraryRelationTuple attris = do
643− let attrisG = V.fromList <$> mapM (arbitrary' . atomType') (V.toList attris)
644− RelationTuple attris <$> attrisG
645−
646−arbitraryRel attris range@(min,max) = do
647− num <- choose (min,max)
648− let tupleListG = vectorOf num (arbitraryRelationTuple attris)
649− Relation attris <$> (RelationTupleSet <$> tupleListG)
650−
651−instance Arbitrary AtomType where
652− arbitrary = genericArbitrary
653−
654−instance Arbitrary Atom where
655− arbitrary = genericArbitrary
656−
657−instance ToADTArbitrary Atom
658−
659−atomType' :: Attribute -> AtomType
660−atomType' (Attribute _ atype) = atype
661−>>>>>>> feature/arbitrary_tupleset-deprecated
573+
src/lib/ProjectM36/RelationalExpression.hs+9−4
@@ -11,6 +11,7 @@ import ProjectM36.ScriptSession
1111import ProjectM36.DataTypes.Primitive
1212import ProjectM36.AtomFunction
1313import ProjectM36.DatabaseContextFunction
14+import ProjectM36.Arbitrary
1415import qualified ProjectM36.Attribute as A
1516import qualified Data.Map as M
1617import qualified Data.HashSet as HS
@@ -595,10 +596,14 @@ evalDatabaseContextIOExpr _ currentContext (CreateArbitraryRelation relVarName a
595596 Nothing -> pure $ Left (RelVarNotDefinedError relVarName)
596597 Just existingRel -> do
597598 let expectedAttributes = attributes existingRel
598− rel <- generate $ arbitraryRel expectedAttributes range
599− case runState (setRelVar relVarName rel) elems of
600− (Left err,_) -> pure (Left err)
601− (Right (), (ctx',_,_)) -> pure $ Right ctx'
599+ let tcMap = typeConstructorMapping ctx
600+ eitherRel <- generate $ runReaderT (arbitraryRelation expectedAttributes range) tcMap
601+ case eitherRel of
602+ Left err -> pure $ Left err
603+ Right rel -> do
604+ case runState (setRelVar relVarName rel) elems of
605+ (Left err,_) -> pure (Left err)
606+ (Right (), (ctx',_,_)) -> pure $ Right ctx'
602607
603608updateTupleWithAtomExprs :: M.Map AttributeName AtomExpr -> DatabaseContext -> RelationTuple -> Either RelationalError RelationTuple
604609updateTupleWithAtomExprs exprMap context tupIn = do