From 191fa1d05a5c3295fa3a5cdb935250866b312458 Mon Sep 17 00:00:00 2001 From: Philippe Suter <philippe.suter@gmail.com> Date: Thu, 15 Nov 2012 12:28:28 +0100 Subject: [PATCH] Fixed horrible bug that made a && false == a... --- src/main/scala/leon/purescala/Trees.scala | 45 ++++++++++++++----- .../{TreeOpsTest.scala => TreeOpsTests.scala} | 2 +- .../scala/leon/test/purescala/TreeTests.scala | 36 +++++++++++++++ 3 files changed, 70 insertions(+), 13 deletions(-) rename src/test/scala/leon/test/purescala/{TreeOpsTest.scala => TreeOpsTests.scala} (94%) create mode 100644 src/test/scala/leon/test/purescala/TreeTests.scala diff --git a/src/main/scala/leon/purescala/Trees.scala b/src/main/scala/leon/purescala/Trees.scala index 74925bce8..250dd8ad2 100644 --- a/src/main/scala/leon/purescala/Trees.scala +++ b/src/main/scala/leon/purescala/Trees.scala @@ -174,18 +174,25 @@ object Trees { /* Propositional logic */ object And { - def apply(l: Expr, r: Expr) : Expr = (l,r) match { - case (BooleanLiteral(false),_) => BooleanLiteral(false) - case (BooleanLiteral(true),_) => r - case (_,BooleanLiteral(true)) => l - case _ => new And(Seq(l,r)) - } + def apply(l: Expr, r: Expr) : Expr = And(Seq(l, r)) + def apply(exprs: Seq[Expr]) : Expr = { - val simpler = exprs.flatMap(_ match { + val flat = exprs.flatMap(_ match { case And(es) => es case o => Seq(o) - }).takeWhile(_ != BooleanLiteral(false)).filter(_ != BooleanLiteral(true)) - if(simpler.isEmpty) BooleanLiteral(true) else new And(simpler) + }) + + var stop = false + val simpler = for(e <- flat if !stop && e != BooleanLiteral(true)) yield { + if(e == BooleanLiteral(false)) stop = true + e + } + + simpler match { + case Seq() => BooleanLiteral(true) + case Seq(x) => x + case _ => new And(simpler) + } } def unapply(and: And) : Option[Seq[Expr]] = @@ -195,6 +202,8 @@ object Trees { class And private (val exprs: Seq[Expr]) extends Expr with FixedType { val fixedType = BooleanType + assert(exprs.size >= 2) + override def equals(that: Any): Boolean = (that != null) && (that match { case t: And => t.exprs == exprs case _ => false @@ -211,12 +220,22 @@ object Trees { case _ => new Or(Seq(l,r)) } def apply(exprs: Seq[Expr]) : Expr = { - val simpler = exprs.flatMap(_ match { + val flat = exprs.flatMap(_ match { case Or(es) => es case o => Seq(o) - }).takeWhile(_ != BooleanLiteral(true)).filter(_ != BooleanLiteral(false)) + }) + + var stop = false + val simpler = for(e <- flat if !stop && e != BooleanLiteral(false)) yield { + if(e == BooleanLiteral(true)) stop = true + e + } - if(simpler.isEmpty) BooleanLiteral(false) else new Or(simpler) + simpler match { + case Seq() => BooleanLiteral(false) + case Seq(x) => x + case _ => new Or(simpler) + } } def unapply(or: Or) : Option[Seq[Expr]] = @@ -226,6 +245,8 @@ object Trees { class Or(val exprs: Seq[Expr]) extends Expr with FixedType { val fixedType = BooleanType + assert(exprs.size >= 2) + override def equals(that: Any): Boolean = (that != null) && (that match { case t: Or => t.exprs == exprs case _ => false diff --git a/src/test/scala/leon/test/purescala/TreeOpsTest.scala b/src/test/scala/leon/test/purescala/TreeOpsTests.scala similarity index 94% rename from src/test/scala/leon/test/purescala/TreeOpsTest.scala rename to src/test/scala/leon/test/purescala/TreeOpsTests.scala index a0ee0fdf3..a729f00d0 100644 --- a/src/test/scala/leon/test/purescala/TreeOpsTest.scala +++ b/src/test/scala/leon/test/purescala/TreeOpsTests.scala @@ -8,7 +8,7 @@ import leon.SilentReporter import org.scalatest.FunSuite -class TreeOpsTest extends FunSuite { +class TreeOpsTests extends FunSuite { private val silentReporter = new SilentReporter private val emptyProgram = Program( diff --git a/src/test/scala/leon/test/purescala/TreeTests.scala b/src/test/scala/leon/test/purescala/TreeTests.scala new file mode 100644 index 000000000..3ca418ec5 --- /dev/null +++ b/src/test/scala/leon/test/purescala/TreeTests.scala @@ -0,0 +1,36 @@ +package leon.test.purescala + +import leon.purescala.Common._ +import leon.purescala.Definitions._ +import leon.purescala.Trees._ +import leon.purescala.TypeTrees._ + +import org.scalatest.FunSuite + +class TreeTests extends FunSuite { + + test("And- and Or- simplifications") { + val x = Variable(FreshIdentifier("x").setType(BooleanType)) + val t = BooleanLiteral(true) + val f = BooleanLiteral(false) + + def and(es : Expr*) : Expr = And(Seq(es : _*)) + def or(es : Expr*) : Expr = Or(Seq(es : _*)) + + assert(and(x, and(x, x), x) === and(x, x, x, x)) + assert(and(x, t, x, t) === and(x, x)) + assert(and(x, t, f, x) === and(x, f)) + assert(and(x) === x) + assert(and() === t) + assert(and(t, t) === t) + assert(and(f) === f) + + assert(or(x, or(x, x), x) === or(x, x, x, x)) + assert(or(x, f, x, f) === or(x, x)) + assert(or(x, f, t, x) === or(x, t)) + assert(or(x) === x) + assert(or() === f) + assert(or(f, f) === f) + assert(or(t) === t) + } +} -- GitLab