{-# LANGUAGE UnicodeSyntax, FlexibleContexts #-}
module GraphRewriting.Rule.Internal where
import GraphRewriting.Graph.Internal
import GraphRewriting.Graph.Write
import qualified Data.IntSet as Set
type MergeEdges = [Edge]
newtype Replace n a = Replace (Rewrite n (a, [MergeEdges]))
mergeEs :: View [Port] n ⇒ MergeEdges -> Rewrite n ()
mergeEs (e:es) = mapM_ (mergeEdges e) es
type Set = Set.IntSet
joinEdges ∷ [[Edge]] → [[Edge]]
joinEdges = map (map Edge . Set.elems) . join . map (Set.fromList . map eKey)
-- The code below is essentially maintaining equivalence classes. TODO: use a library for that.
-- | Join pairs of sets with a common element until all sets are disjoint.
join ∷ [Set] → [Set]
join = foldr join1 []
-- | Add to a list of disjoint sets a further set and join sets with common elements such that the resulting list again only contains disjoint sets.
join1 ∷ Set → [Set] → [Set]
join1 x [ ] = [x]
join1 x (y:ys) = if Set.null $ Set.intersection x y
then y : join1 x ys
else join1 (Set.union x y) ys