From fad0ae765d8c64a7c40f6fe0526af6b3e3502770 Mon Sep 17 00:00:00 2001 From: Etienne Kneuss <ekneuss@gmail.com> Date: Mon, 15 Oct 2012 14:35:54 +0200 Subject: [PATCH] Add tests in main branch --- testcases/SortedList.scala | 127 ++++++++++++++++++++++++ testcases/SortedTree.scala | 195 +++++++++++++++++++++++++++++++++++++ 2 files changed, 322 insertions(+) create mode 100644 testcases/SortedList.scala create mode 100644 testcases/SortedTree.scala diff --git a/testcases/SortedList.scala b/testcases/SortedList.scala new file mode 100644 index 000000000..882dbe2a7 --- /dev/null +++ b/testcases/SortedList.scala @@ -0,0 +1,127 @@ +import scala.collection.immutable.Set +import leon.Annotations._ +import leon.Utils._ + +object SortedList { + sealed abstract class List + case class Cons(head: Int, tail: List) extends List + case class Nil() extends List + + // proved with unrolling=0 + def size(l: List) : Int = (l match { + case Nil() => 0 + case Cons(_, t) => 1 + size(t) + }) ensuring(res => res >= 0) + + def content(l: List): Set[Int] = l match { + case Nil() => Set() + case Cons(i, t) => Set(i) ++ content(t) + } + + def insert1(l: List, v: Int) = ( + Cons(v, l) + ) ensuring(res => content(res) == content(l) ++ Set(v) && size(res) >= size(l)) + + def insert2(l: List, v: Int): List = (l match { + case Nil() => Cons(v, Nil()) + case Cons(x, tail) => if (x == v) l else Cons(x, insert2(tail, v)) + }) ensuring(res => content(res) == content(l) ++ Set(v) && size(res) >= size(l)) + + def insert3(l: List, v: Int): List = { + require(isStrictlySorted(l)) + + l match { + case Nil() => Cons(v, Nil()) + case Cons(x, tail) => + if (v < x) { + Cons(v, l) + } else if (v == x) { + l + } else { + Cons(x, insert3(tail, v)) + } + } + } ensuring(res => content(res) == content(l) ++ Set(v) && size(res) >= size(l)) + + def delete1(l: List, v: Int): List = (l match { + case Nil() => Nil() + case Cons(x, tail) => if (x == v) delete1(tail, v) else Cons(x, delete1(tail, v)) + }) ensuring(res => !(content(res) contains v) && size(res) <= size(l)) + + //def delete2(l: List, v: Int): List = { + // require(isStrictlySorted(l)) + + // l match { + // case Nil() => Nil() + // case Cons(x, tail) => + // if (x == v) { + // tail + // } else { + // Cons(x, delete2(tail, v)) + // } + // } + //} ensuring(res => !(content(res) contains v) && size(res) <= size(l)) + + def contains(list : List, elem : Int) : Boolean = (list match { + case Nil() => false + case Cons(x, xs) => if(elem == x) true else contains(xs, elem) + }) ensuring(res => res == content(list).contains(elem)) + + def deleteMagic(head: Int, tail: List, toDelete: Int): List = ({ + //require(isStrictlySorted(Cons(head, tail)) && toDelete < head); + require(isStrictlySorted(Cons(toDelete, Cons(head, tail)))) + + Cons(head, tail) + })ensuring(res => !(content(res) contains toDelete)) + + def delete3(l: List, v: Int): List = { + require(isStrictlySorted(l)) + + l match { + case Nil() => Nil() + case Cons(x, tail) => + if (x == v) { + tail + } else if (v < x) { + deleteMagic(x, tail, v) + } else { + Cons(x, delete3(tail, v)) + } + } + } ensuring(res => !(content(res) contains v) && size(res) <= size(l)) + + @induct + def isStrictlySorted(l: List): Boolean = (l match { + case Nil() => true + case Cons(x, Nil()) => true + case Cons(x, xs @ Cons(y, ys)) => { + if(x < y) { + if(isStrictlySorted(xs)) discard(ltaLemma(x, y, ys)) else false + } else { + false + } + } + }) ensuring(res => !res || (l match { + case Nil() => true + case Cons(x, xs) => lessThanAll(x, xs) + })) + + def lessThanAll(x : Int, l : List) : Boolean = (l match { + case Nil() => true + case Cons(y, ys) => if(x < y) lessThanAll(x, ys) else false + }) ensuring(res => !res || !contains(l, x)) + + def discard(value : Boolean) = true + + @induct + def ltaLemma(x : Int, y : Int, l : List) : Boolean = { + require(lessThanAll(y, l) && x < y) + lessThanAll(x, Cons(y, l)) + } holds + + def isSorted(l: List): Boolean = l match { + case Nil() => true + case Cons(x, Nil()) => true + case Cons(x, Cons(y, ys)) => x <= y && isSorted(Cons(y, ys)) + } +} diff --git a/testcases/SortedTree.scala b/testcases/SortedTree.scala new file mode 100644 index 000000000..3b69626ec --- /dev/null +++ b/testcases/SortedTree.scala @@ -0,0 +1,195 @@ +import scala.collection.immutable.Set +import leon.Annotations._ +import leon.Utils._ + +object SortedTree { + sealed abstract class Tree + case class Node(v: Int, left: Tree, right: Tree) extends Tree + case class Leaf() extends Tree + + def depth(t: Tree) : Int = (t match { + case Leaf() => 0 + case Node(_, l, r) => + if (depth(l) > depth(r)) { + depth(l)+1 + } else { + depth(r)+1 + } + }) ensuring(res => res >= 0) + + def size(t: Tree) : Int = (t match { + case Leaf() => 0 + case Node(_, l, r) => 1 + size(l) + size(r) + }) ensuring(res => res >= 0) + + def content(t: Tree): Set[Int] = t match { + case Leaf() => Set() + case Node(v, l, r) => Set(v) ++ content(l) ++ content(r) + } + + @induct + def sizeDepthLemma(t: Tree) = ( + (depth(t) <= size(t)) + ).holds + + def isMostlySorted(t: Tree): Boolean = (t match { + case Node(v, l @ Node(v1, l1, r1), r @ Node(v2, l2, r2)) => + isMostlySorted(l) && + isMostlySorted(r) && + v1 < v && + v2 > v + case Node(v, Leaf(), r @ Node(v2, l2, r2)) => + isMostlySorted(r) && + v2 > v + case Node(v, l @ Node(v1, l1, r1), Leaf()) => + isMostlySorted(l) && + v1 < v + case _ => true + }) + + def isSortedMinMax(t: Tree, min: Int, max: Int): Boolean = (t match { + case Node(v, l, r) => + isSortedMinMax(l, min, v) && + isSortedMinMax(r, v, max) && + v < max && + v > min + case _ => true + }) + + def isSortedMin(t: Tree, min: Int): Boolean = (t match { + case Node(v, l, r) => + isSortedMinMax(l, min, v) && + isSortedMin(r, v) && + v > min + case _ => true + }) + + def isSortedMax(t: Tree, max: Int): Boolean = (t match { + case Node(v, l, r) => + isSortedMax(l, v) && + isSortedMinMax(r, v, max) && + v < max + case _ => true + }) + + def isSorted(t: Tree): Boolean = (t match { + case Node(v, l, r) => + isSortedMin(r, v) && + isSortedMax(l, v) + case _ => true + }) ensuring ( res => !res || (t match { + case Node(v, l, r) => + allSmallerThan(l, v) && + allGreaterThan(r, v) + case Leaf() => true + })) + + def allSmallerThan(t: Tree, max: Int): Boolean = (t match { + case Node(v, l, r) => + allSmallerThan(l, max) && + allSmallerThan(r, max) && + v < max + case Leaf() => true + }) + + def allGreaterThan(t: Tree, min: Int): Boolean = (t match { + case Node(v, l, r) => + allGreaterThan(l, min) && + allGreaterThan(r, min) && + v > min + case Leaf() => true + }) + + @induct + def sortedLemma1(t: Tree) = ({ + require(isSorted(t)) + + t match { + case Node(v, l, r) => + allGreaterThan(r, v) && + allSmallerThan(l, v) + case Leaf() => true + } + }).holds + + // + // OPERATIONS: + // + + def insert1(t: Tree, newV: Int): Tree = (t match { + case Leaf() => Node(newV, Leaf(), Leaf()) + case Node(v, l, r) => Node(v, insert1(l, newV), r) + }) ensuring(res => content(res) == content(t) ++ Set(newV)) + + def insert2(t: Tree, newV: Int): Tree = (t match { + case Leaf() => Node(newV, Leaf(), Leaf()) + case Node(v, l, r) => + if (v == newV) + t + else + Node(v, insert2(l, newV), r) + }) ensuring(res => content(res) == content(t) ++ Set(newV)) + + def insert3(t: Tree, newV: Int): Tree = (t match { + case Leaf() => Node(newV, Leaf(), Leaf()) + case Node(v, l, r) => + if (v == newV) + t + else if (newV > v) + Node(v, l, insert3(r, newV)) + else + Node(v, insert3(l, newV), r) + }) ensuring(res => content(res) == content(t) ++ Set(newV) && ((content(t) contains newV) || (size(res) > size(t)))) + + def insert4(t: Tree, newV: Int): Tree = { + require(isMostlySorted(t)); + + (t match { + case Leaf() => Node(newV, Leaf(), Leaf()) + case Node(v, l, r) => + if (v == newV) + t + else if (newV > v) + Node(v, l, insert4(r, newV)) + else + Node(v, insert4(l, newV), r) + })} ensuring(res => content(res) == content(t) ++ Set(newV) && ((content(t) contains newV) || (size(res) > size(t))) && isMostlySorted(res)) + + def contains1(t: Tree, searchV: Int): Boolean = (t match { + case Leaf() => false + case Node(v, l, r) => + (v == searchV) || + contains1(l, searchV) || + contains1(r, searchV) + }) ensuring(res => !res || (content(t) contains searchV)) + + def contains2(t: Tree, searchV: Int): Boolean = { + require(isMostlySorted(t)) + + (t match { + case Leaf() => false + case Node(v, l, r) => + if (searchV > v) { + contains2(r, searchV) + } else if (searchV < v) { + contains2(l, searchV) + } else { + true + } + })} ensuring(res => !res || (content(t) contains searchV)) + + def containsBuggy(t: Tree, searchV: Int): Boolean = { + require(isMostlySorted(t)) + + (t match { + case Leaf() => false + case Node(v, l, r) => + if (searchV > v) { + contains2(l, searchV) + } else if (searchV < v) { + contains2(r, searchV) + } else { + true + } + })} ensuring(res => !res || (content(t) contains searchV)) +} -- GitLab