src/HOL/Library/Power_By_Squaring.thy
author Manuel Eberl <eberlm@in.tum.de>
Mon, 04 Feb 2019 15:39:37 +0100
changeset 69790 154cf64e403e
permissions -rw-r--r--
Exponentiation by squaring, fast modular exponentiation
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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