| author | Christian Urban <urbanc@in.tum.de> | 
| Mon, 18 Sep 2017 14:02:46 +0100 | |
| changeset 499 | b06c81c0b12f | 
| parent 487 | ffbc65112d48 | 
| child 576 | 414f1daf5728 | 
| permissions | -rw-r--r-- | 
| 485 | 1 | // DFAs in Scala using partial functions | 
| 480 | 2 | import scala.util.Try | 
| 479 | 3 | |
| 480 | 4 | // type abbreviation for partial functions | 
| 5 | type :=>[A, B] = PartialFunction[A, B] | |
| 479 | 6 | |
| 483 | 7 | case class DFA[A, C](start: A, // starting state | 
| 8 | delta: (A, C) :=> A, // transition (partial fun) | |
| 9 |                      fins:  A => Boolean) {  // final states
 | |
| 479 | 10 | |
| 480 | 11 |   def deltas(q: A, s: List[C]) : A = s match {
 | 
| 12 | case Nil => q | |
| 13 | case c::cs => deltas(delta(q, c), cs) | |
| 145 
920f675b4ed1
added
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 14 | } | 
| 479 | 15 | |
| 480 | 16 | def accepts(s: List[C]) : Boolean = | 
| 17 | Try(fins(deltas(start, s))) getOrElse false | |
| 479 | 18 | } | 
| 19 | ||
| 487 | 20 | // the example shown in the handout | 
| 145 
920f675b4ed1
added
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 21 | abstract class State | 
| 480 | 22 | case object Q0 extends State | 
| 23 | case object Q1 extends State | |
| 24 | case object Q2 extends State | |
| 25 | case object Q3 extends State | |
| 26 | case object Q4 extends State | |
| 145 
920f675b4ed1
added
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 27 | |
| 480 | 28 | val delta : (State, Char) :=> State = | 
| 29 |   { case (Q0, 'a') => Q1
 | |
| 30 | case (Q0, 'b') => Q2 | |
| 31 | case (Q1, 'a') => Q4 | |
| 32 | case (Q1, 'b') => Q2 | |
| 33 | case (Q2, 'a') => Q3 | |
| 34 | case (Q2, 'b') => Q2 | |
| 35 | case (Q3, 'a') => Q4 | |
| 36 | case (Q3, 'b') => Q0 | |
| 37 | case (Q4, 'a') => Q4 | |
| 38 | case (Q4, 'b') => Q4 } | |
| 145 
920f675b4ed1
added
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 39 | |
| 480 | 40 | val dfa = DFA(Q0, delta, Set[State](Q4)) | 
| 145 
920f675b4ed1
added
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 41 | |
| 480 | 42 | dfa.accepts("bbabaab".toList)   // true
 | 
| 43 | dfa.accepts("baba".toList)      // false
 | |
| 487 | 44 | |
| 45 | ||
| 46 | // another DFA test with a Sink state | |
| 47 | abstract class S | |
| 48 | case object S0 extends S | |
| 49 | case object S1 extends S | |
| 50 | case object S2 extends S | |
| 51 | case object Sink extends S | |
| 52 | ||
| 53 | // transition function with a sink state | |
| 54 | val sigma : (S, Char) :=> S = | |
| 55 |   { case (S0, 'a') => S1
 | |
| 56 | case (S1, 'a') => S2 | |
| 57 | case _ => Sink | |
| 58 | } | |
| 59 | ||
| 60 | val dfa1a = DFA(S0, sigma, Set[S](S2)) | |
| 61 | ||
| 62 | dfa1a.accepts("aa".toList)        // true
 | |
| 63 | dfa1a.accepts("".toList)          // false
 | |
| 64 | dfa1a.accepts("ab".toList)        // false
 | |
| 65 |