module Addition where
open import Data.Nat using (ℕ ; zero ; suc)
open import Relation.Binary.PropositionalEquality
open import Function
open import Relation.Binary.PropositionalEquality.Core
open ≡-Reasoning
_+_ : ℕ → ℕ → ℕ
zero + b = b
suc a + b = suc (a + b)
associative+ : ∀ {a b c} → (a + b) + c ≡ a + (b + c)
associative+ {zero} = refl
associative+ {suc a} = cong suc (associative+ {a})
commutative+ : ∀ {a b} → a + b ≡ b + a
commutative+ {zero} = +0
where
+0 : ∀ {a} → a ≡ a + zero
+0 {zero} = refl
+0 {suc _} = cong suc +0
commutative+ {suc a} = trans (cong suc (commutative+ {a})) +suc
where
+suc : ∀ {a b} → suc (a + b) ≡ a + suc b
+suc {zero} = refl
+suc {suc _} = cong suc +suc
_*_ : ℕ → ℕ → ℕ
zero * b = zero
suc a * b = b + (a * b)
distributive* : ∀ {a b c} → (a + b) * c ≡ (a * c) + (b * c)
distributive* {zero} = refl
distributive* {suc a} {b} {c} = trans (cong (c +_) (distributive* {a}))
(sym (associative+ {c} {a * c} {b * c}))
associative* : ∀ {a b c} → a * (b * c) ≡ (a * b) * c
associative* {zero} = refl
associative* {suc a} {b} {c} rewrite distributive* {b} {a * b} {c}
| sym (associative* {a} {b} {c}) = refl
*0 : ∀ {a} → a * 0 ≡ 0
*0 {zero} = refl
*0 {suc a} = *0 {a}
*suc : ∀ {a b} → a * suc b ≡ a + (a * b)
*suc {zero} = refl
*suc {suc a} {b} = cong suc (begin
b + (a * suc b) ≡⟨ cong (b +_) (*suc {a} {b}) ⟩
b + (a + (a * b)) ≡˘⟨ associative+ {b} {a} {a * b} ⟩
(b + a) + (a * b) ≡⟨ cong (_+ (a * b)) (commutative+ {b} {a}) ⟩
(a + b) + (a * b) ≡⟨ associative+ {a} {b} {a * b} ⟩
a + (b + (a * b)) ∎)
commutative* : ∀ {a b} → a * b ≡ b * a
commutative* {zero} {b} = sym (*0 {b})
commutative* {suc a} {b} = begin
(b + (a * b)) ≡⟨ cong (b +_) (commutative* {a}) ⟩
(b + (b * a)) ≡˘⟨ *suc {b} ⟩
(b * suc a) ∎
2+5≡7 : 2 + 5 ≡ 7
2+5≡7 = refl
2+5≡7₁ : 2 + 5 ≡ 7
2+5≡7₁ = begin 2 + 5 ≡⟨⟩ 1 + 6 ≡⟨⟩ 7 ∎
45*89 : 3 * 45 ≡ 135
45*89 = begin 3 * 45 ≡⟨⟩ (45 + (2 * 45)) ≡⟨⟩ (45 + (45 + 45)) ≡⟨⟩ 135 ∎