Skip to content
Snippets Groups Projects
Commit 379ac744 authored by Manos Koukoutos's avatar Manos Koukoutos
Browse files

PortfolioSolvers

parent caeaec9f
No related branches found
No related tags found
No related merge requests found
...@@ -72,7 +72,7 @@ object SolverResponses { ...@@ -72,7 +72,7 @@ object SolverResponses {
} }
def cast[M, C](resp: SolverResponse[M,C]): Response[M,C] = ((this, resp) match { def cast[M, C](resp: SolverResponse[M,C]): Response[M,C] = ((this, resp) match {
case (_, Unknown) => Unknown case (_, Unknown) => Unknown
case (Simple | Cores, Sat) => Sat case (Simple | Cores, Sat) => Sat
case (Model | All , s @ SatWithModel(_)) => s case (Model | All , s @ SatWithModel(_)) => s
case (Simple | Model, Unsat) => Unsat case (Simple | Model, Unsat) => Unsat
......
/* Copyright 2009-2016 EPFL, Lausanne */ /* Copyright 2009-2016 EPFL, Lausanne */
package leon package inox
package solvers package solvers
package combinators package combinators
import purescala.Expressions._ import inox.solvers.SolverResponses._
import verification.VC
import utils.Interruptible
import scala.concurrent._ import scala.concurrent._
import scala.concurrent.duration._ import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import ExecutionContext.Implicits.global trait PortfolioSolver extends Solver { self =>
import program._
import trees._
class PortfolioSolver[S <: Solver with Interruptible](val sctx: SolverContext, val solvers: Seq[S]) final type SubSolver = Solver { val program: self.program.type }
extends Solver with NaiveAssumptionSolver {
val solvers: Seq[SubSolver]
val name = "Pfolio" val name = "Pfolio"
protected var model = Model.empty
protected var resultSolver: Option[Solver] = None protected var resultSolver: Option[Solver] = None
override def getResultSolver = resultSolver override def getResultSolver = resultSolver
...@@ -27,40 +27,29 @@ class PortfolioSolver[S <: Solver with Interruptible](val sctx: SolverContext, v ...@@ -27,40 +27,29 @@ class PortfolioSolver[S <: Solver with Interruptible](val sctx: SolverContext, v
solvers.foreach(_.assertCnstr(expression)) solvers.foreach(_.assertCnstr(expression))
} }
override def assertVC(vc: VC): Unit = {
solvers.foreach(_.assertVC(vc))
}
override def dbg(msg: => Any) = solvers foreach (_.dbg(msg)) override def dbg(msg: => Any) = solvers foreach (_.dbg(msg))
def check: Option[Boolean] = {
model = Model.empty
private def genericCheck(config: Configuration)(f: SubSolver => config.Response[Model, Cores]): config.Response[Model, Cores] = {
reporter.debug("Running portfolio check") reporter.debug("Running portfolio check")
// solving // solving
val fs = solvers.map { s => val fs: Seq[Future[(SubSolver, config.Response[Model, Cores])]] = solvers.map { s =>
Future { Future {
try { try {
val result = s.check val result = f(s)
val model: Model = if (result == Some(true)) { (s, result)
s.getModel
} else {
Model.empty
}
(s, result, model)
} catch { } catch {
case _: StackOverflowError => case _: StackOverflowError =>
reporter.warning("Stack Overflow while running solver.check()!") reporter.warning("Stack Overflow while running solver.check()!")
(s, None, Model.empty) (s, config.cast(Unknown))
} }
} }
} }
val result = Future.find(fs)(_._2.isDefined) val result = Future.find(fs)(_._2 != Unknown)
val res = Await.result(result, Duration.Inf) match { val res = Await.result(result, Duration.Inf) match {
case Some((s, r, m)) => case Some((s, r)) =>
model = m
resultSolver = s.getResultSolver resultSolver = s.getResultSolver
resultSolver.foreach { solv => resultSolver.foreach { solv =>
reporter.debug("Solved with "+solv) reporter.debug("Solved with "+solv)
...@@ -70,13 +59,24 @@ class PortfolioSolver[S <: Solver with Interruptible](val sctx: SolverContext, v ...@@ -70,13 +59,24 @@ class PortfolioSolver[S <: Solver with Interruptible](val sctx: SolverContext, v
case None => case None =>
reporter.debug("No solver succeeded") reporter.debug("No solver succeeded")
//fs.foreach(f => println(f.value)) //fs.foreach(f => println(f.value))
None config.cast(Unknown)
} }
fs foreach { Await.ready(_, Duration.Inf) } // TODO: Decide if we really want to wait for all the solvers.
// I understand we interrupt them, but what if one gets stuck
// fs foreach { Await.ready(_, Duration.Inf) }
res res
} }
def check(config: Configuration): config.Response[Model, Cores] = {
genericCheck(config)(subSolver => subSolver.check(config))
}
def checkAssumptions(config: Configuration)(assumptions: Set[Trees]): config.Response[Model, Cores] = {
genericCheck(config)(subSolver => subSolver.checkAssumptions(config)(assumptions))
}
def push(): Unit = { def push(): Unit = {
solvers.foreach(_.push()) solvers.foreach(_.push())
} }
...@@ -86,12 +86,7 @@ class PortfolioSolver[S <: Solver with Interruptible](val sctx: SolverContext, v ...@@ -86,12 +86,7 @@ class PortfolioSolver[S <: Solver with Interruptible](val sctx: SolverContext, v
} }
def free() = { def free() = {
solvers.foreach(_.free) solvers.foreach(_.free())
model = Model.empty
}
def getModel: Model = {
model
} }
def interrupt(): Unit = { def interrupt(): Unit = {
...@@ -103,7 +98,6 @@ class PortfolioSolver[S <: Solver with Interruptible](val sctx: SolverContext, v ...@@ -103,7 +98,6 @@ class PortfolioSolver[S <: Solver with Interruptible](val sctx: SolverContext, v
} }
def reset() = { def reset() = {
solvers.foreach(_.reset) solvers.foreach(_.reset())
model = Model.empty
} }
} }
/* Copyright 2009-2016 EPFL, Lausanne */ /* Copyright 2009-2016 EPFL, Lausanne */
package leon package inox
package solvers package solvers
package combinators package combinators
import scala.reflect.runtime.universe._ import scala.reflect.runtime.universe._
class PortfolioSolverFactory[S <: Solver](ctx: SolverContext, sfs: Seq[SolverFactory[S]]) trait PortfolioSolverFactory extends SolverFactory { self =>
extends SolverFactory[PortfolioSolver[S] with TimeoutSolver] {
def getNewSolver(): PortfolioSolver[S] with TimeoutSolver = { final type PT = program.type
new PortfolioSolver[S](ctx, sfs.map(_.getNewSolver())) with TimeoutSolver override type S = PortfolioSolver { val program: PT }
} final type SF = SolverFactory { val program: PT }
val sfs: Seq[SF]
override def reclaim(s: Solver) = s match { def getNewSolver(): S = {
case ps: PortfolioSolver[_] => new PortfolioSolver {
sfs.zip(ps.solvers).foreach { case (sf, s) => val program: PT = self.program
sf.reclaim(s) val solvers = sfs map (_.getNewSolver())
} val options: SolverOptions = solvers.head.options
}
}
case _ => override def reclaim(s: S) = sfs.zip(s.solvers).foreach { case (sf, s) =>
ctx.context.reporter.error("Failed to reclaim a non-portfolio solver.") sf.reclaim(s)
} }
val name = sfs.map(_.name).mkString("Pfolio(", ",", ")") val name = sfs.map(_.name).mkString("Pfolio(", ",", ")")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment