2 (** {1 Fast exponentiation} *)
4 module FastExponentiation
8 use int.ComputerDivision
11 forall x, n. n >= 0 -> mod n 2 = 0 ->
12 power x n = power (x*x) (div n 2)
13 by n = div n 2 + div n 2
15 (* recursive implementation *)
17 let rec fast_exp (x n: int) : int
20 ensures { result = power x n }
24 let r = fast_exp x (div n 2) in
25 if mod n 2 = 0 then r * r else r * r * x
27 (* recursive implementation with an accumulator *)
29 let rec fast_exp_2 (x n acc: int) : int
32 ensures { result = power x n * acc }
35 else if mod n 2 = 0 then
36 fast_exp_2 (x * x) (div n 2) acc
38 fast_exp_2 x (n - 1) (x * acc)
40 (* non-recursive implementation using a while loop *)
44 let fast_exp_imperative (x n: int) : int
46 ensures { result = power x n }
52 invariant { r * power p e = power x n }
55 if mod e 2 = 1 then r := r * p;
58 assert { power p e = let x = power (p at L) e in x * x }