changeset 56000 | 899ad5a3ad00 |
parent 54489 | 03ff4d1e6784 |
child 56009 | dda076a32aea |
55999:6477fc70cfa0 | 56000:899ad5a3ad00 |
---|---|
30 | "polysize (Pw p n) = 1 + polysize p" |
30 | "polysize (Pw p n) = 1 + polysize p" |
31 | "polysize (CN c n p) = 4 + polysize c + polysize p" |
31 | "polysize (CN c n p) = 4 + polysize c + polysize p" |
32 |
32 |
33 primrec polybound0:: "poly \<Rightarrow> bool" -- {* a poly is INDEPENDENT of Bound 0 *} |
33 primrec polybound0:: "poly \<Rightarrow> bool" -- {* a poly is INDEPENDENT of Bound 0 *} |
34 where |
34 where |
35 "polybound0 (C c) = True" |
35 "polybound0 (C c) \<longleftrightarrow> True" |
36 | "polybound0 (Bound n) = (n>0)" |
36 | "polybound0 (Bound n) \<longleftrightarrow> n > 0" |
37 | "polybound0 (Neg a) = polybound0 a" |
37 | "polybound0 (Neg a) \<longleftrightarrow> polybound0 a" |
38 | "polybound0 (Add a b) = (polybound0 a \<and> polybound0 b)" |
38 | "polybound0 (Add a b) \<longleftrightarrow> polybound0 a \<and> polybound0 b" |
39 | "polybound0 (Sub a b) = (polybound0 a \<and> polybound0 b)" |
39 | "polybound0 (Sub a b) \<longleftrightarrow> polybound0 a \<and> polybound0 b" |
40 | "polybound0 (Mul a b) = (polybound0 a \<and> polybound0 b)" |
40 | "polybound0 (Mul a b) \<longleftrightarrow> polybound0 a \<and> polybound0 b" |
41 | "polybound0 (Pw p n) = (polybound0 p)" |
41 | "polybound0 (Pw p n) \<longleftrightarrow> polybound0 p" |
42 | "polybound0 (CN c n p) = (n \<noteq> 0 \<and> polybound0 c \<and> polybound0 p)" |
42 | "polybound0 (CN c n p) \<longleftrightarrow> n \<noteq> 0 \<and> polybound0 c \<and> polybound0 p" |
43 |
43 |
44 primrec polysubst0:: "poly \<Rightarrow> poly \<Rightarrow> poly" -- {* substitute a poly into a poly for Bound 0 *} |
44 primrec polysubst0:: "poly \<Rightarrow> poly \<Rightarrow> poly" -- {* substitute a poly into a poly for Bound 0 *} |
45 where |
45 where |
46 "polysubst0 t (C c) = (C c)" |
46 "polysubst0 t (C c) = C c" |
47 | "polysubst0 t (Bound n) = (if n=0 then t else Bound n)" |
47 | "polysubst0 t (Bound n) = (if n = 0 then t else Bound n)" |
48 | "polysubst0 t (Neg a) = Neg (polysubst0 t a)" |
48 | "polysubst0 t (Neg a) = Neg (polysubst0 t a)" |
49 | "polysubst0 t (Add a b) = Add (polysubst0 t a) (polysubst0 t b)" |
49 | "polysubst0 t (Add a b) = Add (polysubst0 t a) (polysubst0 t b)" |
50 | "polysubst0 t (Sub a b) = Sub (polysubst0 t a) (polysubst0 t b)" |
50 | "polysubst0 t (Sub a b) = Sub (polysubst0 t a) (polysubst0 t b)" |
51 | "polysubst0 t (Mul a b) = Mul (polysubst0 t a) (polysubst0 t b)" |
51 | "polysubst0 t (Mul a b) = Mul (polysubst0 t a) (polysubst0 t b)" |
52 | "polysubst0 t (Pw p n) = Pw (polysubst0 t p) n" |
52 | "polysubst0 t (Pw p n) = Pw (polysubst0 t p) n" |
53 | "polysubst0 t (CN c n p) = (if n=0 then Add (polysubst0 t c) (Mul t (polysubst0 t p)) |
53 | "polysubst0 t (CN c n p) = |
54 else CN (polysubst0 t c) n (polysubst0 t p))" |
54 (if n = 0 then Add (polysubst0 t c) (Mul t (polysubst0 t p)) |
55 else CN (polysubst0 t c) n (polysubst0 t p))" |
|
55 |
56 |
56 fun decrpoly:: "poly \<Rightarrow> poly" |
57 fun decrpoly:: "poly \<Rightarrow> poly" |
57 where |
58 where |
58 "decrpoly (Bound n) = Bound (n - 1)" |
59 "decrpoly (Bound n) = Bound (n - 1)" |
59 | "decrpoly (Neg a) = Neg (decrpoly a)" |
60 | "decrpoly (Neg a) = Neg (decrpoly a)" |
78 | "head p = p" |
79 | "head p = p" |
79 |
80 |
80 (* More general notions of degree and head *) |
81 (* More general notions of degree and head *) |
81 fun degreen:: "poly \<Rightarrow> nat \<Rightarrow> nat" |
82 fun degreen:: "poly \<Rightarrow> nat \<Rightarrow> nat" |
82 where |
83 where |
83 "degreen (CN c n p) = (\<lambda>m. if n=m then 1 + degreen p n else 0)" |
84 "degreen (CN c n p) = (\<lambda>m. if n = m then 1 + degreen p n else 0)" |
84 |"degreen p = (\<lambda>m. 0)" |
85 | "degreen p = (\<lambda>m. 0)" |
85 |
86 |
86 fun headn:: "poly \<Rightarrow> nat \<Rightarrow> poly" |
87 fun headn:: "poly \<Rightarrow> nat \<Rightarrow> poly" |
87 where |
88 where |
88 "headn (CN c n p) = (\<lambda>m. if n \<le> m then headn p m else CN c n p)" |
89 "headn (CN c n p) = (\<lambda>m. if n \<le> m then headn p m else CN c n p)" |
89 | "headn p = (\<lambda>m. p)" |
90 | "headn p = (\<lambda>m. p)" |
90 |
91 |
91 fun coefficients:: "poly \<Rightarrow> poly list" |
92 fun coefficients:: "poly \<Rightarrow> poly list" |
92 where |
93 where |
93 "coefficients (CN c 0 p) = c#(coefficients p)" |
94 "coefficients (CN c 0 p) = c # coefficients p" |
94 | "coefficients p = [p]" |
95 | "coefficients p = [p]" |
95 |
96 |
96 fun isconstant:: "poly \<Rightarrow> bool" |
97 fun isconstant:: "poly \<Rightarrow> bool" |
97 where |
98 where |
98 "isconstant (CN c 0 p) = False" |
99 "isconstant (CN c 0 p) = False" |
114 declare if_cong[fundef_cong del] |
115 declare if_cong[fundef_cong del] |
115 declare let_cong[fundef_cong del] |
116 declare let_cong[fundef_cong del] |
116 |
117 |
117 fun polyadd :: "poly \<Rightarrow> poly \<Rightarrow> poly" (infixl "+\<^sub>p" 60) |
118 fun polyadd :: "poly \<Rightarrow> poly \<Rightarrow> poly" (infixl "+\<^sub>p" 60) |
118 where |
119 where |
119 "polyadd (C c) (C c') = C (c+\<^sub>Nc')" |
120 "polyadd (C c) (C c') = C (c +\<^sub>N c')" |
120 | "polyadd (C c) (CN c' n' p') = CN (polyadd (C c) c') n' p'" |
121 | "polyadd (C c) (CN c' n' p') = CN (polyadd (C c) c') n' p'" |
121 | "polyadd (CN c n p) (C c') = CN (polyadd c (C c')) n p" |
122 | "polyadd (CN c n p) (C c') = CN (polyadd c (C c')) n p" |
122 | "polyadd (CN c n p) (CN c' n' p') = |
123 | "polyadd (CN c n p) (CN c' n' p') = |
123 (if n < n' then CN (polyadd c (CN c' n' p')) n p |
124 (if n < n' then CN (polyadd c (CN c' n' p')) n p |
124 else if n'<n then CN (polyadd (CN c n p) c') n' p' |
125 else if n' < n then CN (polyadd (CN c n p) c') n' p' |
125 else (let cc' = polyadd c c' ; |
126 else |
126 pp' = polyadd p p' |
127 let |
127 in (if pp' = 0\<^sub>p then cc' else CN cc' n pp')))" |
128 cc' = polyadd c c'; |
129 pp' = polyadd p p' |
|
130 in if pp' = 0\<^sub>p then cc' else CN cc' n pp')" |
|
128 | "polyadd a b = Add a b" |
131 | "polyadd a b = Add a b" |
129 |
132 |
130 |
133 |
131 fun polyneg :: "poly \<Rightarrow> poly" ("~\<^sub>p") |
134 fun polyneg :: "poly \<Rightarrow> poly" ("~\<^sub>p") |
132 where |
135 where |
139 |
142 |
140 fun polymul :: "poly \<Rightarrow> poly \<Rightarrow> poly" (infixl "*\<^sub>p" 60) |
143 fun polymul :: "poly \<Rightarrow> poly \<Rightarrow> poly" (infixl "*\<^sub>p" 60) |
141 where |
144 where |
142 "polymul (C c) (C c') = C (c*\<^sub>Nc')" |
145 "polymul (C c) (C c') = C (c*\<^sub>Nc')" |
143 | "polymul (C c) (CN c' n' p') = |
146 | "polymul (C c) (CN c' n' p') = |
144 (if c = 0\<^sub>N then 0\<^sub>p else CN (polymul (C c) c') n' (polymul (C c) p'))" |
147 (if c = 0\<^sub>N then 0\<^sub>p else CN (polymul (C c) c') n' (polymul (C c) p'))" |
145 | "polymul (CN c n p) (C c') = |
148 | "polymul (CN c n p) (C c') = |
146 (if c' = 0\<^sub>N then 0\<^sub>p else CN (polymul c (C c')) n (polymul p (C c')))" |
149 (if c' = 0\<^sub>N then 0\<^sub>p else CN (polymul c (C c')) n (polymul p (C c')))" |
147 | "polymul (CN c n p) (CN c' n' p') = |
150 | "polymul (CN c n p) (CN c' n' p') = |
148 (if n<n' then CN (polymul c (CN c' n' p')) n (polymul p (CN c' n' p')) |
151 (if n < n' then CN (polymul c (CN c' n' p')) n (polymul p (CN c' n' p')) |
149 else if n' < n |
152 else if n' < n then CN (polymul (CN c n p) c') n' (polymul (CN c n p) p') |
150 then CN (polymul (CN c n p) c') n' (polymul (CN c n p) p') |
153 else polyadd (polymul (CN c n p) c') (CN 0\<^sub>p n' (polymul (CN c n p) p')))" |
151 else polyadd (polymul (CN c n p) c') (CN 0\<^sub>p n' (polymul (CN c n p) p')))" |
|
152 | "polymul a b = Mul a b" |
154 | "polymul a b = Mul a b" |
153 |
155 |
154 declare if_cong[fundef_cong] |
156 declare if_cong[fundef_cong] |
155 declare let_cong[fundef_cong] |
157 declare let_cong[fundef_cong] |
156 |
158 |
157 fun polypow :: "nat \<Rightarrow> poly \<Rightarrow> poly" |
159 fun polypow :: "nat \<Rightarrow> poly \<Rightarrow> poly" |
158 where |
160 where |
159 "polypow 0 = (\<lambda>p. (1)\<^sub>p)" |
161 "polypow 0 = (\<lambda>p. (1)\<^sub>p)" |
160 | "polypow n = (\<lambda>p. let q = polypow (n div 2) p ; d = polymul q q in |
162 | "polypow n = |
161 if even n then d else polymul p d)" |
163 (\<lambda>p. |
164 let |
|
165 q = polypow (n div 2) p; |
|
166 d = polymul q q |
|
167 in if even n then d else polymul p d)" |
|
162 |
168 |
163 abbreviation poly_pow :: "poly \<Rightarrow> nat \<Rightarrow> poly" (infixl "^\<^sub>p" 60) |
169 abbreviation poly_pow :: "poly \<Rightarrow> nat \<Rightarrow> poly" (infixl "^\<^sub>p" 60) |
164 where "a ^\<^sub>p k \<equiv> polypow k a" |
170 where "a ^\<^sub>p k \<equiv> polypow k a" |
165 |
171 |
166 function polynate :: "poly \<Rightarrow> poly" |
172 function polynate :: "poly \<Rightarrow> poly" |
167 where |
173 where |
168 "polynate (Bound n) = CN 0\<^sub>p n (1)\<^sub>p" |
174 "polynate (Bound n) = CN 0\<^sub>p n (1)\<^sub>p" |
169 | "polynate (Add p q) = (polynate p +\<^sub>p polynate q)" |
175 | "polynate (Add p q) = polynate p +\<^sub>p polynate q" |
170 | "polynate (Sub p q) = (polynate p -\<^sub>p polynate q)" |
176 | "polynate (Sub p q) = polynate p -\<^sub>p polynate q" |
171 | "polynate (Mul p q) = (polynate p *\<^sub>p polynate q)" |
177 | "polynate (Mul p q) = polynate p *\<^sub>p polynate q" |
172 | "polynate (Neg p) = (~\<^sub>p (polynate p))" |
178 | "polynate (Neg p) = ~\<^sub>p (polynate p)" |
173 | "polynate (Pw p n) = ((polynate p) ^\<^sub>p n)" |
179 | "polynate (Pw p n) = polynate p ^\<^sub>p n" |
174 | "polynate (CN c n p) = polynate (Add c (Mul (Bound n) p))" |
180 | "polynate (CN c n p) = polynate (Add c (Mul (Bound n) p))" |
175 | "polynate (C c) = C (normNum c)" |
181 | "polynate (C c) = C (normNum c)" |
176 by pat_completeness auto |
182 by pat_completeness auto |
177 termination by (relation "measure polysize") auto |
183 termination by (relation "measure polysize") auto |
178 |
184 |
180 where |
186 where |
181 "poly_cmul y (C x) = C (y *\<^sub>N x)" |
187 "poly_cmul y (C x) = C (y *\<^sub>N x)" |
182 | "poly_cmul y (CN c n p) = CN (poly_cmul y c) n (poly_cmul y p)" |
188 | "poly_cmul y (CN c n p) = CN (poly_cmul y c) n (poly_cmul y p)" |
183 | "poly_cmul y p = C y *\<^sub>p p" |
189 | "poly_cmul y p = C y *\<^sub>p p" |
184 |
190 |
185 definition monic :: "poly \<Rightarrow> (poly \<times> bool)" where |
191 definition monic :: "poly \<Rightarrow> (poly \<times> bool)" |
186 "monic p \<equiv> (let h = headconst p in if h = 0\<^sub>N then (p,False) else ((C (Ninv h)) *\<^sub>p p, 0>\<^sub>N h))" |
192 where |
187 |
193 "monic p = |
188 |
194 (let h = headconst p |
189 subsection{* Pseudo-division *} |
195 in if h = 0\<^sub>N then (p, False) else (C (Ninv h) *\<^sub>p p, 0>\<^sub>N h))" |
196 |
|
197 |
|
198 subsection {* Pseudo-division *} |
|
190 |
199 |
191 definition shift1 :: "poly \<Rightarrow> poly" |
200 definition shift1 :: "poly \<Rightarrow> poly" |
192 where "shift1 p \<equiv> CN 0\<^sub>p 0 p" |
201 where "shift1 p = CN 0\<^sub>p 0 p" |
193 |
202 |
194 abbreviation funpow :: "nat \<Rightarrow> ('a \<Rightarrow> 'a) \<Rightarrow> ('a \<Rightarrow> 'a)" |
203 abbreviation funpow :: "nat \<Rightarrow> ('a \<Rightarrow> 'a) \<Rightarrow> ('a \<Rightarrow> 'a)" |
195 where "funpow \<equiv> compow" |
204 where "funpow \<equiv> compow" |
196 |
205 |
197 partial_function (tailrec) polydivide_aux :: "poly \<Rightarrow> nat \<Rightarrow> poly \<Rightarrow> nat \<Rightarrow> poly \<Rightarrow> nat \<times> poly" |
206 partial_function (tailrec) polydivide_aux :: "poly \<Rightarrow> nat \<Rightarrow> poly \<Rightarrow> nat \<Rightarrow> poly \<Rightarrow> nat \<times> poly" |
198 where |
207 where |
199 "polydivide_aux a n p k s = |
208 "polydivide_aux a n p k s = |
200 (if s = 0\<^sub>p then (k,s) |
209 (if s = 0\<^sub>p then (k, s) |
201 else |
210 else |
202 (let b = head s; m = degree s in |
211 let |
203 (if m < n then (k,s) |
212 b = head s; |
204 else |
213 m = degree s |
205 (let p'= funpow (m - n) shift1 p in |
214 in |
206 (if a = b then polydivide_aux a n p k (s -\<^sub>p p') |
215 if m < n then (k,s) |
207 else polydivide_aux a n p (Suc k) ((a *\<^sub>p s) -\<^sub>p (b *\<^sub>p p')))))))" |
216 else |
208 |
217 let p' = funpow (m - n) shift1 p |
209 definition polydivide :: "poly \<Rightarrow> poly \<Rightarrow> (nat \<times> poly)" |
218 in |
210 where "polydivide s p \<equiv> polydivide_aux (head p) (degree p) p 0 s" |
219 if a = b then polydivide_aux a n p k (s -\<^sub>p p') |
220 else polydivide_aux a n p (Suc k) ((a *\<^sub>p s) -\<^sub>p (b *\<^sub>p p')))" |
|
221 |
|
222 definition polydivide :: "poly \<Rightarrow> poly \<Rightarrow> nat \<times> poly" |
|
223 where "polydivide s p = polydivide_aux (head p) (degree p) p 0 s" |
|
211 |
224 |
212 fun poly_deriv_aux :: "nat \<Rightarrow> poly \<Rightarrow> poly" |
225 fun poly_deriv_aux :: "nat \<Rightarrow> poly \<Rightarrow> poly" |
213 where |
226 where |
214 "poly_deriv_aux n (CN c 0 p) = CN (poly_cmul ((int n)\<^sub>N) c) 0 (poly_deriv_aux (n + 1) p)" |
227 "poly_deriv_aux n (CN c 0 p) = CN (poly_cmul ((int n)\<^sub>N) c) 0 (poly_deriv_aux (n + 1) p)" |
215 | "poly_deriv_aux n p = poly_cmul ((int n)\<^sub>N) p" |
228 | "poly_deriv_aux n p = poly_cmul ((int n)\<^sub>N) p" |
220 | "poly_deriv p = 0\<^sub>p" |
233 | "poly_deriv p = 0\<^sub>p" |
221 |
234 |
222 |
235 |
223 subsection{* Semantics of the polynomial representation *} |
236 subsection{* Semantics of the polynomial representation *} |
224 |
237 |
225 primrec Ipoly :: "'a list \<Rightarrow> poly \<Rightarrow> 'a::{field_char_0, field_inverse_zero, power}" where |
238 primrec Ipoly :: "'a list \<Rightarrow> poly \<Rightarrow> 'a::{field_char_0,field_inverse_zero,power}" |
239 where |
|
226 "Ipoly bs (C c) = INum c" |
240 "Ipoly bs (C c) = INum c" |
227 | "Ipoly bs (Bound n) = bs!n" |
241 | "Ipoly bs (Bound n) = bs!n" |
228 | "Ipoly bs (Neg a) = - Ipoly bs a" |
242 | "Ipoly bs (Neg a) = - Ipoly bs a" |
229 | "Ipoly bs (Add a b) = Ipoly bs a + Ipoly bs b" |
243 | "Ipoly bs (Add a b) = Ipoly bs a + Ipoly bs b" |
230 | "Ipoly bs (Sub a b) = Ipoly bs a - Ipoly bs b" |
244 | "Ipoly bs (Sub a b) = Ipoly bs a - Ipoly bs b" |
231 | "Ipoly bs (Mul a b) = Ipoly bs a * Ipoly bs b" |
245 | "Ipoly bs (Mul a b) = Ipoly bs a * Ipoly bs b" |
232 | "Ipoly bs (Pw t n) = (Ipoly bs t) ^ n" |
246 | "Ipoly bs (Pw t n) = Ipoly bs t ^ n" |
233 | "Ipoly bs (CN c n p) = (Ipoly bs c) + (bs!n)*(Ipoly bs p)" |
247 | "Ipoly bs (CN c n p) = Ipoly bs c + (bs!n) * Ipoly bs p" |
234 |
248 |
235 abbreviation |
249 abbreviation Ipoly_syntax :: "poly \<Rightarrow> 'a list \<Rightarrow>'a::{field_char_0,field_inverse_zero,power}" |
236 Ipoly_syntax :: "poly \<Rightarrow> 'a list \<Rightarrow>'a::{field_char_0, field_inverse_zero, power}" ("\<lparr>_\<rparr>\<^sub>p\<^bsup>_\<^esup>") |
250 ("\<lparr>_\<rparr>\<^sub>p\<^bsup>_\<^esup>") |
237 where "\<lparr>p\<rparr>\<^sub>p\<^bsup>bs\<^esup> \<equiv> Ipoly bs p" |
251 where "\<lparr>p\<rparr>\<^sub>p\<^bsup>bs\<^esup> \<equiv> Ipoly bs p" |
238 |
252 |
239 lemma Ipoly_CInt: "Ipoly bs (C (i,1)) = of_int i" |
253 lemma Ipoly_CInt: "Ipoly bs (C (i,1)) = of_int i" |
240 by (simp add: INum_def) |
254 by (simp add: INum_def) |
255 |
|
241 lemma Ipoly_CRat: "Ipoly bs (C (i, j)) = of_int i / of_int j" |
256 lemma Ipoly_CRat: "Ipoly bs (C (i, j)) = of_int i / of_int j" |
242 by (simp add: INum_def) |
257 by (simp add: INum_def) |
243 |
258 |
244 lemmas RIpoly_eqs = Ipoly.simps(2-7) Ipoly_CInt Ipoly_CRat |
259 lemmas RIpoly_eqs = Ipoly.simps(2-7) Ipoly_CInt Ipoly_CRat |
245 |
260 |
247 subsection {* Normal form and normalization *} |
262 subsection {* Normal form and normalization *} |
248 |
263 |
249 fun isnpolyh:: "poly \<Rightarrow> nat \<Rightarrow> bool" |
264 fun isnpolyh:: "poly \<Rightarrow> nat \<Rightarrow> bool" |
250 where |
265 where |
251 "isnpolyh (C c) = (\<lambda>k. isnormNum c)" |
266 "isnpolyh (C c) = (\<lambda>k. isnormNum c)" |
252 | "isnpolyh (CN c n p) = (\<lambda>k. n \<ge> k \<and> (isnpolyh c (Suc n)) \<and> (isnpolyh p n) \<and> (p \<noteq> 0\<^sub>p))" |
267 | "isnpolyh (CN c n p) = (\<lambda>k. n \<ge> k \<and> isnpolyh c (Suc n) \<and> isnpolyh p n \<and> p \<noteq> 0\<^sub>p)" |
253 | "isnpolyh p = (\<lambda>k. False)" |
268 | "isnpolyh p = (\<lambda>k. False)" |
254 |
269 |
255 lemma isnpolyh_mono: "\<lbrakk>n' \<le> n ; isnpolyh p n\<rbrakk> \<Longrightarrow> isnpolyh p n'" |
270 lemma isnpolyh_mono: "n' \<le> n \<Longrightarrow> isnpolyh p n \<Longrightarrow> isnpolyh p n'" |
256 by (induct p rule: isnpolyh.induct) auto |
271 by (induct p rule: isnpolyh.induct) auto |
257 |
272 |
258 definition isnpoly :: "poly \<Rightarrow> bool" |
273 definition isnpoly :: "poly \<Rightarrow> bool" |
259 where "isnpoly p \<equiv> isnpolyh p 0" |
274 where "isnpoly p = isnpolyh p 0" |
260 |
275 |
261 text{* polyadd preserves normal forms *} |
276 text{* polyadd preserves normal forms *} |
262 |
277 |
263 lemma polyadd_normh: "\<lbrakk>isnpolyh p n0 ; isnpolyh q n1\<rbrakk> |
278 lemma polyadd_normh: "isnpolyh p n0 \<Longrightarrow> isnpolyh q n1 \<Longrightarrow> isnpolyh (polyadd p q) (min n0 n1)" |
264 \<Longrightarrow> isnpolyh (polyadd p q) (min n0 n1)" |
|
265 proof (induct p q arbitrary: n0 n1 rule: polyadd.induct) |
279 proof (induct p q arbitrary: n0 n1 rule: polyadd.induct) |
266 case (2 ab c' n' p' n0 n1) |
280 case (2 ab c' n' p' n0 n1) |
267 from 2 have th1: "isnpolyh (C ab) (Suc n')" by simp |
281 from 2 have th1: "isnpolyh (C ab) (Suc n')" by simp |
268 from 2(3) have th2: "isnpolyh c' (Suc n')" and nplen1: "n' \<ge> n1" by simp_all |
282 from 2(3) have th2: "isnpolyh c' (Suc n')" and nplen1: "n' \<ge> n1" by simp_all |
269 with isnpolyh_mono have cp: "isnpolyh c' (Suc n')" by simp |
283 with isnpolyh_mono have cp: "isnpolyh c' (Suc n')" by simp |
400 ultimately have ?case by blast } |
414 ultimately have ?case by blast } |
401 ultimately show ?case by blast |
415 ultimately show ?case by blast |
402 qed simp_all |
416 qed simp_all |
403 |
417 |
404 lemma polymul_properties: |
418 lemma polymul_properties: |
405 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
419 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
406 and np: "isnpolyh p n0" |
420 and np: "isnpolyh p n0" |
407 and nq: "isnpolyh q n1" |
421 and nq: "isnpolyh q n1" |
408 and m: "m \<le> min n0 n1" |
422 and m: "m \<le> min n0 n1" |
409 shows "isnpolyh (p *\<^sub>p q) (min n0 n1)" |
423 shows "isnpolyh (p *\<^sub>p q) (min n0 n1)" |
410 and "(p *\<^sub>p q = 0\<^sub>p) = (p = 0\<^sub>p \<or> q = 0\<^sub>p)" |
424 and "(p *\<^sub>p q = 0\<^sub>p) = (p = 0\<^sub>p \<or> q = 0\<^sub>p)" |
546 |
560 |
547 lemma polymul[simp]: "Ipoly bs (p *\<^sub>p q) = (Ipoly bs p) * (Ipoly bs q)" |
561 lemma polymul[simp]: "Ipoly bs (p *\<^sub>p q) = (Ipoly bs p) * (Ipoly bs q)" |
548 by (induct p q rule: polymul.induct) (auto simp add: field_simps) |
562 by (induct p q rule: polymul.induct) (auto simp add: field_simps) |
549 |
563 |
550 lemma polymul_normh: |
564 lemma polymul_normh: |
551 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
565 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
552 shows "\<lbrakk>isnpolyh p n0 ; isnpolyh q n1\<rbrakk> \<Longrightarrow> isnpolyh (p *\<^sub>p q) (min n0 n1)" |
566 shows "\<lbrakk>isnpolyh p n0 ; isnpolyh q n1\<rbrakk> \<Longrightarrow> isnpolyh (p *\<^sub>p q) (min n0 n1)" |
553 using polymul_properties(1) by blast |
567 using polymul_properties(1) by blast |
554 |
568 |
555 lemma polymul_eq0_iff: |
569 lemma polymul_eq0_iff: |
556 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
570 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
557 shows "\<lbrakk> isnpolyh p n0 ; isnpolyh q n1\<rbrakk> \<Longrightarrow> (p *\<^sub>p q = 0\<^sub>p) = (p = 0\<^sub>p \<or> q = 0\<^sub>p) " |
571 shows "\<lbrakk> isnpolyh p n0 ; isnpolyh q n1\<rbrakk> \<Longrightarrow> (p *\<^sub>p q = 0\<^sub>p) = (p = 0\<^sub>p \<or> q = 0\<^sub>p) " |
558 using polymul_properties(2) by blast |
572 using polymul_properties(2) by blast |
559 |
573 |
560 lemma polymul_degreen: (* FIXME duplicate? *) |
574 lemma polymul_degreen: (* FIXME duplicate? *) |
561 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
575 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
562 shows "\<lbrakk> isnpolyh p n0 ; isnpolyh q n1 ; m \<le> min n0 n1\<rbrakk> \<Longrightarrow> |
576 shows "\<lbrakk> isnpolyh p n0 ; isnpolyh q n1 ; m \<le> min n0 n1\<rbrakk> \<Longrightarrow> |
563 degreen (p *\<^sub>p q) m = (if (p = 0\<^sub>p \<or> q = 0\<^sub>p) then 0 else degreen p m + degreen q m)" |
577 degreen (p *\<^sub>p q) m = (if (p = 0\<^sub>p \<or> q = 0\<^sub>p) then 0 else degreen p m + degreen q m)" |
564 using polymul_properties(3) by blast |
578 using polymul_properties(3) by blast |
565 |
579 |
566 lemma polymul_norm: |
580 lemma polymul_norm: |
567 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
581 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
568 shows "\<lbrakk> isnpoly p; isnpoly q\<rbrakk> \<Longrightarrow> isnpoly (polymul p q)" |
582 shows "\<lbrakk> isnpoly p; isnpoly q\<rbrakk> \<Longrightarrow> isnpoly (polymul p q)" |
569 using polymul_normh[of "p" "0" "q" "0"] isnpoly_def by simp |
583 using polymul_normh[of "p" "0" "q" "0"] isnpoly_def by simp |
570 |
584 |
571 lemma headconst_zero: "isnpolyh p n0 \<Longrightarrow> headconst p = 0\<^sub>N \<longleftrightarrow> p = 0\<^sub>p" |
585 lemma headconst_zero: "isnpolyh p n0 \<Longrightarrow> headconst p = 0\<^sub>N \<longleftrightarrow> p = 0\<^sub>p" |
572 by (induct p arbitrary: n0 rule: headconst.induct) auto |
586 by (induct p arbitrary: n0 rule: headconst.induct) auto |
575 by (induct p arbitrary: n0) auto |
589 by (induct p arbitrary: n0) auto |
576 |
590 |
577 lemma monic_eqI: |
591 lemma monic_eqI: |
578 assumes np: "isnpolyh p n0" |
592 assumes np: "isnpolyh p n0" |
579 shows "INum (headconst p) * Ipoly bs (fst (monic p)) = |
593 shows "INum (headconst p) * Ipoly bs (fst (monic p)) = |
580 (Ipoly bs p ::'a::{field_char_0, field_inverse_zero, power})" |
594 (Ipoly bs p ::'a::{field_char_0,field_inverse_zero, power})" |
581 unfolding monic_def Let_def |
595 unfolding monic_def Let_def |
582 proof (cases "headconst p = 0\<^sub>N", simp_all add: headconst_zero[OF np]) |
596 proof (cases "headconst p = 0\<^sub>N", simp_all add: headconst_zero[OF np]) |
583 let ?h = "headconst p" |
597 let ?h = "headconst p" |
584 assume pz: "p \<noteq> 0\<^sub>p" |
598 assume pz: "p \<noteq> 0\<^sub>p" |
585 { assume hz: "INum ?h = (0::'a)" |
599 { |
600 assume hz: "INum ?h = (0::'a)" |
|
586 from headconst_isnormNum[OF np] have norm: "isnormNum ?h" "isnormNum 0\<^sub>N" by simp_all |
601 from headconst_isnormNum[OF np] have norm: "isnormNum ?h" "isnormNum 0\<^sub>N" by simp_all |
587 from isnormNum_unique[where ?'a = 'a, OF norm] hz have "?h = 0\<^sub>N" by simp |
602 from isnormNum_unique[where ?'a = 'a, OF norm] hz have "?h = 0\<^sub>N" by simp |
588 with headconst_zero[OF np] have "p =0\<^sub>p" by blast with pz have "False" by blast} |
603 with headconst_zero[OF np] have "p =0\<^sub>p" by blast with pz have "False" by blast} |
589 thus "INum (headconst p) = (0::'a) \<longrightarrow> \<lparr>p\<rparr>\<^sub>p\<^bsup>bs\<^esup> = 0" by blast |
604 thus "INum (headconst p) = (0::'a) \<longrightarrow> \<lparr>p\<rparr>\<^sub>p\<^bsup>bs\<^esup> = 0" by blast |
590 qed |
605 qed |
615 by (simp add: polysub_def polyneg_normh polyadd_normh) |
630 by (simp add: polysub_def polyneg_normh polyadd_normh) |
616 |
631 |
617 lemma polysub_norm: "\<lbrakk> isnpoly p; isnpoly q\<rbrakk> \<Longrightarrow> isnpoly (polysub p q)" |
632 lemma polysub_norm: "\<lbrakk> isnpoly p; isnpoly q\<rbrakk> \<Longrightarrow> isnpoly (polysub p q)" |
618 using polyadd_norm polyneg_norm by (simp add: polysub_def) |
633 using polyadd_norm polyneg_norm by (simp add: polysub_def) |
619 lemma polysub_same_0[simp]: |
634 lemma polysub_same_0[simp]: |
620 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
635 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
621 shows "isnpolyh p n0 \<Longrightarrow> polysub p p = 0\<^sub>p" |
636 shows "isnpolyh p n0 \<Longrightarrow> polysub p p = 0\<^sub>p" |
622 unfolding polysub_def split_def fst_conv snd_conv |
637 unfolding polysub_def split_def fst_conv snd_conv |
623 by (induct p arbitrary: n0) (auto simp add: Let_def Nsub0[simplified Nsub_def]) |
638 by (induct p arbitrary: n0) (auto simp add: Let_def Nsub0[simplified Nsub_def]) |
624 |
639 |
625 lemma polysub_0: |
640 lemma polysub_0: |
626 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
641 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
627 shows "\<lbrakk> isnpolyh p n0 ; isnpolyh q n1\<rbrakk> \<Longrightarrow> (p -\<^sub>p q = 0\<^sub>p) = (p = q)" |
642 shows "\<lbrakk> isnpolyh p n0 ; isnpolyh q n1\<rbrakk> \<Longrightarrow> (p -\<^sub>p q = 0\<^sub>p) = (p = q)" |
628 unfolding polysub_def split_def fst_conv snd_conv |
643 unfolding polysub_def split_def fst_conv snd_conv |
629 by (induct p q arbitrary: n0 n1 rule:polyadd.induct) |
644 by (induct p q arbitrary: n0 n1 rule:polyadd.induct) |
630 (auto simp: Nsub0[simplified Nsub_def] Let_def) |
645 (auto simp: Nsub0[simplified Nsub_def] Let_def) |
631 |
646 |
632 text{* polypow is a power function and preserves normal forms *} |
647 text{* polypow is a power function and preserves normal forms *} |
633 |
648 |
634 lemma polypow[simp]: "Ipoly bs (polypow n p) = ((Ipoly bs p :: 'a::{field_char_0, field_inverse_zero})) ^ n" |
649 lemma polypow[simp]: "Ipoly bs (polypow n p) = ((Ipoly bs p :: 'a::{field_char_0,field_inverse_zero})) ^ n" |
635 proof (induct n rule: polypow.induct) |
650 proof (induct n rule: polypow.induct) |
636 case 1 |
651 case 1 |
637 thus ?case by simp |
652 thus ?case by simp |
638 next |
653 next |
639 case (2 n) |
654 case (2 n) |
640 let ?q = "polypow ((Suc n) div 2) p" |
655 let ?q = "polypow ((Suc n) div 2) p" |
641 let ?d = "polymul ?q ?q" |
656 let ?d = "polymul ?q ?q" |
642 have "odd (Suc n) \<or> even (Suc n)" by simp |
657 have "odd (Suc n) \<or> even (Suc n)" by simp |
643 moreover |
658 moreover |
644 { assume odd: "odd (Suc n)" |
659 { assume odd: "odd (Suc n)" |
645 have th: "(Suc (Suc (Suc (0\<Colon>nat)) * (Suc n div Suc (Suc (0\<Colon>nat))))) = Suc n div 2 + Suc n div 2 + 1" |
660 have th: "(Suc (Suc (Suc 0) * (Suc n div Suc (Suc 0)))) = Suc n div 2 + Suc n div 2 + 1" |
646 by arith |
661 by arith |
647 from odd have "Ipoly bs (p ^\<^sub>p Suc n) = Ipoly bs (polymul p ?d)" by (simp add: Let_def) |
662 from odd have "Ipoly bs (p ^\<^sub>p Suc n) = Ipoly bs (polymul p ?d)" by (simp add: Let_def) |
648 also have "\<dots> = (Ipoly bs p) * (Ipoly bs p)^(Suc n div 2)*(Ipoly bs p)^(Suc n div 2)" |
663 also have "\<dots> = (Ipoly bs p) * (Ipoly bs p)^(Suc n div 2)*(Ipoly bs p)^(Suc n div 2)" |
649 using "2.hyps" by simp |
664 using "2.hyps" by simp |
650 also have "\<dots> = (Ipoly bs p) ^ (Suc n div 2 + Suc n div 2 + 1)" |
665 also have "\<dots> = (Ipoly bs p) ^ (Suc n div 2 + Suc n div 2 + 1)" |
651 by (simp only: power_add power_one_right) simp |
666 by (simp only: power_add power_one_right) simp |
652 also have "\<dots> = (Ipoly bs p) ^ (Suc (Suc (Suc (0\<Colon>nat)) * (Suc n div Suc (Suc (0\<Colon>nat)))))" |
667 also have "\<dots> = (Ipoly bs p) ^ (Suc (Suc (Suc 0) * (Suc n div Suc (Suc 0))))" |
653 by (simp only: th) |
668 by (simp only: th) |
654 finally have ?case |
669 finally have ?case |
655 using odd_nat_div_two_times_two_plus_one[OF odd, symmetric] by simp } |
670 using odd_nat_div_two_times_two_plus_one[OF odd, symmetric] by simp } |
656 moreover |
671 moreover |
657 { assume even: "even (Suc n)" |
672 { assume even: "even (Suc n)" |
658 have th: "(Suc (Suc (0\<Colon>nat))) * (Suc n div Suc (Suc (0\<Colon>nat))) = Suc n div 2 + Suc n div 2" |
673 have th: "(Suc (Suc 0)) * (Suc n div Suc (Suc 0)) = Suc n div 2 + Suc n div 2" |
659 by arith |
674 by arith |
660 from even have "Ipoly bs (p ^\<^sub>p Suc n) = Ipoly bs ?d" by (simp add: Let_def) |
675 from even have "Ipoly bs (p ^\<^sub>p Suc n) = Ipoly bs ?d" by (simp add: Let_def) |
661 also have "\<dots> = (Ipoly bs p) ^ (Suc n div 2 + Suc n div 2)" |
676 also have "\<dots> = (Ipoly bs p) ^ (Suc n div 2 + Suc n div 2)" |
662 using "2.hyps" apply (simp only: power_add) by simp |
677 using "2.hyps" apply (simp only: power_add) by simp |
663 finally have ?case using even_nat_div_two_times_two[OF even] by (simp only: th)} |
678 finally have ?case using even_nat_div_two_times_two[OF even] by (simp only: th)} |
664 ultimately show ?case by blast |
679 ultimately show ?case by blast |
665 qed |
680 qed |
666 |
681 |
667 lemma polypow_normh: |
682 lemma polypow_normh: |
668 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
683 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
669 shows "isnpolyh p n \<Longrightarrow> isnpolyh (polypow k p) n" |
684 shows "isnpolyh p n \<Longrightarrow> isnpolyh (polypow k p) n" |
670 proof (induct k arbitrary: n rule: polypow.induct) |
685 proof (induct k arbitrary: n rule: polypow.induct) |
671 case (2 k n) |
686 case (2 k n) |
672 let ?q = "polypow (Suc k div 2) p" |
687 let ?q = "polypow (Suc k div 2) p" |
673 let ?d = "polymul ?q ?q" |
688 let ?d = "polymul ?q ?q" |
676 from polymul_normh[OF th2 dn] have on: "isnpolyh (polymul p ?d) n" by simp |
691 from polymul_normh[OF th2 dn] have on: "isnpolyh (polymul p ?d) n" by simp |
677 from dn on show ?case by (simp add: Let_def) |
692 from dn on show ?case by (simp add: Let_def) |
678 qed auto |
693 qed auto |
679 |
694 |
680 lemma polypow_norm: |
695 lemma polypow_norm: |
681 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
696 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
682 shows "isnpoly p \<Longrightarrow> isnpoly (polypow k p)" |
697 shows "isnpoly p \<Longrightarrow> isnpoly (polypow k p)" |
683 by (simp add: polypow_normh isnpoly_def) |
698 by (simp add: polypow_normh isnpoly_def) |
684 |
699 |
685 text{* Finally the whole normalization *} |
700 text{* Finally the whole normalization *} |
686 |
701 |
687 lemma polynate [simp]: |
702 lemma polynate [simp]: |
688 "Ipoly bs (polynate p) = (Ipoly bs p :: 'a ::{field_char_0, field_inverse_zero})" |
703 "Ipoly bs (polynate p) = (Ipoly bs p :: 'a ::{field_char_0,field_inverse_zero})" |
689 by (induct p rule:polynate.induct) auto |
704 by (induct p rule:polynate.induct) auto |
690 |
705 |
691 lemma polynate_norm[simp]: |
706 lemma polynate_norm[simp]: |
692 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
707 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
693 shows "isnpoly (polynate p)" |
708 shows "isnpoly (polynate p)" |
694 by (induct p rule: polynate.induct) |
709 by (induct p rule: polynate.induct) |
695 (simp_all add: polyadd_norm polymul_norm polysub_norm polyneg_norm polypow_norm, |
710 (simp_all add: polyadd_norm polymul_norm polysub_norm polyneg_norm polypow_norm, |
696 simp_all add: isnpoly_def) |
711 simp_all add: isnpoly_def) |
697 |
712 |
718 and np: "isnpolyh p n" |
733 and np: "isnpolyh p n" |
719 shows "isnpolyh (funpow k f p) n" |
734 shows "isnpolyh (funpow k f p) n" |
720 using f np by (induct k arbitrary: p) auto |
735 using f np by (induct k arbitrary: p) auto |
721 |
736 |
722 lemma funpow_shift1: |
737 lemma funpow_shift1: |
723 "(Ipoly bs (funpow n shift1 p) :: 'a :: {field_char_0, field_inverse_zero}) = |
738 "(Ipoly bs (funpow n shift1 p) :: 'a :: {field_char_0,field_inverse_zero}) = |
724 Ipoly bs (Mul (Pw (Bound 0) n) p)" |
739 Ipoly bs (Mul (Pw (Bound 0) n) p)" |
725 by (induct n arbitrary: p) (simp_all add: shift1_isnpoly shift1) |
740 by (induct n arbitrary: p) (simp_all add: shift1_isnpoly shift1) |
726 |
741 |
727 lemma shift1_isnpolyh: "isnpolyh p n0 \<Longrightarrow> p\<noteq> 0\<^sub>p \<Longrightarrow> isnpolyh (shift1 p) 0" |
742 lemma shift1_isnpolyh: "isnpolyh p n0 \<Longrightarrow> p\<noteq> 0\<^sub>p \<Longrightarrow> isnpolyh (shift1 p) 0" |
728 using isnpolyh_mono[where n="n0" and n'="0" and p="p"] by (simp add: shift1_def) |
743 using isnpolyh_mono[where n="n0" and n'="0" and p="p"] by (simp add: shift1_def) |
729 |
744 |
730 lemma funpow_shift1_1: |
745 lemma funpow_shift1_1: |
731 "(Ipoly bs (funpow n shift1 p) :: 'a :: {field_char_0, field_inverse_zero}) = |
746 "(Ipoly bs (funpow n shift1 p) :: 'a :: {field_char_0,field_inverse_zero}) = |
732 Ipoly bs (funpow n shift1 (1)\<^sub>p *\<^sub>p p)" |
747 Ipoly bs (funpow n shift1 (1)\<^sub>p *\<^sub>p p)" |
733 by (simp add: funpow_shift1) |
748 by (simp add: funpow_shift1) |
734 |
749 |
735 lemma poly_cmul[simp]: "Ipoly bs (poly_cmul c p) = Ipoly bs (Mul (C c) p)" |
750 lemma poly_cmul[simp]: "Ipoly bs (poly_cmul c p) = Ipoly bs (Mul (C c) p)" |
736 by (induct p rule: poly_cmul.induct) (auto simp add: field_simps) |
751 by (induct p rule: poly_cmul.induct) (auto simp add: field_simps) |
737 |
752 |
738 lemma behead: |
753 lemma behead: |
739 assumes np: "isnpolyh p n" |
754 assumes np: "isnpolyh p n" |
740 shows "Ipoly bs (Add (Mul (head p) (Pw (Bound 0) (degree p))) (behead p)) = |
755 shows "Ipoly bs (Add (Mul (head p) (Pw (Bound 0) (degree p))) (behead p)) = |
741 (Ipoly bs p :: 'a :: {field_char_0, field_inverse_zero})" |
756 (Ipoly bs p :: 'a :: {field_char_0,field_inverse_zero})" |
742 using np |
757 using np |
743 proof (induct p arbitrary: n rule: behead.induct) |
758 proof (induct p arbitrary: n rule: behead.induct) |
744 case (1 c p n) hence pn: "isnpolyh p n" by simp |
759 case (1 c p n) hence pn: "isnpolyh p n" by simp |
745 from 1(1)[OF pn] |
760 from 1(1)[OF pn] |
746 have th:"Ipoly bs (Add (Mul (head p) (Pw (Bound 0) (degree p))) (behead p)) = Ipoly bs p" . |
761 have th:"Ipoly bs (Add (Mul (head p) (Pw (Bound 0) (degree p))) (behead p)) = Ipoly bs p" . |
819 | "maxindex (Neg p) = maxindex p" |
834 | "maxindex (Neg p) = maxindex p" |
820 | "maxindex (Pw p n) = maxindex p" |
835 | "maxindex (Pw p n) = maxindex p" |
821 | "maxindex (C x) = 0" |
836 | "maxindex (C x) = 0" |
822 |
837 |
823 definition wf_bs :: "'a list \<Rightarrow> poly \<Rightarrow> bool" |
838 definition wf_bs :: "'a list \<Rightarrow> poly \<Rightarrow> bool" |
824 where "wf_bs bs p = (length bs \<ge> maxindex p)" |
839 where "wf_bs bs p \<longleftrightarrow> length bs \<ge> maxindex p" |
825 |
840 |
826 lemma wf_bs_coefficients: "wf_bs bs p \<Longrightarrow> \<forall> c \<in> set (coefficients p). wf_bs bs c" |
841 lemma wf_bs_coefficients: "wf_bs bs p \<Longrightarrow> \<forall> c \<in> set (coefficients p). wf_bs bs c" |
827 proof (induct p rule: coefficients.induct) |
842 proof (induct p rule: coefficients.induct) |
828 case (1 c p) |
843 case (1 c p) |
829 show ?case |
844 show ?case |
841 qed simp_all |
856 qed simp_all |
842 |
857 |
843 lemma maxindex_coefficients: " \<forall>c\<in> set (coefficients p). maxindex c \<le> maxindex p" |
858 lemma maxindex_coefficients: " \<forall>c\<in> set (coefficients p). maxindex c \<le> maxindex p" |
844 by (induct p rule: coefficients.induct) auto |
859 by (induct p rule: coefficients.induct) auto |
845 |
860 |
846 lemma wf_bs_I: "wf_bs bs p ==> Ipoly (bs@bs') p = Ipoly bs p" |
861 lemma wf_bs_I: "wf_bs bs p \<Longrightarrow> Ipoly (bs @ bs') p = Ipoly bs p" |
847 unfolding wf_bs_def by (induct p) (auto simp add: nth_append) |
862 unfolding wf_bs_def by (induct p) (auto simp add: nth_append) |
848 |
863 |
849 lemma take_maxindex_wf: |
864 lemma take_maxindex_wf: |
850 assumes wf: "wf_bs bs p" |
865 assumes wf: "wf_bs bs p" |
851 shows "Ipoly (take (maxindex p) bs) p = Ipoly bs p" |
866 shows "Ipoly (take (maxindex p) bs) p = Ipoly bs p" |
987 lemma head_nz[simp]: "isnpolyh p n0 \<Longrightarrow> (head p = 0\<^sub>p) = (p = 0\<^sub>p)" |
1002 lemma head_nz[simp]: "isnpolyh p n0 \<Longrightarrow> (head p = 0\<^sub>p) = (p = 0\<^sub>p)" |
988 by (simp add: head_eq_headn0) |
1003 by (simp add: head_eq_headn0) |
989 |
1004 |
990 lemma isnpolyh_zero_iff: |
1005 lemma isnpolyh_zero_iff: |
991 assumes nq: "isnpolyh p n0" |
1006 assumes nq: "isnpolyh p n0" |
992 and eq :"\<forall>bs. wf_bs bs p \<longrightarrow> \<lparr>p\<rparr>\<^sub>p\<^bsup>bs\<^esup> = (0::'a::{field_char_0, field_inverse_zero, power})" |
1007 and eq :"\<forall>bs. wf_bs bs p \<longrightarrow> \<lparr>p\<rparr>\<^sub>p\<^bsup>bs\<^esup> = (0::'a::{field_char_0,field_inverse_zero, power})" |
993 shows "p = 0\<^sub>p" |
1008 shows "p = 0\<^sub>p" |
994 using nq eq |
1009 using nq eq |
995 proof (induct "maxindex p" arbitrary: p n0 rule: less_induct) |
1010 proof (induct "maxindex p" arbitrary: p n0 rule: less_induct) |
996 case less |
1011 case less |
997 note np = `isnpolyh p n0` and zp = `\<forall>bs. wf_bs bs p \<longrightarrow> \<lparr>p\<rparr>\<^sub>p\<^bsup>bs\<^esup> = (0::'a)` |
1012 note np = `isnpolyh p n0` and zp = `\<forall>bs. wf_bs bs p \<longrightarrow> \<lparr>p\<rparr>\<^sub>p\<^bsup>bs\<^esup> = (0::'a)` |
998 {assume nz: "maxindex p = 0" |
1013 { |
999 then obtain c where "p = C c" using np by (cases p) auto |
1014 assume nz: "maxindex p = 0" |
1000 with zp np have "p = 0\<^sub>p" unfolding wf_bs_def by simp} |
1015 then obtain c where "p = C c" |
1016 using np by (cases p) auto |
|
1017 with zp np have "p = 0\<^sub>p" |
|
1018 unfolding wf_bs_def by simp |
|
1019 } |
|
1001 moreover |
1020 moreover |
1002 {assume nz: "maxindex p \<noteq> 0" |
1021 { |
1022 assume nz: "maxindex p \<noteq> 0" |
|
1003 let ?h = "head p" |
1023 let ?h = "head p" |
1004 let ?hd = "decrpoly ?h" |
1024 let ?hd = "decrpoly ?h" |
1005 let ?ihd = "maxindex ?hd" |
1025 let ?ihd = "maxindex ?hd" |
1006 from head_isnpolyh[OF np] head_polybound0[OF np] have h:"isnpolyh ?h n0" "polybound0 ?h" |
1026 from head_isnpolyh[OF np] head_polybound0[OF np] |
1027 have h: "isnpolyh ?h n0" "polybound0 ?h" |
|
1007 by simp_all |
1028 by simp_all |
1008 hence nhd: "isnpolyh ?hd (n0 - 1)" using decrpoly_normh by blast |
1029 then have nhd: "isnpolyh ?hd (n0 - 1)" |
1030 using decrpoly_normh by blast |
|
1009 |
1031 |
1010 from maxindex_coefficients[of p] coefficients_head[of p, symmetric] |
1032 from maxindex_coefficients[of p] coefficients_head[of p, symmetric] |
1011 have mihn: "maxindex ?h \<le> maxindex p" by auto |
1033 have mihn: "maxindex ?h \<le> maxindex p" |
1012 with decr_maxindex[OF h(2)] nz have ihd_lt_n: "?ihd < maxindex p" by auto |
1034 by auto |
1013 {fix bs:: "'a list" assume bs: "wf_bs bs ?hd" |
1035 with decr_maxindex[OF h(2)] nz have ihd_lt_n: "?ihd < maxindex p" |
1036 by auto |
|
1037 { |
|
1038 fix bs :: "'a list" |
|
1039 assume bs: "wf_bs bs ?hd" |
|
1014 let ?ts = "take ?ihd bs" |
1040 let ?ts = "take ?ihd bs" |
1015 let ?rs = "drop ?ihd bs" |
1041 let ?rs = "drop ?ihd bs" |
1016 have ts: "wf_bs ?ts ?hd" using bs unfolding wf_bs_def by simp |
1042 have ts: "wf_bs ?ts ?hd" |
1017 have bs_ts_eq: "?ts@ ?rs = bs" by simp |
1043 using bs unfolding wf_bs_def by simp |
1018 from wf_bs_decrpoly[OF ts] have tsh: " \<forall>x. wf_bs (x#?ts) ?h" by simp |
1044 have bs_ts_eq: "?ts @ ?rs = bs" |
1019 from ihd_lt_n have "ALL x. length (x#?ts) \<le> maxindex p" by simp |
1045 by simp |
1020 with length_le_list_ex obtain xs where xs:"length ((x#?ts) @ xs) = maxindex p" by blast |
1046 from wf_bs_decrpoly[OF ts] have tsh: " \<forall>x. wf_bs (x # ?ts) ?h" |
1021 hence "\<forall> x. wf_bs ((x#?ts) @ xs) p" unfolding wf_bs_def by simp |
1047 by simp |
1022 with zp have "\<forall> x. Ipoly ((x#?ts) @ xs) p = 0" by blast |
1048 from ihd_lt_n have "\<forall>x. length (x # ?ts) \<le> maxindex p" |
1023 hence "\<forall> x. Ipoly (x#(?ts @ xs)) p = 0" by simp |
1049 by simp |
1050 with length_le_list_ex obtain xs where xs: "length ((x # ?ts) @ xs) = maxindex p" |
|
1051 by blast |
|
1052 then have "\<forall>x. wf_bs ((x # ?ts) @ xs) p" |
|
1053 unfolding wf_bs_def by simp |
|
1054 with zp have "\<forall>x. Ipoly ((x # ?ts) @ xs) p = 0" |
|
1055 by blast |
|
1056 then have "\<forall>x. Ipoly (x # (?ts @ xs)) p = 0" |
|
1057 by simp |
|
1024 with polypoly_poly[OF np, where ?'a = 'a] polypoly_polypoly'[OF np, where ?'a = 'a] |
1058 with polypoly_poly[OF np, where ?'a = 'a] polypoly_polypoly'[OF np, where ?'a = 'a] |
1025 have "\<forall>x. poly (polypoly' (?ts @ xs) p) x = poly [] x" by simp |
1059 have "\<forall>x. poly (polypoly' (?ts @ xs) p) x = poly [] x" |
1026 hence "poly (polypoly' (?ts @ xs) p) = poly []" by auto |
1060 by simp |
1027 hence "\<forall> c \<in> set (coefficients p). Ipoly (?ts @ xs) (decrpoly c) = 0" |
1061 then have "poly (polypoly' (?ts @ xs) p) = poly []" |
1062 by auto |
|
1063 then have "\<forall>c \<in> set (coefficients p). Ipoly (?ts @ xs) (decrpoly c) = 0" |
|
1028 using poly_zero[where ?'a='a] by (simp add: polypoly'_def list_all_iff) |
1064 using poly_zero[where ?'a='a] by (simp add: polypoly'_def list_all_iff) |
1029 with coefficients_head[of p, symmetric] |
1065 with coefficients_head[of p, symmetric] |
1030 have th0: "Ipoly (?ts @ xs) ?hd = 0" by simp |
1066 have th0: "Ipoly (?ts @ xs) ?hd = 0" |
1031 from bs have wf'': "wf_bs ?ts ?hd" unfolding wf_bs_def by simp |
1067 by simp |
1032 with th0 wf_bs_I[of ?ts ?hd xs] have "Ipoly ?ts ?hd = 0" by simp |
1068 from bs have wf'': "wf_bs ?ts ?hd" |
1033 with wf'' wf_bs_I[of ?ts ?hd ?rs] bs_ts_eq have "\<lparr>?hd\<rparr>\<^sub>p\<^bsup>bs\<^esup> = 0" by simp } |
1069 unfolding wf_bs_def by simp |
1034 then have hdz: "\<forall>bs. wf_bs bs ?hd \<longrightarrow> \<lparr>?hd\<rparr>\<^sub>p\<^bsup>bs\<^esup> = (0::'a)" by blast |
1070 with th0 wf_bs_I[of ?ts ?hd xs] have "Ipoly ?ts ?hd = 0" |
1035 |
1071 by simp |
1036 from less(1)[OF ihd_lt_n nhd] hdz have "?hd = 0\<^sub>p" by blast |
1072 with wf'' wf_bs_I[of ?ts ?hd ?rs] bs_ts_eq have "\<lparr>?hd\<rparr>\<^sub>p\<^bsup>bs\<^esup> = 0" |
1037 hence "?h = 0\<^sub>p" by simp |
1073 by simp |
1038 with head_nz[OF np] have "p = 0\<^sub>p" by simp} |
1074 } |
1039 ultimately show "p = 0\<^sub>p" by blast |
1075 then have hdz: "\<forall>bs. wf_bs bs ?hd \<longrightarrow> \<lparr>?hd\<rparr>\<^sub>p\<^bsup>bs\<^esup> = (0::'a)" |
1076 by blast |
|
1077 from less(1)[OF ihd_lt_n nhd] hdz have "?hd = 0\<^sub>p" |
|
1078 by blast |
|
1079 then have "?h = 0\<^sub>p" by simp |
|
1080 with head_nz[OF np] have "p = 0\<^sub>p" by simp |
|
1081 } |
|
1082 ultimately show "p = 0\<^sub>p" |
|
1083 by blast |
|
1040 qed |
1084 qed |
1041 |
1085 |
1042 lemma isnpolyh_unique: |
1086 lemma isnpolyh_unique: |
1043 assumes np:"isnpolyh p n0" |
1087 assumes np: "isnpolyh p n0" |
1044 and nq: "isnpolyh q n1" |
1088 and nq: "isnpolyh q n1" |
1045 shows "(\<forall>bs. \<lparr>p\<rparr>\<^sub>p\<^bsup>bs\<^esup> = (\<lparr>q\<rparr>\<^sub>p\<^bsup>bs\<^esup> :: 'a::{field_char_0, field_inverse_zero, power})) \<longleftrightarrow> p = q" |
1089 shows "(\<forall>bs. \<lparr>p\<rparr>\<^sub>p\<^bsup>bs\<^esup> = (\<lparr>q\<rparr>\<^sub>p\<^bsup>bs\<^esup> :: 'a::{field_char_0,field_inverse_zero,power})) \<longleftrightarrow> p = q" |
1046 proof(auto) |
1090 proof auto |
1047 assume H: "\<forall>bs. (\<lparr>p\<rparr>\<^sub>p\<^bsup>bs\<^esup> ::'a)= \<lparr>q\<rparr>\<^sub>p\<^bsup>bs\<^esup>" |
1091 assume H: "\<forall>bs. (\<lparr>p\<rparr>\<^sub>p\<^bsup>bs\<^esup> ::'a) = \<lparr>q\<rparr>\<^sub>p\<^bsup>bs\<^esup>" |
1048 hence "\<forall>bs.\<lparr>p -\<^sub>p q\<rparr>\<^sub>p\<^bsup>bs\<^esup>= (0::'a)" by simp |
1092 then have "\<forall>bs.\<lparr>p -\<^sub>p q\<rparr>\<^sub>p\<^bsup>bs\<^esup>= (0::'a)" |
1049 hence "\<forall>bs. wf_bs bs (p -\<^sub>p q) \<longrightarrow> \<lparr>p -\<^sub>p q\<rparr>\<^sub>p\<^bsup>bs\<^esup> = (0::'a)" |
1093 by simp |
1094 then have "\<forall>bs. wf_bs bs (p -\<^sub>p q) \<longrightarrow> \<lparr>p -\<^sub>p q\<rparr>\<^sub>p\<^bsup>bs\<^esup> = (0::'a)" |
|
1050 using wf_bs_polysub[where p=p and q=q] by auto |
1095 using wf_bs_polysub[where p=p and q=q] by auto |
1051 with isnpolyh_zero_iff[OF polysub_normh[OF np nq]] polysub_0[OF np nq] |
1096 with isnpolyh_zero_iff[OF polysub_normh[OF np nq]] polysub_0[OF np nq] show "p = q" |
1052 show "p = q" by blast |
1097 by blast |
1053 qed |
1098 qed |
1054 |
1099 |
1055 |
1100 |
1056 text{* consequences of unicity on the algorithms for polynomial normalization *} |
1101 text{* consequences of unicity on the algorithms for polynomial normalization *} |
1057 |
1102 |
1058 lemma polyadd_commute: |
1103 lemma polyadd_commute: |
1059 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
1104 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
1060 and np: "isnpolyh p n0" |
1105 and np: "isnpolyh p n0" |
1061 and nq: "isnpolyh q n1" |
1106 and nq: "isnpolyh q n1" |
1062 shows "p +\<^sub>p q = q +\<^sub>p p" |
1107 shows "p +\<^sub>p q = q +\<^sub>p p" |
1063 using isnpolyh_unique[OF polyadd_normh[OF np nq] polyadd_normh[OF nq np]] by simp |
1108 using isnpolyh_unique[OF polyadd_normh[OF np nq] polyadd_normh[OF nq np]] |
1064 |
1109 by simp |
1065 lemma zero_normh: "isnpolyh 0\<^sub>p n" by simp |
1110 |
1066 lemma one_normh: "isnpolyh (1)\<^sub>p n" by simp |
1111 lemma zero_normh: "isnpolyh 0\<^sub>p n" |
1112 by simp |
|
1113 |
|
1114 lemma one_normh: "isnpolyh (1)\<^sub>p n" |
|
1115 by simp |
|
1067 |
1116 |
1068 lemma polyadd_0[simp]: |
1117 lemma polyadd_0[simp]: |
1069 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
1118 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
1070 and np: "isnpolyh p n0" |
1119 and np: "isnpolyh p n0" |
1071 shows "p +\<^sub>p 0\<^sub>p = p" and "0\<^sub>p +\<^sub>p p = p" |
1120 shows "p +\<^sub>p 0\<^sub>p = p" |
1121 and "0\<^sub>p +\<^sub>p p = p" |
|
1072 using isnpolyh_unique[OF polyadd_normh[OF np zero_normh] np] |
1122 using isnpolyh_unique[OF polyadd_normh[OF np zero_normh] np] |
1073 isnpolyh_unique[OF polyadd_normh[OF zero_normh np] np] by simp_all |
1123 isnpolyh_unique[OF polyadd_normh[OF zero_normh np] np] by simp_all |
1074 |
1124 |
1075 lemma polymul_1[simp]: |
1125 lemma polymul_1[simp]: |
1076 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
1126 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
1077 and np: "isnpolyh p n0" |
1127 and np: "isnpolyh p n0" |
1078 shows "p *\<^sub>p (1)\<^sub>p = p" and "(1)\<^sub>p *\<^sub>p p = p" |
1128 shows "p *\<^sub>p (1)\<^sub>p = p" |
1129 and "(1)\<^sub>p *\<^sub>p p = p" |
|
1079 using isnpolyh_unique[OF polymul_normh[OF np one_normh] np] |
1130 using isnpolyh_unique[OF polymul_normh[OF np one_normh] np] |
1080 isnpolyh_unique[OF polymul_normh[OF one_normh np] np] by simp_all |
1131 isnpolyh_unique[OF polymul_normh[OF one_normh np] np] by simp_all |
1081 |
1132 |
1082 lemma polymul_0[simp]: |
1133 lemma polymul_0[simp]: |
1083 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
1134 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
1084 and np: "isnpolyh p n0" |
1135 and np: "isnpolyh p n0" |
1085 shows "p *\<^sub>p 0\<^sub>p = 0\<^sub>p" and "0\<^sub>p *\<^sub>p p = 0\<^sub>p" |
1136 shows "p *\<^sub>p 0\<^sub>p = 0\<^sub>p" |
1137 and "0\<^sub>p *\<^sub>p p = 0\<^sub>p" |
|
1086 using isnpolyh_unique[OF polymul_normh[OF np zero_normh] zero_normh] |
1138 using isnpolyh_unique[OF polymul_normh[OF np zero_normh] zero_normh] |
1087 isnpolyh_unique[OF polymul_normh[OF zero_normh np] zero_normh] by simp_all |
1139 isnpolyh_unique[OF polymul_normh[OF zero_normh np] zero_normh] by simp_all |
1088 |
1140 |
1089 lemma polymul_commute: |
1141 lemma polymul_commute: |
1090 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
1142 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
1091 and np:"isnpolyh p n0" |
1143 and np: "isnpolyh p n0" |
1092 and nq: "isnpolyh q n1" |
1144 and nq: "isnpolyh q n1" |
1093 shows "p *\<^sub>p q = q *\<^sub>p p" |
1145 shows "p *\<^sub>p q = q *\<^sub>p p" |
1094 using isnpolyh_unique[OF polymul_normh[OF np nq] polymul_normh[OF nq np], where ?'a = "'a\<Colon>{field_char_0, field_inverse_zero, power}"] |
1146 using isnpolyh_unique[OF polymul_normh[OF np nq] polymul_normh[OF nq np], where ?'a = "'a::{field_char_0,field_inverse_zero, power}"] |
1095 by simp |
1147 by simp |
1096 |
1148 |
1097 declare polyneg_polyneg [simp] |
1149 declare polyneg_polyneg [simp] |
1098 |
1150 |
1099 lemma isnpolyh_polynate_id [simp]: |
1151 lemma isnpolyh_polynate_id [simp]: |
1100 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
1152 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
1101 and np:"isnpolyh p n0" |
1153 and np: "isnpolyh p n0" |
1102 shows "polynate p = p" |
1154 shows "polynate p = p" |
1103 using isnpolyh_unique[where ?'a= "'a::{field_char_0, field_inverse_zero}", OF polynate_norm[of p, unfolded isnpoly_def] np] polynate[where ?'a = "'a::{field_char_0, field_inverse_zero}"] |
1155 using isnpolyh_unique[where ?'a= "'a::{field_char_0,field_inverse_zero}", OF polynate_norm[of p, unfolded isnpoly_def] np] polynate[where ?'a = "'a::{field_char_0,field_inverse_zero}"] |
1104 by simp |
1156 by simp |
1105 |
1157 |
1106 lemma polynate_idempotent[simp]: |
1158 lemma polynate_idempotent[simp]: |
1107 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
1159 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
1108 shows "polynate (polynate p) = polynate p" |
1160 shows "polynate (polynate p) = polynate p" |
1109 using isnpolyh_polynate_id[OF polynate_norm[of p, unfolded isnpoly_def]] . |
1161 using isnpolyh_polynate_id[OF polynate_norm[of p, unfolded isnpoly_def]] . |
1110 |
1162 |
1111 lemma poly_nate_polypoly': "poly_nate bs p = polypoly' bs (polynate p)" |
1163 lemma poly_nate_polypoly': "poly_nate bs p = polypoly' bs (polynate p)" |
1112 unfolding poly_nate_def polypoly'_def .. |
1164 unfolding poly_nate_def polypoly'_def .. |
1113 |
1165 |
1114 lemma poly_nate_poly: |
1166 lemma poly_nate_poly: |
1115 "poly (poly_nate bs p) = (\<lambda>x:: 'a ::{field_char_0, field_inverse_zero}. \<lparr>p\<rparr>\<^sub>p\<^bsup>x # bs\<^esup>)" |
1167 "poly (poly_nate bs p) = (\<lambda>x:: 'a ::{field_char_0,field_inverse_zero}. \<lparr>p\<rparr>\<^sub>p\<^bsup>x # bs\<^esup>)" |
1116 using polypoly'_poly[OF polynate_norm[unfolded isnpoly_def], symmetric, of bs p] |
1168 using polypoly'_poly[OF polynate_norm[unfolded isnpoly_def], symmetric, of bs p] |
1117 unfolding poly_nate_polypoly' by auto |
1169 unfolding poly_nate_polypoly' by auto |
1118 |
1170 |
1119 |
1171 |
1120 subsection{* heads, degrees and all that *} |
1172 subsection{* heads, degrees and all that *} |
1145 from nq have nq': "isnpolyh (~\<^sub>p q) n1" using polyneg_normh by simp |
1197 from nq have nq': "isnpolyh (~\<^sub>p q) n1" using polyneg_normh by simp |
1146 from degree_polyadd[OF np nq'] show ?thesis by (simp add: polysub_def degree_polyneg[OF nq]) |
1198 from degree_polyadd[OF np nq'] show ?thesis by (simp add: polysub_def degree_polyneg[OF nq]) |
1147 qed |
1199 qed |
1148 |
1200 |
1149 lemma degree_polysub_samehead: |
1201 lemma degree_polysub_samehead: |
1150 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
1202 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
1151 and np: "isnpolyh p n0" and nq: "isnpolyh q n1" and h: "head p = head q" |
1203 and np: "isnpolyh p n0" and nq: "isnpolyh q n1" and h: "head p = head q" |
1152 and d: "degree p = degree q" |
1204 and d: "degree p = degree q" |
1153 shows "degree (p -\<^sub>p q) < degree p \<or> (p -\<^sub>p q = 0\<^sub>p)" |
1205 shows "degree (p -\<^sub>p q) < degree p \<or> (p -\<^sub>p q = 0\<^sub>p)" |
1154 unfolding polysub_def split_def fst_conv snd_conv |
1206 unfolding polysub_def split_def fst_conv snd_conv |
1155 using np nq h d |
1207 using np nq h d |
1261 apply (metis head_nz) |
1313 apply (metis head_nz) |
1262 apply (metis degree.simps(9) gr0_conv_Suc head.simps(1) less_Suc0 not_less_eq) |
1314 apply (metis degree.simps(9) gr0_conv_Suc head.simps(1) less_Suc0 not_less_eq) |
1263 done |
1315 done |
1264 |
1316 |
1265 lemma polymul_head_polyeq: |
1317 lemma polymul_head_polyeq: |
1266 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
1318 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
1267 shows "\<lbrakk>isnpolyh p n0; isnpolyh q n1 ; p \<noteq> 0\<^sub>p ; q \<noteq> 0\<^sub>p \<rbrakk> \<Longrightarrow> head (p *\<^sub>p q) = head p *\<^sub>p head q" |
1319 shows "\<lbrakk>isnpolyh p n0; isnpolyh q n1 ; p \<noteq> 0\<^sub>p ; q \<noteq> 0\<^sub>p \<rbrakk> \<Longrightarrow> head (p *\<^sub>p q) = head p *\<^sub>p head q" |
1268 proof (induct p q arbitrary: n0 n1 rule: polymul.induct) |
1320 proof (induct p q arbitrary: n0 n1 rule: polymul.induct) |
1269 case (2 c c' n' p' n0 n1) |
1321 case (2 c c' n' p' n0 n1) |
1270 hence "isnpolyh (head (CN c' n' p')) n1" "isnormNum c" by (simp_all add: head_isnpolyh) |
1322 hence "isnpolyh (head (CN c' n' p')) n1" "isnormNum c" by (simp_all add: head_isnpolyh) |
1271 thus ?case using 2 by (cases n') auto |
1323 thus ?case using 2 by (cases n') auto |
1343 |
1395 |
1344 lemma degreen_polyneg: "isnpolyh p n0 \<Longrightarrow> degreen (~\<^sub>p p) m = degreen p m" |
1396 lemma degreen_polyneg: "isnpolyh p n0 \<Longrightarrow> degreen (~\<^sub>p p) m = degreen p m" |
1345 by (induct p arbitrary: n0 rule: polyneg.induct) auto |
1397 by (induct p arbitrary: n0 rule: polyneg.induct) auto |
1346 |
1398 |
1347 lemma degree_polymul: |
1399 lemma degree_polymul: |
1348 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
1400 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
1349 and np: "isnpolyh p n0" |
1401 and np: "isnpolyh p n0" |
1350 and nq: "isnpolyh q n1" |
1402 and nq: "isnpolyh q n1" |
1351 shows "degree (p *\<^sub>p q) \<le> degree p + degree q" |
1403 shows "degree (p *\<^sub>p q) \<le> degree p + degree q" |
1352 using polymul_degreen[OF np nq, where m="0"] degree_eq_degreen0 by simp |
1404 using polymul_degreen[OF np nq, where m="0"] degree_eq_degreen0 by simp |
1353 |
1405 |
1359 |
1411 |
1360 |
1412 |
1361 subsection {* Correctness of polynomial pseudo division *} |
1413 subsection {* Correctness of polynomial pseudo division *} |
1362 |
1414 |
1363 lemma polydivide_aux_properties: |
1415 lemma polydivide_aux_properties: |
1364 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
1416 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
1365 and np: "isnpolyh p n0" |
1417 and np: "isnpolyh p n0" |
1366 and ns: "isnpolyh s n1" |
1418 and ns: "isnpolyh s n1" |
1367 and ap: "head p = a" |
1419 and ap: "head p = a" |
1368 and ndp: "degree p = n" and pnz: "p \<noteq> 0\<^sub>p" |
1420 and ndp: "degree p = n" and pnz: "p \<noteq> 0\<^sub>p" |
1369 shows "(polydivide_aux a n p k s = (k',r) \<longrightarrow> (k' \<ge> k) \<and> (degree r = 0 \<or> degree r < degree p) |
1421 shows "(polydivide_aux a n p k s = (k',r) \<longrightarrow> (k' \<ge> k) \<and> (degree r = 0 \<or> degree r < degree p) |
1436 have nq': "isnpolyh (?akk' *\<^sub>p ?xdn +\<^sub>p q) 0" by simp |
1488 have nq': "isnpolyh (?akk' *\<^sub>p ?xdn +\<^sub>p q) 0" by simp |
1437 from polyadd_normh[OF polymul_normh[OF np |
1489 from polyadd_normh[OF polymul_normh[OF np |
1438 polyadd_normh[OF polymul_normh[OF nakk' nxdn] nq]] nr'] |
1490 polyadd_normh[OF polymul_normh[OF nakk' nxdn] nq]] nr'] |
1439 have nqr': "isnpolyh (p *\<^sub>p (?akk' *\<^sub>p ?xdn +\<^sub>p q) +\<^sub>p r) 0" |
1491 have nqr': "isnpolyh (p *\<^sub>p (?akk' *\<^sub>p ?xdn +\<^sub>p q) +\<^sub>p r) 0" |
1440 by simp |
1492 by simp |
1441 from asp have "\<forall> (bs:: 'a::{field_char_0, field_inverse_zero} list). Ipoly bs (a^\<^sub>p (k' - k) *\<^sub>p (s -\<^sub>p ?p')) = |
1493 from asp have "\<forall> (bs:: 'a::{field_char_0,field_inverse_zero} list). Ipoly bs (a^\<^sub>p (k' - k) *\<^sub>p (s -\<^sub>p ?p')) = |
1442 Ipoly bs (p *\<^sub>p q +\<^sub>p r)" by simp |
1494 Ipoly bs (p *\<^sub>p q +\<^sub>p r)" by simp |
1443 hence " \<forall>(bs:: 'a::{field_char_0, field_inverse_zero} list). Ipoly bs (a^\<^sub>p (k' - k)*\<^sub>p s) = |
1495 hence " \<forall>(bs:: 'a::{field_char_0,field_inverse_zero} list). Ipoly bs (a^\<^sub>p (k' - k)*\<^sub>p s) = |
1444 Ipoly bs (a^\<^sub>p (k' - k)) * Ipoly bs ?p' + Ipoly bs p * Ipoly bs q + Ipoly bs r" |
1496 Ipoly bs (a^\<^sub>p (k' - k)) * Ipoly bs ?p' + Ipoly bs p * Ipoly bs q + Ipoly bs r" |
1445 by (simp add: field_simps) |
1497 by (simp add: field_simps) |
1446 hence " \<forall>(bs:: 'a::{field_char_0, field_inverse_zero} list). Ipoly bs (a ^\<^sub>p (k' - k) *\<^sub>p s) = |
1498 hence " \<forall>(bs:: 'a::{field_char_0,field_inverse_zero} list). Ipoly bs (a ^\<^sub>p (k' - k) *\<^sub>p s) = |
1447 Ipoly bs (a^\<^sub>p (k' - k)) * Ipoly bs (funpow (degree s - n) shift1 (1)\<^sub>p *\<^sub>p p) + |
1499 Ipoly bs (a^\<^sub>p (k' - k)) * Ipoly bs (funpow (degree s - n) shift1 (1)\<^sub>p *\<^sub>p p) + |
1448 Ipoly bs p * Ipoly bs q + Ipoly bs r" |
1500 Ipoly bs p * Ipoly bs q + Ipoly bs r" |
1449 by (auto simp only: funpow_shift1_1) |
1501 by (auto simp only: funpow_shift1_1) |
1450 hence "\<forall>(bs:: 'a::{field_char_0, field_inverse_zero} list). Ipoly bs (a ^\<^sub>p (k' - k) *\<^sub>p s) = |
1502 hence "\<forall>(bs:: 'a::{field_char_0,field_inverse_zero} list). Ipoly bs (a ^\<^sub>p (k' - k) *\<^sub>p s) = |
1451 Ipoly bs p * (Ipoly bs (a^\<^sub>p (k' - k)) * Ipoly bs (funpow (degree s - n) shift1 (1)\<^sub>p) + |
1503 Ipoly bs p * (Ipoly bs (a^\<^sub>p (k' - k)) * Ipoly bs (funpow (degree s - n) shift1 (1)\<^sub>p) + |
1452 Ipoly bs q) + Ipoly bs r" |
1504 Ipoly bs q) + Ipoly bs r" |
1453 by (simp add: field_simps) |
1505 by (simp add: field_simps) |
1454 hence "\<forall>(bs:: 'a::{field_char_0, field_inverse_zero} list). Ipoly bs (a ^\<^sub>p (k' - k) *\<^sub>p s) = |
1506 hence "\<forall>(bs:: 'a::{field_char_0,field_inverse_zero} list). Ipoly bs (a ^\<^sub>p (k' - k) *\<^sub>p s) = |
1455 Ipoly bs (p *\<^sub>p ((a^\<^sub>p (k' - k)) *\<^sub>p (funpow (degree s - n) shift1 (1)\<^sub>p) +\<^sub>p q) +\<^sub>p r)" |
1507 Ipoly bs (p *\<^sub>p ((a^\<^sub>p (k' - k)) *\<^sub>p (funpow (degree s - n) shift1 (1)\<^sub>p) +\<^sub>p q) +\<^sub>p r)" |
1456 by simp |
1508 by simp |
1457 with isnpolyh_unique[OF nakks' nqr'] |
1509 with isnpolyh_unique[OF nakks' nqr'] |
1458 have "a ^\<^sub>p (k' - k) *\<^sub>p s = |
1510 have "a ^\<^sub>p (k' - k) *\<^sub>p s = |
1459 p *\<^sub>p ((a^\<^sub>p (k' - k)) *\<^sub>p (funpow (degree s - n) shift1 (1)\<^sub>p) +\<^sub>p q) +\<^sub>p r" |
1511 p *\<^sub>p ((a^\<^sub>p (k' - k)) *\<^sub>p (funpow (degree s - n) shift1 (1)\<^sub>p) +\<^sub>p q) +\<^sub>p r" |
1468 } |
1520 } |
1469 hence ?ths by blast |
1521 hence ?ths by blast |
1470 } |
1522 } |
1471 moreover |
1523 moreover |
1472 { assume spz:"s -\<^sub>p ?p' = 0\<^sub>p" |
1524 { assume spz:"s -\<^sub>p ?p' = 0\<^sub>p" |
1473 from spz isnpolyh_unique[OF polysub_normh[OF ns np'], where q="0\<^sub>p", symmetric, where ?'a = "'a::{field_char_0, field_inverse_zero}"] |
1525 from spz isnpolyh_unique[OF polysub_normh[OF ns np'], where q="0\<^sub>p", symmetric, where ?'a = "'a::{field_char_0,field_inverse_zero}"] |
1474 have " \<forall>(bs:: 'a::{field_char_0, field_inverse_zero} list). Ipoly bs s = Ipoly bs ?p'" |
1526 have " \<forall>(bs:: 'a::{field_char_0,field_inverse_zero} list). Ipoly bs s = Ipoly bs ?p'" |
1475 by simp |
1527 by simp |
1476 hence "\<forall>(bs:: 'a::{field_char_0, field_inverse_zero} list). Ipoly bs s = Ipoly bs (?xdn *\<^sub>p p)" |
1528 hence "\<forall>(bs:: 'a::{field_char_0,field_inverse_zero} list). Ipoly bs s = Ipoly bs (?xdn *\<^sub>p p)" |
1477 using np nxdn |
1529 using np nxdn |
1478 apply simp |
1530 apply simp |
1479 apply (simp only: funpow_shift1_1) |
1531 apply (simp only: funpow_shift1_1) |
1480 apply simp |
1532 apply simp |
1481 done |
1533 done |
1538 and dr: "degree r = 0 \<or> degree r < degree p" |
1590 and dr: "degree r = 0 \<or> degree r < degree p" |
1539 and qr: "a ^\<^sub>p (k' - Suc k) *\<^sub>p ((a *\<^sub>p s) -\<^sub>p (?b *\<^sub>p ?p')) = p *\<^sub>p q +\<^sub>p r" |
1591 and qr: "a ^\<^sub>p (k' - Suc k) *\<^sub>p ((a *\<^sub>p s) -\<^sub>p (?b *\<^sub>p ?p')) = p *\<^sub>p q +\<^sub>p r" |
1540 by auto |
1592 by auto |
1541 from kk' have kk'':"Suc (k' - Suc k) = k' - k" by arith |
1593 from kk' have kk'':"Suc (k' - Suc k) = k' - k" by arith |
1542 { |
1594 { |
1543 fix bs:: "'a::{field_char_0, field_inverse_zero} list" |
1595 fix bs:: "'a::{field_char_0,field_inverse_zero} list" |
1544 from qr isnpolyh_unique[OF polypow_normh[OF head_isnpolyh[OF np], where k="k' - Suc k", simplified ap] nasbp', symmetric] |
1596 from qr isnpolyh_unique[OF polypow_normh[OF head_isnpolyh[OF np], where k="k' - Suc k", simplified ap] nasbp', symmetric] |
1545 have "Ipoly bs (a ^\<^sub>p (k' - Suc k) *\<^sub>p ((a *\<^sub>p s) -\<^sub>p (?b *\<^sub>p ?p'))) = Ipoly bs (p *\<^sub>p q +\<^sub>p r)" |
1597 have "Ipoly bs (a ^\<^sub>p (k' - Suc k) *\<^sub>p ((a *\<^sub>p s) -\<^sub>p (?b *\<^sub>p ?p'))) = Ipoly bs (p *\<^sub>p q +\<^sub>p r)" |
1546 by simp |
1598 by simp |
1547 hence "Ipoly bs a ^ (Suc (k' - Suc k)) * Ipoly bs s = |
1599 hence "Ipoly bs a ^ (Suc (k' - Suc k)) * Ipoly bs s = |
1548 Ipoly bs p * Ipoly bs q + Ipoly bs a ^ (k' - Suc k) * Ipoly bs ?b * Ipoly bs ?p' + Ipoly bs r" |
1600 Ipoly bs p * Ipoly bs q + Ipoly bs a ^ (k' - Suc k) * Ipoly bs ?b * Ipoly bs ?p' + Ipoly bs r" |
1552 by (simp add: kk'' funpow_shift1_1[where n="degree s - n" and p="p"]) |
1604 by (simp add: kk'' funpow_shift1_1[where n="degree s - n" and p="p"]) |
1553 hence "Ipoly bs (a ^\<^sub>p (k' - k) *\<^sub>p s) = |
1605 hence "Ipoly bs (a ^\<^sub>p (k' - k) *\<^sub>p s) = |
1554 Ipoly bs p * (Ipoly bs q + Ipoly bs a ^ (k' - Suc k) * Ipoly bs ?b * Ipoly bs ?xdn) + Ipoly bs r" |
1606 Ipoly bs p * (Ipoly bs q + Ipoly bs a ^ (k' - Suc k) * Ipoly bs ?b * Ipoly bs ?xdn) + Ipoly bs r" |
1555 by (simp add: field_simps) |
1607 by (simp add: field_simps) |
1556 } |
1608 } |
1557 hence ieq:"\<forall>(bs :: 'a::{field_char_0, field_inverse_zero} list). Ipoly bs (a ^\<^sub>p (k' - k) *\<^sub>p s) = |
1609 hence ieq:"\<forall>(bs :: 'a::{field_char_0,field_inverse_zero} list). Ipoly bs (a ^\<^sub>p (k' - k) *\<^sub>p s) = |
1558 Ipoly bs (p *\<^sub>p (q +\<^sub>p (a ^\<^sub>p (k' - Suc k) *\<^sub>p ?b *\<^sub>p ?xdn)) +\<^sub>p r)" |
1610 Ipoly bs (p *\<^sub>p (q +\<^sub>p (a ^\<^sub>p (k' - Suc k) *\<^sub>p ?b *\<^sub>p ?xdn)) +\<^sub>p r)" |
1559 by auto |
1611 by auto |
1560 let ?q = "q +\<^sub>p (a ^\<^sub>p (k' - Suc k) *\<^sub>p ?b *\<^sub>p ?xdn)" |
1612 let ?q = "q +\<^sub>p (a ^\<^sub>p (k' - Suc k) *\<^sub>p ?b *\<^sub>p ?xdn)" |
1561 from polyadd_normh[OF nq polymul_normh[OF polymul_normh[OF polypow_normh[OF head_isnpolyh[OF np], where k="k' - Suc k"] head_isnpolyh[OF ns], simplified ap ] nxdn]] |
1613 from polyadd_normh[OF nq polymul_normh[OF polymul_normh[OF polypow_normh[OF head_isnpolyh[OF np], where k="k' - Suc k"] head_isnpolyh[OF ns], simplified ap ] nxdn]] |
1562 have nqw: "isnpolyh ?q 0" |
1614 have nqw: "isnpolyh ?q 0" |
1575 hence ?ths by blast |
1627 hence ?ths by blast |
1576 } |
1628 } |
1577 moreover |
1629 moreover |
1578 { assume spz: "a *\<^sub>p s -\<^sub>p (?b *\<^sub>p ?p') = 0\<^sub>p" |
1630 { assume spz: "a *\<^sub>p s -\<^sub>p (?b *\<^sub>p ?p') = 0\<^sub>p" |
1579 { |
1631 { |
1580 fix bs :: "'a::{field_char_0, field_inverse_zero} list" |
1632 fix bs :: "'a::{field_char_0,field_inverse_zero} list" |
1581 from isnpolyh_unique[OF nth, where ?'a="'a" and q="0\<^sub>p",simplified,symmetric] spz |
1633 from isnpolyh_unique[OF nth, where ?'a="'a" and q="0\<^sub>p",simplified,symmetric] spz |
1582 have "Ipoly bs (a*\<^sub>p s) = Ipoly bs ?b * Ipoly bs ?p'" |
1634 have "Ipoly bs (a*\<^sub>p s) = Ipoly bs ?b * Ipoly bs ?p'" |
1583 by simp |
1635 by simp |
1584 hence "Ipoly bs (a*\<^sub>p s) = Ipoly bs (?b *\<^sub>p ?xdn) * Ipoly bs p" |
1636 hence "Ipoly bs (a*\<^sub>p s) = Ipoly bs (?b *\<^sub>p ?xdn) * Ipoly bs p" |
1585 by (simp add: funpow_shift1_1[where n="degree s - n" and p="p"]) |
1637 by (simp add: funpow_shift1_1[where n="degree s - n" and p="p"]) |
1586 hence "Ipoly bs (a*\<^sub>p s) = Ipoly bs (p *\<^sub>p (?b *\<^sub>p ?xdn))" |
1638 hence "Ipoly bs (a*\<^sub>p s) = Ipoly bs (p *\<^sub>p (?b *\<^sub>p ?xdn))" |
1587 by simp |
1639 by simp |
1588 } |
1640 } |
1589 hence hth: "\<forall> (bs:: 'a::{field_char_0, field_inverse_zero} list). Ipoly bs (a*\<^sub>p s) = |
1641 hence hth: "\<forall> (bs:: 'a::{field_char_0,field_inverse_zero} list). Ipoly bs (a*\<^sub>p s) = |
1590 Ipoly bs (p *\<^sub>p (?b *\<^sub>p ?xdn))" .. |
1642 Ipoly bs (p *\<^sub>p (?b *\<^sub>p ?xdn))" .. |
1591 from hth have asq: "a *\<^sub>p s = p *\<^sub>p (?b *\<^sub>p ?xdn)" |
1643 from hth have asq: "a *\<^sub>p s = p *\<^sub>p (?b *\<^sub>p ?xdn)" |
1592 using isnpolyh_unique[where ?'a = "'a::{field_char_0, field_inverse_zero}", OF polymul_normh[OF head_isnpolyh[OF np] ns] |
1644 using isnpolyh_unique[where ?'a = "'a::{field_char_0,field_inverse_zero}", OF polymul_normh[OF head_isnpolyh[OF np] ns] |
1593 polymul_normh[OF np polymul_normh[OF head_isnpolyh[OF ns] nxdn]], |
1645 polymul_normh[OF np polymul_normh[OF head_isnpolyh[OF ns] nxdn]], |
1594 simplified ap] by simp |
1646 simplified ap] by simp |
1595 { assume h1: "polydivide_aux a n p k s = (k', r)" |
1647 { assume h1: "polydivide_aux a n p k s = (k', r)" |
1596 from h1 sz ba dn' spz polydivide_aux.simps polydivide_aux.simps |
1648 from h1 sz ba dn' spz polydivide_aux.simps polydivide_aux.simps |
1597 have "(k',r) = (Suc k, 0\<^sub>p)" by (simp add: Let_def) |
1649 have "(k',r) = (Suc k, 0\<^sub>p)" by (simp add: Let_def) |
1617 } |
1669 } |
1618 ultimately show ?ths by blast |
1670 ultimately show ?ths by blast |
1619 qed |
1671 qed |
1620 |
1672 |
1621 lemma polydivide_properties: |
1673 lemma polydivide_properties: |
1622 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
1674 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
1623 and np: "isnpolyh p n0" and ns: "isnpolyh s n1" and pnz: "p \<noteq> 0\<^sub>p" |
1675 and np: "isnpolyh p n0" and ns: "isnpolyh s n1" and pnz: "p \<noteq> 0\<^sub>p" |
1624 shows "\<exists>k r. polydivide s p = (k,r) \<and> |
1676 shows "\<exists>k r. polydivide s p = (k,r) \<and> |
1625 (\<exists>nr. isnpolyh r nr) \<and> (degree r = 0 \<or> degree r < degree p) \<and> |
1677 (\<exists>nr. isnpolyh r nr) \<and> (degree r = 0 \<or> degree r < degree p) \<and> |
1626 (\<exists>q n1. isnpolyh q n1 \<and> ((polypow k (head p)) *\<^sub>p s = p *\<^sub>p q +\<^sub>p r))" |
1678 (\<exists>q n1. isnpolyh q n1 \<and> ((polypow k (head p)) *\<^sub>p s = p *\<^sub>p q +\<^sub>p r))" |
1627 proof - |
1679 proof - |
1629 by simp_all |
1681 by simp_all |
1630 from polydivide_def[where s="s" and p="p"] have ex: "\<exists> k r. polydivide s p = (k,r)" |
1682 from polydivide_def[where s="s" and p="p"] have ex: "\<exists> k r. polydivide s p = (k,r)" |
1631 by auto |
1683 by auto |
1632 then obtain k r where kr: "polydivide s p = (k,r)" |
1684 then obtain k r where kr: "polydivide s p = (k,r)" |
1633 by blast |
1685 by blast |
1634 from trans[OF meta_eq_to_obj_eq[OF polydivide_def[where s="s"and p="p"], symmetric] kr] |
1686 from trans[OF polydivide_def[where s="s"and p="p", symmetric] kr] |
1635 polydivide_aux_properties[OF np ns trv pnz, where k="0" and k'="k" and r="r"] |
1687 polydivide_aux_properties[OF np ns trv pnz, where k="0" and k'="k" and r="r"] |
1636 have "(degree r = 0 \<or> degree r < degree p) \<and> |
1688 have "(degree r = 0 \<or> degree r < degree p) \<and> |
1637 (\<exists>nr. isnpolyh r nr) \<and> (\<exists>q n1. isnpolyh q n1 \<and> head p ^\<^sub>p k - 0 *\<^sub>p s = p *\<^sub>p q +\<^sub>p r)" |
1689 (\<exists>nr. isnpolyh r nr) \<and> (\<exists>q n1. isnpolyh q n1 \<and> head p ^\<^sub>p k - 0 *\<^sub>p s = p *\<^sub>p q +\<^sub>p r)" |
1638 by blast |
1690 by blast |
1639 with kr show ?thesis |
1691 with kr show ?thesis |
1645 qed |
1697 qed |
1646 |
1698 |
1647 |
1699 |
1648 subsection{* More about polypoly and pnormal etc *} |
1700 subsection{* More about polypoly and pnormal etc *} |
1649 |
1701 |
1650 definition "isnonconstant p = (\<not> isconstant p)" |
1702 definition "isnonconstant p \<longleftrightarrow> \<not> isconstant p" |
1651 |
1703 |
1652 lemma isnonconstant_pnormal_iff: |
1704 lemma isnonconstant_pnormal_iff: |
1653 assumes nc: "isnonconstant p" |
1705 assumes nc: "isnonconstant p" |
1654 shows "pnormal (polypoly bs p) \<longleftrightarrow> Ipoly bs (head p) \<noteq> 0" |
1706 shows "pnormal (polypoly bs p) \<longleftrightarrow> Ipoly bs (head p) \<noteq> 0" |
1655 proof |
1707 proof |
1766 definition "swapnorm n m t = polynate (swap n m t)" |
1818 definition "swapnorm n m t = polynate (swap n m t)" |
1767 |
1819 |
1768 lemma swapnorm: |
1820 lemma swapnorm: |
1769 assumes nbs: "n < length bs" |
1821 assumes nbs: "n < length bs" |
1770 and mbs: "m < length bs" |
1822 and mbs: "m < length bs" |
1771 shows "((Ipoly bs (swapnorm n m t) :: 'a\<Colon>{field_char_0, field_inverse_zero})) = |
1823 shows "((Ipoly bs (swapnorm n m t) :: 'a::{field_char_0,field_inverse_zero})) = |
1772 Ipoly ((bs[n:= bs!m])[m:= bs!n]) t" |
1824 Ipoly ((bs[n:= bs!m])[m:= bs!n]) t" |
1773 using swap[OF assms] swapnorm_def by simp |
1825 using swap[OF assms] swapnorm_def by simp |
1774 |
1826 |
1775 lemma swapnorm_isnpoly [simp]: |
1827 lemma swapnorm_isnpoly [simp]: |
1776 assumes "SORT_CONSTRAINT('a::{field_char_0, field_inverse_zero})" |
1828 assumes "SORT_CONSTRAINT('a::{field_char_0,field_inverse_zero})" |
1777 shows "isnpoly (swapnorm n m p)" |
1829 shows "isnpoly (swapnorm n m p)" |
1778 unfolding swapnorm_def by simp |
1830 unfolding swapnorm_def by simp |
1779 |
1831 |
1780 definition "polydivideby n s p = |
1832 definition "polydivideby n s p = |
1781 (let ss = swapnorm 0 n s ; sp = swapnorm 0 n p ; h = head sp; (k,r) = polydivide ss sp |
1833 (let |
1782 in (k, swapnorm 0 n h,swapnorm 0 n r))" |
1834 ss = swapnorm 0 n s; |
1783 |
1835 sp = swapnorm 0 n p; |
1784 lemma swap_nz [simp]: " (swap n m p = 0\<^sub>p) = (p = 0\<^sub>p)" |
1836 h = head sp; |
1837 (k, r) = polydivide ss sp |
|
1838 in (k, swapnorm 0 n h, swapnorm 0 n r))" |
|
1839 |
|
1840 lemma swap_nz [simp]: "swap n m p = 0\<^sub>p \<longleftrightarrow> p = 0\<^sub>p" |
|
1785 by (induct p) simp_all |
1841 by (induct p) simp_all |
1786 |
1842 |
1787 fun isweaknpoly :: "poly \<Rightarrow> bool" |
1843 fun isweaknpoly :: "poly \<Rightarrow> bool" |
1788 where |
1844 where |
1789 "isweaknpoly (C c) = True" |
1845 "isweaknpoly (C c) = True" |