--- a/scala/recs.scala Tue Feb 26 17:38:37 2013 +0000
+++ b/scala/recs.scala Tue Feb 26 17:39:47 2013 +0000
@@ -4,6 +4,7 @@
abstract class Rec {
def eval(ns: List[Int]) : Int
+ def eval(ns: Int*) : Int = eval(ns.toList)
}
case object Z extends Rec {
@@ -53,4 +54,152 @@
else throw new IllegalArgumentException("Mn: args")
}
+
+
+// Recursive Function examples
+def arity(f: Rec) = f match {
+ case Z => 1
+ case S => 1
+ case Id(n, _) => n
+ case Cn(n, _, _) => n
+ case Pr(n, _, _) => n + 1
+ case Mn(n, _) => n
}
+
+val Add = Pr(1, Id(1, 0), Cn(3, S, List(Id(3, 2))))
+val Mult = Pr(1, Z, Cn(3, Add, List(Id(3, 0), Id(3, 2))))
+val Twice = Cn(1, Mult, List(Id(1, 0), Const(2)))
+val Fourtimes = Cn(1, Mult, List(Id(1, 0), Const(4)))
+val Pred = Cn(1, Pr(1, Z, Id(3, 1)), List(Id(1, 0), Id(1, 0)))
+val Minus = Pr(1, Id(1, 0), Cn(3, Pred, List(Id(3, 2))))
+def Const(n: Int) : Rec = n match {
+ case 0 => Z
+ case n => Cn(1, S, List(Const(n - 1)))
+}
+
+val Power = Pr(1, Const(1), Cn(3, Mult, List(Id(3, 0), Id(3, 2))))
+val Sign = Cn(1, Minus, List(Const(1), Cn(1, Minus, List(Const(1), Id(1, 0)))))
+val Less = Cn(2, Sign, List(Cn(2, Minus, List(Id(2, 1), Id(2, 0)))))
+val Not = Cn(1, Minus, List(Const(1), Id(1, 0)))
+val Eq = Cn(2, Minus, List(Cn(2, Const(1), List(Id(2, 0))),
+ Cn(2, Add, List(Cn(2, Minus, List(Id(2, 0), Id(2, 1))),
+ Cn(2, Minus, List(Id(2, 1), Id(2, 0)))))))
+val Noteq = Cn(2, Not, List(Cn(2, Eq, List(Id(2, 0), Id(2, 1)))))
+val Conj = Cn(2, Sign, List(Cn(2, Mult, List(Id(2, 0), Id(2, 1)))))
+val Disj = Cn(2, Sign, List(Cn(2, Add, List(Id(2, 0), Id(2, 1)))))
+
+def Nargs(n: Int, m: Int) : List[Rec] = m match {
+ case 0 => Nil
+ case m => Nargs(n, m - 1) ::: List(Id(n, m - 1))
+}
+
+def Sigma(f: Rec) = {
+ val ar = arity(f)
+ Pr(ar - 1, Cn(ar - 1, f, Nargs(ar - 1, ar - 1) :::
+ List(Cn(ar - 1, Const(0), List(Id(ar - 1, 0))))),
+ Cn(ar + 1, Add, List(Id(ar + 1, ar),
+ Cn(ar + 1, f, Nargs(ar + 1, ar - 1) :::
+ List(Cn(ar + 1, S, List(Id(ar + 1, ar - 1))))))))
+}
+
+def Accum(f: Rec) = {
+ val ar = arity(f)
+ Pr(ar - 1, Cn(ar - 1, f, Nargs(ar - 1, ar - 1) :::
+ List(Cn(ar - 1, Const(0), List(Id(ar - 1, 0))))),
+ Cn(ar + 1, Mult, List(Id(ar + 1, ar),
+ Cn(ar + 1, f, Nargs(ar + 1, ar - 1) :::
+ List(Cn(ar + 1, S, List(Id(ar + 1, ar - 1))))))))
+}
+
+def All(t: Rec, f: Rec) = {
+ val ar = arity(f)
+ Cn(ar - 1, Sign, List(Cn(ar - 1, Accum(f), Nargs(ar - 1, ar - 1) ::: List(t))))
+}
+
+def Ex(t: Rec, f: Rec) = {
+ val ar = arity(f)
+ Cn(ar - 1, Sign, List(Cn(ar - 1, Sigma(f), Nargs(ar - 1, ar - 1) ::: List(t))))
+}
+
+//Definition on page 77 of Boolos's book.
+def Minr(f: Rec) = {
+ val ar = arity(f)
+ val rq = All(Id(ar, ar - 1),
+ Cn(ar + 1, Not, List(Cn(ar + 1, f, Nargs(ar + 1, ar - 1) ::: List(Id(ar + 1, ar))))))
+ Sigma(rq)
+}
+
+//Definition on page 77 of Boolos's book.
+def Maxr(f: Rec) = {
+ val ar = arity(f)
+ val rt = Id(ar + 1, ar - 1)
+ val rf1 = Cn(ar + 2, Less, List(Id(ar + 2, ar + 1), Id(ar + 2, ar)))
+ val rf2 = Cn(ar + 2, Not, List(Cn (ar + 2, f, Nargs(ar + 2, ar - 1) ::: List(Id(ar + 2, ar + 1)))))
+ val rf = Cn(ar + 2, Disj, List(rf1, rf2))
+ val rq = All(rt, rf)
+ val Qf = Cn(ar + 1, Not, List(rq))
+ Cn(ar, Sigma(Qf), Nargs(ar, ar) ::: List(Id(ar, ar - 1)))
+}
+
+//Mutli-way branching statement on page 79 of Boolos's book
+def Branch(rs: List[(Rec, Rec)]) = {
+ val ar = arity(rs.head._1)
+
+ def Branch_aux(rs: List[(Rec, Rec)], l: Int) : Rec = rs match {
+ case Nil => Cn(l, Z, List(Id(l, l - 1)))
+ case (rg, rc)::recs => Cn(l, Add, List(Cn(l, Mult, List(rg, rc)), Branch_aux(recs, l)))
+ }
+
+ Branch_aux(rs, ar)
+}
+
+//Factorial
+val Fact = {
+ val Fact_aux = Pr(1, Const(1), Cn(3, Mult, List(Id(3, 2), Cn(3, S, List(Id(3, 1))))))
+ Cn(1, Fact_aux, List(Id(1, 0), Id(1, 0)))
+}
+
+//Prime test
+val Prime = Cn(1, Conj, List(Cn(1, Less, List(Const(1), Id(1, 0))),
+ All(Cn(1, Minus, List(Id(1, 0), Const(1))),
+ All(Cn(2, Minus, List(Id(2, 0), Cn(2, Const(1), List(Id(2, 0))))),
+ Cn(3, Noteq, List(Cn(3, Mult, List(Id(3, 1), Id(3, 2))), Id(3, 0)))))))
+
+//Returns the first prime number after n
+val NextPrime = {
+ val R = Cn(2, Conj, List(Cn(2, Less, List(Id(2, 0), Id(2, 1))),
+ Cn(2, Prime, List(Id(2, 1)))))
+ Cn(1, Minr(R), List(Id(1, 0), Cn(1, S, List(Fact))))
+}
+
+val NthPrime = {
+ val NthPrime_aux = Pr(1, Const(2), Cn(3, NextPrime, List(Id(3, 2))))
+ Cn(1, NthPrime_aux, List(Id(1, 0), Id(1, 0)))
+}
+
+def Listsum(k: Int, m: Int) : Rec = m match {
+ case 0 => Cn(k, Z, List(Id(k, 0)))
+ case n => Cn(k, Add, List(Listsum(k, n - 1), Id(k, n - 1)))
+}
+
+//strt-function on page 90 of Boolos, but our definition generalises
+//the original one in order to deal with multiple input-arguments
+
+def Strt(n: Int) = {
+ def Strt_aux(l: Int, k: Int) : Rec = k match {
+ case 0 => Cn(l, Z, List(Id(l, 0)))
+ case n => {
+ val rec_dbound = Cn(l, Add, List(Listsum(l, n - 1), Cn(l, Const(n - 1), List(Id(l, 0)))))
+ Cn(l, Add, List(Strt_aux(l, n - 1),
+ Cn(l, Minus, List(Cn(l, Power, List(Cn(l, Const(2), List(Id(l, 0))),
+ Cn(l, Add, List(Id(l, n - 1), rec_dbound)))),
+ Cn(l, Power, List(Cn(l, Const(2), List(Id(l, 0))), rec_dbound))))))
+ }
+ }
+
+ def Rmap(f: Rec, k: Int) = (0 until k).map{i => Cn(k, f, List(Id(k, i)))}.toList
+
+ Cn(n, Strt_aux(n, n), Rmap(S, n))
+}
+
+}