2 (** Sieve of Eratosthenes
4 Author: Martin Clochard
6 See also knuth_prime_numbers.mlw in the gallery.
17 predicate no_factor_lt (bnd num:int) =
18 num > 1 /\ forall k l. 1 < l < bnd /\ k > 1 -> num <> k * l
20 let incr (r:ref int) : unit
21 ensures { !r = old !r + 1 }
24 let sieve (n:int) : (m: array bool)
26 ensures { length m = n /\ forall i. 0 <= i < n -> m[i] <-> prime i }
27 = let t = Array.make n true in
32 invariant { 1 < !i <= n }
33 invariant { forall j. 0 <= j < n -> t[j] <-> no_factor_lt !i j }
36 let s = ref (!i * !i) in
37 let ghost r = ref !i in
39 invariant { 1 < !r <= n /\ !s = !r * !i }
40 invariant { forall j. 0 <= j < n ->
41 t[j] <-> (no_factor_lt !i j /\
42 forall k. 1 < k < !r -> j <> k * !i) }
48 assert { forall j. 0 <= j < n /\ t[j] ->
49 (forall k l. 1 < l < !i + 1 -> j = k * l /\ k > 1 ->
50 (if l = !i then k < !r && false else false) && false) &&
51 no_factor_lt (!i+1) j }
52 end else assert { forall j. 0 <= j < n /\ no_factor_lt !i j ->
53 (forall k l. 1 < l < !i + 1 -> j = k * l /\ k > 1 ->
54 (if l = !i then (forall k0 l. 1 < l < !i /\ k0 > 1 /\ !i = k0 * l ->
55 j = (k*k0) * l && false) && false
56 else false) && false) && no_factor_lt (!i+1) j };
59 assert { forall j. 0 <= j < n /\ no_factor_lt n j -> prime j };
60 assert { forall j. 0 <= j < n /\ prime j ->
61 forall k l. 1 < l < n /\ k > 1 -> j = k * l -> l >= j && false };