12 imports Main |
12 imports Main |
13 begin |
13 begin |
14 |
14 |
15 subsection \<open>Factorial\<close> |
15 subsection \<open>Factorial\<close> |
16 |
16 |
17 fun (in semiring_char_0) fact :: "nat \<Rightarrow> 'a" |
17 definition (in semiring_char_0) fact :: "nat \<Rightarrow> 'a" |
18 where "fact 0 = 1" | "fact (Suc n) = of_nat (Suc n) * fact n" |
18 where |
19 |
19 "fact n = of_nat (\<Prod>{1..n})" |
20 lemmas fact_Suc = fact.simps(2) |
20 |
|
21 lemma fact_altdef': "fact n = of_nat (\<Prod>{1..n})" |
|
22 by (fact fact_def) |
|
23 |
|
24 lemma fact_altdef_nat: "fact n = \<Prod>{1..n}" |
|
25 by (simp add: fact_def) |
|
26 |
|
27 lemma fact_altdef: "fact n = (\<Prod>i=1..n. of_nat i)" |
|
28 by (simp add: fact_def) |
|
29 |
|
30 lemma fact_0 [simp]: "fact 0 = 1" |
|
31 by (simp add: fact_def) |
21 |
32 |
22 lemma fact_1 [simp]: "fact 1 = 1" |
33 lemma fact_1 [simp]: "fact 1 = 1" |
23 by simp |
34 by (simp add: fact_def) |
24 |
35 |
25 lemma fact_Suc_0 [simp]: "fact (Suc 0) = Suc 0" |
36 lemma fact_Suc_0 [simp]: "fact (Suc 0) = Suc 0" |
26 by simp |
37 by (simp add: fact_def) |
|
38 |
|
39 lemma fact_Suc [simp]: "fact (Suc n) = of_nat (Suc n) * fact n" |
|
40 by (simp add: fact_def atLeastAtMostSuc_conv algebra_simps) |
27 |
41 |
28 lemma of_nat_fact [simp]: |
42 lemma of_nat_fact [simp]: |
29 "of_nat (fact n) = fact n" |
43 "of_nat (fact n) = fact n" |
30 by (induct n) (auto simp add: algebra_simps) |
44 by (simp add: fact_def) |
31 |
45 |
32 lemma of_int_fact [simp]: |
46 lemma of_int_fact [simp]: |
33 "of_int (fact n) = fact n" |
47 "of_int (fact n) = fact n" |
34 proof - |
48 by (simp only: fact_def of_int_of_nat_eq) |
35 have "of_int (of_nat (fact n)) = fact n" |
|
36 unfolding of_int_of_nat_eq by simp |
|
37 then show ?thesis |
|
38 by simp |
|
39 qed |
|
40 |
49 |
41 lemma fact_reduce: "n > 0 \<Longrightarrow> fact n = of_nat n * fact (n - 1)" |
50 lemma fact_reduce: "n > 0 \<Longrightarrow> fact n = of_nat n * fact (n - 1)" |
42 by (cases n) auto |
51 by (cases n) auto |
43 |
52 |
44 lemma fact_nonzero [simp]: "fact n \<noteq> (0::'a::{semiring_char_0,semiring_no_zero_divisors})" |
53 lemma fact_nonzero [simp]: "fact n \<noteq> (0::'a::{semiring_char_0,semiring_no_zero_divisors})" |
104 shows "1 \<le> m \<Longrightarrow> m \<le> n \<Longrightarrow> m dvd fact n" |
113 shows "1 \<le> m \<Longrightarrow> m \<le> n \<Longrightarrow> m dvd fact n" |
105 by (induct n) (auto simp: dvdI le_Suc_eq) |
114 by (induct n) (auto simp: dvdI le_Suc_eq) |
106 |
115 |
107 lemma fact_ge_self: "fact n \<ge> n" |
116 lemma fact_ge_self: "fact n \<ge> n" |
108 by (cases "n = 0") (simp_all add: dvd_imp_le dvd_fact) |
117 by (cases "n = 0") (simp_all add: dvd_imp_le dvd_fact) |
109 |
|
110 lemma fact_altdef_nat: "fact n = \<Prod>{1..n}" |
|
111 by (induct n) (auto simp: atLeastAtMostSuc_conv) |
|
112 |
|
113 lemma fact_altdef: "fact n = (\<Prod>i=1..n. of_nat i)" |
|
114 by (induct n) (auto simp: atLeastAtMostSuc_conv) |
|
115 |
|
116 lemma fact_altdef': "fact n = of_nat (\<Prod>{1..n})" |
|
117 by (subst fact_altdef_nat [symmetric]) simp |
|
118 |
118 |
119 lemma fact_dvd: "n \<le> m \<Longrightarrow> fact n dvd (fact m :: 'a :: {semiring_div,linordered_semidom})" |
119 lemma fact_dvd: "n \<le> m \<Longrightarrow> fact n dvd (fact m :: 'a :: {semiring_div,linordered_semidom})" |
120 by (induct m) (auto simp: le_Suc_eq) |
120 by (induct m) (auto simp: le_Suc_eq) |
121 |
121 |
122 lemma fact_mod: "m \<le> n \<Longrightarrow> fact n mod (fact m :: 'a :: {semiring_div,linordered_semidom}) = 0" |
122 lemma fact_mod: "m \<le> n \<Longrightarrow> fact n mod (fact m :: 'a :: {semiring_div,linordered_semidom}) = 0" |
467 |
467 |
468 subsection\<open>Pochhammer's symbol : generalized rising factorial\<close> |
468 subsection\<open>Pochhammer's symbol : generalized rising factorial\<close> |
469 |
469 |
470 text \<open>See @{url "http://en.wikipedia.org/wiki/Pochhammer_symbol"}\<close> |
470 text \<open>See @{url "http://en.wikipedia.org/wiki/Pochhammer_symbol"}\<close> |
471 |
471 |
472 definition (in comm_semiring_1) "pochhammer (a :: 'a) n = |
472 definition (in comm_semiring_1) pochhammer :: "'a \<Rightarrow> nat \<Rightarrow> 'a" |
473 (if n = 0 then 1 else setprod (\<lambda>n. a + of_nat n) {0 .. n - 1})" |
473 where |
474 |
474 "pochhammer (a :: 'a) n = setprod (\<lambda>n. a + of_nat n) {..<n}" |
|
475 |
|
476 lemma pochhammer_Suc_setprod: |
|
477 "pochhammer a (Suc n) = setprod (\<lambda>n. a + of_nat n) {..n}" |
|
478 by (simp add: pochhammer_def lessThan_Suc_atMost) |
|
479 |
475 lemma pochhammer_0 [simp]: "pochhammer a 0 = 1" |
480 lemma pochhammer_0 [simp]: "pochhammer a 0 = 1" |
476 by (simp add: pochhammer_def) |
481 by (simp add: pochhammer_def) |
477 |
482 |
478 lemma pochhammer_1 [simp]: "pochhammer a 1 = a" |
483 lemma pochhammer_1 [simp]: "pochhammer a 1 = a" |
479 by (simp add: pochhammer_def) |
484 by (simp add: pochhammer_def lessThan_Suc) |
480 |
485 |
481 lemma pochhammer_Suc0 [simp]: "pochhammer a (Suc 0) = a" |
486 lemma pochhammer_Suc0 [simp]: "pochhammer a (Suc 0) = a" |
482 by (simp add: pochhammer_def) |
487 by (simp add: pochhammer_def lessThan_Suc) |
483 |
488 |
484 lemma pochhammer_Suc_setprod: "pochhammer a (Suc n) = setprod (\<lambda>n. a + of_nat n) {0 .. n}" |
489 lemma pochhammer_Suc: "pochhammer a (Suc n) = pochhammer a n * (a + of_nat n)" |
485 by (simp add: pochhammer_def) |
490 by (simp add: pochhammer_def lessThan_Suc ac_simps) |
486 |
491 |
487 lemma pochhammer_of_nat: "pochhammer (of_nat x) n = of_nat (pochhammer x n)" |
492 lemma pochhammer_of_nat: "pochhammer (of_nat x) n = of_nat (pochhammer x n)" |
488 by (simp add: pochhammer_def) |
493 by (simp add: pochhammer_def) |
489 |
494 |
490 lemma pochhammer_of_int: "pochhammer (of_int x) n = of_int (pochhammer x n)" |
495 lemma pochhammer_of_int: "pochhammer (of_int x) n = of_int (pochhammer x n)" |
491 by (simp add: pochhammer_def) |
496 by (simp add: pochhammer_def) |
492 |
497 |
493 lemma setprod_nat_ivl_Suc: "setprod f {0 .. Suc n} = setprod f {0..n} * f (Suc n)" |
498 lemma setprod_nat_ivl_Suc: "setprod f {.. Suc n} = setprod f {..n} * f (Suc n)" |
494 proof - |
499 proof - |
495 have "{0..Suc n} = {0..n} \<union> {Suc n}" by auto |
500 have "{..Suc n} = {..n} \<union> {Suc n}" by auto |
496 then show ?thesis by (simp add: field_simps) |
501 then show ?thesis by (simp add: field_simps) |
497 qed |
502 qed |
498 |
503 |
499 lemma setprod_nat_ivl_1_Suc: "setprod f {0 .. Suc n} = f 0 * setprod f {1.. Suc n}" |
504 lemma setprod_nat_ivl_1_Suc: "setprod f {.. Suc n} = f 0 * setprod f {1.. Suc n}" |
500 proof - |
505 proof - |
501 have "{0..Suc n} = {0} \<union> {1 .. Suc n}" by auto |
506 have "{..Suc n} = {0} \<union> {1 .. Suc n}" by auto |
502 then show ?thesis by simp |
507 then show ?thesis by simp |
503 qed |
|
504 |
|
505 |
|
506 lemma pochhammer_Suc: "pochhammer a (Suc n) = pochhammer a n * (a + of_nat n)" |
|
507 proof (cases n) |
|
508 case 0 |
|
509 then show ?thesis by simp |
|
510 next |
|
511 case (Suc n) |
|
512 show ?thesis unfolding Suc pochhammer_Suc_setprod setprod_nat_ivl_Suc .. |
|
513 qed |
508 qed |
514 |
509 |
515 lemma pochhammer_rec: "pochhammer a (Suc n) = a * pochhammer (a + 1) n" |
510 lemma pochhammer_rec: "pochhammer a (Suc n) = a * pochhammer (a + 1) n" |
516 proof (cases "n = 0") |
511 proof (cases "n = 0") |
517 case True |
512 case True |
518 then show ?thesis by (simp add: pochhammer_Suc_setprod) |
513 then show ?thesis by (simp add: pochhammer_Suc_setprod) |
519 next |
514 next |
520 case False |
515 case False |
521 have *: "finite {1 .. n}" "0 \<notin> {1 .. n}" by auto |
516 have *: "finite {1 .. n}" "0 \<notin> {1 .. n}" by auto |
522 have eq: "insert 0 {1 .. n} = {0..n}" by auto |
517 have eq: "insert 0 {1 .. n} = {..n}" by auto |
523 have **: "(\<Prod>n\<in>{1::nat..n}. a + of_nat n) = (\<Prod>n\<in>{0::nat..n - 1}. a + 1 + of_nat n)" |
518 have **: "(\<Prod>n\<in>{1..n}. a + of_nat n) = (\<Prod>n\<in>{..<n}. a + 1 + of_nat n)" |
524 apply (rule setprod.reindex_cong [where l = Suc]) |
519 apply (rule setprod.reindex_cong [where l = Suc]) |
525 using False |
520 using False |
526 apply (auto simp add: fun_eq_iff field_simps) |
521 apply (auto simp add: fun_eq_iff field_simps image_Suc_lessThan) |
527 done |
522 done |
528 show ?thesis |
523 show ?thesis |
529 apply (simp add: pochhammer_def) |
524 apply (simp add: pochhammer_def lessThan_Suc_atMost) |
530 unfolding setprod.insert [OF *, unfolded eq] |
525 unfolding setprod.insert [OF *, unfolded eq] |
531 using ** apply (simp add: field_simps) |
526 using ** apply (simp add: field_simps) |
532 done |
527 done |
533 qed |
528 qed |
534 |
529 |
543 by (simp_all add: pochhammer_rec algebra_simps) |
538 by (simp_all add: pochhammer_rec algebra_simps) |
544 finally show ?case . |
539 finally show ?case . |
545 qed simp_all |
540 qed simp_all |
546 |
541 |
547 lemma pochhammer_fact: "fact n = pochhammer 1 n" |
542 lemma pochhammer_fact: "fact n = pochhammer 1 n" |
548 unfolding fact_altdef |
543 apply (auto simp add: pochhammer_def fact_altdef) |
549 apply (cases n) |
|
550 apply (simp_all add: pochhammer_Suc_setprod) |
|
551 apply (rule setprod.reindex_cong [where l = Suc]) |
544 apply (rule setprod.reindex_cong [where l = Suc]) |
552 apply (auto simp add: fun_eq_iff) |
545 apply (auto simp add: image_Suc_lessThan) |
553 done |
546 done |
554 |
547 |
555 lemma pochhammer_of_nat_eq_0_lemma: |
548 lemma pochhammer_of_nat_eq_0_lemma: |
556 assumes "k > n" |
549 assumes "k > n" |
557 shows "pochhammer (- (of_nat n :: 'a:: idom)) k = 0" |
550 shows "pochhammer (- (of_nat n :: 'a:: idom)) k = 0" |
558 proof (cases "n = 0") |
551 using assms by (auto simp add: pochhammer_def) |
559 case True |
|
560 then show ?thesis |
|
561 using assms by (cases k) (simp_all add: pochhammer_rec) |
|
562 next |
|
563 case False |
|
564 from assms obtain h where "k = Suc h" by (cases k) auto |
|
565 then show ?thesis |
|
566 by (simp add: pochhammer_Suc_setprod) |
|
567 (metis Suc_leI Suc_le_mono assms atLeastAtMost_iff less_eq_nat.simps(1)) |
|
568 qed |
|
569 |
552 |
570 lemma pochhammer_of_nat_eq_0_lemma': |
553 lemma pochhammer_of_nat_eq_0_lemma': |
571 assumes kn: "k \<le> n" |
554 assumes kn: "k \<le> n" |
572 shows "pochhammer (- (of_nat n :: 'a:: {idom,ring_char_0})) k \<noteq> 0" |
555 shows "pochhammer (- (of_nat n :: 'a:: {idom,ring_char_0})) k \<noteq> 0" |
573 proof (cases k) |
556 proof (cases k) |
587 using pochhammer_of_nat_eq_0_lemma[of n k, where ?'a='a] |
570 using pochhammer_of_nat_eq_0_lemma[of n k, where ?'a='a] |
588 pochhammer_of_nat_eq_0_lemma'[of k n, where ?'a = 'a] |
571 pochhammer_of_nat_eq_0_lemma'[of k n, where ?'a = 'a] |
589 by (auto simp add: not_le[symmetric]) |
572 by (auto simp add: not_le[symmetric]) |
590 |
573 |
591 lemma pochhammer_eq_0_iff: "pochhammer a n = (0::'a::field_char_0) \<longleftrightarrow> (\<exists>k < n. a = - of_nat k)" |
574 lemma pochhammer_eq_0_iff: "pochhammer a n = (0::'a::field_char_0) \<longleftrightarrow> (\<exists>k < n. a = - of_nat k)" |
592 apply (auto simp add: pochhammer_of_nat_eq_0_iff) |
575 by (auto simp add: pochhammer_def eq_neg_iff_add_eq_0) |
593 apply (cases n) |
|
594 apply (auto simp add: pochhammer_def algebra_simps group_add_class.eq_neg_iff_add_eq_0) |
|
595 apply (metis leD not_less_eq) |
|
596 done |
|
597 |
576 |
598 lemma pochhammer_eq_0_mono: |
577 lemma pochhammer_eq_0_mono: |
599 "pochhammer a n = (0::'a::field_char_0) \<Longrightarrow> m \<ge> n \<Longrightarrow> pochhammer a m = 0" |
578 "pochhammer a n = (0::'a::field_char_0) \<Longrightarrow> m \<ge> n \<Longrightarrow> pochhammer a m = 0" |
600 unfolding pochhammer_eq_0_iff by auto |
579 unfolding pochhammer_eq_0_iff by auto |
601 |
580 |
648 "m \<le> n \<Longrightarrow> pochhammer z n = pochhammer z m * pochhammer (z + of_nat m) (n - m)" |
627 "m \<le> n \<Longrightarrow> pochhammer z n = pochhammer z m * pochhammer (z + of_nat m) (n - m)" |
649 using pochhammer_product'[of z m "n - m"] by simp |
628 using pochhammer_product'[of z m "n - m"] by simp |
650 |
629 |
651 lemma pochhammer_times_pochhammer_half: |
630 lemma pochhammer_times_pochhammer_half: |
652 fixes z :: "'a :: field_char_0" |
631 fixes z :: "'a :: field_char_0" |
653 shows "pochhammer z (Suc n) * pochhammer (z + 1/2) (Suc n) = (\<Prod>k=0..2*n+1. z + of_nat k / 2)" |
632 shows "pochhammer z (Suc n) * pochhammer (z + 1/2) (Suc n) = (\<Prod>k\<le>2*n+1. z + of_nat k / 2)" |
654 proof (induction n) |
633 proof (induction n) |
655 case (Suc n) |
634 case (Suc n) |
656 define n' where "n' = Suc n" |
635 define n' where "n' = Suc n" |
657 have "pochhammer z (Suc n') * pochhammer (z + 1 / 2) (Suc n') = |
636 have "pochhammer z (Suc n') * pochhammer (z + 1 / 2) (Suc n') = |
658 (pochhammer z n' * pochhammer (z + 1 / 2) n') * |
637 (pochhammer z n' * pochhammer (z + 1 / 2) n') * |
659 ((z + of_nat n') * (z + 1/2 + of_nat n'))" (is "_ = _ * ?A") |
638 ((z + of_nat n') * (z + 1/2 + of_nat n'))" (is "_ = _ * ?A") |
660 by (simp_all add: pochhammer_rec' mult_ac) |
639 by (simp_all add: pochhammer_rec' mult_ac) |
661 also have "?A = (z + of_nat (Suc (2 * n + 1)) / 2) * (z + of_nat (Suc (Suc (2 * n + 1))) / 2)" |
640 also have "?A = (z + of_nat (Suc (2 * n + 1)) / 2) * (z + of_nat (Suc (Suc (2 * n + 1))) / 2)" |
662 (is "_ = ?A") by (simp add: field_simps n'_def) |
641 (is "_ = ?A") by (simp add: field_simps n'_def) |
663 also note Suc[folded n'_def] |
642 also note Suc[folded n'_def] |
664 also have "(\<Prod>k = 0..2 * n + 1. z + of_nat k / 2) * ?A = (\<Prod>k = 0..2 * Suc n + 1. z + of_nat k / 2)" |
643 also have "(\<Prod>k\<le>2 * n + 1. z + of_nat k / 2) * ?A = (\<Prod>k\<le>2 * Suc n + 1. z + of_nat k / 2)" |
665 by (simp add: setprod_nat_ivl_Suc) |
644 by (simp add: setprod_nat_ivl_Suc) |
666 finally show ?case by (simp add: n'_def) |
645 finally show ?case by (simp add: n'_def) |
667 qed (simp add: setprod_nat_ivl_Suc) |
646 qed (simp add: setprod_nat_ivl_Suc) |
668 |
647 |
669 lemma pochhammer_double: |
648 lemma pochhammer_double: |
697 |
676 |
698 |
677 |
699 subsection\<open>Generalized binomial coefficients\<close> |
678 subsection\<open>Generalized binomial coefficients\<close> |
700 |
679 |
701 definition (in field_char_0) gbinomial :: "'a \<Rightarrow> nat \<Rightarrow> 'a" (infixl "gchoose" 65) |
680 definition (in field_char_0) gbinomial :: "'a \<Rightarrow> nat \<Rightarrow> 'a" (infixl "gchoose" 65) |
702 where "a gchoose n = |
681 where |
703 (if n = 0 then 1 else (setprod (\<lambda>i. a - of_nat i) {0 .. n - 1}) / (fact n))" |
682 "a gchoose n = setprod (\<lambda>i. a - of_nat i) {..<n} / fact n" |
|
683 |
|
684 lemma gbinomial_Suc: |
|
685 "a gchoose (Suc k) = setprod (\<lambda>i. a - of_nat i) {..k} / fact (Suc k)" |
|
686 by (simp add: gbinomial_def lessThan_Suc_atMost) |
704 |
687 |
705 lemma gbinomial_0 [simp]: "a gchoose 0 = 1" "0 gchoose (Suc n) = 0" |
688 lemma gbinomial_0 [simp]: "a gchoose 0 = 1" "0 gchoose (Suc n) = 0" |
706 by (simp_all add: gbinomial_def) |
689 by (simp_all add: gbinomial_def) |
707 |
690 |
708 lemma gbinomial_pochhammer: "a gchoose n = (- 1) ^ n * pochhammer (- a) n / (fact n)" |
691 lemma gbinomial_pochhammer: "a gchoose n = (- 1) ^ n * pochhammer (- a) n / (fact n)" |
709 proof (cases "n = 0") |
692 proof (cases "n = 0") |
710 case True |
693 case True |
711 then show ?thesis by simp |
694 then show ?thesis by simp |
712 next |
695 next |
713 case False |
696 case False |
714 then have eq: "(- 1) ^ n = (\<Prod>i = 0..n - 1. - 1)" |
697 then have eq: "(- 1) ^ n = (\<Prod>i<n. - 1)" |
715 by (auto simp add: setprod_constant) |
698 by (auto simp add: setprod_constant) |
716 from False show ?thesis |
699 from False show ?thesis |
717 by (simp add: pochhammer_def gbinomial_def field_simps |
700 by (simp add: pochhammer_def gbinomial_def field_simps |
718 eq setprod.distrib[symmetric]) |
701 eq setprod.distrib[symmetric]) |
719 qed |
702 qed |
738 { assume "k=0" then have ?thesis by simp } |
721 { assume "k=0" then have ?thesis by simp } |
739 moreover |
722 moreover |
740 { assume kn: "k \<le> n" and k0: "k\<noteq> 0" |
723 { assume kn: "k \<le> n" and k0: "k\<noteq> 0" |
741 from k0 obtain h where h: "k = Suc h" by (cases k) auto |
724 from k0 obtain h where h: "k = Suc h" by (cases k) auto |
742 from h |
725 from h |
743 have eq:"(- 1 :: 'a) ^ k = setprod (\<lambda>i. - 1) {0..h}" |
726 have eq:"(- 1 :: 'a) ^ k = setprod (\<lambda>i. - 1) {..h}" |
744 by (subst setprod_constant) auto |
727 by (subst setprod_constant) auto |
745 have eq': "(\<Prod>i\<in>{0..h}. of_nat n + - (of_nat i :: 'a)) = (\<Prod>i\<in>{n - h..n}. of_nat i)" |
728 have eq': "(\<Prod>i\<le>h. of_nat n + - (of_nat i :: 'a)) = (\<Prod>i\<in>{n - h..n}. of_nat i)" |
746 using h kn |
729 using h kn |
747 by (intro setprod.reindex_bij_witness[where i="op - n" and j="op - n"]) |
730 by (intro setprod.reindex_bij_witness[where i="op - n" and j="op - n"]) |
748 (auto simp: of_nat_diff) |
731 (auto simp: of_nat_diff) |
749 have th0: "finite {1..n - Suc h}" "finite {n - h .. n}" |
732 have th0: "finite {1..n - Suc h}" "finite {n - h .. n}" |
750 "{1..n - Suc h} \<inter> {n - h .. n} = {}" and |
733 "{1..n - Suc h} \<inter> {n - h .. n} = {}" and |
768 have "k > n \<or> k = 0 \<or> (k \<le> n \<and> k \<noteq> 0)" by arith |
751 have "k > n \<or> k = 0 \<or> (k \<le> n \<and> k \<noteq> 0)" by arith |
769 ultimately show ?thesis by blast |
752 ultimately show ?thesis by blast |
770 qed |
753 qed |
771 |
754 |
772 lemma gbinomial_1[simp]: "a gchoose 1 = a" |
755 lemma gbinomial_1[simp]: "a gchoose 1 = a" |
773 by (simp add: gbinomial_def) |
756 by (simp add: gbinomial_def lessThan_Suc) |
774 |
757 |
775 lemma gbinomial_Suc0[simp]: "a gchoose (Suc 0) = a" |
758 lemma gbinomial_Suc0[simp]: "a gchoose (Suc 0) = a" |
776 by (simp add: gbinomial_def) |
759 by (simp add: gbinomial_def lessThan_Suc) |
777 |
760 |
778 lemma gbinomial_mult_1: |
761 lemma gbinomial_mult_1: |
779 fixes a :: "'a :: field_char_0" |
762 fixes a :: "'a :: field_char_0" |
780 shows "a * (a gchoose n) = |
763 shows "a * (a gchoose n) = |
781 of_nat n * (a gchoose n) + of_nat (Suc n) * (a gchoose (Suc n))" (is "?l = ?r") |
764 of_nat n * (a gchoose n) + of_nat (Suc n) * (a gchoose (Suc n))" (is "?l = ?r") |
782 proof - |
765 proof - |
783 have "?r = ((- 1) ^n * pochhammer (- a) n / (fact n)) * (of_nat n - (- a + of_nat n))" |
766 have "?r = ((- 1) ^n * pochhammer (- a) n / (fact n)) * (of_nat n - (- a + of_nat n))" |
784 unfolding gbinomial_pochhammer |
767 unfolding gbinomial_pochhammer |
785 pochhammer_Suc right_diff_distrib power_Suc |
768 pochhammer_Suc right_diff_distrib power_Suc |
786 apply (simp del: of_nat_Suc fact.simps) |
769 apply (simp del: of_nat_Suc fact_Suc) |
787 apply (auto simp add: field_simps simp del: of_nat_Suc) |
770 apply (auto simp add: field_simps simp del: of_nat_Suc) |
788 done |
771 done |
789 also have "\<dots> = ?l" unfolding gbinomial_pochhammer |
772 also have "\<dots> = ?l" unfolding gbinomial_pochhammer |
790 by (simp add: field_simps) |
773 by (simp add: field_simps) |
791 finally show ?thesis .. |
774 finally show ?thesis .. |
794 lemma gbinomial_mult_1': |
777 lemma gbinomial_mult_1': |
795 fixes a :: "'a :: field_char_0" |
778 fixes a :: "'a :: field_char_0" |
796 shows "(a gchoose n) * a = of_nat n * (a gchoose n) + of_nat (Suc n) * (a gchoose (Suc n))" |
779 shows "(a gchoose n) * a = of_nat n * (a gchoose n) + of_nat (Suc n) * (a gchoose (Suc n))" |
797 by (simp add: mult.commute gbinomial_mult_1) |
780 by (simp add: mult.commute gbinomial_mult_1) |
798 |
781 |
799 lemma gbinomial_Suc: |
|
800 "a gchoose (Suc k) = (setprod (\<lambda>i. a - of_nat i) {0 .. k}) / (fact (Suc k))" |
|
801 by (simp add: gbinomial_def) |
|
802 |
|
803 lemma gbinomial_mult_fact: |
782 lemma gbinomial_mult_fact: |
804 fixes a :: "'a::field_char_0" |
783 fixes a :: "'a::field_char_0" |
805 shows |
784 shows |
806 "fact (Suc k) * (a gchoose (Suc k)) = |
785 "fact (Suc k) * (a gchoose (Suc k)) = |
807 (setprod (\<lambda>i. a - of_nat i) {0 .. k})" |
786 (setprod (\<lambda>i. a - of_nat i) {.. k})" |
808 by (simp_all add: gbinomial_Suc field_simps del: fact.simps) |
787 by (simp_all add: gbinomial_Suc field_simps del: fact_Suc) |
809 |
788 |
810 lemma gbinomial_mult_fact': |
789 lemma gbinomial_mult_fact': |
811 fixes a :: "'a::field_char_0" |
790 fixes a :: "'a::field_char_0" |
812 shows "(a gchoose (Suc k)) * fact (Suc k) = (setprod (\<lambda>i. a - of_nat i) {0 .. k})" |
791 shows "(a gchoose (Suc k)) * fact (Suc k) = (setprod (\<lambda>i. a - of_nat i) {.. k})" |
813 using gbinomial_mult_fact[of k a] |
792 using gbinomial_mult_fact[of k a] |
814 by (subst mult.commute) |
793 by (subst mult.commute) |
815 |
794 |
816 lemma gbinomial_Suc_Suc: |
795 lemma gbinomial_Suc_Suc: |
817 fixes a :: "'a :: field_char_0" |
796 fixes a :: "'a :: field_char_0" |
819 proof (cases k) |
798 proof (cases k) |
820 case 0 |
799 case 0 |
821 then show ?thesis by simp |
800 then show ?thesis by simp |
822 next |
801 next |
823 case (Suc h) |
802 case (Suc h) |
824 have eq0: "(\<Prod>i\<in>{1..k}. (a + 1) - of_nat i) = (\<Prod>i\<in>{0..h}. a - of_nat i)" |
803 have eq0: "(\<Prod>i\<in>{1..k}. (a + 1) - of_nat i) = (\<Prod>i\<in>{..h}. a - of_nat i)" |
825 apply (rule setprod.reindex_cong [where l = Suc]) |
804 apply (rule setprod.reindex_cong [where l = Suc]) |
826 using Suc |
805 using Suc |
827 apply auto |
806 apply (auto simp add: image_Suc_atMost) |
828 done |
807 done |
829 have "fact (Suc k) * (a gchoose k + (a gchoose (Suc k))) = |
808 have "fact (Suc k) * (a gchoose k + (a gchoose (Suc k))) = |
830 (a gchoose Suc h) * (fact (Suc (Suc h))) + |
809 (a gchoose Suc h) * (fact (Suc (Suc h))) + |
831 (a gchoose Suc (Suc h)) * (fact (Suc (Suc h)))" |
810 (a gchoose Suc (Suc h)) * (fact (Suc (Suc h)))" |
832 by (simp add: Suc field_simps del: fact.simps) |
811 by (simp add: Suc field_simps del: fact_Suc) |
833 also have "... = (a gchoose Suc h) * of_nat (Suc (Suc h) * fact (Suc h)) + |
812 also have "... = (a gchoose Suc h) * of_nat (Suc (Suc h) * fact (Suc h)) + |
834 (\<Prod>i = 0..Suc h. a - of_nat i)" |
813 (\<Prod>i\<le>Suc h. a - of_nat i)" |
835 by (metis fact.simps(2) gbinomial_mult_fact' of_nat_fact of_nat_id) |
814 by (metis fact_Suc gbinomial_mult_fact' of_nat_fact of_nat_id) |
836 also have "... = (fact (Suc h) * (a gchoose Suc h)) * of_nat (Suc (Suc h)) + |
815 also have "... = (fact (Suc h) * (a gchoose Suc h)) * of_nat (Suc (Suc h)) + |
837 (\<Prod>i = 0..Suc h. a - of_nat i)" |
816 (\<Prod>i\<le>Suc h. a - of_nat i)" |
838 by (simp only: fact.simps(2) mult.commute mult.left_commute of_nat_fact of_nat_id of_nat_mult) |
817 by (simp only: fact_Suc mult.commute mult.left_commute of_nat_fact of_nat_id of_nat_mult) |
839 also have "... = of_nat (Suc (Suc h)) * (\<Prod>i = 0..h. a - of_nat i) + |
818 also have "... = of_nat (Suc (Suc h)) * (\<Prod>i\<le>h. a - of_nat i) + |
840 (\<Prod>i = 0..Suc h. a - of_nat i)" |
819 (\<Prod>i\<le>Suc h. a - of_nat i)" |
841 by (metis gbinomial_mult_fact mult.commute) |
820 by (metis gbinomial_mult_fact mult.commute) |
842 also have "... = (\<Prod>i = 0..Suc h. a - of_nat i) + |
821 also have "... = (\<Prod>i\<le>Suc h. a - of_nat i) + |
843 (of_nat h * (\<Prod>i = 0..h. a - of_nat i) + 2 * (\<Prod>i = 0..h. a - of_nat i))" |
822 (of_nat h * (\<Prod>i\<le>h. a - of_nat i) + 2 * (\<Prod>i\<le>h. a - of_nat i))" |
844 by (simp add: field_simps) |
823 by (simp add: field_simps) |
845 also have "... = |
824 also have "... = |
846 ((a gchoose Suc h) * (fact (Suc h)) * of_nat (Suc k)) + (\<Prod>i\<in>{0::nat..Suc h}. a - of_nat i)" |
825 ((a gchoose Suc h) * (fact (Suc h)) * of_nat (Suc k)) + (\<Prod>i\<in>{..Suc h}. a - of_nat i)" |
847 unfolding gbinomial_mult_fact' |
826 unfolding gbinomial_mult_fact' |
848 by (simp add: comm_semiring_class.distrib field_simps Suc) |
827 by (simp add: comm_semiring_class.distrib field_simps Suc) |
849 also have "\<dots> = (\<Prod>i\<in>{0..h}. a - of_nat i) * (a + 1)" |
828 also have "\<dots> = (\<Prod>i\<in>{..h}. a - of_nat i) * (a + 1)" |
850 unfolding gbinomial_mult_fact' setprod_nat_ivl_Suc |
829 unfolding gbinomial_mult_fact' setprod_nat_ivl_Suc |
|
830 atMost_Suc |
851 by (simp add: field_simps Suc) |
831 by (simp add: field_simps Suc) |
852 also have "\<dots> = (\<Prod>i\<in>{0..k}. (a + 1) - of_nat i)" |
832 also have "\<dots> = (\<Prod>i\<in>{..k}. (a + 1) - of_nat i)" |
853 using eq0 |
833 using eq0 setprod_nat_ivl_1_Suc |
854 by (simp add: Suc setprod_nat_ivl_1_Suc) |
834 by (simp add: Suc setprod_nat_ivl_1_Suc) |
855 also have "\<dots> = (fact (Suc k)) * ((a + 1) gchoose (Suc k))" |
835 also have "\<dots> = (fact (Suc k)) * ((a + 1) gchoose (Suc k))" |
856 unfolding gbinomial_mult_fact .. |
836 unfolding gbinomial_mult_fact .. |
857 finally show ?thesis |
837 finally show ?thesis |
858 by (metis fact_nonzero mult_cancel_left) |
838 by (metis fact_nonzero mult_cancel_left) |
1022 lemma Suc_times_gbinomial: |
1002 lemma Suc_times_gbinomial: |
1023 "of_nat (Suc b) * ((a + 1) gchoose (Suc b)) = (a + 1) * (a gchoose b)" |
1003 "of_nat (Suc b) * ((a + 1) gchoose (Suc b)) = (a + 1) * (a gchoose b)" |
1024 proof (cases b) |
1004 proof (cases b) |
1025 case (Suc b) |
1005 case (Suc b) |
1026 hence "((a + 1) gchoose (Suc (Suc b))) = |
1006 hence "((a + 1) gchoose (Suc (Suc b))) = |
1027 (\<Prod>i = 0..Suc b. a + (1 - of_nat i)) / fact (b + 2)" |
1007 (\<Prod>i\<le>Suc b. a + (1 - of_nat i)) / fact (b + 2)" |
1028 by (simp add: field_simps gbinomial_def) |
1008 by (simp add: field_simps gbinomial_def lessThan_Suc_atMost) |
1029 also have "(\<Prod>i = 0..Suc b. a + (1 - of_nat i)) = (a + 1) * (\<Prod>i = 0..b. a - of_nat i)" |
1009 also have "(\<Prod>i\<le>Suc b. a + (1 - of_nat i)) = (a + 1) * (\<Prod>i\<le>b. a - of_nat i)" |
1030 by (simp add: setprod_nat_ivl_1_Suc setprod_shift_bounds_cl_Suc_ivl) |
1010 by (simp add: setprod_nat_ivl_1_Suc setprod_shift_bounds_cl_Suc_ivl atLeast0AtMost) |
1031 also have "... / fact (b + 2) = (a + 1) / of_nat (Suc (Suc b)) * (a gchoose Suc b)" |
1011 also have "... / fact (b + 2) = (a + 1) / of_nat (Suc (Suc b)) * (a gchoose Suc b)" |
1032 by (simp_all add: gbinomial_def setprod_nat_ivl_1_Suc setprod_shift_bounds_cl_Suc_ivl) |
1012 by (simp_all add: gbinomial_def setprod_nat_ivl_1_Suc setprod_shift_bounds_cl_Suc_ivl lessThan_Suc_atMost) |
1033 finally show ?thesis by (simp add: Suc field_simps del: of_nat_Suc) |
1013 finally show ?thesis by (simp add: Suc field_simps del: of_nat_Suc) |
1034 qed simp |
1014 qed simp |
1035 |
1015 |
1036 lemma gbinomial_factors: |
1016 lemma gbinomial_factors: |
1037 "((a + 1) gchoose (Suc b)) = (a + 1) / of_nat (Suc b) * (a gchoose b)" |
1017 "((a + 1) gchoose (Suc b)) = (a + 1) / of_nat (Suc b) * (a gchoose b)" |
1038 proof (cases b) |
1018 proof (cases b) |
1039 case (Suc b) |
1019 case (Suc b) |
1040 hence "((a + 1) gchoose (Suc (Suc b))) = |
1020 hence "((a + 1) gchoose (Suc (Suc b))) = |
1041 (\<Prod>i = 0..Suc b. a + (1 - of_nat i)) / fact (b + 2)" |
1021 (\<Prod>i\<le>Suc b. a + (1 - of_nat i)) / fact (b + 2)" |
1042 by (simp add: field_simps gbinomial_def) |
1022 by (simp add: field_simps gbinomial_def lessThan_Suc_atMost) |
1043 also have "(\<Prod>i = 0..Suc b. a + (1 - of_nat i)) = (a + 1) * (\<Prod>i = 0..b. a - of_nat i)" |
1023 also have "(\<Prod>i\<le>Suc b. a + (1 - of_nat i)) = (a + 1) * (\<Prod>i = 0..b. a - of_nat i)" |
1044 by (simp add: setprod_nat_ivl_1_Suc setprod_shift_bounds_cl_Suc_ivl) |
1024 by (simp add: setprod_nat_ivl_1_Suc setprod_shift_bounds_cl_Suc_ivl) |
1045 also have "... / fact (b + 2) = (a + 1) / of_nat (Suc (Suc b)) * (a gchoose Suc b)" |
1025 also have "... / fact (b + 2) = (a + 1) / of_nat (Suc (Suc b)) * (a gchoose Suc b)" |
1046 by (simp_all add: gbinomial_def setprod_nat_ivl_1_Suc setprod_shift_bounds_cl_Suc_ivl) |
1026 by (simp_all add: gbinomial_def setprod_nat_ivl_1_Suc setprod_shift_bounds_cl_Suc_ivl lessThan_Suc_atMost atLeast0AtMost) |
1047 finally show ?thesis by (simp add: Suc) |
1027 finally show ?thesis by (simp add: Suc) |
1048 qed simp |
1028 qed simp |
1049 |
1029 |
1050 lemma gbinomial_rec: "((r + 1) gchoose (Suc k)) = (r gchoose k) * ((r + 1) / of_nat (Suc k))" |
1030 lemma gbinomial_rec: "((r + 1) gchoose (Suc k)) = (r gchoose k) * ((r + 1) / of_nat (Suc k))" |
1051 using gbinomial_mult_1[of r k] |
1031 using gbinomial_mult_1[of r k] |
1577 also have "\<dots> = fold_atLeastAtMost_nat (op *) 2 n 1" |
1556 also have "\<dots> = fold_atLeastAtMost_nat (op *) 2 n 1" |
1578 by (simp add: setprod_atLeastAtMost_code) |
1557 by (simp add: setprod_atLeastAtMost_code) |
1579 finally show ?thesis . |
1558 finally show ?thesis . |
1580 qed |
1559 qed |
1581 |
1560 |
|
1561 lemma setprod_lessThan_fold_atLeastAtMost_nat: |
|
1562 "setprod f {..<Suc n} = fold_atLeastAtMost_nat (times \<circ> f) 0 n 1" |
|
1563 by (simp add: lessThan_Suc_atMost atLeast0AtMost [symmetric] setprod_atLeastAtMost_code comp_def) |
|
1564 |
|
1565 |
1582 lemma pochhammer_code [code]: |
1566 lemma pochhammer_code [code]: |
1583 "pochhammer a n = (if n = 0 then 1 else |
1567 "pochhammer a n = (if n = 0 then 1 else |
1584 fold_atLeastAtMost_nat (\<lambda>n acc. (a + of_nat n) * acc) 0 (n - 1) 1)" |
1568 fold_atLeastAtMost_nat (\<lambda>n acc. (a + of_nat n) * acc) 0 (n - 1) 1)" |
1585 by (simp add: setprod_atLeastAtMost_code pochhammer_def) |
1569 by (cases n) (simp_all add: pochhammer_def setprod_lessThan_fold_atLeastAtMost_nat comp_def) |
1586 |
1570 |
1587 lemma gbinomial_code [code]: |
1571 lemma gbinomial_code [code]: |
1588 "a gchoose n = (if n = 0 then 1 else |
1572 "a gchoose n = (if n = 0 then 1 else |
1589 fold_atLeastAtMost_nat (\<lambda>n acc. (a - of_nat n) * acc) 0 (n - 1) 1 / fact n)" |
1573 fold_atLeastAtMost_nat (\<lambda>n acc. (a - of_nat n) * acc) 0 (n - 1) 1 / fact n)" |
1590 by (simp add: setprod_atLeastAtMost_code gbinomial_def) |
1574 by (cases n) (simp_all add: gbinomial_def setprod_lessThan_fold_atLeastAtMost_nat comp_def) |
1591 |
1575 |
1592 (*TODO: This code equation breaks Scala code generation in HOL-Codegenerator_Test. We have to figure out why and how to prevent that. *) |
1576 (*TODO: This code equation breaks Scala code generation in HOL-Codegenerator_Test. We have to figure out why and how to prevent that. *) |
1593 |
1577 |
1594 (* |
1578 (* |
1595 lemma binomial_code [code]: |
1579 lemma binomial_code [code]: |