module MagicHaskeller.LibTH(module MagicHaskeller.LibTH, module MagicHaskeller) where
import MagicHaskeller
import MagicHaskeller.Types(size)
#ifdef TFRANDOM
import System.Random.TF(seedTFGen)
#else
import System.Random(mkStdGen)
#endif
import Control.Monad(liftM2)
import Data.List hiding (tail)
import Data.Char
import Data.Maybe
import MagicHaskeller.FastRatio
import qualified Data.Generics as G
import MagicHaskeller.ProgGenSF(mkTrieOptSFIO)
import qualified Data.IntMap as IM
import Data.Hashable
import Prelude hiding (tail, gcd, enumFromThenTo)
succOnlyForNumbers = False
last' = (\x xs -> last (x:xs))
tail = drop 1
gcd x y = gcd' (abs x) (abs y)
where gcd' a 0 = a
gcd' a b = gcd' b (a `rem` b)
enumFromThenTo l m n = map toEnum $
case compare lint mint of
EQ -> error "MagicHaskeller.LibTH.enumFromThenTo m m n"
LT -> takeWhile (<=nint) $ iterate (+(mintlint)) lint
GT -> takeWhile (>=nint) $ iterate (+(mintlint)) lint
where lint = fromEnum l
mint = fromEnum m
nint = fromEnum n
initialize, init075, inittv1 :: IO ()
initialize = do setPrimitives [] (list ++ nat ++ natural ++ mb ++ bool ++ $(p [| hd :: (->) [a] (Maybe a) |]) ++ plusInt ++ plusInteger)
setDepth 10
init075 = do setPG $ mkMemo075 [] (list ++ nat ++ natural ++ mb ++ bool ++ plusInt ++ plusInteger)
setDepth 10
inittv1 = do setPG $ mkPGOpt (options{primopt = Nothing, tv1 = True})
[]
(list ++ nat ++ natural ++ mb ++ bool ++ tuple ++ $(p [| (hd :: (->) [a] (Maybe a)) |]) ++ plusInt ++ plusInteger )
setDepth 10
tuple = $(p [| ((,) :: a -> b -> (a,b), uncurry :: (a->b->c) -> (->) (a,b) c) |])
tuple' = $(p [| ((,) :: a -> b -> (a,b), flip uncurry :: (->) (a,b) ((a->b->c) -> c)) |])
mall, mlist, mlist', mnat, mlistnat, mnat_nc, mnatural, mlistnatural :: ProgramGenerator pg => pg
mall = mkPG (list ++ nat ++ natural ++ mb ++ bool ++ $(p [| hd :: (->) [a] (Maybe a) |]) ++ plusInt ++ plusInteger)
mlist = mkPG list
mlist' = mkPG list'
mnat = mkPG (nat ++ plusInt)
mnatural = mkPG (natural ++ plusInteger)
mlistnat = mkPG (list ++ nat ++ plusInt)
mlistnatural = mkPG (list ++ natural ++ plusInteger)
mnat_nc = mkMemo (nat ++ plusInt)
hd :: [a] -> Maybe a
hd [] = Nothing
hd (x:_) = Just x
mb, mb', nat, natural, nat', nat'woPred, natural', plusInt, plusInteger, list'', list', list, bool, boolean, intinst, list1, list1', list2, list3, list3', nats, tuple, tuple', rich, rich', debug :: [Primitive]
mb = $(p [| ( Nothing :: Maybe a, Just :: a -> Maybe a, maybe :: a -> (b->a) -> (->) (Maybe b) a ) |] )
mb' = $(p [| ( Nothing :: Maybe a, Just :: a -> Maybe a, flip . maybe :: a -> (->) (Maybe b) ((b->a) -> a) ) |] )
nat = $(p [| (0 :: Int, (1+) :: Int->Int, nat_para :: (->) Int (a -> (Int -> a -> a) -> a)) |] )
natural = $(p [| (0 :: Integer, (1+) :: Integer->Integer, nat_para :: (->) Integer (a -> (Integer -> a -> a) -> a)) |] )
nat' = $(p [| (0 :: Int, (1+) :: Int->Int, nat_cata :: (->) Int (a -> (a -> a) -> a), pred :: Int->Int) |] )
nat'woPred = $(p [| (0 :: Int, (1+) :: Int->Int, nat_cata :: (->) Int (a -> (a -> a) -> a)) |] )
natural' = $(p [| (0 :: Integer, (1+) :: Integer->Integer, nat_cata :: (->) Integer (a -> (a -> a) -> a), pred :: Integer->Integer) |] )
plusInt = $(p [| (+) :: (->) Int ((->) Int Int) |])
plusInteger = $(p [| (+) :: (->) Integer ((->) Integer Integer) |])
nat_para :: Integral i => i -> a -> (i -> a -> a) -> a
nat_para i x f = np (abs i)
where np 0 = x
np i = let i' = i1
in f i' (np i')
nat_cata :: Integral i => i -> a -> (a -> a) -> a
nat_cata i x f = nc (abs i)
where nc 0 = x
nc i = f (nc (i1))
list'' = $(p [| ([] :: [a], (:), flip . flip foldr :: a -> (->) [b] ((b -> a -> a) -> a), tail :: (->) [a] [a]) |] )
list' = $(p [| ([] :: [a], (:), foldr :: (b -> a -> a) -> a -> (->) [b] a, tail :: (->) [a] [a]) |] )
list = $(p [| ([] :: [a], (:), list_para :: (->) [b] (a -> (b -> [b] -> a -> a) -> a)) |] )
list_para :: [b] -> a -> (b -> [b] -> a -> a) -> a
list_para [] x f = x
list_para (y:ys) x f = f y ys (list_para ys x f)
bool = $(p [| (True, False, iF :: (->) Bool (a -> a -> a)) |] )
iF :: Bool -> a -> a -> a
iF True t f = t
iF False t f = f
postprocess :: Exp -> Exp
postprocess (AppE (AppE (AppE (InfixE (Just e1) (VarE name) (Just e2)) e3) e4) e5) | nameBase name == "." = postprocess $ ((e1 `AppE` (e2 `AppE` e3)) `AppE` e4) `AppE` e5
postprocess (AppE (AppE (AppE (AppE (ConE name) e1) e2) e3) e4) | nameBase name == "(,,,)" = postprocess $ TupE [e1, e2, e3, e4]
postprocess (AppE (AppE (AppE (AppE (VarE name) e1) e2) e3) e4) | nameBase name == "flip" = postprocess $ ((e1 `AppE` e3) `AppE` e2) `AppE` e4
postprocess (AppE (InfixE (Just e1) (VarE name) (Just e2)) e3) | nameBase name == "." = postprocess $ e1 `AppE` (e2 `AppE` e3)
postprocess (AppE (e@(AppE (AppE (ConE name) p) t)) f) | nameBase name == "(,,)" = postprocess $ TupE [p,t,f]
postprocess (AppE (e@(AppE (AppE (VarE name) p) t)) f)
= case nameBase name of
"iF" -> CondE ppp ppt ppf
"enumFromThenTo" -> ArithSeqE $ FromThenToR ppp ppt ppf
"nat_cata" -> InfixE (Just $ (VarE (mkName "iterate") `AppE` ppf) `AppE` ppt)
(VarE (mkName "!!"))
(Just $ case ppp of LitE (IntegerL i) -> LitE $ IntegerL $ abs i
_ -> VarE (mkName "abs") `AppE` ppp)
"flip" -> postprocess $ (ppp `AppE` ppf) `AppE` ppt
"." -> postprocess (p `AppE` (t `AppE` f))
_ -> postprocess e `AppE` ppf
where ppp = postprocess p
ppt = postprocess t
ppf = postprocess f
postprocess (AppE f@(AppE (ConE name) lj) e) | nameBase name == "(,)" = postprocess $ TupE [lj, e]
postprocess (AppE f@(AppE (VarE name) lj) e)
= case nameBase name of "drop" -> case pplj of LitE (IntegerL j) | j<=0 -> ppe
| j> 0 -> ppdrop j e
_ -> (dropE `AppE` pplj) `AppE` ppe
"enumFromTo" -> ArithSeqE $ FromToR pplj ppe
"last'" -> case ppe of AppE (VarE rev) e' | nameBase rev == "reverse" -> ((VarE (mkName "foldr") `AppE` constE) `AppE` pplj) `AppE` e'
_ -> VarE (mkName "last") `AppE` InfixE (Just pplj) (ConE $ mkName ":") (Just ppe)
"filter" -> case ppe of AppE (VarE rev) e' | nameBase rev == "reverse" -> reverseE `AppE` ((VarE (mkName "filter") `AppE` pplj) `AppE` e')
_ -> (VarE (mkName "filter") `AppE` pplj) `AppE` ppe
_ -> postprocess f `AppE` ppe
where pplj = postprocess lj
ppe = postprocess e
postprocess (AppE (InfixE m@(Just _) op Nothing) e) = postprocess (InfixE m op (Just e))
postprocess (AppE (InfixE Nothing op m@(Just _)) e) = postprocess (InfixE (Just e) op m)
postprocess (AppE v@(VarE name) e)
= case nameBase name of
"tail" -> ppdrop 1 e
"negate" -> case ppe of LitE (IntegerL i) -> LitE $ IntegerL $ (i)
LitE (RationalL r) -> LitE $ RationalL $ (r)
_ -> AppE v ppe
"abs" -> case ppe of LitE (IntegerL i) -> LitE $ IntegerL $ abs i
LitE (RationalL r) -> LitE $ RationalL $ abs r
_ -> AppE (ppv v) ppe
"floor" -> case ppe of LitE (IntegerL i) -> LitE $ IntegerL i
LitE (RationalL r) -> LitE $ IntegerL $ floor r
_ -> AppE v ppe
"round" -> case ppe of LitE (IntegerL i) -> LitE $ IntegerL i
LitE (RationalL r) -> LitE $ IntegerL $ round r
_ -> AppE v ppe
"ceiling" -> case ppe of LitE (IntegerL i) -> LitE $ IntegerL i
LitE (RationalL r) -> LitE $ IntegerL $ ceiling r
_ -> AppE v ppe
"fromIntegral" -> case ppe of LitE i -> LitE i
_ -> AppE v ppe
"exponent" -> case ppe of
LitE (IntegerL i) -> LitE $ IntegerL $ toInteger $ exponent $ fromIntegral i
LitE (RationalL r) -> LitE $ IntegerL $ toInteger $ exponent $ fromRational r
_ -> AppE v ppe
"succ" -> case ppe of
LitE (IntegerL i) -> LitE $ IntegerL $ succ i
LitE (RationalL r) -> LitE $ RationalL $ succ r
LitE (CharL c) -> LitE $ CharL $ succ c
InfixE (Just (LitE (IntegerL n))) (VarE nm) (Just e)
| nameBase nm == "+" -> InfixE (Just $ LitE $ IntegerL $ succ n) plusE (Just e)
AppE (VarE nm) e
| succOnlyForNumbers &&
nameBase nm == "succ" -> InfixE (Just $ LitE $ IntegerL 2) plusE (Just e)
_ -> AppE (ppv v) ppe
"reverse" -> case ppe of
LitE (StringL xs) -> LitE $ StringL $ reverse xs
ListE es -> ListE $ reverse $ map postprocess es
ArithSeqE (FromToR (LitE (IntegerL f)) (LitE (IntegerL t))) -> ArithSeqE $ FromThenToR (LitE $ IntegerL t) (LitE $ IntegerL $ t1) (LitE $ IntegerL f)
AppE (VarE name) e' | nameBase name == "reverse" -> e'
_ -> AppE reverseE ppe
"length" -> case ppe of
LitE (StringL xs) -> LitE $ IntegerL $ toInteger $ length xs
ListE es -> LitE $ IntegerL $ toInteger $ length es
ArithSeqE (FromToR (LitE (IntegerL f)) (LitE (IntegerL t))) -> LitE $ IntegerL $ t f + 1
AppE (VarE name) e' | nameBase name == "reverse" -> AppE lengthE e'
_ -> AppE lengthE ppe
"sum" -> case ppe of
AppE (VarE name) e' | nameBase name == "reverse" -> AppE sumE e'
_ -> AppE sumE ppe
"product" -> case ppe of
AppE (VarE name) e' | nameBase name == "reverse" -> AppE productE e'
_ -> AppE productE ppe
nb -> case IM.lookup (hash nb) byMap of Just fun -> fun ppe $ AppE (ppv v) ppe
Nothing -> AppE (ppv v) ppe
where ppe = postprocess e
postprocess e@(VarE _) = ppv e
postprocess (AppE f x) = postprocess f `AppE` postprocess x
postprocess (InfixE me1 op me2)
= let j1 = fmap postprocess me1
j2 = fmap postprocess me2
in case op of
VarE opname ->
case (j1,j2) of
(Just (LitE (IntegerL i1)), Just (LitE (IntegerL i2))) ->
case nameBase opname of "+" -> LitE $ IntegerL $ i1+i2
"-" -> LitE $ IntegerL $ i1i2
"*" -> LitE $ IntegerL $ i1*i2
_ -> theDefault
(Just (LitE (IntegerL i1)), Just (InfixE (Just (LitE (IntegerL i2))) (VarE inopn) me3))
| nameBase opname == "+" && nameBase inopn `elem` ["+","-"] -> InfixE (Just $ LitE $ IntegerL $ i1+i2) (VarE $ ppopn inopn) me3
_ -> theDefault
where theDefault = InfixE j1 (VarE $ ppopn opname) j2
ConE opname -> InfixE j1 (ConE $ ppopn opname) j2
postprocess (LamE pats e) = ppLambda pats (postprocess e)
postprocess (TupE es) = TupE (map postprocess es)
postprocess (ListE es) = ListE (map postprocess es)
postprocess (SigE e ty) = postprocess e `SigE` ty
postprocess e = e
byMap = IM.fromList $ byEqs++byOrds
byEqs = (hash "deleteFirstsBy", skipEq "\\\\") : [ (hash $ xs++"By", skipEq xs) | xs <- ["nub","delete","union","intersect","group"]]
byOrds = [ (hash $ xs++"By", skipOrd xs) | xs <- ["sort","insert","minimum","maximum"]]
skip op namestr = \eqExp wholeExp -> case eqExp of VarE name | nameBase name == op -> VarE $ mkName namestr
_ -> wholeExp
skipEq = skip "=="
skipOrd = skip "compare"
shown `appearsIn` e = G.everything (||) (False `G.mkQ` (\name -> show (name::Name) == shown)) e
ppLambda [VarP n] (AppE e (VarE n')) | shown == show n' && not (shown `appearsIn` e) = e
where shown = show n
ppLambda [VarP n, VarP m, VarP l] (AppE (AppE (AppE e (VarE n')) (VarE m')) (VarE l'))
| shown == show n' && showm == show m' && showl == show l' && free = e
| shown == show m' && showm == show n' && showl == show l' && free = flipE `AppE` e
where shown = show n
showm = show m
showl = show l
free = not (shown `appearsIn` e) && not (showm `appearsIn` e) && not (showl `appearsIn` e)
ppLambda [VarP n, VarP m] (AppE (AppE e (VarE n')) (VarE m'))
| shown == show n' && showm == show m' && free = e
| shown == show m' && showm == show n' && free = flipE `AppE` e
where shown = show n
showm = show m
free = not (shown `appearsIn` e) && not (showm `appearsIn` e)
ppLambda [VarP n, WildP] (VarE n') | show n == show n' = constE
ppLambda [VarP n] (VarE n') | show n == show n' = VarE (mkName "id")
ppLambda [VarP n, VarP m] (InfixE (Just (VarE n')) op (Just (VarE m'))) | show n == show n' && show m == show m' = op
ppLambda pats@[VarP n, VarP m] e@(InfixE (Just (VarE n')) op@(VarE opna) (Just (VarE m')))
= if show n == show m' && show m == show n'
then case nameBase opna of "<" -> VarE (mkName ">")
"<=" -> VarE (mkName ">=")
"-" -> VarE (mkName "subtract")
name | name `elem` ["==","/=","+","*","&&","||"] -> op
| otherwise -> flipE `AppE` op
else LamE pats e
ppLambda [VarP n] (InfixE (Just (VarE n')) op (Just e))
| shown == show n' && not (shown `appearsIn` e) = case op of VarE name | nameBase name == "-" -> VarE (mkName "subtract") `AppE` e
_ -> InfixE Nothing op (Just e)
where shown = show n
ppLambda [VarP n] (InfixE (Just e) op (Just (VarE n'))) | shown == show n' && not (shown `appearsIn` e) = InfixE (Just e) op Nothing
where shown = show n
ppLambda pats e = LamE pats e
ppv e@(VarE name) | nameBase name `elem` ["iF", "nat_cata"] = LamE [ VarP n | n <- names ] (postprocess (AppE (AppE (AppE e p) t) f))
| nameBase name == "last'" = LamE [ VarP n | n <- tail names ] (postprocess (AppE (AppE e t) f))
| otherwise = VarE $ ppopn name
where names = [ mkName [n] | n <- "ptf" ]
[p,t,f] = map VarE names
ppopn name = case nameModule name of Just mod |
not $ mod `elem` ["Data.Map", "Data.Set", "Data.Text", "Data.ByteString"]
-> mkName $ nameBase name
_ -> name
ppdrop m0j e
= case postprocess e of
AppE (AppE (VarE drn) (LitE (IntegerL i))) list | nameBase drn == "drop" -> droppy (m0j + i) list
ppe -> droppy m0j ppe
where droppy i e = (dropE `AppE` (LitE $ IntegerL i)) `AppE` e
constE = VarE $ mkName "const"
flipE = VarE $ mkName "flip"
plusE = VarE $ mkName "+"
dropE = VarE $ mkName "drop"
reverseE = VarE $ mkName "reverse"
lengthE = VarE $ mkName "length"
sumE = VarE $ mkName "sum"
productE = VarE $ mkName "product"
procSucc n (AppE (VarE name) e) | nameBase name == "succ" = procSucc (n+1) e
procSucc n (LitE (CharL c)) = LitE $ CharL $ iterate succ c `genericIndex` n
procSucc n (LitE (IntegerL i)) = LitE $ IntegerL $ n+i
procSucc n (LitE (RationalL r)) = LitE $ RationalL $ fromInteger n + r
procSucc n e | succOnlyForNumbers = InfixE (Just $ LitE $ IntegerL n) (VarE $ mkName "+") (Just $ postprocess e)
| otherwise = iterate (AppE (VarE $ mkName "succ")) (postprocess e) `genericIndex` n
postprocessQ :: Exp -> ExpQ
postprocessQ (AppE (e@(AppE (AppE (VarE name) p) t)) f)
= case nameBase name of
"iF" -> [| if $(postprocessQ p) then $(postprocessQ t) else $(postprocessQ f) |]
"nat_cata" -> [| iterate $(postprocessQ f) $(postprocessQ t) !! abs $(postprocessQ p) |]
"nat_para" -> [| let {np 0 = $(postprocessQ t); np n = let i=n1 in $(postprocessQ f) i (np i)} in np (abs $(postprocessQ p)) |]
"list_para" -> [| let {lp [] = $(postprocessQ t); lp (y:ys) = $(postprocessQ f) y ys (lp ys)} in lp $(postprocessQ p) |]
_ -> [| $(postprocessQ e) $(postprocessQ f) |]
postprocessQ (AppE f x) = [| $(postprocessQ f) $(postprocessQ x) |]
postprocessQ (InfixE me1 op me2) = let fmapM f Nothing = return Nothing
fmapM f (Just x) = fmap Just (f x)
in liftM2 (\e1 e2 -> InfixE e1 op e2) (fmapM postprocessQ me1) (fmapM postprocessQ me2)
postprocessQ (LamE pats e) = fmap (LamE pats) (postprocessQ e)
postprocessQ (TupE es) = fmap TupE (mapM postprocessQ es)
postprocessQ (ListE es) = fmap ListE (mapM postprocessQ es)
postprocessQ (SigE e ty) = fmap (`SigE` ty) (postprocessQ e)
postprocessQ e = return e
exploit :: (Typeable a, Filtrable a) =>
Bool
-> (a -> Bool) -> IO ()
exploit withAbsents pred = filterThenF pred (everything (reallyall::ProgGenSF) withAbsents) >>= pprs
boolean = $(p [| ((&&) :: (->) Bool ((->) Bool Bool),
(||) :: (->) Bool ((->) Bool Bool),
not :: (->) Bool Bool) |] )
newtype Partial a = Part {undef :: a}
undefs = map (\[a,b] -> (a,b)) $
[
$(p [| (Part 53 :: Partial Int, undefined :: Partial Int) |]),
$(p [| (Part '\29' :: Partial Char, undefined :: Partial Char) |]),
$(p [| (Part [43] :: Partial [Int], undefined :: Partial [Int]) |]),
$(p [| (Part "wleajkf" :: Partial [Char], undefined :: Partial [Char]) |])]
by1_head :: Partial a -> [a] -> a
by1_head (Part u) [] = u
by1_head _ (x:_) = x
(--#!!) :: Partial a -> [a] -> Int -> a
(--#!!) (Part u) [] n = u
(--#!!) (Part u) (x:xs) n
= case compare n 0 of
LT -> u
EQ -> x
GT -> (--#!!) (Part u) xs (n1)
prelPartial = $(p [| ( by1_head :: Partial a -> (->) [a] a,
(--#!!) :: Partial a -> [a] -> (->) Int a) |] )
newtype Equivalence a = Eq {(--#==) :: a -> a -> Bool}
eq = Eq (==)
by1_eqMaybe :: Equivalence a -> Equivalence (Maybe a)
by1_eqMaybe (Eq op) = Eq $ eqMaybeBy op
eqMaybeBy _ Nothing Nothing = True
eqMaybeBy _ Nothing (Just _) = False
eqMaybeBy _ (Just _) Nothing = False
eqMaybeBy e (Just x) (Just y) = e x y
by1_eqList :: Equivalence a -> Equivalence [a]
by1_eqList (Eq e) = Eq $ eqListBy e
eqListBy _ [] [] = True
eqListBy _ [] _ = False
eqListBy _ _ [] = False
eqListBy e (x:xs) (y:ys) = e x y && eqListBy e xs ys
by2_eqEither :: Equivalence a -> Equivalence b -> Equivalence (Either a b)
by2_eqEither (Eq e1) (Eq e2) = Eq $ eqEitherBy e1 e2
eqEitherBy e1 _ (Left x) (Left y) = e1 x y
eqEitherBy _ _ (Left _) (Right _) = False
eqEitherBy _ _ (Right _) (Left _) = False
eqEitherBy _ e2 (Right x) (Right y) = e2 x y
by2_eqPair :: Equivalence a -> Equivalence b -> Equivalence (a,b)
by2_eqPair (Eq e1) (Eq e2) = Eq $ eqPairBy e1 e2
eqPairBy e1 e2 (x,y) (z,w) = e1 x z && e2 y w
eqs = $(p [| (eq :: Equivalence Bool, eq :: Equivalence Ordering, eq :: Equivalence Int, eq :: Equivalence Char,
eq :: Equivalence [Int], eq :: Equivalence [Char], by1_eqMaybe :: Equivalence a -> Equivalence (Maybe a), by1_eqList :: Equivalence a -> Equivalence [a],
by2_eqEither :: Equivalence a -> Equivalence b -> Equivalence (Either a b), by2_eqPair :: Equivalence a -> Equivalence b -> Equivalence (a,b)) |])
prelEqRelated = [$(p [| ((--#==) :: Equivalence a -> (->) a (a -> Bool), (--#/=) :: Equivalence a -> (->) a (a -> Bool)) |]),
$(p [| by1_elem :: Equivalence a -> a -> [a] -> Bool |]),
[]]
dataListEqRelated = [[],
$(p [| (by1_group :: Equivalence a -> [a] -> [[a]],
by1_nub :: Equivalence a -> [a] -> [a]) |]),
$(p [| (by1_isPrefixOf :: Equivalence a -> [a] -> [a] -> Bool,
by1_isSuffixOf :: Equivalence a -> [a] -> [a] -> Bool,
by1_isInfixOf :: Equivalence a -> [a] -> [a] -> Bool,
by1_stripPrefix :: Equivalence a -> [a] -> [a] -> Maybe [a],
by1_lookup :: Equivalence a -> a -> (->) [(a, b)] (Maybe b)
) |])]
(--#/=) :: Equivalence a -> a -> a -> Bool
(--#/=) (Eq e) x y = not $ e x y
by1_elem :: Equivalence a -> a -> [a] -> Bool
by1_elem (Eq e) k = any (e k)
by1_group :: Equivalence a -> [a] -> [[a]]
by1_group (Eq e) = groupBy e
by1_nub :: Equivalence a -> [a] -> [a]
by1_nub (Eq e) = nubBy e
by1_isPrefixOf :: Equivalence a -> [a] -> [a] -> Bool
by1_isPrefixOf _ [] _ = True
by1_isPrefixOf _ _ [] = False
by1_isPrefixOf e@(Eq op) (x:xs) (y:ys) = op x y && by1_isPrefixOf e xs ys
by1_isSuffixOf :: Equivalence a -> [a] -> [a] -> Bool
by1_isSuffixOf e xs ys = by1_isPrefixOf e (reverse xs) (reverse ys)
by1_isInfixOf :: Equivalence a -> [a] -> [a] -> Bool
by1_isInfixOf e xs ys = any (by1_isPrefixOf e xs) (tails ys)
by1_stripPrefix :: Equivalence a -> [a] -> [a] -> Maybe [a]
by1_stripPrefix eq [] ys = Just ys
by1_stripPrefix eq@(Eq op) (x:xs) (y:ys) | op x y = by1_stripPrefix eq xs ys
by1_stripPrefix _ _ _ = Nothing
by1_lookup :: Equivalence a -> a -> (->) [(a, b)] (Maybe b)
by1_lookup _ _ [] = Nothing
by1_lookup eq@(Eq op) key ((x,y):xys)
| op key x = Just y
| otherwise = by1_lookup eq key xys
newtype Ordered a = Ord {by1_compare :: a->a->Ordering}
cmp = Ord compare
by1_cmpMaybe :: Ordered a -> Ordered (Maybe a)
by1_cmpMaybe (Ord compare) = Ord $ compareMaybeBy compare
compareMaybeBy _ Nothing Nothing = EQ
compareMaybeBy _ Nothing (Just _) = LT
compareMaybeBy _ (Just _) Nothing = GT
compareMaybeBy compare (Just x) (Just y) = compare x y
by1_cmpList :: Ordered a -> Ordered [a]
by1_cmpList (Ord compare) = Ord $ compareListBy compare
compareListBy _ [] [] = EQ
compareListBy _ [] _ = LT
compareListBy _ _ [] = GT
compareListBy compare (x:xs) (y:ys) = case compare x y of EQ -> compareListBy compare xs ys
o -> o
by2_cmpEither :: Ordered a -> Ordered b -> Ordered (Either a b)
by2_cmpEither (Ord compare1) (Ord compare2) = Ord $ compareEitherBy compare1 compare2
compareEitherBy compare1 _ (Left x) (Left y) = compare1 x y
compareEitherBy _ _ (Left _) (Right _) = LT
compareEitherBy _ _ (Right _) (Left _) = GT
compareEitherBy _ compare2 (Right x) (Right y) = compare2 x y
by2_cmpPair :: Ordered a -> Ordered b -> Ordered (a, b)
by2_cmpPair (Ord compare1) (Ord compare2) = Ord $ comparePairBy compare1 compare2
comparePairBy compare1 compare2 (x,y) (z,w) = case compare1 x z of EQ -> compare2 y w
o -> o
ords = $(p [| (cmp :: Ordered Bool, cmp :: Ordered Ordering,
cmp :: Ordered Int, cmp :: Ordered Char,
by1_cmpMaybe :: Ordered a -> Ordered (Maybe a), by1_cmpList :: Ordered a -> Ordered [a],
by2_cmpEither :: Ordered a -> Ordered b -> Ordered (Either a b), by2_cmpPair :: Ordered a -> Ordered b -> Ordered (a,b)) |])
prelOrdRelated = [$(p [| by1_compare :: Ordered a -> a->a->Ordering |]) ++
$(p [| ((--#<=) :: Ordered a -> a -> a -> Bool, (--#<) :: Ordered a -> a -> a -> Bool,
by1_max :: Ordered a -> (->) a (a->a), by1_min :: Ordered a -> (->) a (a->a)) |] ), [],
[]]
dataListOrdRelated = [[],[],$(p [| by1_sort :: Ordered a -> [a] -> [a] |] )]
(--#<=) (Ord compare) x y = case compare x y of GT -> False
_ -> True
(--#<) (Ord compare) x y = case compare x y of LT -> True
_ -> False
by1_max c x y = if (--#<=) c x y then y else x
by1_min c x y = if (--#<=) c x y then x else y
by1_sort (Ord compare) = sortBy compare
intinst = intinst1++intinst2
intinst1 = $(p [| (
() :: Int->Int->Int,
(*) :: Int->Int->Int
) |])
intpartials = $(p [| (
div :: Int->Int->Int,
mod :: Int->Int->Int,
(^) :: Int->Int->Int
) |])
intinst2 = $(p [| (
gcd :: Int->Int->Int,
lcm :: Int->Int->Int) |])
list1 = $(p [| (map :: (a -> b) -> (->) [a] [b],
(++) :: (->) [a] ([a] -> [a]),
filter :: (a -> Bool) -> [a] -> [a],
concat :: (->) [[a]] [a],
concatMap :: (a -> [b]) -> (->) [a] [b],
length :: (->) [a] Int,
replicate :: Int -> a -> [a],
take :: Int -> [a] -> [a],
drop :: Int -> [a] -> [a],
takeWhile :: (a -> Bool) -> [a] -> [a],
dropWhile :: (a -> Bool) -> [a] -> [a]) |] )
list1' = $(p [| (flip map :: (->) [a] ((a -> b) -> [b]),
(++) :: (->) [a] ([a] -> [a]),
filter :: (a -> Bool) -> [a] -> [a],
concat :: (->) [[a]] [a],
flip concatMap :: (->) [a] ((a -> [b]) -> [b]),
length :: (->) [a] Int,
replicate :: Int -> a -> [a],
take :: Int -> [a] -> [a],
drop :: Int -> [a] -> [a],
takeWhile :: (a -> Bool) -> [a] -> [a],
dropWhile :: (a -> Bool) -> [a] -> [a]) |] )
list2 = $(p [| (
lines :: [Char] -> [[Char]],
words :: [Char] -> [[Char]],
unlines :: [[Char]] -> [Char],
unwords :: [[Char]] -> [Char] ) |] )
list3 = $(p [| (reverse :: [a] -> [a],
and :: (->) [Bool] Bool,
or :: (->) [Bool] Bool,
any :: (a -> Bool) -> (->) [a] Bool,
all :: (a -> Bool) -> (->) [a] Bool,
zipWith :: (a->b->c) -> (->) [a] ((->) [b] [c]) ) |] )
list3' = $(p [| (reverse :: [a] -> [a],
and :: (->) [Bool] Bool,
or :: (->) [Bool] Bool,
flip any :: (->) [a] ((a -> Bool) -> Bool),
flip all :: (->) [a] ((a -> Bool) -> Bool),
flip . flip zipWith :: (->) [a] ((->) [b] ((a->b->c) -> [c])) ) |] )
nats = $(p [| (1 ::Int, 2 :: Int, 3 :: Int) |])
reallyall :: ProgramGenerator pg => pg
reallyall = mkPG rich
nrnds = repeat 5
#ifdef TFRANDOM
generator = seedTFGen (3497676378205993723,16020016691208771845,6545968067796471226,2770936286170065919)
#else
generator = mkStdGen 123456
#endif
mix, poormix :: ProgramGenerator pg => pg
mix = mkPGSF generator
nrnds
[]
(list++bool)
rich
soso = (list'' ++
nat'woPred ++
mb' ++ bool ++ plusInt ++
boolean ++ intinst1 ++
list1' ++ list3')
rich = soso ++ list2 ++ intinst2 ++ $(p [| init :: [a] -> [a] |])
poormix = mkPGSF generator
nrnds
[]
$(p [| ([] :: [a], True) |] )
rich
ra :: ProgramGenerator pg => pg
ra = mkPG rich'
rich' = (list'++bool++boolean++
list1 ++ list3)
mx :: ProgramGenerator pg => pg
mx = mkPGSF generator
nrnds
[]
(list++bool)
rich'
debug = $(p [| (list_para :: (->) [b] (a -> (b -> [b] -> a -> a) -> a), concatMap :: (a -> [b]) -> (->) [a] [b]) |] )
pgfull :: ProgGenSF
pgfull = mkPGXOpt options{tv1=True,nrands=repeat 20,timeout=Just 100000} (eqs++ords) clspartialss full tupartialssNormal
pgfulls :: [ProgGenSF]
pgfulls = map pgfullSized [0..]
where pgfullSized sz = mkPGXOpt options{memoCondPure = \t d -> size t < sz && 0<d , tv1=True,nrands=repeat 20,timeout=Just 100000} (eqs++ords) clspartialss full tupartialssNormal
mkPgFull :: IO ProgGenSF
mkPgFull = mkPGXOpts mkTrieOptSFIO options{tv1=True,nrands=repeat 20,timeout=Just 20000} (eqs++ords) clspartialss full tupartialssNormal
mkPgTotal :: IO ProgGenSF
mkPgTotal = mkPGXOpts mkTrieOptSFIO options{tv1=True,nrands=repeat 20,timeout=Just 20000} (eqs++ords) [] full []
mkDebugPg :: IO ProgGenSF
mkDebugPg = mkPGXOpts mkTrieOptSFIO options{tv1=True,nrands=repeat 20,timeout=Just 20000} [] [] deb []
deb = [ $(p [| (reverse :: [a] -> [a], enumFromTo :: Int -> Int -> [Int], 1::Int, product :: [Int] -> Int, concatMap :: (a -> [b]) -> [a] -> [b]) |]), [],[]]
pgfullIO :: IO ProgGenSFIORef
pgfullIO = mkPGXOptIO options{tv1=True,nrands=repeat 20} (eqs++ords) clspartialss full tupartialssNormal
full = foldr zipAppend literals [fromPrelude, prelEqRelated, dataListEqRelated, prelOrdRelated, dataListOrdRelated, fromDataList, fromDataChar, fromDataMaybe]
clspartialss :: [(Primitive,Primitive)]
clspartialss = undefs
tupartialss, tupartialssNormal :: [[(Primitive,Primitive)]]
tupartialss
= map (map (\[a,b] -> (a,b)))
[ [],
[$(p [| (chr . (`mod` 65536) . abs, chr . abs) |]),
$(p [| (chr . (`mod` 65536) . succ . ord :: Char->Char, succ :: Char -> Char) |])],
[$(p [| ((\m n -> if n==0 then 83 else div m n) :: Int->Int->Int, div :: Int->Int->Int) |]),
$(p [| ((\m n -> if n==0 then 46 else mod m n) :: Int->Int->Int, mod :: Int->Int->Int) |]),
$(p [| ((\m n -> if n<0 then 23 else m ^ n) :: Int->Int->Int, (^) :: Int->Int->Int) |]),
$(p [| ((\l m n -> if l==m then [n,m,m,n,m,n,n] else [l,m..n]) :: Int->Int->Int->[Int], enumFromThenTo :: Int->Int->Int->[Int]) |]),
$(p [| ((\l m n -> if l==m then [m,n,n,m,n,n,n,m] else [l,m..n]) :: Char->Char->Char->[Char], enumFromThenTo :: Char->Char->Char->[Char]) |]),
$(p [| (chr . (`mod` 65536) . pred . ord :: Char->Char, pred :: Char -> Char) |])
] ]
tupartialssNormal
= map (map (\[a,b] -> (a,b)))
[ [],
[$(p [| (chr . (`mod` 65536) . abs, chr . abs) |]),
$(p [| (chr . (`mod` 65536) . succ . ord :: Char->Char, succ :: Char -> Char) |])],
[$(p [| ((\m n -> if n==0 then 0 else div m n) :: Int->Int->Int, div :: Int->Int->Int) |]),
$(p [| ((\m n -> if n==0 then 0 else mod m n) :: Int->Int->Int, mod :: Int->Int->Int) |]),
$(p [| ((\m n -> if m==0 then 0 else m ^ n) :: Int->Int->Int, (^) :: Int->Int->Int) |]),
$(p [| ((\l m n -> if l==m then [] else [l,m..n]) :: Int->Int->Int->[Int], enumFromThenTo :: Int->Int->Int->[Int]) |]),
$(p [| ((\l m n -> if l==m then [] else [l,m..n]) :: Char->Char->Char->[Char], enumFromThenTo :: Char->Char->Char->[Char]) |]),
$(p [| (chr . (`mod` 65536) . pred . ord :: Char->Char, pred :: Char -> Char) |])
] ]
literals = [$(p [|(1::Int, 2::Int, 3::Int, ' '::Char)|]), [], []]
fromPrelude = [
soso ++ $(p [| (null :: (->) [a] Bool,
abs :: (->) Int Int,
flip . flip foldl :: a -> (->) [b] ((a -> b -> a) -> a),
foldr const :: a -> (->) [a] a,
last' :: a -> [a] -> a,
reverse . drop 1 . reverse :: [a] -> [a],
enumFromTo :: Int->Int->[Int], enumFromTo :: Char->Char->[Char],
fmap :: (a -> b) -> (->) (Maybe a) (Maybe b),
flip (flip . either) :: (->) (Either a b) ((a -> c) -> (b -> c) -> c)) |])
++ intinst2 ++ $(p [| (sum :: (->) [Int] Int, product :: (->) [Int] Int) |]),
list2 ++ $(p [| (scanl :: (a -> b -> a) -> a -> [b] -> [a], scanr :: (a -> b -> b) -> b -> [a] -> [b], scanl1 :: (a -> a -> a) -> [a] -> [a], scanr1 :: (a -> a -> a) -> [a] -> [a],
show :: Int -> [Char]) |])++ $(p [| ((,) :: a -> b -> (a,b), flip uncurry :: (->) (a,b) ((a->b->c) -> c)) |]),
$(p [| ((,,) :: a -> b -> c -> (a,b,c), Left :: a -> Either a b, Right :: b -> Either a b,
zip :: (->) [a] ((->) [b] [(a, b)]),
zip3 :: (->) [a] ((->) [b] ((->) [c] [(a, b, c)])),
unzip :: (->) [(a, b)] ([a], [b]),
unzip3 :: (->) [(a, b, c)] ([a], [b], [c]),
odd :: Int -> Bool, even :: Int -> Bool) |])
]
fromDataList = [$(p [| (sortBy, nubBy, deleteBy, dropWhileEnd, transpose
)|]),
$(p [| (
find :: (a -> Bool) -> [a] -> Maybe a, flip findIndex :: (->) [a] ((a -> Bool) -> Maybe Int), flip findIndices :: (->) [a] ((a -> Bool) -> [Int]), deleteFirstsBy, unionBy :: (a -> a -> Bool) -> (->) [a] ([a] -> [a]), intersectBy :: (a -> a -> Bool) -> (->) [a] ([a] -> [a]), groupBy, insertBy
) |]),
$(p [| (intersperse, subsequences, permutations,
inits, tails,
flip . flip mapAccumL :: acc -> (->) [x] ((acc -> x -> (acc, y)) -> (acc, [y])),
flip . flip mapAccumR :: acc -> (->) [x] ((acc -> x -> (acc, y)) -> (acc, [y]))
) |])]
fromDataChar = [$(p [| (toUpper :: (->) Char Char, toLower :: (->) Char Char) |])++
$(p [| (ord, isControl :: (->) Char Bool, isSpace :: (->) Char Bool, isLower :: (->) Char Bool, isUpper :: (->) Char Bool, isAlpha :: (->) Char Bool, isAlphaNum :: (->) Char Bool, isDigit :: (->) Char Bool, isSymbol :: (->) Char Bool, isPunctuation :: (->) Char Bool, isPrint :: (->) Char Bool) |]),
$(p [| (isOctDigit :: (->) Char Bool, isHexDigit :: (->) Char Bool) |]),
[]]
fromDataMaybe = [[],
$(p [| (catMaybes, listToMaybe :: (->) [a] (Maybe a), maybeToList :: (->) (Maybe a) [a]) |]),
[]]
pgWithDoubleRatio :: ProgGenSF
pgWithDoubleRatio = mkPGXOpt options{tv1=True,nrands=repeat 20,timeout=Just 100000} (eqs++ords++doubleCls++ratioCls) clspartialss withDoubleRatio tupartialssNormal
pgWithDoubleRatios :: [ProgGenSF]
pgWithDoubleRatios = map pgWithDoubleRatioSized [0..]
where pgWithDoubleRatioSized sz = mkPGXOpt options{memoCondPure = \t d -> size t < sz && 0<d , tv1=True,nrands=repeat 20,timeout=Just 100000} (eqs++ords++doubleCls++ratioCls) clspartialss withDoubleRatio tupartialssNormal
withDoubleRatio = zipWith (++) withRatio fromPrelDouble
pgWithRatio :: ProgGenSF
pgWithRatio = mkPGXOpt options{tv1=True,nrands=repeat 20,timeout=Just 100000} (eqs++ords++ratioCls) clspartialss withRatio tupartialssNormal
pgWithRatios :: [ProgGenSF]
pgWithRatios = map pgWithRatioSized [0..]
where pgWithRatioSized sz = mkPGXOpt options{memoCondPure = \t d -> size t < sz && 0<d , tv1=True,nrands=repeat 20,timeout=Just 100000} (eqs++ords++ratioCls) clspartialss withRatio tupartialssNormal
pgRatio :: ProgGenSF
pgRatio = mkPGXOpt options{tv1=True,nrands=repeat 20,timeout=Just 100000} ratioCls [] (zipWith (++) fromPrelRatio fromDataRatio) [[],[],[]]
pgRatios :: [ProgGenSF]
pgRatios = map pgWithRatioSized [0..]
where pgWithRatioSized sz = mkPGXOpt options{memoCondPure = \t d -> size t < sz && 0<d , tv1=True,nrands=repeat 20,timeout=Just 100000} ratioCls [] (zipWith (++) fromPrelRatio fromDataRatio) [[],[],[]]
withRatio = foldr (zipWith (++)) full [fromPrelRatio, fromDataRatio]
ratioCls = $(p [| (eq :: Equivalence (Ratio Int), cmp :: Ordered (Ratio Int)) |])
fromPrelRatio = [ $(p [| (1 :: Ratio Int,
10 :: Ratio Int,
100 :: Ratio Int,
1000 :: Ratio Int,
succ :: Ratio Int -> Ratio Int,
negate :: Ratio Int -> Ratio Int,
abs :: Ratio Int -> Ratio Int,
sum :: (->) [Ratio Int] (Ratio Int),
product :: (->) [Ratio Int] (Ratio Int),
(+) :: Ratio Int -> Ratio Int -> Ratio Int,
() :: Ratio Int -> Ratio Int -> Ratio Int,
(*) :: Ratio Int -> Ratio Int -> Ratio Int,
(/) :: Ratio Int -> Ratio Int -> Ratio Int,
fromIntegral :: Int -> Ratio Int,
properFraction :: (->) (Ratio Int) (Int, Ratio Int),
round :: (->) (Ratio Int) Int,
floor :: (->) (Ratio Int) Int,
ceiling :: (->) (Ratio Int) Int,
(^^) :: Ratio Int -> Int -> Ratio Int) |]),
[],
[] ]
fromDataRatio = [
$(p [| ((%) :: Int -> Int -> Ratio Int,
numerator :: (->) (Ratio Int) Int,
denominator :: (->) (Ratio Int) Int) |]),
[], [] ]
pgWithDouble :: ProgGenSF
pgWithDouble = mkPGXOpt options{tv1=True,nrands=repeat 20,timeout=Just 100000} (eqs++ords++doubleCls) clspartialss withDouble tupartialssNormal
pgWithDoubles :: [ProgGenSF]
pgWithDoubles = map pgWithDoubleSized [0..]
where pgWithDoubleSized sz = mkPGXOpt options{memoCondPure = \t d -> size t < sz && 0<d , tv1=True,nrands=repeat 20,timeout=Just 100000} (eqs++ords++doubleCls) clspartialss withDouble tupartialssNormal
mkPgWithDouble :: IO ProgGenSF
mkPgWithDouble = mkPGXOpts mkTrieOptSFIO options{tv1=True,nrands=repeat 20,timeout=Just 100000} (eqs++ords++doubleCls) clspartialss withDouble tupartialssNormal
withDouble = zipWith (++) full fromPrelDouble
doubleCls = $(p [| (
cmp :: Ordered Double) |])
fromPrelDouble= [ $(p [| (1 :: Double,
10 :: Double,
100 :: Double,
1000 :: Double,
succ :: Double -> Double,
negate :: Double -> Double,
abs :: Double -> Double,
signum :: Double -> Double,
recip :: Double -> Double,
sum :: (->) [Double] Double,
product :: (->) [Double] Double,
(+) :: Double -> Double -> Double,
() :: Double -> Double -> Double,
(*) :: Double -> Double -> Double,
(/) :: Double -> Double -> Double,
fromIntegral :: Int -> Double,
properFraction :: (->) Double (Int, Double),
round :: (->) Double Int,
floor :: (->) Double Int,
ceiling :: (->) Double Int,
truncate :: (->) Double Int,
(^^) :: Double -> Int -> Double,
pi :: Double
) |]),
$(p [| (
exp :: Double -> Double,
log :: Double -> Double,
sqrt :: Double -> Double,
(**) :: Double -> Double -> Double,
logBase :: Double -> Double -> Double,
sin :: Double -> Double,
cos :: Double -> Double,
tan :: Double -> Double,
asin :: Double -> Double,
acos :: Double -> Double,
atan :: Double -> Double,
sinh :: Double -> Double,
cosh :: Double -> Double,
tanh :: Double -> Double,
asinh :: Double -> Double,
acosh :: Double -> Double,
atanh :: Double -> Double,
floatDigits :: Double -> Int,
exponent :: Double -> Int,
significand :: Double -> Double,
scaleFloat :: Int -> Double -> Double,
atan2 :: Double -> Double -> Double
) |]),
[] ]