method Generate(n: int) returns (perm: array<int>)
var all := set x | 0 <= x < n;
CardinalityLemma(n, all);
invariant |used| <= |all|
invariant forall i | 0 <= i < |used| :: perm[i] in used
invariant distinct'(perm, |used|)
CardinalityOrderingLemma(used, all);
var dst :| dst in all && dst !in used;
predicate isValid(a: array<int>, n: nat)
requires a != null && a.Length == n
assume forall i | 0 <= i < n :: i in a[..];
&& (forall i | 0 <= i < a.Length :: 0 <= a[i] < n)
&& (forall i | 0 <= i < n :: i in a[..])
predicate distinct(a: array<int>)
predicate distinct'(a: array<int>, n: int)
forall i,j | 0 <= i < n && 0 <= j < n && i != j :: a[i] != a[j]
lemma CardinalityLemma (size: int, s: set<int>)
requires s == set x | 0 <= x < size
assert size == |(set x | 0 <= x < size)|;
CardinalityLemma(size - 1, s - {size - 1});
lemma CardinalityOrderingLemma<T> (s1: set<T>, s2: set<T>)
CardinalityOrderingLemma(s1, s2 - {e});
lemma SetDiffLemma<T> (s1: set<T>, s2: set<T>)