{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Fcf.Data.Graph where
import Fcf hiding (Map)
import qualified Fcf.Data.AdjacencyMap as AM
import Fcf.Data.Nat
import qualified Fcf.Data.Set as S
data Graph a where
Empty :: Graph a
Vertex :: a -> Graph a
Overlay :: Graph a -> Graph a -> Graph a
Connect :: Graph a -> Graph a -> Graph a
data Empty :: Exp (Graph a)
type instance Eval Empty = 'Empty
data Vertex :: a -> Exp (Graph a)
type instance Eval (Vertex a) = 'Vertex a
data Edge :: a -> a -> Exp (Graph a)
type instance Eval (Edge x y) = 'Connect ('Vertex x) ('Vertex y)
data Overlay :: Graph a -> Graph a -> Exp (Graph a)
type instance Eval (Overlay x y) = 'Overlay x y
data Connect :: Graph a -> Graph a -> Exp (Graph a)
type instance Eval (Connect x y) = 'Connect x y
data Map :: (a -> Exp b) -> Graph a -> Exp (Graph b)
type instance Eval (Map _ 'Empty) = 'Empty
type instance Eval (Map f ('Vertex a)) = 'Vertex (Eval (f $ a))
type instance Eval (Map f ('Overlay x y)) = 'Overlay (Eval (Map f x)) (Eval (Map f y))
type instance Eval (Map f ('Connect x y)) = 'Connect (Eval (Map f x)) (Eval (Map f y))
data FoldG :: Exp b -> (a -> Exp b) -> (b -> b -> Exp b) -> (b -> b -> Exp b) -> Graph a -> Exp b
type instance Eval (FoldG e _ _ _ 'Empty) = Eval e
type instance Eval (FoldG _ v _ _ ('Vertex x)) = Eval (v x)
type instance Eval (FoldG e v o c ('Overlay x y)) = Eval (o (Eval (FoldG e v o c x)) (Eval (FoldG e v o c y)))
type instance Eval (FoldG e v o c ('Connect x y)) = Eval (c (Eval (FoldG e v o c x)) (Eval (FoldG e v o c y)))
data ToAdjacencyMap :: Graph a -> Exp (AM.AdjacencyMap a)
type instance Eval (ToAdjacencyMap x) = Eval (FoldG AM.Empty AM.Vertex AM.Overlay AM.Connect x)
data EqR :: Graph a -> Graph a -> Exp Bool
type instance Eval (EqR x y) = Eval (TyEq (Eval (ToAdjacencyMap x)) (Eval (ToAdjacencyMap y)))
data Size :: Graph a -> Exp Nat
type instance Eval (Size g) = Eval (FoldG (Pure 1) (ConstFn 1) (+) (+) g)
data HasVertex :: a -> Graph a -> Exp Bool
type instance Eval (HasVertex x g) = Eval (FoldG (Pure 'False) (TyEq x) (||) (||) g)
data VertexSet :: Graph a -> Exp (S.Set a)
type instance Eval (VertexSet g) = Eval (FoldG S.Empty S.Singleton S.Union S.Union g)
data Simplify :: Graph a -> Exp (Graph a)
type instance Eval (Simplify x) = Eval (FoldG Empty Vertex (Simple Overlay) (Simple Connect) x)
data Simple :: (Graph a -> Graph a -> Exp (Graph a)) -> Graph a -> Graph a -> Exp (Graph a)
type instance Eval (Simple f x y) = Eval (Simple' x y (Eval (f x y)))
data Simple' :: Graph a -> Graph a -> Graph a -> Exp (Graph a)
type instance
Eval (Simple' x y z) =
If (Eval (EqR x z)) x (If (Eval (EqR y z)) y z)