Skip to content

Commit

Permalink
Fix bug in conditionForPattern when handling unapplyPattern
Browse files Browse the repository at this point in the history
Also add couple of utility functions
  • Loading branch information
manoskouk committed May 12, 2016
1 parent bbdb5c8 commit 9566dcf
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 11 deletions.
17 changes: 7 additions & 10 deletions src/main/scala/leon/purescala/ExprOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -692,22 +692,19 @@ object ExprOps extends GenTreeOps[Expr] {
assert(cct.classDef.fields.size == subps.size)
val pairs = cct.classDef.fields.map(_.id).toList zip subps.toList
val subTests = pairs.map(p => rec(caseClassSelector(cct, in, p._1), p._2))
val together = subTests.foldLeft(bind(ob, in))(_ merge _)
Path(IsInstanceOf(in, cct)) merge together
Path(IsInstanceOf(in, cct)) merge bind(ob, in) merge subTests

case TuplePattern(ob, subps) =>
val TupleType(tpes) = in.getType
assert(tpes.size == subps.size)
val subTests = subps.zipWithIndex.map{case (p, i) => rec(tupleSelect(in, i+1, subps.size), p)}
subTests.foldLeft(bind(ob, in))(_ merge _)
val subTests = subps.zipWithIndex.map {
case (p, i) => rec(tupleSelect(in, i+1, subps.size), p)
}
bind(ob, in) merge subTests

case up @ UnapplyPattern(ob, fd, subps) =>
def someCase(e: Expr) = {
// In the case where unapply returns a Some, it is enough that the subpatterns match
val subTests = unwrapTuple(e, subps.size) zip subps map { case (ex, p) => rec(ex, p) }
subTests.foldLeft(Path.empty)(_ merge _).toClause
}
Path(up.patternMatch(in, BooleanLiteral(false), someCase).setPos(in)) merge bind(ob, in)
val subs = unwrapTuple(up.get(in), subps.size).zip(subps) map (rec _).tupled
bind(ob, in) withCond up.isSome(in) merge subs

case LiteralPattern(ob, lit) =>
Path(Equals(in, lit)) merge bind(ob, in)
Expand Down
3 changes: 3 additions & 0 deletions src/main/scala/leon/purescala/Expressions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,9 @@ object Expressions {
FunctionInvocation(unapplyFun, Seq(scrut)),
someValue.id
)

def isSome(scrut: Expr) = IsInstanceOf(FunctionInvocation(unapplyFun, Seq(scrut)), someType)

}

// Extracts without taking care of the binder. (contrary to Extractos.Pattern)
Expand Down
5 changes: 4 additions & 1 deletion src/main/scala/leon/purescala/Path.scala
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ class Path private[purescala](
def --(ids: Set[Identifier]) = new Path(elements.filterNot(_.left.exists(p => ids(p._1))))

/** Appends `that` path at the end of `this` */
def merge(that: Path) = new Path(elements ++ that.elements)
def merge(that: Path): Path = new Path(elements ++ that.elements)

/** Appends `those` paths at the end of `this` */
def merge(those: Traversable[Path]): Path = those.foldLeft(this)(_ merge _)

/** Transforms all expressions inside the path
*
Expand Down

0 comments on commit 9566dcf

Please sign in to comment.