From 40ed136d8019e10e73b8dff63d60218ab8e9e061 Mon Sep 17 00:00:00 2001
From: Etienne Kneuss <ekneuss@gmail.com>
Date: Thu, 1 Nov 2012 16:01:59 +0100
Subject: [PATCH] Some organization

---
 .../scala/leon/synthesis/Heuristics.scala     | 88 +++++++++++++++++++
 src/main/scala/leon/synthesis/Rules.scala     | 77 +---------------
 .../scala/leon/synthesis/Synthesizer.scala    |  4 +-
 src/main/scala/leon/synthesis/Task.scala      |  2 +-
 testcases/synthesis/SortedList.scala          |  3 +
 5 files changed, 95 insertions(+), 79 deletions(-)
 create mode 100644 src/main/scala/leon/synthesis/Heuristics.scala

diff --git a/src/main/scala/leon/synthesis/Heuristics.scala b/src/main/scala/leon/synthesis/Heuristics.scala
new file mode 100644
index 000000000..2e4a3946a
--- /dev/null
+++ b/src/main/scala/leon/synthesis/Heuristics.scala
@@ -0,0 +1,88 @@
+package leon
+package synthesis
+
+import purescala.Common._
+import purescala.Trees._
+import purescala.Extractors._
+import purescala.TreeOps._
+import purescala.TypeTrees._
+
+object Heuristics {
+  def all(synth: Synthesizer) = Set(
+    new IntInduction(synth)
+  )
+}
+
+class OptimisticGround(synth: Synthesizer) extends Rule("Optimistic Ground", synth, 90) {
+  def applyOn(task: Task): RuleResult = {
+    val p = task.problem
+
+    if (!p.as.isEmpty && !p.xs.isEmpty) {
+      val xss = p.xs.toSet
+      val ass = p.as.toSet
+
+      val tpe = TupleType(p.xs.map(_.getType))
+
+      var i = 0;
+      var maxTries = 3;
+
+      var result: Option[RuleResult]   = None
+      var predicates: Seq[Expr]        = Seq()
+
+      while (result.isEmpty && i < maxTries) {
+        val phi = And(p.phi +: predicates)
+        synth.solveSAT(phi) match {
+          case (Some(true), satModel) =>
+            val satXsModel = satModel.filterKeys(xss) 
+
+            val newPhi = valuateWithModelIn(phi, xss, satModel)
+
+            synth.solveSAT(Not(newPhi)) match {
+              case (Some(true), invalidModel) =>
+                // Found as such as the xs break, refine predicates
+                predicates = valuateWithModelIn(phi, ass, invalidModel) +: predicates
+
+              case (Some(false), _) =>
+                result = Some(RuleSuccess(Solution(BooleanLiteral(true), Tuple(p.xs.map(valuateWithModel(satModel))).setType(tpe))))
+
+              case _ =>
+                result = Some(RuleInapplicable)
+            }
+
+          case (Some(false), _) =>
+            if (predicates.isEmpty) {
+              result = Some(RuleSuccess(Solution(BooleanLiteral(false), Error(p.phi+" is UNSAT!").setType(tpe))))
+            } else {
+              result = Some(RuleInapplicable)
+            }
+          case _ =>
+            result = Some(RuleInapplicable)
+        }
+
+        i += 1 
+      }
+
+      result.getOrElse(RuleInapplicable)
+    } else {
+      RuleInapplicable
+    }
+  }
+}
+
+
+class IntInduction(synth: Synthesizer) extends Rule("Int Induction", synth, 80) {
+  def applyOn(task: Task): RuleResult = {
+    val p = task.problem
+
+    p.as.find(_.getType == Int32Type) match {
+      case Some(inductOn) =>
+              
+        val subBase = Problem(p.as.filterNot(_ == inductOn), subst(inductOn -> IntLiteral(0), p.phi), p.xs)
+      //  val subGT   = Problem(p.as + tmpGT, And(Seq(p.phi, GreaterThan(Variable(inductOn), IntLiteral(0)), subst(inductOn -> IntLiteral(0), p.phi), p.xs)
+
+        RuleDecomposed(List(subBase), forward)
+      case None =>
+        RuleInapplicable
+    }
+  }
+}
diff --git a/src/main/scala/leon/synthesis/Rules.scala b/src/main/scala/leon/synthesis/Rules.scala
index 8b78e8429..7fb8a3c8e 100644
--- a/src/main/scala/leon/synthesis/Rules.scala
+++ b/src/main/scala/leon/synthesis/Rules.scala
@@ -8,13 +8,12 @@ import purescala.TreeOps._
 import purescala.TypeTrees._
 
 object Rules {
-  def all(synth: Synthesizer) = List(
+  def all(synth: Synthesizer) = Set(
     new Unification.DecompTrivialClash(synth),
     new Unification.OccursCheck(synth),
     new ADTDual(synth),
     new OnePoint(synth),
     new Ground(synth),
-    new OptimisticGround(synth),
     new CaseSplit(synth),
     new UnusedInput(synth),
     new UnconstrainedOutput(synth),
@@ -103,62 +102,6 @@ class Ground(synth: Synthesizer) extends Rule("Ground", synth, 500) {
   }
 }
 
-class OptimisticGround(synth: Synthesizer) extends Rule("Optimistic Ground", synth, 90) {
-  def applyOn(task: Task): RuleResult = {
-    val p = task.problem
-
-    if (!p.as.isEmpty && !p.xs.isEmpty) {
-      val xss = p.xs.toSet
-      val ass = p.as.toSet
-
-      val tpe = TupleType(p.xs.map(_.getType))
-
-      var i = 0;
-      var maxTries = 3;
-
-      var result: Option[RuleResult]   = None
-      var predicates: Seq[Expr]        = Seq()
-
-      while (result.isEmpty && i < maxTries) {
-        val phi = And(p.phi +: predicates)
-        synth.solveSAT(phi) match {
-          case (Some(true), satModel) =>
-            val satXsModel = satModel.filterKeys(xss) 
-
-            val newPhi = valuateWithModelIn(phi, xss, satModel)
-
-            synth.solveSAT(Not(newPhi)) match {
-              case (Some(true), invalidModel) =>
-                // Found as such as the xs break, refine predicates
-                predicates = valuateWithModelIn(phi, ass, invalidModel) +: predicates
-
-              case (Some(false), _) =>
-                result = Some(RuleSuccess(Solution(BooleanLiteral(true), Tuple(p.xs.map(valuateWithModel(satModel))).setType(tpe))))
-
-              case _ =>
-                result = Some(RuleInapplicable)
-            }
-
-          case (Some(false), _) =>
-            if (predicates.isEmpty) {
-              result = Some(RuleSuccess(Solution(BooleanLiteral(false), Error(p.phi+" is UNSAT!").setType(tpe))))
-            } else {
-              result = Some(RuleInapplicable)
-            }
-          case _ =>
-            result = Some(RuleInapplicable)
-        }
-
-        i += 1 
-      }
-
-      result.getOrElse(RuleInapplicable)
-    } else {
-      RuleInapplicable
-    }
-  }
-}
-
 class CaseSplit(synth: Synthesizer) extends Rule("Case-Split", synth, 200) {
   def applyOn(task: Task): RuleResult = {
     val p = task.problem
@@ -332,21 +275,3 @@ class ADTDual(synth: Synthesizer) extends Rule("ADTDual", synth, 200) {
   }
 }
 
-object Heuristics {
-  class IntInduction(synth: Synthesizer) extends Rule("Int Induction", synth, 80) {
-    def applyOn(task: Task): RuleResult = {
-      val p = task.problem
-
-      p.as.find(_.getType == Int32Type) match {
-        case Some(inductOn) =>
-                
-          val subBase = Problem(p.as.filterNot(_ == inductOn), subst(inductOn -> IntLiteral(0), p.phi), p.xs)
-        //  val subGT   = Problem(p.as + tmpGT, And(Seq(p.phi, GreaterThan(Variable(inductOn), IntLiteral(0)), subst(inductOn -> IntLiteral(0), p.phi), p.xs)
-
-          RuleDecomposed(List(subBase), forward)
-        case None =>
-          RuleInapplicable
-      }
-    }
-  }
-}
diff --git a/src/main/scala/leon/synthesis/Synthesizer.scala b/src/main/scala/leon/synthesis/Synthesizer.scala
index 7fc3fa884..918b6584a 100644
--- a/src/main/scala/leon/synthesis/Synthesizer.scala
+++ b/src/main/scala/leon/synthesis/Synthesizer.scala
@@ -18,7 +18,7 @@ class Synthesizer(val r: Reporter, val solvers: List[Solver], generateDerivation
 
   var derivationCounter = 1;
 
-  def synthesize(p: Problem, rules: List[Rule]): Solution = {
+  def synthesize(p: Problem, rules: Set[Rule]): Solution = {
 
     val workList = new PriorityQueue[Task]()
     val rootTask = new RootTask(this, p)
@@ -56,7 +56,7 @@ class Synthesizer(val r: Reporter, val solvers: List[Solver], generateDerivation
     (None, Map())
   }
 
-  val rules = Rules.all(this)
+  val rules = Rules.all(this) ++ Heuristics.all(this)
 
   import purescala.Trees._
   def synthesizeAll(program: Program): Map[Choose, Solution] = {
diff --git a/src/main/scala/leon/synthesis/Task.scala b/src/main/scala/leon/synthesis/Task.scala
index 3584447e2..ee579b1a1 100644
--- a/src/main/scala/leon/synthesis/Task.scala
+++ b/src/main/scala/leon/synthesis/Task.scala
@@ -33,7 +33,7 @@ class SimpleTask(synth: Synthesizer,
   }
 
   def run: List[Task] = {
-    synth.rules.map(r => new ApplyRuleTask(synth, this, problem, r))
+    synth.rules.map(r => new ApplyRuleTask(synth, this, problem, r)).toList
   }
 
   var failed = Set[Rule]()
diff --git a/testcases/synthesis/SortedList.scala b/testcases/synthesis/SortedList.scala
index 2e5a42ff9..09f664a12 100644
--- a/testcases/synthesis/SortedList.scala
+++ b/testcases/synthesis/SortedList.scala
@@ -24,6 +24,9 @@ object SortedList {
 
   def insertSynth(in: List, v: Int) = choose{ (out: List) => content(out) == content(in) ++ Set(v) }
 
+  def tailSynth(in: List) = choose{out: List => size(out)+1 == size(in)}
+  def consSynth(in: List) = choose{out: List => size(out) == size(in)+1}
+
   def insert1(l: List, v: Int) = (
     Cons(v, l)
   ) ensuring(res => content(res) == content(l) ++ Set(v) && size(res) >= size(l))
-- 
GitLab