{-# LANGUAGE UnicodeSyntax, FlexibleContexts #-}
module Rules where
import Prelude.Unicode
import Graph
import GraphRewriting
-- The set-up ----------------------------------------------------------------
arity0 ∷ (View [Port] n, View Vertex n) ⇒ Edge → Pattern n Vertex
arity0 i = anyOf [c,v,e] where
c = do {c@Combinator {} ← nodeAt i; return c}
v = do {v@Variable {} ← nodeAt i; return v}
e = do {e@Eraser {} ← nodeAt i; return e}
erase0 ∷ (View [Port] n, View Vertex n) ⇒ Rule n
erase0 = linear $ do
Eraser {out = o} ← node
n ← arity0 o
erase
eraseApplicator ∷ (View [Port] n, View Vertex n) ⇒ Rule n
eraseApplicator = linear $ do
Eraser {out = o} ← node
Applicator {inp = i, out1 = o1, out2 = o2} ← nodeAt o
require (o ≡ i)
replace0 [Node $ Eraser {out = o1}, Node $ Eraser {out = o2}]
duplicate ∷ (View [Port] n, View Vertex n) ⇒ Rule n
duplicate = duplicateApplicator <|> do
Duplicator {inp1 = i1, inp2 = i2, out = o} ← node
n ← arity0 o
replace0 $ [Node $ n {inp = i1}, Node $ n {inp = i2}]
duplicateApplicator ∷ (View [Port] n, View Vertex n) ⇒ Rule n
duplicateApplicator = do
Duplicator {inp1 = i1, inp2 = i2, out = o} ← node
Applicator {inp = i, out1 = o1, out2 = o2} ← nodeAt o
replace4 $ \l1 l2 x1 x2 →
[Node $ Applicator {inp = i1, out1 = l1, out2 = x1},
Node $ Applicator {inp = i2, out1 = x2, out2 = l2},
Node $ Duplicator {inp1 = l1, inp2 = x2, out = o1},
Node $ Duplicator {inp1 = x1, inp2 = l2, out = o2}]
eliminate ∷ (View [Port] n, View Vertex n) ⇒ Rule n
eliminate = do
Eraser {out = oE} ← node
Duplicator {out = oD, inp1 = i1, inp2 = i2} ← nodeAt oE
require (oE ≡ i1 ∨ oE ≡ i2)
if oE ≡ i1
then rewire [[oD,i2]]
else rewire [[oD,i1]]
combinatorPattern ∷ (View [Port] n, View Vertex n) ⇒ Combinator → Int → Pattern n (Edge, [Edge])
combinatorPattern c arity = do
Combinator {inp = i, combinator = c'} ← node
require (c ≡ c')
accumulateArguments i arity
where
accumulateArguments i 0 = return (i,[])
accumulateArguments i n = do
Applicator {inp = iA, out1 = o1, out2 = o2} ← nodeAt i
require (i ≡ o1)
(i',args) ← accumulateArguments iA (n-1)
return (i',o2:args)
-- The show-down -------------------------------------------------------------
combinatorS ∷ (View [Port] n, View Vertex n) ⇒ Rule n
combinatorS = do
(i, [f,g,x]) ← combinatorPattern S 3
replace4 $ \l lr r rr →
[Node $ Applicator {inp = l, out1 = f, out2 = lr},
Node $ Applicator {inp = r, out1 = g, out2 = rr},
Node $ Duplicator {inp1 = lr, inp2 = rr, out = x},
Node $ Applicator {inp = i, out1 = l, out2 = r}]
combinatorK ∷ (View [Port] n, View Vertex n) ⇒ Rule n
combinatorK = do
(i, [x,y]) ← combinatorPattern K 2
replace0 [Node $ Eraser {out = y}, Wire i x]
combinatorI ∷ (View [Port] n, View Vertex n) ⇒ Rule n
combinatorI = do
(i, [x]) ← combinatorPattern I 1
rewire [[i,x]]
combinatorB ∷ (View [Port] n, View Vertex n) ⇒ Rule n
combinatorB = do
(i, [x,y,z]) ← combinatorPattern B 3
replace1 $ \r →
[Node $ Applicator {inp = r, out1 = y, out2 = z},
Node $ Applicator {inp = i, out1 = x, out2 = r}]
combinatorC ∷ (View [Port] n, View Vertex n) ⇒ Rule n
combinatorC = do
(i, [x,y,z]) ← combinatorPattern C 3
replace1 $ \l →
[Node $ Applicator {inp = l, out1 = x, out2 = z},
Node $ Applicator {inp = i, out1 = l, out2 = y}]
combinatorS' ∷ (View [Port] n, View Vertex n) ⇒ Rule n
combinatorS' = do
(i, [k,x,y,z]) ← combinatorPattern S' 4
replace5 $ \l lr lrr r rr →
[Node $ Applicator {inp = lr, out1 = x, out2 = lrr},
Node $ Applicator {inp = l, out1 = k, out2 = lr},
Node $ Applicator {inp = r, out1 = y, out2 = rr},
Node $ Duplicator {inp1 = lrr, inp2 = rr, out = z},
Node $ Applicator {inp = i, out1 = l, out2 = r}]
combinatorB' ∷ (View [Port] n, View Vertex n) ⇒ Rule n
combinatorB' = do
(i, [k,x,y,z]) ← combinatorPattern B' 4
replace2 $ \l r →
[Node $ Applicator {inp = l, out1 = k, out2 = x},
Node $ Applicator {inp = r, out1 = y, out2 = z},
Node $ Applicator {inp = i, out1 = l, out2 = r}]
combinatorC' ∷ (View [Port] n, View Vertex n) ⇒ Rule n
combinatorC' = do
(i, [k,x,y,z]) ← combinatorPattern C' 4
replace2 $ \l lr →
[Node $ Applicator {inp = l, out1 = k, out2 = lr},
Node $ Applicator {inp = lr, out1 = x, out2 = z},
Node $ Applicator {inp = i, out1 = l, out2 = y}]
combinatorW ∷ (View [Port] n, View Vertex n) ⇒ Rule n
combinatorW = do
(i, [x,y]) ← combinatorPattern W 2
replace3 $ \l lr r →
[Node $ Applicator {inp = l, out1 = x, out2 = lr},
Node $ Duplicator {inp1 = lr, inp2 = r, out = y},
Node $ Applicator {inp = i, out1 = l, out2 = r}]