@@ -30,94 +30,131 @@ open Equivalence eq
_*P_ : NaivePoly → NaivePoly → NaivePoly
[] *P b = []
( x : : a) *P [] = []
( x : : a) *P ( y : : b) = ( x * y) : : ( ( map ( x *_) b) +P ( map ( y *_) a) )
( x : : a) *P ( y : : b) = ( x * y) : : ( ( ( map ( x *_) b) +P ( map ( y *_) a) ) +P ( 0 R : : ( a *P b) ) )
p*Commutative : { a b : NaivePoly} → polysEqual ( a *P b) ( b *P a)
p* Commutative { []} { []} = record { }
p* Commutative { [] } { x : : b} = record { }
p*Commutative { x : : a} { []} = record { }
p*Commutative { x : : xs} { y : : ys} = *Commutative ,, AbelianGroup.commutative ( abelian ( record { commutative = Ring.groupIsAbelian R } ) ) { map ( _*_ x) ys} { map ( _*_ y) xs}
abstract
+P Commutative : { x y : NaivePoly} → polysEqual ( x +P y) ( y +P x)
+P Commutative { x } { y} = comm ( record { commutative = groupIsAbelian } ) { x} { y }
zeroTimes1 : { a : NaivePoly} ( c : A) → ( c ∼ 0 G) → polysEqual ( map ( _*_ c ) a) []
zeroTimes1 { []} c c=0 = record { }
zeroTimes1 { x : : a} c c=0 = transitive ( transitive *Commutative ( *WellDefined reflexive c=0) ) ( timesZero { x} ) ,, zeroTimes1 { a } c c=0
p*Commutative : { a b : NaivePoly} → polysEqual ( a *P b ) ( b *P a)
p*Commutative { []} { []} = record { }
p*Commutative { []} { x : : b} = record { }
p*Commutative { x : : a} { []} = record { }
p*Commutative { x : : xs} { y : : ys} = *Commutative ,, +PwellDefined ( +PCommutative { map ( _*_ x) ys} { map ( _*_ y) xs} ) ( reflexive ,, p*Commutative { xs} { ys} )
zeroTimes2 : { a : NaivePoly} ( c : A) → polysEqual a [] → polysEqual ( map ( _*_ c) a) []
zeroTimes2 { []} c a =0 = record { }
zeroTimes2 { x : : a} c ( fst ,, snd) = transi tive ( *WellDefined reflexive fst ) ( timesZero { c } ) ,, zeroTimes2 { a} c snd
zeroTimes1 : { a : NaivePoly} ( c : A) → ( c ∼ 0 G) → polysEqual ( map ( _*_ c) a) []
zeroTimes1 { []} c c =0 = record { }
zeroTimes1 { x : : a} c c=0 = transitive ( transitive *Commuta tive ( *WellDefined reflexive c=0) ) ( timesZero { x } ) ,, zeroTimes1 { a} c c=0
mapWellDefined : ( a c : A) ( bs : NaivePoly) → ( a ∼ c ) → polysEqual ( map ( _*_ a) bs) ( map ( _*_ c) bs )
mapWellDefined a c [] a=c = record { }
mapWellDefined a c ( x : : bs) a= c = *WellDefined a=c reflexive ,, mapWellDefined a c bs a=c
zeroTimes2 : { a : NaivePoly} ( c : A ) → polysEqual a [] → polysEqual ( map ( _*_ c) a ) []
zeroTimes2 { []} c a=0 = record { }
zeroTimes2 { x : : a} c ( fst ,, snd) = transitive ( *WellDefined reflexive fst) ( timesZero { c} ) ,, zeroTimes2 { a} c snd
mapWellDefined' : ( a : A) ( bs cs : NaivePoly) → polysEqual bs cs → polysEqual ( map ( _*_ a) bs) ( map ( _*_ a ) c s)
mapWellDefined' a [] [] bs =cs = record { }
mapWellDefined' a [] ( x : : c s) ( fst ,, snd) = transitive ( *WellDefined reflexive fst) ( timesZero { a} ) ,, Equivalence.symmetric ( Setoid.eq naivePolySetoid) ( zeroTimes2 { cs} a ( Equivalence.symmetric ( Setoid.eq naivePolySetoid) snd) )
mapWellDefined' a ( x : : bs) [] ( fst ,, snd) = transitive ( *WellDefined reflexive fst) ( timesZero { a} ) ,, zeroTimes2 { bs} a snd
mapWellDefined' a ( b : : bs) ( c : : cs) ( fst ,, snd) = *WellDefined reflexive fst ,, mapWellDefined' a bs cs snd
mapWellDefined : ( a c : A) ( bs : NaivePoly) → ( a ∼ c) → polysEqual ( map ( _*_ a) bs) ( map ( _*_ c ) b s)
mapWellDefined a c [] a =c = record { }
mapWellDefined a c ( x : : b s) a=c = *WellDefined a=c reflexive ,, mapWellDefined a c bs a=c
*Pw ellDefinedL : { a b c : NaivePoly} → polysEqual a c → polysEqual ( a *P b) ( c *P b )
*Pw ellDefinedL { []} { []} { []} a =c = record { }
*Pw ellDefinedL { []} { []} { x : : c} a=c = record { }
*Pw ellDefinedL { []} { x : : b} { []} a=c = record { }
*Pw ellDefinedL { []} { b : : bs} { c : : cs} ( fst ,, snd) = transitive ( transitive *Commutative ( *WellDefined reflexive fst) ) ( timesZero { b} ) ,, Equivalence.symmetric ( Setoid.eq naivePolySetoid) ( Equivalence.transitive ( Setoid.eq naivePolySetoid) ( +Pw ellDefined ( zeroTimes1 { bs} c fst) ( zeroTimes2 { cs} b ( Equivalence.symmetric ( Setoid.eq naivePolySetoid) snd) ) ) ( Group.identLeft polyGroup) )
*PwellDefinedL { a : : as} { []} { []} a=c = record { }
*PwellDefinedL { a : : as} { []} { x : : c} a=c = record { }
*PwellDefinedL { a : : as} { b : : bs} { []} ( fst ,, snd) = transitive ( transitive *Commutative ( *WellDefined reflexive fst) ) ( timesZero { b} ) ,, Equivalence.transitive ( Setoid.eq naivePolySetoid) ( +PwellDefined ( zeroTimes1 { bs} a fst) ( zeroTimes2 { as} b snd) ) ( Group.identLeft polyGroup)
*PwellDefinedL { a : : as} { b : : bs} { c : : cs} ( fst ,, snd) = *WellDefined fst reflexive ,, +PwellDefined ( mapWellDefined a c bs fst) ( mapWellDefined' b as cs snd)
mapW ellDefined' : ( a : A) ( bs cs : NaivePoly) → polysEqual bs cs → polysEqual ( map ( _*_ a) bs ) ( map ( _*_ a) cs )
mapW ellDefined' a [] [] bs =cs = record { }
mapW ellDefined' a [] ( x : : cs) ( fst ,, snd) = transitive ( *WellDefined reflexive fst) ( timesZero { a} ) ,, Equivalence.symmetric ( Setoid.eq naivePolySetoid) ( zeroTimes2 { cs} a ( Equivalence.symmetric ( Setoid.eq naivePolySetoid) snd) )
mapW ellDefined' a ( x : : bs) [] ( fst ,, snd) = transitive ( *WellDefined reflexive fst) ( timesZero { a} ) ,, zeroTimes2 { bs } a snd
mapW ellDefined' a ( b : : bs) ( c : : cs) ( fst ,, snd) = *WellDefined reflexive fst ,, mapW ellDefined' a bs cs snd
*PwellDefinedR : { a b c : NaivePoly} → polysEqual b c → polysEqual ( a *P b) ( a *P c )
*PwellDefinedR { a } { b } { c } b =c = Equivalence.transitive ( Setoid.eq naivePolySetoid) ( p*Commutative { a} { b} ) ( Equivalence.transitive ( Setoid.eq naivePolySetoid) ( *PwellDefinedL b=c) ( p*Commutative { c } { a} ) )
*PwellDefinedL : { a b c : NaivePoly} → polysEqual a c → polysEqual ( a *P b) ( c *P b )
*PwellDefinedL { [] } { [] } { [] } a =c = record { }
*PwellDefinedL { []} { []} { x : : c} a=c = record { }
*PwellDefinedL { []} { x : : b} { []} a=c = record { }
*PwellDefinedL { []} { b : : bs} { c : : cs} ( fst ,, snd) = transitive ( transitive *Commutative ( *WellDefined reflexive fst) ) ( timesZero { b} ) ,, Equivalence.transitive ( Setoid.eq naivePolySetoid) ( Equivalence.transitive ( Setoid.eq naivePolySetoid) { _} { ( map ( _*_ c) bs) +P ( 0 G : : ( cs *P bs) ) } ( Equivalence.transitive ( Setoid.eq naivePolySetoid) { _} { [] +P ( 0 G : : ( cs *P bs) ) } ( reflexive ,, ans) ( +PwellDefined ( Equivalence.symmetric ( Setoid.eq naivePolySetoid) ( zeroTimes1 { bs} c fst) ) ( Equivalence.reflexive ( Setoid.eq naivePolySetoid) { 0 G : : ( cs *P bs) } ) ) ) ( +PwellDefined ( Equivalence.symmetric ( Setoid.eq naivePolySetoid) ( Group.identRight polyGroup { map ( _*_ c) bs} ) ) ( Equivalence.reflexive ( Setoid.eq naivePolySetoid) { 0 G : : ( cs *P bs) } ) ) ) ( +PwellDefined { ( map ( _*_ c) bs +P []) } { 0 G : : ( cs *P bs) } { ( map ( _*_ c) bs) +P map ( _*_ b) cs} ( +PwellDefined ( Equivalence.reflexive ( Setoid.eq naivePolySetoid) { map ( _*_ c) bs} ) ( Equivalence.symmetric ( Setoid.eq naivePolySetoid) ( zeroTimes2 { cs} b ( Equivalence.symmetric ( Setoid.eq naivePolySetoid) snd) ) ) ) ( Equivalence.reflexive ( Setoid.eq naivePolySetoid) { 0 G : : ( cs *P bs) } ) )
where
ans : polysEqual [] ( map id ( cs *P bs) )
ans rewrite mapId ( cs *P bs) = *PwellDefinedL snd
*PwellDefinedL { a : : as} { []} { []} a=c = record { }
*PwellDefinedL { a : : as} { []} { x : : c} a=c = record { }
*PwellDefinedL { a : : as} { b : : bs} { []} ( fst ,, snd) = transitive ( transitive *Commutative ( *WellDefined reflexive fst) ) ( timesZero { b} ) ,, Equivalence.transitive ( Setoid.eq naivePolySetoid) ( +PwellDefined { ( map ( _*_ a) bs +P map ( _*_ b) as) } { 0 G : : ( as *P bs) } { [] +P []} { []} ( +PwellDefined { map ( _*_ a) bs} { map ( _*_ b) as} { []} { []} ( zeroTimes1 { bs} a fst) ( zeroTimes2 { as} b snd) ) ( reflexive ,, *PwellDefinedL { as} { bs} { []} snd) ) ( record { } )
*PwellDefinedL { a : : as} { b : : bs} { c : : cs} ( fst ,, snd) = *WellDefined fst reflexive ,, +PwellDefined { ( map ( _*_ a) bs) +P ( map ( _*_ b) as) } { 0 G : : ( as *P bs) } { map ( _*_ c) bs +P map ( _*_ b) cs} { 0 G : : ( cs *P bs) } ( +PwellDefined { map ( _*_ a) bs} { map ( _*_ b) as} { map ( _*_ c) bs} { map ( _*_ b) cs} ( mapWellDefined a c bs fst) ( mapWellDefined' b as cs snd) ) ( reflexive ,, *PwellDefinedL { as} { bs} { cs} snd)
*PwellDefined : { a b c d : NaivePoly} → polysEqual a c → polysEqual b d → polysEqual ( a *P b) ( c *P d )
*PwellDefined { a} { b} { c} { d} a=c b=d = Equivalence.transitive ( Setoid.eq naivePolySetoid) ( *PwellDefinedL a =c) ( *PwellDefinedR b=d )
*PwellDefinedR : { a b c : NaivePoly} → polysEqual b c → polysEqual ( a *P b) ( a *P c )
*PwellDefinedR { a} { b} { c} b=c = Equivalence.transitive ( Setoid.eq naivePolySetoi d) ( p*Commutative { a} { b} ) ( Equivalence.transitive ( Setoid.eq naivePolySetoid) ( *PwellDefinedL b =c) ( p*Commutative { c} { a} ) )
private
*1 : ( a : NaivePoly) → polysEqual ( map ( _*_ 1 R) a) a
*1 [] = record { }
*1 ( x : : a) = Ring.identIsIdent R ,, *1 a
*PwellDefined : { a b c d : NaivePoly} → polysEqual a c → polysEqual b d → polysEqual ( a *P b) ( c *P d)
*PwellDefined { a} { b} { c} { d} a=c b=d = Equivalence.transitive ( Setoid.eq naivePolySetoid) ( *PwellDefinedL a=c) ( *PwellDefinedR b=d)
*Pident : { a : NaivePoly} → polysEqual ( ( 1 R : : []) *P a) a
*Pident { []} = record { }
*Pident { x : : a} = Ring.identIsIdent R ,, ( Equivalence.transitive ( Setoid.eq naivePolySetoid) ( Group.identRight polyGroup { map ( _*_ 1 R) a} ) ( *1 a) )
private
*1 : ( a : NaivePoly) → polysEqual ( map ( _*_ 1 R) a) a
*1 [] = record { }
*1 ( x : : a) = Ring.identIsIdent R ,, *1 a
private
mapMap' : ( f g : A → A) ( xs : NaivePoly) → map f ( map g xs) ≡ map ( λ x → f ( g x) ) xs
mapM ap' f g [] = refl
mapMap' f g ( x : : xs) rewrite mapMap' f g xs = refl
*Pident : { a : NaivePoly} → polysEqual ( ( 1 R : : []) *P a) a
*Pident { []} = record { }
*Pident { x : : a} = Ring.identIsIdent R ,, Equivalence.transitive ( Setoid.eq naivePolySetoid) ( +PwellDefined { map ( _*_ 1 R) a +P []} { 0 G : : []} { m ap ( _*_ 1 R) a} { []} ( Group.identRight polyGroup) ( reflexive ,, record { } ) ) ( Equivalence.transitive ( Setoid.eq naivePolySetoid) ( Group.identRight polyGroup { map ( _*_ 1 R) a} ) ( *1 a) )
mapDist : ( f : A → A) ( fDist : { x y : A} → f ( x + y) ∼ ( f x) + ( f y) ) ( xs ys : NaivePoly) → polysEqual ( map f ( xs +P ys) ) ( ( map f xs) +P ( map f ys) )
mapDist f fDist [] [] = record { }
mapDist f fDist [] ( x : : ys) rewrite mapId ys | mapId ( map f ys) = reflexive ,, Equivalence.reflexive ( Setoid.eq naivePolySetoid)
mapDist f fDist ( x : : xs) [] rewrite mapId xs | mapId ( map f xs) = reflexive ,, Equivalence.reflexive ( Setoid.eq naivePolySetoid)
mapDist f fDist ( x : : xs) ( y : : ys) = fDist { x} { y} ,, mapDist f fDist xs ys
private
mapMap' : ( f g : A → A) ( xs : NaivePoly) → map f ( map g xs) ≡ map ( λ x → f ( g x) ) xs
mapMap' f g [] = refl
mapMap' f g ( x : : xs) rewrite mapMap' f g xs = refl
mapWd : ( f g : A → A) ( xs : NaivePoly) → ( ( x : A) → ( f x) ∼ ( g x) ) → polysEqual ( map f xs ) ( map g xs)
mapWd f g [] ext = record { }
mapWd f g ( x : : xs) ext = ext x ,, mapWd f g xs ext
mapMap'' : ( f g : A → A) ( xs : NaivePoly) → Setoid._∼ _ naivePolySetoid ( map f ( map g xs) ) ( map ( λ x → f ( g x) ) xs)
mapMap'' f g xs rewrite mapMap' f g xs = Equivalence.reflexive ( Setoid.eq naivePolySetoid)
mapDist' : ( b c : A) → ( a s : NaivePoly) → polysEqual ( map ( _*_ ( b + c) ) as ) ( map ( _*_ c) as +P map ( _*_ b) a s)
mapDist' b c [] = record { }
mapDist' b c ( x : : a s) = transitive ( Ring.*DistributesOver+' R { b} { c} { x} ) groupIsAbelian ,, mapDist' b c a s
mapWd : ( f g : A → A) ( x s : NaivePoly) → ( ( x : A) → ( f x ) ∼ ( g x) ) → polysEqual ( map f xs) ( map g x s)
mapWd f g [] ext = record { }
mapWd f g ( x : : x s) ext = ext x ,, mapWd f g x s ext
mapDist' : ( b c : A) → ( as : NaivePoly) → polysEqual ( map ( _*_ ( b + c) ) as) ( map ( _*_ c) as +P map ( _*_ b) as)
mapDist' b c [] = record { }
mapDist' b c ( x : : as) = transitive ( Ring.*DistributesOver+' R { b} { c} { x} ) groupIsAbelian ,, mapDist' b c as
mapTimes : ( a b : NaivePoly) ( c : A) → polysEqual ( a *P ( map ( _*_ c) b) ) ( map ( _*_ c) ( a *P b) )
mapTimes [] b c = record { }
mapTimes ( a : : as) [] c = record { }
mapTimes ( a : : as) ( x : : b) c = transitive *Associative ( transitive ( *WellDefined *Commutative reflexive) ( symmetric *Associative) ) ,, trans ( +PwellDefined { ( map ( _*_ a) ( map ( _*_ c) b) ) +P map ( _*_ ( c * x) ) as} { 0 G : : ( as *P map ( _*_ c) b) } { map ( _*_ c) ( map ( _*_ a) b +P map ( _*_ x) as) } ( trans ( +PwellDefined { map ( _*_ a) ( map ( _*_ c) b) } { map ( _*_ ( c * x) ) as} { map ( _*_ c) ( map ( _*_ a) b) } ( trans ( mapMap'' ( _*_ a) ( _*_ c) b) ( trans ( mapWd ( λ x → a * ( c * x) ) ( λ x → c * ( a * x) ) b ( λ x → transitive *Associative ( transitive ( *WellDefined *Commutative reflexive) ( symmetric *Associative) ) ) ) ( sym ( mapMap'' ( _*_ c) ( _*_ a) b) ) ) ) ( trans ( mapWd ( _*_ ( c * x) ) ( λ y → c * ( x * y) ) as λ y → symmetric *Associative) ( sym ( mapMap'' ( _*_ c) ( _*_ x) as) ) ) ) ( sym ( mapDist ( _*_ c) *DistributesOver+ ( map ( _*_ a) b) ( map ( _*_ x) as) ) ) ) ( symmetric timesZero ,, mapTimes as b c) ) ( sym ( mapDist ( _*_ c) *DistributesOver+ ( map ( _*_ a) b +P map ( _*_ x) as) ( 0 G : : ( as *P b) ) ) )
where
open Equivalence ( Setoid.eq naivePolySetoid) renaming ( transitive to trans ; symmetric to sym ; reflexive to ref)
mapTimes' : ( a b : NaivePoly) ( c : A) → polysEqual ( map ( _*_ c) ( a *P b) ) ( ( map ( _*_ c) a) *P b)
mapTimes' a b c = trans ( trans ( mapWellDefined' c ( a *P b) ( b *P a) ( p*Commutative { a} { b} ) ) ( sym ( mapTimes b a c) ) ) ( p*Commutative { b} { map ( _*_ c) a} )
where
open Equivalence ( Setoid.eq naivePolySetoid) renaming ( transitive to trans ; symmetric to sym ; reflexive to ref)
bumpTimes' : ( a bs : NaivePoly) ( b : A) → polysEqual ( a *P ( b : : bs) ) ( map ( _*_ b) a +P ( 0 G : : ( a *P bs) ) )
bumpTimes' [] bs b = reflexive ,, record { }
bumpTimes' ( x : : a) bs b = transitive *Commutative ( symmetric identRight) ,, trans ( +PwellDefined { map ( _*_ x) bs +P map ( _*_ b) a} { 0 G : : ( a *P bs) } { _} { 0 G : : ( a *P bs) } ( +PCommutative { map ( _*_ x) bs} { map ( _*_ b) a} ) ( ref { 0 G : : ( a *P bs) } ) ) ( trans ( sym ( Group.+Associative polyGroup { map ( _*_ b) a} ) ) ( +PwellDefined { map ( _*_ b) a} { _} { map ( _*_ b) a} { _} ( ref { map ( _*_ b) a} ) ( trans ( trans ( +PwellDefined { map ( _*_ x) bs} { _} { map ( _*_ x) bs} ( ref { map ( _*_ x) bs} ) ( reflexive ,, p*Commutative { a} ) ) ( sym ( bumpTimes' bs a x) ) ) ( p*Commutative { bs} ) ) ) )
where
open Equivalence ( Setoid.eq naivePolySetoid) renaming ( transitive to trans ; symmetric to sym ; reflexive to ref)
bumpTimes : { a b : NaivePoly} → polysEqual ( a *P ( 0 G : : b) ) ( 0 G : : ( a *P b) )
bumpTimes { []} { b} = reflexive ,, record { }
bumpTimes { x : : a} { []} = timesZero ,, trans ( sym ( Group.+Associative polyGroup { []} { map ( _*_ 0 G) a} ) ) ans
where
open Equivalence ( Setoid.eq naivePolySetoid) renaming ( transitive to trans ; symmetric to sym ; reflexive to ref)
ans : polysEqual ( map id ( map ( _*_ 0 G) a +P ( 0 G : : ( a *P []) ) ) ) []
ans rewrite mapId ( map ( _*_ 0 G) a +P ( 0 G : : ( a *P []) ) ) = ( +PwellDefined { map ( _*_ 0 G) a} { 0 G : : ( a *P []) } { []} { []} ( zeroTimes1 0 G reflexive) ( reflexive ,, p*Commutative { a} ) )
bumpTimes { x : : a} { b : : bs} = timesZero ,, trans ( +PwellDefined { ( ( x * b) : : map ( _*_ x) bs) +P map ( _*_ 0 G) a} { 0 G : : ( a *P ( b : : bs) ) } { ( x * b) : : map ( _*_ x) bs} { 0 G : : ( a *P ( b : : bs) ) } ( trans ( +PwellDefined { ( x * b) : : map ( _*_ x) bs} { map ( _*_ 0 G) a} { ( x * b) : : map ( _*_ x) bs} { []} ( ref { ( x * b) : : map ( _*_ x) bs} ) ( zeroTimes1 0 G reflexive) ) ( Group.identRight polyGroup { ( x * b) : : map ( _*_ x) bs} ) ) ( ref { 0 G : : ( a *P ( b : : bs) ) } ) ) ( identRight ,, trans ( +PwellDefined { map ( _*_ x) bs} { _} { map ( _*_ x) bs} ref ( bumpTimes' a bs b) ) ( Group.+Associative polyGroup { map ( _*_ x) bs} { map ( _*_ b) a} { 0 G : : ( a *P bs) } ) )
where
open Equivalence ( Setoid.eq naivePolySetoid) renaming ( transitive to trans ; symmetric to sym ; reflexive to ref)
*Pdistrib : { a b c : NaivePoly} → polysEqual ( a *P ( b +P c) ) ( ( a *P b) +P ( a *P c) )
*Pdistrib { []} { b} { c} = record { }
*Pdistrib { a : : as} { []} { []} = record { }
*Pdistrib { a : : as} { []} { c : : cs} rewrite mapId cs | mapId ( ( map ( _*_ a) cs +P map ( _*_ c) as) +P ( 0 G : : ( as *P cs) ) ) = reflexive ,, +PwellDefined { ( map ( _*_ a) cs) +P ( map ( _*_ c) as) } { _} { ( map ( _*_ a) cs) +P ( map ( _*_ c) as) } ( Equivalence.reflexive ( Setoid.eq naivePolySetoid) ) ( Equivalence.reflexive ( Setoid.eq naivePolySetoid) { 0 G : : ( as *P cs) } )
*Pdistrib { a : : as} { b : : bs} { []} rewrite mapId bs | mapId ( ( map ( _*_ a) bs +P map ( _*_ b) as) +P ( 0 G : : ( as *P bs) ) ) = reflexive ,, +PwellDefined { ( map ( _*_ a) bs) +P ( map ( _*_ b) as) } { _} { ( map ( _*_ a) bs) +P ( map ( _*_ b) as) } ( Equivalence.reflexive ( Setoid.eq naivePolySetoid) ) ( Equivalence.reflexive ( Setoid.eq naivePolySetoid) { 0 G : : ( as *P bs) } )
*Pdistrib { a : : as} { b : : bs} { c : : cs} = *DistributesOver+ ,, trans ( +PwellDefined { ( map ( _*_ a) ( bs +P cs) ) +P ( map ( _*_ ( b + c) ) as) } { 0 G : : ( as *P ( bs +P cs) ) } { ( map ( _*_ a) bs +P map ( _*_ b) as) +P ( ( map ( _*_ a) cs) +P ( map ( _*_ c) as) ) } { 0 G : : ( ( as *P bs) +P ( as *P cs) ) } ( trans ( +PwellDefined ( mapDist ( _*_ a) *DistributesOver+ bs cs) ( mapDist' b c as) ) ( trans ( sym ( +Assoc { map ( _*_ a) bs} { map ( _*_ a) cs} ) ) ( trans ( +PwellDefined ( ref { map ( _*_ a) bs} ) ( trans ( trans ( +Assoc { map ( _*_ a) cs} { map ( _*_ c) as} ) ref) ( +PCommutative { map ( _*_ a) cs +P map ( _*_ c) as} { map ( _*_ b) as} ) ) ) ( +Assoc { map ( _*_ a) bs} { map ( _*_ b) as} ) ) ) ) ( reflexive ,, *Pdistrib { as} { bs} { cs} ) ) ( trans ( sym ( +Assoc { ( map ( _*_ a) bs +P map ( _*_ b) as) } { ( map ( _*_ a) cs +P map ( _*_ c) as) } { 0 G : : ( ( as *P bs) +P ( as *P cs) ) } ) ) ( trans ( +PwellDefined ( ref { map ( _*_ a) bs +P map ( _*_ b) as} ) ( trans ( trans ( +PwellDefined ( ref { map ( _*_ a) cs +P map ( _*_ c) as} ) ( symmetric identLeft ,, +PCommutative { as *P bs} ) ) ( +Assoc { map ( _*_ a) cs +P ( map ( _*_ c) as) } { 0 G : : ( as *P cs) } { 0 G : : ( as *P bs) } ) ) ( +PCommutative { ( map ( _*_ a) cs +P map ( _*_ c) as) +P ( 0 G : : ( as *P cs) ) } { 0 G : : ( as *P bs) } ) ) ) ( +Assoc { map ( _*_ a) bs +P map ( _*_ b) as} { 0 G : : ( as *P bs) } ) ) )
where
open Equivalence ( Setoid.eq naivePolySetoid) renaming ( transitive to trans ; symmetric to sym ; reflexive to ref)
open Group polyGroup renaming ( +Associative to +Assoc ; 0 G to 0 P) hiding ( identLeft)
*Passoc : { a b c : NaivePoly} → polysEqual ( a *P ( b *P c) ) ( ( a *P b) *P c)
*Passoc { []} { b} { c} = record { }
*Passoc { a : : as} { []} { c} = record { }
*Passoc { a : : as} { b : : bs} { []} = record { }
*Passoc { a : : as} { b : : bs} { c : : cs} = *Associative ,, Equivalence.transitive ( Setoid.eq naivePolySetoid) ( +PwellDefined ( mapDist ( _*_ a) *DistributesOver+ ( map ( _*_ b) cs) ( map ( _*_ c) bs) ) ( Equivalence.reflexive ( Setoid.eq naivePolySetoid) ) ) ( Equivalence.transitive ( Setoid.eq naivePolySetoid) ans ( +PwellDefined ( Equivalence.reflexive ( Setoid.eq naivePolySetoid) { map ( _*_ ( a * b) ) cs } ) ( Equivalence.symmetric ( Setoid.eq naivePolySetoid) ( mapDist ( _*_ c) *DistributesOver+ ( map ( _*_ a) bs) ( map ( _*_ b) as) ) ) ) )
*Passoc { a : : as} { b : : bs} { c : : cs} = *Associative ,, trans ( +PwellDefined { ( map ( _*_ a) ( ( map ( _*_ b) cs +P map ( _*_ c) bs) +P ( 0 G : : ( bs *P cs) ) ) +P map ( _*_ ( b * c) ) as) } { 0 G : : ( as *P ( ( map ( _*_ b) cs +P map ( _*_ c) bs) +P ( 0 G : : ( bs *P cs) ) ) ) } { ( ( ( map ( _*_ ( a * b) ) cs) +P ( map ( _*_ ( a * c) ) bs) ) +P ( map ( _*_ a) ( 0 G : : ( bs *P cs) ) ) ) +P ( map ( _*_ ( b * c) ) as) } { 0 G : : ( ( ( map ( _*_ b) ( as *P cs) ) +P ( map ( _*_ c) ( as *P bs) ) ) +P ( as *P ( 0 G : : ( bs *P cs) ) ) ) } ( +PwellDefined { map ( _*_ a) ( ( map ( _*_ b) cs +P map ( _*_ c) bs) +P ( 0 G : : ( bs *P cs) ) ) } { map ( _*_ ( b * c) ) as} { ( ( map ( _*_ ( a * b) ) cs +P map ( _*_ ( a * c) ) bs) +P ( ( a * 0 G) : : map ( _*_ a) ( bs *P cs) ) ) } { map ( _*_ ( b * c) ) as} ( trans ( mapDist ( _*_ a) *DistributesOver+ ( map ( _*_ b) cs +P map ( _*_ c) bs) ( 0 G : : ( bs *P cs) ) ) ( +PwellDefined { map ( _*_ a) ( map ( _*_ b) cs +P map ( _*_ c) bs) } { ( a * 0 G) : : map ( _*_ a) ( bs *P cs) } { map ( _*_ ( a * b) ) cs +P map ( _*_ ( a * c) ) bs} ( trans ( mapDist ( _*_ a) *DistributesOver+ ( map ( _*_ b) cs) ( map ( _*_ c) bs) ) ( +PwellDefined { map ( _*_ a) ( map ( _*_ b) cs) } { map ( _*_ a) ( map ( _*_ c) bs) } { map ( _*_ ( a * b) ) cs} ( trans ( mapMap'' ( _*_ a) ( _*_ b) cs) ( mapWd ( λ x → a * ( b * x) ) ( _*_ ( a * b) ) cs ( λ x → *Associative) ) ) ( trans ( mapMap'' ( _*_ a) ( _*_ c) bs) ( mapWd ( λ x → a * ( c * x) ) ( _*_ ( a * c) ) bs λ x → *Associative) ) ) ) ( ref { ( a * 0 G) : : map ( _*_ a) ( bs *P cs) } ) ) ) ( ref { map ( _*_ ( b * c) ) as} ) ) ( reflexive ,, trans ( *Pdistrib { as} { ( map ( _*_ b) cs +P map ( _*_ c) bs) } { 0 G : : ( bs *P cs) } ) ( +PwellDefined { ( as *P ( map ( _*_ b) cs +P map ( _*_ c) bs) ) } { as *P ( 0 G : : ( bs *P cs) ) } { ( map ( _*_ b) ( as *P cs) +P map ( _*_ c) ( as *P bs) ) } ( trans ( *Pdistrib { as} { map ( _*_ b) cs} { map ( _*_ c) bs} ) ( +PwellDefined { as *P map ( _*_ b) cs} { as *P map ( _*_ c) bs} { map ( _*_ b) ( as *P cs) } ( mapTimes as cs b) ( mapTimes as bs c) ) ) ( ref { as *P ( 0 G : : ( bs *P cs) ) } ) ) ) ) ( trans ( trans ( sym ( Group.+Associative polyGroup { ( ( map ( _*_ ( a * b) ) cs) +P ( map ( _*_ ( a * c) ) bs) ) +P ( ( a * 0 G) : : map ( _*_ a) ( bs *P cs) ) } ) ) ( trans ( sym ( Group.+Associative polyGroup { ( map ( _*_ ( a * b) ) cs) +P ( map ( _*_ ( a * c) ) bs) } ) ) ( trans ( sym ( Group.+Associative polyGroup { map ( _*_ ( a * b) ) cs} ) ) ( +PwellDefined { map ( _*_ ( a * b) ) cs} ( ref { map ( _*_ ( a * b) ) cs} ) ( trans ( trans ans ( Group.+Associative polyGroup { map ( _*_ c) ( map ( _*_ a) bs +P map ( _*_ b) as) } ) ) ( +PwellDefined { _} { 0 G : : ( ( ( map ( _*_ a) bs +P map ( _*_ b) as) +P ( 0 G : : ( as *P bs) ) ) *P cs) } { map ( _*_ c) ( ( map ( _*_ a) bs +P map ( _*_ b) as) +P ( 0 G : : ( as *P bs) ) ) } ( sym ( mapDist ( _*_ c) *DistributesOver+ ( ( map ( _*_ a) bs +P map ( _*_ b) as) ) ( 0 G : : ( as *P bs) ) ) ) ( ref { 0 G : : ( ( ( map ( _*_ a) bs +P map ( _*_ b) as) +P ( 0 G : : ( as *P bs) ) ) *P cs) } ) ) ) ) ) ) ) ( Group.+Associative polyGroup { map ( _*_ ( a * b) ) cs} { map ( _*_ c) ( ( map ( _*_ a) bs +P map ( _*_ b) as) +P ( 0 G : : ( as *P bs) ) ) } ) )
where
ans : polysEqual ( listZip _+_ ( λ z → z) ( λ z → z) ( listZip _+_ ( λ z → z) ( λ z → z) ( map ( _*_ a) ( map ( _*_ b) cs) ) ( map ( _*_ a) ( map ( _*_ c) bs) ) ) ( map ( _*_ ( b * c) ) as) ) ( listZip _+_ ( λ z → z) ( λ z → z) ( map ( _*_ ( a * b) ) cs) ( listZip _+_ ( λ z → z) ( λ z → z) ( map ( _*_ c) ( map ( _*_ a) bs) ) ( map ( _*_ c) ( map ( _*_ b) as) ) ) )
ans rewrite mapMap' ( _*_ a) ( _*_ c) bs | mapMap' ( _*_ a) ( _*_ b) cs | mapMap' ( _*_ c) ( _*_ a) bs | mapMap' ( _*_ c) ( _*_ b) as = Equivalence.transitive ( Setoid.eq naivePolySetoid) ( Equivalence.symmetric ( Setoid.eq naivePolySetoid) ( Group.+Associative polyGroup { map ( λ x → a * ( b * x) ) cs} { map ( λ x → a * ( c * x) ) bs} { map ( _*_ ( b * c) ) as} ) ) ( +PwellDefined { map ( λ x → a * ( b * x) ) cs} { ( map ( λ x → a * ( c * x) ) bs) +P map ( _*_ ( b * c) ) as} { ( map ( _*_ ( a * b) ) cs) } ( mapWd ( λ x → a * ( b * x) ) ( _*_ ( a * b) ) cs λ x → *Associative) ( +PwellDefined { map ( λ x → a * ( c * x) ) bs} { map ( _*_ ( b * c) ) as} { map ( λ x → c * ( a * x) ) bs} { map ( λ x → c * ( b * x) ) as} ( mapWd ( λ x → a * ( c * x) ) ( λ x → c * ( a * x) ) bs λ x → transitive *Commutative ( transitive ( symmetric *Associative) ( *WellDefined reflexive *Commutative) ) ) ( mapWd ( _*_ ( b * c) ) ( λ x → c * ( b * x) ) as λ x → transitive ( *WellDefined *Commutative reflexive) ( symmetric *Associative) ) ) )
*Pdistrib : { a b c : NaivePoly} → polysEqual ( a *P ( b +P c) ) ( ( a *P b) +P ( a *P c) )
*Pdistrib { []} { b} { c} = record { }
*Pdistrib { a : : as} { []} { []} = record { }
*Pdistrib { a : : as} { []} { c : : cs} = reflexive ,, ans
where
ans : polysEqual ( listZip _+_ ( λ z → z ) ( λ z → z) ( map ( _*_ a) ( map ( λ z → z) cs) ) ( map ( _*_ c) as) ) ( map ( λ z → z) ( listZip _+_ ( λ z → z ) ( λ z → z ) ( map ( _*_ a) cs) ( map ( _*_ c) as) ) )
ans rewrite mapId ( listZip _+_ id id ( map ( _*_ a) cs) ( map ( _*_ c) as) ) | mapId cs = Equivalence.reflexive ( Setoid.eq naivePolySetoid)
*Pdistrib { a : : as} { b : : bs} { []} = reflexive ,, ans
where
ans : polysEqual ( listZip _+_ ( λ z → z) ( λ z → z) ( map ( _*_ a) ( map ( λ z → z) bs) ) ( map ( _*_ b) as) ) ( map ( λ z → z) ( listZip _+_ ( λ z → z) ( λ z → z) ( map ( _*_ a) bs) ( map ( _*_ b) as) ) )
ans rewrite mapId ( listZip _+_ id id ( map ( _*_ a) bs) ( map ( _*_ b) as) ) | mapId bs = Equivalence.reflexive ( Setoid.eq naivePolySetoid)
*Pdistrib { a : : as} { b : : bs} { c : : cs} = *DistributesOver+ ,, Equivalence.transitive ( Setoid.eq naivePolySetoid) ( Equivalence.transitive ( Setoid.eq naivePolySetoid) ( Equivalence.transitive ( Setoid.eq naivePolySetoid) ( Equivalence.transitive ( Setoid.eq naivePolySetoid) ( Equivalence.transitive ( Setoid.eq naivePolySetoid) ( +PwellDefined { map ( _*_ a) ( bs +P cs) } { map ( _*_ ( b + c) ) as} { ( map ( _*_ a) bs) +P ( map ( _*_ a) cs) } ( mapDist ( _*_ a) *DistributesOver+ bs cs) ( mapDist' b c as) ) ( Group.+Associative polyGroup { ( map ( _*_ a) bs) +P ( map ( _*_ a) cs) } { map ( _*_ c) as} { map ( _*_ b) as} ) ) ( +PwellDefined ( Equivalence.symmetric ( Setoid.eq naivePolySetoid) ( Group.+Associative polyGroup { map ( _*_ a) bs} { map ( _*_ a) cs} { map ( _*_ c) as} ) ) ( Equivalence.reflexive ( Setoid.eq naivePolySetoid) { map ( _*_ b) as} ) ) ) ( Equivalence.symmetric ( Setoid.eq naivePolySetoid) ( Group.+Associative polyGroup { map ( _*_ a) bs} { ( map ( _*_ a) cs) +P ( map ( _*_ c) as) } { map ( _*_ b) as} ) ) ) ( +PwellDefined ( Equivalence.reflexive ( Setoid.eq naivePolySetoid) { map ( _*_ a) bs} ) ( AbelianGroup.commutative ( abelian ( record { commutative = groupIsAbelian } ) ) { map ( _*_ a) cs +P map ( _*_ c) as} { map ( _*_ b) as} ) ) ) ( Group.+Associative polyGroup { map ( _*_ a) bs} { map ( _*_ b) as} )
open Equivalence ( Setoid.eq naivePolySetoid) renaming ( transitive to trans ; symmetric to sym ; reflexive to ref )
open Group polyGroup renaming ( +Associative to +Asso c ; 0 G to 0 P) hiding ( identLeft ; identRight)
ans2 : polysEqual ( ( map ( _*_ a) ( bs *P cs) +P ( map ( _*_ b) ( as *P cs) +P map ( _*_ c) ( as *P bs) ) ) +P ( as *P ( 0 G : : ( bs *P cs) ) ) ) ( map ( _*_ c) ( as *P bs) +P ( ( ( map ( _*_ a) bs +P map ( _*_ b) as) +P ( 0 G : : ( as *P bs) ) ) *P cs) )
ans2 = trans ( +PwellDefined { _} { as *P ( 0 G : : ( bs *P cs) ) } { _} { as *P ( 0 G : : ( bs *P cs) ) } ( trans ( +Assoc { map ( _*_ a) ( bs *P cs) } { map ( _*_ b) ( as *P cs) } { map ( _*_ c) ( as *P bs) } ) ( +PCommutative { map ( _*_ a) ( bs *P cs) +P map ( _*_ b) ( as *P cs) } { map ( _*_ c) ( as *P bs) } ) ) ref) ( trans ( sym ( +Assoc { map ( _*_ c) ( as *P bs) } { _} { as *P ( 0 G : : ( bs *P cs) ) } ) ) ( +PwellDefined { map ( _*_ c) ( as *P bs) } { _} { map ( _*_ c) ( as *P bs) } ref ( trans ( +PwellDefined { map ( _*_ a) ( bs *P cs) +P map ( _*_ b) ( as *P cs) } { as *P ( 0 G : : ( bs *P cs) ) } { ( ( map ( _*_ a) bs) *P cs) +P ( ( map ( _*_ b) as) *P cs) } { 0 G : : ( as *P ( bs *P cs) ) } ( +PwellDefined { map ( _*_ a) ( bs *P cs) } { map ( _*_ b) ( as *P cs) } { map ( _*_ a) bs *P cs} { map ( _*_ b) as *P cs} ( mapTimes' bs cs a) ( mapTimes' as cs b) ) ( bumpTimes { as} { bs *P cs} ) ) ( trans ( trans ( +PwellDefined { ( map ( _*_ a) bs *P cs) +P ( map ( _*_ b) as *P cs) } { 0 G : : ( as *P ( bs *P cs) ) } { cs *P ( map ( _*_ a) bs +P map ( _*_ b) as) } { cs *P ( 0 G : : ( as *P bs) ) } ( trans ( +PwellDefined { map ( _*_ a) bs *P cs} { map ( _*_ b) as *P cs} { cs *P map ( _*_ a) bs} { cs *P map ( _*_ b) as} ( p*Commutative { _} { cs} ) ( p*Commutative { _} { cs} ) ) ( sym ( *Pdistrib { cs} { map ( _*_ a) bs} { map ( _*_ b) as} ) ) ) ( trans ( reflexive ,, trans ( *Passoc { as} { bs} { cs} ) ( p*Commutative { _} { cs} ) ) ( sym ( bumpTimes { cs} { as *P bs} ) ) ) ) ( sym ( *Pdistrib { cs} { ( map ( _*_ a) bs) +P ( map ( _*_ b) as) } { 0 G : : ( as *P bs) } ) ) ) ( p*Commutative { cs} { ( map ( _*_ a) bs +P map ( _*_ b) as) +P ( 0 G : : ( as *P bs) ) } ) ) ) ) )
ans :
polysEqual
( ( map ( _*_ ( a * c) ) bs) +P ( ( ( a * 0 G) : : map ( _*_ a) ( bs *P cs) ) +P ( map ( _*_ ( b * c) ) as +P ( 0 G : : ( ( map ( _*_ b) ( as *P cs) +P map ( _*_ c) ( as *P bs) ) +P ( as *P ( 0 G : : ( bs *P cs) ) ) ) ) ) ) )
( ( map ( _*_ c) ( ( map ( _*_ a) bs) +P ( map ( _*_ b) as) ) ) +P ( ( ( c * 0 G) : : map ( _*_ c) ( as *P bs) ) +P ( 0 G : : ( ( ( map ( _*_ a) bs +P map ( _*_ b) as) +P ( 0 G : : ( as *P bs) ) ) *P cs) ) ) )
ans = trans ( trans ( +PwellDefined { map ( _*_ ( a * c) ) bs} { _} { map ( _*_ c) ( map ( _*_ a) bs) } ( trans ( mapWd ( _*_ ( a * c) ) ( λ x → c * ( a * x) ) bs ( λ x → transitive ( *WellDefined *Commutative reflexive) ( symmetric *Associative) ) ) ( sym ( mapMap'' ( _*_ c) ( _*_ a) bs) ) ) ( trans ( +PCommutative { ( a * 0 G) : : map ( _*_ a) ( bs *P cs) } { map ( _*_ ( b * c) ) as +P ( 0 G : : ( ( map ( _*_ b) ( as *P cs) +P map ( _*_ c) ( as *P bs) ) +P ( as *P ( 0 G : : bs *P cs) ) ) ) } ) ( trans ( sym ( +Assoc { map ( _*_ ( b * c) ) as} ) ) ( +PwellDefined { map ( _*_ ( b * c) ) as} { _} { map ( _*_ c) ( map ( _*_ b) as) } ( trans ( mapWd ( _*_ ( b * c) ) ( λ x → c * ( b * x) ) as λ x → transitive ( *WellDefined *Commutative reflexive) ( symmetric *Associative) ) ( sym ( mapMap'' ( _*_ c) ( _*_ b) as) ) ) ( transitive identLeft ( transitive ( transitive timesZero ( symmetric timesZero) ) ( symmetric identRight) ) ,, trans ( +PCommutative { ( map ( _*_ b) ( as *P cs) +P map ( _*_ c) ( as *P bs) ) +P ( as *P ( 0 G : : ( bs *P cs) ) ) } { map ( _*_ a) ( bs *P cs) } ) ( trans ( +Assoc { map ( _*_ a) ( bs *P cs) } { ( map ( _*_ b) ( as *P cs) ) +P ( map ( _*_ c) ( as *P bs) ) } { as *P ( 0 G : : ( bs *P cs) ) } ) ans2) ) ) ) ) ) ( +Assoc { map ( _*_ c) ( map ( _*_ a) bs) } ) ) ( +PwellDefined { ( map ( _*_ c ) ( map ( _*_ a) bs) ) +P ( map ( _*_ c) ( map ( _*_ b) as) ) } { ( ( ( c * 0 G) : : map ( _*_ c) ( as *P bs) ) +P ( 0 G : : ( ( ( map ( _*_ a ) bs +P map ( _*_ b) as) +P ( 0 G : : ( as *P bs) ) ) *P cs) ) ) } { map ( _*_ c) ( ( map ( _*_ a) bs) +P ( map ( _*_ b) as) ) } { ( ( ( c * 0 G) : : map ( _*_ c) ( as *P bs) ) +P ( 0 G : : ( ( ( map ( _*_ a) bs +P map ( _*_ b) as) +P ( 0 G : : ( as *P bs) ) ) *P cs) ) ) } ( sym ( mapDist ( _*_ c) ( *DistributesOver+) ( map ( _*_ a) bs) ( map ( _*_ b) as) ) ) ( ref { ( ( ( c * 0 G) : : map ( _*_ c) ( as *P bs) ) +P ( 0 G : : ( ( ( map ( _*_ a) bs +P map ( _*_ b) as) +P ( 0 G : : ( as *P bs) ) ) *P cs) ) ) } ) )