--
-- (c) Susumu Katayama
--
\begin{code}
module MagicHaskeller.ClassLib(mkCL, ClassLib(..), mguPrograms) where
import MagicHaskeller.Types
import MagicHaskeller.TyConLib
import Control.Monad
import Data.Monoid
import MagicHaskeller.CoreLang
import Control.Monad.Search.Combinatorial
import MagicHaskeller.PriorSubsts
import Data.List(partition, sortBy, genericLength)
import Data.Ix(inRange)
import MagicHaskeller.ProgramGenerator
import MagicHaskeller.Classify
import MagicHaskeller.Instantiate
import MagicHaskeller.Expression
import MagicHaskeller.T10
import MagicHaskeller.DebMT
traceTy _ = id
type BF = Recomp
type BFM = Matrix
fromMemo :: Search m => Matrix a -> m a
fromMemo = fromMx
toMemo :: Search m => m a -> Matrix a
toMemo = toMx
newtype ClassLib e = CL (MemoDeb e)
type MemoTrie a = MapType (BFM (Possibility a))
lmt mt fty =
traceTy fty $
lookupMT mt fty
lookupFunsPoly :: (Search m, Expression e) => Generator m e -> Generator m e
lookupFunsPoly behalf memodeb@(mt,_,cmn) reqret
= PS (\subst mx ->
let (tn, decoder) = encode reqret mx
in
(fmap (\ (exprs, sub, m) -> (exprs, retrieve decoder sub `plusSubst` subst, mx+m)) $ fromMemo $ lmt mt tn)
)
type MemoDeb a = (MemoTrie a, [[Prim]], Common)
mkCL :: Expression e => Common -> [Typed [CoreExpr]] -> ClassLib e
mkCL cmn classes = CL $ mkTrieMD [map annotateTCEs classes] cmn
mkTrieMD :: (Expression e) => [[Prim]] -> Common -> MemoDeb e
mkTrieMD qtl cmn
= let trie = mkMT (tcl cmn) (\ty -> fromRc (freezePS ty (mguFuns memoDeb ty)))
memoDeb = (trie,qtl,cmn)
in memoDeb
freezePS :: (Search m, Expression e) => Type -> PriorSubsts m (Bag e) -> m (Possibility e)
freezePS ty ps
= let mxty = maxVarID ty
in mergesortDepthWithBy (\(xs,k,i) (ys,_,_) -> (xs `mappend` ys, k, i)) (\(_,k,_) (_,l,_) -> k `compare` l) $ fps mxty ps
fps :: (Search m, Expression e) => TyVar -> PriorSubsts m [e] -> m ([e],[(TyVar, Type)],TyVar)
fps mxty (PS f) = do
(es, sub, m) <- f emptySubst (mxty+1)
guard $ not $ length es `seq` null es
return (es, filterSubst sub mxty, m)
where filterSubst :: Subst -> TyVar -> [(TyVar, Type)]
filterSubst sub mx = [ t | t@(i,_) <- sub, inRange (0,mx) i ]
type Generator m e = MemoDeb e -> Type -> PriorSubsts m [e]
mguPrograms, mguFuns :: (Search m, Expression e) => Generator m e
mguPrograms memodeb ty = do subst <- getSubst
lookupFunsPoly mguFuns memodeb (apply subst ty)
mguFuns memodeb = generateFuns mguPrograms memodeb
generateFuns :: (Search m, Expression e) =>
Generator m e
-> Generator m e
generateFuns rec memodeb@(_mt, primmono,cmn) reqret
= let clbehalf = error "generateFuns: cannot happen."
behalf = rec memodeb
lltbehalf = error "generateFuns: cannot happen."
lenavails = 0
in mapSum (retPrimMono cmn lenavails clbehalf lltbehalf behalf mguPS reqret) primmono
\end{code}