{-# OPTIONS --warning=error --safe #-} open import LogicalFormulae open import Numbers.Naturals.Naturals open import Numbers.Naturals.Addition -- TODO - remove this dependency open import Numbers.Naturals.Multiplication -- TODO - remove this dependency open import Numbers.Naturals.Order -- TODO - remove this dependency open import Numbers.Naturals.WithK open import WellFoundedInduction open import KeyValue.KeyValue open import Orders open import Vectors open import Maybe open import WithK open import Semirings.Definition module PrimeNumbers where record divisionAlgResult (a : ℕ) (b : ℕ) : Set where field quot : ℕ rem : ℕ pr : a *N quot +N rem ≡ b remIsSmall : (rem 1 : 1 1 : 1 1 = n>1 ; divisor = divisor ; dividesN = dividesN ; divisorLessN = divisorLessN ; divisorNot1 = divisorNot1 } record { p>1 = p>1 ; pr = pr } = lessImpliesNotEqual divisorNot1 (equalityCommutative div=1) where div=1 : divisor ≡ 1 div=1 = pr {divisor} dividesN divisorLessN (orderIsTransitive (succIsPositive 0) divisorNot1) zeroIsNotPrime : Prime 0 → False zeroIsNotPrime record { p>1 = p>1 ; pr = pr } = zeroNeverGreater p>1 oneIsNotPrime : Prime 1 → False oneIsNotPrime record { p>1 = (le x proof) ; pr = pr } = naughtE (equalityCommutative absurd') where absurd : x +N 1 ≡ 0 absurd = succInjective proof absurd' : succ x ≡ 0 absurd' rewrite additionNIsCommutative 1 x = absurd twoIsPrime : Prime 2 Prime.p>1 twoIsPrime = succPreservesInequality (succIsPositive 0) Prime.pr twoIsPrime {i} i|2 i<2 01 = (le x ()) ; pr = pr } primesAreBiggerThanOne {succ zero} pr = exFalso (oneIsNotPrime pr) primesAreBiggerThanOne {succ (succ p)} pr = succPreservesInequality (succIsPositive p) primesAreBiggerThanZero : {p : ℕ} → Prime p → 0 1 = 11 = pr ; divisor = succ (succ firstPoss) ; dividesN = _&&_.fst x1 ; divisorLessN = _&&_.snd x1 ; divisorNot1 = succPreservesInequality (succIsPositive firstPoss) ; divisorPrime = record { p>1 = succPreservesInequality (succIsPositive firstPoss) ; pr = compositeOrPrimeLemma {succ (succ firstPoss)} {a} x (_&&_.fst x1) } }) go' (succ (succ (succ firstPoss))) | inl (inl x) | inr y rewrite y = inr x go' (succ (succ (succ firstPoss))) | inl (inr x) = inl (inr x) go' (succ (succ (succ firstPoss))) | inr x = inr x go {zero} pr = inl (inl (record { previousDoNotDivide = λ x 11 = p>1 ; pr = pr } p1|p2 | inl (inl p1p2) = exFalso (zeroIsNotPrime pr2) primeDivPrimeImpliesEqual {p1} {succ p2} pr1 pr2 p1|p2 | inl (inr p1>p2) = exFalso (divisorIsSmaller p1|p2 p1>p2) primeDivPrimeImpliesEqual {p1} {p2} pr1 pr2 p1|p2 | inr p1=p2 = p1=p2 mult1Lemma : {a b : ℕ} → a *N succ b ≡ 1 → (a ≡ 1) && (b ≡ 0) mult1Lemma {a} {b} pr = record { fst = _&&_.fst p ; snd = q} where p : (a ≡ 1) && (succ b ≡ 1) p = productOneImpliesOperandsOne pr q : b ≡ zero q = succInjective (_&&_.snd p) oneHasNoDivisors : {a : ℕ} → a ∣ 1 → a ≡ 1 oneHasNoDivisors {a} (divides record { quot = zero ; rem = .0 ; pr = pr ; remIsSmall = remIsSmall } refl) rewrite addZeroRight (a *N zero) | multiplicationNIsCommutative a zero | addZeroRight a = naughtE pr oneHasNoDivisors {a} (divides record { quot = (succ quot) ; rem = .0 ; pr = pr ; remIsSmall = remIsSmall } refl) rewrite addZeroRight (a *N succ quot) = _&&_.fst (mult1Lemma pr) notSmallerMeansGE : {a b : ℕ} → (a