From 8c3708b01d7a45a92f9d7d00b3be9e49a8d2a79c Mon Sep 17 00:00:00 2001
From: Etienne Kneuss <ekneuss@gmail.com>
Date: Thu, 15 Nov 2012 02:39:04 +0100
Subject: [PATCH] Mooooaaaar files

---
 .../scala/leon/synthesis/Heuristics.scala     | 231 +-----------------
 .../synthesis/heuristics/ADTInduction.scala   | 107 ++++++++
 .../synthesis/heuristics/IntInduction.scala   |  64 +++++
 .../heuristics/OptimisticInjection.scala      |  46 ++++
 .../heuristics/SelectiveInlining.scala        |  46 ++++
 5 files changed, 268 insertions(+), 226 deletions(-)
 create mode 100644 src/main/scala/leon/synthesis/heuristics/ADTInduction.scala
 create mode 100644 src/main/scala/leon/synthesis/heuristics/IntInduction.scala
 create mode 100644 src/main/scala/leon/synthesis/heuristics/OptimisticInjection.scala
 create mode 100644 src/main/scala/leon/synthesis/heuristics/SelectiveInlining.scala

diff --git a/src/main/scala/leon/synthesis/Heuristics.scala b/src/main/scala/leon/synthesis/Heuristics.scala
index 4f51d8c05..be50b59aa 100644
--- a/src/main/scala/leon/synthesis/Heuristics.scala
+++ b/src/main/scala/leon/synthesis/Heuristics.scala
@@ -1,17 +1,15 @@
 package leon
 package synthesis
 
-import purescala.Common._
 import purescala.Trees._
-import purescala.Extractors._
-import purescala.TreeOps._
-import purescala.TypeTrees._
-import purescala.Definitions._
+
+import heuristics._
 
 object Heuristics {
   def all = Set[Synthesizer => Rule](
-    //new IntInduction(_),
-    new OptimisticInjection(_),
+    new IntInduction(_),
+    //new OptimisticInjection(_),
+    //new SelectiveInlining(_),
     new ADTInduction(_)
   )
 }
@@ -42,225 +40,6 @@ object HeuristicStep {
 }
 
 
-class IntInduction(synth: Synthesizer) extends Rule("Int Induction", synth, 80) with Heuristic {
-  def applyOn(task: Task): RuleResult = {
-    val p = task.problem
-
-    p.as match {
-      case List(IsTyped(origId, Int32Type)) =>
-        val tpe = TupleType(p.xs.map(_.getType))
-
-        val inductOn = FreshIdentifier(origId.name, true).setType(origId.getType)
-
-        val postXs  = p.xs map (id => FreshIdentifier("r", true).setType(id.getType))
-
-        val postXsMap = (p.xs zip postXs).toMap.mapValues(Variable(_))
-
-        val newPhi     = subst(origId -> Variable(inductOn), p.phi)
-        val postCondGT = substAll(postXsMap + (origId -> Minus(Variable(inductOn), IntLiteral(1))), p.phi)
-        val postCondLT = substAll(postXsMap + (origId -> Plus(Variable(inductOn), IntLiteral(1))), p.phi)
-
-        val subBase = Problem(List(), p.c, subst(origId -> IntLiteral(0), p.phi), p.xs)
-        val subGT   = Problem(inductOn :: postXs, p.c, And(Seq(newPhi, GreaterThan(Variable(inductOn), IntLiteral(0)), postCondGT)), p.xs)
-        val subLT   = Problem(inductOn :: postXs, p.c, And(Seq(newPhi, LessThan(Variable(inductOn), IntLiteral(0)), postCondLT)), p.xs)
-
-        val onSuccess: List[Solution] => Solution = {
-          case List(base, gt, lt) =>
-            val preIn = Or(Seq(And(Equals(Variable(inductOn), IntLiteral(0)),      base.pre),
-                               And(GreaterThan(Variable(inductOn), IntLiteral(0)), gt.pre),
-                               And(LessThan(Variable(inductOn), IntLiteral(0)),    lt.pre)))
-            val preOut = subst(inductOn -> Variable(origId), preIn)
-
-            val newFun = new FunDef(FreshIdentifier("rec", true), tpe, Seq(VarDecl(inductOn, inductOn.getType)))
-            newFun.precondition = Some(preIn)
-            newFun.postcondition = Some(LetTuple(p.xs.toSeq, ResultVariable(), p.phi))
-
-            newFun.body = Some(
-              IfExpr(Equals(Variable(inductOn), IntLiteral(0)),
-                base.toExpr,
-              IfExpr(GreaterThan(Variable(inductOn), IntLiteral(0)),
-                LetTuple(postXs, FunctionInvocation(newFun, Seq(Minus(Variable(inductOn), IntLiteral(1)))), gt.toExpr)
-              , LetTuple(postXs, FunctionInvocation(newFun, Seq(Plus(Variable(inductOn), IntLiteral(1)))), lt.toExpr)))
-            )
-
-
-            Solution(preOut, base.defs++gt.defs++lt.defs+newFun, FunctionInvocation(newFun, Seq(Variable(origId))))
-          case _ =>
-            Solution.none
-        }
-
-        HeuristicStep(synth, p, List(subBase, subGT, subLT), onSuccess)
-      case _ =>
-        RuleInapplicable
-    }
-  }
-}
-
-class OptimisticInjection(synth: Synthesizer) extends Rule("Opt. Injection", synth, 50) with Heuristic {
-  def applyOn(task: Task): RuleResult = {
-    val p = task.problem
-
-    val TopLevelAnds(exprs) = p.phi
-
-    val eqfuncalls = exprs.collect{
-      case eq @ Equals(FunctionInvocation(fd, args), e) =>
-        ((fd, e), args, eq : Expr)
-      case eq @ Equals(e, FunctionInvocation(fd, args)) =>
-        ((fd, e), args, eq : Expr)
-    }
-
-    val candidates = eqfuncalls.groupBy(_._1).filter(_._2.size > 1)
-    if (!candidates.isEmpty) {
-
-      var newExprs = exprs
-      for (cands <- candidates.values) {
-        val cand = cands.take(2)
-        val toRemove = cand.map(_._3).toSet
-        val argss    = cand.map(_._2)
-        val args     = argss(0) zip argss(1)
-
-        newExprs ++= args.map{ case (l, r) => Equals(l, r) }
-        newExprs = newExprs.filterNot(toRemove)
-      }
-
-      val sub = p.copy(phi = And(newExprs))
-
-      HeuristicStep(synth, p, List(sub), forward)
-    } else {
-      RuleInapplicable
-    }
-  }
-}
-
-class SelectiveInlining(synth: Synthesizer) extends Rule("Sel. Inlining", synth, 20) with Heuristic {
-  def applyOn(task: Task): RuleResult = {
-    val p = task.problem
-
-    val TopLevelAnds(exprs) = p.phi
-
-    val eqfuncalls = exprs.collect{
-      case eq @ Equals(FunctionInvocation(fd, args), e) =>
-        ((fd, e), args, eq : Expr)
-      case eq @ Equals(e, FunctionInvocation(fd, args)) =>
-        ((fd, e), args, eq : Expr)
-    }
-
-    val candidates = eqfuncalls.groupBy(_._1).filter(_._2.size > 1)
-    if (!candidates.isEmpty) {
-
-      var newExprs = exprs
-      for (cands <- candidates.values) {
-        val cand = cands.take(2)
-        val toRemove = cand.map(_._3).toSet
-        val argss    = cand.map(_._2)
-        val args     = argss(0) zip argss(1)
-
-        newExprs ++= args.map{ case (l, r) => Equals(l, r) }
-        newExprs = newExprs.filterNot(toRemove)
-      }
-
-      val sub = p.copy(phi = And(newExprs))
-
-      HeuristicStep(synth, p, List(sub), forward)
-    } else {
-      RuleInapplicable
-    }
-  }
-}
-
-class ADTInduction(synth: Synthesizer) extends Rule("ADT Induction", synth, 80) with Heuristic {
-  def applyOn(task: Task): RuleResult = {
-    val p = task.problem
-
-    val candidates = p.as.collect {
-        case IsTyped(origId, AbstractClassType(cd)) => (origId, cd)
-    }
-
-    if (!candidates.isEmpty) {
-      val (origId, cd) = candidates.head
-      val oas = p.as.filterNot(_ == origId)
-
-      val resType = TupleType(p.xs.map(_.getType))
-
-      val inductOn     = FreshIdentifier(origId.name, true).setType(origId.getType)
-      val residualArgs = oas.map(id => FreshIdentifier(id.name, true).setType(id.getType))
-      val residualMap  = (oas zip residualArgs).map{ case (id, id2) => id -> Variable(id2) }.toMap
-      val residualArgDefs = residualArgs.map(a => VarDecl(a, a.getType))
-
-      def isAlternativeRecursive(cd: CaseClassDef): Boolean = {
-        cd.fieldsIds.exists(_.getType == origId.getType)
-      }
-
-      val isRecursive = cd.knownDescendents.exists {
-        case ccd: CaseClassDef => isAlternativeRecursive(ccd)
-        case _ => false
-      }
-
-      if (isRecursive) {
-        val newFun = new FunDef(FreshIdentifier("rec", true), resType, VarDecl(inductOn, inductOn.getType) +: residualArgDefs)
-
-        val innerPhi = substAll(residualMap + (origId -> Variable(inductOn)), p.phi)
 
-        val subProblemsInfo = for (dcd <- cd.knownDescendents) yield dcd match {
-          case ccd : CaseClassDef =>
-            var recCalls = Map[List[Identifier], Expr]()
-            var postFs   = List[Expr]()
 
-            val newIds = ccd.fieldsIds.map(id => FreshIdentifier(id.name, true).setType(id.getType)).toList
 
-            val inputs = (for (id <- newIds) yield {
-              if (id.getType == origId.getType) {
-                val postXs  = p.xs map (id => FreshIdentifier("r", true).setType(id.getType))
-                val postXsMap = (p.xs zip postXs).toMap.mapValues(Variable(_))
-
-                recCalls += postXs -> FunctionInvocation(newFun, Variable(id) +: residualArgs.map(id => Variable(id)))
-
-                postFs ::= substAll(postXsMap + (inductOn -> Variable(id)), innerPhi)
-                id :: postXs
-              } else {
-                List(id)
-              }
-            }).flatten
-
-            val subPhi = substAll(Map(inductOn -> CaseClass(ccd, newIds.map(Variable(_)))), innerPhi)
-
-            val subPre = CaseClassInstanceOf(ccd, Variable(origId))
-
-            val subProblem = Problem(inputs ::: residualArgs, And(p.c :: postFs), subPhi, p.xs)
-
-            (subProblem, subPre, ccd, newIds, recCalls)
-          case _ =>
-            sys.error("Woops, non case-class as descendent")
-        }
-
-        val onSuccess: List[Solution] => Solution = {
-          case sols =>
-            var globalPre = List[Expr]()
-
-            val cases = for ((sol, (problem, pre, ccd, ids, calls)) <- (sols zip subProblemsInfo)) yield {
-              globalPre ::= And(pre, sol.pre)
-
-              val caze = CaseClassPattern(None, ccd, ids.map(id => WildcardPattern(Some(id))))
-              SimpleCase(caze, calls.foldLeft(sol.term){ case (t, (binders, call)) => LetTuple(binders, call, t) })
-            }
-
-            val funPre = subst(origId -> Variable(inductOn), Or(globalPre))
-            val outerPre = Or(globalPre)
-
-            newFun.precondition = Some(funPre)
-            newFun.postcondition = Some(LetTuple(p.xs.toSeq, ResultVariable(), p.phi))
-
-            newFun.body = Some(MatchExpr(Variable(inductOn), cases))
-
-            Solution(Or(globalPre), sols.flatMap(_.defs).toSet+newFun, FunctionInvocation(newFun, p.as.map(Variable(_))))
-        }
-
-        HeuristicStep(synth, p, subProblemsInfo.map(_._1).toList, onSuccess)
-      } else {
-        RuleInapplicable
-      }
-    } else {
-      RuleInapplicable
-    }
-  }
-}
diff --git a/src/main/scala/leon/synthesis/heuristics/ADTInduction.scala b/src/main/scala/leon/synthesis/heuristics/ADTInduction.scala
new file mode 100644
index 000000000..d321a61db
--- /dev/null
+++ b/src/main/scala/leon/synthesis/heuristics/ADTInduction.scala
@@ -0,0 +1,107 @@
+package leon
+package synthesis
+package heuristics
+
+import purescala.Common._
+import purescala.Trees._
+import purescala.Extractors._
+import purescala.TreeOps._
+import purescala.TypeTrees._
+import purescala.Definitions._
+
+class ADTInduction(synth: Synthesizer) extends Rule("ADT Induction", synth, 80) with Heuristic {
+  def applyOn(task: Task): RuleResult = {
+    val p = task.problem
+
+    val candidates = p.as.collect {
+        case IsTyped(origId, AbstractClassType(cd)) => (origId, cd)
+    }
+
+    if (!candidates.isEmpty) {
+      val (origId, cd) = candidates.head
+      val oas = p.as.filterNot(_ == origId)
+
+      val resType = TupleType(p.xs.map(_.getType))
+
+      val inductOn     = FreshIdentifier(origId.name, true).setType(origId.getType)
+      val residualArgs = oas.map(id => FreshIdentifier(id.name, true).setType(id.getType))
+      val residualMap  = (oas zip residualArgs).map{ case (id, id2) => id -> Variable(id2) }.toMap
+      val residualArgDefs = residualArgs.map(a => VarDecl(a, a.getType))
+
+      def isAlternativeRecursive(cd: CaseClassDef): Boolean = {
+        cd.fieldsIds.exists(_.getType == origId.getType)
+      }
+
+      val isRecursive = cd.knownDescendents.exists {
+        case ccd: CaseClassDef => isAlternativeRecursive(ccd)
+        case _ => false
+      }
+
+      if (isRecursive) {
+        val newFun = new FunDef(FreshIdentifier("rec", true), resType, VarDecl(inductOn, inductOn.getType) +: residualArgDefs)
+
+        val innerPhi = substAll(residualMap + (origId -> Variable(inductOn)), p.phi)
+
+        val subProblemsInfo = for (dcd <- cd.knownDescendents) yield dcd match {
+          case ccd : CaseClassDef =>
+            var recCalls = Map[List[Identifier], Expr]()
+            var postFs   = List[Expr]()
+
+            val newIds = ccd.fieldsIds.map(id => FreshIdentifier(id.name, true).setType(id.getType)).toList
+
+            val inputs = (for (id <- newIds) yield {
+              if (id.getType == origId.getType) {
+                val postXs  = p.xs map (id => FreshIdentifier("r", true).setType(id.getType))
+                val postXsMap = (p.xs zip postXs).toMap.mapValues(Variable(_))
+
+                recCalls += postXs -> FunctionInvocation(newFun, Variable(id) +: residualArgs.map(id => Variable(id)))
+
+                postFs ::= substAll(postXsMap + (inductOn -> Variable(id)), innerPhi)
+                id :: postXs
+              } else {
+                List(id)
+              }
+            }).flatten
+
+            val subPhi = substAll(Map(inductOn -> CaseClass(ccd, newIds.map(Variable(_)))), innerPhi)
+
+            val subPre = CaseClassInstanceOf(ccd, Variable(origId))
+
+            val subProblem = Problem(inputs ::: residualArgs, And(p.c :: postFs), subPhi, p.xs)
+
+            (subProblem, subPre, ccd, newIds, recCalls)
+          case _ =>
+            sys.error("Woops, non case-class as descendent")
+        }
+
+        val onSuccess: List[Solution] => Solution = {
+          case sols =>
+            var globalPre = List[Expr]()
+
+            val cases = for ((sol, (problem, pre, ccd, ids, calls)) <- (sols zip subProblemsInfo)) yield {
+              globalPre ::= And(pre, sol.pre)
+
+              val caze = CaseClassPattern(None, ccd, ids.map(id => WildcardPattern(Some(id))))
+              SimpleCase(caze, calls.foldLeft(sol.term){ case (t, (binders, call)) => LetTuple(binders, call, t) })
+            }
+
+            val funPre = subst(origId -> Variable(inductOn), Or(globalPre))
+            val outerPre = Or(globalPre)
+
+            newFun.precondition = Some(funPre)
+            newFun.postcondition = Some(LetTuple(p.xs.toSeq, ResultVariable(), p.phi))
+
+            newFun.body = Some(MatchExpr(Variable(inductOn), cases))
+
+            Solution(Or(globalPre), sols.flatMap(_.defs).toSet+newFun, FunctionInvocation(newFun, p.as.map(Variable(_))))
+        }
+
+        HeuristicStep(synth, p, subProblemsInfo.map(_._1).toList, onSuccess)
+      } else {
+        RuleInapplicable
+      }
+    } else {
+      RuleInapplicable
+    }
+  }
+}
diff --git a/src/main/scala/leon/synthesis/heuristics/IntInduction.scala b/src/main/scala/leon/synthesis/heuristics/IntInduction.scala
new file mode 100644
index 000000000..03ee8d6db
--- /dev/null
+++ b/src/main/scala/leon/synthesis/heuristics/IntInduction.scala
@@ -0,0 +1,64 @@
+package leon
+package synthesis
+package heuristics
+
+import purescala.Common._
+import purescala.Trees._
+import purescala.Extractors._
+import purescala.TreeOps._
+import purescala.TypeTrees._
+import purescala.Definitions._
+
+class IntInduction(synth: Synthesizer) extends Rule("Int Induction", synth, 80) with Heuristic {
+  def applyOn(task: Task): RuleResult = {
+    val p = task.problem
+
+    p.as match {
+      case List(IsTyped(origId, Int32Type)) =>
+        val tpe = TupleType(p.xs.map(_.getType))
+
+        val inductOn = FreshIdentifier(origId.name, true).setType(origId.getType)
+
+        val postXs  = p.xs map (id => FreshIdentifier("r", true).setType(id.getType))
+
+        val postXsMap = (p.xs zip postXs).toMap.mapValues(Variable(_))
+
+        val newPhi     = subst(origId -> Variable(inductOn), p.phi)
+        val postCondGT = substAll(postXsMap + (origId -> Minus(Variable(inductOn), IntLiteral(1))), p.phi)
+        val postCondLT = substAll(postXsMap + (origId -> Plus(Variable(inductOn), IntLiteral(1))), p.phi)
+
+        val subBase = Problem(List(), p.c, subst(origId -> IntLiteral(0), p.phi), p.xs)
+        val subGT   = Problem(inductOn :: postXs, p.c, And(Seq(newPhi, GreaterThan(Variable(inductOn), IntLiteral(0)), postCondGT)), p.xs)
+        val subLT   = Problem(inductOn :: postXs, p.c, And(Seq(newPhi, LessThan(Variable(inductOn), IntLiteral(0)), postCondLT)), p.xs)
+
+        val onSuccess: List[Solution] => Solution = {
+          case List(base, gt, lt) =>
+            val preIn = Or(Seq(And(Equals(Variable(inductOn), IntLiteral(0)),      base.pre),
+                               And(GreaterThan(Variable(inductOn), IntLiteral(0)), gt.pre),
+                               And(LessThan(Variable(inductOn), IntLiteral(0)),    lt.pre)))
+            val preOut = subst(inductOn -> Variable(origId), preIn)
+
+            val newFun = new FunDef(FreshIdentifier("rec", true), tpe, Seq(VarDecl(inductOn, inductOn.getType)))
+            newFun.precondition = Some(preIn)
+            newFun.postcondition = Some(LetTuple(p.xs.toSeq, ResultVariable(), p.phi))
+
+            newFun.body = Some(
+              IfExpr(Equals(Variable(inductOn), IntLiteral(0)),
+                base.toExpr,
+              IfExpr(GreaterThan(Variable(inductOn), IntLiteral(0)),
+                LetTuple(postXs, FunctionInvocation(newFun, Seq(Minus(Variable(inductOn), IntLiteral(1)))), gt.toExpr)
+              , LetTuple(postXs, FunctionInvocation(newFun, Seq(Plus(Variable(inductOn), IntLiteral(1)))), lt.toExpr)))
+            )
+
+
+            Solution(preOut, base.defs++gt.defs++lt.defs+newFun, FunctionInvocation(newFun, Seq(Variable(origId))))
+          case _ =>
+            Solution.none
+        }
+
+        HeuristicStep(synth, p, List(subBase, subGT, subLT), onSuccess)
+      case _ =>
+        RuleInapplicable
+    }
+  }
+}
diff --git a/src/main/scala/leon/synthesis/heuristics/OptimisticInjection.scala b/src/main/scala/leon/synthesis/heuristics/OptimisticInjection.scala
new file mode 100644
index 000000000..9c76475e4
--- /dev/null
+++ b/src/main/scala/leon/synthesis/heuristics/OptimisticInjection.scala
@@ -0,0 +1,46 @@
+package leon
+package synthesis
+package heuristics
+
+import purescala.Common._
+import purescala.Trees._
+import purescala.Extractors._
+import purescala.TreeOps._
+import purescala.TypeTrees._
+import purescala.Definitions._
+
+class OptimisticInjection(synth: Synthesizer) extends Rule("Opt. Injection", synth, 50) with Heuristic {
+  def applyOn(task: Task): RuleResult = {
+    val p = task.problem
+
+    val TopLevelAnds(exprs) = p.phi
+
+    val eqfuncalls = exprs.collect{
+      case eq @ Equals(FunctionInvocation(fd, args), e) =>
+        ((fd, e), args, eq : Expr)
+      case eq @ Equals(e, FunctionInvocation(fd, args)) =>
+        ((fd, e), args, eq : Expr)
+    }
+
+    val candidates = eqfuncalls.groupBy(_._1).filter(_._2.size > 1)
+    if (!candidates.isEmpty) {
+
+      var newExprs = exprs
+      for (cands <- candidates.values) {
+        val cand = cands.take(2)
+        val toRemove = cand.map(_._3).toSet
+        val argss    = cand.map(_._2)
+        val args     = argss(0) zip argss(1)
+
+        newExprs ++= args.map{ case (l, r) => Equals(l, r) }
+        newExprs = newExprs.filterNot(toRemove)
+      }
+
+      val sub = p.copy(phi = And(newExprs))
+
+      HeuristicStep(synth, p, List(sub), forward)
+    } else {
+      RuleInapplicable
+    }
+  }
+}
diff --git a/src/main/scala/leon/synthesis/heuristics/SelectiveInlining.scala b/src/main/scala/leon/synthesis/heuristics/SelectiveInlining.scala
new file mode 100644
index 000000000..04d38f5fe
--- /dev/null
+++ b/src/main/scala/leon/synthesis/heuristics/SelectiveInlining.scala
@@ -0,0 +1,46 @@
+package leon
+package synthesis
+package heuristics
+
+import purescala.Common._
+import purescala.Trees._
+import purescala.Extractors._
+import purescala.TreeOps._
+import purescala.TypeTrees._
+import purescala.Definitions._
+
+class SelectiveInlining(synth: Synthesizer) extends Rule("Sel. Inlining", synth, 20) with Heuristic {
+  def applyOn(task: Task): RuleResult = {
+    val p = task.problem
+
+    val TopLevelAnds(exprs) = p.phi
+
+    val eqfuncalls = exprs.collect{
+      case eq @ Equals(FunctionInvocation(fd, args), e) =>
+        ((fd, e), args, eq : Expr)
+      case eq @ Equals(e, FunctionInvocation(fd, args)) =>
+        ((fd, e), args, eq : Expr)
+    }
+
+    val candidates = eqfuncalls.groupBy(_._1).filter(_._2.size > 1)
+    if (!candidates.isEmpty) {
+
+      var newExprs = exprs
+      for (cands <- candidates.values) {
+        val cand = cands.take(2)
+        val toRemove = cand.map(_._3).toSet
+        val argss    = cand.map(_._2)
+        val args     = argss(0) zip argss(1)
+
+        newExprs ++= args.map{ case (l, r) => Equals(l, r) }
+        newExprs = newExprs.filterNot(toRemove)
+      }
+
+      val sub = p.copy(phi = And(newExprs))
+
+      HeuristicStep(synth, p, List(sub), forward)
+    } else {
+      RuleInapplicable
+    }
+  }
+}
-- 
GitLab