| author | wenzelm | 
| Tue, 25 Mar 2025 23:05:15 +0100 | |
| changeset 82407 | fcc0f74ac086 | 
| 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 |