| 7998 |      1 | (*
 | 
|  |      2 |     Universal property and evaluation homomorphism of univariate polynomials
 | 
|  |      3 |     $Id$
 | 
|  |      4 |     Author: Clemens Ballarin, started 15 April 1997
 | 
|  |      5 | *)
 | 
|  |      6 | 
 | 
| 17479 |      7 | theory PolyHomo imports UnivPoly2 begin
 | 
| 7998 |      8 | 
 | 
| 21423 |      9 | definition
 | 
|  |     10 |   EVAL2 :: "['a::ring => 'b, 'b, 'a up] => 'b::ring" where
 | 
|  |     11 |   "EVAL2 phi a p = setsum (%i. phi (coeff p i) * a ^ i) {..deg p}"
 | 
|  |     12 | 
 | 
|  |     13 | definition
 | 
|  |     14 |   EVAL :: "['a::ring, 'a up] => 'a" where
 | 
|  |     15 |   "EVAL = EVAL2 (%x. x)"
 | 
|  |     16 | 
 | 
|  |     17 | lemma SUM_shrink_lemma:
 | 
|  |     18 |   "!! f::(nat=>'a::ring).
 | 
|  |     19 |      m <= n & (ALL i. m < i & i <= n --> f i = 0) -->
 | 
|  |     20 |      setsum f {..m} = setsum f {..n}"
 | 
|  |     21 |   apply (induct_tac n)
 | 
|  |     22 |   (* Base case *)
 | 
|  |     23 |    apply (simp (no_asm))
 | 
|  |     24 |   (* Induction step *)
 | 
|  |     25 |   apply (case_tac "m <= n")
 | 
|  |     26 |    apply auto
 | 
|  |     27 |   apply (subgoal_tac "m = Suc n")
 | 
|  |     28 |    apply (simp (no_asm_simp))
 | 
|  |     29 |   apply arith
 | 
|  |     30 |   done
 | 
|  |     31 | 
 | 
|  |     32 | lemma SUM_shrink:
 | 
|  |     33 |   "!! f::(nat=>'a::ring).
 | 
|  |     34 |      [| m <= n; !!i. [| m < i; i <= n |] ==> f i = 0; P (setsum f {..n}) |]
 | 
|  |     35 |    ==> P (setsum f {..m})"
 | 
|  |     36 |   apply (cut_tac m = m and n = n and f = f in SUM_shrink_lemma)
 | 
|  |     37 |   apply simp
 | 
|  |     38 |   done
 | 
|  |     39 | 
 | 
|  |     40 | lemma SUM_extend:
 | 
|  |     41 |   "!! f::(nat=>'a::ring).
 | 
|  |     42 |      [| m <= n; !!i. [| m < i; i <= n |] ==> f i = 0; P (setsum f {..m}) |]
 | 
|  |     43 |      ==> P (setsum f {..n})"
 | 
|  |     44 |   apply (cut_tac m = m and n = n and f = f in SUM_shrink_lemma)
 | 
|  |     45 |   apply simp
 | 
|  |     46 |   done
 | 
|  |     47 | 
 | 
|  |     48 | lemma DiagSum_lemma:
 | 
|  |     49 |   "!!f::nat=>'a::ring. j <= n + m -->
 | 
|  |     50 |      setsum (%k. setsum (%i. f i * g (k - i)) {..k}) {..j} =
 | 
|  |     51 |      setsum (%k. setsum (%i. f k * g i) {..j - k}) {..j}"
 | 
|  |     52 |   apply (induct_tac j)
 | 
|  |     53 |   (* Base case *)
 | 
|  |     54 |    apply (simp (no_asm))
 | 
|  |     55 |   (* Induction step *)
 | 
|  |     56 |   apply (simp (no_asm) add: Suc_diff_le natsum_add)
 | 
|  |     57 |   apply (simp (no_asm_simp))
 | 
|  |     58 |   done
 | 
|  |     59 | 
 | 
|  |     60 | lemma DiagSum:
 | 
|  |     61 |   "!!f::nat=>'a::ring.
 | 
|  |     62 |      setsum (%k. setsum (%i. f i * g (k - i)) {..k}) {..n + m} =
 | 
|  |     63 |      setsum (%k. setsum (%i. f k * g i) {..n + m - k}) {..n + m}"
 | 
|  |     64 |   apply (rule DiagSum_lemma [THEN mp])
 | 
|  |     65 |   apply (rule le_refl)
 | 
|  |     66 |   done
 | 
|  |     67 | 
 | 
|  |     68 | lemma CauchySum:
 | 
|  |     69 |   "!! f::nat=>'a::ring. [| bound n f; bound m g|] ==>
 | 
|  |     70 |      setsum (%k. setsum (%i. f i * g (k-i)) {..k}) {..n + m} =
 | 
|  |     71 |      setsum f {..n} * setsum g {..m}"
 | 
|  |     72 |   apply (simp (no_asm) add: natsum_ldistr DiagSum)
 | 
|  |     73 |   (* SUM_rdistr must be applied after SUM_ldistr ! *)
 | 
|  |     74 |   apply (simp (no_asm) add: natsum_rdistr)
 | 
|  |     75 |   apply (rule_tac m = n and n = "n + m" in SUM_extend)
 | 
|  |     76 |   apply (rule le_add1)
 | 
|  |     77 |    apply force
 | 
|  |     78 |   apply (rule natsum_cong)
 | 
|  |     79 |    apply (rule refl)
 | 
|  |     80 |   apply (rule_tac m = m and n = "n +m - i" in SUM_shrink)
 | 
|  |     81 |     apply (simp (no_asm_simp) add: le_add_diff)
 | 
|  |     82 |    apply auto
 | 
|  |     83 |   done
 | 
|  |     84 | 
 | 
|  |     85 | (* Evaluation homomorphism *)
 | 
| 7998 |     86 | 
 | 
| 21423 |     87 | lemma EVAL2_homo:
 | 
|  |     88 |     "!! phi::('a::ring=>'b::ring). homo phi ==> homo (EVAL2 phi a)"
 | 
|  |     89 |   apply (rule homoI)
 | 
|  |     90 |     apply (unfold EVAL2_def)
 | 
|  |     91 |   (* + commutes *)
 | 
|  |     92 |   (* degree estimations:
 | 
|  |     93 |     bound of all sums can be extended to max (deg aa) (deg b) *)
 | 
|  |     94 |     apply (rule_tac m = "deg (aa + b) " and n = "max (deg aa) (deg b)" in SUM_shrink)
 | 
|  |     95 |       apply (rule deg_add)
 | 
|  |     96 |      apply (simp (no_asm_simp) del: coeff_add add: deg_aboveD)
 | 
|  |     97 |     apply (rule_tac m = "deg aa" and n = "max (deg aa) (deg b)" in SUM_shrink)
 | 
|  |     98 |      apply (rule le_maxI1)
 | 
|  |     99 |     apply (simp (no_asm_simp) add: deg_aboveD)
 | 
|  |    100 |    apply (rule_tac m = "deg b" and n = "max (deg aa) (deg b) " in SUM_shrink)
 | 
|  |    101 |      apply (rule le_maxI2)
 | 
|  |    102 |     apply (simp (no_asm_simp) add: deg_aboveD)
 | 
|  |    103 |   (* actual homom property + *)
 | 
|  |    104 |     apply (simp (no_asm_simp) add: l_distr natsum_add)
 | 
|  |    105 | 
 | 
|  |    106 |   (* * commutes *)
 | 
|  |    107 |    apply (rule_tac m = "deg (aa * b) " and n = "deg aa + deg b" in SUM_shrink)
 | 
|  |    108 |     apply (rule deg_mult_ring)
 | 
|  |    109 |     apply (simp (no_asm_simp) del: coeff_mult add: deg_aboveD)
 | 
|  |    110 |    apply (rule trans)
 | 
|  |    111 |     apply (rule_tac [2] CauchySum)
 | 
|  |    112 |      prefer 2
 | 
|  |    113 |      apply (simp add: boundI deg_aboveD)
 | 
|  |    114 |     prefer 2
 | 
|  |    115 |     apply (simp add: boundI deg_aboveD)
 | 
|  |    116 |   (* getting a^i and a^(k-i) together is difficult, so we do it manually *)
 | 
|  |    117 |   apply (rule_tac s = "setsum (%k. setsum (%i. phi (coeff aa i) * (phi (coeff b (k - i)) * (a ^ i * a ^ (k - i)))) {..k}) {..deg aa + deg b}" in trans)
 | 
|  |    118 |     apply (simp (no_asm_simp) add: power_mult leD [THEN add_diff_inverse] natsum_ldistr)
 | 
|  |    119 |    apply (simp (no_asm))
 | 
|  |    120 |   (* 1 commutes *)
 | 
|  |    121 |   apply (simp (no_asm_simp))
 | 
|  |    122 |   done
 | 
|  |    123 | 
 | 
|  |    124 | lemma EVAL2_const:
 | 
|  |    125 |     "!!phi::'a::ring=>'b::ring. EVAL2 phi a (monom b 0) = phi b"
 | 
|  |    126 |   by (simp add: EVAL2_def)
 | 
|  |    127 | 
 | 
|  |    128 | lemma EVAL2_monom1:
 | 
|  |    129 |     "!! phi::'a::domain=>'b::ring. homo phi ==> EVAL2 phi a (monom 1 1) = a"
 | 
|  |    130 |   by (simp add: EVAL2_def)
 | 
|  |    131 |   (* Must be able to distinguish 0 from 1, hence 'a::domain *)
 | 
|  |    132 | 
 | 
|  |    133 | lemma EVAL2_monom:
 | 
|  |    134 |   "!! phi::'a::domain=>'b::ring. homo phi ==> EVAL2 phi a (monom 1 n) = a ^ n"
 | 
|  |    135 |   apply (unfold EVAL2_def)
 | 
|  |    136 |   apply (simp (no_asm))
 | 
|  |    137 |   apply (case_tac n)
 | 
|  |    138 |    apply auto
 | 
|  |    139 |   done
 | 
|  |    140 | 
 | 
|  |    141 | lemma EVAL2_smult:
 | 
|  |    142 |   "!!phi::'a::ring=>'b::ring.
 | 
|  |    143 |      homo phi ==> EVAL2 phi a (b *s p) = phi b * EVAL2 phi a p"
 | 
|  |    144 |   by (simp (no_asm_simp) add: monom_mult_is_smult [symmetric] EVAL2_homo EVAL2_const)
 | 
|  |    145 | 
 | 
|  |    146 | lemma monom_decomp: "monom (a::'a::ring) n = monom a 0 * monom 1 n"
 | 
|  |    147 |   apply (simp (no_asm) add: monom_mult_is_smult)
 | 
|  |    148 |   apply (rule up_eqI)
 | 
|  |    149 |   apply (simp (no_asm))
 | 
|  |    150 |   done
 | 
|  |    151 | 
 | 
|  |    152 | lemma EVAL2_monom_n:
 | 
|  |    153 |   "!! phi::'a::domain=>'b::ring.
 | 
|  |    154 |      homo phi ==> EVAL2 phi a (monom b n) = phi b * a ^ n"
 | 
|  |    155 |   apply (subst monom_decomp)
 | 
|  |    156 |   apply (simp (no_asm_simp) add: EVAL2_homo EVAL2_const EVAL2_monom)
 | 
|  |    157 |   done
 | 
|  |    158 | 
 | 
|  |    159 | lemma EVAL_homo: "!!a::'a::ring. homo (EVAL a)"
 | 
|  |    160 |   by (simp add: EVAL_def EVAL2_homo)
 | 
|  |    161 | 
 | 
|  |    162 | lemma EVAL_const: "!!a::'a::ring. EVAL a (monom b 0) = b"
 | 
|  |    163 |   by (simp add: EVAL_def EVAL2_const)
 | 
|  |    164 | 
 | 
|  |    165 | lemma EVAL_monom: "!!a::'a::domain. EVAL a (monom 1 n) = a ^ n"
 | 
|  |    166 |   by (simp add: EVAL_def EVAL2_monom)
 | 
|  |    167 | 
 | 
|  |    168 | lemma EVAL_smult: "!!a::'a::ring. EVAL a (b *s p) = b * EVAL a p"
 | 
|  |    169 |   by (simp add: EVAL_def EVAL2_smult)
 | 
|  |    170 | 
 | 
|  |    171 | lemma EVAL_monom_n: "!!a::'a::domain. EVAL a (monom b n) = b * a ^ n"
 | 
|  |    172 |   by (simp add: EVAL_def EVAL2_monom_n)
 | 
|  |    173 | 
 | 
|  |    174 | 
 | 
|  |    175 | (* Examples *)
 | 
|  |    176 | 
 | 
|  |    177 | lemma "EVAL (x::'a::domain) (a*X^2 + b*X^1 + c*X^0) = a * x ^ 2 + b * x ^ 1 + c"
 | 
|  |    178 |   by (simp del: power_Suc add: EVAL_homo EVAL_monom EVAL_monom_n)
 | 
|  |    179 | 
 | 
|  |    180 | lemma
 | 
|  |    181 |   "EVAL (y::'a::domain)
 | 
|  |    182 |     (EVAL (monom x 0) (monom 1 1 + monom (a*X^2 + b*X^1 + c*X^0) 0)) =
 | 
|  |    183 |    x ^ 1 + (a * y ^ 2 + b * y ^ 1 + c)"
 | 
|  |    184 |   by (simp del: power_Suc add: EVAL_homo EVAL_monom EVAL_monom_n EVAL_const)
 | 
| 7998 |    185 | 
 | 
|  |    186 | end
 |