content: module DDC.Core.Flow.Transform.Rates.Clusters.Base where
  import DDC.Core.Flow.Transform.Rates.Graph
  
  type TransducerMap n = n -> n -> Maybe (n,n)
  
  -- \forall paths p from u to v, fusion preventing \not\in p
  noFusionPreventingPath :: (Ord n) => [((n,n),Bool)] -> n -> n -> Bool
  noFusionPreventingPath arcs u v
   -- for all paths, for all nodes in path, is fusible
   =  all (all snd) (paths u v)
   && all (all snd) (paths v u)
   where
    -- list of all paths from w to x
    paths w x
      | w == x
      = [[]]
      | otherwise
      = let outs = filter (\((i,_j),_f) -> i == w) arcs
        in  concatMap (\((w',j),f) -> map (((w',j),f):) (paths j x)) outs
     
  
  -- | Check if two nodes may be fused based on type.
  -- If they have the same type, it's fine.
  -- If they have a different type, we must look for any common type transducer parents.
  typeComparable :: (Ord n, Eq t) => Graph n t -> TransducerMap n -> n -> n -> Bool
  typeComparable g trans a b
   = case (nodeType g a, nodeType g b) of
     (Just a', Just b')
      -> if   a' == b'
         then True
         else case trans a b of
                   Just _  -> True
                   Nothing -> False
     _
      -> False
  
  
  