src/HOL/Library/Abstract_Rat.thy
changeset 31952 40501bb2d57c
parent 31706 1db0c8f235fb
child 31967 81dbc693143b
equal deleted inserted replaced
31951:9787769764bb 31952:40501bb2d57c
    28 where
    28 where
    29   "normNum = (\<lambda>(a,b). (if a=0 \<or> b = 0 then (0,0) else 
    29   "normNum = (\<lambda>(a,b). (if a=0 \<or> b = 0 then (0,0) else 
    30   (let g = gcd a b 
    30   (let g = gcd a b 
    31    in if b > 0 then (a div g, b div g) else (- (a div g), - (b div g)))))"
    31    in if b > 0 then (a div g, b div g) else (- (a div g), - (b div g)))))"
    32 
    32 
    33 declare int_gcd_dvd1[presburger]
    33 declare gcd_dvd1_int[presburger]
    34 declare int_gcd_dvd2[presburger]
    34 declare gcd_dvd2_int[presburger]
    35 lemma normNum_isnormNum [simp]: "isnormNum (normNum x)"
    35 lemma normNum_isnormNum [simp]: "isnormNum (normNum x)"
    36 proof -
    36 proof -
    37   have " \<exists> a b. x = (a,b)" by auto
    37   have " \<exists> a b. x = (a,b)" by auto
    38   then obtain a b where x[simp]: "x = (a,b)" by blast
    38   then obtain a b where x[simp]: "x = (a,b)" by blast
    39   {assume "a=0 \<or> b = 0" hence ?thesis by (simp add: normNum_def isnormNum_def)}  
    39   {assume "a=0 \<or> b = 0" hence ?thesis by (simp add: normNum_def isnormNum_def)}  
    41   {assume anz: "a \<noteq> 0" and bnz: "b \<noteq> 0" 
    41   {assume anz: "a \<noteq> 0" and bnz: "b \<noteq> 0" 
    42     let ?g = "gcd a b"
    42     let ?g = "gcd a b"
    43     let ?a' = "a div ?g"
    43     let ?a' = "a div ?g"
    44     let ?b' = "b div ?g"
    44     let ?b' = "b div ?g"
    45     let ?g' = "gcd ?a' ?b'"
    45     let ?g' = "gcd ?a' ?b'"
    46     from anz bnz have "?g \<noteq> 0" by simp  with int_gcd_ge_0[of a b] 
    46     from anz bnz have "?g \<noteq> 0" by simp  with gcd_ge_0_int[of a b] 
    47     have gpos: "?g > 0"  by arith
    47     have gpos: "?g > 0"  by arith
    48     have gdvd: "?g dvd a" "?g dvd b" by arith+ 
    48     have gdvd: "?g dvd a" "?g dvd b" by arith+ 
    49     from zdvd_mult_div_cancel[OF gdvd(1)] zdvd_mult_div_cancel[OF gdvd(2)]
    49     from zdvd_mult_div_cancel[OF gdvd(1)] zdvd_mult_div_cancel[OF gdvd(2)]
    50     anz bnz
    50     anz bnz
    51     have nz':"?a' \<noteq> 0" "?b' \<noteq> 0"
    51     have nz':"?a' \<noteq> 0" "?b' \<noteq> 0"
    52       by - (rule notI, simp)+
    52       by - (rule notI, simp)+
    53     from anz bnz have stupid: "a \<noteq> 0 \<or> b \<noteq> 0" by arith 
    53     from anz bnz have stupid: "a \<noteq> 0 \<or> b \<noteq> 0" by arith 
    54     from int_div_gcd_coprime[OF stupid] have gp1: "?g' = 1" .
    54     from div_gcd_coprime_int[OF stupid] have gp1: "?g' = 1" .
    55     from bnz have "b < 0 \<or> b > 0" by arith
    55     from bnz have "b < 0 \<or> b > 0" by arith
    56     moreover
    56     moreover
    57     {assume b: "b > 0"
    57     {assume b: "b > 0"
    58       from b have "?b' \<ge> 0" 
    58       from b have "?b' \<ge> 0" 
    59 	by (presburger add: pos_imp_zdiv_nonneg_iff[OF gpos])  
    59 	by (presburger add: pos_imp_zdiv_nonneg_iff[OF gpos])  
   135   ultimately show ?thesis by blast
   135   ultimately show ?thesis by blast
   136 qed
   136 qed
   137 
   137 
   138 lemma Ninv_normN[simp]: "isnormNum x \<Longrightarrow> isnormNum (Ninv x)"
   138 lemma Ninv_normN[simp]: "isnormNum x \<Longrightarrow> isnormNum (Ninv x)"
   139   by (simp add: Ninv_def isnormNum_def split_def)
   139   by (simp add: Ninv_def isnormNum_def split_def)
   140     (cases "fst x = 0", auto simp add: int_gcd_commute)
   140     (cases "fst x = 0", auto simp add: gcd_commute_int)
   141 
   141 
   142 lemma isnormNum_int[simp]: 
   142 lemma isnormNum_int[simp]: 
   143   "isnormNum 0\<^sub>N" "isnormNum (1::int)\<^sub>N" "i \<noteq> 0 \<Longrightarrow> isnormNum i\<^sub>N"
   143   "isnormNum 0\<^sub>N" "isnormNum (1::int)\<^sub>N" "i \<noteq> 0 \<Longrightarrow> isnormNum i\<^sub>N"
   144   by (simp_all add: isnormNum_def)
   144   by (simp_all add: isnormNum_def)
   145 
   145 
   201   { assume az: "a \<noteq> 0" and bz: "b \<noteq> 0" and a'z: "a'\<noteq>0" and b'z: "b'\<noteq>0"
   201   { assume az: "a \<noteq> 0" and bz: "b \<noteq> 0" and a'z: "a'\<noteq>0" and b'z: "b'\<noteq>0"
   202     from az bz a'z b'z na nb have pos: "b > 0" "b' > 0" by (simp_all add: isnormNum_def)
   202     from az bz a'z b'z na nb have pos: "b > 0" "b' > 0" by (simp_all add: isnormNum_def)
   203     from prems have eq:"a * b' = a'*b" 
   203     from prems have eq:"a * b' = a'*b" 
   204       by (simp add: INum_def  eq_divide_eq divide_eq_eq of_int_mult[symmetric] del: of_int_mult)
   204       by (simp add: INum_def  eq_divide_eq divide_eq_eq of_int_mult[symmetric] del: of_int_mult)
   205     from prems have gcd1: "gcd a b = 1" "gcd b a = 1" "gcd a' b' = 1" "gcd b' a' = 1"       
   205     from prems have gcd1: "gcd a b = 1" "gcd b a = 1" "gcd a' b' = 1" "gcd b' a' = 1"       
   206       by (simp_all add: isnormNum_def add: int_gcd_commute)
   206       by (simp_all add: isnormNum_def add: gcd_commute_int)
   207     from eq have raw_dvd: "a dvd a'*b" "b dvd b'*a" "a' dvd a*b'" "b' dvd b*a'"
   207     from eq have raw_dvd: "a dvd a'*b" "b dvd b'*a" "a' dvd a*b'" "b' dvd b*a'"
   208       apply - 
   208       apply - 
   209       apply algebra
   209       apply algebra
   210       apply algebra
   210       apply algebra
   211       apply simp
   211       apply simp
   212       apply algebra
   212       apply algebra
   213       done
   213       done
   214     from zdvd_dvd_eq[OF bz int_coprime_dvd_mult[OF gcd1(2) raw_dvd(2)]
   214     from zdvd_dvd_eq[OF bz coprime_dvd_mult_int[OF gcd1(2) raw_dvd(2)]
   215       int_coprime_dvd_mult[OF gcd1(4) raw_dvd(4)]]
   215       coprime_dvd_mult_int[OF gcd1(4) raw_dvd(4)]]
   216       have eq1: "b = b'" using pos by arith  
   216       have eq1: "b = b'" using pos by arith  
   217       with eq have "a = a'" using pos by simp
   217       with eq have "a = a'" using pos by simp
   218       with eq1 have ?rhs by simp}
   218       with eq1 have ?rhs by simp}
   219   ultimately show ?rhs by blast
   219   ultimately show ?rhs by blast
   220 next
   220 next
   295 	by (simp add: th Nadd_def normNum_def INum_def split_def)}
   295 	by (simp add: th Nadd_def normNum_def INum_def split_def)}
   296     moreover {assume z: "a * b' + b * a' \<noteq> 0"
   296     moreover {assume z: "a * b' + b * a' \<noteq> 0"
   297       let ?g = "gcd (a * b' + b * a') (b*b')"
   297       let ?g = "gcd (a * b' + b * a') (b*b')"
   298       have gz: "?g \<noteq> 0" using z by simp
   298       have gz: "?g \<noteq> 0" using z by simp
   299       have ?thesis using aa' bb' z gz
   299       have ?thesis using aa' bb' z gz
   300 	of_int_div[where ?'a = 'a, OF gz int_gcd_dvd1[where x="a * b' + b * a'" and y="b*b'"]]	of_int_div[where ?'a = 'a,
   300 	of_int_div[where ?'a = 'a, OF gz gcd_dvd1_int[where x="a * b' + b * a'" and y="b*b'"]]	of_int_div[where ?'a = 'a,
   301 	OF gz int_gcd_dvd2[where x="a * b' + b * a'" and y="b*b'"]]
   301 	OF gz gcd_dvd2_int[where x="a * b' + b * a'" and y="b*b'"]]
   302 	by (simp add: x y Nadd_def INum_def normNum_def Let_def add_divide_distrib)}
   302 	by (simp add: x y Nadd_def INum_def normNum_def Let_def add_divide_distrib)}
   303     ultimately have ?thesis using aa' bb' 
   303     ultimately have ?thesis using aa' bb' 
   304       by (simp add: Nadd_def INum_def normNum_def x y Let_def) }
   304       by (simp add: Nadd_def INum_def normNum_def x y Let_def) }
   305   ultimately show ?thesis by blast
   305   ultimately show ?thesis by blast
   306 qed
   306 qed
   317       done }
   317       done }
   318   moreover
   318   moreover
   319   {assume z: "a \<noteq> 0" "a' \<noteq> 0" "b \<noteq> 0" "b' \<noteq> 0"
   319   {assume z: "a \<noteq> 0" "a' \<noteq> 0" "b \<noteq> 0" "b' \<noteq> 0"
   320     let ?g="gcd (a*a') (b*b')"
   320     let ?g="gcd (a*a') (b*b')"
   321     have gz: "?g \<noteq> 0" using z by simp
   321     have gz: "?g \<noteq> 0" using z by simp
   322     from z of_int_div[where ?'a = 'a, OF gz int_gcd_dvd1[where x="a*a'" and y="b*b'"]] 
   322     from z of_int_div[where ?'a = 'a, OF gz gcd_dvd1_int[where x="a*a'" and y="b*b'"]] 
   323       of_int_div[where ?'a = 'a , OF gz int_gcd_dvd2[where x="a*a'" and y="b*b'"]] 
   323       of_int_div[where ?'a = 'a , OF gz gcd_dvd2_int[where x="a*a'" and y="b*b'"]] 
   324     have ?thesis by (simp add: Nmul_def x y Let_def INum_def)}
   324     have ?thesis by (simp add: Nmul_def x y Let_def INum_def)}
   325   ultimately show ?thesis by blast
   325   ultimately show ?thesis by blast
   326 qed
   326 qed
   327 
   327 
   328 lemma Nneg[simp]: "INum (~\<^sub>N x) = - (INum x ::'a:: field)"
   328 lemma Nneg[simp]: "INum (~\<^sub>N x) = - (INum x ::'a:: field)"
   476   have "INum (x +\<^sub>N y +\<^sub>N z) = (INum (x +\<^sub>N (y +\<^sub>N z)) :: 'a)" by simp
   476   have "INum (x +\<^sub>N y +\<^sub>N z) = (INum (x +\<^sub>N (y +\<^sub>N z)) :: 'a)" by simp
   477   with isnormNum_unique[OF n] show ?thesis by simp
   477   with isnormNum_unique[OF n] show ?thesis by simp
   478 qed
   478 qed
   479 
   479 
   480 lemma Nmul_commute: "isnormNum x \<Longrightarrow> isnormNum y \<Longrightarrow> x *\<^sub>N y = y *\<^sub>N x"
   480 lemma Nmul_commute: "isnormNum x \<Longrightarrow> isnormNum y \<Longrightarrow> x *\<^sub>N y = y *\<^sub>N x"
   481   by (simp add: Nmul_def split_def Let_def int_gcd_commute mult_commute)
   481   by (simp add: Nmul_def split_def Let_def gcd_commute_int mult_commute)
   482 
   482 
   483 lemma Nmul_assoc:
   483 lemma Nmul_assoc:
   484   assumes "SORT_CONSTRAINT('a::{ring_char_0,division_by_zero,field})"
   484   assumes "SORT_CONSTRAINT('a::{ring_char_0,division_by_zero,field})"
   485   assumes nx: "isnormNum x" and ny:"isnormNum y" and nz:"isnormNum z"
   485   assumes nx: "isnormNum x" and ny:"isnormNum y" and nz:"isnormNum z"
   486   shows "x *\<^sub>N y *\<^sub>N z = x *\<^sub>N (y *\<^sub>N z)"
   486   shows "x *\<^sub>N y *\<^sub>N z = x *\<^sub>N (y *\<^sub>N z)"