SSL IntDiv.thy
Interaktion und PortierbarkeitIsabelle
(* Title: ZF/IntDiv.thy Author: Lawrence C Paulson, Cambridge University Computer Laboratory Copyright 1999 University of Cambridge
Here is the division algorithm in ML:
fun posDivAlg (a,b) = if a<b then (0,a) else let val (q,r) = posDivAlg(a, 2*b) in if 0<=r-b then (2*q+1, r-b) else (2*q, r) end
fun negDivAlg (a,b) = if 0<=a+b then (\<not>1,a+b) else let val (q,r) = negDivAlg(a, 2*b) in if 0<=r-b then (2*q+1, r-b) else (2*q, r) end;
fun negateSnd (q,r:int) = (q,\<not>r);
fun divAlg (a,b) = if 0<=a then if b>0 then posDivAlg (a,b) else if a=0 then (0,0) else negateSnd (negDivAlg (\<not>a,\<not>b)) else if 0<b then negDivAlg (a,b) else negateSnd (posDivAlg (\<not>a,\<not>b));
*)
section\<open>The Division Operators Div and Mod\<close>
theory IntDiv imports Bin OrderArith begin
definition
quorem :: "[i,i] \ o" where "quorem \ \\a,b\ \q,r\.
a = b$*q $+ r \<and>
(#0$<b \<and> #0$\<le>r \<and> r$<b | \<not>(#0$<b) \<and> b$<r \<and> r $\<le> #0)"
definition
adjust :: "[i,i] \ i" where "adjust(b) \ \\q,r\. if #0 $\ r$-b then <#2$*q $+ #1,r$-b>
else <#2$*q,r>"
(** the division algorithm **)
definition
posDivAlg :: "i \ i" where (*for the case a>=0, b>0*) (*recdef posDivAlg "inv_image less_than (\<lambda>\<langle>a,b\<rangle>. nat_of(a $- b $+ #1))"*) "posDivAlg(ab) \
wfrec(measure(int*int, \<lambda>\<langle>a,b\<rangle>. nat_of (a $- b $+ #1)),
ab, \<lambda>\<langle>a,b\<rangle> f. if (a$<b | b$\<le>#0) then <#0,a>
else adjust(b, f ` <a,#2$*b>))"
(*for the case a\<langle>0, b\<rangle>0*) definition
negDivAlg :: "i \ i" where (*recdef negDivAlg "inv_image less_than (\<lambda>\<langle>a,b\<rangle>. nat_of(- a $- b))"*) "negDivAlg(ab) \
wfrec(measure(int*int, \<lambda>\<langle>a,b\<rangle>. nat_of ($- a $- b)),
ab, \<lambda>\<langle>a,b\<rangle> f. if (#0 $\<le> a$+b | b$\<le>#0) then <#-1,a$+b>
else adjust(b, f ` <a,#2$*b>))"
(*for the general case @{term"b\<noteq>0"}*)
definition
negateSnd :: "i \ i" where "negateSnd \ \\q,r\. "
(*The full division algorithm considers all possible signs for a, b
including the special case a=0, b<0, because negDivAlg requires a<0*) definition
divAlg :: "i \ i" where "divAlg \ \<lambda>\<langle>a,b\<rangle>. if #0 $\<le> a then if #0 $\<le> b then posDivAlg (\<langle>a,b\<rangle>)
else if a=#0 then <#0,#0>
else negateSnd (negDivAlg (<$-a,$-b>))
else if #0$<b then negDivAlg (\<langle>a,b\<rangle>)
else negateSnd (posDivAlg (<$-a,$-b>))"
definition
zdiv :: "[i,i]\i" (infixl \zdiv\ 70) where "a zdiv b \ fst (divAlg ())"
definition
zmod :: "[i,i]\i" (infixl \zmod\ 70) where "a zmod b \ snd (divAlg ())"
(** Some basic laws by Sidi Ehmety (need linear arithmetic!) **)
lemma zspos_add_zspos_imp_zspos: "\#0 $< x; #0 $< y\ \ #0 $< x $+ y" apply (rule_tac y = "y"in zless_trans) apply (rule_tac [2] zdiff_zless_iff [THEN iffD1]) apply auto done
lemma zpos_add_zpos_imp_zpos: "\#0 $\ x; #0 $\ y\ \ #0 $\ x $+ y" apply (rule_tac y = "y"in zle_trans) apply (rule_tac [2] zdiff_zle_iff [THEN iffD1]) apply auto done
lemma zneg_add_zneg_imp_zneg: "\x $< #0; y $< #0\ \ x $+ y $< #0" apply (rule_tac y = "y"in zless_trans) apply (rule zless_zdiff_iff [THEN iffD1]) apply auto done
(* this theorem is used below *) lemma zneg_or_0_add_zneg_or_0_imp_zneg_or_0: "\x $\ #0; y $\ #0\ \ x $+ y $\ #0" apply (rule_tac y = "y"in zle_trans) apply (rule zle_zdiff_iff [THEN iffD1]) apply auto done
lemma posDivAlg_induct_lemma [rule_format]: assumes prem: "\a b. \a \ int; b \ int; \<not> (a $< b | b $\<le> #0) \<longrightarrow> P(<a, #2 $* b>)\<rbrakk> \<Longrightarrow> P(\<langle>a,b\<rangle>)" shows"\u,v\ \ int*int \ P(\u,v\)" using wf_measure [where A = "int*int"and f = "\\a,b\.nat_of (a $- b $+ #1)"] proof (induct "\u,v\" arbitrary: u v rule: wf_induct) case (step x) hence uv: "u \ int" "v \ int" by auto thus ?case apply (rule prem) apply (rule impI) apply (rule step) apply (auto simp add: step uv not_zle_iff_zless posDivAlg_termination) done qed
lemma posDivAlg_induct [consumes 2]: assumes u_int: "u \ int" and v_int: "v \ int" and ih: "\a b. \a \ int; b \ int; \<not> (a $< b | b $\<le> #0) \<longrightarrow> P(a, #2 $* b)\<rbrakk> \<Longrightarrow> P(a,b)" shows"P(u,v)" apply (subgoal_tac "(\\x,y\. P (x,y)) (\u,v\)") apply simp apply (rule posDivAlg_induct_lemma) apply (simp (no_asm_use)) apply (rule ih) apply (auto simp add: u_int v_int) done
(*FIXME: use intify in integ_of so that we always have @{term"integ_of w \<in> int"}.
then this rewrite can work for all constants\<And>*) lemma intify_eq_0_iff_zle: "intify(m) = #0 \ (m $\ #0 \ #0 $\ m)" by (simp add: int_eq_iff_zle)
subsection\<open>Some convenient biconditionals for products of signs\<close>
lemma zmult_pos: "\#0 $< i; #0 $< j\ \ #0 $< i $* j" by (drule zmult_zless_mono1, auto)
lemma zmult_neg: "\i $< #0; j $< #0\ \ #0 $< i $* j" by (drule zmult_zless_mono1_neg, auto)
lemma zmult_pos_neg: "\#0 $< i; j $< #0\ \ i $* j $< #0" by (drule zmult_zless_mono1_neg, auto)
lemma int_0_less_mult_iff: "(#0 $< x $* y) \ (#0 $< x \ #0 $< y | x $< #0 \ y $< #0)" apply (cut_tac x = "intify (x)"and y = "intify (y)"in int_0_less_lemma) apply auto done
lemma int_0_le_lemma: "\x \ int; y \ int\ \<Longrightarrow> (#0 $\<le> x $* y) \<longleftrightarrow> (#0 $\<le> x \<and> #0 $\<le> y | x $\<le> #0 \<and> y $\<le> #0)" by (auto simp add: zle_def not_zless_iff_zle int_0_less_mult_iff)
lemma int_0_le_mult_iff: "(#0 $\ x $* y) \ ((#0 $\ x \ #0 $\ y) | (x $\ #0 \ y $\ #0))" apply (cut_tac x = "intify (x)"and y = "intify (y)"in int_0_le_lemma) apply auto done
lemma zmult_less_0_iff: "(x $* y $< #0) \ (#0 $< x \ y $< #0 | x $< #0 \ #0 $< y)" apply (auto simp add: int_0_le_mult_iff not_zle_iff_zless [THEN iff_sym]) apply (auto dest: zless_not_sym simp add: not_zle_iff_zless) done
lemma zmult_le_0_iff: "(x $* y $\ #0) \ (#0 $\ x \ y $\ #0 | x $\ #0 \ #0 $\ y)" by (auto dest: zless_not_sym
simp add: int_0_less_mult_iff not_zless_iff_zle [THEN iff_sym])
(** Arbitrary definitions for division by zero. Useful to simplify
certain equations **)
lemma DIVISION_BY_ZERO_ZDIV: "a zdiv #0 = #0" by (simp add: zdiv_def divAlg_def posDivAlg_zero_divisor)
lemma DIVISION_BY_ZERO_ZMOD: "a zmod #0 = intify(a)" by (simp add: zmod_def divAlg_def posDivAlg_zero_divisor)
(** Basic laws about division and remainder **)
lemma raw_zmod_zdiv_equality: "\a \ int; b \ int\ \ a = b $* (a zdiv b) $+ (a zmod b)" apply (case_tac "b = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (cut_tac a = "a"and b = "b"in divAlg_correct) apply (auto simp add: quorem_def zdiv_def zmod_def split_def) done
lemma zmod_zdiv_equality: "intify(a) = b $* (a zdiv b) $+ (a zmod b)" apply (rule trans) apply (rule_tac b = "intify (b)"in raw_zmod_zdiv_equality) apply auto done
lemma pos_mod: "#0 $< b \ #0 $\ a zmod b \ a zmod b $< b" apply (cut_tac a = "intify (a)"and b = "intify (b)"in divAlg_correct) apply (auto simp add: intify_eq_0_iff_zle quorem_def zmod_def split_def) apply (blast dest: zle_zless_trans)+ done
(** proving general properties of zdiv and zmod **)
lemma quorem_div_mod: "\b \ #0; a \ int; b \ int\ \<Longrightarrow> quorem (\<langle>a,b\<rangle>, <a zdiv b, a zmod b>)" apply (cut_tac a = "a"and b = "b"in zmod_zdiv_equality) apply (auto simp add: quorem_def neq_iff_zless pos_mod_sign pos_mod_bound
neg_mod_sign neg_mod_bound) done
(*Surely quorem(\<langle>a,b\<rangle>,\<langle>q,r\<rangle>) implies @{term"a \<in> int"}, but it doesn't matter*) lemma quorem_div: "\quorem(\a,b\,\q,r\); b \ #0; a \ int; b \ int; q \ int\ \<Longrightarrow> a zdiv b = q" by (blast intro: quorem_div_mod [THEN unique_quotient])
lemma quorem_mod: "\quorem(\a,b\,\q,r\); b \ #0; a \ int; b \ int; q \ int; r \ int\ \<Longrightarrow> a zmod b = r" by (blast intro: quorem_div_mod [THEN unique_remainder])
lemma zdiv_pos_pos_trivial_raw: "\a \ int; b \ int; #0 $\ a; a $< b\ \ a zdiv b = #0" apply (rule quorem_div) apply (auto simp add: quorem_def) (*linear arithmetic*) apply (blast dest: zle_zless_trans)+ done
lemma zdiv_pos_pos_trivial: "\#0 $\ a; a $< b\ \ a zdiv b = #0" apply (cut_tac a = "intify (a)"and b = "intify (b)" in zdiv_pos_pos_trivial_raw) apply auto done
lemma zdiv_neg_neg_trivial_raw: "\a \ int; b \ int; a $\ #0; b $< a\ \ a zdiv b = #0" apply (rule_tac r = "a"in quorem_div) apply (auto simp add: quorem_def) (*linear arithmetic*) apply (blast dest: zle_zless_trans zless_trans)+ done
lemma zdiv_neg_neg_trivial: "\a $\ #0; b $< a\ \ a zdiv b = #0" apply (cut_tac a = "intify (a)"and b = "intify (b)" in zdiv_neg_neg_trivial_raw) apply auto done
lemma zdiv_pos_neg_trivial_raw: "\a \ int; b \ int; #0 $< a; a$+b $\ #0\ \ a zdiv b = #-1" apply (rule_tac r = "a $+ b"in quorem_div) apply (auto simp add: quorem_def) (*linear arithmetic*) apply (blast dest: zadd_le_0_lemma zle_zless_trans)+ done
lemma zdiv_pos_neg_trivial: "\#0 $< a; a$+b $\ #0\ \ a zdiv b = #-1" apply (cut_tac a = "intify (a)"and b = "intify (b)" in zdiv_pos_neg_trivial_raw) apply auto done
(*There is no zdiv_neg_pos_trivial because #0 zdiv b = #0 would supersede it*)
lemma zmod_pos_pos_trivial_raw: "\a \ int; b \ int; #0 $\ a; a $< b\ \ a zmod b = a" apply (rule_tac q = "#0"in quorem_mod) apply (auto simp add: quorem_def) (*linear arithmetic*) apply (blast dest: zle_zless_trans)+ done
lemma zmod_pos_pos_trivial: "\#0 $\ a; a $< b\ \ a zmod b = intify(a)" apply (cut_tac a = "intify (a)"and b = "intify (b)" in zmod_pos_pos_trivial_raw) apply auto done
lemma zmod_neg_neg_trivial_raw: "\a \ int; b \ int; a $\ #0; b $< a\ \ a zmod b = a" apply (rule_tac q = "#0"in quorem_mod) apply (auto simp add: quorem_def) (*linear arithmetic*) apply (blast dest: zle_zless_trans zless_trans)+ done
lemma zmod_neg_neg_trivial: "\a $\ #0; b $< a\ \ a zmod b = intify(a)" apply (cut_tac a = "intify (a)"and b = "intify (b)" in zmod_neg_neg_trivial_raw) apply auto done
lemma zmod_pos_neg_trivial: "\#0 $< a; a$+b $\ #0\ \ a zmod b = a$+b" apply (cut_tac a = "intify (a)"and b = "intify (b)" in zmod_pos_neg_trivial_raw) apply auto done
(*There is no zmod_neg_pos_trivial...*)
(*Simpler laws such as -a zdiv b = -(a zdiv b) FAIL*)
lemma zdiv_zminus_zminus_raw: "\a \ int; b \ int\ \ ($-a) zdiv ($-b) = a zdiv b" apply (case_tac "b = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (subst quorem_div_mod [THEN quorem_neg, simplified, THEN quorem_div]) apply auto done
lemma zdiv_zminus_zminus [simp]: "($-a) zdiv ($-b) = a zdiv b" apply (cut_tac a = "intify (a)"and b = "intify (b)"in zdiv_zminus_zminus_raw) apply auto done
(*Simpler laws such as -a zmod b = -(a zmod b) FAIL*) lemma zmod_zminus_zminus_raw: "\a \ int; b \ int\ \ ($-a) zmod ($-b) = $- (a zmod b)" apply (case_tac "b = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (subst quorem_div_mod [THEN quorem_neg, simplified, THEN quorem_mod]) apply auto done
lemma zmod_zminus_zminus [simp]: "($-a) zmod ($-b) = $- (a zmod b)" apply (cut_tac a = "intify (a)"and b = "intify (b)"in zmod_zminus_zminus_raw) apply auto done
subsection\<open>division of a number by itself\<close>
lemma self_quotient_aux1: "\#0 $< a; a = r $+ a$*q; r $< a\ \ #1 $\ q" apply (subgoal_tac "#0 $< a$*q") apply (cut_tac w = "#0"and z = "q"in add1_zle_iff) apply (simp add: int_0_less_mult_iff) apply (blast dest: zless_trans) (*linear arithmetic...*) apply (drule_tac t = "\x. x $- r" in subst_context) apply (drule sym) apply (simp add: zcompare_rls) done
lemma self_quotient_aux2: "\#0 $< a; a = r $+ a$*q; #0 $\ r\ \ q $\ #1" apply (subgoal_tac "#0 $\ a$* (#1$-q)") apply (simp add: int_0_le_mult_iff zcompare_rls) apply (blast dest: zle_zless_trans) apply (simp add: zdiff_zmult_distrib2) apply (drule_tac t = "\x. x $- a $* q" in subst_context) apply (simp add: zcompare_rls) done
lemma self_remainder: "\quorem(\a,a\,\q,r\); a \ int; q \ int; r \ int; a \ #0\ \ r = #0" apply (frule self_quotient) apply (auto simp add: quorem_def) done
lemma zdiv_self_raw: "\a \ #0; a \ int\ \ a zdiv a = #1" apply (blast intro: quorem_div_mod [THEN self_quotient]) done
lemma zdiv_self [simp]: "intify(a) \ #0 \ a zdiv a = #1" apply (drule zdiv_self_raw) apply auto done
(*Here we have 0 zmod 0 = 0, also assumed by Knuth (who puts m zmod 0 = 0) *) lemma zmod_self_raw: "a \ int \ a zmod a = #0" apply (case_tac "a = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (blast intro: quorem_div_mod [THEN self_remainder]) done
lemma zmod_self [simp]: "a zmod a = #0" apply (cut_tac a = "intify (a)"in zmod_self_raw) apply auto done
subsection\<open>Computation of division and remainder\<close>
lemma zdiv_zero [simp]: "#0 zdiv b = #0" by (simp add: zdiv_def divAlg_def)
lemma zdiv_eq_minus1: "#0 $< b \ #-1 zdiv b = #-1" by (simp (no_asm_simp) add: zdiv_def divAlg_def)
lemma zmod_zero [simp]: "#0 zmod b = #0" by (simp add: zmod_def divAlg_def)
lemma zdiv_minus1: "#0 $< b \ #-1 zdiv b = #-1" by (simp add: zdiv_def divAlg_def)
lemma zmod_minus1: "#0 $< b \ #-1 zmod b = b $- #1" by (simp add: zmod_def divAlg_def)
lemma zdiv_pos_neg: "\#0 $< a; b $< #0\ \<Longrightarrow> a zdiv b = fst (negateSnd(negDivAlg (<$-a, $-b>)))" apply (simp (no_asm_simp) add: zdiv_def divAlg_def intify_eq_0_iff_zle) apply auto apply (blast dest: zle_zless_trans)+ apply (blast dest: zless_trans) apply (blast intro: zless_imp_zle) done
lemma zmod_pos_neg: "\#0 $< a; b $< #0\ \<Longrightarrow> a zmod b = snd (negateSnd(negDivAlg (<$-a, $-b>)))" apply (simp (no_asm_simp) add: zmod_def divAlg_def intify_eq_0_iff_zle) apply auto apply (blast dest: zle_zless_trans)+ apply (blast dest: zless_trans) apply (blast intro: zless_imp_zle) done
(** a negative, b negative **)
lemma zdiv_neg_neg: "\a $< #0; b $\ #0\ \<Longrightarrow> a zdiv b = fst (negateSnd(posDivAlg(<$-a, $-b>)))" apply (simp (no_asm_simp) add: zdiv_def divAlg_def) apply auto apply (blast dest!: zle_zless_trans)+ done
lemma zmod_neg_neg: "\a $< #0; b $\ #0\ \<Longrightarrow> a zmod b = snd (negateSnd(posDivAlg(<$-a, $-b>)))" apply (simp (no_asm_simp) add: zmod_def divAlg_def) apply auto apply (blast dest!: zle_zless_trans)+ done
declare zdiv_pos_pos [of "integ_of (v)""integ_of (w)", simp] for v w declare zdiv_neg_pos [of "integ_of (v)""integ_of (w)", simp] for v w declare zdiv_pos_neg [of "integ_of (v)""integ_of (w)", simp] for v w declare zdiv_neg_neg [of "integ_of (v)""integ_of (w)", simp] for v w declare zmod_pos_pos [of "integ_of (v)""integ_of (w)", simp] for v w declare zmod_neg_pos [of "integ_of (v)""integ_of (w)", simp] for v w declare zmod_pos_neg [of "integ_of (v)""integ_of (w)", simp] for v w declare zmod_neg_neg [of "integ_of (v)""integ_of (w)", simp] for v w declare posDivAlg_eqn [of concl: "integ_of (v)""integ_of (w)", simp] for v w declare negDivAlg_eqn [of concl: "integ_of (v)""integ_of (w)", simp] for v w
(** Special-case simplification **)
lemma zmod_1 [simp]: "a zmod #1 = #0" apply (cut_tac a = "a"and b = "#1"in pos_mod_sign) apply (cut_tac [2] a = "a"and b = "#1"in pos_mod_bound) apply auto (*arithmetic*) apply (drule add1_zle_iff [THEN iffD2]) apply (rule zle_anti_sym) apply auto done
lemma zdiv_1 [simp]: "a zdiv #1 = intify(a)" apply (cut_tac a = "a"and b = "#1"in zmod_zdiv_equality) apply auto done
lemma zmod_minus1_right [simp]: "a zmod #-1 = #0" apply (cut_tac a = "a"and b = "#-1"in neg_mod_sign) apply (cut_tac [2] a = "a"and b = "#-1"in neg_mod_bound) apply auto (*arithmetic*) apply (drule add1_zle_iff [THEN iffD2]) apply (rule zle_anti_sym) apply auto done
lemma zdiv_minus1_right_raw: "a \ int \ a zdiv #-1 = $-a" apply (cut_tac a = "a"and b = "#-1"in zmod_zdiv_equality) apply auto apply (rule equation_zminus [THEN iffD2]) apply auto done
lemma zdiv_minus1_right: "a zdiv #-1 = $-a" apply (cut_tac a = "intify (a)"in zdiv_minus1_right_raw) apply auto done declare zdiv_minus1_right [simp]
subsection\<open>Monotonicity in the first argument (divisor)\<close>
lemma zdiv_mono1: "\a $\ a'; #0 $< b\ \ a zdiv b $\ a' zdiv b" apply (cut_tac a = "a"and b = "b"in zmod_zdiv_equality) apply (cut_tac a = "a'"and b = "b"in zmod_zdiv_equality) apply (rule unique_quotient_lemma) apply (erule subst) apply (erule subst) apply (simp_all (no_asm_simp) add: pos_mod_sign pos_mod_bound) done
lemma zdiv_mono1_neg: "\a $\ a'; b $< #0\ \ a' zdiv b $\ a zdiv b" apply (cut_tac a = "a"and b = "b"in zmod_zdiv_equality) apply (cut_tac a = "a'"and b = "b"in zmod_zdiv_equality) apply (rule unique_quotient_lemma_neg) apply (erule subst) apply (erule subst) apply (simp_all (no_asm_simp) add: neg_mod_sign neg_mod_bound) done
subsection\<open>Monotonicity in the second argument (dividend)\<close>
lemma zdiv_mono2_raw: "\#0 $\ a; #0 $< b'; b' $\ b; a \ int\ \<Longrightarrow> a zdiv b $\<le> a zdiv b'" apply (subgoal_tac "#0 $< b") prefer 2 apply (blast dest: zless_zle_trans) apply (cut_tac a = "a"and b = "b"in zmod_zdiv_equality) apply (cut_tac a = "a"and b = "b'"in zmod_zdiv_equality) apply (rule zdiv_mono2_lemma) apply (erule subst) apply (erule subst) apply (simp_all add: pos_mod_sign pos_mod_bound) done
lemma zdiv_mono2: "\#0 $\ a; #0 $< b'; b' $\ b\ \<Longrightarrow> a zdiv b $\<le> a zdiv b'" apply (cut_tac a = "intify (a)"in zdiv_mono2_raw) apply auto done
lemma zdiv_mono2_neg_raw: "\a $< #0; #0 $< b'; b' $\ b; a \ int\ \<Longrightarrow> a zdiv b' $\<le> a zdiv b" apply (subgoal_tac "#0 $< b") prefer 2 apply (blast dest: zless_zle_trans) apply (cut_tac a = "a"and b = "b"in zmod_zdiv_equality) apply (cut_tac a = "a"and b = "b'"in zmod_zdiv_equality) apply (rule zdiv_mono2_neg_lemma) apply (erule subst) apply (erule subst) apply (simp_all add: pos_mod_sign pos_mod_bound) done
lemma zdiv_mono2_neg: "\a $< #0; #0 $< b'; b' $\ b\ \<Longrightarrow> a zdiv b' $\<le> a zdiv b" apply (cut_tac a = "intify (a)"in zdiv_mono2_neg_raw) apply auto done
subsection\<open>More algebraic laws for zdiv and zmod\<close>
(** proving (a*b) zdiv c = a $* (b zdiv c) $+ a * (b zmod c) **)
lemma zdiv_zmult1_eq_raw: "\b \ int; c \ int\ \<Longrightarrow> (a$*b) zdiv c = a$*(b zdiv c) $+ a$*(b zmod c) zdiv c" apply (case_tac "c = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (rule quorem_div_mod [THEN zmult1_lemma, THEN quorem_div]) apply auto done
lemma zdiv_zmult1_eq: "(a$*b) zdiv c = a$*(b zdiv c) $+ a$*(b zmod c) zdiv c" apply (cut_tac b = "intify (b)"and c = "intify (c)"in zdiv_zmult1_eq_raw) apply auto done
lemma zmod_zmult1_eq_raw: "\b \ int; c \ int\ \ (a$*b) zmod c = a$*(b zmod c) zmod c" apply (case_tac "c = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (rule quorem_div_mod [THEN zmult1_lemma, THEN quorem_mod]) apply auto done
lemma zmod_zmult1_eq: "(a$*b) zmod c = a$*(b zmod c) zmod c" apply (cut_tac b = "intify (b)"and c = "intify (c)"in zmod_zmult1_eq_raw) apply auto done
lemma zmod_zmult1_eq': "(a$*b) zmod c = ((a zmod c) $* b) zmod c" apply (rule trans) apply (rule_tac b = " (b $* a) zmod c"in trans) apply (rule_tac [2] zmod_zmult1_eq) apply (simp_all (no_asm) add: zmult_commute) done
(*NOT suitable for rewriting: the RHS has an instance of the LHS*) lemma zdiv_zadd1_eq_raw: "\a \ int; b \ int; c \ int\ \
(a$+b) zdiv c = a zdiv c $+ b zdiv c $+ ((a zmod c $+ b zmod c) zdiv c)" apply (case_tac "c = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (blast intro: zadd1_lemma [OF quorem_div_mod quorem_div_mod, THEN quorem_div]) done
lemma zdiv_zadd1_eq: "(a$+b) zdiv c = a zdiv c $+ b zdiv c $+ ((a zmod c $+ b zmod c) zdiv c)" apply (cut_tac a = "intify (a)"and b = "intify (b)"and c = "intify (c)" in zdiv_zadd1_eq_raw) apply auto done
lemma zmod_zadd1_eq_raw: "\a \ int; b \ int; c \ int\ \<Longrightarrow> (a$+b) zmod c = (a zmod c $+ b zmod c) zmod c" apply (case_tac "c = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (blast intro: zadd1_lemma [OF quorem_div_mod quorem_div_mod, THEN quorem_mod]) done
lemma zmod_zadd1_eq: "(a$+b) zmod c = (a zmod c $+ b zmod c) zmod c" apply (cut_tac a = "intify (a)"and b = "intify (b)"and c = "intify (c)" in zmod_zadd1_eq_raw) apply auto done
lemma zmod_div_trivial_raw: "\a \ int; b \ int\ \ (a zmod b) zdiv b = #0" apply (case_tac "b = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (auto simp add: neq_iff_zless pos_mod_sign pos_mod_bound
zdiv_pos_pos_trivial neg_mod_sign neg_mod_bound zdiv_neg_neg_trivial) done
lemma zmod_div_trivial [simp]: "(a zmod b) zdiv b = #0" apply (cut_tac a = "intify (a)"and b = "intify (b)"in zmod_div_trivial_raw) apply auto done
lemma zmod_mod_trivial_raw: "\a \ int; b \ int\ \ (a zmod b) zmod b = a zmod b" apply (case_tac "b = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (auto simp add: neq_iff_zless pos_mod_sign pos_mod_bound
zmod_pos_pos_trivial neg_mod_sign neg_mod_bound zmod_neg_neg_trivial) done
lemma zmod_mod_trivial [simp]: "(a zmod b) zmod b = a zmod b" apply (cut_tac a = "intify (a)"and b = "intify (b)"in zmod_mod_trivial_raw) apply auto done
lemma zmod_zadd_left_eq: "(a$+b) zmod c = ((a zmod c) $+ b) zmod c" apply (rule trans [symmetric]) apply (rule zmod_zadd1_eq) apply (simp (no_asm)) apply (rule zmod_zadd1_eq [symmetric]) done
lemma zmod_zadd_right_eq: "(a$+b) zmod c = (a $+ (b zmod c)) zmod c" apply (rule trans [symmetric]) apply (rule zmod_zadd1_eq) apply (simp (no_asm)) apply (rule zmod_zadd1_eq [symmetric]) done
lemma zdiv_zadd_self1 [simp]: "intify(a) \ #0 \ (a$+b) zdiv a = b zdiv a $+ #1" by (simp (no_asm_simp) add: zdiv_zadd1_eq)
lemma zdiv_zadd_self2 [simp]: "intify(a) \ #0 \ (b$+a) zdiv a = b zdiv a $+ #1" by (simp (no_asm_simp) add: zdiv_zadd1_eq)
lemma zmod_zadd_self1 [simp]: "(a$+b) zmod a = b zmod a" apply (case_tac "a = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (simp (no_asm_simp) add: zmod_zadd1_eq) done
lemma zmod_zadd_self2 [simp]: "(b$+a) zmod a = b zmod a" apply (case_tac "a = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (simp (no_asm_simp) add: zmod_zadd1_eq) done
subsection\<open>proving a zdiv (b*c) = (a zdiv b) zdiv c\<close>
(*The condition c>0 seems necessary. Consider that 7 zdiv \<not>6 = \<not>2 but 7 zdiv 2 zdiv \<not>3 = 3 zdiv \<not>3 = \<not>1. The subcase (a zdiv b) zmod c = 0 seems
to cause particular problems.*)
(** first, four lemmas to bound the remainder for the cases b<0 and b>0 **)
lemma zdiv_zmult2_eq_raw: "\#0 $< c; a \ int; b \ int\ \ a zdiv (b$*c) = (a zdiv b) zdiv c" apply (case_tac "b = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (rule quorem_div_mod [THEN zdiv_zmult2_lemma, THEN quorem_div]) apply (auto simp add: intify_eq_0_iff_zle) apply (blast dest: zle_zless_trans) done
lemma zdiv_zmult2_eq: "#0 $< c \ a zdiv (b$*c) = (a zdiv b) zdiv c" apply (cut_tac a = "intify (a)"and b = "intify (b)"in zdiv_zmult2_eq_raw) apply auto done
lemma zmod_zmult2_eq_raw: "\#0 $< c; a \ int; b \ int\ \<Longrightarrow> a zmod (b$*c) = b$*(a zdiv b zmod c) $+ a zmod b" apply (case_tac "b = #0") apply (simp add: DIVISION_BY_ZERO_ZDIV DIVISION_BY_ZERO_ZMOD) apply (rule quorem_div_mod [THEN zdiv_zmult2_lemma, THEN quorem_mod]) apply (auto simp add: intify_eq_0_iff_zle) apply (blast dest: zle_zless_trans) done
lemma zmod_zmult2_eq: "#0 $< c \ a zmod (b$*c) = b$*(a zdiv b zmod c) $+ a zmod b" apply (cut_tac a = "intify (a)"and b = "intify (b)"in zmod_zmult2_eq_raw) apply auto done
subsection\<open>Cancellation of common factors in "zdiv"\<close>
lemma zmod_zmult_zmult1: "(c$*a) zmod (c$*b) = c $* (a zmod b)" apply (cut_tac b = "intify (b)"and c = "intify (c)"in zmod_zmult_zmult1_raw) apply auto done
lemma zmod_zmult_zmult2: "(a$*c) zmod (b$*c) = (a zmod b) $* c" apply (cut_tac c = "c"in zmod_zmult_zmult1) apply (auto simp add: zmult_commute) done
(** Quotients of signs **)
lemma zdiv_neg_pos_less0: "\a $< #0; #0 $< b\ \ a zdiv b $< #0" apply (subgoal_tac "a zdiv b $\ #-1") apply (erule zle_zless_trans) apply (simp (no_asm)) apply (rule zle_trans) apply (rule_tac a' = "#-1" in zdiv_mono1) apply (rule zless_add1_iff_zle [THEN iffD1]) apply (simp (no_asm)) apply (auto simp add: zdiv_minus1) done
lemma zdiv_nonneg_neg_le0: "\#0 $\ a; b $< #0\ \ a zdiv b $\ #0" apply (drule zdiv_mono1_neg) apply auto done
lemma pos_imp_zdiv_nonneg_iff: "#0 $< b \ (#0 $\ a zdiv b) \ (#0 $\ a)" apply auto apply (drule_tac [2] zdiv_mono1) apply (auto simp add: neq_iff_zless) apply (simp (no_asm_use) add: not_zless_iff_zle [THEN iff_sym]) apply (blast intro: zdiv_neg_pos_less0) done
lemma neg_imp_zdiv_nonneg_iff: "b $< #0 \ (#0 $\ a zdiv b) \ (a $\ #0)" apply (subst zdiv_zminus_zminus [symmetric]) apply (rule iff_trans) apply (rule pos_imp_zdiv_nonneg_iff) apply auto done
(*But not (a zdiv b $\<le> 0 iff a$\<le>0); consider a=1, b=2 when a zdiv b = 0.*) lemma pos_imp_zdiv_neg_iff: "#0 $< b \ (a zdiv b $< #0) \ (a $< #0)" apply (simp (no_asm_simp) add: not_zle_iff_zless [THEN iff_sym]) apply (erule pos_imp_zdiv_nonneg_iff) done
(*Again the law fails for $\<le>: consider a = -1, b = -2 when a zdiv b = 0*) lemma neg_imp_zdiv_neg_iff: "b $< #0 \ (a zdiv b $< #0) \ (#0 $< a)" apply (simp (no_asm_simp) add: not_zle_iff_zless [THEN iff_sym]) apply (erule neg_imp_zdiv_nonneg_iff) done
(* THESE REMAIN TO BE CONVERTED -- but aren't that useful!
subsection{* Speeding up the division algorithm with shifting *}
lemma zmod_integ_of_BIT: "integ_of (v BIT b) zmod integ_of (w BIT False) =
(if b then if #0 $\<le> integ_of w then #2 $* (integ_of v zmod integ_of w) $+ #1
else #2 $* ((integ_of v $+ #1) zmod integ_of w) - #1
else #2 $* (integ_of v zmod integ_of w))" apply (simp_tac (simpset_of @{theory_context Int} add: zadd_assoc integ_of_BIT) apply (simp (no_asm_simp) del: bin_arith_extra_simps@bin_rel_simps add: zmod_zmult_zmult1 pos_zmod_mult_2 lemma neg_zmod_mult_2) done
declare zmod_integ_of_BIT [simp]
*)
end
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.27Bemerkung:
Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.