# HG changeset patch # User haftmann # Date 1594490949 0 # Node ID 9b4135e8bade14f730f529c10a3e7af0e16bd789 # Parent 08348e364739b0b76d6bcba9e4a8a1bad4b2f0aa a generic horner sum operation diff -r 08348e364739 -r 9b4135e8bade src/HOL/Computational_Algebra/Polynomial.thy --- a/src/HOL/Computational_Algebra/Polynomial.thy Sat Jul 11 18:09:08 2020 +0000 +++ b/src/HOL/Computational_Algebra/Polynomial.thy Sat Jul 11 18:09:09 2020 +0000 @@ -494,8 +494,12 @@ subsection \Canonical morphism on polynomials -- evaluation\ -definition poly :: "'a::comm_semiring_0 poly \ 'a \ 'a" - where "poly p = fold_coeffs (\a f x. a + x * f x) p (\x. 0)" \ \The Horner Schema\ +definition poly :: \'a::comm_semiring_0 poly \ 'a \ 'a\ + where \poly p a = horner_sum id a (coeffs p)\ + +lemma poly_eq_fold_coeffs: + \poly p = fold_coeffs (\a f x. a + x * f x) p (\x. 0)\ + by (induction p) (auto simp add: fun_eq_iff poly_def) lemma poly_0 [simp]: "poly 0 x = 0" by (simp add: poly_def) @@ -575,7 +579,7 @@ lemma poly_monom: "poly (monom a n) x = a * x ^ n" for a x :: "'a::comm_semiring_1" - by (cases "a = 0", simp_all) (induct n, simp_all add: mult.left_commute poly_def) + by (cases "a = 0", simp_all) (induct n, simp_all add: mult.left_commute poly_eq_fold_coeffs) lemma monom_eq_iff': "monom c n = monom d m \ c = d \ (c = 0 \ n = m)" by (auto simp: poly_eq_iff) diff -r 08348e364739 -r 9b4135e8bade src/HOL/Groups_List.thy --- a/src/HOL/Groups_List.thy Sat Jul 11 18:09:08 2020 +0000 +++ b/src/HOL/Groups_List.thy Sat Jul 11 18:09:09 2020 +0000 @@ -339,6 +339,123 @@ qed +subsection \Horner sums\ + +context comm_semiring_0 +begin + +definition horner_sum :: \('b \ 'a) \ 'a \ 'b list \ 'a\ + where horner_sum_foldr: \horner_sum f a xs = foldr (\x b. f x + a * b) xs 0\ + +lemma horner_sum_simps [simp]: + \horner_sum f a [] = 0\ + \horner_sum f a (x # xs) = f x + a * horner_sum f a xs\ + by (simp_all add: horner_sum_foldr) + +lemma horner_sum_eq_sum_funpow: + \horner_sum f a xs = (\n = 0.. +proof (induction xs) + case Nil + then show ?case + by simp +next + case (Cons x xs) + then show ?case + by (simp add: sum.atLeast0_lessThan_Suc_shift sum_distrib_left del: sum.op_ivl_Suc) +qed + +end + +context + includes lifting_syntax +begin + +lemma horner_sum_transfer [transfer_rule]: + \((B ===> A) ===> A ===> list_all2 B ===> A) horner_sum horner_sum\ + if [transfer_rule]: \A 0 0\ + and [transfer_rule]: \(A ===> A ===> A) (+) (+)\ + and [transfer_rule]: \(A ===> A ===> A) (*) (*)\ + by (unfold horner_sum_foldr) transfer_prover + +end + +context comm_semiring_1 +begin + +lemma horner_sum_eq_sum: + \horner_sum f a xs = (\n = 0.. +proof - + have \(*) a ^^ n = (*) (a ^ n)\ for n + by (induction n) (simp_all add: ac_simps) + then show ?thesis + by (simp add: horner_sum_eq_sum_funpow ac_simps) +qed + +end + +context semiring_bit_shifts +begin + +lemma horner_sum_bit_eq_take_bit: + \horner_sum of_bool 2 (map (bit a) [0.. +proof (induction a arbitrary: n rule: bits_induct) + case (stable a) + moreover have \bit a = (\_. odd a)\ + using stable by (simp add: stable_imp_bit_iff_odd fun_eq_iff) + moreover have \{q. q < n} = {0.. + by auto + ultimately show ?case + by (simp add: stable_imp_take_bit_eq horner_sum_eq_sum mask_eq_sum_exp) +next + case (rec a b) + show ?case + proof (cases n) + case 0 + then show ?thesis + by simp + next + case (Suc m) + have \map (bit (of_bool b + 2 * a)) [0.. + by (simp only: upt_conv_Cons) simp + also have \\ = b # map (bit a) [0.. + by (simp only: flip: map_Suc_upt) (simp add: bit_Suc rec.hyps) + finally show ?thesis + using Suc rec.IH [of m] by (simp add: take_bit_Suc rec.hyps, simp add: ac_simps mod_2_eq_odd) + qed +qed + +end + +context unique_euclidean_semiring_with_bit_shifts +begin + +lemma bit_horner_sum_bit_iff: + \bit (horner_sum of_bool 2 bs) n \ n < length bs \ bs ! n\ +proof (induction bs arbitrary: n) + case Nil + then show ?case + by simp +next + case (Cons b bs) + show ?case + proof (cases n) + case 0 + then show ?thesis + by simp + next + case (Suc m) + with bit_rec [of _ n] Cons.prems Cons.IH [of m] + show ?thesis by simp + qed +qed + +lemma take_bit_horner_sum_bit_eq: + \take_bit n (horner_sum of_bool 2 bs) = horner_sum of_bool 2 (take n bs)\ + by (auto simp add: bit_eq_iff bit_take_bit_iff bit_horner_sum_bit_iff) + +end + + subsection \Further facts about \<^const>\List.n_lists\\ lemma length_n_lists: "length (List.n_lists n xs) = length xs ^ n" diff -r 08348e364739 -r 9b4135e8bade src/HOL/Parity.thy --- a/src/HOL/Parity.thy Sat Jul 11 18:09:08 2020 +0000 +++ b/src/HOL/Parity.thy Sat Jul 11 18:09:09 2020 +0000 @@ -172,15 +172,6 @@ by simp qed -lemma mask_eq_seq_sum: - \2 ^ n - 1 = ((\k. 1 + k * 2) ^^ n) 0\ -proof - - have \2 ^ n = ((\k. 1 + k * 2) ^^ n) 0 + 1\ - by (induction n) (simp_all add: ac_simps mult_2) - then show ?thesis - by simp -qed - end class ring_parity = ring + semiring_parity diff -r 08348e364739 -r 9b4135e8bade src/HOL/String.thy --- a/src/HOL/String.thy Sat Jul 11 18:09:08 2020 +0000 +++ b/src/HOL/String.thy Sat Jul 11 18:09:09 2020 +0000 @@ -21,81 +21,6 @@ subsubsection \Bytes as datatype\ -context unique_euclidean_semiring_with_bit_shifts -begin - -lemma bit_horner_sum_iff: - \bit (foldr (\b k. of_bool b + k * 2) bs 0) n \ n < length bs \ bs ! n\ -proof (induction bs arbitrary: n) - case Nil - then show ?case - by simp -next - case (Cons b bs) - show ?case - proof (cases n) - case 0 - then show ?thesis - by simp - next - case (Suc m) - with bit_rec [of _ n] Cons.prems Cons.IH [of m] - show ?thesis by simp - qed -qed - -lemma take_bit_horner_sum_eq: - \take_bit n (foldr (\b k. of_bool b + k * 2) bs 0) = foldr (\b k. of_bool b + k * 2) (take n bs) 0\ -proof (induction bs arbitrary: n) - case Nil - then show ?case - by simp -next - case (Cons b bs) - show ?case - proof (cases n) - case 0 - then show ?thesis - by simp - next - case (Suc m) - with take_bit_rec [of n] Cons.prems Cons.IH [of m] - show ?thesis by (simp add: ac_simps) - qed -qed - -lemma (in semiring_bit_shifts) take_bit_eq_horner_sum: - \take_bit n a = foldr (\b k. of_bool b + k * 2) (map (bit a) [0.. -proof (induction a arbitrary: n rule: bits_induct) - case (stable a) - have *: \((\k. k * 2) ^^ n) 0 = 0\ - by (induction n) simp_all - from stable have \bit a = (\_. odd a)\ - by (simp add: stable_imp_bit_iff_odd fun_eq_iff) - then have \map (bit a) [0.. - by (simp add: map_replicate_const) - with stable show ?case - by (simp add: stable_imp_take_bit_eq mask_eq_seq_sum *) -next - case (rec a b) - show ?case - proof (cases n) - case 0 - then show ?thesis - by simp - next - case (Suc m) - have \map (bit (of_bool b + 2 * a)) [0.. - by (simp only: upt_conv_Cons) simp - also have \\ = b # map (bit a) [0.. - by (simp only: flip: map_Suc_upt) (simp add: bit_Suc rec.hyps) - finally show ?thesis - using Suc rec.IH [of m] by (simp add: take_bit_Suc rec.hyps, simp add: ac_simps mod_2_eq_odd) - qed -qed - -end - datatype char = Char (digit0: bool) (digit1: bool) (digit2: bool) (digit3: bool) (digit4: bool) (digit5: bool) (digit6: bool) (digit7: bool) @@ -104,12 +29,11 @@ begin definition of_char :: \char \ 'a\ - where \of_char c = foldr (\b k. of_bool b + k * 2) - [digit0 c, digit1 c, digit2 c, digit3 c, digit4 c, digit5 c, digit6 c, digit7 c] 0\ + where \of_char c = horner_sum of_bool 2 [digit0 c, digit1 c, digit2 c, digit3 c, digit4 c, digit5 c, digit6 c, digit7 c]\ lemma of_char_Char [simp]: \of_char (Char b0 b1 b2 b3 b4 b5 b6 b7) = - foldr (\b k. of_bool b + k * 2) [b0, b1, b2, b3, b4, b5, b6, b7] 0\ + horner_sum of_bool 2 [b0, b1, b2, b3, b4, b5, b6, b7]\ by (simp add: of_char_def) end @@ -126,7 +50,7 @@ lemma char_of_char [simp]: \char_of (of_char c) = c\ - by (simp only: of_char_def char_of_def bit_horner_sum_iff) simp + by (simp only: of_char_def char_of_def bit_horner_sum_bit_iff) simp lemma char_of_comp_of_char [simp]: "char_of \ of_char = id" @@ -159,7 +83,7 @@ then have \[odd a, bit a 1, bit a 2, bit a 3, bit a 4, bit a 5, bit a 6, bit a 7] = map (bit a) [0..<8]\ by simp then have \of_char (char_of a) = take_bit 8 a\ - by (simp only: char_of_def of_char_def char.sel take_bit_eq_horner_sum) + by (simp only: char_of_def of_char_def char.sel horner_sum_bit_eq_take_bit) then show ?thesis by (simp add: take_bit_eq_mod) qed @@ -440,7 +364,7 @@ qualified lemma char_of_ascii_of [simp]: "of_char (ascii_of c) = take_bit 7 (of_char c :: nat)" - by (cases c) (simp only: ascii_of_Char of_char_Char take_bit_horner_sum_eq, simp) + by (cases c) (simp only: ascii_of_Char of_char_Char take_bit_horner_sum_bit_eq, simp) qualified typedef literal = "{cs. \c\set cs. \ digit7 c}" morphisms explode Abs_literal diff -r 08348e364739 -r 9b4135e8bade src/HOL/ex/Bit_Lists.thy --- a/src/HOL/ex/Bit_Lists.thy Sat Jul 11 18:09:08 2020 +0000 +++ b/src/HOL/ex/Bit_Lists.thy Sat Jul 11 18:09:09 2020 +0000 @@ -13,12 +13,8 @@ context comm_semiring_1 begin -primrec radix_value :: "('b \ 'a) \ 'a \ 'b list \ 'a" - where "radix_value f b [] = 0" - | "radix_value f b (a # as) = f a + radix_value f b as * b" - abbreviation (input) unsigned_of_bits :: "bool list \ 'a" - where "unsigned_of_bits \ radix_value of_bool 2" + where "unsigned_of_bits \ horner_sum of_bool 2" lemma unsigned_of_bits_replicate_False [simp]: "unsigned_of_bits (replicate n False) = 0"