src/HOL/GCD.thy
changeset 73109 783406dd051e
parent 71398 e0237f2eb49d
child 74101 d804e93ae9ff
equal deleted inserted replaced
73108:981a383610df 73109:783406dd051e
  2778 
  2778 
  2779 lemma gcd_proj2_if_dvd_nat [simp]: "y dvd x \<Longrightarrow> gcd x y = y"
  2779 lemma gcd_proj2_if_dvd_nat [simp]: "y dvd x \<Longrightarrow> gcd x y = y"
  2780   for x y :: nat
  2780   for x y :: nat
  2781   by (fact gcd_nat.absorb2)
  2781   by (fact gcd_nat.absorb2)
  2782 
  2782 
       
  2783 lemma Gcd_in:
       
  2784   fixes A :: "nat set"
       
  2785   assumes "\<And>a b. a \<in> A \<Longrightarrow> b \<in> A \<Longrightarrow> gcd a b \<in> A"
       
  2786   assumes "A \<noteq> {}"
       
  2787   shows   "Gcd A \<in> A"
       
  2788 proof (cases "A = {0}")
       
  2789   case False
       
  2790   with assms obtain x where "x \<in> A" "x > 0"
       
  2791     by auto
       
  2792   thus "Gcd A \<in> A"
       
  2793   proof (induction x rule: less_induct)
       
  2794     case (less x)
       
  2795     show ?case
       
  2796     proof (cases "x = Gcd A")
       
  2797       case False
       
  2798       have "\<exists>y\<in>A. \<not>x dvd y"
       
  2799         using False less.prems by (metis Gcd_dvd Gcd_greatest_nat gcd_nat.asym)
       
  2800       then obtain y where y: "y \<in> A" "\<not>x dvd y"
       
  2801         by blast
       
  2802       have "gcd x y \<in> A"
       
  2803         by (rule assms(1)) (use \<open>x \<in> A\<close> y in auto)
       
  2804       moreover have "gcd x y < x"
       
  2805         using \<open>x > 0\<close> y by (metis gcd_dvd1 gcd_dvd2 nat_dvd_not_less nat_neq_iff)
       
  2806       moreover have "gcd x y > 0"
       
  2807         using \<open>x > 0\<close> by auto
       
  2808       ultimately show ?thesis using less.IH by blast
       
  2809     qed (use less in auto)
       
  2810   qed
       
  2811 qed auto
       
  2812 
       
  2813 lemma bezout_gcd_nat':
       
  2814   fixes a b :: nat
       
  2815   shows "\<exists>x y. b * y \<le> a * x \<and> a * x - b * y = gcd a b \<or> a * y \<le> b * x \<and> b * x - a * y = gcd a b"
       
  2816   using bezout_nat[of a b]
       
  2817   by (metis add_diff_cancel_left' diff_zero gcd.commute gcd_0_nat
       
  2818             le_add_same_cancel1 mult.right_neutral zero_le)
       
  2819 
  2783 lemmas Lcm_eq_0_I_nat [simp] = Lcm_eq_0_I [where ?'a = nat]
  2820 lemmas Lcm_eq_0_I_nat [simp] = Lcm_eq_0_I [where ?'a = nat]
  2784 lemmas Lcm_0_iff_nat [simp] = Lcm_0_iff [where ?'a = nat]
  2821 lemmas Lcm_0_iff_nat [simp] = Lcm_0_iff [where ?'a = nat]
  2785 lemmas Lcm_least_int [simp] = Lcm_least [where ?'a = int]
  2822 lemmas Lcm_least_int [simp] = Lcm_least [where ?'a = int]
  2786 
  2823 
       
  2824 
       
  2825 subsection \<open>Characteristic of a semiring\<close>
       
  2826 
       
  2827 definition (in semiring_1) semiring_char :: "'a itself \<Rightarrow> nat" 
       
  2828   where "semiring_char _ = Gcd {n. of_nat n = (0 :: 'a)}"
       
  2829 
       
  2830 context semiring_1
       
  2831 begin
       
  2832 
       
  2833 context
       
  2834   fixes CHAR :: nat
       
  2835   defines "CHAR \<equiv> semiring_char (Pure.type :: 'a itself)"
       
  2836 begin
       
  2837 
       
  2838 lemma of_nat_CHAR [simp]: "of_nat CHAR = (0 :: 'a)"
       
  2839 proof -
       
  2840   have "CHAR \<in> {n. of_nat n = (0::'a)}"
       
  2841     unfolding CHAR_def semiring_char_def
       
  2842   proof (rule Gcd_in, clarify)
       
  2843     fix a b :: nat
       
  2844     assume *: "of_nat a = (0 :: 'a)" "of_nat b = (0 :: 'a)"
       
  2845     show "of_nat (gcd a b) = (0 :: 'a)"
       
  2846     proof (cases "a = 0")
       
  2847       case False
       
  2848       with bezout_nat obtain x y where "a * x = b * y + gcd a b"
       
  2849         by blast
       
  2850       hence "of_nat (a * x) = (of_nat (b * y + gcd a b) :: 'a)"
       
  2851         by (rule arg_cong)
       
  2852       thus "of_nat (gcd a b) = (0 :: 'a)"
       
  2853         using * by simp
       
  2854     qed (use * in auto)
       
  2855   next
       
  2856     have "of_nat 0 = (0 :: 'a)"
       
  2857       by simp
       
  2858     thus "{n. of_nat n = (0 :: 'a)} \<noteq> {}"
       
  2859       by blast
       
  2860   qed
       
  2861   thus ?thesis
       
  2862     by simp
       
  2863 qed
       
  2864 
       
  2865 lemma of_nat_eq_0_iff_char_dvd: "of_nat n = (0 :: 'a) \<longleftrightarrow> CHAR dvd n"
       
  2866 proof
       
  2867   assume "of_nat n = (0 :: 'a)"
       
  2868   thus "CHAR dvd n"
       
  2869     unfolding CHAR_def semiring_char_def by (intro Gcd_dvd) auto
       
  2870 next
       
  2871   assume "CHAR dvd n"
       
  2872   then obtain m where "n = CHAR * m"
       
  2873     by auto
       
  2874   thus "of_nat n = (0 :: 'a)"
       
  2875     by simp
       
  2876 qed
       
  2877 
       
  2878 lemma CHAR_eqI:
       
  2879   assumes "of_nat c = (0 :: 'a)"
       
  2880   assumes "\<And>x. of_nat x = (0 :: 'a) \<Longrightarrow> c dvd x"
       
  2881   shows   "CHAR = c"
       
  2882   using assms by (intro dvd_antisym) (auto simp: of_nat_eq_0_iff_char_dvd)
       
  2883 
       
  2884 lemma CHAR_eq0_iff: "CHAR = 0 \<longleftrightarrow> (\<forall>n>0. of_nat n \<noteq> (0::'a))"
       
  2885   by (auto simp: of_nat_eq_0_iff_char_dvd)
       
  2886 
       
  2887 lemma CHAR_pos_iff: "CHAR > 0 \<longleftrightarrow> (\<exists>n>0. of_nat n = (0::'a))"
       
  2888   using CHAR_eq0_iff neq0_conv by blast
       
  2889 
       
  2890 lemma CHAR_eq_posI:
       
  2891   assumes "c > 0" "of_nat c = (0 :: 'a)" "\<And>x. x > 0 \<Longrightarrow> x < c \<Longrightarrow> of_nat x \<noteq> (0 :: 'a)"
       
  2892   shows   "CHAR = c"
       
  2893 proof (rule antisym)
       
  2894   from assms have "CHAR > 0"
       
  2895     by (auto simp: CHAR_pos_iff)
       
  2896   from assms(3)[OF this] show "CHAR \<ge> c"
       
  2897     by force
       
  2898 next
       
  2899   have "CHAR dvd c"
       
  2900     using assms by (auto simp: of_nat_eq_0_iff_char_dvd)
       
  2901   thus "CHAR \<le> c"
       
  2902     using \<open>c > 0\<close> by (intro dvd_imp_le) auto
       
  2903 qed
       
  2904 
  2787 end
  2905 end
       
  2906 end
       
  2907 
       
  2908 lemma (in semiring_char_0) CHAR_eq_0 [simp]: "semiring_char (Pure.type :: 'a itself) = 0"
       
  2909   by (simp add: CHAR_eq0_iff)
       
  2910 
       
  2911 
       
  2912 (* nicer notation *)
       
  2913 
       
  2914 syntax "_type_char" :: "type => nat" ("(1CHAR/(1'(_')))")
       
  2915 
       
  2916 translations "CHAR('t)" => "CONST semiring_char (CONST Pure.type :: 't itself)"
       
  2917 
       
  2918 print_translation \<open>
       
  2919   let
       
  2920     fun char_type_tr' ctxt [Const (\<^const_syntax>\<open>Pure.type\<close>, Type (_, [T]))] =
       
  2921       Syntax.const \<^syntax_const>\<open>_type_char\<close> $ Syntax_Phases.term_of_typ ctxt T
       
  2922   in [(\<^const_syntax>\<open>semiring_char\<close>, char_type_tr')] end
       
  2923 \<close>
       
  2924 
       
  2925 end