From 2fe24a49808ac223c84066bb8374f8890fa48758 Mon Sep 17 00:00:00 2001 From: Regis Blanc <regwblanc@gmail.com> Date: Fri, 20 Feb 2015 14:01:36 +0100 Subject: [PATCH] fix bug while reading int literal from z3 models --- .../solvers/z3/Z3ModelReconstruction.scala | 5 +++- .../verification/purescala/invalid/Acc.scala | 24 +++++++++++++++++++ .../verification/purescala/valid/Acc.scala | 24 +++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 src/test/resources/regression/verification/purescala/invalid/Acc.scala create mode 100644 src/test/resources/regression/verification/purescala/valid/Acc.scala diff --git a/src/main/scala/leon/solvers/z3/Z3ModelReconstruction.scala b/src/main/scala/leon/solvers/z3/Z3ModelReconstruction.scala index 1bdb9fe6a..bb290cd89 100644 --- a/src/main/scala/leon/solvers/z3/Z3ModelReconstruction.scala +++ b/src/main/scala/leon/solvers/z3/Z3ModelReconstruction.scala @@ -23,7 +23,10 @@ trait Z3ModelReconstruction { variables.getZ3(id.toVariable).flatMap { z3ID => expectedType match { case BooleanType => model.evalAs[Boolean](z3ID).map(BooleanLiteral(_)) - case Int32Type => model.evalAs[Int](z3ID).map(IntLiteral(_)) + case Int32Type => + model.evalAs[Int](z3ID).map(IntLiteral(_)).orElse{ + model.eval(z3ID).flatMap(t => softFromZ3Formula(model, t)) + } case IntegerType => model.evalAs[Int](z3ID).map(InfiniteIntegerLiteral(_)) case other => model.eval(z3ID) match { case None => None diff --git a/src/test/resources/regression/verification/purescala/invalid/Acc.scala b/src/test/resources/regression/verification/purescala/invalid/Acc.scala new file mode 100644 index 000000000..2edd23ab7 --- /dev/null +++ b/src/test/resources/regression/verification/purescala/invalid/Acc.scala @@ -0,0 +1,24 @@ +import leon.annotation._ +import leon.lang._ + +object Acc { + + case class Acc(checking : Int, savings : Int) + + def putAside(x: Int, a: Acc): Acc = { + require (x > 0 && notRed(a) && a.checking >= x) + Acc(a.checking - x, a.savings + x) + } ensuring { + r => notRed(r) && sameTotal(a, r) + } + + + def sameTotal(a1: Acc, a2: Acc): Boolean = { + a1.checking + a1.savings == a2.checking + a2.savings + } + + def notRed(a: Acc) : Boolean = { + a.checking >= 0 && a.savings >= 0 + } + +} diff --git a/src/test/resources/regression/verification/purescala/valid/Acc.scala b/src/test/resources/regression/verification/purescala/valid/Acc.scala new file mode 100644 index 000000000..681f75059 --- /dev/null +++ b/src/test/resources/regression/verification/purescala/valid/Acc.scala @@ -0,0 +1,24 @@ +import leon.annotation._ +import leon.lang._ + +object Acc { + + case class Acc(checking : BigInt, savings : BigInt) + + def putAside(x: BigInt, a: Acc): Acc = { + require (x > 0 && notRed(a) && a.checking >= x) + Acc(a.checking - x, a.savings + x) + } ensuring { + r => notRed(r) && sameTotal(a, r) + } + + + def sameTotal(a1: Acc, a2: Acc): Boolean = { + a1.checking + a1.savings == a2.checking + a2.savings + } + + def notRed(a: Acc) : Boolean = { + a.checking >= 0 && a.savings >= 0 + } + +} -- GitLab