forked from epfl-lara/stainless
-
Notifications
You must be signed in to change notification settings - Fork 0
/
IntSetProp.scala
66 lines (56 loc) · 1.55 KB
/
IntSetProp.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
62
63
64
65
66
import stainless.lang._
import stainless.annotation._
object IntSetProp {
case class Empty() extends IntSet
case class Node(left: IntSet,
elem: Int,
right: IntSet) extends IntSet
sealed abstract class IntSet {
def incl(x: Int): IntSet = {
// decreases(this)
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
}
}
def contains(x: Int): Boolean = {
// decreases(this)
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
}
}
def P1(x: Int): Boolean = {
!(Empty().contains(x))
}.holds
def P2(s: IntSet, x: Int): Boolean = {
// decreases(s)
s match {
case Empty() => true
case Node(left, elem, right) =>
if (x < elem) P2(left, x)
else if (x > elem) P2(right, x)
else true
}
(s.incl(x)) `contains` x
}.holds
def P3(s: IntSet, x: Int, y: Int): Boolean = {
require(x != y)
// decreases(s)
s match {
case Empty() => true
case Node(left, elem, right) =>
if (x < elem) P3(left, x, y)
else if (x > elem) P3(right, x, y)
else true
}
((s.incl(x)) `contains` y) == (s.contains(y))
}.holds
}
}