From 0d8569f0baa35f68520abdf9c00aff16bd3ccd2f Mon Sep 17 00:00:00 2001 From: Etienne Kneuss <colder@php.net> Date: Mon, 14 Jan 2013 19:43:13 +0100 Subject: [PATCH] Use timeouts in all synthesis rules, we don't want it to hang on a difficult problem --- src/main/scala/leon/synthesis/rules/ADTSplit.scala | 6 +++++- src/main/scala/leon/synthesis/rules/Cegis.scala | 3 ++- .../scala/leon/synthesis/rules/EqualitySplit.scala | 7 +++++-- src/main/scala/leon/synthesis/rules/Ground.scala | 5 ++++- .../scala/leon/synthesis/rules/InequalitySplit.scala | 10 +++++++--- .../scala/leon/synthesis/rules/OptimisticGround.scala | 8 ++++++-- 6 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/main/scala/leon/synthesis/rules/ADTSplit.scala b/src/main/scala/leon/synthesis/rules/ADTSplit.scala index 07347e95b..04cd58c5a 100644 --- a/src/main/scala/leon/synthesis/rules/ADTSplit.scala +++ b/src/main/scala/leon/synthesis/rules/ADTSplit.scala @@ -2,6 +2,8 @@ package leon package synthesis package rules +import solvers.TimeoutSolver + import purescala.Trees._ import purescala.Common._ import purescala.TypeTrees._ @@ -11,6 +13,8 @@ import purescala.Definitions._ case object ADTSplit extends Rule("ADT Split.") { def instantiateOn(sctx: SynthesisContext, p: Problem): Traversable[RuleInstantiation]= { + val solver = new TimeoutSolver(sctx.solver, 100L) // We give that 100ms + val candidates = p.as.collect { case IsTyped(id, AbstractClassType(cd)) => @@ -18,7 +22,7 @@ case object ADTSplit extends Rule("ADT Split.") { case ccd : CaseClassDef => val toSat = And(p.pc, Not(CaseClassInstanceOf(ccd, Variable(id)))) - val isImplied = sctx.solver.solveSAT(toSat) match { + val isImplied = solver.solveSAT(toSat) match { case (Some(false), _) => true case _ => false } diff --git a/src/main/scala/leon/synthesis/rules/Cegis.scala b/src/main/scala/leon/synthesis/rules/Cegis.scala index 2cb41ef38..1bdf8d1cf 100644 --- a/src/main/scala/leon/synthesis/rules/Cegis.scala +++ b/src/main/scala/leon/synthesis/rules/Cegis.scala @@ -2,6 +2,7 @@ package leon package synthesis package rules +import solvers.TimeoutSolver import purescala.Trees._ import purescala.Common._ import purescala.Definitions._ @@ -384,7 +385,7 @@ case object CEGIS extends Rule("CEGIS") { var unrolings = 0 val maxUnrolings = 3 - val mainSolver: FairZ3Solver = sctx.solver.asInstanceOf[FairZ3Solver] + val mainSolver = new TimeoutSolver(sctx.solver, 2000L) // 2sec var exampleInputs = Set[Seq[Expr]]() diff --git a/src/main/scala/leon/synthesis/rules/EqualitySplit.scala b/src/main/scala/leon/synthesis/rules/EqualitySplit.scala index 125b2e606..c59d37aa0 100644 --- a/src/main/scala/leon/synthesis/rules/EqualitySplit.scala +++ b/src/main/scala/leon/synthesis/rules/EqualitySplit.scala @@ -2,6 +2,7 @@ package leon package synthesis package rules +import solvers.TimeoutSolver import purescala.Trees._ import purescala.Common._ import purescala.TypeTrees._ @@ -10,11 +11,13 @@ import purescala.Extractors._ case object EqualitySplit extends Rule("Eq. Split.") { def instantiateOn(sctx: SynthesisContext, p: Problem): Traversable[RuleInstantiation] = { + val solver = new TimeoutSolver(sctx.solver, 100L) // We give that 100ms + val candidates = p.as.groupBy(_.getType).mapValues(_.combinations(2).filter { case List(a1, a2) => val toValEQ = Implies(p.pc, Equals(Variable(a1), Variable(a2))) - val impliesEQ = sctx.solver.solveSAT(Not(toValEQ)) match { + val impliesEQ = solver.solveSAT(Not(toValEQ)) match { case (Some(false), _) => true case _ => false } @@ -22,7 +25,7 @@ case object EqualitySplit extends Rule("Eq. Split.") { if (!impliesEQ) { val toValNE = Implies(p.pc, Not(Equals(Variable(a1), Variable(a2)))) - val impliesNE = sctx.solver.solveSAT(Not(toValNE)) match { + val impliesNE = solver.solveSAT(Not(toValNE)) match { case (Some(false), _) => true case _ => false } diff --git a/src/main/scala/leon/synthesis/rules/Ground.scala b/src/main/scala/leon/synthesis/rules/Ground.scala index 953ad5b56..bb74de12a 100644 --- a/src/main/scala/leon/synthesis/rules/Ground.scala +++ b/src/main/scala/leon/synthesis/rules/Ground.scala @@ -2,6 +2,7 @@ package leon package synthesis package rules +import solvers.TimeoutSolver import purescala.Trees._ import purescala.TypeTrees._ import purescala.TreeOps._ @@ -11,9 +12,11 @@ case object Ground extends Rule("Ground") { def instantiateOn(sctx: SynthesisContext, p: Problem): Traversable[RuleInstantiation] = { if (p.as.isEmpty) { + val solver = new TimeoutSolver(sctx.solver, 1000L) // We give that 1s + val tpe = TupleType(p.xs.map(_.getType)) - sctx.solver.solveSAT(p.phi) match { + solver.solveSAT(p.phi) match { case (Some(true), model) => val sol = Solution(BooleanLiteral(true), Set(), Tuple(p.xs.map(valuateWithModel(model))).setType(tpe)) Some(RuleInstantiation.immediateSuccess(p, this, sol)) diff --git a/src/main/scala/leon/synthesis/rules/InequalitySplit.scala b/src/main/scala/leon/synthesis/rules/InequalitySplit.scala index d79bd66f0..11040132b 100644 --- a/src/main/scala/leon/synthesis/rules/InequalitySplit.scala +++ b/src/main/scala/leon/synthesis/rules/InequalitySplit.scala @@ -2,6 +2,8 @@ package leon package synthesis package rules +import solvers.TimeoutSolver + import purescala.Trees._ import purescala.TypeTrees._ import purescala.Common._ @@ -11,11 +13,13 @@ import purescala.Extractors._ case object InequalitySplit extends Rule("Ineq. Split.") { def instantiateOn(sctx: SynthesisContext, p: Problem): Traversable[RuleInstantiation] = { + val solver = new TimeoutSolver(sctx.solver, 100L) // We give that 100ms + val candidates = p.as.filter(_.getType == Int32Type).combinations(2).toList.filter { case List(a1, a2) => val toValLT = Implies(p.pc, LessThan(Variable(a1), Variable(a2))) - val impliesLT = sctx.solver.solveSAT(Not(toValLT)) match { + val impliesLT = solver.solveSAT(Not(toValLT)) match { case (Some(false), _) => true case _ => false } @@ -23,7 +27,7 @@ case object InequalitySplit extends Rule("Ineq. Split.") { if (!impliesLT) { val toValGT = Implies(p.pc, GreaterThan(Variable(a1), Variable(a2))) - val impliesGT = sctx.solver.solveSAT(Not(toValGT)) match { + val impliesGT = solver.solveSAT(Not(toValGT)) match { case (Some(false), _) => true case _ => false } @@ -31,7 +35,7 @@ case object InequalitySplit extends Rule("Ineq. Split.") { if (!impliesGT) { val toValEQ = Implies(p.pc, Equals(Variable(a1), Variable(a2))) - val impliesEQ = sctx.solver.solveSAT(Not(toValEQ)) match { + val impliesEQ = solver.solveSAT(Not(toValEQ)) match { case (Some(false), _) => true case _ => false } diff --git a/src/main/scala/leon/synthesis/rules/OptimisticGround.scala b/src/main/scala/leon/synthesis/rules/OptimisticGround.scala index d25db6600..7e65ed797 100644 --- a/src/main/scala/leon/synthesis/rules/OptimisticGround.scala +++ b/src/main/scala/leon/synthesis/rules/OptimisticGround.scala @@ -2,6 +2,7 @@ package leon package synthesis package rules +import solvers.TimeoutSolver import purescala.Trees._ import purescala.TypeTrees._ import purescala.TreeOps._ @@ -12,6 +13,9 @@ case object OptimisticGround extends Rule("Optimistic Ground") { if (!p.as.isEmpty && !p.xs.isEmpty) { val res = new RuleInstantiation(p, this, SolutionBuilder.none) { def apply(sctx: SynthesisContext) = { + + val solver = new TimeoutSolver(sctx.solver, 100L) // We give that 100ms + val xss = p.xs.toSet val ass = p.as.toSet @@ -27,14 +31,14 @@ case object OptimisticGround extends Rule("Optimistic Ground") { while (result.isEmpty && i < maxTries && continue) { val phi = And(p.pc +: p.phi +: predicates) //println("SOLVING " + phi + " ...") - sctx.solver.solveSAT(phi) match { + solver.solveSAT(phi) match { case (Some(true), satModel) => val satXsModel = satModel.filterKeys(xss) val newPhi = valuateWithModelIn(phi, xss, satModel) //println("REFUTING " + Not(newPhi) + "...") - sctx.solver.solveSAT(Not(newPhi)) match { + solver.solveSAT(Not(newPhi)) match { case (Some(true), invalidModel) => // Found as such as the xs break, refine predicates predicates = valuateWithModelIn(phi, ass, invalidModel) +: predicates -- GitLab