From 7ce76f84593da95250615e6360f07bf696dc1bf1 Mon Sep 17 00:00:00 2001 From: Philippe Suter <philippe.suter@gmail.com> Date: Wed, 13 Jul 2011 06:18:03 +0000 Subject: [PATCH] Now with red-black trees --- cp-demo/PaperExamples.scala | 85 +++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/cp-demo/PaperExamples.scala b/cp-demo/PaperExamples.scala index 437f1e376..acfa87ed0 100644 --- a/cp-demo/PaperExamples.scala +++ b/cp-demo/PaperExamples.scala @@ -134,6 +134,91 @@ object PaperExamples extends App { } Primes.run + object RedBlackTrees extends Demo { + val name = "red-black trees" + + @spec sealed abstract class Color + @spec case class Red() extends Color + @spec case class Black() extends Color + + @spec sealed abstract class Tree + @spec case class Node(c : Color, l : Tree, v : Int, r : Tree) extends Tree + @spec case class Leaf() extends Tree + + @spec sealed abstract class OptionInt + @spec case class SomeInt(v : Int) extends OptionInt + @spec case class NoneInt() extends OptionInt + + @spec def size(t : Tree) : Int = (t match { + case Leaf() => 0 + case Node(_, l, _, r) => 1 + size(l) + size(r) + }) ensuring(_ >= 0) + + @spec def blackBalanced(t : Tree) : Boolean = t match { + case Node(_,l,_,r) => blackBalanced(l) && blackBalanced(r) && blackHeight(l) == blackHeight(r) + case Leaf() => true + } + + @spec def isBlack(t: Tree) : Boolean = t match { + case Leaf() => true + case Node(Black(),_,_,_) => true + case _ => false + } + + @spec def redNodesHaveBlackChildren(t: Tree) : Boolean = t match { + case Leaf() => true + case Node(Black(), l, _, r) => redNodesHaveBlackChildren(l) && redNodesHaveBlackChildren(r) + case Node(Red(), l, _, r) => isBlack(l) && isBlack(r) && redNodesHaveBlackChildren(l) && redNodesHaveBlackChildren(r) + } + + @spec def blackHeight(t : Tree) : Int = t match { + case Leaf() => 0 + case Node(Black(), l, _, _) => blackHeight(l) + 1 + case Node(Red(), l, _, _) => blackHeight(l) + } + + @spec def validColoring(t : Tree) : Boolean = { + isBlack(t) && redNodesHaveBlackChildren(t) && blackBalanced(t) + } + + @spec def valuesWithin(t : Tree, bound : Int) : Boolean = t match { + case Leaf() => true + case Node(_,l,v,r) => 0 < v && v <= bound && valuesWithin(l,bound) && valuesWithin(r,bound) + } + + @spec def orderedKeys(t : Tree) : Boolean = orderedKeys(t, NoneInt(), NoneInt()) + + @spec def orderedKeys(t : Tree, min : OptionInt, max : OptionInt) : Boolean = t match { + case Leaf() => true + case Node(c,a,v,b) => + val minOK = + min match { + case SomeInt(minVal) => + v > minVal + case NoneInt() => true + } + val maxOK = + max match { + case SomeInt(maxVal) => + v < maxVal + case NoneInt() => true + } + minOK && maxOK && orderedKeys(a, min, SomeInt(v)) && orderedKeys(b, SomeInt(v), max) + } + + @spec def validTree(t : Tree) : Boolean = { + validColoring(t) && orderedKeys(t) + } + + def action : Unit = { + (1 to 7).foreach(i => { + val num = ((t : Tree) => validTree(t) && valuesWithin(t,i) && size(t) == i).findAll.size + p("# of RBTs with " + i + " distinct els", num) + }) + } + } + RedBlackTrees.run + object SendMoreMoney extends Demo { val name = "SEND+MORE=MONEY" -- GitLab