From c9a9a67d0f4aa61dca57927f1846cc7a8ba0150b Mon Sep 17 00:00:00 2001
From: "Emmanouil (Manos) Koukoutos" <emmanouil.koukoutos@epfl.ch>
Date: Thu, 13 Nov 2014 14:29:20 +0100
Subject: [PATCH] Try to salvage erroneous/ugly name handling in Guided Match
 split

---
 .../leon/synthesis/rules/GuidedDecomp.scala   | 77 +++++++++++++------
 1 file changed, 53 insertions(+), 24 deletions(-)

diff --git a/src/main/scala/leon/synthesis/rules/GuidedDecomp.scala b/src/main/scala/leon/synthesis/rules/GuidedDecomp.scala
index 878dd149c..e3be7ad00 100644
--- a/src/main/scala/leon/synthesis/rules/GuidedDecomp.scala
+++ b/src/main/scala/leon/synthesis/rules/GuidedDecomp.scala
@@ -52,40 +52,69 @@ case object GuidedDecomp extends Rule("Guided Decomp") {
 
         Some(RuleInstantiation.immediateDecomp(p, this, List(sub1, sub2), onSuccess, "Guided If-Split on '"+c+"'"))
 
-      case m @ MatchExpr(scrut, cs) =>
-        var pcSoFar: Expr = BooleanLiteral(true)
+      case m @ MatchExpr(scrut0, cs) =>
+        
+        val scrut = scrut0 match {
+          case v : Variable => v
+          case _ => Variable(FreshIdentifier("scrut", true).setType(scrut0.getType))
+        }
+        var pcSoFar: Expr = if (scrut == scrut0) BooleanLiteral(true) else Equals(scrut0, scrut)
+
         val subs = for (c <- cs) yield {
-          val s = scrut match {
-            case Variable(_) => scrut
-            case _ => Variable(FreshIdentifier("scrut", true).setType(scrut.getType)) 
-          }
-          val sConstr = scrut match {
-            case Variable(_) => BooleanLiteral(true)
-            case _ => Equals(s,scrut)
-          }
-          val substs = patternSubstitutions(s, c.pattern)
-          val cond   = conditionForPattern(scrut, c.pattern)
+          
+          //println("="*40)
+
+          val localScrut = c.pattern.binder.map(Variable) getOrElse scrut
+          //println("PC so far:")
+          //println(replace(Map(scrut -> localScrut), pcSoFar))
+          val scrutConstraint = if (localScrut == scrut) BooleanLiteral(true) else Equals(localScrut, scrut)
+          val substs = patternSubstitutions(localScrut, c.pattern)
+          
+          //println("Pattern : " + c.pattern)
+          //println("SUBST")
+          //substs foreach println
+
+          val cond = conditionForPattern(localScrut, c.pattern)
+          //println("cond: " + cond)
           val g = c.theGuard.getOrElse(BooleanLiteral(true))
-          val pc  = simplify(doSubstitute(substs, And(Seq(pcSoFar, g, sConstr, replace(Map(m -> c.rhs), p.pc)))))
+          val pc  = simplify(doSubstitute(substs, 
+            And(Seq(
+              scrutConstraint,
+              replace(Map(scrut -> localScrut), pcSoFar),
+              cond, 
+              g, 
+              replace(Map(m -> c.rhs), p.pc)
+            ))
+          ))
+          //println("PC")
+          //println(pc)
+
           val phi = doSubstitute(substs, p.phi) 
           val free = variablesOf(And(pc, phi)) -- p.xs
-
-          pcSoFar = And(pcSoFar, Not(cond))
-
+          val guardSafe = replaceFromIDs(mapForPattern(scrut, c.pattern),g)
+          val condSafe = conditionForPattern(scrut, c.pattern)
+          //println("GUARD SAFE:")
+          //println(guardSafe)
+          //println("="*40)
+          pcSoFar = simplify(And(Not(And(condSafe, guardSafe)), pcSoFar))
           val asPrefix = p.as.filter(free)
+
           Problem(asPrefix ++ (free -- asPrefix), pc, phi, p.xs)
         }
 
-        val onSuccess: List[Solution] => Option[Solution] = { 
-          case subs =>
-            val cases = for ((c, s) <- cs zip subs) yield {
-              c match {
-                case SimpleCase(c, rhs) => SimpleCase(c, s.term)
-                case GuardedCase(c, g, rhs) => GuardedCase(c, g, s.term)
-              }
+        val onSuccess: List[Solution] => Option[Solution] = { subs =>
+          val cases = for ((c, s) <- cs zip subs) yield {
+            c match {
+              case SimpleCase(c, rhs) => SimpleCase(c, s.term)
+              case GuardedCase(c, g, rhs) => GuardedCase(c, g, s.term)
             }
+          }
 
-            Some(Solution(Or(subs.map(_.pre)), subs.map(_.defs).foldLeft(Set[FunDef]())(_ ++ _), MatchExpr(scrut, cases)))
+          Some(Solution(
+            Or(subs.map(_.pre)), 
+            subs.map(_.defs).foldLeft(Set[FunDef]())(_ ++ _), 
+            Let(scrut.id, scrut0, MatchExpr(scrut, cases))
+          ))
         }
 
         Some(RuleInstantiation.immediateDecomp(p, this, subs.toList, onSuccess, "Guided Match-Split"))
-- 
GitLab