From 4299991102e0a2b8e509e62b212d0d35b1f8068c Mon Sep 17 00:00:00 2001 From: Etienne Kneuss <etienne.kneuss@epfl.ch> Date: Thu, 18 Sep 2014 16:04:15 +0200 Subject: [PATCH] FiniteSets should hold Sets, otherwise {1,2} != {2,1} --- src/main/scala/leon/codegen/CompilationUnit.scala | 2 +- src/main/scala/leon/evaluators/RecursiveEvaluator.scala | 8 ++++---- src/main/scala/leon/frontends/scalac/CodeExtraction.scala | 4 ++-- src/main/scala/leon/purescala/Extractors.scala | 6 +++--- src/main/scala/leon/purescala/PrettyPrinter.scala | 2 +- src/main/scala/leon/purescala/ScalaPrinter.scala | 3 ++- src/main/scala/leon/purescala/TreeOps.scala | 2 +- src/main/scala/leon/purescala/Trees.scala | 4 ++-- src/main/scala/leon/purescala/TypeTreeOps.scala | 2 +- src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Target.scala | 6 +++--- src/main/scala/leon/solvers/smtlib/SMTLIBZ3Target.scala | 2 +- src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala | 2 +- src/main/scala/leon/synthesis/rules/Tegis.scala | 2 +- src/test/scala/leon/test/evaluators/EvaluatorsTests.scala | 6 +++--- 14 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/main/scala/leon/codegen/CompilationUnit.scala b/src/main/scala/leon/codegen/CompilationUnit.scala index 3aa980ef8..6015fa8d2 100644 --- a/src/main/scala/leon/codegen/CompilationUnit.scala +++ b/src/main/scala/leon/codegen/CompilationUnit.scala @@ -204,7 +204,7 @@ class CompilationUnit(val ctx: LeonContext, gv case (set : runtime.Set, SetType(b)) => - FiniteSet(set.getElements().asScala.map(jvmToExpr(_, b)).toSeq).setType(SetType(b)) + FiniteSet(set.getElements().asScala.map(jvmToExpr(_, b)).toSet).setType(SetType(b)) case (map : runtime.Map, MapType(from, to)) => val pairs = map.getElements().asScala.map { entry => diff --git a/src/main/scala/leon/evaluators/RecursiveEvaluator.scala b/src/main/scala/leon/evaluators/RecursiveEvaluator.scala index 18dbe6ced..cb3278c09 100644 --- a/src/main/scala/leon/evaluators/RecursiveEvaluator.scala +++ b/src/main/scala/leon/evaluators/RecursiveEvaluator.scala @@ -273,14 +273,14 @@ abstract class RecursiveEvaluator(ctx: LeonContext, prog: Program, maxSteps: Int case SetUnion(s1,s2) => (e(s1), e(s2)) match { - case (f@FiniteSet(els1),FiniteSet(els2)) => FiniteSet((els1 ++ els2).distinct).setType(f.getType) + case (f@FiniteSet(els1),FiniteSet(els2)) => FiniteSet(els1 ++ els2).setType(f.getType) case (le,re) => throw EvalError(typeErrorMsg(le, s1.getType)) } case SetIntersection(s1,s2) => (e(s1), e(s2)) match { case (f @ FiniteSet(els1), FiniteSet(els2)) => { - val newElems = (els1.toSet intersect els2.toSet).toSeq + val newElems = (els1 intersect els2) val baseType = f.getType.asInstanceOf[SetType].base FiniteSet(newElems).setType(f.getType) } @@ -290,7 +290,7 @@ abstract class RecursiveEvaluator(ctx: LeonContext, prog: Program, maxSteps: Int case SetDifference(s1,s2) => (e(s1), e(s2)) match { case (f @ FiniteSet(els1),FiniteSet(els2)) => { - val newElems = (els1.toSet -- els2.toSet).toSeq + val newElems = els1 -- els2 val baseType = f.getType.asInstanceOf[SetType].base FiniteSet(newElems).setType(f.getType) } @@ -312,7 +312,7 @@ abstract class RecursiveEvaluator(ctx: LeonContext, prog: Program, maxSteps: Int case _ => throw EvalError(typeErrorMsg(sr, SetType(Untyped))) } - case f @ FiniteSet(els) => FiniteSet(els.map(e(_)).distinct).setType(f.getType) + case f @ FiniteSet(els) => FiniteSet(els.map(e(_))).setType(f.getType) case i @ IntLiteral(_) => i case b @ BooleanLiteral(_) => b case u @ UnitLiteral() => u diff --git a/src/main/scala/leon/frontends/scalac/CodeExtraction.scala b/src/main/scala/leon/frontends/scalac/CodeExtraction.scala index e2778a359..2398e51b9 100644 --- a/src/main/scala/leon/frontends/scalac/CodeExtraction.scala +++ b/src/main/scala/leon/frontends/scalac/CodeExtraction.scala @@ -1148,7 +1148,7 @@ trait CodeExtraction extends ASTExtractors { case ExFiniteSet(tt, args) => val underlying = extractType(tt) - FiniteSet(args.map(extractTree(_))).setType(SetType(underlying)) + FiniteSet(args.map(extractTree(_)).toSet).setType(SetType(underlying)) case ExFiniteMultiset(tt, args) => val underlying = extractType(tt) @@ -1156,7 +1156,7 @@ trait CodeExtraction extends ASTExtractors { case ExEmptySet(tt) => val underlying = extractType(tt) - FiniteSet(Seq()).setType(SetType(underlying)) + FiniteSet(Set()).setType(SetType(underlying)) case ExEmptyMultiset(tt) => val underlying = extractType(tt) diff --git a/src/main/scala/leon/purescala/Extractors.scala b/src/main/scala/leon/purescala/Extractors.scala index 11a2e7281..be2a14fa5 100644 --- a/src/main/scala/leon/purescala/Extractors.scala +++ b/src/main/scala/leon/purescala/Extractors.scala @@ -93,12 +93,12 @@ object Extractors { case And(args) => Some((args, And.apply)) case Or(args) => Some((args, Or.apply)) case FiniteSet(args) => - Some((args, + Some((args.toSeq, { newargs => if (newargs.isEmpty) { - FiniteSet(Seq()).setType(expr.getType) + FiniteSet(Set()).setType(expr.getType) } else { - FiniteSet(newargs) + FiniteSet(newargs.toSet) } } )) diff --git a/src/main/scala/leon/purescala/PrettyPrinter.scala b/src/main/scala/leon/purescala/PrettyPrinter.scala index 5d97ff989..aafaff753 100644 --- a/src/main/scala/leon/purescala/PrettyPrinter.scala +++ b/src/main/scala/leon/purescala/PrettyPrinter.scala @@ -262,7 +262,7 @@ class PrettyPrinter(opts: PrinterOptions, val sb: StringBuffer = new StringBuffe case GreaterThan(l,r) => optP { p"$l > $r" } case LessEquals(l,r) => optP { p"$l <= $r" } case GreaterEquals(l,r) => optP { p"$l >= $r" } - case FiniteSet(rs) => p"{$rs}" + case FiniteSet(rs) => p"{${rs.toSeq}}" case FiniteMultiset(rs) => p"{|$rs|)" case EmptyMultiset(_) => p"\u2205" case Not(ElementOfSet(e,s)) => p"$e \u2209 $s" diff --git a/src/main/scala/leon/purescala/ScalaPrinter.scala b/src/main/scala/leon/purescala/ScalaPrinter.scala index 8305781b9..f51674901 100644 --- a/src/main/scala/leon/purescala/ScalaPrinter.scala +++ b/src/main/scala/leon/purescala/ScalaPrinter.scala @@ -26,7 +26,8 @@ class ScalaPrinter(opts: PrinterOptions, sb: StringBuffer = new StringBuffer) ex case Iff(l,r) => p"$l == $r" case Implies(l,r) => pp(Or(Not(l), r)) case Choose(vars, pred) => p"choose((${typed(vars)}) => $pred)" - case s @ FiniteSet(rs) => { + case s @ FiniteSet(rss) => { + val rs = rss.toSeq s.getType match { case SetType(ut) => p"Set[$ut]($rs)" diff --git a/src/main/scala/leon/purescala/TreeOps.scala b/src/main/scala/leon/purescala/TreeOps.scala index e9e2c66b1..67cec4c0e 100644 --- a/src/main/scala/leon/purescala/TreeOps.scala +++ b/src/main/scala/leon/purescala/TreeOps.scala @@ -780,7 +780,7 @@ object TreeOps { def simplestValue(tpe: TypeTree) : Expr = tpe match { case Int32Type => IntLiteral(0) case BooleanType => BooleanLiteral(false) - case SetType(baseType) => FiniteSet(Seq()).setType(tpe) + case SetType(baseType) => FiniteSet(Set()).setType(tpe) case MapType(fromType, toType) => FiniteMap(Seq()).setType(tpe) case TupleType(tpes) => Tuple(tpes.map(simplestValue)) case ArrayType(tpe) => ArrayFill(IntLiteral(0), simplestValue(tpe)) diff --git a/src/main/scala/leon/purescala/Trees.scala b/src/main/scala/leon/purescala/Trees.scala index 7f5d5f4c6..44b98012a 100644 --- a/src/main/scala/leon/purescala/Trees.scala +++ b/src/main/scala/leon/purescala/Trees.scala @@ -519,8 +519,8 @@ object Trees { } /* Set expressions */ - case class FiniteSet(elements: Seq[Expr]) extends Expr { - val tpe = if (elements.isEmpty) None else leastUpperBound(elements.map(_.getType)) + case class FiniteSet(elements: Set[Expr]) extends Expr { + val tpe = if (elements.isEmpty) None else leastUpperBound(elements.toSeq.map(_.getType)) tpe.foreach(t => setType(SetType(t))) } // TODO : Figure out what evaluation order is, for this. diff --git a/src/main/scala/leon/purescala/TypeTreeOps.scala b/src/main/scala/leon/purescala/TypeTreeOps.scala index 0cb7e3c6e..469b7606b 100644 --- a/src/main/scala/leon/purescala/TypeTreeOps.scala +++ b/src/main/scala/leon/purescala/TypeTreeOps.scala @@ -255,7 +255,7 @@ object TypeTreeOps { Error(desc).setType(tpeSub(e.getType)).copiedFrom(e) case s @ FiniteSet(elements) if elements.isEmpty => - FiniteSet(Nil).setType(tpeSub(s.getType)).copiedFrom(s) + FiniteSet(Set()).setType(tpeSub(s.getType)).copiedFrom(s) case v @ Variable(id) if idsMap contains id => Variable(idsMap(id)).copiedFrom(v) diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Target.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Target.scala index d26e4d47d..92907a2e7 100644 --- a/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Target.scala +++ b/src/main/scala/leon/solvers/smtlib/SMTLIBCVC4Target.scala @@ -45,15 +45,15 @@ trait SMTLIBCVC4Target extends SMTLIBTarget { GenericValue(tp, n.toInt) case (QualifiedIdentifier(SMTIdentifier(SSymbol("emptyset"), Seq()), _), SetType(base)) => - FiniteSet(Seq()).setType(tpe) + FiniteSet(Set()).setType(tpe) case (FunctionApplication(SimpleSymbol(SSymbol("setenum")), elems), SetType(base)) => - FiniteSet(elems.map(fromSMT(_, base))).setType(tpe) + FiniteSet(elems.map(fromSMT(_, base)).toSet).setType(tpe) case (FunctionApplication(SimpleSymbol(SSymbol("union")), elems), SetType(base)) => FiniteSet(elems.map(fromSMT(_, tpe) match { case FiniteSet(elems) => elems - }).flatten).setType(tpe) + }).flatten.toSet).setType(tpe) case _ => super[SMTLIBTarget].fromSMT(s, tpe) diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Target.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Target.scala index 4feb6a394..48d602402 100644 --- a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Target.scala +++ b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3Target.scala @@ -234,7 +234,7 @@ trait SMTLIBZ3Target extends SMTLIBTarget { case SetType(base) => assert(r.default == BooleanLiteral(false) && r.keyTpe == base) - FiniteSet(r.elems.keySet.toSeq).setType(tpe) + FiniteSet(r.elems.keySet).setType(tpe) case RawArrayType(from, to) => r diff --git a/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala b/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala index 077602062..1529dc7f7 100644 --- a/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala +++ b/src/main/scala/leon/solvers/z3/AbstractZ3Solver.scala @@ -749,7 +749,7 @@ trait AbstractZ3Solver case None => throw new CantTranslateException(t) case Some(set) => val elems = set.map(e => rec(e)) - FiniteSet(elems.toSeq).setType(tpe) + FiniteSet(elems).setType(tpe) } case LeonType(UnitType) => diff --git a/src/main/scala/leon/synthesis/rules/Tegis.scala b/src/main/scala/leon/synthesis/rules/Tegis.scala index f17f75c96..faaa084e5 100644 --- a/src/main/scala/leon/synthesis/rules/Tegis.scala +++ b/src/main/scala/leon/synthesis/rules/Tegis.scala @@ -71,7 +71,7 @@ case object TEGIS extends Rule("TEGIS") { case st @ SetType(base) => List( - Generator(List(base), { case elems => FiniteSet(elems).setType(st) }), + Generator(List(base), { case elems => FiniteSet(elems.toSet).setType(st) }), Generator(List(st, st), { case Seq(a, b) => SetUnion(a, b) }), Generator(List(st, st), { case Seq(a, b) => SetIntersection(a, b) }), Generator(List(st, st), { case Seq(a, b) => SetDifference(a, b) }) diff --git a/src/test/scala/leon/test/evaluators/EvaluatorsTests.scala b/src/test/scala/leon/test/evaluators/EvaluatorsTests.scala index 84c546c05..678373a89 100644 --- a/src/test/scala/leon/test/evaluators/EvaluatorsTests.scala +++ b/src/test/scala/leon/test/evaluators/EvaluatorsTests.scala @@ -315,9 +315,9 @@ class EvaluatorsTests extends leon.test.LeonTestSuite { val nil = mkCaseClass("Nil") val cons12 = mkCaseClass("Cons", IL(1), mkCaseClass("Cons", IL(2), mkCaseClass("Nil"))) - val semp = FiniteSet(Seq.empty).setType(SetType(Int32Type)) - val s123 = FiniteSet(Seq(IL(1), IL(2), IL(3))).setType(SetType(Int32Type)) - val s246 = FiniteSet(Seq(IL(2), IL(4), IL(6))).setType(SetType(Int32Type)) + val semp = FiniteSet(Set()).setType(SetType(Int32Type)) + val s123 = FiniteSet(Set(IL(1), IL(2), IL(3))).setType(SetType(Int32Type)) + val s246 = FiniteSet(Set(IL(2), IL(4), IL(6))).setType(SetType(Int32Type)) for(e <- evaluators) { checkSetComp(e, mkCall("finite"), Set(1, 2, 3)) -- GitLab