{-# LANGUAGE BangPatterns #-}
module Data.Rewriting.Rules.Rewrite (
Reduct (..),
Strategy,
fullRewrite,
outerRewrite,
innerRewrite,
rootRewrite,
nested,
listContexts,
) where
import Data.Rewriting.Substitution
import Data.Rewriting.Pos
import Data.Rewriting.Rule
import Data.Maybe
data Reduct f v v' = Reduct {
result :: Term f v,
pos :: Pos,
rule :: Rule f v',
subst :: GSubst v' f v
}
type Strategy f v v' = Term f v -> [Reduct f v v']
fullRewrite :: (Ord v', Eq v, Eq f)
=> [Rule f v'] -> Strategy f v v'
fullRewrite trs t = rootRewrite trs t ++ nested (fullRewrite trs) t
outerRewrite :: (Ord v', Eq v, Eq f)
=> [Rule f v'] -> Strategy f v v'
outerRewrite trs t = case rootRewrite trs t of
[] -> nested (outerRewrite trs) t
rs -> rs
innerRewrite :: (Ord v', Eq v, Eq f)
=> [Rule f v'] -> Strategy f v v'
innerRewrite trs t = case nested (innerRewrite trs) t of
[] -> rootRewrite trs t
rs -> rs
rootRewrite :: (Ord v', Eq v, Eq f)
=> [Rule f v'] -> Strategy f v v'
rootRewrite trs t = do
r <- trs
s <- maybeToList $ match (lhs r) t
t' <- maybeToList $ gApply s (rhs r)
return Reduct{ result = t', pos = [], rule = r, subst = s }
nested :: Strategy f v v' -> Strategy f v v'
nested _ (Var _) = []
nested s (Fun f ts) = do
(n, cl, t) <- listContexts ts
(\r -> r{ result = Fun f (cl (result r)), pos = n : pos r }) `fmap` s t
listContexts :: [a] -> [(Int, a -> [a], a)]
listContexts = go 0 id where
go !n f [] = []
go !n f (x:xs) = (n, f . (: xs), x) : go (n+1) (f . (x:)) xs