-
Notifications
You must be signed in to change notification settings - Fork 0
/
FindIndexOptionIff.scala
37 lines (31 loc) · 1.07 KB
/
FindIndexOptionIff.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
import stainless.lang._
object FindIndexOptionIff {
def notPresent[T](upto: Int, a: Array[T], t: T): Boolean = {
require(0 <= upto && upto < a.length)
decreases(upto)
a(upto) != t &&
(upto == 0 || notPresent(upto - 1, a, t))
}
def findIndexOpt[T](a: Array[T], t: T): Option[Int] = {
require(a.length < 65536)
val N: Int = a.length
var i: Int = 0
if (0 < N) {
(while (i < N) {
decreases(N - i)
if (a(i) == t) {
assert(0 <= i && i <= N && a.length == N && (i == 0 || notPresent(i - 1, a, t)))
assert(0 <= i && i < a.length && a(i) == t)
return Some[Int](i)
}
i = i + 1
assert(0 <= i && i <= N && a.length == N && (i == 0 || notPresent(i - 1, a, t)))
}).invariant(0 <= i && i <= N && a.length == N && (i == 0 || notPresent(i - 1, a, t)))
None[Int]()
} else None[Int]()
} ensuring((res: Option[Int]) =>
(res match {
case None() => a.length == 0 || notPresent(a.length - 1, a, t)
case Some(i) => 0 <= i && i < a.length && a(i) == t
}))
}