\import Algebra.Meta \import Algebra.Monoid \import Algebra.Ring \import Algebra.Semiring \import Arith.Int \import Arith.Nat \import Data.Array \import Order.StrictOrder \import Paths \open Monoid (pow) \open AddMonoid (BigSum) \func binom (n i : Nat) : Nat | _, 0 => 1 | 0, _ => 0 | suc n, suc i => binom n i + binom n (suc i) \where { \lemma binom_0 {n : Nat} : binom n 0 = 1 \elim n | 0 => idp | suc n => idp \lemma binom_< {n m : Nat} (p : n < m) : binom n m = 0 \elim n, m, p | 0, suc m, _ => idp | suc n, suc m, NatSemiring.suc<suc n<m => pmap2 (+) (binom_< n<m) (binom_< (n<m <∘ id<suc)) \lemma expansion {R : CRing} (x y : R) (n : Nat) : pow (x + y) n = BigSum (\new Array R (suc n) (\lam i => natCoef (binom n i) * (pow x i * pow y (iabs (n Nat.- i))))) \elim n | 0 => equation | suc n => \let | xy i => pow x (suc i) * pow y (iabs (n Nat.- i)) | cxy (i : Fin (suc n)) => natCoef (binom n i) * (pow x i * pow y (iabs (n Nat.- i))) | t1 : pow (x + y) n * x = BigSum (\new Array R (suc n) (\lam i => natCoef (binom n i) * xy i)) => pmap (`* x) (expansion x y n) *> R.BigSum-rdistr {\new Array R.E (suc n) cxy} *> path (\lam j => BigSum (\new Array R (suc n) (\lam i => (equation : cxy i * x = natCoef (binom n i) * xy i) @ j))) | t2 : pow (x + y) n * y = BigSum (\new Array R (suc (suc n)) (\lam i => natCoef (binom n i) * (pow x i * pow y (iabs (suc n Nat.- i))))) => pmap (`* y) (expansion x y n) *> R.BigSum-rdistr {\new Array R (suc n) cxy} *> path (\lam j => BigSum (\new Array R (suc n) (\lam i => ((equation : cxy i * y = natCoef (binom n i) * (pow x i * pow y (suc (iabs (n Nat.- i))))) *> pmap (\lam m => natCoef (binom n i) * (pow x i * pow y m)) (inv (iabs_-_suc (<_suc_<= (fin_< i))))) @ j))) *> inv (pmap (_ +) (pmap (`* _) (pmap natCoef (binom_< (transportInv (n <) (mod_< id<suc) id<suc)) *> natCoefZero) *> zro_*-left) *> zro-right) *> inv (R.BigSum_suc {suc n} {\new Array R (suc (suc n)) (\lam i => natCoef (binom n i) * (pow x i * pow y (iabs (suc n Nat.- i))))}) \in ldistr *> pmap2 (+) t1 (t2 *> pmap (natCoef __ * _ + _) binom_0) *> +-comm *> +-assoc *> pmap (_ +) +-comm *> inv (pmap (_ +) (R.BigSum_+ {suc n} {mkArray (\lam i => natCoef (binom n i) * xy i)} {mkArray (\lam i => natCoef (binom n (suc i)) * xy i)})) *> inv (path (\lam j => _ + BigSum (\new Array R (suc n) (\lam i => (pmap (`* xy i) (Semiring.natCoef_+ (binom n i) (binom n (suc i))) *> rdistr) @ j)))) }