From 5516de65c3e98742c816af31ca999ac7663c4432 Mon Sep 17 00:00:00 2001
From: Manos Koukoutos <emmanouil.koukoutos@epfl.ch>
Date: Thu, 10 Mar 2016 15:05:15 +0100
Subject: [PATCH] Fix this benchmark

---
 .../list-algorithms/MergeSort.scala           | 93 ++++++++-----------
 1 file changed, 39 insertions(+), 54 deletions(-)

diff --git a/testcases/verification/list-algorithms/MergeSort.scala b/testcases/verification/list-algorithms/MergeSort.scala
index 5fc80d117..ed4cda282 100644
--- a/testcases/verification/list-algorithms/MergeSort.scala
+++ b/testcases/verification/list-algorithms/MergeSort.scala
@@ -1,67 +1,52 @@
 import leon.lang._
-import leon.annotation._
+import synthesis._
+import leon.collection._
 
 object MergeSort {
-  sealed abstract class List
-  case class Cons(head:Int,tail:List) extends List
-  case class Nil() extends List
 
-  case class Pair(fst:List,snd:List)
-
-  def contents(l: List): Set[Int] = l match {
-    case Nil() => Set.empty
-    case Cons(x,xs) => contents(xs) ++ Set(x)
+  def isSorted(l: List[BigInt]): Boolean = l match {
+    case Cons(x, t@Cons(y, _)) => x <= y && isSorted(t)
+    case _ => true
   }
 
-  def is_sorted(l: List): Boolean = l match {
-    case Nil() => true
-    case Cons(x,xs) => xs match {
-      case Nil() => true
-      case Cons(y, ys) => x <= y && is_sorted(Cons(y, ys))
+  def merge(l1: List[BigInt], l2: List[BigInt]): List[BigInt] = {
+    require(isSorted(l1) && isSorted(l2))
+    (l1, l2) match {
+      case (Nil(), _) => l2
+      case (_, Nil()) => l1
+      case (Cons(h1,t1), Cons(h2, t2)) =>
+        if (h1 <= h2) Cons(h1, merge(t1, l2))
+        else          Cons(h2, merge(l1, t2))
     }
+  } ensuring { 
+    (res: List[BigInt]) =>
+      isSorted(res) && 
+      res.content == l1.content ++ l2.content &&
+      res.size == l1.size + l2.size
   }
 
-  def length(list:List): Int = list match {
-    case Nil() => 0
-    case Cons(x,xs) => 1 + length(xs)
-  }
-
-  def splithelper(aList:List,bList:List,n:Int): Pair =
-    if (n <= 0) Pair(aList,bList)
-    else
-    bList match {
-              case Nil() => Pair(aList,bList)
-              case Cons(x,xs) => splithelper(Cons(x,aList),xs,n-1)
+  def split(l: List[BigInt]): (List[BigInt], List[BigInt]) = {
+    l match {
+      case Cons(h1, Cons(h2, tail)) =>
+        val (rec1, rec2) = split(tail)
+        (h1 :: rec1, h2 :: rec2)
+      case _ => (l, Nil[BigInt]())
     }
+  } ensuring { (res: (List[BigInt], List[BigInt])) =>
+    val (r1, r2) = res
+    r1.size + r2.size == l.size &&
+    r1.content ++ r2.content == l.content &&
+    r1.size - r2.size <= 1 &&
+    r2.size - r1.size <= 1
+  }
 
-  def split(list:List,n:Int): Pair = splithelper(Nil(),list,n)
-
-  def merge(aList:List, bList:List):List = (bList match {
-    case Nil() => aList
-    case Cons(x,xs) =>
-         aList match {
-           case Nil() => bList
-           case Cons(y,ys) =>
-                if (y < x)
-               Cons(y,merge(ys, bList))
-            else
-           Cons(x,merge(aList, xs))
-     }
-  }) ensuring(res => contents(res) == contents(aList) ++ contents(bList))
-
-  def mergeSort(list:List):List = (list match {
-    case Nil() => list
-    case Cons(x,Nil()) => list
-    case _ =>
-         val p = split(list,length(list)/2)
-     merge(mergeSort(p.fst), mergeSort(p.snd))
-  }) ensuring(res => contents(res) == contents(list) && is_sorted(res))
-
+  def mergeSort(l: List[BigInt]): List[BigInt] = {
+    val (l1, l2) = split(l)
+    merge(mergeSort(l1), mergeSort(l2))
+  } ensuring ( res =>
+    isSorted(res) && 
+    res.content == l.content &&
+    res.size == l.size
+  )
 
-  @ignore
-  def main(args: Array[String]): Unit = {
-    val ls: List = Cons(5, Cons(2, Cons(4, Cons(5, Cons(1, Cons(8,Nil()))))))
-    println(ls)
-    println(mergeSort(ls))
-  }
 }
-- 
GitLab