1309 with assms have "g mod f = 0" |
1329 with assms have "g mod f = 0" |
1310 by (simp add: fps_mod_def Let_def fps_cutoff_zero_iff) |
1330 by (simp add: fps_mod_def Let_def fps_cutoff_zero_iff) |
1311 thus "f dvd g" by (simp add: dvd_eq_mod_eq_0) |
1331 thus "f dvd g" by (simp add: dvd_eq_mod_eq_0) |
1312 qed (simp add: assms dvd_imp_subdegree_le) |
1332 qed (simp add: assms dvd_imp_subdegree_le) |
1313 |
1333 |
|
1334 lemma fps_shift_altdef: |
|
1335 "fps_shift n f = (f :: 'a :: field fps) div X^n" |
|
1336 by (simp add: fps_divide_def) |
|
1337 |
|
1338 lemma fps_div_X_power_nth: "((f :: 'a :: field fps) div X^n) $ k = f $ (k + n)" |
|
1339 by (simp add: fps_shift_altdef [symmetric]) |
|
1340 |
|
1341 lemma fps_div_X_nth: "((f :: 'a :: field fps) div X) $ k = f $ Suc k" |
|
1342 using fps_div_X_power_nth[of f 1] by simp |
|
1343 |
1314 lemma fps_const_inverse: "inverse (fps_const (a::'a::field)) = fps_const (inverse a)" |
1344 lemma fps_const_inverse: "inverse (fps_const (a::'a::field)) = fps_const (inverse a)" |
1315 by (cases "a \<noteq> 0", rule fps_inverse_unique) (auto simp: fps_eq_iff) |
1345 by (cases "a \<noteq> 0", rule fps_inverse_unique) (auto simp: fps_eq_iff) |
1316 |
1346 |
1317 lemma fps_const_divide: "fps_const (x :: _ :: field) / fps_const y = fps_const (x / y)" |
1347 lemma fps_const_divide: "fps_const (x :: _ :: field) / fps_const y = fps_const (x / y)" |
1318 by (cases "y = 0") (simp_all add: fps_divide_unit fps_const_inverse divide_inverse) |
1348 by (cases "y = 0") (simp_all add: fps_divide_unit fps_const_inverse divide_inverse) |
1319 |
1349 |
1320 lemma inverse_fps_numeral: |
1350 lemma inverse_fps_numeral: |
1321 "inverse (numeral n :: ('a :: field_char_0) fps) = fps_const (inverse (numeral n))" |
1351 "inverse (numeral n :: ('a :: field_char_0) fps) = fps_const (inverse (numeral n))" |
1322 by (intro fps_inverse_unique fps_ext) (simp_all add: fps_numeral_nth) |
1352 by (intro fps_inverse_unique fps_ext) (simp_all add: fps_numeral_nth) |
1323 |
1353 |
|
1354 lemma fps_numeral_divide_divide: |
|
1355 "x / numeral b / numeral c = (x / numeral (b * c) :: 'a :: field fps)" |
|
1356 by (cases "numeral b = (0::'a)"; cases "numeral c = (0::'a)") |
|
1357 (simp_all add: fps_divide_unit fps_inverse_mult [symmetric] numeral_fps_const numeral_mult |
|
1358 del: numeral_mult [symmetric]) |
|
1359 |
|
1360 lemma fps_numeral_mult_divide: |
|
1361 "numeral b * x / numeral c = (numeral b / numeral c * x :: 'a :: field fps)" |
|
1362 by (cases "numeral c = (0::'a)") (simp_all add: fps_divide_unit numeral_fps_const) |
|
1363 |
|
1364 lemmas fps_numeral_simps = |
|
1365 fps_numeral_divide_divide fps_numeral_mult_divide inverse_fps_numeral neg_numeral_fps_const |
1324 |
1366 |
1325 |
1367 |
1326 |
1368 |
1327 instantiation fps :: (field) normalization_semidom |
1369 instantiation fps :: (field) normalization_semidom |
1328 begin |
1370 begin |
2305 also have "\<dots> = (a$0) ^ m" |
2365 also have "\<dots> = (a$0) ^ m" |
2306 unfolding c by (rule setprod_constant) |
2366 unfolding c by (rule setprod_constant) |
2307 finally show ?thesis . |
2367 finally show ?thesis . |
2308 qed |
2368 qed |
2309 |
2369 |
|
2370 lemma natpermute_max_card: |
|
2371 assumes n0: "n \<noteq> 0" |
|
2372 shows "card {xs \<in> natpermute n (k + 1). n \<in> set xs} = k + 1" |
|
2373 unfolding natpermute_contain_maximal |
|
2374 proof - |
|
2375 let ?A = "\<lambda>i. {replicate (k + 1) 0[i := n]}" |
|
2376 let ?K = "{0 ..k}" |
|
2377 have fK: "finite ?K" |
|
2378 by simp |
|
2379 have fAK: "\<forall>i\<in>?K. finite (?A i)" |
|
2380 by auto |
|
2381 have d: "\<forall>i\<in> ?K. \<forall>j\<in> ?K. i \<noteq> j \<longrightarrow> |
|
2382 {replicate (k + 1) 0[i := n]} \<inter> {replicate (k + 1) 0[j := n]} = {}" |
|
2383 proof clarify |
|
2384 fix i j |
|
2385 assume i: "i \<in> ?K" and j: "j \<in> ?K" and ij: "i \<noteq> j" |
|
2386 have False if eq: "replicate (k+1) 0 [i:=n] = replicate (k+1) 0 [j:= n]" |
|
2387 proof - |
|
2388 have "(replicate (k+1) 0 [i:=n] ! i) = n" |
|
2389 using i by (simp del: replicate.simps) |
|
2390 moreover |
|
2391 have "(replicate (k+1) 0 [j:=n] ! i) = 0" |
|
2392 using i ij by (simp del: replicate.simps) |
|
2393 ultimately show ?thesis |
|
2394 using eq n0 by (simp del: replicate.simps) |
|
2395 qed |
|
2396 then show "{replicate (k + 1) 0[i := n]} \<inter> {replicate (k + 1) 0[j := n]} = {}" |
|
2397 by auto |
|
2398 qed |
|
2399 from card_UN_disjoint[OF fK fAK d] |
|
2400 show "card (\<Union>i\<in>{0..k}. {replicate (k + 1) 0[i := n]}) = k + 1" |
|
2401 by simp |
|
2402 qed |
|
2403 |
|
2404 lemma fps_power_Suc_nth: |
|
2405 fixes f :: "'a :: comm_ring_1 fps" |
|
2406 assumes k: "k > 0" |
|
2407 shows "(f ^ Suc m) $ k = |
|
2408 of_nat (Suc m) * (f $ k * (f $ 0) ^ m) + |
|
2409 (\<Sum>v\<in>{v\<in>natpermute k (m+1). k \<notin> set v}. \<Prod>j = 0..m. f $ v ! j)" |
|
2410 proof - |
|
2411 define A B |
|
2412 where "A = {v\<in>natpermute k (m+1). k \<in> set v}" |
|
2413 and "B = {v\<in>natpermute k (m+1). k \<notin> set v}" |
|
2414 have [simp]: "finite A" "finite B" "A \<inter> B = {}" by (auto simp: A_def B_def natpermute_finite) |
|
2415 |
|
2416 from natpermute_max_card[of k m] k have card_A: "card A = m + 1" by (simp add: A_def) |
|
2417 { |
|
2418 fix v assume v: "v \<in> A" |
|
2419 from v have [simp]: "length v = Suc m" by (simp add: A_def natpermute_def) |
|
2420 from v have "\<exists>j. j \<le> m \<and> v ! j = k" |
|
2421 by (auto simp: set_conv_nth A_def natpermute_def less_Suc_eq_le) |
|
2422 then guess j by (elim exE conjE) note j = this |
|
2423 |
|
2424 from v have "k = listsum v" by (simp add: A_def natpermute_def) |
|
2425 also have "\<dots> = (\<Sum>i=0..m. v ! i)" |
|
2426 by (simp add: listsum_setsum_nth atLeastLessThanSuc_atLeastAtMost del: setsum_op_ivl_Suc) |
|
2427 also from j have "{0..m} = insert j ({0..m}-{j})" by auto |
|
2428 also from j have "(\<Sum>i\<in>\<dots>. v ! i) = k + (\<Sum>i\<in>{0..m}-{j}. v ! i)" |
|
2429 by (subst setsum.insert) simp_all |
|
2430 finally have "(\<Sum>i\<in>{0..m}-{j}. v ! i) = 0" by simp |
|
2431 hence zero: "v ! i = 0" if "i \<in> {0..m}-{j}" for i using that |
|
2432 by (subst (asm) setsum_eq_0_iff) auto |
|
2433 |
|
2434 from j have "{0..m} = insert j ({0..m} - {j})" by auto |
|
2435 also from j have "(\<Prod>i\<in>\<dots>. f $ (v ! i)) = f $ k * (\<Prod>i\<in>{0..m} - {j}. f $ (v ! i))" |
|
2436 by (subst setprod.insert) auto |
|
2437 also have "(\<Prod>i\<in>{0..m} - {j}. f $ (v ! i)) = (\<Prod>i\<in>{0..m} - {j}. f $ 0)" |
|
2438 by (intro setprod.cong) (simp_all add: zero) |
|
2439 also from j have "\<dots> = (f $ 0) ^ m" by (subst setprod_constant) simp_all |
|
2440 finally have "(\<Prod>j = 0..m. f $ (v ! j)) = f $ k * (f $ 0) ^ m" . |
|
2441 } note A = this |
|
2442 |
|
2443 have "(f ^ Suc m) $ k = (\<Sum>v\<in>natpermute k (m + 1). \<Prod>j = 0..m. f $ v ! j)" |
|
2444 by (rule fps_power_nth_Suc) |
|
2445 also have "natpermute k (m+1) = A \<union> B" unfolding A_def B_def by blast |
|
2446 also have "(\<Sum>v\<in>\<dots>. \<Prod>j = 0..m. f $ (v ! j)) = |
|
2447 (\<Sum>v\<in>A. \<Prod>j = 0..m. f $ (v ! j)) + (\<Sum>v\<in>B. \<Prod>j = 0..m. f $ (v ! j))" |
|
2448 by (intro setsum.union_disjoint) simp_all |
|
2449 also have "(\<Sum>v\<in>A. \<Prod>j = 0..m. f $ (v ! j)) = of_nat (Suc m) * (f $ k * (f $ 0) ^ m)" |
|
2450 by (simp add: A card_A) |
|
2451 finally show ?thesis by (simp add: B_def) |
|
2452 qed |
|
2453 |
|
2454 lemma fps_power_Suc_eqD: |
|
2455 fixes f g :: "'a :: {idom,semiring_char_0} fps" |
|
2456 assumes "f ^ Suc m = g ^ Suc m" "f $ 0 = g $ 0" "f $ 0 \<noteq> 0" |
|
2457 shows "f = g" |
|
2458 proof (rule fps_ext) |
|
2459 fix k :: nat |
|
2460 show "f $ k = g $ k" |
|
2461 proof (induction k rule: less_induct) |
|
2462 case (less k) |
|
2463 show ?case |
|
2464 proof (cases "k = 0") |
|
2465 case False |
|
2466 let ?h = "\<lambda>f. (\<Sum>v | v \<in> natpermute k (m + 1) \<and> k \<notin> set v. \<Prod>j = 0..m. f $ v ! j)" |
|
2467 from False fps_power_Suc_nth[of k f m] fps_power_Suc_nth[of k g m] |
|
2468 have "f $ k * (of_nat (Suc m) * (f $ 0) ^ m) + ?h f = |
|
2469 g $ k * (of_nat (Suc m) * (f $ 0) ^ m) + ?h g" using assms |
|
2470 by (simp add: mult_ac del: power_Suc of_nat_Suc) |
|
2471 also have "v ! i < k" if "v \<in> {v\<in>natpermute k (m+1). k \<notin> set v}" "i \<le> m" for v i |
|
2472 using that elem_le_listsum_nat[of i v] unfolding natpermute_def |
|
2473 by (auto simp: set_conv_nth dest!: spec[of _ i]) |
|
2474 hence "?h f = ?h g" |
|
2475 by (intro setsum.cong refl setprod.cong less lessI) (auto simp: natpermute_def) |
|
2476 finally have "f $ k * (of_nat (Suc m) * (f $ 0) ^ m) = g $ k * (of_nat (Suc m) * (f $ 0) ^ m)" |
|
2477 by simp |
|
2478 with assms show "f $ k = g $ k" |
|
2479 by (subst (asm) mult_right_cancel) (auto simp del: of_nat_Suc) |
|
2480 qed (simp_all add: assms) |
|
2481 qed |
|
2482 qed |
|
2483 |
|
2484 lemma fps_power_Suc_eqD': |
|
2485 fixes f g :: "'a :: {idom,semiring_char_0} fps" |
|
2486 assumes "f ^ Suc m = g ^ Suc m" "f $ subdegree f = g $ subdegree g" |
|
2487 shows "f = g" |
|
2488 proof (cases "f = 0") |
|
2489 case False |
|
2490 have "Suc m * subdegree f = subdegree (f ^ Suc m)" |
|
2491 by (rule subdegree_power [symmetric]) |
|
2492 also have "f ^ Suc m = g ^ Suc m" by fact |
|
2493 also have "subdegree \<dots> = Suc m * subdegree g" by (rule subdegree_power) |
|
2494 finally have [simp]: "subdegree f = subdegree g" |
|
2495 by (subst (asm) Suc_mult_cancel1) |
|
2496 have "fps_shift (subdegree f) f * X ^ subdegree f = f" |
|
2497 by (rule subdegree_decompose [symmetric]) |
|
2498 also have "\<dots> ^ Suc m = g ^ Suc m" by fact |
|
2499 also have "g = fps_shift (subdegree g) g * X ^ subdegree g" |
|
2500 by (rule subdegree_decompose) |
|
2501 also have "subdegree f = subdegree g" by fact |
|
2502 finally have "fps_shift (subdegree g) f ^ Suc m = fps_shift (subdegree g) g ^ Suc m" |
|
2503 by (simp add: algebra_simps power_mult_distrib del: power_Suc) |
|
2504 hence "fps_shift (subdegree g) f = fps_shift (subdegree g) g" |
|
2505 by (rule fps_power_Suc_eqD) (insert assms False, auto) |
|
2506 with subdegree_decompose[of f] subdegree_decompose[of g] show ?thesis by simp |
|
2507 qed (insert assms, simp_all) |
|
2508 |
|
2509 lemma fps_power_eqD': |
|
2510 fixes f g :: "'a :: {idom,semiring_char_0} fps" |
|
2511 assumes "f ^ m = g ^ m" "f $ subdegree f = g $ subdegree g" "m > 0" |
|
2512 shows "f = g" |
|
2513 using fps_power_Suc_eqD'[of f "m-1" g] assms by simp |
|
2514 |
|
2515 lemma fps_power_eqD: |
|
2516 fixes f g :: "'a :: {idom,semiring_char_0} fps" |
|
2517 assumes "f ^ m = g ^ m" "f $ 0 = g $ 0" "f $ 0 \<noteq> 0" "m > 0" |
|
2518 shows "f = g" |
|
2519 by (rule fps_power_eqD'[of f m g]) (insert assms, simp_all) |
|
2520 |
2310 lemma fps_compose_inj_right: |
2521 lemma fps_compose_inj_right: |
2311 assumes a0: "a$0 = (0::'a::idom)" |
2522 assumes a0: "a$0 = (0::'a::idom)" |
2312 and a1: "a$1 \<noteq> 0" |
2523 and a1: "a$1 \<noteq> 0" |
2313 shows "(b oo a = c oo a) \<longleftrightarrow> b = c" |
2524 shows "(b oo a = c oo a) \<longleftrightarrow> b = c" |
2314 (is "?lhs \<longleftrightarrow>?rhs") |
2525 (is "?lhs \<longleftrightarrow>?rhs") |
2438 done |
2649 done |
2439 also have "\<dots> = a$0" |
2650 also have "\<dots> = a$0" |
2440 using r Suc by (simp add: setprod_constant) |
2651 using r Suc by (simp add: setprod_constant) |
2441 finally show ?thesis |
2652 finally show ?thesis |
2442 using Suc by simp |
2653 using Suc by simp |
2443 qed |
|
2444 |
|
2445 lemma natpermute_max_card: |
|
2446 assumes n0: "n \<noteq> 0" |
|
2447 shows "card {xs \<in> natpermute n (k + 1). n \<in> set xs} = k + 1" |
|
2448 unfolding natpermute_contain_maximal |
|
2449 proof - |
|
2450 let ?A = "\<lambda>i. {replicate (k + 1) 0[i := n]}" |
|
2451 let ?K = "{0 ..k}" |
|
2452 have fK: "finite ?K" |
|
2453 by simp |
|
2454 have fAK: "\<forall>i\<in>?K. finite (?A i)" |
|
2455 by auto |
|
2456 have d: "\<forall>i\<in> ?K. \<forall>j\<in> ?K. i \<noteq> j \<longrightarrow> |
|
2457 {replicate (k + 1) 0[i := n]} \<inter> {replicate (k + 1) 0[j := n]} = {}" |
|
2458 proof clarify |
|
2459 fix i j |
|
2460 assume i: "i \<in> ?K" and j: "j \<in> ?K" and ij: "i \<noteq> j" |
|
2461 have False if eq: "replicate (k+1) 0 [i:=n] = replicate (k+1) 0 [j:= n]" |
|
2462 proof - |
|
2463 have "(replicate (k+1) 0 [i:=n] ! i) = n" |
|
2464 using i by (simp del: replicate.simps) |
|
2465 moreover |
|
2466 have "(replicate (k+1) 0 [j:=n] ! i) = 0" |
|
2467 using i ij by (simp del: replicate.simps) |
|
2468 ultimately show ?thesis |
|
2469 using eq n0 by (simp del: replicate.simps) |
|
2470 qed |
|
2471 then show "{replicate (k + 1) 0[i := n]} \<inter> {replicate (k + 1) 0[j := n]} = {}" |
|
2472 by auto |
|
2473 qed |
|
2474 from card_UN_disjoint[OF fK fAK d] |
|
2475 show "card (\<Union>i\<in>{0..k}. {replicate (k + 1) 0[i := n]}) = k + 1" |
|
2476 by simp |
|
2477 qed |
2654 qed |
2478 |
2655 |
2479 lemma power_radical: |
2656 lemma power_radical: |
2480 fixes a:: "'a::field_char_0 fps" |
2657 fixes a:: "'a::field_char_0 fps" |
2481 assumes a0: "a$0 \<noteq> 0" |
2658 assumes a0: "a$0 \<noteq> 0" |
3780 have eq: "inverse ?r $ 0 = 1" |
3980 have eq: "inverse ?r $ 0 = 1" |
3781 by (simp add: fps_inverse_def) |
3981 by (simp add: fps_inverse_def) |
3782 from iffD1[OF fps_binomial_ODE_unique[of "inverse (1 + X)" "- 1"] th'] eq |
3982 from iffD1[OF fps_binomial_ODE_unique[of "inverse (1 + X)" "- 1"] th'] eq |
3783 show ?thesis by (simp add: fps_inverse_def) |
3983 show ?thesis by (simp add: fps_inverse_def) |
3784 qed |
3984 qed |
|
3985 |
|
3986 lemma fps_binomial_of_nat: "fps_binomial (of_nat n) = (1 + X :: 'a :: field_char_0 fps) ^ n" |
|
3987 proof (cases "n = 0") |
|
3988 case [simp]: True |
|
3989 have "fps_deriv ((1 + X) ^ n :: 'a fps) = 0" by simp |
|
3990 also have "\<dots> = fps_const (of_nat n) * (1 + X) ^ n / (1 + X)" by (simp add: fps_binomial_def) |
|
3991 finally show ?thesis by (subst sym, subst fps_binomial_ODE_unique' [symmetric]) simp_all |
|
3992 next |
|
3993 case False |
|
3994 have "fps_deriv ((1 + X) ^ n :: 'a fps) = fps_const (of_nat n) * (1 + X) ^ (n - 1)" |
|
3995 by (simp add: fps_deriv_power) |
|
3996 also have "(1 + X :: 'a fps) $ 0 \<noteq> 0" by simp |
|
3997 hence "(1 + X :: 'a fps) \<noteq> 0" by (intro notI) (simp only: , simp) |
|
3998 with False have "(1 + X :: 'a fps) ^ (n - 1) = (1 + X) ^ n / (1 + X)" |
|
3999 by (cases n) (simp_all ) |
|
4000 also have "fps_const (of_nat n :: 'a) * ((1 + X) ^ n / (1 + X)) = |
|
4001 fps_const (of_nat n) * (1 + X) ^ n / (1 + X)" |
|
4002 by (simp add: unit_div_mult_swap) |
|
4003 finally show ?thesis |
|
4004 by (subst sym, subst fps_binomial_ODE_unique' [symmetric]) (simp_all add: fps_power_nth) |
|
4005 qed |
|
4006 |
|
4007 lemma fps_binomial_0 [simp]: "fps_binomial 0 = 1" |
|
4008 using fps_binomial_of_nat[of 0] by simp |
|
4009 |
|
4010 lemma fps_binomial_power: "fps_binomial a ^ n = fps_binomial (of_nat n * a)" |
|
4011 by (induction n) (simp_all add: fps_binomial_add_mult ring_distribs) |
|
4012 |
|
4013 lemma fps_binomial_1: "fps_binomial 1 = 1 + X" |
|
4014 using fps_binomial_of_nat[of 1] by simp |
|
4015 |
|
4016 lemma fps_binomial_minus_of_nat: |
|
4017 "fps_binomial (- of_nat n) = inverse ((1 + X :: 'a :: field_char_0 fps) ^ n)" |
|
4018 by (rule sym, rule fps_inverse_unique) |
|
4019 (simp add: fps_binomial_of_nat [symmetric] fps_binomial_add_mult [symmetric]) |
|
4020 |
|
4021 lemma one_minus_const_X_power: |
|
4022 "c \<noteq> 0 \<Longrightarrow> (1 - fps_const c * X) ^ n = |
|
4023 fps_compose (fps_binomial (of_nat n)) (-fps_const c * X)" |
|
4024 by (subst fps_binomial_of_nat) |
|
4025 (simp add: fps_compose_power [symmetric] fps_compose_add_distrib fps_const_neg [symmetric] |
|
4026 del: fps_const_neg) |
|
4027 |
|
4028 lemma one_minus_X_const_neg_power: |
|
4029 "inverse ((1 - fps_const c * X) ^ n) = |
|
4030 fps_compose (fps_binomial (-of_nat n)) (-fps_const c * X)" |
|
4031 proof (cases "c = 0") |
|
4032 case False |
|
4033 thus ?thesis |
|
4034 by (subst fps_binomial_minus_of_nat) |
|
4035 (simp add: fps_compose_power [symmetric] fps_inverse_compose fps_compose_add_distrib |
|
4036 fps_const_neg [symmetric] del: fps_const_neg) |
|
4037 qed simp |
|
4038 |
|
4039 lemma X_plus_const_power: |
|
4040 "c \<noteq> 0 \<Longrightarrow> (X + fps_const c) ^ n = |
|
4041 fps_const (c^n) * fps_compose (fps_binomial (of_nat n)) (fps_const (inverse c) * X)" |
|
4042 by (subst fps_binomial_of_nat) |
|
4043 (simp add: fps_compose_power [symmetric] fps_binomial_of_nat fps_compose_add_distrib |
|
4044 fps_const_power [symmetric] power_mult_distrib [symmetric] |
|
4045 algebra_simps inverse_mult_eq_1' del: fps_const_power) |
|
4046 |
|
4047 lemma X_plus_const_neg_power: |
|
4048 "c \<noteq> 0 \<Longrightarrow> inverse ((X + fps_const c) ^ n) = |
|
4049 fps_const (inverse c^n) * fps_compose (fps_binomial (-of_nat n)) (fps_const (inverse c) * X)" |
|
4050 by (subst fps_binomial_minus_of_nat) |
|
4051 (simp add: fps_compose_power [symmetric] fps_binomial_of_nat fps_compose_add_distrib |
|
4052 fps_const_power [symmetric] power_mult_distrib [symmetric] fps_inverse_compose |
|
4053 algebra_simps fps_const_inverse [symmetric] fps_inverse_mult [symmetric] |
|
4054 fps_inverse_power [symmetric] inverse_mult_eq_1' |
|
4055 del: fps_const_power) |
|
4056 |
|
4057 |
|
4058 lemma one_minus_const_X_neg_power': |
|
4059 "n > 0 \<Longrightarrow> inverse ((1 - fps_const (c :: 'a :: field_char_0) * X) ^ n) = |
|
4060 Abs_fps (\<lambda>k. of_nat ((n + k - 1) choose k) * c^k)" |
|
4061 apply (rule fps_ext) |
|
4062 apply (subst one_minus_X_const_neg_power, subst fps_const_neg, subst fps_compose_linear) |
|
4063 apply (simp add: power_mult_distrib [symmetric] mult.assoc [symmetric] |
|
4064 gbinomial_minus binomial_gbinomial of_nat_diff) |
|
4065 done |
3785 |
4066 |
3786 text \<open>Vandermonde's Identity as a consequence.\<close> |
4067 text \<open>Vandermonde's Identity as a consequence.\<close> |
3787 lemma gbinomial_Vandermonde: |
4068 lemma gbinomial_Vandermonde: |
3788 "setsum (\<lambda>k. (a gchoose k) * (b gchoose (n - k))) {0..n} = (a + b) gchoose n" |
4069 "setsum (\<lambda>k. (a gchoose k) * (b gchoose (n - k))) {0..n} = (a + b) gchoose n" |
3789 proof - |
4070 proof - |