diff --git a/src/main/scala/leon/purescala/DefOps.scala b/src/main/scala/leon/purescala/DefOps.scala index 7f0e5b0180bd9318cb3b8cd109ae1b01d843b9c1..753b0944c62023257398b09305ed85020eae64b2 100644 --- a/src/main/scala/leon/purescala/DefOps.scala +++ b/src/main/scala/leon/purescala/DefOps.scala @@ -357,7 +357,7 @@ object DefOps { }) for (cd <- p.definedClasses if requiresReplacement(cd)) trCd(cd) - for (fd <- p.definedFunctions if requiresReplacement(fd)) { + for (fd <- p.definedFunctions if requiresReplacement(fd) && !(fdMap contains fd)) { val newId = transformer.transform(fd.id) val newReturn = transformer.transform(fd.returnType) val newParams = fd.params map (vd => ValDef(transformer.transform(vd.id))) @@ -372,8 +372,10 @@ object DefOps { } for ((fd,nfd) <- fdMap) { - val bindings = (fd.params zip nfd.params).map(p => p._1.id -> p._2.id).toMap - nfd.fullBody = transformer.transform(fd.fullBody)(bindings) + val bindings = (fd.params zip nfd.params).map(p => p._1.id -> p._2.id).toMap ++ + nfd.params.map(vd => vd.id -> vd.id) + + nfd.fullBody = transformer.transform(nfd.fullBody)(bindings) } val fdsMap = fdMap.toMap diff --git a/src/main/scala/leon/solvers/cvc4/CVC4UnrollingSolver.scala b/src/main/scala/leon/solvers/cvc4/CVC4UnrollingSolver.scala index 79498f97b0bd3735969ae9f2bd4de58279ec4a01..3ddfca8d9524f9052dc5e6e49266006e9ffa2e3b 100644 --- a/src/main/scala/leon/solvers/cvc4/CVC4UnrollingSolver.scala +++ b/src/main/scala/leon/solvers/cvc4/CVC4UnrollingSolver.scala @@ -10,4 +10,4 @@ import unrolling._ import theories._ class CVC4UnrollingSolver(context: LeonContext, program: Program, underlying: Solver) - extends UnrollingSolver(context, program, underlying, theories = NoEncoder) + extends UnrollingSolver(context, program, underlying, theories = new NoEncoder) diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Solver.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Solver.scala index 4c17f80892dfad288c0522e3c918a31eb4cef9ae..5de74510b465d76cfc152c476cff96321c4758e9 100644 --- a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Solver.scala +++ b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Solver.scala @@ -5,9 +5,12 @@ package solvers.smtlib import OptionParsers._ +import solvers.theories._ import purescala.Definitions.Program -class SMTLIBCVC4Solver(context: LeonContext, program: Program) extends SMTLIBSolver(context, program) with SMTLIBCVC4Target { +class SMTLIBCVC4Solver(context: LeonContext, program: Program) + extends SMTLIBSolver(context, program, new NoEncoder) + with SMTLIBCVC4Target { def targetName = "cvc4" diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBSolver.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBSolver.scala index 99e1070273b762b824fd0b1543f1ecb035b53c3f..9f6f92b93c0cafc7cf73210879d32b3c9defff2b 100644 --- a/src/main/scala/leon/solvers/smtlib/SMTLIBSolver.scala +++ b/src/main/scala/leon/solvers/smtlib/SMTLIBSolver.scala @@ -16,7 +16,7 @@ import _root_.smtlib.parser.CommandsResponses.{Error => ErrorResponse, _} import theories._ import utils._ -abstract class SMTLIBSolver(val context: LeonContext, val program: Program, theories: TheoryEncoder = NoEncoder) +abstract class SMTLIBSolver(val context: LeonContext, val program: Program, theories: TheoryEncoder) extends Solver with SMTLIBTarget with NaiveAssumptionSolver { /* Solver name */ diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Solver.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Solver.scala index e12b53fb59d21b60b56f3a1cbcbb4d1b01a31ca7..6a58f9f1a294180182595bcb34d35d1a2ffe08a7 100644 --- a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Solver.scala +++ b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Solver.scala @@ -16,7 +16,8 @@ import _root_.smtlib.theories.Core.{Equals => _, _} import theories._ class SMTLIBZ3Solver(context: LeonContext, program: Program) - extends SMTLIBSolver(context, program, StringEncoder) with SMTLIBZ3Target { + extends SMTLIBSolver(context, program, new StringEncoder) + with SMTLIBZ3Target { def getProgram: Program = program } diff --git a/src/main/scala/leon/solvers/theories/BagEncoder.scala b/src/main/scala/leon/solvers/theories/BagEncoder.scala index fb66742247aa5a1a2d0534edc59b58bcf724105e..4ba7fcaa42307ae9c1b65bd3b81c4da03ab62b22 100644 --- a/src/main/scala/leon/solvers/theories/BagEncoder.scala +++ b/src/main/scala/leon/solvers/theories/BagEncoder.scala @@ -8,7 +8,7 @@ import purescala.Common._ import purescala.Expressions._ import purescala.Types._ -object BagEncoder extends TheoryEncoder { +class BagEncoder(val context: LeonContext) extends TheoryEncoder { val encoder = new Encoder val decoder = new Decoder } diff --git a/src/main/scala/leon/solvers/theories/StringEncoder.scala b/src/main/scala/leon/solvers/theories/StringEncoder.scala index f8b55303b4257e50dfb42e05d634381d2dd40e84..8f33513a64898c17a7a4b2dfda13a037b2d93f5d 100644 --- a/src/main/scala/leon/solvers/theories/StringEncoder.scala +++ b/src/main/scala/leon/solvers/theories/StringEncoder.scala @@ -116,7 +116,7 @@ object StringEcoSystem { val funDefs = Seq(StringSize, StringListConcat, StringTake, StringDrop, StringSlice) } -object StringEncoder extends TheoryEncoder { +class StringEncoder extends TheoryEncoder { import StringEcoSystem._ private val stringBijection = new Bijection[String, Expr]() diff --git a/src/main/scala/leon/solvers/theories/TheoryEncoder.scala b/src/main/scala/leon/solvers/theories/TheoryEncoder.scala index 9cb18effd731d15033397d5fbcb2b58dce2ac83a..39b5a632c5321220416e8142f30eb90c65b887a5 100644 --- a/src/main/scala/leon/solvers/theories/TheoryEncoder.scala +++ b/src/main/scala/leon/solvers/theories/TheoryEncoder.scala @@ -75,7 +75,7 @@ trait TheoryEncoder { self => } } -object NoEncoder extends TheoryEncoder { +class NoEncoder extends TheoryEncoder { val encoder = new Encoder val decoder = new Decoder } diff --git a/src/main/scala/leon/solvers/unrolling/UnrollingSolver.scala b/src/main/scala/leon/solvers/unrolling/UnrollingSolver.scala index 76f18864b453df290c372af35658707525058224..852e125ed88db4327b18cfabc329d31e1366a2f6 100644 --- a/src/main/scala/leon/solvers/unrolling/UnrollingSolver.scala +++ b/src/main/scala/leon/solvers/unrolling/UnrollingSolver.scala @@ -394,10 +394,11 @@ trait AbstractUnrollingSolver[T] } if (!foundDefinitiveAnswer) { - unrollingBank.decreaseAllGenerations() + val promote = templateGenerator.manager.getBlockersToPromote(model.eval) + if (promote.nonEmpty) { + unrollingBank.decreaseAllGenerations() - for (b <- templateGenerator.manager.getBlockersToPromote(model.eval)) { - unrollingBank.promoteBlocker(b, force = true) + for (b <- promote) unrollingBank.promoteBlocker(b, force = true) } } } @@ -449,7 +450,7 @@ class UnrollingSolver( val context: LeonContext, val program: Program, underlying: Solver, - theories: TheoryEncoder = NoEncoder + theories: TheoryEncoder = new NoEncoder ) extends AbstractUnrollingSolver[Expr] { override val name = "U:"+underlying.name diff --git a/src/main/scala/leon/solvers/z3/FairZ3Solver.scala b/src/main/scala/leon/solvers/z3/FairZ3Solver.scala index 7c79597f21ba61532cc3f826c00efd6019393e0f..f8237a4885fdc459efe261bb4333afc36944b500 100644 --- a/src/main/scala/leon/solvers/z3/FairZ3Solver.scala +++ b/src/main/scala/leon/solvers/z3/FairZ3Solver.scala @@ -103,7 +103,7 @@ class FairZ3Solver(val context: LeonContext, val program: Program) def asString(implicit ctx: LeonContext) = z3.toString } - val theoryEncoder = StringEncoder + val theoryEncoder = new StringEncoder val templateEncoder = new TemplateEncoder[Z3AST] { def encodeId(id: Identifier): Z3AST = { diff --git a/src/main/scala/leon/solvers/z3/Z3UnrollingSolver.scala b/src/main/scala/leon/solvers/z3/Z3UnrollingSolver.scala index ec1428e3993c87e20abd77bd24844df242ae96d4..99c75199a7d96b64ce42ba9039dd648032e60888 100644 --- a/src/main/scala/leon/solvers/z3/Z3UnrollingSolver.scala +++ b/src/main/scala/leon/solvers/z3/Z3UnrollingSolver.scala @@ -10,4 +10,4 @@ import unrolling._ import theories._ class Z3UnrollingSolver(context: LeonContext, program: Program, underlying: Solver) - extends UnrollingSolver(context, program, underlying, theories = StringEncoder) + extends UnrollingSolver(context, program, underlying, theories = new StringEncoder) diff --git a/src/main/scala/leon/termination/ChainProcessor.scala b/src/main/scala/leon/termination/ChainProcessor.scala index c01fa9fb3afe65e5b798b31db3ebc5cf23e9e626..ef6fde2e21638a9f26117f5ef855f7d9d85ec57f 100644 --- a/src/main/scala/leon/termination/ChainProcessor.scala +++ b/src/main/scala/leon/termination/ChainProcessor.scala @@ -58,11 +58,11 @@ class ChainProcessor( if (structuralDecreasing || numericDecreasing) Some(problem.funDefs map Cleared) else { - val chainsUnlooping = chains.flatMap(c1 => chains.flatMap(c2 => c1 compose c2)).forall { - chain => !definitiveSATwithModel(andJoin(chain.loop())).isDefined + val maybeReentrant = chains.flatMap(c1 => chains.flatMap(c2 => c1 compose c2)).exists { + chain => maybeSAT(andJoin(chain.loop())) } - if (chainsUnlooping) + if (!maybeReentrant) Some(problem.funDefs map Cleared) else None diff --git a/src/main/scala/leon/termination/Processor.scala b/src/main/scala/leon/termination/Processor.scala index 1d0527127344510b803a21666f0ade2d92537dff..6f998b0edcfb80ed41110596c3c754e411a71cc6 100644 --- a/src/main/scala/leon/termination/Processor.scala +++ b/src/main/scala/leon/termination/Processor.scala @@ -34,7 +34,7 @@ trait Solvable extends Processor { val sizeUnit : UnitDef = UnitDef(FreshIdentifier("$size"),Seq(sizeModule)) val newProgram : Program = program.copy( units = sizeUnit :: program.units) - SolverFactory.getFromSettings(context, newProgram).withTimeout(10.seconds) + SolverFactory.getFromSettings(context, newProgram).withTimeout(1.seconds) } type Solution = (Option[Boolean], Map[Identifier, Expr]) @@ -52,23 +52,17 @@ trait Solvable extends Processor { res } - def maybeSAT(problem: Expr): Boolean = { - withoutPosts { - SimpleSolverAPI(solver).solveSAT(problem)._1 getOrElse true - } + def maybeSAT(problem: Expr): Boolean = withoutPosts { + SimpleSolverAPI(solver).solveSAT(problem)._1 getOrElse true } - def definitiveALL(problem: Expr): Boolean = { - withoutPosts { - SimpleSolverAPI(solver).solveSAT(Not(problem))._1.exists(!_) - } + def definitiveALL(problem: Expr): Boolean = withoutPosts { + SimpleSolverAPI(solver).solveSAT(Not(problem))._1.exists(!_) } - def definitiveSATwithModel(problem: Expr): Option[Model] = { - withoutPosts { - val (sat, model) = SimpleSolverAPI(solver).solveSAT(problem) - if (sat.isDefined && sat.get) Some(model) else None - } + def definitiveSATwithModel(problem: Expr): Option[Model] = withoutPosts { + val (sat, model) = SimpleSolverAPI(solver).solveSAT(problem) + if (sat.isDefined && sat.get) Some(model) else None } }