# HG changeset patch # User haftmann # Date 1256812898 -3600 # Node ID 73998ef6ea91111051ee2733eadeb994cd474cff # Parent 74f0dcc0b5fb92680353b64c6c7f4ebc3ac41955 moved some dvd [int] facts to Int diff -r 74f0dcc0b5fb -r 73998ef6ea91 src/HOL/Int.thy --- a/src/HOL/Int.thy Thu Oct 29 11:41:37 2009 +0100 +++ b/src/HOL/Int.thy Thu Oct 29 11:41:38 2009 +0100 @@ -1984,6 +1984,135 @@ lemmas half_gt_zero [simp] = half_gt_zero_iff [THEN iffD2, standard] +subsection {* The divides relation *} + +lemma zdvd_anti_sym: + "0 < m ==> 0 < n ==> m dvd n ==> n dvd m ==> m = (n::int)" + apply (simp add: dvd_def, auto) + apply (simp add: mult_assoc zero_less_mult_iff zmult_eq_1_iff) + done + +lemma zdvd_dvd_eq: assumes "a \ 0" and "(a::int) dvd b" and "b dvd a" + shows "\a\ = \b\" +proof- + from `a dvd b` obtain k where k:"b = a*k" unfolding dvd_def by blast + from `b dvd a` obtain k' where k':"a = b*k'" unfolding dvd_def by blast + from k k' have "a = a*k*k'" by simp + with mult_cancel_left1[where c="a" and b="k*k'"] + have kk':"k*k' = 1" using `a\0` by (simp add: mult_assoc) + hence "k = 1 \ k' = 1 \ k = -1 \ k' = -1" by (simp add: zmult_eq_1_iff) + thus ?thesis using k k' by auto +qed + +lemma zdvd_zdiffD: "k dvd m - n ==> k dvd n ==> k dvd (m::int)" + apply (subgoal_tac "m = n + (m - n)") + apply (erule ssubst) + apply (blast intro: dvd_add, simp) + done + +lemma zdvd_reduce: "(k dvd n + k * m) = (k dvd (n::int))" +apply (rule iffI) + apply (erule_tac [2] dvd_add) + apply (subgoal_tac "n = (n + k * m) - k * m") + apply (erule ssubst) + apply (erule dvd_diff) + apply(simp_all) +done + +lemma dvd_imp_le_int: + fixes d i :: int + assumes "i \ 0" and "d dvd i" + shows "\d\ \ \i\" +proof - + from `d dvd i` obtain k where "i = d * k" .. + with `i \ 0` have "k \ 0" by auto + then have "1 \ \k\" and "0 \ \d\" by auto + then have "\d\ * 1 \ \d\ * \k\" by (rule mult_left_mono) + with `i = d * k` show ?thesis by (simp add: abs_mult) +qed + +lemma zdvd_not_zless: + fixes m n :: int + assumes "0 < m" and "m < n" + shows "\ n dvd m" +proof + from assms have "0 < n" by auto + assume "n dvd m" then obtain k where k: "m = n * k" .. + with `0 < m` have "0 < n * k" by auto + with `0 < n` have "0 < k" by (simp add: zero_less_mult_iff) + with k `0 < n` `m < n` have "n * k < n * 1" by simp + with `0 < n` `0 < k` show False unfolding mult_less_cancel_left by auto +qed + +lemma zdvd_mult_cancel: assumes d:"k * m dvd k * n" and kz:"k \ (0::int)" + shows "m dvd n" +proof- + from d obtain h where h: "k*n = k*m * h" unfolding dvd_def by blast + {assume "n \ m*h" hence "k* n \ k* (m*h)" using kz by simp + with h have False by (simp add: mult_assoc)} + hence "n = m * h" by blast + thus ?thesis by simp +qed + +theorem zdvd_int: "(x dvd y) = (int x dvd int y)" +proof - + have "\k. int y = int x * k \ x dvd y" + proof - + fix k + assume A: "int y = int x * k" + then show "x dvd y" proof (cases k) + case (1 n) with A have "y = x * n" by (simp add: of_nat_mult [symmetric]) + then show ?thesis .. + next + case (2 n) with A have "int y = int x * (- int (Suc n))" by simp + also have "\ = - (int x * int (Suc n))" by (simp only: mult_minus_right) + also have "\ = - int (x * Suc n)" by (simp only: of_nat_mult [symmetric]) + finally have "- int (x * Suc n) = int y" .. + then show ?thesis by (simp only: negative_eq_positive) auto + qed + qed + then show ?thesis by (auto elim!: dvdE simp only: dvd_triv_left of_nat_mult) +qed + +lemma zdvd1_eq[simp]: "(x::int) dvd 1 = ( \x\ = 1)" +proof + assume d: "x dvd 1" hence "int (nat \x\) dvd int (nat 1)" by simp + hence "nat \x\ dvd 1" by (simp add: zdvd_int) + hence "nat \x\ = 1" by simp + thus "\x\ = 1" by (cases "x < 0", auto) +next + assume "\x\=1" + then have "x = 1 \ x = -1" by auto + then show "x dvd 1" by (auto intro: dvdI) +qed + +lemma zdvd_mult_cancel1: + assumes mp:"m \(0::int)" shows "(m * n dvd m) = (\n\ = 1)" +proof + assume n1: "\n\ = 1" thus "m * n dvd m" + by (cases "n >0", auto simp add: minus_dvd_iff minus_equation_iff) +next + assume H: "m * n dvd m" hence H2: "m * n dvd m * 1" by simp + from zdvd_mult_cancel[OF H2 mp] show "\n\ = 1" by (simp only: zdvd1_eq) +qed + +lemma int_dvd_iff: "(int m dvd z) = (m dvd nat (abs z))" + unfolding zdvd_int by (cases "z \ 0") simp_all + +lemma dvd_int_iff: "(z dvd int m) = (nat (abs z) dvd m)" + unfolding zdvd_int by (cases "z \ 0") simp_all + +lemma nat_dvd_iff: "(nat z dvd m) = (if 0 \ z then (z dvd int m) else m = 0)" + by (auto simp add: dvd_int_iff) + +lemma zdvd_imp_le: "[| z dvd n; 0 < n |] ==> z \ (n::int)" + apply (rule_tac z=n in int_cases) + apply (auto simp add: dvd_int_iff) + apply (rule_tac z=z in int_cases) + apply (auto simp add: dvd_imp_le) + done + + subsection {* Configuration of the code generator *} code_datatype Pls Min Bit0 Bit1 "number_of \ int \ int"