# HG changeset patch # User wenzelm # Date 1176762644 -7200 # Node ID 936f7580937d25cb81b50e07e05458696fcbed6a # Parent 74dbc7696083ebe261dd75e7c9404212ef32e6f6 tuned proofs; diff -r 74dbc7696083 -r 936f7580937d src/HOL/Divides.thy --- a/src/HOL/Divides.thy Mon Apr 16 16:11:03 2007 +0200 +++ b/src/HOL/Divides.thy Tue Apr 17 00:30:44 2007 +0200 @@ -34,7 +34,7 @@ instance nat :: "Divides.div" mod_def: "m mod n == wfrec (pred_nat^+) (%f j. if j 'a \ bool" (infixl "dvd" 50) where dvd_def: "m dvd n \ (\k. n = m*k)" -consts - quorem :: "(nat*nat) * (nat*nat) => bool" - -defs +definition + quorem :: "(nat*nat) * (nat*nat) => bool" where (*This definition helps prove the harder properties of div and mod. It is copied from IntDiv.thy; should it be overloaded?*) - quorem_def: "quorem \ (%((a,b), (q,r)). + "quorem = (%((a,b), (q,r)). a = b*q + r & (if 0r & r0))" @@ -56,161 +54,150 @@ subsection{*Initial Lemmas*} -lemmas wf_less_trans = +lemmas wf_less_trans = def_wfrec [THEN trans, OF eq_reflection wf_pred_nat [THEN wf_trancl], standard] -lemma mod_eq: "(%m. m mod n) = +lemma mod_eq: "(%m. m mod n) = wfrec (pred_nat^+) (%f j. if j m mod n = (m::nat)" -by (rule mod_eq [THEN wf_less_trans], simp) + by (rule mod_eq [THEN wf_less_trans]) simp lemma mod_geq: "~ m < (n::nat) ==> m mod n = (m-n) mod n" -apply (case_tac "n=0", simp) -apply (rule mod_eq [THEN wf_less_trans]) -apply (simp add: cut_apply less_eq) -done + apply (cases "n=0") + apply simp + apply (rule mod_eq [THEN wf_less_trans]) + apply (simp add: cut_apply less_eq) + done (*Avoids the ugly ~m m ==> m mod n = (m-n) mod n" -by (simp add: mod_geq linorder_not_less) + by (simp add: mod_geq linorder_not_less) lemma mod_if: "m mod (n::nat) = (if m m div n = (0::nat)" -by (rule div_eq [THEN wf_less_trans], simp) + by (rule div_eq [THEN wf_less_trans], simp) lemma div_geq: "[| 0 m div n = Suc((m-n) div n)" -apply (rule div_eq [THEN wf_less_trans]) -apply (simp add: cut_apply less_eq) -done + apply (rule div_eq [THEN wf_less_trans]) + apply (simp add: cut_apply less_eq) + done (*Avoids the ugly ~mm |] ==> m div n = Suc((m-n) div n)" -by (simp add: div_geq linorder_not_less) + by (simp add: div_geq linorder_not_less) lemma div_if: "0 m div n = (if m m mod n < (n::nat)" -apply (induct "m" rule: nat_less_induct) -apply (case_tac "na na"}*} -apply (simp add: mod_geq) -done + apply (induct m rule: nat_less_induct) + apply (rename_tac m) + apply (case_tac "m m"}*} + apply (simp add: mod_geq) + done lemma mod_le_divisor[simp]: "0 < n \ m mod n \ (n::nat)" -apply(drule mod_less_divisor[where m = m]) -apply simp -done + apply (drule mod_less_divisor [where m = m]) + apply simp + done lemma div_mult_self_is_m [simp]: "0 (m*n) div n = (m::nat)" -by (cut_tac m = "m*n" and n = n in mod_div_equality, auto) + by (cut_tac m = "m*n" and n = n in mod_div_equality, auto) lemma div_mult_self1_is_m [simp]: "0 (n*m) div n = (m::nat)" -by (simp add: mult_commute div_mult_self_is_m) + by (simp add: mult_commute div_mult_self_is_m) (*mod_mult_distrib2 above is the counterpart for remainder*) @@ -252,95 +240,93 @@ subsection{*Proving facts about Quotient and Remainder*} lemma unique_quotient_lemma: - "[| b*q' + r' \ b*q + r; x < b; r < b |] + "[| b*q' + r' \ b*q + r; x < b; r < b |] ==> q' \ (q::nat)" -apply (rule leI) -apply (subst less_iff_Suc_add) -apply (auto simp add: add_mult_distrib2) -done + apply (rule leI) + apply (subst less_iff_Suc_add) + apply (auto simp add: add_mult_distrib2) + done lemma unique_quotient: - "[| quorem ((a,b), (q,r)); quorem ((a,b), (q',r')); 0 < b |] + "[| quorem ((a,b), (q,r)); quorem ((a,b), (q',r')); 0 < b |] ==> q = q'" -apply (simp add: split_ifs quorem_def) -apply (blast intro: order_antisym - dest: order_eq_refl [THEN unique_quotient_lemma] sym) -done + apply (simp add: split_ifs quorem_def) + apply (blast intro: order_antisym + dest: order_eq_refl [THEN unique_quotient_lemma] sym) + done lemma unique_remainder: - "[| quorem ((a,b), (q,r)); quorem ((a,b), (q',r')); 0 < b |] + "[| quorem ((a,b), (q,r)); quorem ((a,b), (q',r')); 0 < b |] ==> r = r'" -apply (subgoal_tac "q = q'") -prefer 2 apply (blast intro: unique_quotient) -apply (simp add: quorem_def) -done + apply (subgoal_tac "q = q'") + prefer 2 apply (blast intro: unique_quotient) + apply (simp add: quorem_def) + done lemma quorem_div_mod: "0 < b ==> quorem ((a, b), (a div b, a mod b))" - unfolding quorem_def by simp + unfolding quorem_def by simp lemma quorem_div: "[| quorem((a,b),(q,r)); 0 < b |] ==> a div b = q" -by (simp add: quorem_div_mod [THEN unique_quotient]) + by (simp add: quorem_div_mod [THEN unique_quotient]) lemma quorem_mod: "[| quorem((a,b),(q,r)); 0 < b |] ==> a mod b = r" -by (simp add: quorem_div_mod [THEN unique_remainder]) + by (simp add: quorem_div_mod [THEN unique_remainder]) (** A dividend of zero **) lemma div_0 [simp]: "0 div m = (0::nat)" -by (case_tac "m=0", simp_all) + by (cases "m = 0") simp_all lemma mod_0 [simp]: "0 mod m = (0::nat)" -by (case_tac "m=0", simp_all) + by (cases "m = 0") simp_all (** proving (a*b) div c = a * (b div c) + a * (b mod c) **) lemma quorem_mult1_eq: - "[| quorem((b,c),(q,r)); 0 < c |] + "[| quorem((b,c),(q,r)); 0 < c |] ==> quorem ((a*b, c), (a*q + a*r div c, a*r mod c))" -apply (auto simp add: split_ifs mult_ac quorem_def add_mult_distrib2) -done + by (auto simp add: split_ifs mult_ac quorem_def add_mult_distrib2) lemma div_mult1_eq: "(a*b) div c = a*(b div c) + a*(b mod c) div (c::nat)" -apply (case_tac "c = 0", simp) -apply (blast intro: quorem_div_mod [THEN quorem_mult1_eq, THEN quorem_div]) -done + apply (cases "c = 0", simp) + apply (blast intro: quorem_div_mod [THEN quorem_mult1_eq, THEN quorem_div]) + done lemma mod_mult1_eq: "(a*b) mod c = a*(b mod c) mod (c::nat)" -apply (case_tac "c = 0", simp) -apply (blast intro: quorem_div_mod [THEN quorem_mult1_eq, THEN quorem_mod]) -done + apply (cases "c = 0", simp) + apply (blast intro: quorem_div_mod [THEN quorem_mult1_eq, THEN quorem_mod]) + done lemma mod_mult1_eq': "(a*b) mod (c::nat) = ((a mod c) * b) mod c" -apply (rule trans) -apply (rule_tac s = "b*a mod c" in trans) -apply (rule_tac [2] mod_mult1_eq) -apply (simp_all (no_asm) add: mult_commute) -done + apply (rule trans) + apply (rule_tac s = "b*a mod c" in trans) + apply (rule_tac [2] mod_mult1_eq) + apply (simp_all add: mult_commute) + done lemma mod_mult_distrib_mod: "(a*b) mod (c::nat) = ((a mod c) * (b mod c)) mod c" -apply (rule mod_mult1_eq' [THEN trans]) -apply (rule mod_mult1_eq) -done + apply (rule mod_mult1_eq' [THEN trans]) + apply (rule mod_mult1_eq) + done (** proving (a+b) div c = a div c + b div c + ((a mod c + b mod c) div c) **) lemma quorem_add1_eq: - "[| quorem((a,c),(aq,ar)); quorem((b,c),(bq,br)); 0 < c |] + "[| quorem((a,c),(aq,ar)); quorem((b,c),(bq,br)); 0 < c |] ==> quorem ((a+b, c), (aq + bq + (ar+br) div c, (ar+br) mod c))" -by (auto simp add: split_ifs mult_ac quorem_def add_mult_distrib2) + by (auto simp add: split_ifs mult_ac quorem_def add_mult_distrib2) (*NOT suitable for rewriting: the RHS has an instance of the LHS*) lemma div_add1_eq: "(a+b) div (c::nat) = a div c + b div c + ((a mod c + b mod c) div c)" -apply (case_tac "c = 0", simp) -apply (blast intro: quorem_add1_eq [THEN quorem_div] quorem_div_mod quorem_div_mod) -done + apply (cases "c = 0", simp) + apply (blast intro: quorem_add1_eq [THEN quorem_div] quorem_div_mod quorem_div_mod) + done lemma mod_add1_eq: "(a+b) mod (c::nat) = (a mod c + b mod c) mod c" -apply (case_tac "c = 0", simp) -apply (blast intro: quorem_div_mod quorem_div_mod - quorem_add1_eq [THEN quorem_mod]) -done + apply (cases "c = 0", simp) + apply (blast intro: quorem_div_mod quorem_div_mod quorem_add1_eq [THEN quorem_mod]) + done subsection{*Proving @{term "a div (b*c) = (a div b) div c"}*} @@ -348,45 +334,44 @@ (** first, a lemma to bound the remainder **) lemma mod_lemma: "[| (0::nat) < c; r < b |] ==> b * (q mod c) + r < b * c" -apply (cut_tac m = q and n = c in mod_less_divisor) -apply (drule_tac [2] m = "q mod c" in less_imp_Suc_add, auto) -apply (erule_tac P = "%x. ?lhs < ?rhs x" in ssubst) -apply (simp add: add_mult_distrib2) -done + apply (cut_tac m = q and n = c in mod_less_divisor) + apply (drule_tac [2] m = "q mod c" in less_imp_Suc_add, auto) + apply (erule_tac P = "%x. ?lhs < ?rhs x" in ssubst) + apply (simp add: add_mult_distrib2) + done -lemma quorem_mult2_eq: "[| quorem ((a,b), (q,r)); 0 < b; 0 < c |] +lemma quorem_mult2_eq: "[| quorem ((a,b), (q,r)); 0 < b; 0 < c |] ==> quorem ((a, b*c), (q div c, b*(q mod c) + r))" -apply (auto simp add: mult_ac quorem_def add_mult_distrib2 [symmetric] mod_lemma) -done + by (auto simp add: mult_ac quorem_def add_mult_distrib2 [symmetric] mod_lemma) lemma div_mult2_eq: "a div (b*c) = (a div b) div (c::nat)" -apply (case_tac "b=0", simp) -apply (case_tac "c=0", simp) -apply (force simp add: quorem_div_mod [THEN quorem_mult2_eq, THEN quorem_div]) -done + apply (cases "b = 0", simp) + apply (cases "c = 0", simp) + apply (force simp add: quorem_div_mod [THEN quorem_mult2_eq, THEN quorem_div]) + done lemma mod_mult2_eq: "a mod (b*c) = b*(a div b mod c) + a mod (b::nat)" -apply (case_tac "b=0", simp) -apply (case_tac "c=0", simp) -apply (auto simp add: mult_commute quorem_div_mod [THEN quorem_mult2_eq, THEN quorem_mod]) -done + apply (cases "b = 0", simp) + apply (cases "c = 0", simp) + apply (auto simp add: mult_commute quorem_div_mod [THEN quorem_mult2_eq, THEN quorem_mod]) + done subsection{*Cancellation of Common Factors in Division*} lemma div_mult_mult_lemma: - "[| (0::nat) < b; 0 < c |] ==> (c*a) div (c*b) = a div b" -by (auto simp add: div_mult2_eq) + "[| (0::nat) < b; 0 < c |] ==> (c*a) div (c*b) = a div b" + by (auto simp add: div_mult2_eq) lemma div_mult_mult1 [simp]: "(0::nat) < c ==> (c*a) div (c*b) = a div b" -apply (case_tac "b = 0") -apply (auto simp add: linorder_neq_iff [of b] div_mult_mult_lemma) -done + apply (cases "b = 0") + apply (auto simp add: linorder_neq_iff [of b] div_mult_mult_lemma) + done lemma div_mult_mult2 [simp]: "(0::nat) < c ==> (a*c) div (b*c) = a div b" -apply (drule div_mult_mult1) -apply (auto simp add: mult_commute) -done + apply (drule div_mult_mult1) + apply (auto simp add: mult_commute) + done (*Distribution of Factors over Remainders: @@ -404,34 +389,32 @@ subsection{*Further Facts about Quotient and Remainder*} lemma div_1 [simp]: "m div Suc 0 = m" -apply (induct "m") -apply (simp_all (no_asm_simp) add: div_geq) -done + by (induct m) (simp_all add: div_geq) lemma div_self [simp]: "0 n div n = (1::nat)" -by (simp add: div_geq) + by (simp add: div_geq) lemma div_add_self2: "0 (m+n) div n = Suc (m div n)" -apply (subgoal_tac "(n + m) div n = Suc ((n+m-n) div n) ") -apply (simp add: add_commute) -apply (subst div_geq [symmetric], simp_all) -done + apply (subgoal_tac "(n + m) div n = Suc ((n+m-n) div n) ") + apply (simp add: add_commute) + apply (subst div_geq [symmetric], simp_all) + done lemma div_add_self1: "0 (n+m) div n = Suc (m div n)" -by (simp add: add_commute div_add_self2) + by (simp add: add_commute div_add_self2) lemma div_mult_self1 [simp]: "!!n::nat. 0 (m + k*n) div n = k + m div n" -apply (subst div_add1_eq) -apply (subst div_mult1_eq, simp) -done + apply (subst div_add1_eq) + apply (subst div_mult1_eq, simp) + done lemma div_mult_self2 [simp]: "0 (m + n*k) div n = k + m div (n::nat)" -by (simp add: mult_commute div_mult_self1) + by (simp add: mult_commute div_mult_self1) (* Monotonicity of div in first argument *) lemma div_le_mono [rule_format (no_asm)]: - "\m::nat. m \ n --> (m div k) \ (n div k)" + "\m::nat. m \ n --> (m div k) \ (n div k)" apply (case_tac "k=0", simp) apply (induct "n" rule: nat_less_induct, clarify) apply (case_tac "nn |] ==> (k div n) \ (k div m)" apply (subgoal_tac "0 (k-m) div n") prefer 2 @@ -469,14 +452,14 @@ apply (simp_all (no_asm_simp)) done -(* Similar for "less than" *) +(* Similar for "less than" *) lemma div_less_dividend [rule_format]: "!!n::nat. 1 0 < m --> m div n < m" apply (induct_tac m rule: nat_less_induct) apply (rename_tac "m") apply (case_tac "m m dvd n" -by (unfold dvd_def, blast) + unfolding dvd_def by blast lemma dvdE [elim?]: "!!P. [|m dvd n; !!k. n = m*k ==> P|] ==> P" -by (unfold dvd_def, blast) + unfolding dvd_def by blast lemma dvd_0_right [iff]: "m dvd (0::nat)" -apply (unfold dvd_def) -apply (blast intro: mult_0_right [symmetric]) -done + unfolding dvd_def by (blast intro: mult_0_right [symmetric]) lemma dvd_0_left: "0 dvd m ==> m = (0::nat)" -by (force simp add: dvd_def) + by (force simp add: dvd_def) lemma dvd_0_left_iff [iff]: "(0 dvd (m::nat)) = (m = 0)" -by (blast intro: dvd_0_left) + by (blast intro: dvd_0_left) lemma dvd_1_left [iff]: "Suc 0 dvd k" -by (unfold dvd_def, simp) + unfolding dvd_def by simp lemma dvd_1_iff_1 [simp]: "(m dvd Suc 0) = (m = Suc 0)" -by (simp add: dvd_def) + by (simp add: dvd_def) lemma dvd_refl [simp]: "m dvd (m::nat)" -apply (unfold dvd_def) -apply (blast intro: mult_1_right [symmetric]) -done + unfolding dvd_def by (blast intro: mult_1_right [symmetric]) lemma dvd_trans [trans]: "[| m dvd n; n dvd p |] ==> m dvd (p::nat)" -apply (unfold dvd_def) -apply (blast intro: mult_assoc) -done + unfolding dvd_def by (blast intro: mult_assoc) lemma dvd_anti_sym: "[| m dvd n; n dvd m |] ==> m = (n::nat)" -apply (unfold dvd_def) -apply (force dest: mult_eq_self_implies_10 simp add: mult_assoc mult_eq_1_iff) -done + unfolding dvd_def + by (force dest: mult_eq_self_implies_10 simp add: mult_assoc mult_eq_1_iff) lemma dvd_add: "[| k dvd m; k dvd n |] ==> k dvd (m+n :: nat)" -apply (unfold dvd_def) -apply (blast intro: add_mult_distrib2 [symmetric]) -done + unfolding dvd_def + by (blast intro: add_mult_distrib2 [symmetric]) lemma dvd_diff: "[| k dvd m; k dvd n |] ==> k dvd (m-n :: nat)" -apply (unfold dvd_def) -apply (blast intro: diff_mult_distrib2 [symmetric]) -done + unfolding dvd_def + by (blast intro: diff_mult_distrib2 [symmetric]) lemma dvd_diffD: "[| k dvd m-n; k dvd n; n\m |] ==> k dvd (m::nat)" -apply (erule linorder_not_less [THEN iffD2, THEN add_diff_inverse, THEN subst]) -apply (blast intro: dvd_add) -done + apply (erule linorder_not_less [THEN iffD2, THEN add_diff_inverse, THEN subst]) + apply (blast intro: dvd_add) + done lemma dvd_diffD1: "[| k dvd m-n; k dvd m; n\m |] ==> k dvd (n::nat)" -by (drule_tac m = m in dvd_diff, auto) + by (drule_tac m = m in dvd_diff, auto) lemma dvd_mult: "k dvd n ==> k dvd (m*n :: nat)" -apply (unfold dvd_def) -apply (blast intro: mult_left_commute) -done + unfolding dvd_def by (blast intro: mult_left_commute) lemma dvd_mult2: "k dvd m ==> k dvd (m*n :: nat)" -apply (subst mult_commute) -apply (erule dvd_mult) -done + apply (subst mult_commute) + apply (erule dvd_mult) + done lemma dvd_triv_right [iff]: "k dvd (m*k :: nat)" -by (rule dvd_refl [THEN dvd_mult]) + by (rule dvd_refl [THEN dvd_mult]) lemma dvd_triv_left [iff]: "k dvd (k*m :: nat)" -by (rule dvd_refl [THEN dvd_mult2]) + by (rule dvd_refl [THEN dvd_mult2]) lemma dvd_reduce: "(k dvd n + k) = (k dvd (n::nat))" -apply (rule iffI) -apply (erule_tac [2] dvd_add) -apply (rule_tac [2] dvd_refl) -apply (subgoal_tac "n = (n+k) -k") - prefer 2 apply simp -apply (erule ssubst) -apply (erule dvd_diff) -apply (rule dvd_refl) -done + apply (rule iffI) + apply (erule_tac [2] dvd_add) + apply (rule_tac [2] dvd_refl) + apply (subgoal_tac "n = (n+k) -k") + prefer 2 apply simp + apply (erule ssubst) + apply (erule dvd_diff) + apply (rule dvd_refl) + done lemma dvd_mod: "!!n::nat. [| f dvd m; f dvd n |] ==> f dvd m mod n" -apply (unfold dvd_def) -apply (case_tac "n=0", auto) -apply (blast intro: mod_mult_distrib2 [symmetric]) -done + unfolding dvd_def + apply (case_tac "n = 0", auto) + apply (blast intro: mod_mult_distrib2 [symmetric]) + done lemma dvd_mod_imp_dvd: "[| (k::nat) dvd m mod n; k dvd n |] ==> k dvd m" -apply (subgoal_tac "k dvd (m div n) *n + m mod n") - apply (simp add: mod_div_equality) -apply (simp only: dvd_add dvd_mult) -done + apply (subgoal_tac "k dvd (m div n) *n + m mod n") + apply (simp add: mod_div_equality) + apply (simp only: dvd_add dvd_mult) + done lemma dvd_mod_iff: "k dvd n ==> ((k::nat) dvd m mod n) = (k dvd m)" -by (blast intro: dvd_mod_imp_dvd dvd_mod) + by (blast intro: dvd_mod_imp_dvd dvd_mod) lemma dvd_mult_cancel: "!!k::nat. [| k*m dvd k*n; 0 m dvd n" -apply (unfold dvd_def) -apply (erule exE) -apply (simp add: mult_ac) -done + unfolding dvd_def + apply (erule exE) + apply (simp add: mult_ac) + done lemma dvd_mult_cancel1: "0 (m*n dvd m) = (n = (1::nat))" -apply auto -apply (subgoal_tac "m*n dvd m*1") -apply (drule dvd_mult_cancel, auto) -done + apply auto + apply (subgoal_tac "m*n dvd m*1") + apply (drule dvd_mult_cancel, auto) + done lemma dvd_mult_cancel2: "0 (n*m dvd m) = (n = (1::nat))" -apply (subst mult_commute) -apply (erule dvd_mult_cancel1) -done + apply (subst mult_commute) + apply (erule dvd_mult_cancel1) + done lemma mult_dvd_mono: "[| i dvd m; j dvd n|] ==> i*j dvd (m*n :: nat)" -apply (unfold dvd_def, clarify) -apply (rule_tac x = "k*ka" in exI) -apply (simp add: mult_ac) -done + apply (unfold dvd_def, clarify) + apply (rule_tac x = "k*ka" in exI) + apply (simp add: mult_ac) + done lemma dvd_mult_left: "(i*j :: nat) dvd k ==> i dvd k" -by (simp add: dvd_def mult_assoc, blast) + by (simp add: dvd_def mult_assoc, blast) lemma dvd_mult_right: "(i*j :: nat) dvd k ==> j dvd k" -apply (unfold dvd_def, clarify) -apply (rule_tac x = "i*k" in exI) -apply (simp add: mult_ac) -done + apply (unfold dvd_def, clarify) + apply (rule_tac x = "i*k" in exI) + apply (simp add: mult_ac) + done lemma dvd_imp_le: "[| k dvd n; 0 < n |] ==> k \ (n::nat)" -apply (unfold dvd_def, clarify) -apply (simp_all (no_asm_use) add: zero_less_mult_iff) -apply (erule conjE) -apply (rule le_trans) -apply (rule_tac [2] le_refl [THEN mult_le_mono]) -apply (erule_tac [2] Suc_leI, simp) -done + apply (unfold dvd_def, clarify) + apply (simp_all (no_asm_use) add: zero_less_mult_iff) + apply (erule conjE) + apply (rule le_trans) + apply (rule_tac [2] le_refl [THEN mult_le_mono]) + apply (erule_tac [2] Suc_leI, simp) + done lemma dvd_eq_mod_eq_0: "!!k::nat. (k dvd n) = (n mod k = 0)" -apply (unfold dvd_def) -apply (case_tac "k=0", simp, safe) -apply (simp add: mult_commute) -apply (rule_tac t = n and n1 = k in mod_div_equality [THEN subst]) -apply (subst mult_commute, simp) -done + apply (unfold dvd_def) + apply (case_tac "k=0", simp, safe) + apply (simp add: mult_commute) + apply (rule_tac t = n and n1 = k in mod_div_equality [THEN subst]) + apply (subst mult_commute, simp) + done lemma dvd_mult_div_cancel: "n dvd m ==> n * (m div n) = (m::nat)" -apply (subgoal_tac "m mod n = 0") - apply (simp add: mult_div_cancel) -apply (simp only: dvd_eq_mod_eq_0) -done + apply (subgoal_tac "m mod n = 0") + apply (simp add: mult_div_cancel) + apply (simp only: dvd_eq_mod_eq_0) + done lemma le_imp_power_dvd: "!!i::nat. m \ n ==> i^m dvd i^n" -apply (unfold dvd_def) -apply (erule linorder_not_less [THEN iffD2, THEN add_diff_inverse, THEN subst]) -apply (simp add: power_add) -done + apply (unfold dvd_def) + apply (erule linorder_not_less [THEN iffD2, THEN add_diff_inverse, THEN subst]) + apply (simp add: power_add) + done lemma nat_zero_less_power_iff [simp]: "(0 < x^n) = (x \ (0::nat) | n=0)" -by (induct "n", auto) + by (induct n) auto lemma power_le_dvd [rule_format]: "k^j dvd n --> i\j --> k^i dvd (n::nat)" -apply (induct "j") -apply (simp_all add: le_Suc_eq) -apply (blast dest!: dvd_mult_right) -done + apply (induct j) + apply (simp_all add: le_Suc_eq) + apply (blast dest!: dvd_mult_right) + done lemma power_dvd_imp_le: "[|i^m dvd i^n; (1::nat) < i|] ==> m \ n" -apply (rule power_le_imp_le_exp, assumption) -apply (erule dvd_imp_le, simp) -done + apply (rule power_le_imp_le_exp, assumption) + apply (erule dvd_imp_le, simp) + done lemma mod_eq_0_iff: "(m mod d = 0) = (\q::nat. m = d*q)" -by (auto simp add: dvd_eq_mod_eq_0 [symmetric] dvd_def) + by (auto simp add: dvd_eq_mod_eq_0 [symmetric] dvd_def) -lemmas mod_eq_0D = mod_eq_0_iff [THEN iffD1] -declare mod_eq_0D [dest!] +lemmas mod_eq_0D [dest!] = mod_eq_0_iff [THEN iffD1] (*Loses information, namely we also have r \q::nat. m = r + q*d" -apply (cut_tac m = m in mod_div_equality) -apply (simp only: add_ac) -apply (blast intro: sym) -done + apply (cut_tac m = m in mod_div_equality) + apply (simp only: add_ac) + apply (blast intro: sym) + done lemma split_div: @@ -713,11 +684,11 @@ assume n: "n = k*i + j" and j: "j < k" show "P i" proof (cases) - assume "i = 0" - with n j P show "P i" by simp + assume "i = 0" + with n j P show "P i" by simp next - assume "i \ 0" - with not0 n j P show "P i" by(simp add:add_ac) + assume "i \ 0" + with not0 n j P show "P i" by(simp add:add_ac) qed qed qed @@ -818,28 +789,28 @@ assume ih: "?A n" show "?A (Suc n)" proof (clarsimp) - assume y: "P (p - Suc n)" - have n: "Suc n < p" - proof (rule ccontr) - assume "\(Suc n < p)" - hence "p - Suc n = 0" - by simp - with y contra show "False" - by simp - qed - hence n2: "Suc (p - Suc n) = p-n" by arith - from p have "p - Suc n < p" by arith - with y step have z: "P ((Suc (p - Suc n)) mod p)" - by blast - show "False" - proof (cases "n=0") - case True - with z n2 contra show ?thesis by simp - next - case False - with p have "p-n < p" by arith - with z n2 False ih show ?thesis by simp - qed + assume y: "P (p - Suc n)" + have n: "Suc n < p" + proof (rule ccontr) + assume "\(Suc n < p)" + hence "p - Suc n = 0" + by simp + with y contra show "False" + by simp + qed + hence n2: "Suc (p - Suc n) = p-n" by arith + from p have "p - Suc n < p" by arith + with y step have z: "P ((Suc (p - Suc n)) mod p)" + by blast + show "False" + proof (cases "n=0") + case True + with z n2 contra show ?thesis by simp + next + case False + with p have "p-n < p" by arith + with z n2 False ih show ?thesis by simp + qed qed qed qed @@ -864,22 +835,22 @@ show "j

P j" (is "?A j") proof (induct j) from step base i show "?A 0" - by (auto elim: mod_induct_0) + by (auto elim: mod_induct_0) next fix k assume ih: "?A k" show "?A (Suc k)" proof - assume suc: "Suc k < p" - hence k: "knat) n = (m div n, m mod n)" -lemma divmod_zero [code]: - "divmod m 0 = (0, m)" +lemma divmod_zero [code]: "divmod m 0 = (0, m)" unfolding divmod_def by simp lemma divmod_succ [code]: "divmod m (Suc k) = (if m < Suc k then (0, m) else let (p, q) = divmod (m - Suc k) (Suc k) - in (Suc p, q) - )" + in (Suc p, q))" unfolding divmod_def Let_def split_def by (auto intro: div_geq mod_geq) -lemma div_divmod [code]: - "m div n = fst (divmod m n)" +lemma div_divmod [code]: "m div n = fst (divmod m n)" unfolding divmod_def by simp -lemma mod_divmod [code]: - "m mod n = snd (divmod m n)" +lemma mod_divmod [code]: "m mod n = snd (divmod m n)" unfolding divmod_def by simp code_modulename SML @@ -934,7 +901,6 @@ hide (open) const divmod - subsection {* Legacy bindings *} ML @@ -1038,7 +1004,6 @@ val mod_eqD = thm "mod_eqD"; *} - (* lemma split_div: assumes m: "m \ 0" diff -r 74dbc7696083 -r 936f7580937d src/HOL/Nat.thy --- a/src/HOL/Nat.thy Mon Apr 16 16:11:03 2007 +0200 +++ b/src/HOL/Nat.thy Tue Apr 17 00:30:44 2007 +0200 @@ -48,13 +48,15 @@ consts Suc :: "nat => nat" - pred_nat :: "(nat * nat) set" local defs Suc_def: "Suc == (%n. Abs_Nat (Suc_Rep (Rep_Nat n)))" - pred_nat_def: "pred_nat == {(m, n). n = Suc m}" + +definition + pred_nat :: "(nat * nat) set" where + "pred_nat = {(m, n). n = Suc m}" instance nat :: "{ord, zero, one}" Zero_nat_def: "0 == Abs_Nat Zero_Rep" @@ -64,8 +66,11 @@ text {* Induction *} -lemmas Rep_Nat' = Rep_Nat [simplified mem_Collect_eq] -lemmas Abs_Nat_inverse' = Abs_Nat_inverse [simplified mem_Collect_eq] +lemma Rep_Nat': "Nat (Rep_Nat x)" + by (rule Rep_Nat [simplified mem_Collect_eq]) + +lemma Abs_Nat_inverse': "Nat y \ Rep_Nat (Abs_Nat y) = y" + by (rule Abs_Nat_inverse [simplified mem_Collect_eq]) theorem nat_induct: "P 0 ==> (!!n. P n ==> P (Suc n)) ==> P n" apply (unfold Zero_nat_def Suc_def) @@ -78,7 +83,7 @@ lemma Suc_not_Zero [iff]: "Suc m \ 0" by (simp add: Zero_nat_def Suc_def Abs_Nat_inject Rep_Nat' Suc_RepI Zero_RepI - Suc_Rep_not_Zero_Rep) + Suc_Rep_not_Zero_Rep) lemma Zero_not_Suc [iff]: "0 \ Suc m" by (rule not_sym, rule Suc_not_Zero not_sym) @@ -92,8 +97,8 @@ text {* Injectiveness of @{term Suc} *} lemma inj_Suc[simp]: "inj_on Suc N" - by (simp add: Suc_def inj_on_def Abs_Nat_inject Rep_Nat' Suc_RepI - inj_Suc_Rep [THEN inj_eq] Rep_Nat_inject) + by (simp add: Suc_def inj_on_def Abs_Nat_inject Rep_Nat' Suc_RepI + inj_Suc_Rep [THEN inj_eq] Rep_Nat_inject) lemma Suc_inject: "Suc x = Suc y ==> x = y" by (rule inj_Suc [THEN injD]) @@ -259,9 +264,9 @@ text {* "Less than" is antisymmetric, sort of *} lemma less_antisym: "\ \ n < m; n < Suc m \ \ m = n" -apply(simp only:less_Suc_eq) -apply blast -done + apply(simp only:less_Suc_eq) + apply blast + done lemma nat_neq_iff: "((m::nat) \ n) = (m < n | n < m)" using less_linear by blast @@ -318,13 +323,12 @@ text {* Can be used with @{text less_Suc_eq} to get @{term "n = m | n < m"} *} lemma not_less_eq: "(~ m < n) = (n < Suc m)" -by (rule_tac m = m and n = n in diff_induct, simp_all) + by (induct m n rule: diff_induct) simp_all text {* Complete induction, aka course-of-values induction *} lemma nat_less_induct: assumes prem: "!!n. \m::nat. m < n --> P m ==> P n" shows "P n" - apply (rule_tac a=n in wf_induct) - apply (rule wf_pred_nat [THEN wf_trancl]) + apply (induct n rule: wf_induct [OF wf_pred_nat [THEN wf_trancl]]) apply (rule prem) apply (unfold less_def, assumption) done @@ -336,13 +340,13 @@ text {* Was @{text le_eq_less_Suc}, but this orientation is more useful *} lemma less_Suc_eq_le: "(m < Suc n) = (m \ n)" - by (unfold le_def, rule not_less_eq [symmetric]) + unfolding le_def by (rule not_less_eq [symmetric]) lemma le_imp_less_Suc: "m \ n ==> m < Suc n" by (rule less_Suc_eq_le [THEN iffD2]) lemma le0 [iff]: "(0::nat) \ n" - by (unfold le_def, rule not_less0) + unfolding le_def by (rule not_less0) lemma Suc_n_not_le_n: "~ Suc n \ n" by (simp add: le_def) @@ -387,23 +391,21 @@ text {* Equivalence of @{term "m \ n"} and @{term "m < n | m = n"} *} lemma le_imp_less_or_eq: "m \ n ==> m < n | m = (n::nat)" - apply (unfold le_def) + unfolding le_def using less_linear - apply (blast elim: less_irrefl less_asym) - done + by (blast elim: less_irrefl less_asym) lemma less_or_eq_imp_le: "m < n | m = n ==> m \ (n::nat)" - apply (unfold le_def) + unfolding le_def using less_linear - apply (blast elim!: less_irrefl elim: less_asym) - done + by (blast elim!: less_irrefl elim: less_asym) lemma le_eq_less_or_eq: "(m \ (n::nat)) = (m < n | m=n)" by (iprover intro: less_or_eq_imp_le le_imp_less_or_eq) -text {* Useful with @{text Blast}. *} +text {* Useful with @{text blast}. *} lemma eq_imp_le: "(m::nat) = n ==> m \ n" - by (rule less_or_eq_imp_le, rule disjI2) + by (rule less_or_eq_imp_le) (rule disjI2) lemma le_refl: "n \ (n::nat)" by (simp add: le_eq_less_or_eq) @@ -433,9 +435,7 @@ text {* Axiom @{text linorder_linear} of class @{text linorder}: *} lemma nat_le_linear: "(m::nat) \ n | n \ m" apply (simp add: le_eq_less_or_eq) - using less_linear - apply blast - done + using less_linear by blast text {* Type {@typ nat} is a wellfounded linear order *} @@ -444,7 +444,7 @@ (assumption | rule le_refl le_trans le_anti_sym nat_less_le nat_le_linear wf_less)+ -lemmas linorder_neqE_nat = linorder_neqE[where 'a = nat] +lemmas linorder_neqE_nat = linorder_neqE [where 'a = nat] lemma not_less_less_Suc_eq: "~ n < m ==> (n < Suc m) = (n = m)" by (blast elim!: less_SucE) @@ -461,8 +461,8 @@ text {* - Re-orientation of the equations @{text "0 = x"} and @{text "1 = x"}. - No longer added as simprules (they loop) + Re-orientation of the equations @{text "0 = x"} and @{text "1 = x"}. + No longer added as simprules (they loop) but via @{text reorient_simproc} in Bin *} @@ -495,7 +495,7 @@ mult_0: "0 * n = 0" mult_Suc: "Suc m * n = n + (m * n)" -text {* These two rules ease the use of primitive recursion. +text {* These two rules ease the use of primitive recursion. NOTE USE OF @{text "=="} *} lemma def_nat_rec_0: "(!!n. f n == nat_rec c h n) ==> f 0 = c" by simp @@ -504,13 +504,13 @@ by simp lemma not0_implies_Suc: "n \ 0 ==> \m. n = Suc m" - by (case_tac n) simp_all + by (cases n) simp_all -lemma gr_implies_not0: "!!n::nat. m n \ 0" - by (case_tac n) simp_all +lemma gr_implies_not0: fixes n :: nat shows "m n \ 0" + by (cases n) simp_all -lemma neq0_conv [iff]: "!!n::nat. (n \ 0) = (0 < n)" - by (case_tac n) simp_all +lemma neq0_conv [iff]: fixes n :: nat shows "(n \ 0) = (0 < n)" + by (cases n) simp_all text {* This theorem is useful with @{text blast} *} lemma gr0I: "((n::nat) = 0 ==> False) ==> 0 < n" @@ -521,7 +521,8 @@ lemma not_gr0 [iff]: "!!n::nat. (~ (0 < n)) = (n = 0)" apply (rule iffI) - apply (rule ccontr, simp_all) + apply (rule ccontr) + apply simp_all done lemma Suc_le_D: "(Suc n \ m') ==> (? m. m' = Suc m)" @@ -529,7 +530,7 @@ text {* Useful in certain inductive arguments *} lemma less_Suc_eq_0_disj: "(m < Suc n) = (m = 0 | (\j. m = Suc j & j < n))" - by (case_tac m) simp_all + by (cases m) simp_all lemma nat_induct2: "[|P 0; P (Suc 0); !!k. P k ==> P (Suc (Suc k))|] ==> P n" apply (rule nat_less_induct) @@ -571,7 +572,7 @@ lemma min_Suc1: "min (Suc n) m = (case m of 0 => 0 | Suc m' => Suc(min n m'))" - by (simp split: nat.split) + by (simp split: nat.split) lemma min_Suc2: "min m (Suc n) = (case m of 0 => 0 | Suc m' => Suc(min m' n))" @@ -588,7 +589,7 @@ lemma max_Suc1: "max (Suc n) m = (case m of 0 => Suc n | Suc m' => Suc(max n m'))" - by (simp split: nat.split) + by (simp split: nat.split) lemma max_Suc2: "max m (Suc n) = (case m of 0 => Suc n | Suc m' => Suc(max m' n))" @@ -657,11 +658,11 @@ text {* Reasoning about @{text "m + 0 = 0"}, etc. *} -lemma add_is_0 [iff]: "!!m::nat. (m + n = 0) = (m = 0 & n = 0)" - by (case_tac m) simp_all +lemma add_is_0 [iff]: fixes m :: nat shows "(m + n = 0) = (m = 0 & n = 0)" + by (cases m) simp_all lemma add_is_1: "(m+n= Suc 0) = (m= Suc 0 & n=0 | m=0 & n= Suc 0)" - by (case_tac m) simp_all + by (cases m) simp_all lemma one_is_add: "(Suc 0 = m + n) = (m = Suc 0 & n = 0 | m = 0 & n = Suc 0)" by (rule trans, rule eq_commute, rule add_is_1) @@ -674,13 +675,12 @@ apply (simp add: nat_add_assoc del: add_0_right) done - lemma inj_on_add_nat[simp]: "inj_on (%n::nat. n+k) N" -apply(induct k) - apply simp -apply(drule comp_inj_on[OF _ inj_Suc]) -apply (simp add:o_def) -done + apply (induct k) + apply simp + apply(drule comp_inj_on[OF _ inj_Suc]) + apply (simp add:o_def) + done subsection {* Multiplication *} @@ -726,7 +726,8 @@ lemma mult_is_0 [simp]: "((m::nat) * n = 0) = (m=0 | n=0)" apply (induct m) - apply (induct_tac [2] n, simp_all) + apply (induct_tac [2] n) + apply simp_all done @@ -746,14 +747,14 @@ lemma less_imp_Suc_add: "m < n ==> (\k. n = Suc (m + k))" apply (induct n) apply (simp_all add: order_le_less) - apply (blast elim!: less_SucE + apply (blast elim!: less_SucE intro!: add_0_right [symmetric] add_Suc_right [symmetric]) done text {* strict, in 1st argument; proof is by induction on @{text "k > 0"} *} lemma mult_less_mono2: "(i::nat) < j ==> 0 < k ==> k * i < k * j" apply (erule_tac m1 = 0 in less_imp_Suc_add [THEN exE], simp) - apply (induct_tac x) + apply (induct_tac x) apply (simp_all add: add_less_mono) done @@ -777,22 +778,22 @@ subsection {* Additional theorems about "less than" *} text{*An induction rule for estabilishing binary relations*} -lemma less_Suc_induct: +lemma less_Suc_induct: assumes less: "i < j" and step: "!!i. P i (Suc i)" and trans: "!!i j k. P i j ==> P j k ==> P i k" shows "P i j" proof - - from less obtain k where j: "j = Suc(i+k)" by (auto dest: less_imp_Suc_add) - have "P i (Suc(i+k))" + from less obtain k where j: "j = Suc(i+k)" by (auto dest: less_imp_Suc_add) + have "P i (Suc (i + k))" proof (induct k) - case 0 - show ?case by (simp add: step) + case 0 + show ?case by (simp add: step) next case (Suc k) - thus ?case by (auto intro: prems) + thus ?case by (auto intro: assms) qed - thus "P i j" by (simp add: j) + thus "P i j" by (simp add: j) qed @@ -800,7 +801,9 @@ monotonicity to @{text "\"} monotonicity *} lemma less_mono_imp_le_mono: assumes lt_mono: "!!i j::nat. i < j ==> f i < f j" - and le: "i \ j" shows "f i \ ((f j)::nat)" using le + and le: "i \ j" + shows "f i \ ((f j)::nat)" + using le apply (simp add: order_le_less) apply (blast intro!: lt_mono) done @@ -814,7 +817,7 @@ by (rule add_mono) lemma le_add2: "n \ ((m + n)::nat)" - by (insert add_right_mono [of 0 m n], simp) + by (insert add_right_mono [of 0 m n], simp) lemma le_add1: "n \ ((n + m)::nat)" by (simp add: add_commute, rule le_add2) @@ -841,7 +844,7 @@ by (rule less_le_trans, assumption, rule le_add2) lemma add_lessD1: "i + j < (k::nat) ==> i < k" - apply (rule le_less_trans [of _ "i+j"]) + apply (rule le_less_trans [of _ "i+j"]) apply (simp_all add: le_add1) done @@ -854,7 +857,7 @@ by (simp add: add_commute not_add_less1) lemma add_leD1: "m + k \ n ==> m \ (n::nat)" - apply (rule order_trans [of _ "m+k"]) + apply (rule order_trans [of _ "m+k"]) apply (simp_all add: le_add1) done @@ -913,9 +916,7 @@ by (simp add: diff_diff_left) lemma diff_Suc_less [simp]: "0 n - Suc i < n" - apply (case_tac "n", safe) - apply (simp add: le_simps) - done + by (cases n) (auto simp add: le_simps) text {* This and the next few suggested by Florian Kammueller *} lemma diff_commute: "(i::nat) - j - k = i - k - j" @@ -934,9 +935,7 @@ by (simp add: diff_add_assoc) lemma le_imp_diff_is_add: "i \ (j::nat) ==> (j - i = k) = (j = k + i)" - apply safe - apply (simp_all add: diff_add_inverse2) - done + by (auto simp add: diff_add_inverse2) lemma diff_is_0_eq [simp]: "((m::nat) - n = 0) = (m \ n)" by (induct m n rule: diff_induct) simp_all @@ -947,10 +946,13 @@ lemma zero_less_diff [simp]: "(0 < n - (m::nat)) = (m < n)" by (induct m n rule: diff_induct) simp_all -lemma less_imp_add_positive: "i < j ==> \k::nat. 0 < k & i + k = j" - apply (rule_tac x = "j - i" in exI) - apply (simp (no_asm_simp) add: add_diff_inverse less_not_sym) - done +lemma less_imp_add_positive: + assumes "i < j" + shows "\k::nat. 0 < k & i + k = j" +proof + from assms show "0 < j - i & i + (j - i) = j" + by (simp add: add_diff_inverse less_not_sym) +qed lemma zero_induct_lemma: "P k ==> (!!n. P (Suc n) ==> P n) ==> P (k - i)" apply (induct k i rule: diff_induct) @@ -989,33 +991,39 @@ subsection {* Monotonicity of Multiplication *} lemma mult_le_mono1: "i \ (j::nat) ==> i * k \ j * k" - by (simp add: mult_right_mono) + by (simp add: mult_right_mono) lemma mult_le_mono2: "i \ (j::nat) ==> k * i \ k * j" - by (simp add: mult_left_mono) + by (simp add: mult_left_mono) text {* @{text "\"} monotonicity, BOTH arguments *} lemma mult_le_mono: "i \ (j::nat) ==> k \ l ==> i * k \ j * l" - by (simp add: mult_mono) + by (simp add: mult_mono) lemma mult_less_mono1: "(i::nat) < j ==> 0 < k ==> i * k < j * k" - by (simp add: mult_strict_right_mono) + by (simp add: mult_strict_right_mono) text{*Differs from the standard @{text zero_less_mult_iff} in that there are no negative numbers.*} lemma nat_0_less_mult_iff [simp]: "(0 < (m::nat) * n) = (0 < m & 0 < n)" apply (induct m) - apply (case_tac [2] n, simp_all) + apply simp + apply (case_tac n) + apply simp_all done lemma one_le_mult_iff [simp]: "(Suc 0 \ m * n) = (1 \ m & 1 \ n)" apply (induct m) - apply (case_tac [2] n, simp_all) + apply simp + apply (case_tac n) + apply simp_all done lemma mult_eq_1_iff [simp]: "(m * n = Suc 0) = (m = 1 & n = 1)" - apply (induct m, simp) - apply (induct n, simp, fastsimp) + apply (induct m) + apply simp + apply (induct n) + apply auto done lemma one_eq_mult_iff [simp]: "(Suc 0 = m * n) = (m = 1 & n = 1)" @@ -1034,10 +1042,10 @@ by (simp add: mult_commute [of k]) lemma mult_le_cancel1 [simp]: "(k * (m::nat) \ k * n) = (0 < k --> m \ n)" -by (simp add: linorder_not_less [symmetric], auto) + by (simp add: linorder_not_less [symmetric], auto) lemma mult_le_cancel2 [simp]: "((m::nat) * k \ n * k) = (0 < k --> m \ n)" -by (simp add: linorder_not_less [symmetric], auto) + by (simp add: linorder_not_less [symmetric], auto) lemma mult_cancel2 [simp]: "(m * k = n * k) = (m = n | (k = (0::nat)))" apply (cut_tac less_linear, safe, auto) @@ -1068,24 +1076,23 @@ subsection {* Code generator setup *} -lemma one_is_Suc_zero [code inline]: - "1 = Suc 0" +lemma one_is_Suc_zero [code inline]: "1 = Suc 0" by simp instance nat :: eq .. lemma [code func]: - "(0\nat) = 0 \ True" - "Suc n = Suc m \ n = m" - "Suc n = 0 \ False" - "0 = Suc m \ False" + "(0\nat) = 0 \ True" + "Suc n = Suc m \ n = m" + "Suc n = 0 \ False" + "0 = Suc m \ False" by auto lemma [code func]: - "(0\nat) \ m \ True" - "Suc (n\nat) \ m \ n < m" - "(n\nat) < 0 \ False" - "(n\nat) < Suc m \ n \ m" + "(0\nat) \ m \ True" + "Suc (n\nat) \ m \ n < m" + "(n\nat) < 0 \ False" + "(n\nat) < Suc m \ n \ m" using Suc_le_eq less_Suc_eq_le by simp_all @@ -1100,14 +1107,12 @@ by (auto simp: le_eq_less_or_eq dest: less_imp_Suc_add) lemma pred_nat_trancl_eq_le: "((m, n) : pred_nat^*) = (m \ n)" -by (simp add: less_eq reflcl_trancl [symmetric] - del: reflcl_trancl, arith) + by (simp add: less_eq reflcl_trancl [symmetric] del: reflcl_trancl, arith) lemma nat_diff_split: - "P(a - b::nat) = ((a P 0) & (ALL d. a = b + d --> P d))" + "P(a - b::nat) = ((a P 0) & (ALL d. a = b + d --> P d))" -- {* elimination of @{text -} on @{text nat} *} - by (cases "a m * (m::nat)" by (induct m) auto @@ -1128,81 +1132,81 @@ text{*Subtraction laws, mostly by Clemens Ballarin*} lemma diff_less_mono: "[| a < (b::nat); c \ a |] ==> a-c < b-c" -by arith + by arith lemma less_diff_conv: "(i < j-k) = (i+k < (j::nat))" -by arith + by arith lemma le_diff_conv: "(j-k \ (i::nat)) = (j \ i+k)" -by arith + by arith lemma le_diff_conv2: "k \ j ==> (i \ j-k) = (i+k \ (j::nat))" -by arith + by arith lemma diff_diff_cancel [simp]: "i \ (n::nat) ==> n - (n - i) = i" -by arith + by arith lemma le_add_diff: "k \ (n::nat) ==> m \ n + m - k" -by arith + by arith (*Replaces the previous diff_less and le_diff_less, which had the stronger second premise n\m*) lemma diff_less[simp]: "!!m::nat. [| 0 m - n < m" -by arith + by arith (** Simplification of relational expressions involving subtraction **) lemma diff_diff_eq: "[| k \ m; k \ (n::nat) |] ==> ((m-k) - (n-k)) = (m-n)" -by (simp split add: nat_diff_split) + by (simp split add: nat_diff_split) lemma eq_diff_iff: "[| k \ m; k \ (n::nat) |] ==> (m-k = n-k) = (m=n)" -by (auto split add: nat_diff_split) + by (auto split add: nat_diff_split) lemma less_diff_iff: "[| k \ m; k \ (n::nat) |] ==> (m-k < n-k) = (m m; k \ (n::nat) |] ==> (m-k \ n-k) = (m\n)" -by (auto split add: nat_diff_split) + by (auto split add: nat_diff_split) text{*(Anti)Monotonicity of subtraction -- by Stephan Merz*} (* Monotonicity of subtraction in first argument *) lemma diff_le_mono: "m \ (n::nat) ==> (m-l) \ (n-l)" -by (simp split add: nat_diff_split) + by (simp split add: nat_diff_split) lemma diff_le_mono2: "m \ (n::nat) ==> (l-n) \ (l-m)" -by (simp split add: nat_diff_split) + by (simp split add: nat_diff_split) lemma diff_less_mono2: "[| m < (n::nat); m (l-n) < (l-m)" -by (simp split add: nat_diff_split) + by (simp split add: nat_diff_split) lemma diffs0_imp_equal: "!!m::nat. [| m-n = 0; n-m = 0 |] ==> m=n" -by (simp split add: nat_diff_split) + by (simp split add: nat_diff_split) text{*Lemmas for ex/Factorization*} lemma one_less_mult: "[| Suc 0 < n; Suc 0 < m |] ==> Suc 0 < m*n" -by (case_tac "m", auto) + by (cases m) auto lemma n_less_m_mult_n: "[| Suc 0 < n; Suc 0 < m |] ==> n nj --> i - (j - k) = i + (k::nat) - j" -by arith + by arith lemma diff_Suc_diff_eq1 [simp]: "k \ j ==> m - Suc (j - k) = m + k - Suc j" -by arith + by arith lemma diff_Suc_diff_eq2 [simp]: "k \ j ==> Suc (j - k) - m = Suc j - (k + m)" -by arith + by arith (*The others are i - j - k = i - (j + k), @@ -1245,8 +1249,9 @@ val diff_Suc_diff_eq2 = thm "diff_Suc_diff_eq2"; *} -subsection{*Embedding of the Naturals into any @{text -semiring_1_cancel}: @{term of_nat}*} + +subsection{*Embedding of the Naturals into any + @{text semiring_1_cancel}: @{term of_nat}*} consts of_nat :: "nat => 'a::semiring_1_cancel" @@ -1255,74 +1260,72 @@ of_nat_Suc: "of_nat (Suc m) = of_nat m + 1" lemma of_nat_1 [simp]: "of_nat 1 = 1" -by simp + by simp lemma of_nat_add [simp]: "of_nat (m+n) = of_nat m + of_nat n" -apply (induct m) -apply (simp_all add: add_ac) -done + by (induct m) (simp_all add: add_ac) lemma of_nat_mult [simp]: "of_nat (m*n) = of_nat m * of_nat n" -apply (induct m) -apply (simp_all add: add_ac left_distrib) -done + by (induct m) (simp_all add: add_ac left_distrib) lemma zero_le_imp_of_nat: "0 \ (of_nat m::'a::ordered_semidom)" -apply (induct m, simp_all) -apply (erule order_trans) -apply (rule less_add_one [THEN order_less_imp_le]) -done + apply (induct m, simp_all) + apply (erule order_trans) + apply (rule less_add_one [THEN order_less_imp_le]) + done lemma less_imp_of_nat_less: - "m < n ==> of_nat m < (of_nat n::'a::ordered_semidom)" -apply (induct m n rule: diff_induct, simp_all) -apply (insert add_le_less_mono [OF zero_le_imp_of_nat zero_less_one], force) -done + "m < n ==> of_nat m < (of_nat n::'a::ordered_semidom)" + apply (induct m n rule: diff_induct, simp_all) + apply (insert add_le_less_mono [OF zero_le_imp_of_nat zero_less_one], force) + done lemma of_nat_less_imp_less: - "of_nat m < (of_nat n::'a::ordered_semidom) ==> m < n" -apply (induct m n rule: diff_induct, simp_all) -apply (insert zero_le_imp_of_nat) -apply (force simp add: linorder_not_less [symmetric]) -done + "of_nat m < (of_nat n::'a::ordered_semidom) ==> m < n" + apply (induct m n rule: diff_induct, simp_all) + apply (insert zero_le_imp_of_nat) + apply (force simp add: linorder_not_less [symmetric]) + done lemma of_nat_less_iff [simp]: - "(of_nat m < (of_nat n::'a::ordered_semidom)) = (m of_nat m < (0::'a::ordered_semidom)" + by (rule of_nat_less_iff [of _ 0, simplified]) lemma of_nat_le_iff [simp]: - "(of_nat m \ (of_nat n::'a::ordered_semidom)) = (m \ n)" -by (simp add: linorder_not_less [symmetric]) + "(of_nat m \ (of_nat n::'a::ordered_semidom)) = (m \ n)" + by (simp add: linorder_not_less [symmetric]) text{*Special cases where either operand is zero*} -lemmas of_nat_0_le_iff = of_nat_le_iff [of 0, simplified] -lemmas of_nat_le_0_iff = of_nat_le_iff [of _ 0, simplified] -declare of_nat_0_le_iff [simp] -declare of_nat_le_0_iff [simp] +lemma of_nat_0_le_iff [simp]: "(0::'a::ordered_semidom) \ of_nat n" + by (rule of_nat_le_iff [of 0, simplified]) +lemma of_nat_le_0_iff [simp]: "(of_nat m \ (0::'a::ordered_semidom)) = (m = 0)" + by (rule of_nat_le_iff [of _ 0, simplified]) text{*The ordering on the @{text semiring_1_cancel} is necessary to exclude the possibility of a finite field, which indeed wraps back to zero.*} lemma of_nat_eq_iff [simp]: - "(of_nat m = (of_nat n::'a::ordered_semidom)) = (m = n)" -by (simp add: order_eq_iff) + "(of_nat m = (of_nat n::'a::ordered_semidom)) = (m = n)" + by (simp add: order_eq_iff) text{*Special cases where either operand is zero*} -lemmas of_nat_0_eq_iff = of_nat_eq_iff [of 0, simplified] -lemmas of_nat_eq_0_iff = of_nat_eq_iff [of _ 0, simplified] -declare of_nat_0_eq_iff [simp] -declare of_nat_eq_0_iff [simp] +lemma of_nat_0_eq_iff [simp]: "((0::'a::ordered_semidom) = of_nat n) = (0 = n)" + by (rule of_nat_eq_iff [of 0, simplified]) +lemma of_nat_eq_0_iff [simp]: "(of_nat m = (0::'a::ordered_semidom)) = (m = 0)" + by (rule of_nat_eq_iff [of _ 0, simplified]) lemma of_nat_diff [simp]: - "n \ m ==> of_nat (m - n) = of_nat m - (of_nat n :: 'a::ring_1)" -by (simp del: of_nat_add - add: compare_rls of_nat_add [symmetric] split add: nat_diff_split) + "n \ m ==> of_nat (m - n) = of_nat m - (of_nat n :: 'a::ring_1)" + by (simp del: of_nat_add + add: compare_rls of_nat_add [symmetric] split add: nat_diff_split) instance nat :: distrib_lattice "inf \ min" @@ -1332,7 +1335,7 @@ subsection {* Size function *} -lemma nat_size[simp]: "size (n::nat) = n" +lemma nat_size [simp]: "size (n::nat) = n" by (induct n) simp_all end