turing.scala
author Christian Urban <christian dot urban at kcl dot ac dot uk>
Mon, 18 Feb 2013 14:39:50 +0000
changeset 183 4cf023ee2f4c
parent 182 0329bc0bceec
child 188 8939cc9b14f9
permissions -rw-r--r--
updated exponent program
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
178
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
     1
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
     2
//some list functions
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
     3
def tl[A](xs: List[A]) : List[A] = xs match {
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
     4
  case Nil => Nil
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
     5
  case x::xs => xs
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
     6
}
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
     7
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
     8
def hd[A](xs: List[A]) : A = xs.head
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
     9
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    10
def nth_of[A](xs: List[A], n: Int) = 
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    11
  if (n <= xs.length) Some(xs(n)) else None 
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    12
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    13
def replicate[A](x: A, n: Int) : List[A] = n match {
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    14
  case 0 => List(x)
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    15
  case n => x::replicate(x, n - 1)
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    16
}
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    17
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    18
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    19
//some map functions
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    20
def dget(m: Map[Int, Int], n: Int) = m.getOrElse(n, 0)
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    21
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    22
//some string functions
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    23
def join[A](xs: List[A]) = xs.foldLeft("")(_.toString + _)
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    24
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    25
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    26
176
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    27
abstract class Cell
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    28
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
    29
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
    30
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    31
abstract class Action
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    32
case object WBk extends Action
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    33
case object WOc extends Action
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    34
case object R extends Action
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    35
case object L extends Action
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    36
case object Nop extends Action
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    37
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    38
type State = Int
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    39
type Prog = List[(Action, State)]
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
//tapes
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    42
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
    43
  def update(a: Action) = a match {
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    44
    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
    45
    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
    46
    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
    47
    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
    48
    case Nop => Tape(l, r)
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    49
  }
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    50
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    51
  def read = r match {
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    52
    case Nil => Bk
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    53
    case x::_ => x
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
178
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    56
  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
    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
// standard tapes
178
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    60
class STape(ns: Int*) extends 
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    61
  Tape(Nil, ns.map(replicate[Cell](Oc, _)).reduceLeft(_ ::: List(Bk) ::: _))
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    62
  
176
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    63
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    64
// configurations
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    65
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
    66
  def is_final = s == 0
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    67
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    68
  override def toString = tp.toString
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    69
}
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
183
4cf023ee2f4c updated exponent program
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 182
diff changeset
    72
// Turing machines
177
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
    73
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
    74
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    75
  def shift(n: Int) =
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
    76
    TM(p.map{case (a, s) => (a, if (s == 0) 0 else s + n)})
176
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 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
    79
    case (0, _) => (Nop, 0)
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    80
      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
    81
        case None => (Nop, 0)
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    82
        case Some(i) => i
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    83
      }
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    84
    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
    85
      case None => (Nop, 0)
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    86
      case Some(i) => i
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    87
    }
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
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    90
  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
    91
    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
    92
  }
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    93
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    94
  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
    95
    case 0 => cf
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
    96
    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
    97
  } 
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
  def run(cf: Config) : Config = {
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   100
    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
   101
  }
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   102
 
177
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   103
  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
   104
}
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   105
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
183
4cf023ee2f4c updated exponent program
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 182
diff changeset
   108
// Turing machine examples
178
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   109
val TMCopy = TM(List((WBk, 5), (R, 2), (R, 3), (R, 2), (WOc, 3), 
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   110
                     (L, 4), (L, 4), (L, 5), (R, 11), (R, 6), 
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   111
                     (R, 7), (WBk, 6), (R, 7), (R, 8), (WOc, 9), 
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   112
                     (R, 8), (L, 10), (L, 9), (L, 10), (L, 5), 
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   113
                     (L, 0), (R, 12), (WOc, 13), (L, 14), (R, 12), 
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   114
                     (R, 12), (L, 15), (WBk, 14), (R, 0), (L, 15)))
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   115
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   116
def TMFindnth(n: Int) : TM = n match {
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   117
  case 0 => TM(Nil)
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   118
  case n => {
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   119
    val tm = TMFindnth(n - 1)
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   120
    TM(tm.p ::: List((WOc, 2 * n - 1), (R, 2 * n), (R, 2 * n + 1), (R, 2 * n)))
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   121
  }
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   122
}
177
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   123
178
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   124
def TMMopup(n: Int) = {
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   125
  def TMMopup1(n: Int) : TM = n match {
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   126
    case 0 => TM(Nil)
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   127
    case n => {
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   128
      val tm = TMMopup1(n - 1) 
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   129
      TM(tm.p ::: List((R, 2 * n + 1), (WBk, 2 * n), (R, 2 * n - 1), (WOc, 2 * n)))
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   130
    }
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   131
  }
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   132
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   133
  val TMMopup2 = TM(List((R, 2), (R, 1), (L, 5), (WBk, 3), (R, 4), (WBk, 3),
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   134
                         (R, 2), (WBk, 3), (L, 5), (L, 6), (R, 0), (L, 6)))
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   135
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   136
  val tm1 = TMMopup1(n)
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   137
  val tm2 = TMMopup2.shift(2 * n)
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   138
  TM(tm1.p ::: tm2.p)
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   139
}
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   140
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   141
println("TMCopy:    " + (TMCopy.run(new STape(3))))
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   142
println("TMfindnth: " + (TMFindnth(3).run(new STape(1,2,3,4,5))))
8248f8adf17d added some TM machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 177
diff changeset
   143
println("TMMopup: "   + (TMMopup(3).run(new STape(1,2,3,4,5))))
177
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   144
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   145
183
4cf023ee2f4c updated exponent program
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 182
diff changeset
   146
// Abacus machines
177
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   147
abstract class AInst 
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   148
case class Inc(n: Int) extends AInst
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   149
case class Dec(n: Int, l: Int) extends AInst
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   150
case class Goto(l: Int) extends AInst
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   151
183
4cf023ee2f4c updated exponent program
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 182
diff changeset
   152
// shifting and adjusting labels
180
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   153
def ashift(ai: AInst, offset: Int, jump: Int) = ai match {
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   154
  case Inc(n) => Inc(n)
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   155
  case Dec(n, l) => if (l == jump) Dec(n, l) else Dec(n, l + offset)
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   156
  case Goto(l) => if (l == jump) Goto(l) else Goto(l + offset)
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   157
}
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   158
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   159
def aadjust(ai: AInst, old_jump: Int, jump: Int) = ai match {
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   160
  case Inc(n) => Inc(n)
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   161
  case Dec(n, l) => if (l == old_jump) Dec(n, jump) else Dec(n, l)
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   162
  case Goto(l) => if (l == old_jump) Goto(jump) else Goto(l)
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   163
}
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   164
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   165
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   166
177
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   167
type AProg = List[AInst]
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   168
type Regs = Map[Int, Int]
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   169
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   170
case class AConfig(s: Int, regs: Regs)  
176
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   171
177
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   172
case class Abacus(p: AProg) {
180
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   173
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   174
  def shift(offset: Int, jump: Int) = Abacus(p.map(ashift(_, offset, jump)))
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   175
  def adjust(old_jump: Int, jump: Int) = Abacus(p.map(aadjust(_, old_jump, jump)))
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   176
 
177
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   177
  def step(cf: AConfig) : AConfig = (nth_of(p, cf.s), cf.s) match {
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   178
    case (None, _) => cf
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   179
    case (Some(Inc(n)), s) => AConfig(s + 1, cf.regs + (n -> (dget(cf.regs, n) + 1)))
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   180
    case (Some(Dec(n, l)), s) => {
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   181
      if (dget(cf.regs, n) == 0) AConfig(l, cf.regs)
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   182
      else AConfig(s + 1, cf.regs + (n -> (dget(cf.regs, n) - 1)))
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   183
    }
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   184
    case (Some(Goto(l)), _) => AConfig(l, cf.regs)
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   185
  }  
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   186
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   187
  def steps(cf: AConfig, n: Int) : AConfig = n match {
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   188
    case 0 => cf
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   189
    case n => steps(step(cf), n - 1)
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   190
  } 
176
d2c85556d290 added scala file
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff changeset
   191
177
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   192
  def steps(regs: Regs, n: Int) : AConfig = steps(AConfig(0, regs), n)
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   193
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   194
  def run(cf: AConfig) : AConfig = {
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   195
    if (cf.s >= p.length || cf.s < 0) cf else run(step(cf))
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   196
  }
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   197
 
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   198
  def run(regs: Regs): Regs = run(AConfig(0, regs)).regs
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   199
}
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   200
183
4cf023ee2f4c updated exponent program
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 182
diff changeset
   201
// Abacus examples
4cf023ee2f4c updated exponent program
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 182
diff changeset
   202
def Copy(in: Int, out: Int, jump: Int) = 
4cf023ee2f4c updated exponent program
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 182
diff changeset
   203
  Abacus(List(Dec(in, jump), Inc(out), Goto(0))) 
177
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   204
180
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   205
def Plus(m: Int, n: Int, tmp: Int, jump: Int) =
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   206
  Abacus(List(Dec(m, 4), Inc(n), Inc(tmp),
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   207
              Goto(0), Dec(tmp, jump), Inc(m), Goto(4))) 
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   208
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   209
def Mult(in1: Int, in2: Int, out: Int, tmp: Int, jump: Int) = {
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   210
  val tm = Plus(in2, out, tmp, -1).shift(1, -1).adjust(-1, 0)
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   211
  Abacus(Dec(in1, jump) :: tm.p)
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   212
}
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   213
183
4cf023ee2f4c updated exponent program
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 182
diff changeset
   214
def Expo(in1: Int, in2: Int, out: Int, tmp1: Int, tmp2: Int, jump: Int) = {
4cf023ee2f4c updated exponent program
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 182
diff changeset
   215
  val tm1 = Mult(out, in2, tmp2, tmp1, -1).shift(2, -1).adjust(-1, 10)
4cf023ee2f4c updated exponent program
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 182
diff changeset
   216
  val tm2 = Copy(tmp2, out, -1).shift(10, -1). adjust(-1, 1)
4cf023ee2f4c updated exponent program
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 182
diff changeset
   217
  Abacus(Inc(out) :: Dec(in1, jump) :: tm1.p ::: tm2.p)
180
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   218
}
177
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   219
1c2e639d4e54 added abacus programs
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 176
diff changeset
   220
183
4cf023ee2f4c updated exponent program
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 182
diff changeset
   221
println("Copy: " + (Copy(0, 1, -1).run(Map(0 -> 3, 1 -> 0))))
4cf023ee2f4c updated exponent program
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 182
diff changeset
   222
println("Plus: 3 + 4 " + (Plus(0, 1, 2, -1).run(Map(0 -> 3, 1 -> 4, 2 -> 0))))
4cf023ee2f4c updated exponent program
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 182
diff changeset
   223
println("Mult: 3 * 5 " + (Mult(0, 1, 2, 3, -1).run(Map(0 -> 3, 1 -> 5, 2 -> 0, 3 -> 0))))
4cf023ee2f4c updated exponent program
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 182
diff changeset
   224
println("Expo: 3 ^ 4 " + (Expo(0, 1, 2, 3, 4, -1).run(Map(0 -> 4, 1 -> 3, 2 -> 0, 3 -> 0, 4 -> 0))))
179
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   225
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   226
//Recursive Functions
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   227
abstract class Rec {
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   228
  def eval(ns: List[Int]) : Int
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   229
}
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   230
case object Z extends Rec {
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   231
  override def eval(ns: List[Int]) = ns match {
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   232
    case n::Nil => 0
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   233
    case _ => throw new IllegalArgumentException("Z: args")
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   234
  }
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   235
} 
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   236
case object S extends Rec {
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   237
  override def eval(ns: List[Int]) = ns match {
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   238
    case n::Nil => n + 1
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   239
    case _ => throw new IllegalArgumentException("S: args")
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   240
  }
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   241
} 
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   242
case class Id(n: Int, m: Int) extends Rec {
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   243
  override def eval(ns: List[Int]) = 
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   244
    if (ns.length == n && m < n) ns(m)
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   245
    else throw new IllegalArgumentException("Id: args")
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   246
}
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   247
case class Cn(n: Int, f: Rec, gs: List[Rec]) extends Rec {
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   248
  override def eval(ns: List[Int]) = 
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   249
    if (ns.length == n) f.eval(gs.map(_.eval(ns)))
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   250
    else throw new IllegalArgumentException("Cn: args")
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   251
}
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   252
case class Pr(n: Int, f: Rec, g: Rec) extends Rec {
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   253
  override def eval(ns: List[Int]) = 
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   254
    if (ns.length == n - 1) {
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   255
      if (ns.last == 0) f.eval(ns.init)
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   256
      else {
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   257
        val r = Pr(n, f, g).eval(ns.init ::: List(ns.last - 1))
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   258
        g.eval(ns.init ::: List(ns.last - 1, r))
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   259
      }
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   260
    }
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   261
    else throw new IllegalArgumentException("Cn: args")
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   262
}
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   263
case class Mn(n: Int, f: Rec) extends Rec {
180
8f443f2ed1f6 added abacus machines
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 179
diff changeset
   264
  override def eval(ns: List[Int]) = 0
179
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   265
    
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   266
}
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents: 178
diff changeset
   267