2 | import Syntax.PreorderReasoning
6 | public export %inline %tcinline
7 | neg : Neg a => a -> a
30 | interface Neg a => Ring a where
32 | 0 plusAssociative : {k,m,n : a} -> k + (m + n) === (k + m) + n
35 | 0 plusCommutative : {m,n : a} -> m + n === n + m
38 | 0 plusZeroLeftNeutral : {n : a} -> 0 + n === n
41 | 0 plusNegLeftZero : {n : a} -> neg n + n === 0
44 | 0 multAssociative : {k,m,n : a} -> k * (m * n) === (k * m) * n
47 | 0 multCommutative : {m,n : a} -> m * n === n * m
50 | 0 multOneLeftNeutral : {n : a} -> 1 * n === n
53 | 0 leftDistributive : {k,m,n : a} -> k * (m + n) === (k * m) + (k * n)
56 | 0 minusIsPlusNeg : {m,n : a} -> m - n === m + neg n
64 | 0 plusZeroRightNeutral : Ring a => {n : a} -> n + 0 === n
65 | plusZeroRightNeutral =
68 | ~~ 0 + n ... plusCommutative
69 | ~~ n ... plusZeroLeftNeutral
73 | 0 plusNegRightZero : Ring a => {n : a} -> n + neg n === 0
77 | ~~ neg n + n ... plusCommutative
78 | ~~ 0 ... plusNegLeftZero
82 | 0 minusSelfZero : Ring a => {n : a} -> n - n === 0
86 | ~~ n + neg n ... minusIsPlusNeg
87 | ~~ 0 ... plusNegRightZero
91 | 0 plusMinusAssociative :
94 | -> k + (m - n) === (k + m) - n
95 | plusMinusAssociative =
98 | ~~ k + (m + neg n) ..> cong (k+) minusIsPlusNeg
99 | ~~ (k + m) + neg n ..> plusAssociative
100 | ~~ (k + m) - n ..< minusIsPlusNeg
109 | solvePlusRight prf =
112 | ~~ k + 0 ..< plusZeroRightNeutral
113 | ~~ k + (m - m) ..< cong (k +) minusSelfZero
114 | ~~ (k + m) - m ..> plusMinusAssociative
115 | ~~ n - m ..> cong (\x => x - m) prf
124 | solvePlusLeft prf =
125 | solvePlusRight $
Calc $
127 | ~~ k + m ... plusCommutative
132 | 0 plusLeftInjective : Ring a => {k,m,n : a} -> k + n === m + n -> k === m
133 | plusLeftInjective prf =
136 | ~~ (m + n) - n ..> solvePlusRight prf
137 | ~~ m + (n - n) ..< plusMinusAssociative
138 | ~~ m + 0 ..> cong (m +) minusSelfZero
139 | ~~ m ..> plusZeroRightNeutral
143 | 0 plusRightInjective : Ring a => {k,m,n : a} -> n + k === n + m -> k === m
144 | plusRightInjective prf =
145 | plusLeftInjective $
148 | ~~ n + k ... plusCommutative
150 | ~~ m + n ... plusCommutative
155 | 0 solvePlusNegRight :
160 | solvePlusNegRight prf =
161 | plusRightInjective (trans prf (sym plusNegRightZero))
166 | 0 solvePlusNegLeft :
171 | solvePlusNegLeft prf =
172 | solvePlusNegRight $
Calc $
174 | ~~ m + n ... plusCommutative
179 | 0 solvePlusZeroRight : Ring a => {m,n : a} -> m + n === m -> n === 0
180 | solvePlusZeroRight prf =
183 | ~~ m - m ... solvePlusLeft prf
184 | ~~ 0 ... minusSelfZero
188 | 0 solvePlusZeroLeft : Ring a => {m,n : a} -> n + m === m -> n === 0
189 | solvePlusZeroLeft prf =
190 | solvePlusZeroRight $
Calc $
192 | ~~ n + m ... plusCommutative
197 | 0 negInvolutory : Ring a => {n : a} -> neg (neg n) === n
198 | negInvolutory = sym $
solvePlusNegLeft plusNegRightZero
202 | 0 solveNegZero : Ring a => {n : a} -> neg n === 0 -> n === 0
206 | ~~ n + 0 ..< plusZeroRightNeutral
207 | ~~ n + neg n ..< cong (n +) prf
208 | ~~ 0 ..> plusNegRightZero
212 | 0 negZero : Ring a => neg {a} 0 === 0
213 | negZero = solveNegZero negInvolutory
216 | 0 negDistributes : Ring a => {m,n : a} -> neg (m + n) === neg m + neg n
218 | sym $
solvePlusNegLeft $
Calc $
219 | |~ (neg m + neg n) + (m + n)
220 | ~~ (neg m + neg n) + (n + m) ... cong ((neg m + neg n) +) plusCommutative
221 | ~~ ((neg m + neg n) + n) + m ... plusAssociative
222 | ~~ (neg m + (neg n + n)) + m ..< cong (+m) plusAssociative
223 | ~~ (neg m + 0) + m ... cong (\x => neg m + x + m) plusNegLeftZero
224 | ~~ neg m + m ... cong (+m) plusZeroRightNeutral
225 | ~~ 0 ... plusNegLeftZero
233 | 0 multOneRightNeutral : Ring a => {n : a} -> n * 1 === n
234 | multOneRightNeutral =
237 | ~~ 1 * n ... multCommutative
238 | ~~ n ... multOneLeftNeutral
242 | 0 multZeroRightAbsorbs : Ring a => {n : a} -> n * 0 === 0
243 | multZeroRightAbsorbs =
244 | solvePlusZeroRight $
Calc $
245 | |~ (n * 0) + (n * 0)
246 | ~~ n * (0 + 0) ..< leftDistributive
247 | ~~ n * 0 ..> cong (n *) plusZeroLeftNeutral
252 | 0 multZeroLeftAbsorbs : Ring a => {n : a} -> 0 * n === 0
253 | multZeroLeftAbsorbs =
256 | ~~ n * 0 ... multCommutative
257 | ~~ 0 ... multZeroRightAbsorbs
261 | 0 multZeroAbsorbs :
264 | -> Either (m === 0) (n === 0)
266 | multZeroAbsorbs (Left rfl) =
269 | ~~ 0 * n ... cong (*n) rfl
270 | ~~ 0 ... multZeroLeftAbsorbs
272 | multZeroAbsorbs (Right rfl) =
275 | ~~ m * 0 ... cong (m*) rfl
276 | ~~ 0 ... multZeroRightAbsorbs
280 | 0 multNegRight : Ring a => {m,n : a} -> m * neg n === neg (m * n)
282 | solvePlusNegRight $
Calc $
283 | |~ m * n + m * neg n
284 | ~~ m * (n + neg n) ..< leftDistributive
285 | ~~ m * 0 ..> cong (m *) plusNegRightZero
286 | ~~ 0 ..> multZeroRightAbsorbs
290 | 0 negMultNegRight : Ring a => {m,n : a} -> neg (m * neg n) === m * n
294 | ~~ neg (neg (m * n)) ... cong neg multNegRight
295 | ~~ m * n ... negInvolutory
299 | 0 multNegLeft : Ring a => {m,n : a} -> neg m * n === neg (m * n)
303 | ~~ n * neg m ... multCommutative
304 | ~~ neg (n * m) ... multNegRight
305 | ~~ neg (m * n) ... cong neg multCommutative
309 | 0 negMultNegLeft : Ring a => {m,n : a} -> neg (neg m * n) === m * n
313 | ~~ neg (neg (m * n)) ... cong neg multNegLeft
314 | ~~ m * n ... negInvolutory
318 | 0 multMinusOneRight : Ring a => {n : a} -> n * neg 1 === neg n
319 | multMinusOneRight =
322 | ~~ neg (n * 1) ... multNegRight
323 | ~~ neg n ... cong neg multOneRightNeutral
327 | 0 multMinusOneLeft : Ring a => {n : a} -> neg 1 * n === neg n
331 | ~~ neg (1 * n) ... multNegLeft
332 | ~~ neg n ... cong neg multOneLeftNeutral
336 | 0 negMultNeg : Ring a => {m,n : a} -> neg m * neg n === m * n
340 | ~~ neg (m * neg n) ... multNegLeft
341 | ~~ neg (neg (m * n)) ... cong neg multNegRight
342 | ~~ m * n ... negInvolutory
346 | 0 rightDistributive :
349 | -> (m + n) * k === m * k + n * k
350 | rightDistributive =
353 | ~~ k * (m + n) ... multCommutative
354 | ~~ (k * m) + (k * n) ... leftDistributive
355 | ~~ m * k + k * n ... cong (+ k * n) multCommutative
356 | ~~ m * k + n * k ... cong (m * k +) multCommutative
359 | 0 multPlusSelf : Ring a => {m,n : a} -> m * n + m === m * (n + 1)
363 | ~~ m * n + m * 1 ..< cong (m*n +) multOneRightNeutral
364 | ~~ m * (n + 1) ..< leftDistributive
370 | unsafeRefl : a === b
371 | unsafeRefl = believe_me (Refl {x = a})
375 | plusAssociative = unsafeRefl
376 | plusCommutative = unsafeRefl
377 | plusZeroLeftNeutral = unsafeRefl
378 | plusNegLeftZero = unsafeRefl
379 | multAssociative = unsafeRefl
380 | multCommutative = unsafeRefl
381 | multOneLeftNeutral = unsafeRefl
382 | leftDistributive = unsafeRefl
383 | minusIsPlusNeg = unsafeRefl
387 | plusAssociative = unsafeRefl
388 | plusCommutative = unsafeRefl
389 | plusZeroLeftNeutral = unsafeRefl
390 | plusNegLeftZero = unsafeRefl
391 | multAssociative = unsafeRefl
392 | multCommutative = unsafeRefl
393 | multOneLeftNeutral = unsafeRefl
394 | leftDistributive = unsafeRefl
395 | minusIsPlusNeg = unsafeRefl
399 | plusAssociative = unsafeRefl
400 | plusCommutative = unsafeRefl
401 | plusZeroLeftNeutral = unsafeRefl
402 | plusNegLeftZero = unsafeRefl
403 | multAssociative = unsafeRefl
404 | multCommutative = unsafeRefl
405 | multOneLeftNeutral = unsafeRefl
406 | leftDistributive = unsafeRefl
407 | minusIsPlusNeg = unsafeRefl
411 | plusAssociative = unsafeRefl
412 | plusCommutative = unsafeRefl
413 | plusZeroLeftNeutral = unsafeRefl
414 | plusNegLeftZero = unsafeRefl
415 | multAssociative = unsafeRefl
416 | multCommutative = unsafeRefl
417 | multOneLeftNeutral = unsafeRefl
418 | leftDistributive = unsafeRefl
419 | minusIsPlusNeg = unsafeRefl
423 | plusAssociative = unsafeRefl
424 | plusCommutative = unsafeRefl
425 | plusZeroLeftNeutral = unsafeRefl
426 | plusNegLeftZero = unsafeRefl
427 | multAssociative = unsafeRefl
428 | multCommutative = unsafeRefl
429 | multOneLeftNeutral = unsafeRefl
430 | leftDistributive = unsafeRefl
431 | minusIsPlusNeg = unsafeRefl
435 | plusAssociative = unsafeRefl
436 | plusCommutative = unsafeRefl
437 | plusZeroLeftNeutral = unsafeRefl
438 | plusNegLeftZero = unsafeRefl
439 | multAssociative = unsafeRefl
440 | multCommutative = unsafeRefl
441 | multOneLeftNeutral = unsafeRefl
442 | leftDistributive = unsafeRefl
443 | minusIsPlusNeg = unsafeRefl
447 | plusAssociative = unsafeRefl
448 | plusCommutative = unsafeRefl
449 | plusZeroLeftNeutral = unsafeRefl
450 | plusNegLeftZero = unsafeRefl
451 | multAssociative = unsafeRefl
452 | multCommutative = unsafeRefl
453 | multOneLeftNeutral = unsafeRefl
454 | leftDistributive = unsafeRefl
455 | minusIsPlusNeg = unsafeRefl
459 | plusAssociative = unsafeRefl
460 | plusCommutative = unsafeRefl
461 | plusZeroLeftNeutral = unsafeRefl
462 | plusNegLeftZero = unsafeRefl
463 | multAssociative = unsafeRefl
464 | multCommutative = unsafeRefl
465 | multOneLeftNeutral = unsafeRefl
466 | leftDistributive = unsafeRefl
467 | minusIsPlusNeg = unsafeRefl
471 | plusAssociative = unsafeRefl
472 | plusCommutative = unsafeRefl
473 | plusZeroLeftNeutral = unsafeRefl
474 | plusNegLeftZero = unsafeRefl
475 | multAssociative = unsafeRefl
476 | multCommutative = unsafeRefl
477 | multOneLeftNeutral = unsafeRefl
478 | leftDistributive = unsafeRefl
479 | minusIsPlusNeg = unsafeRefl
483 | plusAssociative = unsafeRefl
484 | plusCommutative = unsafeRefl
485 | plusZeroLeftNeutral = unsafeRefl
486 | plusNegLeftZero = unsafeRefl
487 | multAssociative = unsafeRefl
488 | multCommutative = unsafeRefl
489 | multOneLeftNeutral = unsafeRefl
490 | leftDistributive = unsafeRefl
491 | minusIsPlusNeg = unsafeRefl