Skip to content
Snippets Groups Projects
Commit 6129717f authored by Viktor Kuncak's avatar Viktor Kuncak
Browse files

The most elegant version of simple binary search tree.

parent 6d72a634
No related branches found
No related tags found
No related merge requests found
...@@ -2,41 +2,49 @@ import leon.lang._ ...@@ -2,41 +2,49 @@ import leon.lang._
import leon.collection._ import leon.collection._
object BSTSimpler { object BSTSimpler {
sealed abstract class Tree case object Leaf extends Tree
case class Node(left: Tree, value: BigInt, right: Tree) extends Tree case class Node(left: Tree, value: BigInt, right: Tree) extends Tree
case class Leaf() extends Tree sealed abstract class Tree {
def isBST: Boolean = this match {
def content(tree: Tree): Set[BigInt] = tree match { case Leaf => true
case Leaf() => Set.empty[BigInt] case Node(left, v, right) => {
case Node(l, v, r) => content(l) ++ Set(v) ++ content(r) left.isBST && right.isBST &&
} forall((x:BigInt) => (left.content.contains(x) ==> x < v)) &&
forall((x:BigInt) => (right.content.contains(x) ==> v < x))
}
}
def isBST(tree: Tree) : Boolean = tree match { def content: Set[BigInt] = this match {
case Leaf() => true case Leaf => Set.empty[BigInt]
case Node(left, v, right) => { case Node(l, v, r) => l.content ++ Set(v) ++ r.content
isBST(left) && isBST(right) &&
forall((x:BigInt) => (content(left).contains(x) ==> x < v)) &&
forall((x:BigInt) => (content(right).contains(x) ==> v < x))
} }
}
def emptySet(): Tree = Leaf() def insert(value: BigInt): Node = {
require(isBST)
this match {
case Leaf => Node(Leaf, value, Leaf)
case Node(l, v, r) => (if (v < value) {
Node(l, v, r.insert(value))
} else if (v > value) {
Node(l.insert(value), v, r)
} else {
Node(l, v, r)
})
}
} ensuring(res => res.isBST && res.content == content ++ Set(value))
def insert(tree: Tree, value: BigInt): Node = { def contains(value: BigInt): Boolean = {
require(isBST(tree)) require(isBST)
tree match { this match {
case Leaf() => Node(Leaf(), value, Leaf()) case Leaf => false
case Node(l, v, r) => (if (v < value) { case Node(l,v,r) => (if (v < value) {
Node(l, v, insert(r, value)) r.contains(value)
} else if (v > value) { } else if (v > value) {
Node(insert(l, value), v, r) l.contains(value)
} else { } else true)
Node(l, v, r) }
}) } ensuring(res => (res == content.contains(value)))
}
} ensuring(res => isBST(res) && content(res) == content(tree) ++ Set(value))
def createRoot(v: BigInt): Node = { }
Node(Leaf(), v, Leaf()) def empty: Tree = Leaf
} ensuring (content(_) == Set(v))
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment