progs/display/thompson2.scala
author Christian Urban <urbanc@in.tum.de>
Sun, 07 May 2017 03:01:29 +0100
changeset 489 e28d7a327870
parent 488 598741d39d21
permissions -rw-r--r--
updated
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
487
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     1
// Thompson Construction (Part 2)
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     2
488
598741d39d21 updated
Christian Urban <urbanc@in.tum.de>
parents: 487
diff changeset
     3
// some more type abbreviations
487
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     4
type NFAtrans = (TState, Char) :=> Set[TState]
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     5
type eNFAtrans = (TState, Option[Char]) :=> Set[TState]
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     6
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     7
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     8
// for composing an eNFA transition with a NFA transition
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     9
implicit class RichPF(val f: eNFAtrans) extends AnyVal {
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    10
  def +++(g: NFAtrans) : eNFAtrans = 
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    11
  { case (q, None) =>  applyOrElse(f, (q, None)) 
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    12
    case (q, Some(c)) => 
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    13
      applyOrElse(f, (q, Some(c))) | applyOrElse(g, (q, c))  }
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    14
}
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    15
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    16
// sequence of two NFAs
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    17
def NFA_SEQ(enfa1: NFAt, enfa2: NFAt) : NFAt = {
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    18
  val new_delta : eNFAtrans = 
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    19
    { case (q, None) if enfa1.fins(q) => enfa2.starts }
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    20
  
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    21
  eNFA(enfa1.starts, new_delta +++ enfa1.delta +++ enfa2.delta, 
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    22
       enfa2.fins)
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    23
}
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    24
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    25
// alternative of two NFAs
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    26
def NFA_ALT(enfa1: NFAt, enfa2: NFAt) : NFAt = {
489
e28d7a327870 updated
Christian Urban <urbanc@in.tum.de>
parents: 488
diff changeset
    27
  val new_delta : NFAtrans = { 
e28d7a327870 updated
Christian Urban <urbanc@in.tum.de>
parents: 488
diff changeset
    28
    case (q, c) => applyOrElse(enfa1.delta, (q, c)) | 
e28d7a327870 updated
Christian Urban <urbanc@in.tum.de>
parents: 488
diff changeset
    29
                   applyOrElse(enfa2.delta, (q, c)) }
487
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    30
  val new_fins = (q: TState) => enfa1.fins(q) || enfa2.fins(q)
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    31
489
e28d7a327870 updated
Christian Urban <urbanc@in.tum.de>
parents: 488
diff changeset
    32
  NFA(enfa1.starts | enfa2.starts, new_delta, new_fins)
487
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    33
}
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    34
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    35
// star of a NFA
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    36
def NFA_STAR(enfa: NFAt) : NFAt = {
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    37
  val Q = TState()
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    38
  val new_delta : eNFAtrans = 
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    39
    { case (Q, None) => enfa.starts
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    40
      case (q, None) if enfa.fins(q) => Set(Q) }
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    41
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    42
  eNFA(Set(Q), new_delta +++ enfa.delta, Set(Q))
a697421eaa04 updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    43
}