From 48c1d6d3a6e67a5f7ddb6cd14085781a1eab5578 Mon Sep 17 00:00:00 2001 From: Etienne Kneuss <ekneuss@gmail.com> Date: Mon, 4 May 2015 15:52:11 +0200 Subject: [PATCH] Set and Map are now implemented in the library and should be executable --- library/lang/Map.scala | 15 ++++++--- library/lang/Set.scala | 28 +++++++++------- .../leon/frontends/scalac/ASTExtractors.scala | 20 ++++++++++++ .../frontends/scalac/CodeExtraction.scala | 32 +++++++++---------- 4 files changed, 63 insertions(+), 32 deletions(-) diff --git a/library/lang/Map.scala b/library/lang/Map.scala index fec773142..289ca7ad4 100644 --- a/library/lang/Map.scala +++ b/library/lang/Map.scala @@ -4,13 +4,18 @@ import leon.annotation._ object Map { @library def empty[A,B] = Map[A,B]() + + @ignore + def apply[A,B](elems: (A,B)*) = { + new Map[A,B](scala.collection.immutable.Map[A,B](elems : _*)) + } } @ignore -case class Map[A, B](elems: (A, B)*) { - def apply(k: A): B = ??? - def ++(b: Map[A, B]): Map[A,B] = ??? - def updated(k: A, v: B): Map[A,B] = ??? - def contains(a: A): Boolean = ??? +class Map[A, B](val theMap: scala.collection.immutable.Map[A,B]) { + def apply(k: A): B = theMap.apply(k) + def ++(b: Map[A, B]): Map[A,B] = new Map (theMap ++ b.theMap) + def updated(k: A, v: B): Map[A,B] = new Map(theMap.updated(k, v)) + def contains(a: A): Boolean = theMap.contains(a) def isDefinedAt(a: A): Boolean = contains(a) } diff --git a/library/lang/Set.scala b/library/lang/Set.scala index 086b31988..af27ec7ae 100644 --- a/library/lang/Set.scala +++ b/library/lang/Set.scala @@ -2,18 +2,24 @@ package leon.lang import leon.annotation._ object Set { - @library - def empty[T] = Set[T]() + @library + def empty[T] = Set[T]() + + @ignore + def apply[T](elems: T*) = { + new Set[T](scala.collection.immutable.Set[T](elems : _*)) + } } @ignore -case class Set[T](elems: T*) { - def +(a: T): Set[T] = ??? - def ++(a: Set[T]): Set[T] = ??? - def -(a: T): Set[T] = ??? - def --(a: Set[T]): Set[T] = ??? - def contains(a: T): Boolean = ??? - def isEmpty: Boolean = ??? - def subsetOf(b: Set[T]): Boolean = ??? - def &(a: Set[T]): Set[T] = ??? +class Set[T](val theSet: scala.collection.immutable.Set[T]) { + def +(a: T): Set[T] = new Set[T](theSet + a) + def ++(a: Set[T]): Set[T] = new Set[T](theSet ++ a.theSet) + def -(a: T): Set[T] = new Set[T](theSet - a) + def --(a: Set[T]): Set[T] = new Set[T](theSet -- a.theSet) + def contains(a: T): Boolean = theSet.contains(a) + def isEmpty: Boolean = theSet.isEmpty + def subsetOf(b: Set[T]): Boolean = theSet.subsetOf(b.theSet) + def &(a: Set[T]): Set[T] = new Set[T](theSet & a.theSet) } + diff --git a/src/main/scala/leon/frontends/scalac/ASTExtractors.scala b/src/main/scala/leon/frontends/scalac/ASTExtractors.scala index f7a40b953..e83f51196 100644 --- a/src/main/scala/leon/frontends/scalac/ASTExtractors.scala +++ b/src/main/scala/leon/frontends/scalac/ASTExtractors.scala @@ -861,6 +861,26 @@ trait ASTExtractors { } } + object ExFiniteSet { + def unapply(tree: Apply): Option[(Tree,List[Tree])] = tree match { + case Apply(TypeApply(ExSelected("Set", "apply"), Seq(tpt)), args) => + Some(tpt, args) + case Apply(TypeApply(ExSelected("leon", "lang", "Set", "apply"), Seq(tpt)), args) => + Some(tpt, args) + case _ => None + } + } + + object ExFiniteMap { + def unapply(tree: Apply): Option[(Tree, Tree, List[Tree])] = tree match { + case Apply(TypeApply(ExSelected("Map", "apply"), Seq(tptFrom, tptTo)), args) => + Some((tptFrom, tptTo, args)) + case Apply(TypeApply(ExSelected("leon", "lang", "Map", "apply"), Seq(tptFrom, tptTo)), args) => + Some((tptFrom, tptTo, args)) + case _ => None + } + } + object ExFiniteMultiset { def unapply(tree: Apply): Option[(Tree,List[Tree])] = tree match { case Apply( diff --git a/src/main/scala/leon/frontends/scalac/CodeExtraction.scala b/src/main/scala/leon/frontends/scalac/CodeExtraction.scala index 03f1d1778..9e34f76b2 100644 --- a/src/main/scala/leon/frontends/scalac/CodeExtraction.scala +++ b/src/main/scala/leon/frontends/scalac/CodeExtraction.scala @@ -917,7 +917,7 @@ trait CodeExtraction extends ASTExtractors { e.emit() //val pos = if (body0.pos == NoPosition) NoPosition else leonPosToScalaPos(body0.pos.source, funDef.getPos) if (ctx.findOptionOrDefault(ExtractionPhase.optStrictCompilation)) { - reporter.error(funDef.getPos, "Function "+funDef.id.name+" could not be extracted. (Forgot @extern ?)") + reporter.error(funDef.getPos, "Function "+funDef.id.name+" could not be extracted. The function likely uses features not supported by Leon.") } else { reporter.warning(funDef.getPos, "Function "+funDef.id.name+" is not fully unavailable to Leon.") } @@ -1397,25 +1397,25 @@ trait CodeExtraction extends ASTExtractors { Forall(vds, exBody) - case ExCaseClassConstruction(tpt, args) => - extractType(tpt) match { - case cct: CaseClassType => - CaseClass(cct, args.map(extractTree)) + case ExFiniteMap(tptFrom, tptTo, args) => + val singletons: Seq[(LeonExpr, LeonExpr)] = args.collect { + case ExTuple(tpes, trees) if trees.size == 2 => + (extractTree(trees(0)), extractTree(trees(1))) + } - case SetType(a) => - finiteSet(args.map(extractTree).toSet, a) + if (singletons.size != args.size) { + outOfSubsetError(tr, "Some map elements could not be extracted as Tuple2") + } - case MapType(a, b) => - val singletons: Seq[(LeonExpr, LeonExpr)] = args.collect { - case ExTuple(tpes, trees) if trees.size == 2 => - (extractTree(trees(0)), extractTree(trees(1))) - } + finiteMap(singletons, extractType(tptFrom), extractType(tptTo)) - if (singletons.size != args.size) { - outOfSubsetError(tr, "Some map elements could not be extracted as Tuple2") - } + case ExFiniteSet(tpt, args) => + finiteSet(args.map(extractTree).toSet, extractType(tpt)) - finiteMap(singletons, a, b) + case ExCaseClassConstruction(tpt, args) => + extractType(tpt) match { + case cct: CaseClassType => + CaseClass(cct, args.map(extractTree)) case _ => outOfSubsetError(tr, "Construction of a non-case class.") -- GitLab