BEWARE SPOILERS!
Don't read this if you haven't proved accoc* and comm* yet.
...
...
...
≡-sym is a correct name for ≡-refl
-- This part is easy:
distrib : (x y z : ℕ) → (x + y) * z ≡ x * z + y * z
distrib zero y z = refl
distrib (succ x) y z = cong (λ a → z + a) (distrib x y z) ~ assoc z (x
* z) (y * z)
-- (**) Prove its properties:
assoc* : (x y z : ℕ) → x * (y * z) ≡ (x * y) * z
assoc* zero y z = refl
assoc* (succ x) y z = cong (λ a → y * z + a) (assoc* x y z) ~ ≡-sym
(distrib y (x * y) z)
-- Another easy lemma:
mulzero : (y : ℕ) → y * zero ≡ zero
mulzero zero = refl
mulzero (succ y) = mulzero y
-- Proof of comm* from right distributivity is fine. I have a similar
one with heavy rewrites.
-- Beware, it looks scary (without the "rewrite" keyword, see Agda
wiki). Viewing in a monospace helps.
-- The mad skillz:
raggr : (x y : ℕ) → x + (x * y) ≡ x * (succ y)
raggr zero y = refl
raggr (succ x) y = cong succ (x+[y+x*y]=y+[x+x*y] ~ cong (λ a → y + a)
(raggr x y)) where
x+[y+x*y]=y+[x+x*y] : x + (y + x * y) ≡ y + (x + x * y) -- This
could be done with simple trans, but I love rewrites
x+[y+x*y]=y+[x+x*y] with x + (y + x * y) | assoc x y (x * y)
| y + (x + x * y) | assoc y x (x * y)
... | ._ | refl
| ._ | refl = cong (λ a → a + x * y) (comm x y)
-- Now this thing is easy.
comm* : (x y : ℕ) → x * y ≡ y * x
comm* x zero = mulzero x
comm* x (succ y) with y * x | comm* x y
... | ._ | refl = refl {x = x * succ y} ~ ≡-sym (raggr x y)
-- {x = x * succ y} is a kind of a comment :)
On Thu, May 10, 2012 at 2:41 PM, Alexey Sergushichev