progs/dfa.scala
author Christian Urban <christian dot urban at kcl dot ac dot uk>
Wed, 16 Oct 2013 02:07:02 +0100
changeset 145 920f675b4ed1
child 479 52aa298211f6
child 480 9e42ccbbd1e6
permissions -rw-r--r--
added
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
145
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     1
// DFAs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     2
import scala.util._
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     3
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     4
abstract class State
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     5
type States = Set[State]
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     6
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     7
case class IntState(i: Int) extends State
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     8
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     9
object NewState {
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    10
  var counter = 0
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    11
  
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    12
  def apply() : IntState = {
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    13
    counter += 1;
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    14
    new IntState(counter - 1)
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    15
  }
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    16
}
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    17
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    18
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    19
// DFA class
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    20
case class DFA(states: States, 
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    21
               start: State, 
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    22
               delta: (State, Char) => State, 
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    23
               fins: States) {
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    24
  
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    25
  def deltas(q: State, s: List[Char]) : State = s match {
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    26
    case Nil => q
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    27
    case c::cs => deltas(delta(q, c), cs) 
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    28
  }
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    29
  
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    30
  // wether a string is accepted by the automaton or not
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    31
  def accepts(s: String) : Boolean = 
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    32
    Try(fins contains 
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    33
      (deltas(start, s.toList))) getOrElse false
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    34
}
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    35
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    36
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    37
// example DFA from the lectures
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    38
val Q0 = NewState()
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    39
val Q1 = NewState()
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    40
val Q2 = NewState()
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    41
val Q3 = NewState()
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    42
val Q4 = NewState()
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    43
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    44
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    45
val delta : (State, Char) => State = {
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    46
  case (Q0, 'a') => Q1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    47
  case (Q0, 'b') => Q2
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    48
  case (Q1, 'a') => Q4
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    49
  case (Q1, 'b') => Q2
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    50
  case (Q2, 'a') => Q3
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    51
  case (Q2, 'b') => Q2
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    52
  case (Q3, 'a') => Q4
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    53
  case (Q3, 'b') => Q0
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    54
  case (Q4, 'a') => Q4
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    55
  case (Q4, 'b') => Q4
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    56
}
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    57
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    58
val DFA1 = DFA(Set(Q0, Q1, Q2, Q3, Q4), Q0, delta, Set(Q4))
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    59
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    60
println(DFA1.accepts("aaa"))
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    61
println(DFA1.accepts("bb"))
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    62
println(DFA1.accepts("aaac"))
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    63
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    64