From 764e9ca0fbe224b19a3d71cbecbebeabe4259545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20Blanc?= <regwblanc@gmail.com> Date: Wed, 9 May 2012 22:48:27 +0000 Subject: [PATCH] using FiniteArray to represent models containing array --- src/main/scala/leon/Evaluator.scala | 35 +++++++------------ src/main/scala/leon/FairZ3Solver.scala | 15 +++++--- .../scala/leon/purescala/PrettyPrinter.scala | 3 ++ src/main/scala/leon/purescala/Trees.scala | 2 ++ 4 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/main/scala/leon/Evaluator.scala b/src/main/scala/leon/Evaluator.scala index c26d7ca3d..d9a0733ec 100644 --- a/src/main/scala/leon/Evaluator.scala +++ b/src/main/scala/leon/Evaluator.scala @@ -85,7 +85,9 @@ object Evaluator { if(fd.hasPrecondition) { rec(frame, matchToIfThenElse(fd.precondition.get)) match { case BooleanLiteral(true) => ; - case BooleanLiteral(false) => throw RuntimeErrorEx("Precondition violation for " + fd.id.name + " reached in evaluation.") + case BooleanLiteral(false) => { + throw RuntimeErrorEx("Precondition violation for " + fd.id.name + " reached in evaluation.: " + fd.precondition.get) + } case other => throw TypeErrorEx(TypeError(other, BooleanType)) } } @@ -260,39 +262,28 @@ object Evaluator { case f @ ArrayFill(length, default) => { val rDefault = rec(ctx, default) val rLength = rec(ctx, length) - ArrayFill(rLength, rDefault) + val IntLiteral(iLength) = rLength + FiniteArray((1 to iLength).map(_ => rDefault).toSeq) } case ArrayLength(a) => { var ra = rec(ctx, a) - while(!ra.isInstanceOf[ArrayFill]) + while(!ra.isInstanceOf[FiniteArray]) ra = ra.asInstanceOf[ArrayUpdated].array - ra.asInstanceOf[ArrayFill].length + IntLiteral(ra.asInstanceOf[FiniteArray].exprs.size) } case ArrayUpdated(a, i, v) => { val ra = rec(ctx, a) val ri = rec(ctx, i) - assert(ri.isInstanceOf[IntLiteral]) val rv = rec(ctx, v) - ArrayUpdated(ra, ri, rv) + + val IntLiteral(index) = ri + val FiniteArray(exprs) = ra + FiniteArray(exprs.updated(index, rv)) } case ArraySelect(a, i) => { val IntLiteral(index) = rec(ctx, i) - var ra = rec(ctx, a) - var found = false - var result: Option[Expr] = None - while(!ra.isInstanceOf[ArrayFill] && !found) { - val ArrayUpdated(ra2, IntLiteral(i), v) = ra - if(index == i) { - result = Some(v) - found = true - } else { - ra = ra2 - } - } - result match { - case Some(r) => r - case None => ra.asInstanceOf[ArrayFill].defaultValue - } + val FiniteArray(exprs) = rec(ctx, a) + exprs(index) } case f @ FiniteMap(ss) => FiniteMap(ss.map(rec(ctx,_)).distinct.asInstanceOf[Seq[SingletonMap]]).setType(f.getType) diff --git a/src/main/scala/leon/FairZ3Solver.scala b/src/main/scala/leon/FairZ3Solver.scala index 90f95153e..8ec0984ee 100644 --- a/src/main/scala/leon/FairZ3Solver.scala +++ b/src/main/scala/leon/FairZ3Solver.scala @@ -1187,13 +1187,18 @@ class FairZ3Solver(reporter: Reporter) extends Solver(reporter) with AbstractZ3S case Some(ArrayType(dt)) => { val Z3AppAST(decl, args) = z3.getASTKind(t) assert(args.size == 2) - val length = rec(args(1), Some(Int32Type)) + val IntLiteral(length) = rec(args(1), Some(Int32Type)) val array = model.getArrayValue(args(0)) match { case None => throw new CantTranslateException(t) - case Some((map, elseValue)) => - map.foldLeft(ArrayFill(length, rec(elseValue, Some(dt))): Expr) { - case (acc, (key, value)) => ArrayUpdated(acc, rec(key, Some(Int32Type)), rec(value, Some(dt))) - } + case Some((map, elseValue)) => { + val exprs = map.foldLeft((1 to length).map(_ => rec(elseValue, Some(dt))).toSeq)((acc, p) => { + val IntLiteral(index) = rec(p._1, Some(Int32Type)) + if(index >= 0 && index < length) + acc.updated(index, rec(p._2, Some(dt))) + else acc + }) + FiniteArray(exprs) + } } array } diff --git a/src/main/scala/leon/purescala/PrettyPrinter.scala b/src/main/scala/leon/purescala/PrettyPrinter.scala index cd3df3797..f03c624af 100644 --- a/src/main/scala/leon/purescala/PrettyPrinter.scala +++ b/src/main/scala/leon/purescala/PrettyPrinter.scala @@ -286,6 +286,9 @@ object PrettyPrinter { pp(v, sb, lvl) sb.append(")") } + case FiniteArray(exprs) => { + ppNary(sb, exprs, "Array(", ", ", ")", lvl) + } case Distinct(exprs) => { var nsb = sb diff --git a/src/main/scala/leon/purescala/Trees.scala b/src/main/scala/leon/purescala/Trees.scala index 11adb22fc..1c015cfe6 100644 --- a/src/main/scala/leon/purescala/Trees.scala +++ b/src/main/scala/leon/purescala/Trees.scala @@ -398,6 +398,7 @@ object Trees { case class ArrayLength(array: Expr) extends Expr with FixedType { val fixedType = Int32Type } + case class FiniteArray(exprs: Seq[Expr]) extends Expr /* List operations */ case class NilList(baseType: TypeTree) extends Expr with Terminal @@ -489,6 +490,7 @@ object Trees { case FiniteMultiset(args) => Some((args, FiniteMultiset)) case ArrayUpdate(t1, t2, t3) => Some((Seq(t1,t2,t3), (as: Seq[Expr]) => ArrayUpdate(as(0), as(1), as(2)))) case ArrayUpdated(t1, t2, t3) => Some((Seq(t1,t2,t3), (as: Seq[Expr]) => ArrayUpdated(as(0), as(1), as(2)))) + case FiniteArray(args) => Some((args, FiniteArray)) case Distinct(args) => Some((args, Distinct)) case Block(args, rest) => Some((args :+ rest, exprs => Block(exprs.init, exprs.last))) case Tuple(args) => Some((args, Tuple)) -- GitLab