src/HOL/Library/Polynomial.thy
changeset 58199 5fbe474b5da8
parent 57862 8f074e6e22fc
child 58513 0bf0cf1d3547
equal deleted inserted replaced
58198:099ca49b5231 58199:5fbe474b5da8
     5 *)
     5 *)
     6 
     6 
     7 header {* Polynomials as type over a ring structure *}
     7 header {* Polynomials as type over a ring structure *}
     8 
     8 
     9 theory Polynomial
     9 theory Polynomial
    10 imports Main GCD
    10 imports Main GCD "~~/src/HOL/Library/More_List"
    11 begin
    11 begin
    12 
    12 
    13 subsection {* Auxiliary: operations for lists (later) representing coefficients *}
    13 subsection {* Auxiliary: operations for lists (later) representing coefficients *}
    14 
       
    15 definition strip_while :: "('a \<Rightarrow> bool) \<Rightarrow> 'a list \<Rightarrow> 'a list"
       
    16 where
       
    17   "strip_while P = rev \<circ> dropWhile P \<circ> rev"
       
    18 
       
    19 lemma strip_while_Nil [simp]:
       
    20   "strip_while P [] = []"
       
    21   by (simp add: strip_while_def)
       
    22 
       
    23 lemma strip_while_append [simp]:
       
    24   "\<not> P x \<Longrightarrow> strip_while P (xs @ [x]) = xs @ [x]"
       
    25   by (simp add: strip_while_def)
       
    26 
       
    27 lemma strip_while_append_rec [simp]:
       
    28   "P x \<Longrightarrow> strip_while P (xs @ [x]) = strip_while P xs"
       
    29   by (simp add: strip_while_def)
       
    30 
       
    31 lemma strip_while_Cons [simp]:
       
    32   "\<not> P x \<Longrightarrow> strip_while P (x # xs) = x # strip_while P xs"
       
    33   by (induct xs rule: rev_induct) (simp_all add: strip_while_def)
       
    34 
       
    35 lemma strip_while_eq_Nil [simp]:
       
    36   "strip_while P xs = [] \<longleftrightarrow> (\<forall>x\<in>set xs. P x)"
       
    37   by (simp add: strip_while_def)
       
    38 
       
    39 lemma strip_while_eq_Cons_rec:
       
    40   "strip_while P (x # xs) = x # strip_while P xs \<longleftrightarrow> \<not> (P x \<and> (\<forall>x\<in>set xs. P x))"
       
    41   by (induct xs rule: rev_induct) (simp_all add: strip_while_def)
       
    42 
       
    43 lemma strip_while_not_last [simp]:
       
    44   "\<not> P (last xs) \<Longrightarrow> strip_while P xs = xs"
       
    45   by (cases xs rule: rev_cases) simp_all
       
    46 
       
    47 lemma split_strip_while_append:
       
    48   fixes xs :: "'a list"
       
    49   obtains ys zs :: "'a list"
       
    50   where "strip_while P xs = ys" and "\<forall>x\<in>set zs. P x" and "xs = ys @ zs"
       
    51 proof (rule that)
       
    52   show "strip_while P xs = strip_while P xs" ..
       
    53   show "\<forall>x\<in>set (rev (takeWhile P (rev xs))). P x" by (simp add: takeWhile_eq_all_conv [symmetric])
       
    54   have "rev xs = rev (strip_while P xs @ rev (takeWhile P (rev xs)))"
       
    55     by (simp add: strip_while_def)
       
    56   then show "xs = strip_while P xs @ rev (takeWhile P (rev xs))"
       
    57     by (simp only: rev_is_rev_conv)
       
    58 qed
       
    59 
       
    60 
       
    61 definition nth_default :: "'a \<Rightarrow> 'a list \<Rightarrow> nat \<Rightarrow> 'a"
       
    62 where
       
    63   "nth_default x xs n = (if n < length xs then xs ! n else x)"
       
    64 
       
    65 lemma nth_default_Nil [simp]:
       
    66   "nth_default y [] n = y"
       
    67   by (simp add: nth_default_def)
       
    68 
       
    69 lemma nth_default_Cons_0 [simp]:
       
    70   "nth_default y (x # xs) 0 = x"
       
    71   by (simp add: nth_default_def)
       
    72 
       
    73 lemma nth_default_Cons_Suc [simp]:
       
    74   "nth_default y (x # xs) (Suc n) = nth_default y xs n"
       
    75   by (simp add: nth_default_def)
       
    76 
       
    77 lemma nth_default_map_eq:
       
    78   "f y = x \<Longrightarrow> nth_default x (map f xs) n = f (nth_default y xs n)"
       
    79   by (simp add: nth_default_def)
       
    80 
       
    81 lemma nth_default_strip_while_eq [simp]:
       
    82   "nth_default x (strip_while (HOL.eq x) xs) n = nth_default x xs n"
       
    83 proof -
       
    84   from split_strip_while_append obtain ys zs
       
    85     where "strip_while (HOL.eq x) xs = ys" and "\<forall>z\<in>set zs. x = z" and "xs = ys @ zs" by blast
       
    86   then show ?thesis by (simp add: nth_default_def not_less nth_append)
       
    87 qed
       
    88 
       
    89 
    14 
    90 definition cCons :: "'a::zero \<Rightarrow> 'a list \<Rightarrow> 'a list"  (infixr "##" 65)
    15 definition cCons :: "'a::zero \<Rightarrow> 'a list \<Rightarrow> 'a list"  (infixr "##" 65)
    91 where
    16 where
    92   "x ## xs = (if xs = [] \<and> x = 0 then [] else x # xs)"
    17   "x ## xs = (if xs = [] \<and> x = 0 then [] else x # xs)"
    93 
    18 
   404   "coeffs (pCons a p) = a ## coeffs p"
   329   "coeffs (pCons a p) = a ## coeffs p"
   405 proof -
   330 proof -
   406   { fix ms :: "nat list" and f :: "nat \<Rightarrow> 'a" and x :: "'a"
   331   { fix ms :: "nat list" and f :: "nat \<Rightarrow> 'a" and x :: "'a"
   407     assume "\<forall>m\<in>set ms. m > 0"
   332     assume "\<forall>m\<in>set ms. m > 0"
   408     then have "map (case_nat x f) ms = map f (map (\<lambda>n. n - 1) ms)"
   333     then have "map (case_nat x f) ms = map f (map (\<lambda>n. n - 1) ms)"
   409       by (induct ms) (auto, metis Suc_pred' nat.case(2)) }
   334       by (induct ms) (auto split: nat.split)
       
   335   }
   410   note * = this
   336   note * = this
   411   show ?thesis
   337   show ?thesis
   412     by (simp add: coeffs_def * upt_conv_Cons coeff_pCons map_decr_upt One_nat_def del: upt_Suc)
   338     by (simp add: coeffs_def * upt_conv_Cons coeff_pCons map_decr_upt One_nat_def del: upt_Suc)
   413 qed
   339 qed
   414 
   340