{-# OPTIONS --warning=error --safe #-} open import LogicalFormulae open import Numbers.Naturals open import WellFoundedInduction open import KeyValue open import KeyValueWithDomain open import Orders open import Vectors open import Maybe 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