I was writing the following proof in Idris:
n : Nat
n = S (k + k)
lemma: n * n = ((k * n) + k) + (1 + (((k * n) + k) + 0))
lemma = sym $
rewrite plusZeroRightNeutral ((k * n) + k) in
rewrite plusAssociative ((k * n) + k) 1 ((k * n) + k) in
rewrite plusCommutative ((k * n) + k) 1 in
rewrite mult2 ((k * n) + k) in
rewrite multDistributesOverPlusRight 2 (k * n) k in
rewrite multAssociative 2 k n in
rewrite sym (mult2 k) in
rewrite plusCommutative ((k + k) * n) (k + k) in
Refl
But of course that's not really what I wrote. What I wrote instead is this:
lemma: n * n = ((k * n) + k) + (1 + (((k * n) + k) + 0))
lemma = sym $
-- ((k * n) + k) + (1 + ((k * n) + k) + 0) =
rewrite plusZeroRightNeutral ((k * n) + k) in
-- ((k * n) + k) + (1 + (k * n) + k) =
rewrite plusAssociative ((k * n) + k) 1 ((k * n) + k) in
-- (((k * n) + k) + 1) + (k * n) + k) =
rewrite plusCommutative ((k * n) + k) 1 in
-- 1 + ((k * n) + k)) + ((k * n) + k) =
rewrite mult2 ((k * n) + k) in
-- 1 + 2 * ((k * n) + k) =
rewrite multDistributesOverPlusRight 2 (k * n) k in
-- 1 + 2 * (k * n) + 2 * k
rewrite multAssociative 2 k n in
-- 1 + (2 * k) * n + 2 * k =
rewrite sym (mult2 k) in
-- 1 + (k + k) * n + (k + k) =
rewrite plusCommutative ((k + k) * n) (k + k) in
-- (k + k) * n + (1 + k + k) =
-- (k + k) * n + n =
-- (1 + k + k) * n =
-- n * n
Refl
If I were writing this in Agda, I could use the ≡-Reasoning
module to keep track of where I am; for example, the above can be done like this (omitting the actual proof steps, since they'd be exactly the same):
lemma : ((k * n) + k) + (1 + (((k * n) + k) + 0)) ≡ n * n
lemma =
begin
((k * n) + k) + (1 + (((k * n) + k) + 0)) ≡⟨ {!!} ⟩
((k * n) + k) + (1 + (((k * n) + k))) ≡⟨ {!!} ⟩
((k * n) + k) + 1 + ((k * n) + k) ≡⟨ {!!} ⟩
1 + ((k * n) + k) + ((k * n) + k) ≡⟨ {!!} ⟩
1 + 2 * ((k * n) + k) ≡⟨ {!!} ⟩
1 + 2 * (k * n) + 2 * k ≡⟨ {!!} ⟩
1 + (2 * k) * n + 2 * k ≡⟨ {!!} ⟩
1 + (k + k) * n + (k + k) ≡⟨ {!!} ⟩
(k + k) * n + (1 + k + k) ≡⟨⟩
(k + k) * n + n ≡⟨ {!!} ⟩
n + (k + k) * n ≡⟨⟩
(1 + k + k) * n ≡⟨⟩
n * n
∎
where
open ≡-Reasoning
Is there a way to do similarly in Idris?
(Note: of course, in Agda I wouldn't hand-prove this: I'd just use the semiring solver and be done with it; but the Idris semiring solver at https://github.com/FranckS/RingIdris seems to be targeting Idris 0.11 and I'm using 1.1.1...)