diff options
| author | krasimir <krasimir@chalmers.se> | 2010-10-02 13:03:57 +0000 |
|---|---|---|
| committer | krasimir <krasimir@chalmers.se> | 2010-10-02 13:03:57 +0000 |
| commit | cb8795c222ae86e4561e1009c382fe0b87e22b62 (patch) | |
| tree | eddba3e578a812347060f5f640cc49e58dc5b263 /src/runtime/haskell/PGF/Generate.hs | |
| parent | 72cc4ddb594599a5e3768a7b3921975542c3591a (diff) | |
refactor the API for random generation again. Now PGF contains probabilities in the abstract syntax
Diffstat (limited to 'src/runtime/haskell/PGF/Generate.hs')
| -rw-r--r-- | src/runtime/haskell/PGF/Generate.hs | 82 |
1 files changed, 29 insertions, 53 deletions
diff --git a/src/runtime/haskell/PGF/Generate.hs b/src/runtime/haskell/PGF/Generate.hs index 797e5e229..55bfd72d9 100644 --- a/src/runtime/haskell/PGF/Generate.hs +++ b/src/runtime/haskell/PGF/Generate.hs @@ -3,8 +3,6 @@ module PGF.Generate , generateFrom, generateFromDepth , generateRandom, generateRandomDepth , generateRandomFrom, generateRandomFromDepth - - , RandomSelector(..) ) where import PGF.CId @@ -17,6 +15,7 @@ import PGF.Probabilistic import qualified Data.Map as Map import qualified Data.IntMap as IntMap import Control.Monad +import Control.Monad.Identity import System.Random -- | Generates an exhaustive possibly infinite list of @@ -44,24 +43,24 @@ generateFromDepth pgf e dp = generateForMetas False pgf (\ty -> generateAllDepth -- | Generates an infinite list of random abstract syntax expressions. -- This is usefull for tree bank generation which after that can be used -- for grammar testing. -generateRandom :: RandomGen g => RandomSelector g -> PGF -> Type -> [Expr] -generateRandom sel pgf ty = - generate sel pgf ty Nothing +generateRandom :: RandomGen g => g -> PGF -> Type -> [Expr] +generateRandom g pgf ty = + generate (Identity g) pgf ty Nothing -- | A variant of 'generateRandom' which also takes as argument -- the upper limit of the depth of the generated expression. -generateRandomDepth :: RandomGen g => RandomSelector g -> PGF -> Type -> Maybe Int -> [Expr] -generateRandomDepth sel pgf ty dp = generate sel pgf ty dp +generateRandomDepth :: RandomGen g => g -> PGF -> Type -> Maybe Int -> [Expr] +generateRandomDepth g pgf ty dp = generate (Identity g) pgf ty dp -- | Random generation based on template -generateRandomFrom :: RandomGen g => RandomSelector g -> PGF -> Expr -> [Expr] -generateRandomFrom sel pgf e = - generateForMetas True pgf (\ty -> generate sel pgf ty Nothing) e +generateRandomFrom :: RandomGen g => g -> PGF -> Expr -> [Expr] +generateRandomFrom g pgf e = + generateForMetas True pgf (\ty -> generate (Identity g) pgf ty Nothing) e -- | Random generation based on template with a limitation in the depth. -generateRandomFromDepth :: RandomGen g => RandomSelector g -> PGF -> Expr -> Maybe Int -> [Expr] -generateRandomFromDepth sel pgf e dp = - generateForMetas True pgf (\ty -> generate sel pgf ty dp) e +generateRandomFromDepth :: RandomGen g => g -> PGF -> Expr -> Maybe Int -> [Expr] +generateRandomFromDepth g pgf e dp = + generateForMetas True pgf (\ty -> generate (Identity g) pgf ty dp) e @@ -103,8 +102,8 @@ prove abs scope tty@(TTyp env (DTyp [] cat es)) dp = do clauses cat = do fn <- select abs cat case Map.lookup fn (funs abs) of - Just (ty,_,_) -> return (fn,ty) - Nothing -> mzero + Just (ty,_,_,_) -> return (fn,ty) + Nothing -> mzero mkEnv env [] = return (env,[]) mkEnv env ((bt,x,ty):hypos) = do @@ -175,46 +174,23 @@ instance Selector () where Just (_,fns) -> iter s fns Nothing -> CFail) where - iter s [] = CFail - iter s (fn:fns) = CBranch (COk () s fn) (iter s fns) - --- | The random selector data type is used to specify the random number generator --- and the distribution among the functions with the same result category. --- The distribution is even for 'RandSel' and weighted for 'WeightSel'. -data RandomSelector g = RandSel g - | WeightSel g Probabilities - -instance RandomGen g => Selector (RandomSelector g) where - splitSelector (RandSel g) = let (g1,g2) = split g - in (RandSel g1, RandSel g2) - splitSelector (WeightSel g probs) = let (g1,g2) = split g - in (WeightSel g1 probs, WeightSel g2 probs) - - select abs cat = GenM (\sel s -> case sel of - RandSel g -> case Map.lookup cat (cats abs) of - Just (_,fns) -> do_rand g s (length fns) fns - Nothing -> CFail - WeightSel g probs -> case Map.lookup cat (catProbs probs) of - Just fns -> do_weight g s 1.0 fns - Nothing -> CFail) + iter s [] = CFail + iter s ((_,fn):fns) = CBranch (COk () s fn) (iter s fns) + +instance RandomGen g => Selector (Identity g) where + splitSelector (Identity g) = let (g1,g2) = split g + in (Identity g1, Identity g2) + + select abs cat = GenM (\(Identity g) s -> + case Map.lookup cat (cats abs) of + Just (_,fns) -> do_rand g s 1.0 fns + Nothing -> CFail) where - do_rand g s n [] = CFail - do_rand g s n fns = let n' = n-1 - (i,g') = randomR (0,n') g + do_rand g s p [] = CFail + do_rand g s p fns = let (d,g') = randomR (0.0,p) g (g1,g2) = split g' - (fn,fns') = pick i fns - in CBranch (COk (RandSel g1) s fn) (do_rand g2 s n' fns') - - do_weight g s p [] = CFail - do_weight g s p fns = let (d,g') = randomR (0.0,p) g - (g1,g2) = split g' - (p',fn,fns') = hit d fns - in CBranch (COk (RandSel g1) s fn) (do_weight g2 s (p-p') fns') - - pick :: Int -> [a] -> (a,[a]) - pick 0 (x:xs) = (x,xs) - pick n (x:xs) = let (x',xs') = pick (n-1) xs - in (x',x:xs') + (p',fn,fns') = hit d fns + in CBranch (COk (Identity g1) s fn) (do_rand g2 s (p-p') fns') hit :: Double -> [(Double,a)] -> (Double,a,[(Double,a)]) hit d (px@(p,x):xs) |
