src/HOL/Proofs/Extraction/Euclid.thy
changeset 61954 1d43f86f48be
parent 61762 d50b993b4fb9
child 61986 2461779da2b8
equal deleted inserted replaced
61953:7247cb62406c 61954:1d43f86f48be
   121       by (auto intro: dvdI simp: ac_simps)
   121       by (auto intro: dvdI simp: ac_simps)
   122     then show ?thesis by (simp add: mult.commute)
   122     then show ?thesis by (simp add: mult.commute)
   123   qed
   123   qed
   124 qed
   124 qed
   125 
   125 
   126 lemma dvd_prod [iff]: "n dvd (PROD m::nat:#mset (n # ns). m)"
   126 lemma dvd_prod [iff]: "n dvd (\<Prod>m::nat \<in># mset (n # ns). m)"
   127   by (simp add: msetprod_Un msetprod_singleton)
   127   by (simp add: msetprod_Un msetprod_singleton)
   128 
   128 
   129 definition all_prime :: "nat list \<Rightarrow> bool" where
   129 definition all_prime :: "nat list \<Rightarrow> bool" where
   130   "all_prime ps \<longleftrightarrow> (\<forall>p\<in>set ps. prime p)"
   130   "all_prime ps \<longleftrightarrow> (\<forall>p\<in>set ps. prime p)"
   131 
   131 
   138   "all_prime (ps @ qs) \<longleftrightarrow> all_prime ps \<and> all_prime qs"
   138   "all_prime (ps @ qs) \<longleftrightarrow> all_prime ps \<and> all_prime qs"
   139   by (simp add: all_prime_def ball_Un)
   139   by (simp add: all_prime_def ball_Un)
   140 
   140 
   141 lemma split_all_prime:
   141 lemma split_all_prime:
   142   assumes "all_prime ms" and "all_prime ns"
   142   assumes "all_prime ms" and "all_prime ns"
   143   shows "\<exists>qs. all_prime qs \<and> (PROD m::nat:#mset qs. m) =
   143   shows "\<exists>qs. all_prime qs \<and> (\<Prod>m::nat \<in># mset qs. m) =
   144     (PROD m::nat:#mset ms. m) * (PROD m::nat:#mset ns. m)" (is "\<exists>qs. ?P qs \<and> ?Q qs")
   144     (\<Prod>m::nat \<in># mset ms. m) * (\<Prod>m::nat \<in># mset ns. m)" (is "\<exists>qs. ?P qs \<and> ?Q qs")
   145 proof -
   145 proof -
   146   from assms have "all_prime (ms @ ns)"
   146   from assms have "all_prime (ms @ ns)"
   147     by (simp add: all_prime_append)
   147     by (simp add: all_prime_append)
   148   moreover from assms have "(PROD m::nat:#mset (ms @ ns). m) =
   148   moreover from assms have "(\<Prod>m::nat \<in># mset (ms @ ns). m) =
   149     (PROD m::nat:#mset ms. m) * (PROD m::nat:#mset ns. m)"
   149     (\<Prod>m::nat \<in># mset ms. m) * (\<Prod>m::nat \<in># mset ns. m)"
   150     by (simp add: msetprod_Un)
   150     by (simp add: msetprod_Un)
   151   ultimately have "?P (ms @ ns) \<and> ?Q (ms @ ns)" ..
   151   ultimately have "?P (ms @ ns) \<and> ?Q (ms @ ns)" ..
   152   then show ?thesis ..
   152   then show ?thesis ..
   153 qed
   153 qed
   154 
   154 
   155 lemma all_prime_nempty_g_one:
   155 lemma all_prime_nempty_g_one:
   156   assumes "all_prime ps" and "ps \<noteq> []"
   156   assumes "all_prime ps" and "ps \<noteq> []"
   157   shows "Suc 0 < (PROD m::nat:#mset ps. m)"
   157   shows "Suc 0 < (\<Prod>m::nat \<in># mset ps. m)"
   158   using `ps \<noteq> []` `all_prime ps` unfolding One_nat_def [symmetric] by (induct ps rule: list_nonempty_induct)
   158   using `ps \<noteq> []` `all_prime ps` unfolding One_nat_def [symmetric] by (induct ps rule: list_nonempty_induct)
   159     (simp_all add: all_prime_simps msetprod_singleton msetprod_Un prime_gt_1_nat less_1_mult del: One_nat_def)
   159     (simp_all add: all_prime_simps msetprod_singleton msetprod_Un prime_gt_1_nat less_1_mult del: One_nat_def)
   160 
   160 
   161 lemma factor_exists: "Suc 0 < n \<Longrightarrow> (\<exists>ps. all_prime ps \<and> (PROD m::nat:#mset ps. m) = n)"
   161 lemma factor_exists: "Suc 0 < n \<Longrightarrow> (\<exists>ps. all_prime ps \<and> (\<Prod>m::nat \<in># mset ps. m) = n)"
   162 proof (induct n rule: nat_wf_ind)
   162 proof (induct n rule: nat_wf_ind)
   163   case (1 n)
   163   case (1 n)
   164   from `Suc 0 < n`
   164   from `Suc 0 < n`
   165   have "(\<exists>m k. Suc 0 < m \<and> Suc 0 < k \<and> m < n \<and> k < n \<and> n = m * k) \<or> prime n"
   165   have "(\<exists>m k. Suc 0 < m \<and> Suc 0 < k \<and> m < n \<and> k < n \<and> n = m * k) \<or> prime n"
   166     by (rule not_prime_ex_mk)
   166     by (rule not_prime_ex_mk)
   167   then show ?case
   167   then show ?case
   168   proof 
   168   proof 
   169     assume "\<exists>m k. Suc 0 < m \<and> Suc 0 < k \<and> m < n \<and> k < n \<and> n = m * k"
   169     assume "\<exists>m k. Suc 0 < m \<and> Suc 0 < k \<and> m < n \<and> k < n \<and> n = m * k"
   170     then obtain m k where m: "Suc 0 < m" and k: "Suc 0 < k" and mn: "m < n"
   170     then obtain m k where m: "Suc 0 < m" and k: "Suc 0 < k" and mn: "m < n"
   171       and kn: "k < n" and nmk: "n = m * k" by iprover
   171       and kn: "k < n" and nmk: "n = m * k" by iprover
   172     from mn and m have "\<exists>ps. all_prime ps \<and> (PROD m::nat:#mset ps. m) = m" by (rule 1)
   172     from mn and m have "\<exists>ps. all_prime ps \<and> (\<Prod>m::nat \<in># mset ps. m) = m" by (rule 1)
   173     then obtain ps1 where "all_prime ps1" and prod_ps1_m: "(PROD m::nat:#mset ps1. m) = m"
   173     then obtain ps1 where "all_prime ps1" and prod_ps1_m: "(\<Prod>m::nat \<in># mset ps1. m) = m"
   174       by iprover
   174       by iprover
   175     from kn and k have "\<exists>ps. all_prime ps \<and> (PROD m::nat:#mset ps. m) = k" by (rule 1)
   175     from kn and k have "\<exists>ps. all_prime ps \<and> (\<Prod>m::nat \<in># mset ps. m) = k" by (rule 1)
   176     then obtain ps2 where "all_prime ps2" and prod_ps2_k: "(PROD m::nat:#mset ps2. m) = k"
   176     then obtain ps2 where "all_prime ps2" and prod_ps2_k: "(\<Prod>m::nat \<in># mset ps2. m) = k"
   177       by iprover
   177       by iprover
   178     from `all_prime ps1` `all_prime ps2`
   178     from `all_prime ps1` `all_prime ps2`
   179     have "\<exists>ps. all_prime ps \<and> (PROD m::nat:#mset ps. m) =
   179     have "\<exists>ps. all_prime ps \<and> (\<Prod>m::nat \<in># mset ps. m) =
   180       (PROD m::nat:#mset ps1. m) * (PROD m::nat:#mset ps2. m)"
   180       (\<Prod>m::nat \<in># mset ps1. m) * (\<Prod>m::nat \<in># mset ps2. m)"
   181       by (rule split_all_prime)
   181       by (rule split_all_prime)
   182     with prod_ps1_m prod_ps2_k nmk show ?thesis by simp
   182     with prod_ps1_m prod_ps2_k nmk show ?thesis by simp
   183   next
   183   next
   184     assume "prime n" then have "all_prime [n]" by (simp add: all_prime_simps)
   184     assume "prime n" then have "all_prime [n]" by (simp add: all_prime_simps)
   185     moreover have "(PROD m::nat:#mset [n]. m) = n" by (simp add: msetprod_singleton)
   185     moreover have "(\<Prod>m::nat \<in># mset [n]. m) = n" by (simp add: msetprod_singleton)
   186     ultimately have "all_prime [n] \<and> (PROD m::nat:#mset [n]. m) = n" ..
   186     ultimately have "all_prime [n] \<and> (\<Prod>m::nat \<in># mset [n]. m) = n" ..
   187     then show ?thesis ..
   187     then show ?thesis ..
   188   qed
   188   qed
   189 qed
   189 qed
   190 
   190 
   191 lemma prime_factor_exists:
   191 lemma prime_factor_exists:
   192   assumes N: "(1::nat) < n"
   192   assumes N: "(1::nat) < n"
   193   shows "\<exists>p. prime p \<and> p dvd n"
   193   shows "\<exists>p. prime p \<and> p dvd n"
   194 proof -
   194 proof -
   195   from N obtain ps where "all_prime ps"
   195   from N obtain ps where "all_prime ps"
   196     and prod_ps: "n = (PROD m::nat:#mset ps. m)" using factor_exists
   196     and prod_ps: "n = (\<Prod>m::nat \<in># mset ps. m)" using factor_exists
   197     by simp iprover
   197     by simp iprover
   198   with N have "ps \<noteq> []"
   198   with N have "ps \<noteq> []"
   199     by (auto simp add: all_prime_nempty_g_one msetprod_empty)
   199     by (auto simp add: all_prime_nempty_g_one msetprod_empty)
   200   then obtain p qs where ps: "ps = p # qs" by (cases ps) simp
   200   then obtain p qs where ps: "ps = p # qs" by (cases ps) simp
   201   with `all_prime ps` have "prime p" by (simp add: all_prime_simps)
   201   with `all_prime ps` have "prime p" by (simp add: all_prime_simps)