From a46ea1f7fb4448df4bc762ff21c062d1936e0cb0 Mon Sep 17 00:00:00 2001 From: Regis Blanc <regwblanc@gmail.com> Date: Tue, 19 Jan 2016 16:00:08 +0100 Subject: [PATCH] fix some issues with asserts and xlang --- .../leon/solvers/smtlib/SMTLIBTarget.scala | 6 ++++-- .../xlang/ImperativeCodeElimination.scala | 21 +++++++++++++------ .../verification/xlang/valid/Assert3.scala | 2 +- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala index 820d74662..b97297fb0 100644 --- a/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala +++ b/src/main/scala/leon/solvers/smtlib/SMTLIBTarget.scala @@ -837,11 +837,13 @@ trait SMTLIBTarget extends Interruptible { val rargs = args.zip(tt.bases).map(fromSMT) tupleWrap(rargs) - case ArrayType(baseType) => + case at@ArrayType(baseType) => val IntLiteral(size) = fromSMT(args(0), Int32Type) val RawArrayValue(_, elems, default) = fromSMT(args(1), RawArrayType(Int32Type, baseType)) - if (size > 10) { + if (size < 0) { + unsupported(at, "Cannot build an array of negative length: " + size) + } else if (size > 10) { val definedElements = elems.collect { case (IntLiteral(i), value) => (i, value) } diff --git a/src/main/scala/leon/xlang/ImperativeCodeElimination.scala b/src/main/scala/leon/xlang/ImperativeCodeElimination.scala index 01472565e..ac9535783 100644 --- a/src/main/scala/leon/xlang/ImperativeCodeElimination.scala +++ b/src/main/scala/leon/xlang/ImperativeCodeElimination.scala @@ -152,14 +152,13 @@ object ImperativeCodeElimination extends UnitPhase[Program] { case Block(exprs, expr) => val (scope, fun) = exprs.foldRight((body: Expr) => body, Map[Identifier, Identifier]())((e, acc) => { val (accScope, accFun) = acc - val (_, rScope, rFun) = toFunction(e) + val (rVal, rScope, rFun) = toFunction(e) val scope = (body: Expr) => { - val withoutPrec = rScope(replaceNames(rFun, accScope(body))) - e match { + rVal match { case FunctionInvocation(tfd, args) if tfd.hasPrecondition => - Assert(tfd.withParamSubst(args, tfd.precondition.get), Some("Precondition failed"), withoutPrec) + rScope(replaceNames(rFun, Let(FreshIdentifier("tmp", tfd.returnType), rVal, accScope(body)))) case _ => - withoutPrec + rScope(replaceNames(rFun, accScope(body))) } } @@ -211,7 +210,7 @@ object ImperativeCodeElimination extends UnitPhase[Program] { (TupleSelect(tmpTuple.toVariable, 1), scope, newMap) } - case None => + case None => (FunctionInvocation(tfd, recArgs).copiedFrom(fi), argScope, argFun) } @@ -315,6 +314,15 @@ object ImperativeCodeElimination extends UnitPhase[Program] { val ifExpr = args.reduceRight((el, acc) => IfExpr(el, BooleanLiteral(true), acc)) toFunction(ifExpr) + //TODO: this should be handled properly by the Operator case, but there seems to be a subtle bug in the way Let's are lifted + // which leads to Assert refering to the wrong value of a var in some cases. + case a@Assert(cond, msg, body) => + val (condVal, condScope, condFun) = toFunction(cond) + val (bodyRes, bodyScope, bodyFun) = toFunction(body) + val scope = (body: Expr) => condScope(Assert(condVal, msg, replaceNames(condFun, bodyScope(body))).copiedFrom(a)) + (bodyRes, scope, condFun ++ bodyFun) + + case n @ Operator(args, recons) => val (recArgs, scope, fun) = args.foldRight((Seq[Expr](), (body: Expr) => body, Map[Identifier, Identifier]()))((arg, acc) => { val (accArgs, accScope, accFun) = acc @@ -322,6 +330,7 @@ object ImperativeCodeElimination extends UnitPhase[Program] { val newScope = (body: Expr) => argScope(replaceNames(argFun, accScope(body))) (argVal +: accArgs, newScope, argFun ++ accFun) }) + (recons(recArgs).copiedFrom(n), scope, fun) case _ => diff --git a/src/test/resources/regression/verification/xlang/valid/Assert3.scala b/src/test/resources/regression/verification/xlang/valid/Assert3.scala index 58af2ef08..49e2f6c55 100644 --- a/src/test/resources/regression/verification/xlang/valid/Assert3.scala +++ b/src/test/resources/regression/verification/xlang/valid/Assert3.scala @@ -11,7 +11,7 @@ object Assert3 { j += 1 assert(j == i + 1) j += 2 - assert(j == i + 2) + assert(j == i + 3) j -- GitLab