# HG changeset patch # User haftmann # Date 1627898466 0 # Node ID d804e93ae9ffa142c42ae9d73fcc8fb0a0b4150e # Parent fb9c119e5b499a0dc581b28643b4f2eba5b5e179 moved theory Bit_Operations into Main corpus diff -r fb9c119e5b49 -r d804e93ae9ff NEWS --- a/NEWS Sun Aug 01 23:18:13 2021 +0200 +++ b/NEWS Mon Aug 02 10:01:06 2021 +0000 @@ -184,18 +184,20 @@ separate theory "Transposition" in HOL-Combinatorics. INCOMPATIBILITY. * Infix syntax for bit operations AND, OR, XOR is now organized in -bundle bit_operations_syntax. INCOMPATIBILITY. +bundle bit_operations_syntax. INCOMPATIBILITY. * Bit operations set_bit, unset_bit and flip_bit are now class operations. INCOMPATIBILITY. +* Theory Bit_Operations is now part of HOL-Main. Minor INCOMPATIBILITY. + * Abbreviation "max_word" has been moved to session Word_Lib in the AFP, as also have constants "shiftl1", "shiftr1", "sshiftr1", "bshiftr1", "setBit", "clearBit". See there further the changelog in theory Guide. INCOMPATIBILITY. * New simp rules: less_exp, min.absorb1, min.absorb2, min.absorb3, -min.absorb4, max.absorb1, max.absorb2, max.absorb3, max.absorb4. Minor +min.absorb4, max.absorb1, max.absorb2, max.absorb3, max.absorb4. Minor INCOMPATIBILITY. * Sledgehammer: @@ -210,6 +212,7 @@ * Metis: - Renamed option "hide_lams" to "opaque_lifting". Minor INCOMPATIBILITY. + *** ML *** * ML antiquotations \<^try>\expr\ and \<^can>\expr\ operate directly on diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Bit_Operations.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/Bit_Operations.thy Mon Aug 02 10:01:06 2021 +0000 @@ -0,0 +1,3574 @@ +(* Author: Florian Haftmann, TUM +*) + +section \Bit operations in suitable algebraic structures\ + +theory Bit_Operations + imports Presburger Groups_List +begin + +subsection \Abstract bit structures\ + +class semiring_bits = semiring_parity + + assumes bits_induct [case_names stable rec]: + \(\a. a div 2 = a \ P a) + \ (\a b. P a \ (of_bool b + 2 * a) div 2 = a \ P (of_bool b + 2 * a)) + \ P a\ + assumes bits_div_0 [simp]: \0 div a = 0\ + and bits_div_by_1 [simp]: \a div 1 = a\ + and bits_mod_div_trivial [simp]: \a mod b div b = 0\ + and even_succ_div_2 [simp]: \even a \ (1 + a) div 2 = a div 2\ + and even_mask_div_iff: \even ((2 ^ m - 1) div 2 ^ n) \ 2 ^ n = 0 \ m \ n\ + and exp_div_exp_eq: \2 ^ m div 2 ^ n = of_bool (2 ^ m \ 0 \ m \ n) * 2 ^ (m - n)\ + and div_exp_eq: \a div 2 ^ m div 2 ^ n = a div 2 ^ (m + n)\ + and mod_exp_eq: \a mod 2 ^ m mod 2 ^ n = a mod 2 ^ min m n\ + and mult_exp_mod_exp_eq: \m \ n \ (a * 2 ^ m) mod (2 ^ n) = (a mod 2 ^ (n - m)) * 2 ^ m\ + and div_exp_mod_exp_eq: \a div 2 ^ n mod 2 ^ m = a mod (2 ^ (n + m)) div 2 ^ n\ + and even_mult_exp_div_exp_iff: \even (a * 2 ^ m div 2 ^ n) \ m > n \ 2 ^ n = 0 \ (m \ n \ even (a div 2 ^ (n - m)))\ + fixes bit :: \'a \ nat \ bool\ + assumes bit_iff_odd: \bit a n \ odd (a div 2 ^ n)\ +begin + +text \ + Having \<^const>\bit\ as definitional class operation + takes into account that specific instances can be implemented + differently wrt. code generation. +\ + +lemma bits_div_by_0 [simp]: + \a div 0 = 0\ + by (metis add_cancel_right_right bits_mod_div_trivial mod_mult_div_eq mult_not_zero) + +lemma bits_1_div_2 [simp]: + \1 div 2 = 0\ + using even_succ_div_2 [of 0] by simp + +lemma bits_1_div_exp [simp]: + \1 div 2 ^ n = of_bool (n = 0)\ + using div_exp_eq [of 1 1] by (cases n) simp_all + +lemma even_succ_div_exp [simp]: + \(1 + a) div 2 ^ n = a div 2 ^ n\ if \even a\ and \n > 0\ +proof (cases n) + case 0 + with that show ?thesis + by simp +next + case (Suc n) + with \even a\ have \(1 + a) div 2 ^ Suc n = a div 2 ^ Suc n\ + proof (induction n) + case 0 + then show ?case + by simp + next + case (Suc n) + then show ?case + using div_exp_eq [of _ 1 \Suc n\, symmetric] + by simp + qed + with Suc show ?thesis + by simp +qed + +lemma even_succ_mod_exp [simp]: + \(1 + a) mod 2 ^ n = 1 + (a mod 2 ^ n)\ if \even a\ and \n > 0\ + using div_mult_mod_eq [of \1 + a\ \2 ^ n\] that + apply simp + by (metis local.add.left_commute local.add_left_cancel local.div_mult_mod_eq) + +lemma bits_mod_by_1 [simp]: + \a mod 1 = 0\ + using div_mult_mod_eq [of a 1] by simp + +lemma bits_mod_0 [simp]: + \0 mod a = 0\ + using div_mult_mod_eq [of 0 a] by simp + +lemma bits_one_mod_two_eq_one [simp]: + \1 mod 2 = 1\ + by (simp add: mod2_eq_if) + +lemma bit_0 [simp]: + \bit a 0 \ odd a\ + by (simp add: bit_iff_odd) + +lemma bit_Suc: + \bit a (Suc n) \ bit (a div 2) n\ + using div_exp_eq [of a 1 n] by (simp add: bit_iff_odd) + +lemma bit_rec: + \bit a n \ (if n = 0 then odd a else bit (a div 2) (n - 1))\ + by (cases n) (simp_all add: bit_Suc) + +lemma bit_0_eq [simp]: + \bit 0 = bot\ + by (simp add: fun_eq_iff bit_iff_odd) + +context + fixes a + assumes stable: \a div 2 = a\ +begin + +lemma bits_stable_imp_add_self: + \a + a mod 2 = 0\ +proof - + have \a div 2 * 2 + a mod 2 = a\ + by (fact div_mult_mod_eq) + then have \a * 2 + a mod 2 = a\ + by (simp add: stable) + then show ?thesis + by (simp add: mult_2_right ac_simps) +qed + +lemma stable_imp_bit_iff_odd: + \bit a n \ odd a\ + by (induction n) (simp_all add: stable bit_Suc) + +end + +lemma bit_iff_idd_imp_stable: + \a div 2 = a\ if \\n. bit a n \ odd a\ +using that proof (induction a rule: bits_induct) + case (stable a) + then show ?case + by simp +next + case (rec a b) + from rec.prems [of 1] have [simp]: \b = odd a\ + by (simp add: rec.hyps bit_Suc) + from rec.hyps have hyp: \(of_bool (odd a) + 2 * a) div 2 = a\ + by simp + have \bit a n \ odd a\ for n + using rec.prems [of \Suc n\] by (simp add: hyp bit_Suc) + then have \a div 2 = a\ + by (rule rec.IH) + then have \of_bool (odd a) + 2 * a = 2 * (a div 2) + of_bool (odd a)\ + by (simp add: ac_simps) + also have \\ = a\ + using mult_div_mod_eq [of 2 a] + by (simp add: of_bool_odd_eq_mod_2) + finally show ?case + using \a div 2 = a\ by (simp add: hyp) +qed + +lemma exp_eq_0_imp_not_bit: + \\ bit a n\ if \2 ^ n = 0\ + using that by (simp add: bit_iff_odd) + +lemma bit_eqI: + \a = b\ if \\n. 2 ^ n \ 0 \ bit a n \ bit b n\ +proof - + have \bit a n \ bit b n\ for n + proof (cases \2 ^ n = 0\) + case True + then show ?thesis + by (simp add: exp_eq_0_imp_not_bit) + next + case False + then show ?thesis + by (rule that) + qed + then show ?thesis proof (induction a arbitrary: b rule: bits_induct) + case (stable a) + from stable(2) [of 0] have **: \even b \ even a\ + by simp + have \b div 2 = b\ + proof (rule bit_iff_idd_imp_stable) + fix n + from stable have *: \bit b n \ bit a n\ + by simp + also have \bit a n \ odd a\ + using stable by (simp add: stable_imp_bit_iff_odd) + finally show \bit b n \ odd b\ + by (simp add: **) + qed + from ** have \a mod 2 = b mod 2\ + by (simp add: mod2_eq_if) + then have \a mod 2 + (a + b) = b mod 2 + (a + b)\ + by simp + then have \a + a mod 2 + b = b + b mod 2 + a\ + by (simp add: ac_simps) + with \a div 2 = a\ \b div 2 = b\ show ?case + by (simp add: bits_stable_imp_add_self) + next + case (rec a p) + from rec.prems [of 0] have [simp]: \p = odd b\ + by simp + from rec.hyps have \bit a n \ bit (b div 2) n\ for n + using rec.prems [of \Suc n\] by (simp add: bit_Suc) + then have \a = b div 2\ + by (rule rec.IH) + then have \2 * a = 2 * (b div 2)\ + by simp + then have \b mod 2 + 2 * a = b mod 2 + 2 * (b div 2)\ + by simp + also have \\ = b\ + by (fact mod_mult_div_eq) + finally show ?case + by (auto simp add: mod2_eq_if) + qed +qed + +lemma bit_eq_iff: + \a = b \ (\n. bit a n \ bit b n)\ + by (auto intro: bit_eqI) + +named_theorems bit_simps \Simplification rules for \<^const>\bit\\ + +lemma bit_exp_iff [bit_simps]: + \bit (2 ^ m) n \ 2 ^ m \ 0 \ m = n\ + by (auto simp add: bit_iff_odd exp_div_exp_eq) + +lemma bit_1_iff [bit_simps]: + \bit 1 n \ 1 \ 0 \ n = 0\ + using bit_exp_iff [of 0 n] by simp + +lemma bit_2_iff [bit_simps]: + \bit 2 n \ 2 \ 0 \ n = 1\ + using bit_exp_iff [of 1 n] by auto + +lemma even_bit_succ_iff: + \bit (1 + a) n \ bit a n \ n = 0\ if \even a\ + using that by (cases \n = 0\) (simp_all add: bit_iff_odd) + +lemma odd_bit_iff_bit_pred: + \bit a n \ bit (a - 1) n \ n = 0\ if \odd a\ +proof - + from \odd a\ obtain b where \a = 2 * b + 1\ .. + moreover have \bit (2 * b) n \ n = 0 \ bit (1 + 2 * b) n\ + using even_bit_succ_iff by simp + ultimately show ?thesis by (simp add: ac_simps) +qed + +lemma bit_double_iff [bit_simps]: + \bit (2 * a) n \ bit a (n - 1) \ n \ 0 \ 2 ^ n \ 0\ + using even_mult_exp_div_exp_iff [of a 1 n] + by (cases n, auto simp add: bit_iff_odd ac_simps) + +lemma bit_eq_rec: + \a = b \ (even a \ even b) \ a div 2 = b div 2\ (is \?P = ?Q\) +proof + assume ?P + then show ?Q + by simp +next + assume ?Q + then have \even a \ even b\ and \a div 2 = b div 2\ + by simp_all + show ?P + proof (rule bit_eqI) + fix n + show \bit a n \ bit b n\ + proof (cases n) + case 0 + with \even a \ even b\ show ?thesis + by simp + next + case (Suc n) + moreover from \a div 2 = b div 2\ have \bit (a div 2) n = bit (b div 2) n\ + by simp + ultimately show ?thesis + by (simp add: bit_Suc) + qed + qed +qed + +lemma bit_mod_2_iff [simp]: + \bit (a mod 2) n \ n = 0 \ odd a\ + by (cases a rule: parity_cases) (simp_all add: bit_iff_odd) + +lemma bit_mask_iff: + \bit (2 ^ m - 1) n \ 2 ^ n \ 0 \ n < m\ + by (simp add: bit_iff_odd even_mask_div_iff not_le) + +lemma bit_Numeral1_iff [simp]: + \bit (numeral Num.One) n \ n = 0\ + by (simp add: bit_rec) + +lemma exp_add_not_zero_imp: + \2 ^ m \ 0\ and \2 ^ n \ 0\ if \2 ^ (m + n) \ 0\ +proof - + have \\ (2 ^ m = 0 \ 2 ^ n = 0)\ + proof (rule notI) + assume \2 ^ m = 0 \ 2 ^ n = 0\ + then have \2 ^ (m + n) = 0\ + by (rule disjE) (simp_all add: power_add) + with that show False .. + qed + then show \2 ^ m \ 0\ and \2 ^ n \ 0\ + by simp_all +qed + +lemma bit_disjunctive_add_iff: + \bit (a + b) n \ bit a n \ bit b n\ + if \\n. \ bit a n \ \ bit b n\ +proof (cases \2 ^ n = 0\) + case True + then show ?thesis + by (simp add: exp_eq_0_imp_not_bit) +next + case False + with that show ?thesis proof (induction n arbitrary: a b) + case 0 + from "0.prems"(1) [of 0] show ?case + by auto + next + case (Suc n) + from Suc.prems(1) [of 0] have even: \even a \ even b\ + by auto + have bit: \\ bit (a div 2) n \ \ bit (b div 2) n\ for n + using Suc.prems(1) [of \Suc n\] by (simp add: bit_Suc) + from Suc.prems(2) have \2 * 2 ^ n \ 0\ \2 ^ n \ 0\ + by (auto simp add: mult_2) + have \a + b = (a div 2 * 2 + a mod 2) + (b div 2 * 2 + b mod 2)\ + using div_mult_mod_eq [of a 2] div_mult_mod_eq [of b 2] by simp + also have \\ = of_bool (odd a \ odd b) + 2 * (a div 2 + b div 2)\ + using even by (auto simp add: algebra_simps mod2_eq_if) + finally have \bit ((a + b) div 2) n \ bit (a div 2 + b div 2) n\ + using \2 * 2 ^ n \ 0\ by simp (simp_all flip: bit_Suc add: bit_double_iff) + also have \\ \ bit (a div 2) n \ bit (b div 2) n\ + using bit \2 ^ n \ 0\ by (rule Suc.IH) + finally show ?case + by (simp add: bit_Suc) + qed +qed + +lemma + exp_add_not_zero_imp_left: \2 ^ m \ 0\ + and exp_add_not_zero_imp_right: \2 ^ n \ 0\ + if \2 ^ (m + n) \ 0\ +proof - + have \\ (2 ^ m = 0 \ 2 ^ n = 0)\ + proof (rule notI) + assume \2 ^ m = 0 \ 2 ^ n = 0\ + then have \2 ^ (m + n) = 0\ + by (rule disjE) (simp_all add: power_add) + with that show False .. + qed + then show \2 ^ m \ 0\ and \2 ^ n \ 0\ + by simp_all +qed + +lemma exp_not_zero_imp_exp_diff_not_zero: + \2 ^ (n - m) \ 0\ if \2 ^ n \ 0\ +proof (cases \m \ n\) + case True + moreover define q where \q = n - m\ + ultimately have \n = m + q\ + by simp + with that show ?thesis + by (simp add: exp_add_not_zero_imp_right) +next + case False + with that show ?thesis + by simp +qed + +end + +lemma nat_bit_induct [case_names zero even odd]: + "P n" if zero: "P 0" + and even: "\n. P n \ n > 0 \ P (2 * n)" + and odd: "\n. P n \ P (Suc (2 * n))" +proof (induction n rule: less_induct) + case (less n) + show "P n" + proof (cases "n = 0") + case True with zero show ?thesis by simp + next + case False + with less have hyp: "P (n div 2)" by simp + show ?thesis + proof (cases "even n") + case True + then have "n \ 1" + by auto + with \n \ 0\ have "n div 2 > 0" + by simp + with \even n\ hyp even [of "n div 2"] show ?thesis + by simp + next + case False + with hyp odd [of "n div 2"] show ?thesis + by simp + qed + qed +qed + +instantiation nat :: semiring_bits +begin + +definition bit_nat :: \nat \ nat \ bool\ + where \bit_nat m n \ odd (m div 2 ^ n)\ + +instance +proof + show \P n\ if stable: \\n. n div 2 = n \ P n\ + and rec: \\n b. P n \ (of_bool b + 2 * n) div 2 = n \ P (of_bool b + 2 * n)\ + for P and n :: nat + proof (induction n rule: nat_bit_induct) + case zero + from stable [of 0] show ?case + by simp + next + case (even n) + with rec [of n False] show ?case + by simp + next + case (odd n) + with rec [of n True] show ?case + by simp + qed + show \q mod 2 ^ m mod 2 ^ n = q mod 2 ^ min m n\ + for q m n :: nat + apply (auto simp add: less_iff_Suc_add power_add mod_mod_cancel split: split_min_lin) + apply (metis div_mult2_eq mod_div_trivial mod_eq_self_iff_div_eq_0 mod_mult_self2_is_0 power_commutes) + done + show \(q * 2 ^ m) mod (2 ^ n) = (q mod 2 ^ (n - m)) * 2 ^ m\ if \m \ n\ + for q m n :: nat + using that + apply (auto simp add: mod_mod_cancel div_mult2_eq power_add mod_mult2_eq le_iff_add split: split_min_lin) + done + show \even ((2 ^ m - (1::nat)) div 2 ^ n) \ 2 ^ n = (0::nat) \ m \ n\ + for m n :: nat + using even_mask_div_iff' [where ?'a = nat, of m n] by simp + show \even (q * 2 ^ m div 2 ^ n) \ n < m \ (2::nat) ^ n = 0 \ m \ n \ even (q div 2 ^ (n - m))\ + for m n q r :: nat + apply (auto simp add: not_less power_add ac_simps dest!: le_Suc_ex) + apply (metis (full_types) dvd_mult dvd_mult_imp_div dvd_power_iff_le not_less not_less_eq order_refl power_Suc) + done +qed (auto simp add: div_mult2_eq mod_mult2_eq power_add power_diff bit_nat_def) + +end + +lemma int_bit_induct [case_names zero minus even odd]: + "P k" if zero_int: "P 0" + and minus_int: "P (- 1)" + and even_int: "\k. P k \ k \ 0 \ P (k * 2)" + and odd_int: "\k. P k \ k \ - 1 \ P (1 + (k * 2))" for k :: int +proof (cases "k \ 0") + case True + define n where "n = nat k" + with True have "k = int n" + by simp + then show "P k" + proof (induction n arbitrary: k rule: nat_bit_induct) + case zero + then show ?case + by (simp add: zero_int) + next + case (even n) + have "P (int n * 2)" + by (rule even_int) (use even in simp_all) + with even show ?case + by (simp add: ac_simps) + next + case (odd n) + have "P (1 + (int n * 2))" + by (rule odd_int) (use odd in simp_all) + with odd show ?case + by (simp add: ac_simps) + qed +next + case False + define n where "n = nat (- k - 1)" + with False have "k = - int n - 1" + by simp + then show "P k" + proof (induction n arbitrary: k rule: nat_bit_induct) + case zero + then show ?case + by (simp add: minus_int) + next + case (even n) + have "P (1 + (- int (Suc n) * 2))" + by (rule odd_int) (use even in \simp_all add: algebra_simps\) + also have "\ = - int (2 * n) - 1" + by (simp add: algebra_simps) + finally show ?case + using even.prems by simp + next + case (odd n) + have "P (- int (Suc n) * 2)" + by (rule even_int) (use odd in \simp_all add: algebra_simps\) + also have "\ = - int (Suc (2 * n)) - 1" + by (simp add: algebra_simps) + finally show ?case + using odd.prems by simp + qed +qed + +context semiring_bits +begin + +lemma bit_of_bool_iff [bit_simps]: + \bit (of_bool b) n \ b \ n = 0\ + by (simp add: bit_1_iff) + +lemma even_of_nat_iff: + \even (of_nat n) \ even n\ + by (induction n rule: nat_bit_induct) simp_all + +lemma bit_of_nat_iff [bit_simps]: + \bit (of_nat m) n \ (2::'a) ^ n \ 0 \ bit m n\ +proof (cases \(2::'a) ^ n = 0\) + case True + then show ?thesis + by (simp add: exp_eq_0_imp_not_bit) +next + case False + then have \bit (of_nat m) n \ bit m n\ + proof (induction m arbitrary: n rule: nat_bit_induct) + case zero + then show ?case + by simp + next + case (even m) + then show ?case + by (cases n) + (auto simp add: bit_double_iff Bit_Operations.bit_double_iff dest: mult_not_zero) + next + case (odd m) + then show ?case + by (cases n) + (auto simp add: bit_double_iff even_bit_succ_iff Bit_Operations.bit_Suc dest: mult_not_zero) + qed + with False show ?thesis + by simp +qed + +end + +instantiation int :: semiring_bits +begin + +definition bit_int :: \int \ nat \ bool\ + where \bit_int k n \ odd (k div 2 ^ n)\ + +instance +proof + show \P k\ if stable: \\k. k div 2 = k \ P k\ + and rec: \\k b. P k \ (of_bool b + 2 * k) div 2 = k \ P (of_bool b + 2 * k)\ + for P and k :: int + proof (induction k rule: int_bit_induct) + case zero + from stable [of 0] show ?case + by simp + next + case minus + from stable [of \- 1\] show ?case + by simp + next + case (even k) + with rec [of k False] show ?case + by (simp add: ac_simps) + next + case (odd k) + with rec [of k True] show ?case + by (simp add: ac_simps) + qed + show \(2::int) ^ m div 2 ^ n = of_bool ((2::int) ^ m \ 0 \ n \ m) * 2 ^ (m - n)\ + for m n :: nat + proof (cases \m < n\) + case True + then have \n = m + (n - m)\ + by simp + then have \(2::int) ^ m div 2 ^ n = (2::int) ^ m div 2 ^ (m + (n - m))\ + by simp + also have \\ = (2::int) ^ m div (2 ^ m * 2 ^ (n - m))\ + by (simp add: power_add) + also have \\ = (2::int) ^ m div 2 ^ m div 2 ^ (n - m)\ + by (simp add: zdiv_zmult2_eq) + finally show ?thesis using \m < n\ by simp + next + case False + then show ?thesis + by (simp add: power_diff) + qed + show \k mod 2 ^ m mod 2 ^ n = k mod 2 ^ min m n\ + for m n :: nat and k :: int + using mod_exp_eq [of \nat k\ m n] + apply (auto simp add: mod_mod_cancel zdiv_zmult2_eq power_add zmod_zmult2_eq le_iff_add split: split_min_lin) + apply (auto simp add: less_iff_Suc_add mod_mod_cancel power_add) + apply (simp only: flip: mult.left_commute [of \2 ^ m\]) + apply (subst zmod_zmult2_eq) apply simp_all + done + show \(k * 2 ^ m) mod (2 ^ n) = (k mod 2 ^ (n - m)) * 2 ^ m\ + if \m \ n\ for m n :: nat and k :: int + using that + apply (auto simp add: power_add zmod_zmult2_eq le_iff_add split: split_min_lin) + done + show \even ((2 ^ m - (1::int)) div 2 ^ n) \ 2 ^ n = (0::int) \ m \ n\ + for m n :: nat + using even_mask_div_iff' [where ?'a = int, of m n] by simp + show \even (k * 2 ^ m div 2 ^ n) \ n < m \ (2::int) ^ n = 0 \ m \ n \ even (k div 2 ^ (n - m))\ + for m n :: nat and k l :: int + apply (auto simp add: not_less power_add ac_simps dest!: le_Suc_ex) + apply (metis Suc_leI dvd_mult dvd_mult_imp_div dvd_power_le dvd_refl power.simps(2)) + done +qed (auto simp add: zdiv_zmult2_eq zmod_zmult2_eq power_add power_diff not_le bit_int_def) + +end + +class semiring_bit_shifts = semiring_bits + + fixes push_bit :: \nat \ 'a \ 'a\ + assumes push_bit_eq_mult: \push_bit n a = a * 2 ^ n\ + fixes drop_bit :: \nat \ 'a \ 'a\ + assumes drop_bit_eq_div: \drop_bit n a = a div 2 ^ n\ + fixes take_bit :: \nat \ 'a \ 'a\ + assumes take_bit_eq_mod: \take_bit n a = a mod 2 ^ n\ +begin + +text \ + Logically, \<^const>\push_bit\, + \<^const>\drop_bit\ and \<^const>\take_bit\ are just aliases; having them + as separate operations makes proofs easier, otherwise proof automation + would fiddle with concrete expressions \<^term>\2 ^ n\ in a way obfuscating the basic + algebraic relationships between those operations. + Having + them as definitional class operations + takes into account that specific instances of these can be implemented + differently wrt. code generation. +\ + +lemma bit_iff_odd_drop_bit: + \bit a n \ odd (drop_bit n a)\ + by (simp add: bit_iff_odd drop_bit_eq_div) + +lemma even_drop_bit_iff_not_bit: + \even (drop_bit n a) \ \ bit a n\ + by (simp add: bit_iff_odd_drop_bit) + +lemma div_push_bit_of_1_eq_drop_bit: + \a div push_bit n 1 = drop_bit n a\ + by (simp add: push_bit_eq_mult drop_bit_eq_div) + +lemma bits_ident: + "push_bit n (drop_bit n a) + take_bit n a = a" + using div_mult_mod_eq by (simp add: push_bit_eq_mult take_bit_eq_mod drop_bit_eq_div) + +lemma push_bit_push_bit [simp]: + "push_bit m (push_bit n a) = push_bit (m + n) a" + by (simp add: push_bit_eq_mult power_add ac_simps) + +lemma push_bit_0_id [simp]: + "push_bit 0 = id" + by (simp add: fun_eq_iff push_bit_eq_mult) + +lemma push_bit_of_0 [simp]: + "push_bit n 0 = 0" + by (simp add: push_bit_eq_mult) + +lemma push_bit_of_1: + "push_bit n 1 = 2 ^ n" + by (simp add: push_bit_eq_mult) + +lemma push_bit_Suc [simp]: + "push_bit (Suc n) a = push_bit n (a * 2)" + by (simp add: push_bit_eq_mult ac_simps) + +lemma push_bit_double: + "push_bit n (a * 2) = push_bit n a * 2" + by (simp add: push_bit_eq_mult ac_simps) + +lemma push_bit_add: + "push_bit n (a + b) = push_bit n a + push_bit n b" + by (simp add: push_bit_eq_mult algebra_simps) + +lemma push_bit_numeral [simp]: + \push_bit (numeral l) (numeral k) = push_bit (pred_numeral l) (numeral (Num.Bit0 k))\ + by (simp add: numeral_eq_Suc mult_2_right) (simp add: numeral_Bit0) + +lemma take_bit_0 [simp]: + "take_bit 0 a = 0" + by (simp add: take_bit_eq_mod) + +lemma take_bit_Suc: + \take_bit (Suc n) a = take_bit n (a div 2) * 2 + a mod 2\ +proof - + have \take_bit (Suc n) (a div 2 * 2 + of_bool (odd a)) = take_bit n (a div 2) * 2 + of_bool (odd a)\ + using even_succ_mod_exp [of \2 * (a div 2)\ \Suc n\] + mult_exp_mod_exp_eq [of 1 \Suc n\ \a div 2\] + by (auto simp add: take_bit_eq_mod ac_simps) + then show ?thesis + using div_mult_mod_eq [of a 2] by (simp add: mod_2_eq_odd) +qed + +lemma take_bit_rec: + \take_bit n a = (if n = 0 then 0 else take_bit (n - 1) (a div 2) * 2 + a mod 2)\ + by (cases n) (simp_all add: take_bit_Suc) + +lemma take_bit_Suc_0 [simp]: + \take_bit (Suc 0) a = a mod 2\ + by (simp add: take_bit_eq_mod) + +lemma take_bit_of_0 [simp]: + "take_bit n 0 = 0" + by (simp add: take_bit_eq_mod) + +lemma take_bit_of_1 [simp]: + "take_bit n 1 = of_bool (n > 0)" + by (cases n) (simp_all add: take_bit_Suc) + +lemma drop_bit_of_0 [simp]: + "drop_bit n 0 = 0" + by (simp add: drop_bit_eq_div) + +lemma drop_bit_of_1 [simp]: + "drop_bit n 1 = of_bool (n = 0)" + by (simp add: drop_bit_eq_div) + +lemma drop_bit_0 [simp]: + "drop_bit 0 = id" + by (simp add: fun_eq_iff drop_bit_eq_div) + +lemma drop_bit_Suc: + "drop_bit (Suc n) a = drop_bit n (a div 2)" + using div_exp_eq [of a 1] by (simp add: drop_bit_eq_div) + +lemma drop_bit_rec: + "drop_bit n a = (if n = 0 then a else drop_bit (n - 1) (a div 2))" + by (cases n) (simp_all add: drop_bit_Suc) + +lemma drop_bit_half: + "drop_bit n (a div 2) = drop_bit n a div 2" + by (induction n arbitrary: a) (simp_all add: drop_bit_Suc) + +lemma drop_bit_of_bool [simp]: + "drop_bit n (of_bool b) = of_bool (n = 0 \ b)" + by (cases n) simp_all + +lemma even_take_bit_eq [simp]: + \even (take_bit n a) \ n = 0 \ even a\ + by (simp add: take_bit_rec [of n a]) + +lemma take_bit_take_bit [simp]: + "take_bit m (take_bit n a) = take_bit (min m n) a" + by (simp add: take_bit_eq_mod mod_exp_eq ac_simps) + +lemma drop_bit_drop_bit [simp]: + "drop_bit m (drop_bit n a) = drop_bit (m + n) a" + by (simp add: drop_bit_eq_div power_add div_exp_eq ac_simps) + +lemma push_bit_take_bit: + "push_bit m (take_bit n a) = take_bit (m + n) (push_bit m a)" + apply (simp add: push_bit_eq_mult take_bit_eq_mod power_add ac_simps) + using mult_exp_mod_exp_eq [of m \m + n\ a] apply (simp add: ac_simps power_add) + done + +lemma take_bit_push_bit: + "take_bit m (push_bit n a) = push_bit n (take_bit (m - n) a)" +proof (cases "m \ n") + case True + then show ?thesis + apply (simp add:) + apply (simp_all add: push_bit_eq_mult take_bit_eq_mod) + apply (auto dest!: le_Suc_ex simp add: power_add ac_simps) + using mult_exp_mod_exp_eq [of m m \a * 2 ^ n\ for n] + apply (simp add: ac_simps) + done +next + case False + then show ?thesis + using push_bit_take_bit [of n "m - n" a] + by simp +qed + +lemma take_bit_drop_bit: + "take_bit m (drop_bit n a) = drop_bit n (take_bit (m + n) a)" + by (simp add: drop_bit_eq_div take_bit_eq_mod ac_simps div_exp_mod_exp_eq) + +lemma drop_bit_take_bit: + "drop_bit m (take_bit n a) = take_bit (n - m) (drop_bit m a)" +proof (cases "m \ n") + case True + then show ?thesis + using take_bit_drop_bit [of "n - m" m a] by simp +next + case False + then obtain q where \m = n + q\ + by (auto simp add: not_le dest: less_imp_Suc_add) + then have \drop_bit m (take_bit n a) = 0\ + using div_exp_eq [of \a mod 2 ^ n\ n q] + by (simp add: take_bit_eq_mod drop_bit_eq_div) + with False show ?thesis + by simp +qed + +lemma even_push_bit_iff [simp]: + \even (push_bit n a) \ n \ 0 \ even a\ + by (simp add: push_bit_eq_mult) auto + +lemma bit_push_bit_iff [bit_simps]: + \bit (push_bit m a) n \ m \ n \ 2 ^ n \ 0 \ bit a (n - m)\ + by (auto simp add: bit_iff_odd push_bit_eq_mult even_mult_exp_div_exp_iff) + +lemma bit_drop_bit_eq [bit_simps]: + \bit (drop_bit n a) = bit a \ (+) n\ + by (simp add: bit_iff_odd fun_eq_iff ac_simps flip: drop_bit_eq_div) + +lemma bit_take_bit_iff [bit_simps]: + \bit (take_bit m a) n \ n < m \ bit a n\ + by (simp add: bit_iff_odd drop_bit_take_bit not_le flip: drop_bit_eq_div) + +lemma stable_imp_drop_bit_eq: + \drop_bit n a = a\ + if \a div 2 = a\ + by (induction n) (simp_all add: that drop_bit_Suc) + +lemma stable_imp_take_bit_eq: + \take_bit n a = (if even a then 0 else 2 ^ n - 1)\ + if \a div 2 = a\ +proof (rule bit_eqI) + fix m + assume \2 ^ m \ 0\ + with that show \bit (take_bit n a) m \ bit (if even a then 0 else 2 ^ n - 1) m\ + by (simp add: bit_take_bit_iff bit_mask_iff stable_imp_bit_iff_odd) +qed + +lemma exp_dvdE: + assumes \2 ^ n dvd a\ + obtains b where \a = push_bit n b\ +proof - + from assms obtain b where \a = 2 ^ n * b\ .. + then have \a = push_bit n b\ + by (simp add: push_bit_eq_mult ac_simps) + with that show thesis . +qed + +lemma take_bit_eq_0_iff: + \take_bit n a = 0 \ 2 ^ n dvd a\ (is \?P \ ?Q\) +proof + assume ?P + then show ?Q + by (simp add: take_bit_eq_mod mod_0_imp_dvd) +next + assume ?Q + then obtain b where \a = push_bit n b\ + by (rule exp_dvdE) + then show ?P + by (simp add: take_bit_push_bit) +qed + +lemma take_bit_tightened: + \take_bit m a = take_bit m b\ if \take_bit n a = take_bit n b\ and \m \ n\ +proof - + from that have \take_bit m (take_bit n a) = take_bit m (take_bit n b)\ + by simp + then have \take_bit (min m n) a = take_bit (min m n) b\ + by simp + with that show ?thesis + by (simp add: min_def) +qed + +lemma take_bit_eq_self_iff_drop_bit_eq_0: + \take_bit n a = a \ drop_bit n a = 0\ (is \?P \ ?Q\) +proof + assume ?P + show ?Q + proof (rule bit_eqI) + fix m + from \?P\ have \a = take_bit n a\ .. + also have \\ bit (take_bit n a) (n + m)\ + unfolding bit_simps + by (simp add: bit_simps) + finally show \bit (drop_bit n a) m \ bit 0 m\ + by (simp add: bit_simps) + qed +next + assume ?Q + show ?P + proof (rule bit_eqI) + fix m + from \?Q\ have \\ bit (drop_bit n a) (m - n)\ + by simp + then have \ \ bit a (n + (m - n))\ + by (simp add: bit_simps) + then show \bit (take_bit n a) m \ bit a m\ + by (cases \m < n\) (auto simp add: bit_simps) + qed +qed + +lemma drop_bit_exp_eq: + \drop_bit m (2 ^ n) = of_bool (m \ n \ 2 ^ n \ 0) * 2 ^ (n - m)\ + by (rule bit_eqI) (auto simp add: bit_simps) + +end + +instantiation nat :: semiring_bit_shifts +begin + +definition push_bit_nat :: \nat \ nat \ nat\ + where \push_bit_nat n m = m * 2 ^ n\ + +definition drop_bit_nat :: \nat \ nat \ nat\ + where \drop_bit_nat n m = m div 2 ^ n\ + +definition take_bit_nat :: \nat \ nat \ nat\ + where \take_bit_nat n m = m mod 2 ^ n\ + +instance + by standard (simp_all add: push_bit_nat_def drop_bit_nat_def take_bit_nat_def) + +end + +context semiring_bit_shifts +begin + +lemma push_bit_of_nat: + \push_bit n (of_nat m) = of_nat (push_bit n m)\ + by (simp add: push_bit_eq_mult semiring_bit_shifts_class.push_bit_eq_mult) + +lemma of_nat_push_bit: + \of_nat (push_bit m n) = push_bit m (of_nat n)\ + by (simp add: push_bit_eq_mult semiring_bit_shifts_class.push_bit_eq_mult) + +lemma take_bit_of_nat: + \take_bit n (of_nat m) = of_nat (take_bit n m)\ + by (rule bit_eqI) (simp add: bit_take_bit_iff Bit_Operations.bit_take_bit_iff bit_of_nat_iff) + +lemma of_nat_take_bit: + \of_nat (take_bit n m) = take_bit n (of_nat m)\ + by (rule bit_eqI) (simp add: bit_take_bit_iff Bit_Operations.bit_take_bit_iff bit_of_nat_iff) + +end + +instantiation int :: semiring_bit_shifts +begin + +definition push_bit_int :: \nat \ int \ int\ + where \push_bit_int n k = k * 2 ^ n\ + +definition drop_bit_int :: \nat \ int \ int\ + where \drop_bit_int n k = k div 2 ^ n\ + +definition take_bit_int :: \nat \ int \ int\ + where \take_bit_int n k = k mod 2 ^ n\ + +instance + by standard (simp_all add: push_bit_int_def drop_bit_int_def take_bit_int_def) + +end + +lemma bit_push_bit_iff_nat: + \bit (push_bit m q) n \ m \ n \ bit q (n - m)\ for q :: nat + by (auto simp add: bit_push_bit_iff) + +lemma bit_push_bit_iff_int: + \bit (push_bit m k) n \ m \ n \ bit k (n - m)\ for k :: int + by (auto simp add: bit_push_bit_iff) + +lemma take_bit_nat_less_exp [simp]: + \take_bit n m < 2 ^ n\ for n m ::nat + by (simp add: take_bit_eq_mod) + +lemma take_bit_nonnegative [simp]: + \take_bit n k \ 0\ for k :: int + by (simp add: take_bit_eq_mod) + +lemma not_take_bit_negative [simp]: + \\ take_bit n k < 0\ for k :: int + by (simp add: not_less) + +lemma take_bit_int_less_exp [simp]: + \take_bit n k < 2 ^ n\ for k :: int + by (simp add: take_bit_eq_mod) + +lemma take_bit_nat_eq_self_iff: + \take_bit n m = m \ m < 2 ^ n\ (is \?P \ ?Q\) + for n m :: nat +proof + assume ?P + moreover note take_bit_nat_less_exp [of n m] + ultimately show ?Q + by simp +next + assume ?Q + then show ?P + by (simp add: take_bit_eq_mod) +qed + +lemma take_bit_nat_eq_self: + \take_bit n m = m\ if \m < 2 ^ n\ for m n :: nat + using that by (simp add: take_bit_nat_eq_self_iff) + +lemma take_bit_int_eq_self_iff: + \take_bit n k = k \ 0 \ k \ k < 2 ^ n\ (is \?P \ ?Q\) + for k :: int +proof + assume ?P + moreover note take_bit_int_less_exp [of n k] take_bit_nonnegative [of n k] + ultimately show ?Q + by simp +next + assume ?Q + then show ?P + by (simp add: take_bit_eq_mod) +qed + +lemma take_bit_int_eq_self: + \take_bit n k = k\ if \0 \ k\ \k < 2 ^ n\ for k :: int + using that by (simp add: take_bit_int_eq_self_iff) + +lemma take_bit_nat_less_eq_self [simp]: + \take_bit n m \ m\ for n m :: nat + by (simp add: take_bit_eq_mod) + +lemma take_bit_nat_less_self_iff: + \take_bit n m < m \ 2 ^ n \ m\ (is \?P \ ?Q\) + for m n :: nat +proof + assume ?P + then have \take_bit n m \ m\ + by simp + then show \?Q\ + by (simp add: take_bit_nat_eq_self_iff) +next + have \take_bit n m < 2 ^ n\ + by (fact take_bit_nat_less_exp) + also assume ?Q + finally show ?P . +qed + +class unique_euclidean_semiring_with_bit_shifts = + unique_euclidean_semiring_with_nat + semiring_bit_shifts +begin + +lemma take_bit_of_exp [simp]: + \take_bit m (2 ^ n) = of_bool (n < m) * 2 ^ n\ + by (simp add: take_bit_eq_mod exp_mod_exp) + +lemma take_bit_of_2 [simp]: + \take_bit n 2 = of_bool (2 \ n) * 2\ + using take_bit_of_exp [of n 1] by simp + +lemma take_bit_of_mask: + \take_bit m (2 ^ n - 1) = 2 ^ min m n - 1\ + by (simp add: take_bit_eq_mod mask_mod_exp) + +lemma push_bit_eq_0_iff [simp]: + "push_bit n a = 0 \ a = 0" + by (simp add: push_bit_eq_mult) + +lemma take_bit_add: + "take_bit n (take_bit n a + take_bit n b) = take_bit n (a + b)" + by (simp add: take_bit_eq_mod mod_simps) + +lemma take_bit_of_1_eq_0_iff [simp]: + "take_bit n 1 = 0 \ n = 0" + by (simp add: take_bit_eq_mod) + +lemma take_bit_Suc_1 [simp]: + \take_bit (Suc n) 1 = 1\ + by (simp add: take_bit_Suc) + +lemma take_bit_Suc_bit0 [simp]: + \take_bit (Suc n) (numeral (Num.Bit0 k)) = take_bit n (numeral k) * 2\ + by (simp add: take_bit_Suc numeral_Bit0_div_2) + +lemma take_bit_Suc_bit1 [simp]: + \take_bit (Suc n) (numeral (Num.Bit1 k)) = take_bit n (numeral k) * 2 + 1\ + by (simp add: take_bit_Suc numeral_Bit1_div_2 mod_2_eq_odd) + +lemma take_bit_numeral_1 [simp]: + \take_bit (numeral l) 1 = 1\ + by (simp add: take_bit_rec [of \numeral l\ 1]) + +lemma take_bit_numeral_bit0 [simp]: + \take_bit (numeral l) (numeral (Num.Bit0 k)) = take_bit (pred_numeral l) (numeral k) * 2\ + by (simp add: take_bit_rec numeral_Bit0_div_2) + +lemma take_bit_numeral_bit1 [simp]: + \take_bit (numeral l) (numeral (Num.Bit1 k)) = take_bit (pred_numeral l) (numeral k) * 2 + 1\ + by (simp add: take_bit_rec numeral_Bit1_div_2 mod_2_eq_odd) + +lemma drop_bit_Suc_bit0 [simp]: + \drop_bit (Suc n) (numeral (Num.Bit0 k)) = drop_bit n (numeral k)\ + by (simp add: drop_bit_Suc numeral_Bit0_div_2) + +lemma drop_bit_Suc_bit1 [simp]: + \drop_bit (Suc n) (numeral (Num.Bit1 k)) = drop_bit n (numeral k)\ + by (simp add: drop_bit_Suc numeral_Bit1_div_2) + +lemma drop_bit_numeral_bit0 [simp]: + \drop_bit (numeral l) (numeral (Num.Bit0 k)) = drop_bit (pred_numeral l) (numeral k)\ + by (simp add: drop_bit_rec numeral_Bit0_div_2) + +lemma drop_bit_numeral_bit1 [simp]: + \drop_bit (numeral l) (numeral (Num.Bit1 k)) = drop_bit (pred_numeral l) (numeral k)\ + by (simp add: drop_bit_rec numeral_Bit1_div_2) + +lemma drop_bit_of_nat: + "drop_bit n (of_nat m) = of_nat (drop_bit n m)" + by (simp add: drop_bit_eq_div Bit_Operations.drop_bit_eq_div of_nat_div [of m "2 ^ n"]) + +lemma bit_of_nat_iff_bit [bit_simps]: + \bit (of_nat m) n \ bit m n\ +proof - + have \even (m div 2 ^ n) \ even (of_nat (m div 2 ^ n))\ + by simp + also have \of_nat (m div 2 ^ n) = of_nat m div of_nat (2 ^ n)\ + by (simp add: of_nat_div) + finally show ?thesis + by (simp add: bit_iff_odd semiring_bits_class.bit_iff_odd) +qed + +lemma of_nat_drop_bit: + \of_nat (drop_bit m n) = drop_bit m (of_nat n)\ + by (simp add: drop_bit_eq_div semiring_bit_shifts_class.drop_bit_eq_div of_nat_div) + +lemma bit_push_bit_iff_of_nat_iff [bit_simps]: + \bit (push_bit m (of_nat r)) n \ m \ n \ bit (of_nat r) (n - m)\ + by (auto simp add: bit_push_bit_iff) + +lemma take_bit_sum: + "take_bit n a = (\k = 0..k = 0..k = Suc 0..k = Suc 0..k = 0..bit (numeral m :: int) n \ bit (numeral m :: nat) n\ + using bit_of_nat_iff_bit [of \numeral m\ n] by simp + +lemma bit_not_int_iff': + \bit (- k - 1) n \ \ bit k n\ + for k :: int +proof (induction n arbitrary: k) + case 0 + show ?case + by simp +next + case (Suc n) + have \- k - 1 = - (k + 2) + 1\ + by simp + also have \(- (k + 2) + 1) div 2 = - (k div 2) - 1\ + proof (cases \even k\) + case True + then have \- k div 2 = - (k div 2)\ + by rule (simp flip: mult_minus_right) + with True show ?thesis + by simp + next + case False + have \4 = 2 * (2::int)\ + by simp + also have \2 * 2 div 2 = (2::int)\ + by (simp only: nonzero_mult_div_cancel_left) + finally have *: \4 div 2 = (2::int)\ . + from False obtain l where k: \k = 2 * l + 1\ .. + then have \- k - 2 = 2 * - (l + 2) + 1\ + by simp + then have \(- k - 2) div 2 + 1 = - (k div 2) - 1\ + by (simp flip: mult_minus_right add: *) (simp add: k) + with False show ?thesis + by simp + qed + finally have \(- k - 1) div 2 = - (k div 2) - 1\ . + with Suc show ?case + by (simp add: bit_Suc) +qed + +lemma bit_minus_int_iff [bit_simps]: + \bit (- k) n \ \ bit (k - 1) n\ + for k :: int + using bit_not_int_iff' [of \k - 1\] by simp + +lemma bit_nat_iff [bit_simps]: + \bit (nat k) n \ k \ 0 \ bit k n\ +proof (cases \k \ 0\) + case True + moreover define m where \m = nat k\ + ultimately have \k = int m\ + by simp + then show ?thesis + by (simp add: bit_simps) +next + case False + then show ?thesis + by simp +qed + +lemma bit_numeral_int_simps [simp]: + \bit (1 :: int) (numeral n) \ bit (0 :: int) (pred_numeral n)\ + \bit (numeral (num.Bit0 w) :: int) (numeral n) \ bit (numeral w :: int) (pred_numeral n)\ + \bit (numeral (num.Bit1 w) :: int) (numeral n) \ bit (numeral w :: int) (pred_numeral n)\ + \bit (numeral (Num.BitM w) :: int) (numeral n) \ \ bit (- numeral w :: int) (pred_numeral n)\ + \bit (- numeral (num.Bit0 w) :: int) (numeral n) \ bit (- numeral w :: int) (pred_numeral n)\ + \bit (- numeral (num.Bit1 w) :: int) (numeral n) \ \ bit (numeral w :: int) (pred_numeral n)\ + \bit (- numeral (Num.BitM w) :: int) (numeral n) \ bit (- (numeral w) :: int) (pred_numeral n)\ + by (simp_all add: bit_1_iff numeral_eq_Suc bit_Suc add_One sub_inc_One_eq bit_minus_int_iff) + +lemma bit_numeral_Bit0_Suc_iff [simp]: + \bit (numeral (Num.Bit0 m) :: int) (Suc n) \ bit (numeral m :: int) n\ + by (simp add: bit_Suc) + +lemma bit_numeral_Bit1_Suc_iff [simp]: + \bit (numeral (Num.Bit1 m) :: int) (Suc n) \ bit (numeral m :: int) n\ + by (simp add: bit_Suc) + +lemma push_bit_nat_eq: + \push_bit n (nat k) = nat (push_bit n k)\ + by (cases \k \ 0\) (simp_all add: push_bit_eq_mult nat_mult_distrib not_le mult_nonneg_nonpos2) + +lemma drop_bit_nat_eq: + \drop_bit n (nat k) = nat (drop_bit n k)\ + apply (cases \k \ 0\) + apply (simp_all add: drop_bit_eq_div nat_div_distrib nat_power_eq not_le) + apply (simp add: divide_int_def) + done + +lemma take_bit_nat_eq: + \take_bit n (nat k) = nat (take_bit n k)\ if \k \ 0\ + using that by (simp add: take_bit_eq_mod nat_mod_distrib nat_power_eq) + +lemma nat_take_bit_eq: + \nat (take_bit n k) = take_bit n (nat k)\ + if \k \ 0\ + using that by (simp add: take_bit_eq_mod nat_mod_distrib nat_power_eq) + +lemma not_exp_less_eq_0_int [simp]: + \\ 2 ^ n \ (0::int)\ + by (simp add: power_le_zero_eq) + +lemma half_nonnegative_int_iff [simp]: + \k div 2 \ 0 \ k \ 0\ for k :: int +proof (cases \k \ 0\) + case True + then show ?thesis + by (auto simp add: divide_int_def sgn_1_pos) +next + case False + then show ?thesis + by (auto simp add: divide_int_def not_le elim!: evenE) +qed + +lemma half_negative_int_iff [simp]: + \k div 2 < 0 \ k < 0\ for k :: int + by (subst Not_eq_iff [symmetric]) (simp add: not_less) + +lemma push_bit_of_Suc_0 [simp]: + "push_bit n (Suc 0) = 2 ^ n" + using push_bit_of_1 [where ?'a = nat] by simp + +lemma take_bit_of_Suc_0 [simp]: + "take_bit n (Suc 0) = of_bool (0 < n)" + using take_bit_of_1 [where ?'a = nat] by simp + +lemma drop_bit_of_Suc_0 [simp]: + "drop_bit n (Suc 0) = of_bool (n = 0)" + using drop_bit_of_1 [where ?'a = nat] by simp + +lemma push_bit_minus_one: + "push_bit n (- 1 :: int) = - (2 ^ n)" + by (simp add: push_bit_eq_mult) + +lemma minus_1_div_exp_eq_int: + \- 1 div (2 :: int) ^ n = - 1\ + by (induction n) (use div_exp_eq [symmetric, of \- 1 :: int\ 1] in \simp_all add: ac_simps\) + +lemma drop_bit_minus_one [simp]: + \drop_bit n (- 1 :: int) = - 1\ + by (simp add: drop_bit_eq_div minus_1_div_exp_eq_int) + +lemma take_bit_Suc_from_most: + \take_bit (Suc n) k = 2 ^ n * of_bool (bit k n) + take_bit n k\ for k :: int + by (simp only: take_bit_eq_mod power_Suc2) (simp_all add: bit_iff_odd odd_iff_mod_2_eq_one zmod_zmult2_eq) + +lemma take_bit_minus: + \take_bit n (- take_bit n k) = take_bit n (- k)\ + for k :: int + by (simp add: take_bit_eq_mod mod_minus_eq) + +lemma take_bit_diff: + \take_bit n (take_bit n k - take_bit n l) = take_bit n (k - l)\ + for k l :: int + by (simp add: take_bit_eq_mod mod_diff_eq) + +lemma bit_imp_take_bit_positive: + \0 < take_bit m k\ if \n < m\ and \bit k n\ for k :: int +proof (rule ccontr) + assume \\ 0 < take_bit m k\ + then have \take_bit m k = 0\ + by (auto simp add: not_less intro: order_antisym) + then have \bit (take_bit m k) n = bit 0 n\ + by simp + with that show False + by (simp add: bit_take_bit_iff) +qed + +lemma take_bit_mult: + \take_bit n (take_bit n k * take_bit n l) = take_bit n (k * l)\ + for k l :: int + by (simp add: take_bit_eq_mod mod_mult_eq) + +lemma (in ring_1) of_nat_nat_take_bit_eq [simp]: + \of_nat (nat (take_bit n k)) = of_int (take_bit n k)\ + by simp + +lemma take_bit_minus_small_eq: + \take_bit n (- k) = 2 ^ n - k\ if \0 < k\ \k \ 2 ^ n\ for k :: int +proof - + define m where \m = nat k\ + with that have \k = int m\ and \0 < m\ and \m \ 2 ^ n\ + by simp_all + have \(2 ^ n - m) mod 2 ^ n = 2 ^ n - m\ + using \0 < m\ by simp + then have \int ((2 ^ n - m) mod 2 ^ n) = int (2 ^ n - m)\ + by simp + then have \(2 ^ n - int m) mod 2 ^ n = 2 ^ n - int m\ + using \m \ 2 ^ n\ by (simp only: of_nat_mod of_nat_diff) simp + with \k = int m\ have \(2 ^ n - k) mod 2 ^ n = 2 ^ n - k\ + by simp + then show ?thesis + by (simp add: take_bit_eq_mod) +qed + +lemma drop_bit_push_bit_int: + \drop_bit m (push_bit n k) = drop_bit (m - n) (push_bit (n - m) k)\ for k :: int + by (cases \m \ n\) (auto simp add: mult.left_commute [of _ \2 ^ n\] mult.commute [of _ \2 ^ n\] mult.assoc + mult.commute [of k] drop_bit_eq_div push_bit_eq_mult not_le power_add dest!: le_Suc_ex less_imp_Suc_add) + +lemma push_bit_nonnegative_int_iff [simp]: + \push_bit n k \ 0 \ k \ 0\ for k :: int + by (simp add: push_bit_eq_mult zero_le_mult_iff) + +lemma push_bit_negative_int_iff [simp]: + \push_bit n k < 0 \ k < 0\ for k :: int + by (subst Not_eq_iff [symmetric]) (simp add: not_less) + +lemma drop_bit_nonnegative_int_iff [simp]: + \drop_bit n k \ 0 \ k \ 0\ for k :: int + by (induction n) (simp_all add: drop_bit_Suc drop_bit_half) + +lemma drop_bit_negative_int_iff [simp]: + \drop_bit n k < 0 \ k < 0\ for k :: int + by (subst Not_eq_iff [symmetric]) (simp add: not_less) + + +subsection \Bit operations\ + +class semiring_bit_operations = semiring_bit_shifts + + fixes "and" :: \'a \ 'a \ 'a\ (infixr \AND\ 64) + and or :: \'a \ 'a \ 'a\ (infixr \OR\ 59) + and xor :: \'a \ 'a \ 'a\ (infixr \XOR\ 59) + and mask :: \nat \ 'a\ + and set_bit :: \nat \ 'a \ 'a\ + and unset_bit :: \nat \ 'a \ 'a\ + and flip_bit :: \nat \ 'a \ 'a\ + assumes bit_and_iff [bit_simps]: \bit (a AND b) n \ bit a n \ bit b n\ + and bit_or_iff [bit_simps]: \bit (a OR b) n \ bit a n \ bit b n\ + and bit_xor_iff [bit_simps]: \bit (a XOR b) n \ bit a n \ bit b n\ + and mask_eq_exp_minus_1: \mask n = 2 ^ n - 1\ + and set_bit_eq_or: \set_bit n a = a OR push_bit n 1\ + and bit_unset_bit_iff [bit_simps]: \bit (unset_bit m a) n \ bit a n \ m \ n\ + and flip_bit_eq_xor: \flip_bit n a = a XOR push_bit n 1\ +begin + +text \ + We want the bitwise operations to bind slightly weaker + than \+\ and \-\. + For the sake of code generation + the operations \<^const>\and\, \<^const>\or\ and \<^const>\xor\ + are specified as definitional class operations. +\ + +sublocale "and": semilattice \(AND)\ + by standard (auto simp add: bit_eq_iff bit_and_iff) + +sublocale or: semilattice_neutr \(OR)\ 0 + by standard (auto simp add: bit_eq_iff bit_or_iff) + +sublocale xor: comm_monoid \(XOR)\ 0 + by standard (auto simp add: bit_eq_iff bit_xor_iff) + +lemma even_and_iff: + \even (a AND b) \ even a \ even b\ + using bit_and_iff [of a b 0] by auto + +lemma even_or_iff: + \even (a OR b) \ even a \ even b\ + using bit_or_iff [of a b 0] by auto + +lemma even_xor_iff: + \even (a XOR b) \ (even a \ even b)\ + using bit_xor_iff [of a b 0] by auto + +lemma zero_and_eq [simp]: + \0 AND a = 0\ + by (simp add: bit_eq_iff bit_and_iff) + +lemma and_zero_eq [simp]: + \a AND 0 = 0\ + by (simp add: bit_eq_iff bit_and_iff) + +lemma one_and_eq: + \1 AND a = a mod 2\ + by (simp add: bit_eq_iff bit_and_iff) (auto simp add: bit_1_iff) + +lemma and_one_eq: + \a AND 1 = a mod 2\ + using one_and_eq [of a] by (simp add: ac_simps) + +lemma one_or_eq: + \1 OR a = a + of_bool (even a)\ + by (simp add: bit_eq_iff bit_or_iff add.commute [of _ 1] even_bit_succ_iff) (auto simp add: bit_1_iff) + +lemma or_one_eq: + \a OR 1 = a + of_bool (even a)\ + using one_or_eq [of a] by (simp add: ac_simps) + +lemma one_xor_eq: + \1 XOR a = a + of_bool (even a) - of_bool (odd a)\ + by (simp add: bit_eq_iff bit_xor_iff add.commute [of _ 1] even_bit_succ_iff) (auto simp add: bit_1_iff odd_bit_iff_bit_pred elim: oddE) + +lemma xor_one_eq: + \a XOR 1 = a + of_bool (even a) - of_bool (odd a)\ + using one_xor_eq [of a] by (simp add: ac_simps) + +lemma take_bit_and [simp]: + \take_bit n (a AND b) = take_bit n a AND take_bit n b\ + by (auto simp add: bit_eq_iff bit_take_bit_iff bit_and_iff) + +lemma take_bit_or [simp]: + \take_bit n (a OR b) = take_bit n a OR take_bit n b\ + by (auto simp add: bit_eq_iff bit_take_bit_iff bit_or_iff) + +lemma take_bit_xor [simp]: + \take_bit n (a XOR b) = take_bit n a XOR take_bit n b\ + by (auto simp add: bit_eq_iff bit_take_bit_iff bit_xor_iff) + +lemma push_bit_and [simp]: + \push_bit n (a AND b) = push_bit n a AND push_bit n b\ + by (rule bit_eqI) (auto simp add: bit_push_bit_iff bit_and_iff) + +lemma push_bit_or [simp]: + \push_bit n (a OR b) = push_bit n a OR push_bit n b\ + by (rule bit_eqI) (auto simp add: bit_push_bit_iff bit_or_iff) + +lemma push_bit_xor [simp]: + \push_bit n (a XOR b) = push_bit n a XOR push_bit n b\ + by (rule bit_eqI) (auto simp add: bit_push_bit_iff bit_xor_iff) + +lemma drop_bit_and [simp]: + \drop_bit n (a AND b) = drop_bit n a AND drop_bit n b\ + by (rule bit_eqI) (auto simp add: bit_drop_bit_eq bit_and_iff) + +lemma drop_bit_or [simp]: + \drop_bit n (a OR b) = drop_bit n a OR drop_bit n b\ + by (rule bit_eqI) (auto simp add: bit_drop_bit_eq bit_or_iff) + +lemma drop_bit_xor [simp]: + \drop_bit n (a XOR b) = drop_bit n a XOR drop_bit n b\ + by (rule bit_eqI) (auto simp add: bit_drop_bit_eq bit_xor_iff) + +lemma bit_mask_iff [bit_simps]: + \bit (mask m) n \ 2 ^ n \ 0 \ n < m\ + by (simp add: mask_eq_exp_minus_1 bit_mask_iff) + +lemma even_mask_iff: + \even (mask n) \ n = 0\ + using bit_mask_iff [of n 0] by auto + +lemma mask_0 [simp]: + \mask 0 = 0\ + by (simp add: mask_eq_exp_minus_1) + +lemma mask_Suc_0 [simp]: + \mask (Suc 0) = 1\ + by (simp add: mask_eq_exp_minus_1 add_implies_diff sym) + +lemma mask_Suc_exp: + \mask (Suc n) = 2 ^ n OR mask n\ + by (rule bit_eqI) + (auto simp add: bit_or_iff bit_mask_iff bit_exp_iff not_less le_less_Suc_eq) + +lemma mask_Suc_double: + \mask (Suc n) = 1 OR 2 * mask n\ +proof (rule bit_eqI) + fix q + assume \2 ^ q \ 0\ + show \bit (mask (Suc n)) q \ bit (1 OR 2 * mask n) q\ + by (cases q) + (simp_all add: even_mask_iff even_or_iff bit_or_iff bit_mask_iff bit_exp_iff bit_double_iff not_less le_less_Suc_eq bit_1_iff, auto simp add: mult_2) +qed + +lemma mask_numeral: + \mask (numeral n) = 1 + 2 * mask (pred_numeral n)\ + by (simp add: numeral_eq_Suc mask_Suc_double one_or_eq ac_simps) + +lemma take_bit_mask [simp]: + \take_bit m (mask n) = mask (min m n)\ + by (rule bit_eqI) (simp add: bit_simps) + +lemma take_bit_eq_mask: + \take_bit n a = a AND mask n\ + by (rule bit_eqI) + (auto simp add: bit_take_bit_iff bit_and_iff bit_mask_iff) + +lemma or_eq_0_iff: + \a OR b = 0 \ a = 0 \ b = 0\ + by (auto simp add: bit_eq_iff bit_or_iff) + +lemma disjunctive_add: + \a + b = a OR b\ if \\n. \ bit a n \ \ bit b n\ + by (rule bit_eqI) (use that in \simp add: bit_disjunctive_add_iff bit_or_iff\) + +lemma bit_iff_and_drop_bit_eq_1: + \bit a n \ drop_bit n a AND 1 = 1\ + by (simp add: bit_iff_odd_drop_bit and_one_eq odd_iff_mod_2_eq_one) + +lemma bit_iff_and_push_bit_not_eq_0: + \bit a n \ a AND push_bit n 1 \ 0\ + apply (cases \2 ^ n = 0\) + apply (simp_all add: push_bit_of_1 bit_eq_iff bit_and_iff bit_push_bit_iff exp_eq_0_imp_not_bit) + apply (simp_all add: bit_exp_iff) + done + +lemmas set_bit_def = set_bit_eq_or + +lemma bit_set_bit_iff [bit_simps]: + \bit (set_bit m a) n \ bit a n \ (m = n \ 2 ^ n \ 0)\ + by (auto simp add: set_bit_def push_bit_of_1 bit_or_iff bit_exp_iff) + +lemma even_set_bit_iff: + \even (set_bit m a) \ even a \ m \ 0\ + using bit_set_bit_iff [of m a 0] by auto + +lemma even_unset_bit_iff: + \even (unset_bit m a) \ even a \ m = 0\ + using bit_unset_bit_iff [of m a 0] by auto + +lemma and_exp_eq_0_iff_not_bit: + \a AND 2 ^ n = 0 \ \ bit a n\ (is \?P \ ?Q\) +proof + assume ?Q + then show ?P + by (auto intro: bit_eqI simp add: bit_simps) +next + assume ?P + show ?Q + proof (rule notI) + assume \bit a n\ + then have \a AND 2 ^ n = 2 ^ n\ + by (auto intro: bit_eqI simp add: bit_simps) + with \?P\ show False + using \bit a n\ exp_eq_0_imp_not_bit by auto + qed +qed + +lemmas flip_bit_def = flip_bit_eq_xor + +lemma bit_flip_bit_iff [bit_simps]: + \bit (flip_bit m a) n \ (m = n \ \ bit a n) \ 2 ^ n \ 0\ + by (auto simp add: flip_bit_def push_bit_of_1 bit_xor_iff bit_exp_iff exp_eq_0_imp_not_bit) + +lemma even_flip_bit_iff: + \even (flip_bit m a) \ \ (even a \ m = 0)\ + using bit_flip_bit_iff [of m a 0] by auto + +lemma set_bit_0 [simp]: + \set_bit 0 a = 1 + 2 * (a div 2)\ +proof (rule bit_eqI) + fix m + assume *: \2 ^ m \ 0\ + then show \bit (set_bit 0 a) m = bit (1 + 2 * (a div 2)) m\ + by (simp add: bit_set_bit_iff bit_double_iff even_bit_succ_iff) + (cases m, simp_all add: bit_Suc) +qed + +lemma set_bit_Suc: + \set_bit (Suc n) a = a mod 2 + 2 * set_bit n (a div 2)\ +proof (rule bit_eqI) + fix m + assume *: \2 ^ m \ 0\ + show \bit (set_bit (Suc n) a) m \ bit (a mod 2 + 2 * set_bit n (a div 2)) m\ + proof (cases m) + case 0 + then show ?thesis + by (simp add: even_set_bit_iff) + next + case (Suc m) + with * have \2 ^ m \ 0\ + using mult_2 by auto + show ?thesis + by (cases a rule: parity_cases) + (simp_all add: bit_set_bit_iff bit_double_iff even_bit_succ_iff *, + simp_all add: Suc \2 ^ m \ 0\ bit_Suc) + qed +qed + +lemma unset_bit_0 [simp]: + \unset_bit 0 a = 2 * (a div 2)\ +proof (rule bit_eqI) + fix m + assume *: \2 ^ m \ 0\ + then show \bit (unset_bit 0 a) m = bit (2 * (a div 2)) m\ + by (simp add: bit_unset_bit_iff bit_double_iff) + (cases m, simp_all add: bit_Suc) +qed + +lemma unset_bit_Suc: + \unset_bit (Suc n) a = a mod 2 + 2 * unset_bit n (a div 2)\ +proof (rule bit_eqI) + fix m + assume *: \2 ^ m \ 0\ + then show \bit (unset_bit (Suc n) a) m \ bit (a mod 2 + 2 * unset_bit n (a div 2)) m\ + proof (cases m) + case 0 + then show ?thesis + by (simp add: even_unset_bit_iff) + next + case (Suc m) + show ?thesis + by (cases a rule: parity_cases) + (simp_all add: bit_unset_bit_iff bit_double_iff even_bit_succ_iff *, + simp_all add: Suc bit_Suc) + qed +qed + +lemma flip_bit_0 [simp]: + \flip_bit 0 a = of_bool (even a) + 2 * (a div 2)\ +proof (rule bit_eqI) + fix m + assume *: \2 ^ m \ 0\ + then show \bit (flip_bit 0 a) m = bit (of_bool (even a) + 2 * (a div 2)) m\ + by (simp add: bit_flip_bit_iff bit_double_iff even_bit_succ_iff) + (cases m, simp_all add: bit_Suc) +qed + +lemma flip_bit_Suc: + \flip_bit (Suc n) a = a mod 2 + 2 * flip_bit n (a div 2)\ +proof (rule bit_eqI) + fix m + assume *: \2 ^ m \ 0\ + show \bit (flip_bit (Suc n) a) m \ bit (a mod 2 + 2 * flip_bit n (a div 2)) m\ + proof (cases m) + case 0 + then show ?thesis + by (simp add: even_flip_bit_iff) + next + case (Suc m) + with * have \2 ^ m \ 0\ + using mult_2 by auto + show ?thesis + by (cases a rule: parity_cases) + (simp_all add: bit_flip_bit_iff bit_double_iff even_bit_succ_iff, + simp_all add: Suc \2 ^ m \ 0\ bit_Suc) + qed +qed + +lemma flip_bit_eq_if: + \flip_bit n a = (if bit a n then unset_bit else set_bit) n a\ + by (rule bit_eqI) (auto simp add: bit_set_bit_iff bit_unset_bit_iff bit_flip_bit_iff) + +lemma take_bit_set_bit_eq: + \take_bit n (set_bit m a) = (if n \ m then take_bit n a else set_bit m (take_bit n a))\ + by (rule bit_eqI) (auto simp add: bit_take_bit_iff bit_set_bit_iff) + +lemma take_bit_unset_bit_eq: + \take_bit n (unset_bit m a) = (if n \ m then take_bit n a else unset_bit m (take_bit n a))\ + by (rule bit_eqI) (auto simp add: bit_take_bit_iff bit_unset_bit_iff) + +lemma take_bit_flip_bit_eq: + \take_bit n (flip_bit m a) = (if n \ m then take_bit n a else flip_bit m (take_bit n a))\ + by (rule bit_eqI) (auto simp add: bit_take_bit_iff bit_flip_bit_iff) + + +end + +class ring_bit_operations = semiring_bit_operations + ring_parity + + fixes not :: \'a \ 'a\ (\NOT\) + assumes bit_not_iff [bit_simps]: \\n. bit (NOT a) n \ 2 ^ n \ 0 \ \ bit a n\ + assumes minus_eq_not_minus_1: \- a = NOT (a - 1)\ +begin + +text \ + For the sake of code generation \<^const>\not\ is specified as + definitional class operation. Note that \<^const>\not\ has no + sensible definition for unlimited but only positive bit strings + (type \<^typ>\nat\). +\ + +lemma bits_minus_1_mod_2_eq [simp]: + \(- 1) mod 2 = 1\ + by (simp add: mod_2_eq_odd) + +lemma not_eq_complement: + \NOT a = - a - 1\ + using minus_eq_not_minus_1 [of \a + 1\] by simp + +lemma minus_eq_not_plus_1: + \- a = NOT a + 1\ + using not_eq_complement [of a] by simp + +lemma bit_minus_iff [bit_simps]: + \bit (- a) n \ 2 ^ n \ 0 \ \ bit (a - 1) n\ + by (simp add: minus_eq_not_minus_1 bit_not_iff) + +lemma even_not_iff [simp]: + \even (NOT a) \ odd a\ + using bit_not_iff [of a 0] by auto + +lemma bit_not_exp_iff [bit_simps]: + \bit (NOT (2 ^ m)) n \ 2 ^ n \ 0 \ n \ m\ + by (auto simp add: bit_not_iff bit_exp_iff) + +lemma bit_minus_1_iff [simp]: + \bit (- 1) n \ 2 ^ n \ 0\ + by (simp add: bit_minus_iff) + +lemma bit_minus_exp_iff [bit_simps]: + \bit (- (2 ^ m)) n \ 2 ^ n \ 0 \ n \ m\ + by (auto simp add: bit_simps simp flip: mask_eq_exp_minus_1) + +lemma bit_minus_2_iff [simp]: + \bit (- 2) n \ 2 ^ n \ 0 \ n > 0\ + by (simp add: bit_minus_iff bit_1_iff) + +lemma not_one [simp]: + \NOT 1 = - 2\ + by (simp add: bit_eq_iff bit_not_iff) (simp add: bit_1_iff) + +sublocale "and": semilattice_neutr \(AND)\ \- 1\ + by standard (rule bit_eqI, simp add: bit_and_iff) + +sublocale bit: boolean_algebra \(AND)\ \(OR)\ NOT 0 \- 1\ + rewrites \bit.xor = (XOR)\ +proof - + interpret bit: boolean_algebra \(AND)\ \(OR)\ NOT 0 \- 1\ + by standard (auto simp add: bit_and_iff bit_or_iff bit_not_iff intro: bit_eqI) + show \boolean_algebra (AND) (OR) NOT 0 (- 1)\ + by standard + show \boolean_algebra.xor (AND) (OR) NOT = (XOR)\ + by (rule ext, rule ext, rule bit_eqI) + (auto simp add: bit.xor_def bit_and_iff bit_or_iff bit_xor_iff bit_not_iff) +qed + +lemma and_eq_not_not_or: + \a AND b = NOT (NOT a OR NOT b)\ + by simp + +lemma or_eq_not_not_and: + \a OR b = NOT (NOT a AND NOT b)\ + by simp + +lemma not_add_distrib: + \NOT (a + b) = NOT a - b\ + by (simp add: not_eq_complement algebra_simps) + +lemma not_diff_distrib: + \NOT (a - b) = NOT a + b\ + using not_add_distrib [of a \- b\] by simp + +lemma (in ring_bit_operations) and_eq_minus_1_iff: + \a AND b = - 1 \ a = - 1 \ b = - 1\ +proof + assume \a = - 1 \ b = - 1\ + then show \a AND b = - 1\ + by simp +next + assume \a AND b = - 1\ + have *: \bit a n\ \bit b n\ if \2 ^ n \ 0\ for n + proof - + from \a AND b = - 1\ + have \bit (a AND b) n = bit (- 1) n\ + by (simp add: bit_eq_iff) + then show \bit a n\ \bit b n\ + using that by (simp_all add: bit_and_iff) + qed + have \a = - 1\ + by (rule bit_eqI) (simp add: *) + moreover have \b = - 1\ + by (rule bit_eqI) (simp add: *) + ultimately show \a = - 1 \ b = - 1\ + by simp +qed + +lemma disjunctive_diff: + \a - b = a AND NOT b\ if \\n. bit b n \ bit a n\ +proof - + have \NOT a + b = NOT a OR b\ + by (rule disjunctive_add) (auto simp add: bit_not_iff dest: that) + then have \NOT (NOT a + b) = NOT (NOT a OR b)\ + by simp + then show ?thesis + by (simp add: not_add_distrib) +qed + +lemma push_bit_minus: + \push_bit n (- a) = - push_bit n a\ + by (simp add: push_bit_eq_mult) + +lemma take_bit_not_take_bit: + \take_bit n (NOT (take_bit n a)) = take_bit n (NOT a)\ + by (auto simp add: bit_eq_iff bit_take_bit_iff bit_not_iff) + +lemma take_bit_not_iff: + \take_bit n (NOT a) = take_bit n (NOT b) \ take_bit n a = take_bit n b\ + apply (simp add: bit_eq_iff) + apply (simp add: bit_not_iff bit_take_bit_iff bit_exp_iff) + apply (use exp_eq_0_imp_not_bit in blast) + done + +lemma take_bit_not_eq_mask_diff: + \take_bit n (NOT a) = mask n - take_bit n a\ +proof - + have \take_bit n (NOT a) = take_bit n (NOT (take_bit n a))\ + by (simp add: take_bit_not_take_bit) + also have \\ = mask n AND NOT (take_bit n a)\ + by (simp add: take_bit_eq_mask ac_simps) + also have \\ = mask n - take_bit n a\ + by (subst disjunctive_diff) + (auto simp add: bit_take_bit_iff bit_mask_iff exp_eq_0_imp_not_bit) + finally show ?thesis + by simp +qed + +lemma mask_eq_take_bit_minus_one: + \mask n = take_bit n (- 1)\ + by (simp add: bit_eq_iff bit_mask_iff bit_take_bit_iff conj_commute) + +lemma take_bit_minus_one_eq_mask: + \take_bit n (- 1) = mask n\ + by (simp add: mask_eq_take_bit_minus_one) + +lemma minus_exp_eq_not_mask: + \- (2 ^ n) = NOT (mask n)\ + by (rule bit_eqI) (simp add: bit_minus_iff bit_not_iff flip: mask_eq_exp_minus_1) + +lemma push_bit_minus_one_eq_not_mask: + \push_bit n (- 1) = NOT (mask n)\ + by (simp add: push_bit_eq_mult minus_exp_eq_not_mask) + +lemma take_bit_not_mask_eq_0: + \take_bit m (NOT (mask n)) = 0\ if \n \ m\ + by (rule bit_eqI) (use that in \simp add: bit_take_bit_iff bit_not_iff bit_mask_iff\) + +lemma unset_bit_eq_and_not: + \unset_bit n a = a AND NOT (push_bit n 1)\ + by (rule bit_eqI) (auto simp add: bit_simps) + +lemmas unset_bit_def = unset_bit_eq_and_not + +end + + +subsection \Instance \<^typ>\int\\ + +lemma int_bit_bound: + fixes k :: int + obtains n where \\m. n \ m \ bit k m \ bit k n\ + and \n > 0 \ bit k (n - 1) \ bit k n\ +proof - + obtain q where *: \\m. q \ m \ bit k m \ bit k q\ + proof (cases \k \ 0\) + case True + moreover from power_gt_expt [of 2 \nat k\] + have \nat k < 2 ^ nat k\ + by simp + then have \int (nat k) < int (2 ^ nat k)\ + by (simp only: of_nat_less_iff) + ultimately have *: \k div 2 ^ nat k = 0\ + by simp + show thesis + proof (rule that [of \nat k\]) + fix m + assume \nat k \ m\ + then show \bit k m \ bit k (nat k)\ + by (auto simp add: * bit_iff_odd power_add zdiv_zmult2_eq dest!: le_Suc_ex) + qed + next + case False + moreover from power_gt_expt [of 2 \nat (- k)\] + have \nat (- k) < 2 ^ nat (- k)\ + by simp + then have \int (nat (- k)) < int (2 ^ nat (- k))\ + by (simp only: of_nat_less_iff) + ultimately have \- k div - (2 ^ nat (- k)) = - 1\ + by (subst div_pos_neg_trivial) simp_all + then have *: \k div 2 ^ nat (- k) = - 1\ + by simp + show thesis + proof (rule that [of \nat (- k)\]) + fix m + assume \nat (- k) \ m\ + then show \bit k m \ bit k (nat (- k))\ + by (auto simp add: * bit_iff_odd power_add zdiv_zmult2_eq minus_1_div_exp_eq_int dest!: le_Suc_ex) + qed + qed + show thesis + proof (cases \\m. bit k m \ bit k q\) + case True + then have \bit k 0 \ bit k q\ + by blast + with True that [of 0] show thesis + by simp + next + case False + then obtain r where **: \bit k r \ bit k q\ + by blast + have \r < q\ + by (rule ccontr) (use * [of r] ** in simp) + define N where \N = {n. n < q \ bit k n \ bit k q}\ + moreover have \finite N\ \r \ N\ + using ** N_def \r < q\ by auto + moreover define n where \n = Suc (Max N)\ + ultimately have \\m. n \ m \ bit k m \ bit k n\ + apply auto + apply (metis (full_types, lifting) "*" Max_ge_iff Suc_n_not_le_n \finite N\ all_not_in_conv mem_Collect_eq not_le) + apply (metis "*" Max_ge Suc_n_not_le_n \finite N\ linorder_not_less mem_Collect_eq) + apply (metis "*" Max_ge Suc_n_not_le_n \finite N\ linorder_not_less mem_Collect_eq) + apply (metis (full_types, lifting) "*" Max_ge_iff Suc_n_not_le_n \finite N\ all_not_in_conv mem_Collect_eq not_le) + done + have \bit k (Max N) \ bit k n\ + by (metis (mono_tags, lifting) "*" Max_in N_def \\m. n \ m \ bit k m = bit k n\ \finite N\ \r \ N\ empty_iff le_cases mem_Collect_eq) + show thesis apply (rule that [of n]) + using \\m. n \ m \ bit k m = bit k n\ apply blast + using \bit k (Max N) \ bit k n\ n_def by auto + qed +qed + +instantiation int :: ring_bit_operations +begin + +definition not_int :: \int \ int\ + where \not_int k = - k - 1\ + +lemma not_int_rec: + \NOT k = of_bool (even k) + 2 * NOT (k div 2)\ for k :: int + by (auto simp add: not_int_def elim: oddE) + +lemma even_not_iff_int: + \even (NOT k) \ odd k\ for k :: int + by (simp add: not_int_def) + +lemma not_int_div_2: + \NOT k div 2 = NOT (k div 2)\ for k :: int + by (cases k) (simp_all add: not_int_def divide_int_def nat_add_distrib) + +lemma bit_not_int_iff [bit_simps]: + \bit (NOT k) n \ \ bit k n\ + for k :: int + by (simp add: bit_not_int_iff' not_int_def) + +function and_int :: \int \ int \ int\ + where \(k::int) AND l = (if k \ {0, - 1} \ l \ {0, - 1} + then - of_bool (odd k \ odd l) + else of_bool (odd k \ odd l) + 2 * ((k div 2) AND (l div 2)))\ + by auto + +termination proof (relation \measure (\(k, l). nat (\k\ + \l\))\) + show \wf (measure (\(k, l). nat (\k\ + \l\)))\ + by simp + show \((k div 2, l div 2), k, l) \ measure (\(k, l). nat (\k\ + \l\))\ + if \\ (k \ {0, - 1} \ l \ {0, - 1})\ for k l + proof - + have less_eq: \\k div 2\ \ \k\\ for k :: int + by (cases k) (simp_all add: divide_int_def nat_add_distrib) + have less: \\k div 2\ < \k\\ if \k \ {0, - 1}\ for k :: int + proof (cases k) + case (nonneg n) + with that show ?thesis + by (simp add: int_div_less_self) + next + case (neg n) + with that have \n \ 0\ + by simp + then have \n div 2 < n\ + by (simp add: div_less_iff_less_mult) + with neg that show ?thesis + by (simp add: divide_int_def nat_add_distrib) + qed + from that have *: \k \ {0, - 1} \ l \ {0, - 1}\ + by simp + then have \0 < \k\ + \l\\ + by auto + moreover from * have \\k div 2\ + \l div 2\ < \k\ + \l\\ + proof + assume \k \ {0, - 1}\ + then have \\k div 2\ < \k\\ + by (rule less) + with less_eq [of l] show ?thesis + by auto + next + assume \l \ {0, - 1}\ + then have \\l div 2\ < \l\\ + by (rule less) + with less_eq [of k] show ?thesis + by auto + qed + ultimately show ?thesis + by simp + qed +qed + +declare and_int.simps [simp del] + +lemma and_int_rec: + \k AND l = of_bool (odd k \ odd l) + 2 * ((k div 2) AND (l div 2))\ + for k l :: int +proof (cases \k \ {0, - 1} \ l \ {0, - 1}\) + case True + then show ?thesis + by auto (simp_all add: and_int.simps) +next + case False + then show ?thesis + by (auto simp add: ac_simps and_int.simps [of k l]) +qed + +lemma bit_and_int_iff: + \bit (k AND l) n \ bit k n \ bit l n\ for k l :: int +proof (induction n arbitrary: k l) + case 0 + then show ?case + by (simp add: and_int_rec [of k l]) +next + case (Suc n) + then show ?case + by (simp add: and_int_rec [of k l] bit_Suc) +qed + +lemma even_and_iff_int: + \even (k AND l) \ even k \ even l\ for k l :: int + using bit_and_int_iff [of k l 0] by auto + +definition or_int :: \int \ int \ int\ + where \k OR l = NOT (NOT k AND NOT l)\ for k l :: int + +lemma or_int_rec: + \k OR l = of_bool (odd k \ odd l) + 2 * ((k div 2) OR (l div 2))\ + for k l :: int + using and_int_rec [of \NOT k\ \NOT l\] + by (simp add: or_int_def even_not_iff_int not_int_div_2) + (simp_all add: not_int_def) + +lemma bit_or_int_iff: + \bit (k OR l) n \ bit k n \ bit l n\ for k l :: int + by (simp add: or_int_def bit_not_int_iff bit_and_int_iff) + +definition xor_int :: \int \ int \ int\ + where \k XOR l = k AND NOT l OR NOT k AND l\ for k l :: int + +lemma xor_int_rec: + \k XOR l = of_bool (odd k \ odd l) + 2 * ((k div 2) XOR (l div 2))\ + for k l :: int + by (simp add: xor_int_def or_int_rec [of \k AND NOT l\ \NOT k AND l\] even_and_iff_int even_not_iff_int) + (simp add: and_int_rec [of \NOT k\ \l\] and_int_rec [of \k\ \NOT l\] not_int_div_2) + +lemma bit_xor_int_iff: + \bit (k XOR l) n \ bit k n \ bit l n\ for k l :: int + by (auto simp add: xor_int_def bit_or_int_iff bit_and_int_iff bit_not_int_iff) + +definition mask_int :: \nat \ int\ + where \mask n = (2 :: int) ^ n - 1\ + +definition set_bit_int :: \nat \ int \ int\ + where \set_bit n k = k OR push_bit n 1\ for k :: int + +definition unset_bit_int :: \nat \ int \ int\ + where \unset_bit n k = k AND NOT (push_bit n 1)\ for k :: int + +definition flip_bit_int :: \nat \ int \ int\ + where \flip_bit n k = k XOR push_bit n 1\ for k :: int + +instance proof + fix k l :: int and m n :: nat + show \- k = NOT (k - 1)\ + by (simp add: not_int_def) + show \bit (k AND l) n \ bit k n \ bit l n\ + by (fact bit_and_int_iff) + show \bit (k OR l) n \ bit k n \ bit l n\ + by (fact bit_or_int_iff) + show \bit (k XOR l) n \ bit k n \ bit l n\ + by (fact bit_xor_int_iff) + show \bit (unset_bit m k) n \ bit k n \ m \ n\ + proof - + have \unset_bit m k = k AND NOT (push_bit m 1)\ + by (simp add: unset_bit_int_def) + also have \NOT (push_bit m 1 :: int) = - (push_bit m 1 + 1)\ + by (simp add: not_int_def) + finally show ?thesis by (simp only: bit_simps bit_and_int_iff) (auto simp add: bit_simps) + qed +qed (simp_all add: bit_not_int_iff mask_int_def set_bit_int_def flip_bit_int_def) + +end + +lemma mask_half_int: + \mask n div 2 = (mask (n - 1) :: int)\ + by (cases n) (simp_all add: mask_eq_exp_minus_1 algebra_simps) + +lemma mask_nonnegative_int [simp]: + \mask n \ (0::int)\ + by (simp add: mask_eq_exp_minus_1) + +lemma not_mask_negative_int [simp]: + \\ mask n < (0::int)\ + by (simp add: not_less) + +lemma not_nonnegative_int_iff [simp]: + \NOT k \ 0 \ k < 0\ for k :: int + by (simp add: not_int_def) + +lemma not_negative_int_iff [simp]: + \NOT k < 0 \ k \ 0\ for k :: int + by (subst Not_eq_iff [symmetric]) (simp add: not_less not_le) + +lemma and_nonnegative_int_iff [simp]: + \k AND l \ 0 \ k \ 0 \ l \ 0\ for k l :: int +proof (induction k arbitrary: l rule: int_bit_induct) + case zero + then show ?case + by simp +next + case minus + then show ?case + by simp +next + case (even k) + then show ?case + using and_int_rec [of \k * 2\ l] + by (simp add: pos_imp_zdiv_nonneg_iff zero_le_mult_iff) +next + case (odd k) + from odd have \0 \ k AND l div 2 \ 0 \ k \ 0 \ l div 2\ + by simp + then have \0 \ (1 + k * 2) div 2 AND l div 2 \ 0 \ (1 + k * 2) div 2 \ 0 \ l div 2\ + by simp + with and_int_rec [of \1 + k * 2\ l] + show ?case + by (auto simp add: zero_le_mult_iff not_le) +qed + +lemma and_negative_int_iff [simp]: + \k AND l < 0 \ k < 0 \ l < 0\ for k l :: int + by (subst Not_eq_iff [symmetric]) (simp add: not_less) + +lemma and_less_eq: + \k AND l \ k\ if \l < 0\ for k l :: int +using that proof (induction k arbitrary: l rule: int_bit_induct) + case zero + then show ?case + by simp +next + case minus + then show ?case + by simp +next + case (even k) + from even.IH [of \l div 2\] even.hyps even.prems + show ?case + by (simp add: and_int_rec [of _ l]) +next + case (odd k) + from odd.IH [of \l div 2\] odd.hyps odd.prems + show ?case + by (simp add: and_int_rec [of _ l]) +qed + +lemma or_nonnegative_int_iff [simp]: + \k OR l \ 0 \ k \ 0 \ l \ 0\ for k l :: int + by (simp only: or_eq_not_not_and not_nonnegative_int_iff) simp + +lemma or_negative_int_iff [simp]: + \k OR l < 0 \ k < 0 \ l < 0\ for k l :: int + by (subst Not_eq_iff [symmetric]) (simp add: not_less) + +lemma or_greater_eq: + \k OR l \ k\ if \l \ 0\ for k l :: int +using that proof (induction k arbitrary: l rule: int_bit_induct) + case zero + then show ?case + by simp +next + case minus + then show ?case + by simp +next + case (even k) + from even.IH [of \l div 2\] even.hyps even.prems + show ?case + by (simp add: or_int_rec [of _ l]) +next + case (odd k) + from odd.IH [of \l div 2\] odd.hyps odd.prems + show ?case + by (simp add: or_int_rec [of _ l]) +qed + +lemma xor_nonnegative_int_iff [simp]: + \k XOR l \ 0 \ (k \ 0 \ l \ 0)\ for k l :: int + by (simp only: bit.xor_def or_nonnegative_int_iff) auto + +lemma xor_negative_int_iff [simp]: + \k XOR l < 0 \ (k < 0) \ (l < 0)\ for k l :: int + by (subst Not_eq_iff [symmetric]) (auto simp add: not_less) + +lemma OR_upper: \<^marker>\contributor \Stefan Berghofer\\ + fixes x y :: int + assumes \0 \ x\ \x < 2 ^ n\ \y < 2 ^ n\ + shows \x OR y < 2 ^ n\ +using assms proof (induction x arbitrary: y n rule: int_bit_induct) + case zero + then show ?case + by simp +next + case minus + then show ?case + by simp +next + case (even x) + from even.IH [of \n - 1\ \y div 2\] even.prems even.hyps + show ?case + by (cases n) (auto simp add: or_int_rec [of \_ * 2\] elim: oddE) +next + case (odd x) + from odd.IH [of \n - 1\ \y div 2\] odd.prems odd.hyps + show ?case + by (cases n) (auto simp add: or_int_rec [of \1 + _ * 2\], linarith) +qed + +lemma XOR_upper: \<^marker>\contributor \Stefan Berghofer\\ + fixes x y :: int + assumes \0 \ x\ \x < 2 ^ n\ \y < 2 ^ n\ + shows \x XOR y < 2 ^ n\ +using assms proof (induction x arbitrary: y n rule: int_bit_induct) + case zero + then show ?case + by simp +next + case minus + then show ?case + by simp +next + case (even x) + from even.IH [of \n - 1\ \y div 2\] even.prems even.hyps + show ?case + by (cases n) (auto simp add: xor_int_rec [of \_ * 2\] elim: oddE) +next + case (odd x) + from odd.IH [of \n - 1\ \y div 2\] odd.prems odd.hyps + show ?case + by (cases n) (auto simp add: xor_int_rec [of \1 + _ * 2\]) +qed + +lemma AND_lower [simp]: \<^marker>\contributor \Stefan Berghofer\\ + fixes x y :: int + assumes \0 \ x\ + shows \0 \ x AND y\ + using assms by simp + +lemma OR_lower [simp]: \<^marker>\contributor \Stefan Berghofer\\ + fixes x y :: int + assumes \0 \ x\ \0 \ y\ + shows \0 \ x OR y\ + using assms by simp + +lemma XOR_lower [simp]: \<^marker>\contributor \Stefan Berghofer\\ + fixes x y :: int + assumes \0 \ x\ \0 \ y\ + shows \0 \ x XOR y\ + using assms by simp + +lemma AND_upper1 [simp]: \<^marker>\contributor \Stefan Berghofer\\ + fixes x y :: int + assumes \0 \ x\ + shows \x AND y \ x\ +using assms proof (induction x arbitrary: y rule: int_bit_induct) + case (odd k) + then have \k AND y div 2 \ k\ + by simp + then show ?case + by (simp add: and_int_rec [of \1 + _ * 2\]) +qed (simp_all add: and_int_rec [of \_ * 2\]) + +lemmas AND_upper1' [simp] = order_trans [OF AND_upper1] \<^marker>\contributor \Stefan Berghofer\\ +lemmas AND_upper1'' [simp] = order_le_less_trans [OF AND_upper1] \<^marker>\contributor \Stefan Berghofer\\ + +lemma AND_upper2 [simp]: \<^marker>\contributor \Stefan Berghofer\\ + fixes x y :: int + assumes \0 \ y\ + shows \x AND y \ y\ + using assms AND_upper1 [of y x] by (simp add: ac_simps) + +lemmas AND_upper2' [simp] = order_trans [OF AND_upper2] \<^marker>\contributor \Stefan Berghofer\\ +lemmas AND_upper2'' [simp] = order_le_less_trans [OF AND_upper2] \<^marker>\contributor \Stefan Berghofer\\ + +lemma plus_and_or: \(x AND y) + (x OR y) = x + y\ for x y :: int +proof (induction x arbitrary: y rule: int_bit_induct) + case zero + then show ?case + by simp +next + case minus + then show ?case + by simp +next + case (even x) + from even.IH [of \y div 2\] + show ?case + by (auto simp add: and_int_rec [of _ y] or_int_rec [of _ y] elim: oddE) +next + case (odd x) + from odd.IH [of \y div 2\] + show ?case + by (auto simp add: and_int_rec [of _ y] or_int_rec [of _ y] elim: oddE) +qed + +lemma set_bit_nonnegative_int_iff [simp]: + \set_bit n k \ 0 \ k \ 0\ for k :: int + by (simp add: set_bit_def) + +lemma set_bit_negative_int_iff [simp]: + \set_bit n k < 0 \ k < 0\ for k :: int + by (simp add: set_bit_def) + +lemma unset_bit_nonnegative_int_iff [simp]: + \unset_bit n k \ 0 \ k \ 0\ for k :: int + by (simp add: unset_bit_def) + +lemma unset_bit_negative_int_iff [simp]: + \unset_bit n k < 0 \ k < 0\ for k :: int + by (simp add: unset_bit_def) + +lemma flip_bit_nonnegative_int_iff [simp]: + \flip_bit n k \ 0 \ k \ 0\ for k :: int + by (simp add: flip_bit_def) + +lemma flip_bit_negative_int_iff [simp]: + \flip_bit n k < 0 \ k < 0\ for k :: int + by (simp add: flip_bit_def) + +lemma set_bit_greater_eq: + \set_bit n k \ k\ for k :: int + by (simp add: set_bit_def or_greater_eq) + +lemma unset_bit_less_eq: + \unset_bit n k \ k\ for k :: int + by (simp add: unset_bit_def and_less_eq) + +lemma set_bit_eq: + \set_bit n k = k + of_bool (\ bit k n) * 2 ^ n\ for k :: int +proof (rule bit_eqI) + fix m + show \bit (set_bit n k) m \ bit (k + of_bool (\ bit k n) * 2 ^ n) m\ + proof (cases \m = n\) + case True + then show ?thesis + apply (simp add: bit_set_bit_iff) + apply (simp add: bit_iff_odd div_plus_div_distrib_dvd_right) + done + next + case False + then show ?thesis + apply (clarsimp simp add: bit_set_bit_iff) + apply (subst disjunctive_add) + apply (clarsimp simp add: bit_exp_iff) + apply (clarsimp simp add: bit_or_iff bit_exp_iff) + done + qed +qed + +lemma unset_bit_eq: + \unset_bit n k = k - of_bool (bit k n) * 2 ^ n\ for k :: int +proof (rule bit_eqI) + fix m + show \bit (unset_bit n k) m \ bit (k - of_bool (bit k n) * 2 ^ n) m\ + proof (cases \m = n\) + case True + then show ?thesis + apply (simp add: bit_unset_bit_iff) + apply (simp add: bit_iff_odd) + using div_plus_div_distrib_dvd_right [of \2 ^ n\ \- (2 ^ n)\ k] + apply (simp add: dvd_neg_div) + done + next + case False + then show ?thesis + apply (clarsimp simp add: bit_unset_bit_iff) + apply (subst disjunctive_diff) + apply (clarsimp simp add: bit_exp_iff) + apply (clarsimp simp add: bit_and_iff bit_not_iff bit_exp_iff) + done + qed +qed + +lemma take_bit_eq_mask_iff: + \take_bit n k = mask n \ take_bit n (k + 1) = 0\ (is \?P \ ?Q\) + for k :: int +proof + assume ?P + then have \take_bit n (take_bit n k + take_bit n 1) = 0\ + by (simp add: mask_eq_exp_minus_1) + then show ?Q + by (simp only: take_bit_add) +next + assume ?Q + then have \take_bit n (k + 1) - 1 = - 1\ + by simp + then have \take_bit n (take_bit n (k + 1) - 1) = take_bit n (- 1)\ + by simp + moreover have \take_bit n (take_bit n (k + 1) - 1) = take_bit n k\ + by (simp add: take_bit_eq_mod mod_simps) + ultimately show ?P + by (simp add: take_bit_minus_one_eq_mask) +qed + +lemma take_bit_eq_mask_iff_exp_dvd: + \take_bit n k = mask n \ 2 ^ n dvd k + 1\ + for k :: int + by (simp add: take_bit_eq_mask_iff flip: take_bit_eq_0_iff) + +context ring_bit_operations +begin + +lemma even_of_int_iff: + \even (of_int k) \ even k\ + by (induction k rule: int_bit_induct) simp_all + +lemma bit_of_int_iff [bit_simps]: + \bit (of_int k) n \ (2::'a) ^ n \ 0 \ bit k n\ +proof (cases \(2::'a) ^ n = 0\) + case True + then show ?thesis + by (simp add: exp_eq_0_imp_not_bit) +next + case False + then have \bit (of_int k) n \ bit k n\ + proof (induction k arbitrary: n rule: int_bit_induct) + case zero + then show ?case + by simp + next + case minus + then show ?case + by simp + next + case (even k) + then show ?case + using bit_double_iff [of \of_int k\ n] Bit_Operations.bit_double_iff [of k n] + by (cases n) (auto simp add: ac_simps dest: mult_not_zero) + next + case (odd k) + then show ?case + using bit_double_iff [of \of_int k\ n] + by (cases n) (auto simp add: ac_simps bit_double_iff even_bit_succ_iff Bit_Operations.bit_Suc dest: mult_not_zero) + qed + with False show ?thesis + by simp +qed + +lemma push_bit_of_int: + \push_bit n (of_int k) = of_int (push_bit n k)\ + by (simp add: push_bit_eq_mult semiring_bit_shifts_class.push_bit_eq_mult) + +lemma of_int_push_bit: + \of_int (push_bit n k) = push_bit n (of_int k)\ + by (simp add: push_bit_eq_mult semiring_bit_shifts_class.push_bit_eq_mult) + +lemma take_bit_of_int: + \take_bit n (of_int k) = of_int (take_bit n k)\ + by (rule bit_eqI) (simp add: bit_take_bit_iff Bit_Operations.bit_take_bit_iff bit_of_int_iff) + +lemma of_int_take_bit: + \of_int (take_bit n k) = take_bit n (of_int k)\ + by (rule bit_eqI) (simp add: bit_take_bit_iff Bit_Operations.bit_take_bit_iff bit_of_int_iff) + +lemma of_int_not_eq: + \of_int (NOT k) = NOT (of_int k)\ + by (rule bit_eqI) (simp add: bit_not_iff Bit_Operations.bit_not_iff bit_of_int_iff) + +lemma of_int_and_eq: + \of_int (k AND l) = of_int k AND of_int l\ + by (rule bit_eqI) (simp add: bit_of_int_iff bit_and_iff Bit_Operations.bit_and_iff) + +lemma of_int_or_eq: + \of_int (k OR l) = of_int k OR of_int l\ + by (rule bit_eqI) (simp add: bit_of_int_iff bit_or_iff Bit_Operations.bit_or_iff) + +lemma of_int_xor_eq: + \of_int (k XOR l) = of_int k XOR of_int l\ + by (rule bit_eqI) (simp add: bit_of_int_iff bit_xor_iff Bit_Operations.bit_xor_iff) + +lemma of_int_mask_eq: + \of_int (mask n) = mask n\ + by (induction n) (simp_all add: mask_Suc_double Bit_Operations.mask_Suc_double of_int_or_eq) + +end + +lemma take_bit_incr_eq: + \take_bit n (k + 1) = 1 + take_bit n k\ if \take_bit n k \ 2 ^ n - 1\ + for k :: int +proof - + from that have \2 ^ n \ k mod 2 ^ n + 1\ + by (simp add: take_bit_eq_mod) + moreover have \k mod 2 ^ n < 2 ^ n\ + by simp + ultimately have *: \k mod 2 ^ n + 1 < 2 ^ n\ + by linarith + have \(k + 1) mod 2 ^ n = (k mod 2 ^ n + 1) mod 2 ^ n\ + by (simp add: mod_simps) + also have \\ = k mod 2 ^ n + 1\ + using * by (simp add: zmod_trivial_iff) + finally have \(k + 1) mod 2 ^ n = k mod 2 ^ n + 1\ . + then show ?thesis + by (simp add: take_bit_eq_mod) +qed + +lemma take_bit_decr_eq: + \take_bit n (k - 1) = take_bit n k - 1\ if \take_bit n k \ 0\ + for k :: int +proof - + from that have \k mod 2 ^ n \ 0\ + by (simp add: take_bit_eq_mod) + moreover have \k mod 2 ^ n \ 0\ \k mod 2 ^ n < 2 ^ n\ + by simp_all + ultimately have *: \k mod 2 ^ n > 0\ + by linarith + have \(k - 1) mod 2 ^ n = (k mod 2 ^ n - 1) mod 2 ^ n\ + by (simp add: mod_simps) + also have \\ = k mod 2 ^ n - 1\ + by (simp add: zmod_trivial_iff) + (use \k mod 2 ^ n < 2 ^ n\ * in linarith) + finally have \(k - 1) mod 2 ^ n = k mod 2 ^ n - 1\ . + then show ?thesis + by (simp add: take_bit_eq_mod) +qed + +lemma take_bit_int_greater_eq: + \k + 2 ^ n \ take_bit n k\ if \k < 0\ for k :: int +proof - + have \k + 2 ^ n \ take_bit n (k + 2 ^ n)\ + proof (cases \k > - (2 ^ n)\) + case False + then have \k + 2 ^ n \ 0\ + by simp + also note take_bit_nonnegative + finally show ?thesis . + next + case True + with that have \0 \ k + 2 ^ n\ and \k + 2 ^ n < 2 ^ n\ + by simp_all + then show ?thesis + by (simp only: take_bit_eq_mod mod_pos_pos_trivial) + qed + then show ?thesis + by (simp add: take_bit_eq_mod) +qed + +lemma take_bit_int_less_eq: + \take_bit n k \ k - 2 ^ n\ if \2 ^ n \ k\ and \n > 0\ for k :: int + using that zmod_le_nonneg_dividend [of \k - 2 ^ n\ \2 ^ n\] + by (simp add: take_bit_eq_mod) + +lemma take_bit_int_less_eq_self_iff: + \take_bit n k \ k \ 0 \ k\ (is \?P \ ?Q\) + for k :: int +proof + assume ?P + show ?Q + proof (rule ccontr) + assume \\ 0 \ k\ + then have \k < 0\ + by simp + with \?P\ + have \take_bit n k < 0\ + by (rule le_less_trans) + then show False + by simp + qed +next + assume ?Q + then show ?P + by (simp add: take_bit_eq_mod zmod_le_nonneg_dividend) +qed + +lemma take_bit_int_less_self_iff: + \take_bit n k < k \ 2 ^ n \ k\ + for k :: int + by (auto simp add: less_le take_bit_int_less_eq_self_iff take_bit_int_eq_self_iff + intro: order_trans [of 0 \2 ^ n\ k]) + +lemma take_bit_int_greater_self_iff: + \k < take_bit n k \ k < 0\ + for k :: int + using take_bit_int_less_eq_self_iff [of n k] by auto + +lemma take_bit_int_greater_eq_self_iff: + \k \ take_bit n k \ k < 2 ^ n\ + for k :: int + by (auto simp add: le_less take_bit_int_greater_self_iff take_bit_int_eq_self_iff + dest: sym not_sym intro: less_trans [of k 0 \2 ^ n\]) + +lemma minus_numeral_inc_eq: + \- numeral (Num.inc n) = NOT (numeral n :: int)\ + by (simp add: not_int_def sub_inc_One_eq add_One) + +lemma sub_one_eq_not_neg: + \Num.sub n num.One = NOT (- numeral n :: int)\ + by (simp add: not_int_def) + +lemma int_not_numerals [simp]: + \NOT (numeral (Num.Bit0 n) :: int) = - numeral (Num.Bit1 n)\ + \NOT (numeral (Num.Bit1 n) :: int) = - numeral (Num.inc (num.Bit1 n))\ + \NOT (numeral (Num.BitM n) :: int) = - numeral (num.Bit0 n)\ + \NOT (- numeral (Num.Bit0 n) :: int) = numeral (Num.BitM n)\ + \NOT (- numeral (Num.Bit1 n) :: int) = numeral (Num.Bit0 n)\ + by (simp_all add: not_int_def add_One inc_BitM_eq) + +text \FIXME: The rule sets below are very large (24 rules for each + operator). Is there a simpler way to do this?\ + +context +begin + +private lemma eqI: + \k = l\ + if num: \\n. bit k (numeral n) \ bit l (numeral n)\ + and even: \even k \ even l\ + for k l :: int +proof (rule bit_eqI) + fix n + show \bit k n \ bit l n\ + proof (cases n) + case 0 + with even show ?thesis + by simp + next + case (Suc n) + with num [of \num_of_nat (Suc n)\] show ?thesis + by (simp only: numeral_num_of_nat) + qed +qed + +lemma int_and_numerals [simp]: + \numeral (Num.Bit0 x) AND numeral (Num.Bit0 y) = (2 :: int) * (numeral x AND numeral y)\ + \numeral (Num.Bit0 x) AND numeral (Num.Bit1 y) = (2 :: int) * (numeral x AND numeral y)\ + \numeral (Num.Bit1 x) AND numeral (Num.Bit0 y) = (2 :: int) * (numeral x AND numeral y)\ + \numeral (Num.Bit1 x) AND numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x AND numeral y)\ + \numeral (Num.Bit0 x) AND - numeral (Num.Bit0 y) = (2 :: int) * (numeral x AND - numeral y)\ + \numeral (Num.Bit0 x) AND - numeral (Num.Bit1 y) = (2 :: int) * (numeral x AND - numeral (y + Num.One))\ + \numeral (Num.Bit1 x) AND - numeral (Num.Bit0 y) = (2 :: int) * (numeral x AND - numeral y)\ + \numeral (Num.Bit1 x) AND - numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x AND - numeral (y + Num.One))\ + \- numeral (Num.Bit0 x) AND numeral (Num.Bit0 y) = (2 :: int) * (- numeral x AND numeral y)\ + \- numeral (Num.Bit0 x) AND numeral (Num.Bit1 y) = (2 :: int) * (- numeral x AND numeral y)\ + \- numeral (Num.Bit1 x) AND numeral (Num.Bit0 y) = (2 :: int) * (- numeral (x + Num.One) AND numeral y)\ + \- numeral (Num.Bit1 x) AND numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral (x + Num.One) AND numeral y)\ + \- numeral (Num.Bit0 x) AND - numeral (Num.Bit0 y) = (2 :: int) * (- numeral x AND - numeral y)\ + \- numeral (Num.Bit0 x) AND - numeral (Num.Bit1 y) = (2 :: int) * (- numeral x AND - numeral (y + Num.One))\ + \- numeral (Num.Bit1 x) AND - numeral (Num.Bit0 y) = (2 :: int) * (- numeral (x + Num.One) AND - numeral y)\ + \- numeral (Num.Bit1 x) AND - numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral (x + Num.One) AND - numeral (y + Num.One))\ + \(1::int) AND numeral (Num.Bit0 y) = 0\ + \(1::int) AND numeral (Num.Bit1 y) = 1\ + \(1::int) AND - numeral (Num.Bit0 y) = 0\ + \(1::int) AND - numeral (Num.Bit1 y) = 1\ + \numeral (Num.Bit0 x) AND (1::int) = 0\ + \numeral (Num.Bit1 x) AND (1::int) = 1\ + \- numeral (Num.Bit0 x) AND (1::int) = 0\ + \- numeral (Num.Bit1 x) AND (1::int) = 1\ + by (auto simp add: bit_and_iff bit_minus_iff even_and_iff bit_double_iff even_bit_succ_iff add_One sub_inc_One_eq intro: eqI) + +lemma int_or_numerals [simp]: + \numeral (Num.Bit0 x) OR numeral (Num.Bit0 y) = (2 :: int) * (numeral x OR numeral y)\ + \numeral (Num.Bit0 x) OR numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x OR numeral y)\ + \numeral (Num.Bit1 x) OR numeral (Num.Bit0 y) = 1 + (2 :: int) * (numeral x OR numeral y)\ + \numeral (Num.Bit1 x) OR numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x OR numeral y)\ + \numeral (Num.Bit0 x) OR - numeral (Num.Bit0 y) = (2 :: int) * (numeral x OR - numeral y)\ + \numeral (Num.Bit0 x) OR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x OR - numeral (y + Num.One))\ + \numeral (Num.Bit1 x) OR - numeral (Num.Bit0 y) = 1 + (2 :: int) * (numeral x OR - numeral y)\ + \numeral (Num.Bit1 x) OR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x OR - numeral (y + Num.One))\ + \- numeral (Num.Bit0 x) OR numeral (Num.Bit0 y) = (2 :: int) * (- numeral x OR numeral y)\ + \- numeral (Num.Bit0 x) OR numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral x OR numeral y)\ + \- numeral (Num.Bit1 x) OR numeral (Num.Bit0 y) = 1 + (2 :: int) * (- numeral (x + Num.One) OR numeral y)\ + \- numeral (Num.Bit1 x) OR numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral (x + Num.One) OR numeral y)\ + \- numeral (Num.Bit0 x) OR - numeral (Num.Bit0 y) = (2 :: int) * (- numeral x OR - numeral y)\ + \- numeral (Num.Bit0 x) OR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral x OR - numeral (y + Num.One))\ + \- numeral (Num.Bit1 x) OR - numeral (Num.Bit0 y) = 1 + (2 :: int) * (- numeral (x + Num.One) OR - numeral y)\ + \- numeral (Num.Bit1 x) OR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral (x + Num.One) OR - numeral (y + Num.One))\ + \(1::int) OR numeral (Num.Bit0 y) = numeral (Num.Bit1 y)\ + \(1::int) OR numeral (Num.Bit1 y) = numeral (Num.Bit1 y)\ + \(1::int) OR - numeral (Num.Bit0 y) = - numeral (Num.BitM y)\ + \(1::int) OR - numeral (Num.Bit1 y) = - numeral (Num.Bit1 y)\ + \numeral (Num.Bit0 x) OR (1::int) = numeral (Num.Bit1 x)\ + \numeral (Num.Bit1 x) OR (1::int) = numeral (Num.Bit1 x)\ + \- numeral (Num.Bit0 x) OR (1::int) = - numeral (Num.BitM x)\ + \- numeral (Num.Bit1 x) OR (1::int) = - numeral (Num.Bit1 x)\ + by (auto simp add: bit_or_iff bit_minus_iff even_or_iff bit_double_iff even_bit_succ_iff add_One sub_inc_One_eq sub_BitM_One_eq intro: eqI) + +lemma int_xor_numerals [simp]: + \numeral (Num.Bit0 x) XOR numeral (Num.Bit0 y) = (2 :: int) * (numeral x XOR numeral y)\ + \numeral (Num.Bit0 x) XOR numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x XOR numeral y)\ + \numeral (Num.Bit1 x) XOR numeral (Num.Bit0 y) = 1 + (2 :: int) * (numeral x XOR numeral y)\ + \numeral (Num.Bit1 x) XOR numeral (Num.Bit1 y) = (2 :: int) * (numeral x XOR numeral y)\ + \numeral (Num.Bit0 x) XOR - numeral (Num.Bit0 y) = (2 :: int) * (numeral x XOR - numeral y)\ + \numeral (Num.Bit0 x) XOR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x XOR - numeral (y + Num.One))\ + \numeral (Num.Bit1 x) XOR - numeral (Num.Bit0 y) = 1 + (2 :: int) * (numeral x XOR - numeral y)\ + \numeral (Num.Bit1 x) XOR - numeral (Num.Bit1 y) = (2 :: int) * (numeral x XOR - numeral (y + Num.One))\ + \- numeral (Num.Bit0 x) XOR numeral (Num.Bit0 y) = (2 :: int) * (- numeral x XOR numeral y)\ + \- numeral (Num.Bit0 x) XOR numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral x XOR numeral y)\ + \- numeral (Num.Bit1 x) XOR numeral (Num.Bit0 y) = 1 + (2 :: int) * (- numeral (x + Num.One) XOR numeral y)\ + \- numeral (Num.Bit1 x) XOR numeral (Num.Bit1 y) = (2 :: int) * (- numeral (x + Num.One) XOR numeral y)\ + \- numeral (Num.Bit0 x) XOR - numeral (Num.Bit0 y) = (2 :: int) * (- numeral x XOR - numeral y)\ + \- numeral (Num.Bit0 x) XOR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral x XOR - numeral (y + Num.One))\ + \- numeral (Num.Bit1 x) XOR - numeral (Num.Bit0 y) = 1 + (2 :: int) * (- numeral (x + Num.One) XOR - numeral y)\ + \- numeral (Num.Bit1 x) XOR - numeral (Num.Bit1 y) = (2 :: int) * (- numeral (x + Num.One) XOR - numeral (y + Num.One))\ + \(1::int) XOR numeral (Num.Bit0 y) = numeral (Num.Bit1 y)\ + \(1::int) XOR numeral (Num.Bit1 y) = numeral (Num.Bit0 y)\ + \(1::int) XOR - numeral (Num.Bit0 y) = - numeral (Num.BitM y)\ + \(1::int) XOR - numeral (Num.Bit1 y) = - numeral (Num.Bit0 (y + Num.One))\ + \numeral (Num.Bit0 x) XOR (1::int) = numeral (Num.Bit1 x)\ + \numeral (Num.Bit1 x) XOR (1::int) = numeral (Num.Bit0 x)\ + \- numeral (Num.Bit0 x) XOR (1::int) = - numeral (Num.BitM x)\ + \- numeral (Num.Bit1 x) XOR (1::int) = - numeral (Num.Bit0 (x + Num.One))\ + by (auto simp add: bit_xor_iff bit_minus_iff even_xor_iff bit_double_iff even_bit_succ_iff add_One sub_inc_One_eq sub_BitM_One_eq intro: eqI) + +end + + +subsection \Bit concatenation\ + +definition concat_bit :: \nat \ int \ int \ int\ + where \concat_bit n k l = take_bit n k OR push_bit n l\ + +lemma bit_concat_bit_iff [bit_simps]: + \bit (concat_bit m k l) n \ n < m \ bit k n \ m \ n \ bit l (n - m)\ + by (simp add: concat_bit_def bit_or_iff bit_and_iff bit_take_bit_iff bit_push_bit_iff ac_simps) + +lemma concat_bit_eq: + \concat_bit n k l = take_bit n k + push_bit n l\ + by (simp add: concat_bit_def take_bit_eq_mask + bit_and_iff bit_mask_iff bit_push_bit_iff disjunctive_add) + +lemma concat_bit_0 [simp]: + \concat_bit 0 k l = l\ + by (simp add: concat_bit_def) + +lemma concat_bit_Suc: + \concat_bit (Suc n) k l = k mod 2 + 2 * concat_bit n (k div 2) l\ + by (simp add: concat_bit_eq take_bit_Suc push_bit_double) + +lemma concat_bit_of_zero_1 [simp]: + \concat_bit n 0 l = push_bit n l\ + by (simp add: concat_bit_def) + +lemma concat_bit_of_zero_2 [simp]: + \concat_bit n k 0 = take_bit n k\ + by (simp add: concat_bit_def take_bit_eq_mask) + +lemma concat_bit_nonnegative_iff [simp]: + \concat_bit n k l \ 0 \ l \ 0\ + by (simp add: concat_bit_def) + +lemma concat_bit_negative_iff [simp]: + \concat_bit n k l < 0 \ l < 0\ + by (simp add: concat_bit_def) + +lemma concat_bit_assoc: + \concat_bit n k (concat_bit m l r) = concat_bit (m + n) (concat_bit n k l) r\ + by (rule bit_eqI) (auto simp add: bit_concat_bit_iff ac_simps) + +lemma concat_bit_assoc_sym: + \concat_bit m (concat_bit n k l) r = concat_bit (min m n) k (concat_bit (m - n) l r)\ + by (rule bit_eqI) (auto simp add: bit_concat_bit_iff ac_simps min_def) + +lemma concat_bit_eq_iff: + \concat_bit n k l = concat_bit n r s + \ take_bit n k = take_bit n r \ l = s\ (is \?P \ ?Q\) +proof + assume ?Q + then show ?P + by (simp add: concat_bit_def) +next + assume ?P + then have *: \bit (concat_bit n k l) m = bit (concat_bit n r s) m\ for m + by (simp add: bit_eq_iff) + have \take_bit n k = take_bit n r\ + proof (rule bit_eqI) + fix m + from * [of m] + show \bit (take_bit n k) m \ bit (take_bit n r) m\ + by (auto simp add: bit_take_bit_iff bit_concat_bit_iff) + qed + moreover have \push_bit n l = push_bit n s\ + proof (rule bit_eqI) + fix m + from * [of m] + show \bit (push_bit n l) m \ bit (push_bit n s) m\ + by (auto simp add: bit_push_bit_iff bit_concat_bit_iff) + qed + then have \l = s\ + by (simp add: push_bit_eq_mult) + ultimately show ?Q + by (simp add: concat_bit_def) +qed + +lemma take_bit_concat_bit_eq: + \take_bit m (concat_bit n k l) = concat_bit (min m n) k (take_bit (m - n) l)\ + by (rule bit_eqI) + (auto simp add: bit_take_bit_iff bit_concat_bit_iff min_def) + +lemma concat_bit_take_bit_eq: + \concat_bit n (take_bit n b) = concat_bit n b\ + by (simp add: concat_bit_def [abs_def]) + + +subsection \Taking bits with sign propagation\ + +context ring_bit_operations +begin + +definition signed_take_bit :: \nat \ 'a \ 'a\ + where \signed_take_bit n a = take_bit n a OR (of_bool (bit a n) * NOT (mask n))\ + +lemma signed_take_bit_eq_if_positive: + \signed_take_bit n a = take_bit n a\ if \\ bit a n\ + using that by (simp add: signed_take_bit_def) + +lemma signed_take_bit_eq_if_negative: + \signed_take_bit n a = take_bit n a OR NOT (mask n)\ if \bit a n\ + using that by (simp add: signed_take_bit_def) + +lemma even_signed_take_bit_iff: + \even (signed_take_bit m a) \ even a\ + by (auto simp add: signed_take_bit_def even_or_iff even_mask_iff bit_double_iff) + +lemma bit_signed_take_bit_iff [bit_simps]: + \bit (signed_take_bit m a) n \ 2 ^ n \ 0 \ bit a (min m n)\ + by (simp add: signed_take_bit_def bit_take_bit_iff bit_or_iff bit_not_iff bit_mask_iff min_def not_le) + (use exp_eq_0_imp_not_bit in blast) + +lemma signed_take_bit_0 [simp]: + \signed_take_bit 0 a = - (a mod 2)\ + by (simp add: signed_take_bit_def odd_iff_mod_2_eq_one) + +lemma signed_take_bit_Suc: + \signed_take_bit (Suc n) a = a mod 2 + 2 * signed_take_bit n (a div 2)\ +proof (rule bit_eqI) + fix m + assume *: \2 ^ m \ 0\ + show \bit (signed_take_bit (Suc n) a) m \ + bit (a mod 2 + 2 * signed_take_bit n (a div 2)) m\ + proof (cases m) + case 0 + then show ?thesis + by (simp add: even_signed_take_bit_iff) + next + case (Suc m) + with * have \2 ^ m \ 0\ + by (metis mult_not_zero power_Suc) + with Suc show ?thesis + by (simp add: bit_signed_take_bit_iff mod2_eq_if bit_double_iff even_bit_succ_iff + ac_simps flip: bit_Suc) + qed +qed + +lemma signed_take_bit_of_0 [simp]: + \signed_take_bit n 0 = 0\ + by (simp add: signed_take_bit_def) + +lemma signed_take_bit_of_minus_1 [simp]: + \signed_take_bit n (- 1) = - 1\ + by (simp add: signed_take_bit_def take_bit_minus_one_eq_mask mask_eq_exp_minus_1) + +lemma signed_take_bit_Suc_1 [simp]: + \signed_take_bit (Suc n) 1 = 1\ + by (simp add: signed_take_bit_Suc) + +lemma signed_take_bit_rec: + \signed_take_bit n a = (if n = 0 then - (a mod 2) else a mod 2 + 2 * signed_take_bit (n - 1) (a div 2))\ + by (cases n) (simp_all add: signed_take_bit_Suc) + +lemma signed_take_bit_eq_iff_take_bit_eq: + \signed_take_bit n a = signed_take_bit n b \ take_bit (Suc n) a = take_bit (Suc n) b\ +proof - + have \bit (signed_take_bit n a) = bit (signed_take_bit n b) \ bit (take_bit (Suc n) a) = bit (take_bit (Suc n) b)\ + by (simp add: fun_eq_iff bit_signed_take_bit_iff bit_take_bit_iff not_le less_Suc_eq_le min_def) + (use exp_eq_0_imp_not_bit in fastforce) + then show ?thesis + by (simp add: bit_eq_iff fun_eq_iff) +qed + +lemma signed_take_bit_signed_take_bit [simp]: + \signed_take_bit m (signed_take_bit n a) = signed_take_bit (min m n) a\ +proof (rule bit_eqI) + fix q + show \bit (signed_take_bit m (signed_take_bit n a)) q \ + bit (signed_take_bit (min m n) a) q\ + by (simp add: bit_signed_take_bit_iff min_def bit_or_iff bit_not_iff bit_mask_iff bit_take_bit_iff) + (use le_Suc_ex exp_add_not_zero_imp in blast) +qed + +lemma signed_take_bit_take_bit: + \signed_take_bit m (take_bit n a) = (if n \ m then take_bit n else signed_take_bit m) a\ + by (rule bit_eqI) (auto simp add: bit_signed_take_bit_iff min_def bit_take_bit_iff) + +lemma take_bit_signed_take_bit: + \take_bit m (signed_take_bit n a) = take_bit m a\ if \m \ Suc n\ + using that by (rule le_SucE; intro bit_eqI) + (auto simp add: bit_take_bit_iff bit_signed_take_bit_iff min_def less_Suc_eq) + +end + +text \Modulus centered around 0\ + +lemma signed_take_bit_eq_concat_bit: + \signed_take_bit n k = concat_bit n k (- of_bool (bit k n))\ + by (simp add: concat_bit_def signed_take_bit_def push_bit_minus_one_eq_not_mask) + +lemma signed_take_bit_add: + \signed_take_bit n (signed_take_bit n k + signed_take_bit n l) = signed_take_bit n (k + l)\ + for k l :: int +proof - + have \take_bit (Suc n) + (take_bit (Suc n) (signed_take_bit n k) + + take_bit (Suc n) (signed_take_bit n l)) = + take_bit (Suc n) (k + l)\ + by (simp add: take_bit_signed_take_bit take_bit_add) + then show ?thesis + by (simp only: signed_take_bit_eq_iff_take_bit_eq take_bit_add) +qed + +lemma signed_take_bit_diff: + \signed_take_bit n (signed_take_bit n k - signed_take_bit n l) = signed_take_bit n (k - l)\ + for k l :: int +proof - + have \take_bit (Suc n) + (take_bit (Suc n) (signed_take_bit n k) - + take_bit (Suc n) (signed_take_bit n l)) = + take_bit (Suc n) (k - l)\ + by (simp add: take_bit_signed_take_bit take_bit_diff) + then show ?thesis + by (simp only: signed_take_bit_eq_iff_take_bit_eq take_bit_diff) +qed + +lemma signed_take_bit_minus: + \signed_take_bit n (- signed_take_bit n k) = signed_take_bit n (- k)\ + for k :: int +proof - + have \take_bit (Suc n) + (- take_bit (Suc n) (signed_take_bit n k)) = + take_bit (Suc n) (- k)\ + by (simp add: take_bit_signed_take_bit take_bit_minus) + then show ?thesis + by (simp only: signed_take_bit_eq_iff_take_bit_eq take_bit_minus) +qed + +lemma signed_take_bit_mult: + \signed_take_bit n (signed_take_bit n k * signed_take_bit n l) = signed_take_bit n (k * l)\ + for k l :: int +proof - + have \take_bit (Suc n) + (take_bit (Suc n) (signed_take_bit n k) * + take_bit (Suc n) (signed_take_bit n l)) = + take_bit (Suc n) (k * l)\ + by (simp add: take_bit_signed_take_bit take_bit_mult) + then show ?thesis + by (simp only: signed_take_bit_eq_iff_take_bit_eq take_bit_mult) +qed + +lemma signed_take_bit_eq_take_bit_minus: + \signed_take_bit n k = take_bit (Suc n) k - 2 ^ Suc n * of_bool (bit k n)\ + for k :: int +proof (cases \bit k n\) + case True + have \signed_take_bit n k = take_bit (Suc n) k OR NOT (mask (Suc n))\ + by (rule bit_eqI) (auto simp add: bit_signed_take_bit_iff min_def bit_take_bit_iff bit_or_iff bit_not_iff bit_mask_iff less_Suc_eq True) + then have \signed_take_bit n k = take_bit (Suc n) k + NOT (mask (Suc n))\ + by (simp add: disjunctive_add bit_take_bit_iff bit_not_iff bit_mask_iff) + with True show ?thesis + by (simp flip: minus_exp_eq_not_mask) +next + case False + show ?thesis + by (rule bit_eqI) (simp add: False bit_signed_take_bit_iff bit_take_bit_iff min_def less_Suc_eq) +qed + +lemma signed_take_bit_eq_take_bit_shift: + \signed_take_bit n k = take_bit (Suc n) (k + 2 ^ n) - 2 ^ n\ + for k :: int +proof - + have *: \take_bit n k OR 2 ^ n = take_bit n k + 2 ^ n\ + by (simp add: disjunctive_add bit_exp_iff bit_take_bit_iff) + have \take_bit n k - 2 ^ n = take_bit n k + NOT (mask n)\ + by (simp add: minus_exp_eq_not_mask) + also have \\ = take_bit n k OR NOT (mask n)\ + by (rule disjunctive_add) + (simp add: bit_exp_iff bit_take_bit_iff bit_not_iff bit_mask_iff) + finally have **: \take_bit n k - 2 ^ n = take_bit n k OR NOT (mask n)\ . + have \take_bit (Suc n) (k + 2 ^ n) = take_bit (Suc n) (take_bit (Suc n) k + take_bit (Suc n) (2 ^ n))\ + by (simp only: take_bit_add) + also have \take_bit (Suc n) k = 2 ^ n * of_bool (bit k n) + take_bit n k\ + by (simp add: take_bit_Suc_from_most) + finally have \take_bit (Suc n) (k + 2 ^ n) = take_bit (Suc n) (2 ^ (n + of_bool (bit k n)) + take_bit n k)\ + by (simp add: ac_simps) + also have \2 ^ (n + of_bool (bit k n)) + take_bit n k = 2 ^ (n + of_bool (bit k n)) OR take_bit n k\ + by (rule disjunctive_add) + (auto simp add: disjunctive_add bit_take_bit_iff bit_double_iff bit_exp_iff) + finally show ?thesis + using * ** by (simp add: signed_take_bit_def concat_bit_Suc min_def ac_simps) +qed + +lemma signed_take_bit_nonnegative_iff [simp]: + \0 \ signed_take_bit n k \ \ bit k n\ + for k :: int + by (simp add: signed_take_bit_def not_less concat_bit_def) + +lemma signed_take_bit_negative_iff [simp]: + \signed_take_bit n k < 0 \ bit k n\ + for k :: int + by (simp add: signed_take_bit_def not_less concat_bit_def) + +lemma signed_take_bit_int_greater_eq_minus_exp [simp]: + \- (2 ^ n) \ signed_take_bit n k\ + for k :: int + by (simp add: signed_take_bit_eq_take_bit_shift) + +lemma signed_take_bit_int_less_exp [simp]: + \signed_take_bit n k < 2 ^ n\ + for k :: int + using take_bit_int_less_exp [of \Suc n\] + by (simp add: signed_take_bit_eq_take_bit_shift) + +lemma signed_take_bit_int_eq_self_iff: + \signed_take_bit n k = k \ - (2 ^ n) \ k \ k < 2 ^ n\ + for k :: int + by (auto simp add: signed_take_bit_eq_take_bit_shift take_bit_int_eq_self_iff algebra_simps) + +lemma signed_take_bit_int_eq_self: + \signed_take_bit n k = k\ if \- (2 ^ n) \ k\ \k < 2 ^ n\ + for k :: int + using that by (simp add: signed_take_bit_int_eq_self_iff) + +lemma signed_take_bit_int_less_eq_self_iff: + \signed_take_bit n k \ k \ - (2 ^ n) \ k\ + for k :: int + by (simp add: signed_take_bit_eq_take_bit_shift take_bit_int_less_eq_self_iff algebra_simps) + linarith + +lemma signed_take_bit_int_less_self_iff: + \signed_take_bit n k < k \ 2 ^ n \ k\ + for k :: int + by (simp add: signed_take_bit_eq_take_bit_shift take_bit_int_less_self_iff algebra_simps) + +lemma signed_take_bit_int_greater_self_iff: + \k < signed_take_bit n k \ k < - (2 ^ n)\ + for k :: int + by (simp add: signed_take_bit_eq_take_bit_shift take_bit_int_greater_self_iff algebra_simps) + linarith + +lemma signed_take_bit_int_greater_eq_self_iff: + \k \ signed_take_bit n k \ k < 2 ^ n\ + for k :: int + by (simp add: signed_take_bit_eq_take_bit_shift take_bit_int_greater_eq_self_iff algebra_simps) + +lemma signed_take_bit_int_greater_eq: + \k + 2 ^ Suc n \ signed_take_bit n k\ if \k < - (2 ^ n)\ + for k :: int + using that take_bit_int_greater_eq [of \k + 2 ^ n\ \Suc n\] + by (simp add: signed_take_bit_eq_take_bit_shift) + +lemma signed_take_bit_int_less_eq: + \signed_take_bit n k \ k - 2 ^ Suc n\ if \k \ 2 ^ n\ + for k :: int + using that take_bit_int_less_eq [of \Suc n\ \k + 2 ^ n\] + by (simp add: signed_take_bit_eq_take_bit_shift) + +lemma signed_take_bit_Suc_bit0 [simp]: + \signed_take_bit (Suc n) (numeral (Num.Bit0 k)) = signed_take_bit n (numeral k) * (2 :: int)\ + by (simp add: signed_take_bit_Suc) + +lemma signed_take_bit_Suc_bit1 [simp]: + \signed_take_bit (Suc n) (numeral (Num.Bit1 k)) = signed_take_bit n (numeral k) * 2 + (1 :: int)\ + by (simp add: signed_take_bit_Suc) + +lemma signed_take_bit_Suc_minus_bit0 [simp]: + \signed_take_bit (Suc n) (- numeral (Num.Bit0 k)) = signed_take_bit n (- numeral k) * (2 :: int)\ + by (simp add: signed_take_bit_Suc) + +lemma signed_take_bit_Suc_minus_bit1 [simp]: + \signed_take_bit (Suc n) (- numeral (Num.Bit1 k)) = signed_take_bit n (- numeral k - 1) * 2 + (1 :: int)\ + by (simp add: signed_take_bit_Suc) + +lemma signed_take_bit_numeral_bit0 [simp]: + \signed_take_bit (numeral l) (numeral (Num.Bit0 k)) = signed_take_bit (pred_numeral l) (numeral k) * (2 :: int)\ + by (simp add: signed_take_bit_rec) + +lemma signed_take_bit_numeral_bit1 [simp]: + \signed_take_bit (numeral l) (numeral (Num.Bit1 k)) = signed_take_bit (pred_numeral l) (numeral k) * 2 + (1 :: int)\ + by (simp add: signed_take_bit_rec) + +lemma signed_take_bit_numeral_minus_bit0 [simp]: + \signed_take_bit (numeral l) (- numeral (Num.Bit0 k)) = signed_take_bit (pred_numeral l) (- numeral k) * (2 :: int)\ + by (simp add: signed_take_bit_rec) + +lemma signed_take_bit_numeral_minus_bit1 [simp]: + \signed_take_bit (numeral l) (- numeral (Num.Bit1 k)) = signed_take_bit (pred_numeral l) (- numeral k - 1) * 2 + (1 :: int)\ + by (simp add: signed_take_bit_rec) + +lemma signed_take_bit_code [code]: + \signed_take_bit n a = + (let l = take_bit (Suc n) a + in if bit l n then l + push_bit (Suc n) (- 1) else l)\ +proof - + have *: \take_bit (Suc n) a + push_bit n (- 2) = + take_bit (Suc n) a OR NOT (mask (Suc n))\ + by (auto simp add: bit_take_bit_iff bit_push_bit_iff bit_not_iff bit_mask_iff disjunctive_add + simp flip: push_bit_minus_one_eq_not_mask) + show ?thesis + by (rule bit_eqI) + (auto simp add: Let_def * bit_signed_take_bit_iff bit_take_bit_iff min_def less_Suc_eq bit_not_iff bit_mask_iff bit_or_iff) +qed + + +subsection \Instance \<^typ>\nat\\ + +instantiation nat :: semiring_bit_operations +begin + +definition and_nat :: \nat \ nat \ nat\ + where \m AND n = nat (int m AND int n)\ for m n :: nat + +definition or_nat :: \nat \ nat \ nat\ + where \m OR n = nat (int m OR int n)\ for m n :: nat + +definition xor_nat :: \nat \ nat \ nat\ + where \m XOR n = nat (int m XOR int n)\ for m n :: nat + +definition mask_nat :: \nat \ nat\ + where \mask n = (2 :: nat) ^ n - 1\ + +definition set_bit_nat :: \nat \ nat \ nat\ + where \set_bit m n = n OR push_bit m 1\ for m n :: nat + +definition unset_bit_nat :: \nat \ nat \ nat\ + where \unset_bit m n = (if bit n m then n - push_bit m 1 else n)\ for m n :: nat + +definition flip_bit_nat :: \nat \ nat \ nat\ + where \flip_bit m n = n XOR push_bit m 1\ for m n :: nat + +instance proof + fix m n q :: nat + show \bit (m AND n) q \ bit m q \ bit n q\ + by (simp add: and_nat_def bit_simps) + show \bit (m OR n) q \ bit m q \ bit n q\ + by (simp add: or_nat_def bit_simps) + show \bit (m XOR n) q \ bit m q \ bit n q\ + by (simp add: xor_nat_def bit_simps) + show \bit (unset_bit m n) q \ bit n q \ m \ q\ + proof (cases \bit n m\) + case False + then show ?thesis by (auto simp add: unset_bit_nat_def) + next + case True + have \push_bit m (drop_bit m n) + take_bit m n = n\ + by (fact bits_ident) + also from \bit n m\ have \drop_bit m n = 2 * drop_bit (Suc m) n + 1\ + by (simp add: drop_bit_Suc drop_bit_half even_drop_bit_iff_not_bit ac_simps) + finally have \push_bit m (2 * drop_bit (Suc m) n) + take_bit m n + push_bit m 1 = n\ + by (simp only: push_bit_add ac_simps) + then have \n - push_bit m 1 = push_bit m (2 * drop_bit (Suc m) n) + take_bit m n\ + by simp + then have \n - push_bit m 1 = push_bit m (2 * drop_bit (Suc m) n) OR take_bit m n\ + by (simp add: or_nat_def bit_simps flip: disjunctive_add) + with \bit n m\ show ?thesis + by (auto simp add: unset_bit_nat_def or_nat_def bit_simps) + qed +qed (simp_all add: mask_nat_def set_bit_nat_def flip_bit_nat_def) + +end + +lemma and_nat_rec: + \m AND n = of_bool (odd m \ odd n) + 2 * ((m div 2) AND (n div 2))\ for m n :: nat + by (simp add: and_nat_def and_int_rec [of \int m\ \int n\] zdiv_int nat_add_distrib nat_mult_distrib) + +lemma or_nat_rec: + \m OR n = of_bool (odd m \ odd n) + 2 * ((m div 2) OR (n div 2))\ for m n :: nat + by (simp add: or_nat_def or_int_rec [of \int m\ \int n\] zdiv_int nat_add_distrib nat_mult_distrib) + +lemma xor_nat_rec: + \m XOR n = of_bool (odd m \ odd n) + 2 * ((m div 2) XOR (n div 2))\ for m n :: nat + by (simp add: xor_nat_def xor_int_rec [of \int m\ \int n\] zdiv_int nat_add_distrib nat_mult_distrib) + +lemma Suc_0_and_eq [simp]: + \Suc 0 AND n = n mod 2\ + using one_and_eq [of n] by simp + +lemma and_Suc_0_eq [simp]: + \n AND Suc 0 = n mod 2\ + using and_one_eq [of n] by simp + +lemma Suc_0_or_eq: + \Suc 0 OR n = n + of_bool (even n)\ + using one_or_eq [of n] by simp + +lemma or_Suc_0_eq: + \n OR Suc 0 = n + of_bool (even n)\ + using or_one_eq [of n] by simp + +lemma Suc_0_xor_eq: + \Suc 0 XOR n = n + of_bool (even n) - of_bool (odd n)\ + using one_xor_eq [of n] by simp + +lemma xor_Suc_0_eq: + \n XOR Suc 0 = n + of_bool (even n) - of_bool (odd n)\ + using xor_one_eq [of n] by simp + +context semiring_bit_operations +begin + +lemma of_nat_and_eq: + \of_nat (m AND n) = of_nat m AND of_nat n\ + by (rule bit_eqI) (simp add: bit_of_nat_iff bit_and_iff Bit_Operations.bit_and_iff) + +lemma of_nat_or_eq: + \of_nat (m OR n) = of_nat m OR of_nat n\ + by (rule bit_eqI) (simp add: bit_of_nat_iff bit_or_iff Bit_Operations.bit_or_iff) + +lemma of_nat_xor_eq: + \of_nat (m XOR n) = of_nat m XOR of_nat n\ + by (rule bit_eqI) (simp add: bit_of_nat_iff bit_xor_iff Bit_Operations.bit_xor_iff) + +end + +context ring_bit_operations +begin + +lemma of_nat_mask_eq: + \of_nat (mask n) = mask n\ + by (induction n) (simp_all add: mask_Suc_double Bit_Operations.mask_Suc_double of_nat_or_eq) + +end + +lemma Suc_mask_eq_exp: + \Suc (mask n) = 2 ^ n\ + by (simp add: mask_eq_exp_minus_1) + +lemma less_eq_mask: + \n \ mask n\ + by (simp add: mask_eq_exp_minus_1 le_diff_conv2) + (metis Suc_mask_eq_exp diff_Suc_1 diff_le_diff_pow diff_zero le_refl not_less_eq_eq power_0) + +lemma less_mask: + \n < mask n\ if \Suc 0 < n\ +proof - + define m where \m = n - 2\ + with that have *: \n = m + 2\ + by simp + have \Suc (Suc (Suc m)) < 4 * 2 ^ m\ + by (induction m) simp_all + then have \Suc (m + 2) < Suc (mask (m + 2))\ + by (simp add: Suc_mask_eq_exp) + then have \m + 2 < mask (m + 2)\ + by (simp add: less_le) + with * show ?thesis + by simp +qed + + +subsection \Horner sums\ + +context semiring_bit_shifts +begin + +lemma horner_sum_bit_eq_take_bit: + \horner_sum of_bool 2 (map (bit a) [0.. +proof (induction a arbitrary: n rule: bits_induct) + case (stable a) + moreover have \bit a = (\_. odd a)\ + using stable by (simp add: stable_imp_bit_iff_odd fun_eq_iff) + moreover have \{q. q < n} = {0.. + by auto + ultimately show ?case + by (simp add: stable_imp_take_bit_eq horner_sum_eq_sum mask_eq_sum_exp) +next + case (rec a b) + show ?case + proof (cases n) + case 0 + then show ?thesis + by simp + next + case (Suc m) + have \map (bit (of_bool b + 2 * a)) [0.. + by (simp only: upt_conv_Cons) simp + also have \\ = b # map (bit a) [0.. + by (simp only: flip: map_Suc_upt) (simp add: bit_Suc rec.hyps) + finally show ?thesis + using Suc rec.IH [of m] by (simp add: take_bit_Suc rec.hyps) + (simp_all add: ac_simps mod_2_eq_odd) + qed +qed + +end + +context unique_euclidean_semiring_with_bit_shifts +begin + +lemma bit_horner_sum_bit_iff [bit_simps]: + \bit (horner_sum of_bool 2 bs) n \ n < length bs \ bs ! n\ +proof (induction bs arbitrary: n) + case Nil + then show ?case + by simp +next + case (Cons b bs) + show ?case + proof (cases n) + case 0 + then show ?thesis + by simp + next + case (Suc m) + with bit_rec [of _ n] Cons.prems Cons.IH [of m] + show ?thesis by simp + qed +qed + +lemma take_bit_horner_sum_bit_eq: + \take_bit n (horner_sum of_bool 2 bs) = horner_sum of_bool 2 (take n bs)\ + by (auto simp add: bit_eq_iff bit_take_bit_iff bit_horner_sum_bit_iff) + +end + +lemma horner_sum_of_bool_2_less: + \(horner_sum of_bool 2 bs :: int) < 2 ^ length bs\ +proof - + have \(\n = 0.. (\n = 0.. + by (rule sum_mono) simp + also have \\ = 2 ^ length bs - 1\ + by (induction bs) simp_all + finally show ?thesis + by (simp add: horner_sum_eq_sum) +qed + + +subsection \Symbolic computations on numeral expressions\ \<^marker>\contributor \Andreas Lochbihler\\ + +fun and_num :: \num \ num \ num option\ +where + \and_num num.One num.One = Some num.One\ +| \and_num num.One (num.Bit0 n) = None\ +| \and_num num.One (num.Bit1 n) = Some num.One\ +| \and_num (num.Bit0 m) num.One = None\ +| \and_num (num.Bit0 m) (num.Bit0 n) = map_option num.Bit0 (and_num m n)\ +| \and_num (num.Bit0 m) (num.Bit1 n) = map_option num.Bit0 (and_num m n)\ +| \and_num (num.Bit1 m) num.One = Some num.One\ +| \and_num (num.Bit1 m) (num.Bit0 n) = map_option num.Bit0 (and_num m n)\ +| \and_num (num.Bit1 m) (num.Bit1 n) = (case and_num m n of None \ Some num.One | Some n' \ Some (num.Bit1 n'))\ + +fun and_not_num :: \num \ num \ num option\ +where + \and_not_num num.One num.One = None\ +| \and_not_num num.One (num.Bit0 n) = Some num.One\ +| \and_not_num num.One (num.Bit1 n) = None\ +| \and_not_num (num.Bit0 m) num.One = Some (num.Bit0 m)\ +| \and_not_num (num.Bit0 m) (num.Bit0 n) = map_option num.Bit0 (and_not_num m n)\ +| \and_not_num (num.Bit0 m) (num.Bit1 n) = map_option num.Bit0 (and_not_num m n)\ +| \and_not_num (num.Bit1 m) num.One = Some (num.Bit0 m)\ +| \and_not_num (num.Bit1 m) (num.Bit0 n) = (case and_not_num m n of None \ Some num.One | Some n' \ Some (num.Bit1 n'))\ +| \and_not_num (num.Bit1 m) (num.Bit1 n) = map_option num.Bit0 (and_not_num m n)\ + +fun or_num :: \num \ num \ num\ +where + \or_num num.One num.One = num.One\ +| \or_num num.One (num.Bit0 n) = num.Bit1 n\ +| \or_num num.One (num.Bit1 n) = num.Bit1 n\ +| \or_num (num.Bit0 m) num.One = num.Bit1 m\ +| \or_num (num.Bit0 m) (num.Bit0 n) = num.Bit0 (or_num m n)\ +| \or_num (num.Bit0 m) (num.Bit1 n) = num.Bit1 (or_num m n)\ +| \or_num (num.Bit1 m) num.One = num.Bit1 m\ +| \or_num (num.Bit1 m) (num.Bit0 n) = num.Bit1 (or_num m n)\ +| \or_num (num.Bit1 m) (num.Bit1 n) = num.Bit1 (or_num m n)\ + +fun or_not_num_neg :: \num \ num \ num\ +where + \or_not_num_neg num.One num.One = num.One\ +| \or_not_num_neg num.One (num.Bit0 m) = num.Bit1 m\ +| \or_not_num_neg num.One (num.Bit1 m) = num.Bit1 m\ +| \or_not_num_neg (num.Bit0 n) num.One = num.Bit0 num.One\ +| \or_not_num_neg (num.Bit0 n) (num.Bit0 m) = Num.BitM (or_not_num_neg n m)\ +| \or_not_num_neg (num.Bit0 n) (num.Bit1 m) = num.Bit0 (or_not_num_neg n m)\ +| \or_not_num_neg (num.Bit1 n) num.One = num.One\ +| \or_not_num_neg (num.Bit1 n) (num.Bit0 m) = Num.BitM (or_not_num_neg n m)\ +| \or_not_num_neg (num.Bit1 n) (num.Bit1 m) = Num.BitM (or_not_num_neg n m)\ + +fun xor_num :: \num \ num \ num option\ +where + \xor_num num.One num.One = None\ +| \xor_num num.One (num.Bit0 n) = Some (num.Bit1 n)\ +| \xor_num num.One (num.Bit1 n) = Some (num.Bit0 n)\ +| \xor_num (num.Bit0 m) num.One = Some (num.Bit1 m)\ +| \xor_num (num.Bit0 m) (num.Bit0 n) = map_option num.Bit0 (xor_num m n)\ +| \xor_num (num.Bit0 m) (num.Bit1 n) = Some (case xor_num m n of None \ num.One | Some n' \ num.Bit1 n')\ +| \xor_num (num.Bit1 m) num.One = Some (num.Bit0 m)\ +| \xor_num (num.Bit1 m) (num.Bit0 n) = Some (case xor_num m n of None \ num.One | Some n' \ num.Bit1 n')\ +| \xor_num (num.Bit1 m) (num.Bit1 n) = map_option num.Bit0 (xor_num m n)\ + +lemma int_numeral_and_num: + \numeral m AND numeral n = (case and_num m n of None \ 0 :: int | Some n' \ numeral n')\ + by (induction m n rule: and_num.induct) (simp_all split: option.split) + +lemma and_num_eq_None_iff: + \and_num m n = None \ numeral m AND numeral n = (0::int)\ + by (simp add: int_numeral_and_num split: option.split) + +lemma and_num_eq_Some_iff: + \and_num m n = Some q \ numeral m AND numeral n = (numeral q :: int)\ + by (simp add: int_numeral_and_num split: option.split) + +lemma int_numeral_and_not_num: + \numeral m AND NOT (numeral n) = (case and_not_num m n of None \ 0 :: int | Some n' \ numeral n')\ + by (induction m n rule: and_not_num.induct) (simp_all add: add_One BitM_inc_eq not_int_def split: option.split) + +lemma int_numeral_not_and_num: + \NOT (numeral m) AND numeral n = (case and_not_num n m of None \ 0 :: int | Some n' \ numeral n')\ + using int_numeral_and_not_num [of n m] by (simp add: ac_simps) + +lemma and_not_num_eq_None_iff: + \and_not_num m n = None \ numeral m AND NOT (numeral n) = (0::int)\ + by (simp add: int_numeral_and_not_num split: option.split) + +lemma and_not_num_eq_Some_iff: + \and_not_num m n = Some q \ numeral m AND NOT (numeral n) = (numeral q :: int)\ + by (simp add: int_numeral_and_not_num split: option.split) + +lemma int_numeral_or_num: + \numeral m OR numeral n = (numeral (or_num m n) :: int)\ + by (induction m n rule: or_num.induct) simp_all + +lemma numeral_or_num_eq: + \numeral (or_num m n) = (numeral m OR numeral n :: int)\ + by (simp add: int_numeral_or_num) + +lemma int_numeral_or_not_num_neg: + \numeral m OR NOT (numeral n :: int) = - numeral (or_not_num_neg m n)\ + by (induction m n rule: or_not_num_neg.induct) (simp_all add: add_One BitM_inc_eq not_int_def) + +lemma int_numeral_not_or_num_neg: + \NOT (numeral m) OR (numeral n :: int) = - numeral (or_not_num_neg n m)\ + using int_numeral_or_not_num_neg [of n m] by (simp add: ac_simps) + +lemma numeral_or_not_num_eq: + \numeral (or_not_num_neg m n) = - (numeral m OR NOT (numeral n :: int))\ + using int_numeral_or_not_num_neg [of m n] by simp + +lemma int_numeral_xor_num: + \numeral m XOR numeral n = (case xor_num m n of None \ 0 :: int | Some n' \ numeral n')\ + by (induction m n rule: xor_num.induct) (simp_all split: option.split) + +lemma xor_num_eq_None_iff: + \xor_num m n = None \ numeral m XOR numeral n = (0::int)\ + by (simp add: int_numeral_xor_num split: option.split) + +lemma xor_num_eq_Some_iff: + \xor_num m n = Some q \ numeral m XOR numeral n = (numeral q :: int)\ + by (simp add: int_numeral_xor_num split: option.split) + + +subsection \Key ideas of bit operations\ + +text \ + When formalizing bit operations, it is tempting to represent + bit values as explicit lists over a binary type. This however + is a bad idea, mainly due to the inherent ambiguities in + representation concerning repeating leading bits. + + Hence this approach avoids such explicit lists altogether + following an algebraic path: + + \<^item> Bit values are represented by numeric types: idealized + unbounded bit values can be represented by type \<^typ>\int\, + bounded bit values by quotient types over \<^typ>\int\. + + \<^item> (A special case are idealized unbounded bit values ending + in @{term [source] 0} which can be represented by type \<^typ>\nat\ but + only support a restricted set of operations). + + \<^item> From this idea follows that + + \<^item> multiplication by \<^term>\2 :: int\ is a bit shift to the left and + + \<^item> division by \<^term>\2 :: int\ is a bit shift to the right. + + \<^item> Concerning bounded bit values, iterated shifts to the left + may result in eliminating all bits by shifting them all + beyond the boundary. The property \<^prop>\(2 :: int) ^ n \ 0\ + represents that \<^term>\n\ is \<^emph>\not\ beyond that boundary. + + \<^item> The projection on a single bit is then @{thm bit_iff_odd [where ?'a = int, no_vars]}. + + \<^item> This leads to the most fundamental properties of bit values: + + \<^item> Equality rule: @{thm bit_eqI [where ?'a = int, no_vars]} + + \<^item> Induction rule: @{thm bits_induct [where ?'a = int, no_vars]} + + \<^item> Typical operations are characterized as follows: + + \<^item> Singleton \<^term>\n\th bit: \<^term>\(2 :: int) ^ n\ + + \<^item> Bit mask upto bit \<^term>\n\: @{thm mask_eq_exp_minus_1 [where ?'a = int, no_vars]} + + \<^item> Left shift: @{thm push_bit_eq_mult [where ?'a = int, no_vars]} + + \<^item> Right shift: @{thm drop_bit_eq_div [where ?'a = int, no_vars]} + + \<^item> Truncation: @{thm take_bit_eq_mod [where ?'a = int, no_vars]} + + \<^item> Negation: @{thm bit_not_iff [where ?'a = int, no_vars]} + + \<^item> And: @{thm bit_and_iff [where ?'a = int, no_vars]} + + \<^item> Or: @{thm bit_or_iff [where ?'a = int, no_vars]} + + \<^item> Xor: @{thm bit_xor_iff [where ?'a = int, no_vars]} + + \<^item> Set a single bit: @{thm set_bit_def [where ?'a = int, no_vars]} + + \<^item> Unset a single bit: @{thm unset_bit_def [where ?'a = int, no_vars]} + + \<^item> Flip a single bit: @{thm flip_bit_def [where ?'a = int, no_vars]} + + \<^item> Signed truncation, or modulus centered around \<^term>\0::int\: @{thm signed_take_bit_def [no_vars]} + + \<^item> Bit concatenation: @{thm concat_bit_def [no_vars]} + + \<^item> (Bounded) conversion from and to a list of bits: @{thm horner_sum_bit_eq_take_bit [where ?'a = int, no_vars]} +\ + +no_notation + "and" (infixr \AND\ 64) + and or (infixr \OR\ 59) + and xor (infixr \XOR\ 59) + +bundle bit_operations_syntax +begin + +notation + "and" (infixr \AND\ 64) + and or (infixr \OR\ 59) + and xor (infixr \XOR\ 59) + +end + +end diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Boolean_Algebra.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/Boolean_Algebra.thy Mon Aug 02 10:01:06 2021 +0000 @@ -0,0 +1,296 @@ +(* Title: HOL/Boolean_Algebra.thy + Author: Brian Huffman +*) + +section \Abstract boolean Algebras\ + +theory Boolean_Algebra + imports Lattices +begin + +locale boolean_algebra = conj: abel_semigroup "(\<^bold>\)" + disj: abel_semigroup "(\<^bold>\)" + for conj :: "'a \ 'a \ 'a" (infixr "\<^bold>\" 70) + and disj :: "'a \ 'a \ 'a" (infixr "\<^bold>\" 65) + + fixes compl :: "'a \ 'a" ("\<^bold>- _" [81] 80) + and zero :: "'a" ("\<^bold>0") + and one :: "'a" ("\<^bold>1") + assumes conj_disj_distrib: "x \<^bold>\ (y \<^bold>\ z) = (x \<^bold>\ y) \<^bold>\ (x \<^bold>\ z)" + and disj_conj_distrib: "x \<^bold>\ (y \<^bold>\ z) = (x \<^bold>\ y) \<^bold>\ (x \<^bold>\ z)" + and conj_one_right: "x \<^bold>\ \<^bold>1 = x" + and disj_zero_right: "x \<^bold>\ \<^bold>0 = x" + and conj_cancel_right [simp]: "x \<^bold>\ \<^bold>- x = \<^bold>0" + and disj_cancel_right [simp]: "x \<^bold>\ \<^bold>- x = \<^bold>1" +begin + +sublocale conj: semilattice_neutr "(\<^bold>\)" "\<^bold>1" +proof + show "x \<^bold>\ \<^bold>1 = x" for x + by (fact conj_one_right) + show "x \<^bold>\ x = x" for x + proof - + have "x \<^bold>\ x = (x \<^bold>\ x) \<^bold>\ \<^bold>0" + by (simp add: disj_zero_right) + also have "\ = (x \<^bold>\ x) \<^bold>\ (x \<^bold>\ \<^bold>- x)" + by simp + also have "\ = x \<^bold>\ (x \<^bold>\ \<^bold>- x)" + by (simp only: conj_disj_distrib) + also have "\ = x \<^bold>\ \<^bold>1" + by simp + also have "\ = x" + by (simp add: conj_one_right) + finally show ?thesis . + qed +qed + +sublocale disj: semilattice_neutr "(\<^bold>\)" "\<^bold>0" +proof + show "x \<^bold>\ \<^bold>0 = x" for x + by (fact disj_zero_right) + show "x \<^bold>\ x = x" for x + proof - + have "x \<^bold>\ x = (x \<^bold>\ x) \<^bold>\ \<^bold>1" + by simp + also have "\ = (x \<^bold>\ x) \<^bold>\ (x \<^bold>\ \<^bold>- x)" + by simp + also have "\ = x \<^bold>\ (x \<^bold>\ \<^bold>- x)" + by (simp only: disj_conj_distrib) + also have "\ = x \<^bold>\ \<^bold>0" + by simp + also have "\ = x" + by (simp add: disj_zero_right) + finally show ?thesis . + qed +qed + + +subsection \Complement\ + +lemma complement_unique: + assumes 1: "a \<^bold>\ x = \<^bold>0" + assumes 2: "a \<^bold>\ x = \<^bold>1" + assumes 3: "a \<^bold>\ y = \<^bold>0" + assumes 4: "a \<^bold>\ y = \<^bold>1" + shows "x = y" +proof - + from 1 3 have "(a \<^bold>\ x) \<^bold>\ (x \<^bold>\ y) = (a \<^bold>\ y) \<^bold>\ (x \<^bold>\ y)" + by simp + then have "(x \<^bold>\ a) \<^bold>\ (x \<^bold>\ y) = (y \<^bold>\ a) \<^bold>\ (y \<^bold>\ x)" + by (simp add: ac_simps) + then have "x \<^bold>\ (a \<^bold>\ y) = y \<^bold>\ (a \<^bold>\ x)" + by (simp add: conj_disj_distrib) + with 2 4 have "x \<^bold>\ \<^bold>1 = y \<^bold>\ \<^bold>1" + by simp + then show "x = y" + by simp +qed + +lemma compl_unique: "x \<^bold>\ y = \<^bold>0 \ x \<^bold>\ y = \<^bold>1 \ \<^bold>- x = y" + by (rule complement_unique [OF conj_cancel_right disj_cancel_right]) + +lemma double_compl [simp]: "\<^bold>- (\<^bold>- x) = x" +proof (rule compl_unique) + show "\<^bold>- x \<^bold>\ x = \<^bold>0" + by (simp only: conj_cancel_right conj.commute) + show "\<^bold>- x \<^bold>\ x = \<^bold>1" + by (simp only: disj_cancel_right disj.commute) +qed + +lemma compl_eq_compl_iff [simp]: + \\<^bold>- x = \<^bold>- y \ x = y\ (is \?P \ ?Q\) +proof + assume \?Q\ + then show ?P by simp +next + assume \?P\ + then have \\<^bold>- (\<^bold>- x) = \<^bold>- (\<^bold>- y)\ + by simp + then show ?Q + by simp +qed + + +subsection \Conjunction\ + +lemma conj_zero_right [simp]: "x \<^bold>\ \<^bold>0 = \<^bold>0" + using conj.left_idem conj_cancel_right by fastforce + +lemma compl_one [simp]: "\<^bold>- \<^bold>1 = \<^bold>0" + by (rule compl_unique [OF conj_zero_right disj_zero_right]) + +lemma conj_zero_left [simp]: "\<^bold>0 \<^bold>\ x = \<^bold>0" + by (subst conj.commute) (rule conj_zero_right) + +lemma conj_cancel_left [simp]: "\<^bold>- x \<^bold>\ x = \<^bold>0" + by (subst conj.commute) (rule conj_cancel_right) + +lemma conj_disj_distrib2: "(y \<^bold>\ z) \<^bold>\ x = (y \<^bold>\ x) \<^bold>\ (z \<^bold>\ x)" + by (simp only: conj.commute conj_disj_distrib) + +lemmas conj_disj_distribs = conj_disj_distrib conj_disj_distrib2 + +lemma conj_assoc: "(x \<^bold>\ y) \<^bold>\ z = x \<^bold>\ (y \<^bold>\ z)" + by (fact ac_simps) + +lemma conj_commute: "x \<^bold>\ y = y \<^bold>\ x" + by (fact ac_simps) + +lemmas conj_left_commute = conj.left_commute +lemmas conj_ac = conj.assoc conj.commute conj.left_commute + +lemma conj_one_left: "\<^bold>1 \<^bold>\ x = x" + by (fact conj.left_neutral) + +lemma conj_left_absorb: "x \<^bold>\ (x \<^bold>\ y) = x \<^bold>\ y" + by (fact conj.left_idem) + +lemma conj_absorb: "x \<^bold>\ x = x" + by (fact conj.idem) + + +subsection \Disjunction\ + +interpretation dual: boolean_algebra "(\<^bold>\)" "(\<^bold>\)" compl \\<^bold>1\ \\<^bold>0\ + apply standard + apply (rule disj_conj_distrib) + apply (rule conj_disj_distrib) + apply simp_all + done + +lemma compl_zero [simp]: "\<^bold>- \<^bold>0 = \<^bold>1" + by (fact dual.compl_one) + +lemma disj_one_right [simp]: "x \<^bold>\ \<^bold>1 = \<^bold>1" + by (fact dual.conj_zero_right) + +lemma disj_one_left [simp]: "\<^bold>1 \<^bold>\ x = \<^bold>1" + by (fact dual.conj_zero_left) + +lemma disj_cancel_left [simp]: "\<^bold>- x \<^bold>\ x = \<^bold>1" + by (rule dual.conj_cancel_left) + +lemma disj_conj_distrib2: "(y \<^bold>\ z) \<^bold>\ x = (y \<^bold>\ x) \<^bold>\ (z \<^bold>\ x)" + by (rule dual.conj_disj_distrib2) + +lemmas disj_conj_distribs = disj_conj_distrib disj_conj_distrib2 + +lemma disj_assoc: "(x \<^bold>\ y) \<^bold>\ z = x \<^bold>\ (y \<^bold>\ z)" + by (fact ac_simps) + +lemma disj_commute: "x \<^bold>\ y = y \<^bold>\ x" + by (fact ac_simps) + +lemmas disj_left_commute = disj.left_commute + +lemmas disj_ac = disj.assoc disj.commute disj.left_commute + +lemma disj_zero_left: "\<^bold>0 \<^bold>\ x = x" + by (fact disj.left_neutral) + +lemma disj_left_absorb: "x \<^bold>\ (x \<^bold>\ y) = x \<^bold>\ y" + by (fact disj.left_idem) + +lemma disj_absorb: "x \<^bold>\ x = x" + by (fact disj.idem) + + +subsection \De Morgan's Laws\ + +lemma de_Morgan_conj [simp]: "\<^bold>- (x \<^bold>\ y) = \<^bold>- x \<^bold>\ \<^bold>- y" +proof (rule compl_unique) + have "(x \<^bold>\ y) \<^bold>\ (\<^bold>- x \<^bold>\ \<^bold>- y) = ((x \<^bold>\ y) \<^bold>\ \<^bold>- x) \<^bold>\ ((x \<^bold>\ y) \<^bold>\ \<^bold>- y)" + by (rule conj_disj_distrib) + also have "\ = (y \<^bold>\ (x \<^bold>\ \<^bold>- x)) \<^bold>\ (x \<^bold>\ (y \<^bold>\ \<^bold>- y))" + by (simp only: conj_ac) + finally show "(x \<^bold>\ y) \<^bold>\ (\<^bold>- x \<^bold>\ \<^bold>- y) = \<^bold>0" + by (simp only: conj_cancel_right conj_zero_right disj_zero_right) +next + have "(x \<^bold>\ y) \<^bold>\ (\<^bold>- x \<^bold>\ \<^bold>- y) = (x \<^bold>\ (\<^bold>- x \<^bold>\ \<^bold>- y)) \<^bold>\ (y \<^bold>\ (\<^bold>- x \<^bold>\ \<^bold>- y))" + by (rule disj_conj_distrib2) + also have "\ = (\<^bold>- y \<^bold>\ (x \<^bold>\ \<^bold>- x)) \<^bold>\ (\<^bold>- x \<^bold>\ (y \<^bold>\ \<^bold>- y))" + by (simp only: disj_ac) + finally show "(x \<^bold>\ y) \<^bold>\ (\<^bold>- x \<^bold>\ \<^bold>- y) = \<^bold>1" + by (simp only: disj_cancel_right disj_one_right conj_one_right) +qed + +lemma de_Morgan_disj [simp]: "\<^bold>- (x \<^bold>\ y) = \<^bold>- x \<^bold>\ \<^bold>- y" + using dual.boolean_algebra_axioms by (rule boolean_algebra.de_Morgan_conj) + + +subsection \Symmetric Difference\ + +definition xor :: "'a \ 'a \ 'a" (infixr "\<^bold>\" 65) + where "x \<^bold>\ y = (x \<^bold>\ \<^bold>- y) \<^bold>\ (\<^bold>- x \<^bold>\ y)" + +sublocale xor: comm_monoid xor \\<^bold>0\ +proof + fix x y z :: 'a + let ?t = "(x \<^bold>\ y \<^bold>\ z) \<^bold>\ (x \<^bold>\ \<^bold>- y \<^bold>\ \<^bold>- z) \<^bold>\ (\<^bold>- x \<^bold>\ y \<^bold>\ \<^bold>- z) \<^bold>\ (\<^bold>- x \<^bold>\ \<^bold>- y \<^bold>\ z)" + have "?t \<^bold>\ (z \<^bold>\ x \<^bold>\ \<^bold>- x) \<^bold>\ (z \<^bold>\ y \<^bold>\ \<^bold>- y) = ?t \<^bold>\ (x \<^bold>\ y \<^bold>\ \<^bold>- y) \<^bold>\ (x \<^bold>\ z \<^bold>\ \<^bold>- z)" + by (simp only: conj_cancel_right conj_zero_right) + then show "(x \<^bold>\ y) \<^bold>\ z = x \<^bold>\ (y \<^bold>\ z)" + by (simp only: xor_def de_Morgan_disj de_Morgan_conj double_compl) + (simp only: conj_disj_distribs conj_ac disj_ac) + show "x \<^bold>\ y = y \<^bold>\ x" + by (simp only: xor_def conj_commute disj_commute) + show "x \<^bold>\ \<^bold>0 = x" + by (simp add: xor_def) +qed + +lemmas xor_assoc = xor.assoc +lemmas xor_commute = xor.commute +lemmas xor_left_commute = xor.left_commute + +lemmas xor_ac = xor.assoc xor.commute xor.left_commute + +lemma xor_def2: "x \<^bold>\ y = (x \<^bold>\ y) \<^bold>\ (\<^bold>- x \<^bold>\ \<^bold>- y)" + using conj.commute conj_disj_distrib2 disj.commute xor_def by auto + +lemma xor_zero_right: "x \<^bold>\ \<^bold>0 = x" + by (fact xor.comm_neutral) + +lemma xor_zero_left: "\<^bold>0 \<^bold>\ x = x" + by (fact xor.left_neutral) + +lemma xor_one_right [simp]: "x \<^bold>\ \<^bold>1 = \<^bold>- x" + by (simp only: xor_def compl_one conj_zero_right conj_one_right disj_zero_left) + +lemma xor_one_left [simp]: "\<^bold>1 \<^bold>\ x = \<^bold>- x" + by (subst xor_commute) (rule xor_one_right) + +lemma xor_self [simp]: "x \<^bold>\ x = \<^bold>0" + by (simp only: xor_def conj_cancel_right conj_cancel_left disj_zero_right) + +lemma xor_left_self [simp]: "x \<^bold>\ (x \<^bold>\ y) = y" + by (simp only: xor_assoc [symmetric] xor_self xor_zero_left) + +lemma xor_compl_left [simp]: "\<^bold>- x \<^bold>\ y = \<^bold>- (x \<^bold>\ y)" + by (simp add: ac_simps flip: xor_one_left) + +lemma xor_compl_right [simp]: "x \<^bold>\ \<^bold>- y = \<^bold>- (x \<^bold>\ y)" + using xor_commute xor_compl_left by auto + +lemma xor_cancel_right: "x \<^bold>\ \<^bold>- x = \<^bold>1" + by (simp only: xor_compl_right xor_self compl_zero) + +lemma xor_cancel_left: "\<^bold>- x \<^bold>\ x = \<^bold>1" + by (simp only: xor_compl_left xor_self compl_zero) + +lemma conj_xor_distrib: "x \<^bold>\ (y \<^bold>\ z) = (x \<^bold>\ y) \<^bold>\ (x \<^bold>\ z)" +proof - + have *: "(x \<^bold>\ y \<^bold>\ \<^bold>- z) \<^bold>\ (x \<^bold>\ \<^bold>- y \<^bold>\ z) = + (y \<^bold>\ x \<^bold>\ \<^bold>- x) \<^bold>\ (z \<^bold>\ x \<^bold>\ \<^bold>- x) \<^bold>\ (x \<^bold>\ y \<^bold>\ \<^bold>- z) \<^bold>\ (x \<^bold>\ \<^bold>- y \<^bold>\ z)" + by (simp only: conj_cancel_right conj_zero_right disj_zero_left) + then show "x \<^bold>\ (y \<^bold>\ z) = (x \<^bold>\ y) \<^bold>\ (x \<^bold>\ z)" + by (simp (no_asm_use) only: + xor_def de_Morgan_disj de_Morgan_conj double_compl + conj_disj_distribs conj_ac disj_ac) +qed + +lemma conj_xor_distrib2: "(y \<^bold>\ z) \<^bold>\ x = (y \<^bold>\ x) \<^bold>\ (z \<^bold>\ x)" + by (simp add: conj.commute conj_xor_distrib) + +lemmas conj_xor_distribs = conj_xor_distrib conj_xor_distrib2 + +end + +end diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Code_Numeral.thy --- a/src/HOL/Code_Numeral.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/Code_Numeral.thy Mon Aug 02 10:01:06 2021 +0000 @@ -5,7 +5,7 @@ section \Numeric types for code generation onto target language numerals only\ theory Code_Numeral -imports Divides Lifting +imports Divides Lifting Bit_Operations begin subsection \Type of target language integers\ @@ -1203,12 +1203,6 @@ hide_const (open) Nat -lifting_update integer.lifting -lifting_forget integer.lifting - -lifting_update natural.lifting -lifting_forget natural.lifting - code_reflect Code_Numeral datatypes natural functions "Code_Numeral.Suc" "0 :: natural" "1 :: natural" @@ -1217,4 +1211,87 @@ "modulo :: natural \ _" integer_of_natural natural_of_integer + +subsection \Bit operations\ + +instantiation integer :: ring_bit_operations +begin + +lift_definition not_integer :: \integer \ integer\ + is not . + +lift_definition and_integer :: \integer \ integer \ integer\ + is \and\ . + +lift_definition or_integer :: \integer \ integer \ integer\ + is or . + +lift_definition xor_integer :: \integer \ integer \ integer\ + is xor . + +lift_definition mask_integer :: \nat \ integer\ + is mask . + +lift_definition set_bit_integer :: \nat \ integer \ integer\ + is set_bit . + +lift_definition unset_bit_integer :: \nat \ integer \ integer\ + is unset_bit . + +lift_definition flip_bit_integer :: \nat \ integer \ integer\ + is flip_bit . + +instance by (standard; transfer) + (simp_all add: minus_eq_not_minus_1 mask_eq_exp_minus_1 + bit_not_iff bit_and_iff bit_or_iff bit_xor_iff + set_bit_def bit_unset_bit_iff flip_bit_def) + end + +lemma [code]: + \mask n = 2 ^ n - (1::integer)\ + by (simp add: mask_eq_exp_minus_1) + +instantiation natural :: semiring_bit_operations +begin + +lift_definition and_natural :: \natural \ natural \ natural\ + is \and\ . + +lift_definition or_natural :: \natural \ natural \ natural\ + is or . + +lift_definition xor_natural :: \natural \ natural \ natural\ + is xor . + +lift_definition mask_natural :: \nat \ natural\ + is mask . + +lift_definition set_bit_natural :: \nat \ natural \ natural\ + is set_bit . + +lift_definition unset_bit_natural :: \nat \ natural \ natural\ + is unset_bit . + +lift_definition flip_bit_natural :: \nat \ natural \ natural\ + is flip_bit . + +instance by (standard; transfer) + (simp_all add: mask_eq_exp_minus_1 + bit_and_iff bit_or_iff bit_xor_iff + set_bit_def bit_unset_bit_iff flip_bit_def) + +end + +lemma [code]: + \integer_of_natural (mask n) = mask n\ + by transfer (simp add: mask_eq_exp_minus_1 of_nat_diff) + + +lifting_update integer.lifting +lifting_forget integer.lifting + +lifting_update natural.lifting +lifting_forget natural.lifting + +end diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Decision_Procs/Cooper.thy --- a/src/HOL/Decision_Procs/Cooper.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/Decision_Procs/Cooper.thy Mon Aug 02 10:01:06 2021 +0000 @@ -46,7 +46,7 @@ datatype (plugins del: size) fm = T | F | Lt num | Le num | Gt num | Ge num | Eq num | NEq num | Dvd int num | NDvd int num - | NOT fm | And fm fm | Or fm fm | Imp fm fm | Iff fm fm + | Not fm | And fm fm | Or fm fm | Imp fm fm | Iff fm fm | E fm | A fm | Closed nat | NClosed nat instantiation fm :: size @@ -54,7 +54,7 @@ primrec size_fm :: "fm \ nat" where - "size_fm (NOT p) = 1 + size_fm p" + "size_fm (Not p) = 1 + size_fm p" | "size_fm (And p q) = 1 + size_fm p + size_fm q" | "size_fm (Or p q) = 1 + size_fm p + size_fm q" | "size_fm (Imp p q) = 3 + size_fm p + size_fm q" @@ -94,7 +94,7 @@ | "Ifm bbs bs (NEq a) \ Inum bs a \ 0" | "Ifm bbs bs (Dvd i b) \ i dvd Inum bs b" | "Ifm bbs bs (NDvd i b) \ \ i dvd Inum bs b" - | "Ifm bbs bs (NOT p) \ \ Ifm bbs bs p" + | "Ifm bbs bs (Not p) \ \ Ifm bbs bs p" | "Ifm bbs bs (And p q) \ Ifm bbs bs p \ Ifm bbs bs q" | "Ifm bbs bs (Or p q) \ Ifm bbs bs p \ Ifm bbs bs q" | "Ifm bbs bs (Imp p q) \ (Ifm bbs bs p \ Ifm bbs bs q)" @@ -109,25 +109,25 @@ "prep (E T) = T" | "prep (E F) = F" | "prep (E (Or p q)) = Or (prep (E p)) (prep (E q))" - | "prep (E (Imp p q)) = Or (prep (E (NOT p))) (prep (E q))" - | "prep (E (Iff p q)) = Or (prep (E (And p q))) (prep (E (And (NOT p) (NOT q))))" - | "prep (E (NOT (And p q))) = Or (prep (E (NOT p))) (prep (E(NOT q)))" - | "prep (E (NOT (Imp p q))) = prep (E (And p (NOT q)))" - | "prep (E (NOT (Iff p q))) = Or (prep (E (And p (NOT q)))) (prep (E(And (NOT p) q)))" + | "prep (E (Imp p q)) = Or (prep (E (Not p))) (prep (E q))" + | "prep (E (Iff p q)) = Or (prep (E (And p q))) (prep (E (And (Not p) (Not q))))" + | "prep (E (Not (And p q))) = Or (prep (E (Not p))) (prep (E(Not q)))" + | "prep (E (Not (Imp p q))) = prep (E (And p (Not q)))" + | "prep (E (Not (Iff p q))) = Or (prep (E (And p (Not q)))) (prep (E(And (Not p) q)))" | "prep (E p) = E (prep p)" | "prep (A (And p q)) = And (prep (A p)) (prep (A q))" - | "prep (A p) = prep (NOT (E (NOT p)))" - | "prep (NOT (NOT p)) = prep p" - | "prep (NOT (And p q)) = Or (prep (NOT p)) (prep (NOT q))" - | "prep (NOT (A p)) = prep (E (NOT p))" - | "prep (NOT (Or p q)) = And (prep (NOT p)) (prep (NOT q))" - | "prep (NOT (Imp p q)) = And (prep p) (prep (NOT q))" - | "prep (NOT (Iff p q)) = Or (prep (And p (NOT q))) (prep (And (NOT p) q))" - | "prep (NOT p) = NOT (prep p)" + | "prep (A p) = prep (Not (E (Not p)))" + | "prep (Not (Not p)) = prep p" + | "prep (Not (And p q)) = Or (prep (Not p)) (prep (Not q))" + | "prep (Not (A p)) = prep (E (Not p))" + | "prep (Not (Or p q)) = And (prep (Not p)) (prep (Not q))" + | "prep (Not (Imp p q)) = And (prep p) (prep (Not q))" + | "prep (Not (Iff p q)) = Or (prep (And p (Not q))) (prep (And (Not p) q))" + | "prep (Not p) = Not (prep p)" | "prep (Or p q) = Or (prep p) (prep q)" | "prep (And p q) = And (prep p) (prep q)" - | "prep (Imp p q) = prep (Or (NOT p) q)" - | "prep (Iff p q) = Or (prep (And p q)) (prep (And (NOT p) (NOT q)))" + | "prep (Imp p q) = prep (Or (Not p) q)" + | "prep (Iff p q) = Or (prep (And p q)) (prep (And (Not p) (Not q)))" | "prep p = p" lemma prep: "Ifm bbs bs (prep p) = Ifm bbs bs p" @@ -138,7 +138,7 @@ where "qfree (E p) \ False" | "qfree (A p) \ False" - | "qfree (NOT p) \ qfree p" + | "qfree (Not p) \ qfree p" | "qfree (And p q) \ qfree p \ qfree q" | "qfree (Or p q) \ qfree p \ qfree q" | "qfree (Imp p q) \ qfree p \ qfree q" @@ -175,7 +175,7 @@ | "bound0 (NEq a) \ numbound0 a" | "bound0 (Dvd i a) \ numbound0 a" | "bound0 (NDvd i a) \ numbound0 a" - | "bound0 (NOT p) \ bound0 p" + | "bound0 (Not p) \ bound0 p" | "bound0 (And p q) \ bound0 p \ bound0 q" | "bound0 (Or p q) \ bound0 p \ bound0 q" | "bound0 (Imp p q) \ bound0 p \ bound0 q" @@ -220,7 +220,7 @@ | "subst0 t (NEq a) = NEq (numsubst0 t a)" | "subst0 t (Dvd i a) = Dvd i (numsubst0 t a)" | "subst0 t (NDvd i a) = NDvd i (numsubst0 t a)" - | "subst0 t (NOT p) = NOT (subst0 t p)" + | "subst0 t (Not p) = Not (subst0 t p)" | "subst0 t (And p q) = And (subst0 t p) (subst0 t q)" | "subst0 t (Or p q) = Or (subst0 t p) (subst0 t q)" | "subst0 t (Imp p q) = Imp (subst0 t p) (subst0 t q)" @@ -254,7 +254,7 @@ | "decr (NEq a) = NEq (decrnum a)" | "decr (Dvd i a) = Dvd i (decrnum a)" | "decr (NDvd i a) = NDvd i (decrnum a)" - | "decr (NOT p) = NOT (decr p)" + | "decr (Not p) = Not (decr p)" | "decr (And p q) = And (decr p) (decr q)" | "decr (Or p q) = Or (decr p) (decr q)" | "decr (Imp p q) = Imp (decr p) (decr q)" @@ -508,12 +508,12 @@ fun not :: "fm \ fm" where - "not (NOT p) = p" + "not (Not p) = p" | "not T = F" | "not F = T" - | "not p = NOT p" + | "not p = Not p" -lemma not: "Ifm bbs bs (not p) = Ifm bbs bs (NOT p)" +lemma not: "Ifm bbs bs (not p) = Ifm bbs bs (Not p)" by (cases p) auto lemma not_qf: "qfree p \ qfree (not p)" @@ -596,7 +596,7 @@ | "simpfm (Or p q) = disj (simpfm p) (simpfm q)" | "simpfm (Imp p q) = imp (simpfm p) (simpfm q)" | "simpfm (Iff p q) = iff (simpfm p) (simpfm q)" - | "simpfm (NOT p) = not (simpfm p)" + | "simpfm (Not p) = not (simpfm p)" | "simpfm (Lt a) = (let a' = simpnum a in case a' of C v \ if v < 0 then T else F | _ \ Lt a')" | "simpfm (Le a) = (let a' = simpnum a in case a' of C v \ if v \ 0 then T else F | _ \ Le a')" | "simpfm (Gt a) = (let a' = simpnum a in case a' of C v \ if v > 0 then T else F | _ \ Gt a')" @@ -825,8 +825,8 @@ fun qelim :: "fm \ (fm \ fm) \ fm" where "qelim (E p) = (\qe. DJ qe (qelim p qe))" - | "qelim (A p) = (\qe. not (qe ((qelim (NOT p) qe))))" - | "qelim (NOT p) = (\qe. not (qelim p qe))" + | "qelim (A p) = (\qe. not (qe ((qelim (Not p) qe))))" + | "qelim (Not p) = (\qe. not (qelim p qe))" | "qelim (And p q) = (\qe. conj (qelim p qe) (qelim q qe))" | "qelim (Or p q) = (\qe. disj (qelim p qe) (qelim q qe))" | "qelim (Imp p q) = (\qe. imp (qelim p qe) (qelim q qe))" @@ -995,8 +995,8 @@ where "zlfm (And p q) = And (zlfm p) (zlfm q)" | "zlfm (Or p q) = Or (zlfm p) (zlfm q)" - | "zlfm (Imp p q) = Or (zlfm (NOT p)) (zlfm q)" - | "zlfm (Iff p q) = Or (And (zlfm p) (zlfm q)) (And (zlfm (NOT p)) (zlfm (NOT q)))" + | "zlfm (Imp p q) = Or (zlfm (Not p)) (zlfm q)" + | "zlfm (Iff p q) = Or (And (zlfm p) (zlfm q)) (And (zlfm (Not p)) (zlfm (Not q)))" | "zlfm (Lt a) = (let (c, r) = zsplit0 a in if c = 0 then Lt r else @@ -1041,23 +1041,23 @@ if c = 0 then NDvd \i\ r else if c > 0 then NDvd \i\ (CN 0 c r) else NDvd \i\ (CN 0 (- c) (Neg r)))" - | "zlfm (NOT (And p q)) = Or (zlfm (NOT p)) (zlfm (NOT q))" - | "zlfm (NOT (Or p q)) = And (zlfm (NOT p)) (zlfm (NOT q))" - | "zlfm (NOT (Imp p q)) = And (zlfm p) (zlfm (NOT q))" - | "zlfm (NOT (Iff p q)) = Or (And(zlfm p) (zlfm(NOT q))) (And (zlfm(NOT p)) (zlfm q))" - | "zlfm (NOT (NOT p)) = zlfm p" - | "zlfm (NOT T) = F" - | "zlfm (NOT F) = T" - | "zlfm (NOT (Lt a)) = zlfm (Ge a)" - | "zlfm (NOT (Le a)) = zlfm (Gt a)" - | "zlfm (NOT (Gt a)) = zlfm (Le a)" - | "zlfm (NOT (Ge a)) = zlfm (Lt a)" - | "zlfm (NOT (Eq a)) = zlfm (NEq a)" - | "zlfm (NOT (NEq a)) = zlfm (Eq a)" - | "zlfm (NOT (Dvd i a)) = zlfm (NDvd i a)" - | "zlfm (NOT (NDvd i a)) = zlfm (Dvd i a)" - | "zlfm (NOT (Closed P)) = NClosed P" - | "zlfm (NOT (NClosed P)) = Closed P" + | "zlfm (Not (And p q)) = Or (zlfm (Not p)) (zlfm (Not q))" + | "zlfm (Not (Or p q)) = And (zlfm (Not p)) (zlfm (Not q))" + | "zlfm (Not (Imp p q)) = And (zlfm p) (zlfm (Not q))" + | "zlfm (Not (Iff p q)) = Or (And(zlfm p) (zlfm(Not q))) (And (zlfm(Not p)) (zlfm q))" + | "zlfm (Not (Not p)) = zlfm p" + | "zlfm (Not T) = F" + | "zlfm (Not F) = T" + | "zlfm (Not (Lt a)) = zlfm (Ge a)" + | "zlfm (Not (Le a)) = zlfm (Gt a)" + | "zlfm (Not (Gt a)) = zlfm (Le a)" + | "zlfm (Not (Ge a)) = zlfm (Lt a)" + | "zlfm (Not (Eq a)) = zlfm (NEq a)" + | "zlfm (Not (NEq a)) = zlfm (Eq a)" + | "zlfm (Not (Dvd i a)) = zlfm (NDvd i a)" + | "zlfm (Not (NDvd i a)) = zlfm (Dvd i a)" + | "zlfm (Not (Closed P)) = NClosed P" + | "zlfm (Not (NClosed P)) = Closed P" | "zlfm p = p" lemma zlfm_I: @@ -2425,8 +2425,8 @@ @{code Or} (fm_of_term ps vs t1, fm_of_term ps vs t2) | fm_of_term ps vs (\<^term>\HOL.implies\ $ t1 $ t2) = @{code Imp} (fm_of_term ps vs t1, fm_of_term ps vs t2) - | fm_of_term ps vs (\<^term>\Not\ $ t') = - @{code NOT} (fm_of_term ps vs t') + | fm_of_term ps vs (\<^term>\HOL.Not\ $ t') = + @{code Not} (fm_of_term ps vs t') | fm_of_term ps vs (Const (\<^const_name>\Ex\, _) $ Abs (xn, xT, p)) = let val (xn', p') = Syntax_Trans.variant_abs (xn, xT, p); (* FIXME !? *) @@ -2467,12 +2467,12 @@ | term_of_fm ps vs (@{code Eq} t) = \<^term>\(=) :: int \ int \ bool\ $ term_of_num vs t $ \<^term>\0::int\ | term_of_fm ps vs (@{code NEq} t) = - term_of_fm ps vs (@{code NOT} (@{code Eq} t)) + term_of_fm ps vs (@{code Not} (@{code Eq} t)) | term_of_fm ps vs (@{code Dvd} (i, t)) = \<^term>\(dvd) :: int \ int \ bool\ $ term_of_num vs (@{code C} i) $ term_of_num vs t | term_of_fm ps vs (@{code NDvd} (i, t)) = - term_of_fm ps vs (@{code NOT} (@{code Dvd} (i, t))) - | term_of_fm ps vs (@{code NOT} t') = + term_of_fm ps vs (@{code Not} (@{code Dvd} (i, t))) + | term_of_fm ps vs (@{code Not} t') = HOLogic.Not $ term_of_fm ps vs t' | term_of_fm ps vs (@{code And} (t1, t2)) = HOLogic.conj $ term_of_fm ps vs t1 $ term_of_fm ps vs t2 @@ -2486,7 +2486,7 @@ let val q = @{code integer_of_nat} n in (fst o the) (find_first (fn (_, m) => m = q) ps) end - | term_of_fm ps vs (@{code NClosed} n) = term_of_fm ps vs (@{code NOT} (@{code Closed} n)); + | term_of_fm ps vs (@{code NClosed} n) = term_of_fm ps vs (@{code Not} (@{code Closed} n)); fun term_bools acc t = let @@ -2494,7 +2494,7 @@ member (=) [\<^term>\HOL.conj\, \<^term>\HOL.disj\, \<^term>\HOL.implies\, \<^term>\(=) :: bool \ _\, \<^term>\(=) :: int \ _\, \<^term>\(<) :: int \ _\, - \<^term>\(\) :: int \ _\, \<^term>\Not\, \<^term>\All :: (int \ _) \ _\, + \<^term>\(\) :: int \ _\, \<^term>\HOL.Not\, \<^term>\All :: (int \ _) \ _\, \<^term>\Ex :: (int \ _) \ _\, \<^term>\True\, \<^term>\False\] fun is_ty t = not (fastype_of t = HOLogic.boolT) in diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Decision_Procs/Ferrack.thy --- a/src/HOL/Decision_Procs/Ferrack.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/Decision_Procs/Ferrack.thy Mon Aug 02 10:01:06 2021 +0000 @@ -46,14 +46,14 @@ (* FORMULAE *) datatype (plugins del: size) fm = T| F| Lt num| Le num| Gt num| Ge num| Eq num| NEq num| - NOT fm| And fm fm| Or fm fm| Imp fm fm| Iff fm fm| E fm| A fm + Not fm| And fm fm| Or fm fm| Imp fm fm| Iff fm fm| E fm| A fm instantiation fm :: size begin primrec size_fm :: "fm \ nat" where - "size_fm (NOT p) = 1 + size_fm p" + "size_fm (Not p) = 1 + size_fm p" | "size_fm (And p q) = 1 + size_fm p + size_fm q" | "size_fm (Or p q) = 1 + size_fm p + size_fm q" | "size_fm (Imp p q) = 3 + size_fm p + size_fm q" @@ -87,7 +87,7 @@ | "Ifm bs (Ge a) = (Inum bs a \ 0)" | "Ifm bs (Eq a) = (Inum bs a = 0)" | "Ifm bs (NEq a) = (Inum bs a \ 0)" -| "Ifm bs (NOT p) = (\ (Ifm bs p))" +| "Ifm bs (Not p) = (\ (Ifm bs p))" | "Ifm bs (And p q) = (Ifm bs p \ Ifm bs q)" | "Ifm bs (Or p q) = (Ifm bs p \ Ifm bs q)" | "Ifm bs (Imp p q) = ((Ifm bs p) \ (Ifm bs q))" @@ -104,7 +104,7 @@ lemma IfmEqSub: "\ Inum bs s = s' ; Inum bs t = t' \ \ Ifm bs (Eq (Sub s t)) = (s' = t')" by simp -lemma IfmNOT: " (Ifm bs p = P) \ (Ifm bs (NOT p) = (\P))" +lemma IfmNot: " (Ifm bs p = P) \ (Ifm bs (Not p) = (\P))" by simp lemma IfmAnd: " \ Ifm bs p = P ; Ifm bs q = Q\ \ (Ifm bs (And p q) = (P \ Q))" @@ -127,12 +127,12 @@ fun not:: "fm \ fm" where - "not (NOT p) = p" + "not (Not p) = p" | "not T = F" | "not F = T" -| "not p = NOT p" +| "not p = Not p" -lemma not[simp]: "Ifm bs (not p) = Ifm bs (NOT p)" +lemma not[simp]: "Ifm bs (not p) = Ifm bs (Not p)" by (cases p) auto definition conj :: "fm \ fm \ fm" @@ -172,7 +172,7 @@ where "iff p q = (if p = q then T - else if p = NOT q \ NOT p = q then F + else if p = Not q \ Not p = q then F else if p = F then not q else if q = F then not p else if p = T then q @@ -180,7 +180,7 @@ else Iff p q)" lemma iff[simp]: "Ifm bs (iff p q) = Ifm bs (Iff p q)" - by (unfold iff_def, cases "p = q", simp, cases "p = NOT q", simp) (cases "NOT p = q", auto) + by (unfold iff_def, cases "p = q", simp, cases "p = Not q", simp) (cases "Not p = q", auto) lemma conj_simps: "conj F Q = F" @@ -209,19 +209,19 @@ "P \ T \ P \ F \ P \ Q \ Q \ T \ Q \ F \ imp P Q = Imp P Q" by (simp_all add: imp_def) -lemma trivNOT: "p \ NOT p" "NOT p \ p" +lemma trivNot: "p \ Not p" "Not p \ p" by (induct p) auto lemma iff_simps: "iff p p = T" - "iff p (NOT p) = F" - "iff (NOT p) p = F" + "iff p (Not p) = F" + "iff (Not p) p = F" "iff p F = not p" "iff F p = not p" - "p \ NOT T \ iff T p = p" - "p\ NOT T \ iff p T = p" - "p\q \ p\ NOT q \ q\ NOT p \ p\ F \ q\ F \ p \ T \ q \ T \ iff p q = Iff p q" - using trivNOT + "p \ Not T \ iff T p = p" + "p\ Not T \ iff p T = p" + "p\q \ p\ Not q \ q\ Not p \ p\ F \ q\ F \ p \ T \ q \ T \ iff p q = Iff p q" + using trivNot by (simp_all add: iff_def, cases p, auto) (* Quantifier freeness *) @@ -229,7 +229,7 @@ where "qfree (E p) = False" | "qfree (A p) = False" -| "qfree (NOT p) = qfree p" +| "qfree (Not p) = qfree p" | "qfree (And p q) = (qfree p \ qfree q)" | "qfree (Or p q) = (qfree p \ qfree q)" | "qfree (Imp p q) = (qfree p \ qfree q)" @@ -262,7 +262,7 @@ | "bound0 (Ge a) = numbound0 a" | "bound0 (Eq a) = numbound0 a" | "bound0 (NEq a) = numbound0 a" -| "bound0 (NOT p) = bound0 p" +| "bound0 (Not p) = bound0 p" | "bound0 (And p q) = (bound0 p \ bound0 q)" | "bound0 (Or p q) = (bound0 p \ bound0 q)" | "bound0 (Imp p q) = ((bound0 p) \ (bound0 q))" @@ -321,7 +321,7 @@ | "decr (Ge a) = Ge (decrnum a)" | "decr (Eq a) = Eq (decrnum a)" | "decr (NEq a) = NEq (decrnum a)" -| "decr (NOT p) = NOT (decr p)" +| "decr (Not p) = Not (decr p)" | "decr (And p q) = conj (decr p) (decr q)" | "decr (Or p q) = disj (decr p) (decr q)" | "decr (Imp p q) = imp (decr p) (decr q)" @@ -890,7 +890,7 @@ | "simpfm (Or p q) = disj (simpfm p) (simpfm q)" | "simpfm (Imp p q) = imp (simpfm p) (simpfm q)" | "simpfm (Iff p q) = iff (simpfm p) (simpfm q)" -| "simpfm (NOT p) = not (simpfm p)" +| "simpfm (Not p) = not (simpfm p)" | "simpfm (Lt a) = (let a' = simpnum a in case a' of C v \ if (v < 0) then T else F | _ \ Lt a')" | "simpfm (Le a) = (let a' = simpnum a in case a' of C v \ if (v \ 0) then T else F | _ \ Le a')" | "simpfm (Gt a) = (let a' = simpnum a in case a' of C v \ if (v > 0) then T else F | _ \ Gt a')" @@ -1031,25 +1031,25 @@ "prep (E T) = T" | "prep (E F) = F" | "prep (E (Or p q)) = disj (prep (E p)) (prep (E q))" -| "prep (E (Imp p q)) = disj (prep (E (NOT p))) (prep (E q))" -| "prep (E (Iff p q)) = disj (prep (E (And p q))) (prep (E (And (NOT p) (NOT q))))" -| "prep (E (NOT (And p q))) = disj (prep (E (NOT p))) (prep (E(NOT q)))" -| "prep (E (NOT (Imp p q))) = prep (E (And p (NOT q)))" -| "prep (E (NOT (Iff p q))) = disj (prep (E (And p (NOT q)))) (prep (E(And (NOT p) q)))" +| "prep (E (Imp p q)) = disj (prep (E (Not p))) (prep (E q))" +| "prep (E (Iff p q)) = disj (prep (E (And p q))) (prep (E (And (Not p) (Not q))))" +| "prep (E (Not (And p q))) = disj (prep (E (Not p))) (prep (E(Not q)))" +| "prep (E (Not (Imp p q))) = prep (E (And p (Not q)))" +| "prep (E (Not (Iff p q))) = disj (prep (E (And p (Not q)))) (prep (E(And (Not p) q)))" | "prep (E p) = E (prep p)" | "prep (A (And p q)) = conj (prep (A p)) (prep (A q))" -| "prep (A p) = prep (NOT (E (NOT p)))" -| "prep (NOT (NOT p)) = prep p" -| "prep (NOT (And p q)) = disj (prep (NOT p)) (prep (NOT q))" -| "prep (NOT (A p)) = prep (E (NOT p))" -| "prep (NOT (Or p q)) = conj (prep (NOT p)) (prep (NOT q))" -| "prep (NOT (Imp p q)) = conj (prep p) (prep (NOT q))" -| "prep (NOT (Iff p q)) = disj (prep (And p (NOT q))) (prep (And (NOT p) q))" -| "prep (NOT p) = not (prep p)" +| "prep (A p) = prep (Not (E (Not p)))" +| "prep (Not (Not p)) = prep p" +| "prep (Not (And p q)) = disj (prep (Not p)) (prep (Not q))" +| "prep (Not (A p)) = prep (E (Not p))" +| "prep (Not (Or p q)) = conj (prep (Not p)) (prep (Not q))" +| "prep (Not (Imp p q)) = conj (prep p) (prep (Not q))" +| "prep (Not (Iff p q)) = disj (prep (And p (Not q))) (prep (And (Not p) q))" +| "prep (Not p) = not (prep p)" | "prep (Or p q) = disj (prep p) (prep q)" | "prep (And p q) = conj (prep p) (prep q)" -| "prep (Imp p q) = prep (Or (NOT p) q)" -| "prep (Iff p q) = disj (prep (And p q)) (prep (And (NOT p) (NOT q)))" +| "prep (Imp p q) = prep (Or (Not p) q)" +| "prep (Iff p q) = disj (prep (And p q)) (prep (And (Not p) (Not q)))" | "prep p = p" lemma prep: "\bs. Ifm bs (prep p) = Ifm bs p" @@ -1059,8 +1059,8 @@ fun qelim :: "fm \ (fm \ fm) \ fm" where "qelim (E p) = (\qe. DJ qe (qelim p qe))" -| "qelim (A p) = (\qe. not (qe ((qelim (NOT p) qe))))" -| "qelim (NOT p) = (\qe. not (qelim p qe))" +| "qelim (A p) = (\qe. not (qe ((qelim (Not p) qe))))" +| "qelim (Not p) = (\qe. not (qelim p qe))" | "qelim (And p q) = (\qe. conj (qelim p qe) (qelim q qe))" | "qelim (Or p q) = (\qe. disj (qelim p qe) (qelim q qe))" | "qelim (Imp p q) = (\qe. imp (qelim p qe) (qelim q qe))" @@ -1219,27 +1219,27 @@ where "rlfm (And p q) = conj (rlfm p) (rlfm q)" | "rlfm (Or p q) = disj (rlfm p) (rlfm q)" -| "rlfm (Imp p q) = disj (rlfm (NOT p)) (rlfm q)" -| "rlfm (Iff p q) = disj (conj (rlfm p) (rlfm q)) (conj (rlfm (NOT p)) (rlfm (NOT q)))" +| "rlfm (Imp p q) = disj (rlfm (Not p)) (rlfm q)" +| "rlfm (Iff p q) = disj (conj (rlfm p) (rlfm q)) (conj (rlfm (Not p)) (rlfm (Not q)))" | "rlfm (Lt a) = case_prod lt (rsplit0 a)" | "rlfm (Le a) = case_prod le (rsplit0 a)" | "rlfm (Gt a) = case_prod gt (rsplit0 a)" | "rlfm (Ge a) = case_prod ge (rsplit0 a)" | "rlfm (Eq a) = case_prod eq (rsplit0 a)" | "rlfm (NEq a) = case_prod neq (rsplit0 a)" -| "rlfm (NOT (And p q)) = disj (rlfm (NOT p)) (rlfm (NOT q))" -| "rlfm (NOT (Or p q)) = conj (rlfm (NOT p)) (rlfm (NOT q))" -| "rlfm (NOT (Imp p q)) = conj (rlfm p) (rlfm (NOT q))" -| "rlfm (NOT (Iff p q)) = disj (conj(rlfm p) (rlfm(NOT q))) (conj(rlfm(NOT p)) (rlfm q))" -| "rlfm (NOT (NOT p)) = rlfm p" -| "rlfm (NOT T) = F" -| "rlfm (NOT F) = T" -| "rlfm (NOT (Lt a)) = rlfm (Ge a)" -| "rlfm (NOT (Le a)) = rlfm (Gt a)" -| "rlfm (NOT (Gt a)) = rlfm (Le a)" -| "rlfm (NOT (Ge a)) = rlfm (Lt a)" -| "rlfm (NOT (Eq a)) = rlfm (NEq a)" -| "rlfm (NOT (NEq a)) = rlfm (Eq a)" +| "rlfm (Not (And p q)) = disj (rlfm (Not p)) (rlfm (Not q))" +| "rlfm (Not (Or p q)) = conj (rlfm (Not p)) (rlfm (Not q))" +| "rlfm (Not (Imp p q)) = conj (rlfm p) (rlfm (Not q))" +| "rlfm (Not (Iff p q)) = disj (conj(rlfm p) (rlfm(Not q))) (conj(rlfm(Not p)) (rlfm q))" +| "rlfm (Not (Not p)) = rlfm p" +| "rlfm (Not T) = F" +| "rlfm (Not F) = T" +| "rlfm (Not (Lt a)) = rlfm (Ge a)" +| "rlfm (Not (Le a)) = rlfm (Gt a)" +| "rlfm (Not (Gt a)) = rlfm (Le a)" +| "rlfm (Not (Ge a)) = rlfm (Lt a)" +| "rlfm (Not (Eq a)) = rlfm (NEq a)" +| "rlfm (Not (NEq a)) = rlfm (Eq a)" | "rlfm p = p" lemma rlfm_I: @@ -2489,7 +2489,7 @@ | fm_of_term vs (\<^term>\HOL.conj\ $ t1 $ t2) = @{code And} (fm_of_term vs t1, fm_of_term vs t2) | fm_of_term vs (\<^term>\HOL.disj\ $ t1 $ t2) = @{code Or} (fm_of_term vs t1, fm_of_term vs t2) | fm_of_term vs (\<^term>\HOL.implies\ $ t1 $ t2) = @{code Imp} (fm_of_term vs t1, fm_of_term vs t2) - | fm_of_term vs (\<^term>\Not\ $ t') = @{code NOT} (fm_of_term vs t') + | fm_of_term vs (\<^term>\HOL.Not\ $ t') = @{code Not} (fm_of_term vs t') | fm_of_term vs (Const (\<^const_name>\Ex\, _) $ Abs (xn, xT, p)) = @{code E} (fm_of_term (("", dummyT) :: vs) p) | fm_of_term vs (Const (\<^const_name>\All\, _) $ Abs (xn, xT, p)) = @@ -2520,8 +2520,8 @@ \<^term>\0::real\ $ term_of_num vs t | term_of_fm vs (@{code Eq} t) = \<^term>\(=) :: real \ real \ bool\ $ term_of_num vs t $ \<^term>\0::real\ - | term_of_fm vs (@{code NEq} t) = term_of_fm vs (@{code NOT} (@{code Eq} t)) - | term_of_fm vs (@{code NOT} t') = HOLogic.Not $ term_of_fm vs t' + | term_of_fm vs (@{code NEq} t) = term_of_fm vs (@{code Not} (@{code Eq} t)) + | term_of_fm vs (@{code Not} t') = HOLogic.Not $ term_of_fm vs t' | term_of_fm vs (@{code And} (t1, t2)) = HOLogic.conj $ term_of_fm vs t1 $ term_of_fm vs t2 | term_of_fm vs (@{code Or} (t1, t2)) = HOLogic.disj $ term_of_fm vs t1 $ term_of_fm vs t2 | term_of_fm vs (@{code Imp} (t1, t2)) = HOLogic.imp $ term_of_fm vs t1 $ term_of_fm vs t2 diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Decision_Procs/MIR.thy --- a/src/HOL/Decision_Procs/MIR.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/Decision_Procs/MIR.thy Mon Aug 02 10:01:06 2021 +0000 @@ -187,14 +187,14 @@ datatype (plugins del: size) fm = T | F | Lt num | Le num | Gt num | Ge num | Eq num | NEq num | Dvd int num | NDvd int num | - NOT fm | And fm fm | Or fm fm | Imp fm fm | Iff fm fm | E fm | A fm + Not fm | And fm fm | Or fm fm | Imp fm fm | Iff fm fm | E fm | A fm instantiation fm :: size begin primrec size_fm :: "fm \ nat" where - "size_fm (NOT p) = 1 + size_fm p" + "size_fm (Not p) = 1 + size_fm p" | "size_fm (And p q) = 1 + size_fm p + size_fm q" | "size_fm (Or p q) = 1 + size_fm p + size_fm q" | "size_fm (Imp p q) = 3 + size_fm p + size_fm q" @@ -232,7 +232,7 @@ | "Ifm bs (NEq a) \ Inum bs a \ 0" | "Ifm bs (Dvd i b) \ real_of_int i rdvd Inum bs b" | "Ifm bs (NDvd i b) \ \ (real_of_int i rdvd Inum bs b)" -| "Ifm bs (NOT p) \ \ (Ifm bs p)" +| "Ifm bs (Not p) \ \ (Ifm bs p)" | "Ifm bs (And p q) \ Ifm bs p \ Ifm bs q" | "Ifm bs (Or p q) \ Ifm bs p \ Ifm bs q" | "Ifm bs (Imp p q) \ (Ifm bs p \ Ifm bs q)" @@ -245,25 +245,25 @@ "prep (E T) = T" | "prep (E F) = F" | "prep (E (Or p q)) = Or (prep (E p)) (prep (E q))" -| "prep (E (Imp p q)) = Or (prep (E (NOT p))) (prep (E q))" -| "prep (E (Iff p q)) = Or (prep (E (And p q))) (prep (E (And (NOT p) (NOT q))))" -| "prep (E (NOT (And p q))) = Or (prep (E (NOT p))) (prep (E(NOT q)))" -| "prep (E (NOT (Imp p q))) = prep (E (And p (NOT q)))" -| "prep (E (NOT (Iff p q))) = Or (prep (E (And p (NOT q)))) (prep (E(And (NOT p) q)))" +| "prep (E (Imp p q)) = Or (prep (E (Not p))) (prep (E q))" +| "prep (E (Iff p q)) = Or (prep (E (And p q))) (prep (E (And (Not p) (Not q))))" +| "prep (E (Not (And p q))) = Or (prep (E (Not p))) (prep (E(Not q)))" +| "prep (E (Not (Imp p q))) = prep (E (And p (Not q)))" +| "prep (E (Not (Iff p q))) = Or (prep (E (And p (Not q)))) (prep (E(And (Not p) q)))" | "prep (E p) = E (prep p)" | "prep (A (And p q)) = And (prep (A p)) (prep (A q))" -| "prep (A p) = prep (NOT (E (NOT p)))" -| "prep (NOT (NOT p)) = prep p" -| "prep (NOT (And p q)) = Or (prep (NOT p)) (prep (NOT q))" -| "prep (NOT (A p)) = prep (E (NOT p))" -| "prep (NOT (Or p q)) = And (prep (NOT p)) (prep (NOT q))" -| "prep (NOT (Imp p q)) = And (prep p) (prep (NOT q))" -| "prep (NOT (Iff p q)) = Or (prep (And p (NOT q))) (prep (And (NOT p) q))" -| "prep (NOT p) = NOT (prep p)" +| "prep (A p) = prep (Not (E (Not p)))" +| "prep (Not (Not p)) = prep p" +| "prep (Not (And p q)) = Or (prep (Not p)) (prep (Not q))" +| "prep (Not (A p)) = prep (E (Not p))" +| "prep (Not (Or p q)) = And (prep (Not p)) (prep (Not q))" +| "prep (Not (Imp p q)) = And (prep p) (prep (Not q))" +| "prep (Not (Iff p q)) = Or (prep (And p (Not q))) (prep (And (Not p) q))" +| "prep (Not p) = Not (prep p)" | "prep (Or p q) = Or (prep p) (prep q)" | "prep (And p q) = And (prep p) (prep q)" -| "prep (Imp p q) = prep (Or (NOT p) q)" -| "prep (Iff p q) = Or (prep (And p q)) (prep (And (NOT p) (NOT q)))" +| "prep (Imp p q) = prep (Or (Not p) q)" +| "prep (Iff p q) = Or (prep (And p q)) (prep (And (Not p) (Not q)))" | "prep p = p" lemma prep: "\ bs. Ifm bs (prep p) = Ifm bs p" @@ -275,7 +275,7 @@ where "qfree (E p) = False" | "qfree (A p) = False" -| "qfree (NOT p) = qfree p" +| "qfree (Not p) = qfree p" | "qfree (And p q) = (qfree p \ qfree q)" | "qfree (Or p q) = (qfree p \ qfree q)" | "qfree (Imp p q) = (qfree p \ qfree q)" @@ -323,7 +323,7 @@ | "bound0 (NEq a) = numbound0 a" | "bound0 (Dvd i a) = numbound0 a" | "bound0 (NDvd i a) = numbound0 a" -| "bound0 (NOT p) = bound0 p" +| "bound0 (Not p) = bound0 p" | "bound0 (And p q) = (bound0 p \ bound0 q)" | "bound0 (Or p q) = (bound0 p \ bound0 q)" | "bound0 (Imp p q) = ((bound0 p) \ (bound0 q))" @@ -365,7 +365,7 @@ | "subst0 t (NEq a) = NEq (numsubst0 t a)" | "subst0 t (Dvd i a) = Dvd i (numsubst0 t a)" | "subst0 t (NDvd i a) = NDvd i (numsubst0 t a)" -| "subst0 t (NOT p) = NOT (subst0 t p)" +| "subst0 t (Not p) = Not (subst0 t p)" | "subst0 t (And p q) = And (subst0 t p) (subst0 t q)" | "subst0 t (Or p q) = Or (subst0 t p) (subst0 t q)" | "subst0 t (Imp p q) = Imp (subst0 t p) (subst0 t q)" @@ -398,7 +398,7 @@ | "decr (NEq a) = NEq (decrnum a)" | "decr (Dvd i a) = Dvd i (decrnum a)" | "decr (NDvd i a) = NDvd i (decrnum a)" -| "decr (NOT p) = NOT (decr p)" +| "decr (Not p) = Not (decr p)" | "decr (And p q) = And (decr p) (decr q)" | "decr (Or p q) = Or (decr p) (decr q)" | "decr (Imp p q) = Imp (decr p) (decr q)" @@ -1044,7 +1044,7 @@ fun not:: "fm \ fm" where - "not (NOT p) = p" + "not (Not p) = p" | "not T = F" | "not F = T" | "not (Lt t) = Ge t" @@ -1057,8 +1057,8 @@ | "not (NDvd i t) = Dvd i t" | "not (And p q) = Or (not p) (not q)" | "not (Or p q) = And (not p) (not q)" -| "not p = NOT p" -lemma not[simp]: "Ifm bs (not p) = Ifm bs (NOT p)" +| "not p = Not p" +lemma not[simp]: "Ifm bs (not p) = Ifm bs (Not p)" by (induct p) auto lemma not_qf[simp]: "qfree p \ qfree (not p)" by (induct p) auto @@ -1188,7 +1188,7 @@ | "simpfm (Or p q) = disj (simpfm p) (simpfm q)" | "simpfm (Imp p q) = imp (simpfm p) (simpfm q)" | "simpfm (Iff p q) = iff (simpfm p) (simpfm q)" -| "simpfm (NOT p) = not (simpfm p)" +| "simpfm (Not p) = not (simpfm p)" | "simpfm (Lt a) = (let a' = simpnum a in case a' of C v \ if (v < 0) then T else F | _ \ Lt (reducecoeff a'))" | "simpfm (Le a) = (let a' = simpnum a in case a' of C v \ if (v \ 0) then T else F | _ \ Le (reducecoeff a'))" @@ -1459,11 +1459,11 @@ fun qelim :: "fm \ (fm \ fm) \ fm" where "qelim (E p) = (\ qe. DJ (CJNB qe) (qelim p qe))" -| "qelim (A p) = (\ qe. not (qe ((qelim (NOT p) qe))))" -| "qelim (NOT p) = (\ qe. not (qelim p qe))" +| "qelim (A p) = (\ qe. not (qe ((qelim (Not p) qe))))" +| "qelim (Not p) = (\ qe. not (qelim p qe))" | "qelim (And p q) = (\ qe. conj (qelim p qe) (qelim q qe))" | "qelim (Or p q) = (\ qe. disj (qelim p qe) (qelim q qe))" -| "qelim (Imp p q) = (\ qe. disj (qelim (NOT p) qe) (qelim q qe))" +| "qelim (Imp p q) = (\ qe. disj (qelim (Not p) qe) (qelim q qe))" | "qelim (Iff p q) = (\ qe. iff (qelim p qe) (qelim q qe))" | "qelim p = (\ y. simpfm p)" @@ -1611,8 +1611,8 @@ where "zlfm (And p q) = conj (zlfm p) (zlfm q)" | "zlfm (Or p q) = disj (zlfm p) (zlfm q)" -| "zlfm (Imp p q) = disj (zlfm (NOT p)) (zlfm q)" -| "zlfm (Iff p q) = disj (conj (zlfm p) (zlfm q)) (conj (zlfm (NOT p)) (zlfm (NOT q)))" +| "zlfm (Imp p q) = disj (zlfm (Not p)) (zlfm q)" +| "zlfm (Iff p q) = disj (conj (zlfm p) (zlfm q)) (conj (zlfm (Not p)) (zlfm (Not q)))" | "zlfm (Lt a) = (let (c,r) = zsplit0 a in if c=0 then Lt r else if c>0 then Or (Lt (CN 0 c (Neg (Floor (Neg r))))) (And (Eq (CN 0 c (Neg (Floor (Neg r))))) (Lt (Add (Floor (Neg r)) r))) @@ -1647,21 +1647,21 @@ if c=0 then NDvd \i\ r else if c>0 then Or (NEq (Sub (Floor r) r)) (NDvd \i\ (CN 0 c (Floor r))) else Or (NEq (Sub (Floor r) r)) (NDvd \i\ (CN 0 (-c) (Neg (Floor r))))))" -| "zlfm (NOT (And p q)) = disj (zlfm (NOT p)) (zlfm (NOT q))" -| "zlfm (NOT (Or p q)) = conj (zlfm (NOT p)) (zlfm (NOT q))" -| "zlfm (NOT (Imp p q)) = conj (zlfm p) (zlfm (NOT q))" -| "zlfm (NOT (Iff p q)) = disj (conj(zlfm p) (zlfm(NOT q))) (conj (zlfm(NOT p)) (zlfm q))" -| "zlfm (NOT (NOT p)) = zlfm p" -| "zlfm (NOT T) = F" -| "zlfm (NOT F) = T" -| "zlfm (NOT (Lt a)) = zlfm (Ge a)" -| "zlfm (NOT (Le a)) = zlfm (Gt a)" -| "zlfm (NOT (Gt a)) = zlfm (Le a)" -| "zlfm (NOT (Ge a)) = zlfm (Lt a)" -| "zlfm (NOT (Eq a)) = zlfm (NEq a)" -| "zlfm (NOT (NEq a)) = zlfm (Eq a)" -| "zlfm (NOT (Dvd i a)) = zlfm (NDvd i a)" -| "zlfm (NOT (NDvd i a)) = zlfm (Dvd i a)" +| "zlfm (Not (And p q)) = disj (zlfm (Not p)) (zlfm (Not q))" +| "zlfm (Not (Or p q)) = conj (zlfm (Not p)) (zlfm (Not q))" +| "zlfm (Not (Imp p q)) = conj (zlfm p) (zlfm (Not q))" +| "zlfm (Not (Iff p q)) = disj (conj(zlfm p) (zlfm(Not q))) (conj (zlfm(Not p)) (zlfm q))" +| "zlfm (Not (Not p)) = zlfm p" +| "zlfm (Not T) = F" +| "zlfm (Not F) = T" +| "zlfm (Not (Lt a)) = zlfm (Ge a)" +| "zlfm (Not (Le a)) = zlfm (Gt a)" +| "zlfm (Not (Gt a)) = zlfm (Le a)" +| "zlfm (Not (Ge a)) = zlfm (Lt a)" +| "zlfm (Not (Eq a)) = zlfm (NEq a)" +| "zlfm (Not (NEq a)) = zlfm (Eq a)" +| "zlfm (Not (Dvd i a)) = zlfm (NDvd i a)" +| "zlfm (Not (NDvd i a)) = zlfm (Dvd i a)" | "zlfm p = p" lemma split_int_less_real: @@ -3210,14 +3210,14 @@ by (simp add: isint_iff) from 10 have id: "j dvd d" by simp from ie[symmetric] have "?p i = (\ (real_of_int j rdvd real_of_int (c*i + \?e\)))" by simp - also have "\ = Not (j dvd c*i + \?e\)" + also have "\ \ \ (j dvd c*i + \?e\)" using int_rdvd_iff [where i="j" and t="c*i + \?e\"] by simp - also have "\ = Not (j dvd c*i - c*d + \?e\)" + also have "\ \ \ (j dvd c*i - c*d + \?e\)" using dvd_period[OF id, where x="c*i" and c="-c" and t="\?e\"] by simp - also have "\ = Not (real_of_int j rdvd real_of_int (c*i - c*d + \?e\))" + also have "\ \ \ (real_of_int j rdvd real_of_int (c*i - c*d + \?e\))" using int_rdvd_iff[where i="j" and t="(c*i - c*d + \?e\)",symmetric, simplified] ie by simp - also have "\ = Not (real_of_int j rdvd real_of_int (c*(i - d)) + ?e)" + also have "\ \ \ (real_of_int j rdvd real_of_int (c*(i - d)) + ?e)" using ie by (simp add:algebra_simps) finally show ?case using numbound0_I[OF bn,where b="real_of_int i - real_of_int d" and b'="real_of_int i" and bs="bs"] p @@ -3960,8 +3960,8 @@ where "rlfm (And p q) = conj (rlfm p) (rlfm q)" | "rlfm (Or p q) = disj (rlfm p) (rlfm q)" -| "rlfm (Imp p q) = disj (rlfm (NOT p)) (rlfm q)" -| "rlfm (Iff p q) = disj (conj(rlfm p) (rlfm q)) (conj(rlfm (NOT p)) (rlfm (NOT q)))" +| "rlfm (Imp p q) = disj (rlfm (Not p)) (rlfm q)" +| "rlfm (Iff p q) = disj (conj(rlfm p) (rlfm q)) (conj(rlfm (Not p)) (rlfm (Not q)))" | "rlfm (Lt a) = rsplit lt a" | "rlfm (Le a) = rsplit le a" | "rlfm (Gt a) = rsplit gt a" @@ -3970,21 +3970,21 @@ | "rlfm (NEq a) = rsplit neq a" | "rlfm (Dvd i a) = rsplit (\ t. DVD i t) a" | "rlfm (NDvd i a) = rsplit (\ t. NDVD i t) a" -| "rlfm (NOT (And p q)) = disj (rlfm (NOT p)) (rlfm (NOT q))" -| "rlfm (NOT (Or p q)) = conj (rlfm (NOT p)) (rlfm (NOT q))" -| "rlfm (NOT (Imp p q)) = conj (rlfm p) (rlfm (NOT q))" -| "rlfm (NOT (Iff p q)) = disj (conj(rlfm p) (rlfm(NOT q))) (conj(rlfm(NOT p)) (rlfm q))" -| "rlfm (NOT (NOT p)) = rlfm p" -| "rlfm (NOT T) = F" -| "rlfm (NOT F) = T" -| "rlfm (NOT (Lt a)) = simpfm (rlfm (Ge a))" -| "rlfm (NOT (Le a)) = simpfm (rlfm (Gt a))" -| "rlfm (NOT (Gt a)) = simpfm (rlfm (Le a))" -| "rlfm (NOT (Ge a)) = simpfm (rlfm (Lt a))" -| "rlfm (NOT (Eq a)) = simpfm (rlfm (NEq a))" -| "rlfm (NOT (NEq a)) = simpfm (rlfm (Eq a))" -| "rlfm (NOT (Dvd i a)) = simpfm (rlfm (NDvd i a))" -| "rlfm (NOT (NDvd i a)) = simpfm (rlfm (Dvd i a))" +| "rlfm (Not (And p q)) = disj (rlfm (Not p)) (rlfm (Not q))" +| "rlfm (Not (Or p q)) = conj (rlfm (Not p)) (rlfm (Not q))" +| "rlfm (Not (Imp p q)) = conj (rlfm p) (rlfm (Not q))" +| "rlfm (Not (Iff p q)) = disj (conj(rlfm p) (rlfm(Not q))) (conj(rlfm(Not p)) (rlfm q))" +| "rlfm (Not (Not p)) = rlfm p" +| "rlfm (Not T) = F" +| "rlfm (Not F) = T" +| "rlfm (Not (Lt a)) = simpfm (rlfm (Ge a))" +| "rlfm (Not (Le a)) = simpfm (rlfm (Gt a))" +| "rlfm (Not (Gt a)) = simpfm (rlfm (Le a))" +| "rlfm (Not (Ge a)) = simpfm (rlfm (Lt a))" +| "rlfm (Not (Eq a)) = simpfm (rlfm (NEq a))" +| "rlfm (Not (NEq a)) = simpfm (rlfm (Eq a))" +| "rlfm (Not (Dvd i a)) = simpfm (rlfm (NDvd i a))" +| "rlfm (Not (NDvd i a)) = simpfm (rlfm (Dvd i a))" | "rlfm p = p" lemma bound0at_l : "\isatom p ; bound0 p\ \ isrlfm p" @@ -4834,7 +4834,7 @@ | "exsplit (Or p q) = Or (exsplit p) (exsplit q)" | "exsplit (Imp p q) = Imp (exsplit p) (exsplit q)" | "exsplit (Iff p q) = Iff (exsplit p) (exsplit q)" -| "exsplit (NOT p) = NOT (exsplit p)" +| "exsplit (Not p) = Not (exsplit p)" | "exsplit p = p" lemma exsplitnum: @@ -5624,8 +5624,8 @@ @{code Or} (fm_of_term vs t1, fm_of_term vs t2) | fm_of_term vs (\<^term>\HOL.implies\ $ t1 $ t2) = @{code Imp} (fm_of_term vs t1, fm_of_term vs t2) - | fm_of_term vs (\<^term>\Not\ $ t') = - @{code NOT} (fm_of_term vs t') + | fm_of_term vs (\<^term>\HOL.Not\ $ t') = + @{code Not} (fm_of_term vs t') | fm_of_term vs (Const (\<^const_name>\Ex\, _) $ Abs (xn, xT, p)) = @{code E} (fm_of_term (map (fn (v, n) => (v, n + 1)) vs) p) | fm_of_term vs (Const (\<^const_name>\All\, _) $ Abs (xn, xT, p)) = @@ -5664,12 +5664,12 @@ | term_of_fm vs (@{code Eq} t) = \<^term>\(=) :: real \ real \ bool\ $ term_of_num vs t $ \<^term>\0::real\ | term_of_fm vs (@{code NEq} t) = - term_of_fm vs (@{code NOT} (@{code Eq} t)) + term_of_fm vs (@{code Not} (@{code Eq} t)) | term_of_fm vs (@{code Dvd} (i, t)) = \<^term>\(rdvd)\ $ term_of_num vs (@{code C} i) $ term_of_num vs t | term_of_fm vs (@{code NDvd} (i, t)) = - term_of_fm vs (@{code NOT} (@{code Dvd} (i, t))) - | term_of_fm vs (@{code NOT} t') = + term_of_fm vs (@{code Not} (@{code Dvd} (i, t))) + | term_of_fm vs (@{code Not} t') = HOLogic.Not $ term_of_fm vs t' | term_of_fm vs (@{code And} (t1, t2)) = HOLogic.conj $ term_of_fm vs t1 $ term_of_fm vs t2 diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Decision_Procs/Parametric_Ferrante_Rackoff.thy --- a/src/HOL/Decision_Procs/Parametric_Ferrante_Rackoff.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/Decision_Procs/Parametric_Ferrante_Rackoff.thy Mon Aug 02 10:01:06 2021 +0000 @@ -501,14 +501,14 @@ subsection \Formulae\ datatype (plugins del: size) fm = T | F | Le tm | Lt tm | Eq tm | NEq tm | - NOT fm | And fm fm | Or fm fm | Imp fm fm | Iff fm fm | E fm | A fm + Not fm | And fm fm | Or fm fm | Imp fm fm | Iff fm fm | E fm | A fm instantiation fm :: size begin primrec size_fm :: "fm \ nat" where - "size_fm (NOT p) = 1 + size_fm p" + "size_fm (Not p) = 1 + size_fm p" | "size_fm (And p q) = 1 + size_fm p + size_fm q" | "size_fm (Or p q) = 1 + size_fm p + size_fm q" | "size_fm (Imp p q) = 3 + size_fm p + size_fm q" @@ -538,7 +538,7 @@ | "Ifm vs bs (Le a) = (Itm vs bs a \ 0)" | "Ifm vs bs (Eq a) = (Itm vs bs a = 0)" | "Ifm vs bs (NEq a) = (Itm vs bs a \ 0)" - | "Ifm vs bs (NOT p) = (\ (Ifm vs bs p))" + | "Ifm vs bs (Not p) = (\ (Ifm vs bs p))" | "Ifm vs bs (And p q) = (Ifm vs bs p \ Ifm vs bs q)" | "Ifm vs bs (Or p q) = (Ifm vs bs p \ Ifm vs bs q)" | "Ifm vs bs (Imp p q) = ((Ifm vs bs p) \ (Ifm vs bs q))" @@ -548,17 +548,17 @@ fun not:: "fm \ fm" where - "not (NOT (NOT p)) = not p" - | "not (NOT p) = p" + "not (Not (Not p)) = not p" + | "not (Not p) = p" | "not T = F" | "not F = T" | "not (Lt t) = Le (tmneg t)" | "not (Le t) = Lt (tmneg t)" | "not (Eq t) = NEq t" | "not (NEq t) = Eq t" - | "not p = NOT p" - -lemma not[simp]: "Ifm vs bs (not p) = Ifm vs bs (NOT p)" + | "not p = Not p" + +lemma not[simp]: "Ifm vs bs (not p) = Ifm vs bs (Not p)" by (induct p rule: not.induct) auto definition conj :: "fm \ fm \ fm" @@ -596,7 +596,7 @@ definition iff :: "fm \ fm \ fm" where "iff p q \ (if p = q then T - else if p = NOT q \ NOT p = q then F + else if p = Not q \ Not p = q then F else if p = F then not q else if q = F then not p else if p = T then q @@ -604,14 +604,14 @@ else Iff p q)" lemma iff[simp]: "Ifm vs bs (iff p q) = Ifm vs bs (Iff p q)" - by (unfold iff_def, cases "p = q", simp, cases "p = NOT q", simp) (cases "NOT p= q", auto) + by (unfold iff_def, cases "p = q", simp, cases "p = Not q", simp) (cases "Not p= q", auto) text \Quantifier freeness.\ fun qfree:: "fm \ bool" where "qfree (E p) = False" | "qfree (A p) = False" - | "qfree (NOT p) = qfree p" + | "qfree (Not p) = qfree p" | "qfree (And p q) = (qfree p \ qfree q)" | "qfree (Or p q) = (qfree p \ qfree q)" | "qfree (Imp p q) = (qfree p \ qfree q)" @@ -627,7 +627,7 @@ | "boundslt n (Le t) = tmboundslt n t" | "boundslt n (Eq t) = tmboundslt n t" | "boundslt n (NEq t) = tmboundslt n t" - | "boundslt n (NOT p) = boundslt n p" + | "boundslt n (Not p) = boundslt n p" | "boundslt n (And p q) = (boundslt n p \ boundslt n q)" | "boundslt n (Or p q) = (boundslt n p \ boundslt n q)" | "boundslt n (Imp p q) = ((boundslt n p) \ (boundslt n q))" @@ -643,7 +643,7 @@ | "bound0 (Le a) = tmbound0 a" | "bound0 (Eq a) = tmbound0 a" | "bound0 (NEq a) = tmbound0 a" - | "bound0 (NOT p) = bound0 p" + | "bound0 (Not p) = bound0 p" | "bound0 (And p q) = (bound0 p \ bound0 q)" | "bound0 (Or p q) = (bound0 p \ bound0 q)" | "bound0 (Imp p q) = ((bound0 p) \ (bound0 q))" @@ -664,7 +664,7 @@ | "bound m (Le t) = tmbound m t" | "bound m (Eq t) = tmbound m t" | "bound m (NEq t) = tmbound m t" - | "bound m (NOT p) = bound m p" + | "bound m (Not p) = bound m p" | "bound m (And p q) = (bound m p \ bound m q)" | "bound m (Or p q) = (bound m p \ bound m q)" | "bound m (Imp p q) = ((bound m p) \ (bound m q))" @@ -706,7 +706,7 @@ | "decr0 (Le a) = Le (decrtm0 a)" | "decr0 (Eq a) = Eq (decrtm0 a)" | "decr0 (NEq a) = NEq (decrtm0 a)" - | "decr0 (NOT p) = NOT (decr0 p)" + | "decr0 (Not p) = Not (decr0 p)" | "decr0 (And p q) = conj (decr0 p) (decr0 q)" | "decr0 (Or p q) = disj (decr0 p) (decr0 q)" | "decr0 (Imp p q) = imp (decr0 p) (decr0 q)" @@ -726,7 +726,7 @@ | "decr m (Le t) = (Le (decrtm m t))" | "decr m (Eq t) = (Eq (decrtm m t))" | "decr m (NEq t) = (NEq (decrtm m t))" - | "decr m (NOT p) = NOT (decr m p)" + | "decr m (Not p) = Not (decr m p)" | "decr m (And p q) = conj (decr m p) (decr m q)" | "decr m (Or p q) = disj (decr m p) (decr m q)" | "decr m (Imp p q) = imp (decr m p) (decr m q)" @@ -774,7 +774,7 @@ | "subst0 t (Le a) = Le (tmsubst0 t a)" | "subst0 t (Eq a) = Eq (tmsubst0 t a)" | "subst0 t (NEq a) = NEq (tmsubst0 t a)" - | "subst0 t (NOT p) = NOT (subst0 t p)" + | "subst0 t (Not p) = Not (subst0 t p)" | "subst0 t (And p q) = And (subst0 t p) (subst0 t q)" | "subst0 t (Or p q) = Or (subst0 t p) (subst0 t q)" | "subst0 t (Imp p q) = Imp (subst0 t p) (subst0 t q)" @@ -802,7 +802,7 @@ | "subst n t (Le a) = Le (tmsubst n t a)" | "subst n t (Eq a) = Eq (tmsubst n t a)" | "subst n t (NEq a) = NEq (tmsubst n t a)" - | "subst n t (NOT p) = NOT (subst n t p)" + | "subst n t (Not p) = Not (subst n t p)" | "subst n t (And p q) = And (subst n t p) (subst n t q)" | "subst n t (Or p q) = Or (subst n t p) (subst n t q)" | "subst n t (Imp p q) = Imp (subst n t p) (subst n t q)" @@ -1081,7 +1081,7 @@ | "islin (NEq (CNP 0 c s)) = (isnpoly c \ c \ 0\<^sub>p \ tmbound0 s \ allpolys isnpoly s)" | "islin (Lt (CNP 0 c s)) = (isnpoly c \ c \ 0\<^sub>p \ tmbound0 s \ allpolys isnpoly s)" | "islin (Le (CNP 0 c s)) = (isnpoly c \ c \ 0\<^sub>p \ tmbound0 s \ allpolys isnpoly s)" - | "islin (NOT p) = False" + | "islin (Not p) = False" | "islin (Imp p q) = False" | "islin (Iff p q) = False" | "islin p = bound0 p" @@ -1520,21 +1520,21 @@ | "simpfm (NEq t) = simpneq(simptm t)" | "simpfm (And p q) = conj (simpfm p) (simpfm q)" | "simpfm (Or p q) = disj (simpfm p) (simpfm q)" - | "simpfm (Imp p q) = disj (simpfm (NOT p)) (simpfm q)" + | "simpfm (Imp p q) = disj (simpfm (Not p)) (simpfm q)" | "simpfm (Iff p q) = - disj (conj (simpfm p) (simpfm q)) (conj (simpfm (NOT p)) (simpfm (NOT q)))" - | "simpfm (NOT (And p q)) = disj (simpfm (NOT p)) (simpfm (NOT q))" - | "simpfm (NOT (Or p q)) = conj (simpfm (NOT p)) (simpfm (NOT q))" - | "simpfm (NOT (Imp p q)) = conj (simpfm p) (simpfm (NOT q))" - | "simpfm (NOT (Iff p q)) = - disj (conj (simpfm p) (simpfm (NOT q))) (conj (simpfm (NOT p)) (simpfm q))" - | "simpfm (NOT (Eq t)) = simpneq t" - | "simpfm (NOT (NEq t)) = simpeq t" - | "simpfm (NOT (Le t)) = simplt (Neg t)" - | "simpfm (NOT (Lt t)) = simple (Neg t)" - | "simpfm (NOT (NOT p)) = simpfm p" - | "simpfm (NOT T) = F" - | "simpfm (NOT F) = T" + disj (conj (simpfm p) (simpfm q)) (conj (simpfm (Not p)) (simpfm (Not q)))" + | "simpfm (Not (And p q)) = disj (simpfm (Not p)) (simpfm (Not q))" + | "simpfm (Not (Or p q)) = conj (simpfm (Not p)) (simpfm (Not q))" + | "simpfm (Not (Imp p q)) = conj (simpfm p) (simpfm (Not q))" + | "simpfm (Not (Iff p q)) = + disj (conj (simpfm p) (simpfm (Not q))) (conj (simpfm (Not p)) (simpfm q))" + | "simpfm (Not (Eq t)) = simpneq t" + | "simpfm (Not (NEq t)) = simpeq t" + | "simpfm (Not (Le t)) = simplt (Neg t)" + | "simpfm (Not (Lt t)) = simple (Neg t)" + | "simpfm (Not (Not p)) = simpfm p" + | "simpfm (Not T) = F" + | "simpfm (Not F) = T" | "simpfm p = p" lemma simpfm[simp]: "Ifm vs bs (simpfm p) = Ifm vs bs p" @@ -1600,25 +1600,25 @@ "prep (E T) = T" | "prep (E F) = F" | "prep (E (Or p q)) = disj (prep (E p)) (prep (E q))" - | "prep (E (Imp p q)) = disj (prep (E (NOT p))) (prep (E q))" - | "prep (E (Iff p q)) = disj (prep (E (And p q))) (prep (E (And (NOT p) (NOT q))))" - | "prep (E (NOT (And p q))) = disj (prep (E (NOT p))) (prep (E(NOT q)))" - | "prep (E (NOT (Imp p q))) = prep (E (And p (NOT q)))" - | "prep (E (NOT (Iff p q))) = disj (prep (E (And p (NOT q)))) (prep (E(And (NOT p) q)))" + | "prep (E (Imp p q)) = disj (prep (E (Not p))) (prep (E q))" + | "prep (E (Iff p q)) = disj (prep (E (And p q))) (prep (E (And (Not p) (Not q))))" + | "prep (E (Not (And p q))) = disj (prep (E (Not p))) (prep (E(Not q)))" + | "prep (E (Not (Imp p q))) = prep (E (And p (Not q)))" + | "prep (E (Not (Iff p q))) = disj (prep (E (And p (Not q)))) (prep (E(And (Not p) q)))" | "prep (E p) = E (prep p)" | "prep (A (And p q)) = conj (prep (A p)) (prep (A q))" - | "prep (A p) = prep (NOT (E (NOT p)))" - | "prep (NOT (NOT p)) = prep p" - | "prep (NOT (And p q)) = disj (prep (NOT p)) (prep (NOT q))" - | "prep (NOT (A p)) = prep (E (NOT p))" - | "prep (NOT (Or p q)) = conj (prep (NOT p)) (prep (NOT q))" - | "prep (NOT (Imp p q)) = conj (prep p) (prep (NOT q))" - | "prep (NOT (Iff p q)) = disj (prep (And p (NOT q))) (prep (And (NOT p) q))" - | "prep (NOT p) = not (prep p)" + | "prep (A p) = prep (Not (E (Not p)))" + | "prep (Not (Not p)) = prep p" + | "prep (Not (And p q)) = disj (prep (Not p)) (prep (Not q))" + | "prep (Not (A p)) = prep (E (Not p))" + | "prep (Not (Or p q)) = conj (prep (Not p)) (prep (Not q))" + | "prep (Not (Imp p q)) = conj (prep p) (prep (Not q))" + | "prep (Not (Iff p q)) = disj (prep (And p (Not q))) (prep (And (Not p) q))" + | "prep (Not p) = not (prep p)" | "prep (Or p q) = disj (prep p) (prep q)" | "prep (And p q) = conj (prep p) (prep q)" - | "prep (Imp p q) = prep (Or (NOT p) q)" - | "prep (Iff p q) = disj (prep (And p q)) (prep (And (NOT p) (NOT q)))" + | "prep (Imp p q) = prep (Or (Not p) q)" + | "prep (Iff p q) = disj (prep (And p q)) (prep (And (Not p) (Not q)))" | "prep p = p" lemma prep: "Ifm vs bs (prep p) = Ifm vs bs p" @@ -1629,8 +1629,8 @@ fun qelim :: "fm \ (fm \ fm) \ fm" where "qelim (E p) = (\qe. DJ (CJNB qe) (qelim p qe))" - | "qelim (A p) = (\qe. not (qe ((qelim (NOT p) qe))))" - | "qelim (NOT p) = (\qe. not (qelim p qe))" + | "qelim (A p) = (\qe. not (qe ((qelim (Not p) qe))))" + | "qelim (Not p) = (\qe. not (qelim p qe))" | "qelim (And p q) = (\qe. conj (qelim p qe) (qelim q qe))" | "qelim (Or p q) = (\qe. disj (qelim p qe) (qelim q qe))" | "qelim (Imp p q) = (\qe. imp (qelim p qe) (qelim q qe))" @@ -3541,7 +3541,7 @@ "msubstpos (And p q) c t = And (msubstpos p c t) (msubstpos q c t)" | "msubstpos (Or p q) c t = Or (msubstpos p c t) (msubstpos q c t)" | "msubstpos (Eq (CNP 0 a r)) c t = msubsteq2 c t a r" - | "msubstpos (NEq (CNP 0 a r)) c t = NOT (msubsteq2 c t a r)" + | "msubstpos (NEq (CNP 0 a r)) c t = Not (msubsteq2 c t a r)" | "msubstpos (Lt (CNP 0 a r)) c t = msubstltpos c t a r" | "msubstpos (Le (CNP 0 a r)) c t = msubstlepos c t a r" | "msubstpos p c t = p" @@ -3562,7 +3562,7 @@ "msubstneg (And p q) c t = And (msubstneg p c t) (msubstneg q c t)" | "msubstneg (Or p q) c t = Or (msubstneg p c t) (msubstneg q c t)" | "msubstneg (Eq (CNP 0 a r)) c t = msubsteq2 c t a r" - | "msubstneg (NEq (CNP 0 a r)) c t = NOT (msubsteq2 c t a r)" + | "msubstneg (NEq (CNP 0 a r)) c t = Not (msubsteq2 c t a r)" | "msubstneg (Lt (CNP 0 a r)) c t = msubstltneg c t a r" | "msubstneg (Le (CNP 0 a r)) c t = msubstleneg c t a r" | "msubstneg p c t = p" @@ -3973,8 +3973,8 @@ fun fm_of_term fs ps \<^term>\True\ = @{code T} | fm_of_term fs ps \<^term>\False\ = @{code F} - | fm_of_term fs ps (Const (\<^const_name>\Not\, _) $ p) = - @{code NOT} (fm_of_term fs ps p) + | fm_of_term fs ps (Const (\<^const_name>\HOL.Not\, _) $ p) = + @{code Not} (fm_of_term fs ps p) | fm_of_term fs ps (Const (\<^const_name>\HOL.conj\, _) $ p $ q) = @{code And} (fm_of_term fs ps p, fm_of_term fs ps q) | fm_of_term fs ps (Const (\<^const_name>\HOL.disj\, _) $ p $ q) = @@ -4039,7 +4039,7 @@ fun term_of_fm T fs ps @{code T} = \<^term>\True\ | term_of_fm T fs ps @{code F} = \<^term>\False\ - | term_of_fm T fs ps (@{code NOT} p) = \<^term>\Not\ $ term_of_fm T fs ps p + | term_of_fm T fs ps (@{code Not} p) = \<^term>\HOL.Not\ $ term_of_fm T fs ps p | term_of_fm T fs ps (@{code And} (p, q)) = \<^term>\HOL.conj\ $ term_of_fm T fs ps p $ term_of_fm T fs ps q | term_of_fm T fs ps (@{code Or} (p, q)) = diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Divides.thy --- a/src/HOL/Divides.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/Divides.thy Mon Aug 02 10:01:06 2021 +0000 @@ -1106,14 +1106,6 @@ \divmod (Num.BitM m) (Num.Bit0 Num.One) = (numeral m - 1, (1 :: int))\ by (cases m) simp_all -lemma bit_numeral_Bit0_Suc_iff [simp]: - \bit (numeral (Num.Bit0 m) :: int) (Suc n) \ bit (numeral m :: int) n\ - by (simp add: bit_Suc) - -lemma bit_numeral_Bit1_Suc_iff [simp]: - \bit (numeral (Num.Bit1 m) :: int) (Suc n) \ bit (numeral m :: int) n\ - by (simp add: bit_Suc) - lemma div_positive_int: "k div l > 0" if "k \ l" and "l > 0" for k l :: int using that div_positive [of l k] by blast @@ -1225,113 +1217,6 @@ code_module Divides \ (SML) Arith and (OCaml) Arith and (Haskell) Arith -subsection \More on bit operations\ - -lemma take_bit_incr_eq: - \take_bit n (k + 1) = 1 + take_bit n k\ if \take_bit n k \ 2 ^ n - 1\ - for k :: int -proof - - from that have \2 ^ n \ k mod 2 ^ n + 1\ - by (simp add: take_bit_eq_mod) - moreover have \k mod 2 ^ n < 2 ^ n\ - by simp - ultimately have *: \k mod 2 ^ n + 1 < 2 ^ n\ - by linarith - have \(k + 1) mod 2 ^ n = (k mod 2 ^ n + 1) mod 2 ^ n\ - by (simp add: mod_simps) - also have \\ = k mod 2 ^ n + 1\ - using * by (simp add: zmod_trivial_iff) - finally have \(k + 1) mod 2 ^ n = k mod 2 ^ n + 1\ . - then show ?thesis - by (simp add: take_bit_eq_mod) -qed - -lemma take_bit_decr_eq: - \take_bit n (k - 1) = take_bit n k - 1\ if \take_bit n k \ 0\ - for k :: int -proof - - from that have \k mod 2 ^ n \ 0\ - by (simp add: take_bit_eq_mod) - moreover have \k mod 2 ^ n \ 0\ \k mod 2 ^ n < 2 ^ n\ - by simp_all - ultimately have *: \k mod 2 ^ n > 0\ - by linarith - have \(k - 1) mod 2 ^ n = (k mod 2 ^ n - 1) mod 2 ^ n\ - by (simp add: mod_simps) - also have \\ = k mod 2 ^ n - 1\ - by (simp add: zmod_trivial_iff) - (use \k mod 2 ^ n < 2 ^ n\ * in linarith) - finally have \(k - 1) mod 2 ^ n = k mod 2 ^ n - 1\ . - then show ?thesis - by (simp add: take_bit_eq_mod) -qed - -lemma take_bit_int_greater_eq: - \k + 2 ^ n \ take_bit n k\ if \k < 0\ for k :: int -proof - - have \k + 2 ^ n \ take_bit n (k + 2 ^ n)\ - proof (cases \k > - (2 ^ n)\) - case False - then have \k + 2 ^ n \ 0\ - by simp - also note take_bit_nonnegative - finally show ?thesis . - next - case True - with that have \0 \ k + 2 ^ n\ and \k + 2 ^ n < 2 ^ n\ - by simp_all - then show ?thesis - by (simp only: take_bit_eq_mod mod_pos_pos_trivial) - qed - then show ?thesis - by (simp add: take_bit_eq_mod) -qed - -lemma take_bit_int_less_eq: - \take_bit n k \ k - 2 ^ n\ if \2 ^ n \ k\ and \n > 0\ for k :: int - using that zmod_le_nonneg_dividend [of \k - 2 ^ n\ \2 ^ n\] - by (simp add: take_bit_eq_mod) - -lemma take_bit_int_less_eq_self_iff: - \take_bit n k \ k \ 0 \ k\ (is \?P \ ?Q\) - for k :: int -proof - assume ?P - show ?Q - proof (rule ccontr) - assume \\ 0 \ k\ - then have \k < 0\ - by simp - with \?P\ - have \take_bit n k < 0\ - by (rule le_less_trans) - then show False - by simp - qed -next - assume ?Q - then show ?P - by (simp add: take_bit_eq_mod zmod_le_nonneg_dividend) -qed - -lemma take_bit_int_less_self_iff: - \take_bit n k < k \ 2 ^ n \ k\ - for k :: int - by (auto simp add: less_le take_bit_int_less_eq_self_iff take_bit_int_eq_self_iff - intro: order_trans [of 0 \2 ^ n\ k]) - -lemma take_bit_int_greater_self_iff: - \k < take_bit n k \ k < 0\ - for k :: int - using take_bit_int_less_eq_self_iff [of n k] by auto - -lemma take_bit_int_greater_eq_self_iff: - \k \ take_bit n k \ k < 2 ^ n\ - for k :: int - by (auto simp add: le_less take_bit_int_greater_self_iff take_bit_int_eq_self_iff - dest: sym not_sym intro: less_trans [of k 0 \2 ^ n\]) - - subsection \Lemmas of doubtful value\ lemma div_geq: "m div n = Suc ((m - n) div n)" if "0 < n" and " \ m < n" for m n :: nat diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Fun.thy --- a/src/HOL/Fun.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/Fun.thy Mon Aug 02 10:01:06 2021 +0000 @@ -93,7 +93,7 @@ lemma (in group_add) minus_comp_minus [simp]: "uminus \ uminus = id" by (simp add: fun_eq_iff) -lemma (in boolean_algebra) minus_comp_minus [simp]: "uminus \ uminus = id" +lemma (in Lattices.boolean_algebra) minus_comp_minus [simp]: "uminus \ uminus = id" by (simp add: fun_eq_iff) code_printing diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/GCD.thy --- a/src/HOL/GCD.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/GCD.thy Mon Aug 02 10:01:06 2021 +0000 @@ -31,7 +31,7 @@ section \Greatest common divisor and least common multiple\ theory GCD - imports Groups_List + imports Groups_List Code_Numeral begin subsection \Abstract bounded quasi semilattices as common foundation\ diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Groups_List.thy --- a/src/HOL/Groups_List.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/Groups_List.thy Mon Aug 02 10:01:06 2021 +0000 @@ -403,80 +403,6 @@ end -context semiring_bit_shifts -begin - -lemma horner_sum_bit_eq_take_bit: - \horner_sum of_bool 2 (map (bit a) [0.. -proof (induction a arbitrary: n rule: bits_induct) - case (stable a) - moreover have \bit a = (\_. odd a)\ - using stable by (simp add: stable_imp_bit_iff_odd fun_eq_iff) - moreover have \{q. q < n} = {0.. - by auto - ultimately show ?case - by (simp add: stable_imp_take_bit_eq horner_sum_eq_sum mask_eq_sum_exp) -next - case (rec a b) - show ?case - proof (cases n) - case 0 - then show ?thesis - by simp - next - case (Suc m) - have \map (bit (of_bool b + 2 * a)) [0.. - by (simp only: upt_conv_Cons) simp - also have \\ = b # map (bit a) [0.. - by (simp only: flip: map_Suc_upt) (simp add: bit_Suc rec.hyps) - finally show ?thesis - using Suc rec.IH [of m] by (simp add: take_bit_Suc rec.hyps) - (simp_all add: ac_simps mod_2_eq_odd) - qed -qed - -end - -context unique_euclidean_semiring_with_bit_shifts -begin - -lemma bit_horner_sum_bit_iff [bit_simps]: - \bit (horner_sum of_bool 2 bs) n \ n < length bs \ bs ! n\ -proof (induction bs arbitrary: n) - case Nil - then show ?case - by simp -next - case (Cons b bs) - show ?case - proof (cases n) - case 0 - then show ?thesis - by simp - next - case (Suc m) - with bit_rec [of _ n] Cons.prems Cons.IH [of m] - show ?thesis by simp - qed -qed - -lemma take_bit_horner_sum_bit_eq: - \take_bit n (horner_sum of_bool 2 bs) = horner_sum of_bool 2 (take n bs)\ - by (auto simp add: bit_eq_iff bit_take_bit_iff bit_horner_sum_bit_iff) - -end - -lemma horner_sum_of_bool_2_less: - \(horner_sum of_bool 2 bs :: int) < 2 ^ length bs\ -proof - - have \(\n = 0.. (\n = 0.. - by (rule sum_mono) simp - also have \\ = 2 ^ length bs - 1\ - by (induction bs) simp_all - finally show ?thesis - by (simp add: horner_sum_eq_sum) -qed - subsection \Further facts about \<^const>\List.n_lists\\ diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/HOLCF/IOA/Pred.thy --- a/src/HOL/HOLCF/IOA/Pred.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/HOLCF/IOA/Pred.thy Mon Aug 02 10:01:06 2021 +0000 @@ -18,8 +18,8 @@ definition valid :: "'a predicate \ bool" ("\ _" [9] 8) where "(\ P) \ (\s. (s \ P))" -definition NOT :: "'a predicate \ 'a predicate" ("\<^bold>\ _" [40] 40) - where "NOT P s \ \ P s" +definition Not :: "'a predicate \ 'a predicate" ("\<^bold>\ _" [40] 40) + where NOT_def: "Not P s \ \ P s" definition AND :: "'a predicate \ 'a predicate \ 'a predicate" (infixr "\<^bold>\" 35) where "(P \<^bold>\ Q) s \ P s \ Q s" diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/IMP/OO.thy --- a/src/HOL/IMP/OO.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/IMP/OO.thy Mon Aug 02 10:01:06 2021 +0000 @@ -55,7 +55,7 @@ ve = (\x. null)(''this'' := or, ''param'' := pr); me \ (me m,ve,sn\<^sub>3) \ (r,ve',sn\<^sub>4) \ \ - me \ (oe\m,c\<^sub>1) \ (r,ve\<^sub>3,sn\<^sub>4)" | + me \ (oe\m,c\<^sub>1) \ (r,ve\<^sub>3,sn\<^sub>4)" for or | Seq: "\ me \ (e\<^sub>1,c\<^sub>1) \ (r,c\<^sub>2); me \ (e\<^sub>2,c\<^sub>2) \ c\<^sub>3 \ \ me \ (e\<^sub>1; e\<^sub>2,c\<^sub>1) \ c\<^sub>3" | diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Library/Bit_Operations.thy --- a/src/HOL/Library/Bit_Operations.thy Sun Aug 01 23:18:13 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2105 +0,0 @@ -(* Author: Florian Haftmann, TUM -*) - -section \Bit operations in suitable algebraic structures\ - -theory Bit_Operations - imports - Main - "HOL-Library.Boolean_Algebra" -begin - -subsection \Bit operations\ - -class semiring_bit_operations = semiring_bit_shifts + - fixes "and" :: \'a \ 'a \ 'a\ (infixr \AND\ 64) - and or :: \'a \ 'a \ 'a\ (infixr \OR\ 59) - and xor :: \'a \ 'a \ 'a\ (infixr \XOR\ 59) - and mask :: \nat \ 'a\ - and set_bit :: \nat \ 'a \ 'a\ - and unset_bit :: \nat \ 'a \ 'a\ - and flip_bit :: \nat \ 'a \ 'a\ - assumes bit_and_iff [bit_simps]: \bit (a AND b) n \ bit a n \ bit b n\ - and bit_or_iff [bit_simps]: \bit (a OR b) n \ bit a n \ bit b n\ - and bit_xor_iff [bit_simps]: \bit (a XOR b) n \ bit a n \ bit b n\ - and mask_eq_exp_minus_1: \mask n = 2 ^ n - 1\ - and set_bit_eq_or: \set_bit n a = a OR push_bit n 1\ - and bit_unset_bit_iff [bit_simps]: \bit (unset_bit m a) n \ bit a n \ m \ n\ - and flip_bit_eq_xor: \flip_bit n a = a XOR push_bit n 1\ -begin - -text \ - We want the bitwise operations to bind slightly weaker - than \+\ and \-\. - For the sake of code generation - the operations \<^const>\and\, \<^const>\or\ and \<^const>\xor\ - are specified as definitional class operations. -\ - -sublocale "and": semilattice \(AND)\ - by standard (auto simp add: bit_eq_iff bit_and_iff) - -sublocale or: semilattice_neutr \(OR)\ 0 - by standard (auto simp add: bit_eq_iff bit_or_iff) - -sublocale xor: comm_monoid \(XOR)\ 0 - by standard (auto simp add: bit_eq_iff bit_xor_iff) - -lemma even_and_iff: - \even (a AND b) \ even a \ even b\ - using bit_and_iff [of a b 0] by auto - -lemma even_or_iff: - \even (a OR b) \ even a \ even b\ - using bit_or_iff [of a b 0] by auto - -lemma even_xor_iff: - \even (a XOR b) \ (even a \ even b)\ - using bit_xor_iff [of a b 0] by auto - -lemma zero_and_eq [simp]: - \0 AND a = 0\ - by (simp add: bit_eq_iff bit_and_iff) - -lemma and_zero_eq [simp]: - \a AND 0 = 0\ - by (simp add: bit_eq_iff bit_and_iff) - -lemma one_and_eq: - \1 AND a = a mod 2\ - by (simp add: bit_eq_iff bit_and_iff) (auto simp add: bit_1_iff) - -lemma and_one_eq: - \a AND 1 = a mod 2\ - using one_and_eq [of a] by (simp add: ac_simps) - -lemma one_or_eq: - \1 OR a = a + of_bool (even a)\ - by (simp add: bit_eq_iff bit_or_iff add.commute [of _ 1] even_bit_succ_iff) (auto simp add: bit_1_iff) - -lemma or_one_eq: - \a OR 1 = a + of_bool (even a)\ - using one_or_eq [of a] by (simp add: ac_simps) - -lemma one_xor_eq: - \1 XOR a = a + of_bool (even a) - of_bool (odd a)\ - by (simp add: bit_eq_iff bit_xor_iff add.commute [of _ 1] even_bit_succ_iff) (auto simp add: bit_1_iff odd_bit_iff_bit_pred elim: oddE) - -lemma xor_one_eq: - \a XOR 1 = a + of_bool (even a) - of_bool (odd a)\ - using one_xor_eq [of a] by (simp add: ac_simps) - -lemma take_bit_and [simp]: - \take_bit n (a AND b) = take_bit n a AND take_bit n b\ - by (auto simp add: bit_eq_iff bit_take_bit_iff bit_and_iff) - -lemma take_bit_or [simp]: - \take_bit n (a OR b) = take_bit n a OR take_bit n b\ - by (auto simp add: bit_eq_iff bit_take_bit_iff bit_or_iff) - -lemma take_bit_xor [simp]: - \take_bit n (a XOR b) = take_bit n a XOR take_bit n b\ - by (auto simp add: bit_eq_iff bit_take_bit_iff bit_xor_iff) - -lemma push_bit_and [simp]: - \push_bit n (a AND b) = push_bit n a AND push_bit n b\ - by (rule bit_eqI) (auto simp add: bit_push_bit_iff bit_and_iff) - -lemma push_bit_or [simp]: - \push_bit n (a OR b) = push_bit n a OR push_bit n b\ - by (rule bit_eqI) (auto simp add: bit_push_bit_iff bit_or_iff) - -lemma push_bit_xor [simp]: - \push_bit n (a XOR b) = push_bit n a XOR push_bit n b\ - by (rule bit_eqI) (auto simp add: bit_push_bit_iff bit_xor_iff) - -lemma drop_bit_and [simp]: - \drop_bit n (a AND b) = drop_bit n a AND drop_bit n b\ - by (rule bit_eqI) (auto simp add: bit_drop_bit_eq bit_and_iff) - -lemma drop_bit_or [simp]: - \drop_bit n (a OR b) = drop_bit n a OR drop_bit n b\ - by (rule bit_eqI) (auto simp add: bit_drop_bit_eq bit_or_iff) - -lemma drop_bit_xor [simp]: - \drop_bit n (a XOR b) = drop_bit n a XOR drop_bit n b\ - by (rule bit_eqI) (auto simp add: bit_drop_bit_eq bit_xor_iff) - -lemma bit_mask_iff [bit_simps]: - \bit (mask m) n \ 2 ^ n \ 0 \ n < m\ - by (simp add: mask_eq_exp_minus_1 bit_mask_iff) - -lemma even_mask_iff: - \even (mask n) \ n = 0\ - using bit_mask_iff [of n 0] by auto - -lemma mask_0 [simp]: - \mask 0 = 0\ - by (simp add: mask_eq_exp_minus_1) - -lemma mask_Suc_0 [simp]: - \mask (Suc 0) = 1\ - by (simp add: mask_eq_exp_minus_1 add_implies_diff sym) - -lemma mask_Suc_exp: - \mask (Suc n) = 2 ^ n OR mask n\ - by (rule bit_eqI) - (auto simp add: bit_or_iff bit_mask_iff bit_exp_iff not_less le_less_Suc_eq) - -lemma mask_Suc_double: - \mask (Suc n) = 1 OR 2 * mask n\ -proof (rule bit_eqI) - fix q - assume \2 ^ q \ 0\ - show \bit (mask (Suc n)) q \ bit (1 OR 2 * mask n) q\ - by (cases q) - (simp_all add: even_mask_iff even_or_iff bit_or_iff bit_mask_iff bit_exp_iff bit_double_iff not_less le_less_Suc_eq bit_1_iff, auto simp add: mult_2) -qed - -lemma mask_numeral: - \mask (numeral n) = 1 + 2 * mask (pred_numeral n)\ - by (simp add: numeral_eq_Suc mask_Suc_double one_or_eq ac_simps) - -lemma take_bit_mask [simp]: - \take_bit m (mask n) = mask (min m n)\ - by (rule bit_eqI) (simp add: bit_simps) - -lemma take_bit_eq_mask: - \take_bit n a = a AND mask n\ - by (rule bit_eqI) - (auto simp add: bit_take_bit_iff bit_and_iff bit_mask_iff) - -lemma or_eq_0_iff: - \a OR b = 0 \ a = 0 \ b = 0\ - by (auto simp add: bit_eq_iff bit_or_iff) - -lemma disjunctive_add: - \a + b = a OR b\ if \\n. \ bit a n \ \ bit b n\ - by (rule bit_eqI) (use that in \simp add: bit_disjunctive_add_iff bit_or_iff\) - -lemma bit_iff_and_drop_bit_eq_1: - \bit a n \ drop_bit n a AND 1 = 1\ - by (simp add: bit_iff_odd_drop_bit and_one_eq odd_iff_mod_2_eq_one) - -lemma bit_iff_and_push_bit_not_eq_0: - \bit a n \ a AND push_bit n 1 \ 0\ - apply (cases \2 ^ n = 0\) - apply (simp_all add: push_bit_of_1 bit_eq_iff bit_and_iff bit_push_bit_iff exp_eq_0_imp_not_bit) - apply (simp_all add: bit_exp_iff) - done - -lemmas set_bit_def = set_bit_eq_or - -lemma bit_set_bit_iff [bit_simps]: - \bit (set_bit m a) n \ bit a n \ (m = n \ 2 ^ n \ 0)\ - by (auto simp add: set_bit_def push_bit_of_1 bit_or_iff bit_exp_iff) - -lemma even_set_bit_iff: - \even (set_bit m a) \ even a \ m \ 0\ - using bit_set_bit_iff [of m a 0] by auto - -lemma even_unset_bit_iff: - \even (unset_bit m a) \ even a \ m = 0\ - using bit_unset_bit_iff [of m a 0] by auto - -lemma and_exp_eq_0_iff_not_bit: - \a AND 2 ^ n = 0 \ \ bit a n\ (is \?P \ ?Q\) -proof - assume ?Q - then show ?P - by (auto intro: bit_eqI simp add: bit_simps) -next - assume ?P - show ?Q - proof (rule notI) - assume \bit a n\ - then have \a AND 2 ^ n = 2 ^ n\ - by (auto intro: bit_eqI simp add: bit_simps) - with \?P\ show False - using \bit a n\ exp_eq_0_imp_not_bit by auto - qed -qed - -lemmas flip_bit_def = flip_bit_eq_xor - -lemma bit_flip_bit_iff [bit_simps]: - \bit (flip_bit m a) n \ (m = n \ \ bit a n) \ 2 ^ n \ 0\ - by (auto simp add: flip_bit_def push_bit_of_1 bit_xor_iff bit_exp_iff exp_eq_0_imp_not_bit) - -lemma even_flip_bit_iff: - \even (flip_bit m a) \ \ (even a \ m = 0)\ - using bit_flip_bit_iff [of m a 0] by auto - -lemma set_bit_0 [simp]: - \set_bit 0 a = 1 + 2 * (a div 2)\ -proof (rule bit_eqI) - fix m - assume *: \2 ^ m \ 0\ - then show \bit (set_bit 0 a) m = bit (1 + 2 * (a div 2)) m\ - by (simp add: bit_set_bit_iff bit_double_iff even_bit_succ_iff) - (cases m, simp_all add: bit_Suc) -qed - -lemma set_bit_Suc: - \set_bit (Suc n) a = a mod 2 + 2 * set_bit n (a div 2)\ -proof (rule bit_eqI) - fix m - assume *: \2 ^ m \ 0\ - show \bit (set_bit (Suc n) a) m \ bit (a mod 2 + 2 * set_bit n (a div 2)) m\ - proof (cases m) - case 0 - then show ?thesis - by (simp add: even_set_bit_iff) - next - case (Suc m) - with * have \2 ^ m \ 0\ - using mult_2 by auto - show ?thesis - by (cases a rule: parity_cases) - (simp_all add: bit_set_bit_iff bit_double_iff even_bit_succ_iff *, - simp_all add: Suc \2 ^ m \ 0\ bit_Suc) - qed -qed - -lemma unset_bit_0 [simp]: - \unset_bit 0 a = 2 * (a div 2)\ -proof (rule bit_eqI) - fix m - assume *: \2 ^ m \ 0\ - then show \bit (unset_bit 0 a) m = bit (2 * (a div 2)) m\ - by (simp add: bit_unset_bit_iff bit_double_iff) - (cases m, simp_all add: bit_Suc) -qed - -lemma unset_bit_Suc: - \unset_bit (Suc n) a = a mod 2 + 2 * unset_bit n (a div 2)\ -proof (rule bit_eqI) - fix m - assume *: \2 ^ m \ 0\ - then show \bit (unset_bit (Suc n) a) m \ bit (a mod 2 + 2 * unset_bit n (a div 2)) m\ - proof (cases m) - case 0 - then show ?thesis - by (simp add: even_unset_bit_iff) - next - case (Suc m) - show ?thesis - by (cases a rule: parity_cases) - (simp_all add: bit_unset_bit_iff bit_double_iff even_bit_succ_iff *, - simp_all add: Suc bit_Suc) - qed -qed - -lemma flip_bit_0 [simp]: - \flip_bit 0 a = of_bool (even a) + 2 * (a div 2)\ -proof (rule bit_eqI) - fix m - assume *: \2 ^ m \ 0\ - then show \bit (flip_bit 0 a) m = bit (of_bool (even a) + 2 * (a div 2)) m\ - by (simp add: bit_flip_bit_iff bit_double_iff even_bit_succ_iff) - (cases m, simp_all add: bit_Suc) -qed - -lemma flip_bit_Suc: - \flip_bit (Suc n) a = a mod 2 + 2 * flip_bit n (a div 2)\ -proof (rule bit_eqI) - fix m - assume *: \2 ^ m \ 0\ - show \bit (flip_bit (Suc n) a) m \ bit (a mod 2 + 2 * flip_bit n (a div 2)) m\ - proof (cases m) - case 0 - then show ?thesis - by (simp add: even_flip_bit_iff) - next - case (Suc m) - with * have \2 ^ m \ 0\ - using mult_2 by auto - show ?thesis - by (cases a rule: parity_cases) - (simp_all add: bit_flip_bit_iff bit_double_iff even_bit_succ_iff, - simp_all add: Suc \2 ^ m \ 0\ bit_Suc) - qed -qed - -lemma flip_bit_eq_if: - \flip_bit n a = (if bit a n then unset_bit else set_bit) n a\ - by (rule bit_eqI) (auto simp add: bit_set_bit_iff bit_unset_bit_iff bit_flip_bit_iff) - -lemma take_bit_set_bit_eq: - \take_bit n (set_bit m a) = (if n \ m then take_bit n a else set_bit m (take_bit n a))\ - by (rule bit_eqI) (auto simp add: bit_take_bit_iff bit_set_bit_iff) - -lemma take_bit_unset_bit_eq: - \take_bit n (unset_bit m a) = (if n \ m then take_bit n a else unset_bit m (take_bit n a))\ - by (rule bit_eqI) (auto simp add: bit_take_bit_iff bit_unset_bit_iff) - -lemma take_bit_flip_bit_eq: - \take_bit n (flip_bit m a) = (if n \ m then take_bit n a else flip_bit m (take_bit n a))\ - by (rule bit_eqI) (auto simp add: bit_take_bit_iff bit_flip_bit_iff) - - -end - -class ring_bit_operations = semiring_bit_operations + ring_parity + - fixes not :: \'a \ 'a\ (\NOT\) - assumes bit_not_iff [bit_simps]: \\n. bit (NOT a) n \ 2 ^ n \ 0 \ \ bit a n\ - assumes minus_eq_not_minus_1: \- a = NOT (a - 1)\ -begin - -text \ - For the sake of code generation \<^const>\not\ is specified as - definitional class operation. Note that \<^const>\not\ has no - sensible definition for unlimited but only positive bit strings - (type \<^typ>\nat\). -\ - -lemma bits_minus_1_mod_2_eq [simp]: - \(- 1) mod 2 = 1\ - by (simp add: mod_2_eq_odd) - -lemma not_eq_complement: - \NOT a = - a - 1\ - using minus_eq_not_minus_1 [of \a + 1\] by simp - -lemma minus_eq_not_plus_1: - \- a = NOT a + 1\ - using not_eq_complement [of a] by simp - -lemma bit_minus_iff [bit_simps]: - \bit (- a) n \ 2 ^ n \ 0 \ \ bit (a - 1) n\ - by (simp add: minus_eq_not_minus_1 bit_not_iff) - -lemma even_not_iff [simp]: - \even (NOT a) \ odd a\ - using bit_not_iff [of a 0] by auto - -lemma bit_not_exp_iff [bit_simps]: - \bit (NOT (2 ^ m)) n \ 2 ^ n \ 0 \ n \ m\ - by (auto simp add: bit_not_iff bit_exp_iff) - -lemma bit_minus_1_iff [simp]: - \bit (- 1) n \ 2 ^ n \ 0\ - by (simp add: bit_minus_iff) - -lemma bit_minus_exp_iff [bit_simps]: - \bit (- (2 ^ m)) n \ 2 ^ n \ 0 \ n \ m\ - by (auto simp add: bit_simps simp flip: mask_eq_exp_minus_1) - -lemma bit_minus_2_iff [simp]: - \bit (- 2) n \ 2 ^ n \ 0 \ n > 0\ - by (simp add: bit_minus_iff bit_1_iff) - -lemma not_one [simp]: - \NOT 1 = - 2\ - by (simp add: bit_eq_iff bit_not_iff) (simp add: bit_1_iff) - -sublocale "and": semilattice_neutr \(AND)\ \- 1\ - by standard (rule bit_eqI, simp add: bit_and_iff) - -sublocale bit: boolean_algebra \(AND)\ \(OR)\ NOT 0 \- 1\ - rewrites \bit.xor = (XOR)\ -proof - - interpret bit: boolean_algebra \(AND)\ \(OR)\ NOT 0 \- 1\ - by standard (auto simp add: bit_and_iff bit_or_iff bit_not_iff intro: bit_eqI) - show \boolean_algebra (AND) (OR) NOT 0 (- 1)\ - by standard - show \boolean_algebra.xor (AND) (OR) NOT = (XOR)\ - by (rule ext, rule ext, rule bit_eqI) - (auto simp add: bit.xor_def bit_and_iff bit_or_iff bit_xor_iff bit_not_iff) -qed - -lemma and_eq_not_not_or: - \a AND b = NOT (NOT a OR NOT b)\ - by simp - -lemma or_eq_not_not_and: - \a OR b = NOT (NOT a AND NOT b)\ - by simp - -lemma not_add_distrib: - \NOT (a + b) = NOT a - b\ - by (simp add: not_eq_complement algebra_simps) - -lemma not_diff_distrib: - \NOT (a - b) = NOT a + b\ - using not_add_distrib [of a \- b\] by simp - -lemma (in ring_bit_operations) and_eq_minus_1_iff: - \a AND b = - 1 \ a = - 1 \ b = - 1\ -proof - assume \a = - 1 \ b = - 1\ - then show \a AND b = - 1\ - by simp -next - assume \a AND b = - 1\ - have *: \bit a n\ \bit b n\ if \2 ^ n \ 0\ for n - proof - - from \a AND b = - 1\ - have \bit (a AND b) n = bit (- 1) n\ - by (simp add: bit_eq_iff) - then show \bit a n\ \bit b n\ - using that by (simp_all add: bit_and_iff) - qed - have \a = - 1\ - by (rule bit_eqI) (simp add: *) - moreover have \b = - 1\ - by (rule bit_eqI) (simp add: *) - ultimately show \a = - 1 \ b = - 1\ - by simp -qed - -lemma disjunctive_diff: - \a - b = a AND NOT b\ if \\n. bit b n \ bit a n\ -proof - - have \NOT a + b = NOT a OR b\ - by (rule disjunctive_add) (auto simp add: bit_not_iff dest: that) - then have \NOT (NOT a + b) = NOT (NOT a OR b)\ - by simp - then show ?thesis - by (simp add: not_add_distrib) -qed - -lemma push_bit_minus: - \push_bit n (- a) = - push_bit n a\ - by (simp add: push_bit_eq_mult) - -lemma take_bit_not_take_bit: - \take_bit n (NOT (take_bit n a)) = take_bit n (NOT a)\ - by (auto simp add: bit_eq_iff bit_take_bit_iff bit_not_iff) - -lemma take_bit_not_iff: - \take_bit n (NOT a) = take_bit n (NOT b) \ take_bit n a = take_bit n b\ - apply (simp add: bit_eq_iff) - apply (simp add: bit_not_iff bit_take_bit_iff bit_exp_iff) - apply (use exp_eq_0_imp_not_bit in blast) - done - -lemma take_bit_not_eq_mask_diff: - \take_bit n (NOT a) = mask n - take_bit n a\ -proof - - have \take_bit n (NOT a) = take_bit n (NOT (take_bit n a))\ - by (simp add: take_bit_not_take_bit) - also have \\ = mask n AND NOT (take_bit n a)\ - by (simp add: take_bit_eq_mask ac_simps) - also have \\ = mask n - take_bit n a\ - by (subst disjunctive_diff) - (auto simp add: bit_take_bit_iff bit_mask_iff exp_eq_0_imp_not_bit) - finally show ?thesis - by simp -qed - -lemma mask_eq_take_bit_minus_one: - \mask n = take_bit n (- 1)\ - by (simp add: bit_eq_iff bit_mask_iff bit_take_bit_iff conj_commute) - -lemma take_bit_minus_one_eq_mask: - \take_bit n (- 1) = mask n\ - by (simp add: mask_eq_take_bit_minus_one) - -lemma minus_exp_eq_not_mask: - \- (2 ^ n) = NOT (mask n)\ - by (rule bit_eqI) (simp add: bit_minus_iff bit_not_iff flip: mask_eq_exp_minus_1) - -lemma push_bit_minus_one_eq_not_mask: - \push_bit n (- 1) = NOT (mask n)\ - by (simp add: push_bit_eq_mult minus_exp_eq_not_mask) - -lemma take_bit_not_mask_eq_0: - \take_bit m (NOT (mask n)) = 0\ if \n \ m\ - by (rule bit_eqI) (use that in \simp add: bit_take_bit_iff bit_not_iff bit_mask_iff\) - -lemma unset_bit_eq_and_not: - \unset_bit n a = a AND NOT (push_bit n 1)\ - by (rule bit_eqI) (auto simp add: bit_simps) - -lemmas unset_bit_def = unset_bit_eq_and_not - -end - - -subsection \Instance \<^typ>\int\\ - -lemma int_bit_bound: - fixes k :: int - obtains n where \\m. n \ m \ bit k m \ bit k n\ - and \n > 0 \ bit k (n - 1) \ bit k n\ -proof - - obtain q where *: \\m. q \ m \ bit k m \ bit k q\ - proof (cases \k \ 0\) - case True - moreover from power_gt_expt [of 2 \nat k\] - have \nat k < 2 ^ nat k\ - by simp - then have \int (nat k) < int (2 ^ nat k)\ - by (simp only: of_nat_less_iff) - ultimately have *: \k div 2 ^ nat k = 0\ - by simp - show thesis - proof (rule that [of \nat k\]) - fix m - assume \nat k \ m\ - then show \bit k m \ bit k (nat k)\ - by (auto simp add: * bit_iff_odd power_add zdiv_zmult2_eq dest!: le_Suc_ex) - qed - next - case False - moreover from power_gt_expt [of 2 \nat (- k)\] - have \nat (- k) < 2 ^ nat (- k)\ - by simp - then have \int (nat (- k)) < int (2 ^ nat (- k))\ - by (simp only: of_nat_less_iff) - ultimately have \- k div - (2 ^ nat (- k)) = - 1\ - by (subst div_pos_neg_trivial) simp_all - then have *: \k div 2 ^ nat (- k) = - 1\ - by simp - show thesis - proof (rule that [of \nat (- k)\]) - fix m - assume \nat (- k) \ m\ - then show \bit k m \ bit k (nat (- k))\ - by (auto simp add: * bit_iff_odd power_add zdiv_zmult2_eq minus_1_div_exp_eq_int dest!: le_Suc_ex) - qed - qed - show thesis - proof (cases \\m. bit k m \ bit k q\) - case True - then have \bit k 0 \ bit k q\ - by blast - with True that [of 0] show thesis - by simp - next - case False - then obtain r where **: \bit k r \ bit k q\ - by blast - have \r < q\ - by (rule ccontr) (use * [of r] ** in simp) - define N where \N = {n. n < q \ bit k n \ bit k q}\ - moreover have \finite N\ \r \ N\ - using ** N_def \r < q\ by auto - moreover define n where \n = Suc (Max N)\ - ultimately have \\m. n \ m \ bit k m \ bit k n\ - apply auto - apply (metis (full_types, lifting) "*" Max_ge_iff Suc_n_not_le_n \finite N\ all_not_in_conv mem_Collect_eq not_le) - apply (metis "*" Max_ge Suc_n_not_le_n \finite N\ linorder_not_less mem_Collect_eq) - apply (metis "*" Max_ge Suc_n_not_le_n \finite N\ linorder_not_less mem_Collect_eq) - apply (metis (full_types, lifting) "*" Max_ge_iff Suc_n_not_le_n \finite N\ all_not_in_conv mem_Collect_eq not_le) - done - have \bit k (Max N) \ bit k n\ - by (metis (mono_tags, lifting) "*" Max_in N_def \\m. n \ m \ bit k m = bit k n\ \finite N\ \r \ N\ empty_iff le_cases mem_Collect_eq) - show thesis apply (rule that [of n]) - using \\m. n \ m \ bit k m = bit k n\ apply blast - using \bit k (Max N) \ bit k n\ n_def by auto - qed -qed - -instantiation int :: ring_bit_operations -begin - -definition not_int :: \int \ int\ - where \not_int k = - k - 1\ - -lemma not_int_rec: - \NOT k = of_bool (even k) + 2 * NOT (k div 2)\ for k :: int - by (auto simp add: not_int_def elim: oddE) - -lemma even_not_iff_int: - \even (NOT k) \ odd k\ for k :: int - by (simp add: not_int_def) - -lemma not_int_div_2: - \NOT k div 2 = NOT (k div 2)\ for k :: int - by (simp add: not_int_def) - -lemma bit_not_int_iff [bit_simps]: - \bit (NOT k) n \ \ bit k n\ - for k :: int - by (simp add: bit_not_int_iff' not_int_def) - -function and_int :: \int \ int \ int\ - where \(k::int) AND l = (if k \ {0, - 1} \ l \ {0, - 1} - then - of_bool (odd k \ odd l) - else of_bool (odd k \ odd l) + 2 * ((k div 2) AND (l div 2)))\ - by auto - -termination - by (relation \measure (\(k, l). nat (\k\ + \l\))\) auto - -declare and_int.simps [simp del] - -lemma and_int_rec: - \k AND l = of_bool (odd k \ odd l) + 2 * ((k div 2) AND (l div 2))\ - for k l :: int -proof (cases \k \ {0, - 1} \ l \ {0, - 1}\) - case True - then show ?thesis - by auto (simp_all add: and_int.simps) -next - case False - then show ?thesis - by (auto simp add: ac_simps and_int.simps [of k l]) -qed - -lemma bit_and_int_iff: - \bit (k AND l) n \ bit k n \ bit l n\ for k l :: int -proof (induction n arbitrary: k l) - case 0 - then show ?case - by (simp add: and_int_rec [of k l]) -next - case (Suc n) - then show ?case - by (simp add: and_int_rec [of k l] bit_Suc) -qed - -lemma even_and_iff_int: - \even (k AND l) \ even k \ even l\ for k l :: int - using bit_and_int_iff [of k l 0] by auto - -definition or_int :: \int \ int \ int\ - where \k OR l = NOT (NOT k AND NOT l)\ for k l :: int - -lemma or_int_rec: - \k OR l = of_bool (odd k \ odd l) + 2 * ((k div 2) OR (l div 2))\ - for k l :: int - using and_int_rec [of \NOT k\ \NOT l\] - by (simp add: or_int_def even_not_iff_int not_int_div_2) - (simp_all add: not_int_def) - -lemma bit_or_int_iff: - \bit (k OR l) n \ bit k n \ bit l n\ for k l :: int - by (simp add: or_int_def bit_not_int_iff bit_and_int_iff) - -definition xor_int :: \int \ int \ int\ - where \k XOR l = k AND NOT l OR NOT k AND l\ for k l :: int - -lemma xor_int_rec: - \k XOR l = of_bool (odd k \ odd l) + 2 * ((k div 2) XOR (l div 2))\ - for k l :: int - by (simp add: xor_int_def or_int_rec [of \k AND NOT l\ \NOT k AND l\] even_and_iff_int even_not_iff_int) - (simp add: and_int_rec [of \NOT k\ \l\] and_int_rec [of \k\ \NOT l\] not_int_div_2) - -lemma bit_xor_int_iff: - \bit (k XOR l) n \ bit k n \ bit l n\ for k l :: int - by (auto simp add: xor_int_def bit_or_int_iff bit_and_int_iff bit_not_int_iff) - -definition mask_int :: \nat \ int\ - where \mask n = (2 :: int) ^ n - 1\ - -definition set_bit_int :: \nat \ int \ int\ - where \set_bit n k = k OR push_bit n 1\ for k :: int - -definition unset_bit_int :: \nat \ int \ int\ - where \unset_bit n k = k AND NOT (push_bit n 1)\ for k :: int - -definition flip_bit_int :: \nat \ int \ int\ - where \flip_bit n k = k XOR push_bit n 1\ for k :: int - -instance proof - fix k l :: int and m n :: nat - show \- k = NOT (k - 1)\ - by (simp add: not_int_def) - show \bit (k AND l) n \ bit k n \ bit l n\ - by (fact bit_and_int_iff) - show \bit (k OR l) n \ bit k n \ bit l n\ - by (fact bit_or_int_iff) - show \bit (k XOR l) n \ bit k n \ bit l n\ - by (fact bit_xor_int_iff) - show \bit (unset_bit m k) n \ bit k n \ m \ n\ - proof - - have \unset_bit m k = k AND NOT (push_bit m 1)\ - by (simp add: unset_bit_int_def) - also have \NOT (push_bit m 1 :: int) = - (push_bit m 1 + 1)\ - by (simp add: not_int_def) - finally show ?thesis by (simp only: bit_simps bit_and_int_iff) (auto simp add: bit_simps) - qed -qed (simp_all add: bit_not_int_iff mask_int_def set_bit_int_def flip_bit_int_def) - -end - - -lemma mask_half_int: - \mask n div 2 = (mask (n - 1) :: int)\ - by (cases n) (simp_all add: mask_eq_exp_minus_1 algebra_simps) - -lemma mask_nonnegative_int [simp]: - \mask n \ (0::int)\ - by (simp add: mask_eq_exp_minus_1) - -lemma not_mask_negative_int [simp]: - \\ mask n < (0::int)\ - by (simp add: not_less) - -lemma not_nonnegative_int_iff [simp]: - \NOT k \ 0 \ k < 0\ for k :: int - by (simp add: not_int_def) - -lemma not_negative_int_iff [simp]: - \NOT k < 0 \ k \ 0\ for k :: int - by (subst Not_eq_iff [symmetric]) (simp add: not_less not_le) - -lemma and_nonnegative_int_iff [simp]: - \k AND l \ 0 \ k \ 0 \ l \ 0\ for k l :: int -proof (induction k arbitrary: l rule: int_bit_induct) - case zero - then show ?case - by simp -next - case minus - then show ?case - by simp -next - case (even k) - then show ?case - using and_int_rec [of \k * 2\ l] by (simp add: pos_imp_zdiv_nonneg_iff) -next - case (odd k) - from odd have \0 \ k AND l div 2 \ 0 \ k \ 0 \ l div 2\ - by simp - then have \0 \ (1 + k * 2) div 2 AND l div 2 \ 0 \ (1 + k * 2) div 2\ 0 \ l div 2\ - by simp - with and_int_rec [of \1 + k * 2\ l] - show ?case - by auto -qed - -lemma and_negative_int_iff [simp]: - \k AND l < 0 \ k < 0 \ l < 0\ for k l :: int - by (subst Not_eq_iff [symmetric]) (simp add: not_less) - -lemma and_less_eq: - \k AND l \ k\ if \l < 0\ for k l :: int -using that proof (induction k arbitrary: l rule: int_bit_induct) - case zero - then show ?case - by simp -next - case minus - then show ?case - by simp -next - case (even k) - from even.IH [of \l div 2\] even.hyps even.prems - show ?case - by (simp add: and_int_rec [of _ l]) -next - case (odd k) - from odd.IH [of \l div 2\] odd.hyps odd.prems - show ?case - by (simp add: and_int_rec [of _ l]) -qed - -lemma or_nonnegative_int_iff [simp]: - \k OR l \ 0 \ k \ 0 \ l \ 0\ for k l :: int - by (simp only: or_eq_not_not_and not_nonnegative_int_iff) simp - -lemma or_negative_int_iff [simp]: - \k OR l < 0 \ k < 0 \ l < 0\ for k l :: int - by (subst Not_eq_iff [symmetric]) (simp add: not_less) - -lemma or_greater_eq: - \k OR l \ k\ if \l \ 0\ for k l :: int -using that proof (induction k arbitrary: l rule: int_bit_induct) - case zero - then show ?case - by simp -next - case minus - then show ?case - by simp -next - case (even k) - from even.IH [of \l div 2\] even.hyps even.prems - show ?case - by (simp add: or_int_rec [of _ l]) -next - case (odd k) - from odd.IH [of \l div 2\] odd.hyps odd.prems - show ?case - by (simp add: or_int_rec [of _ l]) -qed - -lemma xor_nonnegative_int_iff [simp]: - \k XOR l \ 0 \ (k \ 0 \ l \ 0)\ for k l :: int - by (simp only: bit.xor_def or_nonnegative_int_iff) auto - -lemma xor_negative_int_iff [simp]: - \k XOR l < 0 \ (k < 0) \ (l < 0)\ for k l :: int - by (subst Not_eq_iff [symmetric]) (auto simp add: not_less) - -lemma OR_upper: \<^marker>\contributor \Stefan Berghofer\\ - fixes x y :: int - assumes \0 \ x\ \x < 2 ^ n\ \y < 2 ^ n\ - shows \x OR y < 2 ^ n\ -using assms proof (induction x arbitrary: y n rule: int_bit_induct) - case zero - then show ?case - by simp -next - case minus - then show ?case - by simp -next - case (even x) - from even.IH [of \n - 1\ \y div 2\] even.prems even.hyps - show ?case - by (cases n) (auto simp add: or_int_rec [of \_ * 2\] elim: oddE) -next - case (odd x) - from odd.IH [of \n - 1\ \y div 2\] odd.prems odd.hyps - show ?case - by (cases n) (auto simp add: or_int_rec [of \1 + _ * 2\], linarith) -qed - -lemma XOR_upper: \<^marker>\contributor \Stefan Berghofer\\ - fixes x y :: int - assumes \0 \ x\ \x < 2 ^ n\ \y < 2 ^ n\ - shows \x XOR y < 2 ^ n\ -using assms proof (induction x arbitrary: y n rule: int_bit_induct) - case zero - then show ?case - by simp -next - case minus - then show ?case - by simp -next - case (even x) - from even.IH [of \n - 1\ \y div 2\] even.prems even.hyps - show ?case - by (cases n) (auto simp add: xor_int_rec [of \_ * 2\] elim: oddE) -next - case (odd x) - from odd.IH [of \n - 1\ \y div 2\] odd.prems odd.hyps - show ?case - by (cases n) (auto simp add: xor_int_rec [of \1 + _ * 2\]) -qed - -lemma AND_lower [simp]: \<^marker>\contributor \Stefan Berghofer\\ - fixes x y :: int - assumes \0 \ x\ - shows \0 \ x AND y\ - using assms by simp - -lemma OR_lower [simp]: \<^marker>\contributor \Stefan Berghofer\\ - fixes x y :: int - assumes \0 \ x\ \0 \ y\ - shows \0 \ x OR y\ - using assms by simp - -lemma XOR_lower [simp]: \<^marker>\contributor \Stefan Berghofer\\ - fixes x y :: int - assumes \0 \ x\ \0 \ y\ - shows \0 \ x XOR y\ - using assms by simp - -lemma AND_upper1 [simp]: \<^marker>\contributor \Stefan Berghofer\\ - fixes x y :: int - assumes \0 \ x\ - shows \x AND y \ x\ -using assms proof (induction x arbitrary: y rule: int_bit_induct) - case (odd k) - then have \k AND y div 2 \ k\ - by simp - then show ?case - by (simp add: and_int_rec [of \1 + _ * 2\]) -qed (simp_all add: and_int_rec [of \_ * 2\]) - -lemmas AND_upper1' [simp] = order_trans [OF AND_upper1] \<^marker>\contributor \Stefan Berghofer\\ -lemmas AND_upper1'' [simp] = order_le_less_trans [OF AND_upper1] \<^marker>\contributor \Stefan Berghofer\\ - -lemma AND_upper2 [simp]: \<^marker>\contributor \Stefan Berghofer\\ - fixes x y :: int - assumes \0 \ y\ - shows \x AND y \ y\ - using assms AND_upper1 [of y x] by (simp add: ac_simps) - -lemmas AND_upper2' [simp] = order_trans [OF AND_upper2] \<^marker>\contributor \Stefan Berghofer\\ -lemmas AND_upper2'' [simp] = order_le_less_trans [OF AND_upper2] \<^marker>\contributor \Stefan Berghofer\\ - -lemma plus_and_or: \(x AND y) + (x OR y) = x + y\ for x y :: int -proof (induction x arbitrary: y rule: int_bit_induct) - case zero - then show ?case - by simp -next - case minus - then show ?case - by simp -next - case (even x) - from even.IH [of \y div 2\] - show ?case - by (auto simp add: and_int_rec [of _ y] or_int_rec [of _ y] elim: oddE) -next - case (odd x) - from odd.IH [of \y div 2\] - show ?case - by (auto simp add: and_int_rec [of _ y] or_int_rec [of _ y] elim: oddE) -qed - -lemma set_bit_nonnegative_int_iff [simp]: - \set_bit n k \ 0 \ k \ 0\ for k :: int - by (simp add: set_bit_def) - -lemma set_bit_negative_int_iff [simp]: - \set_bit n k < 0 \ k < 0\ for k :: int - by (simp add: set_bit_def) - -lemma unset_bit_nonnegative_int_iff [simp]: - \unset_bit n k \ 0 \ k \ 0\ for k :: int - by (simp add: unset_bit_def) - -lemma unset_bit_negative_int_iff [simp]: - \unset_bit n k < 0 \ k < 0\ for k :: int - by (simp add: unset_bit_def) - -lemma flip_bit_nonnegative_int_iff [simp]: - \flip_bit n k \ 0 \ k \ 0\ for k :: int - by (simp add: flip_bit_def) - -lemma flip_bit_negative_int_iff [simp]: - \flip_bit n k < 0 \ k < 0\ for k :: int - by (simp add: flip_bit_def) - -lemma set_bit_greater_eq: - \set_bit n k \ k\ for k :: int - by (simp add: set_bit_def or_greater_eq) - -lemma unset_bit_less_eq: - \unset_bit n k \ k\ for k :: int - by (simp add: unset_bit_def and_less_eq) - -lemma set_bit_eq: - \set_bit n k = k + of_bool (\ bit k n) * 2 ^ n\ for k :: int -proof (rule bit_eqI) - fix m - show \bit (set_bit n k) m \ bit (k + of_bool (\ bit k n) * 2 ^ n) m\ - proof (cases \m = n\) - case True - then show ?thesis - apply (simp add: bit_set_bit_iff) - apply (simp add: bit_iff_odd div_plus_div_distrib_dvd_right) - done - next - case False - then show ?thesis - apply (clarsimp simp add: bit_set_bit_iff) - apply (subst disjunctive_add) - apply (clarsimp simp add: bit_exp_iff) - apply (clarsimp simp add: bit_or_iff bit_exp_iff) - done - qed -qed - -lemma unset_bit_eq: - \unset_bit n k = k - of_bool (bit k n) * 2 ^ n\ for k :: int -proof (rule bit_eqI) - fix m - show \bit (unset_bit n k) m \ bit (k - of_bool (bit k n) * 2 ^ n) m\ - proof (cases \m = n\) - case True - then show ?thesis - apply (simp add: bit_unset_bit_iff) - apply (simp add: bit_iff_odd) - using div_plus_div_distrib_dvd_right [of \2 ^ n\ \- (2 ^ n)\ k] - apply (simp add: dvd_neg_div) - done - next - case False - then show ?thesis - apply (clarsimp simp add: bit_unset_bit_iff) - apply (subst disjunctive_diff) - apply (clarsimp simp add: bit_exp_iff) - apply (clarsimp simp add: bit_and_iff bit_not_iff bit_exp_iff) - done - qed -qed - -lemma take_bit_eq_mask_iff: - \take_bit n k = mask n \ take_bit n (k + 1) = 0\ (is \?P \ ?Q\) - for k :: int -proof - assume ?P - then have \take_bit n (take_bit n k + take_bit n 1) = 0\ - by (simp add: mask_eq_exp_minus_1) - then show ?Q - by (simp only: take_bit_add) -next - assume ?Q - then have \take_bit n (k + 1) - 1 = - 1\ - by simp - then have \take_bit n (take_bit n (k + 1) - 1) = take_bit n (- 1)\ - by simp - moreover have \take_bit n (take_bit n (k + 1) - 1) = take_bit n k\ - by (simp add: take_bit_eq_mod mod_simps) - ultimately show ?P - by (simp add: take_bit_minus_one_eq_mask) -qed - -lemma take_bit_eq_mask_iff_exp_dvd: - \take_bit n k = mask n \ 2 ^ n dvd k + 1\ - for k :: int - by (simp add: take_bit_eq_mask_iff flip: take_bit_eq_0_iff) - -context ring_bit_operations -begin - -lemma even_of_int_iff: - \even (of_int k) \ even k\ - by (induction k rule: int_bit_induct) simp_all - -lemma bit_of_int_iff [bit_simps]: - \bit (of_int k) n \ (2::'a) ^ n \ 0 \ bit k n\ -proof (cases \(2::'a) ^ n = 0\) - case True - then show ?thesis - by (simp add: exp_eq_0_imp_not_bit) -next - case False - then have \bit (of_int k) n \ bit k n\ - proof (induction k arbitrary: n rule: int_bit_induct) - case zero - then show ?case - by simp - next - case minus - then show ?case - by simp - next - case (even k) - then show ?case - using bit_double_iff [of \of_int k\ n] Parity.bit_double_iff [of k n] - by (cases n) (auto simp add: ac_simps dest: mult_not_zero) - next - case (odd k) - then show ?case - using bit_double_iff [of \of_int k\ n] - by (cases n) (auto simp add: ac_simps bit_double_iff even_bit_succ_iff Parity.bit_Suc dest: mult_not_zero) - qed - with False show ?thesis - by simp -qed - -lemma push_bit_of_int: - \push_bit n (of_int k) = of_int (push_bit n k)\ - by (simp add: push_bit_eq_mult semiring_bit_shifts_class.push_bit_eq_mult) - -lemma of_int_push_bit: - \of_int (push_bit n k) = push_bit n (of_int k)\ - by (simp add: push_bit_eq_mult semiring_bit_shifts_class.push_bit_eq_mult) - -lemma take_bit_of_int: - \take_bit n (of_int k) = of_int (take_bit n k)\ - by (rule bit_eqI) (simp add: bit_take_bit_iff Parity.bit_take_bit_iff bit_of_int_iff) - -lemma of_int_take_bit: - \of_int (take_bit n k) = take_bit n (of_int k)\ - by (rule bit_eqI) (simp add: bit_take_bit_iff Parity.bit_take_bit_iff bit_of_int_iff) - -lemma of_int_not_eq: - \of_int (NOT k) = NOT (of_int k)\ - by (rule bit_eqI) (simp add: bit_not_iff Bit_Operations.bit_not_iff bit_of_int_iff) - -lemma of_int_and_eq: - \of_int (k AND l) = of_int k AND of_int l\ - by (rule bit_eqI) (simp add: bit_of_int_iff bit_and_iff Bit_Operations.bit_and_iff) - -lemma of_int_or_eq: - \of_int (k OR l) = of_int k OR of_int l\ - by (rule bit_eqI) (simp add: bit_of_int_iff bit_or_iff Bit_Operations.bit_or_iff) - -lemma of_int_xor_eq: - \of_int (k XOR l) = of_int k XOR of_int l\ - by (rule bit_eqI) (simp add: bit_of_int_iff bit_xor_iff Bit_Operations.bit_xor_iff) - -lemma of_int_mask_eq: - \of_int (mask n) = mask n\ - by (induction n) (simp_all add: mask_Suc_double Bit_Operations.mask_Suc_double of_int_or_eq) - -end - -lemma minus_numeral_inc_eq: - \- numeral (Num.inc n) = NOT (numeral n :: int)\ - by (simp add: not_int_def sub_inc_One_eq add_One) - -lemma sub_one_eq_not_neg: - \Num.sub n num.One = NOT (- numeral n :: int)\ - by (simp add: not_int_def) - -lemma int_not_numerals [simp]: - \NOT (numeral (Num.Bit0 n) :: int) = - numeral (Num.Bit1 n)\ - \NOT (numeral (Num.Bit1 n) :: int) = - numeral (Num.inc (num.Bit1 n))\ - \NOT (numeral (Num.BitM n) :: int) = - numeral (num.Bit0 n)\ - \NOT (- numeral (Num.Bit0 n) :: int) = numeral (Num.BitM n)\ - \NOT (- numeral (Num.Bit1 n) :: int) = numeral (Num.Bit0 n)\ - by (simp_all add: not_int_def add_One inc_BitM_eq) - -text \FIXME: The rule sets below are very large (24 rules for each - operator). Is there a simpler way to do this?\ - -context -begin - -private lemma eqI: - \k = l\ - if num: \\n. bit k (numeral n) \ bit l (numeral n)\ - and even: \even k \ even l\ - for k l :: int -proof (rule bit_eqI) - fix n - show \bit k n \ bit l n\ - proof (cases n) - case 0 - with even show ?thesis - by simp - next - case (Suc n) - with num [of \num_of_nat (Suc n)\] show ?thesis - by (simp only: numeral_num_of_nat) - qed -qed - -lemma int_and_numerals [simp]: - \numeral (Num.Bit0 x) AND numeral (Num.Bit0 y) = (2 :: int) * (numeral x AND numeral y)\ - \numeral (Num.Bit0 x) AND numeral (Num.Bit1 y) = (2 :: int) * (numeral x AND numeral y)\ - \numeral (Num.Bit1 x) AND numeral (Num.Bit0 y) = (2 :: int) * (numeral x AND numeral y)\ - \numeral (Num.Bit1 x) AND numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x AND numeral y)\ - \numeral (Num.Bit0 x) AND - numeral (Num.Bit0 y) = (2 :: int) * (numeral x AND - numeral y)\ - \numeral (Num.Bit0 x) AND - numeral (Num.Bit1 y) = (2 :: int) * (numeral x AND - numeral (y + Num.One))\ - \numeral (Num.Bit1 x) AND - numeral (Num.Bit0 y) = (2 :: int) * (numeral x AND - numeral y)\ - \numeral (Num.Bit1 x) AND - numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x AND - numeral (y + Num.One))\ - \- numeral (Num.Bit0 x) AND numeral (Num.Bit0 y) = (2 :: int) * (- numeral x AND numeral y)\ - \- numeral (Num.Bit0 x) AND numeral (Num.Bit1 y) = (2 :: int) * (- numeral x AND numeral y)\ - \- numeral (Num.Bit1 x) AND numeral (Num.Bit0 y) = (2 :: int) * (- numeral (x + Num.One) AND numeral y)\ - \- numeral (Num.Bit1 x) AND numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral (x + Num.One) AND numeral y)\ - \- numeral (Num.Bit0 x) AND - numeral (Num.Bit0 y) = (2 :: int) * (- numeral x AND - numeral y)\ - \- numeral (Num.Bit0 x) AND - numeral (Num.Bit1 y) = (2 :: int) * (- numeral x AND - numeral (y + Num.One))\ - \- numeral (Num.Bit1 x) AND - numeral (Num.Bit0 y) = (2 :: int) * (- numeral (x + Num.One) AND - numeral y)\ - \- numeral (Num.Bit1 x) AND - numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral (x + Num.One) AND - numeral (y + Num.One))\ - \(1::int) AND numeral (Num.Bit0 y) = 0\ - \(1::int) AND numeral (Num.Bit1 y) = 1\ - \(1::int) AND - numeral (Num.Bit0 y) = 0\ - \(1::int) AND - numeral (Num.Bit1 y) = 1\ - \numeral (Num.Bit0 x) AND (1::int) = 0\ - \numeral (Num.Bit1 x) AND (1::int) = 1\ - \- numeral (Num.Bit0 x) AND (1::int) = 0\ - \- numeral (Num.Bit1 x) AND (1::int) = 1\ - by (auto simp add: bit_and_iff bit_minus_iff even_and_iff bit_double_iff even_bit_succ_iff add_One sub_inc_One_eq intro: eqI) - -lemma int_or_numerals [simp]: - \numeral (Num.Bit0 x) OR numeral (Num.Bit0 y) = (2 :: int) * (numeral x OR numeral y)\ - \numeral (Num.Bit0 x) OR numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x OR numeral y)\ - \numeral (Num.Bit1 x) OR numeral (Num.Bit0 y) = 1 + (2 :: int) * (numeral x OR numeral y)\ - \numeral (Num.Bit1 x) OR numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x OR numeral y)\ - \numeral (Num.Bit0 x) OR - numeral (Num.Bit0 y) = (2 :: int) * (numeral x OR - numeral y)\ - \numeral (Num.Bit0 x) OR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x OR - numeral (y + Num.One))\ - \numeral (Num.Bit1 x) OR - numeral (Num.Bit0 y) = 1 + (2 :: int) * (numeral x OR - numeral y)\ - \numeral (Num.Bit1 x) OR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x OR - numeral (y + Num.One))\ - \- numeral (Num.Bit0 x) OR numeral (Num.Bit0 y) = (2 :: int) * (- numeral x OR numeral y)\ - \- numeral (Num.Bit0 x) OR numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral x OR numeral y)\ - \- numeral (Num.Bit1 x) OR numeral (Num.Bit0 y) = 1 + (2 :: int) * (- numeral (x + Num.One) OR numeral y)\ - \- numeral (Num.Bit1 x) OR numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral (x + Num.One) OR numeral y)\ - \- numeral (Num.Bit0 x) OR - numeral (Num.Bit0 y) = (2 :: int) * (- numeral x OR - numeral y)\ - \- numeral (Num.Bit0 x) OR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral x OR - numeral (y + Num.One))\ - \- numeral (Num.Bit1 x) OR - numeral (Num.Bit0 y) = 1 + (2 :: int) * (- numeral (x + Num.One) OR - numeral y)\ - \- numeral (Num.Bit1 x) OR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral (x + Num.One) OR - numeral (y + Num.One))\ - \(1::int) OR numeral (Num.Bit0 y) = numeral (Num.Bit1 y)\ - \(1::int) OR numeral (Num.Bit1 y) = numeral (Num.Bit1 y)\ - \(1::int) OR - numeral (Num.Bit0 y) = - numeral (Num.BitM y)\ - \(1::int) OR - numeral (Num.Bit1 y) = - numeral (Num.Bit1 y)\ - \numeral (Num.Bit0 x) OR (1::int) = numeral (Num.Bit1 x)\ - \numeral (Num.Bit1 x) OR (1::int) = numeral (Num.Bit1 x)\ - \- numeral (Num.Bit0 x) OR (1::int) = - numeral (Num.BitM x)\ - \- numeral (Num.Bit1 x) OR (1::int) = - numeral (Num.Bit1 x)\ - by (auto simp add: bit_or_iff bit_minus_iff even_or_iff bit_double_iff even_bit_succ_iff add_One sub_inc_One_eq sub_BitM_One_eq intro: eqI) - -lemma int_xor_numerals [simp]: - \numeral (Num.Bit0 x) XOR numeral (Num.Bit0 y) = (2 :: int) * (numeral x XOR numeral y)\ - \numeral (Num.Bit0 x) XOR numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x XOR numeral y)\ - \numeral (Num.Bit1 x) XOR numeral (Num.Bit0 y) = 1 + (2 :: int) * (numeral x XOR numeral y)\ - \numeral (Num.Bit1 x) XOR numeral (Num.Bit1 y) = (2 :: int) * (numeral x XOR numeral y)\ - \numeral (Num.Bit0 x) XOR - numeral (Num.Bit0 y) = (2 :: int) * (numeral x XOR - numeral y)\ - \numeral (Num.Bit0 x) XOR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x XOR - numeral (y + Num.One))\ - \numeral (Num.Bit1 x) XOR - numeral (Num.Bit0 y) = 1 + (2 :: int) * (numeral x XOR - numeral y)\ - \numeral (Num.Bit1 x) XOR - numeral (Num.Bit1 y) = (2 :: int) * (numeral x XOR - numeral (y + Num.One))\ - \- numeral (Num.Bit0 x) XOR numeral (Num.Bit0 y) = (2 :: int) * (- numeral x XOR numeral y)\ - \- numeral (Num.Bit0 x) XOR numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral x XOR numeral y)\ - \- numeral (Num.Bit1 x) XOR numeral (Num.Bit0 y) = 1 + (2 :: int) * (- numeral (x + Num.One) XOR numeral y)\ - \- numeral (Num.Bit1 x) XOR numeral (Num.Bit1 y) = (2 :: int) * (- numeral (x + Num.One) XOR numeral y)\ - \- numeral (Num.Bit0 x) XOR - numeral (Num.Bit0 y) = (2 :: int) * (- numeral x XOR - numeral y)\ - \- numeral (Num.Bit0 x) XOR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral x XOR - numeral (y + Num.One))\ - \- numeral (Num.Bit1 x) XOR - numeral (Num.Bit0 y) = 1 + (2 :: int) * (- numeral (x + Num.One) XOR - numeral y)\ - \- numeral (Num.Bit1 x) XOR - numeral (Num.Bit1 y) = (2 :: int) * (- numeral (x + Num.One) XOR - numeral (y + Num.One))\ - \(1::int) XOR numeral (Num.Bit0 y) = numeral (Num.Bit1 y)\ - \(1::int) XOR numeral (Num.Bit1 y) = numeral (Num.Bit0 y)\ - \(1::int) XOR - numeral (Num.Bit0 y) = - numeral (Num.BitM y)\ - \(1::int) XOR - numeral (Num.Bit1 y) = - numeral (Num.Bit0 (y + Num.One))\ - \numeral (Num.Bit0 x) XOR (1::int) = numeral (Num.Bit1 x)\ - \numeral (Num.Bit1 x) XOR (1::int) = numeral (Num.Bit0 x)\ - \- numeral (Num.Bit0 x) XOR (1::int) = - numeral (Num.BitM x)\ - \- numeral (Num.Bit1 x) XOR (1::int) = - numeral (Num.Bit0 (x + Num.One))\ - by (auto simp add: bit_xor_iff bit_minus_iff even_xor_iff bit_double_iff even_bit_succ_iff add_One sub_inc_One_eq sub_BitM_One_eq intro: eqI) - -end - - -subsection \Bit concatenation\ - -definition concat_bit :: \nat \ int \ int \ int\ - where \concat_bit n k l = take_bit n k OR push_bit n l\ - -lemma bit_concat_bit_iff [bit_simps]: - \bit (concat_bit m k l) n \ n < m \ bit k n \ m \ n \ bit l (n - m)\ - by (simp add: concat_bit_def bit_or_iff bit_and_iff bit_take_bit_iff bit_push_bit_iff ac_simps) - -lemma concat_bit_eq: - \concat_bit n k l = take_bit n k + push_bit n l\ - by (simp add: concat_bit_def take_bit_eq_mask - bit_and_iff bit_mask_iff bit_push_bit_iff disjunctive_add) - -lemma concat_bit_0 [simp]: - \concat_bit 0 k l = l\ - by (simp add: concat_bit_def) - -lemma concat_bit_Suc: - \concat_bit (Suc n) k l = k mod 2 + 2 * concat_bit n (k div 2) l\ - by (simp add: concat_bit_eq take_bit_Suc push_bit_double) - -lemma concat_bit_of_zero_1 [simp]: - \concat_bit n 0 l = push_bit n l\ - by (simp add: concat_bit_def) - -lemma concat_bit_of_zero_2 [simp]: - \concat_bit n k 0 = take_bit n k\ - by (simp add: concat_bit_def take_bit_eq_mask) - -lemma concat_bit_nonnegative_iff [simp]: - \concat_bit n k l \ 0 \ l \ 0\ - by (simp add: concat_bit_def) - -lemma concat_bit_negative_iff [simp]: - \concat_bit n k l < 0 \ l < 0\ - by (simp add: concat_bit_def) - -lemma concat_bit_assoc: - \concat_bit n k (concat_bit m l r) = concat_bit (m + n) (concat_bit n k l) r\ - by (rule bit_eqI) (auto simp add: bit_concat_bit_iff ac_simps) - -lemma concat_bit_assoc_sym: - \concat_bit m (concat_bit n k l) r = concat_bit (min m n) k (concat_bit (m - n) l r)\ - by (rule bit_eqI) (auto simp add: bit_concat_bit_iff ac_simps min_def) - -lemma concat_bit_eq_iff: - \concat_bit n k l = concat_bit n r s - \ take_bit n k = take_bit n r \ l = s\ (is \?P \ ?Q\) -proof - assume ?Q - then show ?P - by (simp add: concat_bit_def) -next - assume ?P - then have *: \bit (concat_bit n k l) m = bit (concat_bit n r s) m\ for m - by (simp add: bit_eq_iff) - have \take_bit n k = take_bit n r\ - proof (rule bit_eqI) - fix m - from * [of m] - show \bit (take_bit n k) m \ bit (take_bit n r) m\ - by (auto simp add: bit_take_bit_iff bit_concat_bit_iff) - qed - moreover have \push_bit n l = push_bit n s\ - proof (rule bit_eqI) - fix m - from * [of m] - show \bit (push_bit n l) m \ bit (push_bit n s) m\ - by (auto simp add: bit_push_bit_iff bit_concat_bit_iff) - qed - then have \l = s\ - by (simp add: push_bit_eq_mult) - ultimately show ?Q - by (simp add: concat_bit_def) -qed - -lemma take_bit_concat_bit_eq: - \take_bit m (concat_bit n k l) = concat_bit (min m n) k (take_bit (m - n) l)\ - by (rule bit_eqI) - (auto simp add: bit_take_bit_iff bit_concat_bit_iff min_def) - -lemma concat_bit_take_bit_eq: - \concat_bit n (take_bit n b) = concat_bit n b\ - by (simp add: concat_bit_def [abs_def]) - - -subsection \Taking bits with sign propagation\ - -context ring_bit_operations -begin - -definition signed_take_bit :: \nat \ 'a \ 'a\ - where \signed_take_bit n a = take_bit n a OR (of_bool (bit a n) * NOT (mask n))\ - -lemma signed_take_bit_eq_if_positive: - \signed_take_bit n a = take_bit n a\ if \\ bit a n\ - using that by (simp add: signed_take_bit_def) - -lemma signed_take_bit_eq_if_negative: - \signed_take_bit n a = take_bit n a OR NOT (mask n)\ if \bit a n\ - using that by (simp add: signed_take_bit_def) - -lemma even_signed_take_bit_iff: - \even (signed_take_bit m a) \ even a\ - by (auto simp add: signed_take_bit_def even_or_iff even_mask_iff bit_double_iff) - -lemma bit_signed_take_bit_iff [bit_simps]: - \bit (signed_take_bit m a) n \ 2 ^ n \ 0 \ bit a (min m n)\ - by (simp add: signed_take_bit_def bit_take_bit_iff bit_or_iff bit_not_iff bit_mask_iff min_def not_le) - (use exp_eq_0_imp_not_bit in blast) - -lemma signed_take_bit_0 [simp]: - \signed_take_bit 0 a = - (a mod 2)\ - by (simp add: signed_take_bit_def odd_iff_mod_2_eq_one) - -lemma signed_take_bit_Suc: - \signed_take_bit (Suc n) a = a mod 2 + 2 * signed_take_bit n (a div 2)\ -proof (rule bit_eqI) - fix m - assume *: \2 ^ m \ 0\ - show \bit (signed_take_bit (Suc n) a) m \ - bit (a mod 2 + 2 * signed_take_bit n (a div 2)) m\ - proof (cases m) - case 0 - then show ?thesis - by (simp add: even_signed_take_bit_iff) - next - case (Suc m) - with * have \2 ^ m \ 0\ - by (metis mult_not_zero power_Suc) - with Suc show ?thesis - by (simp add: bit_signed_take_bit_iff mod2_eq_if bit_double_iff even_bit_succ_iff - ac_simps flip: bit_Suc) - qed -qed - -lemma signed_take_bit_of_0 [simp]: - \signed_take_bit n 0 = 0\ - by (simp add: signed_take_bit_def) - -lemma signed_take_bit_of_minus_1 [simp]: - \signed_take_bit n (- 1) = - 1\ - by (simp add: signed_take_bit_def take_bit_minus_one_eq_mask mask_eq_exp_minus_1) - -lemma signed_take_bit_Suc_1 [simp]: - \signed_take_bit (Suc n) 1 = 1\ - by (simp add: signed_take_bit_Suc) - -lemma signed_take_bit_rec: - \signed_take_bit n a = (if n = 0 then - (a mod 2) else a mod 2 + 2 * signed_take_bit (n - 1) (a div 2))\ - by (cases n) (simp_all add: signed_take_bit_Suc) - -lemma signed_take_bit_eq_iff_take_bit_eq: - \signed_take_bit n a = signed_take_bit n b \ take_bit (Suc n) a = take_bit (Suc n) b\ -proof - - have \bit (signed_take_bit n a) = bit (signed_take_bit n b) \ bit (take_bit (Suc n) a) = bit (take_bit (Suc n) b)\ - by (simp add: fun_eq_iff bit_signed_take_bit_iff bit_take_bit_iff not_le less_Suc_eq_le min_def) - (use exp_eq_0_imp_not_bit in fastforce) - then show ?thesis - by (simp add: bit_eq_iff fun_eq_iff) -qed - -lemma signed_take_bit_signed_take_bit [simp]: - \signed_take_bit m (signed_take_bit n a) = signed_take_bit (min m n) a\ -proof (rule bit_eqI) - fix q - show \bit (signed_take_bit m (signed_take_bit n a)) q \ - bit (signed_take_bit (min m n) a) q\ - by (simp add: bit_signed_take_bit_iff min_def bit_or_iff bit_not_iff bit_mask_iff bit_take_bit_iff) - (use le_Suc_ex exp_add_not_zero_imp in blast) -qed - -lemma signed_take_bit_take_bit: - \signed_take_bit m (take_bit n a) = (if n \ m then take_bit n else signed_take_bit m) a\ - by (rule bit_eqI) (auto simp add: bit_signed_take_bit_iff min_def bit_take_bit_iff) - -lemma take_bit_signed_take_bit: - \take_bit m (signed_take_bit n a) = take_bit m a\ if \m \ Suc n\ - using that by (rule le_SucE; intro bit_eqI) - (auto simp add: bit_take_bit_iff bit_signed_take_bit_iff min_def less_Suc_eq) - -end - -text \Modulus centered around 0\ - -lemma signed_take_bit_eq_concat_bit: - \signed_take_bit n k = concat_bit n k (- of_bool (bit k n))\ - by (simp add: concat_bit_def signed_take_bit_def push_bit_minus_one_eq_not_mask) - -lemma signed_take_bit_add: - \signed_take_bit n (signed_take_bit n k + signed_take_bit n l) = signed_take_bit n (k + l)\ - for k l :: int -proof - - have \take_bit (Suc n) - (take_bit (Suc n) (signed_take_bit n k) + - take_bit (Suc n) (signed_take_bit n l)) = - take_bit (Suc n) (k + l)\ - by (simp add: take_bit_signed_take_bit take_bit_add) - then show ?thesis - by (simp only: signed_take_bit_eq_iff_take_bit_eq take_bit_add) -qed - -lemma signed_take_bit_diff: - \signed_take_bit n (signed_take_bit n k - signed_take_bit n l) = signed_take_bit n (k - l)\ - for k l :: int -proof - - have \take_bit (Suc n) - (take_bit (Suc n) (signed_take_bit n k) - - take_bit (Suc n) (signed_take_bit n l)) = - take_bit (Suc n) (k - l)\ - by (simp add: take_bit_signed_take_bit take_bit_diff) - then show ?thesis - by (simp only: signed_take_bit_eq_iff_take_bit_eq take_bit_diff) -qed - -lemma signed_take_bit_minus: - \signed_take_bit n (- signed_take_bit n k) = signed_take_bit n (- k)\ - for k :: int -proof - - have \take_bit (Suc n) - (- take_bit (Suc n) (signed_take_bit n k)) = - take_bit (Suc n) (- k)\ - by (simp add: take_bit_signed_take_bit take_bit_minus) - then show ?thesis - by (simp only: signed_take_bit_eq_iff_take_bit_eq take_bit_minus) -qed - -lemma signed_take_bit_mult: - \signed_take_bit n (signed_take_bit n k * signed_take_bit n l) = signed_take_bit n (k * l)\ - for k l :: int -proof - - have \take_bit (Suc n) - (take_bit (Suc n) (signed_take_bit n k) * - take_bit (Suc n) (signed_take_bit n l)) = - take_bit (Suc n) (k * l)\ - by (simp add: take_bit_signed_take_bit take_bit_mult) - then show ?thesis - by (simp only: signed_take_bit_eq_iff_take_bit_eq take_bit_mult) -qed - -lemma signed_take_bit_eq_take_bit_minus: - \signed_take_bit n k = take_bit (Suc n) k - 2 ^ Suc n * of_bool (bit k n)\ - for k :: int -proof (cases \bit k n\) - case True - have \signed_take_bit n k = take_bit (Suc n) k OR NOT (mask (Suc n))\ - by (rule bit_eqI) (auto simp add: bit_signed_take_bit_iff min_def bit_take_bit_iff bit_or_iff bit_not_iff bit_mask_iff less_Suc_eq True) - then have \signed_take_bit n k = take_bit (Suc n) k + NOT (mask (Suc n))\ - by (simp add: disjunctive_add bit_take_bit_iff bit_not_iff bit_mask_iff) - with True show ?thesis - by (simp flip: minus_exp_eq_not_mask) -next - case False - show ?thesis - by (rule bit_eqI) (simp add: False bit_signed_take_bit_iff bit_take_bit_iff min_def less_Suc_eq) -qed - -lemma signed_take_bit_eq_take_bit_shift: - \signed_take_bit n k = take_bit (Suc n) (k + 2 ^ n) - 2 ^ n\ - for k :: int -proof - - have *: \take_bit n k OR 2 ^ n = take_bit n k + 2 ^ n\ - by (simp add: disjunctive_add bit_exp_iff bit_take_bit_iff) - have \take_bit n k - 2 ^ n = take_bit n k + NOT (mask n)\ - by (simp add: minus_exp_eq_not_mask) - also have \\ = take_bit n k OR NOT (mask n)\ - by (rule disjunctive_add) - (simp add: bit_exp_iff bit_take_bit_iff bit_not_iff bit_mask_iff) - finally have **: \take_bit n k - 2 ^ n = take_bit n k OR NOT (mask n)\ . - have \take_bit (Suc n) (k + 2 ^ n) = take_bit (Suc n) (take_bit (Suc n) k + take_bit (Suc n) (2 ^ n))\ - by (simp only: take_bit_add) - also have \take_bit (Suc n) k = 2 ^ n * of_bool (bit k n) + take_bit n k\ - by (simp add: take_bit_Suc_from_most) - finally have \take_bit (Suc n) (k + 2 ^ n) = take_bit (Suc n) (2 ^ (n + of_bool (bit k n)) + take_bit n k)\ - by (simp add: ac_simps) - also have \2 ^ (n + of_bool (bit k n)) + take_bit n k = 2 ^ (n + of_bool (bit k n)) OR take_bit n k\ - by (rule disjunctive_add) - (auto simp add: disjunctive_add bit_take_bit_iff bit_double_iff bit_exp_iff) - finally show ?thesis - using * ** by (simp add: signed_take_bit_def concat_bit_Suc min_def ac_simps) -qed - -lemma signed_take_bit_nonnegative_iff [simp]: - \0 \ signed_take_bit n k \ \ bit k n\ - for k :: int - by (simp add: signed_take_bit_def not_less concat_bit_def) - -lemma signed_take_bit_negative_iff [simp]: - \signed_take_bit n k < 0 \ bit k n\ - for k :: int - by (simp add: signed_take_bit_def not_less concat_bit_def) - -lemma signed_take_bit_int_greater_eq_minus_exp [simp]: - \- (2 ^ n) \ signed_take_bit n k\ - for k :: int - by (simp add: signed_take_bit_eq_take_bit_shift) - -lemma signed_take_bit_int_less_exp [simp]: - \signed_take_bit n k < 2 ^ n\ - for k :: int - using take_bit_int_less_exp [of \Suc n\] - by (simp add: signed_take_bit_eq_take_bit_shift) - -lemma signed_take_bit_int_eq_self_iff: - \signed_take_bit n k = k \ - (2 ^ n) \ k \ k < 2 ^ n\ - for k :: int - by (auto simp add: signed_take_bit_eq_take_bit_shift take_bit_int_eq_self_iff algebra_simps) - -lemma signed_take_bit_int_eq_self: - \signed_take_bit n k = k\ if \- (2 ^ n) \ k\ \k < 2 ^ n\ - for k :: int - using that by (simp add: signed_take_bit_int_eq_self_iff) - -lemma signed_take_bit_int_less_eq_self_iff: - \signed_take_bit n k \ k \ - (2 ^ n) \ k\ - for k :: int - by (simp add: signed_take_bit_eq_take_bit_shift take_bit_int_less_eq_self_iff algebra_simps) - linarith - -lemma signed_take_bit_int_less_self_iff: - \signed_take_bit n k < k \ 2 ^ n \ k\ - for k :: int - by (simp add: signed_take_bit_eq_take_bit_shift take_bit_int_less_self_iff algebra_simps) - -lemma signed_take_bit_int_greater_self_iff: - \k < signed_take_bit n k \ k < - (2 ^ n)\ - for k :: int - by (simp add: signed_take_bit_eq_take_bit_shift take_bit_int_greater_self_iff algebra_simps) - linarith - -lemma signed_take_bit_int_greater_eq_self_iff: - \k \ signed_take_bit n k \ k < 2 ^ n\ - for k :: int - by (simp add: signed_take_bit_eq_take_bit_shift take_bit_int_greater_eq_self_iff algebra_simps) - -lemma signed_take_bit_int_greater_eq: - \k + 2 ^ Suc n \ signed_take_bit n k\ if \k < - (2 ^ n)\ - for k :: int - using that take_bit_int_greater_eq [of \k + 2 ^ n\ \Suc n\] - by (simp add: signed_take_bit_eq_take_bit_shift) - -lemma signed_take_bit_int_less_eq: - \signed_take_bit n k \ k - 2 ^ Suc n\ if \k \ 2 ^ n\ - for k :: int - using that take_bit_int_less_eq [of \Suc n\ \k + 2 ^ n\] - by (simp add: signed_take_bit_eq_take_bit_shift) - -lemma signed_take_bit_Suc_bit0 [simp]: - \signed_take_bit (Suc n) (numeral (Num.Bit0 k)) = signed_take_bit n (numeral k) * (2 :: int)\ - by (simp add: signed_take_bit_Suc) - -lemma signed_take_bit_Suc_bit1 [simp]: - \signed_take_bit (Suc n) (numeral (Num.Bit1 k)) = signed_take_bit n (numeral k) * 2 + (1 :: int)\ - by (simp add: signed_take_bit_Suc) - -lemma signed_take_bit_Suc_minus_bit0 [simp]: - \signed_take_bit (Suc n) (- numeral (Num.Bit0 k)) = signed_take_bit n (- numeral k) * (2 :: int)\ - by (simp add: signed_take_bit_Suc) - -lemma signed_take_bit_Suc_minus_bit1 [simp]: - \signed_take_bit (Suc n) (- numeral (Num.Bit1 k)) = signed_take_bit n (- numeral k - 1) * 2 + (1 :: int)\ - by (simp add: signed_take_bit_Suc) - -lemma signed_take_bit_numeral_bit0 [simp]: - \signed_take_bit (numeral l) (numeral (Num.Bit0 k)) = signed_take_bit (pred_numeral l) (numeral k) * (2 :: int)\ - by (simp add: signed_take_bit_rec) - -lemma signed_take_bit_numeral_bit1 [simp]: - \signed_take_bit (numeral l) (numeral (Num.Bit1 k)) = signed_take_bit (pred_numeral l) (numeral k) * 2 + (1 :: int)\ - by (simp add: signed_take_bit_rec) - -lemma signed_take_bit_numeral_minus_bit0 [simp]: - \signed_take_bit (numeral l) (- numeral (Num.Bit0 k)) = signed_take_bit (pred_numeral l) (- numeral k) * (2 :: int)\ - by (simp add: signed_take_bit_rec) - -lemma signed_take_bit_numeral_minus_bit1 [simp]: - \signed_take_bit (numeral l) (- numeral (Num.Bit1 k)) = signed_take_bit (pred_numeral l) (- numeral k - 1) * 2 + (1 :: int)\ - by (simp add: signed_take_bit_rec) - -lemma signed_take_bit_code [code]: - \signed_take_bit n a = - (let l = take_bit (Suc n) a - in if bit l n then l + push_bit (Suc n) (- 1) else l)\ -proof - - have *: \take_bit (Suc n) a + push_bit n (- 2) = - take_bit (Suc n) a OR NOT (mask (Suc n))\ - by (auto simp add: bit_take_bit_iff bit_push_bit_iff bit_not_iff bit_mask_iff disjunctive_add - simp flip: push_bit_minus_one_eq_not_mask) - show ?thesis - by (rule bit_eqI) - (auto simp add: Let_def * bit_signed_take_bit_iff bit_take_bit_iff min_def less_Suc_eq bit_not_iff bit_mask_iff bit_or_iff) -qed - - -subsection \Instance \<^typ>\nat\\ - -instantiation nat :: semiring_bit_operations -begin - -definition and_nat :: \nat \ nat \ nat\ - where \m AND n = nat (int m AND int n)\ for m n :: nat - -definition or_nat :: \nat \ nat \ nat\ - where \m OR n = nat (int m OR int n)\ for m n :: nat - -definition xor_nat :: \nat \ nat \ nat\ - where \m XOR n = nat (int m XOR int n)\ for m n :: nat - -definition mask_nat :: \nat \ nat\ - where \mask n = (2 :: nat) ^ n - 1\ - -definition set_bit_nat :: \nat \ nat \ nat\ - where \set_bit m n = n OR push_bit m 1\ for m n :: nat - -definition unset_bit_nat :: \nat \ nat \ nat\ - where \unset_bit m n = (if bit n m then n - push_bit m 1 else n)\ for m n :: nat - -definition flip_bit_nat :: \nat \ nat \ nat\ - where \flip_bit m n = n XOR push_bit m 1\ for m n :: nat - -instance proof - fix m n q :: nat - show \bit (m AND n) q \ bit m q \ bit n q\ - by (simp add: and_nat_def bit_simps) - show \bit (m OR n) q \ bit m q \ bit n q\ - by (simp add: or_nat_def bit_simps) - show \bit (m XOR n) q \ bit m q \ bit n q\ - by (simp add: xor_nat_def bit_simps) - show \bit (unset_bit m n) q \ bit n q \ m \ q\ - proof (cases \bit n m\) - case False - then show ?thesis by (auto simp add: unset_bit_nat_def) - next - case True - have \push_bit m (drop_bit m n) + take_bit m n = n\ - by (fact bits_ident) - also from \bit n m\ have \drop_bit m n = 2 * drop_bit (Suc m) n + 1\ - by (simp add: drop_bit_Suc drop_bit_half even_drop_bit_iff_not_bit ac_simps) - finally have \push_bit m (2 * drop_bit (Suc m) n) + take_bit m n + push_bit m 1 = n\ - by (simp only: push_bit_add ac_simps) - then have \n - push_bit m 1 = push_bit m (2 * drop_bit (Suc m) n) + take_bit m n\ - by simp - then have \n - push_bit m 1 = push_bit m (2 * drop_bit (Suc m) n) OR take_bit m n\ - by (simp add: or_nat_def bit_simps flip: disjunctive_add) - with \bit n m\ show ?thesis - by (auto simp add: unset_bit_nat_def or_nat_def bit_simps) - qed -qed (simp_all add: mask_nat_def set_bit_nat_def flip_bit_nat_def) - -end - -lemma and_nat_rec: - \m AND n = of_bool (odd m \ odd n) + 2 * ((m div 2) AND (n div 2))\ for m n :: nat - by (simp add: and_nat_def and_int_rec [of \int m\ \int n\] zdiv_int nat_add_distrib nat_mult_distrib) - -lemma or_nat_rec: - \m OR n = of_bool (odd m \ odd n) + 2 * ((m div 2) OR (n div 2))\ for m n :: nat - by (simp add: or_nat_def or_int_rec [of \int m\ \int n\] zdiv_int nat_add_distrib nat_mult_distrib) - -lemma xor_nat_rec: - \m XOR n = of_bool (odd m \ odd n) + 2 * ((m div 2) XOR (n div 2))\ for m n :: nat - by (simp add: xor_nat_def xor_int_rec [of \int m\ \int n\] zdiv_int nat_add_distrib nat_mult_distrib) - -lemma Suc_0_and_eq [simp]: - \Suc 0 AND n = n mod 2\ - using one_and_eq [of n] by simp - -lemma and_Suc_0_eq [simp]: - \n AND Suc 0 = n mod 2\ - using and_one_eq [of n] by simp - -lemma Suc_0_or_eq: - \Suc 0 OR n = n + of_bool (even n)\ - using one_or_eq [of n] by simp - -lemma or_Suc_0_eq: - \n OR Suc 0 = n + of_bool (even n)\ - using or_one_eq [of n] by simp - -lemma Suc_0_xor_eq: - \Suc 0 XOR n = n + of_bool (even n) - of_bool (odd n)\ - using one_xor_eq [of n] by simp - -lemma xor_Suc_0_eq: - \n XOR Suc 0 = n + of_bool (even n) - of_bool (odd n)\ - using xor_one_eq [of n] by simp - -context semiring_bit_operations -begin - -lemma of_nat_and_eq: - \of_nat (m AND n) = of_nat m AND of_nat n\ - by (rule bit_eqI) (simp add: bit_of_nat_iff bit_and_iff Bit_Operations.bit_and_iff) - -lemma of_nat_or_eq: - \of_nat (m OR n) = of_nat m OR of_nat n\ - by (rule bit_eqI) (simp add: bit_of_nat_iff bit_or_iff Bit_Operations.bit_or_iff) - -lemma of_nat_xor_eq: - \of_nat (m XOR n) = of_nat m XOR of_nat n\ - by (rule bit_eqI) (simp add: bit_of_nat_iff bit_xor_iff Bit_Operations.bit_xor_iff) - -end - -context ring_bit_operations -begin - -lemma of_nat_mask_eq: - \of_nat (mask n) = mask n\ - by (induction n) (simp_all add: mask_Suc_double Bit_Operations.mask_Suc_double of_nat_or_eq) - -end - -lemma Suc_mask_eq_exp: - \Suc (mask n) = 2 ^ n\ - by (simp add: mask_eq_exp_minus_1) - -lemma less_eq_mask: - \n \ mask n\ - by (simp add: mask_eq_exp_minus_1 le_diff_conv2) - (metis Suc_mask_eq_exp diff_Suc_1 diff_le_diff_pow diff_zero le_refl not_less_eq_eq power_0) - -lemma less_mask: - \n < mask n\ if \Suc 0 < n\ -proof - - define m where \m = n - 2\ - with that have *: \n = m + 2\ - by simp - have \Suc (Suc (Suc m)) < 4 * 2 ^ m\ - by (induction m) simp_all - then have \Suc (m + 2) < Suc (mask (m + 2))\ - by (simp add: Suc_mask_eq_exp) - then have \m + 2 < mask (m + 2)\ - by (simp add: less_le) - with * show ?thesis - by simp -qed - - -subsection \Symbolic computations on numeral expressions\ \<^marker>\contributor \Andreas Lochbihler\\ - -fun and_num :: \num \ num \ num option\ -where - \and_num num.One num.One = Some num.One\ -| \and_num num.One (num.Bit0 n) = None\ -| \and_num num.One (num.Bit1 n) = Some num.One\ -| \and_num (num.Bit0 m) num.One = None\ -| \and_num (num.Bit0 m) (num.Bit0 n) = map_option num.Bit0 (and_num m n)\ -| \and_num (num.Bit0 m) (num.Bit1 n) = map_option num.Bit0 (and_num m n)\ -| \and_num (num.Bit1 m) num.One = Some num.One\ -| \and_num (num.Bit1 m) (num.Bit0 n) = map_option num.Bit0 (and_num m n)\ -| \and_num (num.Bit1 m) (num.Bit1 n) = (case and_num m n of None \ Some num.One | Some n' \ Some (num.Bit1 n'))\ - -fun and_not_num :: \num \ num \ num option\ -where - \and_not_num num.One num.One = None\ -| \and_not_num num.One (num.Bit0 n) = Some num.One\ -| \and_not_num num.One (num.Bit1 n) = None\ -| \and_not_num (num.Bit0 m) num.One = Some (num.Bit0 m)\ -| \and_not_num (num.Bit0 m) (num.Bit0 n) = map_option num.Bit0 (and_not_num m n)\ -| \and_not_num (num.Bit0 m) (num.Bit1 n) = map_option num.Bit0 (and_not_num m n)\ -| \and_not_num (num.Bit1 m) num.One = Some (num.Bit0 m)\ -| \and_not_num (num.Bit1 m) (num.Bit0 n) = (case and_not_num m n of None \ Some num.One | Some n' \ Some (num.Bit1 n'))\ -| \and_not_num (num.Bit1 m) (num.Bit1 n) = map_option num.Bit0 (and_not_num m n)\ - -fun or_num :: \num \ num \ num\ -where - \or_num num.One num.One = num.One\ -| \or_num num.One (num.Bit0 n) = num.Bit1 n\ -| \or_num num.One (num.Bit1 n) = num.Bit1 n\ -| \or_num (num.Bit0 m) num.One = num.Bit1 m\ -| \or_num (num.Bit0 m) (num.Bit0 n) = num.Bit0 (or_num m n)\ -| \or_num (num.Bit0 m) (num.Bit1 n) = num.Bit1 (or_num m n)\ -| \or_num (num.Bit1 m) num.One = num.Bit1 m\ -| \or_num (num.Bit1 m) (num.Bit0 n) = num.Bit1 (or_num m n)\ -| \or_num (num.Bit1 m) (num.Bit1 n) = num.Bit1 (or_num m n)\ - -fun or_not_num_neg :: \num \ num \ num\ -where - \or_not_num_neg num.One num.One = num.One\ -| \or_not_num_neg num.One (num.Bit0 m) = num.Bit1 m\ -| \or_not_num_neg num.One (num.Bit1 m) = num.Bit1 m\ -| \or_not_num_neg (num.Bit0 n) num.One = num.Bit0 num.One\ -| \or_not_num_neg (num.Bit0 n) (num.Bit0 m) = Num.BitM (or_not_num_neg n m)\ -| \or_not_num_neg (num.Bit0 n) (num.Bit1 m) = num.Bit0 (or_not_num_neg n m)\ -| \or_not_num_neg (num.Bit1 n) num.One = num.One\ -| \or_not_num_neg (num.Bit1 n) (num.Bit0 m) = Num.BitM (or_not_num_neg n m)\ -| \or_not_num_neg (num.Bit1 n) (num.Bit1 m) = Num.BitM (or_not_num_neg n m)\ - -fun xor_num :: \num \ num \ num option\ -where - \xor_num num.One num.One = None\ -| \xor_num num.One (num.Bit0 n) = Some (num.Bit1 n)\ -| \xor_num num.One (num.Bit1 n) = Some (num.Bit0 n)\ -| \xor_num (num.Bit0 m) num.One = Some (num.Bit1 m)\ -| \xor_num (num.Bit0 m) (num.Bit0 n) = map_option num.Bit0 (xor_num m n)\ -| \xor_num (num.Bit0 m) (num.Bit1 n) = Some (case xor_num m n of None \ num.One | Some n' \ num.Bit1 n')\ -| \xor_num (num.Bit1 m) num.One = Some (num.Bit0 m)\ -| \xor_num (num.Bit1 m) (num.Bit0 n) = Some (case xor_num m n of None \ num.One | Some n' \ num.Bit1 n')\ -| \xor_num (num.Bit1 m) (num.Bit1 n) = map_option num.Bit0 (xor_num m n)\ - -lemma int_numeral_and_num: - \numeral m AND numeral n = (case and_num m n of None \ 0 :: int | Some n' \ numeral n')\ - by (induction m n rule: and_num.induct) (simp_all split: option.split) - -lemma and_num_eq_None_iff: - \and_num m n = None \ numeral m AND numeral n = (0::int)\ - by (simp add: int_numeral_and_num split: option.split) - -lemma and_num_eq_Some_iff: - \and_num m n = Some q \ numeral m AND numeral n = (numeral q :: int)\ - by (simp add: int_numeral_and_num split: option.split) - -lemma int_numeral_and_not_num: - \numeral m AND NOT (numeral n) = (case and_not_num m n of None \ 0 :: int | Some n' \ numeral n')\ - by (induction m n rule: and_not_num.induct) (simp_all add: add_One BitM_inc_eq not_int_def split: option.split) - -lemma int_numeral_not_and_num: - \NOT (numeral m) AND numeral n = (case and_not_num n m of None \ 0 :: int | Some n' \ numeral n')\ - using int_numeral_and_not_num [of n m] by (simp add: ac_simps) - -lemma and_not_num_eq_None_iff: - \and_not_num m n = None \ numeral m AND NOT (numeral n) = (0::int)\ - by (simp add: int_numeral_and_not_num split: option.split) - -lemma and_not_num_eq_Some_iff: - \and_not_num m n = Some q \ numeral m AND NOT (numeral n) = (numeral q :: int)\ - by (simp add: int_numeral_and_not_num split: option.split) - -lemma int_numeral_or_num: - \numeral m OR numeral n = (numeral (or_num m n) :: int)\ - by (induction m n rule: or_num.induct) simp_all - -lemma numeral_or_num_eq: - \numeral (or_num m n) = (numeral m OR numeral n :: int)\ - by (simp add: int_numeral_or_num) - -lemma int_numeral_or_not_num_neg: - \numeral m OR NOT (numeral n :: int) = - numeral (or_not_num_neg m n)\ - by (induction m n rule: or_not_num_neg.induct) (simp_all add: add_One BitM_inc_eq not_int_def) - -lemma int_numeral_not_or_num_neg: - \NOT (numeral m) OR (numeral n :: int) = - numeral (or_not_num_neg n m)\ - using int_numeral_or_not_num_neg [of n m] by (simp add: ac_simps) - -lemma numeral_or_not_num_eq: - \numeral (or_not_num_neg m n) = - (numeral m OR NOT (numeral n :: int))\ - using int_numeral_or_not_num_neg [of m n] by simp - -lemma int_numeral_xor_num: - \numeral m XOR numeral n = (case xor_num m n of None \ 0 :: int | Some n' \ numeral n')\ - by (induction m n rule: xor_num.induct) (simp_all split: option.split) - -lemma xor_num_eq_None_iff: - \xor_num m n = None \ numeral m XOR numeral n = (0::int)\ - by (simp add: int_numeral_xor_num split: option.split) - -lemma xor_num_eq_Some_iff: - \xor_num m n = Some q \ numeral m XOR numeral n = (numeral q :: int)\ - by (simp add: int_numeral_xor_num split: option.split) - - -subsection \Instances for \<^typ>\integer\ and \<^typ>\natural\\ - -unbundle integer.lifting natural.lifting - -instantiation integer :: ring_bit_operations -begin - -lift_definition not_integer :: \integer \ integer\ - is not . - -lift_definition and_integer :: \integer \ integer \ integer\ - is \and\ . - -lift_definition or_integer :: \integer \ integer \ integer\ - is or . - -lift_definition xor_integer :: \integer \ integer \ integer\ - is xor . - -lift_definition mask_integer :: \nat \ integer\ - is mask . - -lift_definition set_bit_integer :: \nat \ integer \ integer\ - is set_bit . - -lift_definition unset_bit_integer :: \nat \ integer \ integer\ - is unset_bit . - -lift_definition flip_bit_integer :: \nat \ integer \ integer\ - is flip_bit . - -instance by (standard; transfer) - (simp_all add: minus_eq_not_minus_1 mask_eq_exp_minus_1 - bit_not_iff bit_and_iff bit_or_iff bit_xor_iff - set_bit_def bit_unset_bit_iff flip_bit_def) - -end - -lemma [code]: - \mask n = 2 ^ n - (1::integer)\ - by (simp add: mask_eq_exp_minus_1) - -instantiation natural :: semiring_bit_operations -begin - -lift_definition and_natural :: \natural \ natural \ natural\ - is \and\ . - -lift_definition or_natural :: \natural \ natural \ natural\ - is or . - -lift_definition xor_natural :: \natural \ natural \ natural\ - is xor . - -lift_definition mask_natural :: \nat \ natural\ - is mask . - -lift_definition set_bit_natural :: \nat \ natural \ natural\ - is set_bit . - -lift_definition unset_bit_natural :: \nat \ natural \ natural\ - is unset_bit . - -lift_definition flip_bit_natural :: \nat \ natural \ natural\ - is flip_bit . - -instance by (standard; transfer) - (simp_all add: mask_eq_exp_minus_1 - bit_and_iff bit_or_iff bit_xor_iff - set_bit_def bit_unset_bit_iff flip_bit_def) - -end - -lemma [code]: - \integer_of_natural (mask n) = mask n\ - by transfer (simp add: mask_eq_exp_minus_1 of_nat_diff) - -lifting_update integer.lifting -lifting_forget integer.lifting - -lifting_update natural.lifting -lifting_forget natural.lifting - - -subsection \Key ideas of bit operations\ - -text \ - When formalizing bit operations, it is tempting to represent - bit values as explicit lists over a binary type. This however - is a bad idea, mainly due to the inherent ambiguities in - representation concerning repeating leading bits. - - Hence this approach avoids such explicit lists altogether - following an algebraic path: - - \<^item> Bit values are represented by numeric types: idealized - unbounded bit values can be represented by type \<^typ>\int\, - bounded bit values by quotient types over \<^typ>\int\. - - \<^item> (A special case are idealized unbounded bit values ending - in @{term [source] 0} which can be represented by type \<^typ>\nat\ but - only support a restricted set of operations). - - \<^item> From this idea follows that - - \<^item> multiplication by \<^term>\2 :: int\ is a bit shift to the left and - - \<^item> division by \<^term>\2 :: int\ is a bit shift to the right. - - \<^item> Concerning bounded bit values, iterated shifts to the left - may result in eliminating all bits by shifting them all - beyond the boundary. The property \<^prop>\(2 :: int) ^ n \ 0\ - represents that \<^term>\n\ is \<^emph>\not\ beyond that boundary. - - \<^item> The projection on a single bit is then @{thm bit_iff_odd [where ?'a = int, no_vars]}. - - \<^item> This leads to the most fundamental properties of bit values: - - \<^item> Equality rule: @{thm bit_eqI [where ?'a = int, no_vars]} - - \<^item> Induction rule: @{thm bits_induct [where ?'a = int, no_vars]} - - \<^item> Typical operations are characterized as follows: - - \<^item> Singleton \<^term>\n\th bit: \<^term>\(2 :: int) ^ n\ - - \<^item> Bit mask upto bit \<^term>\n\: @{thm mask_eq_exp_minus_1 [where ?'a = int, no_vars]} - - \<^item> Left shift: @{thm push_bit_eq_mult [where ?'a = int, no_vars]} - - \<^item> Right shift: @{thm drop_bit_eq_div [where ?'a = int, no_vars]} - - \<^item> Truncation: @{thm take_bit_eq_mod [where ?'a = int, no_vars]} - - \<^item> Negation: @{thm bit_not_iff [where ?'a = int, no_vars]} - - \<^item> And: @{thm bit_and_iff [where ?'a = int, no_vars]} - - \<^item> Or: @{thm bit_or_iff [where ?'a = int, no_vars]} - - \<^item> Xor: @{thm bit_xor_iff [where ?'a = int, no_vars]} - - \<^item> Set a single bit: @{thm set_bit_def [where ?'a = int, no_vars]} - - \<^item> Unset a single bit: @{thm unset_bit_def [where ?'a = int, no_vars]} - - \<^item> Flip a single bit: @{thm flip_bit_def [where ?'a = int, no_vars]} - - \<^item> Signed truncation, or modulus centered around \<^term>\0::int\: @{thm signed_take_bit_def [no_vars]} - - \<^item> Bit concatenation: @{thm concat_bit_def [no_vars]} - - \<^item> (Bounded) conversion from and to a list of bits: @{thm horner_sum_bit_eq_take_bit [where ?'a = int, no_vars]} -\ - -code_identifier - type_class semiring_bits \ - (SML) Bit_Operations.semiring_bits and (OCaml) Bit_Operations.semiring_bits and (Haskell) Bit_Operations.semiring_bits and (Scala) Bit_Operations.semiring_bits -| class_relation semiring_bits < semiring_parity \ - (SML) Bit_Operations.semiring_parity_semiring_bits and (OCaml) Bit_Operations.semiring_parity_semiring_bits and (Haskell) Bit_Operations.semiring_parity_semiring_bits and (Scala) Bit_Operations.semiring_parity_semiring_bits -| constant bit \ - (SML) Bit_Operations.bit and (OCaml) Bit_Operations.bit and (Haskell) Bit_Operations.bit and (Scala) Bit_Operations.bit -| class_instance nat :: semiring_bits \ - (SML) Bit_Operations.semiring_bits_nat and (OCaml) Bit_Operations.semiring_bits_nat and (Haskell) Bit_Operations.semiring_bits_nat and (Scala) Bit_Operations.semiring_bits_nat -| class_instance int :: semiring_bits \ - (SML) Bit_Operations.semiring_bits_int and (OCaml) Bit_Operations.semiring_bits_int and (Haskell) Bit_Operations.semiring_bits_int and (Scala) Bit_Operations.semiring_bits_int -| type_class semiring_bit_shifts \ - (SML) Bit_Operations.semiring_bit_shifts and (OCaml) Bit_Operations.semiring_bit_shifts and (Haskell) Bit_Operations.semiring_bits and (Scala) Bit_Operations.semiring_bit_shifts -| class_relation semiring_bit_shifts < semiring_bits \ - (SML) Bit_Operations.semiring_bits_semiring_bit_shifts and (OCaml) Bit_Operations.semiring_bits_semiring_bit_shifts and (Haskell) Bit_Operations.semiring_bits_semiring_bit_shifts and (Scala) Bit_Operations.semiring_bits_semiring_bit_shifts -| constant push_bit \ - (SML) Bit_Operations.push_bit and (OCaml) Bit_Operations.push_bit and (Haskell) Bit_Operations.push_bit and (Scala) Bit_Operations.push_bit -| constant drop_bit \ - (SML) Bit_Operations.drop_bit and (OCaml) Bit_Operations.drop_bit and (Haskell) Bit_Operations.drop_bit and (Scala) Bit_Operations.drop_bit -| constant take_bit \ - (SML) Bit_Operations.take_bit and (OCaml) Bit_Operations.take_bit and (Haskell) Bit_Operations.take_bit and (Scala) Bit_Operations.take_bit -| class_instance nat :: semiring_bit_shifts \ - (SML) Bit_Operations.semiring_bit_shifts and (OCaml) Bit_Operations.semiring_bit_shifts and (Haskell) Bit_Operations.semiring_bit_shifts and (Scala) Bit_Operations.semiring_bit_shifts -| class_instance int :: semiring_bit_shifts \ - (SML) Bit_Operations.semiring_bit_shifts and (OCaml) Bit_Operations.semiring_bit_shifts and (Haskell) Bit_Operations.semiring_bit_shifts and (Scala) Bit_Operations.semiring_bit_shifts - -no_notation - "and" (infixr \AND\ 64) - and or (infixr \OR\ 59) - and xor (infixr \XOR\ 59) - -bundle bit_operations_syntax -begin - -notation - "and" (infixr \AND\ 64) - and or (infixr \OR\ 59) - and xor (infixr \XOR\ 59) - -end - -end diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Library/Boolean_Algebra.thy --- a/src/HOL/Library/Boolean_Algebra.thy Sun Aug 01 23:18:13 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,286 +0,0 @@ -(* Title: HOL/Library/Boolean_Algebra.thy - Author: Brian Huffman -*) - -section \Boolean Algebras\ - -theory Boolean_Algebra - imports Main -begin - -locale boolean_algebra = conj: abel_semigroup "(\<^bold>\)" + disj: abel_semigroup "(\<^bold>\)" - for conj :: "'a \ 'a \ 'a" (infixr "\<^bold>\" 70) - and disj :: "'a \ 'a \ 'a" (infixr "\<^bold>\" 65) + - fixes compl :: "'a \ 'a" ("\ _" [81] 80) - and zero :: "'a" ("\") - and one :: "'a" ("\") - assumes conj_disj_distrib: "x \<^bold>\ (y \<^bold>\ z) = (x \<^bold>\ y) \<^bold>\ (x \<^bold>\ z)" - and disj_conj_distrib: "x \<^bold>\ (y \<^bold>\ z) = (x \<^bold>\ y) \<^bold>\ (x \<^bold>\ z)" - and conj_one_right: "x \<^bold>\ \ = x" - and disj_zero_right: "x \<^bold>\ \ = x" - and conj_cancel_right [simp]: "x \<^bold>\ \ x = \" - and disj_cancel_right [simp]: "x \<^bold>\ \ x = \" -begin - -sublocale conj: semilattice_neutr "(\<^bold>\)" "\" -proof - show "x \<^bold>\ \ = x" for x - by (fact conj_one_right) - show "x \<^bold>\ x = x" for x - proof - - have "x \<^bold>\ x = (x \<^bold>\ x) \<^bold>\ \" - by (simp add: disj_zero_right) - also have "\ = (x \<^bold>\ x) \<^bold>\ (x \<^bold>\ \ x)" - by simp - also have "\ = x \<^bold>\ (x \<^bold>\ \ x)" - by (simp only: conj_disj_distrib) - also have "\ = x \<^bold>\ \" - by simp - also have "\ = x" - by (simp add: conj_one_right) - finally show ?thesis . - qed -qed - -sublocale disj: semilattice_neutr "(\<^bold>\)" "\" -proof - show "x \<^bold>\ \ = x" for x - by (fact disj_zero_right) - show "x \<^bold>\ x = x" for x - proof - - have "x \<^bold>\ x = (x \<^bold>\ x) \<^bold>\ \" - by simp - also have "\ = (x \<^bold>\ x) \<^bold>\ (x \<^bold>\ \ x)" - by simp - also have "\ = x \<^bold>\ (x \<^bold>\ \ x)" - by (simp only: disj_conj_distrib) - also have "\ = x \<^bold>\ \" - by simp - also have "\ = x" - by (simp add: disj_zero_right) - finally show ?thesis . - qed -qed - - -subsection \Complement\ - -lemma complement_unique: - assumes 1: "a \<^bold>\ x = \" - assumes 2: "a \<^bold>\ x = \" - assumes 3: "a \<^bold>\ y = \" - assumes 4: "a \<^bold>\ y = \" - shows "x = y" -proof - - from 1 3 have "(a \<^bold>\ x) \<^bold>\ (x \<^bold>\ y) = (a \<^bold>\ y) \<^bold>\ (x \<^bold>\ y)" - by simp - then have "(x \<^bold>\ a) \<^bold>\ (x \<^bold>\ y) = (y \<^bold>\ a) \<^bold>\ (y \<^bold>\ x)" - by (simp add: ac_simps) - then have "x \<^bold>\ (a \<^bold>\ y) = y \<^bold>\ (a \<^bold>\ x)" - by (simp add: conj_disj_distrib) - with 2 4 have "x \<^bold>\ \ = y \<^bold>\ \" - by simp - then show "x = y" - by simp -qed - -lemma compl_unique: "x \<^bold>\ y = \ \ x \<^bold>\ y = \ \ \ x = y" - by (rule complement_unique [OF conj_cancel_right disj_cancel_right]) - -lemma double_compl [simp]: "\ (\ x) = x" -proof (rule compl_unique) - show "\ x \<^bold>\ x = \" - by (simp only: conj_cancel_right conj.commute) - show "\ x \<^bold>\ x = \" - by (simp only: disj_cancel_right disj.commute) -qed - -lemma compl_eq_compl_iff [simp]: "\ x = \ y \ x = y" - by (rule inj_eq [OF inj_on_inverseI]) (rule double_compl) - - -subsection \Conjunction\ - -lemma conj_zero_right [simp]: "x \<^bold>\ \ = \" - using conj.left_idem conj_cancel_right by fastforce - -lemma compl_one [simp]: "\ \ = \" - by (rule compl_unique [OF conj_zero_right disj_zero_right]) - -lemma conj_zero_left [simp]: "\ \<^bold>\ x = \" - by (subst conj.commute) (rule conj_zero_right) - -lemma conj_cancel_left [simp]: "\ x \<^bold>\ x = \" - by (subst conj.commute) (rule conj_cancel_right) - -lemma conj_disj_distrib2: "(y \<^bold>\ z) \<^bold>\ x = (y \<^bold>\ x) \<^bold>\ (z \<^bold>\ x)" - by (simp only: conj.commute conj_disj_distrib) - -lemmas conj_disj_distribs = conj_disj_distrib conj_disj_distrib2 - -lemma conj_assoc: "(x \<^bold>\ y) \<^bold>\ z = x \<^bold>\ (y \<^bold>\ z)" - by (fact ac_simps) - -lemma conj_commute: "x \<^bold>\ y = y \<^bold>\ x" - by (fact ac_simps) - -lemmas conj_left_commute = conj.left_commute -lemmas conj_ac = conj.assoc conj.commute conj.left_commute - -lemma conj_one_left: "\ \<^bold>\ x = x" - by (fact conj.left_neutral) - -lemma conj_left_absorb: "x \<^bold>\ (x \<^bold>\ y) = x \<^bold>\ y" - by (fact conj.left_idem) - -lemma conj_absorb: "x \<^bold>\ x = x" - by (fact conj.idem) - - -subsection \Disjunction\ - -interpretation dual: boolean_algebra "(\<^bold>\)" "(\<^bold>\)" compl \ \ - apply standard - apply (rule disj_conj_distrib) - apply (rule conj_disj_distrib) - apply simp_all - done - -lemma compl_zero [simp]: "\ \ = \" - by (fact dual.compl_one) - -lemma disj_one_right [simp]: "x \<^bold>\ \ = \" - by (fact dual.conj_zero_right) - -lemma disj_one_left [simp]: "\ \<^bold>\ x = \" - by (fact dual.conj_zero_left) - -lemma disj_cancel_left [simp]: "\ x \<^bold>\ x = \" - by (rule dual.conj_cancel_left) - -lemma disj_conj_distrib2: "(y \<^bold>\ z) \<^bold>\ x = (y \<^bold>\ x) \<^bold>\ (z \<^bold>\ x)" - by (rule dual.conj_disj_distrib2) - -lemmas disj_conj_distribs = disj_conj_distrib disj_conj_distrib2 - -lemma disj_assoc: "(x \<^bold>\ y) \<^bold>\ z = x \<^bold>\ (y \<^bold>\ z)" - by (fact ac_simps) - -lemma disj_commute: "x \<^bold>\ y = y \<^bold>\ x" - by (fact ac_simps) - -lemmas disj_left_commute = disj.left_commute - -lemmas disj_ac = disj.assoc disj.commute disj.left_commute - -lemma disj_zero_left: "\ \<^bold>\ x = x" - by (fact disj.left_neutral) - -lemma disj_left_absorb: "x \<^bold>\ (x \<^bold>\ y) = x \<^bold>\ y" - by (fact disj.left_idem) - -lemma disj_absorb: "x \<^bold>\ x = x" - by (fact disj.idem) - - -subsection \De Morgan's Laws\ - -lemma de_Morgan_conj [simp]: "\ (x \<^bold>\ y) = \ x \<^bold>\ \ y" -proof (rule compl_unique) - have "(x \<^bold>\ y) \<^bold>\ (\ x \<^bold>\ \ y) = ((x \<^bold>\ y) \<^bold>\ \ x) \<^bold>\ ((x \<^bold>\ y) \<^bold>\ \ y)" - by (rule conj_disj_distrib) - also have "\ = (y \<^bold>\ (x \<^bold>\ \ x)) \<^bold>\ (x \<^bold>\ (y \<^bold>\ \ y))" - by (simp only: conj_ac) - finally show "(x \<^bold>\ y) \<^bold>\ (\ x \<^bold>\ \ y) = \" - by (simp only: conj_cancel_right conj_zero_right disj_zero_right) -next - have "(x \<^bold>\ y) \<^bold>\ (\ x \<^bold>\ \ y) = (x \<^bold>\ (\ x \<^bold>\ \ y)) \<^bold>\ (y \<^bold>\ (\ x \<^bold>\ \ y))" - by (rule disj_conj_distrib2) - also have "\ = (\ y \<^bold>\ (x \<^bold>\ \ x)) \<^bold>\ (\ x \<^bold>\ (y \<^bold>\ \ y))" - by (simp only: disj_ac) - finally show "(x \<^bold>\ y) \<^bold>\ (\ x \<^bold>\ \ y) = \" - by (simp only: disj_cancel_right disj_one_right conj_one_right) -qed - -lemma de_Morgan_disj [simp]: "\ (x \<^bold>\ y) = \ x \<^bold>\ \ y" - using dual.boolean_algebra_axioms by (rule boolean_algebra.de_Morgan_conj) - - -subsection \Symmetric Difference\ - -definition xor :: "'a \ 'a \ 'a" (infixr "\" 65) - where "x \ y = (x \<^bold>\ \ y) \<^bold>\ (\ x \<^bold>\ y)" - -sublocale xor: comm_monoid xor \ -proof - fix x y z :: 'a - let ?t = "(x \<^bold>\ y \<^bold>\ z) \<^bold>\ (x \<^bold>\ \ y \<^bold>\ \ z) \<^bold>\ (\ x \<^bold>\ y \<^bold>\ \ z) \<^bold>\ (\ x \<^bold>\ \ y \<^bold>\ z)" - have "?t \<^bold>\ (z \<^bold>\ x \<^bold>\ \ x) \<^bold>\ (z \<^bold>\ y \<^bold>\ \ y) = ?t \<^bold>\ (x \<^bold>\ y \<^bold>\ \ y) \<^bold>\ (x \<^bold>\ z \<^bold>\ \ z)" - by (simp only: conj_cancel_right conj_zero_right) - then show "(x \ y) \ z = x \ (y \ z)" - by (simp only: xor_def de_Morgan_disj de_Morgan_conj double_compl) - (simp only: conj_disj_distribs conj_ac disj_ac) - show "x \ y = y \ x" - by (simp only: xor_def conj_commute disj_commute) - show "x \ \ = x" - by (simp add: xor_def) -qed - -lemmas xor_assoc = xor.assoc -lemmas xor_commute = xor.commute -lemmas xor_left_commute = xor.left_commute - -lemmas xor_ac = xor.assoc xor.commute xor.left_commute - -lemma xor_def2: "x \ y = (x \<^bold>\ y) \<^bold>\ (\ x \<^bold>\ \ y)" - using conj.commute conj_disj_distrib2 disj.commute xor_def by auto - -lemma xor_zero_right [simp]: "x \ \ = x" - by (simp only: xor_def compl_zero conj_one_right conj_zero_right disj_zero_right) - -lemma xor_zero_left [simp]: "\ \ x = x" - by (subst xor_commute) (rule xor_zero_right) - -lemma xor_one_right [simp]: "x \ \ = \ x" - by (simp only: xor_def compl_one conj_zero_right conj_one_right disj_zero_left) - -lemma xor_one_left [simp]: "\ \ x = \ x" - by (subst xor_commute) (rule xor_one_right) - -lemma xor_self [simp]: "x \ x = \" - by (simp only: xor_def conj_cancel_right conj_cancel_left disj_zero_right) - -lemma xor_left_self [simp]: "x \ (x \ y) = y" - by (simp only: xor_assoc [symmetric] xor_self xor_zero_left) - -lemma xor_compl_left [simp]: "\ x \ y = \ (x \ y)" - by (metis xor_assoc xor_one_left) - -lemma xor_compl_right [simp]: "x \ \ y = \ (x \ y)" - using xor_commute xor_compl_left by auto - -lemma xor_cancel_right: "x \ \ x = \" - by (simp only: xor_compl_right xor_self compl_zero) - -lemma xor_cancel_left: "\ x \ x = \" - by (simp only: xor_compl_left xor_self compl_zero) - -lemma conj_xor_distrib: "x \<^bold>\ (y \ z) = (x \<^bold>\ y) \ (x \<^bold>\ z)" -proof - - have *: "(x \<^bold>\ y \<^bold>\ \ z) \<^bold>\ (x \<^bold>\ \ y \<^bold>\ z) = - (y \<^bold>\ x \<^bold>\ \ x) \<^bold>\ (z \<^bold>\ x \<^bold>\ \ x) \<^bold>\ (x \<^bold>\ y \<^bold>\ \ z) \<^bold>\ (x \<^bold>\ \ y \<^bold>\ z)" - by (simp only: conj_cancel_right conj_zero_right disj_zero_left) - then show "x \<^bold>\ (y \ z) = (x \<^bold>\ y) \ (x \<^bold>\ z)" - by (simp (no_asm_use) only: - xor_def de_Morgan_disj de_Morgan_conj double_compl - conj_disj_distribs conj_ac disj_ac) -qed - -lemma conj_xor_distrib2: "(y \ z) \<^bold>\ x = (y \<^bold>\ x) \ (z \<^bold>\ x)" - by (simp add: conj.commute conj_xor_distrib) - -lemmas conj_xor_distribs = conj_xor_distrib conj_xor_distrib2 - -end - -end diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Library/Library.thy --- a/src/HOL/Library/Library.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/Library/Library.thy Mon Aug 02 10:01:06 2021 +0000 @@ -4,10 +4,8 @@ AList Adhoc_Overloading BigO - Bit_Operations BNF_Axiomatization BNF_Corec - Boolean_Algebra Bourbaki_Witt_Fixpoint Char_ord Code_Cardinality diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Library/Linear_Temporal_Logic_on_Streams.thy --- a/src/HOL/Library/Linear_Temporal_Logic_on_Streams.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/Library/Linear_Temporal_Logic_on_Streams.thy Mon Aug 02 10:01:06 2021 +0000 @@ -39,7 +39,7 @@ abbreviation (input) AND (infix "aand" 60) where "\ aand \ \ \ xs. \ xs \ \ xs" -abbreviation (input) "not \ \ \ xs. \ \ xs" +abbreviation (input) not where "not \ \ \ xs. \ \ xs" abbreviation (input) "true \ \ xs. True" diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Library/Word.thy --- a/src/HOL/Library/Word.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/Library/Word.thy Mon Aug 02 10:01:06 2021 +0000 @@ -7,8 +7,6 @@ theory Word imports "HOL-Library.Type_Length" - "HOL-Library.Boolean_Algebra" - "HOL-Library.Bit_Operations" begin subsection \Preliminaries\ @@ -1131,18 +1129,18 @@ with \2 ^ m \ 0\ have \2 ^ (m - n) \ 0\ by (metis (full_types) diff_add exp_add_not_zero_imp) with True show ?thesis - by (simp add: bit_unsigned_iff bit_push_bit_iff Parity.bit_push_bit_iff bit_take_bit_iff not_le exp_eq_zero_iff ac_simps) + by (simp add: bit_unsigned_iff bit_push_bit_iff Bit_Operations.bit_push_bit_iff bit_take_bit_iff not_le ac_simps) next case False then show ?thesis - by (simp add: not_le bit_unsigned_iff bit_push_bit_iff Parity.bit_push_bit_iff bit_take_bit_iff) + by (simp add: not_le bit_unsigned_iff bit_push_bit_iff Bit_Operations.bit_push_bit_iff bit_take_bit_iff) qed qed lemma unsigned_take_bit_eq: \unsigned (take_bit n w) = take_bit n (unsigned w)\ for w :: \'b::len word\ - by (rule bit_eqI) (simp add: bit_unsigned_iff bit_take_bit_iff Parity.bit_take_bit_iff) + by (rule bit_eqI) (simp add: bit_unsigned_iff bit_take_bit_iff Bit_Operations.bit_take_bit_iff) end @@ -1152,7 +1150,7 @@ lemma unsigned_drop_bit_eq: \unsigned (drop_bit n w) = drop_bit n (take_bit LENGTH('b) (unsigned w))\ for w :: \'b::len word\ - by (rule bit_eqI) (auto simp add: bit_unsigned_iff bit_take_bit_iff bit_drop_bit_eq Parity.bit_drop_bit_eq dest: bit_imp_le_length) + by (rule bit_eqI) (auto simp add: bit_unsigned_iff bit_take_bit_iff bit_drop_bit_eq Bit_Operations.bit_drop_bit_eq dest: bit_imp_le_length) end @@ -1198,7 +1196,7 @@ \unsigned (NOT w) = take_bit LENGTH('b) (NOT (unsigned w))\ for w :: \'b::len word\ by (rule bit_eqI) - (simp add: bit_unsigned_iff bit_take_bit_iff bit_not_iff Bit_Operations.bit_not_iff exp_eq_zero_iff not_le) + (simp add: bit_unsigned_iff bit_take_bit_iff bit_not_iff Bit_Operations.bit_not_iff not_le) end @@ -1264,15 +1262,14 @@ moreover from \2 ^ q \ 0\ have \2 ^ (q - n) \ 0\ by (rule exp_not_zero_imp_exp_diff_not_zero) ultimately show ?thesis - by (auto simp add: bit_signed_iff bit_signed_take_bit_iff bit_push_bit_iff Parity.bit_push_bit_iff - min_def * exp_eq_zero_iff le_diff_conv2) + by (auto simp add: bit_signed_iff bit_signed_take_bit_iff bit_push_bit_iff Bit_Operations.bit_push_bit_iff + min_def * le_diff_conv2) next case False then show ?thesis using exp_not_zero_imp_exp_diff_not_zero [of m n] - by (auto simp add: bit_signed_iff bit_signed_take_bit_iff bit_push_bit_iff Parity.bit_push_bit_iff - min_def not_le not_less * le_diff_conv2 less_diff_conv2 Parity.exp_eq_0_imp_not_bit exp_eq_0_imp_not_bit - exp_eq_zero_iff) + by (auto simp add: bit_signed_iff bit_signed_take_bit_iff bit_push_bit_iff Bit_Operations.bit_push_bit_iff + min_def not_le not_less * le_diff_conv2 less_diff_conv2 Bit_Operations.exp_eq_0_imp_not_bit exp_eq_0_imp_not_bit) qed qed @@ -1302,13 +1299,11 @@ have \2 ^ Suc q \ 0\ using exp_add_not_zero_imp_right by blast ultimately show ?thesis - by (simp add: * bit_signed_iff bit_not_iff bit_signed_take_bit_iff Bit_Operations.bit_not_iff min_def - exp_eq_zero_iff) + by (simp add: * bit_signed_iff bit_not_iff bit_signed_take_bit_iff Bit_Operations.bit_not_iff min_def) next case False then show ?thesis - by (auto simp add: * bit_signed_iff bit_not_iff bit_signed_take_bit_iff Bit_Operations.bit_not_iff min_def - exp_eq_zero_iff) + by (auto simp add: * bit_signed_iff bit_not_iff bit_signed_take_bit_iff Bit_Operations.bit_not_iff min_def) qed qed @@ -1411,7 +1406,7 @@ lemma unsigned_ucast_eq: \unsigned (ucast w :: 'c::len word) = take_bit LENGTH('c) (unsigned w)\ for w :: \'b::len word\ - by (rule bit_eqI) (simp add: bit_unsigned_iff Word.bit_unsigned_iff bit_take_bit_iff exp_eq_zero_iff not_le) + by (rule bit_eqI) (simp add: bit_unsigned_iff Word.bit_unsigned_iff bit_take_bit_iff not_le) end @@ -1428,7 +1423,7 @@ by (simp add: min_def) (metis (mono_tags) diff_diff_cancel exp_not_zero_imp_exp_diff_not_zero) then show \bit (signed (ucast w :: 'c::len word)) n \ bit (signed_take_bit (LENGTH('c) - Suc 0) (unsigned w)) n\ - by (simp add: bit_signed_iff bit_unsigned_iff Word.bit_unsigned_iff bit_signed_take_bit_iff exp_eq_zero_iff not_le) + by (simp add: bit_signed_iff bit_unsigned_iff Word.bit_unsigned_iff bit_signed_take_bit_iff not_le) qed lemma signed_scast_eq: @@ -1441,7 +1436,7 @@ by (simp add: min_def) (metis (mono_tags) diff_diff_cancel exp_not_zero_imp_exp_diff_not_zero) then show \bit (signed (scast w :: 'c::len word)) n \ bit (signed_take_bit (LENGTH('c) - Suc 0) (signed w)) n\ - by (simp add: bit_signed_iff bit_unsigned_iff Word.bit_signed_iff bit_signed_take_bit_iff exp_eq_zero_iff not_le) + by (simp add: bit_signed_iff bit_unsigned_iff Word.bit_signed_iff bit_signed_take_bit_iff not_le) qed end @@ -2104,8 +2099,7 @@ (drop_bit (n mod LENGTH('a)) (uint w)) (uint (take_bit (n mod LENGTH('a)) w))\ for w :: \'a::len word\ - apply transfer - by (simp add: min.absorb2 take_bit_concat_bit_eq) + by transfer (simp add: take_bit_concat_bit_eq) lemma [code]: \Word.the_int (word_rotr n w) = concat_bit (LENGTH('a) - n mod LENGTH('a)) @@ -2347,7 +2341,7 @@ \ lemma bit_ucast_iff: - \bit (ucast a :: 'a::len word) n \ n < LENGTH('a::len) \ Parity.bit a n\ + \bit (ucast a :: 'a::len word) n \ n < LENGTH('a::len) \ bit a n\ by transfer (simp add: bit_take_bit_iff) lemma ucast_id [simp]: "ucast w = w" @@ -2358,7 +2352,7 @@ lemma ucast_mask_eq: \ucast (mask n :: 'b word) = mask (min LENGTH('b::len) n)\ - by (simp add: bit_eq_iff) (auto simp add: bit_mask_iff bit_ucast_iff exp_eq_zero_iff) + by (simp add: bit_eq_iff) (auto simp add: bit_mask_iff bit_ucast_iff) \ \literal u(s)cast\ lemma ucast_bintr [simp]: @@ -2491,7 +2485,7 @@ then show ?thesis apply transfer apply (simp add: take_bit_drop_bit) - by (simp add: bit_iff_odd_drop_bit drop_bit_take_bit min.absorb2 odd_iff_mod_2_eq_one) + by (simp add: bit_iff_odd_drop_bit drop_bit_take_bit odd_iff_mod_2_eq_one) qed auto @@ -3623,7 +3617,7 @@ lemma minus_1_eq_mask: \- 1 = (mask LENGTH('a) :: 'a::len word)\ - by (rule bit_eqI) (simp add: bit_exp_iff bit_mask_iff exp_eq_zero_iff) + by (rule bit_eqI) (simp add: bit_exp_iff bit_mask_iff) lemma mask_eq_decr_exp: \mask n = 2 ^ n - (1 :: 'a::len word)\ @@ -3638,7 +3632,7 @@ qualified lemma bit_mask_iff [bit_simps]: \bit (mask m :: 'a::len word) n \ n < min LENGTH('a) m\ - by (simp add: bit_mask_iff exp_eq_zero_iff not_le) + by (simp add: bit_mask_iff not_le) end @@ -4218,10 +4212,10 @@ by (metis add.commute diff_add_cancel word_rec_Suc) lemma word_rec_in: "f (word_rec z (\_. f) n) = word_rec (f z) (\_. f) n" - by (induct n) (simp_all add: word_rec_Suc) + by (induct n) simp_all lemma word_rec_in2: "f n (word_rec z f n) = word_rec (f 0 z) (f \ (+) 1) n" - by (induct n) (simp_all add: word_rec_Suc) + by (induct n) simp_all lemma word_rec_twice: "m \ n \ word_rec z f n = word_rec (word_rec z f (n - m)) (f \ (+) (n - m)) m" diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Library/Z2.thy --- a/src/HOL/Library/Z2.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/Library/Z2.thy Mon Aug 02 10:01:06 2021 +0000 @@ -5,11 +5,11 @@ section \The Field of Integers mod 2\ theory Z2 -imports Main "HOL-Library.Bit_Operations" +imports Main begin text \ - Note that in most cases \<^typ>\bool\ is appropriate hen a binary type is needed; the + Note that in most cases \<^typ>\bool\ is appropriate when a binary type is needed; the type provided here, for historical reasons named \<^text>\bit\, is only needed if proper field operations are required. \ diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/List.thy --- a/src/HOL/List.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/List.thy Mon Aug 02 10:01:06 2021 +0000 @@ -5,7 +5,7 @@ section \The datatype of finite lists\ theory List -imports Sledgehammer Code_Numeral Lifting_Set +imports Sledgehammer Lifting_Set begin datatype (set: 'a) list = diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Main.thy --- a/src/HOL/Main.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/Main.thy Mon Aug 02 10:01:06 2021 +0000 @@ -71,4 +71,6 @@ "_SUP1" :: "pttrns \ 'b \ 'b" ("(3\_./ _)" [0, 10] 10) "_SUP" :: "pttrn \ 'a set \ 'b \ 'b" ("(3\_\_./ _)" [0, 0, 10] 10) +thy_deps + end diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Nominal/Examples/Class1.thy --- a/src/HOL/Nominal/Examples/Class1.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/Nominal/Examples/Class1.thy Mon Aug 02 10:01:06 2021 +0000 @@ -8,6 +8,8 @@ text \types\ +no_notation not ("NOT") + nominal_datatype ty = PR "string" | NOT "ty" diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Numeral_Simprocs.thy --- a/src/HOL/Numeral_Simprocs.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/Numeral_Simprocs.thy Mon Aug 02 10:01:06 2021 +0000 @@ -299,14 +299,4 @@ Numeral_Simprocs.field_divide_cancel_numeral_factor]) \ -lemma bit_numeral_int_simps [simp]: - \bit (1 :: int) (numeral n) \ bit (0 :: int) (pred_numeral n)\ - \bit (numeral (num.Bit0 w) :: int) (numeral n) \ bit (numeral w :: int) (pred_numeral n)\ - \bit (numeral (num.Bit1 w) :: int) (numeral n) \ bit (numeral w :: int) (pred_numeral n)\ - \bit (numeral (Num.BitM w) :: int) (numeral n) \ \ bit (- numeral w :: int) (pred_numeral n)\ - \bit (- numeral (num.Bit0 w) :: int) (numeral n) \ bit (- numeral w :: int) (pred_numeral n)\ - \bit (- numeral (num.Bit1 w) :: int) (numeral n) \ \ bit (numeral w :: int) (pred_numeral n)\ - \bit (- numeral (Num.BitM w) :: int) (numeral n) \ bit (- (numeral w) :: int) (pred_numeral n)\ - by (simp_all add: bit_1_iff numeral_eq_Suc bit_Suc add_One sub_inc_One_eq bit_minus_int_iff) - end diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Parity.thy --- a/src/HOL/Parity.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/Parity.thy Mon Aug 02 10:01:06 2021 +0000 @@ -699,1333 +699,6 @@ end - -subsection \Abstract bit structures\ - -class semiring_bits = semiring_parity + - assumes bits_induct [case_names stable rec]: - \(\a. a div 2 = a \ P a) - \ (\a b. P a \ (of_bool b + 2 * a) div 2 = a \ P (of_bool b + 2 * a)) - \ P a\ - assumes bits_div_0 [simp]: \0 div a = 0\ - and bits_div_by_1 [simp]: \a div 1 = a\ - and bits_mod_div_trivial [simp]: \a mod b div b = 0\ - and even_succ_div_2 [simp]: \even a \ (1 + a) div 2 = a div 2\ - and even_mask_div_iff: \even ((2 ^ m - 1) div 2 ^ n) \ 2 ^ n = 0 \ m \ n\ - and exp_div_exp_eq: \2 ^ m div 2 ^ n = of_bool (2 ^ m \ 0 \ m \ n) * 2 ^ (m - n)\ - and div_exp_eq: \a div 2 ^ m div 2 ^ n = a div 2 ^ (m + n)\ - and mod_exp_eq: \a mod 2 ^ m mod 2 ^ n = a mod 2 ^ min m n\ - and mult_exp_mod_exp_eq: \m \ n \ (a * 2 ^ m) mod (2 ^ n) = (a mod 2 ^ (n - m)) * 2 ^ m\ - and div_exp_mod_exp_eq: \a div 2 ^ n mod 2 ^ m = a mod (2 ^ (n + m)) div 2 ^ n\ - and even_mult_exp_div_exp_iff: \even (a * 2 ^ m div 2 ^ n) \ m > n \ 2 ^ n = 0 \ (m \ n \ even (a div 2 ^ (n - m)))\ - fixes bit :: \'a \ nat \ bool\ - assumes bit_iff_odd: \bit a n \ odd (a div 2 ^ n)\ -begin - -text \ - Having \<^const>\bit\ as definitional class operation - takes into account that specific instances can be implemented - differently wrt. code generation. -\ - -lemma bits_div_by_0 [simp]: - \a div 0 = 0\ - by (metis add_cancel_right_right bits_mod_div_trivial mod_mult_div_eq mult_not_zero) - -lemma bits_1_div_2 [simp]: - \1 div 2 = 0\ - using even_succ_div_2 [of 0] by simp - -lemma bits_1_div_exp [simp]: - \1 div 2 ^ n = of_bool (n = 0)\ - using div_exp_eq [of 1 1] by (cases n) simp_all - -lemma even_succ_div_exp [simp]: - \(1 + a) div 2 ^ n = a div 2 ^ n\ if \even a\ and \n > 0\ -proof (cases n) - case 0 - with that show ?thesis - by simp -next - case (Suc n) - with \even a\ have \(1 + a) div 2 ^ Suc n = a div 2 ^ Suc n\ - proof (induction n) - case 0 - then show ?case - by simp - next - case (Suc n) - then show ?case - using div_exp_eq [of _ 1 \Suc n\, symmetric] - by simp - qed - with Suc show ?thesis - by simp -qed - -lemma even_succ_mod_exp [simp]: - \(1 + a) mod 2 ^ n = 1 + (a mod 2 ^ n)\ if \even a\ and \n > 0\ - using div_mult_mod_eq [of \1 + a\ \2 ^ n\] that - apply simp - by (metis local.add.left_commute local.add_left_cancel local.div_mult_mod_eq) - -lemma bits_mod_by_1 [simp]: - \a mod 1 = 0\ - using div_mult_mod_eq [of a 1] by simp - -lemma bits_mod_0 [simp]: - \0 mod a = 0\ - using div_mult_mod_eq [of 0 a] by simp - -lemma bits_one_mod_two_eq_one [simp]: - \1 mod 2 = 1\ - by (simp add: mod2_eq_if) - -lemma bit_0 [simp]: - \bit a 0 \ odd a\ - by (simp add: bit_iff_odd) - -lemma bit_Suc: - \bit a (Suc n) \ bit (a div 2) n\ - using div_exp_eq [of a 1 n] by (simp add: bit_iff_odd) - -lemma bit_rec: - \bit a n \ (if n = 0 then odd a else bit (a div 2) (n - 1))\ - by (cases n) (simp_all add: bit_Suc) - -lemma bit_0_eq [simp]: - \bit 0 = bot\ - by (simp add: fun_eq_iff bit_iff_odd) - -context - fixes a - assumes stable: \a div 2 = a\ -begin - -lemma bits_stable_imp_add_self: - \a + a mod 2 = 0\ -proof - - have \a div 2 * 2 + a mod 2 = a\ - by (fact div_mult_mod_eq) - then have \a * 2 + a mod 2 = a\ - by (simp add: stable) - then show ?thesis - by (simp add: mult_2_right ac_simps) -qed - -lemma stable_imp_bit_iff_odd: - \bit a n \ odd a\ - by (induction n) (simp_all add: stable bit_Suc) - -end - -lemma bit_iff_idd_imp_stable: - \a div 2 = a\ if \\n. bit a n \ odd a\ -using that proof (induction a rule: bits_induct) - case (stable a) - then show ?case - by simp -next - case (rec a b) - from rec.prems [of 1] have [simp]: \b = odd a\ - by (simp add: rec.hyps bit_Suc) - from rec.hyps have hyp: \(of_bool (odd a) + 2 * a) div 2 = a\ - by simp - have \bit a n \ odd a\ for n - using rec.prems [of \Suc n\] by (simp add: hyp bit_Suc) - then have \a div 2 = a\ - by (rule rec.IH) - then have \of_bool (odd a) + 2 * a = 2 * (a div 2) + of_bool (odd a)\ - by (simp add: ac_simps) - also have \\ = a\ - using mult_div_mod_eq [of 2 a] - by (simp add: of_bool_odd_eq_mod_2) - finally show ?case - using \a div 2 = a\ by (simp add: hyp) -qed - -lemma exp_eq_0_imp_not_bit: - \\ bit a n\ if \2 ^ n = 0\ - using that by (simp add: bit_iff_odd) - -lemma bit_eqI: - \a = b\ if \\n. 2 ^ n \ 0 \ bit a n \ bit b n\ -proof - - have \bit a n \ bit b n\ for n - proof (cases \2 ^ n = 0\) - case True - then show ?thesis - by (simp add: exp_eq_0_imp_not_bit) - next - case False - then show ?thesis - by (rule that) - qed - then show ?thesis proof (induction a arbitrary: b rule: bits_induct) - case (stable a) - from stable(2) [of 0] have **: \even b \ even a\ - by simp - have \b div 2 = b\ - proof (rule bit_iff_idd_imp_stable) - fix n - from stable have *: \bit b n \ bit a n\ - by simp - also have \bit a n \ odd a\ - using stable by (simp add: stable_imp_bit_iff_odd) - finally show \bit b n \ odd b\ - by (simp add: **) - qed - from ** have \a mod 2 = b mod 2\ - by (simp add: mod2_eq_if) - then have \a mod 2 + (a + b) = b mod 2 + (a + b)\ - by simp - then have \a + a mod 2 + b = b + b mod 2 + a\ - by (simp add: ac_simps) - with \a div 2 = a\ \b div 2 = b\ show ?case - by (simp add: bits_stable_imp_add_self) - next - case (rec a p) - from rec.prems [of 0] have [simp]: \p = odd b\ - by simp - from rec.hyps have \bit a n \ bit (b div 2) n\ for n - using rec.prems [of \Suc n\] by (simp add: bit_Suc) - then have \a = b div 2\ - by (rule rec.IH) - then have \2 * a = 2 * (b div 2)\ - by simp - then have \b mod 2 + 2 * a = b mod 2 + 2 * (b div 2)\ - by simp - also have \\ = b\ - by (fact mod_mult_div_eq) - finally show ?case - by (auto simp add: mod2_eq_if) - qed -qed - -lemma bit_eq_iff: - \a = b \ (\n. bit a n \ bit b n)\ - by (auto intro: bit_eqI) - -named_theorems bit_simps \Simplification rules for \<^const>\bit\\ - -lemma bit_exp_iff [bit_simps]: - \bit (2 ^ m) n \ 2 ^ m \ 0 \ m = n\ - by (auto simp add: bit_iff_odd exp_div_exp_eq) - -lemma bit_1_iff [bit_simps]: - \bit 1 n \ 1 \ 0 \ n = 0\ - using bit_exp_iff [of 0 n] by simp - -lemma bit_2_iff [bit_simps]: - \bit 2 n \ 2 \ 0 \ n = 1\ - using bit_exp_iff [of 1 n] by auto - -lemma even_bit_succ_iff: - \bit (1 + a) n \ bit a n \ n = 0\ if \even a\ - using that by (cases \n = 0\) (simp_all add: bit_iff_odd) - -lemma odd_bit_iff_bit_pred: - \bit a n \ bit (a - 1) n \ n = 0\ if \odd a\ -proof - - from \odd a\ obtain b where \a = 2 * b + 1\ .. - moreover have \bit (2 * b) n \ n = 0 \ bit (1 + 2 * b) n\ - using even_bit_succ_iff by simp - ultimately show ?thesis by (simp add: ac_simps) -qed - -lemma bit_double_iff [bit_simps]: - \bit (2 * a) n \ bit a (n - 1) \ n \ 0 \ 2 ^ n \ 0\ - using even_mult_exp_div_exp_iff [of a 1 n] - by (cases n, auto simp add: bit_iff_odd ac_simps) - -lemma bit_eq_rec: - \a = b \ (even a \ even b) \ a div 2 = b div 2\ (is \?P = ?Q\) -proof - assume ?P - then show ?Q - by simp -next - assume ?Q - then have \even a \ even b\ and \a div 2 = b div 2\ - by simp_all - show ?P - proof (rule bit_eqI) - fix n - show \bit a n \ bit b n\ - proof (cases n) - case 0 - with \even a \ even b\ show ?thesis - by simp - next - case (Suc n) - moreover from \a div 2 = b div 2\ have \bit (a div 2) n = bit (b div 2) n\ - by simp - ultimately show ?thesis - by (simp add: bit_Suc) - qed - qed -qed - -lemma bit_mod_2_iff [simp]: - \bit (a mod 2) n \ n = 0 \ odd a\ - by (cases a rule: parity_cases) (simp_all add: bit_iff_odd) - -lemma bit_mask_iff: - \bit (2 ^ m - 1) n \ 2 ^ n \ 0 \ n < m\ - by (simp add: bit_iff_odd even_mask_div_iff not_le) - -lemma bit_Numeral1_iff [simp]: - \bit (numeral Num.One) n \ n = 0\ - by (simp add: bit_rec) - -lemma exp_add_not_zero_imp: - \2 ^ m \ 0\ and \2 ^ n \ 0\ if \2 ^ (m + n) \ 0\ -proof - - have \\ (2 ^ m = 0 \ 2 ^ n = 0)\ - proof (rule notI) - assume \2 ^ m = 0 \ 2 ^ n = 0\ - then have \2 ^ (m + n) = 0\ - by (rule disjE) (simp_all add: power_add) - with that show False .. - qed - then show \2 ^ m \ 0\ and \2 ^ n \ 0\ - by simp_all -qed - -lemma bit_disjunctive_add_iff: - \bit (a + b) n \ bit a n \ bit b n\ - if \\n. \ bit a n \ \ bit b n\ -proof (cases \2 ^ n = 0\) - case True - then show ?thesis - by (simp add: exp_eq_0_imp_not_bit) -next - case False - with that show ?thesis proof (induction n arbitrary: a b) - case 0 - from "0.prems"(1) [of 0] show ?case - by auto - next - case (Suc n) - from Suc.prems(1) [of 0] have even: \even a \ even b\ - by auto - have bit: \\ bit (a div 2) n \ \ bit (b div 2) n\ for n - using Suc.prems(1) [of \Suc n\] by (simp add: bit_Suc) - from Suc.prems(2) have \2 * 2 ^ n \ 0\ \2 ^ n \ 0\ - by (auto simp add: mult_2) - have \a + b = (a div 2 * 2 + a mod 2) + (b div 2 * 2 + b mod 2)\ - using div_mult_mod_eq [of a 2] div_mult_mod_eq [of b 2] by simp - also have \\ = of_bool (odd a \ odd b) + 2 * (a div 2 + b div 2)\ - using even by (auto simp add: algebra_simps mod2_eq_if) - finally have \bit ((a + b) div 2) n \ bit (a div 2 + b div 2) n\ - using \2 * 2 ^ n \ 0\ by simp (simp_all flip: bit_Suc add: bit_double_iff) - also have \\ \ bit (a div 2) n \ bit (b div 2) n\ - using bit \2 ^ n \ 0\ by (rule Suc.IH) - finally show ?case - by (simp add: bit_Suc) - qed -qed - -lemma - exp_add_not_zero_imp_left: \2 ^ m \ 0\ - and exp_add_not_zero_imp_right: \2 ^ n \ 0\ - if \2 ^ (m + n) \ 0\ -proof - - have \\ (2 ^ m = 0 \ 2 ^ n = 0)\ - proof (rule notI) - assume \2 ^ m = 0 \ 2 ^ n = 0\ - then have \2 ^ (m + n) = 0\ - by (rule disjE) (simp_all add: power_add) - with that show False .. - qed - then show \2 ^ m \ 0\ and \2 ^ n \ 0\ - by simp_all -qed - -lemma exp_not_zero_imp_exp_diff_not_zero: - \2 ^ (n - m) \ 0\ if \2 ^ n \ 0\ -proof (cases \m \ n\) - case True - moreover define q where \q = n - m\ - ultimately have \n = m + q\ - by simp - with that show ?thesis - by (simp add: exp_add_not_zero_imp_right) -next - case False - with that show ?thesis - by simp -qed - -end - -lemma nat_bit_induct [case_names zero even odd]: - "P n" if zero: "P 0" - and even: "\n. P n \ n > 0 \ P (2 * n)" - and odd: "\n. P n \ P (Suc (2 * n))" -proof (induction n rule: less_induct) - case (less n) - show "P n" - proof (cases "n = 0") - case True with zero show ?thesis by simp - next - case False - with less have hyp: "P (n div 2)" by simp - show ?thesis - proof (cases "even n") - case True - then have "n \ 1" - by auto - with \n \ 0\ have "n div 2 > 0" - by simp - with \even n\ hyp even [of "n div 2"] show ?thesis - by simp - next - case False - with hyp odd [of "n div 2"] show ?thesis - by simp - qed - qed -qed - -instantiation nat :: semiring_bits -begin - -definition bit_nat :: \nat \ nat \ bool\ - where \bit_nat m n \ odd (m div 2 ^ n)\ - -instance -proof - show \P n\ if stable: \\n. n div 2 = n \ P n\ - and rec: \\n b. P n \ (of_bool b + 2 * n) div 2 = n \ P (of_bool b + 2 * n)\ - for P and n :: nat - proof (induction n rule: nat_bit_induct) - case zero - from stable [of 0] show ?case - by simp - next - case (even n) - with rec [of n False] show ?case - by simp - next - case (odd n) - with rec [of n True] show ?case - by simp - qed - show \q mod 2 ^ m mod 2 ^ n = q mod 2 ^ min m n\ - for q m n :: nat - apply (auto simp add: less_iff_Suc_add power_add mod_mod_cancel split: split_min_lin) - apply (metis div_mult2_eq mod_div_trivial mod_eq_self_iff_div_eq_0 mod_mult_self2_is_0 power_commutes) - done - show \(q * 2 ^ m) mod (2 ^ n) = (q mod 2 ^ (n - m)) * 2 ^ m\ if \m \ n\ - for q m n :: nat - using that - apply (auto simp add: mod_mod_cancel div_mult2_eq power_add mod_mult2_eq le_iff_add split: split_min_lin) - apply (simp add: mult.commute) - done - show \even ((2 ^ m - (1::nat)) div 2 ^ n) \ 2 ^ n = (0::nat) \ m \ n\ - for m n :: nat - using even_mask_div_iff' [where ?'a = nat, of m n] by simp - show \even (q * 2 ^ m div 2 ^ n) \ n < m \ (2::nat) ^ n = 0 \ m \ n \ even (q div 2 ^ (n - m))\ - for m n q r :: nat - apply (auto simp add: not_less power_add ac_simps dest!: le_Suc_ex) - apply (metis (full_types) dvd_mult dvd_mult_imp_div dvd_power_iff_le not_less not_less_eq order_refl power_Suc) - done -qed (auto simp add: div_mult2_eq mod_mult2_eq power_add power_diff bit_nat_def) - -end - -lemma int_bit_induct [case_names zero minus even odd]: - "P k" if zero_int: "P 0" - and minus_int: "P (- 1)" - and even_int: "\k. P k \ k \ 0 \ P (k * 2)" - and odd_int: "\k. P k \ k \ - 1 \ P (1 + (k * 2))" for k :: int -proof (cases "k \ 0") - case True - define n where "n = nat k" - with True have "k = int n" - by simp - then show "P k" - proof (induction n arbitrary: k rule: nat_bit_induct) - case zero - then show ?case - by (simp add: zero_int) - next - case (even n) - have "P (int n * 2)" - by (rule even_int) (use even in simp_all) - with even show ?case - by (simp add: ac_simps) - next - case (odd n) - have "P (1 + (int n * 2))" - by (rule odd_int) (use odd in simp_all) - with odd show ?case - by (simp add: ac_simps) - qed -next - case False - define n where "n = nat (- k - 1)" - with False have "k = - int n - 1" - by simp - then show "P k" - proof (induction n arbitrary: k rule: nat_bit_induct) - case zero - then show ?case - by (simp add: minus_int) - next - case (even n) - have "P (1 + (- int (Suc n) * 2))" - by (rule odd_int) (use even in \simp_all add: algebra_simps\) - also have "\ = - int (2 * n) - 1" - by (simp add: algebra_simps) - finally show ?case - using even.prems by simp - next - case (odd n) - have "P (- int (Suc n) * 2)" - by (rule even_int) (use odd in \simp_all add: algebra_simps\) - also have "\ = - int (Suc (2 * n)) - 1" - by (simp add: algebra_simps) - finally show ?case - using odd.prems by simp - qed -qed - -context semiring_bits -begin - -lemma bit_of_bool_iff [bit_simps]: - \bit (of_bool b) n \ b \ n = 0\ - by (simp add: bit_1_iff) - -lemma even_of_nat_iff: - \even (of_nat n) \ even n\ - by (induction n rule: nat_bit_induct) simp_all - -lemma bit_of_nat_iff [bit_simps]: - \bit (of_nat m) n \ (2::'a) ^ n \ 0 \ bit m n\ -proof (cases \(2::'a) ^ n = 0\) - case True - then show ?thesis - by (simp add: exp_eq_0_imp_not_bit) -next - case False - then have \bit (of_nat m) n \ bit m n\ - proof (induction m arbitrary: n rule: nat_bit_induct) - case zero - then show ?case - by simp - next - case (even m) - then show ?case - by (cases n) - (auto simp add: bit_double_iff Parity.bit_double_iff dest: mult_not_zero) - next - case (odd m) - then show ?case - by (cases n) - (auto simp add: bit_double_iff even_bit_succ_iff Parity.bit_Suc dest: mult_not_zero) - qed - with False show ?thesis - by simp -qed - -end - -instantiation int :: semiring_bits -begin - -definition bit_int :: \int \ nat \ bool\ - where \bit_int k n \ odd (k div 2 ^ n)\ - -instance -proof - show \P k\ if stable: \\k. k div 2 = k \ P k\ - and rec: \\k b. P k \ (of_bool b + 2 * k) div 2 = k \ P (of_bool b + 2 * k)\ - for P and k :: int - proof (induction k rule: int_bit_induct) - case zero - from stable [of 0] show ?case - by simp - next - case minus - from stable [of \- 1\] show ?case - by simp - next - case (even k) - with rec [of k False] show ?case - by (simp add: ac_simps) - next - case (odd k) - with rec [of k True] show ?case - by (simp add: ac_simps) - qed - show \(2::int) ^ m div 2 ^ n = of_bool ((2::int) ^ m \ 0 \ n \ m) * 2 ^ (m - n)\ - for m n :: nat - proof (cases \m < n\) - case True - then have \n = m + (n - m)\ - by simp - then have \(2::int) ^ m div 2 ^ n = (2::int) ^ m div 2 ^ (m + (n - m))\ - by simp - also have \\ = (2::int) ^ m div (2 ^ m * 2 ^ (n - m))\ - by (simp add: power_add) - also have \\ = (2::int) ^ m div 2 ^ m div 2 ^ (n - m)\ - by (simp add: zdiv_zmult2_eq) - finally show ?thesis using \m < n\ by simp - next - case False - then show ?thesis - by (simp add: power_diff) - qed - show \k mod 2 ^ m mod 2 ^ n = k mod 2 ^ min m n\ - for m n :: nat and k :: int - using mod_exp_eq [of \nat k\ m n] - apply (auto simp add: mod_mod_cancel zdiv_zmult2_eq power_add zmod_zmult2_eq le_iff_add split: split_min_lin) - apply (auto simp add: less_iff_Suc_add mod_mod_cancel power_add) - apply (simp only: flip: mult.left_commute [of \2 ^ m\]) - apply (subst zmod_zmult2_eq) apply simp_all - done - show \(k * 2 ^ m) mod (2 ^ n) = (k mod 2 ^ (n - m)) * 2 ^ m\ - if \m \ n\ for m n :: nat and k :: int - using that - apply (auto simp add: power_add zmod_zmult2_eq le_iff_add split: split_min_lin) - apply (simp add: ac_simps) - done - show \even ((2 ^ m - (1::int)) div 2 ^ n) \ 2 ^ n = (0::int) \ m \ n\ - for m n :: nat - using even_mask_div_iff' [where ?'a = int, of m n] by simp - show \even (k * 2 ^ m div 2 ^ n) \ n < m \ (2::int) ^ n = 0 \ m \ n \ even (k div 2 ^ (n - m))\ - for m n :: nat and k l :: int - apply (auto simp add: not_less power_add ac_simps dest!: le_Suc_ex) - apply (metis Suc_leI dvd_mult dvd_mult_imp_div dvd_power_le dvd_refl power.simps(2)) - done -qed (auto simp add: zdiv_zmult2_eq zmod_zmult2_eq power_add power_diff not_le bit_int_def) - -end - -class semiring_bit_shifts = semiring_bits + - fixes push_bit :: \nat \ 'a \ 'a\ - assumes push_bit_eq_mult: \push_bit n a = a * 2 ^ n\ - fixes drop_bit :: \nat \ 'a \ 'a\ - assumes drop_bit_eq_div: \drop_bit n a = a div 2 ^ n\ - fixes take_bit :: \nat \ 'a \ 'a\ - assumes take_bit_eq_mod: \take_bit n a = a mod 2 ^ n\ -begin - -text \ - Logically, \<^const>\push_bit\, - \<^const>\drop_bit\ and \<^const>\take_bit\ are just aliases; having them - as separate operations makes proofs easier, otherwise proof automation - would fiddle with concrete expressions \<^term>\2 ^ n\ in a way obfuscating the basic - algebraic relationships between those operations. - Having - them as definitional class operations - takes into account that specific instances of these can be implemented - differently wrt. code generation. -\ - -lemma bit_iff_odd_drop_bit: - \bit a n \ odd (drop_bit n a)\ - by (simp add: bit_iff_odd drop_bit_eq_div) - -lemma even_drop_bit_iff_not_bit: - \even (drop_bit n a) \ \ bit a n\ - by (simp add: bit_iff_odd_drop_bit) - -lemma div_push_bit_of_1_eq_drop_bit: - \a div push_bit n 1 = drop_bit n a\ - by (simp add: push_bit_eq_mult drop_bit_eq_div) - -lemma bits_ident: - "push_bit n (drop_bit n a) + take_bit n a = a" - using div_mult_mod_eq by (simp add: push_bit_eq_mult take_bit_eq_mod drop_bit_eq_div) - -lemma push_bit_push_bit [simp]: - "push_bit m (push_bit n a) = push_bit (m + n) a" - by (simp add: push_bit_eq_mult power_add ac_simps) - -lemma push_bit_0_id [simp]: - "push_bit 0 = id" - by (simp add: fun_eq_iff push_bit_eq_mult) - -lemma push_bit_of_0 [simp]: - "push_bit n 0 = 0" - by (simp add: push_bit_eq_mult) - -lemma push_bit_of_1: - "push_bit n 1 = 2 ^ n" - by (simp add: push_bit_eq_mult) - -lemma push_bit_Suc [simp]: - "push_bit (Suc n) a = push_bit n (a * 2)" - by (simp add: push_bit_eq_mult ac_simps) - -lemma push_bit_double: - "push_bit n (a * 2) = push_bit n a * 2" - by (simp add: push_bit_eq_mult ac_simps) - -lemma push_bit_add: - "push_bit n (a + b) = push_bit n a + push_bit n b" - by (simp add: push_bit_eq_mult algebra_simps) - -lemma push_bit_numeral [simp]: - \push_bit (numeral l) (numeral k) = push_bit (pred_numeral l) (numeral (Num.Bit0 k))\ - by (simp add: numeral_eq_Suc mult_2_right) (simp add: numeral_Bit0) - -lemma take_bit_0 [simp]: - "take_bit 0 a = 0" - by (simp add: take_bit_eq_mod) - -lemma take_bit_Suc: - \take_bit (Suc n) a = take_bit n (a div 2) * 2 + a mod 2\ -proof - - have \take_bit (Suc n) (a div 2 * 2 + of_bool (odd a)) = take_bit n (a div 2) * 2 + of_bool (odd a)\ - using even_succ_mod_exp [of \2 * (a div 2)\ \Suc n\] - mult_exp_mod_exp_eq [of 1 \Suc n\ \a div 2\] - by (auto simp add: take_bit_eq_mod ac_simps) - then show ?thesis - using div_mult_mod_eq [of a 2] by (simp add: mod_2_eq_odd) -qed - -lemma take_bit_rec: - \take_bit n a = (if n = 0 then 0 else take_bit (n - 1) (a div 2) * 2 + a mod 2)\ - by (cases n) (simp_all add: take_bit_Suc) - -lemma take_bit_Suc_0 [simp]: - \take_bit (Suc 0) a = a mod 2\ - by (simp add: take_bit_eq_mod) - -lemma take_bit_of_0 [simp]: - "take_bit n 0 = 0" - by (simp add: take_bit_eq_mod) - -lemma take_bit_of_1 [simp]: - "take_bit n 1 = of_bool (n > 0)" - by (cases n) (simp_all add: take_bit_Suc) - -lemma drop_bit_of_0 [simp]: - "drop_bit n 0 = 0" - by (simp add: drop_bit_eq_div) - -lemma drop_bit_of_1 [simp]: - "drop_bit n 1 = of_bool (n = 0)" - by (simp add: drop_bit_eq_div) - -lemma drop_bit_0 [simp]: - "drop_bit 0 = id" - by (simp add: fun_eq_iff drop_bit_eq_div) - -lemma drop_bit_Suc: - "drop_bit (Suc n) a = drop_bit n (a div 2)" - using div_exp_eq [of a 1] by (simp add: drop_bit_eq_div) - -lemma drop_bit_rec: - "drop_bit n a = (if n = 0 then a else drop_bit (n - 1) (a div 2))" - by (cases n) (simp_all add: drop_bit_Suc) - -lemma drop_bit_half: - "drop_bit n (a div 2) = drop_bit n a div 2" - by (induction n arbitrary: a) (simp_all add: drop_bit_Suc) - -lemma drop_bit_of_bool [simp]: - "drop_bit n (of_bool b) = of_bool (n = 0 \ b)" - by (cases n) simp_all - -lemma even_take_bit_eq [simp]: - \even (take_bit n a) \ n = 0 \ even a\ - by (simp add: take_bit_rec [of n a]) - -lemma take_bit_take_bit [simp]: - "take_bit m (take_bit n a) = take_bit (min m n) a" - by (simp add: take_bit_eq_mod mod_exp_eq ac_simps) - -lemma drop_bit_drop_bit [simp]: - "drop_bit m (drop_bit n a) = drop_bit (m + n) a" - by (simp add: drop_bit_eq_div power_add div_exp_eq ac_simps) - -lemma push_bit_take_bit: - "push_bit m (take_bit n a) = take_bit (m + n) (push_bit m a)" - apply (simp add: push_bit_eq_mult take_bit_eq_mod power_add ac_simps) - using mult_exp_mod_exp_eq [of m \m + n\ a] apply (simp add: ac_simps power_add) - done - -lemma take_bit_push_bit: - "take_bit m (push_bit n a) = push_bit n (take_bit (m - n) a)" -proof (cases "m \ n") - case True - then show ?thesis - apply (simp add:) - apply (simp_all add: push_bit_eq_mult take_bit_eq_mod) - apply (auto dest!: le_Suc_ex simp add: power_add ac_simps) - using mult_exp_mod_exp_eq [of m m \a * 2 ^ n\ for n] - apply (simp add: ac_simps) - done -next - case False - then show ?thesis - using push_bit_take_bit [of n "m - n" a] - by simp -qed - -lemma take_bit_drop_bit: - "take_bit m (drop_bit n a) = drop_bit n (take_bit (m + n) a)" - by (simp add: drop_bit_eq_div take_bit_eq_mod ac_simps div_exp_mod_exp_eq) - -lemma drop_bit_take_bit: - "drop_bit m (take_bit n a) = take_bit (n - m) (drop_bit m a)" -proof (cases "m \ n") - case True - then show ?thesis - using take_bit_drop_bit [of "n - m" m a] by simp -next - case False - then obtain q where \m = n + q\ - by (auto simp add: not_le dest: less_imp_Suc_add) - then have \drop_bit m (take_bit n a) = 0\ - using div_exp_eq [of \a mod 2 ^ n\ n q] - by (simp add: take_bit_eq_mod drop_bit_eq_div) - with False show ?thesis - by simp -qed - -lemma even_push_bit_iff [simp]: - \even (push_bit n a) \ n \ 0 \ even a\ - by (simp add: push_bit_eq_mult) auto - -lemma bit_push_bit_iff [bit_simps]: - \bit (push_bit m a) n \ m \ n \ 2 ^ n \ 0 \ bit a (n - m)\ - by (auto simp add: bit_iff_odd push_bit_eq_mult even_mult_exp_div_exp_iff) - -lemma bit_drop_bit_eq [bit_simps]: - \bit (drop_bit n a) = bit a \ (+) n\ - by (simp add: bit_iff_odd fun_eq_iff ac_simps flip: drop_bit_eq_div) - -lemma bit_take_bit_iff [bit_simps]: - \bit (take_bit m a) n \ n < m \ bit a n\ - by (simp add: bit_iff_odd drop_bit_take_bit not_le flip: drop_bit_eq_div) - -lemma stable_imp_drop_bit_eq: - \drop_bit n a = a\ - if \a div 2 = a\ - by (induction n) (simp_all add: that drop_bit_Suc) - -lemma stable_imp_take_bit_eq: - \take_bit n a = (if even a then 0 else 2 ^ n - 1)\ - if \a div 2 = a\ -proof (rule bit_eqI) - fix m - assume \2 ^ m \ 0\ - with that show \bit (take_bit n a) m \ bit (if even a then 0 else 2 ^ n - 1) m\ - by (simp add: bit_take_bit_iff bit_mask_iff stable_imp_bit_iff_odd) -qed - -lemma exp_dvdE: - assumes \2 ^ n dvd a\ - obtains b where \a = push_bit n b\ -proof - - from assms obtain b where \a = 2 ^ n * b\ .. - then have \a = push_bit n b\ - by (simp add: push_bit_eq_mult ac_simps) - with that show thesis . -qed - -lemma take_bit_eq_0_iff: - \take_bit n a = 0 \ 2 ^ n dvd a\ (is \?P \ ?Q\) -proof - assume ?P - then show ?Q - by (simp add: take_bit_eq_mod mod_0_imp_dvd) -next - assume ?Q - then obtain b where \a = push_bit n b\ - by (rule exp_dvdE) - then show ?P - by (simp add: take_bit_push_bit) -qed - -lemma take_bit_tightened: - \take_bit m a = take_bit m b\ if \take_bit n a = take_bit n b\ and \m \ n\ -proof - - from that have \take_bit m (take_bit n a) = take_bit m (take_bit n b)\ - by simp - then have \take_bit (min m n) a = take_bit (min m n) b\ - by simp - with that show ?thesis - by (simp add: min_def) -qed - -lemma take_bit_eq_self_iff_drop_bit_eq_0: - \take_bit n a = a \ drop_bit n a = 0\ (is \?P \ ?Q\) -proof - assume ?P - show ?Q - proof (rule bit_eqI) - fix m - from \?P\ have \a = take_bit n a\ .. - also have \\ bit (take_bit n a) (n + m)\ - unfolding bit_simps - by (simp add: bit_simps) - finally show \bit (drop_bit n a) m \ bit 0 m\ - by (simp add: bit_simps) - qed -next - assume ?Q - show ?P - proof (rule bit_eqI) - fix m - from \?Q\ have \\ bit (drop_bit n a) (m - n)\ - by simp - then have \ \ bit a (n + (m - n))\ - by (simp add: bit_simps) - then show \bit (take_bit n a) m \ bit a m\ - by (cases \m < n\) (auto simp add: bit_simps) - qed -qed - -lemma drop_bit_exp_eq: - \drop_bit m (2 ^ n) = of_bool (m \ n \ 2 ^ n \ 0) * 2 ^ (n - m)\ - by (rule bit_eqI) (auto simp add: bit_simps) - -end - -instantiation nat :: semiring_bit_shifts -begin - -definition push_bit_nat :: \nat \ nat \ nat\ - where \push_bit_nat n m = m * 2 ^ n\ - -definition drop_bit_nat :: \nat \ nat \ nat\ - where \drop_bit_nat n m = m div 2 ^ n\ - -definition take_bit_nat :: \nat \ nat \ nat\ - where \take_bit_nat n m = m mod 2 ^ n\ - -instance - by standard (simp_all add: push_bit_nat_def drop_bit_nat_def take_bit_nat_def) - -end - -context semiring_bit_shifts -begin - -lemma push_bit_of_nat: - \push_bit n (of_nat m) = of_nat (push_bit n m)\ - by (simp add: push_bit_eq_mult semiring_bit_shifts_class.push_bit_eq_mult) - -lemma of_nat_push_bit: - \of_nat (push_bit m n) = push_bit m (of_nat n)\ - by (simp add: push_bit_eq_mult semiring_bit_shifts_class.push_bit_eq_mult) - -lemma take_bit_of_nat: - \take_bit n (of_nat m) = of_nat (take_bit n m)\ - by (rule bit_eqI) (simp add: bit_take_bit_iff Parity.bit_take_bit_iff bit_of_nat_iff) - -lemma of_nat_take_bit: - \of_nat (take_bit n m) = take_bit n (of_nat m)\ - by (rule bit_eqI) (simp add: bit_take_bit_iff Parity.bit_take_bit_iff bit_of_nat_iff) - -end - -instantiation int :: semiring_bit_shifts -begin - -definition push_bit_int :: \nat \ int \ int\ - where \push_bit_int n k = k * 2 ^ n\ - -definition drop_bit_int :: \nat \ int \ int\ - where \drop_bit_int n k = k div 2 ^ n\ - -definition take_bit_int :: \nat \ int \ int\ - where \take_bit_int n k = k mod 2 ^ n\ - -instance - by standard (simp_all add: push_bit_int_def drop_bit_int_def take_bit_int_def) - -end - -lemma bit_push_bit_iff_nat: - \bit (push_bit m q) n \ m \ n \ bit q (n - m)\ for q :: nat - by (auto simp add: bit_push_bit_iff) - -lemma bit_push_bit_iff_int: - \bit (push_bit m k) n \ m \ n \ bit k (n - m)\ for k :: int - by (auto simp add: bit_push_bit_iff) - -lemma take_bit_nat_less_exp [simp]: - \take_bit n m < 2 ^ n\ for n m ::nat - by (simp add: take_bit_eq_mod) - -lemma take_bit_nonnegative [simp]: - \take_bit n k \ 0\ for k :: int - by (simp add: take_bit_eq_mod) - -lemma not_take_bit_negative [simp]: - \\ take_bit n k < 0\ for k :: int - by (simp add: not_less) - -lemma take_bit_int_less_exp [simp]: - \take_bit n k < 2 ^ n\ for k :: int - by (simp add: take_bit_eq_mod) - -lemma take_bit_nat_eq_self_iff: - \take_bit n m = m \ m < 2 ^ n\ (is \?P \ ?Q\) - for n m :: nat -proof - assume ?P - moreover note take_bit_nat_less_exp [of n m] - ultimately show ?Q - by simp -next - assume ?Q - then show ?P - by (simp add: take_bit_eq_mod) -qed - -lemma take_bit_nat_eq_self: - \take_bit n m = m\ if \m < 2 ^ n\ for m n :: nat - using that by (simp add: take_bit_nat_eq_self_iff) - -lemma take_bit_int_eq_self_iff: - \take_bit n k = k \ 0 \ k \ k < 2 ^ n\ (is \?P \ ?Q\) - for k :: int -proof - assume ?P - moreover note take_bit_int_less_exp [of n k] take_bit_nonnegative [of n k] - ultimately show ?Q - by simp -next - assume ?Q - then show ?P - by (simp add: take_bit_eq_mod) -qed - -lemma take_bit_int_eq_self: - \take_bit n k = k\ if \0 \ k\ \k < 2 ^ n\ for k :: int - using that by (simp add: take_bit_int_eq_self_iff) - -lemma take_bit_nat_less_eq_self [simp]: - \take_bit n m \ m\ for n m :: nat - by (simp add: take_bit_eq_mod) - -lemma take_bit_nat_less_self_iff: - \take_bit n m < m \ 2 ^ n \ m\ (is \?P \ ?Q\) - for m n :: nat -proof - assume ?P - then have \take_bit n m \ m\ - by simp - then show \?Q\ - by (simp add: take_bit_nat_eq_self_iff) -next - have \take_bit n m < 2 ^ n\ - by (fact take_bit_nat_less_exp) - also assume ?Q - finally show ?P . -qed - -class unique_euclidean_semiring_with_bit_shifts = - unique_euclidean_semiring_with_nat + semiring_bit_shifts -begin - -lemma take_bit_of_exp [simp]: - \take_bit m (2 ^ n) = of_bool (n < m) * 2 ^ n\ - by (simp add: take_bit_eq_mod exp_mod_exp) - -lemma take_bit_of_2 [simp]: - \take_bit n 2 = of_bool (2 \ n) * 2\ - using take_bit_of_exp [of n 1] by simp - -lemma take_bit_of_mask: - \take_bit m (2 ^ n - 1) = 2 ^ min m n - 1\ - by (simp add: take_bit_eq_mod mask_mod_exp) - -lemma push_bit_eq_0_iff [simp]: - "push_bit n a = 0 \ a = 0" - by (simp add: push_bit_eq_mult) - -lemma take_bit_add: - "take_bit n (take_bit n a + take_bit n b) = take_bit n (a + b)" - by (simp add: take_bit_eq_mod mod_simps) - -lemma take_bit_of_1_eq_0_iff [simp]: - "take_bit n 1 = 0 \ n = 0" - by (simp add: take_bit_eq_mod) - -lemma take_bit_Suc_1 [simp]: - \take_bit (Suc n) 1 = 1\ - by (simp add: take_bit_Suc) - -lemma take_bit_Suc_bit0 [simp]: - \take_bit (Suc n) (numeral (Num.Bit0 k)) = take_bit n (numeral k) * 2\ - by (simp add: take_bit_Suc numeral_Bit0_div_2) - -lemma take_bit_Suc_bit1 [simp]: - \take_bit (Suc n) (numeral (Num.Bit1 k)) = take_bit n (numeral k) * 2 + 1\ - by (simp add: take_bit_Suc numeral_Bit1_div_2 mod_2_eq_odd) - -lemma take_bit_numeral_1 [simp]: - \take_bit (numeral l) 1 = 1\ - by (simp add: take_bit_rec [of \numeral l\ 1]) - -lemma take_bit_numeral_bit0 [simp]: - \take_bit (numeral l) (numeral (Num.Bit0 k)) = take_bit (pred_numeral l) (numeral k) * 2\ - by (simp add: take_bit_rec numeral_Bit0_div_2) - -lemma take_bit_numeral_bit1 [simp]: - \take_bit (numeral l) (numeral (Num.Bit1 k)) = take_bit (pred_numeral l) (numeral k) * 2 + 1\ - by (simp add: take_bit_rec numeral_Bit1_div_2 mod_2_eq_odd) - -lemma drop_bit_Suc_bit0 [simp]: - \drop_bit (Suc n) (numeral (Num.Bit0 k)) = drop_bit n (numeral k)\ - by (simp add: drop_bit_Suc numeral_Bit0_div_2) - -lemma drop_bit_Suc_bit1 [simp]: - \drop_bit (Suc n) (numeral (Num.Bit1 k)) = drop_bit n (numeral k)\ - by (simp add: drop_bit_Suc numeral_Bit1_div_2) - -lemma drop_bit_numeral_bit0 [simp]: - \drop_bit (numeral l) (numeral (Num.Bit0 k)) = drop_bit (pred_numeral l) (numeral k)\ - by (simp add: drop_bit_rec numeral_Bit0_div_2) - -lemma drop_bit_numeral_bit1 [simp]: - \drop_bit (numeral l) (numeral (Num.Bit1 k)) = drop_bit (pred_numeral l) (numeral k)\ - by (simp add: drop_bit_rec numeral_Bit1_div_2) - -lemma drop_bit_of_nat: - "drop_bit n (of_nat m) = of_nat (drop_bit n m)" - by (simp add: drop_bit_eq_div Parity.drop_bit_eq_div of_nat_div [of m "2 ^ n"]) - -lemma bit_of_nat_iff_bit [bit_simps]: - \bit (of_nat m) n \ bit m n\ -proof - - have \even (m div 2 ^ n) \ even (of_nat (m div 2 ^ n))\ - by simp - also have \of_nat (m div 2 ^ n) = of_nat m div of_nat (2 ^ n)\ - by (simp add: of_nat_div) - finally show ?thesis - by (simp add: bit_iff_odd semiring_bits_class.bit_iff_odd) -qed - -lemma of_nat_drop_bit: - \of_nat (drop_bit m n) = drop_bit m (of_nat n)\ - by (simp add: drop_bit_eq_div semiring_bit_shifts_class.drop_bit_eq_div of_nat_div) - -lemma bit_push_bit_iff_of_nat_iff [bit_simps]: - \bit (push_bit m (of_nat r)) n \ m \ n \ bit (of_nat r) (n - m)\ - by (auto simp add: bit_push_bit_iff) - -end - -instance nat :: unique_euclidean_semiring_with_bit_shifts .. - -instance int :: unique_euclidean_semiring_with_bit_shifts .. - -lemma bit_numeral_int_iff [bit_simps]: - \bit (numeral m :: int) n \ bit (numeral m :: nat) n\ - using bit_of_nat_iff_bit [of \numeral m\ n] by simp - -lemma bit_not_int_iff': - \bit (- k - 1) n \ \ bit k n\ - for k :: int -proof (induction n arbitrary: k) - case 0 - show ?case - by simp -next - case (Suc n) - have \- k - 1 = - (k + 2) + 1\ - by simp - also have \(- (k + 2) + 1) div 2 = - (k div 2) - 1\ - proof (cases \even k\) - case True - then have \- k div 2 = - (k div 2)\ - by rule (simp flip: mult_minus_right) - with True show ?thesis - by simp - next - case False - have \4 = 2 * (2::int)\ - by simp - also have \2 * 2 div 2 = (2::int)\ - by (simp only: nonzero_mult_div_cancel_left) - finally have *: \4 div 2 = (2::int)\ . - from False obtain l where k: \k = 2 * l + 1\ .. - then have \- k - 2 = 2 * - (l + 2) + 1\ - by simp - then have \(- k - 2) div 2 + 1 = - (k div 2) - 1\ - by (simp flip: mult_minus_right add: *) (simp add: k) - with False show ?thesis - by simp - qed - finally have \(- k - 1) div 2 = - (k div 2) - 1\ . - with Suc show ?case - by (simp add: bit_Suc) -qed - -lemma bit_minus_int_iff [bit_simps]: - \bit (- k) n \ \ bit (k - 1) n\ - for k :: int - using bit_not_int_iff' [of \k - 1\] by simp - -lemma bit_nat_iff [bit_simps]: - \bit (nat k) n \ k \ 0 \ bit k n\ -proof (cases \k \ 0\) - case True - moreover define m where \m = nat k\ - ultimately have \k = int m\ - by simp - then show ?thesis - by (simp add: bit_simps) -next - case False - then show ?thesis - by simp -qed - -lemma push_bit_nat_eq: - \push_bit n (nat k) = nat (push_bit n k)\ - by (cases \k \ 0\) (simp_all add: push_bit_eq_mult nat_mult_distrib not_le mult_nonneg_nonpos2) - -lemma drop_bit_nat_eq: - \drop_bit n (nat k) = nat (drop_bit n k)\ - apply (cases \k \ 0\) - apply (simp_all add: drop_bit_eq_div nat_div_distrib nat_power_eq not_le) - apply (simp add: divide_int_def) - done - -lemma take_bit_nat_eq: - \take_bit n (nat k) = nat (take_bit n k)\ if \k \ 0\ - using that by (simp add: take_bit_eq_mod nat_mod_distrib nat_power_eq) - -lemma nat_take_bit_eq: - \nat (take_bit n k) = take_bit n (nat k)\ - if \k \ 0\ - using that by (simp add: take_bit_eq_mod nat_mod_distrib nat_power_eq) - -lemma not_exp_less_eq_0_int [simp]: - \\ 2 ^ n \ (0::int)\ - by (simp add: power_le_zero_eq) - -lemma half_nonnegative_int_iff [simp]: - \k div 2 \ 0 \ k \ 0\ for k :: int -proof (cases \k \ 0\) - case True - then show ?thesis - by (auto simp add: divide_int_def sgn_1_pos) -next - case False - then show ?thesis - apply (auto simp add: divide_int_def not_le elim!: evenE) - apply (simp only: minus_mult_right) - apply (subst (asm) nat_mult_distrib) - apply simp_all - done -qed - -lemma half_negative_int_iff [simp]: - \k div 2 < 0 \ k < 0\ for k :: int - by (subst Not_eq_iff [symmetric]) (simp add: not_less) - -lemma push_bit_of_Suc_0 [simp]: - "push_bit n (Suc 0) = 2 ^ n" - using push_bit_of_1 [where ?'a = nat] by simp - -lemma take_bit_of_Suc_0 [simp]: - "take_bit n (Suc 0) = of_bool (0 < n)" - using take_bit_of_1 [where ?'a = nat] by simp - -lemma drop_bit_of_Suc_0 [simp]: - "drop_bit n (Suc 0) = of_bool (n = 0)" - using drop_bit_of_1 [where ?'a = nat] by simp - -lemma push_bit_minus_one: - "push_bit n (- 1 :: int) = - (2 ^ n)" - by (simp add: push_bit_eq_mult) - -lemma minus_1_div_exp_eq_int: - \- 1 div (2 :: int) ^ n = - 1\ - by (induction n) (use div_exp_eq [symmetric, of \- 1 :: int\ 1] in \simp_all add: ac_simps\) - -lemma drop_bit_minus_one [simp]: - \drop_bit n (- 1 :: int) = - 1\ - by (simp add: drop_bit_eq_div minus_1_div_exp_eq_int) - -lemma take_bit_Suc_from_most: - \take_bit (Suc n) k = 2 ^ n * of_bool (bit k n) + take_bit n k\ for k :: int - by (simp only: take_bit_eq_mod power_Suc2) (simp_all add: bit_iff_odd odd_iff_mod_2_eq_one zmod_zmult2_eq) - -lemma take_bit_minus: - \take_bit n (- take_bit n k) = take_bit n (- k)\ - for k :: int - by (simp add: take_bit_eq_mod mod_minus_eq) - -lemma take_bit_diff: - \take_bit n (take_bit n k - take_bit n l) = take_bit n (k - l)\ - for k l :: int - by (simp add: take_bit_eq_mod mod_diff_eq) - -lemma bit_imp_take_bit_positive: - \0 < take_bit m k\ if \n < m\ and \bit k n\ for k :: int -proof (rule ccontr) - assume \\ 0 < take_bit m k\ - then have \take_bit m k = 0\ - by (auto simp add: not_less intro: order_antisym) - then have \bit (take_bit m k) n = bit 0 n\ - by simp - with that show False - by (simp add: bit_take_bit_iff) -qed - -lemma take_bit_mult: - \take_bit n (take_bit n k * take_bit n l) = take_bit n (k * l)\ - for k l :: int - by (simp add: take_bit_eq_mod mod_mult_eq) - -lemma (in ring_1) of_nat_nat_take_bit_eq [simp]: - \of_nat (nat (take_bit n k)) = of_int (take_bit n k)\ - by simp - -lemma take_bit_minus_small_eq: - \take_bit n (- k) = 2 ^ n - k\ if \0 < k\ \k \ 2 ^ n\ for k :: int -proof - - define m where \m = nat k\ - with that have \k = int m\ and \0 < m\ and \m \ 2 ^ n\ - by simp_all - have \(2 ^ n - m) mod 2 ^ n = 2 ^ n - m\ - using \0 < m\ by simp - then have \int ((2 ^ n - m) mod 2 ^ n) = int (2 ^ n - m)\ - by simp - then have \(2 ^ n - int m) mod 2 ^ n = 2 ^ n - int m\ - using \m \ 2 ^ n\ by (simp only: of_nat_mod of_nat_diff) simp - with \k = int m\ have \(2 ^ n - k) mod 2 ^ n = 2 ^ n - k\ - by simp - then show ?thesis - by (simp add: take_bit_eq_mod) -qed - -lemma drop_bit_push_bit_int: - \drop_bit m (push_bit n k) = drop_bit (m - n) (push_bit (n - m) k)\ for k :: int - by (cases \m \ n\) (auto simp add: mult.left_commute [of _ \2 ^ n\] mult.commute [of _ \2 ^ n\] mult.assoc - mult.commute [of k] drop_bit_eq_div push_bit_eq_mult not_le power_add dest!: le_Suc_ex less_imp_Suc_add) - -lemma push_bit_nonnegative_int_iff [simp]: - \push_bit n k \ 0 \ k \ 0\ for k :: int - by (simp add: push_bit_eq_mult zero_le_mult_iff) - -lemma push_bit_negative_int_iff [simp]: - \push_bit n k < 0 \ k < 0\ for k :: int - by (subst Not_eq_iff [symmetric]) (simp add: not_less) - -lemma drop_bit_nonnegative_int_iff [simp]: - \drop_bit n k \ 0 \ k \ 0\ for k :: int - by (induction n) (simp_all add: drop_bit_Suc drop_bit_half) - -lemma drop_bit_negative_int_iff [simp]: - \drop_bit n k < 0 \ k < 0\ for k :: int - by (subst Not_eq_iff [symmetric]) (simp add: not_less) - code_identifier code_module Parity \ (SML) Arith and (OCaml) Arith and (Haskell) Arith diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Random.thy --- a/src/HOL/Random.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/Random.thy Mon Aug 02 10:01:06 2021 +0000 @@ -3,7 +3,7 @@ section \A HOL random engine\ theory Random -imports List Groups_List +imports List Groups_List Code_Numeral begin subsection \Auxiliary functions\ diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Set.thy --- a/src/HOL/Set.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/Set.thy Mon Aug 02 10:01:06 2021 +0000 @@ -7,7 +7,7 @@ section \Set theory for higher-order logic\ theory Set - imports Lattices + imports Lattices Boolean_Algebra begin subsection \Sets as predicates\ diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/Set_Interval.thy --- a/src/HOL/Set_Interval.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/Set_Interval.thy Mon Aug 02 10:01:06 2021 +0000 @@ -2140,31 +2140,6 @@ by (subst sum_subtractf_nat) auto -context unique_euclidean_semiring_with_bit_shifts -begin - -lemma take_bit_sum: - "take_bit n a = (\k = 0..k = 0..k = Suc 0..k = Suc 0..k = 0..Shifting bounds\ context comm_monoid_add diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/String.thy --- a/src/HOL/String.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/String.thy Mon Aug 02 10:01:06 2021 +0000 @@ -3,7 +3,7 @@ section \Character and string types\ theory String -imports Enum +imports Enum Bit_Operations Code_Numeral begin subsection \Strings as list of bytes\ diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/ex/Meson_Test.thy --- a/src/HOL/ex/Meson_Test.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/ex/Meson_Test.thy Mon Aug 02 10:01:06 2021 +0000 @@ -10,7 +10,7 @@ below and constants declared in HOL! \ -hide_const (open) implies union inter subset quotient sum +hide_const (open) implies union inter subset quotient sum or text \ Test data for the MESON proof procedure @@ -1286,7 +1286,7 @@ (\X Y. value(X::'a,truth) & value(Y::'a,falsity) --> value(xor(X::'a,Y),truth)) & (\X Y. value(X::'a,falsity) & value(Y::'a,truth) --> value(xor(X::'a,Y),truth)) & (\X Y. value(X::'a,falsity) & value(Y::'a,falsity) --> value(xor(X::'a,Y),falsity)) & - (\Value. ~value(xor(xor(xor(xor(truth::'a,falsity),falsity),truth),falsity),Value)) --> False" + (\Value. ~value(xor(xor(xor(xor(truth::'a,falsity),falsity),truth),falsity),Value)) --> False" for xor by meson (*19116 inferences so far. Searching to depth 16. 15.9 secs*) diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/ex/Reflection_Examples.thy --- a/src/HOL/ex/Reflection_Examples.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/ex/Reflection_Examples.thy Mon Aug 02 10:01:06 2021 +0000 @@ -66,7 +66,7 @@ apply reify oops -datatype fm = And fm fm | Or fm fm | Imp fm fm | Iff fm fm | NOT fm | At nat +datatype fm = And fm fm | Or fm fm | Imp fm fm | Iff fm fm | Not fm | At nat primrec Ifm :: "fm \ bool list \ bool" where @@ -75,7 +75,7 @@ | "Ifm (Or p q) vs \ Ifm p vs \ Ifm q vs" | "Ifm (Imp p q) vs \ Ifm p vs \ Ifm q vs" | "Ifm (Iff p q) vs \ Ifm p vs = Ifm q vs" -| "Ifm (NOT p) vs \ \ Ifm p vs" +| "Ifm (Not p) vs \ \ Ifm p vs" lemma "Q \ (D \ F \ ((\ D) \ (\ F)))" apply (reify Ifm.simps) @@ -93,7 +93,7 @@ primrec fmsize :: "fm \ nat" where "fmsize (At n) = 1" -| "fmsize (NOT p) = 1 + fmsize p" +| "fmsize (Not p) = 1 + fmsize p" | "fmsize (And p q) = 1 + fmsize p + fmsize q" | "fmsize (Or p q) = 1 + fmsize p + fmsize q" | "fmsize (Imp p q) = 2 + fmsize p + fmsize q" @@ -106,14 +106,14 @@ "nnf (At n) = At n" | "nnf (And p q) = And (nnf p) (nnf q)" | "nnf (Or p q) = Or (nnf p) (nnf q)" -| "nnf (Imp p q) = Or (nnf (NOT p)) (nnf q)" -| "nnf (Iff p q) = Or (And (nnf p) (nnf q)) (And (nnf (NOT p)) (nnf (NOT q)))" -| "nnf (NOT (And p q)) = Or (nnf (NOT p)) (nnf (NOT q))" -| "nnf (NOT (Or p q)) = And (nnf (NOT p)) (nnf (NOT q))" -| "nnf (NOT (Imp p q)) = And (nnf p) (nnf (NOT q))" -| "nnf (NOT (Iff p q)) = Or (And (nnf p) (nnf (NOT q))) (And (nnf (NOT p)) (nnf q))" -| "nnf (NOT (NOT p)) = nnf p" -| "nnf (NOT p) = NOT p" +| "nnf (Imp p q) = Or (nnf (Not p)) (nnf q)" +| "nnf (Iff p q) = Or (And (nnf p) (nnf q)) (And (nnf (Not p)) (nnf (Not q)))" +| "nnf (Not (And p q)) = Or (nnf (Not p)) (nnf (Not q))" +| "nnf (Not (Or p q)) = And (nnf (Not p)) (nnf (Not q))" +| "nnf (Not (Imp p q)) = And (nnf p) (nnf (Not q))" +| "nnf (Not (Iff p q)) = Or (And (nnf p) (nnf (Not q))) (And (nnf (Not p)) (nnf q))" +| "nnf (Not (Not p)) = nnf p" +| "nnf (Not p) = Not p" text \The correctness theorem of \<^const>\nnf\: it preserves the semantics of \<^typ>\fm\\ lemma nnf [reflection]: diff -r fb9c119e5b49 -r d804e93ae9ff src/HOL/ex/Tree23.thy --- a/src/HOL/ex/Tree23.thy Sun Aug 01 23:18:13 2021 +0200 +++ b/src/HOL/ex/Tree23.thy Mon Aug 02 10:01:06 2021 +0000 @@ -8,6 +8,8 @@ imports Main begin +hide_const (open) or + text\This is a very direct translation of some of the functions in table.ML in the Isabelle source code. That source is due to Makarius Wenzel and Stefan Berghofer.