diff --git a/cp-demo/Assuming.scala b/cp-demo/Assuming.scala index eadd00cfe71bd7c77c30d33b14d1b5acd8d4b235..6180393d7e7c057bc744aa011064ad360ffe2ebb 100644 --- a/cp-demo/Assuming.scala +++ b/cp-demo/Assuming.scala @@ -2,20 +2,32 @@ import cp.Definitions._ import cp.Terms._ object Assuming { - def assuming(c: Constraint0)(block: => Unit) : Unit = { - for (u <- c.lazyFindAll) { - block - } - } - def main(args: Array[String]): Unit = { for (x <- ((x: Int) => x >= 0 && x < 4).lazyFindAll) { - assuming(() => x <= 1) { - println("hey!") - } - assuming(() => x > 1) { - println("ho!") + when (x < 3) { + println("I'm assuming x is less than three") } + + println(when(x < 2) { + "furthermore, less than two" + } otherwise { + "ok, not less than two" + }) + + val anInt: Int = when (x < 1) { 42 } + + // cif (x <= 1) { + // println(x) + // println("hi") + // } celse { + // println(x) + // println("hola") + // } + + // assuming(x == 0) { + // println(x) + // println("I assume this was zero!") + // } } } } diff --git a/src/cp/CallTransformation.scala b/src/cp/CallTransformation.scala index bc5f43601ac961006f554406f1c1cd69f1cf53bd..1ae9a8e95a8d7d8ab7abb189b5dea851a6a97d19 100644 --- a/src/cp/CallTransformation.scala +++ b/src/cp/CallTransformation.scala @@ -54,6 +54,9 @@ trait CallTransformation val Function(funValDefs, funBody) = predicate extracted += (predicate.pos -> extractWithFilterPredicate(unit, funValDefs, funBody)) } + case Apply(Select(lhs, boolean2constraint0Name), List(b: Tree)) if boolean2constraint0Name.toString == "boolean2constraint0" => { + extracted += (b.pos -> extractFunction(unit, Nil, b)) + } case _ => } new ForeachTreeTraverser(extractFunDefs).traverse(unit.body) @@ -72,9 +75,7 @@ trait CallTransformation val extractedFunDefs : Map[Position,FunDef] = funDefMap(unit) - private def transformHelper(tree : Tree, function : Function, codeGen : CodeGenerator) : Option[(Serialized, Serialized, Serialized, Serialized, Tree, Tree, Tree, Int)] = { - val Function(funValDefs, funBody) = function - + private def transformHelper(tree : Tree, function : Tree, codeGen : CodeGenerator) : Option[(Serialized, Serialized, Serialized, Serialized, Tree, Tree, Tree, Int)] = { val fd = extractedFunDefs(function.pos) val outputVars : Seq[Identifier] = fd.args.map(_.id) @@ -82,7 +83,7 @@ trait CallTransformation purescalaReporter.info(fd) fd.body match { - case None => purescalaReporter.error("Could not extract function: " + funBody); None + case None => purescalaReporter.error("Could not extract : " + function); None case Some(b) => // serialize expression val serializedExpr = serialize(matchToIfThenElse(b)) @@ -119,7 +120,7 @@ trait CallTransformation override def transform(tree: Tree) : Tree = { tree match { /** Transform implicit conversions to terms into instantiation of base terms */ - case Apply(TypeApply(Select(Select(cpIdent, definitionsName), func2termName), typeTreeList), List(function: Function)) if + case Apply(TypeApply(Select(Select(cpIdent, definitionsName), func2termName), typeTreeList), List(function: Tree)) if (definitionsName.toString == "Definitions" && func2termName.toString.matches("func2term\\d")) => { val codeGen = new CodeGenerator(unit, currentOwner, tree.pos) @@ -135,6 +136,22 @@ trait CallTransformation case None => super.transform(tree) } } + case Apply(Select(Select(cpIdent, definitionsName), boolean2constraint0Name), List(function: Tree)) if + (definitionsName.toString == "Definitions" && boolean2constraint0Name.toString.matches("boolean2constraint0")) => { + val codeGen = new CodeGenerator(unit, currentOwner, tree.pos) + + transformHelper(tree, function, codeGen) match { + case Some((serializedInputVarList, serializedLVarList, serializedOutputVars, serializedExpr, inputVarValues, lVarValues, actualLVars, arity)) => { + // create constraint instance + val code = codeGen.newBaseTerm(exprToScalaSym, serializedProg, serializedInputVarList, serializedLVarList, serializedOutputVars, serializedExpr, inputVarValues, lVarValues, actualLVars, NULL, List(TypeTree(definitions.BooleanClass.tpe)), arity) + + typer.typed(atOwner(currentOwner) { + code + }) + } + case None => super.transform(tree) + } + } case Apply(Select(lhs, withFilterName), List(predicate: Function)) if withFilterName.toString == "withFilter" && hasLIteratorType(lhs) => { val codeGen = new CodeGenerator(unit, currentOwner, tree.pos) diff --git a/src/cp/Definitions.scala b/src/cp/Definitions.scala index 9caa35be3a44caff6a82c75e14473d5ca37d66f1..ff91c55018710de486b2d62bc5cdd7bf8ae72c85 100644 --- a/src/cp/Definitions.scala +++ b/src/cp/Definitions.scala @@ -11,18 +11,59 @@ object Definitions { final class UnsatisfiableConstraintException extends Exception final class UnknownConstraintException extends Exception - implicit def func2term0[R](func : () => R) : Term0[R] = throw new NotImplementedException - implicit def func2term1[T1,R](func : T1 => R) : Term1[T1,R] = throw new NotImplementedException - implicit def func2term2[T1,T2,R](func : (T1,T2) => R) : Term2[T1,T2,R] = throw new NotImplementedException - implicit def func2term3[T1,T2,T3,R](func : (T1,T2,T3) => R) : Term3[T1,T2,T3,R] = throw new NotImplementedException - implicit def func2term4[T1,T2,T3,T4,R](func : (T1,T2,T3,T4) => R) : Term4[T1,T2,T3,T4,R] = throw new NotImplementedException - implicit def func2term5[T1,T2,T3,T4,T5,R](func : (T1,T2,T3,T4,T5) => R) : Term5[T1,T2,T3,T4,T5,R] = throw new NotImplementedException - implicit def func2term6[T1,T2,T3,T4,T5,T6,R](func : (T1,T2,T3,T4,T5,T6) => R) : Term6[T1,T2,T3,T4,T5,T6,R] = throw new NotImplementedException - implicit def func2term7[T1,T2,T3,T4,T5,T6,T7,R](func : (T1,T2,T3,T4,T5,T6,T7) => R) : Term7[T1,T2,T3,T4,T5,T6,T7,R] = throw new NotImplementedException - implicit def func2term8[T1,T2,T3,T4,T5,T6,T7,T8,R](func : (T1,T2,T3,T4,T5,T6,T7,T8) => R) : Term8[T1,T2,T3,T4,T5,T6,T7,T8,R] = throw new NotImplementedException - implicit def func2term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,R](func : (T1,T2,T3,T4,T5,T6,T7,T8,T9) => R) : Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,R] = throw new NotImplementedException - - implicit def force[T](l : L[T]): T = { + def assuming(cond: Constraint0)(block: => Unit): Unit = { + for (u <- cond.lazyFindAll) { + block + } + } + + def when[A](cond: Constraint0)(block: => A): When[A] = { + var v: Option[A] = None + for (i <- cond.lazyFindAll) + v = Some(block) + new When(v) + } + + final class When[A](val thenResult: Option[A]) { + def otherwise(elseBlock: => A): A = thenResult match { + case None => elseBlock + case Some(tr) => tr + } + } + + implicit def when2value[A](w: When[A]): A = w.thenResult match { + case Some(tr) => tr + case None => throw new Exception("Cannot find value for result of `when'") + } + + def cif[A](cond: Constraint0)(block: => A): CIf[A] = new CIf(cond, block) + + final class CIf[A](cond: Constraint0, ifBlock: => A) { + def celse(elseBlock: => A): A = { + var enteredIf = false + for (u <- cond.lazyFindAll) { + enteredIf = true + } + if (enteredIf) + ifBlock + else + elseBlock + } + } + + implicit def boolean2constraint0(b: Boolean): Constraint0 = throw new NotImplementedException + implicit def func2term0[R](func: () => R): Term0[R] = throw new NotImplementedException + implicit def func2term1[T1,R](func: T1 => R): Term1[T1,R] = throw new NotImplementedException + implicit def func2term2[T1,T2,R](func: (T1,T2) => R): Term2[T1,T2,R] = throw new NotImplementedException + implicit def func2term3[T1,T2,T3,R](func: (T1,T2,T3) => R): Term3[T1,T2,T3,R] = throw new NotImplementedException + implicit def func2term4[T1,T2,T3,T4,R](func: (T1,T2,T3,T4) => R): Term4[T1,T2,T3,T4,R] = throw new NotImplementedException + implicit def func2term5[T1,T2,T3,T4,T5,R](func: (T1,T2,T3,T4,T5) => R): Term5[T1,T2,T3,T4,T5,R] = throw new NotImplementedException + implicit def func2term6[T1,T2,T3,T4,T5,T6,R](func: (T1,T2,T3,T4,T5,T6) => R): Term6[T1,T2,T3,T4,T5,T6,R] = throw new NotImplementedException + implicit def func2term7[T1,T2,T3,T4,T5,T6,T7,R](func: (T1,T2,T3,T4,T5,T6,T7) => R): Term7[T1,T2,T3,T4,T5,T6,T7,R] = throw new NotImplementedException + implicit def func2term8[T1,T2,T3,T4,T5,T6,T7,T8,R](func: (T1,T2,T3,T4,T5,T6,T7,T8) => R): Term8[T1,T2,T3,T4,T5,T6,T7,T8,R] = throw new NotImplementedException + implicit def func2term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,R](func: (T1,T2,T3,T4,T5,T6,T7,T8,T9) => R): Term9[T1,T2,T3,T4,T5,T6,T7,T8,T9,R] = throw new NotImplementedException + + implicit def force[T](l: L[T]): T = { l.value } @@ -45,7 +86,7 @@ object Definitions { implicit def tupleOfL2lTuple8[T1,T2,T3,T4,T5,T6,T7,T8](lt: (L[T1],L[T2],L[T3],L[T4],L[T5],L[T6],L[T7],L[T8])): LTuple8[T1,T2,T3,T4,T5,T6,T7,T8] = new LTuple8(lt._1,lt._2,lt._3,lt._4,lt._5,lt._6,lt._7,lt._8) implicit def tupleOfL2lTuple9[T1,T2,T3,T4,T5,T6,T7,T8,T9](lt: (L[T1],L[T2],L[T3],L[T4],L[T5],L[T6],L[T7],L[T8],L[T9])): LTuple9[T1,T2,T3,T4,T5,T6,T7,T8,T9] = new LTuple9(lt._1,lt._2,lt._3,lt._4,lt._5,lt._6,lt._7,lt._8,lt._9) - def distinct[A](args: A*) : Boolean = { + def distinct[A](args: A*): Boolean = { args.toList.distinct.size == args.size } } diff --git a/src/cp/Extractors.scala b/src/cp/Extractors.scala index 2274840337a5aff2c9b4574c34ee111de06af2ad..0fe539602a2d5f260c48412a2e788fe314cd1292 100644 --- a/src/cp/Extractors.scala +++ b/src/cp/Extractors.scala @@ -375,10 +375,13 @@ trait Extractors { // extracts a tree typed as L, returns parameter type tree and tree itself object ExLTyped { - def unapply(tree: Tree): Option[(Type,Tree)] = tree.tpe match { - case TypeRef(_, sym, List(t)) if sym == lClassSym => - Some((t, tree)) - case _ => None + def unapply(tree: Tree): Option[(Type,Tree)] = { + val tpe = if (tree.symbol == null) tree.tpe else tree.symbol.tpe + tpe match { + case TypeRef(_, sym, List(t)) if sym == lClassSym => + Some((t, tree)) + case _ => None + } } }