progs/display/enfa.scala
changeset 487 a697421eaa04
parent 485 bd6d999ab7b6
child 488 598741d39d21
equal deleted inserted replaced
486:8178fcf377dc 487:a697421eaa04
       
     1 // epsilon NFAs...immediately translated into NFAs
       
     2 // (needs nfa.scala)
       
     3 
       
     4 // fixpoint construction
       
     5 import scala.annotation.tailrec
       
     6 @tailrec
       
     7 def fixpT[A](f: A => A, x: A): A = {
       
     8   val fx = f(x)
       
     9   if (fx == x) x else fixpT(f, fx) 
       
    10 }
       
    11 
       
    12 // translates eNFAs directly into NFAs 
       
    13 def eNFA[A, C](starts: Set[A],                     // starting states
       
    14                delta: (A, Option[C]) :=> Set[A],   // epsilon-transitions
       
    15                fins: A => Boolean) : NFA[A, C] = { // final states 
       
    16 
       
    17   // epsilon transitions
       
    18   def enext(q: A) : Set[A] = 
       
    19     applyOrElse(delta, (q, None))
       
    20 
       
    21   def enexts(qs: Set[A]) : Set[A] = 
       
    22     qs | qs.flatMap(enext(_))
       
    23 
       
    24   // epsilon closure
       
    25   def ecl(qs: Set[A]) : Set[A] = 
       
    26     fixpT(enexts, qs)
       
    27 
       
    28   // "normal" transitions
       
    29   def next(q: A, c: C) : Set[A] = 
       
    30     applyOrElse(delta, (q, Some(c)))
       
    31 
       
    32   def nexts(qs: Set[A], c: C) : Set[A] = 
       
    33     ecl(ecl(qs).flatMap(next(_, c)))
       
    34 
       
    35   // result NFA
       
    36   NFA(ecl(starts), 
       
    37       { case (q, c) => nexts(Set(q), c) }, 
       
    38       q => ecl(Set(q)) exists fins)
       
    39 }