packages feed

graph-rewriting-lambdascope-0.5.2: Graph.hs

{-# 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