module MagicHaskeller.MemoToFiles where
import System.IO
import System.Directory(doesFileExist, createDirectoryIfMissing)
import MagicHaskeller.ShortString
import Data.ByteString.Char8 as C
import Data.ByteString.Lazy.Char8 as LC
import Control.Monad.Search.Combinatorial
import MagicHaskeller.DebMT
import MagicHaskeller.Types
import MagicHaskeller.PriorSubsts
import Data.Monoid
import Data.Ix
freezePS :: Search m => Type -> PriorSubsts m (Bag e) -> m (Possibility e)
freezePS :: Type -> PriorSubsts m (Bag e) -> m (Possibility e)
freezePS Type
ty PriorSubsts m (Bag e)
ps
= let mxty :: TyVar
mxty = Type -> TyVar
maxVarID Type
ty
in (Possibility e -> Possibility e -> Possibility e)
-> (Possibility e -> Possibility e -> Ordering)
-> m (Possibility e)
-> m (Possibility e)
forall (m :: * -> *) k.
Search m =>
(k -> k -> k) -> (k -> k -> Ordering) -> m k -> m k
mergesortDepthWithBy (\(Bag e
xs,[(TyVar, Type)]
k,TyVar
i) (Bag e
ys,[(TyVar, Type)]
_,TyVar
_) -> (Bag e
xs Bag e -> Bag e -> Bag e
forall a. Monoid a => a -> a -> a
`mappend` Bag e
ys, [(TyVar, Type)]
k, TyVar
i)) (\(Bag e
_,[(TyVar, Type)]
k,TyVar
_) (Bag e
_,[(TyVar, Type)]
l,TyVar
_) -> [(TyVar, Type)]
k [(TyVar, Type)] -> [(TyVar, Type)] -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` [(TyVar, Type)]
l) (m (Possibility e) -> m (Possibility e))
-> m (Possibility e) -> m (Possibility e)
forall a b. (a -> b) -> a -> b
$ TyVar -> PriorSubsts m (Bag e) -> m (Possibility e)
forall (m :: * -> *) es.
Search m =>
TyVar -> PriorSubsts m es -> m (es, [(TyVar, Type)], TyVar)
fps TyVar
mxty PriorSubsts m (Bag e)
ps
fps :: Search m => TyVar -> PriorSubsts m es -> m (es,[(TyVar, Type)],TyVar)
fps :: TyVar -> PriorSubsts m es -> m (es, [(TyVar, Type)], TyVar)
fps TyVar
mxty (PS [(TyVar, Type)] -> TyVar -> m (es, [(TyVar, Type)], TyVar)
f) = do (es
exprs, [(TyVar, Type)]
sub, TyVar
m) <- [(TyVar, Type)] -> TyVar -> m (es, [(TyVar, Type)], TyVar)
f [(TyVar, Type)]
forall a. [a]
emptySubst (TyVar
mxtyTyVar -> TyVar -> TyVar
forall a. Num a => a -> a -> a
+TyVar
1)
(es, [(TyVar, Type)], TyVar) -> m (es, [(TyVar, Type)], TyVar)
forall (m :: * -> *) a. Monad m => a -> m a
return (es
exprs, [(TyVar, Type)] -> TyVar -> [(TyVar, Type)]
filterSubst [(TyVar, Type)]
sub TyVar
mxty, TyVar
m)
where filterSubst :: Subst -> TyVar -> [(TyVar, Type)]
filterSubst :: [(TyVar, Type)] -> TyVar -> [(TyVar, Type)]
filterSubst [(TyVar, Type)]
sub TyVar
mx = [ (TyVar, Type)
t | t :: (TyVar, Type)
t@(TyVar
i,Type
_) <- [(TyVar, Type)]
sub, (TyVar, TyVar) -> TyVar -> Bool
forall a. Ix a => (a, a) -> a -> Bool
inRange (TyVar
0,TyVar
mx) TyVar
i ]
memoPSRTIO :: ShortString b =>
MemoCond
-> MapType (Matrix (Possibility b))
-> (Type -> PriorSubsts (RecompT IO) [b])
-> Type -> PriorSubsts (RecompT IO) [b]
memoPSRTIO :: MemoCond
-> MapType (Matrix (Possibility b))
-> (Type -> PriorSubsts (RecompT IO) [b])
-> Type
-> PriorSubsts (RecompT IO) [b]
memoPSRTIO MemoCond
policy MapType (Matrix (Possibility b))
mt Type -> PriorSubsts (RecompT IO) [b]
f Type
t = ([(TyVar, Type)] -> TyVar -> RecompT IO (Possibility b))
-> PriorSubsts (RecompT IO) [b]
forall (m :: * -> *) a.
([(TyVar, Type)] -> TyVar -> m (a, [(TyVar, Type)], TyVar))
-> PriorSubsts m a
PS (([(TyVar, Type)] -> TyVar -> RecompT IO (Possibility b))
-> PriorSubsts (RecompT IO) [b])
-> ([(TyVar, Type)] -> TyVar -> RecompT IO (Possibility b))
-> PriorSubsts (RecompT IO) [b]
forall a b. (a -> b) -> a -> b
$ \[(TyVar, Type)]
subst TyVar
mx ->
let (Type
tn, Decoder
decoder) = Type -> TyVar -> (Type, Decoder)
encode Type
t TyVar
mx
in ((Possibility b -> Possibility b)
-> RecompT IO (Possibility b) -> RecompT IO (Possibility b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\ ([b]
exprs, [(TyVar, Type)]
sub, TyVar
m) -> ([b]
exprs, Decoder -> [(TyVar, Type)] -> [(TyVar, Type)]
retrieve Decoder
decoder [(TyVar, Type)]
sub [(TyVar, Type)] -> [(TyVar, Type)] -> [(TyVar, Type)]
`plusSubst` [(TyVar, Type)]
subst, TyVar
mxTyVar -> TyVar -> TyVar
forall a. Num a => a -> a -> a
+TyVar
m)) (RecompT IO (Possibility b) -> RecompT IO (Possibility b))
-> RecompT IO (Possibility b) -> RecompT IO (Possibility b)
forall a b. (a -> b) -> a -> b
$ (MemoCond
-> (Type -> Int -> IO [Possibility b])
-> (Type -> RecompT IO (Possibility b))
-> Type
-> RecompT IO (Possibility b)
forall b.
ShortString b =>
MemoCond
-> (Type -> Int -> IO [b])
-> (Type -> RecompT IO b)
-> Type
-> RecompT IO b
memoRTIO MemoCond
policy (\Type
ty Int
depth -> [Possibility b] -> IO [Possibility b]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Possibility b] -> IO [Possibility b])
-> [Possibility b] -> IO [Possibility b]
forall a b. (a -> b) -> a -> b
$ Matrix (Possibility b) -> Stream [Possibility b]
forall a. Matrix a -> Stream (Bag a)
unMx (MapType (Matrix (Possibility b)) -> Type -> Matrix (Possibility b)
forall a. MapType a -> Type -> a
lookupMT MapType (Matrix (Possibility b))
mt Type
ty) Stream [Possibility b] -> Int -> [Possibility b]
forall a. [a] -> Int -> a
!! Int
depth) (\Type
u -> Type -> PriorSubsts (RecompT IO) [b] -> RecompT IO (Possibility b)
forall (m :: * -> *) e.
Search m =>
Type -> PriorSubsts m (Bag e) -> m (Possibility e)
freezePS Type
u (Type -> PriorSubsts (RecompT IO) [b]
f Type
u)) Type
tn))
memoRTIO :: ShortString b =>
MemoCond
-> (Type -> Int -> IO [b])
-> (Type -> RecompT IO b)
-> Type -> RecompT IO b
memoRTIO :: MemoCond
-> (Type -> Int -> IO [b])
-> (Type -> RecompT IO b)
-> Type
-> RecompT IO b
memoRTIO MemoCond
policy Type -> Int -> IO [b]
lor Type -> RecompT IO b
f Type
t = (Int -> IO [b]) -> RecompT IO b
forall (m :: * -> *) a. (Int -> m (Bag a)) -> RecompT m a
RcT ((Int -> IO [b]) -> RecompT IO b)
-> (Int -> IO [b]) -> RecompT IO b
forall a b. (a -> b) -> a -> b
$ MemoCond
-> (Type -> Int -> IO [b])
-> (Type -> Int -> IO [b])
-> Type
-> Int
-> IO [b]
forall b.
ShortString b =>
MemoCond
-> (Type -> Int -> IO [b])
-> (Type -> Int -> IO [b])
-> Type
-> Int
-> IO [b]
memoer MemoCond
policy Type -> Int -> IO [b]
lor (\Type
ty -> RecompT IO b -> Int -> IO [b]
forall (m :: * -> *) a. RecompT m a -> Int -> m (Bag a)
unRcT (Type -> RecompT IO b
f Type
ty)) Type
t
memoer :: ShortString b =>
MemoCond
-> (Type -> Int -> IO [b])
-> (Type -> Int -> IO [b])
-> Type -> Int -> IO [b]
memoer :: MemoCond
-> (Type -> Int -> IO [b])
-> (Type -> Int -> IO [b])
-> Type
-> Int
-> IO [b]
memoer MemoCond
policy Type -> Int -> IO [b]
lor Type -> Int -> IO [b]
f Type
ty Int
depth
= do MemoType
memotype <- MemoCond
policy Type
ty Int
depth
case MemoType
memotype of MemoType
Recompute -> IO [b]
compute
MemoType
Ram -> Type -> Int -> IO [b]
lor Type
ty Int
depth
Disk FilePath
fp | FilePath -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
Prelude.length FilePath
filepath Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
250 -> do
Bool -> FilePath -> IO ()
createDirectoryIfMissing Bool
True FilePath
directory
(ByteString -> Maybe [b])
-> ([b] -> ByteString) -> FilePath -> IO [b] -> IO [b]
forall a.
(ByteString -> Maybe a)
-> (a -> ByteString) -> FilePath -> IO a -> IO a
memoToFile ByteString -> Maybe [b]
forall a. ShortString a => ByteString -> Maybe a
readBriefly [b] -> ByteString
forall a. ShortString a => a -> ByteString
showBriefly FilePath
filepath IO [b]
compute
| Bool
otherwise -> IO [b]
compute
where
directory :: FilePath
directory = FilePath
fpFilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++Int -> FilePath -> FilePath
forall a. Show a => a -> FilePath -> FilePath
shows Int
depth FilePath
"/"
filepath :: FilePath
filepath = FilePath
directory FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ Type -> FilePath
forall a. Show a => a -> FilePath
show Type
ty
where compute :: IO [b]
compute = Type -> Int -> IO [b]
f Type
ty Int
depth
data MemoType = Recompute
| Ram
| Disk FilePath
type MemoCond = Type -> Int -> IO MemoType
memoToFile :: (C.ByteString -> Maybe a)
-> (a -> LC.ByteString)
-> FilePath
-> IO a
-> IO a
memoToFile :: (ByteString -> Maybe a)
-> (a -> ByteString) -> FilePath -> IO a -> IO a
memoToFile ByteString -> Maybe a
parser a -> ByteString
printer FilePath
filepath IO a
compute
= let write :: IO a
write = do a
result <- IO a
compute
FilePath -> ByteString -> IO ()
LC.writeFile FilePath
filepath (a -> ByteString
printer a
result)
a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
result
in do Bool
there <- FilePath -> IO Bool
doesFileExist FilePath
filepath
if Bool
there then do ByteString
cs <- FilePath -> IO ByteString
C.readFile FilePath
filepath
case ByteString -> Maybe a
parser ByteString
cs of Just a
x -> a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
x
Maybe a
_ -> do
Handle -> FilePath -> IO ()
System.IO.hPutStrLn Handle
stderr (FilePath
"File " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
filepath FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
" was broken.")
IO a
write
else IO a
write