lhc-0.6.20081127: src/E/Arbitrary.hs
module E.Arbitrary where
--import Test.QuickCheck
import E.E
import E.TypeCheck()
import qualified Data.Set as Set
import qualified Data.Map as Map
import Random
import Doc.DocLike
import Doc.PPrint
import Doc.Pretty (putDoc, Doc)
import E.Show
import Data.Monoid
import GenUtil
import Support.FreeVars
import Name.VConsts
import Support.CanType
import CharIO
data EP = EP {
canDiverge :: Bool,
usedVars :: Set.Set TVr
}
choose :: [IO a] -> IO a
choose [] = fail "nothing to choose from"
choose as = do
x <- randomRIO (0,length as - 1)
as !! x
value t
| t == tInteger = choose [return $ ELit $ LitInt 1 tInteger]
| t == tChar = choose [return $ ELit $ LitInt (fromIntegral (fromEnum 'x')) tChar]
| t == eStar = choose $ map return [tChar, tInteger]
var t = do
x <- randomRIO (1,100)
return $ TVr (2*x) t mempty
complicate :: Set.Set TVr -> E -> IO E
complicate fvs e = do
let re = if Set.null fvs then (replicate 1 (return e) ++ ) else id
e <- choose $ re (replicate 2 $ complicate' fvs e >>= complicate fvs )
return e
complicate' fvs e
| EPi (TVr _ a1 _) a2 <- te = choose [ do v <- value a1; return (EAp e v), f e ]
| otherwise = f e
where
te = getType e
f (EAp a b) = choose [do
a' <- complicate fvs a
b' <- complicate fvs b
return (EAp a b), g e]
f (ELam v e) = choose [do
e' <- complicate fvs e
return (ELam v e'),
g e]
f e = g e
g e = do
t <- value eStar
v <- var t
return (ELam v e)
genE = do
v <- value tInteger
complicate mempty v
ge = do
e <- genE
CharIO.print e
CharIO.putStrLn (render $ (ePretty e :: Doc))
putDoc (pprint (getType e))
testE = do
CharIO.putStrLn "Testing E"
ge
ge
{-
typeSet env = Map.keys env
typeCnt env a
| Just x <- Map.lookup a env = x
| otherwise = 0
typeCntInc env a = Map.insert a (typeCnt env a + 1) env
countTerm :: E -> Map.Map E Int -> Int -> Int
countTerm _t _env 0 = 0
countTerm t env 1 = typeCnt env t
countTerm t@(EPi (TVr _ a1 _) a2) env s = countTerm a2 (typeCntInc env a1) (s - 1) + countHeadVarTerm t env s
countTerm t env s = countHeadVarTerm t env s
countHeadVarTerm t env s = sum [ countHeadVarArgTerms bs env s | bs <- validHeadVarTypeSet t env]
countHeadVarArgTerms (b,bs) env s
| numVarWithTypeInEnv <= 0 = 0 -- multiplication is too strict here
| otherwise = numVarWithTypeInEnv * numTerms where
numVarWithTypeInEnv = typeCnt env b
m = length bs
numTerms = sum [ product [ countTerm b env s | s <- ss | b <- bs ] | ss <- ndk (s - 1 - m) m]
validHeadVarTypeSet a env = concat (map (f []) (Map.keys env)) where
f rs b | b == a = return (a,reverse rs)
f rs (EPi (TVr _ b1 _) b2) = f (b1:rs) b2
f _ _ = fail "not valid head var type set"
ndk :: Int -> Int -> [[Int]]
ndk n m | n < 0 = error "ndk: n < 0"
ndk n m | m < 0 = error "ndk: m < 0"
ndk n m | n < m = error "ndk: n < m"
ndk 0 m = []
ndk n m | n == m = [replicate m 1]
ndk n m = snub $ concat [ f ss | ss <- ndk (n - 1) m] where
f ss = [ [ if i == i' then s + 1 else s | s <- ss | i' <- [0 :: Int ..] ] | _ <- ss | i <- [0 :: Int ..] ]
testE = do
putStrLn "Testing E"
let f x i = do
putStrLn $ "countTerm" <+> show x <+> show i <+> "=" <+> show (countTerm x (Map.singleton eStar 1) i)
f eStar 2
f eStar 4
f eStar 1
f (ePi (TVr 0 eStar mempty) eStar) 7
let prop_ndk n m = abs n >= abs m ==> let ss = ndk (abs n) (abs m) in and [ sum s == (abs n) |s <- ss] && unique mempty ss where
unique _ [] = True
unique ss (x:xs) | x `Set.member` ss = False
unique ss (x:xs) = unique (Set.insert x ss) xs
--quickCheck prop_ndk
print (ndk 4 2)
--print (ndk 10 4)
gen a s = genTerm a mempty s
genTerm _a _env s | s < 1 = return Nothing
genTerm a env 1
| typeCnt env a > 0 = genVarTerm env a
| otherwise = return Nothing
genTerm (EPi (TVr _ a1) a2) env s = do
let totalNumTerm = countTerm a env s
numLamTerm = countTerm a2 (typeCntInc env a1 (s - 1))
x <- randomRIO (0,totalNumTerm)
if x <= numLamTerm then
genLamTerm a1 a2 env s
else genAppTerm a env s (totalNumTerm - numLamTerm)
genTerm a env s = genAppTerm a env s (countTerm a env s)
genVarTerm a env | typeCnt env a == 0 = return Nothing
-}