src/HOL/Factorial.thy
author haftmann
Sun, 08 Oct 2017 22:28:22 +0200
changeset 66814 a24cde9588bb
parent 66806 a4e82b58d833
child 67399 eab6ce8368fa
permissions -rw-r--r--
generalized some rules
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
66589
b884c42694e0 tuned headers;
wenzelm
parents: 66394
diff changeset
     1
(*  Title:      HOL/Factorial.thy
65812
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
     2
    Author:     Jacques D. Fleuriot
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
     3
    Author:     Lawrence C Paulson
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
     4
    Author:     Jeremy Avigad
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
     5
    Author:     Chaitanya Mangla
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
     6
    Author:     Manuel Eberl
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
     7
*)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
     8
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
     9
section \<open>Factorial Function, Rising Factorials\<close>
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    10
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    11
theory Factorial
65813
bdd17b18e103 relaxed theory dependencies
haftmann
parents: 65812
diff changeset
    12
  imports Groups_List
65812
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    13
begin
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    14
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    15
subsection \<open>Factorial Function\<close>
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    16
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    17
context semiring_char_0
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    18
begin
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    19
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    20
definition fact :: "nat \<Rightarrow> 'a"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    21
  where fact_prod: "fact n = of_nat (\<Prod>{1..n})"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    22
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    23
lemma fact_prod_Suc: "fact n = of_nat (prod Suc {0..<n})"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    24
  by (cases n)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    25
    (simp_all add: fact_prod prod.atLeast_Suc_atMost_Suc_shift
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    26
      atLeastLessThanSuc_atLeastAtMost)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    27
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    28
lemma fact_prod_rev: "fact n = of_nat (\<Prod>i = 0..<n. n - i)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    29
  using prod.atLeast_atMost_rev [of "\<lambda>i. i" 1 n]
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    30
  by (cases n)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    31
    (simp_all add: fact_prod_Suc prod.atLeast_Suc_atMost_Suc_shift
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    32
      atLeastLessThanSuc_atLeastAtMost)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    33
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    34
lemma fact_0 [simp]: "fact 0 = 1"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    35
  by (simp add: fact_prod)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    36
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    37
lemma fact_1 [simp]: "fact 1 = 1"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    38
  by (simp add: fact_prod)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    39
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    40
lemma fact_Suc_0 [simp]: "fact (Suc 0) = 1"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    41
  by (simp add: fact_prod)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    42
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    43
lemma fact_Suc [simp]: "fact (Suc n) = of_nat (Suc n) * fact n"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    44
  by (simp add: fact_prod atLeastAtMostSuc_conv algebra_simps)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    45
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    46
lemma fact_2 [simp]: "fact 2 = 2"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    47
  by (simp add: numeral_2_eq_2)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    48
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    49
lemma fact_split: "k \<le> n \<Longrightarrow> fact n = of_nat (prod Suc {n - k..<n}) * fact (n - k)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    50
  by (simp add: fact_prod_Suc prod.union_disjoint [symmetric]
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    51
    ivl_disj_un ac_simps of_nat_mult [symmetric])
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    52
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    53
end
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    54
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    55
lemma of_nat_fact [simp]: "of_nat (fact n) = fact n"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    56
  by (simp add: fact_prod)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    57
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    58
lemma of_int_fact [simp]: "of_int (fact n) = fact n"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    59
  by (simp only: fact_prod of_int_of_nat_eq)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    60
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    61
lemma fact_reduce: "n > 0 \<Longrightarrow> fact n = of_nat n * fact (n - 1)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    62
  by (cases n) auto
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    63
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    64
lemma fact_nonzero [simp]: "fact n \<noteq> (0::'a::{semiring_char_0,semiring_no_zero_divisors})"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    65
  apply (induct n)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    66
  apply auto
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    67
  using of_nat_eq_0_iff
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    68
  apply fastforce
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    69
  done
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    70
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    71
lemma fact_mono_nat: "m \<le> n \<Longrightarrow> fact m \<le> (fact n :: nat)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    72
  by (induct n) (auto simp: le_Suc_eq)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    73
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    74
lemma fact_in_Nats: "fact n \<in> \<nat>"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    75
  by (induct n) auto
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    76
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    77
lemma fact_in_Ints: "fact n \<in> \<int>"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    78
  by (induct n) auto
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    79
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    80
context
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    81
  assumes "SORT_CONSTRAINT('a::linordered_semidom)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    82
begin
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    83
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    84
lemma fact_mono: "m \<le> n \<Longrightarrow> fact m \<le> (fact n :: 'a)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    85
  by (metis of_nat_fact of_nat_le_iff fact_mono_nat)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    86
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    87
lemma fact_ge_1 [simp]: "fact n \<ge> (1 :: 'a)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    88
  by (metis le0 fact_0 fact_mono)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    89
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    90
lemma fact_gt_zero [simp]: "fact n > (0 :: 'a)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    91
  using fact_ge_1 less_le_trans zero_less_one by blast
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    92
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    93
lemma fact_ge_zero [simp]: "fact n \<ge> (0 :: 'a)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    94
  by (simp add: less_imp_le)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    95
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    96
lemma fact_not_neg [simp]: "\<not> fact n < (0 :: 'a)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    97
  by (simp add: not_less_iff_gr_or_eq)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    98
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
    99
lemma fact_le_power: "fact n \<le> (of_nat (n^n) :: 'a)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   100
proof (induct n)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   101
  case 0
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   102
  then show ?case by simp
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   103
next
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   104
  case (Suc n)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   105
  then have *: "fact n \<le> (of_nat (Suc n ^ n) ::'a)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   106
    by (rule order_trans) (simp add: power_mono del: of_nat_power)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   107
  have "fact (Suc n) = (of_nat (Suc n) * fact n ::'a)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   108
    by (simp add: algebra_simps)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   109
  also have "\<dots> \<le> of_nat (Suc n) * of_nat (Suc n ^ n)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   110
    by (simp add: * ordered_comm_semiring_class.comm_mult_left_mono del: of_nat_power)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   111
  also have "\<dots> \<le> of_nat (Suc n ^ Suc n)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   112
    by (metis of_nat_mult order_refl power_Suc)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   113
  finally show ?case .
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   114
qed
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   115
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   116
end
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   117
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   118
lemma fact_less_mono_nat: "0 < m \<Longrightarrow> m < n \<Longrightarrow> fact m < (fact n :: nat)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   119
  by (induct n) (auto simp: less_Suc_eq)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   120
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   121
lemma fact_less_mono: "0 < m \<Longrightarrow> m < n \<Longrightarrow> fact m < (fact n :: 'a::linordered_semidom)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   122
  by (metis of_nat_fact of_nat_less_iff fact_less_mono_nat)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   123
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   124
lemma fact_ge_Suc_0_nat [simp]: "fact n \<ge> Suc 0"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   125
  by (metis One_nat_def fact_ge_1)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   126
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   127
lemma dvd_fact: "1 \<le> m \<Longrightarrow> m \<le> n \<Longrightarrow> m dvd fact n"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   128
  by (induct n) (auto simp: dvdI le_Suc_eq)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   129
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   130
lemma fact_ge_self: "fact n \<ge> n"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   131
  by (cases "n = 0") (simp_all add: dvd_imp_le dvd_fact)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   132
66806
a4e82b58d833 abolished (semi)ring_div in favour of euclidean_(semi)ring_cancel
haftmann
parents: 66589
diff changeset
   133
lemma fact_dvd: "n \<le> m \<Longrightarrow> fact n dvd (fact m :: 'a::linordered_semidom)"
65812
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   134
  by (induct m) (auto simp: le_Suc_eq)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   135
66806
a4e82b58d833 abolished (semi)ring_div in favour of euclidean_(semi)ring_cancel
haftmann
parents: 66589
diff changeset
   136
lemma fact_mod: "m \<le> n \<Longrightarrow> fact n mod (fact m :: 'a::{semidom_modulo, linordered_semidom}) = 0"
a4e82b58d833 abolished (semi)ring_div in favour of euclidean_(semi)ring_cancel
haftmann
parents: 66589
diff changeset
   137
  by (simp add: mod_eq_0_iff_dvd fact_dvd)
65812
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   138
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   139
lemma fact_div_fact:
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   140
  assumes "m \<ge> n"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   141
  shows "fact m div fact n = \<Prod>{n + 1..m}"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   142
proof -
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   143
  obtain d where "d = m - n"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   144
    by auto
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   145
  with assms have "m = n + d"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   146
    by auto
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   147
  have "fact (n + d) div (fact n) = \<Prod>{n + 1..n + d}"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   148
  proof (induct d)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   149
    case 0
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   150
    show ?case by simp
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   151
  next
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   152
    case (Suc d')
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   153
    have "fact (n + Suc d') div fact n = Suc (n + d') * fact (n + d') div fact n"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   154
      by simp
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   155
    also from Suc.hyps have "\<dots> = Suc (n + d') * \<Prod>{n + 1..n + d'}"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   156
      unfolding div_mult1_eq[of _ "fact (n + d')"] by (simp add: fact_mod)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   157
    also have "\<dots> = \<Prod>{n + 1..n + Suc d'}"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   158
      by (simp add: atLeastAtMostSuc_conv)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   159
    finally show ?case .
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   160
  qed
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   161
  with \<open>m = n + d\<close> show ?thesis by simp
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   162
qed
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   163
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   164
lemma fact_num_eq_if: "fact m = (if m = 0 then 1 else of_nat m * fact (m - 1))"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   165
  by (cases m) auto
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   166
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   167
lemma fact_div_fact_le_pow:
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   168
  assumes "r \<le> n"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   169
  shows "fact n div fact (n - r) \<le> n ^ r"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   170
proof -
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   171
  have "r \<le> n \<Longrightarrow> \<Prod>{n - r..n} = (n - r) * \<Prod>{Suc (n - r)..n}" for r
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   172
    by (subst prod.insert[symmetric]) (auto simp: atLeastAtMost_insertL)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   173
  with assms show ?thesis
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   174
    by (induct r rule: nat.induct) (auto simp add: fact_div_fact Suc_diff_Suc mult_le_mono)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   175
qed
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   176
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   177
lemma fact_numeral: "fact (numeral k) = numeral k * fact (pred_numeral k)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   178
  \<comment> \<open>Evaluation for specific numerals\<close>
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   179
  by (metis fact_Suc numeral_eq_Suc of_nat_numeral)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   180
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   181
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   182
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   183
subsection \<open>Pochhammer's symbol: generalized rising factorial\<close>
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   184
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   185
text \<open>See \<^url>\<open>http://en.wikipedia.org/wiki/Pochhammer_symbol\<close>.\<close>
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   186
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   187
context comm_semiring_1
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   188
begin
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   189
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   190
definition pochhammer :: "'a \<Rightarrow> nat \<Rightarrow> 'a"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   191
  where pochhammer_prod: "pochhammer a n = prod (\<lambda>i. a + of_nat i) {0..<n}"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   192
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   193
lemma pochhammer_prod_rev: "pochhammer a n = prod (\<lambda>i. a + of_nat (n - i)) {1..n}"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   194
  using prod.atLeast_lessThan_rev_at_least_Suc_atMost [of "\<lambda>i. a + of_nat i" 0 n]
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   195
  by (simp add: pochhammer_prod)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   196
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   197
lemma pochhammer_Suc_prod: "pochhammer a (Suc n) = prod (\<lambda>i. a + of_nat i) {0..n}"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   198
  by (simp add: pochhammer_prod atLeastLessThanSuc_atLeastAtMost)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   199
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   200
lemma pochhammer_Suc_prod_rev: "pochhammer a (Suc n) = prod (\<lambda>i. a + of_nat (n - i)) {0..n}"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   201
  by (simp add: pochhammer_prod_rev prod.atLeast_Suc_atMost_Suc_shift)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   202
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   203
lemma pochhammer_0 [simp]: "pochhammer a 0 = 1"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   204
  by (simp add: pochhammer_prod)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   205
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   206
lemma pochhammer_1 [simp]: "pochhammer a 1 = a"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   207
  by (simp add: pochhammer_prod lessThan_Suc)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   208
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   209
lemma pochhammer_Suc0 [simp]: "pochhammer a (Suc 0) = a"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   210
  by (simp add: pochhammer_prod lessThan_Suc)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   211
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   212
lemma pochhammer_Suc: "pochhammer a (Suc n) = pochhammer a n * (a + of_nat n)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   213
  by (simp add: pochhammer_prod atLeast0_lessThan_Suc ac_simps)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   214
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   215
end
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   216
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   217
lemma pochhammer_nonneg:
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   218
  fixes x :: "'a :: linordered_semidom"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   219
  shows "x > 0 \<Longrightarrow> pochhammer x n \<ge> 0"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   220
  by (induction n) (auto simp: pochhammer_Suc intro!: mult_nonneg_nonneg add_nonneg_nonneg)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   221
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   222
lemma pochhammer_pos:
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   223
  fixes x :: "'a :: linordered_semidom"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   224
  shows "x > 0 \<Longrightarrow> pochhammer x n > 0"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   225
  by (induction n) (auto simp: pochhammer_Suc intro!: mult_pos_pos add_pos_nonneg)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   226
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   227
lemma pochhammer_of_nat: "pochhammer (of_nat x) n = of_nat (pochhammer x n)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   228
  by (simp add: pochhammer_prod)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   229
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   230
lemma pochhammer_of_int: "pochhammer (of_int x) n = of_int (pochhammer x n)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   231
  by (simp add: pochhammer_prod)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   232
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   233
lemma pochhammer_rec: "pochhammer a (Suc n) = a * pochhammer (a + 1) n"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   234
  by (simp add: pochhammer_prod prod.atLeast0_lessThan_Suc_shift ac_simps)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   235
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   236
lemma pochhammer_rec': "pochhammer z (Suc n) = (z + of_nat n) * pochhammer z n"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   237
  by (simp add: pochhammer_prod prod.atLeast0_lessThan_Suc ac_simps)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   238
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   239
lemma pochhammer_fact: "fact n = pochhammer 1 n"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   240
  by (simp add: pochhammer_prod fact_prod_Suc)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   241
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   242
lemma pochhammer_of_nat_eq_0_lemma: "k > n \<Longrightarrow> pochhammer (- (of_nat n :: 'a:: idom)) k = 0"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   243
  by (auto simp add: pochhammer_prod)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   244
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   245
lemma pochhammer_of_nat_eq_0_lemma':
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   246
  assumes kn: "k \<le> n"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   247
  shows "pochhammer (- (of_nat n :: 'a::{idom,ring_char_0})) k \<noteq> 0"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   248
proof (cases k)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   249
  case 0
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   250
  then show ?thesis by simp
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   251
next
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   252
  case (Suc h)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   253
  then show ?thesis
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   254
    apply (simp add: pochhammer_Suc_prod)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   255
    using Suc kn
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   256
    apply (auto simp add: algebra_simps)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   257
    done
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   258
qed
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   259
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   260
lemma pochhammer_of_nat_eq_0_iff:
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   261
  "pochhammer (- (of_nat n :: 'a::{idom,ring_char_0})) k = 0 \<longleftrightarrow> k > n"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   262
  (is "?l = ?r")
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   263
  using pochhammer_of_nat_eq_0_lemma[of n k, where ?'a='a]
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   264
    pochhammer_of_nat_eq_0_lemma'[of k n, where ?'a = 'a]
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   265
  by (auto simp add: not_le[symmetric])
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   266
66394
32084d7e6b59 Some facts about orders of zeros
eberlm <eberlm@in.tum.de>
parents: 65813
diff changeset
   267
lemma pochhammer_0_left:
32084d7e6b59 Some facts about orders of zeros
eberlm <eberlm@in.tum.de>
parents: 65813
diff changeset
   268
  "pochhammer 0 n = (if n = 0 then 1 else 0)"
32084d7e6b59 Some facts about orders of zeros
eberlm <eberlm@in.tum.de>
parents: 65813
diff changeset
   269
  by (induction n) (simp_all add: pochhammer_rec)
32084d7e6b59 Some facts about orders of zeros
eberlm <eberlm@in.tum.de>
parents: 65813
diff changeset
   270
65812
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   271
lemma pochhammer_eq_0_iff: "pochhammer a n = (0::'a::field_char_0) \<longleftrightarrow> (\<exists>k < n. a = - of_nat k)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   272
  by (auto simp add: pochhammer_prod eq_neg_iff_add_eq_0)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   273
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   274
lemma pochhammer_eq_0_mono:
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   275
  "pochhammer a n = (0::'a::field_char_0) \<Longrightarrow> m \<ge> n \<Longrightarrow> pochhammer a m = 0"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   276
  unfolding pochhammer_eq_0_iff by auto
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   277
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   278
lemma pochhammer_neq_0_mono:
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   279
  "pochhammer a m \<noteq> (0::'a::field_char_0) \<Longrightarrow> m \<ge> n \<Longrightarrow> pochhammer a n \<noteq> 0"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   280
  unfolding pochhammer_eq_0_iff by auto
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   281
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   282
lemma pochhammer_minus:
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   283
  "pochhammer (- b) k = ((- 1) ^ k :: 'a::comm_ring_1) * pochhammer (b - of_nat k + 1) k"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   284
proof (cases k)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   285
  case 0
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   286
  then show ?thesis by simp
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   287
next
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   288
  case (Suc h)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   289
  have eq: "((- 1) ^ Suc h :: 'a) = (\<Prod>i = 0..h. - 1)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   290
    using prod_constant [where A="{0.. h}" and y="- 1 :: 'a"]
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   291
    by auto
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   292
  with Suc show ?thesis
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   293
    using pochhammer_Suc_prod_rev [of "b - of_nat k + 1"]
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   294
    by (auto simp add: pochhammer_Suc_prod prod.distrib [symmetric] eq of_nat_diff)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   295
qed
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   296
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   297
lemma pochhammer_minus':
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   298
  "pochhammer (b - of_nat k + 1) k = ((- 1) ^ k :: 'a::comm_ring_1) * pochhammer (- b) k"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   299
  apply (simp only: pochhammer_minus [where b = b])
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   300
  apply (simp only: mult.assoc [symmetric])
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   301
  apply (simp only: power_add [symmetric])
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   302
  apply simp
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   303
  done
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   304
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   305
lemma pochhammer_same: "pochhammer (- of_nat n) n =
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   306
    ((- 1) ^ n :: 'a::{semiring_char_0,comm_ring_1,semiring_no_zero_divisors}) * fact n"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   307
  unfolding pochhammer_minus
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   308
  by (simp add: of_nat_diff pochhammer_fact)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   309
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   310
lemma pochhammer_product': "pochhammer z (n + m) = pochhammer z n * pochhammer (z + of_nat n) m"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   311
proof (induct n arbitrary: z)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   312
  case 0
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   313
  then show ?case by simp
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   314
next
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   315
  case (Suc n z)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   316
  have "pochhammer z (Suc n) * pochhammer (z + of_nat (Suc n)) m =
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   317
      z * (pochhammer (z + 1) n * pochhammer (z + 1 + of_nat n) m)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   318
    by (simp add: pochhammer_rec ac_simps)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   319
  also note Suc[symmetric]
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   320
  also have "z * pochhammer (z + 1) (n + m) = pochhammer z (Suc (n + m))"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   321
    by (subst pochhammer_rec) simp
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   322
  finally show ?case
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   323
    by simp
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   324
qed
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   325
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   326
lemma pochhammer_product:
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   327
  "m \<le> n \<Longrightarrow> pochhammer z n = pochhammer z m * pochhammer (z + of_nat m) (n - m)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   328
  using pochhammer_product'[of z m "n - m"] by simp
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   329
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   330
lemma pochhammer_times_pochhammer_half:
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   331
  fixes z :: "'a::field_char_0"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   332
  shows "pochhammer z (Suc n) * pochhammer (z + 1/2) (Suc n) = (\<Prod>k=0..2*n+1. z + of_nat k / 2)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   333
proof (induct n)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   334
  case 0
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   335
  then show ?case
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   336
    by (simp add: atLeast0_atMost_Suc)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   337
next
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   338
  case (Suc n)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   339
  define n' where "n' = Suc n"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   340
  have "pochhammer z (Suc n') * pochhammer (z + 1 / 2) (Suc n') =
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   341
      (pochhammer z n' * pochhammer (z + 1 / 2) n') * ((z + of_nat n') * (z + 1/2 + of_nat n'))"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   342
    (is "_ = _ * ?A")
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   343
    by (simp_all add: pochhammer_rec' mult_ac)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   344
  also have "?A = (z + of_nat (Suc (2 * n + 1)) / 2) * (z + of_nat (Suc (Suc (2 * n + 1))) / 2)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   345
    (is "_ = ?B")
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   346
    by (simp add: field_simps n'_def)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   347
  also note Suc[folded n'_def]
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   348
  also have "(\<Prod>k=0..2 * n + 1. z + of_nat k / 2) * ?B = (\<Prod>k=0..2 * Suc n + 1. z + of_nat k / 2)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   349
    by (simp add: atLeast0_atMost_Suc)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   350
  finally show ?case
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   351
    by (simp add: n'_def)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   352
qed
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   353
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   354
lemma pochhammer_double:
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   355
  fixes z :: "'a::field_char_0"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   356
  shows "pochhammer (2 * z) (2 * n) = of_nat (2^(2*n)) * pochhammer z n * pochhammer (z+1/2) n"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   357
proof (induct n)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   358
  case 0
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   359
  then show ?case by simp
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   360
next
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   361
  case (Suc n)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   362
  have "pochhammer (2 * z) (2 * (Suc n)) = pochhammer (2 * z) (2 * n) *
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   363
      (2 * (z + of_nat n)) * (2 * (z + of_nat n) + 1)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   364
    by (simp add: pochhammer_rec' ac_simps)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   365
  also note Suc
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   366
  also have "of_nat (2 ^ (2 * n)) * pochhammer z n * pochhammer (z + 1/2) n *
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   367
        (2 * (z + of_nat n)) * (2 * (z + of_nat n) + 1) =
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   368
      of_nat (2 ^ (2 * (Suc n))) * pochhammer z (Suc n) * pochhammer (z + 1/2) (Suc n)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   369
    by (simp add: field_simps pochhammer_rec')
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   370
  finally show ?case .
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   371
qed
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   372
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   373
lemma fact_double:
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   374
  "fact (2 * n) = (2 ^ (2 * n) * pochhammer (1 / 2) n * fact n :: 'a::field_char_0)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   375
  using pochhammer_double[of "1/2::'a" n] by (simp add: pochhammer_fact)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   376
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   377
lemma pochhammer_absorb_comp: "(r - of_nat k) * pochhammer (- r) k = r * pochhammer (-r + 1) k"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   378
  (is "?lhs = ?rhs")
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   379
  for r :: "'a::comm_ring_1"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   380
proof -
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   381
  have "?lhs = - pochhammer (- r) (Suc k)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   382
    by (subst pochhammer_rec') (simp add: algebra_simps)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   383
  also have "\<dots> = ?rhs"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   384
    by (subst pochhammer_rec) simp
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   385
  finally show ?thesis .
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   386
qed
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   387
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   388
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   389
subsection \<open>Misc\<close>
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   390
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   391
lemma fact_code [code]:
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   392
  "fact n = (of_nat (fold_atLeastAtMost_nat (op *) 2 n 1) :: 'a::semiring_char_0)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   393
proof -
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   394
  have "fact n = (of_nat (\<Prod>{1..n}) :: 'a)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   395
    by (simp add: fact_prod)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   396
  also have "\<Prod>{1..n} = \<Prod>{2..n}"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   397
    by (intro prod.mono_neutral_right) auto
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   398
  also have "\<dots> = fold_atLeastAtMost_nat (op *) 2 n 1"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   399
    by (simp add: prod_atLeastAtMost_code)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   400
  finally show ?thesis .
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   401
qed
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   402
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   403
lemma pochhammer_code [code]:
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   404
  "pochhammer a n =
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   405
    (if n = 0 then 1
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   406
     else fold_atLeastAtMost_nat (\<lambda>n acc. (a + of_nat n) * acc) 0 (n - 1) 1)"
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   407
  by (cases n)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   408
    (simp_all add: pochhammer_prod prod_atLeastAtMost_code [symmetric]
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   409
      atLeastLessThanSuc_atLeastAtMost)
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   410
04ba6d530c87 explicit theory for factorials
haftmann
parents:
diff changeset
   411
end