-- Typdefinitionen für den NFA:
-------------------------------

module NFA where

type Sigma       = [Char] -- = String, hier aber nicht gemeint...

-- Uebergangsfunktion fuer NFAs 
-- (Epsilon-Transitionen: Maybe, Nichtdeterminismus: Menge von Zustaenden)
type DeltaNFA state = state -> Maybe Char -> [state]

data NFA state = NFA [state]          -- Liste der Zustaende
                     Sigma            -- Alphabet
                     (DeltaNFA state) -- Transitionsfunktion
                     state            -- Anfangszustand
                     [state]          -- Menge der Endzustaende

--
-- Show: NFA, DFA
--
--------------------------------------------------------------------------------

showNFA :: Show state => NFA state -> IO()
showNFA (NFA qs cs delta q0 finals) 
 = putStr ("Zustandsmenge:   " ++ show qs ++
   '\n':"Alphabet: " ++ show cs  ++
   '\n':"Transitionstabelle:" ++ (showDelta qs cs delta) ++ 
   '\n':"Startzustand:" ++ show q0 ++
   '\n':"Endzustaende:" ++ show finals) 

showDelta :: Show state => [state] -> Sigma -> DeltaNFA state -> String
showDelta [] cs delta = ['\n']
showDelta (q:qs) cs delta 
    = concat (map (showLine q delta) cs)
          ++ '\n': show q ++ " - eps -> " ++ show (delta q Nothing)  ++
      (showDelta qs cs delta)
    where showLine q delta c = '\n': show q ++ " - " ++ [c] ++ "   -> " 
                               ++ show (delta q (Just c))  
