Skip to content

Instantly share code, notes, and snippets.

@philnguyen
Last active August 29, 2015 14:21
Show Gist options
  • Save philnguyen/bd27a30b6075a5536a66 to your computer and use it in GitHub Desktop.
Save philnguyen/bd27a30b6075a5536a66 to your computer and use it in GitHub Desktop.
This file demonstrates a seemingly bug in the Leon verifier
import leon.lang._
import leon.lang.synthesis._
import leon.annotation._
object BraunTree {
sealed abstract class Tree
case object Leaf extends Tree
case class Node(l: Tree, n: Int, r: Tree) extends Tree
def size(t: Tree): Int = t match {
case Leaf => 0
case Node(l, _, r) => 1 + size(l) + size(r)
}
def isBraunTree (t: Tree): Boolean = t match {
case Leaf => true
case Node(l, n, r) =>
val nl = size(l)
val nr = size(r)
isBraunTree(l) && isBraunTree(r) && (nl == nr || nl == 1 + nr)
}
// Normal "weak" insert without pre/post conditions
def weakInsert(t: Tree, x: Int): Tree = t match {
case Leaf => Node(Leaf, x, Leaf)
case Node(l, v, r) => Node(weakInsert(l, x), v, r)
}
// Wrap "weak" insert with pre/post conditions
def wrappedInsert(t: Tree, x: Int): Tree = {
require (isBraunTree(t))
weakInsert(t, x) ensuring (isBraunTree(_))
}
// couterexample triggering `wrapInsert`'s post-condition failure
val booYa: Tree = wrappedInsert(Node(Node(Leaf, 0, Leaf), 0, Leaf), 0)
// "Strong" insert with pre/post condition
def strongInsert(t: Tree, x: Int): Tree = {
require (isBraunTree(t))
t match {
case Leaf => Node(Leaf, x, Leaf)
case Node(l, v, r) => Node(strongInsert(l, x), v ,r)
}
} ensuring (isBraunTree(_))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment