{-# LANGUAGE UnicodeSyntax, FlexibleInstances, MultiParamTypeClasses #-} module Graph where import Data.View import GraphRewriting.Graph import GraphRewriting.Graph.Write import qualified Term import Data.Maybe (listToMaybe) data Combinator = S | K | I | B | C | S' | B' | C' | W deriving (Show,Read,Eq) data Vertex = Applicator {inp, out1, out2 ∷ Port} | Combinator {inp ∷ Port, combinator ∷ Combinator} | Duplicator {inp1, inp2, out ∷ Port} | Variable {inp ∷ Port, variable ∷ String} | Eraser {out ∷ Port} | Root {out ∷ Port} instance View [Port] Vertex where inspect node = case node of Applicator {inp = i, out1 = o1, out2 = o2} → [i,o1,o2] Combinator {inp = i} → [i] Duplicator {inp1 = i1, inp2 = i2, out = o} → [i1,i2,o] Variable {inp = i} → [i] Eraser {out = o} → [o] Root {out = o} → [o] update ports node = case node of Applicator {} → node {inp = i, out1 = o1, out2 = o2} where [i,o1,o2] = ports Combinator {} → node {inp = i} where [i] = ports Duplicator {} → node {inp1 = i1, inp2 = i2, out = o} where [i1,i2,o] = ports Variable {} → node {inp = i} where [i] = ports Eraser {} → node {out = o} where [o] = ports Root {} → node {out = o} where [o] = ports fromTerm ∷ Term.Expr → Graph Vertex fromTerm term = flip execGraph emptyGraph $ do e ← compile term newNode Root {out = e} compile ∷ Term.Expr → Rewrite Vertex Edge compile term = do e ← newEdge case term of Term.Application f x → do ef ← compile f ex ← compile x newNode Applicator {inp = e, out1 = ef, out2 = ex} Term.Variable v → case maybeRead v of Just c → newNode Combinator {inp = e, combinator = c} Nothing → newNode Variable {inp = e, variable = v} return e maybeRead :: Read a => String -> Maybe a maybeRead = fmap fst . listToMaybe . reads