{-# OPTIONS --without-K #-}
module sets.nat.properties where
open import equality.core
open import equality.calculus
open import equality.reasoning
open import function.isomorphism.core
open import sets.nat.core
open import sets.empty
+-left-unit : ∀ n → 0 + n ≡ n
+-left-unit n = refl
+-right-unit : ∀ n → n + 0 ≡ n
+-right-unit zero = refl
+-right-unit (suc n) = ap suc (+-right-unit n)
+-associativity : ∀ n m p → n + m + p ≡ n + (m + p)
+-associativity 0 m p = refl
+-associativity (suc n) m p = ap suc (+-associativity n m p)
+-left-cancel : ∀ n → injective (_+_ n)
+-left-cancel 0 p = p
+-left-cancel (suc n) p = +-left-cancel n (ap pred p)
right-distr : ∀ n m p → (n + m) * p ≡ n * p + m * p
right-distr 0 m p = refl
right-distr (suc n) m p = begin
p + (n + m) * p
≡⟨ ap (_+_ p) (right-distr n m p) ⟩
p + (n * p + m * p)
≡⟨ sym (+-associativity p (n * p) (m * p)) ⟩
p + n * p + m * p
∎
where open ≡-Reasoning
*-left-unit : ∀ n → 1 * n ≡ n
*-left-unit n = +-right-unit n
*-right-unit : ∀ n → n * 1 ≡ n
*-right-unit zero = refl
*-right-unit (suc n) = ap suc (*-right-unit n)
*-associativity : ∀ n m p → n * m * p ≡ n * (m * p)
*-associativity 0 m p = refl
*-associativity (suc n) m p =
right-distr m (n * m) p
· ap (λ z → (m * p) + z)
(*-associativity n m p)
+-commutativity : ∀ n m → n + m ≡ m + n
+-commutativity 0 m = sym (+-right-unit m)
+-commutativity (suc n) m = begin
suc (n + m)
≡⟨ ap suc (+-commutativity n m) ⟩
suc (m + n)
≡⟨ lem m n ⟩
m + suc n
∎
where
open ≡-Reasoning
lem : ∀ n m → suc n + m ≡ n + suc m
lem 0 m = refl
lem (suc n) m = ap suc (lem n m)
left-distr : ∀ n m p → n * (m + p) ≡ n * m + n * p
left-distr 0 m p = refl
left-distr (suc n) m p = begin
m + p + n * (m + p)
≡⟨ +-associativity m p _ ⟩
m + (p + n * (m + p))
≡⟨ ap (λ z → m + (p + z))
(left-distr n m p) ⟩
m + (p + (n * m + n * p))
≡⟨ ap (_+_ m)
(sym (+-associativity p (n * m) _)) ⟩
m + (p + n * m + n * p)
≡⟨ ap (λ z → m + (z + n * p))
(+-commutativity p (n * m)) ⟩
m + (n * m + p + n * p)
≡⟨ ap (_+_ m) (+-associativity (n * m) p _) ⟩
m + (n * m + (p + n * p))
≡⟨ sym (+-associativity m (n * m) _) ⟩
m + n * m + (p + n * p)
∎
where open ≡-Reasoning
left-zero : ∀ n → 0 * n ≡ 0
left-zero n = refl
right-zero : ∀ n → n * 0 ≡ 0
right-zero 0 = refl
right-zero (suc n) = right-zero n
*-commutativity : ∀ n m → n * m ≡ m * n
*-commutativity 0 m = sym (right-zero m)
*-commutativity (suc n) m = begin
m + n * m
≡⟨ ap₂ _+_ (sym (*-right-unit m))
(*-commutativity n m) ⟩
m * 1 + m * n
≡⟨ sym (left-distr m 1 n) ⟩
m * suc n
∎
where open ≡-Reasoning
suc-fixpoint : ∀ {n} → ¬ (suc n ≡ n)
suc-fixpoint {zero} ()
suc-fixpoint {suc n} p = suc-fixpoint (suc-inj p)