1 (* 'Checking a large routine' Alan Mathison Turing, 1949
3 One of the earliest proof of program.
4 The routine computes n! using only additions, with two nested loops.
7 module CheckingALargeRoutine
13 (* using 'while' loops, to keep close to Turing's flowchart *)
14 let routine (n: int) requires { n >= 0 } ensures { result = fact n } =
18 invariant { 0 <= !r <= n /\ !u = fact !r }
23 invariant { 1 <= !s <= !r + 1 /\ !u = !s * fact !r }
32 (* using 'for' loops, for clearer code and annotations *)
33 let routine2 (n: int) requires { n >= 0 } ensures { result = fact n } =
35 for r = 0 to n-1 do invariant { !u = fact r }
37 for s = 1 to r do invariant { !u = s * fact r }
43 let downward (n: int) requires { n >= 0 } ensures { result = fact n } =
47 invariant { 0 <= !r <= n /\ !u * fact !r = fact n }
52 invariant { 1 <= !s <= !r /\ !u = !s * v }