------------------------------------------------------------------------ -- The Agda standard library -- -- Boring lemmas used in Data.Nat.GCD and Data.Nat.Coprimality ------------------------------------------------------------------------ {-# OPTIONS --cubical-compatible --safe #-} module Data.Nat.GCD.Lemmas where open import Data.Nat.Base using (ℕ; suc; zero; _+_; _*_; _∸_; _≤_; s≤s; z≤n; _≤′_) open import Data.Nat.Properties open import Function.Base using (_$_) open import Relation.Binary.PropositionalEquality.Core using (_≡_; refl; cong; cong₂; sym) open import Relation.Binary.PropositionalEquality.Properties using (module ≡-Reasoning) open ≡-Reasoning private comm-factor : ∀ x k n → x * k + x * n ≡ x * (n + k) comm-factor x k n = begin x * k + x * n ≡⟨ +-comm (x * k) _ ⟩ x * n + x * k ≡⟨ *-distribˡ-+ x n k ⟨ x * (n + k) ∎ distrib-comm₂ : ∀ d x k n → d + x * (n + k) ≡ d + x * k + x * n distrib-comm₂ d x k n = begin d + x * (n + k) ≡⟨ cong (d +_) (comm-factor x k n) ⟨ d + (x * k + x * n) ≡⟨ +-assoc d _ _ ⟨ d + x * k + x * n ∎ -- Other properties -- TODO: Can this proof be simplified? An automatic solver which can -- handle ∸ would be nice... lem₀ : ∀ i j m n → i * m ≡ j * m + n → (i ∸ j) * m ≡ n lem₀ i j m n eq = begin (i ∸ j) * m ≡⟨ *-distribʳ-∸ m i j ⟩ (i * m) ∸ (j * m) ≡⟨ cong (_∸ j * m) eq ⟩ (j * m + n) ∸ (j * m) ≡⟨ cong (_∸ j * m) (+-comm (j * m) n) ⟩ (n + j * m) ∸ (j * m) ≡⟨ m+n∸n≡m n (j * m) ⟩ n ∎ lem₁ : ∀ i j → 2 + i ≤′ 2 + j + i lem₁ i j = ≤⇒≤′ $ s≤s $ s≤s $ m≤n+m i j private times2 : ∀ x → x + x ≡ 2 * x times2 x = cong (x +_) (sym (+-identityʳ x)) times2′ : ∀ x y → x * y + x * y ≡ 2 * x * y times2′ x y = begin x * y + x * y ≡⟨ times2 (x * y) ⟩ 2 * (x * y) ≡⟨ *-assoc 2 x y ⟨ 2 * x * y ∎ lem₂ : ∀ d x {k n} → d + x * k ≡ x * n → d + x * (n + k) ≡ 2 * x * n lem₂ d x {k} {n} eq = begin d + x * (n + k) ≡⟨ distrib-comm₂ d x k n ⟩ d + x * k + x * n ≡⟨ cong (_+ x * n) eq ⟩ x * n + x * n ≡⟨ times2′ x n ⟩ 2 * x * n ∎ private distrib₃ : ∀ a b c x → (a + b + c) * x ≡ a * x + b * x + c * x distrib₃ a b c x = begin (a + b + c) * x ≡⟨ *-distribʳ-+ x (a + b) c ⟩ (a + b) * x + c * x ≡⟨ cong (_+ c * x) (*-distribʳ-+ x a b) ⟩ a * x + b * x + c * x ∎ lem₃₁ : ∀ a b c → a + (b + c) ≡ b + a + c lem₃₁ a b c = begin a + (b + c) ≡⟨ +-assoc a b c ⟨ (a + b) + c ≡⟨ cong (_+ c) (+-comm a b) ⟩ b + a + c ∎ +-assoc-comm : ∀ a b c d → a + (b + c + d) ≡ (a + c) + (b + d) +-assoc-comm a b c d = begin a + (b + c + d) ≡⟨ cong (a +_) (cong (_+ d) (+-comm b c)) ⟩ a + (c + b + d) ≡⟨ cong (a +_) (+-assoc c b d) ⟩ a + (c + (b + d)) ≡⟨ +-assoc a c _ ⟨ (a + c) + (b + d) ∎ *-on-right : ∀ a b c {d} → b * c ≡ d → a * b * c ≡ a * d *-on-right a b c {d} eq = begin a * b * c ≡⟨ *-assoc a b c ⟩ a * (b * c) ≡⟨ cong (a *_) eq ⟩ a * d ∎ *-on-left : ∀ a b c {d} → a * b ≡ d → a * (b * c) ≡ d * c *-on-left a b c {d} eq = begin a * (b * c) ≡⟨ *-assoc a b c ⟨ a * b * c ≡⟨ cong (_* c) eq ⟩ d * c ∎ +-on-right : ∀ a b c {d} → b + c ≡ d → a + b + c ≡ a + d +-on-right a b c {d} eq = begin a + b + c ≡⟨ +-assoc a b c ⟩ a + (b + c) ≡⟨ cong (a +_) eq ⟩ a + d ∎ +-on-left : ∀ a b c d → a + b ≡ d → a + (b + c) ≡ d + c +-on-left a b c d eq = begin a + (b + c) ≡⟨ +-assoc a b c ⟨ a + b + c ≡⟨ cong (_+ c) eq ⟩ d + c ∎ +-focus-mid : ∀ a b c d → a + b + c + d ≡ a + (b + c) + d +-focus-mid a b c d = begin a + b + c + d ≡⟨ cong (_+ d) (+-assoc a b c) ⟩ a + (b + c) + d ∎ +-assoc-comm′ : ∀ a b c d → a + b + c + d ≡ a + (b + d) + c +-assoc-comm′ a b c d = begin a + b + c + d ≡⟨ +-on-left a (b + c) d (a + b + c) (sym $ +-assoc a b c) ⟨ a + (b + c + d) ≡⟨ cong (a +_) (+-on-right b c d (+-comm c d)) ⟩ a + (b + (d + c)) ≡⟨ cong (a +_) (+-assoc b d c) ⟨ a + (b + d + c) ≡⟨ +-assoc a _ c ⟨ a + (b + d) + c ∎ lem₃₂ : ∀ a b c n → a * n + (b * n + a * n + c * n) ≡ (a + a + (b + c)) * n lem₃₂ a b c n = begin a * n + (b * n + a * n + c * n) ≡⟨ cong (a * n +_) (distrib₃ b a c n) ⟨ a * n + (b + a + c) * n ≡⟨ *-distribʳ-+ n a _ ⟨ (a + (b + a + c)) * n ≡⟨ cong (_* n) (+-assoc-comm a b a c) ⟩ (a + a + (b + c)) * n ∎ mid-to-right : ∀ a b c → a + 2 * b + c ≡ (a + b + c) + b mid-to-right a b c = begin a + 2 * b + c ≡⟨ cong (λ x → a + x + c) (times2 b) ⟨ a + (b + b) + c ≡⟨ +-assoc-comm′ a b c b ⟨ a + b + c + b ∎ mid-to-left : ∀ a b c → a + 2 * b + c ≡ b + (a + b + c) mid-to-left a b c = begin a + 2 * b + c ≡⟨ cong (λ x → a + x + c) (times2 b) ⟨ a + (b + b) + c ≡⟨ cong (_+ c) (+-on-left a b b _ (+-comm a b)) ⟩ b + a + b + c ≡⟨ +-on-left b (a + b) c (b + a + b) (sym $ +-assoc b a b) ⟨ b + (a + b + c) ∎ lem₃ : ∀ d x {i k n} → d + (1 + x + i) * k ≡ x * n → d + (1 + x + i) * (n + k) ≡ (1 + 2 * x + i) * n lem₃ d x {i} {k} {n} eq = begin d + y * (n + k) ≡⟨ distrib-comm₂ d y k n ⟩ d + y * k + y * n ≡⟨ cong (_+ y * n) eq ⟩ x * n + y * n ≡⟨ cong (x * n +_) (distrib₃ 1 x i n) ⟩ x * n + (1 * n + x * n + i * n) ≡⟨ lem₃₂ x 1 i n ⟩ (x + x + (1 + i)) * n ≡⟨ cong (_* n) (cong (_+ (1 + i)) (times2 x)) ⟩ (2 * x + (1 + i)) * n ≡⟨ cong (_* n) (lem₃₁ (2 * x) 1 i) ⟩ (1 + 2 * x + i) * n ∎ where y = 1 + x + i lem₄ : ∀ d y {k i} n → d + y * k ≡ (1 + y + i) * n → d + y * (n + k) ≡ (1 + 2 * y + i) * n lem₄ d y {k} {i} n eq = begin d + y * (n + k) ≡⟨ distrib-comm₂ d y k n ⟩ d + y * k + y * n ≡⟨ cong (_+ y * n) eq ⟩ (1 + y + i) * n + y * n ≡⟨ *-distribʳ-+ n (1 + y + i) y ⟨ (1 + y + i + y) * n ≡⟨ cong (_* n) (mid-to-right 1 y i) ⟨ (1 + 2 * y + i) * n ∎ lem₅ : ∀ d x {n k} → d + x * n ≡ x * k → d + 2 * x * n ≡ x * (n + k) lem₅ d x {n} {k} eq = begin d + 2 * x * n ≡⟨ cong (d +_) (times2′ x n) ⟨ d + (x * n + x * n) ≡⟨ +-assoc d (x * n) _ ⟨ d + x * n + x * n ≡⟨ cong (_+ x * n) eq ⟩ x * k + x * n ≡⟨ comm-factor x k n ⟩ x * (n + k) ∎ lem₆ : ∀ d x {n i k} → d + x * n ≡ (1 + x + i) * k → d + (1 + 2 * x + i) * n ≡ (1 + x + i) * (n + k) lem₆ d x {n} {i} {k} eq = begin d + (1 + 2 * x + i) * n ≡⟨ cong (λ z → d + z * n) (mid-to-left 1 x i) ⟩ d + (x + y) * n ≡⟨ cong (d +_) (*-distribʳ-+ n x y) ⟩ d + (x * n + y * n) ≡⟨ +-on-left d _ _ _ eq ⟩ y * k + y * n ≡⟨ comm-factor y k n ⟩ y * (n + k) ∎ where y = 1 + x + i lem₇ : ∀ d y {i} n {k} → d + (1 + y + i) * n ≡ y * k → d + (1 + 2 * y + i) * n ≡ y * (n + k) lem₇ d y {i} n {k} eq = begin d + (1 + 2 * y + i) * n ≡⟨ cong (λ z → d + z * n) (mid-to-right 1 y i) ⟩ d + (1 + y + i + y) * n ≡⟨ cong (d +_) (*-distribʳ-+ n (1 + y + i) y) ⟩ d + ((1 + y + i) * n + y * n) ≡⟨ +-on-left d _ _ _ eq ⟩ y * k + y * n ≡⟨ comm-factor y k n ⟩ y * (n + k) ∎ lem₈ : ∀ {i j k q} x y → 1 + y * j ≡ x * i → j * k ≡ q * i → k ≡ (x * k ∸ y * q) * i lem₈ {i} {j} {k} {q} x y eq eq′ = sym (lem₀ (x * k) (y * q) i k lemma) where lemma = begin x * k * i ≡⟨ *-on-right x k i (*-comm k i) ⟩ x * (i * k) ≡⟨ *-on-left x i k (sym eq) ⟩ (1 + y * j) * k ≡⟨ +-comm k _ ⟩ (y * j) * k + k ≡⟨ cong (_+ k) (*-assoc y j k) ⟩ y * (j * k) + k ≡⟨ cong (λ n → y * n + k) eq′ ⟩ y * (q * i) + k ≡⟨ cong (_+ k) (*-assoc y q i) ⟨ y * q * i + k ∎ lem₉ : ∀ {i j k q} x y → 1 + x * i ≡ y * j → j * k ≡ q * i → k ≡ (y * q ∸ x * k) * i lem₉ {i} {j} {k} {q} x y eq eq′ = sym (lem₀ (y * q) (x * k) i k lemma) where lem : ∀ a b c → a * b * c ≡ b * c * a lem a b c = begin a * b * c ≡⟨ *-assoc a b c ⟩ a * (b * c) ≡⟨ *-comm a _ ⟩ b * c * a ∎ lemma = begin y * q * i ≡⟨ lem y q i ⟩ q * i * y ≡⟨ cong (λ n → n * y) eq′ ⟨ j * k * y ≡⟨ lem y j k ⟨ y * j * k ≡⟨ cong (λ n → n * k) eq ⟨ (1 + x * i) * k ≡⟨ +-comm k _ ⟩ x * i * k + k ≡⟨ cong (_+ k) (*-on-right x i k (*-comm i k)) ⟩ x * (k * i) + k ≡⟨ cong (_+ k) (*-assoc x k i) ⟨ x * k * i + k ∎ lem₁₀ : ∀ {a′} b c {d} e f → let a = suc a′ in a + b * (c * d * a) ≡ e * (f * d * a) → d ≡ 1 lem₁₀ {a′} b c {d} e f eq = m*n≡1⇒n≡1 (e * f ∸ b * c) d (lem₀ (e * f) (b * c) d 1 (*-cancelʳ-≡ (e * f * d) (b * c * d + 1) _ (begin e * f * d * a ≡⟨ *-assoc₄₃ e f d a ⟩ e * (f * d * a) ≡⟨ eq ⟨ a + b * (c * d * a) ≡⟨ cong (a +_) (*-assoc₄₃ b c d a) ⟨ a + b * c * d * a ≡⟨ +-comm a _ ⟩ b * c * d * a + a ≡⟨ cong (b * c * d * a +_) (+-identityʳ a) ⟨ b * c * d * a + (a + 0) ≡⟨ *-distribʳ-+ a (b * c * d) 1 ⟨ (b * c * d + 1) * a ∎))) where a = suc a′ *-assoc₄₃ : ∀ w x y z → w * x * y * z ≡ w * (x * y * z) *-assoc₄₃ w x y z = begin w * x * y * z ≡⟨ cong (_* z) (*-assoc w x y) ⟩ w * (x * y) * z ≡⟨ *-assoc w _ z ⟩ w * (x * y * z) ∎ lem₁₁ : ∀ {i j m n k d} x y → 1 + y * j ≡ x * i → i * k ≡ m * d → j * k ≡ n * d → k ≡ (x * m ∸ y * n) * d lem₁₁ {i} {j} {m} {n} {k} {d} x y eq eq₁ eq₂ = sym (lem₀ (x * m) (y * n) d k (begin x * m * d ≡⟨ *-on-right x m d (sym eq₁) ⟩ x * (i * k) ≡⟨ *-on-left x i k (sym eq) ⟩ (1 + y * j) * k ≡⟨ +-comm k _ ⟩ y * j * k + k ≡⟨ cong (_+ k) (*-assoc y j k) ⟩ y * (j * k) + k ≡⟨ cong (λ p → y * p + k) eq₂ ⟩ y * (n * d) + k ≡⟨ cong (_+ k) (*-assoc y n d) ⟨ y * n * d + k ∎))
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4