| author | Christian Urban <urbanc@in.tum.de> | 
| Thu, 26 Sep 2019 12:59:33 +0100 | |
| changeset 635 | 81b85ccfa40c | 
| parent 491 | 7a0182c66403 | 
| permissions | -rw-r--r-- | 
| 485 | 1  | 
// NFAs in Scala using partial functions (returning  | 
2  | 
// sets of states)  | 
|
| 491 | 3  | 
//  | 
4  | 
// needs :load dfa.scala for states  | 
|
5  | 
||
| 
144
 
0cb61bed557d
added
 
Christian Urban <christian dot urban at kcl dot ac dot uk> 
parents:  
diff
changeset
 | 
6  | 
|
| 482 | 7  | 
// type abbreviation for partial functions  | 
8  | 
type :=>[A, B] = PartialFunction[A, B]  | 
|
| 
144
 
0cb61bed557d
added
 
Christian Urban <christian dot urban at kcl dot ac dot uk> 
parents:  
diff
changeset
 | 
9  | 
|
| 485 | 10  | 
// return an empty set when not defined  | 
11  | 
def applyOrElse[A, B](f: A :=> Set[B], x: A) : Set[B] =  | 
|
12  | 
Try(f(x)) getOrElse Set[B]()  | 
|
13  | 
||
14  | 
||
15  | 
// NFAs  | 
|
| 487 | 16  | 
case class NFA[A, C](starts: Set[A], // starting states  | 
17  | 
delta: (A, C) :=> Set[A], // transition function  | 
|
18  | 
                     fins:  A => Boolean) {    // final states 
 | 
|
| 
144
 
0cb61bed557d
added
 
Christian Urban <christian dot urban at kcl dot ac dot uk> 
parents:  
diff
changeset
 | 
19  | 
|
| 485 | 20  | 
// given a state and a character, what is the set of  | 
21  | 
// next states? if there is none => empty set  | 
|
| 482 | 22  | 
def next(q: A, c: C) : Set[A] =  | 
| 485 | 23  | 
applyOrElse(delta, (q, c))  | 
| 
144
 
0cb61bed557d
added
 
Christian Urban <christian dot urban at kcl dot ac dot uk> 
parents:  
diff
changeset
 | 
24  | 
|
| 482 | 25  | 
def nexts(qs: Set[A], c: C) : Set[A] =  | 
26  | 
qs.flatMap(next(_, c))  | 
|
| 
144
 
0cb61bed557d
added
 
Christian Urban <christian dot urban at kcl dot ac dot uk> 
parents:  
diff
changeset
 | 
27  | 
|
| 485 | 28  | 
// given some states and a string, what is the set  | 
29  | 
// of next states?  | 
|
| 482 | 30  | 
  def deltas(qs: Set[A], s: List[C]) : Set[A] = s match {
 | 
31  | 
case Nil => qs  | 
|
32  | 
case c::cs => deltas(nexts(qs, c), cs)  | 
|
| 
144
 
0cb61bed557d
added
 
Christian Urban <christian dot urban at kcl dot ac dot uk> 
parents:  
diff
changeset
 | 
33  | 
}  | 
| 
 
0cb61bed557d
added
 
Christian Urban <christian dot urban at kcl dot ac dot uk> 
parents:  
diff
changeset
 | 
34  | 
|
| 485 | 35  | 
// is a string accepted by an NFA?  | 
| 482 | 36  | 
def accepts(s: List[C]) : Boolean =  | 
37  | 
deltas(starts, s).exists(fins)  | 
|
| 
144
 
0cb61bed557d
added
 
Christian Urban <christian dot urban at kcl dot ac dot uk> 
parents:  
diff
changeset
 | 
38  | 
}  |