{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
{-|
   Module for the definition of 'EClass'.
-}
module Data.Equality.Graph.Classes
    ( module Data.Equality.Graph.Classes
    , module Data.Equality.Graph.Classes.Id
    ) where

import qualified Data.Set as S

import Data.Functor.Classes

import Data.Equality.Graph.Classes.Id
import Data.Equality.Graph.Nodes

import Data.Equality.Utils.SizedList

-- | An e-class (an equivalence class of terms) of a language @l@.
--
-- Intuitively, an e-graph is a set of equivalence classes (e-classes). Each
-- e-class is a set of e-nodes representing equivalent terms from a given
-- language, and an e-node is a function symbol paired with a list of children
-- e-classes.
data EClass analysis_domain language = EClass
    { forall analysis_domain (language :: * -> *).
EClass analysis_domain language -> ClassId
eClassId      :: {-# UNPACK #-} !ClassId -- ^ E-class identifier
    , forall analysis_domain (language :: * -> *).
EClass analysis_domain language -> Set (ENode language)
eClassNodes   :: !(S.Set (ENode language))      -- ^ E-nodes in this class
    , forall analysis_domain (language :: * -> *).
EClass analysis_domain language -> analysis_domain
eClassData    :: analysis_domain                       -- ^ The analysis data associated with this eclass.
    , forall analysis_domain (language :: * -> *).
EClass analysis_domain language -> SList (ClassId, ENode language)
eClassParents :: !(SList (ClassId, ENode language)) -- ^ E-nodes which are parents of this e-class and their corresponding e-class ids.
    }

instance (Show a, Show1 l) => Show (EClass a l) where
    show :: EClass a l -> String
show (EClass ClassId
a Set (ENode l)
b a
d (SList [(ClassId, ENode l)]
c ClassId
_)) = String
"Id: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> ClassId -> String
forall a. Show a => a -> String
show ClassId
a String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"\nNodes: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Set (ENode l) -> String
forall a. Show a => a -> String
show Set (ENode l)
b String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"\nParents: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> [(ClassId, ENode l)] -> String
forall a. Show a => a -> String
show [(ClassId, ENode l)]
c String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"\nData: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> a -> String
forall a. Show a => a -> String
show a
d