diff --git a/src/main/scala/leon/codegen/runtime/ChooseEntryPoint.scala b/src/main/scala/leon/codegen/runtime/ChooseEntryPoint.scala index 2a99f01315dd26ea4053954bb551852175f0a7ac..e8b38e5ba82f81fa9d5d174b9dbf43650cbcf54e 100644 --- a/src/main/scala/leon/codegen/runtime/ChooseEntryPoint.scala +++ b/src/main/scala/leon/codegen/runtime/ChooseEntryPoint.scala @@ -79,8 +79,8 @@ object ChooseEntryPoint { } else { val tStart = System.currentTimeMillis - val solverf = SolverFactory.default(ctx, program).withTimeout(10.second) - val solver = solverf.getNewSolver() + val solverf = SolverFactory.default(ctx, program) + val solver = solverf.getNewSolver().setTimeout(10.seconds) val inputsMap = (p.as zip inputs).map { case (id, v) => @@ -113,7 +113,7 @@ object ChooseEntryPoint { throw new LeonCodeGenRuntimeException("Timeout exceeded") } } finally { - solver.free() + solverf.reclaim(solver) solverf.shutdown() } } diff --git a/src/main/scala/leon/evaluators/RecursiveEvaluator.scala b/src/main/scala/leon/evaluators/RecursiveEvaluator.scala index 95a0c0195ecc96bd8e1204228fe2442f7be6bfe4..1eb6398ea0687b5b58dd78fc22ad83bae803d846 100644 --- a/src/main/scala/leon/evaluators/RecursiveEvaluator.scala +++ b/src/main/scala/leon/evaluators/RecursiveEvaluator.scala @@ -587,7 +587,7 @@ abstract class RecursiveEvaluator(ctx: LeonContext, prog: Program, maxSteps: Int throw RuntimeError("Timeout exceeded") } } finally { - solver.free() + solverf.reclaim(solver) solverf.shutdown() } }) diff --git a/src/main/scala/leon/repair/rules/Verify.scala b/src/main/scala/leon/repair/rules/Verify.scala index b3590729e00d4ffa019108bc56a16ca326153c9c..e9bb92bc320fbc0a0860c9b088abe1a77ab276b0 100644 --- a/src/main/scala/leon/repair/rules/Verify.scala +++ b/src/main/scala/leon/repair/rules/Verify.scala @@ -38,34 +38,34 @@ case object Verify extends NormalizingRule("Verify") { val vc = simp(and(p.pc, letTuple(p.xs, e, not(p.phi)))) - val solver = hctx.sctx.newSolver.setTimeout(2000L) - - solver.assertCnstr(vc) - val osol = solver.check match { - case Some(false) => - Some(Solution(BooleanLiteral(true), Set(), e, true)) - - case None => - hctx.reporter.ifDebug { printer => - printer(vc) - printer("== Unknown ==") - } - //None - //Some(Solution(BooleanLiteral(true), Set(), wrappedE, false)) - None - - case _ => - hctx.reporter.ifDebug { printer => - printer(vc) - printer("== Invalid! ==") + val solverf = hctx.sctx.solverFactory + val solver = solverf.getNewSolver.setTimeout(2000L) + try { + solver.assertCnstr(vc) + + solver.check match { + case Some(false) => + Some(solve(Solution(BooleanLiteral(true), Set(), e, true))) + + case None => + hctx.reporter.ifDebug { printer => + printer(vc) + printer("== Unknown ==") + } + //None + //Some(Solution(BooleanLiteral(true), Set(), wrappedE, false)) + None + + case _ => + hctx.reporter.ifDebug { printer => + printer(vc) + printer("== Invalid! ==") + } + None } - None - } - - solver.free - - osol.map { solve } - + } finally { + solverf.reclaim(solver) + } } alts diff --git a/src/main/scala/leon/solvers/CantResetException.scala b/src/main/scala/leon/solvers/CantResetException.scala new file mode 100644 index 0000000000000000000000000000000000000000..51646c8fe1ed92a171269a02fc299f03e715c9e1 --- /dev/null +++ b/src/main/scala/leon/solvers/CantResetException.scala @@ -0,0 +1,3 @@ +package leon.solvers + +class CantResetException(s: Solver) extends Exception(s"Unable to reset solver $s") diff --git a/src/main/scala/leon/solvers/EnumerationSolver.scala b/src/main/scala/leon/solvers/EnumerationSolver.scala index d432aaddc830518da7c6bc5f72babfeee3ba6e64..5b14c05da378511c4437a498d6b477578f4fc101 100644 --- a/src/main/scala/leon/solvers/EnumerationSolver.scala +++ b/src/main/scala/leon/solvers/EnumerationSolver.scala @@ -33,15 +33,22 @@ class EnumerationSolver(val context: LeonContext, val program: Program) extends } def push() = { - freeVars = Nil :: freeVars + freeVars = Nil :: freeVars constraints = Nil :: constraints } def pop(lvl: Int) = { - freeVars = freeVars.drop(lvl) + freeVars = freeVars.drop(lvl) constraints = constraints.drop(lvl) } + def reset() = { + freeVars = List(Nil) + constraints = List(Nil) + interrupted = false + datagen = None + } + private var modelMap = Map[Identifier, Expr]() def check: Option[Boolean] = { diff --git a/src/main/scala/leon/solvers/GroundSolver.scala b/src/main/scala/leon/solvers/GroundSolver.scala index 5cdaa5e42cbb219a60b1c7907589556d4982962c..443706fdf1d9ccaf7e86820bd4453f1543b0de66 100644 --- a/src/main/scala/leon/solvers/GroundSolver.scala +++ b/src/main/scala/leon/solvers/GroundSolver.scala @@ -51,6 +51,10 @@ class GroundSolver(val context: LeonContext, val program: Program) extends Solve def free(): Unit = assertions = Nil + def reset() = { + assertions = Nil + } + def interrupt(): Unit = {} def recoverInterrupt(): Unit = {} diff --git a/src/main/scala/leon/solvers/ResettableSolver.scala b/src/main/scala/leon/solvers/ResettableSolver.scala new file mode 100644 index 0000000000000000000000000000000000000000..ca5eba931d3a99e63ac9d8a8d4057dec99041e07 --- /dev/null +++ b/src/main/scala/leon/solvers/ResettableSolver.scala @@ -0,0 +1,10 @@ +/* Copyright 2009-2015 EPFL, Lausanne */ + +package leon +package solvers + +import purescala.Expressions.Expr + +trait ResettableSolver extends Solver { + def reset() +} diff --git a/src/main/scala/leon/solvers/SimpleAssumptionSolverAPI.scala b/src/main/scala/leon/solvers/SimpleAssumptionSolverAPI.scala index cc382dd41cf0fdb74b3c077914528c40ff161c89..eb92c529cecb1e2ddef88e188ad8de8767efcea8 100644 --- a/src/main/scala/leon/solvers/SimpleAssumptionSolverAPI.scala +++ b/src/main/scala/leon/solvers/SimpleAssumptionSolverAPI.scala @@ -21,7 +21,7 @@ class SimpleAssumptionSolverAPI(sf: SolverFactory[AssumptionSolver]) extends Sim (None, Map(), Set()) } } finally { - s.free() + sf.reclaim(s) } } } diff --git a/src/main/scala/leon/solvers/SimpleSolverAPI.scala b/src/main/scala/leon/solvers/SimpleSolverAPI.scala index 9e92f37753d9f46e207e34bbc5630930fe1bda7d..907f903dfb13207c0568a3d8727fb78d1cc6cc36 100644 --- a/src/main/scala/leon/solvers/SimpleSolverAPI.scala +++ b/src/main/scala/leon/solvers/SimpleSolverAPI.scala @@ -13,7 +13,7 @@ class SimpleSolverAPI(sf: SolverFactory[Solver]) { s.assertCnstr(Not(expression)) s.check.map(r => !r) } finally { - s.free() + sf.reclaim(s) } } @@ -30,7 +30,7 @@ class SimpleSolverAPI(sf: SolverFactory[Solver]) { (None, Map()) } } finally { - s.free() + sf.reclaim(s) } } } diff --git a/src/main/scala/leon/solvers/Solver.scala b/src/main/scala/leon/solvers/Solver.scala index 69eef744946d8ca3435feb2e315bde2dc135d5b3..54879dcc4b6862bf5c44456d308e89f680a6ccdf 100644 --- a/src/main/scala/leon/solvers/Solver.scala +++ b/src/main/scala/leon/solvers/Solver.scala @@ -25,6 +25,8 @@ trait Solver { def free() + def reset() + implicit val debugSection = DebugSectionSolver private[solvers] def debugS(msg: String) = { diff --git a/src/main/scala/leon/solvers/SolverFactory.scala b/src/main/scala/leon/solvers/SolverFactory.scala index 64cf6e3d771c5f323cd00e14e76844a8ced1bdde..a43dc966456363f50f2b7c9c4b1d74bbbca8f738 100644 --- a/src/main/scala/leon/solvers/SolverFactory.scala +++ b/src/main/scala/leon/solvers/SolverFactory.scala @@ -14,12 +14,13 @@ import _root_.smtlib.interpreters._ abstract class SolverFactory[+S <: Solver : TypeTag] { def getNewSolver(): S - def init(): Unit = {} def shutdown(): Unit = {} - val name = typeOf[S].toString.split("\\.").last.replaceAll("Solver", "")+"*" + def reclaim(s: Solver) { + s.free() + } - init() + val name = typeOf[S].toString.split("\\.").last.replaceAll("Solver", "")+"*" } object SolverFactory { @@ -118,7 +119,7 @@ object SolverFactory { } else if (selectedSolvers.size == 1) { selectedSolvers.head } else { - SolverFactory( () => new PortfolioSolver(ctx, selectedSolvers.toSeq) with TimeoutSolver) + new PortfolioSolverFactory(ctx, selectedSolvers.toSeq) } } diff --git a/src/main/scala/leon/solvers/TimeoutSolver.scala b/src/main/scala/leon/solvers/TimeoutSolver.scala index 1ff88c1d68f0786fd55b9a7e16360713341e60e8..a7c27f1a0773f40ac9be42a28cfa11811baee894 100644 --- a/src/main/scala/leon/solvers/TimeoutSolver.scala +++ b/src/main/scala/leon/solvers/TimeoutSolver.scala @@ -5,6 +5,8 @@ package solvers import utils._ +import scala.concurrent.duration._ + trait TimeoutSolver extends Solver with Interruptible { val ti = new TimeoutFor(this) @@ -16,6 +18,11 @@ trait TimeoutSolver extends Solver with Interruptible { this } + def setTimeout(timeout: Duration): this.type = { + optTimeout = Some(timeout.toMillis) + this + } + abstract override def check: Option[Boolean] = { optTimeout match { case Some(to) => diff --git a/src/main/scala/leon/solvers/TimeoutSolverFactory.scala b/src/main/scala/leon/solvers/TimeoutSolverFactory.scala index 587b1d744edadc167ad707cf518c74e77aa478de..b5a042147d256bd60be6f947fd62c93aaf1e0974 100644 --- a/src/main/scala/leon/solvers/TimeoutSolverFactory.scala +++ b/src/main/scala/leon/solvers/TimeoutSolverFactory.scala @@ -5,12 +5,13 @@ package solvers import scala.reflect.runtime.universe._ -class TimeoutSolverFactory[+S <: TimeoutSolver : TypeTag](sf: SolverFactory[S], to: Long) extends SolverFactory[S] { +class TimeoutSolverFactory[+S <: TimeoutSolver : TypeTag](val sf: SolverFactory[S], to: Long) extends SolverFactory[S] { override def getNewSolver() = sf.getNewSolver().setTimeout(to) - override val name = "SFact("+typeOf[S].toString+") with t.o" + override val name = sf.name+" with t.o" + + override def reclaim(s: Solver) = sf.reclaim(s) - override def init() = sf.init() override def shutdown() = sf.shutdown() } diff --git a/src/main/scala/leon/solvers/combinators/DNFSolver.scala b/src/main/scala/leon/solvers/combinators/DNFSolver.scala index 9f9bd8ed096701d042400faaa1671ecd65e6eedb..ad48ca2cd27604f3106698454febbc5cc1c6faa7 100644 --- a/src/main/scala/leon/solvers/combinators/DNFSolver.scala +++ b/src/main/scala/leon/solvers/combinators/DNFSolver.scala @@ -26,6 +26,10 @@ class DNFSolver(val context: LeonContext, theConstraint = Some(expression) } + def reset() = { + throw new CantResetException(this) + } + def check : Option[Boolean] = theConstraint.map { expr => val simpleSolver = SimpleSolverAPI(underlyings) diff --git a/src/main/scala/leon/solvers/combinators/PortfolioSolver.scala b/src/main/scala/leon/solvers/combinators/PortfolioSolver.scala index 1f990a0c5336193643460d840f42217f397adc88..ea8331a4adb516ba93b839eb3c13c84141e3e328 100644 --- a/src/main/scala/leon/solvers/combinators/PortfolioSolver.scala +++ b/src/main/scala/leon/solvers/combinators/PortfolioSolver.scala @@ -14,7 +14,7 @@ import scala.concurrent.duration._ import ExecutionContext.Implicits.global -class PortfolioSolver[S <: Solver with Interruptible](val context: LeonContext, val solvers: Seq[SolverFactory[S]]) +class PortfolioSolver[S <: Solver with Interruptible](val context: LeonContext, val solvers: Seq[S]) extends Solver with Interruptible { val name = "Pfolio" @@ -22,17 +22,16 @@ class PortfolioSolver[S <: Solver with Interruptible](val context: LeonContext, var constraints = List[Expr]() protected var modelMap = Map[Identifier, Expr]() - protected var solversInsts: Seq[S] = solvers.map(_.getNewSolver()) protected var resultSolver: Option[Solver] = None override def getResultSolver = resultSolver def assertCnstr(expression: Expr): Unit = { - solversInsts.foreach(_.assertCnstr(expression)) + solvers.foreach(_.assertCnstr(expression)) } override def assertVC(vc: VC): Unit = { - solversInsts.foreach(_.assertVC(vc)) + solvers.foreach(_.assertVC(vc)) } def check: Option[Boolean] = { @@ -40,7 +39,7 @@ class PortfolioSolver[S <: Solver with Interruptible](val context: LeonContext, context.reporter.debug("Running portfolio check") // solving - val fs = solversInsts.map { s => + val fs = solvers.map { s => Future { val result = s.check val model: Map[Identifier, Expr] = if (result == Some(true)) { @@ -61,7 +60,7 @@ class PortfolioSolver[S <: Solver with Interruptible](val context: LeonContext, resultSolver.foreach { solv => context.reporter.debug("Solved with "+solv) } - solversInsts.foreach(_.interrupt()) + solvers.foreach(_.interrupt()) r case None => None @@ -72,8 +71,7 @@ class PortfolioSolver[S <: Solver with Interruptible](val context: LeonContext, } def free() = { - solversInsts.foreach(_.free) - solversInsts = Nil + solvers.foreach(_.free) modelMap = Map() constraints = Nil } @@ -83,10 +81,16 @@ class PortfolioSolver[S <: Solver with Interruptible](val context: LeonContext, } def interrupt(): Unit = { - solversInsts.foreach(_.interrupt()) + solvers.foreach(_.interrupt()) } def recoverInterrupt(): Unit = { - solversInsts.foreach(_.recoverInterrupt()) + solvers.foreach(_.recoverInterrupt()) + } + + def reset() = { + solvers.foreach(_.reset) + modelMap = Map() + constraints = Nil } } diff --git a/src/main/scala/leon/solvers/combinators/PortfolioSolverFactory.scala b/src/main/scala/leon/solvers/combinators/PortfolioSolverFactory.scala new file mode 100644 index 0000000000000000000000000000000000000000..85c862d297cd2df87d85ec64774a81cecc791df4 --- /dev/null +++ b/src/main/scala/leon/solvers/combinators/PortfolioSolverFactory.scala @@ -0,0 +1,27 @@ +/* Copyright 2009-2015 EPFL, Lausanne */ + +package leon +package solvers +package combinators + +import utils.Interruptible +import scala.collection.mutable.Queue +import scala.reflect.runtime.universe._ + +class PortfolioSolverFactory[S <: Solver with Interruptible](ctx: LeonContext, sfs: Seq[SolverFactory[S]])(implicit tag: TypeTag[S]) extends SolverFactory[PortfolioSolver[S] with TimeoutSolver] { + + def getNewSolver(): PortfolioSolver[S] with TimeoutSolver = { + new PortfolioSolver[S](ctx, sfs.map(_.getNewSolver())) with TimeoutSolver + } + + override def reclaim(s: Solver) = s match { + case ps: PortfolioSolver[_] => + sfs.zip(ps.solvers).foreach { case (sf, s) => + sf.reclaim(s) + } + + case _ => + ctx.reporter.error("Failed to reclaim a non-portfolio solver.") + } +} + diff --git a/src/main/scala/leon/solvers/combinators/SolverPool.scala b/src/main/scala/leon/solvers/combinators/SolverPool.scala new file mode 100644 index 0000000000000000000000000000000000000000..296e6b7131830535401aeaa6618c64e3acf4f6b4 --- /dev/null +++ b/src/main/scala/leon/solvers/combinators/SolverPool.scala @@ -0,0 +1,73 @@ +/* Copyright 2009-2015 EPFL, Lausanne */ + +package leon +package solvers +package combinators + +import scala.collection.mutable.Queue +import scala.reflect.runtime.universe._ + +/** + * This is a straitforward implementation of solver pools. The goal is to avoid + * the cost of spawing processes for SMT solvers. + * + * Sadly smt-z3 is the only SMT solver that supports reset. + * + * If necessary, we may want to implement async reclaim/reset, + * growing/shrinking pool size... + */ + +class SolverPoolFactory[+S <: Solver](ctx: LeonContext, sf: SolverFactory[S])(implicit tag: TypeTag[S]) extends SolverFactory[S] { + + var poolSize = 0 + val poolMaxSize = 5 + + private[this] val availables = Queue[S]() + private[this] var inUse = Set[Solver]() + + def getNewSolver(): S = { + if (availables.isEmpty) { + poolSize += 1 + availables += sf.getNewSolver() + } + + val s = availables.dequeue() + inUse += s + s + } + + override def reclaim(s: Solver) = { + try { + s.reset() + inUse -= s + s.reset() + availables += s.asInstanceOf[S] + } catch { + case _: CantResetException => + inUse -= s + s.free() + sf.reclaim(s) + availables += sf.getNewSolver() + } + } + + def init(): Unit = { + for (i <- 1 to poolMaxSize) { + availables += sf.getNewSolver() + } + + poolSize = poolMaxSize + } + + override def shutdown(): Unit = { + for (s <- availables ++ inUse) { + sf.reclaim(s) + } + + availables.clear() + + inUse = Set() + } + + init() +} diff --git a/src/main/scala/leon/solvers/combinators/UnrollingSolver.scala b/src/main/scala/leon/solvers/combinators/UnrollingSolver.scala index 7ab3180384b8b997e08e2ece3da1a36cc1fd5248..b93e6826a652fdddaeaaca3740f50e3a00efe900 100644 --- a/src/main/scala/leon/solvers/combinators/UnrollingSolver.scala +++ b/src/main/scala/leon/solvers/combinators/UnrollingSolver.scala @@ -29,12 +29,12 @@ class UnrollingSolver(val context: LeonContext, program: Program, underlying: In } } - private var lastCheckResult : (Boolean, Option[Boolean], Option[Map[Identifier,Expr]]) = (false, None, None) + protected var lastCheckResult : (Boolean, Option[Boolean], Option[Map[Identifier,Expr]]) = (false, None, None) - private var varsInVC = List[Set[Identifier]](Set()) - private var frameExpressions = List[List[Expr]](Nil) + protected var varsInVC = List[Set[Identifier]](Set()) + protected var frameExpressions = List[List[Expr]](Nil) - private var interrupted : Boolean = false + protected var interrupted : Boolean = false val reporter = context.reporter @@ -250,6 +250,14 @@ class UnrollingSolver(val context: LeonContext, program: Program, underlying: In } } + override def reset() = { + underlying.reset() + lastCheckResult = (false, None, None) + varsInVC = List(Set()) + frameExpressions = List(Nil) + interrupted = false + } + override def interrupt(): Unit = { interrupted = true solver.interrupt() diff --git a/src/main/scala/leon/solvers/package.scala b/src/main/scala/leon/solvers/package.scala index e796cf4d1f6099e2c5270801bdd7d5a8a1086556..e08e536da7f534383fa674ac04107b46d086b94c 100644 --- a/src/main/scala/leon/solvers/package.scala +++ b/src/main/scala/leon/solvers/package.scala @@ -6,13 +6,18 @@ import scala.reflect.runtime.universe._ import scala.concurrent.duration._ package object solvers { - implicit class TimeoutableSolverFactory[+S <: TimeoutSolver : TypeTag](sf: SolverFactory[S]) { - def withTimeout(to: Long) = { - new TimeoutSolverFactory[S](sf, to) + implicit class TimeoutableSolverFactory[+S <: TimeoutSolver : TypeTag](val sf: SolverFactory[S]) { + def withTimeout(to: Long): TimeoutSolverFactory[S] = { + sf match { + case tsf: TimeoutSolverFactory[_] => + new TimeoutSolverFactory[S](tsf.sf, to) + case _ => + new TimeoutSolverFactory[S](sf, to) + } } - def withTimeout(du: Duration) = { - new TimeoutSolverFactory[S](sf, du.toMillis) + def withTimeout(du: Duration): TimeoutSolverFactory[S] = { + withTimeout(du.toMillis) } } } diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4QuantifiedSolver.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4QuantifiedSolver.scala index fd9085a95c2a20bfaacbd5ea180162bff5244410..df167148eebd13b05a4fd69267506a49071aa823 100644 --- a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4QuantifiedSolver.scala +++ b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4QuantifiedSolver.scala @@ -107,7 +107,7 @@ abstract class SMTLIBCVC4QuantifiedSolver(context: LeonContext, program: Program } } - parameterlessAssertions foreach sendCommand + parameterlessAssertions.foreach(a => sendCommand(a)) functions.toB(tfd) } diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBSolver.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBSolver.scala index e9faa425c32880c2b312db677eb5846a7eb82ed9..478c17d5d2af82ad178a65a81fb2bac2aaf6443e 100644 --- a/src/main/scala/leon/solvers/smtlib/SMTLIBSolver.scala +++ b/src/main/scala/leon/solvers/smtlib/SMTLIBSolver.scala @@ -31,7 +31,7 @@ import _root_.smtlib.{Interpreter => SMTInterpreter} abstract class SMTLIBSolver(val context: LeonContext, val program: Program) - extends IncrementalSolver with Interruptible { + extends IncrementalSolver with ResettableSolver with Interruptible { /* Solver name */ @@ -686,14 +686,14 @@ abstract class SMTLIBSolver(val context: LeonContext, /* Send a command to the solver */ - def sendCommand(cmd: Command): CommandResponse = { + def sendCommand(cmd: Command, rawOut: Boolean = false): CommandResponse = { out foreach { o => SMTPrinter.printCommand(cmd, o) o.write("\n") o.flush() } interpreter.eval(cmd) match { - case err@ErrorResponse(msg) if !hasError && !interrupted => + case err@ErrorResponse(msg) if !hasError && !interrupted && !rawOut => reporter.warning(s"Unexpected error from $name solver: $msg") // Store that there was an error. Now all following check() // invocations will return None @@ -725,6 +725,15 @@ abstract class SMTLIBSolver(val context: LeonContext, } } + override def reset() = { + sendCommand(Reset(), rawOut = true) match { + case ErrorResponse(msg) => + reporter.warning(s"Failed to reset $name: $msg") + throw new CantResetException(this) + case _ => + } + } + override def check: Option[Boolean] = { if (hasError) None else sendCommand(CheckSat()) match { diff --git a/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala b/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala index 1b33ca60db3dcc1f2baa1c340218361aea409895..d24b8847308fd87da221111d6bdd41b11f244e0b 100644 --- a/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala +++ b/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala @@ -810,4 +810,8 @@ trait AbstractZ3Solver z3.mkFreshConst(id.uniqueName, typeToSort(id.getType)) } + def reset() = { + throw new CantResetException(this) + } + } diff --git a/src/main/scala/leon/synthesis/SynthesisContext.scala b/src/main/scala/leon/synthesis/SynthesisContext.scala index 77de6d641e1bd6177cb755177805e64084e621cd..bb90d2a268411c44e9dfdbde013886b7db5b56d9 100644 --- a/src/main/scala/leon/synthesis/SynthesisContext.scala +++ b/src/main/scala/leon/synthesis/SynthesisContext.scala @@ -4,7 +4,7 @@ package leon package synthesis import solvers._ -import solvers.z3._ +import solvers.combinators._ import purescala.Definitions.{Program, FunDef} /** @@ -22,16 +22,6 @@ case class SynthesisContext( val rules = settings.rules val solverFactory = SolverFactory.getFromSettings(context, program) - - def newSolver = { - solverFactory.getNewSolver() - } - - val fastSolverFactory = SolverFactory.uninterpreted(context, program) - - def newFastSolver = { - fastSolverFactory.getNewSolver() - } } object SynthesisContext { diff --git a/src/main/scala/leon/synthesis/Synthesizer.scala b/src/main/scala/leon/synthesis/Synthesizer.scala index 2d2590da0b26f3fe324fe1fe1a537215245b646c..9659f2b7704520ef871211aa969d24d01fa0ece3 100644 --- a/src/main/scala/leon/synthesis/Synthesizer.scala +++ b/src/main/scala/leon/synthesis/Synthesizer.scala @@ -112,7 +112,6 @@ class Synthesizer(val context : LeonContext, def shutdown(): Unit = { sctx.solverFactory.shutdown() - sctx.fastSolverFactory.shutdown() } } diff --git a/src/main/scala/leon/synthesis/rules/CEGISLike.scala b/src/main/scala/leon/synthesis/rules/CEGISLike.scala index 52f104bae48d0870a24541a8266cdec2ea8d1cb5..c78750adc05e98162f60d6609304a76b66bf16b5 100644 --- a/src/main/scala/leon/synthesis/rules/CEGISLike.scala +++ b/src/main/scala/leon/synthesis/rules/CEGISLike.scala @@ -502,7 +502,7 @@ abstract class CEGISLike[T <% Typed](name: String) extends Rule(name) { } } } finally { - solver.free() + solverf.reclaim(solver) solverf.shutdown() cTreeFd.fullBody = origImpl } @@ -598,7 +598,7 @@ abstract class CEGISLike[T <% Typed](name: String) extends Rule(name) { Some(None) } } finally { - solver.free() + solverf.reclaim(solver) solverf.shutdown() } } @@ -631,14 +631,10 @@ abstract class CEGISLike[T <% Typed](name: String) extends Rule(name) { None } } finally { - solver.free() + solverf.reclaim(solver) solverf.shutdown() } } - - def free(): Unit = { - - } } List(new RuleInstantiation(this.name) { @@ -668,7 +664,8 @@ abstract class CEGISLike[T <% Typed](name: String) extends Rule(name) { if (p.pc == BooleanLiteral(true)) { baseExampleInputs += InExample(p.as.map(a => simplestValue(a.getType))) } else { - val solver = sctx.newSolver.setTimeout(exSolverTo) + val solverf = sctx.solverFactory + val solver = solverf.getNewSolver.setTimeout(exSolverTo) solver.assertCnstr(p.pc) @@ -687,7 +684,7 @@ abstract class CEGISLike[T <% Typed](name: String) extends Rule(name) { return RuleFailed() // This is not necessary though, but probably wanted } } finally { - solver.free() + solverf.reclaim(solver) } } @@ -913,8 +910,6 @@ abstract class CEGISLike[T <% Typed](name: String) extends Rule(name) { sctx.reporter.warning("CEGIS crashed: "+e.getMessage) e.printStackTrace() RuleFailed() - } finally { - ndProgram.free() } } }) diff --git a/src/main/scala/leon/synthesis/rules/EqualitySplit.scala b/src/main/scala/leon/synthesis/rules/EqualitySplit.scala index b1653596a1a9cdd8ec082e40b1962b6fe2c2c0ec..bc62dbba88c8b7dea8b6aaefc5879dfc3909774f 100644 --- a/src/main/scala/leon/synthesis/rules/EqualitySplit.scala +++ b/src/main/scala/leon/synthesis/rules/EqualitySplit.scala @@ -10,9 +10,11 @@ import purescala.Constructors._ import solvers._ +import scala.concurrent.duration._ + case object EqualitySplit extends Rule("Eq. Split") { def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = { - val solver = SimpleSolverAPI(hctx.sctx.fastSolverFactory) + val solver = SimpleSolverAPI(hctx.sctx.solverFactory.withTimeout(50.millis)) val candidates = p.as.groupBy(_.getType).mapValues(_.combinations(2).filter { case List(a1, a2) => diff --git a/src/main/scala/leon/synthesis/rules/InequalitySplit.scala b/src/main/scala/leon/synthesis/rules/InequalitySplit.scala index 8cc0f2f314cf82ae33d7ba29d7241578cffb31f8..292e99de80d4cf7eb3351621edde3587645b0402 100644 --- a/src/main/scala/leon/synthesis/rules/InequalitySplit.scala +++ b/src/main/scala/leon/synthesis/rules/InequalitySplit.scala @@ -10,9 +10,11 @@ import purescala.Constructors._ import solvers._ +import scala.concurrent.duration._ + case object InequalitySplit extends Rule("Ineq. Split.") { def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = { - val solver = SimpleSolverAPI(hctx.sctx.fastSolverFactory) + val solver = SimpleSolverAPI(hctx.sctx.solverFactory.withTimeout(50.millis)) val argsPairs = p.as.filter(_.getType == IntegerType).combinations(2) ++ p.as.filter(_.getType == Int32Type).combinations(2) diff --git a/src/main/scala/leon/synthesis/rules/OptimisticGround.scala b/src/main/scala/leon/synthesis/rules/OptimisticGround.scala index 423206003a73629cbbdc94e1a4fb66efccc6739f..6085ef9eb2067fa092ffacfdefbf27532b02b5d9 100644 --- a/src/main/scala/leon/synthesis/rules/OptimisticGround.scala +++ b/src/main/scala/leon/synthesis/rules/OptimisticGround.scala @@ -10,13 +10,15 @@ import purescala.Constructors._ import solvers._ +import scala.concurrent.duration._ + case object OptimisticGround extends Rule("Optimistic Ground") { def instantiateOn(implicit hctx: SearchContext, p: Problem): Traversable[RuleInstantiation] = { if (p.as.nonEmpty && p.xs.nonEmpty) { val res = new RuleInstantiation(this.name) { def apply(hctx: SearchContext) = { - val solver = SimpleSolverAPI(hctx.sctx.fastSolverFactory) // Optimistic ground is given a simple solver (uninterpreted) + val solver = SimpleSolverAPI(hctx.sctx.solverFactory.withTimeout(50.millis)) val xss = p.xs.toSet val ass = p.as.toSet