729 |
729 |
730 subsection \<open>Prime factorizations\<close> |
730 subsection \<open>Prime factorizations\<close> |
731 |
731 |
732 (* FIXME some overlap with material in UniqueFactorization, class unique_factorization *) |
732 (* FIXME some overlap with material in UniqueFactorization, class unique_factorization *) |
733 |
733 |
734 definition "primefact ps n \<longleftrightarrow> foldr op * ps 1 = n \<and> (\<forall>p\<in> set ps. prime p)" |
734 definition "primefact ps n \<longleftrightarrow> foldr ( * ) ps 1 = n \<and> (\<forall>p\<in> set ps. prime p)" |
735 |
735 |
736 lemma primefact: |
736 lemma primefact: |
737 fixes n :: nat |
737 fixes n :: nat |
738 assumes n: "n \<noteq> 0" |
738 assumes n: "n \<noteq> 0" |
739 shows "\<exists>ps. primefact ps n" |
739 shows "\<exists>ps. primefact ps n" |
741 obtain xs where xs: "mset xs = prime_factorization n" |
741 obtain xs where xs: "mset xs = prime_factorization n" |
742 using ex_mset [of "prime_factorization n"] by blast |
742 using ex_mset [of "prime_factorization n"] by blast |
743 from assms have "n = prod_mset (prime_factorization n)" |
743 from assms have "n = prod_mset (prime_factorization n)" |
744 by (simp add: prod_mset_prime_factorization) |
744 by (simp add: prod_mset_prime_factorization) |
745 also have "\<dots> = prod_mset (mset xs)" by (simp add: xs) |
745 also have "\<dots> = prod_mset (mset xs)" by (simp add: xs) |
746 also have "\<dots> = foldr op * xs 1" by (induct xs) simp_all |
746 also have "\<dots> = foldr ( * ) xs 1" by (induct xs) simp_all |
747 finally have "foldr op * xs 1 = n" .. |
747 finally have "foldr ( * ) xs 1 = n" .. |
748 moreover from xs have "\<forall>p\<in>#mset xs. prime p" by auto |
748 moreover from xs have "\<forall>p\<in>#mset xs. prime p" by auto |
749 ultimately have "primefact xs n" by (auto simp: primefact_def) |
749 ultimately have "primefact xs n" by (auto simp: primefact_def) |
750 then show ?thesis .. |
750 then show ?thesis .. |
751 qed |
751 qed |
752 |
752 |
761 case Nil |
761 case Nil |
762 then show ?case by (auto simp: primefact_def) |
762 then show ?case by (auto simp: primefact_def) |
763 next |
763 next |
764 case (Cons q qs) |
764 case (Cons q qs) |
765 from Cons.prems[unfolded primefact_def] |
765 from Cons.prems[unfolded primefact_def] |
766 have q: "prime q" "q * foldr op * qs 1 = n" "\<forall>p \<in>set qs. prime p" |
766 have q: "prime q" "q * foldr ( * ) qs 1 = n" "\<forall>p \<in>set qs. prime p" |
767 and p: "prime p" "p dvd q * foldr op * qs 1" |
767 and p: "prime p" "p dvd q * foldr ( * ) qs 1" |
768 by simp_all |
768 by simp_all |
769 consider "p dvd q" | "p dvd foldr op * qs 1" |
769 consider "p dvd q" | "p dvd foldr ( * ) qs 1" |
770 by (metis p prime_dvd_mult_eq_nat) |
770 by (metis p prime_dvd_mult_eq_nat) |
771 then show ?case |
771 then show ?case |
772 proof cases |
772 proof cases |
773 case 1 |
773 case 1 |
774 with p(1) q(1) have "p = q" |
774 with p(1) q(1) have "p = q" |
775 unfolding prime_nat_iff by auto |
775 unfolding prime_nat_iff by auto |
776 then show ?thesis by simp |
776 then show ?thesis by simp |
777 next |
777 next |
778 case prem: 2 |
778 case prem: 2 |
779 from q(3) have pqs: "primefact qs (foldr op * qs 1)" |
779 from q(3) have pqs: "primefact qs (foldr ( * ) qs 1)" |
780 by (simp add: primefact_def) |
780 by (simp add: primefact_def) |
781 from Cons.hyps[OF pqs p(1) prem] show ?thesis by simp |
781 from Cons.hyps[OF pqs p(1) prem] show ?thesis by simp |
782 qed |
782 qed |
783 qed |
783 qed |
784 |
784 |
785 lemma primefact_variant: "primefact ps n \<longleftrightarrow> foldr op * ps 1 = n \<and> list_all prime ps" |
785 lemma primefact_variant: "primefact ps n \<longleftrightarrow> foldr ( * ) ps 1 = n \<and> list_all prime ps" |
786 by (auto simp add: primefact_def list_all_iff) |
786 by (auto simp add: primefact_def list_all_iff) |
787 |
787 |
788 text \<open>Variant of Lucas theorem.\<close> |
788 text \<open>Variant of Lucas theorem.\<close> |
789 lemma lucas_primefact: |
789 lemma lucas_primefact: |
790 assumes n: "n \<ge> 2" and an: "[a^(n - 1) = 1] (mod n)" |
790 assumes n: "n \<ge> 2" and an: "[a^(n - 1) = 1] (mod n)" |
791 and psn: "foldr op * ps 1 = n - 1" |
791 and psn: "foldr ( * ) ps 1 = n - 1" |
792 and psp: "list_all (\<lambda>p. prime p \<and> \<not> [a^((n - 1) div p) = 1] (mod n)) ps" |
792 and psp: "list_all (\<lambda>p. prime p \<and> \<not> [a^((n - 1) div p) = 1] (mod n)) ps" |
793 shows "prime n" |
793 shows "prime n" |
794 proof - |
794 proof - |
795 { |
795 { |
796 fix p |
796 fix p |
804 qed |
804 qed |
805 |
805 |
806 text \<open>Variant of Pocklington theorem.\<close> |
806 text \<open>Variant of Pocklington theorem.\<close> |
807 lemma pocklington_primefact: |
807 lemma pocklington_primefact: |
808 assumes n: "n \<ge> 2" and qrn: "q*r = n - 1" and nq2: "n \<le> q\<^sup>2" |
808 assumes n: "n \<ge> 2" and qrn: "q*r = n - 1" and nq2: "n \<le> q\<^sup>2" |
809 and arnb: "(a^r) mod n = b" and psq: "foldr op * ps 1 = q" |
809 and arnb: "(a^r) mod n = b" and psq: "foldr ( * ) ps 1 = q" |
810 and bqn: "(b^q) mod n = 1" |
810 and bqn: "(b^q) mod n = 1" |
811 and psp: "list_all (\<lambda>p. prime p \<and> coprime ((b^(q div p)) mod n - 1) n) ps" |
811 and psp: "list_all (\<lambda>p. prime p \<and> coprime ((b^(q div p)) mod n - 1) n) ps" |
812 shows "prime n" |
812 shows "prime n" |
813 proof - |
813 proof - |
814 from bqn psp qrn |
814 from bqn psp qrn |