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)" |