{-# LANGUAGE UnicodeSyntax, FlexibleInstances, FlexibleContexts #-}
module GraphRewriting.Rule (Replace, module GraphRewriting.Rule) where
import Prelude.Unicode
import GraphRewriting.Graph.Read
import GraphRewriting.Graph.Write
import GraphRewriting.Rule.Internal
import GraphRewriting.Pattern
import Control.Monad.State
import Control.Monad.Reader
import Data.List (nub)
type Rule n = Pattern n (Rewrite n ())
apply ∷ Rule n → Rewrite n ()
apply :: forall n. Rule n -> Rewrite n ()
apply = let void :: m a -> m ()
void m a
m = m a
m forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return () in forall {m :: * -> *} {a}. Monad m => m a -> m ()
void forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. Rule n -> Rewrite n Bool
apply'
apply' ∷ Rule n → Rewrite n Bool
apply' :: forall n. Rule n -> Rewrite n Bool
apply' Rule n
r = do
[Rewrite n ()]
contractions ← forall n a. Pattern n a -> Graph n -> [a]
evalPattern Rule n
r forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall r (m :: * -> *). MonadReader r m => m r
ask
if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Rewrite n ()]
contractions
then forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
else forall a. [a] -> a
head [Rewrite n ()]
contractions forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
rewrite ∷ (Match → Rewrite n a) → Rule n
rewrite :: forall n a. (Match -> Rewrite n a) -> Rule n
rewrite Match -> Rewrite n a
r = do
Match
h ← forall (m :: * -> *) n. Monad m => PatternT n m Match
history
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Match -> Rewrite n a
r Match
h forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return ()
erase ∷ View [Port] n ⇒ Rule n
erase :: forall n. View [Port] n => Rule n
erase = forall n a. (Match -> Rewrite n a) -> Rule n
rewrite forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall n. View [Port] n => Node -> Rewrite n ()
deleteNode forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Eq a => [a] -> [a]
nub
rewire ∷ View [Port] n ⇒ [[Edge]] → Rule n
rewire :: forall n. View [Port] n => [[Port]] -> Rule n
rewire [[Port]]
ess = forall n a. (Match -> Rewrite n a) -> Rule n
rewrite forall a b. (a -> b) -> a -> b
$ \Match
hist → do
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall n. View [Port] n => [Port] -> Rewrite n ()
mergeEs forall a b. (a -> b) -> a -> b
$ [[Port]] -> [[Port]]
joinEdges [[Port]]
ess
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall n. View [Port] n => Node -> Rewrite n ()
deleteNode forall a b. (a -> b) -> a -> b
$ forall a. Eq a => [a] -> [a]
nub Match
hist
instance Monad (Replace n) where
return :: forall a. a -> Replace n a
return a
x = forall n a. Rewrite n (a, [[Port]]) -> Replace n a
Replace forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return (a
x, [])
Replace Rewrite n (a, [[Port]])
r1 >>= :: forall a b. Replace n a -> (a -> Replace n b) -> Replace n b
>>= a -> Replace n b
f = forall n a. Rewrite n (a, [[Port]]) -> Replace n a
Replace forall a b. (a -> b) -> a -> b
$ do
(a
x1, [[Port]]
merges1) ← Rewrite n (a, [[Port]])
r1
let Replace Rewrite n (b, [[Port]])
r2 = a -> Replace n b
f a
x1
(b
y, [[Port]]
merges2) ← Rewrite n (b, [[Port]])
r2
forall (m :: * -> *) a. Monad m => a -> m a
return (b
y, [[Port]]
merges1 forall α. [α] -> [α] -> [α]
⧺ [[Port]]
merges2)
instance Functor (Replace n) where
fmap :: forall a b. (a -> b) -> Replace n a -> Replace n b
fmap a -> b
f (Replace Rewrite n (a, [[Port]])
r) = forall n a. Rewrite n (a, [[Port]]) -> Replace n a
Replace forall a b. (a -> b) -> a -> b
$ do
(a
x, [[Port]]
merges) ← Rewrite n (a, [[Port]])
r
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> b
f a
x, [[Port]]
merges)
instance Applicative (Replace n) where
Replace Rewrite n (a -> b, [[Port]])
rf <*> :: forall a b. Replace n (a -> b) -> Replace n a -> Replace n b
<*> Replace Rewrite n (a, [[Port]])
rx = forall n a. Rewrite n (a, [[Port]]) -> Replace n a
Replace forall a b. (a -> b) -> a -> b
$ do
(a -> b
f, [[Port]]
merges1) ← Rewrite n (a -> b, [[Port]])
rf
(a
x, [[Port]]
merges2) ← Rewrite n (a, [[Port]])
rx
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> b
f a
x, [[Port]]
merges1 forall α. [α] -> [α] -> [α]
⧺ [[Port]]
merges2)
pure :: forall a. a -> Replace n a
pure = forall (m :: * -> *) a. Monad m => a -> m a
return
instance Semigroup (Replace n ()) where
<> :: Replace n () -> Replace n () -> Replace n ()
(<>) = forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
(>>)
instance Monoid (Replace n ()) where
mempty :: Replace n ()
mempty = forall (m :: * -> *) a. Monad m => a -> m a
return ()
mappend :: Replace n () -> Replace n () -> Replace n ()
mappend = forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
(>>)
replace ∷ View [Port] n ⇒ Replace n () → Rule n
replace :: forall n. View [Port] n => Replace n () -> Rule n
replace (Replace Rewrite n ((), [[Port]])
rhs) = do
Match
lhs ← forall a. Eq a => [a] -> [a]
nub forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) n. Monad m => PatternT n m Match
history
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (forall (t :: * -> *) a. Foldable t => t a -> Bool
null Match
lhs) (forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"replace: must match at least one node")
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ do
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall n. View [Port] n => [Port] -> Rewrite n ()
mergeEs forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [[Port]] -> [[Port]]
joinEdges forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> b
snd forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Rewrite n ((), [[Port]])
rhs
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall n. View [Port] n => Node -> Rewrite n ()
deleteNode Match
lhs
byNode ∷ (View [Port] n, View v n) ⇒ v → Replace n ()
byNode :: forall n v. (View [Port] n, View v n) => v -> Replace n ()
byNode v
v = forall n a. Rewrite n (a, [[Port]]) -> Replace n a
Replace forall a b. (a -> b) -> a -> b
$ do
Node
n ← forall a. [a] -> a
head forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall n (m :: * -> *). MonadReader (Graph n) m => m Match
readNodeList
Node
_ ← forall n v.
(View [Port] n, View v n) =>
Node -> v -> Rewrite n Node
copyNode Node
n v
v
forall (m :: * -> *) a. Monad m => a -> m a
return ((), [])
byNewNode ∷ View [Port] n ⇒ n → Replace n ()
byNewNode :: forall n. View [Port] n => n -> Replace n ()
byNewNode n
n = forall n a. Rewrite n (a, [[Port]]) -> Replace n a
Replace forall a b. (a -> b) -> a -> b
$ forall n. View [Port] n => n -> Rewrite n Node
newNode n
n forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return ((), [])
byEdge ∷ Replace n Edge
byEdge :: forall n. Replace n Port
byEdge = forall n a. Rewrite n (a, [[Port]]) -> Replace n a
Replace forall a b. (a -> b) -> a -> b
$ do
Port
e ← forall n. Rewrite n Port
newEdge
forall (m :: * -> *) a. Monad m => a -> m a
return (Port
e, [])
byWire ∷ Edge → Edge → Replace n ()
byWire :: forall n. Port -> Port -> Replace n ()
byWire Port
e1 Port
e2 = forall n. [Port] -> Replace n ()
byConnector [Port
e1,Port
e2]
byConnector ∷ [Edge] → Replace n ()
byConnector :: forall n. [Port] -> Replace n ()
byConnector [Port]
es = forall n a. Rewrite n (a, [[Port]]) -> Replace n a
Replace forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. Monad m => a -> m a
return ((), [[Port]
es])
(>>>) ∷ Rule n → Rule n → Rule n
Rule n
r1 >>> :: forall n. Rule n -> Rule n -> Rule n
>>> Rule n
r2 = do
Rewrite n ()
rw1 ← Rule n
r1
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Rewrite n ()
rw1 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall n. Rule n -> Rewrite n ()
apply Rule n
r2
exhaustive ∷ Rule n → Rule n
exhaustive :: forall n. Rule n -> Rule n
exhaustive = forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 forall n. Rule n -> Rule n -> Rule n
(>>>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a]
repeat
everywhere ∷ Rule n → Rule n
everywhere :: forall n. Rule n -> Rule n
everywhere Rule n
r = do
[Match]
ms ← forall (m :: * -> *) n a.
Monad m =>
PatternT n m a -> PatternT n m a
amnesia forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) n a.
Monad m =>
PatternT n m a -> PatternT n m [Match]
matches Rule n
r
forall n. Rule n -> Rule n
exhaustive forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) n a.
Monad m =>
(Match -> Match -> Bool) -> PatternT n m a -> PatternT n m a
restrictOverlap (\Match
hist Match
future → Match
future forall α. Eq α => α -> [α] -> Bool
∈ [Match]
ms) Rule n
r
benchmark ∷ [Rule n] → Rewrite n [Int]
benchmark :: forall n. [Rule n] -> Rewrite n [Int]
benchmark [Rule n]
rules = Rewrite n [Int]
rec where
rec :: Rewrite n [Int]
rec = do
[(Int, Rewrite n ())]
contractions ← forall n a. Pattern n a -> Graph n -> [a]
evalPattern (forall (f :: * -> *) a. Alternative f => [f a] -> f a
anyOf [PatternT n Identity (Int, Rewrite n ())]
indexedRules) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall r (m :: * -> *). MonadReader r m => m r
ask
case [(Int, Rewrite n ())]
contractions of
[] → forall (m :: * -> *) a. Monad m => a -> m a
return []
(Int
i,Rewrite n ()
rw) : [(Int, Rewrite n ())]
_ → forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int
iforall a. a -> [a] -> [a]
:) (Rewrite n ()
rw forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Rewrite n [Int]
rec)
indexedRules :: [PatternT n Identity (Int, Rewrite n ())]
indexedRules = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall {m :: * -> *} {a} {b}. Monad m => a -> m b -> m (a, b)
addIndex [Int
0..] [Rule n]
rules where
addIndex :: a -> m b -> m (a, b)
addIndex a
i m b
rule = do
b
rw ← m b
rule
forall (m :: * -> *) a. Monad m => a -> m a
return (a
i, b
rw)