From 05156cb23657eaf83469ddacc2b7e35e5e8d6e81 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9gis=20Blanc?= <regwblanc@gmail.com>
Date: Fri, 18 May 2012 17:42:42 +0200
Subject: [PATCH] add a List imperative and use bestRealType

---
 src/main/scala/leon/purescala/Trees.scala |  6 +--
 testcases/ListImp.scala                   | 49 +++++++++++++++++++++++
 2 files changed, 52 insertions(+), 3 deletions(-)
 create mode 100644 testcases/ListImp.scala

diff --git a/src/main/scala/leon/purescala/Trees.scala b/src/main/scala/leon/purescala/Trees.scala
index aff4f7c55..361cbf4d5 100644
--- a/src/main/scala/leon/purescala/Trees.scala
+++ b/src/main/scala/leon/purescala/Trees.scala
@@ -45,14 +45,14 @@ object Trees {
   /* Like vals */
   case class Let(binder: Identifier, value: Expr, body: Expr) extends Expr {
     binder.markAsLetBinder
-    val et = body.getType
+    val et = binder.getType
     if(et != Untyped)
       setType(et)
   }
   //same as let, buf for mutable variable declaration
   case class LetVar(binder: Identifier, value: Expr, body: Expr) extends Expr {
     binder.markAsLetBinder
-    val et = body.getType
+    val et = binder.getType
     if(et != Untyped)
       setType(et)
   }
@@ -77,7 +77,7 @@ object Trees {
   case class IfExpr(cond: Expr, then: Expr, elze: Expr) extends Expr 
 
   case class Tuple(exprs: Seq[Expr]) extends Expr {
-    val subTpes = exprs.map(_.getType)
+    val subTpes = exprs.map(_.getType).map(bestRealType)
     if(!subTpes.exists(_ == Untyped)) {
       setType(TupleType(subTpes))
     }
diff --git a/testcases/ListImp.scala b/testcases/ListImp.scala
new file mode 100644
index 000000000..f3887419e
--- /dev/null
+++ b/testcases/ListImp.scala
@@ -0,0 +1,49 @@
+import leon.Utils._
+
+object ListImp {
+
+  sealed abstract class List
+  case class Cons(head: Int, tail: List) extends List
+  case class Nil() extends List
+
+  def content(l: List) : Set[Int] = l match {
+    case Nil() => Set.empty[Int]
+    case Cons(x, xs) => Set(x) ++ content(xs)
+  }
+
+  def size(l: List) : Int = {
+    var r = 0
+    (while(!l.isInstanceOf[Nil]) {
+      r = r+1
+    }) invariant(r >= 0)
+    r
+  } ensuring(res => res >= 0)
+
+  def reverse(l: List): List = {
+    var r: List = Nil()
+    var l2: List = l
+
+    (while(!l2.isInstanceOf[Nil]) {
+      val Cons(head, tail) = l2
+      l2 = tail
+      r = Cons(head, r)
+    }) invariant(content(r) ++ content(l2) == content(l))
+
+    r
+  } ensuring(res => content(res) == content(l))
+
+  def append(l1 : List, l2 : List) : List = {
+    var r: List = l2
+    var tmp: List = reverse(l1)
+
+    (while(!tmp.isInstanceOf[Nil]) {
+      val Cons(head, tail) = tmp
+      tmp = tail
+      r = Cons(head, r)
+    }) invariant(content(r) ++ content(tmp) == content(l1) ++ content(l2))
+
+    r
+  } ensuring(content(_) == content(l1) ++ content(l2))
+
+
+}
-- 
GitLab