progs/automata/nfa2.scala
author Christian Urban <urbanc@in.tum.de>
Sat, 04 Mar 2017 21:35:12 +0000
changeset 229 81c85f2746f5
permissions -rw-r--r--
updated
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
229
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     1
// DFAs and NFAs based on Scala's partial functions
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     2
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     3
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     4
// edges of the DFAs and NFAs
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     5
type Edge[A, C] = PartialFunction[(A, C), A]
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     6
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     7
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     8
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     9
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    10
// some states for test cases 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    11
abstract class State
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    12
case object Q0 extends State
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    13
case object Q1 extends State
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    14
case object Q2 extends State
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    15
case object Q3 extends State
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    16
case object Q4 extends State
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    17
case object Q5 extends State
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    18
case object Q6 extends State
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    19
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    20
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    21
// class for DFAs
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    22
case class DFA[A, C](start: A,               // starting state
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    23
                     trans: Edge[A, C],      // transition
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    24
                     fins:  A => Boolean) {  // final states
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    25
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    26
  // given a state and a character, 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    27
  // what is the next state, if there is any?
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    28
  def next(q: A, c: C) : Option[A] = 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    29
    trans.lift.apply((q, c))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    30
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    31
  // given a state and a string, what is the next state?
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    32
  def nexts(q: A, s: List[C]) : Option[A] = s match {
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    33
    case Nil => Some(q)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    34
    case c::cs => next(q, c).flatMap(nexts(_, cs))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    35
  }
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    36
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    37
  // is a string accepted by an DFA?
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    38
  def accepts(s: List[C]) : Boolean = nexts(start, s) match {
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    39
    case None => false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    40
    case Some(q) => fins(q)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    41
  }
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    42
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    43
}
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    44
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    45
// DFA 1
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    46
val dtrans1 : Edge[State, Char] = 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    47
  { case (Q0, 'a') => Q0 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    48
    case (Q0, 'b') => Q1 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    49
  }
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    50
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    51
val dfa1 = DFA(Q0, dtrans1, Set[State](Q1))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    52
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    53
dfa1.accepts("aaab".toList)     // true
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    54
dfa1.accepts("aacb".toList)     // false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    55
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    56
// another DFA test
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    57
abstract class S
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    58
case object S0 extends S
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    59
case object S1 extends S
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    60
case object S2 extends S
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    61
case object Sink extends S
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    62
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    63
// transition function
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    64
// S0 --a--> S1 --a--> S2
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    65
val sigma : Edge[S, Char] = 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    66
  { case (S0, 'a') => S1
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    67
    case (S1, 'a') => S2
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    68
    case _ => Sink
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    69
  }
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    70
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    71
val dfa1a = DFA(S0, sigma, Set[S](S2))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    72
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    73
dfa1a.accepts("aa".toList)               //true
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    74
dfa1a.accepts("".toList)                 //false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    75
dfa1a.accepts("ab".toList)               //false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    76
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    77
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    78
// class for NFAs
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    79
case class NFA[A, C](starts: Set[A],            // starting states
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    80
                     trans: Set[Edge[A, C]],    // transition edges
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    81
                     fins:  A => Boolean) {     // final states 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    82
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    83
  // given a state and a character, what is the set of next states?
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    84
  def next(q: A, c: C) : Set[A] = 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    85
    trans.flatMap(_.lift.apply((q, c)))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    86
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    87
  // given some states and a character, what is the set of next states?
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    88
  def nexts(qs: Set[A], c: C) : Set[A] = 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    89
    qs.flatMap(next(_, c))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    90
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    91
  // given some states and a string, what is the set of next states?
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    92
  def nextss(qs: Set[A], s: List[C]) : Set[A] = s match {
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    93
    case Nil => qs
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    94
    case c::cs => nextss(nexts(qs, c), cs)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    95
  }
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    96
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    97
  // is a string accepted by an NFA?
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    98
  def accepts(s: List[C]) : Boolean = 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    99
    nextss(starts, s.toList).exists(fins)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   100
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   101
}
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   102
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   103
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   104
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   105
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   106
// NFA test cases
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   107
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   108
// 1 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   109
val trans1 = Set[Edge[State, Char]](
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   110
  { case (Q0, 'a') => Q1 },
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   111
  { case (Q0, _)   => Q0 },
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   112
  { case (Q1, _)   => Q2 },
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   113
  { case (Q2, _)   => Q3 },
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   114
  { case (Q3, _)   => Q4 },
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   115
  { case (Q4, 'b') => Q5 },
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   116
  { case (Q5, 'c') => Q6 }
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   117
)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   118
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   119
val nfa1 = NFA(Set[State](Q0), trans1, Set[State](Q6))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   120
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   121
nfa1.accepts("axaybzbc".toList)     // true
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   122
nfa1.accepts("aaaaxaybzbc".toList)  // true
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   123
nfa1.accepts("axaybzbd".toList)     // false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   124
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   125
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   126
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   127
// 2
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   128
val trans2 = Set[Edge[State, Char]](
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   129
  { case (Q0, 'a') => Q0 },
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   130
  { case (Q0, 'a') => Q1 },
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   131
  { case (Q0, 'b') => Q2 },
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   132
  { case (Q1, 'a') => Q1 },
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   133
  { case (Q2, 'b') => Q2 }
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   134
)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   135
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   136
val nfa2 = NFA(Set[State](Q0), trans2, Set[State](Q2))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   137
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   138
nfa2.accepts("aa".toList)             // false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   139
nfa2.accepts("aaaaa".toList)          // false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   140
nfa2.accepts("aaaaab".toList)         // true
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   141
nfa2.accepts("aaaaabbb".toList)       // true
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   142
nfa2.accepts("aaaaabbbaaa".toList)    // false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   143
nfa2.accepts("ac".toList)             // false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   144
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   145
// 3
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   146
val trans3 = Set[Edge[State, Char]](
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   147
  { case (Q0, _)   => Q0 },
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   148
  { case (Q0, 'a') => Q1 },
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   149
  { case (Q0, 'b') => Q3 },
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   150
  { case (Q1, 'b') => Q2 },
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   151
  { case (Q2, 'c') => Q5 },
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   152
  { case (Q3, 'c') => Q4 },
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   153
  { case (Q4, 'd') => Q5 }
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   154
)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   155
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   156
val nfa3 = NFA(Set[State](Q0), trans3, Set[State](Q5))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   157
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   158
nfa3.accepts("aaaaabc".toList)      // true
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   159
nfa3.accepts("aaaabcd".toList)      // true
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   160
nfa3.accepts("aaaaab".toList)       // false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   161
nfa3.accepts("aaaabc".toList)       // true
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   162
nfa3.accepts("aaaaabbbaaa".toList)  // false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   163
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   164
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   165
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   166
// subset, or powerset, construction
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   167
def powerset[A, C](nfa: NFA[A, C]) : DFA[Set[A], C] = {
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   168
  DFA(nfa.starts, 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   169
      { case (qs, c) => nfa.nexts(qs, c) },
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   170
      _.exists(nfa.fins))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   171
}
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   172
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   173
val dfa2 = powerset(nfa1)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   174
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   175
dfa2.accepts("axaybzbc".toList)     // true
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   176
dfa2.accepts("aaaaxaybzbc".toList)  // true
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   177
dfa2.accepts("axaybzbd".toList)     // false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   178
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   179
val dfa3 = powerset(nfa2)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   180
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   181
dfa3.accepts("aa".toList)             // false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   182
dfa3.accepts("aaaaa".toList)          // false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   183
dfa3.accepts("aaaaab".toList)         // true
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   184
dfa3.accepts("aaaaabbb".toList)       // true
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   185
dfa3.accepts("aaaaabbbaaa".toList)    // false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   186
dfa3.accepts("ac".toList)             // false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   187
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   188
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   189
import scala.annotation.tailrec
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   190
@tailrec
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   191
def fixpT[A](f: A => A, x: A): A = {
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   192
  val fx = f(x)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   193
  if (fx == x) x else fixpT(f, fx) 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   194
}
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   195
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   196
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   197
case class eNFA[A, C](starts: Set[A],                    // starting state
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   198
                      trans: Set[Edge[A, Option[C]]],    // transition edges
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   199
                      fins:  A => Boolean) {             // final states 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   200
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   201
  def enext(q: A) : Set[A] = 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   202
    trans.flatMap(_.lift.apply((q, None)))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   203
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   204
  def enexts(qs: Set[A]) : Set[A] = 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   205
    qs ++ qs.flatMap(enext(_))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   206
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   207
  // epsilon closure
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   208
  def ecl(qs: Set[A]) : Set[A] = 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   209
    fixpT(enexts, qs)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   210
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   211
  def next(q: A, c: C) : Set[A] = 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   212
    trans.flatMap(_.lift.apply((q, Some(c))))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   213
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   214
  def nexts(qs: Set[A], c: C) : Set[A] = 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   215
    qs.flatMap(next(_, c))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   216
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   217
  def nextss(qs: Set[A], s: List[C]) : Set[A] = s match {
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   218
    case Nil => ecl(qs)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   219
    case c::cs => nextss(ecl(nexts(ecl(qs), c)), cs)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   220
  }
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   221
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   222
  def accepts(s: List[C]) : Boolean = 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   223
    nextss(starts, s.toList).exists(fins)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   224
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   225
}
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   226
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   227
val etrans1 = Set[Edge[State, Option[Char]]](
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   228
  { case (Q0, Some('a')) => Q1 },
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   229
  { case (Q1, None) => Q0 }
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   230
)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   231
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   232
val enfa = eNFA(Set[State](Q0), etrans1, Set[State](Q1))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   233
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   234
enfa.accepts("a".toList)              // true
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   235
enfa.accepts("".toList)               // false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   236
enfa.accepts("aaaaa".toList)          // true
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   237
enfa.accepts("aaaaab".toList)         // flase
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   238
enfa.accepts("aaaaabbb".toList)       // false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   239
enfa.accepts("aaaaabbbaaa".toList)    // false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   240
enfa.accepts("ac".toList)             // false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   241
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   242
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   243
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   244
abstract class Rexp
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   245
case object ZERO extends Rexp
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   246
case object ONE extends Rexp
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   247
case class CHAR(c: Char) extends Rexp
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   248
case object ALL extends Rexp
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   249
case class ALT(r1: Rexp, r2: Rexp) extends Rexp 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   250
case class SEQ(r1: Rexp, r2: Rexp) extends Rexp 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   251
case class STAR(r: Rexp) extends Rexp 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   252
case class NTIMES(r: Rexp, n: Int) extends Rexp 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   253
case class UPNTIMES(r: Rexp, n: Int) extends Rexp 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   254
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   255
import scala.language.implicitConversions    
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   256
import scala.language.reflectiveCalls 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   257
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   258
def charlist2rexp(s: List[Char]): Rexp = s match {
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   259
  case Nil => ONE
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   260
  case c::Nil => CHAR(c)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   261
  case c::s => SEQ(CHAR(c), charlist2rexp(s))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   262
}
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   263
implicit def string2rexp(s: String): Rexp = charlist2rexp(s.toList)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   264
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   265
implicit def RexpOps (r: Rexp) = new {
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   266
  def | (s: Rexp) = ALT(r, s)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   267
  def % = STAR(r)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   268
  def ~ (s: Rexp) = SEQ(r, s)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   269
}
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   270
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   271
implicit def stringOps (s: String) = new {
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   272
  def | (r: Rexp) = ALT(s, r)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   273
  def | (r: String) = ALT(s, r)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   274
  def % = STAR(s)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   275
  def ~ (r: Rexp) = SEQ(s, r)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   276
  def ~ (r: String) = SEQ(s, r)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   277
}
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   278
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   279
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   280
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   281
// nullable function: tests whether the regular 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   282
// expression can recognise the empty string
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   283
def nullable (r: Rexp) : Boolean = r match {
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   284
  case ZERO => false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   285
  case ONE => true
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   286
  case CHAR(_) => false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   287
  case ALL => false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   288
  case ALT(r1, r2) => nullable(r1) || nullable(r2)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   289
  case SEQ(r1, r2) => nullable(r1) && nullable(r2)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   290
  case STAR(_) => true
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   291
  case NTIMES(r, i) => if (i == 0) true else nullable(r)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   292
  case UPNTIMES(r: Rexp, n: Int) => true
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   293
}
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   294
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   295
// derivative of a regular expression w.r.t. a character
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   296
def der (c: Char, r: Rexp) : Rexp = r match {
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   297
  case ZERO => ZERO
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   298
  case ONE => ZERO
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   299
  case CHAR(d) => if (c == d) ONE else ZERO
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   300
  case ALL => ONE
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   301
  case ALT(r1, r2) => ALT(der(c, r1), der(c, r2))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   302
  case SEQ(r1, r2) => 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   303
    if (nullable(r1)) ALT(SEQ(der(c, r1), r2), der(c, r2))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   304
    else SEQ(der(c, r1), r2)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   305
  case STAR(r1) => SEQ(der(c, r1), STAR(r1))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   306
  case NTIMES(r1, i) => 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   307
    if (i == 0) ZERO else
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   308
    if (nullable(r1)) SEQ(der(c, r1), UPNTIMES(r1, i - 1))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   309
    else SEQ(der(c, r1), NTIMES(r1, i - 1))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   310
  case UPNTIMES(r1, i) => 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   311
    if (i == 0) ZERO
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   312
    else SEQ(der(c, r1), UPNTIMES(r1, i - 1)) 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   313
}
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   314
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   315
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   316
// partial derivative of a regular expression w.r.t. a character
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   317
def pder (c: Char, r: Rexp) : Set[Rexp] = r match {
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   318
  case ZERO => Set()
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   319
  case ONE => Set()
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   320
  case CHAR(d) => if (c == d) Set(ONE) else Set()
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   321
  case ALL => Set(ONE)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   322
  case ALT(r1, r2) => pder(c, r1) ++ pder(c, r2)
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   323
  case SEQ(r1, r2) => 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   324
    (for (pr1 <- pder(c, r1)) yield SEQ(pr1, r2)) ++ 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   325
    (if (nullable(r1)) pder(c, r2) else Set())
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   326
  case STAR(r1) => 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   327
    for (pr1 <- pder(c, r1)) yield SEQ(pr1, STAR(r1))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   328
  case NTIMES(r1, i) => 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   329
    if (i == 0) Set() else
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   330
    if (nullable(r1)) 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   331
      for (pr1 <- pder(c, r1)) yield SEQ(pr1, UPNTIMES(r1, i - 1))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   332
    else 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   333
      for (pr1 <- pder(c, r1)) yield SEQ(pr1, NTIMES(r1, i - 1))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   334
  case UPNTIMES(r1, i) => 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   335
    if (i == 0) Set()
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   336
    else 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   337
      for (pr1 <- pder(c, r1)) yield SEQ(pr1, UPNTIMES(r1, i - 1))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   338
}
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   339
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   340
val r = STAR(ALL) ~ "a" ~ NTIMES(ALL, 3) ~ "bc"
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   341
val pder_nfa = NFA[Set[Rexp], Char](Set(Set(r)), 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   342
                                    Set( { case (rs, c) => rs.flatMap(pder(c, _))} ), 
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   343
                                    _.exists(nullable))
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   344
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   345
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   346
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   347
pder_nfa.accepts("axaybzbc".toList)     // true
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   348
pder_nfa.accepts("aaaaxaybzbc".toList)  // true
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   349
pder_nfa.accepts("axaybzbd".toList)     // false
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   350
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   351
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   352
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   353
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   354
///
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   355
type Trans[A, C] = Map[(A, C), A]
81c85f2746f5 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
   356