paulson@7998
|
1 |
(*
|
paulson@7998
|
2 |
Univariate Polynomials
|
paulson@7998
|
3 |
$Id$
|
paulson@7998
|
4 |
Author: Clemens Ballarin, started 9 December 1996
|
paulson@7998
|
5 |
TODO: monom is *mono*morphism (probably induction needed)
|
paulson@7998
|
6 |
*)
|
paulson@7998
|
7 |
|
paulson@7998
|
8 |
(* Closure of UP under +, *s, monom, const and * *)
|
paulson@7998
|
9 |
|
paulson@7998
|
10 |
Goalw [UP_def]
|
paulson@7998
|
11 |
"!! f g. [| f : UP; g : UP |] ==> (%n. (f n + g n::'a::ring)) : UP";
|
paulson@7998
|
12 |
by (Step_tac 1);
|
paulson@7998
|
13 |
(* instantiate bound for the sum and do case split *)
|
paulson@7998
|
14 |
by (res_inst_tac [("x", "if n<=na then na else n")] exI 1);
|
paulson@7998
|
15 |
by (case_tac "n <= na" 1);
|
paulson@7998
|
16 |
by (Asm_simp_tac 1);
|
paulson@7998
|
17 |
by (Asm_simp_tac 2);
|
paulson@7998
|
18 |
(* first case, bound of g higher *)
|
paulson@7998
|
19 |
by (etac (make_elim le_bound) 1 THEN atac 1);
|
paulson@7998
|
20 |
by (REPEAT (Step_tac 1));
|
paulson@7998
|
21 |
by (Asm_simp_tac 1);
|
paulson@7998
|
22 |
(* second case is identical,
|
paulson@7998
|
23 |
apart from we have to massage the inequality *)
|
paulson@7998
|
24 |
by (dtac (not_leE RS less_imp_le) 1);
|
paulson@7998
|
25 |
by (etac (make_elim le_bound) 1 THEN atac 1);
|
paulson@7998
|
26 |
by (REPEAT (Step_tac 1));
|
paulson@7998
|
27 |
by (Asm_simp_tac 1);
|
paulson@7998
|
28 |
qed "UP_closed_add";
|
paulson@7998
|
29 |
|
paulson@7998
|
30 |
Goalw [UP_def]
|
paulson@7998
|
31 |
"!! f. f : UP ==> (%n. (a * f n::'a::ring)) : UP";
|
paulson@7998
|
32 |
by (REPEAT (Step_tac 1));
|
paulson@7998
|
33 |
by (Asm_simp_tac 1);
|
paulson@7998
|
34 |
qed "UP_closed_smult";
|
paulson@7998
|
35 |
|
paulson@7998
|
36 |
Goalw [UP_def]
|
paulson@7998
|
37 |
"!! m. (%n. if m = n then <1> else <0>) : UP";
|
paulson@7998
|
38 |
by (Step_tac 1);
|
paulson@7998
|
39 |
by (res_inst_tac [("x", "m")] exI 1);
|
paulson@7998
|
40 |
by (Step_tac 1);
|
paulson@7998
|
41 |
by (dtac (less_not_refl2 RS not_sym) 1);
|
paulson@7998
|
42 |
by (Asm_simp_tac 1);
|
paulson@7998
|
43 |
qed "UP_closed_monom";
|
paulson@7998
|
44 |
|
paulson@7998
|
45 |
Goalw [UP_def]
|
paulson@7998
|
46 |
"!! a. (%n. if n = 0 then a else <0>) : UP";
|
paulson@7998
|
47 |
by (Step_tac 1);
|
paulson@7998
|
48 |
by (res_inst_tac [("x", "0")] exI 1);
|
paulson@7998
|
49 |
by (rtac boundI 1);
|
paulson@7998
|
50 |
by (asm_simp_tac (simpset() addsimps [less_not_refl2]) 1);
|
paulson@7998
|
51 |
qed "UP_closed_const";
|
paulson@7998
|
52 |
|
paulson@7998
|
53 |
Goal
|
paulson@7998
|
54 |
"!! f::nat=>'a::ring. \
|
paulson@7998
|
55 |
\ [| bound n f; bound m g; n + m < k |] ==> f i * g (k - i) = <0>";
|
paulson@7998
|
56 |
(* Case split: either f i or g (k - i) is zero *)
|
paulson@7998
|
57 |
by (case_tac "n<i" 1);
|
paulson@7998
|
58 |
(* First case, f i is zero *)
|
paulson@7998
|
59 |
by (SELECT_GOAL Auto_tac 1);
|
paulson@7998
|
60 |
(* Second case, we have to derive m < k-i *)
|
paulson@7998
|
61 |
by (subgoal_tac "m < k-i" 1);
|
paulson@7998
|
62 |
by (SELECT_GOAL Auto_tac 1);
|
paulson@7998
|
63 |
(* More inequalities, quite nasty *)
|
paulson@7998
|
64 |
by (rtac add_less_imp_less_diff 1);
|
paulson@7998
|
65 |
by (stac add_commute 1);
|
paulson@7998
|
66 |
by (dtac leI 1);
|
paulson@7998
|
67 |
by (rtac le_less_trans 1);
|
paulson@7998
|
68 |
by (assume_tac 2);
|
paulson@7998
|
69 |
by (asm_simp_tac (simpset() addsimps [add_le_mono1]) 1);
|
paulson@7998
|
70 |
qed "bound_mult_zero";
|
paulson@7998
|
71 |
|
paulson@7998
|
72 |
Goalw [UP_def]
|
paulson@7998
|
73 |
"!! f g. [| f : UP; g : UP |] ==> \
|
paulson@7998
|
74 |
\ (%n. (SUM n (%i. f i * g (n-i))::'a::ring)) : UP";
|
paulson@7998
|
75 |
by (Step_tac 1);
|
paulson@7998
|
76 |
(* Instantiate bound for the product, and remove bound in goal *)
|
paulson@7998
|
77 |
by (res_inst_tac [("x", "n + na")] exI 1);
|
paulson@7998
|
78 |
by (Step_tac 1);
|
paulson@7998
|
79 |
(* Show that the sum is 0 *)
|
paulson@7998
|
80 |
by (asm_simp_tac (simpset() addsimps [bound_mult_zero]) 1);
|
paulson@7998
|
81 |
qed "UP_closed_mult";
|
paulson@7998
|
82 |
|
paulson@7998
|
83 |
(* %x. <0> represents a polynomial *)
|
paulson@7998
|
84 |
|
paulson@7998
|
85 |
Goalw [UP_def] "(%x. <0>) : UP";
|
paulson@7998
|
86 |
by (Fast_tac 1);
|
paulson@7998
|
87 |
qed "UP_zero";
|
paulson@7998
|
88 |
|
paulson@7998
|
89 |
(* Effect of +, *s, monom, * and the other operations on the coefficients *)
|
paulson@7998
|
90 |
|
paulson@7998
|
91 |
Goalw [coeff_def, up_add_def]
|
paulson@7998
|
92 |
"coeff n (p+q) = (coeff n p + coeff n q::'a::ring)";
|
paulson@7998
|
93 |
by (asm_simp_tac (simpset() addsimps [Abs_UP_inverse, UP_closed_add, Rep_UP]) 1);
|
paulson@7998
|
94 |
qed "coeff_add";
|
paulson@7998
|
95 |
|
paulson@7998
|
96 |
Goalw [coeff_def, up_smult_def]
|
paulson@7998
|
97 |
"!!a::'a::ring. coeff n (a *s p) = a * coeff n p";
|
paulson@7998
|
98 |
by (asm_simp_tac (simpset() addsimps [Abs_UP_inverse, UP_closed_smult, Rep_UP]) 1);
|
paulson@7998
|
99 |
qed "coeff_smult";
|
paulson@7998
|
100 |
|
paulson@7998
|
101 |
Goalw [coeff_def, monom_def]
|
paulson@7998
|
102 |
"coeff n (monom m) = (if m=n then <1> else <0>)";
|
paulson@7998
|
103 |
by (asm_simp_tac (simpset() addsimps [Abs_UP_inverse, UP_closed_monom, Rep_UP]) 1);
|
paulson@7998
|
104 |
qed "coeff_monom";
|
paulson@7998
|
105 |
|
paulson@7998
|
106 |
Goalw [coeff_def, const_def]
|
paulson@7998
|
107 |
"coeff n (const a) = (if n=0 then a else <0>)";
|
paulson@7998
|
108 |
by (asm_simp_tac (simpset() addsimps [Abs_UP_inverse, UP_closed_const, Rep_UP]) 1);
|
paulson@7998
|
109 |
qed "coeff_const";
|
paulson@7998
|
110 |
|
paulson@7998
|
111 |
Goalw [coeff_def, up_mult_def]
|
paulson@7998
|
112 |
"coeff n (p * q) = (SUM n (%i. coeff i p * coeff (n-i) q)::'a::ring)";
|
paulson@7998
|
113 |
by (asm_simp_tac (simpset() addsimps [Abs_UP_inverse, UP_closed_mult, Rep_UP]) 1);
|
paulson@7998
|
114 |
qed "coeff_mult";
|
paulson@7998
|
115 |
|
paulson@7998
|
116 |
Goalw [coeff_def, up_zero_def] "coeff n <0> = <0>";
|
paulson@7998
|
117 |
by (asm_simp_tac (simpset() addsimps [Abs_UP_inverse, UP_zero, Rep_UP]) 1);
|
paulson@7998
|
118 |
qed "coeff_zero";
|
paulson@7998
|
119 |
|
paulson@7998
|
120 |
Addsimps [coeff_add, coeff_smult, coeff_monom, coeff_const,
|
paulson@7998
|
121 |
coeff_mult, coeff_zero];
|
paulson@7998
|
122 |
|
paulson@7998
|
123 |
Goalw [up_one_def]
|
paulson@7998
|
124 |
"coeff n <1> = (if n=0 then <1> else <0>)";
|
paulson@7998
|
125 |
by (Simp_tac 1);
|
paulson@7998
|
126 |
qed "coeff_one";
|
paulson@7998
|
127 |
|
paulson@7998
|
128 |
Goalw [up_uminus_def] "coeff n (-p) = (-coeff n p::'a::ring)";
|
paulson@7998
|
129 |
by (simp_tac (simpset() addsimps m_minus) 1);
|
paulson@7998
|
130 |
qed "coeff_uminus";
|
paulson@7998
|
131 |
|
paulson@7998
|
132 |
Addsimps [coeff_one, coeff_uminus];
|
paulson@7998
|
133 |
|
paulson@7998
|
134 |
(* Polynomials form a ring *)
|
paulson@7998
|
135 |
|
paulson@7998
|
136 |
Goalw [coeff_def]
|
paulson@7998
|
137 |
"!! p q. [| !! n. coeff n p = coeff n q |] ==> p = q";
|
paulson@7998
|
138 |
by (res_inst_tac [("t", "p")] (Rep_UP_inverse RS subst) 1);
|
paulson@7998
|
139 |
by (res_inst_tac [("t", "q")] (Rep_UP_inverse RS subst) 1);
|
paulson@7998
|
140 |
by (Asm_simp_tac 1);
|
paulson@7998
|
141 |
qed "up_eqI";
|
paulson@7998
|
142 |
|
paulson@7998
|
143 |
Goalw [coeff_def]
|
paulson@7998
|
144 |
"!! p q. coeff n p ~= coeff n q ==> p ~= q";
|
paulson@7998
|
145 |
by (etac contrapos 1);
|
paulson@7998
|
146 |
by (Asm_simp_tac 1);
|
paulson@7998
|
147 |
qed "up_neqI";
|
paulson@7998
|
148 |
|
paulson@7998
|
149 |
Goal "!! a::('a::ring) up. (a + b) + c = a + (b + c)";
|
paulson@7998
|
150 |
by (rtac up_eqI 1);
|
paulson@7998
|
151 |
by (Simp_tac 1);
|
paulson@7998
|
152 |
by (rtac a_assoc 1);
|
paulson@7998
|
153 |
qed "up_a_assoc";
|
paulson@7998
|
154 |
|
paulson@7998
|
155 |
Goal "!! a::('a::ring) up. <0> + a = a";
|
paulson@7998
|
156 |
by (rtac up_eqI 1);
|
paulson@7998
|
157 |
by (Simp_tac 1);
|
paulson@7998
|
158 |
qed "up_l_zero";
|
paulson@7998
|
159 |
|
paulson@7998
|
160 |
Goal "!! a::('a::ring) up. (-a) + a = <0>";
|
paulson@7998
|
161 |
by (rtac up_eqI 1);
|
paulson@7998
|
162 |
by (Simp_tac 1);
|
paulson@7998
|
163 |
qed "up_l_neg";
|
paulson@7998
|
164 |
|
paulson@7998
|
165 |
Goal "!! a::('a::ring) up. a + b = b + a";
|
paulson@7998
|
166 |
by (rtac up_eqI 1);
|
paulson@7998
|
167 |
by (Simp_tac 1);
|
paulson@7998
|
168 |
by (rtac a_comm 1);
|
paulson@7998
|
169 |
qed "up_a_comm";
|
paulson@7998
|
170 |
|
paulson@7998
|
171 |
Goal "!! a::('a::ring) up. (a * b) * c = a * (b * c)";
|
paulson@7998
|
172 |
by (rtac up_eqI 1);
|
paulson@7998
|
173 |
by (Simp_tac 1);
|
paulson@7998
|
174 |
by (rtac poly_assoc_lemma 1);
|
paulson@7998
|
175 |
qed "up_m_assoc";
|
paulson@7998
|
176 |
|
paulson@7998
|
177 |
Goal "!! a::('a::ring) up. <1> * a = a";
|
paulson@7998
|
178 |
by (rtac up_eqI 1);
|
paulson@7998
|
179 |
by (Simp_tac 1);
|
paulson@7998
|
180 |
by (nat_ind_tac "n" 1); (* this is only a case split *)
|
paulson@7998
|
181 |
(* Base case *)
|
paulson@7998
|
182 |
by (Simp_tac 1);
|
paulson@7998
|
183 |
(* Induction step *)
|
paulson@7998
|
184 |
by (simp_tac (simpset() delsimps [SUM_Suc] addsimps [SUM_Suc2]) 1);
|
paulson@7998
|
185 |
qed "up_l_one";
|
paulson@7998
|
186 |
|
paulson@7998
|
187 |
Goal "!! a::('a::ring) up. (a + b) * c = a * c + b * c";
|
paulson@7998
|
188 |
by (rtac up_eqI 1);
|
paulson@7998
|
189 |
by (simp_tac (simpset() addsimps [l_distr, SUM_add]) 1);
|
paulson@7998
|
190 |
qed "up_l_distr";
|
paulson@7998
|
191 |
|
paulson@7998
|
192 |
Goal "!! a::('a::ring) up. a * b = b * a";
|
paulson@7998
|
193 |
by (rtac up_eqI 1);
|
paulson@7998
|
194 |
by (cut_inst_tac [("a", "%i. coeff i a"), ("b", "%i. coeff i b")]
|
paulson@7998
|
195 |
poly_comm_lemma 1);
|
paulson@7998
|
196 |
by (asm_full_simp_tac (simpset() addsimps [m_comm]) 1);
|
paulson@7998
|
197 |
qed "up_m_comm";
|
paulson@7998
|
198 |
|
paulson@7998
|
199 |
Goal "<1> ~= (<0>::('a::ring) up)";
|
paulson@7998
|
200 |
by (res_inst_tac [("n", "0")] up_neqI 1);
|
paulson@7998
|
201 |
by (Simp_tac 1);
|
paulson@7998
|
202 |
qed "up_one_not_zero";
|
paulson@7998
|
203 |
|
paulson@7998
|
204 |
(* Further algebraic rules *)
|
paulson@7998
|
205 |
|
paulson@7998
|
206 |
Goal "!! a::'a::ring. const a * p = a *s p";
|
paulson@7998
|
207 |
by (rtac up_eqI 1);
|
paulson@7998
|
208 |
by (nat_ind_tac "n" 1); (* really only a case split *)
|
paulson@7998
|
209 |
by (Simp_tac 1);
|
paulson@7998
|
210 |
by (simp_tac (simpset() delsimps [SUM_Suc] addsimps [SUM_Suc2]) 1);
|
paulson@7998
|
211 |
qed "const_mult_is_smult";
|
paulson@7998
|
212 |
|
paulson@7998
|
213 |
Goal "!! a::'a::ring. const (a + b) = const a + const b";
|
paulson@7998
|
214 |
by (rtac up_eqI 1);
|
paulson@7998
|
215 |
by (simp_tac (simpset() setloop (split_tac [expand_if])) 1);
|
paulson@7998
|
216 |
qed "const_add";
|
paulson@7998
|
217 |
|
paulson@7998
|
218 |
Goal "!! a::'a::ring. const (a * b) = const a * const b";
|
paulson@7998
|
219 |
by (simp_tac (simpset() addsimps [const_mult_is_smult]) 1);
|
paulson@7998
|
220 |
by (rtac up_eqI 1);
|
paulson@7998
|
221 |
by (simp_tac (simpset() setloop (split_tac [expand_if])) 1);
|
paulson@7998
|
222 |
qed "const_mult";
|
paulson@7998
|
223 |
|
paulson@7998
|
224 |
Goal "const (<1>::'a::ring) = <1>";
|
paulson@7998
|
225 |
by (rtac up_eqI 1);
|
paulson@7998
|
226 |
by (Simp_tac 1);
|
paulson@7998
|
227 |
qed "const_one";
|
paulson@7998
|
228 |
|
paulson@7998
|
229 |
Goal "const (<0>::'a::ring) = <0>";
|
paulson@7998
|
230 |
by (rtac up_eqI 1);
|
paulson@7998
|
231 |
by (simp_tac (simpset() setloop (split_tac [expand_if])) 1);
|
paulson@7998
|
232 |
qed "const_zero";
|
paulson@7998
|
233 |
|
paulson@7998
|
234 |
Addsimps [const_add, const_mult, const_one, const_zero];
|
paulson@7998
|
235 |
|
paulson@7998
|
236 |
Goalw [inj_on_def, UNIV_def, const_def] "inj const";
|
paulson@7998
|
237 |
by (Simp_tac 1);
|
paulson@7998
|
238 |
by (strip_tac 1);
|
paulson@7998
|
239 |
by (dres_inst_tac [("f", "Rep_UP")] arg_cong 1);
|
paulson@7998
|
240 |
by (full_simp_tac (simpset() addsimps [Abs_UP_inverse, UP_closed_const,
|
paulson@7998
|
241 |
expand_fun_eq]) 1);
|
paulson@7998
|
242 |
by (dres_inst_tac [("x", "0")] spec 1);
|
paulson@7998
|
243 |
by (Full_simp_tac 1);
|
paulson@7998
|
244 |
qed "const_inj";
|
paulson@7998
|
245 |
|
paulson@7998
|
246 |
(*Lemma used in PolyHomo*)
|
paulson@7998
|
247 |
Goal
|
paulson@7998
|
248 |
"!! f::nat=>'a::ring. [| bound n f; bound m g|] ==> \
|
paulson@7998
|
249 |
\ SUM (n + m) (%k. SUM k (%i. f i * g (k-i))) = SUM n f * SUM m g";
|
paulson@7998
|
250 |
by (simp_tac (simpset() addsimps [SUM_ldistr, DiagSum]) 1);
|
paulson@7998
|
251 |
(* SUM_rdistr must be applied after SUM_ldistr ! *)
|
paulson@7998
|
252 |
by (simp_tac (simpset() addsimps [SUM_rdistr]) 1);
|
paulson@7998
|
253 |
by (res_inst_tac [("m", "n"), ("n", "n+m")] SUM_extend 1);
|
paulson@7998
|
254 |
by (rtac le_add1 1);
|
paulson@7998
|
255 |
by (SELECT_GOAL Auto_tac 1);
|
paulson@7998
|
256 |
by (rtac SUM_cong 1);
|
paulson@7998
|
257 |
by (rtac refl 1);
|
paulson@7998
|
258 |
by (res_inst_tac [("m", "m"), ("n", "n+m-i")] SUM_shrink 1);
|
paulson@7998
|
259 |
by (asm_simp_tac (simpset() addsimps [le_add_diff]) 1);
|
paulson@7998
|
260 |
by (SELECT_GOAL Auto_tac 1);
|
paulson@7998
|
261 |
by (rtac refl 1);
|
paulson@7998
|
262 |
qed "CauchySum";
|