From 2bb9282dadfcbeeaee205a807cf23698181ebfb5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ali=20Sinan=20K=C3=B6ksal?= <alisinan@gmail.com>
Date: Sun, 14 Nov 2010 18:38:16 +0000
Subject: [PATCH] Copying sorting and RB tree examples from testcases

---
 pldi2011-testcases/InsertionSort.scala | 98 ++++++++++++++++++++++++++
 pldi2011-testcases/MergeSort.scala     | 66 +++++++++++++++++
 pldi2011-testcases/QuickSort.scala     | 58 +++++++++++++++
 pldi2011-testcases/RedBlackTree.scala  | 54 ++++++++++++++
 pldi2011-testcases/TreeMap.scala       | 41 +++++++----
 5 files changed, 302 insertions(+), 15 deletions(-)
 create mode 100644 pldi2011-testcases/InsertionSort.scala
 create mode 100644 pldi2011-testcases/MergeSort.scala
 create mode 100644 pldi2011-testcases/QuickSort.scala
 create mode 100644 pldi2011-testcases/RedBlackTree.scala

diff --git a/pldi2011-testcases/InsertionSort.scala b/pldi2011-testcases/InsertionSort.scala
new file mode 100644
index 000000000..0db222160
--- /dev/null
+++ b/pldi2011-testcases/InsertionSort.scala
@@ -0,0 +1,98 @@
+import scala.collection.immutable.Set
+import funcheck.Utils._
+
+object InsertionSort {
+  sealed abstract class List
+  case class Cons(head:Int,tail:List) extends List
+  case class Nil() extends List
+
+  sealed abstract class OptInt
+  case class Some(value: Int) extends OptInt
+  case class None() extends OptInt
+
+  def size(l : List) : Int = (l match {
+    case Nil() => 0
+    case Cons(_, xs) => 1 + size(xs)
+  }) ensuring(_ >= 0)
+
+  def contents(l: List): Set[Int] = l match {
+    case Nil() => Set.empty
+    case Cons(x,xs) => contents(xs) ++ Set(x)
+  }
+
+  def min(l : List) : OptInt = l match {
+    case Nil() => None()
+    case Cons(x, xs) => min(xs) match {
+      case None() => Some(x)
+      case Some(x2) => if(x < x2) Some(x) else Some(x2)
+    }
+  }
+
+  def minProp0(l : List) : Boolean = (l match {
+    case Nil() => true
+    case c @ Cons(x, xs) => min(c) match {
+      case None() => false
+      case Some(m) => x >= m
+    }
+  }) holds
+
+  def minProp1(l : List) : Boolean = {
+    require(isSorted(l) && size(l) <= 5)
+    l match {
+      case Nil() => true
+      case c @ Cons(x, xs) => min(c) match {
+        case None() => false
+        case Some(m) => x == m
+      }
+    }
+  } holds
+
+  def isSorted(l: List): Boolean = l match {
+    case Nil() => true
+    case Cons(x, Nil()) => true
+    case Cons(x, Cons(y, ys)) => x <= y && isSorted(Cons(y, ys))
+  }   
+
+//  def sortedInsInduct0(e: Int, l: List) : List = {
+//    require(l == Nil())
+//    l match {
+//      case Nil() => Cons(e,Nil())
+//      case Cons(x,xs) => if (x <= e) Cons(x,sortedIns(e, xs)) else Cons(e, l)
+//    } 
+//  } ensuring(res => isSorted(res))
+//
+//  def sortedInsInduct1(e: Int, l: List) : List = {
+//    require(
+//      isSorted(l) &&
+//      (l match {
+//        case Nil() => false
+//        case Cons(x,xs) => isSorted(sortedIns(e,xs))
+//       })
+//     )
+//
+//    l match {
+//      case Nil() => Cons(e,Nil())
+//      case Cons(x,xs) => if (x <= e) Cons(x,sortedIns(e, xs)) else Cons(e, l)
+//    } 
+//  } ensuring(res => isSorted(res))
+
+  def sortedIns(e: Int, l: List): List = {
+    require(isSorted(l) && size(l) <= 5)
+    l match {
+      case Nil() => Cons(e,Nil())
+      case Cons(x,xs) => if (x <= e) Cons(x,sortedIns(e, xs)) else Cons(e, l)
+    } 
+  } ensuring(res => contents(res) == contents(l) ++ Set(e) && isSorted(res))
+
+  def sort(l: List): List = (l match {
+    case Nil() => Nil()
+    case Cons(x,xs) => sortedIns(x, sort(xs))
+  }) ensuring(res => contents(res) == contents(l) && isSorted(res))
+
+  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(sort(ls))
+  }
+}
diff --git a/pldi2011-testcases/MergeSort.scala b/pldi2011-testcases/MergeSort.scala
new file mode 100644
index 000000000..da575c8bb
--- /dev/null
+++ b/pldi2011-testcases/MergeSort.scala
@@ -0,0 +1,66 @@
+import scala.collection.immutable.Set
+
+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 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 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(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 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))
+  }
+}
diff --git a/pldi2011-testcases/QuickSort.scala b/pldi2011-testcases/QuickSort.scala
new file mode 100644
index 000000000..83dd2c364
--- /dev/null
+++ b/pldi2011-testcases/QuickSort.scala
@@ -0,0 +1,58 @@
+import scala.collection.immutable.Set
+
+object QuickSort {
+  sealed abstract class List
+  case class Cons(head:Int,tail:List) extends List
+  case class Nil() extends List
+
+  def contents(l: List): Set[Int] = l match {
+    case Nil() => Set.empty
+    case Cons(x,xs) => contents(xs) ++ Set(x)
+  }
+
+  def is_sorted(l: List): Boolean = l match {
+    case Nil() => true
+    case Cons(x,Nil()) => true
+    case Cons(x,Cons(y,xs)) => x<=y && is_sorted(Cons(y,xs))
+  }
+
+  def rev_append(aList:List,bList:List): List = aList match {
+    case Nil() => bList
+    case Cons(x,xs) => rev_append(xs,Cons(x,bList))
+  }
+
+  def reverse(list:List): List = rev_append(list,Nil())
+
+  def append(aList:List,bList:List): List = aList match {
+    case Nil() => bList
+    case _ => rev_append(reverse(aList),bList)
+  }
+  
+  def greater(n:Int,list:List) : List = list match {
+    case Nil() => Nil()
+    case Cons(x,xs) => if (n < x) Cons(x,greater(n,xs)) else greater(n,xs)
+  }
+
+  def smaller(n:Int,list:List) : List = list match {
+    case Nil() => Nil()
+    case Cons(x,xs) => if (n>x) Cons(x,smaller(n,xs)) else smaller(n,xs)
+  }
+
+  def equals(n:Int,list:List) : List = list match {
+    case Nil() => Nil()
+    case Cons(x,xs) => if (n==x) Cons(x,equals(n,xs)) else equals(n,xs)
+  }
+
+  def quickSort(list:List): List = (list match {
+    case Nil() => Nil()
+    case Cons(x,Nil()) => list
+    case Cons(x,xs) => append(append(quickSort(smaller(x,xs)),Cons(x,equals(x,xs))),quickSort(greater(x,xs)))
+  }) ensuring(res => contents(res) == contents(list)) // && is_sorted(res))
+
+  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(quickSort(ls))
+  }
+}
diff --git a/pldi2011-testcases/RedBlackTree.scala b/pldi2011-testcases/RedBlackTree.scala
new file mode 100644
index 000000000..04ccb08fa
--- /dev/null
+++ b/pldi2011-testcases/RedBlackTree.scala
@@ -0,0 +1,54 @@
+import scala.collection.immutable.Set
+//import scala.collection.immutable.Multiset
+
+object RedBlackTree { 
+  sealed abstract class Color
+  case class Red() extends Color
+  case class Black() extends Color
+ 
+  sealed abstract class Tree
+  case class Empty() extends Tree
+  case class Node(color: Color, left: Tree, value: Int, right: Tree) extends Tree
+
+  def content(t : Tree) : Set[Int] = t match {
+    case Empty() => Set.empty
+    case Node(_, l, v, r) => content(l) ++ Set(v) ++ content(r)
+  }
+
+  def size(t : Tree) : Int = t match {
+    case Empty() => 0
+    case Node(_, l, v, r) => size(l) + 1 + size(r)
+  }
+
+  def ins(x : Int, t: Tree): Tree = (t match {
+    case Empty() => Node(Red(),Empty(),x,Empty())
+    case Node(c,a,y,b) =>
+      if      (x < y)  balance(c, ins(x, a), y, b)
+      else if (x == y) Node(c,a,y,b)
+      else             balance(c,a,y,ins(x, b))
+  }) ensuring (res => (
+             content(res) == content(t) ++ Set(x) 
+//          && size(t) <= size(res) && size(res) < size(t) + 2)
+              ))
+
+  def add(x: Int, t: Tree): Tree = {
+    makeBlack(ins(x, t))
+  } ensuring (content(_) == content(t) ++ Set(x))
+  
+  def balance(c: Color, a: Tree, x: Int, b: Tree): Tree = (Node(c,a,x,b) match {
+    case Node(Black(),Node(Red(),Node(Red(),a,xV,b),yV,c),zV,d) => 
+      Node(Red(),Node(Black(),a,xV,b),yV,Node(Black(),c,zV,d))
+    case Node(Black(),Node(Red(),a,xV,Node(Red(),b,yV,c)),zV,d) => 
+      Node(Red(),Node(Black(),a,xV,b),yV,Node(Black(),c,zV,d))
+    case Node(Black(),a,xV,Node(Red(),Node(Red(),b,yV,c),zV,d)) => 
+      Node(Red(),Node(Black(),a,xV,b),yV,Node(Black(),c,zV,d))
+    case Node(Black(),a,xV,Node(Red(),b,yV,Node(Red(),c,zV,d))) => 
+      Node(Red(),Node(Black(),a,xV,b),yV,Node(Black(),c,zV,d))
+    case Node(c,a,xV,b) => Node(c,a,xV,b)
+  }) ensuring (res => content(res) == content(Node(c,a,x,b)))
+
+  def makeBlack(n: Tree): Tree = n match {
+    case Node(Red(),l,v,r) => Node(Black(),l,v,r)
+    case _ => n
+  }
+}
diff --git a/pldi2011-testcases/TreeMap.scala b/pldi2011-testcases/TreeMap.scala
index 5b734cf92..821458aa0 100644
--- a/pldi2011-testcases/TreeMap.scala
+++ b/pldi2011-testcases/TreeMap.scala
@@ -76,12 +76,18 @@ object TreeMap {
   }
 
   def create(k: Int, d: Int, l: TreeMap, r: TreeMap): TreeMap = {
-    require(nodeHeightsAreCorrect(l) && nodeHeightsAreCorrect(r) && isBalanced(l) && isBalanced(r) &&
-      height(l) - height(r) <= 2 && height(r) - height(l) <= 2)
+    require(
+      nodeHeightsAreCorrect(l) && nodeHeightsAreCorrect(r) && isBalanced(l) && isBalanced(r) &&
+      height(l) - height(r) <= 2 && height(r) - height(l) <= 2 &&
+      isBST(l) && isBST(r) // and max l < min r
+    )
     val hl = height(l)
     val hr = height(r)
     Node(k, d, l, r, mmax(hl, hr) + 1)
-  } ensuring(res => setOf(res) == Set(k) ++ setOf(l) ++ setOf(r) && isBalanced(res))
+  } ensuring(
+    res => setOf(res) == Set(k) ++ setOf(l) ++ setOf(r) && 
+    isBalanced(res) && isBST(res)
+  )
 
   def balance(x: Int, d: Int, l: TreeMap, r: TreeMap): TreeMap = {
     require(
@@ -125,7 +131,7 @@ object TreeMap {
       }
     } else
       Node(x, d, l, r, if(hl >= hr) hl + 1 else hr + 1)
-  } ensuring(isBalanced(_))
+  } ensuring(res => isBalanced(res)) // && setOf(res) == Set[Int](x) ++ setOf(l) ++ setOf(r))
 
   def add(x: Int, data: Int, tm: TreeMap): TreeMap = {
     require(isBalanced(tm) && nodeHeightsAreCorrect(tm))
@@ -139,9 +145,9 @@ object TreeMap {
         else
           balance(v, d, l, add(x, data, r))
     }
-  } ensuring(isBalanced(_))
+  } ensuring(res => isBalanced(res)) // && setOf(res) == Set(x) ++ setOf(tm))
 
-  def removeMinBinding(t: TreeMap): Triple = {
+  def removeMinBinding(t: TreeMap): Tuple = {
     require(isBalanced(t) && (t match {
       case Empty() => false
       case _ => true
@@ -151,11 +157,15 @@ object TreeMap {
         l match {
           case Empty() => Triple(x, d, r)
           case Node(_,_,ll, lr, h2) =>
-            val triple = removeMinBinding(l)
-            Triple(triple.key, triple.datum, balance(x, d, triple.tree, r))
+            removeMinBinding(l) match {
+              case Triple(key, datum, tree) =>
+                Triple(key, datum, balance(x, d, tree, r))
+            }
         }
     }
-  } ensuring(res => isBalanced(res.tree))
+  } ensuring(res => res match {
+    case Triple(resKey, _, resTree) => isBalanced(resTree) // && (setOf(resTree) == setOf(t) -- Set(resKey)) && setOf(resTree) ++ Set(resKey) == setOf(t)
+  })
 
   // m is not used here!
   def merge(m: Int, t1: TreeMap, t2: TreeMap): TreeMap = {
@@ -166,11 +176,12 @@ object TreeMap {
         t2 match {
           case Empty() => t1
           case Node(r, _, rl, rr, h2) =>
-            val triple = removeMinBinding(t2)
-            balance(triple.key, triple.datum, t1, triple.tree)
+            removeMinBinding(t2) match {
+              case Triple(key, datum, tree) => balance(key, datum, t1, tree)
+            }
         }
     }
-  } ensuring(isBalanced(_))
+  } ensuring(res => isBalanced(res)) // && setOf(res) == setOf(t1) ++ setOf(t2))
 
   def remove(x: Int, t: TreeMap): TreeMap = {
     require(isBalanced(t))
@@ -184,7 +195,7 @@ object TreeMap {
         else
           balance(v, d, l, remove(x, r))
     }
-  } ensuring(isBalanced(_))
+  } ensuring(res => isBalanced(res)) // && (setOf(res) == setOf(t) -- Set(x)))
 
   def find(t: TreeMap, x: Int): Int = {
     require(t match {
@@ -216,10 +227,10 @@ object TreeMap {
       v < k && iter2(l, v) && iter2(r, v)
   }
 
-  def checkBST(t: TreeMap): Boolean = t match {
+  def isBST(t: TreeMap): Boolean = t match {
     case Empty() => true
     case Node(v, _, l, r, _) =>
-      iter1(l, v) && iter2(r, v) && checkBST(l) && checkBST(r)
+      iter1(l, v) && iter2(r, v) && isBST(l) && isBST(r)
   }
 
   // We have a variant of AVL trees where the heights of the subtrees differ at
-- 
GitLab