diff --git a/src/HOL/Library/Z2.thy b/src/HOL/Library/Z2.thy --- a/src/HOL/Library/Z2.thy +++ b/src/HOL/Library/Z2.thy @@ -1,267 +1,234 @@ (* Title: HOL/Library/Z2.thy Author: Brian Huffman *) section \The Field of Integers mod 2\ theory Z2 imports Main "HOL-Library.Bit_Operations" begin text \ Note that in most cases \<^typ>\bool\ is appropriate hen a binary type is needed; the type provided here, for historical reasons named \<^text>\bit\, is only needed if proper field operations are required. \ -subsection \Bits as a datatype\ +typedef bit = \UNIV :: bool set\ .. -typedef bit = "UNIV :: bool set" - morphisms set Bit .. - -instantiation bit :: "{zero, one}" +instantiation bit :: zero_neq_one begin -definition zero_bit_def: "0 = Bit False" +definition zero_bit :: bit + where \0 = Abs_bit False\ -definition one_bit_def: "1 = Bit True" +definition one_bit :: bit + where \1 = Abs_bit True\ -instance .. +instance + by standard (simp add: zero_bit_def one_bit_def Abs_bit_inject) end -old_rep_datatype "0::bit" "1::bit" +free_constructors case_bit for \0::bit\ | \1::bit\ proof - - fix P :: "bit \ bool" - fix x :: bit - assume "P 0" and "P 1" - then have "\b. P (Bit b)" - unfolding zero_bit_def one_bit_def - by (simp add: all_bool_eq) - then show "P x" - by (induct x) simp -next - show "(0::bit) \ (1::bit)" - unfolding zero_bit_def one_bit_def - by (simp add: Bit_inject) + fix P :: bool + fix a :: bit + assume \a = 0 \ P\ and \a = 1 \ P\ + then show P + by (cases a) (auto simp add: zero_bit_def one_bit_def Abs_bit_inject) +qed simp + +lemma bit_not_zero_iff [simp]: + \a \ 0 \ a = 1\ for a :: bit + by (cases a) simp_all + +lemma bit_not_one_imp [simp]: + \a \ 1 \ a = 0\ for a :: bit + by (cases a) simp_all + +instantiation bit :: semidom_modulo +begin + +definition plus_bit :: \bit \ bit \ bit\ + where \a + b = Abs_bit (Rep_bit a \ Rep_bit b)\ + +definition minus_bit :: \bit \ bit \ bit\ + where [simp]: \minus_bit = plus\ + +definition times_bit :: \bit \ bit \ bit\ + where \a * b = Abs_bit (Rep_bit a \ Rep_bit b)\ + +definition divide_bit :: \bit \ bit \ bit\ + where [simp]: \divide_bit = times\ + +definition modulo_bit :: \bit \ bit \ bit\ + where \a mod b = Abs_bit (Rep_bit a \ \ Rep_bit b)\ + +instance + by standard + (auto simp flip: Rep_bit_inject + simp add: zero_bit_def one_bit_def plus_bit_def times_bit_def modulo_bit_def Abs_bit_inverse Rep_bit_inverse) + +end + +lemma bit_2_eq_0 [simp]: + \2 = (0::bit)\ + by (simp flip: one_add_one add: zero_bit_def plus_bit_def) + +instance bit :: semiring_parity + apply standard + apply (auto simp flip: Rep_bit_inject simp add: modulo_bit_def Abs_bit_inverse Rep_bit_inverse) + apply (auto simp add: zero_bit_def one_bit_def Abs_bit_inverse Rep_bit_inverse) + done + +lemma Abs_bit_eq_of_bool [code_abbrev]: + \Abs_bit = of_bool\ + by (simp add: fun_eq_iff zero_bit_def one_bit_def) + +lemma Rep_bit_eq_odd: + \Rep_bit = odd\ +proof - + have \\ Rep_bit 0\ + by (simp only: zero_bit_def) (subst Abs_bit_inverse, auto) + then show ?thesis + by (auto simp flip: Rep_bit_inject simp add: fun_eq_iff) qed -lemma Bit_set_eq [simp]: "Bit (set b) = b" - by (fact set_inverse) +lemma Rep_bit_iff_odd [code_abbrev]: + \Rep_bit b \ odd b\ + by (simp add: Rep_bit_eq_odd) -lemma set_Bit_eq [simp]: "set (Bit P) = P" - by (rule Bit_inverse) rule +lemma Not_Rep_bit_iff_even [code_abbrev]: + \\ Rep_bit b \ even b\ + by (simp add: Rep_bit_eq_odd) + +lemma Not_Not_Rep_bit [code_unfold]: + \\ \ Rep_bit b \ Rep_bit b\ + by simp + +code_datatype \0::bit\ \1::bit\ + +lemma Abs_bit_code [code]: + \Abs_bit False = 0\ + \Abs_bit True = 1\ + by (simp_all add: Abs_bit_eq_of_bool) + +lemma Rep_bit_code [code]: + \Rep_bit 0 \ False\ + \Rep_bit 1 \ True\ + by (simp_all add: Rep_bit_eq_odd) + +context zero_neq_one +begin + +abbreviation of_bit :: \bit \ 'a\ + where \of_bit b \ of_bool (odd b)\ + +end context begin -qualified lemma bit_eq_iff: "x = y \ (set x \ set y)" - by (auto simp add: set_inject) - -end - -lemma Bit_inject [simp]: "Bit P = Bit Q \ (P \ Q)" - by (auto simp add: Bit_inject) - -lemma set [iff]: - "\ set 0" - "set 1" - by (simp_all add: zero_bit_def one_bit_def Bit_inverse) - -lemma [code]: - "set 0 \ False" - "set 1 \ True" - by simp_all - -lemma set_iff: "set b \ b = 1" - by (cases b) simp_all - -lemma bit_eq_iff_set: - "b = 0 \ \ set b" - "b = 1 \ set b" - by (simp_all add: Z2.bit_eq_iff) - -lemma Bit [simp, code]: - "Bit False = 0" - "Bit True = 1" - by (simp_all add: zero_bit_def one_bit_def) - -lemma bit_not_0_iff [iff]: "x \ 0 \ x = 1" for x :: bit - by (simp add: Z2.bit_eq_iff) - -lemma bit_not_1_iff [iff]: "x \ 1 \ x = 0" for x :: bit - by (simp add: Z2.bit_eq_iff) - -lemma [code]: - "HOL.equal 0 b \ \ set b" - "HOL.equal 1 b \ set b" - by (simp_all add: equal set_iff) - - -subsection \Type \<^typ>\bit\ forms a field\ - -instantiation bit :: field -begin - -definition plus_bit_def: "x + y = case_bit y (case_bit 1 0 y) x" - -definition times_bit_def: "x * y = case_bit 0 y x" - -definition uminus_bit_def [simp]: "- x = x" for x :: bit - -definition minus_bit_def [simp]: "x - y = x + y" for x y :: bit - -definition inverse_bit_def [simp]: "inverse x = x" for x :: bit - -definition divide_bit_def [simp]: "x div y = x * y" for x y :: bit - -lemmas field_bit_defs = - plus_bit_def times_bit_def minus_bit_def uminus_bit_def - divide_bit_def inverse_bit_def - -instance - by standard (auto simp: plus_bit_def times_bit_def split: bit.split) +qualified lemma bit_eq_iff: + \a = b \ (even a \ even b)\ for a b :: bit + by (cases a; cases b) simp_all end -lemma bit_add_self: "x + x = 0" for x :: bit - unfolding plus_bit_def by (simp split: bit.split) - -lemma bit_mult_eq_1_iff [simp]: "x * y = 1 \ x = 1 \ y = 1" for x y :: bit - unfolding times_bit_def by (simp split: bit.split) - -text \Not sure whether the next two should be simp rules.\ - -lemma bit_add_eq_0_iff: "x + y = 0 \ x = y" for x y :: bit - unfolding plus_bit_def by (simp split: bit.split) - -lemma bit_add_eq_1_iff: "x + y = 1 \ x \ y" for x y :: bit - unfolding plus_bit_def by (simp split: bit.split) - - -subsection \Numerals at type \<^typ>\bit\\ - -text \All numerals reduce to either 0 or 1.\ - -lemma bit_minus1 [simp]: "- 1 = (1 :: bit)" - by (simp only: uminus_bit_def) - -lemma bit_neg_numeral [simp]: "(- numeral w :: bit) = numeral w" - by (simp only: uminus_bit_def) - -lemma bit_numeral_even [simp]: "numeral (Num.Bit0 w) = (0 :: bit)" - by (simp only: numeral_Bit0 bit_add_self) - -lemma bit_numeral_odd [simp]: "numeral (Num.Bit1 w) = (1 :: bit)" - by (simp only: numeral_Bit1 bit_add_self add_0_left) - - -subsection \Conversion from \<^typ>\bit\\ +lemma modulo_bit_unfold [simp, code]: + \a mod b = of_bool (odd a \ even b)\ for a b :: bit + by (simp add: modulo_bit_def Abs_bit_eq_of_bool Rep_bit_eq_odd) -context zero_neq_one -begin - -definition of_bit :: "bit \ 'a" - where "of_bit b = case_bit 0 1 b" - -lemma of_bit_eq [simp, code]: - "of_bit 0 = 0" - "of_bit 1 = 1" - by (simp_all add: of_bit_def) - -lemma of_bit_eq_iff: "of_bit x = of_bit y \ x = y" - by (cases x) (cases y; simp)+ - -end - -lemma (in semiring_1) of_nat_of_bit_eq: "of_nat (of_bit b) = of_bit b" - by (cases b) simp_all - -lemma (in ring_1) of_int_of_bit_eq: "of_int (of_bit b) = of_bit b" - by (cases b) simp_all - - -subsection \Bit structure\ - -instantiation bit :: semidom_modulo -begin - -definition modulo_bit :: \bit \ bit \ bit\ - where [simp]: \a mod b = a * of_bool (b = 0)\ for a b :: bit - -instance - by standard simp - -end +lemma power_bit_unfold [simp, code]: + \a ^ n = of_bool (odd a \ n = 0)\ for a :: bit + by (cases a) simp_all instantiation bit :: semiring_bits begin definition bit_bit :: \bit \ nat \ bool\ - where [simp]: \bit_bit b n \ b = 1 \ n = 0\ + where [simp]: \bit_bit b n \ odd b \ n = 0\ instance apply standard - apply (auto simp add: power_0_left power_add set_iff) - apply (metis bit_not_1_iff of_bool_eq(2)) + apply auto + apply (metis bit.exhaust of_bool_eq(2)) done end instantiation bit :: semiring_bit_shifts begin definition push_bit_bit :: \nat \ bit \ bit\ - where \push_bit n b = (if n = 0 then b else 0)\ for b :: bit + where [simp]: \push_bit n b = of_bool (odd b \ n = 0)\ for b :: bit definition drop_bit_bit :: \nat \ bit \ bit\ - where \drop_bit n b = (if n = 0 then b else 0)\ for b :: bit + where [simp]: \drop_bit_bit = push_bit\ definition take_bit_bit :: \nat \ bit \ bit\ - where \take_bit n b = (if n = 0 then 0 else b)\ for b :: bit + where [simp]: \take_bit n b = of_bool (odd b \ n > 0)\ for b :: bit instance - by standard (simp_all add: push_bit_bit_def drop_bit_bit_def take_bit_bit_def) + by standard simp_all + +end + +instantiation bit :: semiring_bit_operations +begin + +definition and_bit :: \bit \ bit \ bit\ + where [simp]: \b AND c = of_bool (odd b \ odd c)\ for b c :: bit + +definition or_bit :: \bit \ bit \ bit\ + where [simp]: \b OR c = of_bool (odd b \ odd c)\ for b c :: bit + +definition xor_bit :: \bit \ bit \ bit\ + where [simp]: \b XOR c = of_bool (odd b \ odd c)\ for b c :: bit + +instance + by standard auto + +end + +lemma add_bit_eq_xor [simp, code]: + \(+) = ((XOR) :: bit \ _)\ + by (auto simp add: fun_eq_iff) + +lemma mult_bit_eq_and [simp, code]: + \(*) = ((AND) :: bit \ _)\ + by (simp add: fun_eq_iff) + +instantiation bit :: field +begin + +definition uminus_bit :: \bit \ bit\ + where [simp]: \uminus_bit = id\ + +definition inverse_bit :: \bit \ bit\ + where [simp]: \inverse_bit = id\ + +instance + by standard simp_all end instantiation bit :: ring_bit_operations begin definition not_bit :: \bit \ bit\ - where \NOT b = of_bool (even b)\ for b :: bit - -definition and_bit :: \bit \ bit \ bit\ - where \b AND c = of_bool (odd b \ odd c)\ for b c :: bit - -definition or_bit :: \bit \ bit \ bit\ - where \b OR c = of_bool (odd b \ odd c)\ for b c :: bit - -definition xor_bit :: \bit \ bit \ bit\ - where \b XOR c = of_bool (odd b \ odd c)\ for b c :: bit + where [simp]: \NOT b = of_bool (even b)\ for b :: bit instance - by standard (auto simp add: and_bit_def or_bit_def xor_bit_def not_bit_def add_eq_0_iff) + by standard simp_all end -lemma add_bit_eq_xor: - \(+) = ((XOR) :: bit \ _)\ - by (auto simp add: fun_eq_iff plus_bit_def xor_bit_def) - -lemma mult_bit_eq_and: - \(*) = ((AND) :: bit \ _)\ - by (simp add: fun_eq_iff times_bit_def and_bit_def split: bit.split) +lemma bit_numeral_even [simp]: "numeral (Num.Bit0 w) = (0 :: bit)" + by (simp only: Z2.bit_eq_iff even_numeral) simp -lemma bit_NOT_eq_1_iff [simp]: "NOT b = 1 \ b = 0" - for b :: bit - by (cases b) simp_all - -lemma bit_AND_eq_1_iff [simp]: "a AND b = 1 \ a = 1 \ b = 1" - for a b :: bit - by (cases a; cases b) simp_all - - -hide_const (open) set +lemma bit_numeral_odd [simp]: "numeral (Num.Bit1 w) = (1 :: bit)" + by (simp only: Z2.bit_eq_iff odd_numeral) simp end