lojysamban-0.0.2: PrologTools.hs
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
module PrologTools (
TwoD(..),
Fact,
NotFact,
Rule(..),
notAsk,
checkAll
) where
import Unif
import NotUnif
import Control.Applicative
class TwoD td where
next :: td -> td
down :: td -> td
type Fact sc s = sc -> [Term sc s]
type NotFact sc s = Fact sc s
data Unify sc s
= Unify (Term sc s) (Term sc s)
| NotUnify (Term sc s) (Term sc s)
deriving Show
data Rule sc s = Rule (Fact sc s) [Unify sc s] [Fact sc s] [NotFact sc s]
notAsk :: (TwoD sc, Eq sc, Eq s) => sc ->
Fact sc s -> [Rule sc s] -> [Maybe [(Term sc s, Term sc s)]]
notAsk sc q rs = zipWith (\sc r -> notAskRule sc q r rs) (iterate next $ down sc) rs
notAskRule :: (TwoD sc, Eq sc, Eq s) => sc ->
Fact sc s -> Rule sc s -> [Rule sc s] -> Maybe [(Term sc s, Term sc s)]
notAskRule sc q r@(Rule fact unify facts notFacts) rs = liftA concat $
case match of
Nothing -> Just []
Just _ ->
liftA2 (:) start $ maybeOut $ concat $
map ((flip (notAsk sc) rs) . const . ($ sc)) facts
where
start = notUnification (q sc) $ fact sc
match = unification [head $ q sc] [head $ fact sc]
maybeOut :: [Maybe a] -> Maybe [a]
maybeOut [] = Just []
maybeOut (Nothing : xs) = Nothing
maybeOut (Just x : xs) = maybe Nothing (Just . (x :)) $ maybeOut xs