src/HOL/Algebra/poly/UnivPoly.ML
author paulson
Fri, 05 Nov 1999 11:14:26 +0100
changeset 7998 3d0c34795831
child 8006 299127ded09d
permissions -rw-r--r--
Algebra and Polynomial theories, by Clemens Ballarin
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";