scala/turing.scala
author Christian Urban <christian dot urban at kcl dot ac dot uk>
Thu, 21 Feb 2013 16:07:40 +0000
changeset 193 317a2532c567
parent 192 turing.scala@3c1107984b41
child 194 fc2a5e9fbb97
permissions -rw-r--r--
split up scala-file into separate components
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
193
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 192
diff changeset
     1
package object turing {
178
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
     2
193
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 192
diff changeset
     3
import scala.annotation.tailrec
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 192
diff changeset
     4
import lib._
178
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
     5
192
3c1107984b41 introduced sealed classes
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 191
diff changeset
     6
sealed abstract class Cell {
188
8939cc9b14f9 tuned Scala implementation
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 183
diff changeset
     7
  def * (n: Int) : List[Cell] = n match {
8939cc9b14f9 tuned Scala implementation
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 183
diff changeset
     8
    case 0 => Nil
8939cc9b14f9 tuned Scala implementation
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 183
diff changeset
     9
    case n => this :: this * (n - 1)
8939cc9b14f9 tuned Scala implementation
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 183
diff changeset
    10
  }
8939cc9b14f9 tuned Scala implementation
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 183
diff changeset
    11
}
176
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    12
case object Bk extends Cell { override def toString = "0" }
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    13
case object Oc extends Cell { override def toString = "1" }
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    14
192
3c1107984b41 introduced sealed classes
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 191
diff changeset
    15
sealed abstract class Action
176
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    16
case object WBk extends Action
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    17
case object WOc extends Action
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    18
case object R extends Action
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    19
case object L extends Action
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    20
case object Nop extends Action
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    21
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    22
type State = Int
188
8939cc9b14f9 tuned Scala implementation
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 183
diff changeset
    23
type Inst = (Action, State)
8939cc9b14f9 tuned Scala implementation
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 183
diff changeset
    24
type Prog = List[Inst]
176
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    25
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    26
//tapes
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    27
case class Tape(l: List[Cell], r: List[Cell]) {
193
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 192
diff changeset
    28
  
176
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    29
  def update(a: Action) = a match {
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    30
    case WBk => Tape(l, Bk::tl(r))
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    31
    case WOc => Tape(l, Oc::tl(r))
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    32
    case L => if (l == Nil) Tape(Nil, Bk::r) else Tape (tl(l), hd(l)::r)
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    33
    case R => if (r == Nil) Tape(Bk::l, Nil) else Tape(hd(r)::l, tl(r))
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    34
    case Nop => Tape(l, r)
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    35
  }
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    36
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    37
  def read = r match {
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    38
    case Nil => Bk
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    39
    case x::_ => x
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    40
  }
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    41
178
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    42
  override def toString = join(l.reverse) + ">" + join(r)
176
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    43
}
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    44
193
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 192
diff changeset
    45
//standard tapes
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 192
diff changeset
    46
object Tape {
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 192
diff changeset
    47
  def apply(ns: Int*) : Tape = 
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 192
diff changeset
    48
    Tape(Nil, ns.map(n => Oc * (n + 1)).reduceLeft(_ ::: List(Bk) ::: _))
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 192
diff changeset
    49
}
317a2532c567 split up scala-file into separate components
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 192
diff changeset
    50
176
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    51
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    52
// configurations
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    53
case class Config(s: State, tp: Tape) {
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    54
  def is_final = s == 0
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    55
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    56
  override def toString = tp.toString
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    57
}
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    58
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    59
183
4cf023ee2f4c updated exponent program
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 182
diff changeset
    60
// Turing machines
177
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
    61
case class TM(p: Prog) {
178
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    62
188
8939cc9b14f9 tuned Scala implementation
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 183
diff changeset
    63
  def ++ (that: TM) = TM(this.p ::: that.p)
8939cc9b14f9 tuned Scala implementation
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 183
diff changeset
    64
178
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    65
  def shift(n: Int) =
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    66
    TM(p.map{case (a, s) => (a, if (s == 0) 0 else s + n)})
189
5974111de158 parts of the Abacus translation
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 188
diff changeset
    67
  def adjust(n: Int) : TM =
5974111de158 parts of the Abacus translation
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 188
diff changeset
    68
    TM(p.map{case (a, s) => (a, if (s == 0) n else s)})
5974111de158 parts of the Abacus translation
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 188
diff changeset
    69
  def adjust : TM = adjust(p.length / 2 + 1)
176
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    70
  
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    71
  def fetch(s: State, a: Cell) = (s, a) match {
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    72
    case (0, _) => (Nop, 0)
188
8939cc9b14f9 tuned Scala implementation
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 183
diff changeset
    73
    case (s, Bk) => nth_of(p, 2 * (s - 1)) match {
8939cc9b14f9 tuned Scala implementation
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 183
diff changeset
    74
      case None => (Nop, 0)
8939cc9b14f9 tuned Scala implementation
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 183
diff changeset
    75
      case Some(i) => i
8939cc9b14f9 tuned Scala implementation
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 183
diff changeset
    76
    }
176
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    77
    case (s, Oc) => nth_of(p, 2 * (s - 1) + 1) match {
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    78
      case None => (Nop, 0)
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    79
      case Some(i) => i
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    80
    }
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    81
  } 
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    82
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    83
  def step(cf: Config) : Config = fetch (cf.s, cf.tp.read) match {
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    84
    case (a, s_next) => Config(s_next, cf.tp.update(a))
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    85
  }
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    86
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    87
  def steps(cf: Config, n: Int) : Config = n match {
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    88
    case 0 => cf
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    89
    case n => steps(step(cf), n - 1)
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    90
  } 
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    91
191
98370b96c1c5 compilation from Abacus to Turing in Scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 189
diff changeset
    92
  @tailrec
98370b96c1c5 compilation from Abacus to Turing in Scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 189
diff changeset
    93
  final def run(cf: Config) : Config = {
176
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    94
    if (cf.is_final) cf else run(step(cf))
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    95
  }
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    96
 
177
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
    97
  def run(tp: Tape) : Tape = run(Config(1, tp)).tp
176
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    98
}
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    99
178
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   100
}