diff -r e85600529ca5 -r 4794759139ea scala/automata1.scala --- a/scala/automata1.scala Sat Jun 15 09:11:11 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +0,0 @@ - -// a class for deterministic finite automata, -// the type of states is kept polymorphic - -case class Automaton[A](start: A, states: Set[A], delta: Map[(A, Char), A], fins: Set[A]) { - - // the transition function lifted to list of characters - def deltas(q: A, cs: List[Char]) : A = - if (states.contains(q)) cs match { - case Nil => q - case c::cs => - if (delta.isDefinedAt(q, c)) deltas(delta(q, c), cs) - else throw new RuntimeException(q + " does not have a transition for " + c) - } - else throw new RuntimeException(q + " is not a state of the automaton") - - // wether a string is accepted by the automaton - def accepts(s: String) = - try { - fins.contains(deltas(start, s.toList)) - } catch { - case e:RuntimeException => false - } -} - - - -abstract class Rexp - -case object NULL extends Rexp -case object EMPTY extends Rexp -case class CHAR(c: Char) extends Rexp -case class ALT(r1: Rexp, r2: Rexp) extends Rexp -case class SEQ(r1: Rexp, r2: Rexp) extends Rexp -case class STAR(r: Rexp) extends Rexp - -implicit def string2rexp(s : String) = { - def chars2rexp (cs: List[Char]) : Rexp = cs match { - case Nil => EMPTY - case c::Nil => CHAR(c) - case c::cs => SEQ(CHAR(c), chars2rexp(cs)) - } - chars2rexp(s.toList) -} - -def nullable (r: Rexp) : Boolean = r match { - case NULL => false - case EMPTY => true - case CHAR(_) => false - case ALT(r1, r2) => nullable(r1) || nullable(r2) - case SEQ(r1, r2) => nullable(r1) && nullable(r2) - case STAR(_) => true -} - -def der (r: Rexp, c: Char) : Rexp = r match { - case NULL => NULL - case EMPTY => NULL - case CHAR(d) => if (c == d) EMPTY else NULL - case ALT(r1, r2) => ALT(der(r1, c), der(r2, c)) - case SEQ(r1, r2) => if (nullable(r1)) ALT(SEQ(der(r1, c), r2), der(r2, c)) - else SEQ(der(r1, c), r2) - case STAR(r) => SEQ(der(r, c), STAR(r)) -} - - -// Here we construct an automaton whose -// states are regular expressions -type State = Rexp -type States = Set[State] -type Transition = Map[(State, Char), State] - -def goto(q: State, c: Char, qs: States, delta: Transition) : (States, Transition) = { - val qc : State = der(q, c) - if (qs.contains(qc)) (qs, delta + ((q, c) -> q)) - else explore(qs + qc, delta + ((q, c) -> qc), qc) -} - -// we use as alphabet all lowercase letters -val alphabet = "abcdefghijklmnopqrstuvwxyz".toSet - -def explore (qs: States, delta: Transition, q: State) : (States, Transition) = - alphabet.foldRight[(States, Transition)] (qs, delta) ((c, qsd) => goto(q, c, qsd._1, qsd._2)) - - -def mk_automaton (r: Rexp) : Automaton[Rexp] = { - val (qs, delta) = explore(Set(r), Map(), r); - val fins = for (q <- qs if nullable(q)) yield q; - Automaton[Rexp](r, qs, delta, fins) -} - -val A = mk_automaton(ALT("ab","ac")) - -println(A.accepts("bd")) -println(A.accepts("ab")) -println(A.accepts("ac"))