diff --git a/CHANGELOG.md b/CHANGELOG.md index 479eb395bc..af7a35ea0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -645,10 +645,14 @@ Non-backwards compatible changes * To make it easier to use, reason about and read, the definition has been changed to: ```agda - Prime 0 = ⊥ - Prime 1 = ⊥ - Prime n = ∀ {d} → 2 ≤ d → d < n → d ∤ n + record Prime (p : ℕ) : Set where + constructor prime + field + .{{nontrivial}} : NonTrivial p + notComposite : ¬ Composite p ``` + where `Composite` is now defined as the diagonal of the new relation + `_HasNonTrivialDivisorLessThan_` in `Data.Nat.Divisibility.Core`. ### Changes to operation reduction behaviour in `Data.Rational(.Unnormalised)` @@ -2731,6 +2735,18 @@ Additions to existing modules s≤″s⁻¹ : suc m ≤″ suc n → m ≤″ n s<″s⁻¹ : suc m <″ suc n → m <″ n + pattern 2+ n = suc (suc n) + pattern 1<2+n {n} = s1⇒nonTrivial : 1 < n → NonTrivial n + nonZero⇒≢1⇒nonTrivial : .{{NonZero n}} → n ≢ 1 → NonTrivial n + recompute-nonTrivial : .{{NonTrivial n}} → NonTrivial n + nonTrivial⇒nonZero : .{{NonTrivial n}} → NonZero n + nonTrivial⇒n>1 : .{{NonTrivial n}} → 1 < n + nonTrivial⇒≢1 : .{{NonTrivial n}} → n ≢ 1 + _⊔′_ : ℕ → ℕ → ℕ _⊓′_ : ℕ → ℕ → ℕ ∣_-_∣′ : ℕ → ℕ → ℕ @@ -2756,20 +2772,42 @@ Additions to existing modules <-asym : Asymmetric _<_ ``` -* Added a new pattern synonym to `Data.Nat.Divisibility.Core`: +* Added a new pattern synonym and a new definition to `Data.Nat.Divisibility.Core`: ```agda pattern divides-refl q = divides q refl + record _HasNonTrivialDivisorLessThan_ (m n : ℕ) : Set where + ``` + +* Added new proofs to `Data.Nat.Divisibility`: + ```agda + hasNonTrivialDivisor-≢ : .{{NonTrivial d}} → .{{NonZero n}} → d ≢ n → d ∣ n → n HasNonTrivialDivisorLessThan n + hasNonTrivialDivisor-∣ : m HasNonTrivialDivisorLessThan n → m ∣ o → o HasNonTrivialDivisorLessThan n + hasNonTrivialDivisor-≤ : m HasNonTrivialDivisorLessThan n → n ≤ o → m HasNonTrivialDivisorLessThan o ``` -* Added new definitions and proofs to `Data.Nat.Primality`: +* Added new definitions, smart constructors and proofs to `Data.Nat.Primality`: ```agda - Composite : ℕ → Set - composite? : Decidable Composite - composite⇒¬prime : Composite n → ¬ Prime n - ¬composite⇒prime : 2 ≤ n → ¬ Composite n → Prime n - prime⇒¬composite : Prime n → ¬ Composite n - ¬prime⇒composite : 2 ≤ n → ¬ Prime n → Composite n - euclidsLemma : Prime p → p ∣ m * n → p ∣ m ⊎ p ∣ n + infix 10 _Rough_ + _Rough_ : ℕ → Pred ℕ _ + 0-rough : 0 Rough n + 1-rough : 1 Rough n + 2-rough : 2 Rough n + rough⇒≤ : .{{NonTrivial n}} → m Rough n → m ≤ n + ∤⇒rough-suc : m ∤ n → m Rough n → (suc m) Rough n + rough∧∣⇒rough : m Rough o → n ∣ o → m Rough n + Composite : ℕ → Set + composite-≢ : .{{NonTrivial d}} → .{{NonZero n}} → d ≢ n → d ∣ n → Composite n + composite-∣ : .{{NonZero n}} → Composite m → m ∣ n → Composite n + composite? : Decidable Composite + Irreducible : ℕ → Set + irreducible? : Decidable Irreducible + composite⇒¬prime : Composite n → ¬ Prime n + ¬composite⇒prime : .{{NonTrivial n} → ¬ Composite n → Prime n + prime⇒¬composite : Prime n → ¬ Composite n + ¬prime⇒composite : .{{NonTrivial n} → ¬ Prime n → Composite n + prime⇒irreducible : Prime p → Irreducible p + irreducible⇒prime : .{{NonTrivial p}} → Irreducible p → Prime p + euclidsLemma : Prime p → p ∣ m * n → p ∣ m ⊎ p ∣ n ``` * Added new proofs in `Data.Nat.Properties`: @@ -2779,8 +2817,12 @@ Additions to existing modules n+1+m≢m : n + suc m ≢ m m*n≡0⇒m≡0 : .{{_ : NonZero n}} → m * n ≡ 0 → m ≡ 0 n>0⇒n≢0 : n > 0 → n ≢ 0 - m^n≢0 : .{{_ : NonZero m}} → NonZero (m ^ n) m*n≢0 : .{{_ : NonZero m}} .{{_ : NonZero n}} → NonZero (m * n) + m*n≢0⇒m≢0 : .{{NonZero (m * n)}} → NonZero m + m*n≢0⇒n≢0 : .{{NonZero (m * n)}} → NonZero n + m≢0∧n>1⇒m*n>1 : .{{_ : NonZero m}} .{{_ : NonTrivial n}} → NonTrivial (m * n) + n≢0∧m>1⇒m*n>1 : .{{_ : NonZero n}} .{{_ : NonTrivial m}} → NonTrivial (m * n) + m^n≢0 : .{{_ : NonZero m}} → NonZero (m ^ n) m≤n⇒n∸m≤n : m ≤ n → n ∸ m ≤ n s-connex : Connex _≥_ _>_ @@ -2855,21 +2897,21 @@ Additions to existing modules m%n≤n : .{{_ : NonZero n}} → m % n ≤ n m*n/m!≡n/[m∸1]! : .{{_ : NonZero m}} → m * n / m ! ≡ n / (pred m) ! - %-congˡ : .⦃ _ : NonZero o ⦄ → m ≡ n → m % o ≡ n % o - %-congʳ : .⦃ _ : NonZero m ⦄ .⦃ _ : NonZero n ⦄ → m ≡ n → o % m ≡ o % n - m≤n⇒[n∸m]%m≡n%m : .⦃ _ : NonZero m ⦄ → m ≤ n → (n ∸ m) % m ≡ n % m - m*n≤o⇒[o∸m*n]%n≡o%n : .⦃ _ : NonZero n ⦄ → m * n ≤ o → (o ∸ m * n) % n ≡ o % n - m∣n⇒o%n%m≡o%m : .⦃ _ : NonZero m ⦄ .⦃ _ : NonZero n ⦄ → m ∣ n → o % n % m ≡ o % m - m b ------------------------------------------------------------------------ -- Simple predicates --- Defining `NonZero` in terms of `T` and therefore ultimately `⊤` and --- `⊥` allows Agda to automatically infer nonZero-ness for any natural --- of the form `suc n`. Consequently in many circumstances this --- eliminates the need to explicitly pass a proof when the NonZero --- argument is either an implicit or an instance argument. +-- Defining these predicates in terms of `T` and therefore ultimately +-- `⊤` and `⊥` allows Agda to automatically infer them for any natural +-- of the correct form. Consequently in many circumstances this +-- eliminates the need to explicitly pass a proof when the predicate +-- argument is either an implicit or an instance argument. See `_/_` +-- and `_%_` further down this file for examples. -- --- See `Data.Nat.DivMod` for an example. +-- Furthermore, defining these predicates as single-field records +-- (rather defining them directly as the type of their field) is +-- necessary as the current version of Agda is far better at +-- reconstructing meta-variable values for the record parameters. + +-- A predicate saying that a number is not equal to 0. record NonZero (n : ℕ) : Set where field @@ -130,6 +141,34 @@ instance >-nonZero⁻¹ : ∀ n → .{{NonZero n}} → n > 0 >-nonZero⁻¹ (suc n) = z1⇒nonTrivial : ∀ {n} → n > 1 → NonTrivial n +n>1⇒nonTrivial sz1 : ∀ n → .{{NonTrivial n}} → n > 1 +nonTrivial⇒n>1 (2+ _) = sz 1 is m-rough, then m ≤ n +rough⇒≤ : .{{NonTrivial n}} → m Rough n → m ≤ n +rough⇒≤ rough = ≮⇒≥ n≮m + where n≮m = λ m>n → rough (hasNonTrivialDivisor m>n ∣-refl) + +-- If a number n is m-rough, and m ∤ n, then n is (suc m)-rough +∤⇒rough-suc : m ∤ n → m Rough n → (suc m) Rough n +∤⇒rough-suc m∤n r (hasNonTrivialDivisor d<1+m d∣n) + with m<1+n⇒m1⇒m*n>1 q d + _ = m*n≢0⇒m≢0 q + +-- Basic (counter-)examples of Composite + +¬composite[0] : ¬ Composite 0 +¬composite[0] = 0-rough + +¬composite[1] : ¬ Composite 1 +¬composite[1] = 1-rough + +composite[4] : Composite 4 +composite[4] = composite-≢ 2 (λ()) (divides-refl 2) + +composite[6] : Composite 6 +composite[6] = composite-≢ 3 (λ()) (divides-refl 2) + +composite⇒nonZero : Composite n → NonZero n +composite⇒nonZero {suc _} _ = _ + +composite⇒nonTrivial : Composite n → NonTrivial n +composite⇒nonTrivial {1} composite[1] = + contradiction composite[1] ¬composite[1] +composite⇒nonTrivial {2+ _} _ = _ + +composite? : Decidable Composite +composite? n = Dec.map CompositeUpTo⇔Composite (compositeUpTo? n) + where + -- For technical reasons, in order to be able to prove decidability + -- via the `all?` and `any?` combinators for *bounded* predicates on + -- `ℕ`, we further define the bounded counterparts to predicates + -- `P...` as `P...UpTo` and show the equivalence of the two. + + -- Equivalent bounded predicate definition + CompositeUpTo : Pred ℕ _ + CompositeUpTo n = ∃[ d ] d < n × NonTrivial d × d ∣ n + + -- Proof of equivalence + comp-upto⇒comp : CompositeUpTo n → Composite n + comp-upto⇒comp (_ , d 1 divides n, then p must be prime +rough∧∣⇒prime : .{{NonTrivial p}} → p Rough n → p ∣ n → Prime p +rough∧∣⇒prime r p∣n = prime (rough∧∣⇒rough r p∣n) + +-- Relationship between compositeness and primality. +composite⇒¬prime : Composite n → ¬ Prime n +composite⇒¬prime composite[d] (prime p) = p composite[d] + +¬composite⇒prime : .{{NonTrivial n}} → ¬ Composite n → Prime n +¬composite⇒prime = prime + +prime⇒¬composite : Prime n → ¬ Composite n +prime⇒¬composite (prime p) = p + +-- Note that this has to recompute the factor! +¬prime⇒composite : .{{NonTrivial n}} → ¬ Prime n → Composite n +¬prime⇒composite {n} ¬prime[n] = + decidable-stable (composite? n) (¬prime[n] ∘′ ¬composite⇒prime) + +------------------------------------------------------------------------ +-- Basic (counter-)examples of Irreducible + +¬irreducible[0] : ¬ Irreducible 0 +¬irreducible[0] irr[0] = contradiction₂ 2≡1⊎2≡0 (λ ()) (λ ()) + where 2≡1⊎2≡0 = irr[0] {2} (divides-refl 0) + +irreducible[1] : Irreducible 1 +irreducible[1] m|1 = inj₁ (∣1⇒≡1 m|1) + +irreducible[2] : Irreducible 2 +irreducible[2] {zero} 0∣2 with () ← 0∣⇒≡0 0∣2 +irreducible[2] {suc _} d∣2 with ∣⇒≤ d∣2 +... | z1⇒m*n>1 : ∀ m n .{{_ : NonZero m}} .{{_ : NonTrivial n}} → NonTrivial (m * n) +m≢0∧n>1⇒m*n>1 (suc m) (2+ n) = _ + +n≢0∧m>1⇒m*n>1 : ∀ m n .{{_ : NonZero n}} .{{_ : NonTrivial m}} → NonTrivial (m * n) +n≢0∧m>1⇒m*n>1 m n rewrite *-comm m n = m≢0∧n>1⇒m*n>1 n m + ------------------------------------------------------------------------ -- Other properties of _*_ and _≤_/_<_ @@ -1704,7 +1725,7 @@ pred-mono-≤ : pred Preserves _≤_ ⟶ _≤_ pred-mono-≤ {zero} _ = z≤n pred-mono-≤ {suc _} {suc _} m≤n = s≤s⁻¹ m≤n -pred-mono-< : .⦃ _ : NonZero m ⦄ → m < n → pred m < pred n +pred-mono-< : .{{NonZero m}} → m < n → pred m < pred n pred-mono-< {m = suc _} {n = suc _} = s-nonZero : ∀ {p} → p > 0ℚ → NonZero p >-nonZero {p@(mkℚ _ _ _)} (*<* p-nonZero {toℚᵘ p} (ℚᵘ.*<* p