# HG changeset patch # User haftmann # Date 1626090062 0 # Node ID ca2a35c0fe6e9e2c5c5a359e1bdbb3ca83b7fc73 # Parent 0274d442b7eac7e92d148063aada10f108ddea02 operations for symbolic computation of bit operations diff -r 0274d442b7ea -r ca2a35c0fe6e src/HOL/Library/Bit_Operations.thy --- a/src/HOL/Library/Bit_Operations.thy Mon Jul 12 11:41:02 2021 +0000 +++ b/src/HOL/Library/Bit_Operations.thy Mon Jul 12 11:41:02 2021 +0000 @@ -58,35 +58,35 @@ using bit_xor_iff [of a b 0] by auto lemma zero_and_eq [simp]: - "0 AND a = 0" + \0 AND a = 0\ by (simp add: bit_eq_iff bit_and_iff) lemma and_zero_eq [simp]: - "a AND 0 = 0" + \a AND 0 = 0\ by (simp add: bit_eq_iff bit_and_iff) lemma one_and_eq: - "1 AND a = a mod 2" + \1 AND a = a mod 2\ by (simp add: bit_eq_iff bit_and_iff) (auto simp add: bit_1_iff) lemma and_one_eq: - "a AND 1 = a mod 2" + \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)" + \1 OR a = a + of_bool (even a)\ by (simp add: bit_eq_iff bit_or_iff add.commute [of _ 1] even_bit_succ_iff) (auto simp add: bit_1_iff) lemma or_one_eq: - "a OR 1 = a + of_bool (even a)" + \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)" + \1 XOR a = a + of_bool (even a) - of_bool (odd a)\ by (simp add: bit_eq_iff bit_xor_iff add.commute [of _ 1] even_bit_succ_iff) (auto simp add: bit_1_iff odd_bit_iff_bit_pred elim: oddE) lemma xor_one_eq: - "a XOR 1 = a + of_bool (even a) - of_bool (odd a)" + \a XOR 1 = a + of_bool (even a) - of_bool (odd a)\ using one_xor_eq [of a] by (simp add: ac_simps) lemma take_bit_and [simp]: @@ -370,7 +370,7 @@ by (simp add: minus_eq_not_minus_1 bit_not_iff) lemma even_not_iff [simp]: - "even (NOT a) \ odd a" + \even (NOT a) \ odd a\ using bit_not_iff [of a 0] by auto lemma bit_not_exp_iff [bit_simps]: @@ -390,7 +390,7 @@ by (simp add: bit_minus_iff bit_1_iff) lemma not_one [simp]: - "NOT 1 = - 2" + \NOT 1 = - 2\ by (simp add: bit_eq_iff bit_not_iff) (simp add: bit_1_iff) sublocale "and": semilattice_neutr \(AND)\ \- 1\ @@ -468,7 +468,7 @@ by (auto simp add: bit_eq_iff bit_take_bit_iff bit_not_iff) lemma take_bit_not_iff: - "take_bit n (NOT a) = take_bit n (NOT b) \ take_bit n a = take_bit n b" + \take_bit n (NOT a) = take_bit n (NOT b) \ take_bit n a = take_bit n b\ apply (simp add: bit_eq_iff) apply (simp add: bit_not_iff bit_take_bit_iff bit_exp_iff) apply (use exp_eq_0_imp_not_bit in blast) @@ -599,7 +599,7 @@ where \not_int k = - k - 1\ lemma not_int_rec: - "NOT k = of_bool (even k) + 2 * NOT (k div 2)" for k :: int + \NOT k = of_bool (even k) + 2 * NOT (k div 2)\ for k :: int by (auto simp add: not_int_def elim: oddE) lemma even_not_iff_int: @@ -828,8 +828,8 @@ lemma OR_upper: \<^marker>\contributor \Stefan Berghofer\\ fixes x y :: int - assumes "0 \ x" "x < 2 ^ n" "y < 2 ^ n" - shows "x OR y < 2 ^ n" + assumes \0 \ x\ \x < 2 ^ n\ \y < 2 ^ n\ + shows \x OR y < 2 ^ n\ using assms proof (induction x arbitrary: y n rule: int_bit_induct) case zero then show ?case @@ -852,8 +852,8 @@ lemma XOR_upper: \<^marker>\contributor \Stefan Berghofer\\ fixes x y :: int - assumes "0 \ x" "x < 2 ^ n" "y < 2 ^ n" - shows "x XOR y < 2 ^ n" + assumes \0 \ x\ \x < 2 ^ n\ \y < 2 ^ n\ + shows \x XOR y < 2 ^ n\ using assms proof (induction x arbitrary: y n rule: int_bit_induct) case zero then show ?case @@ -876,26 +876,26 @@ lemma AND_lower [simp]: \<^marker>\contributor \Stefan Berghofer\\ fixes x y :: int - assumes "0 \ x" - shows "0 \ x AND y" + assumes \0 \ x\ + shows \0 \ x AND y\ using assms by simp lemma OR_lower [simp]: \<^marker>\contributor \Stefan Berghofer\\ fixes x y :: int - assumes "0 \ x" "0 \ y" - shows "0 \ x OR y" + assumes \0 \ x\ \0 \ y\ + shows \0 \ x OR y\ using assms by simp lemma XOR_lower [simp]: \<^marker>\contributor \Stefan Berghofer\\ fixes x y :: int - assumes "0 \ x" "0 \ y" - shows "0 \ x XOR y" + assumes \0 \ x\ \0 \ y\ + shows \0 \ x XOR y\ using assms by simp lemma AND_upper1 [simp]: \<^marker>\contributor \Stefan Berghofer\\ fixes x y :: int - assumes "0 \ x" - shows "x AND y \ x" + assumes \0 \ x\ + shows \x AND y \ x\ using assms proof (induction x arbitrary: y rule: int_bit_induct) case (odd k) then have \k AND y div 2 \ k\ @@ -909,8 +909,8 @@ lemma AND_upper2 [simp]: \<^marker>\contributor \Stefan Berghofer\\ fixes x y :: int - assumes "0 \ y" - shows "x AND y \ y" + assumes \0 \ y\ + shows \x AND y \ y\ using assms AND_upper1 [of y x] by (simp add: ac_simps) lemmas AND_upper2' [simp] = order_trans [OF AND_upper2] \<^marker>\contributor \Stefan Berghofer\\ @@ -1118,6 +1118,22 @@ end +lemma minus_numeral_inc_eq: + \- numeral (Num.inc n) = NOT (numeral n :: int)\ + by (simp add: not_int_def sub_inc_One_eq add_One) + +lemma sub_one_eq_not_neg: + \Num.sub n num.One = NOT (- numeral n :: int)\ + by (simp add: not_int_def) + +lemma int_not_numerals [simp]: + \NOT (numeral (Num.Bit0 n) :: int) = - numeral (Num.Bit1 n)\ + \NOT (numeral (Num.Bit1 n) :: int) = - numeral (Num.inc (num.Bit1 n))\ + \NOT (numeral (Num.BitM n) :: int) = - numeral (num.Bit0 n)\ + \NOT (- numeral (Num.Bit0 n) :: int) = numeral (Num.BitM n)\ + \NOT (- numeral (Num.Bit1 n) :: int) = numeral (Num.Bit0 n)\ + by (simp_all add: not_int_def add_One inc_BitM_eq) + text \FIXME: The rule sets below are very large (24 rules for each operator). Is there a simpler way to do this?\ @@ -1144,84 +1160,84 @@ qed lemma int_and_numerals [simp]: - "numeral (Num.Bit0 x) AND numeral (Num.Bit0 y) = (2 :: int) * (numeral x AND numeral y)" - "numeral (Num.Bit0 x) AND numeral (Num.Bit1 y) = (2 :: int) * (numeral x AND numeral y)" - "numeral (Num.Bit1 x) AND numeral (Num.Bit0 y) = (2 :: int) * (numeral x AND numeral y)" - "numeral (Num.Bit1 x) AND numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x AND numeral y)" - "numeral (Num.Bit0 x) AND - numeral (Num.Bit0 y) = (2 :: int) * (numeral x AND - numeral y)" - "numeral (Num.Bit0 x) AND - numeral (Num.Bit1 y) = (2 :: int) * (numeral x AND - numeral (y + Num.One))" - "numeral (Num.Bit1 x) AND - numeral (Num.Bit0 y) = (2 :: int) * (numeral x AND - numeral y)" - "numeral (Num.Bit1 x) AND - numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x AND - numeral (y + Num.One))" - "- numeral (Num.Bit0 x) AND numeral (Num.Bit0 y) = (2 :: int) * (- numeral x AND numeral y)" - "- numeral (Num.Bit0 x) AND numeral (Num.Bit1 y) = (2 :: int) * (- numeral x AND numeral y)" - "- numeral (Num.Bit1 x) AND numeral (Num.Bit0 y) = (2 :: int) * (- numeral (x + Num.One) AND numeral y)" - "- numeral (Num.Bit1 x) AND numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral (x + Num.One) AND numeral y)" - "- numeral (Num.Bit0 x) AND - numeral (Num.Bit0 y) = (2 :: int) * (- numeral x AND - numeral y)" - "- numeral (Num.Bit0 x) AND - numeral (Num.Bit1 y) = (2 :: int) * (- numeral x AND - numeral (y + Num.One))" - "- numeral (Num.Bit1 x) AND - numeral (Num.Bit0 y) = (2 :: int) * (- numeral (x + Num.One) AND - numeral y)" - "- numeral (Num.Bit1 x) AND - numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral (x + Num.One) AND - numeral (y + Num.One))" - "(1::int) AND numeral (Num.Bit0 y) = 0" - "(1::int) AND numeral (Num.Bit1 y) = 1" - "(1::int) AND - numeral (Num.Bit0 y) = 0" - "(1::int) AND - numeral (Num.Bit1 y) = 1" - "numeral (Num.Bit0 x) AND (1::int) = 0" - "numeral (Num.Bit1 x) AND (1::int) = 1" - "- numeral (Num.Bit0 x) AND (1::int) = 0" - "- numeral (Num.Bit1 x) AND (1::int) = 1" + \numeral (Num.Bit0 x) AND numeral (Num.Bit0 y) = (2 :: int) * (numeral x AND numeral y)\ + \numeral (Num.Bit0 x) AND numeral (Num.Bit1 y) = (2 :: int) * (numeral x AND numeral y)\ + \numeral (Num.Bit1 x) AND numeral (Num.Bit0 y) = (2 :: int) * (numeral x AND numeral y)\ + \numeral (Num.Bit1 x) AND numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x AND numeral y)\ + \numeral (Num.Bit0 x) AND - numeral (Num.Bit0 y) = (2 :: int) * (numeral x AND - numeral y)\ + \numeral (Num.Bit0 x) AND - numeral (Num.Bit1 y) = (2 :: int) * (numeral x AND - numeral (y + Num.One))\ + \numeral (Num.Bit1 x) AND - numeral (Num.Bit0 y) = (2 :: int) * (numeral x AND - numeral y)\ + \numeral (Num.Bit1 x) AND - numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x AND - numeral (y + Num.One))\ + \- numeral (Num.Bit0 x) AND numeral (Num.Bit0 y) = (2 :: int) * (- numeral x AND numeral y)\ + \- numeral (Num.Bit0 x) AND numeral (Num.Bit1 y) = (2 :: int) * (- numeral x AND numeral y)\ + \- numeral (Num.Bit1 x) AND numeral (Num.Bit0 y) = (2 :: int) * (- numeral (x + Num.One) AND numeral y)\ + \- numeral (Num.Bit1 x) AND numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral (x + Num.One) AND numeral y)\ + \- numeral (Num.Bit0 x) AND - numeral (Num.Bit0 y) = (2 :: int) * (- numeral x AND - numeral y)\ + \- numeral (Num.Bit0 x) AND - numeral (Num.Bit1 y) = (2 :: int) * (- numeral x AND - numeral (y + Num.One))\ + \- numeral (Num.Bit1 x) AND - numeral (Num.Bit0 y) = (2 :: int) * (- numeral (x + Num.One) AND - numeral y)\ + \- numeral (Num.Bit1 x) AND - numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral (x + Num.One) AND - numeral (y + Num.One))\ + \(1::int) AND numeral (Num.Bit0 y) = 0\ + \(1::int) AND numeral (Num.Bit1 y) = 1\ + \(1::int) AND - numeral (Num.Bit0 y) = 0\ + \(1::int) AND - numeral (Num.Bit1 y) = 1\ + \numeral (Num.Bit0 x) AND (1::int) = 0\ + \numeral (Num.Bit1 x) AND (1::int) = 1\ + \- numeral (Num.Bit0 x) AND (1::int) = 0\ + \- numeral (Num.Bit1 x) AND (1::int) = 1\ by (auto simp add: bit_and_iff bit_minus_iff even_and_iff bit_double_iff even_bit_succ_iff add_One sub_inc_One_eq intro: eqI) lemma int_or_numerals [simp]: - "numeral (Num.Bit0 x) OR numeral (Num.Bit0 y) = (2 :: int) * (numeral x OR numeral y)" - "numeral (Num.Bit0 x) OR numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x OR numeral y)" - "numeral (Num.Bit1 x) OR numeral (Num.Bit0 y) = 1 + (2 :: int) * (numeral x OR numeral y)" - "numeral (Num.Bit1 x) OR numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x OR numeral y)" - "numeral (Num.Bit0 x) OR - numeral (Num.Bit0 y) = (2 :: int) * (numeral x OR - numeral y)" - "numeral (Num.Bit0 x) OR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x OR - numeral (y + Num.One))" - "numeral (Num.Bit1 x) OR - numeral (Num.Bit0 y) = 1 + (2 :: int) * (numeral x OR - numeral y)" - "numeral (Num.Bit1 x) OR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x OR - numeral (y + Num.One))" - "- numeral (Num.Bit0 x) OR numeral (Num.Bit0 y) = (2 :: int) * (- numeral x OR numeral y)" - "- numeral (Num.Bit0 x) OR numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral x OR numeral y)" - "- numeral (Num.Bit1 x) OR numeral (Num.Bit0 y) = 1 + (2 :: int) * (- numeral (x + Num.One) OR numeral y)" - "- numeral (Num.Bit1 x) OR numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral (x + Num.One) OR numeral y)" - "- numeral (Num.Bit0 x) OR - numeral (Num.Bit0 y) = (2 :: int) * (- numeral x OR - numeral y)" - "- numeral (Num.Bit0 x) OR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral x OR - numeral (y + Num.One))" - "- numeral (Num.Bit1 x) OR - numeral (Num.Bit0 y) = 1 + (2 :: int) * (- numeral (x + Num.One) OR - numeral y)" - "- numeral (Num.Bit1 x) OR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral (x + Num.One) OR - numeral (y + Num.One))" - "(1::int) OR numeral (Num.Bit0 y) = numeral (Num.Bit1 y)" - "(1::int) OR numeral (Num.Bit1 y) = numeral (Num.Bit1 y)" - "(1::int) OR - numeral (Num.Bit0 y) = - numeral (Num.BitM y)" - "(1::int) OR - numeral (Num.Bit1 y) = - numeral (Num.Bit1 y)" - "numeral (Num.Bit0 x) OR (1::int) = numeral (Num.Bit1 x)" - "numeral (Num.Bit1 x) OR (1::int) = numeral (Num.Bit1 x)" - "- numeral (Num.Bit0 x) OR (1::int) = - numeral (Num.BitM x)" - "- numeral (Num.Bit1 x) OR (1::int) = - numeral (Num.Bit1 x)" + \numeral (Num.Bit0 x) OR numeral (Num.Bit0 y) = (2 :: int) * (numeral x OR numeral y)\ + \numeral (Num.Bit0 x) OR numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x OR numeral y)\ + \numeral (Num.Bit1 x) OR numeral (Num.Bit0 y) = 1 + (2 :: int) * (numeral x OR numeral y)\ + \numeral (Num.Bit1 x) OR numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x OR numeral y)\ + \numeral (Num.Bit0 x) OR - numeral (Num.Bit0 y) = (2 :: int) * (numeral x OR - numeral y)\ + \numeral (Num.Bit0 x) OR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x OR - numeral (y + Num.One))\ + \numeral (Num.Bit1 x) OR - numeral (Num.Bit0 y) = 1 + (2 :: int) * (numeral x OR - numeral y)\ + \numeral (Num.Bit1 x) OR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x OR - numeral (y + Num.One))\ + \- numeral (Num.Bit0 x) OR numeral (Num.Bit0 y) = (2 :: int) * (- numeral x OR numeral y)\ + \- numeral (Num.Bit0 x) OR numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral x OR numeral y)\ + \- numeral (Num.Bit1 x) OR numeral (Num.Bit0 y) = 1 + (2 :: int) * (- numeral (x + Num.One) OR numeral y)\ + \- numeral (Num.Bit1 x) OR numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral (x + Num.One) OR numeral y)\ + \- numeral (Num.Bit0 x) OR - numeral (Num.Bit0 y) = (2 :: int) * (- numeral x OR - numeral y)\ + \- numeral (Num.Bit0 x) OR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral x OR - numeral (y + Num.One))\ + \- numeral (Num.Bit1 x) OR - numeral (Num.Bit0 y) = 1 + (2 :: int) * (- numeral (x + Num.One) OR - numeral y)\ + \- numeral (Num.Bit1 x) OR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral (x + Num.One) OR - numeral (y + Num.One))\ + \(1::int) OR numeral (Num.Bit0 y) = numeral (Num.Bit1 y)\ + \(1::int) OR numeral (Num.Bit1 y) = numeral (Num.Bit1 y)\ + \(1::int) OR - numeral (Num.Bit0 y) = - numeral (Num.BitM y)\ + \(1::int) OR - numeral (Num.Bit1 y) = - numeral (Num.Bit1 y)\ + \numeral (Num.Bit0 x) OR (1::int) = numeral (Num.Bit1 x)\ + \numeral (Num.Bit1 x) OR (1::int) = numeral (Num.Bit1 x)\ + \- numeral (Num.Bit0 x) OR (1::int) = - numeral (Num.BitM x)\ + \- numeral (Num.Bit1 x) OR (1::int) = - numeral (Num.Bit1 x)\ by (auto simp add: bit_or_iff bit_minus_iff even_or_iff bit_double_iff even_bit_succ_iff add_One sub_inc_One_eq sub_BitM_One_eq intro: eqI) lemma int_xor_numerals [simp]: - "numeral (Num.Bit0 x) XOR numeral (Num.Bit0 y) = (2 :: int) * (numeral x XOR numeral y)" - "numeral (Num.Bit0 x) XOR numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x XOR numeral y)" - "numeral (Num.Bit1 x) XOR numeral (Num.Bit0 y) = 1 + (2 :: int) * (numeral x XOR numeral y)" - "numeral (Num.Bit1 x) XOR numeral (Num.Bit1 y) = (2 :: int) * (numeral x XOR numeral y)" - "numeral (Num.Bit0 x) XOR - numeral (Num.Bit0 y) = (2 :: int) * (numeral x XOR - numeral y)" - "numeral (Num.Bit0 x) XOR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x XOR - numeral (y + Num.One))" - "numeral (Num.Bit1 x) XOR - numeral (Num.Bit0 y) = 1 + (2 :: int) * (numeral x XOR - numeral y)" - "numeral (Num.Bit1 x) XOR - numeral (Num.Bit1 y) = (2 :: int) * (numeral x XOR - numeral (y + Num.One))" - "- numeral (Num.Bit0 x) XOR numeral (Num.Bit0 y) = (2 :: int) * (- numeral x XOR numeral y)" - "- numeral (Num.Bit0 x) XOR numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral x XOR numeral y)" - "- numeral (Num.Bit1 x) XOR numeral (Num.Bit0 y) = 1 + (2 :: int) * (- numeral (x + Num.One) XOR numeral y)" - "- numeral (Num.Bit1 x) XOR numeral (Num.Bit1 y) = (2 :: int) * (- numeral (x + Num.One) XOR numeral y)" - "- numeral (Num.Bit0 x) XOR - numeral (Num.Bit0 y) = (2 :: int) * (- numeral x XOR - numeral y)" - "- numeral (Num.Bit0 x) XOR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral x XOR - numeral (y + Num.One))" - "- numeral (Num.Bit1 x) XOR - numeral (Num.Bit0 y) = 1 + (2 :: int) * (- numeral (x + Num.One) XOR - numeral y)" - "- numeral (Num.Bit1 x) XOR - numeral (Num.Bit1 y) = (2 :: int) * (- numeral (x + Num.One) XOR - numeral (y + Num.One))" - "(1::int) XOR numeral (Num.Bit0 y) = numeral (Num.Bit1 y)" - "(1::int) XOR numeral (Num.Bit1 y) = numeral (Num.Bit0 y)" - "(1::int) XOR - numeral (Num.Bit0 y) = - numeral (Num.BitM y)" - "(1::int) XOR - numeral (Num.Bit1 y) = - numeral (Num.Bit0 (y + Num.One))" - "numeral (Num.Bit0 x) XOR (1::int) = numeral (Num.Bit1 x)" - "numeral (Num.Bit1 x) XOR (1::int) = numeral (Num.Bit0 x)" - "- numeral (Num.Bit0 x) XOR (1::int) = - numeral (Num.BitM x)" - "- numeral (Num.Bit1 x) XOR (1::int) = - numeral (Num.Bit0 (x + Num.One))" + \numeral (Num.Bit0 x) XOR numeral (Num.Bit0 y) = (2 :: int) * (numeral x XOR numeral y)\ + \numeral (Num.Bit0 x) XOR numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x XOR numeral y)\ + \numeral (Num.Bit1 x) XOR numeral (Num.Bit0 y) = 1 + (2 :: int) * (numeral x XOR numeral y)\ + \numeral (Num.Bit1 x) XOR numeral (Num.Bit1 y) = (2 :: int) * (numeral x XOR numeral y)\ + \numeral (Num.Bit0 x) XOR - numeral (Num.Bit0 y) = (2 :: int) * (numeral x XOR - numeral y)\ + \numeral (Num.Bit0 x) XOR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (numeral x XOR - numeral (y + Num.One))\ + \numeral (Num.Bit1 x) XOR - numeral (Num.Bit0 y) = 1 + (2 :: int) * (numeral x XOR - numeral y)\ + \numeral (Num.Bit1 x) XOR - numeral (Num.Bit1 y) = (2 :: int) * (numeral x XOR - numeral (y + Num.One))\ + \- numeral (Num.Bit0 x) XOR numeral (Num.Bit0 y) = (2 :: int) * (- numeral x XOR numeral y)\ + \- numeral (Num.Bit0 x) XOR numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral x XOR numeral y)\ + \- numeral (Num.Bit1 x) XOR numeral (Num.Bit0 y) = 1 + (2 :: int) * (- numeral (x + Num.One) XOR numeral y)\ + \- numeral (Num.Bit1 x) XOR numeral (Num.Bit1 y) = (2 :: int) * (- numeral (x + Num.One) XOR numeral y)\ + \- numeral (Num.Bit0 x) XOR - numeral (Num.Bit0 y) = (2 :: int) * (- numeral x XOR - numeral y)\ + \- numeral (Num.Bit0 x) XOR - numeral (Num.Bit1 y) = 1 + (2 :: int) * (- numeral x XOR - numeral (y + Num.One))\ + \- numeral (Num.Bit1 x) XOR - numeral (Num.Bit0 y) = 1 + (2 :: int) * (- numeral (x + Num.One) XOR - numeral y)\ + \- numeral (Num.Bit1 x) XOR - numeral (Num.Bit1 y) = (2 :: int) * (- numeral (x + Num.One) XOR - numeral (y + Num.One))\ + \(1::int) XOR numeral (Num.Bit0 y) = numeral (Num.Bit1 y)\ + \(1::int) XOR numeral (Num.Bit1 y) = numeral (Num.Bit0 y)\ + \(1::int) XOR - numeral (Num.Bit0 y) = - numeral (Num.BitM y)\ + \(1::int) XOR - numeral (Num.Bit1 y) = - numeral (Num.Bit0 (y + Num.One))\ + \numeral (Num.Bit0 x) XOR (1::int) = numeral (Num.Bit1 x)\ + \numeral (Num.Bit1 x) XOR (1::int) = numeral (Num.Bit0 x)\ + \- numeral (Num.Bit0 x) XOR (1::int) = - numeral (Num.BitM x)\ + \- numeral (Num.Bit1 x) XOR (1::int) = - numeral (Num.Bit0 (x + Num.One))\ by (auto simp add: bit_xor_iff bit_minus_iff even_xor_iff bit_double_iff even_bit_succ_iff add_One sub_inc_One_eq sub_BitM_One_eq intro: eqI) end @@ -1621,10 +1637,6 @@ (auto simp add: Let_def * bit_signed_take_bit_iff bit_take_bit_iff min_def less_Suc_eq bit_not_iff bit_mask_iff bit_or_iff) qed -lemma not_minus_numeral_inc_eq: - \NOT (- numeral (Num.inc n)) = (numeral n :: int)\ - by (simp add: not_int_def sub_inc_One_eq) - subsection \Instance \<^typ>\nat\\ @@ -1771,6 +1783,129 @@ qed +subsection \Symbolic computations on numeral expressions\ \<^marker>\contributor \Andreas Lochbihler\\ + +fun and_num :: \num \ num \ num option\ +where + \and_num num.One num.One = Some num.One\ +| \and_num num.One (num.Bit0 n) = None\ +| \and_num num.One (num.Bit1 n) = Some num.One\ +| \and_num (num.Bit0 m) num.One = None\ +| \and_num (num.Bit0 m) (num.Bit0 n) = map_option num.Bit0 (and_num m n)\ +| \and_num (num.Bit0 m) (num.Bit1 n) = map_option num.Bit0 (and_num m n)\ +| \and_num (num.Bit1 m) num.One = Some num.One\ +| \and_num (num.Bit1 m) (num.Bit0 n) = map_option num.Bit0 (and_num m n)\ +| \and_num (num.Bit1 m) (num.Bit1 n) = (case and_num m n of None \ Some num.One | Some n' \ Some (num.Bit1 n'))\ + +fun and_not_num :: \num \ num \ num option\ +where + \and_not_num num.One num.One = None\ +| \and_not_num num.One (num.Bit0 n) = Some num.One\ +| \and_not_num num.One (num.Bit1 n) = None\ +| \and_not_num (num.Bit0 m) num.One = Some (num.Bit0 m)\ +| \and_not_num (num.Bit0 m) (num.Bit0 n) = map_option num.Bit0 (and_not_num m n)\ +| \and_not_num (num.Bit0 m) (num.Bit1 n) = map_option num.Bit0 (and_not_num m n)\ +| \and_not_num (num.Bit1 m) num.One = Some (num.Bit0 m)\ +| \and_not_num (num.Bit1 m) (num.Bit0 n) = (case and_not_num m n of None \ Some num.One | Some n' \ Some (num.Bit1 n'))\ +| \and_not_num (num.Bit1 m) (num.Bit1 n) = map_option num.Bit0 (and_not_num m n)\ + +fun or_num :: \num \ num \ num\ +where + \or_num num.One num.One = num.One\ +| \or_num num.One (num.Bit0 n) = num.Bit1 n\ +| \or_num num.One (num.Bit1 n) = num.Bit1 n\ +| \or_num (num.Bit0 m) num.One = num.Bit1 m\ +| \or_num (num.Bit0 m) (num.Bit0 n) = num.Bit0 (or_num m n)\ +| \or_num (num.Bit0 m) (num.Bit1 n) = num.Bit1 (or_num m n)\ +| \or_num (num.Bit1 m) num.One = num.Bit1 m\ +| \or_num (num.Bit1 m) (num.Bit0 n) = num.Bit1 (or_num m n)\ +| \or_num (num.Bit1 m) (num.Bit1 n) = num.Bit1 (or_num m n)\ + +fun or_not_num_neg :: \num \ num \ num\ +where + \or_not_num_neg num.One num.One = num.One\ +| \or_not_num_neg num.One (num.Bit0 m) = num.Bit1 m\ +| \or_not_num_neg num.One (num.Bit1 m) = num.Bit1 m\ +| \or_not_num_neg (num.Bit0 n) num.One = num.Bit0 num.One\ +| \or_not_num_neg (num.Bit0 n) (num.Bit0 m) = Num.BitM (or_not_num_neg n m)\ +| \or_not_num_neg (num.Bit0 n) (num.Bit1 m) = num.Bit0 (or_not_num_neg n m)\ +| \or_not_num_neg (num.Bit1 n) num.One = num.One\ +| \or_not_num_neg (num.Bit1 n) (num.Bit0 m) = Num.BitM (or_not_num_neg n m)\ +| \or_not_num_neg (num.Bit1 n) (num.Bit1 m) = Num.BitM (or_not_num_neg n m)\ + +fun xor_num :: \num \ num \ num option\ +where + \xor_num num.One num.One = None\ +| \xor_num num.One (num.Bit0 n) = Some (num.Bit1 n)\ +| \xor_num num.One (num.Bit1 n) = Some (num.Bit0 n)\ +| \xor_num (num.Bit0 m) num.One = Some (num.Bit1 m)\ +| \xor_num (num.Bit0 m) (num.Bit0 n) = map_option num.Bit0 (xor_num m n)\ +| \xor_num (num.Bit0 m) (num.Bit1 n) = Some (case xor_num m n of None \ num.One | Some n' \ num.Bit1 n')\ +| \xor_num (num.Bit1 m) num.One = Some (num.Bit0 m)\ +| \xor_num (num.Bit1 m) (num.Bit0 n) = Some (case xor_num m n of None \ num.One | Some n' \ num.Bit1 n')\ +| \xor_num (num.Bit1 m) (num.Bit1 n) = map_option num.Bit0 (xor_num m n)\ + +lemma int_numeral_and_num: + \numeral m AND numeral n = (case and_num m n of None \ 0 :: int | Some n' \ numeral n')\ + by (induction m n rule: and_num.induct) (simp_all split: option.split) + +lemma and_num_eq_None_iff: + \and_num m n = None \ numeral m AND numeral n = (0::int)\ + by (simp add: int_numeral_and_num split: option.split) + +lemma and_num_eq_Some_iff: + \and_num m n = Some q \ numeral m AND numeral n = (numeral q :: int)\ + by (simp add: int_numeral_and_num split: option.split) + +lemma int_numeral_and_not_num: + \numeral m AND NOT (numeral n) = (case and_not_num m n of None \ 0 :: int | Some n' \ numeral n')\ + by (induction m n rule: and_not_num.induct) (simp_all add: add_One BitM_inc_eq not_int_def split: option.split) + +lemma int_numeral_not_and_num: + \NOT (numeral m) AND numeral n = (case and_not_num n m of None \ 0 :: int | Some n' \ numeral n')\ + using int_numeral_and_not_num [of n m] by (simp add: ac_simps) + +lemma and_not_num_eq_None_iff: + \and_not_num m n = None \ numeral m AND NOT (numeral n) = (0::int)\ + by (simp add: int_numeral_and_not_num split: option.split) + +lemma and_not_num_eq_Some_iff: + \and_not_num m n = Some q \ numeral m AND NOT (numeral n) = (numeral q :: int)\ + by (simp add: int_numeral_and_not_num split: option.split) + +lemma int_numeral_or_num: + \numeral m OR numeral n = (numeral (or_num m n) :: int)\ + by (induction m n rule: or_num.induct) simp_all + +lemma numeral_or_num_eq: + \numeral (or_num m n) = (numeral m OR numeral n :: int)\ + by (simp add: int_numeral_or_num) + +lemma int_numeral_or_not_num_neg: + \numeral m OR NOT (numeral n :: int) = - numeral (or_not_num_neg m n)\ + by (induction m n rule: or_not_num_neg.induct) (simp_all add: add_One BitM_inc_eq not_int_def) + +lemma int_numeral_not_or_num_neg: + \NOT (numeral m) OR (numeral n :: int) = - numeral (or_not_num_neg n m)\ + using int_numeral_or_not_num_neg [of n m] by (simp add: ac_simps) + +lemma numeral_or_not_num_eq: + \numeral (or_not_num_neg m n) = - (numeral m OR NOT (numeral n :: int))\ + using int_numeral_or_not_num_neg [of m n] by simp + +lemma int_numeral_xor_num: + \numeral m XOR numeral n = (case xor_num m n of None \ 0 :: int | Some n' \ numeral n')\ + by (induction m n rule: xor_num.induct) (simp_all split: option.split) + +lemma xor_num_eq_None_iff: + \xor_num m n = None \ numeral m XOR numeral n = (0::int)\ + by (simp add: int_numeral_xor_num split: option.split) + +lemma xor_num_eq_Some_iff: + \xor_num m n = Some q \ numeral m XOR numeral n = (numeral q :: int)\ + by (simp add: int_numeral_xor_num split: option.split) + + subsection \Instances for \<^typ>\integer\ and \<^typ>\natural\\ unbundle integer.lifting natural.lifting diff -r 0274d442b7ea -r ca2a35c0fe6e src/HOL/Parity.thy --- a/src/HOL/Parity.thy Mon Jul 12 11:41:02 2021 +0000 +++ b/src/HOL/Parity.thy Mon Jul 12 11:41:02 2021 +0000 @@ -1584,6 +1584,10 @@ qed qed +lemma drop_bit_exp_eq: + \drop_bit m (2 ^ n) = of_bool (m \ n \ 2 ^ n \ 0) * 2 ^ (n - m)\ + by (rule bit_eqI) (auto simp add: bit_simps) + end instantiation nat :: semiring_bit_shifts