Skip to content

Commit

Permalink
much more straightforward apply loop
Browse files Browse the repository at this point in the history
  • Loading branch information
Jake Donham committed May 12, 2011
1 parent ba9621f commit a976a52
Showing 1 changed file with 59 additions and 75 deletions.
134 changes: 59 additions & 75 deletions _code/scala-logic/LogicSFKDefuncTailrec.scala
@@ -1,91 +1,75 @@
object LogicSFKDefuncTailrec extends Logic {
type O[A] = Option[(A,T[A])]

sealed trait T[A]
case class Fail[A]() extends T[A]
case class Unit[A](a: A) extends T[A]
case class Or[A](t1: T[A], t2: () => T[A]) extends T[A]
case class Bind[A,B](t: T[A], f: A => T[B]) extends T[B]
case class Apply[A,B](t: T[A], f: A => B) extends T[B]
case class Filter[A](t: T[A], p: A => Boolean) extends T[A]
case class Unsplit[A](fk: FK) extends T[A]
type T[A] = I

sealed trait FK
case class FKOr(t: () => T[Any], sk: SK, fk: FK) extends FK
case class FKSplit(r: O[Any]) extends FK
sealed trait I
case class Fail() extends I
case class Unit(a: Any) extends I
case class Or(t1: I, t2: () => I) extends I
case class Bind(t: I, f: Any => I) extends I
case class Apply(t: I, f: Any => Any) extends I
case class Filter(t: I, p: Any => Boolean) extends I
case class Unsplit(fk: I) extends I

sealed trait SK
case class SKBind(f: Any => T[Any], sk: SK) extends SK
case class SKApply(f: Any => Any, sk: SK) extends SK
case class SKFilter(p: Any => Boolean, sk: SK) extends SK
case class SKSplit(r: (Any, FK) => O[Any]) extends SK
case class FKOr(t: () => I, sk: I, fk: I) extends I
case class FKSplit(r: O[Any]) extends I

sealed trait K
case object KReturn extends K
case class KUnsplit(sk: SK, fk: FK, k: K) extends K
case class SKBind(f: Any => I, sk: I) extends I
case class SKApply(f: Any => Any, sk: I) extends I
case class SKFilter(p: Any => Boolean, sk: I) extends I
case class SKSplit(r: (Any, I) => O[Any]) extends I

def fail[A] = Fail()
def unit[A](a: A) = Unit(a)
def or[A](t1: T[A], t2: => T[A]) = Or(t1, { () => t2 })
def bind[A,B](t: T[A], f: A => T[B]) = Bind(t, f)
def apply[A,B](t: T[A], f: A => B) = Apply(t, f)
def filter[A](t: T[A], p: A => Boolean) = Filter(t, p)
case object KReturn extends I
case class KUnsplit(sk: I, fk: I, k: I) extends I

def split[A](t2: T[A]): O[A] = {
var app = 0
var t = t2.asInstanceOf[T[Any]]
var a: Any = null
var r: O[Any] = null
var sk: SK = SKSplit((a, fk) => Some((a, Unsplit(fk))))
var fk: FK = FKSplit(None)
var k: K = KReturn
def fail[A]: T[A] = Fail()
def unit[A](a: A): T[A] = Unit(a)
def or[A](t1: T[A], t2: => T[A]): T[A] = Or(t1, { () => t2 })
def bind[A,B](t: T[A], f: A => T[B]): T[B] =
Bind(t, f.asInstanceOf[Any => I])
def apply[A,B](t: T[A], f: A => B): T[B] =
Apply(t, f.asInstanceOf[Any => I])
def filter[A](t: T[A], p: A => Boolean): T[A] =
Filter(t, p.asInstanceOf[Any => Boolean])

while (true) {
app match {
case 0 => // applyT
t match {
case Fail() => app = 1
case Unit(a2) => { a = a2; app = 2 }
case Or(t1, t2) => { t = t1; fk = FKOr(t2, sk, fk) }
case Bind(t2, f) => { t = t2; sk = SKBind(f, sk) }
case Apply(t2, f) => { t = t2; sk = SKApply(f, sk) }
case Filter(t2, p) => { t = t2; sk = SKFilter(p, sk) }
case Unsplit(fk2) => {
app = 1; k = KUnsplit(sk, fk, k); fk = fk2
}
}
def split[A](t: T[A]): O[A] = {
def apply(i: I, a: Any, r: O[Any], sk: I, fk: I, k: I): O[Any] =
i match {
case Fail() => apply(fk, null, null, null, null, k)
case Unit(a) => apply(sk, a, null, null, fk, k)
case Or(t1, t2) => apply(t1, null, null, sk, FKOr(t2, sk, fk), k)
case Bind(t, f) => apply(t, null, null, SKBind(f, sk), fk, k)
case Apply(t, f) => apply(t, null, null, SKApply(f, sk), fk, k)
case Filter(t, p) => apply(t, null, null, SKFilter(p, sk), fk, k)
case Unsplit(fk2) => apply(fk2, null, null, null, null, KUnsplit(sk, fk, k))

case 1 => // applyFK
fk match {
case FKOr(t2, sk2, fk2) => {
app = 0; t = t2(); sk = sk2; fk = fk2
}
case FKSplit(r2) => { app = 3; r = r2 }
}
case FKOr(t, sk, fk) => apply(t(), null, null, sk, fk, k)
case FKSplit(r) => apply(k, null, r, null, null, null)

case 2 => // applySK
sk match {
case SKBind(f, sk2) => { app = 0; t = f(a); sk = sk2 }
case SKApply(f, sk2) => { sk = sk2; a = f(a) }
case SKFilter(p, sk2) =>
if (p(a)) sk = sk2 else app = 1
case SKSplit(rf) => { app = 3; r = rf(a, fk) }
}
case SKBind(f, sk) => apply(f(a), null, null, sk, fk, k)
case SKApply(f, sk) => apply(sk, f(a), null, null, fk, k)
case SKFilter(p, sk) =>
if (p(a))
apply(sk, a, null, null, fk, k)
else
apply(fk, null, null, null, null, k)
case SKSplit(rf) => apply(k, null, rf(a, fk), null, null, null)

case 3 => // applyK
k match {
case KReturn => return r.asInstanceOf[O[A]]
case KUnsplit(sk2, fk2, k2) =>
r match {
case None => { app = 1; fk = fk2; k = k2 }
case Some((a2, t2)) => {
app = 0; t = or(unit(a2), t2); sk = sk2
fk = fk2; k = k2
}
}
case KReturn => r
case KUnsplit(sk, fk, k) => {
r match {
case None => apply(fk, null, null, null, null, k)
case Some((a, t)) => apply(or(unit(a), t), null, null, sk, fk, k)
}
}
}
}
throw new Exception("not reached")

apply(t,
null,
null,
SKSplit((a, fk) => Some((a, Unsplit(fk)))),
FKSplit(None),
KReturn).asInstanceOf[O[A]]
}
}

0 comments on commit a976a52

Please sign in to comment.