From 08d644c054d786f9e10d3013a84a3dfa36dc8a5e Mon Sep 17 00:00:00 2001
From: Etienne Kneuss <ekneuss@gmail.com>
Date: Mon, 27 Apr 2015 01:02:53 +0200
Subject: [PATCH] Add Ravi's benchmarks

---
 testcases/web/verification/14_HeapSort.scala  | 147 ++++++++++++++++++
 .../web/verification/15_LeftistHeap.scala     | 141 +++++++++++++++++
 2 files changed, 288 insertions(+)
 create mode 100644 testcases/web/verification/14_HeapSort.scala
 create mode 100644 testcases/web/verification/15_LeftistHeap.scala

diff --git a/testcases/web/verification/14_HeapSort.scala b/testcases/web/verification/14_HeapSort.scala
new file mode 100644
index 000000000..22d9d55f3
--- /dev/null
+++ b/testcases/web/verification/14_HeapSort.scala
@@ -0,0 +1,147 @@
+import leon.lang._
+import leon.collection._
+
+object HeapSort {
+  sealed abstract class Heap
+  case class Leaf() extends Heap
+  case class Node(rk: BigInt, value: BigInt, left: Heap, right: Heap) extends Heap
+
+  def rightHeight(h: Heap): BigInt = {
+    h match {
+      case Leaf() => 0
+      case Node(_, _, _, r) => rightHeight(r) + 1
+    }
+  } ensuring (_ >= 0)
+
+  def rank(h: Heap): BigInt = h match {
+    case Leaf() => 0
+    case Node(rk, _, _, _) => rk
+  }
+
+  def max(x: BigInt, y: BigInt): BigInt = {
+    if (x <= y) y else x
+  }
+
+  def rootVal(h: Heap): BigInt = {
+    require(h != Leaf())
+    h match {
+      case Node(_, v, _, _) => v
+    }
+  }
+
+  private def hasLeftistProperty(h: Heap): Boolean = (h match {
+    case Leaf() => true
+    case Node(_, v, l, r) => hasLeftistProperty(l) && hasLeftistProperty(r) &&
+      // properties about rank (necessary for proving running time)
+      rightHeight(l) >= rightHeight(r) && (rank(h) == rightHeight(h)) &&
+      // properties of a max heap
+      (l == Leaf() || v >= rootVal(l)) && (r == Leaf() || v >= rootVal(r))
+  })
+
+  def heapSize(t: Heap): BigInt = {
+    (t match {
+      case Leaf() => 0
+      case Node(_, v, l, r) => heapSize(l) + 1 + heapSize(r)
+    })
+  } ensuring (_ >= 0)
+
+  def heapContents(t: Heap): Set[BigInt] = {
+    t match {
+      case Leaf() => Set()
+      case Node(_, v, l, r) =>
+        Set(v) ++ heapContents(l) ++ heapContents(r)
+    }
+  }
+
+  def merge(h1: Heap, h2: Heap): Heap = {
+    require(hasLeftistProperty(h1) && hasLeftistProperty(h2))
+    h1 match {
+      case Leaf() => h2
+      case Node(_, v1, l1, r1) => h2 match {
+        case Leaf() => h1
+        case Node(_, v2, l2, r2) =>
+          if (v1 > v2)
+            makeT(v1, l1, merge(r1, h2))
+          else
+            makeT(v2, l2, merge(h1, r2))
+      }
+    }
+  } ensuring (res =>
+    //the root value is one of the root values of the merged heaps
+    (res match {
+      case Leaf() => h1 == Leaf() && h2 == Leaf()
+      case Node(_, v, _, _) =>
+        (h1 != Leaf() && rootVal(h1) == v) || (h2 != Leaf() && rootVal(h2) == v)
+    }) &&
+      hasLeftistProperty(res) &&
+      heapSize(h1) + heapSize(h2) == heapSize(res) &&
+      heapContents(h1) ++ heapContents(h2) == heapContents(res))
+
+  private def makeT(value: BigInt, left: Heap, right: Heap): Heap = {
+    if (rank(left) >= rank(right))
+      Node(rank(right) + 1, value, left, right)
+    else
+      Node(rank(left) + 1, value, right, left)
+  }
+
+  def insert(element: BigInt, heap: Heap): Heap = {
+    require(hasLeftistProperty(heap))
+
+    merge(Node(1, element, Leaf(), Leaf()), heap)
+
+  } ensuring (res => heapSize(res) == heapSize(heap) + 1 &&
+    heapContents(res) == Set(element) ++ heapContents(heap))
+
+  def findMax(h: Heap): BigInt = {
+    require(hasLeftistProperty(h) && h != Leaf())
+    rootVal(h)
+  }
+
+  def removeMax(h: Heap): Heap = {
+    require(hasLeftistProperty(h))
+    h match {
+      case Node(_, _, l, r) => merge(l, r)
+      case l @ Leaf() => l
+    }
+  } ensuring (res => hasLeftistProperty(res) &&
+    (h == Leaf() || heapContents(h) == heapContents(res) ++ Set(findMax(h))) &&
+    (res == Leaf() || findMax(res) <= findMax(h)))
+
+  def sortedDescending(l: List[BigInt]): Boolean = {
+    l match {
+      case Nil() => true
+      case Cons(x, Nil()) => true
+      case Cons(x, tail @ Cons(y, _)) =>
+        (x >= y) && sortedDescending(tail)
+    }
+  }
+
+  def removeElements(h: Heap): List[BigInt] = {
+    require(hasLeftistProperty(h))
+    h match {
+      case Leaf() => Nil[BigInt]()
+      case _ =>
+        Cons(findMax(h), removeElements(removeMax(h)))
+    }
+  } ensuring (res => sortedDescending(res) &&
+    heapSize(h) == res.size && //sizes are preserved 
+    heapContents(h) == res.content //contents are preserved
+    )
+
+  def buildHeap(l: List[BigInt]): Heap = {
+    l match {
+      case Nil() => Leaf()
+      case Cons(x, xs) => insert(x, buildHeap(xs))
+    }
+  } ensuring (res => hasLeftistProperty(res) &&
+    heapContents(res) == l.content && //contents are preserved
+    heapSize(res) == l.size) //sizes are preserved       
+
+  def heapSort(l: List[BigInt]): List[BigInt] = ({
+
+    val heap = buildHeap(l)
+    removeElements(heap)
+
+  }) ensuring (res => sortedDescending(res) && //elements are in descending order
+    res.size == l.size && res.content == l.content) //contents and sizes are preserved    
+}
diff --git a/testcases/web/verification/15_LeftistHeap.scala b/testcases/web/verification/15_LeftistHeap.scala
new file mode 100644
index 000000000..356af0154
--- /dev/null
+++ b/testcases/web/verification/15_LeftistHeap.scala
@@ -0,0 +1,141 @@
+import leon.lang._
+import leon.collection._
+
+object HeapSort {
+  sealed abstract class Heap
+  case class Leaf() extends Heap
+  case class Node(rk: BigInt, value: BigInt, left: Heap, right: Heap) extends Heap
+
+  def rightHeight(h: Heap): BigInt = {
+    h match {
+      case Leaf() => 0
+      case Node(_, _, _, r) => rightHeight(r) + 1
+    }
+  } ensuring (_ >= 0)
+
+  def rank(h: Heap): BigInt = h match {
+    case Leaf() => 0
+    case Node(rk, _, _, _) => rk
+  }
+
+  def max(x: BigInt, y: BigInt): BigInt = {
+    if (x <= y) y else x
+  }
+
+  def rootVal(h: Heap): BigInt = {
+    require(h != Leaf())
+    h match {
+      case Node(_, v, _, _) => v
+    }
+  }
+
+  private def hasLeftistProperty(h: Heap): Boolean = (h match {
+    case Leaf() => true
+    case Node(_, v, l, r) => hasLeftistProperty(l) && hasLeftistProperty(r) &&
+      // properties about rank (necessary for proving running time)
+      rightHeight(l) >= rightHeight(r) && (rank(h) == rightHeight(h)) &&
+      // properties of a max heap
+      (l == Leaf() || v >= rootVal(l)) && (r == Leaf() || v >= rootVal(r))
+  })
+
+  def heapSize(t: Heap): BigInt = {
+    (t match {
+      case Leaf() => 0
+      case Node(_, v, l, r) => heapSize(l) + 1 + heapSize(r)
+    })
+  } ensuring (_ >= 0)
+
+  def heapContents(t: Heap): Set[BigInt] = {
+    t match {
+      case Leaf() => Set()
+      case Node(_, v, l, r) =>
+        Set(v) ++ heapContents(l) ++ heapContents(r)
+    }
+  }
+
+  def merge(h1: Heap, h2: Heap): Heap = {
+    require(hasLeftistProperty(h1) && hasLeftistProperty(h2))
+    h1 match {
+      case Leaf() => h2
+      case Node(_, v1, l1, r1) => h2 match {
+        case Leaf() => h1
+        case Node(_, v2, l2, r2) =>
+          if (v1 > v2)
+            makeT(v1, l1, merge(r1, h2))
+          else
+            makeT(v2, l2, merge(h1, r2))
+      }
+    }
+  } ensuring (res =>
+    //the root value is one of the root values of the merged heaps
+    (res match {
+      case Leaf() => h1 == Leaf() && h2 == Leaf()
+      case Node(_, v, _, _) =>
+        (h1 != Leaf() && rootVal(h1) == v) || (h2 != Leaf() && rootVal(h2) == v)
+    }) &&
+      hasLeftistProperty(res) &&
+      heapSize(h1) + heapSize(h2) == heapSize(res) &&
+      heapContents(h1) ++ heapContents(h2) == heapContents(res))
+
+  private def makeT(value: BigInt, left: Heap, right: Heap): Heap = {
+    if (rank(left) >= rank(right))
+      Node(rank(right) + 1, value, left, right)
+    else
+      Node(rank(left) + 1, value, right, left)
+  }
+
+  def insert(element: BigInt, heap: Heap): Heap = {
+    require(hasLeftistProperty(heap))
+
+    merge(Node(1, element, Leaf(), Leaf()), heap)
+
+  } ensuring (res => heapSize(res) == heapSize(heap) + 1 &&
+    heapContents(res) == Set(element) ++ heapContents(heap))
+
+  def listMax(l: List[BigInt]): BigInt = {
+    require(l != Nil[BigInt]())
+    l match {
+      case Cons(x, Nil()) =>
+        x
+      case Cons(x, tail) =>
+        max(x, listMax(tail))
+    }
+  }
+
+  def append(l1: List[BigInt], l2: List[BigInt]): List[BigInt] = {
+    l1 match {
+      case Nil() => l2
+      case Cons(x, tail) =>
+        Cons(x, append(tail, l2))
+    }
+  } ensuring (res => (l2 != Nil[BigInt]() || res == l1) &&
+    (res == Nil[BigInt]() ||
+      ((l1 == Nil[BigInt]() && listMax(res) == listMax(l2)) ||
+        (l2 == Nil[BigInt]() && listMax(res) == listMax(l1)) ||
+        (listMax(res) == max(listMax(l1), listMax(l2))))))
+
+  def heapElements(t: Heap): List[BigInt] = {
+    require(hasLeftistProperty(t))
+    t match {
+      case Leaf() => Nil()
+      case Node(_, v, l, r) =>
+        v :: append(heapElements(l), heapElements(r))
+    }
+  } ensuring (res => t == Leaf() ||
+    (res != Nil[BigInt]() && rootVal(t) == listMax(res)))
+
+  def findMax(h: Heap): BigInt = {
+    require(hasLeftistProperty(h) && h != Leaf())
+    rootVal(h)
+  } ensuring (res => res == listMax(heapElements(h))) // max heap property
+
+  def removeMax(h: Heap): Heap = {
+    require(hasLeftistProperty(h))
+    h match {
+      case Node(_, _, l, r) => merge(l, r)
+      case l @ Leaf() => l
+    }
+  } ensuring (res => hasLeftistProperty(res) &&
+    (h == Leaf() || heapContents(h) == heapContents(res) ++ Set(findMax(h))) &&
+    (res == Leaf() || findMax(res) <= findMax(h)))
+}
-- 
GitLab