From 290e50f34a4cb3b6546ccdf71c914a1339efaeb8 Mon Sep 17 00:00:00 2001 From: Manos Koukoutos <emmanouil.koukoutos@epfl.ch> Date: Thu, 10 Mar 2016 17:10:08 +0100 Subject: [PATCH] Change reconstruction in DetupleInput Use a LetPattern Also reenable printing of LetPattern --- .../scala/leon/purescala/PrettyPrinter.scala | 2 - .../leon/synthesis/rules/DetupleInput.scala | 73 ++++++++----------- 2 files changed, 30 insertions(+), 45 deletions(-) diff --git a/src/main/scala/leon/purescala/PrettyPrinter.scala b/src/main/scala/leon/purescala/PrettyPrinter.scala index 88f6fd70c..d1975779e 100644 --- a/src/main/scala/leon/purescala/PrettyPrinter.scala +++ b/src/main/scala/leon/purescala/PrettyPrinter.scala @@ -392,11 +392,9 @@ class PrettyPrinter(opts: PrinterOptions, |}""" } - /* case LetPattern(p,s,rhs) => p"""|val $p = $s |$rhs""" - */ case MatchExpr(s, csc) => optP { diff --git a/src/main/scala/leon/synthesis/rules/DetupleInput.scala b/src/main/scala/leon/synthesis/rules/DetupleInput.scala index 0c5385358..28d567e1b 100644 --- a/src/main/scala/leon/synthesis/rules/DetupleInput.scala +++ b/src/main/scala/leon/synthesis/rules/DetupleInput.scala @@ -8,8 +8,9 @@ import Witnesses.Hint import purescala.Expressions._ import purescala.Common._ import purescala.Types._ -import purescala.ExprOps._ +import purescala.ExprOps.simplePostTransform import purescala.Constructors._ +import purescala.Extractors.LetPattern /** Rule for detupling input variables, to be able to use their sub-expressions. For example, the input variable: * {{{d: Cons(head: Int, tail: List)}}} @@ -31,28 +32,24 @@ case object DetupleInput extends NormalizingRule("Detuple In") { * into a list of fresh typed identifiers, the tuple of these new identifiers, * and the mapping of those identifiers to their respective expressions. */ - def decompose(id: Identifier): (List[Identifier], Expr, Map[Identifier, Expr], Expr => Seq[Expr]) = id.getType match { + def decompose(id: Identifier): (List[Identifier], Expr, Expr => Seq[Expr]) = id.getType match { case cct @ CaseClassType(ccd, _) if !ccd.isAbstract => val newIds = cct.fields.map{ vd => FreshIdentifier(vd.id.name, vd.getType, true) } - val map = (ccd.fields zip newIds).map{ case (vd, nid) => nid -> caseClassSelector(cct, Variable(id), vd.id) }.toMap - val tMap: (Expr => Seq[Expr]) = { case CaseClass(ccd, fields) => fields } - (newIds.toList, CaseClass(cct, newIds.map(Variable)), map, tMap) + (newIds.toList, CaseClass(cct, newIds.map(Variable)), tMap) case TupleType(ts) => val newIds = ts.zipWithIndex.map{ case (t, i) => FreshIdentifier(id.name+"_"+(i+1), t, true) } - val map = newIds.zipWithIndex.map{ case (nid, i) => nid -> TupleSelect(Variable(id), i+1) }.toMap - val tMap: (Expr => Seq[Expr]) = { case Tuple(fields) => fields } - (newIds.toList, tupleWrap(newIds.map(Variable)), map, tMap) + (newIds.toList, tupleWrap(newIds.map(Variable)), tMap) case _ => sys.error("woot") } @@ -62,21 +59,32 @@ case object DetupleInput extends NormalizingRule("Detuple In") { var subPc = p.pc var subWs = p.ws var hints: Seq[Expr] = Nil - - var reverseMap = Map[Identifier, Expr]() + var patterns = List[(Identifier, Pattern)]() + var revMap = Map[Expr, Expr]().withDefault((e: Expr) => e) var ebMapInfo = Map[Identifier, Expr => Seq[Expr]]() val subAs = p.as.map { a => if (isDecomposable(a)) { - val (newIds, expr, map, tMap) = decompose(a) + val (newIds, expr, tMap) = decompose(a) subProblem = subst(a -> expr, subProblem) subPc = subst(a -> expr, subPc) subWs = subst(a -> expr, subWs) + revMap += expr -> Variable(a) hints +:= Hint(expr) - reverseMap ++= map + val patts = newIds map (id => WildcardPattern(Some(id))) + + patterns +:= (( + a, + a.getType match { + case TupleType(_) => + TuplePattern(None, patts) + case cct: CaseClassType => + CaseClassPattern(None, cct, patts) + } + )) ebMapInfo += a -> tMap @@ -99,40 +107,19 @@ case object DetupleInput extends NormalizingRule("Detuple In") { val newAs = subAs.flatten - // Recompose CaseClasses and Tuples. - // E.g. Cons(l.head, l.tail) ~~> l - // (t._1, t._2, t._3) ~~> t - def recompose(e : Expr) : Expr = e match { - case CaseClass(ct, args) => - val (cts, es) = args.zip(ct.fields).map { - case (CaseClassSelector(ct, e, id), field) if field.id == id => (ct, e) - case _ => - return e - }.unzip - - if (cts.distinct.size == 1 && es.distinct.size == 1) { - es.head - } else { - e - } - case Tuple(args) => - val es = args.zipWithIndex.map { - case (TupleSelect(e, i), index) if i == index + 1 => e - case _ => return e - } - if (es.distinct.size == 1) { - es.head - } else { - e - } - case other => other - } - + val (as, patts) = patterns.unzip + val sub = Problem(newAs, subWs, subPc, subProblem, p.xs, eb).withWs(hints) - val s = (substAll(reverseMap, _:Expr)) andThen simplePostTransform(recompose) + val s = { (e: Expr) => + LetPattern( + tuplePatternWrap(patts), + tupleWrap(as map Variable), + simplePostTransform(revMap)(e) + ) + } - Some(decomp(List(sub), forwardMap(s), s"Detuple ${reverseMap.keySet.mkString(", ")}")) + Some(decomp(List(sub), forwardMap(s), s"Detuple ${as.mkString(", ")}")) } else { None } -- GitLab