--
-- (c) Susumu Katayama
--
\begin{code}
module MagicHaskeller.ProgGenSF(ProgGenSF, PGSF(..), freezePS, funApSub_, funApSub_spec, lookupNormalized, tokoro10fst, mkTrieOptSFIO) where
import MagicHaskeller.Types
import MagicHaskeller.TyConLib
import Control.Monad
import MagicHaskeller.CoreLang
import Control.Monad.Search.Combinatorial
import MagicHaskeller.PriorSubsts
import Data.List(partition, sortBy, sort, nub, (\\))
import Data.Ix(inRange)
import MagicHaskeller.ClassifyDM
import MagicHaskeller.Instantiate
import MagicHaskeller.ProgramGenerator
import MagicHaskeller.ClassLib(mkCL, ClassLib(..), mguPrograms)
import MagicHaskeller.Options(Opt(..))
import MagicHaskeller.Expression
import Data.Monoid
import MagicHaskeller.T10(mergesortWithBy, diffSortedBy)
import qualified Data.Map as M
import MagicHaskeller.DebMT
import Data.Function(fix)
import System.IO(fixIO)
import System.IO.Unsafe(unsafeInterleaveIO)
import Data.Bits
import Data.Word
import Data.Array
#if __GLASGOW_HASKELL__ >= 710
import Prelude hiding ((<$>))
#endif
import Debug.Trace
reorganize_ f av = f $ mergesortWithBy const compare av
reorganizer' = id
reorganizerId' :: (Functor m, Expression e) => ([Type] -> m e) -> [Type] -> m e
reorganizerId' = reorganizeId'
classify = True
traceExpTy _ = id
traceTy _ = id
type ProgGenSF = PGSF CoreExpr
data PGSF e = PGSF (MemoDeb e) TypeTrie (ExpTrie e)
type ExpTip e = Matrix e
type ExpTrie e = MapType (ExpTip e)
type TypeTrie = MapType (Matrix (Type, Subst, TyVar))
lmt :: Expression e => ExpTrie e -> Type -> Matrix e
lmt mt fty = traceExpTy fty $
lookupMT mt fty
filtBF :: Expression e => Common -> Type -> Recomp e -> Matrix e
filtBF cmn ty | classify = dbToCumulativeMx . fmap fromAnnExpr . fDM cmn ty . fmap (toAnnExprWind (execute (opt cmn) (vl cmn)) ty) . fromRc . mapDepth uniqSort
| otherwise = toMx . mapDepth uniqSort
fDM = filterDM
filtBFIO :: Expression e => Common -> Type -> Recomp e -> IO (Matrix e)
filtBFIO cmn ty rc | classify = dbtToCumulativeMx $ fmap fromAnnExpr $ filterDMIO cmn ty $ fmap (toAnnExprWind (execute (opt cmn) (vl cmn)) ty) $ fromRc $ mapDepth uniqSort rc
| otherwise = return $ toMx $ mapDepth uniqSort rc
lmtty mt fty = traceTy fty $
lookupMT mt fty
memocond i = True
instance (Expression e) => ProgramGenerator (PGSF e) where
mkTrieOpt = mkTrieOptSF
matchingProgramsWOAbsents ty (PGSF (_,_,cmn) _ etrie) = fromMx $ zipDepthMx (\i es -> if i < getArity ty 1 then [] else es) $ matchProgs cmn etrie ty
matchingPrograms ty pgsf@(PGSF (_,_,cmn) _ _) = fromRc $ fmap (toAnnExprWindWind (reducer cmn) ty) $ lookupWithAbsents pgsf ty
unifyingPrograms ty pgsf@(PGSF (_,_,cmn) _ _) = catBags $ fromRc $ fmap (\ ((es,_),_,_) -> map (toAnnExpr $ reducer cmn) es) $ unifyingPossibilities ty pgsf
instance Expression e => WithCommon (PGSF e) where
extractCommon (PGSF (_,_,cmn) _ _) = cmn
unifyingPossibilities ty memodeb = unPS (unifyableExprs memodeb [] ty) emptySubst 0
matchProgs :: Expression e => Common -> ExpTrie e -> Type -> Matrix AnnExpr
matchProgs cmn etrie ty = fmap (toAnnExprWindWind (reducer cmn) ty) $ lookupReorganized etrie ty
specializedPossibleTypes :: Type -> MemoDeb CoreExpr -> TypeTrie -> Recomp Type
specializedPossibleTypes ty memodeb ttrie = runPS (fmap (\(av,t) -> popArgs av t) $ specializedTypes memodeb ttrie [] ty)
type MemoDeb e = (ClassLib e, (([[Prim]],[[Prim]]),([[Prim]],[[Prim]])), Common)
mkTrieOptSF :: Expression e => Common -> [Typed [CoreExpr]] -> [[Typed [CoreExpr]]] -> [[Typed [CoreExpr]]] -> PGSF e
mkTrieOptSF cmn classes txsopt txs
= fix $ \pgsf -> PGSF memoDeb typeTrie $ mkMTexp (tcl cmn) (\ty -> filtBF cmn ty $ matchFunctions pgsf ty)
where qtlopt = splitPrimss txsopt
qtl = splitPrimss txs
memoDeb = (mkCL cmn classes, (qtlopt,qtl), cmn)
typeTrie = mkMTty (tcl cmn) (\ty -> freezePS ty (specTypes memoDeb typeTrie ty))
dbToCumulativeMx :: (Ord a) => DBound a -> Matrix a
dbToCumulativeMx (DB f) = Mx $ case map (sort . map fst . f) [0..] of
xss -> let result = zipWith (diffSortedBy compare) xss $ scanl (++) [] result in result
mkTrieOptSFIO :: Expression e => Common -> [Typed [CoreExpr]] -> [[Typed [CoreExpr]]] -> [[Typed [CoreExpr]]] -> IO (PGSF e)
mkTrieOptSFIO cmn classes txsopt txs
= fixIO $ \pgsf -> fmap (PGSF memoDeb typeTrie) $ mkMTIO (tcl cmn) (\ty -> filtBFIO cmn ty $ matchFunctions pgsf ty)
where qtlopt = splitPrimss txsopt
qtl = splitPrimss txs
memoDeb = (mkCL cmn classes, (qtlopt,qtl), cmn)
typeTrie = mkMTty (tcl cmn) (\ty -> freezePS ty (specTypes memoDeb typeTrie ty))
dbtToCumulativeMx :: (Ord a) => DBoundT IO a -> IO (Matrix a)
dbtToCumulativeMx (DBT f) = do ts <- interleaveActions $ map f [0..]
let xss = map (sort . map fst) ts
let result = zipWith (diffSortedBy compare) xss $ scanl (++) [] result
return $ Mx result
mkMTty = mkMT
mkMTexp = mkMT
mondepth = zipDepthRc (\d xs -> trace ("depth="++show d++", and the length is "++show (length xs)) xs)
type BFT = Recomp
unBFM = unMx
freezePS :: Type -> PriorSubsts Recomp Type -> Matrix (Type,Subst,TyVar)
freezePS ty ps
= let mxty = maxVarID ty
in mapDepth tokoro10ap $ toMx $ fmap fst $ Rc $ unDB $ fromRc $ unPS ps emptySubst (mxty+1)
tokoro10 :: (Eq k, Ord k) => [(a,k,i)] -> [(a,k,i)]
tokoro10 = mergesortWithBy const (\ (_,k,_) (_,l,_) -> k `compare` l)
tokoro10ap :: [(Type,s,i)] -> [(Type,s,i)]
tokoro10ap = M.elems . M.fromListWith const . map (\ t@(ty,_,_) -> ( ty, t))
fps :: Search m => TyVar -> PriorSubsts m e -> m (e,[(TyVar, Type)],TyVar)
fps mxty (PS f) = do (exprs, sub, m) <- f emptySubst (mxty+1)
return (exprs, filterSubst sub mxty, m)
where filterSubst :: Subst -> TyVar -> [(TyVar, Type)]
filterSubst sub mx = [ t | t@(i,_) <- sub, inRange (0,mx) i ]
specializedTypes :: (Search m, Expression e) => MemoDeb e -> TypeTrie -> [Type] -> Type -> PriorSubsts m ([Type],Type)
specializedTypes memodeb ttrie avail t = do _ <- specializedCases memodeb ttrie avail t
subst <- getSubst
return (map (apply subst) avail, apply subst t)
specializedCases, specCases :: (Search m, Expression e) => MemoDeb e -> TypeTrie -> [Type] -> Type -> PriorSubsts m BitSet
specializedCases memodeb ttrie = applyDo (specCases memodeb ttrie)
specCases memodeb ttrie avail (t0:->t1) = fmap (`unsafeShiftR` 1) $ specCases memodeb ttrie (t0 : avail) t1
specCases memodeb ttrie avail reqret = reorganize_ (\newavail -> uniExprs_ memodeb ttrie newavail reqret) avail
uniExprs_ :: (Search m, Expression e) => MemoDeb e -> TypeTrie -> [Type] -> Type -> PriorSubsts m BitSet
uniExprs_ memodeb ttrie avail t
= convertPS fromMx $ lookupNormalizedSharedBits (\ixs _ -> ixs) (lookupTypeTrie memodeb ttrie) avail t
lookupReorganized md typ = let (avs, retty) = splitArgs $ normalize typ
in reorganizerId' (\av -> lmt md $ popArgs av retty) avs
specTypes :: Expression e => MemoDeb e -> TypeTrie -> Type -> PriorSubsts Recomp Type
specTypes memodeb ttrie ty
= let (avail,t) = splitArgs ty
in convertPS (zipDepthRc (\i es -> if i < length avail 1 then [] else es)) $ do
reorganize_ (\av -> specCases' memodeb ttrie av t) avail
applyPS ty
instance Monoid BitSet where
mappend = (.|.)
mempty = 0
funApSub_ :: (Search m, Monoid a) => (Type -> PriorSubsts m ()) -> (Type -> PriorSubsts m a) -> (Type -> PriorSubsts m a) -> Type -> PriorSubsts m a
funApSub_ clbehalf lltbehalf behalf (t:=>ts) = do clbehalf t
funApSub_ clbehalf lltbehalf behalf ts
funApSub_ clbehalf lltbehalf behalf (t:>ts) = liftM2 mappend (lltbehalf t) (funApSub_ clbehalf lltbehalf behalf ts)
funApSub_ clbehalf lltbehalf behalf (t:->ts) = liftM2 mappend (behalf t) (funApSub_ clbehalf lltbehalf behalf ts)
funApSub_ clbehalf lltbehalf behalf _t = return mempty
funApSub_spec clbehalf behalf = funApSub_ clbehalf behalf behalf
funApSub_forcingNil :: (Type -> PriorSubsts Recomp ()) -> (Type -> PriorSubsts Recomp BitSet) -> (Type -> PriorSubsts Recomp BitSet) -> Type -> BitSet -> PriorSubsts Recomp ()
funApSub_forcingNil clbehalf lltbehalf behalf t bsf
= funApSub_forcingNil_cont clbehalf lltbehalf behalf t bsf $ \bs -> guard $ bs == 0
funApSub_forcingNil_spec clbehalf behalf = funApSub_forcingNil clbehalf behalf behalf
funApSub_forcingNil_cont :: (Type -> PriorSubsts Recomp ()) -> (Type -> PriorSubsts Recomp BitSet) -> (Type -> PriorSubsts Recomp BitSet) -> Type -> BitSet -> (BitSet->PriorSubsts Recomp a) -> PriorSubsts Recomp a
funApSub_forcingNil_cont clbehalf lltbehalf behalf (t:=>ts) bsf cont = do clbehalf t
funApSub_forcingNil_cont clbehalf lltbehalf behalf ts bsf cont
funApSub_forcingNil_cont clbehalf lltbehalf behalf (t:>ts) bsf cont = do bse <- lltbehalf t
let newRemaining = bsf .&. complement bse
forceNil newRemaining $
funApSub_forcingNil_cont clbehalf lltbehalf behalf ts newRemaining cont
funApSub_forcingNil_cont clbehalf lltbehalf behalf (t:->ts) bsf cont = do bse <- behalf t
let newRemaining = bsf .&. complement bse
forceNil newRemaining $
funApSub_forcingNil_cont clbehalf lltbehalf behalf ts newRemaining cont
funApSub_forcingNil_cont clbehalf lltbehalf behalf _t bsf cont = cont bsf
funApSub_forcingNil_cont_spec clbehalf behalf = funApSub_forcingNil_cont clbehalf behalf behalf
mguAssumptionsBits :: (Functor m, MonadPlus m) => Type -> [Type] -> PriorSubsts m BitSet
mguAssumptionsBits patty assumptions = applyDo mguAssumptionsBits' assumptions patty
mguAssumptionsBits' assumptions patty = msum $ zipWith (\n t -> mguPS patty t >> return (1 `shiftL` n)) [0..] assumptions
specCases' :: Expression e => MemoDeb e -> TypeTrie -> [Type] -> Type -> PriorSubsts Recomp ()
specCases' memodeb@(CL classLib, (prims@(primgen,primmono),_),cmn) ttrie avail reqret
= mapSum retPrimMono primmono `mplus` msum (zipWith retMono (iterate (`unsafeShiftL` 1) 1) avail) `mplus` mapSum retGen primgen
where fas | constrL $ opt cmn = funApSub_ clbehalf lltbehalf behalf
| otherwise = funApSub_spec clbehalf behalf
fasf| constrL $ opt cmn = funApSub_forcingNil clbehalf lltbehalf behalf
| otherwise = funApSub_forcingNil_spec clbehalf behalf
behalf = specializedCases memodeb ttrie avail
lltbehalf ty = mguAssumptionsBits ty avail
clbehalf ty = mguPrograms classLib ty >> return ()
lenavails = length avail
fullBits | lenavails > 29 = 0
| otherwise = (1 `unsafeShiftL` lenavails) 1
retPrimMono (_, arity, retty, numtvs, _xs:::ty)
= napply arity delayPS $
do tvid <- reserveTVars numtvs
mguPS reqret (mapTV (tvid+) retty)
fasf (mapTV (tvid+) ty) fullBits
retMono ix ty = napply (getArity ty) delayPS $ do
mguPS reqret (getRet ty)
fasf ty $ fullBits .&. complement ix
retGen (_, arity, _r, numtvs, _s:::ty) = napply arity delayPS $
do tvid <- reserveTVars numtvs
mkSubsts (tvndelay $ opt cmn) tvid reqret
funApSub_forcingNil_cont_spec clbehalf behalf (mapTV (tvid+) ty) fullBits $ \i -> do
gentvar <- applyPS (TV tvid)
guard (orderedAndUsedArgs gentvar)
fasf gentvar i
lookupWithAbsents :: (Search m, Expression e) => PGSF e -> Type -> m e
lookupWithAbsents memodeb ty
= case splitArgs ty of
(a,r) -> wind (fmap (mapCE Lambda)) (lookupNormalizedSharedET (lookupTypeTrieAndExpTrie memodeb)) a r
lookupNormalizedSharedET :: (Search m, Search n, Expression e) => (Type -> m ([e], Subst, TyVar)) -> [Type] -> Type -> n e
lookupNormalizedSharedET fun avail t
= let annAvails = zip [0..] avail
in fromRc $ Rc $ \d -> [ decodeVars (length avail) ixs e
| avs <- combs (d+1) annAvails
, let (ixs, newavails) = unzip avs
(tn, _decoder) = encode newt (maxVarID newt + 1)
newt = popArgs newavails t
, (exprs, _, _) <- unRc (toRc (fun tn)) d
, e <- exprs
]
type Generator m e = PGSF e -> [Type] -> Type -> PriorSubsts m ([e], BitSet)
unifyableExprs :: Expression e => Generator Recomp e
unifyableExprs memodeb
= applyDo (wind (fmap (\ (es, bs) -> (map (mapCE Lambda) es, bs `unsafeShiftR` 1)))
(\avail -> lookupNormalizedShared (\ixs ixBits e -> (map (decodeVars (length avail) ixs) e, ixBits)) (lookupTypeTrieAndExpTrie memodeb) avail))
memocondexp t d = size t < 8 && 0<d && d<7
lookupTypeTrie :: Expression e => MemoDeb e -> TypeTrie -> Type -> Recomp (Type, Subst, TyVar)
lookupTypeTrie memodeb@(_, _, cmn) ttrie t
= Rc $ \d -> unMx (if memoCondPure (opt cmn) t d
then lookupNorm (lmtty ttrie) t
else freezePS t $ specTypes memodeb ttrie t ) !! d
lookupTypeTrieAndExpTrie :: Expression e => PGSF e -> Type -> Recomp ([e], Subst, TyVar)
lookupTypeTrieAndExpTrie (PGSF memodeb@(_, _, cmn) ttrie etrie) t
= Rc $ \d -> if memoCondPure (opt cmn) t d
then [ (unMx (lookupReorganized etrie $ apply s t) !! d, s, i)
| (_ty, s, i) <- unMx (lookupNormReorganized (lmtty ttrie) t) !! d ]
else
[ (unMx (lookupReorganized etrie $ apply s t) !! d, s, i)
| (ty, s, i) <- unMx (freezePS t $ specTypes memodeb ttrie t) !! d ]
lookupNormReorganized fun typ = let (avs, retty) = splitArgs typ
in reorganize_ (\av -> lookupNorm fun (popArgs av retty)) avs
lookupNorm :: MonadPlus m => (Type -> m (e, Subst, TyVar)) -> Type -> m (e, Subst, TyVar)
lookupNorm = id
lookupNormalized :: (Functor m, MonadPlus m) => (Type -> m (e, Subst, TyVar)) -> [Type] -> Type -> PriorSubsts m e
lookupNormalized fun avail t
= do mx <- getMx
let typ = popArgs avail t
(tn, decoder) = encode typ mx
(es, sub, m) <- mkPS (fun tn)
updatePS (retrieve decoder sub)
updateMx (m+)
return es
lookupNormalizedShared :: (Search m, Search n) => ([Int8] -> BitSet -> e -> r) -> (Type -> m (e, Subst, TyVar)) -> [Type] -> Type -> PriorSubsts n r
lookupNormalizedShared ceDecoder fun avail t
= let annAvails = zip3 [0..] (iterate (`unsafeShiftL` 1) 1) avail
in PS (\subst mx -> fromRc $ Rc $ \d ->concat
[ map (\ (exprs, sub, m) -> (ceDecoder ixs ixBits exprs, retrieve decoder sub `plusSubst` subst, mx+m)) $ unRc (toRc (fun tn)) d
| annAvs <- combs (d+1) annAvails
, let (ixs, ixBitss, newavails) = unzip3 annAvs
ixBits = foldl (.|.) 0 ixBitss
(tn, decoder) = encode (popArgs newavails t) mx
])
type BitSet = Word32
#if __GLASGOW_HASKELL__ < 706
countBits = countBits32
#else
countBits = popCount
#endif
lookupNormalizedSharedBits :: (Search m, Search n) => (BitSet -> e -> r) -> (Type -> m (e, Subst, TyVar)) -> [Type] -> Type -> PriorSubsts n r
lookupNormalizedSharedBits f = lookupNormalizedShared (const f)
tokoro10fst :: (Eq k, Ord k) => [(k,s,i)] -> [(k,s,i)]
tokoro10fst = M.elems . M.fromListWith const . map (\ t@(k,_,_) -> (k,t))
matchFunctions :: (Expression e) => PGSF e -> Type -> Recomp e
matchFunctions memodeb ty =
case splitArgs (saferQuantify ty) of (avail,t) -> matchFuns memodeb avail t
matchFuns :: Expression e => PGSF e -> [Type] -> Type -> Recomp e
matchFuns memodeb avail reqret = zipDepthRc (\i es -> if i < length avail 1 then [] else es) $ catBags $ runPS (matchFuns' unifyableExprs memodeb avail reqret)
matchFuns' :: Expression e => Generator Recomp e -> PGSF e -> [Type] -> Type -> PriorSubsts Recomp [e]
matchFuns' rec md@(PGSF (CL classLib, (_,(primgen,primmono)),cmn) _ _) avail reqret
= let clbehalf = mguPrograms classLib
behalf = rec md avail
lltbehalf = lookupListrie lenavails rec md avail
lenavails = length avail
fullBits | lenavails > 29 = 0
| otherwise = (1 `unsafeShiftL` lenavails) 1
fe = filtExprs (guess $ opt cmn)
in fromAssumptionsBits cmn lenavails fullBits behalf (\a b -> guard $ a==b) reqret avail `mplus`
convertPS (zipDepthRc (\i es -> if i < lenavails then [] else es))
(mapSum (retPrimMonoBits cmn lenavails fullBits clbehalf lltbehalf behalf matchPS reqret) primmono `mplus`
mapSum (( if tv0 $ opt cmn then retGenTV0Bits else
if tv1 $ opt cmn then retGenTV1Bits else retGenOrdBits) cmn lenavails fullBits fe clbehalf lltbehalf behalf reqret) primgen)
fromAssumptionsBits :: (Expression e) => Common -> Int -> BitSet -> (Type -> PriorSubsts Recomp ([e],BitSet)) -> (Type -> Type -> PriorSubsts Recomp ()) -> Type -> [Type] -> PriorSubsts Recomp [e]
fromAssumptionsBits cmn lenavails fullBits behalf mps reqret avail = msum $ map (retMonoBits cmn lenavails fullBits behalf (flip mps reqret)) (zip [0..] avail)
retMonoBits :: (Expression e) => Common -> Int -> BitSet -> (Type -> PriorSubsts Recomp ([e],BitSet)) -> (Type -> PriorSubsts Recomp ()) -> (Int, Type) -> PriorSubsts Recomp [e]
retMonoBits cmn lenavails fullBits behalf tok fromBlah
= do let (n, ty) = fromBlah
(arity,args,retty) = revSplitArgs ty
tok retty
convertPS (ndelay arity) $
funApSubBits_forcingNil undefined behalf behalf ty ([ mkHead (reducer cmn) lenavails 0 arity $ X $ fromIntegral n], fullBits `clearBit` n)
retPrimMonoBits :: (Expression e) => Common -> Int -> BitSet -> (Type -> PriorSubsts Recomp [e]) -> (Type -> PriorSubsts Recomp ([e],BitSet)) -> (Type -> PriorSubsts Recomp ([e],BitSet)) -> (Type -> Type -> PriorSubsts Recomp ()) -> Type -> Prim -> PriorSubsts Recomp [e]
retPrimMonoBits cmn lenavails fullBits clbehalf lltbehalf behalf mps reqret (numcxts, arity, retty, numtvs, xs:::ty)
= do tvid <- reserveTVars numtvs
mps (mapTV (tvid+) retty) reqret
convertPS (ndelay arity) $
funApSubBits_forcingNil clbehalf lltbehalf behalf (mapTV (tvid+) ty) (map (mkHead (reducer cmn) lenavails numcxts arity) xs, fullBits)
funApSubBits, funApSubBits_resetting :: (Search m, Expression e) => (Type -> PriorSubsts m [e]) -> (Type -> PriorSubsts m ([e],BitSet)) -> (Type -> PriorSubsts m ([e],BitSet)) -> Type -> ([e],BitSet) -> PriorSubsts m ([e],BitSet)
funApSubBits = funApSubOpBits (<$>)
funApSubOpBits op clbehalf lltbehalf behalf = faso
where faso (t:=>ts) (funs, bsf)
= do args <- clbehalf t
faso ts (liftM2 op funs args, bsf)
faso (t:> ts) (funs, bsf)
= do (args, bse) <- lltbehalf t
faso ts (liftM2 op funs args, bsf .|. bse)
faso (t:->ts) (funs, bsf)
= do (args, bse) <- behalf t
faso ts (liftM2 op funs args, bsf .|. bse)
faso _ tup = return tup
funApSubBits_resetting = funApSubOpBits_resetting (<$>)
funApSubOpBits_resetting op clbehalf lltbehalf behalf = faso
where faso (t:=>ts) (funs, bsf)
= do args <- clbehalf t
faso ts (liftM2 op funs args, bsf)
faso (t:> ts) (funs, bsf)
= do (args, bse) <- lltbehalf t
faso ts (liftM2 op funs args, bsf .&. complement bse)
faso (t:->ts) (funs, bsf)
= do (args, bse) <- behalf t
faso ts (liftM2 op funs args, bsf .&. complement bse)
faso _ tup = return tup
fapBits behalf ts tups = foldM (\ (fs,bsf) t -> do (args, bse) <- behalf t
return (liftM2 (<$>) fs args, bsf .|. bse))
tups
ts
forceNil :: BitSet -> PriorSubsts Recomp e -> PriorSubsts Recomp e
forceNil newRemaining = convertPS (zipDepthRc (\i es -> if i < countBits newRemaining 1 then [] else es))
funApSubBits_forcingNil :: (Expression e) => (Type -> PriorSubsts Recomp [e]) -> (Type -> PriorSubsts Recomp ([e],BitSet)) -> (Type -> PriorSubsts Recomp ([e],BitSet)) -> Type -> ([e],BitSet) -> PriorSubsts Recomp [e]
funApSubBits_forcingNil clbehalf lltbehalf behalf ty = funApSubOpBits_forcingNil (aeAppErr (" to the request of "++show ty)) clbehalf lltbehalf behalf ty
funApSubBits_forcingNil_cont :: (Expression e) => (Type -> PriorSubsts Recomp [e]) -> (Type -> PriorSubsts Recomp ([e],BitSet)) -> (Type -> PriorSubsts Recomp ([e],BitSet)) -> Type -> ([e],BitSet) -> (([e],BitSet) -> PriorSubsts Recomp [e]) -> PriorSubsts Recomp [e]
funApSubBits_forcingNil_cont clbehalf lltbehalf behalf ty = funApSubOpBits_forcingNil_cont (aeAppErr (" to the request of "++show ty)) clbehalf lltbehalf behalf ty
funApSubOpBits_forcingNil_cont op clbehalf lltbehalf behalf = faso
where faso (t:=>ts) (funs, bsf) cont
= do args <- clbehalf t
faso ts (liftM2 op funs args, bsf) cont
faso (t:> ts) (funs, bsf) cont
= do (args, bse) <- lltbehalf t
let newRemaining = bsf .&. complement bse
forceNil newRemaining $
faso ts (liftM2 op funs args, newRemaining) cont
faso (t:->ts) (funs, bsf) cont
= do (args, bse) <- behalf t
let newRemaining = bsf .&. complement bse
forceNil newRemaining $
faso ts (liftM2 op funs args, newRemaining) cont
faso _ (funs, bsf) cont = cont (funs, bsf)
funApSubOpBits_forcingNil op clbehalf lltbehalf behalf t tup
= funApSubOpBits_forcingNil_cont op clbehalf lltbehalf behalf t tup $ \(funs, bsf) ->
do guard $ bsf == 0
return funs
countBits32 bin
= let quad = bin ((bin `unsafeShiftR` 1) .&. 0x55555555)
hex = (quad .&. 0x33333333) + ((quad `unsafeShiftR` 2) .&. 0x33333333)
in fromIntegral $ ((((hex + (hex `unsafeShiftR` 4)) .&. 0x0F0F0F0F) * 0x01010101) `unsafeShiftR` 24) .&. 0xFF
retGenOrdBits cmn lenavails fullBits fe clbehalf lltbehalf behalf reqret (numcxts, arity, _retty, numtvs, xs:::ty)
= convertPS (ndelay arity) $ do tvid <- reserveTVars numtvs
a <- mkSubsts (tvndelay $ opt cmn) tvid reqret
(exprs, bs1) <- funApSubBits_resetting clbehalf lltbehalf behalf (mapTV (tvid+) ty) (map (mkHead (reducer cmn) lenavails numcxts (arity+a)) xs, fullBits)
gentvar <- applyPS (TV tvid)
guard (orderedAndUsedArgs gentvar)
(es, bs2) <- funApSub'' False gentvar (fe gentvar ty exprs, bs1)
guard $ bs2 == 0
return es
where
funApSub'' filtexp (t:->ts@(u:->_)) (funs, bs)
| otherwise = do (args, ixs) <- behalf t
funApSub'' (t==u) ts (if filtexp then [ f <$> e | f <- funs, e <- args, let _:$d = toCE f, d <= toCE e ]
else liftM2 (<$>) funs args,
bs .&. complement ixs)
funApSub'' filtexp (t:->ts) (funs, bs)
= do (args, ixs) <- behalf t
return (if filtexp then [ f <$> e | f <- funs, e <- args, let _:$d = toCE f, d <= toCE e]
else liftM2 (<$>) funs args,
bs .&. complement ixs)
funApSub'' _fe _t tups = return tups
retGenTV1Bits cmn lenavails fullBits fe clbehalf lltbehalf behalf reqret (numcxts, arity, _retty, numtvs, xs:::ty)
= convertPS (ndelay arity) $ do tvid <- reserveTVars numtvs
a <- mkSubst (tvndelay $ opt cmn) tvid reqret
funApSubBits_forcingNil_cont clbehalf lltbehalf behalf (mapTV (tvid+) ty) (map (mkHead (reducer cmn) lenavails numcxts (arity+a)) xs, fullBits) $ \(exprs, bs1) -> do
gentvar <- applyPS (TV tvid)
guard (usedArg (tvid+1) gentvar)
funApSubBits_forcingNil clbehalf lltbehalf behalf gentvar (fe gentvar ty exprs, bs1)
retGenTV0Bits cmn lenavails fullBits fe clbehalf lltbehalf behalf reqret (numcxts, arity, _retty, numtvs, xs:::ty)
= convertPS (ndelay arity) $ do tvid <- reserveTVars numtvs
updatePS (unitSubst tvid reqret)
exprs <- funApSubBits_forcingNil clbehalf lltbehalf behalf (mapTV (tvid+) ty) (map (mkHead (reducer cmn) lenavails numcxts arity) xs, fullBits)
gentvar <- applyPS (TV tvid)
return $ fe gentvar ty exprs
matchAssumptionsBits :: (Functor m, MonadPlus m, Expression e) => Common -> Int -> Type -> [Type] -> PriorSubsts m ([e],BitSet)
matchAssumptionsBits cmn lenavails reqty assumptions
= do s <- getSubst
let newty = apply s reqty
(numcxts, arity) = getArities newty
msum $ zipWith (\n t -> matchPS newty t >> return ([mkHead (reducer cmn) lenavails numcxts arity (X n)], 1 `shiftL` fromIntegral n)) [0..] assumptions
lookupListrie :: (Search m, Expression e) => Int -> Generator m e -> Generator m e
lookupListrie lenavails rec memodeb avail t
| constrL opts = matchAssumptionsBits cmn lenavails t avail
| guess opts = do
(args, ixBits) <- rec memodeb avail t
let args' = filter (not.isClosed.toCE) args
when (null args') mzero
return (args', ixBits)
| otherwise = do
(args, ixBits) <- rec memodeb avail t
let args' = filter (not.isConstrExpr.toCE) args
when (null args') mzero
return (args', ixBits)
where opts = opt cmn
cmn = extractCommon memodeb
\end{code}