diff --git a/src/main/scala/leon/solvers/templates/TemplateGenerator.scala b/src/main/scala/leon/solvers/templates/TemplateGenerator.scala index 6d4789421edf9f6ee3d6572251f0880e051de41e..5c5098b7766b28b7d05ee9fa8ddf33f92c759842 100644 --- a/src/main/scala/leon/solvers/templates/TemplateGenerator.scala +++ b/src/main/scala/leon/solvers/templates/TemplateGenerator.scala @@ -181,6 +181,12 @@ class TemplateGenerator[T](val encoder: TemplateEncoder[T], } def mkClauses(pathVar: Identifier, expr: Expr, substMap: Map[Identifier, T]): Clauses = { + val (p, (condVars, exprVars, condTree, guardedExprs, lambdas, quantifications)) = mkExprClauses(pathVar, expr, substMap) + val allGuarded = guardedExprs + (pathVar -> (p +: guardedExprs.getOrElse(pathVar, Seq.empty))) + (condVars, exprVars, condTree, allGuarded, lambdas, quantifications) + } + + private def mkExprClauses(pathVar: Identifier, expr: Expr, substMap: Map[Identifier, T]): (Expr, Clauses) = { var condVars = Map[Identifier, T]() var condTree = Map[Identifier, Set[Identifier]](pathVar -> Set.empty).withDefaultValue(Set.empty) @@ -247,14 +253,11 @@ class TemplateGenerator[T](val encoder: TemplateEncoder[T], res } - def liftToIfExpr(parts: Seq[Expr], join: Seq[Expr] => Expr, recons: (Expr, Expr) => Expr): Expr = { + def liftToIfExpr(pathVar: Identifier, parts: Seq[Expr], join: Seq[Expr] => Expr, recons: (Expr, Expr) => Expr): Expr = { val partitions = groupWhile(parts)(!requireDecomposition(_)) partitions.map(join) match { case Seq(e) => e - case s @ Seq(e1, e2) if !requireDecomposition(e1) => - join(Seq(e1, rec(pathVar, e2))) - case seq => - rec(pathVar, seq.reduceRight(recons)) + case seq => rec(pathVar, seq.reduceRight(recons)) } } @@ -308,10 +311,10 @@ class TemplateGenerator[T](val encoder: TemplateEncoder[T], } case a @ And(parts) => - liftToIfExpr(parts, andJoin, (a,b) => IfExpr(a, b, BooleanLiteral(false))) + liftToIfExpr(pathVar, parts, andJoin, (a,b) => IfExpr(a, b, BooleanLiteral(false))) case o @ Or(parts) => - liftToIfExpr(parts, orJoin, (a,b) => IfExpr(a, BooleanLiteral(true), b)) + liftToIfExpr(pathVar, parts, orJoin, (a,b) => IfExpr(a, BooleanLiteral(true), b)) case i @ IfExpr(cond, thenn, elze) => { if(!requireDecomposition(i)) { @@ -395,14 +398,16 @@ class TemplateGenerator[T](val encoder: TemplateEncoder[T], val qs: (Identifier, T) = q -> encoder.encodeId(q) val localSubst: Map[Identifier, T] = substMap ++ condVars ++ exprVars ++ lambdaVars val clauseSubst: Map[Identifier, T] = localSubst ++ (idQuantifiers zip trQuantifiers) - val (qConds, qExprs, qTree, qGuarded, qTemplates, qQuants) = mkClauses(pathVar, clause, clauseSubst) + val (p, (qConds, qExprs, qTree, qGuarded, qTemplates, qQuants)) = mkExprClauses(pathVar, flatConj, clauseSubst) assert(qQuants.isEmpty, "Unhandled nested quantification in "+clause) - val binder = Equals(Variable(q), And(Variable(q2), Variable(inst))) - val allQGuarded = qGuarded + (pathVar -> (binder +: qGuarded.getOrElse(pathVar, Seq.empty))) + val allGuarded = qGuarded + (pathVar -> (Seq( + Equals(Variable(inst), Implies(Variable(guard), p)), + Equals(Variable(q), And(Variable(q2), Variable(inst))) + ) ++ qGuarded.getOrElse(pathVar, Seq.empty))) val template = QuantificationTemplate[T](encoder, manager, pathVar -> encodedCond(pathVar), - qs, q2, inst, guard, idQuantifiers zip trQuantifiers, qConds, qExprs, qTree, allQGuarded, qTemplates, localSubst) + qs, q2, inst, guard, idQuantifiers zip trQuantifiers, qConds, qExprs, qTree, allGuarded, qTemplates, localSubst) registerQuantification(template) Variable(q) } @@ -414,9 +419,7 @@ class TemplateGenerator[T](val encoder: TemplateEncoder[T], } val p = rec(pathVar, expr) - storeGuarded(pathVar, p) - - (condVars, exprVars, condTree, guardedExprs, lambdas, quantifications) + (p, (condVars, exprVars, condTree, guardedExprs, lambdas, quantifications)) } } diff --git a/src/test/resources/regression/verification/purescala/invalid/PropositionalLogic.scala b/src/test/resources/regression/verification/purescala/invalid/PropositionalLogic.scala index 547978dbcca900272b76aac30dfd8e2a8f9e2c62..ea73b834b364b8b943f1d288bb38a7463b669545 100644 --- a/src/test/resources/regression/verification/purescala/invalid/PropositionalLogic.scala +++ b/src/test/resources/regression/verification/purescala/invalid/PropositionalLogic.scala @@ -67,7 +67,7 @@ object PropositionalLogic { // nnf(simplify(f)) == simplify(nnf(f)) // }.holds - @induct + //@induct def simplifyBreaksNNF(f: Formula) : Boolean = { require(isNNF(f)) isNNF(simplify(f)) @@ -78,7 +78,7 @@ object PropositionalLogic { require(isNNF(f)) nnf(f) == f }.holds - + @induct def simplifyIsStable(f: Formula) : Boolean = { require(isSimplified(f)) diff --git a/src/test/resources/regression/verification/purescala/invalid/TestLazinessOfAnd.scala b/src/test/resources/regression/verification/purescala/invalid/TestLazinessOfAnd.scala index 113e7193a592f8f34739d53992b41857000acd5d..9ee698e1d42d38214a0290cbad859b0b5ad87405 100644 --- a/src/test/resources/regression/verification/purescala/invalid/TestLazinessOfAnd.scala +++ b/src/test/resources/regression/verification/purescala/invalid/TestLazinessOfAnd.scala @@ -1,5 +1,7 @@ import leon.lang._ + object AndTest { + def nonterm(x: BigInt) : BigInt = { nonterm(x + 1) } ensuring(res => false) diff --git a/src/test/scala/leon/regression/repair/RepairSuite.scala b/src/test/scala/leon/regression/repair/RepairSuite.scala index 5b6667d5f4233521a4dc79a5d309618e49e8f07d..6301f4ea1a61144f4b38cd2d7660579c192f5089 100644 --- a/src/test/scala/leon/regression/repair/RepairSuite.scala +++ b/src/test/scala/leon/regression/repair/RepairSuite.scala @@ -47,7 +47,7 @@ class RepairSuite extends LeonRegressionSuite { test(name) { pipeline.run(ctx, List(path)) if(reporter.errorCount > 0) { - fail("Errors during repair:\n")//+reporter.lastErrors.mkString("\n")) + fail("Errors during repair:\n"+reporter.lastErrors.mkString("\n")) } } } diff --git a/src/test/scala/leon/regression/verification/purescala/PureScalaVerificationSuite.scala b/src/test/scala/leon/regression/verification/purescala/PureScalaVerificationSuite.scala index 974615e6484304de738ebdd43ecafbb323e589c2..629e2c677d3ad3e73033f85674883769ae93c1c6 100644 --- a/src/test/scala/leon/regression/verification/purescala/PureScalaVerificationSuite.scala +++ b/src/test/scala/leon/regression/verification/purescala/PureScalaVerificationSuite.scala @@ -66,6 +66,11 @@ class PureScalaValidSuiteCVC4 extends PureScalaValidSuite { } class PureScalaInvalidSuite extends PureScalaVerificationSuite { + override val ignored = Seq( + "verification/purescala/invalid/PropositionalLogic.scala", + "verification/purescala/invalid/InductiveQuantification.scala" + ) + override def testAll() = testInvalid() val optionVariants = opts } diff --git a/testcases/verification/higher-order/valid/FlatMap.scala b/testcases/verification/higher-order/valid/FlatMap.scala index aa4baa08baf2e7fe4c454536da2f5853a3f8b09c..06d356c5fe5b1e7443831e7d541450c36449ef18 100644 --- a/testcases/verification/higher-order/valid/FlatMap.scala +++ b/testcases/verification/higher-order/valid/FlatMap.scala @@ -1,4 +1,5 @@ import leon.lang._ +import leon.proof._ import leon.collection._ object FlatMap { diff --git a/testcases/web/verification/10_FoldAssociative.scala b/testcases/web/verification/10_FoldAssociative.scala index 63354e13ab862c8d60c0af922af5fbac250c8332..6920231115fea93a1b7c7cefc27691a0ee2471bb 100644 --- a/testcases/web/verification/10_FoldAssociative.scala +++ b/testcases/web/verification/10_FoldAssociative.scala @@ -2,6 +2,7 @@ import leon._ import leon.lang._ +import leon.proof._ object FoldAssociative {