module Data.Rewriting.CriticalPair.Ops (
cps,
cpsIn,
cpsOut,
cps',
cpsIn',
cpsOut',
) where
import Data.Rewriting.CriticalPair.Type
import Data.Rewriting.Substitution
import Data.Rewriting.Rule.Type
import qualified Data.Rewriting.Term as Term
import Data.Rewriting.Pos
import Data.Rewriting.Rules.Rewrite (listContexts)
import Data.Maybe
import Control.Monad
import Data.List
cpW :: (Ord v, Ord v', Eq f)
=> (Term f (Either v v')
-> [(Pos, Context f (Either v v'), Term f (Either v v'))])
-> Rule f v -> Rule f v' -> [(CP f v v')]
cpW f rl rr = do
let rl' = Term.map id Left (lhs rl)
rr' = Term.map id Right (lhs rr)
(pos, ctx, rr'') <- f rr'
guard $ not (Term.isVar rr'')
subst <- maybeToList $ unify rl' rr''
return CP{
left = apply subst (ctx (Term.map id Left (rhs rl))),
top = apply subst rr',
right = apply subst (Term.map id Right (rhs rr)),
leftRule = rl,
leftPos = pos,
rightRule = rr,
subst = subst
}
type Context f v = Term f v -> Term f v
contexts :: Term f v -> [(Pos, Context f v, Term f v)]
contexts t@(Var _) = [([], id, t)]
contexts t@(Fun f ts) = ([], id, t) : do
(i, ctxL, t) <- listContexts ts
(pos, ctxT, t') <- contexts t
return (i : pos, Fun f . ctxL . ctxT, t')
cp :: (Ord v, Ord v', Eq f)
=> Rule f v -> Rule f v' -> [(CP f v v')]
cp = cpW contexts
cpOut :: (Ord v, Ord v', Eq f)
=> Rule f v -> Rule f v' -> [(CP f v v')]
cpOut = cpW (take 1 . contexts)
cpIn :: (Ord v, Ord v', Eq f)
=> Rule f v -> Rule f v' -> [(CP f v v')]
cpIn = cpW (tail . contexts)
cps :: (Ord v, Ord v', Eq f) => [Rule f v] -> [Rule f v']
-> [(CP f v v')]
cps trs1 trs2 = do
rl <- trs1
rr <- trs2
cp rl rr
cpsIn :: (Ord v, Ord v', Eq f) => [Rule f v] -> [Rule f v']
-> [(CP f v v')]
cpsIn trs1 trs2 = do
rl <- trs1
rr <- trs2
cpIn rl rr
cpsOut :: (Ord v, Ord v', Eq f) => [Rule f v] -> [Rule f v']
-> [(CP f v v')]
cpsOut trs1 trs2 = do
rl <- trs1
rr <- trs2
cpOut rl rr
cps' :: (Ord v, Eq f) => [Rule f v] -> [(CP f v v)]
cps' trs = cpsIn' trs ++ cpsOut' trs
cpsIn' :: (Ord v, Eq f) => [Rule f v] -> [(CP f v v)]
cpsIn' trs = do
r1 : trs' <- tails trs
cpIn r1 r1 ++ do
r2 <- trs'
cpIn r1 r2 ++ cpIn r2 r1
cpsOut' :: (Ord v, Eq f) => [Rule f v] -> [(CP f v v)]
cpsOut' trs = do
rl : trs' <- tails trs
rr <- trs'
cpOut rl rr