#define CHTO
module MagicHaskeller.ClassifyDM(filterDM, filterList, filterListDB, filterDMIO, spreexecuteDM) where
import Control.Monad.Search.Combinatorial
import Data.Maybe
import MagicHaskeller.Instantiate
import MagicHaskeller.Types
import MagicHaskeller.TyConLib
import MagicHaskeller.DebMT
import MagicHaskeller.MyDynamic
#ifdef CHTO
import System.IO.Unsafe
import MagicHaskeller.TimeOut
import Data.IORef
#endif
import MagicHaskeller.T10(mergesortWithBy, mergesortWithByBot, mergesortWithByBotIO)
import MagicHaskeller.PriorSubsts
import MagicHaskeller.Classify(opreexecute, ofilterDB, CmpBot, cmpBot, cmpBotIO)
import MagicHaskeller.Expression
import MagicHaskeller.ProgramGenerator(Common(..))
import MagicHaskeller.Options(Opt(..))
sortWithByBot = mergesortWithByBot
select :: DBound ([[Dynamic]], AnnExpr) -> DBound ([Dynamic], AnnExpr)
select = zipDepthDB $ \d -> map (\((xss,ae),i) -> (((xss!!d), ae),i))
spreexecuteDM :: (Dynamic->Dynamic) -> [[Dynamic]] -> AnnExpr -> ([[Dynamic]], AnnExpr)
spreexecuteDM uncurrier rnds e@(AE _ dyn) = let f = uncurrier dyn in (map ( map (dynAppErr "in ClassifyDM.spreexecuteDM" f)) rnds, e)
sprDM :: (Dynamic->Dynamic) -> [[Dynamic]] -> AnnExpr -> Int -> ([Dynamic], AnnExpr)
sprDM unc rnds e db = case spreexecuteDM unc rnds e of (xss, ae) -> (xss!!db, ae)
forceList :: [a] -> [a]
forceList [] = []
forceList xs@(y:ys) = y `seq` forceList ys `seq` xs
filterList :: Common -> Type -> Int -> [AnnExpr] -> [AnnExpr]
filterList cmn typ db
= case typeToRandomsOrdDM (nrands $ opt cmn) (tcl cmn) (rt cmn) typ of
Nothing -> id
Just ([], op) ->
sortWithByBot const (\(AE _ k) (AE _ l) -> cmpBot (op, opt cmn) k l)
Just (rndss,op) ->
map snd .
sortWithByBot const
(nthCompareBot (nrands $ opt cmn) db (op, opt cmn)) .
map (\ae -> sprDM (uncurryDyn (mkUncurry $ tcl cmn) typ) rndss ae db)
filterListDB :: Common -> Type -> [AnnExpr] -> DBound [AnnExpr]
filterListDB cmn typ aes
= DB $ \db -> [(filterList cmn typ db aes,db)]
filterDM :: DB m => Common -> Type -> m AnnExpr -> m AnnExpr
filterDM cmn typ
= case typeToRandomsOrdDM (nrands $ opt cmn) (tcl cmn) (rt cmn) typ of
Nothing -> id
Just ([], op) ->
mapDepthDB $ sortWithByBot const (\((AE _ k),_) ((AE _ l),_) -> cmpBot (op, opt cmn) k l)
Just (rndss,op) ->
zipDepthDB (\d -> map (\((_dyns,ae),i) -> (ae,i)) .
sortWithByBot (\x@(_,i) y@(_,j) -> if i<j then y else x)
(\(k,_) (l,_) -> nthCompareBot (nrands $ opt cmn) d (op, opt cmn) k l) .
map (\(ae,i) -> (sprDM (uncurryDyn (mkUncurry $ tcl cmn) typ) rndss ae d, i)))
filterDMIO :: Common -> Type -> DBound AnnExpr -> DBoundT IO AnnExpr
filterDMIO cmn typ db
= case typeToRandomsOrdDM (nrands $ opt cmn) (tcl cmn) (rt cmn) typ of
Nothing -> fromDB db
Just ([], op) ->
DBT $ \d -> mergesortWithByBotIO const (\((AE _ k),_) ((AE _ l),_) -> cmpBotIO (op, opt cmn) k l) $ unDB db d
Just (rndss,op) ->
DBT $ \d -> fmap (map (\ ((_dyns,ae),i) -> (ae,i))) $
mergesortWithByBotIO (\x@(_,i) y@(_,j) -> if i<j then y else x)
(\ (k,_) (l,_) -> nthCompareBotIO (nrands $ opt cmn) d (op, opt cmn) k l)
(map (\(ae,i) -> (sprDM (uncurryDyn (mkUncurry $ tcl cmn) typ) rndss ae d, i)) $ unDB db d)
filterDMlite :: Common -> Type -> DBound AnnExpr -> DBound AnnExpr
filterDMlite cmn typ
= case typeToRandomsOrdDM (nrands $ opt cmn) (tcl cmn) (rt cmn) typ of
Nothing -> id
Just ([], op) ->
mapDepthDB $ sortWithByBot const (\((AE _ k),_) ((AE _ l),_) -> cmpBot (op, opt cmn) k l)
Just (rndss,op) ->
zipDepthDB (\d -> map (\((_dyns,ae),i) -> (ae,i)) .
shrink const (\k l -> nthCompareBot (nrands $ opt cmn) d (op, opt cmn) k l) d .
map (\(ae,i) -> (sprDM (uncurryDyn (mkUncurry $ tcl cmn) typ) rndss ae i , i)))
listCmp :: Int -> (a->a->Ordering) -> [a] -> [a] -> Ordering
listCmp 0 cmp _ _ = EQ
listCmp n cmp [] [] = EQ
listCmp n cmp (x:xs) (y:ys) = case cmp x y of EQ -> listCmp (n1) cmp xs ys
c -> c
nthCompareBot :: [Int] -> Int -> CmpBot a -> ([a],e) -> ([a],e) -> Maybe Ordering
nthCompareBot nrnds m cmp (xs,_) (ys,_) = listCmpBot (nrnds !! m) cmp xs ys
listCmpBot :: Int -> CmpBot a -> [a] -> [a] -> Maybe Ordering
#ifdef CHTO
listCmpBot len (cmp,pto) xs ys = unsafeWithPTOOpt pto $ listCmp len cmp xs ys
#else
listCmpBot len (cmp,_) xs ys = Just $ listCmp len cmp xs ys
#endif
nthCompareBotIO :: [Int] -> Int -> CmpBot a -> ([a],e) -> ([a],e) -> IO (Maybe Ordering)
nthCompareBotIO nrnds m cmp (xs,_) (ys,_) = listCmpBotIO (nrnds !! m) cmp xs ys
listCmpBotIO :: Int -> CmpBot a -> [a] -> [a] -> IO (Maybe Ordering)
#ifdef CHTO
listCmpBotIO len (cmp,pto) xs ys = maybeWithTOOpt pto $ return $! listCmp len cmp xs ys
#else
listCmpBotIO len (cmp,_) xs ys = return $ Just $ listCmp len cmp xs ys
#endif
sfilterDM :: [Int] -> CmpBot k -> DBound ([k],e) -> DBound ([k],e)
sfilterDM nrnds cmp = zipDepthDB $ \d -> sortWithByBot (\x@(_,i) y@(_,j) -> if i<j then y else x) (\(k,_) (l,_) -> nthCompareBot nrnds d cmp k l)