Andrew Sneap, 26 November 2021 In this file, I define addition of integers, and prove some common properties of multiplication. \begin{code} {-# OPTIONS --safe --without-K #-} open import MLTT.Spartan renaming (_+_ to _∔_) open import Naturals.Addition renaming (_+_ to _ℕ+_) open import Naturals.Multiplication renaming (_*_ to _ℕ*_) open import Naturals.Properties open import Integers.Type open import Integers.Addition open import Integers.Negation module Integers.Multiplication where \end{code} Instead of defining auxilliary functions with a natural number argument, multiplication is defined by pattern matching. \begin{code} _*_ : ℤ → ℤ → ℤ x * pos 0 = pos 0 x * pos (succ y) = x + (x * pos y) x * negsucc 0 = - x x * negsucc (succ y) = (- x) + (x * negsucc y) infixl 32 _*_ pos-multiplication-equiv-to-ℕ : (x y : ℕ) → pos x * pos y = pos (x ℕ* y) pos-multiplication-equiv-to-ℕ x = ℕ-induction base step where base : pos x * pos 0 = pos (x ℕ* 0) base = refl step : (k : ℕ) → pos x * pos k = pos (x ℕ* k) → pos x * pos (succ k) = pos (x ℕ* succ k) step k IH = pos x * pos (succ k) =⟨ ap (pos x +_) IH ⟩ pos x + pos (x ℕ* k) =⟨ distributivity-pos-addition x (x ℕ* k) ⟩ pos (x ℕ* succ k) ∎ \end{code} The following proofs that 0 is the base and 1 is the identity for multiplication exemplify the "induction on both positives and negatives" strategy. To choose a specific example, the left identity element of multiplication is 1. The two bases cases are 0 and -1, and definitionally we have that 1 * 0 = 0, and 1 * (- 1) = (- 1). Induction on positives: 1 * pos (succ x) = 1 + 1 * pos x (by definition) = 1 + pos x (by applying (_+ 1) to the IH) = pos (succ x) (by commutativity of addition). Induction on negatives: 1 * negsucc (succ x) = (- 1) + 1 * negsucc x (by definition) = (- 1) + negsucc x (by applying (_- 1) to the IH) = negsucc (succ x) (by commutativity of addition). \begin{code} ℤ-zero-right-is-zero : (x : ℤ) → x * pos 0 = pos 0 ℤ-zero-right-is-zero x = refl ℤ-zero-left-base : (x : ℤ) → pos 0 * x = pos 0 ℤ-zero-left-base (pos 0) = refl ℤ-zero-left-base (pos (succ x)) = pos 0 * pos (succ x) =⟨ ℤ-zero-left-neutral (pos 0 * pos x) ⟩ pos 0 * pos x =⟨ ℤ-zero-left-base (pos x) ⟩ pos 0 ∎ ℤ-zero-left-base (negsucc 0) = refl ℤ-zero-left-base (negsucc (succ x)) = pos 0 * negsucc (succ x) =⟨ ℤ-zero-left-neutral (pos 0 * negsucc x) ⟩ pos 0 * negsucc x =⟨ ℤ-zero-left-base (negsucc x) ⟩ pos 0 ∎ ℤ-mult-right-id : (x : ℤ) → x * pos 1 = x ℤ-mult-right-id x = refl ℤ-mult-left-id : (x : ℤ) → pos 1 * x = x ℤ-mult-left-id (pos 0) = refl ℤ-mult-left-id (pos (succ x)) = pos 1 * pos (succ x) =⟨ ℤ+-comm (pos 1) (pos 1 * pos x) ⟩ pos 1 * pos x + pos 1 =⟨ ap succℤ (ℤ-mult-left-id (pos x)) ⟩ succℤ (pos x) ∎ ℤ-mult-left-id (negsucc 0) = refl ℤ-mult-left-id (negsucc (succ x)) = pos 1 * negsucc (succ x) =⟨ ℤ+-comm (negsucc 0) (pos 1 * negsucc x) ⟩ pos 1 * negsucc x + negsucc 0 =⟨ ap predℤ (ℤ-mult-left-id (negsucc x)) ⟩ predℤ (negsucc x) ∎ \end{code} Now we have an example where the positive and negative inductions are separated into subfunctions, for readibility, since the individual proofs are lengthy. Distributivity of addition relies on commutativity and associativity (and distributivity of negation). \begin{code} distributivity-mult-ℤ₀ : (x y : ℤ) (z : ℕ) → (x + y) * pos z = x * pos z + y * pos z distributivity-mult-ℤ₀ x y = ℕ-induction base step where base : (x + y) * pos 0 = x * pos 0 + y * pos 0 base = refl step : (k : ℕ) → (x + y) * pos k = x * pos k + y * pos k → (x + y) * pos (succ k) = x * pos (succ k) + y * pos (succ k) step k IH = (x + y) * pos (succ k) =⟨ i ⟩ (x + y) + (u + w) =⟨ ii ⟩ (x + y) + u + w =⟨ iii ⟩ x + (y + u) + w =⟨ iv ⟩ x + (u + y) + w =⟨ v ⟩ x + u + y + w =⟨ vi ⟩ x + u + (y + w) =⟨ refl ⟩ x * pos (succ k) + y * pos (succ k) ∎ where u w : ℤ u = x * pos k w = y * pos k i = ap ((x + y) +_) IH ii = ℤ+-assoc (x + y) u w ⁻¹ iii = ap (_+ w) (ℤ+-assoc x y u) iv = ap (λ z → (x + z) + w) (ℤ+-comm y u) v = ap (_+ w) (ℤ+-assoc x u y ⁻¹) vi = ℤ+-assoc (x + u) y w distributivity-mult-ℤ₁ : (x y : ℤ) → (z : ℕ) → (x + y) * negsucc z = x * negsucc z + y * negsucc z distributivity-mult-ℤ₁ x y = ℕ-induction base step where base : (x + y) * negsucc 0 = x * negsucc 0 + y * negsucc 0 base = (x + y) * negsucc 0 =⟨ refl ⟩ - (x + y) =⟨ negation-dist x y ⁻¹ ⟩ (- x) + (- y) =⟨ refl ⟩ x * negsucc 0 + y * negsucc 0 ∎ step : (k : ℕ) → (x + y) * negsucc k = x * negsucc k + y * negsucc k → (- (x + y)) + (x + y) * negsucc k = (- x) + x * negsucc k + ((- y) + y * negsucc k) step k IH = (- (x + y)) + (x + y) * negsucc k =⟨ i ⟩ (- (x + y)) + (u + w) =⟨ ii ⟩ (- x) - y + (u + w) =⟨ iii ⟩ (- x) + ((- y) + (u + w)) =⟨ iv ⟩ (- x) + ((- y) + u + w) =⟨ v ⟩ (- x) + (u - y + w) =⟨ vi ⟩ (- x) + (u + ((- y) + w)) =⟨ vii ⟩ (- x) + u + ((- y) + w) =⟨ refl ⟩ (- x) + x * negsucc k + ((- y) + y * negsucc k) ∎ where u w : ℤ u = x * negsucc k w = y * negsucc k i = ap ((- (x + y)) +_) IH ii = ap (_+ ((u + w))) (negation-dist x y ⁻¹) iii = ℤ+-assoc (- x) (- y) (u + w) iv = ap ((- x) +_) (ℤ+-assoc (- y) u w ⁻¹) v = ap (λ z → (- x) + (z + w)) (ℤ+-comm (- y) u) vi = ap ((- x) +_) (ℤ+-assoc u (- y) w) vii = ℤ+-assoc (- x) u ((- y) + w) ⁻¹ distributivity-mult-over-ℤ : (x y z : ℤ) → (x + y) * z = (x * z) + (y * z) distributivity-mult-over-ℤ x y (pos z) = distributivity-mult-ℤ₀ x y z distributivity-mult-over-ℤ x y (negsucc z) = distributivity-mult-ℤ₁ x y z \end{code} Following the same strategy as distributivity, we have proofs that relate multiplication and negation, commutativity of integers, and how negation distributes over multiplication. \begin{code} mult-negation : (x : ℤ) → - x = negsucc 0 * x mult-negation = ℤ-induction base step₁ step₂ where base : - pos 0 = negsucc 0 * pos 0 base = refl step₁ : (k : ℤ) → - k = negsucc 0 * k → - succℤ k = negsucc 0 * succℤ k step₁ (pos 0) IH = refl step₁ (pos (succ x)) IH = predℤ (negsucc x) =⟨ i ⟩ predℤ (negsucc 0 * pos (succ x)) =⟨ ii ⟩ negsucc 0 * succℤ (pos (succ x)) ∎ where i = ap predℤ IH ii = ℤ-pred-is-minus-one (negsucc 0 * pos (succ x)) step₁ (negsucc 0) IH = refl step₁ (negsucc (succ x)) IH = ℤ+-lc (- succℤ (negsucc (succ x))) (negsucc 0 * succℤ (negsucc (succ x))) (pos 1) I where I : pos 1 + (- succℤ (negsucc (succ x))) = pos 1 + negsucc 0 * succℤ (negsucc (succ x)) I = pos 1 + (- succℤ (negsucc (succ x))) =⟨ i ⟩ succℤ (pos x + pos 1) =⟨ IH ⟩ negsucc 0 * negsucc (succ x) ∎ where i = ap succℤ (ℤ+-comm (pos 1) (pos x)) step₂ : (k : ℤ) → - succℤ k = negsucc 0 * succℤ k → - k = negsucc 0 * k step₂ (pos 0) IH = refl step₂ (pos (succ x)) IH = ℤ+-lc (- pos (succ x)) (negsucc 0 * pos (succ x)) (negsucc 0) I where I : negsucc 0 - pos (succ x) = negsucc 0 * pos (succ (succ x)) I = negsucc 0 - pos (succ x) =⟨ ℤ+-comm (negsucc 0) (negsucc x) ⟩ negsucc x + negsucc 0 =⟨ IH ⟩ negsucc 0 * succℤ (pos (succ x)) ∎ step₂ (negsucc 0) IH = refl step₂ (negsucc (succ x)) IH = I where I : pos (succ x) + pos 1 = pos 1 + negsucc 0 * succℤ (negsucc (succ x)) I = pos (succ x) + pos 1 =⟨ i ⟩ pos 1 + pos (succ x) =⟨ ii ⟩ pos 1 + negsucc 0 * succℤ (negsucc (succ x)) ∎ where i = ℤ+-comm (pos (succ x)) (pos 1) ii = ap (pos (succ 0) +_) IH ℤ*-comm₀ : (x : ℤ) → (y : ℕ) → x * pos y = pos y * x ℤ*-comm₀ x = ℕ-induction base step where base : x * pos 0 = pos 0 * x base = x * pos 0 =⟨ ℤ-zero-left-base x ⁻¹ ⟩ pos 0 * x ∎ step : (k : ℕ) → x * pos k = pos k * x → x * pos (succ k) = (pos k + pos 1) * x step k IH = x + x * pos k =⟨ i ⟩ x + pos k * x =⟨ ii ⟩ pos 1 * x + pos k * x =⟨ iii ⟩ (pos 1 + pos k) * x =⟨ iv ⟩ (pos k + pos 1) * x ∎ where i = ap (x +_) IH ii = ap (_+ (pos k * x)) (ℤ-mult-left-id x ⁻¹) iii = distributivity-mult-over-ℤ (pos 1) (pos k) x ⁻¹ iv = ap (_* x) (ℤ+-comm (pos 1) (pos k)) ℤ*-comm₁ : (x : ℤ) → (y : ℕ) → x * negsucc y = negsucc y * x ℤ*-comm₁ x = ℕ-induction base step where base : x * negsucc 0 = negsucc 0 * x base = mult-negation x step : (k : ℕ) → x * negsucc k = negsucc k * x → x * negsucc (succ k) = negsucc (succ k) * x step k IH = x * negsucc (succ k) =⟨ refl ⟩ (- x) + x * negsucc k =⟨ i ⟩ (- x) + negsucc k * x =⟨ ii ⟩ negsucc 0 * x + negsucc k * x =⟨ iii ⟩ (negsucc 0 + negsucc k) * x =⟨ iv ⟩ negsucc (succ k) * x ∎ where i = ap ((- x) +_) IH ii = ap (_+ (negsucc k * x)) (mult-negation x) iii = distributivity-mult-over-ℤ (negsucc 0) (negsucc k) x ⁻¹ iv = ap (_* x) (ℤ+-comm (negsucc 0) (negsucc k)) ℤ*-comm : (x y : ℤ) → x * y = y * x ℤ*-comm x (pos y) = ℤ*-comm₀ x y ℤ*-comm x (negsucc y) = ℤ*-comm₁ x y distributivity-mult-over-ℤ' : (x y z : ℤ) → z * (x + y) = z * x + z * y distributivity-mult-over-ℤ' x y z = γ where γ : z * (x + y) = z * x + z * y γ = z * (x + y) =⟨ ℤ*-comm z (x + y) ⟩ (x + y) * z =⟨ distributivity-mult-over-ℤ x y z ⟩ x * z + y * z =⟨ ap (_+ (y * z)) (ℤ*-comm x z) ⟩ z * x + y * z =⟨ ap ((z * x) +_ ) (ℤ*-comm y z) ⟩ z * x + z * y ∎ negation-dist-over-mult₀ : (x : ℤ) → (y : ℕ) → x * (- pos y) = - x * pos y negation-dist-over-mult₀ x = ℕ-induction base step where base : x * (- pos 0) = - (x * pos 0) base = refl step : (k : ℕ) → x * (- pos k) = - (x * pos k) → x * (- pos (succ k)) = - (x * pos (succ k)) step 0 IH = refl step (succ k) IH = x * (- pos (succ (succ k))) =⟨ i ⟩ (- x) + (- x * pos (succ k)) =⟨ ii ⟩ - (x + (x + x * pos k)) ∎ where i = ap ((- x) +_) IH ii = negation-dist x (x + (x * pos k)) negation-dist-over-mult₁ : (x : ℤ) → (y : ℕ) → x * (- negsucc y) = - x * negsucc y negation-dist-over-mult₁ x = ℕ-induction base step where base : x * (- negsucc 0) = - x * negsucc 0 base = minus-minus-is-plus x ⁻¹ step : (k : ℕ) → x * (- negsucc k) = - x * negsucc k → x + x * (- negsucc k) = - ((- x) + x * negsucc k) step k IH = x + x * (- negsucc k) =⟨ i ⟩ x + (- x * negsucc k) =⟨ ii ⟩ (- (- x)) + (- x * negsucc k) =⟨ iii ⟩ - ((- x) + x * negsucc k) ∎ where i = ap (x +_) IH ii = ap (_+ (- (x * negsucc k)) ) (minus-minus-is-plus x ⁻¹) iii = negation-dist (- x) (x * negsucc k) negation-dist-over-mult : (x y : ℤ) → x * (- y) = - (x * y) negation-dist-over-mult x (pos y) = negation-dist-over-mult₀ x y negation-dist-over-mult x (negsucc y) = negation-dist-over-mult₁ x y negation-dist-over-mult' : (x y : ℤ) → (- x) * y = - (x * y) negation-dist-over-mult' x y = II where I : y * (- x) = - (y * x) I = negation-dist-over-mult y x II : (- x) * y = - x * y II = (- x) * y =⟨ ℤ*-comm (- x) y ⟩ y * (- x) =⟨ I ⟩ - (y * x) =⟨ ap -_ (ℤ*-comm y x) ⟩ - (x * y) ∎ minus-times-minus-is-positive : (x y : ℤ) → (- x) * (- y) = x * y minus-times-minus-is-positive x y = γ where γ : (- x) * (- y) = x * y γ = (- x) * (- y) =⟨ negation-dist-over-mult' x (- y) ⟩ - (x * (- y)) =⟨ ap -_ (negation-dist-over-mult x y) ⟩ - (- (x * y)) =⟨ minus-minus-is-plus (x * y) ⟩ x * y ∎ ℤ*-assoc₀ : (x y : ℤ) → (z : ℕ ) → x * (y * pos z) = x * y * pos z ℤ*-assoc₀ x y = ℕ-induction base step where base : x * (y * pos 0) = x * y * pos 0 base = refl step : (k : ℕ) → x * (y * pos k) = x * y * pos k → x * (y * pos (succ k)) = x * y * pos (succ k) step k IH = x * (y * pos (succ k)) =⟨ i ⟩ x * y + x * (y * pos k) =⟨ ii ⟩ x * y + x * y * pos k ∎ where i = distributivity-mult-over-ℤ' y (y * pos k) x ii = ap ((x * y) +_) IH ℤ*-assoc₁ : (x y : ℤ) → (z : ℕ) → x * (y * negsucc z) = x * y * negsucc z ℤ*-assoc₁ x y = ℕ-induction base step where base : x * (y * negsucc 0) = x * y * negsucc 0 base = negation-dist-over-mult x y step : (k : ℕ) → x * (y * negsucc k) = x * y * negsucc k → x * (y * negsucc (succ k)) = x * y * negsucc (succ k) step k IH = x * (y * negsucc (succ k)) =⟨ i ⟩ x * (- y) + x * (y * negsucc k) =⟨ ii ⟩ x * (- y) + x * y * negsucc k =⟨ iii ⟩ (- x * y) + x * y * negsucc k ∎ where i = distributivity-mult-over-ℤ' (- y) (y * negsucc k) x ii = ap ((x * (- y)) +_) IH iii = ap (_+ ((x * y) * negsucc k)) (negation-dist-over-mult x y) ℤ*-assoc : (x y z : ℤ) → x * y * z = x * (y * z) ℤ*-assoc x y (pos z) = ℤ*-assoc₀ x y z ⁻¹ ℤ*-assoc x y (negsucc z) = ℤ*-assoc₁ x y z ⁻¹ is-pos-succ-addition : (x y : ℤ) → is-pos-succ x → is-pos-succ y → is-pos-succ (x + y) is-pos-succ-addition x (negsucc y) x>0 y>0 = 𝟘-elim y>0 is-pos-succ-addition x (pos 0) x>0 y>0 = 𝟘-elim y>0 is-pos-succ-addition x (pos (succ 0)) x>0 y>0 = is-pos-succ-succℤ x x>0 is-pos-succ-addition x (pos (succ (succ y))) x>0 y>0 = is-pos-succ-succℤ (x + pos (succ y)) (is-pos-succ-addition x (pos (succ y)) x>0 y>0) is-pos-succ-mult : (x y : ℤ) → is-pos-succ x → is-pos-succ y → is-pos-succ (x * y) is-pos-succ-mult x (negsucc y) x>0 y>0 = 𝟘-elim y>0 is-pos-succ-mult x (pos 0) x>0 y>0 = 𝟘-elim y>0 is-pos-succ-mult x (pos (succ 0)) x>0 y>0 = x>0 is-pos-succ-mult x (pos (succ (succ y))) x>0 y>0 = is-pos-succ-addition x (x * pos (succ y)) x>0 (is-pos-succ-mult x (pos (succ y)) x>0 y>0) pos-times-negative : (n k : ℕ) → Σ m ꞉ ℕ , pos (succ n) * negsucc k = negsucc m pos-times-negative n 0 = n , refl pos-times-negative n (succ k) = I IH where IH : Σ m ꞉ ℕ , pos (succ n) * negsucc k = negsucc m IH = pos-times-negative n k I : Σ m ꞉ ℕ , pos (succ n) * negsucc k = negsucc m → Σ m ꞉ ℕ , pos (succ n) * negsucc (succ k) = negsucc m I (m , e) = succ n ℕ+ m , II where II : pos (succ n) * negsucc (succ k) = negsucc (succ n ℕ+ m) II = pos (succ n) * negsucc (succ k) =⟨ refl ⟩ negsucc n + pos (succ n) * negsucc k =⟨ i ⟩ negsucc n + negsucc m =⟨ ii ⟩ - (succℤ (pos (succ n) + pos m)) =⟨ iii ⟩ - succℤ (pos (succ n ℕ+ m)) =⟨ refl ⟩ negsucc (succ n ℕ+ m) ∎ where i = ap (negsucc n +_) e ii = negation-dist (pos (succ n)) (pos (succ m)) iii = ap (λ z → - (succℤ z)) (distributivity-pos-addition (succ n) m) negatives-equal : (x y : ℤ) → (- x) = (- y) → x = y negatives-equal x y e = I where I : x = y I = x =⟨ minus-minus-is-plus x ⁻¹ ⟩ - (- x) =⟨ ap -_ e ⟩ - (- y) =⟨ minus-minus-is-plus y ⟩ y ∎ ppnnp-lemma : (a b : ℕ) → Σ c ꞉ ℕ , negsucc a + negsucc b = negsucc c ppnnp-lemma a = ℕ-induction base step where base : Σ c ꞉ ℕ , negsucc a + negsucc 0 = negsucc c base = succ a , refl step : (k : ℕ) → Σ c ꞉ ℕ , negsucc a + negsucc k = negsucc c → Σ c ꞉ ℕ , negsucc a + negsucc (succ k) = negsucc c step k (c , IH) = succ c , ap predℤ IH product-positive-negative-not-positive : (a b c : ℕ) → ¬ (pos a * negsucc b = pos (succ c)) product-positive-negative-not-positive 0 0 c e = 𝟘-elim (positive-not-zero c I) where I : succ c = 0 I = pos-lc e ⁻¹ product-positive-negative-not-positive 0 (succ b) c e = 𝟘-elim II where I : pos 0 = pos (succ c) I = pos 0 =⟨ ℤ-zero-left-base (negsucc (succ b)) ⁻¹ ⟩ pos 0 * negsucc (succ b) =⟨ e ⟩ pos (succ c) ∎ II : 𝟘 II = positive-not-zero c (pos-lc I ⁻¹) product-positive-negative-not-positive (succ a) (succ b) c e₁ = γ I where I : Σ z ꞉ ℕ , succ z = succ a ℕ* succ b I = pos-mult-is-succ a b γ : ¬ (Σ z ꞉ ℕ , succ z = succ a ℕ* succ b) γ (z , e₂) = γ' II where II : Σ d ꞉ ℕ , negsucc a + negsucc z = negsucc d II = ppnnp-lemma a z γ' : ¬ (Σ d ꞉ ℕ , negsucc a + negsucc z = negsucc d) γ' (d , e₃) = negsucc-not-pos IV where III : negsucc z = pos (succ a) * negsucc b III = negsucc z =⟨ refl ⟩ - pos (succ z) =⟨ i ⟩ - pos (succ a ℕ* succ b) =⟨ ii ⟩ - pos (succ a) * pos (succ b) =⟨ iii ⟩ pos (succ a) * negsucc b ∎ where i = ap (λ α → -_ (pos α)) e₂ ii = ap -_ (pos-multiplication-equiv-to-ℕ (succ a) (succ b)) ⁻¹ iii = negation-dist-over-mult (pos (succ a)) (pos (succ b)) ⁻¹ IV : negsucc d = pos (succ c) IV = negsucc d =⟨ e₃ ⁻¹ ⟩ negsucc a + negsucc z =⟨ ap (negsucc a +_) III ⟩ negsucc a + pos (succ a) * negsucc b =⟨ refl ⟩ pos (succ a) * negsucc (succ b) =⟨ e₁ ⟩ pos (succ c) ∎ \end{code} Finally, we have equivalences of various re-arrangements of multiplication of integers, which can be useful to reduce the size of larger proofs. \begin{code} ℤ-mult-rearrangement : (x y z : ℤ) → x * y * z = x * z * y ℤ-mult-rearrangement x y z = x * y * z =⟨ ℤ*-assoc x y z ⟩ x * (y * z) =⟨ ap (x *_) (ℤ*-comm y z) ⟩ x * (z * y) =⟨ ℤ*-assoc x z y ⁻¹ ⟩ x * z * y ∎ ℤ-mult-rearrangement' : (x y z : ℤ) → z * (x * y) = y * (x * z) ℤ-mult-rearrangement' x y z = z * (x * y) =⟨ ℤ*-comm z (x * y) ⟩ x * y * z =⟨ ℤ-mult-rearrangement x y z ⟩ x * z * y =⟨ ℤ*-comm (x * z) y ⟩ y * (x * z) ∎ ℤ-mult-rearrangement'' : (w x y z : ℤ) → x * y * (w * z) = w * y * (x * z) ℤ-mult-rearrangement'' w x y z = γ where γ : x * y * (w * z) = w * y * (x * z) γ = x * y * (w * z) =⟨ ℤ-mult-rearrangement x y (w * z) ⟩ x * (w * z) * y =⟨ ap (_* y) (ℤ*-assoc x w z ⁻¹) ⟩ x * w * z * y =⟨ ap (λ a → (a * z) * y) (ℤ*-comm x w) ⟩ w * x * z * y =⟨ ℤ*-assoc (w * x) z y ⟩ w * x * (z * y) =⟨ ap ((w * x) *_) (ℤ*-comm z y) ⟩ w * x * (y * z) =⟨ ℤ*-assoc (w * x) y z ⁻¹ ⟩ w * x * y * z =⟨ ap (_* z) (ℤ*-assoc w x y ) ⟩ w * (x * y) * z =⟨ ap (λ a → (w * a) * z) (ℤ*-comm x y) ⟩ w * (y * x) * z =⟨ ap (_* z) (ℤ*-assoc w y x ⁻¹) ⟩ w * y * x * z =⟨ ℤ*-assoc (w * y) x z ⟩ w * y * (x * z) ∎ ℤ-mult-rearrangement''' : (x y z : ℤ) → x * (y * z) = y * (x * z) ℤ-mult-rearrangement''' x y z = x * (y * z) =⟨ ℤ*-assoc x y z ⁻¹ ⟩ x * y * z =⟨ ap (_* z) (ℤ*-comm x y) ⟩ y * x * z =⟨ ℤ*-assoc y x z ⟩ y * (x * z) ∎ \end{code}