Scaludita Examples
Scaludita is based on Udita system but adapted to Scala by Tihomir Gvero
Finding a Solution of Simple Constraint
def assume(p : Boolean) = Verify.ignoreIf(!p) def choose = Verify.getInt(1,20) val y = 11 val x = choose assume(10 < y && x < 5 && y < 3*x) println("x = " + x)
Structural Constraints: Red-Black Tree Implementation
package redblacktree import gov.nasa.jpf.jvm.Verify; import gov.nasa.jpf.jvm.generators.StructureCounter; object RedBlackTreeTest extends Application { val MAXTREESIZE = 4 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 member(x: Int, t:Tree): Boolean = t match { case Empty() => false case Node(_,a,y,b) => if (x < y) member(x,a) else if (x > y) member(x,b) else true } def insert(x: Int, t: Tree): Tree = { def ins(t: Tree): Tree = t match { case Empty() => Node(RED(),Empty(),x,Empty()) case Node(c,a,y,b) => if (x < y) balance(c, ins(a), y, b) else if (x == y) Node(c,a,y,b) else // balance(c,a,y,ins(b)) Node(c,a,y,ins(b)) } makeBlack(ins(t)) } def balance(c: Color, a: Tree, x: Int, b: Tree): Tree = (c,a,x,b) match { case (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 (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 (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 (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 (c,a,xV,b) => Node(c,a,xV,b) } /** makeBLACK: Turn a node BLACK. */ def makeBlack(n: Tree): Tree = n match { case Node(RED(),l,v,r) => Node(BLACK(),l,v,r) case _ => n } /* global invariants: * RED-BLACK trees are binary search trees obeying two key invariants: * * (1) Any path from a root node to a leaf node contains the same number * of BLACK nodes. (A balancing condition.) * * (2) RED nodes always have BLACK children. * */ /* Empty tree are consideRED to be BLACK */ def isBLACK(t: Tree): Boolean = t match { case Node(RED(),_,_,_) => false case _ => true } private def getSubTree(size:Int, min:Int, max:Int): Tree = { if (size == 0) Empty() else if (size == 1) Node(if (Verify.getBoolean()) RED() else BLACK(), Empty(), Verify.getInt(min,max), Empty()) else { val value = Verify.getInt(min,max) val leftSize = value - min val rightSize = size - 1 - leftSize Node(if (Verify.getBoolean()) RED() else BLACK(), getSubTree(leftSize, min, value - 1), value, getSubTree(rightSize, value + 1, max)) } } private def generateBinarySearchTree(treeSize:Int): Tree = { val size = Verify.getInt(1, treeSize) val maxNodeValue = size - 1 val t = getSubTree(size, 0, maxNodeValue) t } // declarative, naive representation def anyPathsContainsSameNumberOfBlackNodes(t: Tree): Boolean = { def blackNodeNos(t: Tree, acc: Int): List[Int] = t match { case Empty() => List(acc + 1) // because Empty are assumed to be BLACK case Node(_,l,_,r) => { val upAcc = if(isBLACK(t)) acc + 1 else acc blackNodeNos(l,upAcc) ::: blackNodeNos(r,upAcc) } } val paths = blackNodeNos(t, 0) paths.forall(_ == paths.head) } def areRedNodeChildrenBlack(t: Tree): Boolean = t match { case Node(RED(),l,_,r) => isBLACK(l) && isBLACK(r) && areRedNodeChildrenBlack(l) && areRedNodeChildrenBlack(r) case Node(BLACK(),l,_,r) => areRedNodeChildrenBlack(l) && areRedNodeChildrenBlack(r) case _ => true } def generateRedBlackTree(treeSize:Int): Tree = { val t = generateBinarySearchTree(treeSize) Verify.ignoreIf(!(anyPathsContainsSameNumberOfBlackNodes(t) && areRedNodeChildrenBlack(t))) t } def content(t:Tree):Set[Int] = t match { case Empty() => Set.empty case Node(_,left,value,right) => (content(left) ++ Set(value) ++ content(right)) } def forAllrbt(property: (Tree,Int) => Boolean){ val size = Verify.getInt(1,MAXTREESIZE+1) val t = generateRedBlackTree(size) val x = Verify.getInt(0,size) val prop = property(t,x) StructureCounter.incCounters(prop) if (!prop) { System.out.println("____________________________________________________________________") System.out.println("| Found counterexample: " + t+" "+x) System.out.println("--------------------------------------------------------------------") assert(false) } //System.out.println(t+" "+x) } forAllrbt((t:Tree, x:Int) => ({ val t1 = insert(x,t) anyPathsContainsSameNumberOfBlackNodes(t1) && areRedNodeChildrenBlack(t1)})) }