-
Notifications
You must be signed in to change notification settings - Fork 242
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add prime factorization and its properties #1969
Merged
Merged
Changes from 2 commits
Commits
Show all changes
46 commits
Select commit
Hold shift + click to select a range
98dff4f
Add prime factorization and its properties
Taneb 54ed74c
Add missing header comment
Taneb 9c05449
Remove completely trivial lemma
Taneb 6c9a9e1
Use equational reasoning in quotient|n proof
Taneb 7ec3801
Fix typo in module header
Taneb 8e0d749
Factorization => Factorisation
Taneb f77023e
Use Nat lemma in extend-|/
Taneb 2f4193c
[ cleanup ] part of the proof
gallais 1b45ff5
[ cleanup ] finishing up the job
gallais cec5fac
[ cleanup ] a little bit more
gallais 4c8b43e
[ cleanup ] the import list
gallais dd898f9
[ fix ] header style
gallais b330ae5
Merge branch 'master' into prime-factorization
gallais bec7b21
[ fix ] broken merge: missing import
gallais 294bdad
Move Data.Nat.Rough to Data.Nat.Primality.Rough
Taneb 8796eee
Rename productPreserves↭⇒≡ to product-↭
Taneb f0948e8
Use proof of Prime=>NonZero
Taneb 2a1ab80
Open reasoning once in factoriseRec
Taneb 7e73c8d
Rename Factorisation => PrimeFactorisation
Taneb c2a712f
Move wheres around
Taneb 6262285
Merge branch 'master' into prime-factorization
Taneb 4073e5f
Tidy up Rough a bit
Taneb 8afce74
Move quotient|n to top of file
Taneb 87022d8
Replace factorisationPullToFront with slightly more generally useful …
Taneb ea1142d
Merge branch 'master' into prime-factorization
Taneb 58a71c5
Merge branch 'master' into prime-factorization
Taneb 230d498
Fix import after merge
Taneb 1f1ed8e
Clean up proof of 2-rough-n
Taneb 8b34d27
Make argument to 2-rough-n implicit
Taneb 7482c46
Rename 2-rough-n to 2-rough
Taneb 20d8d66
Merge branch 'master' into prime-factorization
Taneb aca45ad
Complete merge, rewrite factorisation logic a bit
Taneb e24f0be
Short circuit when candidate is greater than square root of product
Taneb fd4e806
Remove redefined lemma
Taneb 510b7ec
Minor simplifications
Taneb 9f2ef51
Remove private pattern synonyms
Taneb 217d0cd
Change name of lemma
Taneb 286bc7e
Typo
Taneb 5063190
Remove using list from import
Taneb cf8a9c4
Clean up proof
Taneb 35153ca
Merge remote-tracking branch 'origin/master' into prime-factorization
Taneb 578718d
Fixes after merge
Taneb a556522
Addressed some feedback
MatthewDaggitt cc8cef2
Merge branch 'master' into prime-factorization
MatthewDaggitt 7dcd066
Merge branch 'master' into prime-factorization
MatthewDaggitt eb893ed
Fix previous merge
MatthewDaggitt File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
------------------------------------------------------------------------ | ||
-- The Agda standard library | ||
-- | ||
-- Prime factorization of naturla numbers and its properties | ||
gallais marked this conversation as resolved.
Show resolved
Hide resolved
|
||
------------------------------------------------------------------------ | ||
|
||
{-# OPTIONS --cubical-compatible --safe #-} | ||
|
||
module Data.Nat.Primality.Factorization where | ||
|
||
open import Data.Empty | ||
open import Data.Nat.Base | ||
open import Data.Nat.Divisibility | ||
open import Data.Nat.Properties | ||
open import Data.Nat.Induction | ||
open import Data.Nat.Primality | ||
open import Data.Nat.Rough | ||
open import Data.Product as Π | ||
open import Data.List.Base | ||
open import Data.List.Relation.Unary.All as All | ||
open import Data.List.Relation.Binary.Permutation.Propositional as ↭ | ||
open import Data.List.Relation.Binary.Permutation.Propositional.Properties | ||
open import Data.Sum.Base | ||
open import Function.Base | ||
open import Relation.Nullary.Decidable | ||
open import Relation.Nullary.Negation | ||
open import Relation.Binary.PropositionalEquality as ≡ | ||
|
||
-- Core definition | ||
------------------------------------------------------------------------ | ||
|
||
record Factorization (n : ℕ) : Set where | ||
gallais marked this conversation as resolved.
Show resolved
Hide resolved
|
||
field | ||
factors : List ℕ | ||
isFactorization : product factors ≡ n | ||
factorsPrime : All Prime factors | ||
|
||
open Factorization public using (factors) | ||
|
||
-- Finding a factorization | ||
------------------------------------------------------------------------ | ||
|
||
-- this builds up three important things: | ||
-- * a proof that every number we've gotten to so far has increasingly higher | ||
-- possible least prime factor, so we don't have to repeat smaller factores | ||
-- over and over (this is the "k" and "k-rough-n" parameters) | ||
-- * a witness that this limit is getting closer to the number of interest, in a | ||
-- way that helps the termination checker (the k≤n parameter) | ||
-- * a proof that we can factorize any smaller number, which is useful when we | ||
-- encounter a factor, as we can then divide by that factor and continue from | ||
-- there without termination issues | ||
|
||
factorize : ∀ n → .{{NonZero n}} → Factorization n | ||
factorize 1 = record | ||
{ factors = [] | ||
; isFactorization = refl | ||
; factorsPrime = [] | ||
} | ||
factorize (suc (suc n)) = <-rec (λ n′ → ∀ {k} → 2 ≤ n′ → k ≤‴ n′ → k Rough n′ → Factorization n′) factorizeRec (2 + n) {2} (s≤s (s≤s z≤n)) (≤⇒≤‴ (s≤s (s≤s z≤n))) (2-rough-n (2 + n)) | ||
where | ||
factorizeRec : ∀ n → <-Rec (λ n′ → ∀ {k} → 2 ≤ n′ → k ≤‴ n′ → k Rough n′ → Factorization n′) n → ∀ {k} → 2 ≤ n → k ≤‴ n → k Rough n → Factorization n | ||
factorizeRec (suc (suc n)) rec (s≤s (s≤s n≤z)) ≤‴-refl k-rough-n = record | ||
{ factors = 2 + n ∷ [] | ||
; isFactorization = *-identityʳ (2 + n) | ||
; factorsPrime = (λ 2≤d d<n d∣n → rough⇒∤ k-rough-n 2≤d d<n d∣n) ∷ [] | ||
} | ||
factorizeRec (suc (suc n)) rec {0} (s≤s (s≤s z≤n)) (≤‴-step (≤‴-step k<n)) k-rough-n = factorizeRec (2 + n) rec (s≤s (s≤s z≤n)) k<n (2-rough-n (2 + n)) | ||
factorizeRec (suc (suc n)) rec {1} (s≤s (s≤s z≤n)) (≤‴-step k<n) k-rough-n = factorizeRec (2 + n) rec (s≤s (s≤s z≤n)) k<n (2-rough-n (2 + n)) | ||
factorizeRec (suc (suc n)) rec {suc (suc k)} (s≤s (s≤s z≤n)) (≤‴-step k<n) k-rough-n with 2 + k ∣? 2 + n | ||
... | no k∤n = factorizeRec (2 + n) rec {3 + k} (s≤s (s≤s z≤n)) k<n (extend-∤ k-rough-n k∤n) | ||
... | yes k∣n = record | ||
{ factors = 2 + k ∷ Factorization.factors res | ||
; isFactorization = prop | ||
; factorsPrime = roughn∧∣n⇒prime k-rough-n (s≤s (s≤s z≤n)) k∣n ∷ Factorization.factorsPrime res | ||
} | ||
where | ||
open ≡-Reasoning | ||
|
||
-- we know that k < n, so if q is 0 or 1 then q * k < n | ||
2≤q : 2 ≤ quotient k∣n | ||
2≤q = ≮⇒≥ λ { (s≤s q≤1) → >⇒≢ (<-transʳ (*-monoˡ-≤ (2 + k) q≤1) (<-transʳ (≤-reflexive (+-identityʳ (2 + k))) (≤‴⇒≤ k<n))) (_∣_.equality k∣n) } | ||
|
||
q<n : quotient k∣n < 2 + n | ||
q<n = <-transˡ (m<m*n (quotient k∣n) (2 + k) ⦃ >-nonZero (<-transˡ (s≤s z≤n) 2≤q) ⦄ (s≤s (s≤s z≤n))) (≤-reflexive (sym (_∣_.equality k∣n))) | ||
|
||
res : Factorization (quotient k∣n) | ||
res = rec (quotient k∣n) q<n {2 + k} 2≤q (≤⇒≤‴ (≮⇒≥ (λ q<k → rough⇒∤ k-rough-n 2≤q q<k (quotient∣n k∣n)))) λ {d} d<k d-prime → k-rough-n d<k d-prime ∘ flip ∣-trans (quotient∣n k∣n) | ||
|
||
prop : (2 + k) * product (factors res) ≡ 2 + n | ||
prop = begin | ||
(2 + k) * product (factors res) ≡⟨ cong ((2 + k) *_) (Factorization.isFactorization res) ⟩ | ||
(2 + k) * quotient k∣n ≡⟨ *-comm (2 + k) (quotient k∣n) ⟩ | ||
quotient k∣n * (2 + k) ≡˘⟨ _∣_.equality k∣n ⟩ | ||
2 + n ∎ | ||
|
||
------------------------------------------------------------------------ | ||
-- Properties of a factorization | ||
|
||
factorization≥1 : ∀ {as} → All Prime as → product as ≥ 1 | ||
factorization≥1 {[]} [] = s≤s z≤n | ||
factorization≥1 {suc a ∷ as} (pa ∷ asPrime) = *-mono-≤ {1} {1 + a} (s≤s z≤n) (factorization≥1 asPrime) | ||
|
||
factorizationPullToFront : ∀ {as} {p} → Prime p → p ∣ product as → All Prime as → ∃[ as′ ] as ↭ (p ∷ as′) | ||
factorizationPullToFront {[]} {suc (suc p)} pPrime p∣Πas asPrime = contradiction (∣1⇒≡1 p∣Πas) λ () | ||
factorizationPullToFront {a ∷ as} {p} pPrime p∣aΠas (aPrime ∷ asPrime) with euclidsLemma a (product as) pPrime p∣aΠas | ||
... | inj₂ p∣Πas = Π.map (a ∷_) (λ as↭p∷as′ → ↭-trans (prep a as↭p∷as′) (↭.swap a p refl)) (factorizationPullToFront pPrime p∣Πas asPrime) | ||
... | inj₁ p∣a with ∣p⇒≡1∨≡p p aPrime p∣a | ||
... | inj₁ refl = ⊥-elim pPrime | ||
... | inj₂ refl = as , ↭-refl | ||
|
||
factorizationUnique′ : (as bs : List ℕ) → product as ≡ product bs → All Prime as → All Prime bs → as ↭ bs | ||
factorizationUnique′ [] [] Πas≡Πbs asPrime bsPrime = refl | ||
factorizationUnique′ [] (suc (suc b) ∷ bs) Πas≡Πbs asPrime (bPrime ∷ bsPrime) = contradiction Πas≡Πbs (<⇒≢ (<-transˡ (*-monoˡ-< 1 {1} {2 + b} (s≤s (s≤s z≤n))) (*-monoʳ-≤ (2 + b) (factorization≥1 bsPrime)))) | ||
factorizationUnique′ (a ∷ as) bs Πas≡Πbs (aPrime ∷ asPrime) bsPrime with bs′ , bs↭a∷bs′ ← factorizationPullToFront aPrime (divides (product as) (≡.trans (sym Πas≡Πbs) (*-comm a (product as)))) bsPrime = begin | ||
a ∷ as <⟨ factorizationUnique′ as bs′ | ||
(*-cancelˡ-≡ (product as) (product bs′) a {{Prime⇒NonZero aPrime}} (≡.trans Πas≡Πbs (productPreserves↭⇒≡ bs↭a∷bs′))) | ||
asPrime | ||
(All.tail (All-resp-↭ bs↭a∷bs′ bsPrime)) | ||
⟩ | ||
a ∷ bs′ ↭˘⟨ bs↭a∷bs′ ⟩ | ||
bs ∎ | ||
where open PermutationReasoning | ||
|
||
factorizationUnique : {n : ℕ} (f f′ : Factorization n) → factors f ↭ factors f′ | ||
factorizationUnique f f′ = factorizationUnique′ (factors f) (factors f′) (≡.trans (Factorization.isFactorization f) (sym (Factorization.isFactorization f′))) (Factorization.factorsPrime f) (Factorization.factorsPrime f′) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
------------------------------------------------------------------------ | ||
-- The Agda standard library | ||
-- | ||
-- Natural numbers whose prime factors are all above a bound | ||
------------------------------------------------------------------------ | ||
|
||
{-# OPTIONS --cubical-compatible --safe #-} | ||
|
||
module Data.Nat.Rough where | ||
Taneb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
open import Data.Nat.Base using (ℕ; suc; _≤_; _<_; z≤n; s≤s; _+_) | ||
open import Data.Nat.Divisibility using (_∣_; _∤_; ∣-trans; ∣1⇒≡1) | ||
open import Data.Nat.Induction using (<-rec; <-Rec) | ||
open import Data.Nat.Primality using (Prime; composite?) | ||
open import Data.Nat.Properties using (_≟_; <-trans; ≤∧≢⇒<) | ||
open import Data.Product.Base using (_,_) | ||
open import Function.Base using (_∘_; flip) | ||
open import Relation.Nullary.Decidable.Core using (yes; no) | ||
open import Relation.Binary.PropositionalEquality.Core using (refl) | ||
|
||
-- A number is k-rough if all its prime factors are greater than or equal to k | ||
_Rough_ : ℕ → ℕ → Set | ||
k Rough n = ∀ {d} → 1 < d → d < k → d ∤ n | ||
|
||
-- any number is 2-rough because all primes are greater than or equal to 2 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we have consistent capitalisation of comments? I think a starting capital is good 👍 |
||
2-rough-n : ∀ n → 2 Rough n | ||
2-rough-n n {1} (s≤s ()) 1<2 | ||
2-rough-n n {suc (suc d)} 1<d (s≤s (s≤s ())) | ||
|
||
-- if a number is k-rough, and it's not a multiple of k, then it's (k+1)-rough | ||
extend-∤ : ∀ {k n} → k Rough n → k ∤ n → suc k Rough n | ||
Taneb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
extend-∤ {k = k} k-rough-n k∤n {suc d} 1<d (s≤s d<k) with suc d ≟ k | ||
... | yes refl = k∤n | ||
... | no d≢k = k-rough-n 1<d (≤∧≢⇒< d<k d≢k) | ||
gallais marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
-- 1 is always rough | ||
b-rough-1 : ∀ k → k Rough 1 | ||
Taneb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
b-rough-1 k {d} 1<d d<k d∣1 with ∣1⇒≡1 d∣1 | ||
b-rough-1 k {.1} (s≤s ()) d<k d∣1 | refl | ||
|
||
-- if a number is k-rough, then so are all of its divisors | ||
reduce-∣ : ∀ {k m n} → k Rough m → n ∣ m → k Rough n | ||
reduce-∣ k-rough-n n∣m d<k d-prime d∣n = k-rough-n d<k d-prime (∣-trans d∣n n∣m) | ||
|
||
-- if a number is k-rough, then no number 2 ≤ d < k will divide it, whether prime or not | ||
rough⇒∤ : ∀ {d k n} → k Rough n → 2 ≤ d → d < k → d ∤ n | ||
rough⇒∤ {d} {k} {n} k-rough-n = <-rec (λ d′ → 2 ≤ d′ → d′ < k → d′ ∤ n) (rough⇒∤Rec k-rough-n) d | ||
where | ||
rough⇒∤Rec : ∀ {n k} → k Rough n → ∀ d → <-Rec (λ d′ → 2 ≤ d′ → d′ < k → d′ ∤ n) d → 2 ≤ d → d < k → d ∤ n | ||
rough⇒∤Rec {n} {k} k-rough-n (suc (suc d)) rec (s≤s (s≤s z≤n)) d<k with composite? (2 + d) | ||
... | yes (d′ , 2≤d′ , d′<d , d′∣d) = rec d′ d′<d 2≤d′ (<-trans d′<d d<k) ∘ ∣-trans d′∣d | ||
... | no ¬d-composite = k-rough-n {2 + d} (s≤s (s≤s z≤n)) d<k | ||
gallais marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
-- if a number is k-rough, and k divides it, then it must be prime | ||
MatthewDaggitt marked this conversation as resolved.
Show resolved
Hide resolved
|
||
roughn∧∣n⇒prime : ∀ {k n} → k Rough n → 2 ≤ k → k ∣ n → Prime k | ||
roughn∧∣n⇒prime {k = suc (suc k)} {n = n} k-rough-n (s≤s (s≤s z≤n)) k∣n | ||
= <-rec (λ d → 2 ≤ d → d < 2 + k → d ∤ 2 + k) (roughn∧∣n⇒primeRec k-rough-n k∣n) _ | ||
where | ||
roughn∧∣n⇒primeRec : ∀ {k n} → k Rough n → k ∣ n → ∀ d → <-Rec (λ d′ → 2 ≤ d′ → d′ < k → d′ ∤ k) d → 2 ≤ d → d < k → d ∤ k | ||
roughn∧∣n⇒primeRec {k} {n} k-rough-n k∣n (suc (suc d)) rec (s≤s (s≤s z≤n)) d<k with composite? (2 + d) | ||
... | yes (d′ , 2≤d′ , d′<d , d′∣d) = rec d′ d′<d 2≤d′ (<-trans d′<d d<k) ∘ ∣-trans d′∣d | ||
... | no ¬d-composite = k-rough-n (s≤s (s≤s z≤n)) d<k ∘ flip ∣-trans k∣n |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is
inspect
still on theimport
list?