2QLPCGXFMHV6EF5SVXUQ4UVVVH55XMJAMMNA64IK3J7QD3ZIZO5QC addcomm : {x,y:Poly} -> (x + y = y + x)addcomm {x = []} = sym $ addzero'addcomm {y = []} = addzero'addcomm {x=(x::_), y=(y::_)} =eqList (plusCommutative x y) (addcomm)
addcomm : (x,y:Poly) -> x + y = y + xaddcomm [] y = sym $ addzero' yaddcomm x [] = addzero' xaddcomm (x::xs) (y::ys) =rewrite plusCommutative x y inrewrite addcomm xs ys in Refl
addassoc : {x,y,z:Poly} -> ((x + y) + z = x + (y + z))addassoc {x = []} = Refladdassoc {y = []} = rewrite addzero' in Refladdassoc {z = []} = trans (addzero') $ cong (x + ) (sym $ addzero')addassoc {x=(x::_), y=(y::_), z=(z::_)} =eqList (sym $ (plusAssociative x y z)) $ addassoc
addassoc : (x,y,z:Poly) -> (x + y) + z = x + (y + z)addassoc [] y z = Refladdassoc x [] z = rewrite addzero' x in Refladdassoc x y [] = rewrite addzero' (x+y) in rewrite addzero' y in Refladdassoc (x::xs) (y::ys) (z::zs) =rewrite plusAssociative x y z inrewrite addassoc xs ys zs inRefl
mulone : {x:Poly} -> ([1] * x = x)mulone {x = []} = Reflmulone {x = (x :: xs)} = eqList (plusZeroRightNeutral x) $trans (cong (+ []) mulone) addzero'
mulone : (x:Poly) -> [1] * x = xmulone [] = Reflmulone (x :: xs) =rewrite plusZeroRightNeutral x inrewrite mulone xs inrewrite addzero' xs in Refl
eqadd : (Num ty) => {a,b,c,d:ty} -> a=c -> b=d -> a+b=c+deqadd Refl Refl = Refl
eqadd : (a,b,c,d:Poly) -> (a + b) + (c + d) = (a + c) + (b + d)eqadd a b c d =rewrite addassoc a b (c + d) inrewrite addassoc a c (b + d) inrewrite sym $ addassoc b c d inrewrite sym $ addassoc c b d inrewrite addcomm b c in Refl
eqadd2 : {a,b,c,d:Poly} -> ((a+b)+(c+d) = (a+c)+(b+d))eqadd2 = trans addassoc$ trans (cong (a+)$ trans (sym addassoc)$ trans (cong (+d) addcomm) addassoc)$ sym addassoc
public exportdist : (x,y,z:Poly) -> x * (y + z) = x * y + x * zdist [] _ _ = Refldist x [] z = rewrite mulzero' x in Refldist x y [] =rewrite mulzero' x inrewrite addzero' y inrewrite addzero' (x * y) in Refldist (x::xs) (y::ys) (z::zs) =rewrite multDistributesOverPlusRight x y z inrewrite dist xs (y::ys) (z::zs) inrewrite dist [x] ys zs inrewrite eqadd ([x] * ys) ([x] * zs) (xs * (y::ys)) (xs * (z::zs)) inRefl
dist : {x,y,z:Poly} -> (x*(y+z) = x*y+ x*z)dist {x = []} = Refldist {y = []} = cong (+ (x * z)) $ sym $ mulzero'dist {z = []} =trans (cong (x * ) addzero')$ trans (sym addzero')$ cong (x * y + ) $ sym mulzero'dist {x = [x], y = (y :: ys), z = (z :: zs)} =eqList (multDistributesOverPlusRight x y z)$ trans addzero' $ trans dist$ sym $ eqadd addzero' addzero'dist {x = (x::xs), y = (y::ys), z = (z::zs)} =eqList (multDistributesOverPlusRight x y z)$ trans (eqadd dist dist)$ eqadd2
mulcomm : (x,y:Poly) -> x * y = y * x
mulcomm' : (x,y:Poly) -> (x * y = y * x)mulcomm' [] _ = sym mulzero'mulcomm' _ [] = mulzero'mulcomm' [x] (y::ys) =eqList (multCommutative x y)$ trans addzero' (mulcomm' [x] ys)mulcomm' (x :: xx :: xs) [y] = sym $ mulcomm' [y] (x :: xx :: xs)mulcomm' (x :: xx :: xs) (y :: yy :: ys) =eqList (multCommutative x y)$ trans (eqadd (mulcomm' [x] (yy::ys)) (mulcomm' (xx::xs) (y :: yy :: ys)))$ trans (eqList (trans (plusCommutative (yy * x) (y * xx))$ eqadd (multCommutative y xx)$ multCommutative yy x)$ trans (sym addassoc)$ trans (eqadd (trans addcomm $ eqadd (mulcomm' [y] xs) (mulcomm' ys [x]))$ mulcomm' (yy::ys) (xx::xs))$ addassoc)$ sym $ eqadd (mulcomm' [y] (xx::xs)) (mulcomm' (yy::ys) (x :: xx :: xs))
lemma x [] y ys = addzero' ([x] * ys)lemma x xs y [] = sym $ addzero' ([y] * xs)lemma x (xx :: xs) y (yy :: ys) =rewrite mulcomm (xx::xs) (yy::ys) inrewrite plusCommutative (x * yy) (y * xx) inrewrite addzero' ([x] * ys) inrewrite addzero' ([y] * xs) inrewrite eqadd [] ([x] * ys) ([y] * xs) ((yy::ys) * (xx::xs)) inRefl
public exportmulcomm : {x,y:Poly} -> (x * y = y * x)mulcomm {x, y} = mulcomm' x y
mulcomm [] y = sym $ mulzero' ymulcomm x [] = mulzero' xmulcomm (x::xs) (y::ys) =rewrite mulcomm xs (y::ys) inrewrite mulcomm ys (x::xs) inrewrite multCommutative x y inrewrite lemma x xs y ys in Refl