section‹Bit operations in suitable algebraic structures›
theory Bit_Operations imports Presburger Groups_List begin
subsection‹Abstract bit structures›
class semiring_bits = semiring_parity + semiring_modulo_trivial + assumes bit_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_mod_div_trivial [simp]: ‹a mod b div b = 0› and half_div_exp_eq: ‹a div 2 div 2 ^ n = a div 2 ^ Suc n› and even_double_div_exp_iff: ‹2 ^ Suc n ≠ 0 ==> even (2 * a div 2 ^ Suc n) ⟷ even (a div 2 ^ n)› fixes bit :: ‹'a ==> nat ==> bool› assumes bit_iff_odd: ‹bit a n ⟷ odd (a div 2 ^ n)› begin
text‹ Having 🍋‹bit›as definitional class operation takes into account that specific instances can be implemented differently wrt. code generation. ›
lemma half_1 [simp]: ‹1 div 2 = 0› using even_half_succ_eq [of 0] by simp
lemma div_exp_eq_funpow_half: ‹a div 2 ^ n = ((λa. a div 2) ^^ n) a› proof - have‹((λa. a div 2) ^^ n) = (λa. a div 2 ^ n)› by (induction n)
(simp_all del: funpow.simps power.simps add: power_0 funpow_Suc_right half_div_exp_eq) thenshow ?thesis by simp qed
lemma div_exp_eq: ‹a div 2 ^ m div 2 ^ n = a div 2 ^ (m + n)› by (simp add: div_exp_eq_funpow_half Groups.add.commute [of m] funpow_add)
lemma bit_0: ‹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 bit_0)
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) thenhave‹a * 2 + a mod 2 = a› by (simp add: stable) thenshow ?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 bit_0)
end
lemma bit_iff_odd_imp_stable: ‹a div 2 = a›if‹∧n. bit a n ⟷ odd a› using that proof (induction a rule: bit_induct) case (stable a) thenshow ?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 bit_0) 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) thenhave‹a div 2 = a› by (rule rec.IH) thenhave‹of_bool (odd a) + 2 * a = 2 * (a div 2) + of_bool (odd a)› by (simp add: ac_simps) alsohave‹… = a› using mult_div_mod_eq [of 2 a] by (simp add: of_bool_odd_eq_mod_2) finallyshow ?case using‹a div 2 = a›by (simp add: hyp) qed
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 thenshow ?case by simp next case (Suc n) thenshow ?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›] div_mult_mod_eq [of a ‹2 ^ n›] that by simp (metis (full_types) add.left_commute add_left_imp_eq)
lemma half_numeral_Bit1_eq [simp]: ‹numeral (num.Bit1 m) div 2 = numeral (num.Bit0 m) div 2› using even_half_succ_eq [of ‹2 * numeral m›] by simp
lemma double_half_numeral_Bit_0_eq [simp]: ‹2 * (numeral (num.Bit0 m) div 2) = numeral (num.Bit0 m)› ‹(numeral (num.Bit0 m) div 2) * 2 = numeral (num.Bit0 m)› using mod_mult_div_eq [of ‹numeral (Num.Bit0 m)› 2] by (simp_all add: mod2_eq_if ac_simps)
named_theorems bit_simps ‹Simplification rules for 🍋‹bit›\›
definition possible_bit :: ‹'a itself ==> nat ==> bool› where‹possible_bit TYPE('a) n ⟷ 2 ^ n ≠ 0› 🍋‹This auxiliary avoids non-termination with extensionality.›
lemma possible_bit_0 [simp]: ‹possible_bit TYPE('a) 0› by (simp add: possible_bit_def)
lemma fold_possible_bit: ‹2 ^ n = 0 ⟷¬ possible_bit TYPE('a) n› by (simp add: possible_bit_def)
lemma bit_imp_possible_bit: ‹possible_bit TYPE('a) n›if‹bit a n› by (rule ccontr) (use that in‹auto simp: bit_iff_odd possible_bit_def›)
lemma impossible_bit: ‹¬ bit a n›if‹¬ possible_bit TYPE('a) n› using that by (blast dest: bit_imp_possible_bit)
lemma possible_bit_less_imp: ‹possible_bit TYPE('a) j›if‹possible_bit TYPE('a) i›‹j ≤ i› using power_add [of 2 j ‹i - j›] that mult_not_zero [of ‹2 ^ j›‹2 ^ (i - j)›] by (simp add: possible_bit_def)
lemma possible_bit_min [simp]: ‹possible_bit TYPE('a) (min i j) ⟷ possible_bit TYPE('a) i ∨ possible_bit TYPE('a) j› by (auto simp: min_def elim: possible_bit_less_imp)
lemma bit_eqI: ‹a = b›if‹∧n. possible_bit TYPE('a) n ==> bit a n ⟷ bit b n› proof - have‹bit a n ⟷ bit b n›for n proof (cases ‹possible_bit TYPE('a) n›) case False thenshow ?thesis by (simp add: impossible_bit) next case True thenshow ?thesis by (rule that) qed thenshow ?thesis proof (induction a arbitrary: b rule: bit_induct) case (stable a) from stable(2) [of 0] have **: ‹even b ⟷ even a› by (simp add: bit_0) have‹b div 2 = b› proof (rule bit_iff_odd_imp_stable) fix n from stable have *: ‹bit b n ⟷ bit a n› by simp alsohave‹bit a n ⟷ odd a› using stable by (simp add: stable_imp_bit_iff_odd) finallyshow‹bit b n ⟷ odd b› by (simp add: **) qed from ** have‹a mod 2 = b mod 2› by (simp add: mod2_eq_if) thenhave‹a mod 2 + (a + b) = b mod 2 + (a + b)› by simp thenhave‹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 add: bit_0) 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) thenhave‹a = b div 2› by (rule rec.IH) thenhave‹2 * a = 2 * (b div 2)› by simp thenhave‹b mod 2 + 2 * a = b mod 2 + 2 * (b div 2)› by simp alsohave‹… = b› by (fact mod_mult_div_eq) finallyshow ?case by (auto simp: mod2_eq_if) qed qed
lemma bit_eq_rec: ‹a = b ⟷ (even a ⟷ even b) ∧ a div 2 = b div 2› (is‹?P = ?Q›) proof assume ?P thenshow ?Q by simp next assume ?Q thenhave‹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 add: bit_0) next case (Suc n) moreoverfrom‹a div 2 = b div 2›have‹bit (a div 2) n = bit (b div 2) n› by simp ultimatelyshow ?thesis by (simp add: bit_Suc) qed qed qed
lemma bit_eq_iff: ‹a = b ⟷ (∀n. possible_bit TYPE('a) n ⟶ bit a n ⟷ bit b n)› by (auto intro: bit_eqI simp add: possible_bit_def)
lemma bit_0_eq [simp]: ‹bit 0 = ⊥› proof - have‹0 div 2 ^ n = 0›for n unfolding div_exp_eq_funpow_half by (induction n) simp_all thenshow ?thesis by (simp add: fun_eq_iff bit_iff_odd) qed
lemma bit_double_Suc_iff: ‹bit (2 * a) (Suc n) ⟷ possible_bit TYPE('a) (Suc n) ∧ bit a n› using even_double_div_exp_iff [of n a] by (cases ‹possible_bit TYPE('a) (Suc n)›)
(auto simp: bit_iff_odd possible_bit_def)
lemma bit_double_iff [bit_simps]: ‹bit (2 * a) n ⟷ possible_bit TYPE('a) n ∧ n ≠ 0 ∧ bit a (n - 1)› by (cases n) (simp_all add: bit_0 bit_double_Suc_iff)
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› .. moreoverhave‹bit (2 * b) n ∨ n = 0 ⟷ bit (1 + 2 * b) n› using even_bit_succ_iff by simp ultimatelyshow ?thesis by (simp add: ac_simps) qed
lemma bit_exp_iff [bit_simps]: ‹bit (2 ^ m) n ⟷ possible_bit TYPE('a) n ∧ n = m› proof (cases ‹possible_bit TYPE('a) n›) case False thenshow ?thesis by (simp add: impossible_bit) next case True thenshow ?thesis proof (induction n arbitrary: m) case 0 show ?case by (simp add: bit_0) next case (Suc n) thenhave‹possible_bit TYPE('a) n› by (simp add: possible_bit_less_imp) show ?case proof (cases m) case 0 thenshow ?thesis by (simp add: bit_Suc) next case (Suc m) with Suc.IH [of m] ‹possible_bit TYPE('a) n›show ?thesis by (simp add: bit_double_Suc_iff) qed qed qed
lemma bit_1_iff [bit_simps]: ‹bit 1 n ⟷ n = 0› using bit_exp_iff [of 0 n] by auto
lemma bit_2_iff [bit_simps]: ‹bit 2 n ⟷ possible_bit TYPE('a) 1 ∧ n = 1› using bit_exp_iff [of 1 n] by auto
lemma bit_of_bool_iff [bit_simps]: ‹bit (of_bool b) n ⟷ n = 0 ∧ b› by (simp add: bit_1_iff)
lemma bit_mod_2_iff [simp]: ‹bit (a mod 2) n ⟷ n = 0 ∧ odd a› by (simp add: mod_2_eq_odd bit_simps)
lemma stable_index: obtains m where‹possible_bit TYPE('a) m› ‹∧n. possible_bit TYPE('a) n ==> n ≥ m ==> bit a n ⟷ bit a m› proof - have‹∃m. possible_bit TYPE('a) m ∧ (∀n≥m. possible_bit TYPE('a) n ⟶ bit a n ⟷ bit a m)› proof (induction a rule: bit_induct) case (stable a) show ?case by (rule exI [of _ ‹0::nat›]) (simp add: stable_imp_bit_iff_odd stable) next case (rec a b) thenobtain m where‹possible_bit TYPE('a) m› and hyp: ‹∧n. possible_bit TYPE('a) n ==> n ≥ m ==> bit a n ⟷ bit a m› by blast show ?case proof (cases ‹possible_bit TYPE('a) (Suc m)›) case True moreoverhave‹bit (of_bool b + 2 * a) n ⟷ bit (of_bool b + 2 * a) (Suc m)› if‹possible_bit TYPE('a) n›‹Suc m ≤ n›for n using hyp [of ‹n - 1›] possible_bit_less_imp [of n ‹n - 1›] rec.hyps that by (cases n) (simp_all add: bit_Suc) ultimatelyshow ?thesis by blast next case False have‹bit (of_bool b + 2 * a) n ⟷ bit (of_bool b + 2 * a) m› if‹possible_bit TYPE('a) n›‹m ≤ n›for n proof (cases ‹m = n›) case True thenshow ?thesis by simp next case False with‹m ≤ n›have‹m 🚫› by simp with‹¬ possible_bit TYPE('a) (Suc m)› have‹¬ possible_bit TYPE('a) n›using possible_bit_less_imp [of n ‹Suc m›] by auto with‹possible_bit TYPE('a) n› show ?thesis by simp qed with‹possible_bit TYPE('a) m›show ?thesis by blast qed qed with that show thesis by blast 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 thenhave‹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 qed (auto simp: div_mult2_eq bit_nat_def)
end
lemma possible_bit_nat [simp]: ‹possible_bit TYPE(nat) n› by (simp add: possible_bit_def)
lemma bit_Suc_0_iff [bit_simps]: ‹bit (Suc 0) n ⟷ n = 0› using bit_1_iff [of n, where ?'a = nat] by simp
lemma not_bit_Suc_0_Suc [simp]: ‹¬ bit (Suc 0) (Suc n)› by (simp add: bit_Suc)
lemma not_bit_Suc_0_numeral [simp]: ‹¬ bit (Suc 0) (numeral n)› by (simp add: numeral_eq_Suc)
context semiring_bits begin
lemma bit_of_nat_iff [bit_simps]: ‹bit (of_nat m) n ⟷ possible_bit TYPE('a) n ∧ bit m n› proof (cases ‹possible_bit TYPE('a) n›) case False thenshow ?thesis by (simp add: impossible_bit) next case True thenhave‹bit (of_nat m) n ⟷ bit m n› proof (induction m arbitrary: n rule: nat_bit_induct) case zero thenshow ?case by simp next case (even m) thenshow ?case by (cases n)
(auto simp: bit_double_iff Bit_Operations.bit_double_iff possible_bit_def bit_0 dest: mult_not_zero) next case (odd m) thenshow ?case by (cases n)
(auto simp: bit_double_iff even_bit_succ_iff possible_bit_def
Bit_Operations.bit_Suc Bit_Operations.bit_0 dest: mult_not_zero) qed with True show ?thesis by simp qed
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 thenshow‹P k› proof (induction n arbitrary: k rule: nat_bit_induct) case zero thenshow ?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 thenshow‹P k› proof (induction n arbitrary: k rule: nat_bit_induct) case zero thenshow ?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›) alsohave‹… = - int (2 * n) - 1› by (simp add: algebra_simps) finallyshow ?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›) alsohave‹… = - int (Suc (2 * n)) - 1› by (simp add: algebra_simps) finallyshow ?case using odd.prems by simp qed qed
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 qed (auto simp: zdiv_zmult2_eq bit_int_def)
end
lemma possible_bit_int [simp]: ‹possible_bit TYPE(int) n› by (simp add: possible_bit_def)
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› ultimatelyhave‹k = int m› by simp thenshow ?thesis by (simp add: bit_simps) next case False thenshow ?thesis by simp qed
subsection‹Bit operations›
class semiring_bit_operations = semiring_bits + 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› and push_bit :: ‹nat ==> 'a ==> 'a› and drop_bit :: ‹nat ==> 'a ==> 'a› and take_bit :: ‹nat ==> 'a ==> 'a› assumes and_rec: ‹a AND b = of_bool (odd a ∧ odd b) + 2 * ((a div 2) AND (b div 2))› and or_rec: ‹a OR b = of_bool (odd a ∨ odd b) + 2 * ((a div 2) OR (b div 2))› and xor_rec: ‹a XOR b = of_bool (odd a ≠ odd b) + 2 * ((a div 2) XOR (b div 2))› 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 unset_bit_eq_or_xor: ‹unset_bit n a = (a OR push_bit n 1) XOR push_bit n 1› and flip_bit_eq_xor: ‹flip_bit n a = a XOR push_bit n 1› and push_bit_eq_mult: ‹push_bit n a = a * 2 ^ n› and drop_bit_eq_div: ‹drop_bit n a = a div 2 ^ n› and take_bit_eq_mod: ‹take_bit n a = a mod 2 ^ n› begin
text‹ We want the bitwise operations to bind slightly weaker than ‹+›and ‹-›. Logically, 🍋‹push_bit›, 🍋‹drop_bit›and 🍋‹take_bit› are just aliases; having them as separate operations makes proofs easier, otherwise proof automation would fiddle with concrete expressions 🍋‹2 ^ n›in a way obfuscating the basic algebraic relationships between those operations. For the sake of code generation operations are specified as definitional class operations, taking 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 bit_and_iff [bit_simps]: ‹bit (a AND b) n ⟷ bit a n ∧ bit b n› proof (induction n arbitrary: a b) case 0 show ?case by (simp add: bit_0 and_rec [of a b] even_bit_succ_iff) next case (Suc n) from Suc [of ‹a div 2›‹b div 2›] show ?case by (simp add: and_rec [of a b] bit_Suc)
(auto simp flip: bit_Suc simp add: bit_double_iff dest: bit_imp_possible_bit) qed
lemma bit_or_iff [bit_simps]: ‹bit (a OR b) n ⟷ bit a n ∨ bit b n› proof (induction n arbitrary: a b) case 0 show ?case by (simp add: bit_0 or_rec [of a b] even_bit_succ_iff) next case (Suc n) from Suc [of ‹a div 2›‹b div 2›] show ?case by (simp add: or_rec [of a b] bit_Suc)
(auto simp flip: bit_Suc simp add: bit_double_iff dest: bit_imp_possible_bit) qed
lemma bit_xor_iff [bit_simps]: ‹bit (a XOR b) n ⟷ bit a n ≠ bit b n› proof (induction n arbitrary: a b) case 0 show ?case by (simp add: bit_0 xor_rec [of a b] even_bit_succ_iff) next case (Suc n) from Suc [of ‹a div 2›‹b div 2›] show ?case by (simp add: xor_rec [of a b] bit_Suc)
(auto simp flip: bit_Suc simp add: bit_double_iff dest: bit_imp_possible_bit) qed
sublocale "and": semilattice ‹(AND)› by standard (auto simp: bit_eq_iff bit_and_iff)
sublocale or: semilattice_neutr ‹(OR)› 0 by standard (auto simp: bit_eq_iff bit_or_iff)
sublocale xor: comm_monoid ‹(XOR)› 0 by standard (auto simp: 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 simp: bit_0)
lemma even_or_iff: ‹even (a OR b) ⟷ even a ∧ even b› using bit_or_iff [of a b 0] by (auto simp: bit_0)
lemma even_xor_iff: ‹even (a XOR b) ⟷ (even a ⟷ even b)› using bit_xor_iff [of a b 0] by (auto simp: bit_0)
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: bit_1_iff bit_0)
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: bit_1_iff bit_0)
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: bit_1_iff odd_bit_iff_bit_pred bit_0 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 xor_self_eq [simp]: ‹a XOR a = 0› by (rule bit_eqI) (simp add: bit_simps)
lemma inc_mask_eq_exp: ‹mask n + 1 = 2 ^ n› proof (induction n) case 0 thenshow ?case by simp next case (Suc n) from Suc.IH [symmetric] have‹2 ^ Suc n = 2 * mask n + 2› by (simp add: algebra_simps) alsohave‹… = 2 * mask n + 1 + 1› by (simp add: add.assoc) finallyhave *: ‹2 ^ Suc n = 2 * mask n + 1 + 1› . thenshow ?case by (simp add: mask_eq_exp_minus_1) qed
lemma mask_eq_iff_eq_exp: ‹mask n = a ⟷ a + 1 = 2 ^ n› by (auto simp flip: inc_mask_eq_exp)
lemma eq_mask_iff_eq_exp: ‹a = mask n ⟷ a + 1 = 2 ^ n› by (auto simp flip: inc_mask_eq_exp)
lemma mask_Suc_double: ‹mask (Suc n) = 1 OR 2 * mask n› proof - have‹mask (Suc n) + 1 = (mask n + 1) + (mask n + 1)› by (simp add: inc_mask_eq_exp mult_2) alsohave‹… = (1 OR 2 * mask n) + 1› by (simp add: one_or_eq mult_2_right algebra_simps) finallyshow ?thesis by simp qed
lemma bit_mask_iff [bit_simps]: ‹bit (mask m) n ⟷ possible_bit TYPE('a) n ∧ n 🚫› proof (cases ‹possible_bit TYPE('a) n›) case False thenshow ?thesis by (simp add: impossible_bit) next case True thenhave‹bit (mask m) n ⟷ n 🚫› proof (induction m arbitrary: n) case 0 thenshow ?case by (simp add: bit_iff_odd) next case (Suc m) show ?case proof (cases n) case 0 thenshow ?thesis by (simp add: bit_0 mask_Suc_double even_or_iff) next case (Suc n) with Suc.prems have‹possible_bit TYPE('a) n› using possible_bit_less_imp by auto with Suc.IH [of n] have‹bit (mask m) n ⟷ n 🚫› . with Suc.prems show ?thesis by (simp add: Suc mask_Suc_double bit_simps) qed qed with True show ?thesis by simp qed
lemma even_mask_iff: ‹even (mask n) ⟷ n = 0› using bit_mask_iff [of n 0] by (auto simp: bit_0)
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 bit_push_bit_iff [bit_simps]: ‹bit (push_bit m a) n ⟷ m ≤ n ∧ possible_bit TYPE('a) n ∧ bit a (n - m)› proof (induction n arbitrary: m) case 0 thenshow ?case by (auto simp: bit_0 push_bit_eq_mult) next case (Suc n) show ?case proof (cases m) case 0 thenshow ?thesis by (auto simp: bit_imp_possible_bit) next case (Suc m') with Suc.prems Suc.IH [of m'] show ?thesis apply (simp add: push_bit_double) apply (auto simp: possible_bit_less_imp bit_simps mult.commute [of _ 2]) done qed qed
lemma funpow_double_eq_push_bit: ‹times 2 ^^ n = push_bit n› by (induction n) (simp_all add: fun_eq_iff push_bit_double ac_simps)
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_of_0 [simp]: ‹push_bit n 0 = 0› by (simp add: push_bit_eq_mult)
lemma push_bit_of_1 [simp]: ‹push_bit n 1 = 2 ^ n› by (simp add: push_bit_eq_mult)
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 bit_drop_bit_eq [bit_simps]: ‹bit (drop_bit n a) = bit a ∘ (+) n› by rule (simp add: drop_bit_eq_div bit_iff_odd div_exp_eq)
lemma disjunctive_xor_eq_or: ‹a XOR b = a OR b›if‹a AND b = 0› using that by (auto simp: bit_eq_iff bit_simps)
lemma disjunctive_add_eq_or: ‹a + b = a OR b›if‹a AND b = 0› proof (rule bit_eqI) fix n assume‹possible_bit TYPE('a) n› moreoverfrom that have‹∧n. ¬ bit (a AND b) n› by simp thenhave‹∧n. ¬ bit a n ∨¬ bit b n› by (simp add: bit_simps) ultimatelyshow‹bit (a + b) n ⟷ bit (a OR b) n› proof (induction n arbitrary: a b) case 0 from"0"(2)[of 0] show ?case by (auto simp: even_or_iff bit_0) next case (Suc n) from Suc.prems(2) [of 0] have even: ‹even a ∨ even b› by (auto simp: bit_0) have bit: ‹¬ bit (a div 2) n ∨¬ bit (b div 2) n›for n using Suc.prems(2) [of ‹Suc n›] by (simp add: bit_Suc) from Suc.prems have‹possible_bit TYPE('a) n› using possible_bit_less_imp by force with‹∧n. ¬ bit (a div 2) n ∨¬ bit (b div 2) n› Suc.IH [of ‹a div 2›‹b div 2›] have IH: ‹bit (a div 2 + b div 2) n ⟷ bit (a div 2 OR b div 2) n› by (simp add: bit_Suc) 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 alsohave‹… = of_bool (odd a ∨ odd b) + 2 * (a div 2 + b div 2)› using even by (auto simp: algebra_simps mod2_eq_if) finallyhave‹bit ((a + b) div 2) n ⟷ bit (a div 2 + b div 2) n› using‹possible_bit TYPE('a) (Suc n)›by simp (simp_all flip: bit_Suc add: bit_double_iff possible_bit_def) alsohave‹…⟷ bit (a div 2 OR b div 2) n› by (rule IH) finallyshow ?case by (simp add: bit_simps flip: bit_Suc) qed qed
lemma disjunctive_add_eq_xor: ‹a + b = a XOR b›if‹a AND b = 0› using that by (simp add: disjunctive_add_eq_or disjunctive_xor_eq_or)
lemma take_bit_0 [simp]: "take_bit 0 a = 0" by (simp add: take_bit_eq_mod)
lemma bit_take_bit_iff [bit_simps]: ‹bit (take_bit m a) n ⟷ n 🚫∧ bit a n› proof - have‹push_bit m (drop_bit m a) AND take_bit m a = 0› (is‹?lhs = _›) proof (rule bit_eqI) fix n show‹bit ?lhs n ⟷ bit 0 n› proof (cases ‹m ≤ n›) case False thenshow ?thesis by (simp add: bit_simps) next case True moreover define q where‹q = n - m› ultimatelyhave‹n = m + q›by simp moreoverhave‹¬ bit (take_bit m a) (m + q)› by (simp add: take_bit_eq_mod bit_iff_odd flip: div_exp_eq) ultimatelyshow ?thesis by (simp add: bit_simps) qed qed thenhave‹push_bit m (drop_bit m a) XOR take_bit m a = push_bit m (drop_bit m a) + take_bit m a› by (simp add: disjunctive_add_eq_xor) alsohave‹… = a› by (simp add: bits_ident) finallyhave‹bit (push_bit m (drop_bit m a) XOR take_bit m a) n ⟷ bit a n› by simp alsohave‹…⟷ (m ≤ n ∨ n 🚫) ∧ bit a n› by auto alsohave‹…⟷ m ≤ n ∧ bit a n ∨ n 🚫∧ bit a n› by auto alsohave‹m ≤ n ∧ bit a n ⟷ bit (push_bit m (drop_bit m a)) n› by (auto simp: bit_simps bit_imp_possible_bit) finallyshow ?thesis by (auto simp: bit_simps) qed
lemma take_bit_Suc: ‹take_bit (Suc n) a = take_bit n (a div 2) * 2 + a mod 2› (is‹?lhs = ?rhs›) proof (rule bit_eqI) fix m assume‹possible_bit TYPE('a) m› thenshow‹bit ?lhs m ⟷ bit ?rhs m› apply (cases a rule: parity_cases; cases m) apply (simp_all add: bit_simps even_bit_succ_iff mult.commute [of _ 2] add.commute [of _ 1] flip: bit_Suc) apply (simp_all add: bit_0) done 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 (rule bit_eqI) (simp add: bit_simps)
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 (rule bit_eqI) (simp add: bit_simps)
lemma drop_bit_of_1 [simp]: ‹drop_bit n 1 = of_bool (n = 0)› by (rule bit_eqI) (simp add: bit_simps ac_simps)
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 (rule bit_eqI) (simp add: bit_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)› by (rule bit_eqI) (auto simp: bit_simps)
lemma take_bit_push_bit: ‹take_bit m (push_bit n a) = push_bit n (take_bit (m - n) a)› by (rule bit_eqI) (auto simp: bit_simps)
lemma take_bit_drop_bit: ‹take_bit m (drop_bit n a) = drop_bit n (take_bit (m + n) a)› by (rule bit_eqI) (auto simp: bit_simps)
lemma drop_bit_take_bit: ‹drop_bit m (take_bit n a) = take_bit (n - m) (drop_bit m a)› by (rule bit_eqI) (auto simp: bit_simps)
lemma even_push_bit_iff [simp]: ‹even (push_bit n a) ⟷ n ≠ 0 ∨ even a› by (simp add: push_bit_eq_mult) auto
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 mask n)› if‹a div 2 = a› by (rule bit_eqI) (use that in‹simp add: bit_simps stable_imp_bit_iff_odd›)
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› .. thenhave‹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 thenshow ?Q by (simp add: take_bit_eq_mod mod_0_imp_dvd) next assume ?Q thenobtain b where‹a = push_bit n b› by (rule exp_dvdE) thenshow ?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 thenhave‹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› .. alsohave‹¬ bit (take_bit n a) (n + m)› unfolding bit_simps by (simp add: bit_simps) finallyshow‹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 thenhave‹¬ bit a (n + (m - n))› by (simp add: bit_simps) thenshow‹bit (take_bit n a) m ⟷ bit a m› by (cases ‹m 🚫›) (auto simp: bit_simps) qed qed
lemma impossible_bit_imp_take_bit_eq_self: ‹take_bit n a = a›if‹¬ possible_bit TYPE('a) n› proof - have‹drop_bit n a = 0› proof (rule bit_eqI) fix m show‹bit (drop_bit n a) m ⟷ bit 0 m› using possible_bit_less_imp [of ‹n + m› n] that by (auto simp add: bit_simps dest: bit_imp_possible_bit) qed thenshow ?thesis by (simp add: take_bit_eq_self_iff_drop_bit_eq_0) qed
lemma drop_bit_exp_eq: ‹drop_bit m (2 ^ n) = of_bool (m ≤ n ∧ possible_bit TYPE('a) n) * 2 ^ (n - m)› by (auto simp: bit_eq_iff bit_simps)
lemma take_bit_and [simp]: ‹take_bit n (a AND b) = take_bit n a AND take_bit n b› by (auto simp: bit_eq_iff bit_simps)
lemma take_bit_or [simp]: ‹take_bit n (a OR b) = take_bit n a OR take_bit n b› by (auto simp: bit_eq_iff bit_simps)
lemma take_bit_xor [simp]: ‹take_bit n (a XOR b) = take_bit n a XOR take_bit n b› by (auto simp: bit_eq_iff bit_simps)
lemma push_bit_and [simp]: ‹push_bit n (a AND b) = push_bit n a AND push_bit n b› by (auto simp: bit_eq_iff bit_simps)
lemma push_bit_or [simp]: ‹push_bit n (a OR b) = push_bit n a OR push_bit n b› by (auto simp: bit_eq_iff bit_simps)
lemma push_bit_xor [simp]: ‹push_bit n (a XOR b) = push_bit n a XOR push_bit n b› by (auto simp: bit_eq_iff bit_simps)
lemma drop_bit_and [simp]: ‹drop_bit n (a AND b) = drop_bit n a AND drop_bit n b› by (auto simp: bit_eq_iff bit_simps)
lemma drop_bit_or [simp]: ‹drop_bit n (a OR b) = drop_bit n a OR drop_bit n b› by (auto simp: bit_eq_iff bit_simps)
lemma drop_bit_xor [simp]: ‹drop_bit n (a XOR b) = drop_bit n a XOR drop_bit n b› by (auto simp: bit_eq_iff bit_simps)
lemma take_bit_of_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 (auto simp: bit_eq_iff bit_simps)
lemma or_eq_0_iff: ‹a OR b = 0 ⟷ a = 0 ∧ b = 0› by (auto simp: bit_eq_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› by (cases ‹possible_bit TYPE('a) n›) (simp_all add: bit_eq_iff bit_simps impossible_bit)
lemma bit_set_bit_iff [bit_simps]: ‹bit (set_bit m a) n ⟷ bit a n ∨ (m = n ∧ possible_bit TYPE('a) n)› by (auto simp: set_bit_eq_or 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 simp: bit_0)
lemma bit_unset_bit_iff [bit_simps]: ‹bit (unset_bit m a) n ⟷ bit a n ∧ m ≠ n› by (auto simp: unset_bit_eq_or_xor bit_simps dest: bit_imp_possible_bit)
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 simp: bit_0)
lemma bit_flip_bit_iff [bit_simps]: ‹bit (flip_bit m a) n ⟷ (m = n ⟷¬ bit a n) ∧ possible_bit TYPE('a) n› by (auto simp: bit_eq_iff bit_simps flip_bit_eq_xor bit_imp_possible_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 simp: possible_bit_def bit_0)
lemma and_exp_eq_0_iff_not_bit: ‹a AND 2 ^ n = 0 ⟷¬ bit a n› (is‹?P ⟷ ?Q›) using bit_imp_possible_bit[of a n] by (auto simp: bit_eq_iff bit_simps)
lemma bit_sum_mult_2_cases: assumes a: ‹∀j. ¬ bit a (Suc j)› shows‹bit (a + 2 * b) n = (if n = 0 then odd a else bit (2 * b) n)› proof - from a have‹n = 0›if‹bit a n›for n using that by (cases n) simp_all thenhave‹a = 0 ∨ a = 1› by (auto simp: bit_eq_iff bit_1_iff) thenshow ?thesis by (cases n) (auto simp: bit_0 bit_double_iff even_bit_succ_iff) qed
lemma set_bit_0: ‹set_bit 0 a = 1 + 2 * (a div 2)› by (auto simp: bit_eq_iff bit_simps even_bit_succ_iff simp flip: bit_Suc)
lemma set_bit_Suc: ‹set_bit (Suc n) a = a mod 2 + 2 * set_bit n (a div 2)› by (auto simp: bit_eq_iff bit_sum_mult_2_cases bit_simps bit_0 simp flip: bit_Suc
elim: possible_bit_less_imp)
lemma unset_bit_0: ‹unset_bit 0 a = 2 * (a div 2)› by (auto simp: bit_eq_iff bit_simps simp flip: bit_Suc)
lemma unset_bit_Suc: ‹unset_bit (Suc n) a = a mod 2 + 2 * unset_bit n (a div 2)› by (auto simp: bit_eq_iff bit_sum_mult_2_cases bit_simps bit_0 simp flip: bit_Suc)
lemma flip_bit_0: ‹flip_bit 0 a = of_bool (even a) + 2 * (a div 2)› by (auto simp: bit_eq_iff bit_simps even_bit_succ_iff bit_0 simp flip: bit_Suc)
lemma flip_bit_Suc: ‹flip_bit (Suc n) a = a mod 2 + 2 * flip_bit n (a div 2)› by (auto simp: bit_eq_iff bit_sum_mult_2_cases bit_simps bit_0 simp flip: bit_Suc
elim: possible_bit_less_imp)
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: 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: 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: 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: bit_take_bit_iff bit_flip_bit_iff)
lemma mask_eq_0_iff [simp]: ‹mask n = 0 ⟷ n = 0› by (cases n) (simp_all add: mask_Suc_double or_eq_0_iff)
lemma bit_horner_sum_bit_iff [bit_simps]: ‹bit (horner_sum of_bool 2 bs) n ⟷ possible_bit TYPE('a) n ∧ n 🚫 bs ∧ bs ! n› proof (induction bs arbitrary: n) case Nil thenshow ?case by simp next case (Cons b bs) show ?case proof (cases n) case 0 thenshow ?thesis by (simp add: bit_0) next case (Suc m) with bit_rec [of _ n] Cons.prems Cons.IH [of m] show ?thesis by (simp add: bit_simps)
(auto simp: possible_bit_less_imp bit_simps simp flip: bit_Suc) qed qed
lemma horner_sum_bit_eq_take_bit: ‹horner_sum of_bool 2 (map (bit a) [0..🚫) = take_bit n a› by (rule bit_eqI) (auto simp: bit_simps)
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: bit_eq_iff bit_take_bit_iff bit_horner_sum_bit_iff)
lemma take_bit_sum: ‹take_bit n a = (∑k = 0..🚫 push_bit k (of_bool (bit a k)))› by (simp flip: horner_sum_bit_eq_take_bit add: horner_sum_eq_sum push_bit_eq_mult)
lemma set_bit_eq: ‹set_bit n a = a + of_bool (¬ bit a n) * 2 ^ n› proof - have‹a AND of_bool (¬ bit a n) * 2 ^ n = 0› by (auto simp: bit_eq_iff bit_simps) thenshow ?thesis by (auto simp: bit_eq_iff bit_simps disjunctive_add_eq_or) qed
end
class ring_bit_operations = semiring_bit_operations + ring_parity + fixes not :: ‹'a ==> 'a› (‹NOT›) assumes not_eq_complement: ‹NOT a = - a - 1› begin
text‹ For the sake of code generation 🍋‹not›is specified as definitional class operation. Note that 🍋‹not›has no sensible definition for unlimited but only positive bit strings (type 🍋‹nat›). ›
lemma bits_minus_1_mod_2_eq [simp]: ‹(- 1) mod 2 = 1› by (simp add: mod_2_eq_odd)
lemma minus_eq_not_plus_1: ‹- a = NOT a + 1› using not_eq_complement [of a] by simp
lemma minus_eq_not_minus_1: ‹- a = NOT (a - 1)› using not_eq_complement [of ‹a - 1›] by simp (simp add: algebra_simps)
lemma not_rec: ‹NOT a = of_bool (even a) + 2 * NOT (a div 2)› by (simp add: not_eq_complement algebra_simps mod_2_eq_odd flip: minus_mod_eq_mult_div)
lemma decr_eq_not_minus: ‹a - 1 = NOT (- a)› using not_eq_complement [of ‹- a›] by simp
lemma even_not_iff [simp]: ‹even (NOT a) ⟷ odd a› by (simp add: not_eq_complement)
lemma bit_not_iff [bit_simps]: ‹bit (NOT a) n ⟷ possible_bit TYPE('a) n ∧¬ bit a n› proof (cases ‹possible_bit TYPE('a) n›) case False thenshow ?thesis by (auto dest: bit_imp_possible_bit) next case True moreoverhave‹bit (NOT a) n ⟷¬ bit a n› using‹possible_bit TYPE('a) n›proof (induction n arbitrary: a) case 0 thenshow ?case by (simp add: bit_0) next case (Suc n) from Suc.prems Suc.IH [of ‹a div 2›] show ?case by (simp add: impossible_bit possible_bit_less_imp not_rec [of a] even_bit_succ_iff bit_double_iff flip: bit_Suc) qed ultimatelyshow ?thesis by simp qed
lemma bit_not_exp_iff [bit_simps]: ‹bit (NOT (2 ^ m)) n ⟷ possible_bit TYPE('a) n ∧ n ≠ m› by (auto simp: bit_not_iff bit_exp_iff)
lemma bit_minus_iff [bit_simps]: ‹bit (- a) n ⟷ possible_bit TYPE('a) n ∧¬ bit (a - 1) n› by (simp add: minus_eq_not_minus_1 bit_not_iff)
lemma bit_minus_1_iff [simp]: ‹bit (- 1) n ⟷ possible_bit TYPE('a) n› by (simp add: bit_minus_iff)
lemma bit_minus_exp_iff [bit_simps]: ‹bit (- (2 ^ m)) n ⟷ possible_bit TYPE('a) n ∧ n ≥ m› by (auto simp: bit_simps simp flip: mask_eq_exp_minus_1)
lemma bit_minus_2_iff [simp]: ‹bit (- 2) n ⟷ possible_bit TYPE('a) n ∧ n > 0› by (simp add: bit_minus_iff bit_1_iff)
lemma bit_decr_iff: ‹bit (a - 1) n ⟷ possible_bit TYPE('a) n ∧¬ bit (- a) n› by (simp add: decr_eq_not_minus bit_not_iff)
lemma bit_not_iff_eq: ‹bit (NOT a) n ⟷ 2 ^ n ≠ 0 ∧¬ bit a n› by (simp add: bit_simps possible_bit_def)
sublocale "and": semilattice_neutr ‹(AND)›‹- 1› by standard (rule bit_eqI, simp add: bit_and_iff)
sublocale bit: abstract_boolean_algebra ‹(AND)›‹(OR)› NOT 0 ‹- 1› by standard (auto simp: bit_and_iff bit_or_iff bit_not_iff intro: bit_eqI)
sublocale bit: abstract_boolean_algebra_sym_diff ‹(AND)›‹(OR)› NOT 0 ‹- 1›‹(XOR)› proof show‹∧x y. x XOR y = x AND NOT y OR NOT x AND y› by (intro bit_eqI) (auto simp: bit_simps) 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 and_eq_minus_1_iff: ‹a AND b = - 1 ⟷ a = - 1 ∧ b = - 1› by (auto simp: bit_eq_iff bit_simps)
lemma disjunctive_and_not_eq_xor: ‹a AND NOT b = a XOR b›if‹NOT a AND b = 0› using that by (auto simp: bit_eq_iff bit_simps)
lemma disjunctive_diff_eq_and_not: ‹a - b = a AND NOT b›if‹NOT a AND b = 0› proof - from that have‹NOT a + b = NOT a OR b› by (rule disjunctive_add_eq_or) thenhave‹NOT (NOT a + b) = NOT (NOT a OR b)› by simp thenshow ?thesis by (simp add: not_add_distrib) qed
lemma disjunctive_diff_eq_xor: ‹a AND NOT b = a XOR b›if‹NOT a AND b = 0› using that by (simp add: disjunctive_and_not_eq_xor disjunctive_diff_eq_and_not)
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: 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› by (auto simp: bit_eq_iff bit_simps)
lemma take_bit_not_eq_mask_diff: ‹take_bit n (NOT a) = mask n - take_bit n a› proof - have‹NOT (mask n) AND take_bit n a = 0› by (simp add: bit_eq_iff bit_simps) moreoverhave‹take_bit n (NOT a) = mask n AND NOT (take_bit n a)› by (auto simp: bit_eq_iff bit_simps) ultimatelyshow ?thesis by (simp add: disjunctive_diff_eq_and_not) 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 [simp]: ‹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 [simp]: ‹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 mask_eq_minus_one_if_not_possible_bit: ‹mask n = - 1›if‹¬ possible_bit TYPE('a) n› using that mask_eq_take_bit_minus_one [of n] impossible_bit_imp_take_bit_eq_self [of n ‹- 1›] by simp
lemma unset_bit_eq_and_not: ‹unset_bit n a = a AND NOT (push_bit n 1)› by (rule bit_eqI) (auto simp: bit_simps)
lemma push_bit_Suc_minus_numeral [simp]: ‹push_bit (Suc n) (- numeral k) = push_bit n (- numeral (Num.Bit0 k))› usinglocal.push_bit_Suc_numeral push_bit_minus by presburger
lemma unset_bit_eq: ‹unset_bit n a = a - of_bool (bit a n) * 2 ^ n› proof - have‹NOT a AND of_bool (bit a n) * 2 ^ n = 0› by (auto simp: bit_eq_iff bit_simps) moreoverhave‹unset_bit n a = a AND NOT (of_bool (bit a n) * 2 ^ n)› by (auto simp: bit_eq_iff bit_simps) ultimatelyshow ?thesis by (simp add: disjunctive_diff_eq_and_not) qed
end
subsection‹Common algebraic structure›
class linordered_euclidean_semiring_bit_operations =
linordered_euclidean_semiring + semiring_bit_operations begin
lemma possible_bit [simp]: ‹possible_bit TYPE('a) n› by (simp add: possible_bit_def)
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 alsohave‹of_nat (m div 2 ^ n) = of_nat m div of_nat (2 ^ n)› by (simp add: of_nat_div) finallyshow ?thesis by (simp add: bit_iff_odd semiring_bits_class.bit_iff_odd) qed
lemma drop_bit_mask_eq: ‹drop_bit m (mask n) = mask (n - m)› by (rule bit_eqI) (auto simp: bit_simps possible_bit_def)
lemma bit_push_bit_iff': ‹bit (push_bit m a) n ⟷ m ≤ n ∧ bit a (n - m)› by (simp add: bit_simps)
lemma mask_half: ‹mask n div 2 = mask (n - 1)› by (cases n) (simp_all add: mask_Suc_double one_or_eq)
lemma take_bit_Suc_from_most: ‹take_bit (Suc n) a = 2 ^ n * of_bool (bit a n) + take_bit n a› using mod_mult2_eq' [of a ‹2 ^ n› 2] by (simp only: take_bit_eq_mod power_Suc2)
(simp_all add: bit_iff_odd odd_iff_mod_2_eq_one)
lemma take_bit_nonnegative [simp]: ‹0 ≤ take_bit n a› using horner_sum_nonnegative by (simp flip: horner_sum_bit_eq_take_bit)
lemma not_take_bit_negative [simp]: ‹¬ take_bit n a 🚫› by (simp add: not_less)
lemma bit_imp_take_bit_positive: ‹0 🚫 m a›if‹n 🚫›and‹bit a n› proof (rule ccontr) assume‹¬ 0 🚫 m a› thenhave‹take_bit m a = 0› by (auto simp: not_less intro: order_antisym) thenhave‹bit (take_bit m a) 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 a * take_bit n b) = take_bit n (a * b)› by (simp add: take_bit_eq_mod mod_mult_eq)
lemma drop_bit_push_bit: ‹drop_bit m (push_bit n a) = drop_bit (m - n) (push_bit (n - m) a)› by (cases ‹m ≤ n›)
(auto simp: mult.left_commute [of _ ‹2 ^ n›] mult.commute [of _ ‹2 ^ n›] mult.assoc
mult.commute [of a] drop_bit_eq_div push_bit_eq_mult not_le power_add Orderings.not_le dest!: le_Suc_ex less_imp_Suc_add)
end
subsection‹Instance 🍋‹int›\›
locale fold2_bit_int = fixes f :: ‹bool ==> bool ==> bool› begin
context begin
function F :: ‹int ==> int ==> int› where‹F k l = (if k ∈ {0, - 1} ∧ l ∈ {0, - 1} then - of_bool (f (odd k) (odd l)) else of_bool (f (odd k) (odd l)) + 2 * (F (k div 2) (l div 2)))› by auto
private terminationproof (relation ‹measure (λ(k, l). nat (∣k∣ + ∣l∣))›) have less_eq: ‹∣k div 2∣≤∣k∣›for k :: int by (cases k) (simp_all add: divide_int_def nat_add_distrib) thenhave less: ‹∣k div 2∣🚫∣k∣›if‹k ∉ {0, - 1}›for k :: int using that by (auto simp: less_le [of k]) 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 - from that have *: ‹k ∉ {0, - 1} ∨ l ∉ {0, - 1}› by simp thenhave‹0 🚫∣k∣ + ∣l∣› by auto moreoverfrom * have‹∣k div 2∣ + ∣l div 2∣🚫∣k∣ + ∣l∣› proof assume‹k ∉ {0, - 1}› thenhave‹∣k div 2∣🚫∣k∣› by (rule less) with less_eq [of l] show ?thesis by auto next assume‹l ∉ {0, - 1}› thenhave‹∣l div 2∣🚫∣l∣› by (rule less) with less_eq [of k] show ?thesis by auto qed ultimatelyshow ?thesis by (simp only: in_measure split_def fst_conv snd_conv nat_mono_iff) qed qed
declare F.simps [simp del]
lemma rec: ‹F k l = of_bool (f (odd k) (odd l)) + 2 * (F (k div 2) (l div 2))› for k l :: int proof (cases ‹k ∈ {0, - 1} ∧ l ∈ {0, - 1}›) case True thenshow ?thesis by (auto simp: F.simps [of 0] F.simps [of ‹- 1›]) next case False thenshow ?thesis by (auto simp: ac_simps F.simps [of k l]) qed
lemma bit_iff: ‹bit (F k l) n ⟷ f (bit k n) (bit l n)›for k l :: int proof (induction n arbitrary: k l) case 0 thenshow ?case by (simp add: rec [of k l] bit_0) next case (Suc n) thenshow ?case by (simp add: rec [of k l] bit_Suc) qed
end
end
instantiation int :: ring_bit_operations begin
definition not_int :: ‹int ==> int› where‹not_int k = - k - 1›
definition mask_int :: ‹nat ==> int› where‹mask n = (2 :: int) ^ n - 1›
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›
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
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 (NOT k) n ⟷¬ bit k n›for k :: int proof (rule sym, induction n arbitrary: k) case 0 thenshow ?case by (simp add: bit_0 not_int_def) next case (Suc n) thenshow ?case by (simp add: bit_Suc not_int_div_2) qed
instanceproof fix k l :: int and m n :: nat show‹unset_bit n k = (k OR push_bit n 1) XOR push_bit n 1› by (rule bit_eqI)
(auto simp: unset_bit_int_def
and_int.bit_iff or_int.bit_iff xor_int.bit_iff bit_not_int_iff push_bit_int_def bit_simps) qed (fact and_int.rec or_int.rec xor_int.rec mask_int_def set_bit_int_def flip_bit_int_def
push_bit_int_def drop_bit_int_def take_bit_int_def not_int_def)+
end
instance int :: linordered_euclidean_semiring_bit_operations ..
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 ⟷ possible_bit TYPE('a) n ∧ bit k n› proof (cases ‹possible_bit TYPE('a) n›) case False thenshow ?thesis by (simp add: impossible_bit) next case True thenhave‹bit (of_int k) n ⟷ bit k n› proof (induction k arbitrary: n rule: int_bit_induct) case zero thenshow ?case by simp next case minus thenshow ?case by simp next case (even k) thenshow ?case using bit_double_iff [of ‹of_int k› n] Bit_Operations.bit_double_iff [of k n] by (cases n) (auto simp: ac_simps possible_bit_def dest: mult_not_zero) next case (odd k) thenshow ?case using bit_double_iff [of ‹of_int k› n] by (cases n)
(auto simp: ac_simps bit_double_iff even_bit_succ_iff Bit_Operations.bit_0 Bit_Operations.bit_Suc
possible_bit_def dest: mult_not_zero) qed with True 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 Bit_Operations.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 Bit_Operations.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_not_numeral: ‹of_int (NOT (numeral k)) = NOT (numeral k)› by (simp add: local.of_int_not_eq)
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 take_bit_int_less_exp [simp]: ‹take_bit n k 🚫 ^ n›for k :: int by (simp add: take_bit_eq_mod)
lemma take_bit_int_eq_self_iff: ‹take_bit n k = k ⟷ 0 ≤ k ∧ k 🚫 ^ n› (is‹?P ⟷ ?Q›) for k :: int proof assume ?P moreovernote take_bit_int_less_exp [of n k] take_bit_nonnegative [of n k] ultimatelyshow ?Q by simp next assume ?Q thenshow ?P by (simp add: take_bit_eq_mod) qed
lemma take_bit_int_eq_self: ‹take_bit n k = k›if‹0 ≤ k›‹k 🚫 ^ n›for k :: int using that by (simp add: take_bit_int_eq_self_iff)
lemma mask_nonnegative_int [simp]: ‹mask n ≥ (0::int)› by (simp add: mask_eq_exp_minus_1 add_le_imp_le_diff)
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 🚫›for k :: int by (simp add: not_int_def)
lemma not_negative_int_iff [simp]: ‹NOT k 🚫⟷ 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 thenshow ?case by simp next case minus thenshow ?case by simp next case (even k) thenshow ?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 thenhave‹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: zero_le_mult_iff not_le) qed
lemma and_negative_int_iff [simp]: ‹k AND l 🚫⟷ k 🚫∧ l 🚫›for k l :: int by (subst Not_eq_iff [symmetric]) (simp add: not_less)
lemma and_less_eq: ‹k AND l ≤ k›if‹l 🚫›for k l :: int using that proof (induction k arbitrary: l rule: int_bit_induct) case zero thenshow ?case by simp next case minus thenshow ?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 🚫⟷ k 🚫∨ l 🚫›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 thenshow ?case by simp next case minus thenshow ?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 🚫⟷ (k 🚫) ≠ (l 🚫)›for k l :: int by (subst Not_eq_iff [symmetric]) (auto simp: not_less)
lemma OR_upper: 🍋‹contributor ‹Stefan Berghofer›\› ‹x OR y 🚫 ^ n›if‹0 ≤ x›‹x 🚫 ^ n›‹y 🚫 ^ n›for x y :: int using that proof (induction x arbitrary: y n rule: int_bit_induct) case zero thenshow ?case by simp next case minus thenshow ?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: 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: or_int.rec [of ‹1 + _ * 2›], linarith) qed
lemma XOR_upper: 🍋‹contributor ‹Stefan Berghofer›\› ‹x XOR y 🚫 ^ n›if‹0 ≤ x›‹x 🚫 ^ n›‹y 🚫 ^ n›for x y :: int using that proof (induction x arbitrary: y n rule: int_bit_induct) case zero thenshow ?case by simp next case minus thenshow ?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: 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: xor_int.rec [of ‹1 + _ * 2›]) qed
lemma AND_lower [simp]: 🍋‹contributor ‹Stefan Berghofer›\› ‹0 ≤ x AND y›if‹0 ≤ x›for x y :: int using that by simp
lemma OR_lower [simp]: 🍋‹contributor ‹Stefan Berghofer›\› ‹0 ≤ x OR y›if‹0 ≤ x›‹0 ≤ y›for x y :: int using that by simp
lemma XOR_lower [simp]: 🍋‹contributor ‹Stefan Berghofer›\› ‹0 ≤ x XOR y›if‹0 ≤ x›‹0 ≤ y›for x y :: int using that by simp
lemma AND_upper1 [simp]: 🍋‹contributor ‹Stefan Berghofer›\› ‹x AND y ≤ x›if‹0 ≤ x›for x y :: int using that proof (induction x arbitrary: y rule: int_bit_induct) case (odd k) thenhave‹k AND y div 2 ≤ k› by simp thenshow ?case by (simp add: and_int.rec [of ‹1 + _ * 2›]) qed (simp_all add: and_int.rec [of ‹_ * 2›])
lemma AND_upper1' [simp]: 🍋‹contributor ‹Stefan Berghofer›\› ‹y AND x ≤ z›if‹0 ≤ y›‹y ≤ z›for x y z :: int using _ ‹y ≤ z›by (rule order_trans) (use‹0 ≤ y›in simp)
lemma AND_upper1'' [simp]: 🍋‹contributor ‹Stefan Berghofer›\› ‹y AND x 🚫›if‹0 ≤ y›‹y 🚫›for x y z :: int using _ ‹y 🚫›by (rule order_le_less_trans) (use‹0 ≤ y›in simp)
lemma AND_upper2 [simp]: 🍋‹contributor ‹Stefan Berghofer›\› ‹x AND y ≤ y›if‹0 ≤ y›for x y :: int using that AND_upper1 [of y x] by (simp add: ac_simps)
lemma AND_upper2' [simp]: 🍋‹contributor ‹Stefan Berghofer›\› ‹x AND y ≤ z›if‹0 ≤ y›‹y ≤ z›for x y :: int using that AND_upper1' [of y z x] by (simp add: ac_simps)
lemma AND_upper2'' [simp]: 🍋‹contributor ‹Stefan Berghofer›\› ‹x AND y 🚫›if‹0 ≤ y›‹y 🚫›for x y :: int using that AND_upper1'' [of y z x] by (simp add: ac_simps)
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 thenshow ?case by simp next case minus thenshow ?case by simp next case (even x) from even.IH [of ‹y div 2›] show ?case by (auto simp: 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: and_int.rec [of _ y] or_int.rec [of _ y] elim: oddE) qed
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_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 (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 ≤ 2 ^ n›for k :: int proof -
define m where‹m = nat k› with that have‹k = int m›and‹0 🚫›and‹m ≤ 2 ^ n› by simp_all have‹(2 ^ n - m) mod 2 ^ n = 2 ^ n - m› using‹0 🚫›by simp thenhave‹int ((2 ^ n - m) mod 2 ^ n) = int (2 ^ n - m)› by simp thenhave‹(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 thenshow ?thesis by (simp add: take_bit_eq_mod) qed
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 power_le_zero_eq)
lemma push_bit_negative_int_iff [simp]: ‹push_bit n k 🚫⟷ k 🚫›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) (auto simp: drop_bit_Suc drop_bit_half)
lemma drop_bit_negative_int_iff [simp]: ‹drop_bit n k 🚫⟷ k 🚫›for k :: int by (subst Not_eq_iff [symmetric]) (simp add: not_less)
lemma set_bit_nonnegative_int_iff [simp]: ‹set_bit n k ≥ 0 ⟷ k ≥ 0›for k :: int by (simp add: set_bit_eq_or)
lemma set_bit_negative_int_iff [simp]: ‹set_bit n k 🚫⟷ k 🚫›for k :: int by (simp add: set_bit_eq_or)
lemma unset_bit_nonnegative_int_iff [simp]: ‹unset_bit n k ≥ 0 ⟷ k ≥ 0›for k :: int by (simp add: unset_bit_eq_and_not)
lemma unset_bit_negative_int_iff [simp]: ‹unset_bit n k 🚫⟷ k 🚫›for k :: int by (simp add: unset_bit_eq_and_not)
lemma flip_bit_nonnegative_int_iff [simp]: ‹flip_bit n k ≥ 0 ⟷ k ≥ 0›for k :: int by (simp add: flip_bit_eq_xor)
lemma flip_bit_negative_int_iff [simp]: ‹flip_bit n k 🚫⟷ k 🚫›for k :: int by (simp add: flip_bit_eq_xor)
lemma set_bit_greater_eq: ‹set_bit n k ≥ k›for k :: int by (simp add: set_bit_eq_or or_greater_eq)
lemma unset_bit_less_eq: ‹unset_bit n k ≤ k›for k :: int by (simp add: unset_bit_eq_and_not and_less_eq)
lemma and_int_unfold: ‹k AND l = (if k = 0 ∨ l = 0 then 0 else if k = - 1 then l else if l = - 1 then k else (k mod 2) * (l mod 2) + 2 * ((k div 2) AND (l div 2)))› by (auto simp: and_int.rec [of k l] zmult_eq_1_iff elim: oddE)
lemma or_int_unfold: ‹k OR l = (if k = - 1 ∨ l = - 1 then - 1 else if k = 0 then l else if l = 0 then k else max (k mod 2) (l mod 2) + 2 * ((k div 2) OR (l div 2)))› by (auto simp: or_int.rec [of k l] elim: oddE)
lemma xor_int_unfold: ‹k XOR l = (if k = - 1 then NOT l else if l = - 1 then NOT k else if k = 0 then l else if l = 0 then k else ∣k mod 2 - l mod 2∣ + 2 * ((k div 2) XOR (l div 2)))› by (auto simp: xor_int.rec [of k l] not_int_def elim!: oddE)
lemma bit_minus_int_iff: ‹bit (- k) n ⟷ bit (NOT (k - 1)) n›for k :: int by (simp add: bit_simps)
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) moreoverhave‹k mod 2 ^ n 🚫 ^ n› by simp ultimatelyhave *: ‹k mod 2 ^ n + 1 🚫 ^ n› by linarith have‹(k + 1) mod 2 ^ n = (k mod 2 ^ n + 1) mod 2 ^ n› by (simp add: mod_simps) alsohave‹… = k mod 2 ^ n + 1› using * by (simp add: zmod_trivial_iff) finallyhave‹(k + 1) mod 2 ^ n = k mod 2 ^ n + 1› . thenshow ?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) moreoverhave‹k mod 2 ^ n ≥ 0›‹k mod 2 ^ n 🚫 ^ n› by simp_all ultimatelyhave *: ‹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) alsohave‹… = k mod 2 ^ n - 1› by (simp add: zmod_trivial_iff)
(use‹k mod 2 ^ n 🚫 ^ n› * in linarith) finallyhave‹(k - 1) mod 2 ^ n = k mod 2 ^ n - 1› . thenshow ?thesis by (simp add: take_bit_eq_mod) qed
lemma take_bit_int_greater_eq: ‹k + 2 ^ n ≤ take_bit n k›if‹k 🚫›for k :: int proof - have‹k + 2 ^ n ≤ take_bit n (k + 2 ^ n)› proof (cases ‹k > - (2 ^ n)›) case False thenhave‹k + 2 ^ n ≤ 0› by simp alsonote take_bit_nonnegative finallyshow ?thesis . next case True with that have‹0 ≤ k + 2 ^ n›and‹k + 2 ^ n 🚫 ^ n› by simp_all thenshow ?thesis by (simp only: take_bit_eq_mod mod_pos_pos_trivial) qed thenshow ?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› thenhave‹k 🚫› by simp with‹?P› have‹take_bit n k 🚫› by (rule le_less_trans) thenshow False by simp qed next assume ?Q thenshow ?P by (simp add: take_bit_eq_mod zmod_le_nonneg_dividend) qed
lemma take_bit_int_less_self_iff: ‹take_bit n k 🚫⟷ 2 ^ n ≤ k›for k :: int by (auto simp: 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_less_eq_mask: ‹take_bit n k ≤ mask n›for k :: int using take_bit_int_less_exp [of n k] by (simp add: mask_eq_exp_minus_1)
lemma take_bit_int_greater_self_iff: ‹k 🚫 n k ⟷ k 🚫›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 🚫 ^ n›for k :: int by (auto simp: 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 take_bit_tightened_less_eq_int: ‹take_bit m k ≤ take_bit n k›if‹m ≤ n›for k :: int proof - have‹take_bit m (take_bit n k) ≤ take_bit n k› by (simp only: take_bit_int_less_eq_self_iff take_bit_nonnegative) with that show ?thesis by simp qed
lemma not_exp_less_eq_0_int [simp]: ‹¬ 2 ^ n ≤ (0::int)› by (simp add: power_le_zero_eq)
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 moreoverfrom power_gt_expt [of 2 ‹nat k›] have‹nat k 🚫 ^ nat k› by simp thenhave‹int (nat k) 🚫 (2 ^ nat k)› by (simp only: of_nat_less_iff) ultimatelyhave *: ‹k div 2 ^ nat k = 0› by simp show thesis proof (rule that [of ‹nat k›]) fix m assume‹nat k ≤ m› thenshow‹bit k m ⟷ bit k (nat k)› by (auto simp: * bit_iff_odd power_add zdiv_zmult2_eq dest!: le_Suc_ex) qed next case False moreoverfrom power_gt_expt [of 2 ‹nat (- k)›] have‹nat (- k) 🚫 ^ nat (- k)› by simp thenhave‹int (nat (- k)) 🚫 (2 ^ nat (- k))› by (simp only: of_nat_less_iff) ultimatelyhave‹- k div - (2 ^ nat (- k)) = - 1› by (subst div_pos_neg_trivial) simp_all thenhave *: ‹k div 2 ^ nat (- k) = - 1› by simp show thesis proof (rule that [of ‹nat (- k)›]) fix m assume‹nat (- k) ≤ m› thenshow‹bit k m ⟷ bit k (nat (- k))› by (auto simp: * 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 thenhave‹bit k 0 ⟷ bit k q› by blast with True that [of 0] show thesis by simp next case False thenobtain r where **: ‹bit k r ≠ bit k q› by blast have‹r 🚫› by (rule ccontr) (use * [of r] ** in simp)
define N where‹N = {n. n 🚫∧ bit k n ≠ bit k q}› moreoverhave‹finite N›‹r ∈ N› using ** N_def ‹r 🚫›by auto moreover define n where‹n = Suc (Max N)› ultimatelyhave†: ‹∧m. n ≤ m ==> bit k m ⟷ bit k n› by (smt (verit) "*" Max_ge Suc_n_not_le_n linorder_not_less mem_Collect_eq not_less_eq_eq) 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) with† n_def that [of n] show thesis by fastforce qed qed
subsection‹Instance 🍋‹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 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›
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 = (n OR push_bit m 1) XOR push_bit m 1›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
instanceproof fix m n :: nat show‹m AND n = of_bool (odd m ∧ odd n) + 2 * (m div 2 AND n div 2)› by (simp add: and_nat_def and_rec [of ‹int m›‹int n›] nat_add_distrib of_nat_div) show‹m OR n = of_bool (odd m ∨ odd n) + 2 * (m div 2 OR n div 2)› by (simp add: or_nat_def or_rec [of ‹int m›‹int n›] nat_add_distrib of_nat_div) show‹m XOR n = of_bool (odd m ≠ odd n) + 2 * (m div 2 XOR n div 2)› by (simp add: xor_nat_def xor_rec [of ‹int m›‹int n›] nat_add_distrib of_nat_div) qed (simp_all add: mask_nat_def set_bit_nat_def unset_bit_nat_def flip_bit_nat_def
push_bit_nat_def drop_bit_nat_def take_bit_nat_def)
lemma push_bit_of_nat: ‹push_bit n (of_nat m) = of_nat (push_bit n m)› by (simp add: push_bit_eq_mult Bit_Operations.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 Bit_Operations.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)
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)
lemma of_nat_set_bit_eq: ‹of_nat (set_bit n m) = set_bit n (of_nat m)› by (simp add: set_bit_eq_or Bit_Operations.set_bit_eq_or of_nat_or_eq Bit_Operations.push_bit_eq_mult)
lemma of_nat_unset_bit_eq: ‹of_nat (unset_bit n m) = unset_bit n (of_nat m)› by (simp add: unset_bit_eq_or_xor Bit_Operations.unset_bit_eq_or_xor of_nat_or_eq of_nat_xor_eq Bit_Operations.push_bit_eq_mult)
lemma of_nat_flip_bit_eq: ‹of_nat (flip_bit n m) = flip_bit n (of_nat m)› by (simp add: flip_bit_eq_xor Bit_Operations.flip_bit_eq_xor of_nat_xor_eq Bit_Operations.push_bit_eq_mult)
end
context linordered_euclidean_semiring_bit_operations begin
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 of_nat_drop_bit: ‹of_nat (drop_bit m n) = drop_bit m (of_nat n)› by (simp add: drop_bit_eq_div Bit_Operations.drop_bit_eq_div of_nat_div)
end
lemma take_bit_nat_less_exp [simp]: ‹take_bit n m 🚫 ^ n›for n m :: nat by (simp add: take_bit_eq_mod)
lemma take_bit_nat_eq_self_iff: ‹take_bit n m = m ⟷ m 🚫 ^ n› (is‹?P ⟷ ?Q›) for n m :: nat proof assume ?P moreovernote take_bit_nat_less_exp [of n m] ultimatelyshow ?Q by simp next assume ?Q thenshow ?P by (simp add: take_bit_eq_mod) qed
lemma take_bit_nat_eq_self: ‹take_bit n m = m›if‹m 🚫 ^ n›for m n :: nat using that by (simp add: take_bit_nat_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 🚫⟷ 2 ^ n ≤ m› (is‹?P ⟷ ?Q›) for m n :: nat proof assume ?P thenhave‹take_bit n m ≠ m› by simp thenshow‹?Q› by (simp add: take_bit_nat_eq_self_iff) next have‹take_bit n m 🚫 ^ n› by (fact take_bit_nat_less_exp) alsoassume ?Q finallyshow ?P . qed
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
lemma and_nat_unfold [code]: ‹m AND n = (if m = 0 ∨ n = 0 then 0 else (m mod 2) * (n mod 2) + 2 * ((m div 2) AND (n div 2)))› for m n :: nat by (auto simp: and_rec [of m n] elim: oddE)
lemma or_nat_unfold [code]: ‹m OR n = (if m = 0 then n else if n = 0 then m else max (m mod 2) (n mod 2) + 2 * ((m div 2) OR (n div 2)))› by (auto simp: or_rec [of m n] elim: oddE)
lemma xor_nat_unfold [code]: ‹m XOR n = (if m = 0 then n else if n = 0 then m else (m mod 2 + n mod 2) mod 2 + 2 * ((m div 2) XOR (n div 2)))› by (auto simp: xor_rec [of m n] elim!: oddE)
lemma [code]: ‹unset_bit 0 m = 2 * (m div 2)› ‹unset_bit (Suc n) m = m mod 2 + 2 * unset_bit n (m div 2)›for m n :: nat by (simp_all add: unset_bit_0 unset_bit_Suc)
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 🚫)› 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 less_mask: ‹n 🚫 n›if‹Suc 0 🚫› proof -
define m where‹m = n - 2› with that have *: ‹n = m + 2› by simp have‹Suc (Suc (Suc m)) 🚫 * 2 ^ m› by (induction m) simp_all thenhave‹Suc (m + 2) 🚫 (mask (m + 2))› by (simp add: Suc_mask_eq_exp) thenhave‹m + 2 🚫 (m + 2)› by (simp add: less_le) with * show ?thesis by simp qed
lemma mask_nat_less_exp [simp]: ‹(mask n :: nat) 🚫 ^ n› by (simp add: mask_eq_exp_minus_1)
lemma mask_nat_positive_iff [simp]: ‹(0::nat) 🚫 n ⟷ 0 🚫› proof (cases ‹n = 0›) case True thenshow ?thesis by simp next case False thenhave‹0 🚫› by simp thenhave‹(0::nat) 🚫 n› using less_eq_mask [of n] by (rule order_less_le_trans) with‹0 🚫›show ?thesis by simp qed
lemma take_bit_nat_less_eq_mask: ‹take_bit n m ≤ mask n›for m :: nat using take_bit_nat_less_exp [of n m] by (simp flip: Suc_mask_eq_exp)
lemma take_bit_tightened_less_eq_nat: ‹take_bit m q ≤ take_bit n q›if‹m ≤ n›for q :: nat proof - have‹take_bit m (take_bit n q) ≤ take_bit n q› by (rule take_bit_nat_less_eq_self) with that 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)› proof (cases ‹k ≥ 0›) case True thenshow ?thesis by (metis drop_bit_of_nat int_nat_eq nat_int) qed (simp add: nat_eq_iff2)
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 bit_numeral_Bit0_iff: ‹bit (numeral (num.Bit0 m)) n ⟷ possible_bit TYPE('a) n ∧ n > 0 ∧ bit (numeral m) (n - 1)› by (simp only: numeral_Bit0_eq_double [of m] bit_simps) simp
lemma bit_numeral_Bit1_Suc_iff: ‹bit (numeral (num.Bit1 m)) (Suc n) ⟷ possible_bit TYPE('a) (Suc n) ∧ bit (numeral m) n› using even_bit_succ_iff [of ‹2 * numeral m›‹Suc n›] by (simp only: numeral_Bit1_eq_inc_double [of m] bit_simps) simp
end
context ring_bit_operations begin
lemma not_bit_minus_numeral_Bit0_0 [simp]: ‹¬ bit (- numeral (Num.Bit0 m)) 0› by (simp add: bit_0)
lemma bit_numeral_BitM_Suc_iff: ‹bit (numeral (Num.BitM m)) (Suc n) ⟷ possible_bit TYPE('a) (Suc n) ∧¬ bit (- numeral m) n› by (simp_all only: numeral_BitM bit_decr_iff bit_minus_numeral_Bit0_Suc_iff) auto
end
context linordered_euclidean_semiring_bit_operations begin
lemma bit_numeral_iff: ‹bit (numeral m) n ⟷ bit (numeral m :: nat) n› using bit_of_nat_iff_bit [of ‹numeral m› n] by simp
lemma bit_numeral_Bit0_Suc_iff [simp]: ‹bit (numeral (Num.Bit0 m)) (Suc n) ⟷ bit (numeral m) n› by (simp add: bit_Suc numeral_Bit0_div_2)
lemma bit_numeral_Bit1_Suc_iff [simp]: ‹bit (numeral (Num.Bit1 m)) (Suc n) ⟷ bit (numeral m) n› by (simp add: bit_Suc numeral_Bit0_div_2)
lemma bit_numeral_rec: ‹bit (numeral (Num.Bit0 w)) n ⟷ (case n of 0 ==> False | Suc m ==> bit (numeral w) m)› ‹bit (numeral (Num.Bit1 w)) n ⟷ (case n of 0 ==> True | Suc m ==> bit (numeral w) m)› by (cases n; simp add: bit_0)+
lemma bit_minus_numeral_int [simp]: ‹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)› by (simp_all add: bit_minus_iff bit_not_iff numeral_eq_Suc bit_Suc add_One sub_inc_One_eq)
lemma bit_minus_numeral_Bit0_Suc_iff [simp]: ‹bit (- numeral (num.Bit0 w) :: int) (Suc n) ⟷ bit (- numeral w :: int) n› by (simp add: bit_Suc)
lemma bit_minus_numeral_Bit1_Suc_iff [simp]: ‹bit (- numeral (num.Bit1 w) :: int) (Suc n) ⟷¬ bit (numeral w :: int) n› by (simp add: bit_Suc add_One flip: bit_not_int_iff)
lemma and_not_numerals: ‹1 AND NOT 1 = (0 :: int)› ‹1 AND NOT (numeral (Num.Bit0 n)) = (1 :: int)› ‹1 AND NOT (numeral (Num.Bit1 n)) = (0 :: int)› ‹numeral (Num.Bit0 m) AND NOT (1 :: int) = numeral (Num.Bit0 m)› ‹numeral (Num.Bit0 m) AND NOT (numeral (Num.Bit0 n)) = (2 :: int) * (numeral m AND NOT (numeral n))› ‹numeral (Num.Bit0 m) AND NOT (numeral (Num.Bit1 n)) = (2 :: int) * (numeral m AND NOT (numeral n))› ‹numeral (Num.Bit1 m) AND NOT (1 :: int) = numeral (Num.Bit0 m)› ‹numeral (Num.Bit1 m) AND NOT (numeral (Num.Bit0 n)) = 1 + (2 :: int) * (numeral m AND NOT (numeral n))› ‹numeral (Num.Bit1 m) AND NOT (numeral (Num.Bit1 n)) = (2 :: int) * (numeral m AND NOT (numeral n))› by (simp_all add: bit_eq_iff)
(auto simp: bit_0 bit_simps bit_Suc bit_numeral_rec BitM_inc_eq sub_inc_One_eq split: nat.split)
fun and_not_num :: ‹num ==> num ==> num option›🍋‹contributor ‹Andreas Lochbihler›\› 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)›
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 del: not_numeral_eq not_one_eq add: and_not_numerals split: option.splits)
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 del: not_numeral_eq 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 del: not_numeral_eq add: int_numeral_and_not_num split: option.split)
lemma and_minus_numerals [simp]: ‹1 AND - (numeral (num.Bit0 n)) = (0::int)› ‹1 AND - (numeral (num.Bit1 n)) = (1::int)› ‹numeral m AND - (numeral (num.Bit0 n)) = (case and_not_num m (Num.BitM n) of None ==> 0 :: int | Some n' ==> numeral n')› ‹numeral m AND - (numeral (num.Bit1 n)) = (case and_not_num m (Num.Bit0 n) of None ==> 0 :: int | Some n' ==> numeral n')› ‹- (numeral (num.Bit0 n)) AND 1 = (0::int)› ‹- (numeral (num.Bit1 n)) AND 1 = (1::int)› ‹- (numeral (num.Bit0 n)) AND numeral m = (case and_not_num m (Num.BitM n) of None ==> 0 :: int | Some n' ==> numeral n')› ‹- (numeral (num.Bit1 n)) AND numeral m = (case and_not_num m (Num.Bit0 n) of None ==> 0 :: int | Some n' ==> numeral n')› by (simp_all del: not_numeral_eq add: ac_simps
and_not_numerals one_and_eq not_numeral_BitM_eq not_numeral_Bit0_eq and_not_num_eq_None_iff and_not_num_eq_Some_iff split: option.split)
lemma and_minus_minus_numerals [simp]: ‹- (numeral m :: int) AND - (numeral n :: int) = NOT ((numeral m - 1) OR (numeral n - 1))› by (simp add: minus_numeral_eq_not_sub_one)
lemma or_not_numerals: ‹1 OR NOT 1 = NOT (0 :: int)› ‹1 OR NOT (numeral (Num.Bit0 n)) = NOT (numeral (Num.Bit0 n) :: int)› ‹1 OR NOT (numeral (Num.Bit1 n)) = NOT (numeral (Num.Bit0 n) :: int)› ‹numeral (Num.Bit0 m) OR NOT (1 :: int) = NOT (1 :: int)› ‹numeral (Num.Bit0 m) OR NOT (numeral (Num.Bit0 n)) = 1 + (2 :: int) * (numeral m OR NOT (numeral n))› ‹numeral (Num.Bit0 m) OR NOT (numeral (Num.Bit1 n)) = (2 :: int) * (numeral m OR NOT (numeral n))› ‹numeral (Num.Bit1 m) OR NOT (1 :: int) = NOT (0 :: int)› ‹numeral (Num.Bit1 m) OR NOT (numeral (Num.Bit0 n)) = 1 + (2 :: int) * (numeral m OR NOT (numeral n))› ‹numeral (Num.Bit1 m) OR NOT (numeral (Num.Bit1 n)) = 1 + (2 :: int) * (numeral m OR NOT (numeral n))› by (simp_all add: bit_eq_iff)
(auto simp: bit_0 bit_simps bit_Suc bit_numeral_rec sub_inc_One_eq split: nat.split)
fun or_not_num_neg :: ‹num ==> num ==> num›🍋‹contributor ‹Andreas Lochbihler›\› 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)›
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 del: not_numeral_eq not_one_eq add: or_not_numerals, simp_all)
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 or_minus_numerals [simp]: ‹1 OR - (numeral (num.Bit0 n)) = - (numeral (or_not_num_neg num.One (Num.BitM n)) :: int)› ‹1 OR - (numeral (num.Bit1 n)) = - (numeral (num.Bit1 n) :: int)› ‹numeral m OR - (numeral (num.Bit0 n)) = - (numeral (or_not_num_neg m (Num.BitM n)) :: int)› ‹numeral m OR - (numeral (num.Bit1 n)) = - (numeral (or_not_num_neg m (Num.Bit0 n)) :: int)› ‹- (numeral (num.Bit0 n)) OR 1 = - (numeral (or_not_num_neg num.One (Num.BitM n)) :: int)› ‹- (numeral (num.Bit1 n)) OR 1 = - (numeral (num.Bit1 n) :: int)› ‹- (numeral (num.Bit0 n)) OR numeral m = - (numeral (or_not_num_neg m (Num.BitM n)) :: int)› ‹- (numeral (num.Bit1 n)) OR numeral m = - (numeral (or_not_num_neg m (Num.Bit0 n)) :: int)› by (simp_all only: or.commute [of _ 1] or.commute [of _ ‹numeral m›]
minus_numeral_eq_not_sub_one or_not_numerals
numeral_or_not_num_eq arith_simps minus_minus numeral_One)
lemma or_minus_minus_numerals [simp]: ‹- (numeral m :: int) OR - (numeral n :: int) = NOT ((numeral m - 1) AND (numeral n - 1))› by (simp add: minus_numeral_eq_not_sub_one)
lemma xor_minus_numerals [simp]: ‹- numeral n XOR k = NOT (neg_numeral_class.sub n num.One XOR k)› ‹k XOR - numeral n = NOT (k XOR (neg_numeral_class.sub n num.One))›for k :: int by (simp_all add: minus_numeral_eq_not_sub_one)
definition take_bit_num :: ‹nat ==> num ==> num option› where‹take_bit_num n m = (if take_bit n (numeral m :: nat) = 0 then None else Some (num_of_nat (take_bit n (numeral m :: nat))))›
lemma take_bit_num_simps: ‹take_bit_num 0 m = None› ‹take_bit_num (Suc n) Num.One = Some Num.One› ‹take_bit_num (Suc n) (Num.Bit0 m) = (case take_bit_num n m of None ==> None | Some q ==> Some (Num.Bit0 q))› ‹take_bit_num (Suc n) (Num.Bit1 m) = Some (case take_bit_num n m of None ==> Num.One | Some q ==> Num.Bit1 q)› ‹take_bit_num (numeral r) Num.One = Some Num.One› ‹take_bit_num (numeral r) (Num.Bit0 m) = (case take_bit_num (pred_numeral r) m of None ==> None | Some q ==> Some (Num.Bit0 q))› ‹take_bit_num (numeral r) (Num.Bit1 m) = Some (case take_bit_num (pred_numeral r) m of None ==> Num.One | Some q ==>Num.Bit1 q)› by (auto simp: take_bit_num_def ac_simps mult_2 num_of_nat_double
take_bit_Suc_bit0 take_bit_Suc_bit1 take_bit_numeral_bit0 take_bit_numeral_bit1)
lemma take_bit_num_code [code]: 🍋‹Ocaml-style pattern matching is more robust wrt. different representations of🍋‹nat›\› ‹take_bit_num n m = (case (n, m) of (0, _) ==> None | (Suc n, Num.One) ==> Some Num.One | (Suc n, Num.Bit0 m) ==> (case take_bit_num n m of None ==> None | Some q ==> Some (Num.Bit0 q)) | (Suc n, Num.Bit1 m) ==> Some (case take_bit_num n m of None ==> Num.One | Some q ==> Num.Bit1 q))› by (cases n; cases m) (simp_all add: take_bit_num_simps)
context semiring_bit_operations begin
lemma take_bit_num_eq_None_imp: ‹take_bit m (numeral n) = 0›if‹take_bit_num m n = None› proof - from that have‹take_bit m (numeral n :: nat) = 0› by (simp add: take_bit_num_def split: if_splits) thenhave‹of_nat (take_bit m (numeral n)) = of_nat 0› by simp thenshow ?thesis by (simp add: of_nat_take_bit) qed
lemma take_bit_num_eq_Some_imp: ‹take_bit m (numeral n) = numeral q›if‹take_bit_num m n = Some q› proof - from that have‹take_bit m (numeral n :: nat) = numeral q› by (auto simp: take_bit_num_def Num.numeral_num_of_nat_unfold split: if_splits) thenhave‹of_nat (take_bit m (numeral n)) = of_nat (numeral q)› by simp thenshow ?thesis by (simp add: of_nat_take_bit) qed
lemma take_bit_numeral_numeral: ‹take_bit (numeral m) (numeral n) = (case take_bit_num (numeral m) n of None ==> 0 | Some q ==> numeral q)› by (auto split: option.split dest: take_bit_num_eq_None_imp take_bit_num_eq_Some_imp)
end
lemma take_bit_numeral_minus_numeral_int: ‹take_bit (numeral m) (- numeral n :: int) = (case take_bit_num (numeral m) n of None ==> 0 | Some q ==> take_bit (numeral m) (2 ^ numeral m - numeral q))› proof (cases ‹take_bit_num (numeral m) n›) case None thenshow ?thesis by (auto dest: take_bit_num_eq_None_imp [where ?'a = int] simp add: take_bit_eq_0_iff) next case (Some q) thenhave q: ‹take_bit (numeral m) (numeral n :: int) = numeral q› by (auto dest: take_bit_num_eq_Some_imp) let ?T = ‹take_bit (numeral m) :: int ==> int› have *: ‹?T (2 ^ numeral m) = ?T (?T 0)› by (simp add: take_bit_eq_0_iff) have‹?lhs = ?T (0 - numeral n)› by simp alsohave‹… = ?T (?T (?T 0) - ?T (?T (numeral n)))› by (simp only: take_bit_diff) alsohave‹… = ?T (2 ^ numeral m - ?T (numeral n))› by (simp only: take_bit_diff flip: *) alsohave‹… = ?rhs› by (simp add: q Some) finallyshow ?thesis . qed
fun and_num :: ‹num ==> num ==> num option›🍋‹contributor ‹Andreas Lochbihler›\› 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'))›
context linordered_euclidean_semiring_bit_operations begin
lemma numeral_and_num: ‹numeral m AND numeral n = (case and_num m n of None ==> 0 | Some n' ==> numeral n')› by (induction m n rule: and_num.induct) (simp_all add: split: option.split)
lemma and_num_eq_None_iff: ‹and_num m n = None ⟷ numeral m AND numeral n = 0› by (simp add: 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› by (simp add: numeral_and_num split: option.split)
end
lemma and_int_code [code]: fixes i j :: int shows ‹0 AND j = 0› ‹i AND 0 = 0› ‹Int.Pos n AND Int.Pos m = (case and_num n m of None ==> 0 | Some n' ==> Int.Pos n')› ‹Int.Neg n AND Int.Neg m = NOT (Num.sub n num.One OR Num.sub m num.One)› ‹Int.Pos n AND Int.Neg num.One = Int.Pos n› ‹Int.Pos n AND Int.Neg (num.Bit0 m) = Num.sub (or_not_num_neg (Num.BitM m) n) num.One› ‹Int.Pos n AND Int.Neg (num.Bit1 m) = Num.sub (or_not_num_neg (num.Bit0 m) n) num.One› ‹Int.Neg num.One AND Int.Pos m = Int.Pos m› ‹Int.Neg (num.Bit0 n) AND Int.Pos m = Num.sub (or_not_num_neg (Num.BitM n) m) num.One› ‹Int.Neg (num.Bit1 n) AND Int.Pos m = Num.sub (or_not_num_neg (num.Bit0 n) m) num.One› apply (auto simp: and_num_eq_None_iff [where ?'a = int] and_num_eq_Some_iff [where ?'a = int]
split: option.split) apply (simp_all only: sub_one_eq_not_neg numeral_or_not_num_eq minus_minus and_not_numerals
bit.de_Morgan_disj bit.double_compl and_not_num_eq_None_iff and_not_num_eq_Some_iff ac_simps) done
context linordered_euclidean_semiring_bit_operations begin
fun or_num :: ‹num ==> num ==> num›🍋‹contributor ‹Andreas Lochbihler›\› 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)›
lemma numeral_or_num: ‹numeral m OR numeral n = numeral (or_num m n)› 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› by (simp add: numeral_or_num)
end
lemma or_int_code [code]: fixes i j :: int shows ‹0 OR j = j› ‹i OR 0 = i› ‹Int.Pos n OR Int.Pos m = Int.Pos (or_num n m)› ‹Int.Neg n OR Int.Neg m = NOT (Num.sub n num.One AND Num.sub m num.One)› ‹Int.Pos n OR Int.Neg num.One = Int.Neg num.One› ‹Int.Pos n OR Int.Neg (num.Bit0 m) = (case and_not_num (Num.BitM m) n of None ==> -1 | Some n' ==> Int.Neg (Num.inc n'))› ‹Int.Pos n OR Int.Neg (num.Bit1 m) = (case and_not_num (num.Bit0 m) n of None ==> -1 | Some n' ==> Int.Neg (Num.inc n'))› ‹Int.Neg num.One OR Int.Pos m = Int.Neg num.One› ‹Int.Neg (num.Bit0 n) OR Int.Pos m = (case and_not_num (Num.BitM n) m of None ==> -1 | Some n' ==> Int.Neg (Num.inc n'))› ‹Int.Neg (num.Bit1 n) OR Int.Pos m = (case and_not_num (num.Bit0 n) m of None ==> -1 | Some n' ==> Int.Neg (Num.inc n'))› apply (auto simp: numeral_or_num_eq split: option.splits) apply (simp_all only: and_not_num_eq_None_iff and_not_num_eq_Some_iff and_not_numerals
numeral_or_not_num_eq or_eq_not_not_and bit.double_compl ac_simps flip: numeral_eq_iff [where ?'a = int]) apply simp_all done
fun xor_num :: ‹num ==> num ==> num option›🍋‹contributor ‹Andreas Lochbihler›\› 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)›
context linordered_euclidean_semiring_bit_operations begin
lemma numeral_xor_num: ‹numeral m XOR numeral n = (case xor_num m n of None ==> 0 | 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› by (simp add: 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› by (simp add: numeral_xor_num split: option.split)
lemma flip_bit_numeral_eq_xor [simp]: ‹flip_bit (numeral n) (numeral m) = numeral m XOR push_bit (numeral n) 1› by (fact flip_bit_eq_xor)
end
context ring_bit_operations begin
lemma set_bit_minus_numeral_eq_or [simp]: ‹set_bit (numeral n) (- numeral m) = - numeral m OR push_bit (numeral n) 1› by (fact set_bit_eq_or)
lemma unset_bit_minus_numeral_eq_and_not [simp]: ‹unset_bit (numeral n) (- numeral m) = - numeral m AND NOT (push_bit (numeral n) 1)› by (fact unset_bit_eq_and_not)
lemma flip_bit_minus_numeral_eq_xor [simp]: ‹flip_bit (numeral n) (- numeral m) = - numeral m XOR push_bit (numeral n) 1› by (fact flip_bit_eq_xor)
end
lemma xor_int_code [code]: fixes i j :: int shows ‹0 XOR j = j› ‹i XOR 0 = i› ‹Int.Pos n XOR Int.Pos m = (case xor_num n m of None ==> 0 | Some n' ==> Int.Pos n')› ‹Int.Neg n XOR Int.Neg m = Num.sub n num.One XOR Num.sub m num.One› ‹Int.Neg n XOR Int.Pos m = NOT (Num.sub n num.One XOR Int.Pos m)› ‹Int.Pos n XOR Int.Neg m = NOT (Int.Pos n XOR Num.sub m num.One)› by (simp_all add: xor_num_eq_None_iff [where ?'a = int] xor_num_eq_Some_iff [where ?'a = int] split: option.split)
lemma push_bit_int_code [code]: ‹push_bit 0 i = i› ‹push_bit (Suc n) i = push_bit n (Int.dup i)› by (simp_all add: ac_simps)
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 thenhave‹take_bit n (take_bit n k + take_bit n 1) = 0› by (simp add: mask_eq_exp_minus_1 take_bit_eq_0_iff) thenshow ?Q by (simp only: take_bit_add) next assume ?Q thenhave‹take_bit n (k + 1) - 1 = - 1› by simp thenhave‹take_bit n (take_bit n (k + 1) - 1) = take_bit n (- 1)› by simp moreoverhave‹take_bit n (take_bit n (k + 1) - 1) = take_bit n k› by (simp add: take_bit_eq_mod mod_simps) ultimatelyshow ?P by simp 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)
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 🚫∧ 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› proof - have‹take_bit n k AND push_bit n l = 0› by (simp add: bit_eq_iff bit_simps) thenshow ?thesis by (simp add: bit_eq_iff bit_simps disjunctive_add_eq_or) qed
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 🚫⟷ l 🚫› 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: 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: 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› proof assume ?Q thenshow ?P by (simp add: concat_bit_def) next assume ?P thenhave *: ‹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: bit_take_bit_iff bit_concat_bit_iff) qed moreoverhave‹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: bit_push_bit_iff bit_concat_bit_iff) qed thenhave‹l = s› by (simp add: push_bit_eq_mult) ultimatelyshow ?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: 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: bit_0 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 ⟷ possible_bit TYPE('a) n ∧ 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)
(blast dest: bit_imp_possible_bit)
lemma signed_take_bit_0 [simp]: ‹signed_take_bit 0 a = - (a mod 2)› by (simp add: bit_0 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)› by (simp add: bit_eq_iff bit_sum_mult_2_cases bit_simps bit_0 possible_bit_less_imp flip: bit_Suc min_Suc_Suc)
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 mask_eq_exp_minus_1 possible_bit_def)
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 bit_imp_possible_bit in fastforce) thenshow ?thesis by (auto simp: fun_eq_iff intro: bit_eqI) 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› by (auto simp: bit_eq_iff bit_simps ac_simps)
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: 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: bit_take_bit_iff bit_signed_take_bit_iff min_def less_Suc_eq)
lemma signed_take_bit_eq_take_bit_add: ‹signed_take_bit n k = take_bit (Suc n) k + NOT (mask (Suc n)) * of_bool (bit k n)› proof (cases ‹bit k n›) case False show ?thesis by (rule bit_eqI) (simp add: False bit_simps min_def less_Suc_eq) next case True have‹signed_take_bit n k = take_bit (Suc n) k OR NOT (mask (Suc n))› by (rule bit_eqI) (auto simp: bit_signed_take_bit_iff min_def bit_take_bit_iff bit_or_iff bit_not_iff bit_mask_iff less_Suc_eq True) alsohave‹… = take_bit (Suc n) k + NOT (mask (Suc n))› by (simp add: disjunctive_add_eq_or bit_eq_iff bit_simps) finallyshow ?thesis by (simp add: True) 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)› by (simp add: signed_take_bit_eq_take_bit_add flip: minus_exp_eq_not_mask)
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)
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) thenshow ?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) thenshow ?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) thenshow ?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) thenshow ?thesis by (simp only: signed_take_bit_eq_iff_take_bit_eq take_bit_mult) qed
lemma signed_take_bit_eq_take_bit_shift: ‹signed_take_bit n k = take_bit (Suc n) (k + 2 ^ n) - 2 ^ n› (is‹?lhs = ?rhs›) for k :: int proof - have‹take_bit n k AND 2 ^ n = 0› by (rule bit_eqI) (simp add: bit_simps) thenhave *: ‹take_bit n k OR 2 ^ n = take_bit n k + 2 ^ n› by (simp add: disjunctive_add_eq_or) have‹take_bit n k - 2 ^ n = take_bit n k + NOT (mask n)› by (simp add: minus_exp_eq_not_mask) alsohave‹… = take_bit n k OR NOT (mask n)› by (rule disjunctive_add_eq_or) (simp add: bit_eq_iff bit_simps) finallyhave **: ‹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) alsohave‹take_bit (Suc n) k = 2 ^ n * of_bool (bit k n) + take_bit n k› by (simp add: take_bit_Suc_from_most) finallyhave‹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) alsohave‹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_eq_or, rule bit_eqI) (simp add: bit_simps) finallyshow ?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 🚫⟷ 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 🚫 ^ 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 🚫 ^ n› for k :: int by (auto simp: 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 🚫 ^ 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 🚫⟷ 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 🚫 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 🚫 ^ 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_sgn_eq [simp]: ‹signed_take_bit (Suc n) (sgn k) = sgn k›for k :: int by (simp add: sgn_if)
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)› by (simp add: signed_take_bit_eq_take_bit_add bit_simps)
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: 🪙 Bit values are represented by numeric types: idealized unbounded bit values can be represented by type 🍋‹int›, bounded bit values by quotient types over 🍋‹int›. 🪙 (A special case are idealized unbounded bit values ending in @{term [source] 0} which can be represented by type 🍋‹nat›but only support a restricted set of operations). 🪙 From this idea follows that 🪙 multiplication by 🍋‹2 :: int›is a bit shift to the left and 🪙 division by 🍋‹2 :: int›is a bit shift to the right. 🪙 Concerning bounded bit values, iterated shifts to the left may result in eliminating all bits by shifting them all beyond the boundary. The property 🍋‹(2 :: int) ^ n ≠ 0› represents that 🍋‹n›is 🪙‹not› beyond that boundary. 🪙 The projection on a single bit is then @{thm bit_iff_odd [where ?'a = int, no_vars]}. 🪙 This leads to the most fundamental properties of bit values: 🪙 Equality rule: @{thm bit_eqI [where ?'a = int, no_vars]} 🪙 Induction rule: @{thm bit_induct [where ?'a = int, no_vars]} 🪙 Typical operations are characterized as follows: 🪙 Singleton 🍋‹n›th bit: 🍋‹(2 :: int) ^ n› 🪙 Bit mask upto bit 🍋‹n›: @{thm mask_eq_exp_minus_1 [where ?'a = int, no_vars]} 🪙 Left shift: @{thm push_bit_eq_mult [where ?'a = int, no_vars]} 🪙 Right shift: @{thm drop_bit_eq_div [where ?'a = int, no_vars]} 🪙 Truncation: @{thm take_bit_eq_mod [where ?'a = int, no_vars]} 🪙 Negation: @{thm bit_not_iff [where ?'a = int, no_vars]} 🪙 And: @{thm bit_and_iff [where ?'a = int, no_vars]} 🪙 Or: @{thm bit_or_iff [where ?'a = int, no_vars]} 🪙 Xor: @{thm bit_xor_iff [where ?'a = int, no_vars]} 🪙 Set a single bit: @{thm set_bit_eq_or [where ?'a = int, no_vars]} 🪙 Unset a single bit: @{thm unset_bit_eq_and_not [where ?'a = int, no_vars]} 🪙 Flip a single bit: @{thm flip_bit_eq_xor [where ?'a = int, no_vars]} 🪙 Signed truncation, or modulus centered around 🍋‹0::int›: @{thm signed_take_bit_def [no_vars]} 🪙 Bit concatenation: @{thm concat_bit_def [no_vars]} 🪙 (Bounded) conversion from and to a list of bits: @{thm horner_sum_bit_eq_take_bit [where ?'a = int, no_vars]} ›
subsection‹Lemma duplicates and other›
context semiring_bits begin
lemma exp_div_exp_eq: ‹2 ^ m div 2 ^ n = of_bool (2 ^ m ≠ 0 ∧ m ≥ n) * 2 ^ (m - n)› using bit_exp_iff div_exp_eq by (intro bit_eqI) (auto simp: bit_iff_odd possible_bit_def)
lemma bits_1_div_2: ‹1 div 2 = 0› by (fact half_1)
lemma bits_1_div_exp: ‹1 div 2 ^ n = of_bool (n = 0)› using div_exp_eq [of 1 1] by (cases n) simp_all
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› thenhave‹2 ^ (m + n) = 0› by (rule disjE) (simp_all add: power_add) with that show False .. qed thenshow‹2 ^ m ≠ 0›and‹2 ^ n ≠ 0› by simp_all 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› thenhave‹2 ^ (m + n) = 0› by (rule disjE) (simp_all add: power_add) with that show False .. qed thenshow‹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› ultimatelyhave‹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
lemma exp_eq_0_imp_not_bit: ‹¬ bit a n›if‹2 ^ n = 0› using that by (simp add: bit_iff_odd)
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 ‹possible_bit TYPE('a) n›) case False thenshow ?thesis by (auto dest: impossible_bit) next case True with that show ?thesis proof (induction n arbitrary: a b) case 0 from"0.prems"(1) [of 0] show ?case by (auto simp: bit_0) next case (Suc n) from Suc.prems(1) [of 0] have even: ‹even a ∨ even b› by (auto simp: bit_0) 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‹possible_bit TYPE('a) (Suc n)›‹possible_bit TYPE('a) n› by (simp_all add: possible_bit_less_imp) 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 alsohave‹… = of_bool (odd a ∨ odd b) + 2 * (a div 2 + b div 2)› using even by (auto simp: algebra_simps mod2_eq_if) finallyhave‹bit ((a + b) div 2) n ⟷ bit (a div 2 + b div 2) n› using‹possible_bit TYPE('a) (Suc n)›by simp (simp_all flip: bit_Suc add: bit_double_iff possible_bit_def) alsohave‹…⟷ bit (a div 2) n ∨ bit (b div 2) n› using bit ‹possible_bit TYPE('a) n›by (rule Suc.IH) finallyshow ?case by (simp add: bit_Suc) qed qed
end
context semiring_bit_operations begin
lemma even_mask_div_iff: ‹even ((2 ^ m - 1) div 2 ^ n) ⟷ 2 ^ n = 0 ∨ m ≤ n› using bit_mask_iff [of m n] by (auto simp: mask_eq_exp_minus_1 bit_iff_odd possible_bit_def)
lemma mod_exp_eq: ‹a mod 2 ^ m mod 2 ^ n = a mod 2 ^ min m n› by (simp flip: take_bit_eq_mod add: ac_simps)
lemma mult_exp_mod_exp_eq: ‹m ≤ n ==> (a * 2 ^ m) mod (2 ^ n) = (a mod 2 ^ (n - m)) * 2 ^ m› by (simp flip: push_bit_eq_mult take_bit_eq_mod add: push_bit_take_bit)
lemma div_exp_mod_exp_eq: ‹a div 2 ^ n mod 2 ^ m = a mod (2 ^ (n + m)) div 2 ^ n› by (simp flip: drop_bit_eq_div take_bit_eq_mod add: drop_bit_take_bit)
lemma 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)))› by (simp flip: push_bit_eq_mult drop_bit_eq_div add: even_drop_bit_iff_not_bit bit_simps possible_bit_def) auto
lemma mod_exp_div_exp_eq_0: ‹a mod 2 ^ n div 2 ^ n = 0› by (simp flip: take_bit_eq_mod drop_bit_eq_div add: drop_bit_take_bit)
lemma disjunctive_add: ‹a + b = a OR b›if‹∧n. ¬ bit a n ∨¬ bit b n› by (rule disjunctive_add_eq_or) (use that in‹simp add: bit_eq_iff bit_simps›)
lemma even_mod_exp_div_exp_iff: ‹even (a mod 2 ^ m div 2 ^ n) ⟷ m ≤ n ∨ even (a div 2 ^ n)› by (auto simp: even_drop_bit_iff_not_bit bit_simps simp flip: drop_bit_eq_div take_bit_eq_mod)
end
context ring_bit_operations begin
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: bit_not_iff dest: that) thenhave‹NOT (NOT a + b) = NOT (NOT a OR b)› by simp thenshow ?thesis by (simp add: not_add_distrib) qed
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 (fact and_rec)
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 (fact or_rec)
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 (fact xor_rec)
lemma bit_push_bit_iff_nat: ‹bit (push_bit m q) n ⟷ m ≤ n ∧ bit q (n - m)›for q :: nat by (fact bit_push_bit_iff')
lemma mask_half_int: ‹mask n div 2 = (mask (n - 1) :: int)› by (fact mask_half)
lemma not_int_rec: ‹NOT k = of_bool (even k) + 2 * NOT (k div 2)›for k :: int by (fact not_rec)
lemma even_not_iff_int: ‹even (NOT k) ⟷ odd k›for k :: int by (fact even_not_iff)
lemma bit_not_int_iff': ‹bit (- k - 1) n ⟷¬ bit k n›for k :: int by (simp flip: not_eq_complement add: bit_simps)
lemmas and_int_rec = and_int.rec
lemma even_and_iff_int: ‹even (k AND l) ⟷ even k ∨ even l›for k l :: int by (fact even_and_iff)
lemmas bit_and_int_iff = and_int.bit_iff
lemmas or_int_rec = or_int.rec
lemmas bit_or_int_iff = or_int.bit_iff
lemmas xor_int_rec = xor_int.rec
lemmas bit_xor_int_iff = xor_int.bit_iff
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 (fact drop_bit_push_bit)
lemma bit_push_bit_iff_int: ‹bit (push_bit m k) n ⟷ m ≤ n ∧ bit k (n - m)›for k :: int by (fact bit_push_bit_iff')
bundle bit_operations_syntax begin notation
not (‹NOT›) and"and" (infixr‹AND› 64) and or (infixr‹OR› 59) and xor (infixr‹XOR› 59) end
unbundle no bit_operations_syntax
end
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.170Bemerkung:
(vorverarbeitet am 2026-05-01)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.