From 3560caf3c52b7edd4b1b8aa46a0e4230f154e3ee Mon Sep 17 00:00:00 2001
From: Manos Koukoutos <emmanouil.koukoutos@epfl.ch>
Date: Mon, 8 Aug 2016 15:45:54 +0200
Subject: [PATCH] GrammarDataGen, EnumerationSolver

---
 .../scala/inox/datagen/GrammarDataGen.scala   |  9 +-
 .../inox/solvers/EnumerationSolver.scala      | 87 +++++++++++--------
 2 files changed, 55 insertions(+), 41 deletions(-)

diff --git a/src/main/scala/inox/datagen/GrammarDataGen.scala b/src/main/scala/inox/datagen/GrammarDataGen.scala
index 0318f76eb..7b9280831 100644
--- a/src/main/scala/inox/datagen/GrammarDataGen.scala
+++ b/src/main/scala/inox/datagen/GrammarDataGen.scala
@@ -13,13 +13,16 @@ import grammars._
 /** Utility functions to generate values of a given type.
   * In fact, it could be used to generate *terms* of a given type,
   * e.g. by passing trees representing variables for the "bounds". */
-trait GrammarDataGen extends DataGenerator with GrammarsUniverse { self =>
+trait GrammarDataGen extends DataGenerator { self =>
+  val grammars: GrammarsUniverse { val program: self.program.type }
+  import grammars._
   val evaluator: DeterministicEvaluator { val program: self.program.type }
   val grammar: ExpressionGrammar
 
   import program._
   import program.trees._
   import program.symbols._
+  import exprOps._
 
   // Assume e contains generic values with index 0.
   // Return a series of expressions with all normalized combinations of generic values.
@@ -56,7 +59,7 @@ trait GrammarDataGen extends DataGenerator with GrammarsUniverse { self =>
     enum.iterator(Label(tpe)).flatMap(expandGenerics).takeWhile(_ => !interrupted.get)
   }
 
-  def generateFor(ins: Seq[Variable], satisfying: Expr, maxValid: Int, maxEnumerated: Int): Iterator[Seq[Expr]] = {
+  def generateFor(ins: Seq[ValDef], satisfying: Expr, maxValid: Int, maxEnumerated: Int): Iterator[Seq[Expr]] = {
 
     def filterCond(vs: Seq[Expr]): Boolean = satisfying match {
       case BooleanLiteral(true) =>
@@ -85,7 +88,7 @@ trait GrammarDataGen extends DataGenerator with GrammarsUniverse { self =>
     }
   }
 
-  def generateMapping(ins: Seq[Variable], satisfying: Expr, maxValid: Int, maxEnumerated: Int) = {
+  def generateMapping(ins: Seq[ValDef], satisfying: Expr, maxValid: Int, maxEnumerated: Int) = {
     generateFor(ins, satisfying, maxValid, maxEnumerated) map (ins zip _)
   }
 
diff --git a/src/main/scala/inox/solvers/EnumerationSolver.scala b/src/main/scala/inox/solvers/EnumerationSolver.scala
index 86a3a91f0..4ba5e19db 100644
--- a/src/main/scala/inox/solvers/EnumerationSolver.scala
+++ b/src/main/scala/inox/solvers/EnumerationSolver.scala
@@ -1,32 +1,39 @@
 /* Copyright 2009-2016 EPFL, Lausanne */
 
-package leon
+package inox
 package solvers
 
+import evaluators._
+import SolverResponses._
+import grammars.GrammarsUniverse
 import utils._
-import purescala.Common._
-import purescala.Definitions._
-import purescala.Constructors._
-import purescala.Expressions._
-import purescala.ExprOps._
-
 import datagen._
 
-class EnumerationSolver(val sctx: SolverContext, val program: Program) extends Solver with NaiveAssumptionSolver {
+trait EnumerationSolver extends Solver { self =>
+
+  val grammars: GrammarsUniverse { val program: self.program.type }
+
+  val evaluator: DeterministicEvaluator { val program: self.program.type }
+
+  import program._
+  import trees._
+  import symbols._
+  import exprOps._
+
   def name = "Enum"
 
   val maxTried = 10000
 
-  var datagen: Option[DataGenerator] = None
+  var datagen: Option[DataGenerator { val program: self.program.type }] = None
 
   private var interrupted = false
 
-  val freeVars    = new IncrementalSet[Identifier]()
+  val freeVars    = new IncrementalSet[ValDef]()
   val constraints = new IncrementalSeq[Expr]()
 
   def assertCnstr(expression: Expr): Unit = {
     constraints += expression
-    freeVars ++= variablesOf(expression)
+    freeVars ++= variablesOf(expression).map(_.toVal)
   }
 
   def push() = {
@@ -46,43 +53,49 @@ class EnumerationSolver(val sctx: SolverContext, val program: Program) extends S
     datagen     = None
   }
 
-  private var model = Model.empty
-
-  /** @inheritdoc */
-  def check: Option[Boolean] = {
-    val timer = context.timers.solvers.enum.check.start()
-    val res = try {
-      datagen = Some(new VanuatooDataGen(context, program, sctx.bank))
+  def check(config: Configuration): config.Response[Model, Cores] = config.cast {
+    val res: SolverResponse[Model, Cores] = try {
+      datagen = Some(new GrammarDataGen {
+        val grammars: self.grammars.type = self.grammars
+        val evaluator: DeterministicEvaluator { val program: self.program.type } = self.evaluator
+        val grammar: grammars.ExpressionGrammar = grammars.ValueGrammar
+        val program: self.program.type = self.program
+        def functionsAvailable(p: Program): Set[FunDef] = Set()
+      })
       if (interrupted) {
-        None
+        Unknown
       } else {
-        model = Model.empty
-        val allFreeVars = freeVars.toSeq.sortBy(_.name)
+        val allFreeVars = freeVars.toSeq.sortBy(_.id.name)
         val allConstraints = constraints.toSeq
 
-        val it = datagen.get.generateFor(allFreeVars, andJoin(allConstraints), 1, maxTried)
+        val it: Iterator[Seq[Expr]] = datagen.get.generateFor(allFreeVars, andJoin(allConstraints), 1, maxTried)
 
         if (it.hasNext) {
-          val varModels = it.next
-          model = new Model((allFreeVars zip varModels).toMap)
-          Some(true)
+          config match {
+            case All | Model =>
+              val varModels = it.next
+              SatWithModel(allFreeVars.zip(varModels).toMap)
+            case _ =>
+              Sat
+          }
         } else {
-          None
+          config match {
+            case All | Cores =>
+              ??? // TODO
+            case _ =>
+              Unsat
+          }
         }
       }
     } catch {
-      case e: codegen.CompilationException =>
-        None
+      case e: Throwable =>
+        Unknown
     }
     datagen = None
-    timer.stop()
     res
   }
 
-  /** @inheritdoc */
-  def getModel: Model = {
-    model
-  }
+  def checkAssumptions(config: Configuration)(assumptions: Set[Trees]): config.Response[Model, Cores] = ??? // TODO
 
   def free() = {
     constraints.clear()
@@ -90,13 +103,11 @@ class EnumerationSolver(val sctx: SolverContext, val program: Program) extends S
 
   def interrupt(): Unit = {
     interrupted = true
-
-    datagen.foreach{ s =>
-      s.interrupt
-    }
+    datagen.foreach(_.interrupt())
   }
 
   def recoverInterrupt(): Unit = {
-    datagen.foreach(_.recoverInterrupt)
+    interrupted = false
+    datagen.foreach(_.recoverInterrupt())
   }
 }
-- 
GitLab