author | Christian Urban <urbanc@in.tum.de> |
Tue, 21 Mar 2017 11:40:22 +0000 | |
changeset 240 | 820228ac1d0f |
parent 239 | e59cec211f4f |
child 241 | 1075bba7b8b1 |
permissions | -rw-r--r-- |
239
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
1 |
// DFAs and NFAs based on Scala's partial functions |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
2 |
import scala.util.Try |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
3 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
4 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
5 |
// type abbreviation for partial functions |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
6 |
type :=>[A, B] = PartialFunction[A, B] |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
7 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
8 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
9 |
// some states for test cases |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
10 |
abstract class State |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
11 |
case object Q0 extends State |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
12 |
case object Q1 extends State |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
13 |
case object Q2 extends State |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
14 |
case object Q3 extends State |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
15 |
case object Q4 extends State |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
16 |
case object Q5 extends State |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
17 |
case object Q6 extends State |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
18 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
19 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
20 |
// class for DFAs |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
21 |
case class DFA[A, C](start: A, // starting state |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
22 |
delta: (A, C) :=> A, // transition |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
23 |
fins: A => Boolean) { // final states |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
24 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
25 |
// given a state and a "string", what is the next |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
26 |
// state, if there is any? |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
27 |
def deltas(q: A, s: List[C]) : A = s match { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
28 |
case Nil => q |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
29 |
case c::cs => deltas(delta(q, c), cs) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
30 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
31 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
32 |
// is a "string" accepted by an DFA? |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
33 |
def accepts(s: List[C]) : Boolean = |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
34 |
Try(fins(deltas(start, s))) getOrElse false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
35 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
36 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
37 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
38 |
// DFA 1 |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
39 |
val dtrans1 : (State, Char) :=> State = |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
40 |
{ case (Q0, 'a') => Q0 |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
41 |
case (Q0, 'b') => Q1 |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
42 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
43 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
44 |
val dfa1 = DFA(Q0, dtrans1, Set[State](Q1)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
45 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
46 |
dfa1.accepts("aaab".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
47 |
dfa1.accepts("aacb".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
48 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
49 |
// another DFA test |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
50 |
abstract class S |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
51 |
case object S0 extends S |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
52 |
case object S1 extends S |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
53 |
case object S2 extends S |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
54 |
case object Sink extends S |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
55 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
56 |
// transition function with a sink state |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
57 |
// S0 --a--> S1 --a--> S2 |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
58 |
val sigma : (S, Char) :=> S = |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
59 |
{ case (S0, 'a') => S1 |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
60 |
case (S1, 'a') => S2 |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
61 |
case _ => Sink |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
62 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
63 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
64 |
val dfa1a = DFA(S0, sigma, Set[S](S2)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
65 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
66 |
dfa1a.accepts("aa".toList) //true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
67 |
dfa1a.accepts("".toList) //false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
68 |
dfa1a.accepts("ab".toList) //false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
69 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
70 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
71 |
// class for NFAs |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
72 |
case class NFA[A, C](starts: Set[A], // starting states |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
73 |
delta: Set[(A, C) :=> A], // transitions |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
74 |
fins: A => Boolean) { // final states |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
75 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
76 |
// given a state and a character, what is the set of next states? |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
77 |
// if there is none => empty set |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
78 |
def next(q: A, c: C) : Set[A] = |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
79 |
delta.flatMap((d) => Try(d(q, c)).toOption) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
80 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
81 |
def nexts(qs: Set[A], c: C) : Set[A] = |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
82 |
qs.flatMap(next(_, c)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
83 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
84 |
// given some states and a string, what is the set of next states? |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
85 |
def deltas(qs: Set[A], s: List[C]) : Set[A] = s match { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
86 |
case Nil => qs |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
87 |
case c::cs => deltas(nexts(qs, c), cs) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
88 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
89 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
90 |
// is a string accepted by an NFA? |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
91 |
def accepts(s: List[C]) : Boolean = |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
92 |
deltas(starts, s).exists(fins) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
93 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
94 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
95 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
96 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
97 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
98 |
// NFA test cases |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
99 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
100 |
// 1 |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
101 |
val trans1 = Set[(State, Char) :=> State]( |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
102 |
{ case (Q0, 'a') => Q1 }, |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
103 |
{ case (Q0, _) => Q0 }, |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
104 |
{ case (Q1, _) => Q2 }, |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
105 |
{ case (Q2, _) => Q3 }, |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
106 |
{ case (Q3, _) => Q4 }, |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
107 |
{ case (Q4, 'b') => Q5 }, |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
108 |
{ case (Q5, 'c') => Q6 } |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
109 |
) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
110 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
111 |
val nfa1 = NFA(Set[State](Q0), trans1, Set[State](Q6)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
112 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
113 |
nfa1.accepts("axaybzbc".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
114 |
nfa1.accepts("aaaaxaybzbc".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
115 |
nfa1.accepts("axaybzbd".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
116 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
117 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
118 |
// 2 |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
119 |
val trans2 = Set[(State, Char) :=> State]( |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
120 |
{ case (Q0, 'a') => Q0 }, |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
121 |
{ case (Q0, 'a') => Q1 }, |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
122 |
{ case (Q0, 'b') => Q2 }, |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
123 |
{ case (Q1, 'a') => Q1 }, |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
124 |
{ case (Q2, 'b') => Q2 } |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
125 |
) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
126 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
127 |
val nfa2 = NFA(Set[State](Q0), trans2, Set[State](Q2)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
128 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
129 |
nfa2.accepts("aa".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
130 |
nfa2.accepts("aaaaa".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
131 |
nfa2.accepts("aaaaab".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
132 |
nfa2.accepts("aaaaabbb".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
133 |
nfa2.accepts("aaaaabbbaaa".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
134 |
nfa2.accepts("ac".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
135 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
136 |
// 3 |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
137 |
val trans3 = Set[(State, Char) :=> State]( |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
138 |
{ case (Q0, _) => Q0 }, |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
139 |
{ case (Q0, 'a') => Q1 }, |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
140 |
{ case (Q0, 'b') => Q3 }, |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
141 |
{ case (Q1, 'b') => Q2 }, |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
142 |
{ case (Q2, 'c') => Q5 }, |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
143 |
{ case (Q3, 'c') => Q4 }, |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
144 |
{ case (Q4, 'd') => Q5 } |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
145 |
) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
146 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
147 |
val nfa3 = NFA(Set[State](Q0), trans3, Set[State](Q5)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
148 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
149 |
nfa3.accepts("aaaaabc".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
150 |
nfa3.accepts("aaaabcd".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
151 |
nfa3.accepts("aaaaab".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
152 |
nfa3.accepts("aaaabc".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
153 |
nfa3.accepts("aaaaabbbaaa".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
154 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
155 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
156 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
157 |
// subset, or powerset, construction |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
158 |
def powerset[A, C](nfa: NFA[A, C]) : DFA[Set[A], C] = { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
159 |
DFA(nfa.starts, |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
160 |
{ case (qs, c) => nfa.nexts(qs, c) }, |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
161 |
_.exists(nfa.fins)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
162 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
163 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
164 |
val dfa2 = powerset(nfa1) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
165 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
166 |
dfa2.accepts("axaybzbc".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
167 |
dfa2.accepts("aaaaxaybzbc".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
168 |
dfa2.accepts("axaybzbd".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
169 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
170 |
val dfa3 = powerset(nfa2) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
171 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
172 |
dfa3.accepts("aa".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
173 |
dfa3.accepts("aaaaa".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
174 |
dfa3.accepts("aaaaab".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
175 |
dfa3.accepts("aaaaabbb".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
176 |
dfa3.accepts("aaaaabbbaaa".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
177 |
dfa3.accepts("ac".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
178 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
179 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
180 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
181 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
182 |
// epsilon NFA |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
183 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
184 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
185 |
// fixpoint construction |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
186 |
import scala.annotation.tailrec |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
187 |
@tailrec |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
188 |
def fixpT[A](f: A => A, x: A): A = { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
189 |
val fx = f(x) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
190 |
if (fx == x) x else fixpT(f, fx) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
191 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
192 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
193 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
194 |
case class eNFA[A, C](starts: Set[A], // starting state |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
195 |
delta: Set[(A, Option[C]) :=> A], // transition edges |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
196 |
fins: A => Boolean) { // final states |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
197 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
198 |
// epsilon transitions |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
199 |
def enext(q: A) : Set[A] = |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
200 |
delta.flatMap((d) => Try(d(q, None)).toOption) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
201 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
202 |
def enexts(qs: Set[A]) : Set[A] = |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
203 |
qs ++ qs.flatMap(enext(_)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
204 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
205 |
// epsilon closure |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
206 |
def ecl(qs: Set[A]) : Set[A] = |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
207 |
fixpT(enexts, qs) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
208 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
209 |
// "normal" transition |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
210 |
def next(q: A, c: C) : Set[A] = |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
211 |
delta.flatMap((d) => Try(d(q, Some(c))).toOption) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
212 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
213 |
def nexts(qs: Set[A], c: C) : Set[A] = |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
214 |
qs.flatMap(next(_, c)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
215 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
216 |
def deltas(qs: Set[A], s: List[C]) : Set[A] = s match { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
217 |
case Nil => ecl(qs) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
218 |
case c::cs => deltas(ecl(nexts(ecl(qs), c)), cs) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
219 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
220 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
221 |
def accepts(s: List[C]) : Boolean = |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
222 |
deltas(starts, s.toList).exists(fins) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
223 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
224 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
225 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
226 |
val etrans1 = Set[(State, Option[Char]) :=> State]( |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
227 |
{ case (Q0, Some('a')) => Q1 }, |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
228 |
{ case (Q1, None) => Q0 } |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
229 |
) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
230 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
231 |
val enfa = eNFA(Set[State](Q0), etrans1, Set[State](Q1)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
232 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
233 |
enfa.accepts("a".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
234 |
enfa.accepts("".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
235 |
enfa.accepts("aaaaa".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
236 |
enfa.accepts("aaaaab".toList) // flase |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
237 |
enfa.accepts("aaaaabbb".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
238 |
enfa.accepts("aaaaabbbaaa".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
239 |
enfa.accepts("ac".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
240 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
241 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
242 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
243 |
// Regular expressions fro derivative automata |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
244 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
245 |
abstract class Rexp |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
246 |
case object ZERO extends Rexp |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
247 |
case object ONE extends Rexp |
240
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
248 |
case class CHAR(c: Char) extends Rexp |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
249 |
case object ALL extends Rexp |
239
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
250 |
case class ALT(r1: Rexp, r2: Rexp) extends Rexp |
240
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
251 |
case class SEQ(r1: Rexp, r2: Rexp) extends Rexp |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
252 |
case class STAR(r: Rexp) extends Rexp |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
253 |
case class NTIMES(r: Rexp, n: Int) extends Rexp |
239
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
254 |
case class UPNTIMES(r: Rexp, n: Int) extends Rexp |
240
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
255 |
case class NOT(r: Rexp) extends Rexp |
239
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
256 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
257 |
def get_chars(r: Rexp) : Set[Char] = r match { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
258 |
case ZERO => Set() |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
259 |
case ONE => Set() |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
260 |
case CHAR(c) => Set(c) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
261 |
case ALT(r1, r2) => get_chars(r1) ++ get_chars(r2) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
262 |
case SEQ(r1, r2) => get_chars(r1) ++ get_chars(r2) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
263 |
case STAR(r) => get_chars(r) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
264 |
case NTIMES(r, _) => get_chars(r) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
265 |
case UPNTIMES(r, _) => get_chars(r) |
240
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
266 |
case ALL => ('a' to 'z').toSet ++ Set('*','/','\\') |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
267 |
case NOT(r) => get_chars(r) |
239
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
268 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
269 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
270 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
271 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
272 |
import scala.language.implicitConversions |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
273 |
import scala.language.reflectiveCalls |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
274 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
275 |
def charlist2rexp(s: List[Char]): Rexp = s match { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
276 |
case Nil => ONE |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
277 |
case c::Nil => CHAR(c) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
278 |
case c::s => SEQ(CHAR(c), charlist2rexp(s)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
279 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
280 |
implicit def string2rexp(s: String): Rexp = charlist2rexp(s.toList) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
281 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
282 |
implicit def RexpOps (r: Rexp) = new { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
283 |
def | (s: Rexp) = ALT(r, s) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
284 |
def % = STAR(r) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
285 |
def ~ (s: Rexp) = SEQ(r, s) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
286 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
287 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
288 |
implicit def stringOps (s: String) = new { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
289 |
def | (r: Rexp) = ALT(s, r) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
290 |
def | (r: String) = ALT(s, r) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
291 |
def % = STAR(s) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
292 |
def ~ (r: Rexp) = SEQ(s, r) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
293 |
def ~ (r: String) = SEQ(s, r) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
294 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
295 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
296 |
def simp(r: Rexp) : Rexp = r match { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
297 |
case ALT(r1, r2) => (simp(r1), simp(r2)) match { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
298 |
case (ZERO, r2s) => r2s |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
299 |
case (r1s, ZERO) => r1s |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
300 |
case (r1s, r2s) => if (r1s == r2s) r1s else ALT (r1s, r2s) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
301 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
302 |
case SEQ(r1, r2) => (simp(r1), simp(r2)) match { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
303 |
case (ZERO, _) => ZERO |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
304 |
case (_, ZERO) => ZERO |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
305 |
case (ONE, r2s) => r2s |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
306 |
case (r1s, ONE) => r1s |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
307 |
case (r1s, r2s) => SEQ(r1s, r2s) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
308 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
309 |
case NTIMES(r, n) => if (n == 0) ONE else NTIMES(simp(r), n) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
310 |
case UPNTIMES(r, n) => if (n == 0) ONE else UPNTIMES(simp(r), n) |
240
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
311 |
case NOT(r) => NOT(simp(r)) |
239
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
312 |
case r => r |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
313 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
314 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
315 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
316 |
// nullable function: tests whether the regular |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
317 |
// expression can recognise the empty string |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
318 |
def nullable(r: Rexp) : Boolean = r match { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
319 |
case ZERO => false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
320 |
case ONE => true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
321 |
case CHAR(_) => false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
322 |
case ALL => false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
323 |
case ALT(r1, r2) => nullable(r1) || nullable(r2) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
324 |
case SEQ(r1, r2) => nullable(r1) && nullable(r2) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
325 |
case STAR(_) => true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
326 |
case NTIMES(r, i) => if (i == 0) true else nullable(r) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
327 |
case UPNTIMES(r: Rexp, n: Int) => true |
240
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
328 |
case NOT(r) => !nullable(r) |
239
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
329 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
330 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
331 |
// derivative of a regular expression w.r.t. a character |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
332 |
def der(c: Char, r: Rexp) : Rexp = r match { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
333 |
case ZERO => ZERO |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
334 |
case ONE => ZERO |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
335 |
case CHAR(d) => if (c == d) ONE else ZERO |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
336 |
case ALL => ONE |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
337 |
case ALT(r1, r2) => ALT(der(c, r1), der(c, r2)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
338 |
case SEQ(r1, r2) => |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
339 |
if (nullable(r1)) ALT(SEQ(der(c, r1), r2), der(c, r2)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
340 |
else SEQ(der(c, r1), r2) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
341 |
case STAR(r1) => SEQ(der(c, r1), STAR(r1)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
342 |
case NTIMES(r1, i) => |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
343 |
if (i == 0) ZERO else |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
344 |
if (nullable(r1)) SEQ(der(c, r1), UPNTIMES(r1, i - 1)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
345 |
else SEQ(der(c, r1), NTIMES(r1, i - 1)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
346 |
case UPNTIMES(r1, i) => |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
347 |
if (i == 0) ZERO |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
348 |
else SEQ(der(c, r1), UPNTIMES(r1, i - 1)) |
240
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
349 |
case NOT(r) => NOT(der(c, r)) |
239
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
350 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
351 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
352 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
353 |
// partial derivative of a regular expression w.r.t. a character |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
354 |
def pder(c: Char, r: Rexp) : Set[Rexp] = r match { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
355 |
case ZERO => Set() |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
356 |
case ONE => Set() |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
357 |
case CHAR(d) => if (c == d) Set(ONE) else Set() |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
358 |
case ALL => Set(ONE) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
359 |
case ALT(r1, r2) => pder(c, r1) ++ pder(c, r2) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
360 |
case SEQ(r1, r2) => |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
361 |
(for (pr1 <- pder(c, r1)) yield SEQ(pr1, r2)) ++ |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
362 |
(if (nullable(r1)) pder(c, r2) else Set()) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
363 |
case STAR(r1) => |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
364 |
for (pr1 <- pder(c, r1)) yield SEQ(pr1, STAR(r1)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
365 |
case NTIMES(r1, i) => |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
366 |
if (i == 0) Set() else |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
367 |
if (nullable(r1)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
368 |
for (pr1 <- pder(c, r1)) yield SEQ(pr1, UPNTIMES(r1, i - 1)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
369 |
else |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
370 |
for (pr1 <- pder(c, r1)) yield SEQ(pr1, NTIMES(r1, i - 1)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
371 |
case UPNTIMES(r1, i) => |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
372 |
if (i == 0) Set() |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
373 |
else |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
374 |
for (pr1 <- pder(c, r1)) yield SEQ(pr1, UPNTIMES(r1, i - 1)) |
240
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
375 |
case NOT(r1) => |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
376 |
for (pr1 <- pder(c, r1)) yield NOT(pr1) |
239
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
377 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
378 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
379 |
def ppder(c: Char, rs: Set[Rexp]) : Set[Rexp] = |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
380 |
rs.flatMap(pder(c, _)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
381 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
382 |
|
240
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
383 |
// matchers |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
384 |
def matcher(r: Rexp, s: List[Char]): Boolean = s match { |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
385 |
case Nil => nullable(r) |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
386 |
case c::cs => matcher(der(c, r), cs) |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
387 |
} |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
388 |
|
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
389 |
def pmatcher(rs: Set[Rexp], s: List[Char]): Boolean = s match { |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
390 |
case Nil => rs.exists(nullable(_)) |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
391 |
case c::cs => pmatcher(rs.flatMap(pder(c, _)), cs) |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
392 |
} |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
393 |
|
239
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
394 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
395 |
// quick-and-dirty translation of a pder automaton |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
396 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
397 |
val r = STAR(ALL) ~ "a" ~ NTIMES(ALL, 3) ~ "bc" |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
398 |
val pder_nfa = NFA[Set[Rexp], Char](Set(Set(r)), |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
399 |
Set( { case (rs, c) => rs.flatMap(pder(c, _))} ), |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
400 |
_.exists(nullable)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
401 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
402 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
403 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
404 |
pder_nfa.accepts("axaybzbc".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
405 |
pder_nfa.accepts("aaaaxaybzbc".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
406 |
pder_nfa.accepts("axaybzbd".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
407 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
408 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
409 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
410 |
// Derivative and Partial Derivative Automaton construction |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
411 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
412 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
413 |
type DState = Rexp // state type of the derivative automaton |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
414 |
type DStates = Set[Rexp] |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
415 |
type Trans = (DState, Char) :=> DState // transition functions of the der/pder auto |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
416 |
type MTrans = Map[(DState, Char), DState] // transition Maps |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
417 |
type STrans = Set[MTrans] // set of transition Maps |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
418 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
419 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
420 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
421 |
// Brzozoswki Derivative automaton construction ... simple |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
422 |
// version, might not terminate |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
423 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
424 |
def goto(sigma: Set[Char], delta: MTrans, qs: DStates, q: DState, c: Char) : (DStates, MTrans) = { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
425 |
val qder = simp(der(c, q)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
426 |
qs.find(_ == qder) match { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
427 |
case Some(qexists) => (qs, delta + ((q, c) -> qexists)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
428 |
case None => explore(sigma, delta + ((q, c) -> qder), qs + qder, qder) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
429 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
430 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
431 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
432 |
def explore(sigma: Set[Char], delta: MTrans, qs: DStates, q: DState) : (DStates, MTrans) = |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
433 |
sigma.foldLeft((qs, delta)) { case ((qs, delta), c) => goto(sigma, delta, qs, q, c) } |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
434 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
435 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
436 |
def mkDFA(r: Rexp) = { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
437 |
val sigma = get_chars(r) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
438 |
val (qs, delta) = explore(sigma, Map(), Set[Rexp](r), r) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
439 |
val fins = qs.filter(nullable(_)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
440 |
val deltaf : (Rexp, Char) :=> Rexp = { case (q, c) => delta(q, c) } |
240
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
441 |
println(s"DFA size: ${qs.size}") |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
442 |
println(s"""DFA states\n${qs.mkString("\n")}""") |
239
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
443 |
DFA(r, deltaf, fins) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
444 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
445 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
446 |
val re = "ab" | "ac" |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
447 |
val d1 = mkDFA(re) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
448 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
449 |
d1.accepts("ab".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
450 |
d1.accepts("ac".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
451 |
d1.accepts("aa".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
452 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
453 |
val d2 = mkDFA(r) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
454 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
455 |
d2.accepts("axaybzbc".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
456 |
d2.accepts("aaaaxaybzbc".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
457 |
d2.accepts("axaybzbd".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
458 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
459 |
for (n <- (1 to 10).toList) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
460 |
mkDFA(STAR(ALL) ~ "a" ~ NTIMES(ALL, n) ~ "bc") |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
461 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
462 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
463 |
// this is an example where mkDFA does not terminate |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
464 |
val big_aux = STAR("a" | "b") |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
465 |
val big = SEQ(big_aux, SEQ("a",SEQ("b", big_aux))) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
466 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
467 |
//mkDFA(big) // does not terminate |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
468 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
469 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
470 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
471 |
// Antimirov Partial derivative automata construction ... definitely terminates |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
472 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
473 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
474 |
// to transform (concrete) Maps into functions |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
475 |
def toFun(m: MTrans) : Trans = |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
476 |
{ case (q, c) => m(q, c) } |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
477 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
478 |
def pgoto(sigma: Set[Char], delta: STrans, qs: DStates, q: DState, c: Char) : (DStates, STrans) = { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
479 |
val qders = pder(c, q).map(simp(_)) // set of simplified partial derivatives |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
480 |
qders.foldLeft((qs, delta)) { case ((qs, delta), qnew) => padd(sigma, delta, qs, q, qnew, c) } |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
481 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
482 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
483 |
def padd(sigma: Set[Char], delta: STrans, qs: DStates, |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
484 |
q: DState, qnew: DState, c: Char) : (DStates, STrans) = { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
485 |
qs.find(_ == qnew) match { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
486 |
case Some(qexists) => (qs, delta + Map((q, c) -> qexists)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
487 |
case None => pexplore(sigma, delta + Map((q, c) -> qnew), qs + qnew, qnew) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
488 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
489 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
490 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
491 |
def pexplore(sigma: Set[Char], delta: STrans, qs: DStates, q: DState) : (DStates, STrans) = |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
492 |
sigma.foldLeft((qs, delta)) { case ((qs, delta), c) => pgoto(sigma, delta, qs, q, c) } |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
493 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
494 |
def mkNFA(r: Rexp) : NFA[Rexp, Char]= { |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
495 |
val sigma = get_chars(r) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
496 |
val (qs, delta) = pexplore(sigma, Set(), Set(r), r) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
497 |
val fins = qs.filter(nullable(_)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
498 |
val deltaf = delta.map(toFun(_)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
499 |
println(s"NFA size: ${qs.size}") |
240
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
500 |
println(s"""NFA states\n${qs.mkString("\n")}""") |
239
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
501 |
NFA(Set(r), deltaf, fins) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
502 |
} |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
503 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
504 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
505 |
// simple example from Scott's paper |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
506 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
507 |
val n1 = mkNFA(re) // size = 4 |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
508 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
509 |
n1.accepts("ab".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
510 |
n1.accepts("ac".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
511 |
n1.accepts("aa".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
512 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
513 |
// example from: Partial Derivative and Position Bisimilarity |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
514 |
// Automata, Eva Maia, Nelma Moreira, Rogerio Reis |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
515 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
516 |
val r_test = STAR(("a" ~ STAR("b")) | "b") ~ "a" |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
517 |
val t1 = pder('a', r_test).map(simp(_)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
518 |
val t2 = pder('b', r_test).map(simp(_)) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
519 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
520 |
mkNFA(r_test) // size = 3 |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
521 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
522 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
523 |
// simple example involving double star |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
524 |
// with depth-first search causes catastrophic backtracing |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
525 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
526 |
val n2 = mkNFA(STAR(STAR("a")) ~ "b") // size 3 |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
527 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
528 |
n2.accepts("aaaaaab".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
529 |
n2.accepts("aaaaaa".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
530 |
n2.accepts(("a" * 100).toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
531 |
|
240
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
532 |
|
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
533 |
// example involving not |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
534 |
|
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
535 |
val rnot = "/*" ~ (NOT ((ALL.%) ~ "*/" ~ (ALL.%))) ~ "*/" |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
536 |
val nnot = mkNFA(rnot) // size 7 |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
537 |
|
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
538 |
nnot.accepts("/**/".toList) // true |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
539 |
nnot.accepts("/*aaabaa*/".toList) // true |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
540 |
nnot.accepts("/*/**/".toList) // true |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
541 |
nnot.accepts("/*aaa*/aa*/".toList) // false ???? |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
542 |
nnot.accepts("/aaa*/aa*/".toList) // false |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
543 |
|
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
544 |
matcher(rnot, "/**/".toList) // true |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
545 |
matcher(rnot, "/*aaabaa*/".toList) // true |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
546 |
matcher(rnot, "/*/**/".toList) // true |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
547 |
matcher(rnot, "/*aaa*/aa*/".toList) // false |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
548 |
matcher(rnot, "/aaa*/aa*/".toList) // false |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
549 |
|
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
550 |
pmatcher(Set(rnot), "/**/".toList) // true |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
551 |
pmatcher(Set(rnot), "/*aaabaa*/".toList) // true |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
552 |
pmatcher(Set(rnot), "/*/**/".toList) // true |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
553 |
pmatcher(Set(rnot), "/*aaa*/aa*/".toList) // false ????? |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
554 |
pmatcher(Set(rnot), "/aaa*/aa*/".toList) // false |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
555 |
|
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
556 |
// example from automata paper with counters and backreferences |
820228ac1d0f
updated for extended partial derivatives
Christian Urban <urbanc@in.tum.de>
parents:
239
diff
changeset
|
557 |
|
239
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
558 |
val r1 = STAR(ALL) ~ "a" ~ NTIMES(ALL, 1) ~ "bc" |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
559 |
mkNFA(r1) // size = 5 |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
560 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
561 |
val n3 = mkNFA(r) // size = 7 |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
562 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
563 |
n3.accepts("axaybzbc".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
564 |
n3.accepts("aaaaxaybzbc".toList) // true |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
565 |
n3.accepts("axaybzbd".toList) // false |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
566 |
|
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
567 |
for (n <- (1 to 100).toList) |
e59cec211f4f
added automata implementation
Christian Urban <urbanc@in.tum.de>
parents:
diff
changeset
|
568 |
mkNFA(STAR(ALL) ~ "a" ~ NTIMES(ALL, n) ~ "bc") |