function fib(n: nat): nat
else fib(n - 1) + fib(n - 2)
method ComputeFib(n: nat) returns (ret: nat)
method Find(a: array<int>, key: int) returns (index: int)
ensures 0 <= index ==> index < a.Length && a[index] == key
ensures index < 0 ==> (forall k :: 0 <= k < a.Length ==> a[k] != key)
invariant 0 <= index <= a.Length
invariant forall k :: 0 <= k < index ==> a[k] != key
predicate sorted(a: array<int>)
forall n, m :: 0 <= n < m < a.Length ==> a[n] <= a[m]
method BinarySearch(a: array<int>, value: int) returns (index: int)
requires 0 <= a.Length && sorted(a)
ensures 0 <= index ==> index < a.Length && a[index] == value
ensures index < 0 ==> forall k :: 0 <= k < a.Length ==> a[k] != value
var high := a.Length - 1;
invariant 0 <= low && high < a.Length
invariant forall k :: 0 <= k < a.Length && (k < low || k > high) ==> a[k] != value
var mid : int := (low + high) / 2;
assert 0 <= low <= mid < high < a.Length;
} else if a[mid] > value {
if low < a.Length && a[low] == value {
function update(s: seq<int>, i: int, v: int): seq<int>
ensures update(s, i, v) == s[i := v]
lemma SkippingLemma(a: array<int>, j: int)
requires forall i :: 0 <= i < a.Length ==> 0 <= a[i]
requires forall i :: 0 < i < a.Length ==> a[i-1]-1 <= a[i]
requires 0 <= j < a.Length
ensures forall i :: j <= i < j + a[j] && i < a.Length ==> a[i] != 0
while i < j + a[j] && i < a.Length
invariant i < a.Length ==> a[i] >= a[j] - (i-j)
invariant forall k :: j <= k < i && k < a.Length ==> a[k] != 0
method FindZero(a: array<int>) returns (index: int)
requires forall i :: 0 <= i < a.Length ==> 0 <= a[i]
requires forall i :: 0 < i < a.Length ==> a[i-1]-1 <= a[i]
ensures index < 0 ==> forall i :: 0 <= i < a.Length ==> a[i] != 0
ensures 0 <= index ==> index < a.Length && a[index] == 0
invariant forall k :: 0 <= k < index && k < a.Length ==> a[k] != 0
if a[index] == 0 { return; }
index := index + a[index];
function count(a: seq<bool>): nat
(if a[0] then 1 else 0) + count(a[1..])
lemma DistributiveLemma(a: seq<bool>, b: seq<bool>)
ensures count(a + b) == count(a) + count(b)
assert a + b == [a[0]] + (a[1..] + b);
predicate closed(graph: set<Node>)
forall i :: i in graph ==> forall k :: 0 <= k < |i.next| ==> i.next[k] in graph && i.next[k] != i
predicate path(p: seq<Node>, graph: set<Node>)
requires closed(graph) && 0 < |p|
(|p| > 1 ==> p[1] in p[0].next &&
predicate pathSpecific(p: seq<Node>, start: Node, end: Node, graph: set<Node>)
start == p[0] && end == p[|p|-1] &&
lemma DisproofLemma(p: seq<Node>, subgraph: set<Node>,
root: Node, goal: Node, graph: set<Node>)
requires closed(subgraph) && closed(graph) && subgraph <= graph
requires root in subgraph && goal in graph - subgraph
ensures !pathSpecific(p, root, goal, graph)
if |p| >= 2 && p[0] == root && p[1] in p[0].next {
DisproofLemma(p[1..], subgraph, p[1], goal, graph);
lemma ClosedLemma(subgraph: set<Node>, root: Node, goal: Node, graph: set<Node>)
requires closed(subgraph) && closed(graph) && subgraph <= graph
requires root in subgraph && goal in graph - subgraph
ensures !(exists p: seq<Node> :: pathSpecific(p, root, goal, graph))
forall p { DisproofLemma(p, subgraph, root, goal, graph); }