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