{-# LANGUAGE CPP
, Rank2Types
, MultiParamTypeClasses
, UndecidableInstances
, FlexibleInstances
#-}
{-# OPTIONS_GHC -Wall -fwarn-tabs #-}
module Control.Unification.STVar
( STVar()
, STBinding()
, runSTBinding
) where
import Prelude hiding (mapM, sequence, foldr, foldr1, foldl, foldl1)
import Data.STRef
#if __GLASGOW_HASKELL__ < 710
import Control.Applicative (Applicative(..), (<$>))
#endif
import Control.Monad (ap)
import Control.Monad.Trans (lift)
import Control.Monad.ST
import Control.Monad.Reader (ReaderT, runReaderT, ask)
import Control.Unification.Types
data STVar s t =
STVar
{-# UNPACK #-} !Int
{-# UNPACK #-} !(STRef s (Maybe (UTerm t (STVar s t))))
instance Show (STVar s t) where
show :: STVar s t -> String
show (STVar Int
i STRef s (Maybe (UTerm t (STVar s t)))
_) = String
"STVar " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i
instance Eq (STVar s t) where
(STVar Int
i STRef s (Maybe (UTerm t (STVar s t)))
_) == :: STVar s t -> STVar s t -> Bool
== (STVar Int
j STRef s (Maybe (UTerm t (STVar s t)))
_) = (Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
j)
instance Variable (STVar s t) where
getVarID :: STVar s t -> Int
getVarID (STVar Int
i STRef s (Maybe (UTerm t (STVar s t)))
_) = Int
i
newtype STBinding s a = STB { STBinding s a -> ReaderT (STRef s Int) (ST s) a
unSTB :: ReaderT (STRef s Int) (ST s) a }
runSTBinding :: (forall s. STBinding s a) -> a
runSTBinding :: (forall s. STBinding s a) -> a
runSTBinding forall s. STBinding s a
stb =
(forall s. ST s a) -> a
forall a. (forall s. ST s a) -> a
runST (Int -> ST s (STRef s Int)
forall a s. a -> ST s (STRef s a)
newSTRef Int
forall a. Bounded a => a
minBound ST s (STRef s Int) -> (STRef s Int -> ST s a) -> ST s a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ReaderT (STRef s Int) (ST s) a -> STRef s Int -> ST s a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (STBinding s a -> ReaderT (STRef s Int) (ST s) a
forall s a. STBinding s a -> ReaderT (STRef s Int) (ST s) a
unSTB STBinding s a
forall s. STBinding s a
stb))
instance Functor (STBinding s) where
fmap :: (a -> b) -> STBinding s a -> STBinding s b
fmap a -> b
f = ReaderT (STRef s Int) (ST s) b -> STBinding s b
forall s a. ReaderT (STRef s Int) (ST s) a -> STBinding s a
STB (ReaderT (STRef s Int) (ST s) b -> STBinding s b)
-> (STBinding s a -> ReaderT (STRef s Int) (ST s) b)
-> STBinding s a
-> STBinding s b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b)
-> ReaderT (STRef s Int) (ST s) a -> ReaderT (STRef s Int) (ST s) b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f (ReaderT (STRef s Int) (ST s) a -> ReaderT (STRef s Int) (ST s) b)
-> (STBinding s a -> ReaderT (STRef s Int) (ST s) a)
-> STBinding s a
-> ReaderT (STRef s Int) (ST s) b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. STBinding s a -> ReaderT (STRef s Int) (ST s) a
forall s a. STBinding s a -> ReaderT (STRef s Int) (ST s) a
unSTB
instance Applicative (STBinding s) where
pure :: a -> STBinding s a
pure = a -> STBinding s a
forall (m :: * -> *) a. Monad m => a -> m a
return
<*> :: STBinding s (a -> b) -> STBinding s a -> STBinding s b
(<*>) = STBinding s (a -> b) -> STBinding s a -> STBinding s b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
*> :: STBinding s a -> STBinding s b -> STBinding s b
(*>) = STBinding s a -> STBinding s b -> STBinding s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
(>>)
STBinding s a
x <* :: STBinding s a -> STBinding s b -> STBinding s a
<* STBinding s b
y = STBinding s a
x STBinding s a -> (a -> STBinding s a) -> STBinding s a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
a -> STBinding s b
y STBinding s b -> STBinding s a -> STBinding s a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> a -> STBinding s a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a
instance Monad (STBinding s) where
return :: a -> STBinding s a
return = ReaderT (STRef s Int) (ST s) a -> STBinding s a
forall s a. ReaderT (STRef s Int) (ST s) a -> STBinding s a
STB (ReaderT (STRef s Int) (ST s) a -> STBinding s a)
-> (a -> ReaderT (STRef s Int) (ST s) a) -> a -> STBinding s a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> ReaderT (STRef s Int) (ST s) a
forall (m :: * -> *) a. Monad m => a -> m a
return
STBinding s a
stb >>= :: STBinding s a -> (a -> STBinding s b) -> STBinding s b
>>= a -> STBinding s b
f = ReaderT (STRef s Int) (ST s) b -> STBinding s b
forall s a. ReaderT (STRef s Int) (ST s) a -> STBinding s a
STB (STBinding s a -> ReaderT (STRef s Int) (ST s) a
forall s a. STBinding s a -> ReaderT (STRef s Int) (ST s) a
unSTB STBinding s a
stb ReaderT (STRef s Int) (ST s) a
-> (a -> ReaderT (STRef s Int) (ST s) b)
-> ReaderT (STRef s Int) (ST s) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= STBinding s b -> ReaderT (STRef s Int) (ST s) b
forall s a. STBinding s a -> ReaderT (STRef s Int) (ST s) a
unSTB (STBinding s b -> ReaderT (STRef s Int) (ST s) b)
-> (a -> STBinding s b) -> a -> ReaderT (STRef s Int) (ST s) b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> STBinding s b
f)
_newSTVar
:: String
-> Maybe (UTerm t (STVar s t))
-> STBinding s (STVar s t)
_newSTVar :: String -> Maybe (UTerm t (STVar s t)) -> STBinding s (STVar s t)
_newSTVar String
fun Maybe (UTerm t (STVar s t))
mb = ReaderT (STRef s Int) (ST s) (STVar s t) -> STBinding s (STVar s t)
forall s a. ReaderT (STRef s Int) (ST s) a -> STBinding s a
STB (ReaderT (STRef s Int) (ST s) (STVar s t)
-> STBinding s (STVar s t))
-> ReaderT (STRef s Int) (ST s) (STVar s t)
-> STBinding s (STVar s t)
forall a b. (a -> b) -> a -> b
$ do
STRef s Int
nr <- ReaderT (STRef s Int) (ST s) (STRef s Int)
forall r (m :: * -> *). MonadReader r m => m r
ask
ST s (STVar s t) -> ReaderT (STRef s Int) (ST s) (STVar s t)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ST s (STVar s t) -> ReaderT (STRef s Int) (ST s) (STVar s t))
-> ST s (STVar s t) -> ReaderT (STRef s Int) (ST s) (STVar s t)
forall a b. (a -> b) -> a -> b
$ do
Int
n <- STRef s Int -> ST s Int
forall s a. STRef s a -> ST s a
readSTRef STRef s Int
nr
if Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
forall a. Bounded a => a
maxBound
then String -> ST s (STVar s t)
forall a. HasCallStack => String -> a
error (String -> ST s (STVar s t)) -> String -> ST s (STVar s t)
forall a b. (a -> b) -> a -> b
$ String
fun String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
": no more variables!"
else do
STRef s Int -> Int -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef STRef s Int
nr (Int -> ST s ()) -> Int -> ST s ()
forall a b. (a -> b) -> a -> b
$! Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1
Int -> STRef s (Maybe (UTerm t (STVar s t))) -> STVar s t
forall s (t :: * -> *).
Int -> STRef s (Maybe (UTerm t (STVar s t))) -> STVar s t
STVar Int
n (STRef s (Maybe (UTerm t (STVar s t))) -> STVar s t)
-> ST s (STRef s (Maybe (UTerm t (STVar s t)))) -> ST s (STVar s t)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (UTerm t (STVar s t))
-> ST s (STRef s (Maybe (UTerm t (STVar s t))))
forall a s. a -> ST s (STRef s a)
newSTRef Maybe (UTerm t (STVar s t))
mb
instance (Unifiable t) =>
BindingMonad t (STVar s t) (STBinding s)
where
lookupVar :: STVar s t -> STBinding s (Maybe (UTerm t (STVar s t)))
lookupVar (STVar Int
_ STRef s (Maybe (UTerm t (STVar s t)))
p) = ReaderT (STRef s Int) (ST s) (Maybe (UTerm t (STVar s t)))
-> STBinding s (Maybe (UTerm t (STVar s t)))
forall s a. ReaderT (STRef s Int) (ST s) a -> STBinding s a
STB (ReaderT (STRef s Int) (ST s) (Maybe (UTerm t (STVar s t)))
-> STBinding s (Maybe (UTerm t (STVar s t))))
-> (ST s (Maybe (UTerm t (STVar s t)))
-> ReaderT (STRef s Int) (ST s) (Maybe (UTerm t (STVar s t))))
-> ST s (Maybe (UTerm t (STVar s t)))
-> STBinding s (Maybe (UTerm t (STVar s t)))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ST s (Maybe (UTerm t (STVar s t)))
-> ReaderT (STRef s Int) (ST s) (Maybe (UTerm t (STVar s t)))
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ST s (Maybe (UTerm t (STVar s t)))
-> STBinding s (Maybe (UTerm t (STVar s t))))
-> ST s (Maybe (UTerm t (STVar s t)))
-> STBinding s (Maybe (UTerm t (STVar s t)))
forall a b. (a -> b) -> a -> b
$ STRef s (Maybe (UTerm t (STVar s t)))
-> ST s (Maybe (UTerm t (STVar s t)))
forall s a. STRef s a -> ST s a
readSTRef STRef s (Maybe (UTerm t (STVar s t)))
p
freeVar :: STBinding s (STVar s t)
freeVar = String -> Maybe (UTerm t (STVar s t)) -> STBinding s (STVar s t)
forall (t :: * -> *) s.
String -> Maybe (UTerm t (STVar s t)) -> STBinding s (STVar s t)
_newSTVar String
"freeVar" Maybe (UTerm t (STVar s t))
forall a. Maybe a
Nothing
newVar :: UTerm t (STVar s t) -> STBinding s (STVar s t)
newVar UTerm t (STVar s t)
t = String -> Maybe (UTerm t (STVar s t)) -> STBinding s (STVar s t)
forall (t :: * -> *) s.
String -> Maybe (UTerm t (STVar s t)) -> STBinding s (STVar s t)
_newSTVar String
"newVar" (UTerm t (STVar s t) -> Maybe (UTerm t (STVar s t))
forall a. a -> Maybe a
Just UTerm t (STVar s t)
t)
bindVar :: STVar s t -> UTerm t (STVar s t) -> STBinding s ()
bindVar (STVar Int
_ STRef s (Maybe (UTerm t (STVar s t)))
p) UTerm t (STVar s t)
t = ReaderT (STRef s Int) (ST s) () -> STBinding s ()
forall s a. ReaderT (STRef s Int) (ST s) a -> STBinding s a
STB (ReaderT (STRef s Int) (ST s) () -> STBinding s ())
-> (ST s () -> ReaderT (STRef s Int) (ST s) ())
-> ST s ()
-> STBinding s ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ST s () -> ReaderT (STRef s Int) (ST s) ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ST s () -> STBinding s ()) -> ST s () -> STBinding s ()
forall a b. (a -> b) -> a -> b
$ STRef s (Maybe (UTerm t (STVar s t)))
-> Maybe (UTerm t (STVar s t)) -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef STRef s (Maybe (UTerm t (STVar s t)))
p (UTerm t (STVar s t) -> Maybe (UTerm t (STVar s t))
forall a. a -> Maybe a
Just UTerm t (STVar s t)
t)