author | wenzelm |
Mon, 26 Jun 2023 23:20:32 +0200 | |
changeset 78209 | 50c5be88ad59 |
parent 69790 | 154cf64e403e |
permissions | -rw-r--r-- |
69790
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
1 |
(* |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
2 |
File: Power_By_Squaring.thy |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
3 |
Author: Manuel Eberl, TU München |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
4 |
|
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
5 |
Fast computing of funpow (applying some functon n times) for weakly associative binary |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
6 |
functions using exponentiation by squaring. Yields efficient exponentiation algorithms on |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
7 |
monoid_mult and for modular exponentiation "b ^ e mod m" (and thus also for "cong") |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
8 |
*) |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
9 |
section \<open>Exponentiation by Squaring\<close> |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
10 |
theory Power_By_Squaring |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
11 |
imports Main |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
12 |
begin |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
13 |
|
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
14 |
context |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
15 |
fixes f :: "'a \<Rightarrow> 'a \<Rightarrow> 'a" |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
16 |
begin |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
17 |
|
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
18 |
function efficient_funpow :: "'a \<Rightarrow> 'a \<Rightarrow> nat \<Rightarrow> 'a" where |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
19 |
"efficient_funpow y x 0 = y" |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
20 |
| "efficient_funpow y x (Suc 0) = f x y" |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
21 |
| "n \<noteq> 0 \<Longrightarrow> even n \<Longrightarrow> efficient_funpow y x n = efficient_funpow y (f x x) (n div 2)" |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
22 |
| "n \<noteq> 1 \<Longrightarrow> odd n \<Longrightarrow> efficient_funpow y x n = efficient_funpow (f x y) (f x x) (n div 2)" |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
23 |
by force+ |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
24 |
termination by (relation "measure (snd \<circ> snd)") (auto elim: oddE) |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
25 |
|
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
26 |
lemma efficient_funpow_code [code]: |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
27 |
"efficient_funpow y x n = |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
28 |
(if n = 0 then y |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
29 |
else if n = 1 then f x y |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
30 |
else if even n then efficient_funpow y (f x x) (n div 2) |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
31 |
else efficient_funpow (f x y) (f x x) (n div 2))" |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
32 |
by (induction y x n rule: efficient_funpow.induct) auto |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
33 |
|
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
34 |
end |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
35 |
|
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
36 |
lemma efficient_funpow_correct: |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
37 |
assumes f_assoc: "\<And>x z. f x (f x z) = f (f x x) z" |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
38 |
shows "efficient_funpow f y x n = (f x ^^ n) y" |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
39 |
proof - |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
40 |
have [simp]: "f ^^ 2 = (\<lambda>x. f (f x))" for f :: "'a \<Rightarrow> 'a" |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
41 |
by (simp add: eval_nat_numeral o_def) |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
42 |
show ?thesis |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
43 |
by (induction y x n rule: efficient_funpow.induct[of _ f]) |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
44 |
(auto elim!: evenE oddE simp: funpow_mult [symmetric] funpow_Suc_right f_assoc |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
45 |
simp del: funpow.simps(2)) |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
46 |
qed |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
47 |
|
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
48 |
(* |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
49 |
TODO: This could be used as a code_unfold rule or something like that but the |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
50 |
implications are not quite clear. Would this be a good default implementation |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
51 |
for powers? |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
52 |
*) |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
53 |
context monoid_mult |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
54 |
begin |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
55 |
|
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
56 |
lemma power_by_squaring: "efficient_funpow (*) (1 :: 'a) = (^)" |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
57 |
proof (intro ext) |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
58 |
fix x :: 'a and n |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
59 |
have "efficient_funpow (*) 1 x n = ((*) x ^^ n) 1" |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
60 |
by (subst efficient_funpow_correct) (simp_all add: mult.assoc) |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
61 |
also have "\<dots> = x ^ n" |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
62 |
by (induction n) simp_all |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
63 |
finally show "efficient_funpow (*) 1 x n = x ^ n" . |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
64 |
qed |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
65 |
|
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
66 |
end |
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
67 |
|
154cf64e403e
Exponentiation by squaring, fast modular exponentiation
Manuel Eberl <eberlm@in.tum.de>
parents:
diff
changeset
|
68 |
end |