From fddd97ca76c95b9be4e0cea0a608a878d3f656d8 Mon Sep 17 00:00:00 2001 From: Etienne Kneuss <colder@php.net> Date: Fri, 25 Apr 2014 14:22:42 +0200 Subject: [PATCH] Add BinarySearchTree with isSorted and buggyMerge --- .../BinarySearchTreeSorted.scala | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 testcases/datastructures/BinarySearchTreeSorted.scala diff --git a/testcases/datastructures/BinarySearchTreeSorted.scala b/testcases/datastructures/BinarySearchTreeSorted.scala new file mode 100644 index 000000000..464335f62 --- /dev/null +++ b/testcases/datastructures/BinarySearchTreeSorted.scala @@ -0,0 +1,57 @@ +import leon.lang._ +import leon.annotation._ +import leon._ + +object BinaryTree { + sealed abstract class Tree + case class Node(left: Tree, value: Int, right: Tree) extends Tree + case class Leaf() extends Tree + + case class SortedTriple(min: Option[Int], max: Option[Int], sorted: Boolean) + + def isSortedTriple(tree: Tree) : SortedTriple = (tree match { + case Leaf() => SortedTriple(None(), None(), true) + case Node(l, v, r) => + (isSortedTriple(l), isSortedTriple(r)) match { + case (SortedTriple(minl, maxl, sortedl), SortedTriple(minr, maxr, sortedr)) => + val sorted = sortedl && sortedr && (v > maxl.getOrElse(v-1)) && (v < minr.getOrElse(v+1)) + SortedTriple(minl.orElse(Some(v)), maxr.orElse(Some(v)), sorted) + } + }) ensuring { res => res match { + case SortedTriple(Some(min), Some(max), res) => !res || (min <= max) + case SortedTriple(None(), None(), res) => res + case _ => false + }} + + def isSorted(tree: Tree): Boolean = isSortedTriple(tree).sorted + + def insert(tree: Tree, value: Int): Tree = ({ + require(isSorted(tree)) + tree match { + case Leaf() => Node(Leaf(), value, Leaf()) + case Node(l, v, r) => if (v < value) { + Node(l, v, insert(r, value)) + } else if (v > value) { + Node(insert(l, value), v, r) + } else { + Node(l,v,r) + } + } + }) ensuring (res => isSorted(res)) + + def buggyMerge(t1 : Tree, t2 : Tree) : Tree = ({ + require(isSorted(t1) && isSorted(t2)) + (t1, t2) match { + case (Leaf(), _) => t2 + case (_, Leaf()) => t1 + case (t1 @ Node(l1, v1, r1), t2 @ Node(l2, v2, r2)) => + if (v1 < v2) { + Node(buggyMerge(t1, l2), v2, r2) + } else if (v2 < v1) { + Node(buggyMerge(l1, t2), v1, r1) + } else { + Node(buggyMerge(l1, l2), v1, buggyMerge(r1, r2)) + } + } + }) ensuring (res => isSorted(res)) +} -- GitLab