-
Notifications
You must be signed in to change notification settings - Fork 53
/
IntSetInv.scala
61 lines (51 loc) · 2.07 KB
/
IntSetInv.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/**
* NOTE: This test won't run with the current stainless configuration
* as the proofs in the function bodies will be simplified away!
*/
import stainless.lang._
import stainless.annotation._
object IntSetInv {
case class Empty() extends IntSet
case class Node(left: IntSet,
elem: Int,
right: IntSet) extends IntSet {
require(forall((x:Int) =>
(left.content.contains(x) ==> x < elem)) &&
forall((x:Int) =>
(right.content.contains(x) ==> elem < x)))
}
sealed abstract class IntSet {
def content: Set[Int] = this match {
case Empty() => Set()
case Node(left, elem, right) =>
left.content ++ Set(elem) ++ right.content
}
def incl(x: Int): IntSet = { this match {
case Empty() => Node(Empty(),x,Empty())
case Node(left, elem, right) =>
if (x < elem) Node(left.incl(x), elem, right)
else if (x > elem) Node(left, elem, right.incl(x))
else this
}}.ensuring(res => res.content == this.content ++ Set(x))
def contains(x: Int): Boolean = {this match {
case Empty() => false
case Node(left, elem, right) =>
if (x < elem) left.contains(x)
else if (x > elem) right.contains(x)
else true
}}.ensuring(res => (res == (this.content.contains(x))))
def union(s: IntSet): IntSet = (this match {
case Empty() => s
case Node(left, x, right) => (left.union((right.union(s)))).incl(x)
}).ensuring (res => res.content == this.content ++ s.content)
def P1(x: Int): Unit =
().ensuring(_ => !(Empty().contains(x)))
def P2(s: IntSet, x: Int): Unit =
().ensuring(_ => (s.incl(x)).contains(x))
def P3(s: IntSet, x: Int, y: Int): Unit = {
require(x != y)
}.ensuring(_ => ((s.incl(x)).contains(y))==(s.contains(y)))
def P4(t1: IntSet, t2: IntSet, x: Int): Unit =
().ensuring (_ => (((t1.union(t2)).contains(x)) == (t1.contains(x))) || (t2.contains(x)))
}
}