src/HOL/Algebra/abstract/NatSum.ML
changeset 11093 62c2e0af1d30
parent 10962 cda180b1e2e0
equal deleted inserted replaced
11092:69c1abb9a129 11093:62c2e0af1d30
     4     Author: Clemens Ballarin, started 12 December 1996
     4     Author: Clemens Ballarin, started 12 December 1996
     5 *)
     5 *)
     6 
     6 
     7 section "Basic Properties";
     7 section "Basic Properties";
     8 
     8 
     9 Goalw [SUM_def] "SUM 0 f = (f 0::'a::ring)";
     9 Goal "setsum f {..0::nat} = (f 0::'a::ring)";
    10 by (Asm_simp_tac 1);
    10 by (Asm_simp_tac 1);
    11 qed "SUM_0";
    11 qed "SUM_0";
    12 
    12 
    13 Goalw [SUM_def]
    13 Goal "setsum f {..Suc n} = (f (Suc n) + setsum f {..n}::'a::ring)";
    14   "SUM (Suc n) f = (f (Suc n) + SUM n f::'a::ring)";
    14 by (simp_tac (simpset() addsimps [atMost_Suc]) 1);
    15 by (Simp_tac 1);
       
    16 qed "SUM_Suc";
    15 qed "SUM_Suc";
    17 
    16 
    18 Addsimps [SUM_0, SUM_Suc];
    17 Addsimps [SUM_0, SUM_Suc];
    19 
    18 
    20 Goal "SUM (Suc n) f = (SUM n (%i. f (Suc i)) + f 0::'a::ring)";
    19 Goal
       
    20   "setsum f {..Suc n} = (setsum (%i. f (Suc i)) {..n} + f 0::'a::ring)";
    21 by (induct_tac "n" 1);
    21 by (induct_tac "n" 1);
    22 (* Base case *)
    22 (* Base case *)
    23 by (Simp_tac 1);
    23 by (Simp_tac 1);
    24 (* Induction step *)
    24 (* Induction step *)
    25 by (asm_full_simp_tac (simpset() addsimps [a_assoc]) 1);
    25 by (asm_full_simp_tac (simpset() addsimps [a_assoc]) 1);
    26 qed "SUM_Suc2";
    26 qed "SUM_Suc2";
    27 
    27 
    28 (* Congruence rules *)
    28 (* Congruence rules *)
    29 
    29 
    30 Goal "ALL j'. j=j' --> (ALL i. i<=j' --> f i = (f' i :: 'a :: ring)) \
    30 Goal "ALL j'::nat. j=j' --> (ALL i. i<=j' --> f i = (f' i :: 'a :: ring)) \
    31 \     --> SUM j f = SUM j' f'";
    31 \     --> setsum f {..j} = setsum f' {..j'}";
    32 by (induct_tac "j" 1);
    32 by (induct_tac "j" 1);
    33 by Auto_tac;  
    33 by Auto_tac;  
    34 bind_thm ("SUM_cong", (impI RS allI) RSN (2, result() RS spec RS mp RS mp));
    34 bind_thm ("SUM_cong", (impI RS allI) RSN (2, result() RS spec RS mp RS mp));
    35 Addcongs [SUM_cong];
    35 Addcongs [SUM_cong];
    36 
    36 
    37 (* Results needed for the development of polynomials *)
    37 (* Results needed for the development of polynomials *)
    38 
    38 
    39 section "Ring Properties";
    39 section "Ring Properties";
    40 
    40 
    41 Goal "SUM n (%i. <0>) = (<0>::'a::ring)";
    41 Goal "setsum (%i. 0) {..n::nat} = (0::'a::ring)";
    42 by (induct_tac "n" 1);
    42 by (induct_tac "n" 1);
    43 by (Simp_tac 1);
    43 by (Simp_tac 1);
    44 by (Asm_simp_tac 1);
    44 by (Asm_simp_tac 1);
    45 qed "SUM_zero";
    45 qed "SUM_zero";
    46 
    46 
    47 Addsimps [SUM_zero];
    47 Addsimps [SUM_zero];
    48 
    48 
    49 Goal
    49 Goal
    50   "!!f::nat=>'a::ring. SUM n (%i. f i + g i) = SUM n f + SUM n g";
    50   "!!f::nat=>'a::ring. \
       
    51 \  setsum (%i. f i + g i) {..n::nat} = setsum f {..n} + setsum g {..n}";
    51 by (induct_tac "n" 1);
    52 by (induct_tac "n" 1);
    52 (* Base case *)
    53 (* Base case *)
    53 by (Simp_tac 1);
    54 by (Simp_tac 1);
    54 (* Induction step *)
    55 (* Induction step *)
    55 by (asm_simp_tac (simpset() addsimps a_ac) 1);
    56 by (asm_simp_tac (simpset() addsimps a_ac) 1);
    56 qed "SUM_add";
    57 qed "SUM_add";
    57 
    58 
    58 Goal
    59 Goal
    59   "!!a::'a::ring. SUM n f * a = SUM n (%i. f i * a)";
    60   "!!a::'a::ring. setsum f {..n::nat} * a = setsum (%i. f i * a) {..n}";
    60 by (induct_tac "n" 1);
    61 by (induct_tac "n" 1);
    61 (* Base case *)
    62 (* Base case *)
    62 by (Simp_tac 1);
    63 by (Simp_tac 1);
    63 (* Induction step *)
    64 (* Induction step *)
    64 by (asm_simp_tac (simpset() addsimps [l_distr]) 1);
    65 by (asm_simp_tac (simpset() addsimps [l_distr]) 1);
    65 qed "SUM_ldistr";
    66 qed "SUM_ldistr";
    66 
    67 
    67 Goal "!!a::'a::ring. a * SUM n f = SUM n (%i. a * f i)";
    68 Goal
       
    69   "!!a::'a::ring. a * setsum f {..n::nat} = setsum (%i. a * f i) {..n}";
    68 by (induct_tac "n" 1);
    70 by (induct_tac "n" 1);
    69 (* Base case *)
    71 (* Base case *)
    70 by (Simp_tac 1);
    72 by (Simp_tac 1);
    71 (* Induction step *)
    73 (* Induction step *)
    72 by (asm_simp_tac (simpset() addsimps [r_distr]) 1);
    74 by (asm_simp_tac (simpset() addsimps [r_distr]) 1);
    74 
    76 
    75 section "Results for the Construction of Polynomials";
    77 section "Results for the Construction of Polynomials";
    76 
    78 
    77 Goal
    79 Goal
    78   "!!a::nat=>'a::ring. k <= n --> \
    80   "!!a::nat=>'a::ring. k <= n --> \
    79 \  SUM k (%j. SUM j (%i. a i * b (j-i)) * c (n-j)) = \
    81 \  setsum (%j. setsum (%i. a i * b (j-i)) {..j} * c (n-j)) {..k} = \
    80 \  SUM k (%j. a j * SUM (k-j) (%i. b i * c (n-j-i)))";
    82 \  setsum (%j. a j * setsum  (%i. b i * c (n-j-i)) {..k-j}) {..k}";
    81 by (induct_tac "k" 1);
    83 by (induct_tac "k" 1);
    82 (* Base case *)
    84 (* Base case *)
    83 by (simp_tac (simpset() addsimps [m_assoc]) 1);
    85 by (simp_tac (simpset() addsimps [m_assoc]) 1);
    84 (* Induction step *)
    86 (* Induction step *)
    85 by (rtac impI 1);
    87 by (rtac impI 1);
    91 by (asm_simp_tac (simpset() addsimps a_ac@ [SUM_ldistr, m_assoc]) 1);
    93 by (asm_simp_tac (simpset() addsimps a_ac@ [SUM_ldistr, m_assoc]) 1);
    92 qed_spec_mp "poly_assoc_lemma1";
    94 qed_spec_mp "poly_assoc_lemma1";
    93 
    95 
    94 Goal
    96 Goal
    95   "!!a::nat=>'a::ring. \
    97   "!!a::nat=>'a::ring. \
    96 \  SUM n (%j. SUM j (%i. a i * b (j-i)) * c (n-j)) = \
    98 \  setsum (%j. setsum (%i. a i * b (j-i)) {..j} * c (n-j)) {..n} = \
    97 \  SUM n (%j. a j * SUM (n-j) (%i. b i * c (n-(j+i))))";
    99 \  setsum (%j. a j * setsum (%i. b i * c (n-(j+i))) {..n-j}) {..n}";
    98 by (asm_simp_tac (simpset() addsimps [poly_assoc_lemma1]) 1);
   100 by (asm_simp_tac (simpset() addsimps [poly_assoc_lemma1]) 1);
    99 qed "poly_assoc_lemma";
   101 qed "poly_assoc_lemma";
   100 
   102 
   101 Goal
   103 Goal
   102   "!! a::nat=>'a::ring. j <= n --> \
   104   "!! a::nat=>'a::ring. j <= n --> \
   103 \    SUM j (%i. a i * b (n-i)) = SUM j (%i. a (n-i-(n-j)) * b (i+(n-j)))";
   105 \    setsum (%i. a i * b (n-i)) {..j} = \
       
   106 \    setsum (%i. a (n-i-(n-j)) * b (i+(n-j))) {..j}";
   104 by (Simp_tac 1); 
   107 by (Simp_tac 1); 
   105 by (induct_tac "j" 1);
   108 by (induct_tac "j" 1);
   106 (* Base case *)
   109 (* Base case *)
   107 by (Simp_tac 1);
   110 by (Simp_tac 1);
   108 (* Induction step *)
   111 (* Induction step *)
   109 by (stac SUM_Suc2 1);
   112 by (stac SUM_Suc2 1);
   110 by (asm_simp_tac (simpset() addsimps [a_comm]) 1);
   113 by (asm_simp_tac (simpset() addsimps [a_comm]) 1);
   111 qed "poly_comm_lemma1";
   114 qed "poly_comm_lemma1";
   112 
   115 
   113 Goal
   116 Goal
   114  "!!a::nat=>'a::ring. SUM n (%i. a i * b (n-i)) = SUM n (%i. a (n-i) * b i)";
   117  "!!a::nat=>'a::ring. \
       
   118 \   setsum (%i. a i * b (n-i)) {..n} = \
       
   119 \   setsum (%i. a (n-i) * b i) {..n}";
   115 by (cut_inst_tac [("j", "n"), ("n", "n")] poly_comm_lemma1 1);
   120 by (cut_inst_tac [("j", "n"), ("n", "n")] poly_comm_lemma1 1);
   116 by (Asm_full_simp_tac 1);
   121 by (Asm_full_simp_tac 1);
   117 qed "poly_comm_lemma";
   122 qed "poly_comm_lemma";
   118 
   123 
   119 section "Changing the Range of Summation";
   124 section "Changing the Range of Summation";
   120 
   125 
   121 Goal
   126 Goal
   122   "!! f::(nat=>'a::ring). \
   127   "!! f::(nat=>'a::ring). \
   123 \    SUM n (%i. if i = x then f i else <0>) = (if x <= n then f x else <0>)";
   128 \   setsum (%i. if i = x then f i else 0) {..n} = (if x <= n then f x else 0)";
   124 by (induct_tac "n" 1);
   129 by (induct_tac "n" 1);
   125 (* Base case *)
   130 (* Base case *)
   126 by (Simp_tac 1);
   131 by (Simp_tac 1);
   127 (* Induction step *)
   132 (* Induction step *)
   128 by (Asm_simp_tac 1);
   133 by (Asm_simp_tac 1);
   131 by (arith_tac 1);
   136 by (arith_tac 1);
   132 qed "SUM_if_singleton";
   137 qed "SUM_if_singleton";
   133 
   138 
   134 Goal
   139 Goal
   135   "!! f::(nat=>'a::ring). \
   140   "!! f::(nat=>'a::ring). \
   136 \    m <= n & (ALL i. m < i & i <= n --> f i = <0>) --> \
   141 \    m <= n & (ALL i. m < i & i <= n --> f i = 0) --> \
   137 \    SUM m f = SUM n f";
   142 \    setsum f {..m} = setsum f {..n}";
   138 by (induct_tac "n" 1);
   143 by (induct_tac "n" 1);
   139 (* Base case *)
   144 (* Base case *)
   140 by (Simp_tac 1);
   145 by (Simp_tac 1);
   141 (* Induction step *)
   146 (* Induction step *)
   142 by (case_tac "m <= n" 1);
   147 by (case_tac "m <= n" 1);
   146 by (fast_arith_tac 1);
   151 by (fast_arith_tac 1);
   147 val SUM_shrink_lemma = result();
   152 val SUM_shrink_lemma = result();
   148 
   153 
   149 Goal
   154 Goal
   150   "!! f::(nat=>'a::ring). \
   155   "!! f::(nat=>'a::ring). \
   151 \    [| m <= n; !!i. [| m < i; i <= n |] ==> f i = <0>; P (SUM n f) |] ==> \
   156 \    [| m <= n; !!i. [| m < i; i <= n |] ==> f i = 0; P (setsum f {..n}) |] \
   152 \      P (SUM m f)";
   157 \  ==> P (setsum f {..m})";
   153 by (cut_inst_tac [("m", "m"), ("n", "n"), ("f", "f")] SUM_shrink_lemma 1);
   158 by (cut_inst_tac [("m", "m"), ("n", "n"), ("f", "f")] SUM_shrink_lemma 1);
   154 by (Asm_full_simp_tac 1);
   159 by (Asm_full_simp_tac 1);
   155 qed "SUM_shrink";
   160 qed "SUM_shrink";
   156 
   161 
   157 Goal
   162 Goal
   158   "!! f::(nat=>'a::ring). \
   163   "!! f::(nat=>'a::ring). \
   159 \    [| m <= n; !!i. [| m < i; i <= n |] ==> f i = <0>; P (SUM m f) |] ==> \
   164 \    [| m <= n; !!i. [| m < i; i <= n |] ==> f i = 0; P (setsum f {..m}) |] \
   160 \      P (SUM n f)";
   165 \    ==> P (setsum f {..n})";
   161 by (cut_inst_tac [("m", "m"), ("n", "n"), ("f", "f")] SUM_shrink_lemma 1);
   166 by (cut_inst_tac [("m", "m"), ("n", "n"), ("f", "f")] SUM_shrink_lemma 1);
   162 by (Asm_full_simp_tac 1);
   167 by (Asm_full_simp_tac 1);
   163 qed "SUM_extend";
   168 qed "SUM_extend";
   164 
   169 
   165 Goal
   170 Goal
   166   "!! f::(nat=>'a::ring). \
   171   "!! f::(nat=>'a::ring). \
   167 \    (ALL i. i < m --> f i = <0>) --> SUM d (%i. f (i+m)) = SUM (m+d) f";
   172 \    (ALL i. i < m --> f i = 0) --> \
       
   173 \      setsum (%i. f (i+m)) {..d} = setsum f {..m+d}";
   168 by (induct_tac "d" 1);
   174 by (induct_tac "d" 1);
   169 (* Base case *)
   175 (* Base case *)
   170 by (induct_tac "m" 1);
   176 by (induct_tac "m" 1);
   171 by (Simp_tac 1);
   177 by (Simp_tac 1);
   172 by (Force_tac 1);
   178 by (Force_tac 1);
   174 by (asm_simp_tac (simpset() addsimps add_ac) 1);
   180 by (asm_simp_tac (simpset() addsimps add_ac) 1);
   175 val SUM_shrink_below_lemma = result();
   181 val SUM_shrink_below_lemma = result();
   176 
   182 
   177 Goal
   183 Goal
   178   "!! f::(nat=>'a::ring). \
   184   "!! f::(nat=>'a::ring). \
   179 \    [| m <= n; !!i. i < m ==> f i = <0>; P (SUM (n-m) (%i. f (i+m))) |] ==> \
   185 \    [| m <= n; !!i. i < m ==> f i = 0; P (setsum (%i. f (i+m)) {..n-m}) |] \
   180 \    P (SUM n f)";
   186 \    ==> P (setsum f {..n})";
   181 by (asm_full_simp_tac 
   187 by (asm_full_simp_tac 
   182     (simpset() addsimps [SUM_shrink_below_lemma, add_diff_inverse, leD]) 1);
   188     (simpset() addsimps [SUM_shrink_below_lemma, add_diff_inverse, leD]) 1);
   183 qed "SUM_extend_below";
   189 qed "SUM_extend_below";
   184 
   190 
   185 section "Result for the Univeral Property of Polynomials";
   191 section "Result for the Univeral Property of Polynomials";
   186 
   192 
   187 Goal
   193 Goal
   188   "!!f::nat=>'a::ring. j <= n + m --> \
   194   "!!f::nat=>'a::ring. j <= n + m --> \
   189 \    SUM j (%k. SUM k (%i. f i * g (k - i))) = \
   195 \    setsum (%k. setsum (%i. f i * g (k - i)) {..k}) {..j} = \
   190 \    SUM j (%k. SUM (j - k) (%i. f k * g i))";
   196 \    setsum (%k. setsum (%i. f k * g i) {..j - k}) {..j}";
   191 by (induct_tac "j" 1);
   197 by (induct_tac "j" 1);
   192 (* Base case *)
   198 (* Base case *)
   193 by (Simp_tac 1);
   199 by (Simp_tac 1);
   194 (* Induction step *)
   200 (* Induction step *)
   195 by (simp_tac (simpset() addsimps [Suc_diff_le, SUM_add]) 1);
   201 by (simp_tac (simpset() addsimps [Suc_diff_le, SUM_add]) 1);
   196 by (asm_simp_tac (simpset() addsimps a_ac) 1);
   202 by (asm_simp_tac (simpset() addsimps a_ac) 1);
   197 val DiagSum_lemma = result();
   203 val DiagSum_lemma = result();
   198 
   204 
   199 Goal
   205 Goal
   200   "!!f::nat=>'a::ring. \
   206   "!!f::nat=>'a::ring. \
   201 \    SUM (n + m) (%k. SUM k (%i. f i * g (k - i))) = \
   207 \    setsum (%k. setsum (%i. f i * g (k - i)) {..k}) {..n + m} = \
   202 \    SUM (n + m) (%k. SUM (n + m - k) (%i. f k * g i))";
   208 \    setsum (%k. setsum (%i. f k * g i) {..n + m - k}) {..n + m}";
   203 by (rtac (DiagSum_lemma RS mp) 1);
   209 by (rtac (DiagSum_lemma RS mp) 1);
   204 by (rtac le_refl 1);
   210 by (rtac le_refl 1);
   205 qed "DiagSum";
   211 qed "DiagSum";
   206 
   212 
   207 
   213