turing.scala
author Christian Urban <christian dot urban at kcl dot ac dot uk>
Fri, 15 Feb 2013 18:24:00 +0000
changeset 176 d2c85556d290
child 177 1c2e639d4e54
permissions -rw-r--r--
added scala file
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
176
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     1
abstract class Cell
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     2
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
     3
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
     4
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     5
abstract class Action
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     6
case object WBk extends Action
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     7
case object WOc extends Action
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     8
case object R extends Action
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
     9
case object L extends Action
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    10
case object Nop extends Action
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    11
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    12
type State = Int
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    13
type Prog = List[(Action, State)]
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    14
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    15
//some list functions
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    16
def tl[A](xs: List[A]) : List[A] = xs match {
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    17
  case Nil => Nil
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    18
  case x::xs => xs
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    19
}
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    20
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    21
def hd[A](xs: List[A]) : A = xs.head
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    22
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    23
def nth_of[A](xs: List[A], n: Int) = 
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    24
  if (n <= xs.length) Some(xs(n)) else None 
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
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    27
//tapes
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    28
case class Tape(l: List[Cell], r: List[Cell]) {
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
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    42
  override def toString = 
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    43
    l.reverse.map(_.toString).foldLeft("")(_+_) + 
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    44
    ">" + r.map(_.toString).foldLeft("")(_+_)
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    45
}
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    46
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    47
// standard tapes
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    48
def std(n: Int) : List[Cell] = n match {
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    49
  case 0 => List(Oc)
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    50
  case n => Oc::std(n - 1)
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
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    53
class STape(ns: Int*) extends Tape(Nil, ns.map(std).reduceLeft(_ ::: List(Bk) ::: _))
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    54
  
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    55
// configurations
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    56
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
    57
  def is_final = s == 0
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
  override def toString = tp.toString
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    60
}
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    61
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    62
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    63
// Turing Machines
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    64
case class TM(p: Prog, tp: Tape) {
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    65
  
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    66
  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
    67
    case (0, _) => (Nop, 0)
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    68
      case (s, Bk) => nth_of(p, 2 * (s - 1)) match {
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    69
        case None => (Nop, 0)
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    70
        case Some(i) => i
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    71
      }
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    72
    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
    73
      case None => (Nop, 0)
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    74
      case Some(i) => i
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    75
    }
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    76
  } 
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    77
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    78
  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
    79
    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
    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
  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
    83
    case 0 => cf
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    84
    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
    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(n: Int) : Config = steps(Config(1, tp), n)
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    88
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    89
  def run(cf: Config) : Config = {
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    90
    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
    91
  }
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    92
 
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    93
  def run : Tape = run(Config(1, tp)).tp
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    94
}
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
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    97
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    98
// examples
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    99
class TMCopy(n: Int) extends 
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   100
  TM(List((WBk, 5), (R, 2), (R, 3), (R, 2), (WOc, 3), 
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   101
          (L, 4), (L, 4), (L, 5), (R, 11), (R, 6), 
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   102
          (R, 7), (WBk, 6), (R, 7), (R, 8), (WOc, 9), 
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   103
          (R, 8), (L, 10), (L, 9), (L, 10), (L, 5), 
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   104
          (L, 0), (R, 12), (WOc, 13), (L, 14), (R, 12), 
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   105
          (R, 12), (L, 15), (WBk, 14), (R, 0), (L, 15)), new STape(n))
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   106
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   107
println((new TMCopy(0)).run)
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   108