From c649694289adc712498ea60468ebcb5ace447cb2 Mon Sep 17 00:00:00 2001 From: jamesmckinna <31931406+jamesmckinna@users.noreply.github.com> Date: Thu, 14 Dec 2023 06:05:35 +0000 Subject: [PATCH] [fixes #1711] Refactoring `Data.Nat.Divisibility` and `Data.Nat.DivMod` (#2182) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * added new definitions to `_∣_` * `CHANGELOG` * don't declare `quotient≢0` as an `instance` * replace use of `subst` with one of `trans` * what's sauce for the goose... * switch to a `rewrite`-based solution... * tightened `import`s * simplified dependenciess * simplified dependencies; `CHANGELOG` * removed `module` abstractions * delegated proof of `quotient≢0` to `Data.Nat.Properties` * removed redundant property * cosmetic review changes; others to follow * better proof of `quotient>1` * `where` clause layout * leaving in the flipped equality; moved everything else * new lemmas moved from `Core`; knock-on consequences; lots of tidying up * tidying up; `CHANGELOG` * cosmetic tweaks * reverted to simple version * problems with exporting `quotient` * added last lemma: defining equation for `_/_` * improved `CHANGELOG` * revert: simplified imports * improved `CHANGELOG` * endpoint of simplifying the proof of `*-pres-∣` * simplified the proof of `n/m≡quotient` * simplified the proof of `∣m+n∣m⇒∣n` * simplified the proof of `∣m∸n∣n⇒∣m` * simplified `import`s * simplified a lot of proofs, esp. wrt `divides-refl` and `NonZero` reasoning * simplified more proofs, esp. wrt `divides-refl` reasoning * simplified `import`s * moved `equalityᵒ` proof out of `Core` * `CHANGELOG` * temporary fix: further `NonZero` refactoring advised! * regularised use of instance brackets * further instance simplification * further streamlining * tidied up `CHANGELOG` * simplified `NonZero` pattern matching * regularised use of instance brackets * simplified proof of `/-*-interchange` * simplified proof of `/-*-interchange` * ... permitting the migration of `*-pres-∣` to `Data.Nat.Divisibility` * tweaked proof of `/-*-interchange` * narrowed `import`s * simplified proof; renamed new proofs * Capitalisation * streamlined `import`s; streamlined proof of decidability * spurious duplication after merge * missing symbol import * replaced one use of `1 < m` with `{{NonTrivial m}}` * fixed `CHANGELOG` * removed use of identifier `k` * refactoring: more use of `NonTrivial` instances * knock-on consequences: simplified function * two new lemmas * refactoring: use of `connex` in proofs * new lemmas about `pred` * new lemmas about monus * refactoring: use of the new properties, simplifying pattern analysis * whitespace * questionable? revision after comments on #2221 * silly argument name typo; remove parens * tidied up imports of `Relation.Nullary` * removed spurious `instance` * localised appeals to `Reasoning` * further use of `variable`s * tidied up `record` name in comment * cosmetic * reconciled implicit/explicit arguments in various monus lemmas * fixed knock-on change re monus; reverted change to `m/n1 : m ∣ n → m < n → 1 < quotient + quotient-< : m ∣ n → .{{NonTrivial m}} → .{{NonZero n}} → quotient < n + n/m≡quotient : m ∣ n → .{{_ : NonZero m}} → n / m ≡ quotient + + m/n≡0⇒m0 : ∀ {m n} .{{_ : NonZero n}} → m ≥ n → m / n > 0 m≥n⇒m/n>0 {m@(suc _)} {n@(suc _)} m≥n = begin - 1 ≡⟨ sym (n/n≡1 m) ⟩ + 1 ≡⟨ n/n≡1 m ⟨ m / m ≤⟨ /-monoʳ-≤ m m≥n ⟩ m / n ∎ +m/n≡0⇒m-nonZero (m≥n⇒m/n>0 n≤m) + +m/n≢0⇒n≤m : ∀ {m n} .{{_ : NonZero n}} → m / n ≢ 0 → n ≤ m +m/n≢0⇒n≤m {m} {n@(suc _)} m/n≢0 with <-≤-connex m n +... | inj₁ m0 (≢-nonZero⁻¹ o)) (≮⇒≥ n≮o) + where n∸o0 (≢-nonZero⁻¹ o)) n≥o -m*n/o*n≡m/o : ∀ m n o .⦃ _ : NonZero o ⦄ ⦃ _ : NonZero (o * n) ⦄ → +m*n/o*n≡m/o : ∀ m n o .{{_ : NonZero o}} .{{_ : NonZero (o * n)}} → m * n / (o * n) ≡ m / o -m*n/o*n≡m/o m n o ⦃ _ ⦄ ⦃ o*n≢0 ⦄ = begin-equality +m*n/o*n≡m/o m n o = begin-equality m * n / (o * n) ≡⟨ /-congˡ (*-comm m n) ⟩ n * m / (o * n) ≡⟨ /-congʳ (*-comm o n) ⟩ n * m / (n * o) ≡⟨ m*n/m*o≡n/o n m o ⟩ m / o ∎ - where instance n*o≢0 = subst NonZero (*-comm o n) o*n≢0 - -m1 : (m∣n : m ∣ n) → m < n → 1 < quotient m∣n +quotient>1 {m} {n} m∣n m1 m) ⟩ + quotient m∣n * m ≡⟨ _∣_.equality m∣n ⟨ + n ∎ + where open ≤-Reasoning; instance _ = quotient≢0 m∣n + +------------------------------------------------------------------------ +-- Relating _/_ and quotient + +n/m≡quotient : (m∣n : m ∣ n) .{{_ : NonZero m}} → n / m ≡ quotient m∣n +n/m≡quotient {m = m} (divides-refl q) = m*n/n≡m q m ------------------------------------------------------------------------ -- Relationship with _%_ m%n≡0⇒n∣m : ∀ m n .{{_ : NonZero n}} → m % n ≡ 0 → n ∣ m -m%n≡0⇒n∣m m n eq = divides (m / n) (begin-equality - m ≡⟨ m≡m%n+[m/n]*n m n ⟩ - m % n + m / n * n ≡⟨ cong₂ _+_ eq refl ⟩ - m / n * n ∎) - where open ≤-Reasoning +m%n≡0⇒n∣m m n eq = divides (m / n) $ begin + m ≡⟨ m≡m%n+[m/n]*n m n ⟩ + m % n + [m/n]*n ≡⟨ cong (_+ [m/n]*n) eq ⟩ + [m/n]*n ∎ + where open ≡-Reasoning; [m/n]*n = m / n * n n∣m⇒m%n≡0 : ∀ m n .{{_ : NonZero n}} → n ∣ m → m % n ≡ 0 n∣m⇒m%n≡0 .(q * n) n (divides-refl q) = m*n%n≡0 q n @@ -53,15 +91,11 @@ m%n≡0⇔n∣m m n = mk⇔ (m%n≡0⇒n∣m m n) (n∣m⇒m%n≡0 m n) ------------------------------------------------------------------------ -- Properties of _∣_ and _≤_ -∣⇒≤ : ∀ {m n} .{{_ : NonZero n}} → m ∣ n → m ≤ n -∣⇒≤ {m} {n@(suc _)} (divides (suc q) eq) = begin - m ≤⟨ m≤m+n m (q * m) ⟩ - suc q * m ≡⟨ sym eq ⟩ - n ∎ - where open ≤-Reasoning +∣⇒≤ : .{{_ : NonZero n}} → m ∣ n → m ≤ n +∣⇒≤ {n@.(q * m)} {m} (divides-refl q@(suc p)) = m≤m+n m (p * m) ->⇒∤ : ∀ {m n} .{{_ : NonZero n}} → m > n → m ∤ n ->⇒∤ (s≤s m>n) m∣n = contradiction (∣⇒≤ m∣n) (≤⇒≯ m>n) +>⇒∤ : .{{_ : NonZero n}} → m > n → m ∤ n +>⇒∤ {n@(suc _)} n1⇒m*n>1 m n rewrite *-comm m n = m≢0∧n>1⇒m*n>1 n m -- Other properties of _*_ and _≤_/_<_ *-cancelʳ-≤ : ∀ m n o .{{_ : NonZero o}} → m * o ≤ n * o → m ≤ n -*-cancelʳ-≤ zero _ (suc o) _ = z≤n -*-cancelʳ-≤ (suc m) (suc n) (suc o) le = - s≤s (*-cancelʳ-≤ m n (suc o) (+-cancelˡ-≤ _ _ _ le)) +*-cancelʳ-≤ zero _ _ _ = z≤n +*-cancelʳ-≤ (suc m) (suc n) o@(suc _) le = + s≤s (*-cancelʳ-≤ m n o (+-cancelˡ-≤ _ _ _ le)) *-cancelˡ-≤ : ∀ o .{{_ : NonZero o}} → o * m ≤ o * n → m ≤ n *-cancelˡ-≤ {m} {n} o rewrite *-comm o m | *-comm o n = *-cancelʳ-≤ m n o @@ -969,14 +969,12 @@ n≢0∧m>1⇒m*n>1 m n rewrite *-comm m n = m≢0∧n>1⇒m*n>1 n m *-mono-< (s