| author | Christian Urban <urbanc@in.tum.de> | 
| Thu, 03 Aug 2017 01:21:19 +0100 | |
| changeset 498 | cd2d192775a4 | 
| 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  |