Up to index of Isabelle/HOL/HOL-Complex/NumberTheory
theory NatIntLib = WilsonRuss:(* Title: NatIntLib.thy
Authors: Jeremy Avigad
Gathering theorems by Jeremy Avigad and David Gray especially,
but also Adam Kramer and Paul Raff
*)
header {* Facts about integers and natural numbers *}
theory NatIntLib = WilsonRuss:;
lemma [simp]: "of_nat(n::nat) = n";
apply (induct_tac n);
apply auto;
done;
(*****************************************************************)
(* *)
(* Useful lemmas about dvd *)
(* *)
(*****************************************************************)
subsection {* Integer divisibility and powers *}
lemma zpower_zdvd_prop1 [rule_format]: "((0 < n) & (p dvd y)) -->
p dvd ((y::int) ^ n)";
by (induct_tac n, auto simp add: zdvd_zmult zdvd_zmult2 [of p y])
lemma zdvd_bounds: "n dvd m ==> (m ≤ (0::int) | n ≤ m)";
proof -;
assume "n dvd m";
then have "~(0 < m & m < n)";
apply (insert zdvd_not_zless [of m n])
by (rule contrapos_pn, auto)
then have "(~0 < m | ~m < n)" by auto
then show ?thesis by auto
qed;
lemma zprime_zdvd_zmult_better: "[| p ∈ zprime; p dvd (m * n) |] ==>
(p dvd m) | (p dvd n)";
apply (case_tac "0 ≤ m")
apply (simp add: zprime_zdvd_zmult)
by (insert zprime_zdvd_zmult [of "-m" p n], auto)
lemma zpower_zdvd_prop2 [rule_format]: "p ∈ zprime --> p dvd ((y::int) ^ n)
--> 0 < n --> p dvd y";
apply (induct_tac n, auto)
apply (frule zprime_zdvd_zmult_better, auto)
done
lemma stupid: "(0 :: int) ≤ y ==> x ≤ x + y";
by arith
lemma div_prop1: "[| 0 < z; (x::int) < y * z |] ==> x div z < y";
proof -;
assume "0 < z";
then have "(x div z) * z ≤ (x div z) * z + x mod z";
apply (rule_tac x = "x div z * z" in stupid)
by (simp add: pos_mod_sign)
also have "... = x";
by (auto simp add: zmod_zdiv_equality [THEN sym] zmult_ac)
also assume "x < y * z";
finally show ?thesis;
by (auto simp add: prems mult_less_cancel_right, insert prems, arith)
qed;
lemma div_prop2: "[| 0 < z; (x::int) < (y * z) + z |] ==> x div z ≤ y";
proof -;
assume "0 < z" and "x < (y * z) + z";
then have "x < (y + 1) * z" by (auto simp add: int_distrib)
then have "x div z < y + 1";
by (rule_tac y = "y + 1" in div_prop1, auto simp add: prems)
then show ?thesis by auto
qed;
lemma zdiv_leq_prop: "[| 0 < y |] ==> y * (x div y) ≤ (x::int)";
proof-;
assume "0 < y";
from zmod_zdiv_equality have "x = y * (x div y) + x mod y" by auto
moreover have "0 ≤ x mod y";
by (auto simp add: prems pos_mod_sign)
ultimately show ?thesis;
by arith
qed;
lemma zdiv_gr_zero: "[| 0 < a; 0 < b; a dvd b |] ==> (0::int) < (b div a)";
by (auto simp add: dvd_def zero_less_mult_iff);
lemma zdiv_zdiv_prop: "[| 0 < a; 0 < b; b dvd a |] ==> a div (a div b)
= (b::int)";
proof -;
assume "0 < a" and "0 < b" and "b dvd a";
then have p: "0 < a div b" by (auto simp add: zdiv_gr_zero);
have "a = a" by auto;
with prems have "a = b * (a div b)" by (auto simp add: dvd_def);
with prems have "a div (a div b) = (b * (a div b)) div (a div b)" by auto;
also from prems p have "... = b" by auto;
finally show ?thesis .;
qed;
lemma x_div_pa_prop: "[| p:zprime; x dvd (p * a) |] ==>
(p dvd x) | (x dvd a)";
apply (simp only: dvd_def, drule_tac Q = "(EX k. x = p * k) | (EX
k. a = x * k)" in exE);
defer 1; apply (force);
proof -;
fix y;
assume "p * a = x * y" and "p:zprime";
then have "p dvd (x * y)";
apply (auto simp add: dvd_def);
apply (rule_tac x = "a" in exI);
apply (auto);
done;
then have "(p dvd x) | (p dvd y)"
by (insert prems, auto simp add: zprime_zdvd_zmult_better);
moreover have "p dvd y ==> x dvd a";
proof-;
assume "p dvd y";
then have "x * y = x * (y div p) * p";
by (auto simp add: dvd_def);
also have "x * y = a * p" by (insert prems, auto simp add: zmult_ac);
finally have "a * p = x * (y div p) * p".;
then have "a = x * (y div p)";
by (insert prems, auto simp add: zprime_def);
thus "x dvd a" by (auto simp add: dvd_def);
qed;
ultimately have "(p dvd x) | (x dvd a)" by (auto);
thus "(EX k. x = p * k) | (EX k. a = x * k)" by (auto simp add: dvd_def);
qed;
(*****************************************************************)
(* *)
(* Divisibility and powers *)
(* *)
(*****************************************************************)
subsection {* Divisibility and powers *}
lemma zpower_gr_0: "0 < (x::int) ==> 0 < x ^ k";
by (induct_tac k, auto simp add: mult_pos);
lemma zpower_minus_one: "[| 0 < k; 0 < p |] ==> ((p::int) ^ k) div p =
p ^ (k - 1)";
proof-;
assume "0 < k" and "0 < p";
then have "(p^k) = (p ^ Suc(k - 1))";
by auto;
also have "...= p^(k - 1) * p";
by (auto simp add: power_Suc);
finally have "p^k = p^(k - 1) * p".;
then have "p^k div p = (p^(k - 1) * p) div p";
by (auto);
thus ?thesis by (insert prems, auto);
qed;
lemma zpower_zmult: "[| 0 < k; 0 < p |] ==> (p::int) ^ k =
p ^ (k - 1) * p"
proof -
assume "0 < k" and "0 < p"
then have "(p^k) = (p ^ Suc(k - 1))"
by auto
thus "p ^ k = p^(k - 1) * p"
by (auto simp add: power_Suc)
qed
lemma x_dvd_pk_prop [rule_format]: "p:zprime --> 0 <= x --> x dvd (p^k)
--> (x = 1) | (p dvd x)";
apply (induct_tac k);
apply (clarsimp);
apply (frule zdvd_bounds);
apply (subgoal_tac "x = 0 | x = 1");
apply (force, arith);
apply (clarsimp);
apply (frule x_div_pa_prop, auto);
done;
(*****************************************************************)
(* *)
(* Properties of gcd *)
(* *)
(*****************************************************************)
subsection {* Properties of gcd *}
(* The contrapositive of gcd_zero *)
lemma gcd_ne_zero: "(m::nat) ~= 0 ==> gcd(m,n) ~= 0";
by (auto simp add: gcd_zero);
lemma zgcd_gr_zero1: "0 < a ==> 0 < zgcd(a, b)";
apply (auto simp add: zgcd_def);
apply (subgoal_tac "abs a = a");
apply (rule ssubst);
apply (auto);
apply (subgoal_tac "nat a ~= 0");
apply (drule gcd_ne_zero);
apply (auto simp add: zabs_def);
done;
lemma zgcd_gr_zero2: "0 < a ==> 0 < zgcd(b, a)";
by (auto simp add: zgcd_gr_zero1 zgcd_ac);
lemma zdvd_zgcd_prop: "[| 0 < d; d dvd m; d dvd n |] ==> zgcd(m,n) =
d * zgcd( m div d, n div d)";
proof -;
assume "0 < d" and "d dvd m" and "d dvd n";
then have "d * zgcd (m div d, n div d) = zgcd(d * (m div d), d * (n div d))";
apply (rule_tac m = "m div d" and n = "n div d" in zgcd_zmult_distrib2);
apply (insert prems, auto);
done;
also have "... = zgcd(m,n)";
by (insert prems, auto simp add: dvd_def zmult_ac);
finally show ?thesis by auto;
qed;
lemma zgcd_equiv: "0 < d ==> (zgcd(k, n) = d) =
(d dvd k & d dvd n & zgcd(k div d, n div d) = 1)";
proof;
assume "0 < d" and "zgcd(k, n) = d";
then show "d dvd k & d dvd n & zgcd(k div d, n div d) = 1";
apply (subgoal_tac "0 < d");
apply (drule_tac d = d and m = k and n = n in zdvd_zgcd_prop);
apply (auto);
done;
next;
assume "0 < d" and "d dvd k & d dvd n & zgcd (k div d, n div d) = 1";
then show "(d dvd k & d dvd n & zgcd(k div d, n div d) = 1) ==>
zgcd(k, n) = d";
(* apply (subgoal_tac "0 < d", auto); *)
apply (frule_tac d = d and m = k and n = n in zdvd_zgcd_prop);
apply (auto);
done;
qed;
lemma gcd_prime_power_iff_zdvd_prop: "[| 0 < k; p:zprime |] ==>
(zgcd(x, p^k) ~= 1) = (p dvd x)";
proof;
assume "p:zprime" and "zgcd(x, p ^ k) ~= 1";
then have "zgcd(x, p ^ k) dvd p ^ k" by auto;
then have "(zgcd(x, p ^ k) = 1) | (p dvd zgcd(x, p ^ k))";
apply (insert prems);
apply (rule_tac x = "zgcd(x, p ^ k)" in x_dvd_pk_prop);
apply (auto);
proof -;
have "0 < p ^ k" by (insert prems, auto simp add: zpower_gr_0 zprime_def);
then have "0 < zgcd (x, p ^ k)" by (rule zgcd_gr_zero2);
thus "0 <= zgcd (x, p ^ k)" by auto;
qed;
then have "p dvd zgcd(x, p ^ k)" by (insert prems, auto);
moreover have "zgcd(x, p ^ k) dvd x" by auto;
ultimately show "p dvd x" by (rule zdvd_trans);
next;
assume "0 < k" and "p:zprime" and "p dvd x";
moreover have "p dvd (p ^ k)";
by (rule zpower_zdvd_prop1, auto simp add: prems);
ultimately have "p dvd zgcd(x, p ^ k)";
by (auto simp add: zgcd_greatest_iff);
thus "zgcd(x, p ^ k) ~= 1"
apply (insert prems, auto simp add: zprime_def);
apply (drule_tac n = p and m = 1 in zdvd_bounds, auto);
done;
qed;
(*****************************************************************)
(* *)
(* Useful properties of congruences *)
(* *)
(*****************************************************************)
subsection {* Properties of integers and congruence *}
lemma zcong_eq_zdvd_prop: "[x = 0](mod p) = (p dvd x)";
by (auto simp add: zcong_def)
lemma zcong_id: "[m = 0] (mod m)";
by (auto simp add: zcong_def zdvd_0_right)
lemma zcong_shift: "[a = b] (mod m) ==> [a + c = b + c] (mod m)";
by (auto simp add: zcong_refl zcong_zadd)
lemma zcong_zpower: "[x = y](mod m) ==> [x^z = y^z](mod m)";
by (induct_tac z, auto simp add: zcong_zmult)
lemma zcong_eq_trans: "[| [a = b](mod m); b = c; [c = d](mod m) |] ==>
[a = d](mod m)";
by (auto, rule_tac b = c in zcong_trans)
lemma aux1: "a - b = (c::int) ==> a = c + b";
by auto
lemma zcong_zmult_prop1: "[a = b](mod m) ==> ([c = a * d](mod m) =
[c = b * d] (mod m))";
apply (auto simp add: zcong_def dvd_def)
apply (rule_tac x = "ka + k * d" in exI)
apply (drule aux1)+;
apply (auto simp add: int_distrib)
apply (rule_tac x = "ka - k * d" in exI)
apply (drule aux1)+;
apply (auto simp add: int_distrib)
done
lemma zcong_zmult_prop2: "[a = b](mod m) ==>
([c = d * a](mod m) = [c = d * b] (mod m))";
by (auto simp add: zmult_ac zcong_zmult_prop1)
lemma zcong_zmult_prop3: "[|p ∈ zprime; ~[x = 0] (mod p);
~[y = 0] (mod p) |] ==> ~[x * y = 0] (mod p)";
apply (auto simp add: zcong_def)
apply (drule zprime_zdvd_zmult_better, auto)
done
lemma zcong_less_eq: "[| 0 < x; 0 < y; 0 < m; [x = y] (mod m);
x < m; y < m |] ==> x = y";
apply (simp add: zcong_zmod_eq)
apply (subgoal_tac "(x mod m) = x");
apply (subgoal_tac "(y mod m) = y");
apply simp
apply (rule_tac [1-2] mod_pos_pos_trivial)
by auto
lemma zcong_neg_1_impl_ne_1: "[| 2 < p; [x = -1] (mod p) |] ==>
~([x = 1] (mod p))";
proof;
assume "2 < p" and "[x = 1] (mod p)" and "[x = -1] (mod p)"
then have "[1 = -1] (mod p)";
apply (auto simp add: zcong_sym)
apply (drule zcong_trans, auto)
done
then have "[1 + 1 = -1 + 1] (mod p)";
by (simp only: zcong_shift)
then have "[2 = 0] (mod p)";
by auto
then have "p dvd 2";
by (auto simp add: dvd_def zcong_def)
with prems show False;
by (auto simp add: zdvd_not_zless)
qed;
lemma zcong_zero_equiv_div: "[a = 0] (mod m) = (m dvd a)";
by (auto simp add: zcong_def)
lemma zcong_zprime_prod_zero: "[| p ∈ zprime; 0 < a |] ==>
[a * b = 0] (mod p) ==> [a = 0] (mod p) | [b = 0] (mod p)";
by (auto simp add: zcong_zero_equiv_div zprime_zdvd_zmult)
lemma zcong_zprime_prod_zero_contra: "[| p ∈ zprime; 0 < a |] ==>
~[a = 0](mod p) & ~[b = 0](mod p) ==> ~[a * b = 0] (mod p)";
apply auto
apply (frule_tac a = a and b = b and p = p in zcong_zprime_prod_zero)
by auto
lemma zcong_not_zero: "[| 0 < x; x < m |] ==> ~[x = 0] (mod m)";
by (auto simp add: zcong_zero_equiv_div zdvd_not_zless)
lemma zcong_zero: "[| 0 ≤ x; x < m; [x = 0](mod m) |] ==> x = 0";
apply (drule order_le_imp_less_or_eq, auto)
by (frule_tac m = m in zcong_not_zero, auto)
lemma all_relprime_prod_relprime: "[| finite A; ∀x ∈ A.
(zgcd(x,y) = 1) |] ==> zgcd (setprod id A,y) = 1";
by (induct set: Finites, auto simp add: zgcd_zgcd_zmult)
lemma zmod_zmult_zmod: "0 < m ==> (x::int) mod m = (x mod (m*n)) mod m";
proof-;
assume "0 < m";
moreover have "m dvd (m*n)" by auto;
ultimately show ?thesis by (auto simp add: zmod_zdvd_zmod);
qed;
lemma zmod_zmult_zmod2: "0 < n ==> (x::int) mod n = (x mod (m*n)) mod n";
proof-;
assume "0 < n";
moreover have "n dvd (m*n)" by auto;
ultimately show ?thesis by (auto simp add: zmod_zdvd_zmod);
qed;
(* similar to zgcd_eq *)
lemma zgcd_eq2: "zgcd(m, n) = zgcd(m, n mod m)";
proof-;
have "zgcd(m, n) = zgcd(n, m)" by (auto simp add: zgcd_commute);
also have "... = zgcd(m, n mod m)" by (insert zgcd_eq [of n m], auto);
finally show ?thesis .;
qed;
lemma zcong_m_scalar_prop: "[a = b] (mod m) ==> [a + (m*c) = b] (mod m)";
apply (auto simp add: zcong_def);
apply (auto simp add: dvd_def zmult_ac);
apply (rule_tac x = "k + c" in exI);
apply (auto simp add: int_distrib);
done;
lemma setsum_same_function_zcong:
"[| finite S; ∀x ∈ S. [f x = g x](mod m) |]
==> [setsum f S = setsum g S] (mod m)";
by (induct set: Finites, auto simp add: zcong_zadd)
lemma setprod_same_function_zcong:
"[| finite S; ∀x ∈ S. [f x = g x](mod m) |]
==> [setprod f S = setprod g S] (mod m)";
by (induct set: Finites, auto simp add: zcong_zmult)
(**********************************************)
(* Note to self: *)
(* a lot of useful lemmas for powers are *)
(* only done for nats (like this one), but *)
(* not for ints... this needs to be fixed *)
(**********************************************)
lemma le_imp_zpower_zdvd [rule_format]: "a <= b --> (p::int)^a dvd p^b";
apply (induct b, auto simp add: dvd_def);
apply (rule_tac x = 1 in exI, auto);
apply (subgoal_tac "a = Suc n", auto);
done;
lemma ge_1_imp_zpower_ge_1: "1 <= (p::int) ==> 1 <= p ^ k";
apply (induct k, auto);
apply (subgoal_tac "0 < p ^ n & 0 < p & 0 < p * p ^n", auto);
apply (auto simp add: zero_less_mult_iff);
done;
(********************************************)
(* Useful? But how useful? *)
(********************************************)
lemma ge_0_zdvd_1: "[| (a::int) dvd 1; 0 <= a |] ==> a = 1";
apply (insert zdvd_imp_le [of a 1], auto);
apply (case_tac "a = 0", auto);
done;
(* Actually Pretty useful... *)
lemma ne_0_zdvd_prop: "[| a ~= 0; (a::int) * b dvd a * c |] ==> b dvd c";
by (auto simp add: dvd_def);
lemma aux [rule_format]:
"p:zprime --> p ~= 0 --> p ^ k dvd a * b --> ~ p dvd b --> p ^ k dvd a";
apply (induct k);
apply (auto simp add: dvd_def);
proof-;
fix k; fix ka;
assume "ka * b = p * k" and "ALL k. b ~= p * k";
then have "p dvd (ka * b)" and "~ p dvd b" by (auto simp add: dvd_def);
moreover assume "p:zprime";
moreover note zprime_zdvd_zmult_better;
ultimately have "p dvd ka" by auto;
then show "EX k. ka = p * k" by (auto simp add: dvd_def);
qed;
lemma zprime_zdvd_zpower: "[| p : zprime; p ^ k dvd a * b; ~ p dvd b |] ==> p ^ k dvd a";
apply (subgoal_tac "p ~= 0");
apply (insert aux [of p k a b]);
apply (auto simp add: zprime_def);
done;
subsection {* Imported from later files *}
lemma prime_ge_2: "p:prime ==> 2<=p";
apply (auto simp add: prime_def);
done;
lemma prime_pos: "p :prime ==> 0 < p";
apply (subgoal_tac "2 <= p");
apply simp;
apply (rule prime_ge_2);
by auto;
lemma zero_not_prime: "0~:prime";
apply (auto simp add: prime_def);
done;
lemma one_not_prime: "(Suc 0)~:prime";
apply (auto simp add: prime_def);
done;
lemma prime_dvd_prime_eq: "a:prime ==> b:prime ==> a dvd b ==> a=b";
apply (auto simp add: prime_def);
done;
lemma prime_dvd_power [rule_format]: "p:prime ==> p dvd m^n --> p dvd m";
apply (induct_tac n);
apply auto;
apply (frule prime_dvd_mult);
by auto;
subsection {* Finite sets of nats and integers *}
lemma finite_subset_AtMost_nat: "A <= {..(x::nat)} ==> finite A";
apply (rule finite_subset);
apply assumption;
apply auto;
done;
lemma finite_subset_GreaterThan0AtMost_int: "A <= {)0..(x::int)} ==> finite A";
apply (erule finite_subset);
apply simp;
done;
lemma finite_subset_GreaterThan0AtMost_nat: "A <= {)0..(x::nat)} ==> finite A";
apply (erule finite_subset);
apply simp;
done;
lemma int_card_eq_setsum: "finite A ==> int (card A) = setsum (%x.1) A";
apply (subst card_eq_setsum);
apply assumption;
apply (subst int_setsum);
apply (unfold o_def);
apply simp;
done;
subsection {* Stuff from later files *}
lemma int_dvd_times_div_cancel:
"(y::int) ~= 0 ==> y dvd x ==> y * (x div y) = x";
by (auto simp add: dvd_def);
lemma int_dvd_times_div_cancel2: "[| 0 < (y::int); y dvd x |] ==>
y * (x div y) = x";
by (auto simp add: dvd_def);
lemma int_inj_div: "0 < (n::int) ==> x dvd n ==> y dvd n ==>
n div x = n div y ==> x = y";
apply (subgoal_tac "x * (n div x) = y * (n div y)");
apply simp;
apply clarsimp;
apply (subgoal_tac "x * (n div x) = 0");
apply (subgoal_tac "x * (n div x) = n");
apply force;
apply (rule int_dvd_times_div_cancel);
apply force;
apply force;
apply simp;
apply (subst int_dvd_times_div_cancel);
apply (force, assumption);
apply (subst int_dvd_times_div_cancel);
apply auto;
done;
lemma int_dvd_div_eq: "x ~= 0 ==> (x::int) dvd y ==>
(y div x = z) = (y = x * z)";
apply auto;
apply (erule int_dvd_times_div_cancel [THEN sym], assumption);
done;
lemma int_div_div: "n ~= 0 ==> x dvd (n::int) ==> n div (n div x) = x";
apply (subst int_dvd_div_eq);
apply (rule notI);
apply (subgoal_tac "x * (n div x) = n");
apply simp;
apply (rule int_dvd_times_div_cancel);
apply force;
apply assumption;
apply (auto simp add: dvd_def);
done;
lemma int_pos_mult_le: "0 <= y ==> (0::int) < x ==> y <= x * y";
apply (subgoal_tac "1 * y <= x * y");
apply simp;
apply (rule mult_right_mono);
apply auto;
done;
lemma int_nonneg_div_nonneg: "(0::int) <= x ==> 0 <= y ==> 0 <= y div x";
apply (case_tac "x = 0");
apply simp;
apply (subgoal_tac "0 = 0 div x");
apply (erule ssubst);
apply (rule zdiv_mono1);
apply auto;
done;
lemma zdvd_leq: "0 <= n ==> n div x <= (n::int)";
apply (case_tac "0 < x");
apply (subgoal_tac "n div x <= n div 1");
apply simp;
apply (rule zdiv_mono2);
apply auto;
apply (case_tac "x = 0");
apply simp;
apply (subgoal_tac "x < 0");
apply (frule div_nonneg_neg_le0);
apply assumption;
apply (erule order_trans);
apply assumption;
apply force;
done;
lemma finite_nat_dvd_set: "0 < (n::nat) ==> finite {x. x dvd n}";
apply (rule finite_subset_AtMost_nat);
apply auto;
apply (erule dvd_imp_le);
apply assumption;
done;
lemma finite_int_dvd_set: "0 < n ==> finite {(d::int). 0 < d & d dvd n}";
apply (rule finite_subset_GreaterThan0AtMost_int);
apply auto;
apply (erule zdvd_imp_le);
apply assumption;
done;
lemma image_int_dvd_set: "0 < n ==>
int ` {x. x dvd n} = {x. 0 < x & x dvd (int n)}";
apply (unfold image_def);
apply auto;
apply (subgoal_tac "xa ~= 0");
apply force;
apply (force simp add: dvd_def);
apply (subst zdvd_int [THEN sym]);
apply assumption;
apply (rule_tac x = "nat x" in exI);
apply simp;
apply (simp add: dvd_int_iff abs_if);
done;
lemma le_int_eq_nat_le: "(x ≤ int y) = (nat x ≤ y)";
apply auto;
apply (subgoal_tac "nat x <= nat (int y)");
apply simp;
apply (subst nat_le_eq_zle);
apply simp;
apply assumption;
apply (case_tac "x < 0");
apply simp;
apply (subgoal_tac "int (nat x) <= int y");
apply simp;
apply (subst zle_int);
apply assumption;
done;
lemma image_int_GreaterThanAtMost: "int ` {)x..y} =
{)int x..int y}";
apply (unfold image_def);
apply auto;
apply (rule_tac x = "nat xa" in bexI);
apply auto;
apply (subst zless_nat_eq_int_zless);
apply assumption;
apply (subst le_int_eq_nat_le [THEN sym]);
apply assumption;
done;
lemma int_div: "int(x div y) = ((int x) div (int y))";
proof -;
have "x = (x div y) * y + x mod y";
by (rule mod_div_equality [THEN sym]);
then have "int x = int (…)"; by simp;
also have "… = int (x div y) * int y + int (x mod y)";
by (simp add: zmult_int zadd_int);
finally have "int x = int (x div y) * int y + int (x mod y)";.;
then have "int x div int y = (…) div int y";by simp;
also have "… = int (x div y)";
apply (subst zdiv_zadd1_eq);
apply auto;
apply (rule div_pos_pos_trivial);
apply force;
apply force;
done;
finally show ?thesis; by (rule sym);
qed;
lemma nat_dvd_mult_div: "(y::nat) ~= 0 ==> y dvd x ==> y * (x div y) = x";
by (auto simp add: dvd_def);
lemma nat_dvd_div_eq: "x ~= 0 ==> (x::nat) dvd y ==>
(y div x = z) = (y = x * z)";
apply auto;
apply (rule nat_dvd_mult_div [THEN sym]);
apply auto;
done;
lemma nat_div_div: "n ~= 0 ==> x dvd (n::nat) ==> n div (n div x) = x";
apply (subst nat_dvd_div_eq);
apply (rule notI);
apply (subgoal_tac "x * (n div x) = n");
apply simp;
apply (rule nat_dvd_mult_div);
apply (rule notI);
apply force;
apply assumption;
apply (auto simp add: dvd_def);
done;
lemma nat_pos_div_dvd_gr_0: "0 < (n::nat) ==> x dvd n ==> 0 < n div x";
apply (subgoal_tac "0 ~= n div x");
apply force;
apply (rule notI);
apply (subgoal_tac "n = x * (n div x)");
apply force;
apply (rule nat_dvd_mult_div [THEN sym]);
apply (rule notI);
apply simp;
apply assumption;
done;
lemma nat_pos_dvd_pos: "[|(x::nat) dvd n; 0 < n|] ==> 0 < x";
apply (subgoal_tac "x ~= 0");
apply force;
apply (rule notI);
apply force;
done;
lemma nat_div_div_eq_div: "y dvd z ==> z ~= 0 ==>
((x::nat) div y div (z div y)) = x div z";
apply (subst div_mult2_eq [THEN sym]);
apply (subst nat_dvd_mult_div);
apply (subgoal_tac "0 < y");
apply force;
apply (rule nat_pos_dvd_pos);
apply assumption;
apply force;
apply assumption;
apply (rule refl);
done;
lemma dvd_pos_pos: "0 < (n::nat) ==> m dvd n ==> 0 < m";
apply (subgoal_tac "m ~= 0");
apply force;
apply (rule notI);
apply simp;
done;
lemma nat_le_imp_1_le_div: "0 < y ==> y <= (x::nat) ==> 1 <= x div y";
apply (subgoal_tac "y div y <= x div y");
apply simp;
apply (rule div_le_mono);
apply assumption;
done;
lemma nat_div_times_le: "((x::nat) div y) * y <= x";
apply (subgoal_tac "(x div y) * y + 0 <= (x div y) * y + x mod y");
apply force;
apply (rule add_le_mono);
apply auto;
done;
lemma nat_pos_prop: "[| 0 <= x; 0 <= y; nat x = nat y |] ==> x = y";
proof-;
assume "0 <= x" and "0 <= y" and "nat x = nat y";
then have "int (nat x) = int (nat y)" by (auto);
also have "int (nat x) = x" by auto;
also have "int (nat y) = y" by auto;
finally show "x = y" by auto;
qed;
lemma relprime_dvd_prod_dvd: "gcd(a,b) = 1 ==> a dvd m ==>
b dvd m ==> (a * b) dvd (m::nat)";
apply (unfold dvd_def);
apply (clarify);
apply (subgoal_tac "a dvd ka");
apply (force simp add: dvd_def);
apply (subst relprime_dvd_mult_iff [THEN sym]);
apply assumption;
apply (auto simp add: mult_commute dvd_def);
apply (rule exI);
apply (erule sym);
done;
lemma distinct_primes_gcd_1: "p:prime ==> q:prime ==> p ~= q ==> gcd(p,q) = 1";
apply (rule prime_imp_relprime);
apply assumption;
apply (auto simp add: prime_def);
done;
lemma all_relprime_prod_relprime_nat: "finite A ==> ALL x:A. gcd(x,y) = 1 ==>
gcd(setprod id A, y) = 1";
apply (induct set: Finites);
apply (auto simp add: gcd_mult_cancel);
done;
lemma distinct_primes_power_gcd_1_aux: "p:prime ==> q:prime ==> p ~= q ==>
gcd(p^a, q) = 1";
apply (induct_tac a);
apply simp;
apply (subst power_Suc);
apply (subst gcd_mult_cancel);
apply (rule distinct_primes_gcd_1);
apply assumption+;
done;
lemma distinct_primes_power_gcd_1: "p:prime ==> q:prime ==> p ~= q ==>
gcd(p^a, q^b) = 1";
apply (induct_tac a);
apply simp;
apply (subst power_Suc);
apply (subst gcd_mult_cancel);
apply (subst gcd_commute);
apply (rule distinct_primes_power_gcd_1_aux);
apply auto;
done;
lemma setprod_primes_dvd: "finite A ==>
ALL x:A. (x : prime & x dvd M) ==> setprod id A dvd M";
apply (induct set: Finites);
apply auto;
apply (rule relprime_dvd_prod_dvd);
apply (subst gcd_commute);
apply (rule all_relprime_prod_relprime_nat);
apply assumption;
apply (rule ballI);
apply (rule distinct_primes_gcd_1);
apply auto;
done;
(* Should also prove the conclusion of Euclid's algorithm, at some point... *)
lemma nat_div_gr_0: "0 < x ==> (x::nat) <= y ==> 0 < y div x";
apply (subgoal_tac "y div x ~= 0");
apply force;
apply (rule notI);
apply (insert mod_div_equality [of y x]);
apply simp;
apply (subgoal_tac "y mod x < x");
apply arith;
apply (erule mod_less_divisor);
done;
end
lemma
of_nat n = n
lemma zpower_zdvd_prop1:
0 < n ∧ p dvd y ==> p dvd y ^ n
lemma zdvd_bounds:
n dvd m ==> m ≤ 0 ∨ n ≤ m
lemma zprime_zdvd_zmult_better:
[| p ∈ zprime; p dvd m * n |] ==> p dvd m ∨ p dvd n
lemma zpower_zdvd_prop2:
[| p ∈ zprime; p dvd y ^ n; 0 < n |] ==> p dvd y
lemma stupid:
0 ≤ y ==> x ≤ x + y
lemma div_prop1:
[| 0 < z; x < y * z |] ==> x div z < y
lemma div_prop2:
[| 0 < z; x < y * z + z |] ==> x div z ≤ y
lemma zdiv_leq_prop:
0 < y ==> y * (x div y) ≤ x
lemma zdiv_gr_zero:
[| 0 < a; 0 < b; a dvd b |] ==> 0 < b div a
lemma zdiv_zdiv_prop:
[| 0 < a; 0 < b; b dvd a |] ==> a div (a div b) = b
lemma x_div_pa_prop:
[| p ∈ zprime; x dvd p * a |] ==> p dvd x ∨ x dvd a
lemma zpower_gr_0:
0 < x ==> 0 < x ^ k
lemma zpower_minus_one:
[| 0 < k; 0 < p |] ==> p ^ k div p = p ^ (k - 1)
lemma zpower_zmult:
[| 0 < k; 0 < p |] ==> p ^ k = p ^ (k - 1) * p
lemma x_dvd_pk_prop:
[| p ∈ zprime; 0 ≤ x; x dvd p ^ k |] ==> x = 1 ∨ p dvd x
lemma gcd_ne_zero:
m ≠ 0 ==> gcd (m, n) ≠ 0
lemma zgcd_gr_zero1:
0 < a ==> 0 < zgcd (a, b)
lemma zgcd_gr_zero2:
0 < a ==> 0 < zgcd (b, a)
lemma zdvd_zgcd_prop:
[| 0 < d; d dvd m; d dvd n |] ==> zgcd (m, n) = d * zgcd (m div d, n div d)
lemma zgcd_equiv:
0 < d ==> (zgcd (k, n) = d) = (d dvd k ∧ d dvd n ∧ zgcd (k div d, n div d) = 1)
lemma gcd_prime_power_iff_zdvd_prop:
[| 0 < k; p ∈ zprime |] ==> (zgcd (x, p ^ k) ≠ 1) = (p dvd x)
lemma zcong_eq_zdvd_prop:
[x = 0] (mod p) = (p dvd x)
lemma zcong_id:
[m = 0] (mod m)
lemma zcong_shift:
[a = b] (mod m) ==> [a + c = b + c] (mod m)
lemma zcong_zpower:
[x = y] (mod m) ==> [x ^ z = y ^ z] (mod m)
lemma zcong_eq_trans:
[| [a = b] (mod m); b = c; [c = d] (mod m) |] ==> [a = d] (mod m)
lemma aux1:
a - b = c ==> a = c + b
lemma zcong_zmult_prop1:
[a = b] (mod m) ==> [c = a * d] (mod m) = [c = b * d] (mod m)
lemma zcong_zmult_prop2:
[a = b] (mod m) ==> [c = d * a] (mod m) = [c = d * b] (mod m)
lemma zcong_zmult_prop3:
[| p ∈ zprime; ¬ [x = 0] (mod p); ¬ [y = 0] (mod p) |] ==> ¬ [x * y = 0] (mod p)
lemma zcong_less_eq:
[| 0 < x; 0 < y; 0 < m; [x = y] (mod m); x < m; y < m |] ==> x = y
lemma zcong_neg_1_impl_ne_1:
[| 2 < p; [x = -1] (mod p) |] ==> ¬ [x = 1] (mod p)
lemma zcong_zero_equiv_div:
[a = 0] (mod m) = (m dvd a)
lemma zcong_zprime_prod_zero:
[| p ∈ zprime; 0 < a; [a * b = 0] (mod p) |] ==> [a = 0] (mod p) ∨ [b = 0] (mod p)
lemma zcong_zprime_prod_zero_contra:
[| p ∈ zprime; 0 < a; ¬ [a = 0] (mod p) ∧ ¬ [b = 0] (mod p) |] ==> ¬ [a * b = 0] (mod p)
lemma zcong_not_zero:
[| 0 < x; x < m |] ==> ¬ [x = 0] (mod m)
lemma zcong_zero:
[| 0 ≤ x; x < m; [x = 0] (mod m) |] ==> x = 0
lemma all_relprime_prod_relprime:
[| finite A; ∀x∈A. zgcd (x, y) = 1 |] ==> zgcd (setprod id A, y) = 1
lemma zmod_zmult_zmod:
0 < m ==> x mod m = x mod (m * n) mod m
lemma zmod_zmult_zmod2:
0 < n ==> x mod n = x mod (m * n) mod n
lemma zgcd_eq2:
zgcd (m, n) = zgcd (m, n mod m)
lemma zcong_m_scalar_prop:
[a = b] (mod m) ==> [a + m * c = b] (mod m)
lemma setsum_same_function_zcong:
[| finite S; ∀x∈S. [f x = g x] (mod m) |] ==> [setsum f S = setsum g S] (mod m)
lemma setprod_same_function_zcong:
[| finite S; ∀x∈S. [f x = g x] (mod m) |] ==> [setprod f S = setprod g S] (mod m)
lemma le_imp_zpower_zdvd:
a ≤ b ==> p ^ a dvd p ^ b
lemma ge_1_imp_zpower_ge_1:
1 ≤ p ==> 1 ≤ p ^ k
lemma ge_0_zdvd_1:
[| a dvd 1; 0 ≤ a |] ==> a = 1
lemma ne_0_zdvd_prop:
[| a ≠ 0; a * b dvd a * c |] ==> b dvd c
lemma aux:
[| p ∈ zprime; p ≠ 0; p ^ k dvd a * b; ¬ p dvd b |] ==> p ^ k dvd a
lemma zprime_zdvd_zpower:
[| p ∈ zprime; p ^ k dvd a * b; ¬ p dvd b |] ==> p ^ k dvd a
lemma prime_ge_2:
p ∈ prime ==> 2 ≤ p
lemma prime_pos:
p ∈ prime ==> 0 < p
lemma zero_not_prime:
0 ∉ prime
lemma one_not_prime:
Suc 0 ∉ prime
lemma prime_dvd_prime_eq:
[| a ∈ prime; b ∈ prime; a dvd b |] ==> a = b
lemma prime_dvd_power:
[| p ∈ prime; p dvd m ^ n |] ==> p dvd m
lemma finite_subset_AtMost_nat:
A ⊆ {..x} ==> finite A
lemma finite_subset_GreaterThan0AtMost_int:
A ⊆ {)0..x} ==> finite A
lemma finite_subset_GreaterThan0AtMost_nat:
A ⊆ {)0..x} ==> finite A
lemma int_card_eq_setsum:
finite A ==> int (card A) = (∑x∈A. 1)
lemma int_dvd_times_div_cancel:
[| y ≠ 0; y dvd x |] ==> y * (x div y) = x
lemma int_dvd_times_div_cancel2:
[| 0 < y; y dvd x |] ==> y * (x div y) = x
lemma int_inj_div:
[| 0 < n; x dvd n; y dvd n; n div x = n div y |] ==> x = y
lemma int_dvd_div_eq:
[| x ≠ 0; x dvd y |] ==> (y div x = z) = (y = x * z)
lemma int_div_div:
[| n ≠ 0; x dvd n |] ==> n div (n div x) = x
lemma int_pos_mult_le:
[| 0 ≤ y; 0 < x |] ==> y ≤ x * y
lemma int_nonneg_div_nonneg:
[| 0 ≤ x; 0 ≤ y |] ==> 0 ≤ y div x
lemma zdvd_leq:
0 ≤ n ==> n div x ≤ n
lemma finite_nat_dvd_set:
0 < n ==> finite {x. x dvd n}
lemma finite_int_dvd_set:
0 < n ==> finite {d. 0 < d ∧ d dvd n}
lemma image_int_dvd_set:
0 < n ==> int ` {x. x dvd n} = {x. 0 < x ∧ x dvd int n}
lemma le_int_eq_nat_le:
(x ≤ int y) = (nat x ≤ y)
lemma image_int_GreaterThanAtMost:
int ` {)x..y} = {)int x..int y}
lemma int_div:
int (x div y) = int x div int y
lemma nat_dvd_mult_div:
[| y ≠ 0; y dvd x |] ==> y * (x div y) = x
lemma nat_dvd_div_eq:
[| x ≠ 0; x dvd y |] ==> (y div x = z) = (y = x * z)
lemma nat_div_div:
[| n ≠ 0; x dvd n |] ==> n div (n div x) = x
lemma nat_pos_div_dvd_gr_0:
[| 0 < n; x dvd n |] ==> 0 < n div x
lemma nat_pos_dvd_pos:
[| x dvd n; 0 < n |] ==> 0 < x
lemma nat_div_div_eq_div:
[| y dvd z; z ≠ 0 |] ==> x div y div (z div y) = x div z
lemma dvd_pos_pos:
[| 0 < n; m dvd n |] ==> 0 < m
lemma nat_le_imp_1_le_div:
[| 0 < y; y ≤ x |] ==> 1 ≤ x div y
lemma nat_div_times_le:
x div y * y ≤ x
lemma nat_pos_prop:
[| 0 ≤ x; 0 ≤ y; nat x = nat y |] ==> x = y
lemma relprime_dvd_prod_dvd:
[| gcd (a, b) = 1; a dvd m; b dvd m |] ==> a * b dvd m
lemma distinct_primes_gcd_1:
[| p ∈ prime; q ∈ prime; p ≠ q |] ==> gcd (p, q) = 1
lemma all_relprime_prod_relprime_nat:
[| finite A; ∀x∈A. gcd (x, y) = 1 |] ==> gcd (setprod id A, y) = 1
lemma distinct_primes_power_gcd_1_aux:
[| p ∈ prime; q ∈ prime; p ≠ q |] ==> gcd (p ^ a, q) = 1
lemma distinct_primes_power_gcd_1:
[| p ∈ prime; q ∈ prime; p ≠ q |] ==> gcd (p ^ a, q ^ b) = 1
lemma setprod_primes_dvd:
[| finite A; ∀x∈A. x ∈ prime ∧ x dvd M |] ==> setprod id A dvd M
lemma nat_div_gr_0:
[| 0 < x; x ≤ y |] ==> 0 < y div x