module Data.Nat.Properties.Core where open import Prelude add-0-r : ∀ n → n + 0 ≡ n add-0-r 0 = refl add-0-r (suc n) rewrite add-0-r n = refl private add-suc-r : (n m : Nat) → n + suc m ≡ suc n + m add-suc-r zero m = refl add-suc-r (suc n) m rewrite add-suc-r n m = refl add-commute : (x y : Nat) → x + y ≡ y + x add-commute zero y = sym (add-0-r _) add-commute (suc x) y rewrite add-commute x y = sym (add-suc-r y _) add-assoc : (x y z : Nat) → x + (y + z) ≡ x + y + z add-assoc zero y z = refl add-assoc (suc x) y z rewrite add-assoc x y z = refl mul-1-r : (x : Nat) → x * 1 ≡ x mul-1-r zero = refl mul-1-r (suc x) rewrite mul-1-r x = add-commute x _ mul-0-r : (x : Nat) → x * 0 ≡ 0 mul-0-r zero = refl mul-0-r (suc x) rewrite mul-0-r x = refl mul-distr-r : (x y z : Nat) → (x + y) * z ≡ x * z + y * z mul-distr-r zero y z = refl mul-distr-r (suc x) y z rewrite mul-distr-r x y z | sym (add-assoc (x * z) (y * z) z) | add-commute (y * z) z = add-assoc (x * z) _ _ mul-distr-l : (x y z : Nat) → x * (y + z) ≡ x * y + x * z mul-distr-l zero y z = refl mul-distr-l (suc x) y z rewrite mul-distr-l x y z | sym (add-assoc (x * y) (x * z) (y + z)) | add-assoc (x * z) y z | add-commute (x * z) y | sym (add-assoc y (x * z) z) = add-assoc (x * y) _ _ mul-assoc : (x y z : Nat) → x * (y * z) ≡ x * y * z mul-assoc zero y z = refl mul-assoc (suc x) y z rewrite mul-distr-r (x * y) y z | mul-assoc x y z = refl mul-commute : (x y : Nat) → x * y ≡ y * x mul-commute zero y = sym (mul-0-r y) mul-commute (suc x) y rewrite mul-commute x y | mul-distr-l y 1 x | mul-1-r y = add-commute (y * x) _ add-inj₂ : (x y z : Nat) → x + y ≡ x + z → y ≡ z add-inj₂ zero y z p = p add-inj₂ (suc x) y z p = add-inj₂ x y z (suc-inj p) add-inj₁ : ∀ x y z → x + z ≡ y + z → x ≡ y add-inj₁ x y z rewrite add-commute x z | add-commute y z = add-inj₂ z x y