diff -r dfa7b4ca199f -r 14318f1d3b0f progs/dfa.scala --- a/progs/dfa.scala Wed Mar 15 14:34:10 2017 +0000 +++ b/progs/dfa.scala Wed Mar 22 14:10:01 2017 +0000 @@ -1,64 +1,43 @@ -// DFAs -import scala.util._ +// DFAs in Scala based on partial functions +import scala.util.Try -abstract class State -type States = Set[State] - -case class IntState(i: Int) extends State +// type abbreviation for partial functions +type :=>[A, B] = PartialFunction[A, B] -object NewState { - var counter = 0 - - def apply() : IntState = { - counter += 1; - new IntState(counter - 1) +case class DFA[A, C](start: A, // starting state + delta: (A, C) :=> A, // transition partial fun + fins: A => Boolean) { // final states + + def deltas(q: A, s: List[C]) : A = s match { + case Nil => q + case c::cs => deltas(delta(q, c), cs) } + + def accepts(s: List[C]) : Boolean = + Try(fins(deltas(start, s))) getOrElse false } - -// DFA class -case class DFA(states: States, - start: State, - delta: (State, Char) => State, - fins: States) { - - def deltas(q: State, s: List[Char]) : State = s match { - case Nil => q - case c::cs => deltas(delta(q, c), cs) - } - - // wether a string is accepted by the automaton or not - def accepts(s: String) : Boolean = - Try(fins contains - (deltas(start, s.toList))) getOrElse false -} - +// the example shown earlier in the handout +abstract class State +case object Q0 extends State +case object Q1 extends State +case object Q2 extends State +case object Q3 extends State +case object Q4 extends State -// example DFA from the lectures -val Q0 = NewState() -val Q1 = NewState() -val Q2 = NewState() -val Q3 = NewState() -val Q4 = NewState() - +val delta : (State, Char) :=> State = + { case (Q0, 'a') => Q1 + case (Q0, 'b') => Q2 + case (Q1, 'a') => Q4 + case (Q1, 'b') => Q2 + case (Q2, 'a') => Q3 + case (Q2, 'b') => Q2 + case (Q3, 'a') => Q4 + case (Q3, 'b') => Q0 + case (Q4, 'a') => Q4 + case (Q4, 'b') => Q4 } -val delta : (State, Char) => State = { - case (Q0, 'a') => Q1 - case (Q0, 'b') => Q2 - case (Q1, 'a') => Q4 - case (Q1, 'b') => Q2 - case (Q2, 'a') => Q3 - case (Q2, 'b') => Q2 - case (Q3, 'a') => Q4 - case (Q3, 'b') => Q0 - case (Q4, 'a') => Q4 - case (Q4, 'b') => Q4 -} +val dfa = DFA(Q0, delta, Set[State](Q4)) -val DFA1 = DFA(Set(Q0, Q1, Q2, Q3, Q4), Q0, delta, Set(Q4)) - -println(DFA1.accepts("aaa")) -println(DFA1.accepts("bb")) -println(DFA1.accepts("aaac")) - - +dfa.accepts("bbabaab".toList) // true +dfa.accepts("baba".toList) // false