module Minimalize where
import DFA
import MUtils(usort,mapSnd,collectBySnd)
import qualified OrdMap as OM
import Maybe(fromMaybe)

minimalize (s,DFA states) = iter [] (s,OM.toList states)
  where
    iter eqs dfa = case equalStates dfa of
	             ([],(s,states)) -> (eqs,(s,DFA (OM.fromList states)))
		     (eqs',dfa) -> iter (eqs':eqs) dfa

equalStates ((st,fin),states) =
    (eqclasses,((sren st,usort $ map sren fin),states'))
  where
     eqstates = collectBySnd states
     eqclasses = filter ((>1).length) . map fst $ eqstates
     smap = [(s',s)|s:ss<-eqclasses,s'<-ss]
     sren s = fromMaybe s (lookup s smap)

     states' = map renState eqstates

     renState (s:_,(is,os)) = (s,(nubMapSnd sren is,nubMapSnd sren os))

     nubMapSnd f = usort . mapSnd f