src/HOL/Number_Theory/Pocklington.thy
changeset 67399 eab6ce8368fa
parent 67345 debef21cbed6
child 68157 057d5b4ce47e
equal deleted inserted replaced
67398:5eb932e604a2 67399:eab6ce8368fa
   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