0 | module Algebra.Solver.Product
4 | import public Data.List.Elem
5 | import Syntax.PreorderReasoning
24 | data Prod : (a : Type) -> (as : List a) -> Type where
26 | (::) : (exp : Nat) -> Prod a xs -> Prod a (x :: xs)
31 | mult : Prod a as -> Prod a as -> Prod a as
33 | mult (x :: xs) (y :: ys) = (x + y) :: mult xs ys
38 | compProd : Prod a as -> Prod a as -> Ordering
40 | compProd (x :: xs) (y :: ys) = case compare x y of
43 | EQ => compProd xs ys
47 | one : {as : List a} -> Prod a as
49 | one {as = x :: xs} = 0 :: one
53 | fromVar : {as : List a} -> Elem x as -> Prod a as
54 | fromVar {as = x :: xs} Here = 1 :: one
55 | fromVar {as = x :: xs} (There y) = 0 :: fromVar y
56 | fromVar {as = []
} Here
impossible
57 | fromVar {as = []
} (There y
) impossible
74 | record Term (a : Type) (as : List a) where
81 | negTerm : (neg : a -> a) -> Term a as -> Term a as
82 | negTerm neg (T f p) = T (neg f) p
89 | mult : (p : a -> a -> a) -> Term a as -> Term a as -> Term a as
90 | mult p (T f1 p1) (T f2 p2) = T (p f1 f2) (mult p1 p2)
97 | times : (p : a -> a -> a) -> (n : a) -> Nat -> a -> a
99 | times p n (S k) x = x `p` times p n k x
102 | eprod : {as : _} -> (p : a -> a -> a) -> (n : a) -> Prod a as -> a
104 | eprod {as = v :: vs} p n (exp :: x) = times p n exp v `p` eprod p n x
108 | eterm : {as : List a} -> (p : a -> a -> a) -> (n : a) -> Term a as -> a
109 | eterm p n (T f prod) = f `p` eprod p n prod
118 | CommutativeSemigroup a p
120 | -> (k `p` l) `p` (m `p` n) === (k `p` m) `p` (l `p` n)
121 | lemma1324 c = Calc $
122 | |~ (k `p` l) `p` (m `p` n)
123 | ~~ ((k `p` l) `p` m) `p` n ... c.associative
124 | ~~ (k `p` (l `p` m)) `p` n ..< cong (`p` n) c.associative
125 | ~~ (k `p` (m `p` l)) `p` n ... cong (\x => (k `p` x) `p` n) c.commutative
126 | ~~ ((k `p` m) `p` l) `p` n ... cong (`p` n) c.associative
127 | ~~ (k `p` m) `p` (l `p` n) ..< c.associative
132 | CommutativeSemigroup a p
134 | -> k `p` (m `p` n) === m `p` (k `p` n)
135 | lemma213 c = Calc $
137 | ~~ (k `p` m) `p` n ... c.associative
138 | ~~ (m `p` k) `p` n ... cong (`p` n) c.commutative
139 | ~~ m `p` (k `p` n) ..< c.associative
143 | CommutativeMonoid a z p
146 | -> times p z m x `p` times p z n x === times p z (m + n) x
147 | ptimes c 0 n x = c.leftNeutral
148 | ptimes c (S k) n x = Calc $
149 | |~ (x `p` times p z k x) `p` times p z n x
150 | ~~ x `p` (times p z k x `p` times p z n x) ..< c.associative
151 | ~~ x `p` (times p z (k + n) x) ... cong (p x) (ptimes c k n x)
155 | CommutativeMonoid a z p
156 | -> (e1,e2 : Prod a as)
157 | -> eprod p z e1 `p` eprod p z e2 === eprod p z (mult e1 e2)
158 | peprod c [] [] = c.rightNeutral
159 | peprod {as = v :: vs} c (m :: xs) (n :: ys) = Calc $
160 | |~ (times p z m v `p` eprod p z xs) `p` (times p z n v `p` eprod p z ys)
161 | ~~ (times p z m v `p` times p z n v) `p` (eprod p z xs `p` eprod p z ys)
162 | ... lemma1324 c.csgrp
163 | ~~ (times p z m v `p` times p z n v) `p` (eprod p z (mult xs ys))
164 | ... cong (p (times p z m v `p` times p z n v)) (peprod c xs ys)
165 | ~~ times p z (m + n) v `p` eprod p z (mult xs ys)
166 | ... cong (`p` eprod p z (mult xs ys)) (ptimes c m n v)
170 | CommutativeMonoid a z p
171 | -> (e1,e2 : Term a as)
172 | -> eterm p z e1 `p` eterm p z e2 === eterm p z (mult p e1 e2)
173 | pappend c (T f v) (T g w) = Calc $
174 | |~ (f `p` eprod p z v) `p` (g `p` eprod p z w)
175 | ~~ (f `p` g) `p` (eprod p z v `p` eprod p z w)
176 | ... lemma1324 c.csgrp
177 | ~~ (f `p` g) `p` eprod p z (mult v w)
178 | ... cong ((f `p` g) `p`) (peprod c v w)
183 | CommutativeMonoid a z p
185 | -> eprod p z {as} Product.one === z
187 | pone c (v :: vs) = Calc $
188 | |~ z `p` eprod p z {as = vs} one
189 | ~~ z `p` z ... cong (z `p`) (pone c vs)
190 | ~~ z ... c.leftNeutral
195 | CommutativeMonoid a z p
198 | -> eprod p z (fromVar {as} e) === x
199 | pvar c (x :: vs) Here = Calc $
200 | |~ (x `p` z) `p` eprod p z {as = vs} one
201 | ~~ (x `p` z) `p` z ... cong ((x `p` z) `p`) (pone c vs)
202 | ~~ x `p` z ... c.rightNeutral
203 | ~~ x ... c.rightNeutral
205 | pvar c (v :: vs) (There y) = Calc $
206 | |~ z `p` eprod p z (fromVar y)
207 | ~~ eprod p z (fromVar y) ... c.leftNeutral
208 | ~~ x ... pvar c vs y
210 | pvar c [] Here
impossible
211 | pvar c []
(There y
) impossible
217 | Uninhabited (LT = EQ) where
218 | uninhabited _ impossible
220 | Uninhabited (GT = EQ) where
221 | uninhabited _ impossible
224 | 0 pcompNat : (x,y : Nat) -> (compare x y === EQ) -> x === y
225 | pcompNat 0 0 prf = Refl
226 | pcompNat (S k) (S j) prf = cong S $
pcompNat k j prf
227 | pcompNat Z (S k) Refl impossible
228 | pcompNat (S k) Z Refl impossible
233 | -> (compProd x y === EQ)
235 | pcompProd [] [] prf = Refl
236 | pcompProd (x :: xs) (y :: ys) prf with (compare x y) proof eq
237 | _ | EQ = cong2 (::) (pcompNat x y eq) (pcompProd xs ys prf)
238 | _ | LT = absurd prf
239 | _ | GT = absurd prf
240 | pcompProd []
(_ ::
_) Refl
impossible
241 | pcompProd (_ ::
_) [] Refl
impossible
253 | -> (x,y : Prod a as)
254 | -> eprod m o (mult x y) === eprod m o x `m` eprod m o y
255 | pmult r [] [] = sym r.mult.leftNeutral
256 | pmult r {as = h :: t} (x :: xs) (y :: ys) = Calc $
257 | |~ times m o (x + y) h `m` eprod m o (mult xs ys)
258 | ~~ (times m o x h `m` times m o y h) `m` eprod m o (mult xs ys)
259 | ..< cong (`m` eprod m o (mult xs ys)) (ptimes r.mult x y h)
260 | ~~ (times m o x h `m` times m o y h) `m` (eprod m o xs `m` eprod m o ys)
261 | ... cong ((times m o x h `m` times m o y h) `m`) (pmult r xs ys)
262 | ~~ (times m o x h `m` eprod m o xs) `m` (times m o y h `m` eprod m o ys)
263 | ... lemma1324 r.mult.csgrp