ajhc-0.8.0.5: src/E/Arbitrary.hs
module E.Arbitrary where
--import Test.QuickCheck
import Data.Monoid
import Doc.DocLike()
import Doc.PPrint
import Doc.Pretty (putDoc, Doc)
import E.E
import E.Show
import E.TypeCheck()
import GenUtil()
import Name.Id
import Name.VConsts
import System.Random
import Support.CanType
import Support.FreeVars()
-- import qualified Data.Map as Map
import qualified Data.Set as Set
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]
| otherwise = fail "not support value"
var t = do
x <- randomRIO (1,100)
return $ TVr (anonymous 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
print e
putStrLn (render $ (ePretty e :: Doc))
putDoc (pprint (getType e))
testE = do
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
-}