module Prolog2 (
ask,
Fact,
-- Unify(..),
Rule(..),
Term(..),
TwoD(..),
Result
) where
import PrologTools
import Unif
import Data.Maybe
ask :: (TwoD sc, Eq sc, Eq s) =>
sc -> Result sc s -> Fact sc s -> [Rule sc s] -> [Result sc s]
ask sc ret q rs =
concat $ zipWith (\sc r -> askrule sc ret q r rs) (iterate next $ down sc) rs
askrule :: (TwoD sc, Eq sc, Eq s) =>
sc -> Result sc s -> Fact sc s -> Rule sc s -> [Rule sc s] -> [Result sc s]
askrule sc ret q r@(Rule fact _ facts notFacts) rs =
filter (flip checkAll nots) ret'
where
ret' = foldl (\rets (sc', f) -> rets >>= \r -> ask sc' r f rs) r0 $ zip (iterate next sc0) $
map (const . ($ sc0)) facts
sc0 = down sc
r0 = case (q sc) `unification` (fact sc0) of
Nothing -> []
Just r0' -> maybeToList $ ret `merge` r0'
nots = concat $ map ((flip (notAsk sc0) rs) . const . ($sc0)) notFacts