Commit bb19c174 authored by Arthur Bit-Monnot's avatar Arthur Bit-Monnot

[anml] Get rid of Wrapped function, using boxing operators instead.

parent 7f0d756b
......@@ -66,14 +66,13 @@ lazy val anml = project
.in(file("anml"))
.settings(name := "dahu-anml")
.settings(commonSettings: _*)
.settings(
libraryDependencies ++= Seq(
"com.lihaoyi" %% "fastparse" % "1.0.0",
"com.github.scopt" %% "scopt" % "3.7.0",
"com.chuusai" %% "shapeless" % "2.3.3",
"org.typelevel" %% "spire" % "0.14.1",
"org.scalatest" %% "scalatest" % "3.0.5" % "test"
))
.settings(libraryDependencies ++= Seq(
"com.lihaoyi" %% "fastparse" % "1.0.0",
"com.github.scopt" %% "scopt" % "3.7.0",
"com.chuusai" %% "shapeless" % "2.3.3",
"org.typelevel" %% "spire" % "0.14.1",
"org.scalatest" %% "scalatest" % "3.0.5" % "test"
))
lazy val utils = project
.in(file("utils"))
......
......@@ -27,6 +27,19 @@ abstract class Fun1[-I: Tag, O: Tag] extends Fun[O] {
abstract class Reversible[A: Tag, B: Tag] extends Fun1[A, B] {
def reverse: Reversible[B, A]
}
sealed abstract class Box[T: TagIsoInt] extends Reversible[Int, T] {
def reverse: Unbox[T]
}
final class Unbox[T: TagIsoInt] extends Reversible[T, Int] { self =>
val tag: TagIsoInt[T] = TagIsoInt[T]
override val reverse: Box[T] = new Box[T] {
override def reverse: Unbox[T] = self
override def of(in: Int): T = tag.fromInt(in)
override def name: String = "box"
}
override def of(in: T): Int = tag.toInt(in)
override def name: String = "unbox"
}
object Fun1 {
def embed[A: Tag, B: Tag](f: A => B): Fun1[A, B] = new Fun1[A, B] {
......@@ -85,20 +98,3 @@ abstract class FunN[-I: Tag, O: Tag] extends Fun[O] {
def of(args: Seq[I]): O //TODO
}
trait WrappedFunction {
def f: Fun[_]
}
object WrappedFunction {
def wrap[T, O](f: Fun2[Int, Int, O])(implicit tag: TagIsoInt[T],
outTag: TagIsoInt[O]): Fun2[T, T, O] =
new WrappedFun2[T, T, O](f)
}
final case class WrappedFun2[I1: TagIsoInt, I2: TagIsoInt, O: TagIsoInt](f: Fun2[Int, Int, O])
extends Fun2[I1, I2, O]
with WrappedFunction {
override def of(in1: I1, in2: I2): O = f.of(TagIsoInt[I1].toInt(in1), TagIsoInt[I2].toInt(in2))
override def name: String = s"wrapped-${f.name}"
}
package dahu.model.input
import dahu.model.functions.{Fun, Fun1, Fun2}
import dahu.model.ir.Total
import dahu.model.math.BooleanLike.BooleanOps
import dahu.model.math.Numeric.{NumericBase, NumericOps}
import dahu.model.math._
import dahu.model.math.obj.Unboxed
import dahu.model.types.{BoxedInt, Tag}
import dahu.model.types.{BoxedInt, Tag, TagIsoInt}
import shapeless.=:!=
import scala.language.implicitConversions
object dsl {
implicit class Fun1Ops[I, O](private val lhs: Fun1[I, O]) extends AnyVal {
def apply(arg: Tentative[I]): Tentative[O] = Computation1(lhs, arg)
}
implicit class Fun2Ops[I1, I2, O: Tag](f: Fun2[I1, I2, O]) {
def apply(i1: Tentative[I1], i2: Tentative[I2]): Computation2[I1, I2, O] =
Computation(f, i1, i2)
......@@ -37,6 +40,14 @@ object dsl {
tag: Tag[T]) =
new NumericOps[T, Tentative](lhs)
implicit class TentativeOrderOps[T: TagIsoInt](lhs: Tentative[T])(implicit ev: T =:!= Int,
ev2: T =:!= Double) {
def ===(rhs: Tentative[T]): Tentative[Boolean] =
int.EQ(TagIsoInt[T].unbox(lhs), TagIsoInt[T].unbox(rhs))
def =!=(rhs: Tentative[T]): Tentative[Boolean] =
bool.Not(new TentativeOrderOps(lhs) === rhs)
}
implicit def tentative2boolOps(lhs: Tentative[Boolean])(
implicit bool: BooleanLike[Boolean, Tentative]) =
new BooleanOps[Boolean, Tentative](lhs)(bool)
......@@ -50,8 +61,8 @@ object dsl {
}
implicit class UnboxOps[A](private val lhs: Tentative[A]) extends AnyVal {
def unboxed(implicit tag: BoxedInt[A]): Tentative[Int] =
Computation(new Unboxed[A], lhs)
def unboxed(implicit tag: TagIsoInt[A]): Tentative[Int] =
Computation(tag.unbox, lhs)
}
implicit class ProductOps[T[_[_]]](private val lhs: Product[T]) extends AnyVal {
......
......@@ -22,9 +22,12 @@ object Numeric {
def apply[T, F[_]](implicit ev: Numeric[T, F]): Numeric[T, F] = ev
trait NumericBase[T] {
trait OrderBase[T] {
def leq: Fun2[T, T, Boolean]
def eqv: Fun2[T, T, Boolean]
}
trait NumericBase[T] extends OrderBase[T] {
def neg: Fun1[T, T]
def add: Monoid[T]
def times: Monoid[T]
......@@ -49,15 +52,6 @@ object Numeric {
override def epsilonOrLesserThan: Either[Double, Fun2[Double, Double, Boolean]] =
Right(double.LT)
}
implicit def isoIntNumeric[T](implicit tag: TagIsoInt[T]): NumericBase[T] = new NumericBase[T] {
override def leq: Fun2[T, T, Boolean] = WrappedFunction.wrap(int.LEQ)
override def eqv: Fun2[T, T, Boolean] = WrappedFunction.wrap(int.EQ)
override def neg: Fun1[T, T] = ???
override def add: Monoid[T] = ???
override def times: Monoid[T] = ???
override def epsilonOrLesserThan: Either[T, Fun2[T, T, Boolean]] = ???
}
implicit def exprNumeric[T: Tag, F[_]](implicit ev: NumericBase[T],
F: ReifiedApplicative[F]): Numeric[T, F] =
......
......@@ -5,15 +5,6 @@ import dahu.model.input.Cst
import dahu.model.ir.CstF
import dahu.model.types.{BoxedInt, Tag}
object obj {
/** Transforms a boxed int into an int. */
class Unboxed[A](implicit tag: BoxedInt[A]) extends Fun1[A, Int] {
override def of(in: A): Int = tag.toInt(in)
override def name: String = "unbox"
}
}
object double {
object Times extends CommutativeMonoid[Double] {
......
......@@ -7,7 +7,6 @@ import dahu.model.functions._
import dahu.model.input.Anonymous
import dahu.model.ir._
import dahu.model.math._
import dahu.model.math.obj.Unboxed
import dahu.model.problem.SatisfactionProblem.{ILazyTree, RootedLazyTree, TreeNode}
import dahu.model.types._
import dahu.utils.SFunctor
......@@ -166,12 +165,6 @@ class IntBoolSatisfactionProblem[X](val ast: RootedLazyTree[X, Total, cats.Id])
case x @ ComputationF(f: Fun1[_, _], Vec1(arg), t: TagIsoInt[_])
if isUnbox(f) && sup(prev(arg)) => //TODO double check
prev(arg)
case x @ ComputationF(wf: WrappedFunction, args, t: TagIsoInt[_])
if supportedFunctions.contains(wf.f) && args.forall(x => sup(prev(x))) =>
TRANS(rec)(prev)(ComputationF(wf.f, args, t)) // unwrap and retry
case x @ ComputationF(f: Unboxed[_], Vec1(arg), t) =>
prev(arg) // unbox operation, use the previous cell
case x =>
dahu.utils.debug.warning(s"unsupported: $x")
......
......@@ -3,7 +3,7 @@ package dahu.model.problem
import cats.Functor
import cats.implicits._
import dahu.model.compiler.Algebras
import dahu.model.functions.Reversible
import dahu.model.functions.{Box, Reversible, Unbox}
import dahu.utils._
import dahu.model.ir._
import dahu.model.math._
......@@ -12,6 +12,7 @@ import dahu.recursion._
import dahu.utils.SFunctor
import dahu.utils.Vec._
import dahu.utils.errors._
import spire.math.Interval
import spire.syntax.cfor._
import scala.collection.mutable
......@@ -49,6 +50,10 @@ object SatisfactionProblem {
retrieve(arg) match {
case ComputationF(f2: Reversible[_, _], Vec1(arg2), _) if f2 == f.reverse =>
retrieve(arg2)
case ComputationF(f2: Box[_], _, _) =>
println(f)
println(f2)
???
case _ => orig
}
case x => x
......@@ -56,11 +61,33 @@ object SatisfactionProblem {
}
object ElimTautologies extends Optimizer {
def dom(t: Tag[_]): Interval[Int] = t match {
case t: TagIsoInt[_] => Interval(t.min, t.max)
case _ => Interval.all
}
def dom(e: Total[ID]): Interval[Int] = e match {
case ComputationF(f: Unbox[_], _, _) =>
dom(f.inType) intersect dom(f.outType)
case CstF(v: Int, _) =>
Interval.point(v)
case x =>
dom(x.typ)
}
override def optim(retrieve: ID => Total[ID],
record: Total[ID] => ID): Total[ID] => Total[ID] = {
case ComputationF(int.EQ, Vec2(a1, a2), _) if a1 == a2 => bool.TrueF
case ComputationF(int.LEQ, Vec2(a1, a2), _) if a1 == a2 => bool.TrueF
case x => x
case x @ ComputationF(int.EQ, Vec2(a1, a2), _) =>
val dom1 = dom(retrieve(a1))
val dom2 = dom(retrieve(a2))
if(!(dom1 intersects dom1))
bool.FalseF
else if(dom1.isPoint && dom1 == dom2)
bool.TrueF
else
x
case x => x
}
}
......@@ -395,6 +422,9 @@ object SatisfactionProblem {
override def getInternalID(k: X): ID = lt.get(k).value
}
val satRoot = lt.get(root).valid
val str = RootedLazyTree(satRoot, totalTrees).fullTree.toString
println(str)
println(str.size)
RootedLazyTree(satRoot, totalTrees)
}
......
package dahu.model.types
import cats.Id
import dahu.model.functions.{Fun1, Reversible}
import dahu.model.functions.{Box, Fun1, Reversible, Unbox}
import dahu.utils._
import dahu.model.input.{ProductExpr, Tentative}
......@@ -77,16 +77,8 @@ trait TagIsoInt[T] extends Tag[T] {
private implicit def selfTag: TagIsoInt[T] = this
val box: Reversible[Int, T] = new Reversible[Int, T] { self =>
override val reverse: Reversible[T, Int] = new Reversible[T, Int] {
override def reverse: Reversible[Int, T] = self
override def of(in: T): Int = toInt(in)
override def name: String = "unbox"
}
override def of(in: Int): T = fromInt(in)
override def name: String = "box"
}
val unbox: Reversible[T, Int] = box.reverse
val unbox: Unbox[T] = new Unbox[T]()(this)
val box: Box[T] = unbox.reverse
}
object TagIsoInt {
......
......@@ -5,7 +5,7 @@ import copla.lang.model.common.operators.BinaryOperator
import copla.lang.model.common.{Cst => _, _}
import copla.lang.model.core._
import copla.lang.model.core
import dahu.model.functions.{Fun2, FunN, Reversible, WrappedFunction}
import dahu.model.functions.{Fun2, FunN, Reversible}
import dahu.model.input._
import dahu.model.input.dsl._
import dahu.model.math.{bool, int}
......@@ -180,8 +180,6 @@ case class ProblemContext(intTag: BoxedInt[Literal],
implicit argRewrite: Arg => Tentative[Literal]): Tentative[Boolean] =
eqv(encode(lhs), encode(rhs))
private val ObjEquality = WrappedFunction.wrap(int.EQ)(topTag, implicitly[TagIsoInt[Boolean]])
private val IntEquality = WrappedFunction.wrap(int.EQ)(intTag, implicitly[TagIsoInt[Boolean]])
private def isInt(e: Tentative[Literal]): Boolean = e.typ match {
case t: BoxedInt[_] =>
assert(t == intTag)
......@@ -197,13 +195,10 @@ case class ProblemContext(intTag: BoxedInt[Literal],
case (Cst(x), Cst(y)) if x == y => bool.True
case (Cst(x), Cst(y)) if x != y => bool.False
case _ =>
if(isInt(lhs) && isInt(rhs))
Computation(IntEquality, lhs, rhs)
else if(isInt(lhs) || isInt(rhs))
if(isInt(lhs) != isInt(rhs))
bool.False
else {
Computation(ObjEquality, lhs, rhs)
}
else
int.EQ(intUnbox(lhs), intUnbox(rhs))
}
def neq(lhs: common.Term, rhs: common.Term)(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment