author wenzelm Sat, 20 Jun 2015 20:55:31 +0200 changeset 60538 b9add7665d7a parent 60537 5398aa5a4df9 child 60539 f909f1a5cb22
tuned proofs;
```--- a/src/HOL/Decision_Procs/Rat_Pair.thy	Sat Jun 20 20:17:29 2015 +0200
+++ b/src/HOL/Decision_Procs/Rat_Pair.thy	Sat Jun 20 20:55:31 2015 +0200
@@ -16,12 +16,14 @@
abbreviation Numi_syn :: "int \<Rightarrow> Num"  ("'((_)')\<^sub>N")
where "(i)\<^sub>N \<equiv> (i, 1)"

-definition isnormNum :: "Num \<Rightarrow> bool" where
-  "isnormNum = (\<lambda>(a,b). (if a = 0 then b = 0 else b > 0 \<and> gcd a b = 1))"
+definition isnormNum :: "Num \<Rightarrow> bool"
+  where "isnormNum = (\<lambda>(a, b). if a = 0 then b = 0 else b > 0 \<and> gcd a b = 1)"

-definition normNum :: "Num \<Rightarrow> Num" where
+definition normNum :: "Num \<Rightarrow> Num"
+where
"normNum = (\<lambda>(a,b).
-    (if a=0 \<or> b = 0 then (0,0) else
+    (if a = 0 \<or> b = 0 then (0, 0)
+     else
(let g = gcd a b
in if b > 0 then (a div g, b div g) else (- (a div g), - (b div g)))))"

@@ -30,61 +32,72 @@
lemma normNum_isnormNum [simp]: "isnormNum (normNum x)"
proof -
obtain a b where x: "x = (a, b)" by (cases x)
-  { assume "a=0 \<or> b = 0" hence ?thesis by (simp add: x normNum_def isnormNum_def) }
-  moreover
-  { assume anz: "a \<noteq> 0" and bnz: "b \<noteq> 0"
+  consider "a = 0 \<or> b = 0" | "a \<noteq> 0" "b \<noteq> 0" by blast
+  then show ?thesis
+  proof cases
+    case 1
+    then show ?thesis
+      by (simp add: x normNum_def isnormNum_def)
+  next
+    case 2
let ?g = "gcd a b"
let ?a' = "a div ?g"
let ?b' = "b div ?g"
let ?g' = "gcd ?a' ?b'"
-    from anz bnz have "?g \<noteq> 0" by simp  with gcd_ge_0_int[of a b]
+    from 2 have "?g \<noteq> 0" by simp  with gcd_ge_0_int[of a b]
have gpos: "?g > 0" by arith
have gdvd: "?g dvd a" "?g dvd b" by arith+
-    from dvd_mult_div_cancel[OF gdvd(1)] dvd_mult_div_cancel[OF gdvd(2)] anz bnz
+    from dvd_mult_div_cancel[OF gdvd(1)] dvd_mult_div_cancel[OF gdvd(2)] 2
have nz': "?a' \<noteq> 0" "?b' \<noteq> 0" by - (rule notI, simp)+
-    from anz bnz have stupid: "a \<noteq> 0 \<or> b \<noteq> 0" by arith
+    from 2 have stupid: "a \<noteq> 0 \<or> b \<noteq> 0" by arith
from div_gcd_coprime_int[OF stupid] have gp1: "?g' = 1" .
-    from bnz have "b < 0 \<or> b > 0" by arith
-    moreover
-    { assume b: "b > 0"
-      from b have "?b' \<ge> 0"
+    from 2 consider "b < 0" | "b > 0" by arith
+    then show ?thesis
+    proof cases
+      case 1
+      have False if b': "?b' \<ge> 0"
+      proof -
+        from gpos have th: "?g \<ge> 0" by arith
+        from mult_nonneg_nonneg[OF th b'] dvd_mult_div_cancel[OF gdvd(2)]
+        show ?thesis using 1 by arith
+      qed
+      then have b': "?b' < 0" by (presburger add: linorder_not_le[symmetric])
+      from \<open>a \<noteq> 0\<close> nz' 1 b' gp1 show ?thesis
+        by (simp add: x isnormNum_def normNum_def Let_def split_def)
+    next
+      case 2
+      then have "?b' \<ge> 0"
with nz' have b': "?b' > 0" by arith
-      from b b' anz bnz nz' gp1 have ?thesis
-        by (simp add: x isnormNum_def normNum_def Let_def split_def) }
-    moreover {
-      assume b: "b < 0"
-      { assume b': "?b' \<ge> 0"
-        from gpos have th: "?g \<ge> 0" by arith
-        from mult_nonneg_nonneg[OF th b'] dvd_mult_div_cancel[OF gdvd(2)]
-        have False using b by arith }
-      hence b': "?b' < 0" by (presburger add: linorder_not_le[symmetric])
-      from anz bnz nz' b b' gp1 have ?thesis
-        by (simp add: x isnormNum_def normNum_def Let_def split_def) }
-    ultimately have ?thesis by blast
-  }
-  ultimately show ?thesis by blast
+      from 2 b' \<open>a \<noteq> 0\<close> nz' gp1 show ?thesis
+        by (simp add: x isnormNum_def normNum_def Let_def split_def)
+    qed
+  qed
qed

text \<open>Arithmetic over Num\<close>

-definition Nadd :: "Num \<Rightarrow> Num \<Rightarrow> Num"  (infixl "+\<^sub>N" 60) where
-  "Nadd = (\<lambda>(a,b) (a',b'). if a = 0 \<or> b = 0 then normNum(a',b')
-    else if a'=0 \<or> b' = 0 then normNum(a,b)
-    else normNum(a*b' + b*a', b*b'))"
+definition Nadd :: "Num \<Rightarrow> Num \<Rightarrow> Num"  (infixl "+\<^sub>N" 60)
+where
+  "Nadd = (\<lambda>(a, b) (a', b').
+    if a = 0 \<or> b = 0 then normNum (a', b')
+    else if a' = 0 \<or> b' = 0 then normNum (a, b)
+    else normNum (a * b' + b * a', b * b'))"

-definition Nmul :: "Num \<Rightarrow> Num \<Rightarrow> Num"  (infixl "*\<^sub>N" 60) where
-  "Nmul = (\<lambda>(a,b) (a',b'). let g = gcd (a*a') (b*b')
-    in (a*a' div g, b*b' div g))"
+definition Nmul :: "Num \<Rightarrow> Num \<Rightarrow> Num"  (infixl "*\<^sub>N" 60)
+where
+  "Nmul = (\<lambda>(a, b) (a', b').
+    let g = gcd (a * a') (b * b')
+    in (a * a' div g, b * b' div g))"

definition Nneg :: "Num \<Rightarrow> Num" ("~\<^sub>N")
-  where "Nneg \<equiv> (\<lambda>(a,b). (-a,b))"
+  where "Nneg = (\<lambda>(a, b). (- a, b))"

definition Nsub :: "Num \<Rightarrow> Num \<Rightarrow> Num"  (infixl "-\<^sub>N" 60)
where "Nsub = (\<lambda>a b. a +\<^sub>N ~\<^sub>N b)"

definition Ninv :: "Num \<Rightarrow> Num"
-  where "Ninv = (\<lambda>(a,b). if a < 0 then (-b, \<bar>a\<bar>) else (b,a))"
+  where "Ninv = (\<lambda>(a, b). if a < 0 then (- b, \<bar>a\<bar>) else (b, a))"

definition Ndiv :: "Num \<Rightarrow> Num \<Rightarrow> Num"  (infixl "\<div>\<^sub>N" 60)
where "Ndiv = (\<lambda>a b. a *\<^sub>N Ninv b)"
@@ -95,53 +108,59 @@
lemma Nadd_normN[simp]: "isnormNum (x +\<^sub>N y)"

-lemma Nsub_normN[simp]: "\<lbrakk> isnormNum y\<rbrakk> \<Longrightarrow> isnormNum (x -\<^sub>N y)"
+lemma Nsub_normN[simp]: "isnormNum y \<Longrightarrow> isnormNum (x -\<^sub>N y)"

lemma Nmul_normN[simp]:
-  assumes xn: "isnormNum x" and yn: "isnormNum y"
+  assumes xn: "isnormNum x"
+    and yn: "isnormNum y"
shows "isnormNum (x *\<^sub>N y)"
proof -
obtain a b where x: "x = (a, b)" by (cases x)
obtain a' b' where y: "y = (a', b')" by (cases y)
-  { assume "a = 0"
-    hence ?thesis using xn x y
-      by (simp add: isnormNum_def Let_def Nmul_def split_def) }
-  moreover
-  { assume "a' = 0"
-    hence ?thesis using yn x y
-      by (simp add: isnormNum_def Let_def Nmul_def split_def) }
-  moreover
-  { assume a: "a \<noteq>0" and a': "a'\<noteq>0"
-    hence bp: "b > 0" "b' > 0" using xn yn x y by (simp_all add: isnormNum_def)
+  consider "a = 0" | "a' = 0" | "a \<noteq> 0" "a' \<noteq> 0" by blast
+  then show ?thesis
+  proof cases
+    case 1
+    then show ?thesis
+      using xn x y by (simp add: isnormNum_def Let_def Nmul_def split_def)
+  next
+    case 2
+    then show ?thesis
+      using yn x y by (simp add: isnormNum_def Let_def Nmul_def split_def)
+  next
+    case 3
+    then have bp: "b > 0" "b' > 0"
+      using xn yn x y by (simp_all add: isnormNum_def)
from bp have "x *\<^sub>N y = normNum (a * a', b * b')"
-      using x y a a' bp by (simp add: Nmul_def Let_def split_def normNum_def)
-    hence ?thesis by simp }
-  ultimately show ?thesis by blast
+      using x y 3 bp by (simp add: Nmul_def Let_def split_def normNum_def)
+    then show ?thesis by simp
+  qed
qed

lemma Ninv_normN[simp]: "isnormNum x \<Longrightarrow> isnormNum (Ninv x)"
-  by (simp add: Ninv_def isnormNum_def split_def)
-    (cases "fst x = 0", auto simp add: gcd_commute_int)
+  apply (simp add: Ninv_def isnormNum_def split_def)
+  apply (cases "fst x = 0")
+  apply (auto simp add: gcd_commute_int)
+  done

-lemma isnormNum_int[simp]:
-  "isnormNum 0\<^sub>N" "isnormNum ((1::int)\<^sub>N)" "i \<noteq> 0 \<Longrightarrow> isnormNum (i)\<^sub>N"
+lemma isnormNum_int[simp]: "isnormNum 0\<^sub>N" "isnormNum ((1::int)\<^sub>N)" "i \<noteq> 0 \<Longrightarrow> isnormNum (i)\<^sub>N"

text \<open>Relations over Num\<close>

definition Nlt0:: "Num \<Rightarrow> bool"  ("0>\<^sub>N")
-  where "Nlt0 = (\<lambda>(a,b). a < 0)"
+  where "Nlt0 = (\<lambda>(a, b). a < 0)"

definition Nle0:: "Num \<Rightarrow> bool"  ("0\<ge>\<^sub>N")
-  where "Nle0 = (\<lambda>(a,b). a \<le> 0)"
+  where "Nle0 = (\<lambda>(a, b). a \<le> 0)"

definition Ngt0:: "Num \<Rightarrow> bool"  ("0<\<^sub>N")
-  where "Ngt0 = (\<lambda>(a,b). a > 0)"
+  where "Ngt0 = (\<lambda>(a, b). a > 0)"

definition Nge0:: "Num \<Rightarrow> bool"  ("0\<le>\<^sub>N")
-  where "Nge0 = (\<lambda>(a,b). a \<ge> 0)"
+  where "Nge0 = (\<lambda>(a, b). a \<ge> 0)"

definition Nlt :: "Num \<Rightarrow> Num \<Rightarrow> bool"  (infix "<\<^sub>N" 55)
where "Nlt = (\<lambda>a b. 0>\<^sub>N (a -\<^sub>N b))"
@@ -149,27 +168,34 @@
definition Nle :: "Num \<Rightarrow> Num \<Rightarrow> bool"  (infix "\<le>\<^sub>N" 55)
where "Nle = (\<lambda>a b. 0\<ge>\<^sub>N (a -\<^sub>N b))"

-definition "INum = (\<lambda>(a,b). of_int a / of_int b)"
+definition "INum = (\<lambda>(a, b). of_int a / of_int b)"

-lemma INum_int [simp]: "INum (i)\<^sub>N = ((of_int i) ::'a::field)" "INum 0\<^sub>N = (0::'a::field)"
+lemma INum_int [simp]: "INum (i)\<^sub>N = (of_int i ::'a::field)" "INum 0\<^sub>N = (0::'a::field)"

lemma isnormNum_unique[simp]:
-  assumes na: "isnormNum x" and nb: "isnormNum y"
-  shows "((INum x ::'a::{field_char_0, field}) = INum y) = (x = y)" (is "?lhs = ?rhs")
+  assumes na: "isnormNum x"
+    and nb: "isnormNum y"
+  shows "(INum x ::'a::{field_char_0,field}) = INum y \<longleftrightarrow> x = y"
+  (is "?lhs = ?rhs")
proof
obtain a b where x: "x = (a, b)" by (cases x)
obtain a' b' where y: "y = (a', b')" by (cases y)
-  assume H: ?lhs
-  { assume "a = 0 \<or> b = 0 \<or> a' = 0 \<or> b' = 0"
-    hence ?rhs using na nb H
-      by (simp add: x y INum_def split_def isnormNum_def split: split_if_asm) }
-  moreover
-  { assume az: "a \<noteq> 0" and bz: "b \<noteq> 0" and a'z: "a'\<noteq>0" and b'z: "b'\<noteq>0"
-    from az bz a'z b'z na nb have pos: "b > 0" "b' > 0" by (simp_all add: x y isnormNum_def)
-    from H bz b'z have eq: "a * b' = a'*b"
+  consider "a = 0 \<or> b = 0 \<or> a' = 0 \<or> b' = 0" | "a \<noteq> 0" "b \<noteq> 0" "a' \<noteq> 0" "b' \<noteq> 0"
+    by blast
+  then show ?rhs if H: ?lhs
+  proof cases
+    case 1
+    then show ?thesis
+      using na nb H by (simp add: x y INum_def split_def isnormNum_def split: split_if_asm)
+  next
+    case 2
+    with na nb have pos: "b > 0" "b' > 0"
+      by (simp_all add: x y isnormNum_def)
+    from H \<open>b \<noteq> 0\<close> \<open>b' \<noteq> 0\<close> have eq: "a * b' = a'*b"
by (simp add: x y INum_def eq_divide_eq divide_eq_eq of_int_mult[symmetric] del: of_int_mult)
-    from az a'z na nb have gcd1: "gcd a b = 1" "gcd b a = 1" "gcd a' b' = 1" "gcd b' a' = 1"
+    from \<open>a \<noteq> 0\<close> \<open>a' \<noteq> 0\<close> na nb
+    have gcd1: "gcd a b = 1" "gcd b a = 1" "gcd a' b' = 1" "gcd b' a' = 1"
from eq have raw_dvd: "a dvd a' * b" "b dvd b' * a" "a' dvd a * b'" "b' dvd b * a'"
apply -
@@ -182,23 +208,22 @@
coprime_dvd_mult_int[OF gcd1(4) raw_dvd(4)]]
have eq1: "b = b'" using pos by arith
with eq have "a = a'" using pos by simp
-      with eq1 have ?rhs by (simp add: x y) }
-  ultimately show ?rhs by blast
-next
-  assume ?rhs thus ?lhs by simp
+      with eq1 show ?thesis by (simp add: x y)
+  qed
+  show ?lhs if ?rhs
+    using that by simp
qed

-
-lemma isnormNum0[simp]:
-    "isnormNum x \<Longrightarrow> (INum x = (0::'a::{field_char_0, field})) = (x = 0\<^sub>N)"
+lemma isnormNum0[simp]: "isnormNum x \<Longrightarrow> INum x = (0::'a::{field_char_0,field}) \<longleftrightarrow> x = 0\<^sub>N"
unfolding INum_int(2)[symmetric]
by (rule isnormNum_unique) simp_all

-lemma of_int_div_aux: "d ~= 0 ==> ((of_int x)::'a::field_char_0) / (of_int d) =
-    of_int (x div d) + (of_int (x mod d)) / ((of_int d)::'a)"
+lemma of_int_div_aux:
+  assumes "d \<noteq> 0"
+  shows "(of_int x ::'a::field_char_0) / of_int d =
+    of_int (x div d) + (of_int (x mod d)) / of_int d"
proof -
-  assume "d ~= 0"
-  let ?t = "of_int (x div d) * ((of_int d)::'a) + of_int(x mod d)"
+  let ?t = "of_int (x div d) * (of_int d ::'a) + of_int (x mod d)"
let ?f = "\<lambda>x. x / of_int d"
have "x = (x div d) * d + x mod d"
by auto
@@ -206,30 +231,36 @@
by (simp only: of_int_mult[symmetric] of_int_add [symmetric])
then have "of_int x / of_int d = ?t / of_int d"
using cong[OF refl[of ?f] eq] by simp
-  then show ?thesis by (simp add: add_divide_distrib algebra_simps \<open>d ~= 0\<close>)
+  then show ?thesis
qed

-lemma of_int_div: "(d::int) ~= 0 ==> d dvd n ==>
-    (of_int(n div d)::'a::field_char_0) = of_int n / of_int d"
-  using of_int_div_aux [of d n, where ?'a = 'a] by simp
+lemma of_int_div:
+  fixes d :: int
+  assumes "d \<noteq> 0" "d dvd n"
+  shows "(of_int (n div d) ::'a::field_char_0) = of_int n / of_int d"
+  using assms of_int_div_aux [of d n, where ?'a = 'a] by simp

-lemma normNum[simp]: "INum (normNum x) = (INum x :: 'a::{field_char_0, field})"
+lemma normNum[simp]: "INum (normNum x) = (INum x :: 'a::{field_char_0,field})"
proof -
obtain a b where x: "x = (a, b)" by (cases x)
-  { assume "a = 0 \<or> b = 0"
-    hence ?thesis by (simp add: x INum_def normNum_def split_def Let_def) }
-  moreover
-  { assume a: "a \<noteq> 0" and b: "b \<noteq> 0"
+  consider "a = 0 \<or> b = 0" | "a \<noteq> 0" "b \<noteq> 0" by blast
+  then show ?thesis
+  proof cases
+    case 1
+    then show ?thesis
+      by (simp add: x INum_def normNum_def split_def Let_def)
+  next
+    case 2
let ?g = "gcd a b"
-    from a b have g: "?g \<noteq> 0"by simp
-    from of_int_div[OF g, where ?'a = 'a]
-    have ?thesis by (auto simp add: x INum_def normNum_def split_def Let_def) }
-  ultimately show ?thesis by blast
+    from 2 have g: "?g \<noteq> 0"by simp
+    from of_int_div[OF g, where ?'a = 'a] show ?thesis
+      by (auto simp add: x INum_def normNum_def split_def Let_def)
+  qed
qed

-lemma INum_normNum_iff:
-  "(INum x ::'a::{field_char_0, field}) = INum y \<longleftrightarrow> normNum x = normNum y"
-  (is "?lhs = ?rhs")
+lemma INum_normNum_iff: "(INum x ::'a::{field_char_0,field}) = INum y \<longleftrightarrow> normNum x = normNum y"
+  (is "?lhs \<longleftrightarrow> _")
proof -
have "normNum x = normNum y \<longleftrightarrow> (INum (normNum x) :: 'a) = INum (normNum y)"
by (simp del: normNum)
@@ -237,178 +268,231 @@
finally show ?thesis by simp
qed

-lemma Nadd[simp]: "INum (x +\<^sub>N y) = INum x + (INum y :: 'a :: {field_char_0, field})"
-proof -
-  let ?z = "0:: 'a"
-  obtain a b where x: "x = (a, b)" by (cases x)
-  obtain a' b' where y: "y = (a', b')" by (cases y)
-  { assume "a=0 \<or> a'= 0 \<or> b =0 \<or> b' = 0"
-    hence ?thesis
-      apply (cases "b= 0", simp_all add: INum_def)
-       apply (cases "a'= 0", simp_all)
-       apply (cases "b'= 0", simp_all)
-       done }
-  moreover
-  { assume aa': "a \<noteq> 0" "a'\<noteq> 0" and bb': "b \<noteq> 0" "b' \<noteq> 0"
-    { assume z: "a * b' + b * a' = 0"
-      hence "of_int (a*b' + b*a') / (of_int b* of_int b') = ?z" by simp
-      hence "of_int b' * of_int a / (of_int b * of_int b') +
-          of_int b * of_int a' / (of_int b * of_int b') = ?z"
-      hence th: "of_int a / of_int b + of_int a' / of_int b' = ?z" using bb' aa'
-        by simp
-      from z aa' bb' have ?thesis
-        by (simp add: x y th Nadd_def normNum_def INum_def split_def) }
-    moreover {
-      assume z: "a * b' + b * a' \<noteq> 0"
-      let ?g = "gcd (a * b' + b * a') (b * b')"
-      have gz: "?g \<noteq> 0" using z by simp
-      have ?thesis using aa' bb' z gz
-        of_int_div [where ?'a = 'a, OF gz gcd_dvd1 [of "a * b' + b * a'" "b * b'"]]
-        of_int_div [where ?'a = 'a, OF gz gcd_dvd2 [of "a * b' + b * a'" "b * b'"]]
-    }
-    ultimately have ?thesis using aa' bb'
-  ultimately show ?thesis by blast
-qed
-
-lemma Nmul[simp]: "INum (x *\<^sub>N y) = INum x * (INum y:: 'a :: {field_char_0, field})"
+lemma Nadd[simp]: "INum (x +\<^sub>N y) = INum x + (INum y :: 'a :: {field_char_0,field})"
proof -
let ?z = "0::'a"
obtain a b where x: "x = (a, b)" by (cases x)
obtain a' b' where y: "y = (a', b')" by (cases y)
-  { assume "a=0 \<or> a'= 0 \<or> b = 0 \<or> b' = 0"
-    hence ?thesis
-      apply (cases "a=0", simp_all add: x y Nmul_def INum_def Let_def)
-      apply (cases "b=0", simp_all)
-      apply (cases "a'=0", simp_all)
-      done }
-  moreover
-  { assume z: "a \<noteq> 0" "a' \<noteq> 0" "b \<noteq> 0" "b' \<noteq> 0"
-    let ?g="gcd (a*a') (b*b')"
-    have gz: "?g \<noteq> 0" using z by simp
-    from z of_int_div [where ?'a = 'a, OF gz gcd_dvd1 [of "a * a'" "b * b'"]]
-      of_int_div [where ?'a = 'a , OF gz gcd_dvd2 [of "a * a'" "b * b'"]]
-    have ?thesis by (simp add: Nmul_def x y Let_def INum_def) }
-  ultimately show ?thesis by blast
+  consider "a = 0 \<or> a'= 0 \<or> b =0 \<or> b' = 0" | "a \<noteq> 0" "a'\<noteq> 0" "b \<noteq> 0" "b' \<noteq> 0"
+    by blast
+  then show ?thesis
+  proof cases
+    case 1
+    then show ?thesis
+      apply (cases "a = 0")
+      apply (cases "b = 0")
+      apply (cases "a'= 0")
+      apply simp_all
+      apply (cases "b'= 0")
+      apply simp_all
+      done
+  next
+    case 2
+    show ?thesis
+    proof (cases "a * b' + b * a' = 0")
+      case True
+      then have "of_int (a * b' + b * a') / (of_int b * of_int b') = ?z"
+        by simp
+      then have "of_int b' * of_int a / (of_int b * of_int b') +
+          of_int b * of_int a' / (of_int b * of_int b') = ?z"
+      then have th: "of_int a / of_int b + of_int a' / of_int b' = ?z"
+        using 2 by simp
+      from True 2 show ?thesis
+    next
+      case False
+      let ?g = "gcd (a * b' + b * a') (b * b')"
+      have gz: "?g \<noteq> 0"
+        using False by simp
+      show ?thesis
+        using 2 False gz
+          of_int_div [where ?'a = 'a, OF gz gcd_dvd1 [of "a * b' + b * a'" "b * b'"]]
+          of_int_div [where ?'a = 'a, OF gz gcd_dvd2 [of "a * b' + b * a'" "b * b'"]]
+    qed
+  qed
qed

-lemma Nneg[simp]: "INum (~\<^sub>N x) = - (INum x ::'a:: field)"
+lemma Nmul[simp]: "INum (x *\<^sub>N y) = INum x * (INum y:: 'a::{field_char_0,field})"
+proof -
+  let ?z = "0::'a"
+  obtain a b where x: "x = (a, b)" by (cases x)
+  obtain a' b' where y: "y = (a', b')" by (cases y)
+  consider "a = 0 \<or> a' = 0 \<or> b = 0 \<or> b' = 0" | "a \<noteq> 0" "a' \<noteq> 0" "b \<noteq> 0" "b' \<noteq> 0"
+    by blast
+  then show ?thesis
+  proof cases
+    case 1
+    then show ?thesis
+      apply (cases "a = 0")
+      apply (simp_all add: x y Nmul_def INum_def Let_def)
+      apply (cases "b = 0")
+      apply simp_all
+      apply (cases "a' = 0")
+      apply simp_all
+      done
+  next
+    case 2
+    let ?g = "gcd (a * a') (b * b')"
+    have gz: "?g \<noteq> 0"
+      using 2 by simp
+    from 2 of_int_div [where ?'a = 'a, OF gz gcd_dvd1 [of "a * a'" "b * b'"]]
+      of_int_div [where ?'a = 'a , OF gz gcd_dvd2 [of "a * a'" "b * b'"]]
+    show ?thesis
+      by (simp add: Nmul_def x y Let_def INum_def)
+  qed
+qed
+
+lemma Nneg[simp]: "INum (~\<^sub>N x) = - (INum x ::'a::field)"
by (simp add: Nneg_def split_def INum_def)

-lemma Nsub[simp]: "INum (x -\<^sub>N y) = INum x - (INum y:: 'a :: {field_char_0, field})"
+lemma Nsub[simp]: "INum (x -\<^sub>N y) = INum x - (INum y:: 'a :: {field_char_0,field})"

lemma Ninv[simp]: "INum (Ninv x) = (1::'a :: field) / (INum x)"
by (simp add: Ninv_def INum_def split_def)

-lemma Ndiv[simp]: "INum (x \<div>\<^sub>N y) = INum x / (INum y ::'a :: {field_char_0, field})"
+lemma Ndiv[simp]: "INum (x \<div>\<^sub>N y) = INum x / (INum y ::'a :: {field_char_0,field})"

lemma Nlt0_iff[simp]:
assumes nx: "isnormNum x"
-  shows "((INum x :: 'a :: {field_char_0, linordered_field})< 0) = 0>\<^sub>N x"
+  shows "((INum x :: 'a::{field_char_0,linordered_field})< 0) = 0>\<^sub>N x"
proof -
obtain a b where x: "x = (a, b)" by (cases x)
-  { assume "a = 0" hence ?thesis by (simp add: x Nlt0_def INum_def) }
-  moreover
-  { assume a: "a \<noteq> 0" hence b: "(of_int b::'a) > 0"
+  show ?thesis
+  proof (cases "a = 0")
+    case True
+    then show ?thesis
+      by (simp add: x Nlt0_def INum_def)
+  next
+    case False
+    then have b: "(of_int b::'a) > 0"
using nx by (simp add: x isnormNum_def)
from pos_divide_less_eq[OF b, where b="of_int a" and a="0::'a"]
-    have ?thesis by (simp add: x Nlt0_def INum_def) }
-  ultimately show ?thesis by blast
+    show ?thesis
+      by (simp add: x Nlt0_def INum_def)
+  qed
qed

lemma Nle0_iff[simp]:
assumes nx: "isnormNum x"
-  shows "((INum x :: 'a :: {field_char_0, linordered_field}) \<le> 0) = 0\<ge>\<^sub>N x"
+  shows "((INum x :: 'a::{field_char_0,linordered_field}) \<le> 0) = 0\<ge>\<^sub>N x"
proof -
obtain a b where x: "x = (a, b)" by (cases x)
-  { assume "a = 0" hence ?thesis by (simp add: x Nle0_def INum_def) }
-  moreover
-  { assume a: "a \<noteq> 0" hence b: "(of_int b :: 'a) > 0"
+  show ?thesis
+  proof (cases "a = 0")
+    case True
+    then show ?thesis
+      by (simp add: x Nle0_def INum_def)
+  next
+    case False
+    then have b: "(of_int b :: 'a) > 0"
using nx by (simp add: x isnormNum_def)
from pos_divide_le_eq[OF b, where b="of_int a" and a="0::'a"]
-    have ?thesis by (simp add: x Nle0_def INum_def) }
-  ultimately show ?thesis by blast
+    show ?thesis
+      by (simp add: x Nle0_def INum_def)
+  qed
qed

lemma Ngt0_iff[simp]:
assumes nx: "isnormNum x"
-  shows "((INum x :: 'a :: {field_char_0, linordered_field})> 0) = 0<\<^sub>N x"
+  shows "((INum x :: 'a::{field_char_0,linordered_field})> 0) = 0<\<^sub>N x"
proof -
obtain a b where x: "x = (a, b)" by (cases x)
-  { assume "a = 0" hence ?thesis by (simp add: x Ngt0_def INum_def) }
-  moreover
-  { assume a: "a \<noteq> 0" hence b: "(of_int b::'a) > 0" using nx
-      by (simp add: x isnormNum_def)
+  show ?thesis
+  proof (cases "a = 0")
+    case True
+    then show ?thesis
+      by (simp add: x Ngt0_def INum_def)
+  next
+    case False
+    then have b: "(of_int b::'a) > 0"
+      using nx by (simp add: x isnormNum_def)
from pos_less_divide_eq[OF b, where b="of_int a" and a="0::'a"]
-    have ?thesis by (simp add: x Ngt0_def INum_def) }
-  ultimately show ?thesis by blast
+    show ?thesis
+      by (simp add: x Ngt0_def INum_def)
+  qed
qed

lemma Nge0_iff[simp]:
assumes nx: "isnormNum x"
-  shows "((INum x :: 'a :: {field_char_0, linordered_field}) \<ge> 0) = 0\<le>\<^sub>N x"
+  shows "((INum x :: 'a::{field_char_0,linordered_field}) \<ge> 0) = 0\<le>\<^sub>N x"
proof -
obtain a b where x: "x = (a, b)" by (cases x)
-  { assume "a = 0" hence ?thesis by (simp add: x Nge0_def INum_def) }
-  moreover
-  { assume "a \<noteq> 0" hence b: "(of_int b::'a) > 0" using nx
-      by (simp add: x isnormNum_def)
+  show ?thesis
+  proof (cases "a = 0")
+    case True
+    then show ?thesis
+      by (simp add: x Nge0_def INum_def)
+  next
+    case False
+    then have b: "(of_int b::'a) > 0"
+      using nx by (simp add: x isnormNum_def)
from pos_le_divide_eq[OF b, where b="of_int a" and a="0::'a"]
-    have ?thesis by (simp add: x Nge0_def INum_def) }
-  ultimately show ?thesis by blast
+    show ?thesis
+      by (simp add: x Nge0_def INum_def)
+  qed
qed

lemma Nlt_iff[simp]:
-  assumes nx: "isnormNum x" and ny: "isnormNum y"
-  shows "((INum x :: 'a :: {field_char_0, linordered_field}) < INum y) = (x <\<^sub>N y)"
+  assumes nx: "isnormNum x"
+    and ny: "isnormNum y"
+  shows "((INum x :: 'a::{field_char_0,linordered_field}) < INum y) = (x <\<^sub>N y)"
proof -
let ?z = "0::'a"
have "((INum x ::'a) < INum y) = (INum (x -\<^sub>N y) < ?z)"
using nx ny by simp
also have "\<dots> = (0>\<^sub>N (x -\<^sub>N y))"
using Nlt0_iff[OF Nsub_normN[OF ny]] by simp
-  finally show ?thesis by (simp add: Nlt_def)
+  finally show ?thesis
qed

lemma Nle_iff[simp]:
-  assumes nx: "isnormNum x" and ny: "isnormNum y"
-  shows "((INum x :: 'a :: {field_char_0, linordered_field})\<le> INum y) = (x \<le>\<^sub>N y)"
+  assumes nx: "isnormNum x"
+    and ny: "isnormNum y"
+  shows "((INum x :: 'a::{field_char_0,linordered_field})\<le> INum y) = (x \<le>\<^sub>N y)"
proof -
have "((INum x ::'a) \<le> INum y) = (INum (x -\<^sub>N y) \<le> (0::'a))"
using nx ny by simp
also have "\<dots> = (0\<ge>\<^sub>N (x -\<^sub>N y))"
using Nle0_iff[OF Nsub_normN[OF ny]] by simp
-  finally show ?thesis by (simp add: Nle_def)
+  finally show ?thesis
qed

-  assumes "SORT_CONSTRAINT('a::{field_char_0, field})"
+  assumes "SORT_CONSTRAINT('a::{field_char_0,field})"
shows "x +\<^sub>N y = y +\<^sub>N x"
proof -
-  have n: "isnormNum (x +\<^sub>N y)" "isnormNum (y +\<^sub>N x)" by simp_all
-  have "(INum (x +\<^sub>N y)::'a) = INum (y +\<^sub>N x)" by simp
-  with isnormNum_unique[OF n] show ?thesis by simp
+  have n: "isnormNum (x +\<^sub>N y)" "isnormNum (y +\<^sub>N x)"
+    by simp_all
+  have "(INum (x +\<^sub>N y)::'a) = INum (y +\<^sub>N x)"
+    by simp
+  with isnormNum_unique[OF n] show ?thesis
+    by simp
qed

lemma [simp]:
-  assumes "SORT_CONSTRAINT('a::{field_char_0, field})"
+  assumes "SORT_CONSTRAINT('a::{field_char_0,field})"
shows "(0, b) +\<^sub>N y = normNum y"
and "(a, 0) +\<^sub>N y = normNum y"
and "x +\<^sub>N (0, b) = normNum x"
and "x +\<^sub>N (a, 0) = normNum x"
done

lemma normNum_nilpotent_aux[simp]:
-  assumes "SORT_CONSTRAINT('a::{field_char_0, field})"
+  assumes "SORT_CONSTRAINT('a::{field_char_0,field})"
assumes nx: "isnormNum x"
shows "normNum x = x"
proof -
@@ -419,7 +503,7 @@
qed

lemma normNum_nilpotent[simp]:
-  assumes "SORT_CONSTRAINT('a::{field_char_0, field})"
+  assumes "SORT_CONSTRAINT('a::{field_char_0,field})"
shows "normNum (normNum x) = normNum x"
by simp

@@ -427,11 +511,12 @@

-  assumes "SORT_CONSTRAINT('a::{field_char_0, field})"
-  shows "normNum (x +\<^sub>N y) = x +\<^sub>N y" by simp
+  assumes "SORT_CONSTRAINT('a::{field_char_0,field})"
+  shows "normNum (x +\<^sub>N y) = x +\<^sub>N y"
+  by simp

-  assumes "SORT_CONSTRAINT('a::{field_char_0, field})"
+  assumes "SORT_CONSTRAINT('a::{field_char_0,field})"
shows "normNum x +\<^sub>N y = x +\<^sub>N y"
proof -
have n: "isnormNum (normNum x +\<^sub>N y)" "isnormNum (x +\<^sub>N y)" by simp_all
@@ -441,7 +526,7 @@
qed

-  assumes "SORT_CONSTRAINT('a::{field_char_0, field})"
+  assumes "SORT_CONSTRAINT('a::{field_char_0,field})"
shows "x +\<^sub>N normNum y = x +\<^sub>N y"
proof -
have n: "isnormNum (x +\<^sub>N normNum y)" "isnormNum (x +\<^sub>N y)" by simp_all
@@ -451,7 +536,7 @@
qed

-  assumes "SORT_CONSTRAINT('a::{field_char_0, field})"
+  assumes "SORT_CONSTRAINT('a::{field_char_0,field})"
shows "x +\<^sub>N y +\<^sub>N z = x +\<^sub>N (y +\<^sub>N z)"
proof -
have n: "isnormNum (x +\<^sub>N y +\<^sub>N z)" "isnormNum (x +\<^sub>N (y +\<^sub>N z))" by simp_all
@@ -463,8 +548,10 @@
by (simp add: Nmul_def split_def Let_def gcd_commute_int mult.commute)

lemma Nmul_assoc:
-  assumes "SORT_CONSTRAINT('a::{field_char_0, field})"
-  assumes nx: "isnormNum x" and ny: "isnormNum y" and nz: "isnormNum z"
+  assumes "SORT_CONSTRAINT('a::{field_char_0,field})"
+  assumes nx: "isnormNum x"
+    and ny: "isnormNum y"
+    and nz: "isnormNum z"
shows "x *\<^sub>N y *\<^sub>N z = x *\<^sub>N (y *\<^sub>N z)"
proof -
from nx ny nz have n: "isnormNum (x *\<^sub>N y *\<^sub>N z)" "isnormNum (x *\<^sub>N (y *\<^sub>N z))"
@@ -474,11 +561,11 @@
qed

lemma Nsub0:
-  assumes "SORT_CONSTRAINT('a::{field_char_0, field})"
-  assumes x: "isnormNum x" and y: "isnormNum y"
+  assumes "SORT_CONSTRAINT('a::{field_char_0,field})"
+  assumes x: "isnormNum x"
+    and y: "isnormNum y"
shows "x -\<^sub>N y = 0\<^sub>N \<longleftrightarrow> x = y"
proof -
-  fix h :: 'a
from isnormNum_unique[where 'a = 'a, OF Nsub_normN[OF y], where y="0\<^sub>N"]
have "(x -\<^sub>N y = 0\<^sub>N) = (INum (x -\<^sub>N y) = (INum 0\<^sub>N :: 'a)) " by simp
also have "\<dots> = (INum x = (INum y :: 'a))" by simp
@@ -490,11 +577,11 @@
by (simp_all add: Nmul_def Let_def split_def)

lemma Nmul_eq0[simp]:
-  assumes "SORT_CONSTRAINT('a::{field_char_0, field})"
-  assumes nx: "isnormNum x" and ny: "isnormNum y"
+  assumes "SORT_CONSTRAINT('a::{field_char_0,field})"
+  assumes nx: "isnormNum x"
+    and ny: "isnormNum y"
shows "x*\<^sub>N y = 0\<^sub>N \<longleftrightarrow> x = 0\<^sub>N \<or> y = 0\<^sub>N"
proof -
-  fix h :: 'a
obtain a b where x: "x = (a, b)" by (cases x)
obtain a' b' where y: "y = (a', b')" by (cases y)
have n0: "isnormNum 0\<^sub>N" by simp
@@ -508,9 +595,7 @@
lemma Nneg_Nneg[simp]: "~\<^sub>N (~\<^sub>N c) = c"

-lemma Nmul1[simp]:
-    "isnormNum c \<Longrightarrow> (1)\<^sub>N *\<^sub>N c = c"
-    "isnormNum c \<Longrightarrow> c *\<^sub>N (1)\<^sub>N = c"
+lemma Nmul1[simp]: "isnormNum c \<Longrightarrow> (1)\<^sub>N *\<^sub>N c = c" "isnormNum c \<Longrightarrow> c *\<^sub>N (1)\<^sub>N = c"
apply (simp_all add: Nmul_def Let_def split_def isnormNum_def)
apply (cases "fst c = 0", simp_all, cases c, simp_all)+
done```