agda2hs-1.3: lib/Haskell/Law/Num/Integer.agda
module Haskell.Law.Num.Integer where
open import Haskell.Prim
open import Haskell.Prim.Num
open import Haskell.Prim.Integer
open import Haskell.Law.Equality
open import Haskell.Law.Num.Def
open import Haskell.Law.Num.Nat
-- Open the internal definitions because
-- these must be transparent for proofs.
open Haskell.Prim.Integer.Internal
addInteger-idˡ : ∀ (x : Integer) → 0 + x ≡ x
addInteger-idˡ (pos _) = refl
addInteger-idˡ (negsuc _) = cong negsuc refl
addInteger-idʳ : ∀ (x : Integer) → x + 0 ≡ x
addInteger-idʳ (pos n) = cong pos $ addNat-idʳ n
addInteger-idʳ (negsuc _) = cong negsuc refl
mulInteger-idˡ : ∀ (x : Integer) → 1 * x ≡ x
mulInteger-idˡ (pos x) = cong pos (addNat-idʳ x)
mulInteger-idˡ (negsuc x) = cong negsuc (addNat-idʳ x)
mulInteger-idʳ : ∀ (x : Integer) → x * 1 ≡ x
mulInteger-idʳ (pos x) = cong pos (mulNat-idʳ x)
mulInteger-idʳ (negsuc x) = cong negsuc (mulNat-idʳ x)
subNat-refl : ∀ (x : Nat) → subNat x x ≡ 0
subNat-refl zero = refl
subNat-refl (suc x) = subNat-refl x
n-n≡0-Nat : ∀ (x y : Nat) → subNat (x + y) x ≡ pos y
n-n≡0-Nat x zero rewrite addNat-idʳ x = subNat-refl x
n-n≡0-Nat zero (suc _) = refl
n-n≡0-Nat (suc x) (suc y) = n-n≡0-Nat x (suc y)
n-n≡0-Integer : ∀ (x : Integer) → x + (negateInteger x) ≡ 0
n-n≡0-Integer (pos zero) = refl
n-n≡0-Integer (pos (suc x)) = subNat-refl x
n-n≡0-Integer (negsuc x) = subNat-refl x
mulInteger-zeroˡ : ∀ (x : Integer) → 0 * x ≡ 0
mulInteger-zeroˡ (pos _) = refl
mulInteger-zeroˡ (negsuc _) = refl
mulInteger-zeroʳ : ∀ (x : Integer) → x * 0 ≡ 0
mulInteger-zeroʳ (pos n) = cong pos (mulNat-zeroʳ n)
mulInteger-zeroʳ (negsuc n) rewrite mulNat-zeroʳ n = refl
addInteger-comm : ∀ (x y : Integer) → x + y ≡ y + x
addInteger-comm (pos x) (pos y) = cong pos (addNat-comm x y)
addInteger-comm (pos _) (negsuc _) = refl
addInteger-comm (negsuc _) (pos _) = refl
addInteger-comm (negsuc x) (negsuc y) = cong negsuc (cong suc (addNat-comm x y))
subNat|x-[y+z]≡x-y-z : ∀ (x y z : Nat) → subNat x (y + suc z) ≡ subNat x y + negsuc z
subNat|x-[y+z]≡x-y-z _ zero _ = refl
subNat|x-[y+z]≡x-y-z zero (suc y) z = cong negsuc (addNat-suc y z)
subNat|x-[y+z]≡x-y-z (suc x) (suc y) z = subNat|x-[y+z]≡x-y-z x y z
subNat|x-y+z≡[x+z]-y : ∀ (x y z : Nat) → subNat x y + pos (suc z) ≡ subNat (x + suc z) y
subNat|x-y+z≡[x+z]-y _ zero _ = refl
subNat|x-y+z≡[x+z]-y zero (suc _) _ = refl
subNat|x-y+z≡[x+z]-y (suc x) (suc y) z = subNat|x-y+z≡[x+z]-y x y z
subNat-cong-suc : ∀ (x y : Nat) → subNat (suc x) y ≡ pos 1 + subNat x y
subNat-cong-suc _ zero = refl
subNat-cong-suc zero (suc _) = refl
subNat-cong-suc (suc x) (suc y) = subNat-cong-suc x y
subNat|x+[y-z]≡[1+x]+[y-[1+z]] : ∀ (x y z : Nat) → pos x + subNat y z ≡ pos (suc x) + subNat y (suc z)
subNat|x+[y-z]≡[1+x]+[y-[1+z]] x zero zero = cong pos (addNat-idʳ x)
subNat|x+[y-z]≡[1+x]+[y-[1+z]] x (suc y) zero = cong pos (addNat-suc x y)
subNat|x+[y-z]≡[1+x]+[y-[1+z]] _ zero (suc _) = refl
subNat|x+[y-z]≡[1+x]+[y-[1+z]] x (suc y) (suc z) = subNat|x+[y-z]≡[1+x]+[y-[1+z]] x y z
subNat|x-y+[1+z]≡[1+x]+[z-y] : ∀ (x y z : Nat) → subNat x y + pos (suc z) ≡ pos (suc x) + subNat z y
subNat|x-y+[1+z]≡[1+x]+[z-y] x zero z = cong pos (addNat-suc x z)
subNat|x-y+[1+z]≡[1+x]+[z-y] zero (suc _) zero = refl
subNat|x-y+[1+z]≡[1+x]+[z-y] zero (suc y) (suc z) = subNat-cong-suc z y
subNat|x-y+[1+z]≡[1+x]+[z-y] (suc x) (suc y) z =
subNat x y + pos (suc z) ≡⟨ subNat|x-y+[1+z]≡[1+x]+[z-y] x y z ⟩
pos (suc x) + subNat z y ≡⟨ subNat|x+[y-z]≡[1+x]+[y-[1+z]] (suc x) z y ⟩
pos (suc (suc x)) + subNat z (suc y) ∎
subNat|[1+x+y]-z≡[1+x]+[y-z] : ∀ (x y z : Nat) → subNat (suc x + y) z ≡ pos (suc x) + subNat y z
subNat|[1+x+y]-z≡[1+x]+[y-z] _ _ zero = refl
subNat|[1+x+y]-z≡[1+x]+[y-z] x zero (suc z) = cong (λ eq → subNat eq z) (addNat-idʳ x)
subNat|[1+x+y]-z≡[1+x]+[y-z] x (suc y) (suc z) =
subNat (x + suc y) z ≡⟨ sym (subNat|x-y+z≡[x+z]-y x z y) ⟩
subNat x z + pos (suc y) ≡⟨ subNat|x-y+[1+z]≡[1+x]+[z-y] x z y ⟩
pos (suc x) + subNat y z ∎
subNat|x-y+[-[1+z]]≡x-z+[-[1+y]] : ∀ (x y z : Nat) → subNat x y + negsuc z ≡ subNat x z + negsuc y
subNat|x-y+[-[1+z]]≡x-z+[-[1+y]] x y z = begin
subNat x y + negsuc z ≡⟨ sym (subNat|x-[y+z]≡x-y-z x y z) ⟩
subNat x (y + suc z) ≡⟨ cong (subNat x) (addNat-comm y (suc z)) ⟩
subNat x (suc z + y) ≡⟨ cong (subNat x) (sym (addNat-suc z y)) ⟩
subNat x (z + suc y) ≡⟨ subNat|x-[y+z]≡x-y-z x z y ⟩
subNat x z + negsuc y ∎
subNat-cong-+ : ∀ (x y z : Nat) → subNat (x + y) (x + z) ≡ subNat y z
subNat-cong-+ x y zero rewrite addNat-idʳ x = n-n≡0-Nat x y
subNat-cong-+ zero _ (suc _) = refl
subNat-cong-+ (suc x) y (suc z) = subNat-cong-+ x y (suc z)
subNat-distrib-minus : ∀ (m n o : Nat) → subNat n o * pos m ≡ subNat (n * m) (o * m)
subNat-distrib-minus _ _ zero = refl
subNat-distrib-minus zero zero (suc o) rewrite mulNat-zeroʳ o = refl
subNat-distrib-minus (suc _) zero (suc _) = refl
subNat-distrib-minus zero (suc n) (suc o) rewrite mulNat-zeroʳ o | mulInteger-zeroʳ (subNat n o) | mulNat-zeroʳ n = refl
subNat-distrib-minus (suc m) (suc n) (suc o) =
subNat n o * (pos (suc m)) ≡⟨ subNat-distrib-minus (suc m) n o ⟩
subNat (n * suc m) (o * suc m) ≡⟨ sym (subNat-cong-+ m (n * suc m) (o * suc m)) ⟩
subNat (m + (n * suc m)) (m + (o * suc m)) ∎
subNat-mult-flip-negsuc : ∀ (m n o : Nat) → subNat o n * negsuc m ≡ subNat n o * pos (suc m)
subNat-mult-flip-negsuc _ zero zero = refl
subNat-mult-flip-negsuc _ zero (suc _) = refl
subNat-mult-flip-negsuc _ (suc _) zero = refl
subNat-mult-flip-negsuc m (suc n) (suc o) = subNat-mult-flip-negsuc m n o
subNat-distrib-minus-cong-+ : ∀ (m n o : Nat) → subNat o n * (pos (suc m)) ≡ subNat (m + (o * suc m)) (m + (n * suc m))
subNat-distrib-minus-cong-+ m n o = begin
subNat o n * (pos (suc m)) ≡⟨ subNat-distrib-minus (suc m) o n ⟩
subNat (o * suc m) (n * suc m) ≡⟨ sym (subNat-cong-+ m (o * suc m) (n * suc m)) ⟩
subNat (m + (o * suc m)) (m + (n * suc m)) ∎
addInteger-assoc : ∀ (x y z : Integer) → (x + y) + z ≡ x + (y + z)
addInteger-assoc (pos zero) j k rewrite addInteger-idˡ j | addInteger-idˡ (j + k) = refl
addInteger-assoc i (pos zero) k rewrite addInteger-idʳ i | addInteger-idˡ k = refl
addInteger-assoc i j (pos zero) rewrite addInteger-idʳ (i + j) | addInteger-idʳ j = refl
addInteger-assoc (negsuc m) (negsuc n) (pos (suc o)) =
(negsuc m + negsuc n) + pos (suc o) ≡⟨⟩
negsuc (suc (m + n)) + pos (suc o) ≡⟨⟩
subNat o (suc m + n) ≡⟨ cong (subNat o) (addNat-comm (suc m) n) ⟩
subNat o (n + suc m) ≡⟨ subNat|x-[y+z]≡x-y-z o n m ⟩
subNat o n + negsuc m ≡⟨ addInteger-comm (subNat o n) (negsuc m) ⟩
negsuc m + subNat o n ≡⟨⟩
negsuc m + (negsuc n + pos (suc o)) ∎
addInteger-assoc (negsuc m) (pos (suc n)) (pos (suc o)) =
(negsuc m + pos (suc n)) + pos (suc o) ≡⟨⟩
subNat n m + pos (suc o) ≡⟨ subNat|x-y+z≡[x+z]-y n m o ⟩
subNat (n + suc o) m ≡⟨⟩
negsuc m + pos (suc (n + suc o)) ≡⟨⟩
negsuc m + (pos (suc n) + pos (suc o)) ∎
addInteger-assoc (pos (suc m)) (negsuc n) (negsuc o) =
(pos (suc m) + negsuc n) + negsuc o ≡⟨⟩
subNat m n + negsuc o ≡⟨ sym $ subNat|x-[y+z]≡x-y-z m n o ⟩
subNat m (n + suc o) ≡⟨ cong (subNat m) (addNat-suc n o) ⟩
subNat m (suc (n + o)) ≡⟨⟩
pos (suc m) + (negsuc (suc (n + o))) ≡⟨⟩
pos (suc m) + (negsuc n + negsuc o) ∎
addInteger-assoc (pos (suc m)) (negsuc n) (pos (suc o)) =
(pos (suc m) + negsuc n) + pos (suc o) ≡⟨⟩
subNat m n + pos (suc o) ≡⟨ subNat|x-y+[1+z]≡[1+x]+[z-y] m n o ⟩
pos (suc m) + subNat o n ≡⟨⟩
pos (suc m) + (negsuc n + pos (suc o)) ∎
addInteger-assoc (pos (suc x)) (pos (suc y)) (negsuc z) = begin
(pos (suc x) + pos (suc y)) + negsuc z ≡⟨⟩
pos (suc (x + (suc y))) + negsuc z ≡⟨ cong (_+ negsuc z) (cong pos (cong suc (addNat-suc x y))) ⟩
pos (suc (suc (x + y))) + negsuc z ≡⟨⟩
subNat (suc (x + y)) z ≡⟨⟩
subNat (suc x + y) z ≡⟨ subNat|[1+x+y]-z≡[1+x]+[y-z] x y z ⟩
pos (suc x) + subNat y z ≡⟨⟩
pos (suc x) + (pos (suc y) + negsuc z) ∎
addInteger-assoc (negsuc m) (negsuc n) (negsuc o) = cong negsuc $ cong suc $
suc ((m + n) + o) ≡⟨ cong suc (addNat-assoc m n o) ⟩
suc (m + (n + o)) ≡⟨ sym (addNat-suc m (n + o)) ⟩
m + (suc (n + o)) ∎
addInteger-assoc (negsuc m) (pos (suc n)) (negsuc o) =
(negsuc m + pos (suc n)) + negsuc o ≡⟨⟩
subNat n m + negsuc o ≡⟨ subNat|x-y+[-[1+z]]≡x-z+[-[1+y]] n m o ⟩
subNat n o + negsuc m ≡⟨ addInteger-comm (subNat n o) (negsuc m) ⟩
negsuc m + subNat n o ≡⟨⟩
negsuc m + (pos (suc n) - pos (suc o)) ∎
addInteger-assoc (pos (suc m)) (pos (suc n)) (pos (suc o)) = cong pos (addNat-assoc (suc m) (suc n) (suc o))
distribute-1ˡ : ∀ (x y : Nat) → x * (1 + y) ≡ x + (y * x)
distribute-1ˡ x y = begin
x * (suc y) ≡⟨ mulNat-suc x y ⟩
x + (x * y) ≡⟨ cong (x +_) (mulNat-comm x y) ⟩
x + (y * x) ∎
mulInteger-comm : ∀ (x y : Integer) → x * y ≡ y * x
mulInteger-comm (pos x) (pos y) = cong pos (mulNat-comm x y)
mulInteger-comm (pos x) (negsuc y) = cong negNat $ distribute-1ˡ x y
mulInteger-comm (negsuc x) (pos y) = cong negNat $ sym $ distribute-1ˡ y x
mulInteger-comm (negsuc x) (negsuc y) = cong pos $ cong suc $
y + (x * (suc y)) ≡⟨ cong (y +_) (distribute-1ˡ x y) ⟩
y + (x + (y * x)) ≡⟨ cong (y +_) (cong (x +_) (mulNat-comm y x)) ⟩
y + (x + (x * y)) ≡⟨ sym (addNat-assoc y x (x * y)) ⟩
(y + x) + (x * y) ≡⟨ cong (_+ x * y) (addNat-comm y x) ⟩
(x + y) + (x * y) ≡⟨ addNat-assoc x y (x * y) ⟩
x + (y + (x * y)) ≡⟨ cong (x +_) (sym (distribute-1ˡ y x)) ⟩
x + (y * (suc x)) ∎
distrib-lemma : ∀ (m n o : Nat) → suc (m + ((n + o) * suc m)) ≡ (n * suc m) + (suc (m + (o * suc m)))
distrib-lemma m n o =
suc (m + ((n + o) * suc m)) ≡⟨ cong suc (cong (m +_) (mulNat-distributeʳ-addNat (suc m) n o)) ⟩
suc (m + ((n * suc m) + (o * suc m))) ≡⟨⟩
suc m + ((n * suc m) + (o * suc m)) ≡⟨ sym (addNat-assoc (suc m) (n * suc m) (o * suc m) ) ⟩
(suc m + (n * suc m)) + (o * suc m) ≡⟨ cong (_+ o * suc m) (addNat-comm (suc m) (n * suc m)) ⟩
((n * suc m) + suc m) + (o * suc m) ≡⟨ addNat-assoc (n * suc m) (suc m) (o * suc m) ⟩
(n * suc m) + (suc (m + (o * suc m))) ∎
distrib-lemma2 : ∀ (m n o : Nat) → m + ((n * suc m) + (suc m + (o * suc m))) ≡ suc ((m + (n * suc m)) + (m + (o * suc m)))
distrib-lemma2 m n o =
m + ( (n * suc m) + (suc m + (o * suc m))) ≡⟨⟩
m + ( (n * suc m) + suc (m + (o * suc m))) ≡⟨ sym (addNat-assoc m (n * suc m) (suc (m + (o * suc m)))) ⟩
(m + (n * suc m)) + suc (m + (o * suc m)) ≡⟨ addNat-suc (m + (n * suc m)) (m + (o * suc m)) ⟩
suc ((m + (n * suc m)) + (m + (o * suc m))) ∎
mulInteger-distributeʳ-addInteger : ∀ (x y z : Integer) → (y + z) * x ≡ (y * x) + (z * x)
mulInteger-distributeʳ-addInteger (pos zero) j k rewrite mulInteger-zeroʳ j | mulInteger-zeroʳ k | mulInteger-zeroʳ (j + k) = refl
mulInteger-distributeʳ-addInteger i (pos zero) k rewrite addInteger-idˡ k | mulInteger-zeroˡ i | addInteger-idˡ (k * i) = refl
mulInteger-distributeʳ-addInteger i j (pos zero) rewrite addInteger-idʳ j | mulInteger-zeroˡ i | addInteger-idʳ (j * i) = refl
mulInteger-distributeʳ-addInteger (negsuc m) (negsuc n) (pos (suc o)) = begin
subNat o n * negsuc m ≡⟨ subNat-mult-flip-negsuc m n o ⟩
subNat n o * pos (suc m) ≡⟨ subNat-distrib-minus-cong-+ m o n ⟩
subNat (m + (n * suc m)) (m + (o * suc m)) ∎
mulInteger-distributeʳ-addInteger (negsuc m) (pos (suc n)) (pos (suc o)) = cong negsuc $ begin
m + ((n + suc o) * suc m) ≡⟨ cong (m +_) (mulNat-distributeʳ-addNat (suc m) n (suc o)) ⟩
m + ( (n * suc m) + (suc m + (o * suc m))) ≡⟨ distrib-lemma2 m n o ⟩
suc ((m + (n * suc m)) + (m + (o * suc m))) ∎ -- Y
mulInteger-distributeʳ-addInteger (pos (suc m)) (negsuc n) (negsuc o) = cong negsuc $ begin
m + (suc (m + ((n + o) * suc m))) ≡⟨⟩
m + (suc m + ((n + o) * suc m)) ≡⟨ cong (m +_) (distrib-lemma m n o) ⟩
m + ( (n * suc m) + (suc m + (o * suc m))) ≡⟨ distrib-lemma2 m n o ⟩
suc ((m + (n * suc m)) + (m + (o * suc m))) ∎ -- Y
mulInteger-distributeʳ-addInteger (pos (suc m)) (negsuc n) (pos (suc o)) = subNat-distrib-minus-cong-+ m n o
mulInteger-distributeʳ-addInteger (pos (suc m)) (pos (suc n)) (negsuc o) = subNat-distrib-minus-cong-+ m o n
mulInteger-distributeʳ-addInteger (negsuc m) (negsuc n) (negsuc o) = cong pos $ cong suc $
m + (suc (m + ((n + o) * suc m))) ≡⟨⟩
m + (suc m + ((n + o) * suc m)) ≡⟨ cong (m +_) (distrib-lemma m n o) ⟩
m + ((n * suc m) + (suc m + (o * suc m))) ≡⟨ sym (addNat-assoc m (n * suc m) (suc m + (o * suc m))) ⟩
(m + (n * suc m)) + (suc (m + (o * suc m))) ∎ -- X
mulInteger-distributeʳ-addInteger (negsuc m) (pos (suc n)) (negsuc o) =
subNat n o * negsuc m ≡⟨ subNat-mult-flip-negsuc m o n ⟩
subNat o n * pos (suc m) ≡⟨ subNat-distrib-minus-cong-+ m n o ⟩
subNat (m + (o * suc m)) (m + (n * suc m)) ∎
mulInteger-distributeʳ-addInteger (pos (suc m)) (pos (suc n)) (pos (suc o)) = cong pos $ cong suc $
m + ((n + suc o) * suc m) ≡⟨ cong (m +_) (mulNat-distributeʳ-addNat (suc m) n (suc o)) ⟩
m + ((n * suc m) + (suc m + (o * suc m))) ≡⟨ sym (addNat-assoc m (n * suc m) (suc m + (o * suc m))) ⟩
(m + (n * suc m)) + (suc m + (o * suc m)) ≡⟨⟩
(m + (n * suc m)) + (suc (m + (o * suc m))) ∎ -- X
mulInteger-distributeˡ-addInteger : ∀ (x y z : Integer) → x * (y + z) ≡ (x * y) + (x * z)
mulInteger-distributeˡ-addInteger x y z
-- This proof works the very same as addNat-distributeˡ-mulNat.
rewrite (mulInteger-comm x (y + z)) -- makes or goal become: (y + z) * x ≡ (x * y) + (x * z)
rewrite (mulInteger-comm x y) -- makes or goal become: (y + z) * x ≡ (y * x) + (x * z)
rewrite (mulInteger-comm x z) -- makes or goal become: (y + z) * x ≡ (y * x) + (z * x)
= mulInteger-distributeʳ-addInteger x y z
mulInteger-assoc-lemma-2 : ∀ (m n o : Nat) → (n + m * suc n) * suc o ≡ (n * suc o) + (m * suc (o + (n * suc o)))
mulInteger-assoc-lemma-2 m n o = begin
(n + (m * suc n)) * (suc o) ≡⟨ mulNat-distributeʳ-addNat (suc o) n (m * suc n) ⟩
(n * (suc o)) + ((m * suc n) * (suc o)) ≡⟨ cong (n * suc o +_) (mulNat-assoc m (suc n) (suc o)) ⟩
(n * suc o) + (m * suc (o + (n * suc o))) ∎
mulInteger-assoc-lemma : ∀ (m n o : Nat)
→ o + ((n + m * suc n) * suc o) ≡ (o + (n * suc o)) + (m * suc (o + (n * suc o)))
mulInteger-assoc-lemma m n o = begin
o + ((n + m * suc n) * suc o) ≡⟨ cong (o +_) (mulInteger-assoc-lemma-2 m n o) ⟩
o + ((n * suc o) + (m * suc (o + (n * suc o)))) ≡⟨ sym (addNat-assoc o (n * suc o) (m * suc (o + (n * suc o)))) ⟩
(o + (n * suc o)) + (m * suc (o + (n * suc o))) ∎
mulInteger-assoc : ∀ (x y z : Integer) → (x * y) * z ≡ x * (y * z)
mulInteger-assoc (pos zero) j k rewrite mulInteger-zeroˡ j | mulInteger-zeroˡ k | mulInteger-zeroˡ (j * k) = refl
mulInteger-assoc i (pos zero) k rewrite mulInteger-zeroʳ i | mulInteger-zeroˡ k | mulInteger-zeroʳ i = refl
mulInteger-assoc i j (pos zero) rewrite mulInteger-zeroʳ j | mulInteger-zeroʳ i | mulInteger-zeroʳ (i * j) = refl
mulInteger-assoc (negsuc m) (negsuc n) (pos (suc o)) = cong pos (cong suc (mulInteger-assoc-lemma m n o))
mulInteger-assoc (negsuc m) (pos (suc n)) (pos (suc o)) = cong negsuc (mulInteger-assoc-lemma m n o)
mulInteger-assoc (pos (suc m)) (negsuc n) (negsuc o) = cong pos (cong suc (mulInteger-assoc-lemma m n o))
mulInteger-assoc (pos (suc m)) (negsuc n) (pos (suc o)) = cong negsuc (mulInteger-assoc-lemma m n o)
mulInteger-assoc (pos (suc m)) (pos (suc n)) (negsuc o) = cong negsuc (mulInteger-assoc-lemma m n o)
mulInteger-assoc (negsuc m) (negsuc n) (negsuc o) = cong negsuc (mulInteger-assoc-lemma m n o)
mulInteger-assoc (negsuc m) (pos (suc n)) (negsuc o) = cong pos (cong suc (mulInteger-assoc-lemma m n o))
mulInteger-assoc (pos (suc m)) (pos (suc n)) (pos (suc o)) = cong pos (cong suc (mulInteger-assoc-lemma m n o))
instance
iLawfulNumInteger : IsLawfulNum Integer
iLawfulNumInteger .IsLawfulNum.+-assoc = addInteger-assoc
iLawfulNumInteger .IsLawfulNum.+-comm = addInteger-comm
iLawfulNumInteger .IsLawfulNum.+-idˡ x = addInteger-idˡ x
iLawfulNumInteger .IsLawfulNum.+-idʳ x = addInteger-idʳ x
iLawfulNumInteger .IsLawfulNum.neg-inv x = n-n≡0-Integer x
iLawfulNumInteger .IsLawfulNum.*-assoc = mulInteger-assoc
iLawfulNumInteger .IsLawfulNum.*-idˡ x = mulInteger-idˡ x
iLawfulNumInteger .IsLawfulNum.*-idʳ x = mulInteger-idʳ x
iLawfulNumInteger .IsLawfulNum.distributeˡ = mulInteger-distributeˡ-addInteger
iLawfulNumInteger .IsLawfulNum.distributeʳ = mulInteger-distributeʳ-addInteger