From cfe3a050fbb2b56a76f0943d4577779ebf87d656 Mon Sep 17 00:00:00 2001 From: ravi <ravi.kandhadai@epfl.ch> Date: Fri, 4 Dec 2015 16:54:12 +0100 Subject: [PATCH] (a) Adding a test case to test the laziness of And (b) Adding an option: unfoldFactor to unfold functions more than once in each iteration of verification --- .../solvers/combinators/UnrollingSolver.scala | 16 ++++++++++------ .../scala/leon/solvers/z3/FairZ3Component.scala | 3 ++- .../leon/verification/VerificationPhase.scala | 1 - .../purescala/invalid/TestLazinessOfAnd.scala | 16 ++++++++++++++++ 4 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 src/test/resources/regression/verification/purescala/invalid/TestLazinessOfAnd.scala diff --git a/src/main/scala/leon/solvers/combinators/UnrollingSolver.scala b/src/main/scala/leon/solvers/combinators/UnrollingSolver.scala index f7d395feb..b9c0dfd94 100644 --- a/src/main/scala/leon/solvers/combinators/UnrollingSolver.scala +++ b/src/main/scala/leon/solvers/combinators/UnrollingSolver.scala @@ -13,7 +13,7 @@ import purescala.ExprOps._ import purescala.Types._ import utils._ -import z3.FairZ3Component.{optFeelingLucky, optUseCodeGen, optAssumePre, optNoChecks} +import z3.FairZ3Component.{optFeelingLucky, optUseCodeGen, optAssumePre, optNoChecks, optUnfoldFactor} import templates._ import evaluators._ @@ -27,6 +27,7 @@ class UnrollingSolver(val context: LeonContext, val program: Program, underlying val useCodeGen = context.findOptionOrDefault(optUseCodeGen) val assumePreHolds = context.findOptionOrDefault(optAssumePre) val disableChecks = context.findOptionOrDefault(optNoChecks) + val unfoldFactor = context.findOptionOrDefault(optUnfoldFactor) protected var lastCheckResult : (Boolean, Option[Boolean], Option[HenkinModel]) = (false, None, None) @@ -306,14 +307,17 @@ class UnrollingSolver(val context: LeonContext, val program: Program, underlying if(!hasFoundAnswer) { reporter.debug("- We need to keep going.") - val toRelease = unrollingBank.getBlockersToUnlock + // unfolling `unfoldFactor` times + for (i <- 1 to unfoldFactor.toInt) { + val toRelease = unrollingBank.getBlockersToUnlock - reporter.debug(" - more unrollings") + reporter.debug(" - more unrollings") - val newClauses = unrollingBank.unrollBehind(toRelease) + val newClauses = unrollingBank.unrollBehind(toRelease) - for(ncl <- newClauses) { - solver.assertCnstr(ncl) + for (ncl <- newClauses) { + solver.assertCnstr(ncl) + } } reporter.debug(" - finished unrolling") diff --git a/src/main/scala/leon/solvers/z3/FairZ3Component.scala b/src/main/scala/leon/solvers/z3/FairZ3Component.scala index 256dcf38f..70ebd260f 100644 --- a/src/main/scala/leon/solvers/z3/FairZ3Component.scala +++ b/src/main/scala/leon/solvers/z3/FairZ3Component.scala @@ -14,9 +14,10 @@ trait FairZ3Component extends LeonComponent { val optUnrollCores = LeonFlagOptionDef("unrollcores", "Use unsat-cores to drive unrolling while remaining fair", false) val optAssumePre = LeonFlagOptionDef("assumepre", "Assume precondition holds (pre && f(x) = body) when unfolding", false) val optNoChecks = LeonFlagOptionDef("nochecks", "Disable counter-example check in presence of foralls" , false) + val optUnfoldFactor = LeonLongOptionDef("unfoldFactor", "Number of unfoldings to perform in each unfold step", default = 1, "<PosInt>") override val definedOptions: Set[LeonOptionDef[Any]] = - Set(optEvalGround, optCheckModels, optFeelingLucky, optUseCodeGen, optUnrollCores, optAssumePre) + Set(optEvalGround, optCheckModels, optFeelingLucky, optUseCodeGen, optUnrollCores, optAssumePre, optUnfoldFactor) } object FairZ3Component extends FairZ3Component diff --git a/src/main/scala/leon/verification/VerificationPhase.scala b/src/main/scala/leon/verification/VerificationPhase.scala index 21119c4e2..ea09de821 100644 --- a/src/main/scala/leon/verification/VerificationPhase.scala +++ b/src/main/scala/leon/verification/VerificationPhase.scala @@ -57,7 +57,6 @@ object VerificationPhase extends SimpleLeonPhase[Program,VerificationReport] { } } - try { val vcs = generateVCs(vctx, toVerify) diff --git a/src/test/resources/regression/verification/purescala/invalid/TestLazinessOfAnd.scala b/src/test/resources/regression/verification/purescala/invalid/TestLazinessOfAnd.scala new file mode 100644 index 000000000..113e7193a --- /dev/null +++ b/src/test/resources/regression/verification/purescala/invalid/TestLazinessOfAnd.scala @@ -0,0 +1,16 @@ +import leon.lang._ +object AndTest { + def nonterm(x: BigInt) : BigInt = { + nonterm(x + 1) + } ensuring(res => false) + + def precond(y : BigInt) = y < 0 + + /** + * Leon should find a counter-example here. + **/ + def foo(y: BigInt) : Boolean = { + require(precond(y)) + y >= 0 && (nonterm(0) == 0) + } holds +} -- GitLab