{-# LANGUAGE UnicodeSyntax, FlexibleInstances, MultiParamTypeClasses #-}
module Graph where
import Prelude.Unicode
import Data.View
import GraphRewriting.Graph.Types
import GraphRewriting.Pattern.InteractionNet
-- import Control
import GraphRewriting.Strategies.LeftmostOutermost
-- | The signature of our graph
data NodeLS
= Initiator {out ∷ Port}
| Applicator {inp, func, arg ∷ Port}
| Abstractor {inp, body, var ∷ Port, name ∷ String}
| Constant {inp ∷ Port, args ∷ [Port], name ∷ String}
| Eraser {inp ∷ Port}
| Duplicator {level ∷ Int, inp, out1, out2 ∷ Port}
| Delimiter {level ∷ Int, inp, out ∷ Port}
| Multiplexer {out ∷ Port, ins ∷ [Port]} -- only intermediate compilation result
| Case {inp ∷ Port, out ∷ Port, alts ∷ [Port], names ∷ [String]}
| Operator {inp ∷ Port, ops ∷ [Port], arity ∷ Int, lmop ∷ Int,
function ∷ [String] → Maybe String, name ∷ String}
-- | equality as defined in the paper with only the relevant cases included
instance Eq NodeLS where
Eraser {} == Eraser {} = True
Duplicator {level = l1} == Duplicator {level = l2} = l1 ≡ l2
Delimiter {level = l1} == Delimiter {level = l2} = l1 ≡ l2
_ == _ = False
instance View [Port] NodeLS where
inspect node = case node of
Initiator {out = o} → [o]
Applicator {inp = i, func = f, arg = a} → [i,f,a]
Abstractor {inp = i, body = b, var = v} → [i,b,v]
Constant {inp = i, args = as} → i:as
Eraser {inp = i} → [i]
Duplicator {inp = i, out1 = o1, out2 = o2} → [i,o1,o2]
Delimiter {inp = i, out = o} → [i,o]
Multiplexer {out = o, ins = is} → o:is
Case {inp = i, out = o, alts = as} → i:o:as
Operator {inp = i, ops = os} → i:os
update ports node = case node of
Initiator {} → node {out = o} where [o] = ports
Applicator {} → node {inp = i, func = f, arg = a} where [i,f,a] = ports
Abstractor {} → node {inp = i, body = b, var = v} where [i,b,v] = ports
Constant {} → node {inp = i, args = as} where i:as = ports
Eraser {} → node {inp = i} where [i] = ports
Duplicator {} → node {inp = i, out1 = o1, out2 = o2} where [i,o1,o2] = ports
Delimiter {} → node {inp = i, out = o} where [i,o] = ports
Multiplexer {} → node {out = o, ins = is} where o:is = ports
Case {} → node {inp = i, out = o, alts = as} where i:o:as = ports
Operator {} → node {inp = i, ops = os} where i:os = ports
instance INet NodeLS where principalPort = pp
-- The number is an index that specifies which port is the principal port out of the list of ports
pp ∷ NodeLS → Port
pp node = case node of
Initiator {out = o} → o
Applicator {inp = i, func = f, arg = a} → f
Abstractor {inp = i, body = b, var = v} → i
Constant {inp = i, args = as} → i
Eraser {inp = i} → i
Duplicator {inp = i, out1 = o1, out2 = o2} → i
Delimiter {inp = i, out = o} → i
Multiplexer {out = o, ins = is} → o
Case {inp = i, out = o, alts = as} → o
Operator {lmop = i, ops = os} → inspect node !! i
instance LeftmostOutermost NodeLS where lmoPort = lmo
lmo ∷ NodeLS → Maybe Port
lmo node = case node of
Initiator {out = o} → Just o
Applicator {inp = i, func = f, arg = a} → Just f
Abstractor {inp = i, body = b, var = v} → Nothing
Constant {inp = i, args = as} → Nothing
Eraser {inp = i} → Just i
Duplicator {inp = i, out1 = o1, out2 = o2} → Just i
Delimiter {inp = i, out = o} → Just i
Case {inp = i, out = o, alts = as} → Just o
Operator {lmop = i, ops = os} → Just $ inspect node !! i