Substitute with the version from the video
This commit is contained in:
parent
288c999c0e
commit
2e819b454f
@ -1,49 +1,50 @@
|
|||||||
module Binding
|
module Binding
|
||||||
( newVar, unify, instantiate
|
( newVar, unify, instantiate
|
||||||
) where
|
) where
|
||||||
|
import Primitives
|
||||||
import Terms
|
import Terms
|
||||||
import Nondeterminism
|
import Nondeterminism
|
||||||
import Primitives
|
import Control.Monad
|
||||||
import Control.Monad
|
|
||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
|
|
||||||
newVar :: Name -> PrologStream Var
|
newVar :: Name -> PrologStream Slot
|
||||||
newVar name = reversibly (newVarPrim name) unnewVarPrim
|
newVar name = reversibly (newVarPrim name) unnewVarPrim
|
||||||
|
|
||||||
getVar :: Var -> PrologStream (Maybe Term)
|
getVar :: Slot -> PrologStream (Maybe Term)
|
||||||
getVar var = liftPrologIO (getVarPrim var)
|
getVar slot = liftPrologIO (getVarPrim slot)
|
||||||
|
|
||||||
setVar :: Var -> Term -> PrologStream ()
|
setVar :: Slot -> Term -> PrologStream ()
|
||||||
setVar var value = reversibly set unset
|
setVar slot value = reversibly set unset
|
||||||
where
|
where
|
||||||
set = do
|
set = do
|
||||||
oldValue <- getVarPrim var
|
oldValue <- getVarPrim slot
|
||||||
when (oldValue /= Nothing) (errorPrim "cannot set var that is currently set")
|
when (oldValue /= Nothing) (errorPrim "cannot set var that is already set")
|
||||||
setVarPrim var (Just value)
|
setVarPrim slot (Just value)
|
||||||
unset = do
|
unset = do
|
||||||
oldValue <- getVarPrim var
|
oldValue <- getVarPrim slot
|
||||||
when (oldValue == Nothing) (errorPrim "cannot unset var that is already unset")
|
when (oldValue == Nothing) (errorPrim "cannot unset var that is already unset")
|
||||||
setVarPrim var Nothing
|
setVarPrim slot Nothing
|
||||||
|
|
||||||
unify :: Term -> Term -> PrologStream ()
|
unify :: Term -> Term -> PrologStream ()
|
||||||
unify (Compound h0 args0) (Compound h1 args1) = do
|
unify (Compound h0 args0) (Compound h1 args1) = do
|
||||||
when (h0 /= h1) empty
|
when (h0 /= h1) empty
|
||||||
when (length args0 /= length args1) empty
|
when (length args0 /= length args1) empty
|
||||||
forM_ (zip args0 args1) $ \(arg0, arg1) -> unify arg0 arg1
|
forM_ (zip args0 args1) $ \(arg0, arg1) ->
|
||||||
unify (Var v0) (Var v1) | v0 == v1 = return ()
|
unify arg0 arg1
|
||||||
|
unify (Var v0) (Var v1) | v0 == v1 = return () -- succeed with {} (no bindings)
|
||||||
unify (Var v0) t1 = do
|
unify (Var v0) t1 = do
|
||||||
binding <- getVar v0
|
binding <- getVar v0
|
||||||
case binding of
|
case binding of
|
||||||
Just t0 -> unify t0 t1
|
Just t0 -> unify t0 t1
|
||||||
Nothing -> setVar v0 t1
|
Nothing -> setVar v0 t1
|
||||||
unify t0 t1@(Var _) = unify t1 t0
|
unify t0@(Compound _ _) t1@(Var _) = unify t1 t0
|
||||||
|
|
||||||
instantiate :: Term -> PrologStream Term
|
instantiate :: Term -> PrologStream Term
|
||||||
instantiate t@(Var v) = do
|
instantiate t@(Var v) = do
|
||||||
binding <- getVar v
|
binding <- getVar v
|
||||||
case binding of
|
case binding of
|
||||||
Just t0 -> instantiate t0
|
Just t0 -> instantiate t0
|
||||||
Nothing -> return t
|
Nothing -> return t
|
||||||
instantiate (Compound h args) = do
|
instantiate (Compound h args) = do
|
||||||
instantiatedArgs <- mapM instantiate args
|
instantiatedArgs <- mapM instantiate args
|
||||||
return (Compound h instantiatedArgs)
|
return (Compound h instantiatedArgs)
|
@ -1,6 +1,5 @@
|
|||||||
module Classes
|
module Classes (LiftIO(..)) where
|
||||||
( LiftIO (..)
|
|
||||||
) where
|
|
||||||
|
|
||||||
class Monad m => LiftIO m where
|
class Monad m => LiftIO m where
|
||||||
liftIO :: IO a -> m a
|
liftIO :: IO a -> m a
|
||||||
|
|
||||||
|
@ -1,13 +1,9 @@
|
|||||||
module Database
|
module Database where
|
||||||
( Clause(..)
|
import Nondeterminism
|
||||||
, Database(..)
|
|
||||||
, seekAndInstantiate, seek
|
|
||||||
) where
|
|
||||||
import Binding
|
|
||||||
import Nondeterminism
|
|
||||||
import Terms
|
import Terms
|
||||||
import Control.Monad
|
|
||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
|
import Binding
|
||||||
|
import Control.Monad
|
||||||
|
|
||||||
data Clause = Clause Term [Term]
|
data Clause = Clause Term [Term]
|
||||||
|
|
||||||
@ -22,9 +18,9 @@ seekAndInstantiate goal db = do
|
|||||||
|
|
||||||
seek :: Term -> Database -> PrologStream ()
|
seek :: Term -> Database -> PrologStream ()
|
||||||
seek goal db = do
|
seek goal db = do
|
||||||
foldr (<|>) mzero (map doClause (clauses db))
|
foldr (<|>) empty (map doClause (clauses db))
|
||||||
where
|
where
|
||||||
doClause clause = do
|
doClause clause = do
|
||||||
Clause chead body <- clause
|
Clause chead body <- clause
|
||||||
unify goal chead
|
unify goal chead
|
||||||
forM_ body $ \newGoal -> seek newGoal db
|
forM_ body $ \newGoal -> seek newGoal db
|
55
app/Main.hs
55
app/Main.hs
@ -1,37 +1,36 @@
|
|||||||
{-# LANGUAGE InstanceSigs #-}
|
|
||||||
module Main where
|
module Main where
|
||||||
|
import Database
|
||||||
import Binding
|
import Nondeterminism
|
||||||
import Classes
|
import Classes
|
||||||
import Database
|
|
||||||
import Nondeterminism
|
|
||||||
import Terms
|
import Terms
|
||||||
|
import Binding
|
||||||
|
|
||||||
demoProgram :: Database
|
demoProgram :: Database
|
||||||
demoProgram = Database
|
demoProgram = Database
|
||||||
{ clauses =
|
{ clauses =
|
||||||
[ do
|
-- act(sam, 'goes to law school')
|
||||||
who <- newVar "who"
|
[ return $ Clause (Compound "act" [Compound "Sam" [], Compound "goes to law school" []]) []
|
||||||
action <- newVar "action"
|
, return $ Clause (Compound "vampire_behavior" [Compound "drinks blood" []]) []
|
||||||
return $ Clause (Compound "act" [Var who, Var action])
|
, return $ Clause (Compound "vampire_behavior" [Compound "spits venom" []]) []
|
||||||
|
, do
|
||||||
|
-- act(Who, Action) :- is_vampire(Who), vampire_behavior(Action).
|
||||||
|
who <- newVar "Who"
|
||||||
|
action <- newVar "Action"
|
||||||
|
return $ Clause (Compound "act" [Var who, Var action])
|
||||||
[ Compound "is_vampire" [Var who]
|
[ Compound "is_vampire" [Var who]
|
||||||
, Compound "vampire_behavior" [Var action]
|
, Compound "vampire_behavior" [Var action]
|
||||||
]
|
]
|
||||||
, do
|
, do
|
||||||
progenitor <- newVar "progenitor"
|
-- is_vampire(Progeny) :- has_progenitor(Progenitor, Progeny), is_vampire(Progenitor)>
|
||||||
progeny <- newVar "progeny"
|
progenitor <- newVar "Progenitor"
|
||||||
|
progeny <- newVar "Progeny"
|
||||||
return $ Clause (Compound "is_vampire" [Var progeny])
|
return $ Clause (Compound "is_vampire" [Var progeny])
|
||||||
[ Compound "has_progenitor" [Var progenitor, Var progeny]
|
[ Compound "has_progenitor" [Var progenitor, Var progeny]
|
||||||
, Compound "is_vampire" [Var progenitor]
|
, Compound "is_vampire" [Var progenitor]
|
||||||
]
|
]
|
||||||
, return $ Clause (Compound "act" [Compound "Sam" [], Compound "goes to law school" []]) []
|
|
||||||
|
|
||||||
, return $ Clause (Compound "vampire_behavior" [Compound "drinks blood" []]) []
|
|
||||||
, return $ Clause (Compound "vampire_behavior" [Compound "spits venom" []]) []
|
|
||||||
, return $ Clause (Compound "is_vampire" [Compound "Nyeogmi" []]) []
|
, return $ Clause (Compound "is_vampire" [Compound "Nyeogmi" []]) []
|
||||||
, return $ Clause (Compound "has_progenitor" [Compound "Nyeogmi" [], Compound "Pyrex" []]) []
|
|
||||||
, return $ Clause (Compound "has_progenitor" [Compound "Sam" [], Compound "Alex" []]) []
|
, return $ Clause (Compound "has_progenitor" [Compound "Sam" [], Compound "Alex" []]) []
|
||||||
-- , return $ Clause (Compound "is_vampire" [Compound "Sam" []]) []
|
, return $ Clause (Compound "is_vampire" [Compound "Sam" []]) []
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,11 +39,11 @@ main = do
|
|||||||
thread <- newThread runDemoProgram
|
thread <- newThread runDemoProgram
|
||||||
_ <- takeAllRemainingSolutions thread
|
_ <- takeAllRemainingSolutions thread
|
||||||
return ()
|
return ()
|
||||||
where
|
where
|
||||||
runDemoProgram = do
|
runDemoProgram :: PrologStream ()
|
||||||
who <- newVar "who"
|
runDemoProgram = do
|
||||||
what <- newVar "what"
|
who <- newVar "who"
|
||||||
let goal = Compound "act" [Var who, Var what]
|
what <- newVar "what"
|
||||||
seek goal demoProgram
|
let goal = Compound "act" [Var who, Var what]
|
||||||
instantiatedGoal <- instantiate goal
|
goal' <- seekAndInstantiate goal demoProgram
|
||||||
liftIO $ putStrLn ("Got " ++ show instantiatedGoal)
|
liftIO $ putStrLn ("Got " ++ show goal')
|
||||||
|
@ -1,54 +1,68 @@
|
|||||||
{-# LANGUAGE InstanceSigs #-}
|
{-# LANGUAGE InstanceSigs, PartialTypeSignatures #-}
|
||||||
module Nondeterminism
|
module Nondeterminism
|
||||||
( PrologStream
|
( PrologStream
|
||||||
, newThread
|
, newThread
|
||||||
, takeNextSolution, takeAllRemainingSolutions
|
, takeNextSolution, takeAllRemainingSolutions
|
||||||
, reversibly
|
, reversibly, liftPrologIO
|
||||||
, liftPrologIO
|
|
||||||
) where
|
) where
|
||||||
import Primitives (Globals, PrologIO(..), newGlobals)
|
import Primitives
|
||||||
import Control.Applicative
|
import Classes
|
||||||
|
import Control.Applicative
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Classes (LiftIO (..))
|
import Data.IORef
|
||||||
import GHC.IORef
|
|
||||||
|
|
||||||
data Suspend a = Yield a | Suspend
|
data Suspend a = Yield a | Suspend
|
||||||
|
data PrologStream a
|
||||||
|
= PMaybe (Suspend a) (PrologIO (PrologStream a))
|
||||||
|
| PNo
|
||||||
|
|
||||||
|
reversibly :: PrologIO a -> PrologIO () -> PrologStream a
|
||||||
|
reversibly forward backward =
|
||||||
|
PMaybe Suspend $ forward >>= \fwdValue -> return $
|
||||||
|
PMaybe (Yield fwdValue) $ backward >>= \_ -> return $
|
||||||
|
PNo
|
||||||
|
|
||||||
|
liftPrologIO :: PrologIO a -> PrologStream a
|
||||||
|
liftPrologIO forward = reversibly forward (return ())
|
||||||
|
|
||||||
|
instance LiftIO PrologStream where
|
||||||
|
liftIO :: IO a -> PrologStream a
|
||||||
|
liftIO x = liftPrologIO (liftIO x)
|
||||||
|
|
||||||
instance Functor Suspend where
|
instance Functor Suspend where
|
||||||
fmap f (Yield a) = Yield (f a)
|
fmap f (Yield a) = Yield (f a)
|
||||||
fmap _ Suspend = Suspend
|
fmap _ Suspend = Suspend
|
||||||
|
|
||||||
data PrologStream a
|
|
||||||
= PYes (Suspend a) (PrologIO (PrologStream a))
|
|
||||||
| PNo
|
|
||||||
|
|
||||||
instance Functor PrologStream where
|
instance Functor PrologStream where
|
||||||
fmap :: (a -> b) -> PrologStream a -> PrologStream b
|
fmap :: (a -> b) -> PrologStream a -> PrologStream b
|
||||||
fmap f (PYes a next) = PYes (fmap f a) (fmap (fmap f) next)
|
fmap f (PMaybe a as)
|
||||||
|
= PMaybe (fmap f a) (fmap (fmap f) as)
|
||||||
fmap _ PNo = PNo
|
fmap _ PNo = PNo
|
||||||
|
|
||||||
instance Applicative PrologStream where
|
|
||||||
pure :: a -> PrologStream a
|
|
||||||
pure x = PYes (Yield x) (pure PNo)
|
|
||||||
|
|
||||||
(<*>) :: PrologStream (a -> b) -> PrologStream a -> PrologStream b
|
|
||||||
f <*> x = f >>= (\f' -> x >>= (\x' -> return (f' x')))
|
|
||||||
|
|
||||||
instance Monad PrologStream where
|
instance Monad PrologStream where
|
||||||
return :: a -> PrologStream a
|
return :: a -> PrologStream a
|
||||||
return = pure
|
return = pure
|
||||||
|
|
||||||
(>>=) :: PrologStream a -> (a -> PrologStream b) -> PrologStream b
|
(>>=) :: PrologStream a -> (a -> PrologStream b) -> PrologStream b
|
||||||
PNo >>= _ = PNo
|
PNo >>= _ = PNo
|
||||||
PYes (Yield x) xs >>= f = f x <|> PYes Suspend (fmap (>>= f) xs)
|
(>>=) (PMaybe (Yield x) xs) f = f x <|> PMaybe Suspend (fmap (>>= f) xs)
|
||||||
PYes Suspend xs >>= f = PYes Suspend (fmap (>>= f) xs)
|
(>>=) (PMaybe Suspend xs) f = PMaybe Suspend (fmap (>>= f) xs)
|
||||||
|
|
||||||
instance Alternative PrologStream where
|
instance Applicative PrologStream where
|
||||||
|
pure :: a -> PrologStream a
|
||||||
|
pure x = PMaybe (Yield x) (pure PNo)
|
||||||
|
|
||||||
|
(<*>) :: PrologStream (a -> b) -> PrologStream a -> PrologStream b
|
||||||
|
fs <*> xs = do { f <- fs; x <- xs; return (f x) }
|
||||||
|
|
||||||
|
instance Alternative PrologStream where
|
||||||
empty :: PrologStream a
|
empty :: PrologStream a
|
||||||
empty = PNo
|
empty = PNo
|
||||||
|
|
||||||
(<|>) :: PrologStream a -> PrologStream a -> PrologStream a
|
(<|>) :: PrologStream a -> PrologStream a -> PrologStream a
|
||||||
(PYes x xs) <|> next = PYes x (liftM2 (<|>) xs (return next))
|
(PMaybe x xsFuture) <|> next = PMaybe x merged
|
||||||
|
where
|
||||||
|
merged = do { xs <- xsFuture; return (xs <|> next) }
|
||||||
PNo <|> next = next
|
PNo <|> next = next
|
||||||
|
|
||||||
instance MonadPlus PrologStream where
|
instance MonadPlus PrologStream where
|
||||||
@ -58,6 +72,12 @@ instance MonadPlus PrologStream where
|
|||||||
mplus :: PrologStream a -> PrologStream a -> PrologStream a
|
mplus :: PrologStream a -> PrologStream a -> PrologStream a
|
||||||
mplus = (<|>)
|
mplus = (<|>)
|
||||||
|
|
||||||
|
squeeze :: PrologStream a -> PrologIO (Maybe a, PrologStream a)
|
||||||
|
squeeze PNo = return (Nothing, PNo)
|
||||||
|
squeeze (PMaybe Suspend rest) = do { v <- rest; squeeze v }
|
||||||
|
squeeze (PMaybe (Yield x) rest)
|
||||||
|
= return (Just x, PMaybe Suspend rest)
|
||||||
|
|
||||||
data Thread a = Thread
|
data Thread a = Thread
|
||||||
{ threadGlobals :: Globals
|
{ threadGlobals :: Globals
|
||||||
, threadStream :: IORef (PrologStream a)
|
, threadStream :: IORef (PrologStream a)
|
||||||
@ -67,16 +87,16 @@ newThread :: PrologStream a -> IO (Thread a)
|
|||||||
newThread stream = do
|
newThread stream = do
|
||||||
globals <- newGlobals
|
globals <- newGlobals
|
||||||
streamRef <- newIORef stream
|
streamRef <- newIORef stream
|
||||||
return $ Thread
|
return $ Thread
|
||||||
{ threadGlobals = globals
|
{ threadGlobals = globals
|
||||||
, threadStream = streamRef
|
, threadStream = streamRef
|
||||||
}
|
}
|
||||||
|
|
||||||
takeNextSolution :: Thread a -> IO (Maybe a)
|
takeNextSolution :: Thread a -> IO (Maybe a)
|
||||||
takeNextSolution (Thread { threadGlobals = globals, threadStream = streamRef }) = do
|
takeNextSolution thread = do
|
||||||
stream <- readIORef streamRef
|
stream <- readIORef (threadStream thread)
|
||||||
(value, newStream) <- runPrologIO (squeeze stream) globals
|
(value, newStream) <- runPrologIO (squeeze stream) (threadGlobals thread)
|
||||||
writeIORef streamRef newStream
|
writeIORef (threadStream thread) newStream
|
||||||
return value
|
return value
|
||||||
|
|
||||||
takeAllRemainingSolutions :: Thread a -> IO [a]
|
takeAllRemainingSolutions :: Thread a -> IO [a]
|
||||||
@ -84,21 +104,4 @@ takeAllRemainingSolutions thread = do
|
|||||||
value <- takeNextSolution thread
|
value <- takeNextSolution thread
|
||||||
case value of
|
case value of
|
||||||
Nothing -> return []
|
Nothing -> return []
|
||||||
Just x -> fmap (x:) (takeAllRemainingSolutions thread)
|
Just x -> fmap (x:) (takeAllRemainingSolutions thread)
|
||||||
|
|
||||||
squeeze :: PrologStream a -> PrologIO (Maybe a, PrologStream a)
|
|
||||||
squeeze PNo = return (Nothing, PNo)
|
|
||||||
squeeze (PYes Suspend rest) = rest >>= squeeze
|
|
||||||
squeeze (PYes (Yield x) rest) = fmap ((,) (Just x)) rest
|
|
||||||
|
|
||||||
reversibly :: PrologIO a -> PrologIO () -> PrologStream a
|
|
||||||
reversibly forward backward =
|
|
||||||
PYes Suspend $ forward >>= \v -> return $
|
|
||||||
PYes (Yield v) $ backward >>= \_ -> return $
|
|
||||||
PNo
|
|
||||||
|
|
||||||
liftPrologIO :: PrologIO a -> PrologStream a
|
|
||||||
liftPrologIO forward = reversibly forward (return ())
|
|
||||||
|
|
||||||
instance LiftIO PrologStream where
|
|
||||||
liftIO x = liftPrologIO (liftIO x)
|
|
@ -1,20 +1,25 @@
|
|||||||
{-# LANGUAGE InstanceSigs #-}
|
{-# LANGUAGE InstanceSigs #-}
|
||||||
module Primitives
|
module Primitives
|
||||||
( PrologIO(..)
|
( Globals(..)
|
||||||
, Globals
|
, PrologIO(..)
|
||||||
, newGlobals
|
, newGlobals
|
||||||
, newVarPrim, unnewVarPrim
|
, newVarPrim, unnewVarPrim, getVarPrim, setVarPrim, errorPrim
|
||||||
, getVarPrim, setVarPrim
|
) where
|
||||||
, errorPrim
|
import Classes
|
||||||
)
|
|
||||||
where
|
|
||||||
|
|
||||||
import Data.IORef
|
|
||||||
import qualified Data.IntMap.Strict as M
|
import qualified Data.IntMap.Strict as M
|
||||||
|
import Data.IORef
|
||||||
import Terms
|
import Terms
|
||||||
import Classes (LiftIO(..))
|
|
||||||
|
|
||||||
newtype PrologIO a = PrologIO { runPrologIO :: Globals -> IO a }
|
newtype PrologIO a = PrologIO { runPrologIO :: Globals -> IO a }
|
||||||
|
data Globals = Globals
|
||||||
|
{ values :: IORef (M.IntMap Term)
|
||||||
|
, names :: IORef (M.IntMap Name)
|
||||||
|
, nextSlot :: IORef Int
|
||||||
|
}
|
||||||
|
|
||||||
|
instance LiftIO PrologIO where
|
||||||
|
liftIO :: IO a -> PrologIO a
|
||||||
|
liftIO io = PrologIO (\_ -> io)
|
||||||
|
|
||||||
instance Functor PrologIO where
|
instance Functor PrologIO where
|
||||||
fmap :: (a -> b) -> PrologIO a -> PrologIO b
|
fmap :: (a -> b) -> PrologIO a -> PrologIO b
|
||||||
@ -24,17 +29,19 @@ instance Applicative PrologIO where
|
|||||||
pure :: a -> PrologIO a
|
pure :: a -> PrologIO a
|
||||||
pure x = PrologIO (\_ -> pure x)
|
pure x = PrologIO (\_ -> pure x)
|
||||||
|
|
||||||
|
(<*>) :: PrologIO (a -> b) -> PrologIO a -> PrologIO b
|
||||||
(PrologIO f) <*> (PrologIO x) = PrologIO (
|
(PrologIO f) <*> (PrologIO x) = PrologIO (
|
||||||
\globals -> do
|
\globals -> do
|
||||||
f' <- f globals
|
f' <- f globals
|
||||||
x' <- x globals
|
x' <- x globals
|
||||||
pure (f' x')
|
return (f' x')
|
||||||
)
|
)
|
||||||
|
|
||||||
instance Monad PrologIO where
|
instance Monad PrologIO where
|
||||||
return :: a -> PrologIO a
|
return :: a -> PrologIO a
|
||||||
return = pure
|
return = pure
|
||||||
|
|
||||||
|
(>>=) :: PrologIO a -> (a -> PrologIO b) -> PrologIO b
|
||||||
(PrologIO a) >>= f = PrologIO (
|
(PrologIO a) >>= f = PrologIO (
|
||||||
\globals -> do
|
\globals -> do
|
||||||
a' <- a globals
|
a' <- a globals
|
||||||
@ -42,44 +49,33 @@ instance Monad PrologIO where
|
|||||||
b' globals
|
b' globals
|
||||||
)
|
)
|
||||||
|
|
||||||
data Globals = Globals
|
newGlobals :: IO Globals
|
||||||
{ values :: IORef (M.IntMap Term)
|
|
||||||
, names :: IORef (M.IntMap Name)
|
|
||||||
, nextVar :: IORef Int
|
|
||||||
}
|
|
||||||
|
|
||||||
newGlobals :: IO (Globals)
|
|
||||||
newGlobals = do
|
newGlobals = do
|
||||||
vs <- newIORef (M.empty)
|
vs <- newIORef M.empty
|
||||||
ns <- newIORef (M.empty)
|
ns <- newIORef M.empty
|
||||||
next <- newIORef 0
|
next <- newIORef 0
|
||||||
return $ Globals { values = vs, names = ns, nextVar = next }
|
return Globals { values=vs, names=ns, nextSlot=next }
|
||||||
|
|
||||||
newVarPrim :: Name -> PrologIO Var
|
newVarPrim :: Name -> PrologIO Slot
|
||||||
newVarPrim name = PrologIO $ \globals -> do
|
newVarPrim name = PrologIO $ \globals -> do
|
||||||
var <- readIORef (nextVar globals)
|
slot <- readIORef (nextSlot globals)
|
||||||
modifyIORef (names globals) (M.insert var name)
|
modifyIORef (names globals) (M.insert slot name)
|
||||||
modifyIORef (nextVar globals) succ
|
modifyIORef (nextSlot globals) (\s -> s + 1)
|
||||||
return (VInt var)
|
return (Slot slot)
|
||||||
|
|
||||||
unnewVarPrim :: PrologIO ()
|
unnewVarPrim :: PrologIO ()
|
||||||
unnewVarPrim = PrologIO $ \globals -> do
|
unnewVarPrim = PrologIO $ \globals -> do
|
||||||
modifyIORef (nextVar globals) pred
|
modifyIORef (nextSlot globals) (\s -> s - 1)
|
||||||
var <- readIORef (nextVar globals)
|
slot <- readIORef (nextSlot globals)
|
||||||
modifyIORef (names globals) (M.delete var)
|
modifyIORef (names globals) (M.delete slot)
|
||||||
return ()
|
|
||||||
|
|
||||||
getVarPrim :: Var -> PrologIO (Maybe Term)
|
getVarPrim :: Slot -> PrologIO (Maybe Term)
|
||||||
getVarPrim (VInt var) = PrologIO $ \globals ->
|
getVarPrim (Slot slot) = PrologIO $ \globals ->
|
||||||
fmap (M.lookup var) (readIORef (values globals))
|
fmap (M.lookup slot) (readIORef (values globals))
|
||||||
|
|
||||||
setVarPrim :: Var -> Maybe Term -> PrologIO ()
|
setVarPrim :: Slot -> Maybe Term -> PrologIO ()
|
||||||
setVarPrim (VInt var) term = PrologIO $ \globals -> do
|
setVarPrim (Slot slot) term = PrologIO $ \globals ->
|
||||||
modifyIORef (values globals) (M.alter (\_ -> term) var)
|
modifyIORef (values globals) (M.alter (\_ -> term) slot)
|
||||||
return ()
|
|
||||||
|
|
||||||
errorPrim :: String -> PrologIO a
|
errorPrim :: String -> PrologIO a
|
||||||
errorPrim message = error message
|
errorPrim message = error message
|
||||||
|
|
||||||
instance LiftIO PrologIO where
|
|
||||||
liftIO x = PrologIO (\_ -> x)
|
|
22
app/Terms.hs
22
app/Terms.hs
@ -1,17 +1,17 @@
|
|||||||
module Terms(
|
module Terms
|
||||||
Atom,
|
( Atom
|
||||||
Name,
|
, Name
|
||||||
Term(..),
|
, Term(..)
|
||||||
Var(..),
|
, Slot(..)
|
||||||
) where
|
) where
|
||||||
|
|
||||||
type Atom = String
|
type Atom = String
|
||||||
type Name = String
|
type Name = String
|
||||||
|
|
||||||
data Term
|
data Term
|
||||||
= Compound Atom [Term] -- functor, args
|
= Compound Atom [Term]
|
||||||
| Var Var
|
| Var Slot
|
||||||
deriving (Eq, Show)
|
deriving (Eq, Show)
|
||||||
|
|
||||||
newtype Var = VInt Int
|
newtype Slot = Slot Int
|
||||||
deriving (Ord, Eq, Show)
|
deriving (Eq, Show)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user