diff --git a/cp-demo/LazyVars.scala b/cp-demo/LazyVars.scala index e40727686da939d76506a8a61a31a7ddeb7d660a..6c13ae0d41b6ff7c2065214a53daa3637ee0422a 100644 --- a/cp-demo/LazyVars.scala +++ b/cp-demo/LazyVars.scala @@ -13,6 +13,7 @@ object LazyVars { println f3() println + // f5() } def f1() { @@ -59,4 +60,10 @@ object LazyVars { println("x: " + x.value) println("y: " + y.value) } + + def f5() { + val p = ((x: Int, y: Int) => x > 0 && y == 2 * x && x <= 5).lazySolve + val scalaPair: (Int, Int) = p + println("scala pair: " + scalaPair) + } } diff --git a/src/cp/CallTransformation.scala b/src/cp/CallTransformation.scala index c3a0f238cc34746d94dfba9b617596883917b60b..efbe97e2bd60a22773fe573d8929688d28c14c3e 100644 --- a/src/cp/CallTransformation.scala +++ b/src/cp/CallTransformation.scala @@ -20,20 +20,20 @@ trait CallTransformation private lazy val cpPackage = definitions.getModule("cp") private lazy val cpDefinitionsModule = definitions.getModule("cp.Definitions") - private lazy val lstreamClass = definitions.getClass("cp.LTrees.LStream") - private lazy val withFilter2Function = definitions.getMember(lstreamClass, "withFilter2") + private lazy val lIteratorClass = definitions.getClass("cp.LTrees.LIterator") + private lazy val withFilter2Function = definitions.getMember(lIteratorClass, "withFilter2") private lazy val lClassSym = definitions.getClass("cp.LTrees.L") private def isLSym(sym: Symbol): Boolean = { sym == lClassSym } - private def isLStreamSym(sym: Symbol): Boolean = { - sym == lstreamClass + private def isLIterator(sym: Symbol): Boolean = { + sym == lIteratorClass } - private def hasLStreamType(tr: Tree): Boolean = tr.tpe match { - case TypeRef(_, sym, _) if isLStreamSym(sym) => true + private def hasLIteratorType(tr: Tree): Boolean = tr.tpe match { + case TypeRef(_, sym, _) if isLIterator(sym) => true case _ => false } @@ -48,7 +48,7 @@ trait CallTransformation val Function(funValDefs, funBody) = function extracted += (function.pos -> extractFunction(unit, funValDefs, funBody)) } - case Apply(Select(lhs, withFilterName), List(predicate: Function)) if withFilterName.toString == "withFilter" && hasLStreamType(lhs) => { + case Apply(Select(lhs, withFilterName), List(predicate: Function)) if withFilterName.toString == "withFilter" && hasLIteratorType(lhs) => { val Function(funValDefs, funBody) = predicate extracted += (predicate.pos -> extractWithFilterPredicate(unit, funValDefs, funBody)) } @@ -129,7 +129,7 @@ trait CallTransformation case None => super.transform(tree) } } - case Apply(Select(lhs, withFilterName), List(predicate: Function)) if withFilterName.toString == "withFilter" && hasLStreamType(lhs) => { + case Apply(Select(lhs, withFilterName), List(predicate: Function)) if withFilterName.toString == "withFilter" && hasLIteratorType(lhs) => { val codeGen = new CodeGenerator(unit, currentOwner, tree.pos) val Function(funValDefs, _) = predicate diff --git a/src/cp/LTrees.scala b/src/cp/LTrees.scala index 40f781675064c22ec1e1502740be23ca3e63c25a..b21e675a6d51980e1421a2ff117bb027ef780738 100644 --- a/src/cp/LTrees.scala +++ b/src/cp/LTrees.scala @@ -133,7 +133,7 @@ object LTrees { /** END OF GENERATED CODE ***/ /** A stream for symbolic variables */ - class LStream[T](val constraint: (L[T]) => Constraint[T]) extends scala.collection.generic.FilterMonadic[L[T], Traversable[L[T]]] { + class LIterator[T](val constraint: (L[T]) => Constraint[T]) extends Iterator[L[T]] { import ConstraintSolving.GlobalContext private var guards: Map[Seq[Identifier],Identifier] = Map.empty @@ -199,12 +199,13 @@ object LTrees { enqueueAsForcedInStream(ids, values) } + private var underlying = underlyingStream() + private def underlyingStream(): Stream[L[T]] = { // set of tricks to overcome circular dependency between creation of L's // and Constraints - // currently works for only LStreams generating one L val placeHolders = Seq(FreshIdentifier("placeholder", true).setType(BottomType)) val candidateL = new L[T](handler(), placeHolders) val instantiatedCnstr = constraint(candidateL) @@ -229,24 +230,15 @@ object LTrees { } } - def flatMap [B, That] (f: (L[T]) ⇒ GenTraversableOnce[B])(implicit bf: CanBuildFrom[Traversable[L[T]], B, That]): That = { - underlyingStream().flatMap(f) - } - - def foreach [U] (f: (L[T]) ⇒ U): Unit = { - underlyingStream().foreach(f) - } - - def map [B, That] (f: (L[T]) ⇒ B)(implicit bf: CanBuildFrom[Traversable[L[T]], B, That]): That = { - underlyingStream().map(f) - } - - def withFilter (p: (L[T]) ⇒ Boolean): FilterMonadic[L[T], Traversable[L[T]]] = { - underlyingStream().withFilter(p) + def hasNext: Boolean = !underlying.isEmpty + def next: L[T] = { + val toRet = underlying.head + underlying = underlying.tail + toRet } - def withFilter2(p: (L[T]) => Constraint[T]): LStream[T] = { - new LStream[T]((l: L[T]) => this.constraint(l).asInstanceOf[Constraint1[T]] && p(l).asInstanceOf[Constraint1[T]]) + def withFilter2(p: (L[T]) => Constraint[T]): LIterator[T] = { + new LIterator[T]((l: L[T]) => this.constraint(l).asInstanceOf[Constraint1[T]] && p(l).asInstanceOf[Constraint1[T]]) } } diff --git a/src/cp/Terms.scala b/src/cp/Terms.scala index 19c8221eb35edbe3136113182c5faeb2742dc77b..82924f6c12ff3fea657d0097ab68a768f12aee81 100644 --- a/src/cp/Terms.scala +++ b/src/cp/Terms.scala @@ -48,8 +48,8 @@ object Terms { } } - def lazyFindAll(implicit asConstraint: (Term[T,R]) => Constraint[T]): LStream[T] = { - new LStream((l: L[T]) => asConstraint(this)) + def lazyFindAll(implicit asConstraint: (Term[T,R]) => Constraint[T]): LIterator[T] = { + new LIterator((l: L[T]) => asConstraint(this)) } } @@ -198,6 +198,8 @@ object Terms { val (constants, guards) = constantsAndGuards(constraint) new LTuple1[T1](createL[T1](constraint, constants(0), guards(0))) } + + // def lazyFindAll(implicit asConstraint: (Term1[T1,R]) => Constraint1[T1]): LStream def compose0[A1](other : Term1[A1, T1]) : Term1[A1, R] = { val (newExpr, newTypes) = Terms.compose(other, this, 0, 1, 1)