From cfd9787bb88bd8ddd47fb8bdf5b2318238f45040 Mon Sep 17 00:00:00 2001 From: Patrick Stevens Date: Wed, 4 Dec 2019 19:53:34 +0000 Subject: [PATCH] Problem 1 of Project Euler (#85) --- Decidable/Relations.agda | 37 ++ Decidable/Sets.agda | 10 + DecidableSet.agda | 10 - Everything/Safe.agda | 3 +- Everything/WithK.agda | 2 + Groups/FreeGroups.agda | 4 +- LogicalFormulae.agda | 4 + Numbers/BinaryNaturals/Definition.agda | 564 ++++++++++----------- Numbers/BinaryNaturals/Multiplication.agda | 304 +++++------ ProjectEuler/Problem1.agda | 35 ++ 10 files changed, 526 insertions(+), 447 deletions(-) create mode 100644 Decidable/Relations.agda create mode 100644 Decidable/Sets.agda delete mode 100644 DecidableSet.agda create mode 100644 ProjectEuler/Problem1.agda diff --git a/Decidable/Relations.agda b/Decidable/Relations.agda new file mode 100644 index 0000000..cbd245e --- /dev/null +++ b/Decidable/Relations.agda @@ -0,0 +1,37 @@ +{-# OPTIONS --safe --warning=error --without-K #-} + +open import LogicalFormulae +open import Agda.Primitive using (Level; lzero; lsuc; _⊔_) + +module Decidable.Relations where + +DecidableRelation : {a b : _} {A : Set a} (f : A → Set b) → Set (a ⊔ b) +DecidableRelation {A = A} f = (x : A) → (f x) || (f x → False) + +orDecidable : {a b c : _} {A : Set a} {f : A → Set b} {g : A → Set c} → DecidableRelation f → DecidableRelation g → DecidableRelation (λ x → (f x) || (g x)) +orDecidable fDec gDec x with fDec x +orDecidable fDec gDec x | inl fx = inl (inl fx) +orDecidable fDec gDec x | inr !fx with gDec x +orDecidable fDec gDec x | inr !fx | inl gx = inl (inr gx) +orDecidable {f = f} {g} fDec gDec x | inr !fx | inr !gx = inr t + where + t : (f x || g x) → False + t (inl x) = !fx x + t (inr x) = !gx x + +andDecidable : {a b c : _} {A : Set a} {f : A → Set b} {g : A → Set c} → DecidableRelation f → DecidableRelation g → DecidableRelation (λ x → (f x) && (g x)) +andDecidable fDec gDec x with fDec x +andDecidable fDec gDec x | inl fx with gDec x +andDecidable fDec gDec x | inl fx | inl gx = inl (fx ,, gx) +andDecidable fDec gDec x | inl fx | inr !gx = inr (λ x → !gx (_&&_.snd x)) +andDecidable fDec gDec x | inr !fx = inr (λ x → !fx (_&&_.fst x)) + +notDecidable : {a b : _} {A : Set a} {f : A → Set b} → DecidableRelation f → DecidableRelation (λ x → (f x) → False) +notDecidable fDec x with fDec x +notDecidable fDec x | inl fx = inr (λ x → x fx) +notDecidable fDec x | inr !fx = inl !fx + +doubleNegation : {a b : _} {A : Set a} {f : A → Set b} → DecidableRelation f → (x : A) → (((f x) → False) → False) → f x +doubleNegation fDec x with fDec x +doubleNegation fDec x | inl fx = λ _ → fx +doubleNegation fDec x | inr !fx = λ p → exFalso (p !fx) diff --git a/Decidable/Sets.agda b/Decidable/Sets.agda new file mode 100644 index 0000000..b8b0991 --- /dev/null +++ b/Decidable/Sets.agda @@ -0,0 +1,10 @@ +{-# OPTIONS --safe --warning=error --without-K #-} + +open import LogicalFormulae +open import Agda.Primitive using (Level; lzero; lsuc; _⊔_) + +module Decidable.Sets where + +record DecidableSet {a : _} (A : Set a) : Set a where + field + eq : (a b : A) → ((a ≡ b) || ((a ≡ b) → False)) diff --git a/DecidableSet.agda b/DecidableSet.agda deleted file mode 100644 index e652af0..0000000 --- a/DecidableSet.agda +++ /dev/null @@ -1,10 +0,0 @@ -{-# OPTIONS --safe --warning=error --without-K #-} - -open import LogicalFormulae -open import Agda.Primitive using (Level; lzero; lsuc; _⊔_) - -module DecidableSet where - - record DecidableSet {a : _} (A : Set a) : Set a where - field - eq : (a b : A) → ((a ≡ b) || ((a ≡ b) → False)) diff --git a/Everything/Safe.agda b/Everything/Safe.agda index 43f9d2a..8d418ee 100644 --- a/Everything/Safe.agda +++ b/Everything/Safe.agda @@ -79,7 +79,8 @@ open import Setoids.Functions.Extension open import Sets.Cardinality open import Sets.FinSet -open import DecidableSet +open import Decidable.Sets +open import Decidable.Relations open import Vectors open import Vectors.VectorSpace diff --git a/Everything/WithK.agda b/Everything/WithK.agda index 169c2c0..dca4934 100644 --- a/Everything/WithK.agda +++ b/Everything/WithK.agda @@ -27,4 +27,6 @@ open import Groups.LectureNotes.Lecture1 open import LectureNotes.NumbersAndSets.Lecture1 open import LectureNotes.Groups.Lecture1 +open import ProjectEuler.Problem1 + module Everything.WithK where diff --git a/Groups/FreeGroups.agda b/Groups/FreeGroups.agda index a31c226..4807c4a 100644 --- a/Groups/FreeGroups.agda +++ b/Groups/FreeGroups.agda @@ -11,7 +11,7 @@ open import Numbers.Naturals.WithK open import Sets.FinSet open import Groups.Definition open import Groups.SymmetricGroups.Definition -open import DecidableSet +open import Decidable.Sets module Groups.FreeGroups where @@ -107,7 +107,7 @@ badPrepend' {decA = decA} {x} (wordEnding pr x₁) | inr pr2 = pr2 refl freeGroupGenerators : {a : _} (A : Set a) (decA : DecidableSet A) (w : FreeGroupGenerators A) → SymmetryGroupElements (reflSetoid (ReducedWord decA)) freeGroupGenerators A decA (χ x) = sym {f = f} bij where - open DecidableSet.DecidableSet decA + open DecidableSet decA f : ReducedWord decA → ReducedWord decA f empty = prependLetter (ofLetter x) empty (wordEmpty refl) f (prependLetter (ofLetter startLetter) w pr) = prependLetter (ofLetter x) (prependLetter (ofLetter startLetter) w pr) (wordEnding (succIsPositive _) ans) diff --git a/LogicalFormulae.agda b/LogicalFormulae.agda index 87ab1b2..30642eb 100644 --- a/LogicalFormulae.agda +++ b/LogicalFormulae.agda @@ -94,6 +94,10 @@ boolAnd : Bool → Bool → Bool boolAnd BoolTrue y = y boolAnd BoolFalse y = BoolFalse +boolOr : Bool → Bool → Bool +boolOr BoolTrue y = BoolTrue +boolOr BoolFalse y = y + typeCast : {a : _} {A : Set a} {B : Set a} (el : A) (pr : A ≡ B) → B typeCast {a} {A} {.A} elt refl = elt diff --git a/Numbers/BinaryNaturals/Definition.agda b/Numbers/BinaryNaturals/Definition.agda index 0f2c6cb..8bcf49e 100644 --- a/Numbers/BinaryNaturals/Definition.agda +++ b/Numbers/BinaryNaturals/Definition.agda @@ -12,343 +12,343 @@ open import Orders module Numbers.BinaryNaturals.Definition where - data Bit : Set where - zero : Bit - one : Bit +data Bit : Set where + zero : Bit + one : Bit - BinNat : Set - BinNat = List Bit +BinNat : Set +BinNat = List Bit - ::Inj : {xs ys : BinNat} {i : Bit} → i :: xs ≡ i :: ys → xs ≡ ys - ::Inj {i = zero} refl = refl - ::Inj {i = one} refl = refl +::Inj : {xs ys : BinNat} {i : Bit} → i :: xs ≡ i :: ys → xs ≡ ys +::Inj {i = zero} refl = refl +::Inj {i = one} refl = refl - nonEmptyNotEmpty : {a : _} {A : Set a} {l1 : List A} {i : A} → i :: l1 ≡ [] → False - nonEmptyNotEmpty {l1 = l1} {i} () +nonEmptyNotEmpty : {a : _} {A : Set a} {l1 : List A} {i : A} → i :: l1 ≡ [] → False +nonEmptyNotEmpty {l1 = l1} {i} () -- TODO - maybe we should do the floating-point style of assuming there's a leading bit and not storing it. -- That way, everything is already canonical. - canonical : BinNat → BinNat - canonical [] = [] - canonical (zero :: n) with canonical n - canonical (zero :: n) | [] = [] - canonical (zero :: n) | x :: bl = zero :: x :: bl - canonical (one :: n) = one :: canonical n +canonical : BinNat → BinNat +canonical [] = [] +canonical (zero :: n) with canonical n +canonical (zero :: n) | [] = [] +canonical (zero :: n) | x :: bl = zero :: x :: bl +canonical (one :: n) = one :: canonical n - Canonicalised : Set - Canonicalised = Sg BinNat (λ i → canonical i ≡ i) +Canonicalised : Set +Canonicalised = Sg BinNat (λ i → canonical i ≡ i) - binNatToN : BinNat → ℕ - binNatToN [] = 0 - binNatToN (zero :: b) = 2 *N binNatToN b - binNatToN (one :: b) = 1 +N (2 *N binNatToN b) +binNatToN : BinNat → ℕ +binNatToN [] = 0 +binNatToN (zero :: b) = 2 *N binNatToN b +binNatToN (one :: b) = 1 +N (2 *N binNatToN b) - incr : BinNat → BinNat - incr [] = one :: [] - incr (zero :: n) = one :: n - incr (one :: n) = zero :: (incr n) +incr : BinNat → BinNat +incr [] = one :: [] +incr (zero :: n) = one :: n +incr (one :: n) = zero :: (incr n) - incrNonzero : (x : BinNat) → canonical (incr x) ≡ [] → False +incrNonzero : (x : BinNat) → canonical (incr x) ≡ [] → False - incrPreservesCanonical : (x : BinNat) → (canonical x ≡ x) → canonical (incr x) ≡ incr x - incrPreservesCanonical [] pr = refl - incrPreservesCanonical (zero :: xs) pr with canonical xs - incrPreservesCanonical (zero :: xs) pr | x :: t = applyEquality (one ::_) (::Inj pr) - incrPreservesCanonical (one :: xs) pr with inspect (canonical (incr xs)) - incrPreservesCanonical (one :: xs) pr | [] with≡ x = exFalso (incrNonzero xs x) - incrPreservesCanonical (one :: xs) pr | (x₁ :: y) with≡ x rewrite x = applyEquality (zero ::_) (transitivity (equalityCommutative x) (incrPreservesCanonical xs (::Inj pr))) +incrPreservesCanonical : (x : BinNat) → (canonical x ≡ x) → canonical (incr x) ≡ incr x +incrPreservesCanonical [] pr = refl +incrPreservesCanonical (zero :: xs) pr with canonical xs +incrPreservesCanonical (zero :: xs) pr | x :: t = applyEquality (one ::_) (::Inj pr) +incrPreservesCanonical (one :: xs) pr with inspect (canonical (incr xs)) +incrPreservesCanonical (one :: xs) pr | [] with≡ x = exFalso (incrNonzero xs x) +incrPreservesCanonical (one :: xs) pr | (x₁ :: y) with≡ x rewrite x = applyEquality (zero ::_) (transitivity (equalityCommutative x) (incrPreservesCanonical xs (::Inj pr))) - incrPreservesCanonical' : (x : BinNat) → canonical (incr x) ≡ incr (canonical x) +incrPreservesCanonical' : (x : BinNat) → canonical (incr x) ≡ incr (canonical x) - incrC : Canonicalised → Canonicalised - incrC (a , b) = incr a , incrPreservesCanonical a b +incrC : Canonicalised → Canonicalised +incrC (a , b) = incr a , incrPreservesCanonical a b - NToBinNat : ℕ → BinNat - NToBinNat zero = [] - NToBinNat (succ n) with NToBinNat n - NToBinNat (succ n) | t = incr t +NToBinNat : ℕ → BinNat +NToBinNat zero = [] +NToBinNat (succ n) with NToBinNat n +NToBinNat (succ n) | t = incr t - NToBinNatC : ℕ → Canonicalised - NToBinNatC zero = [] , refl - NToBinNatC (succ n) = incrC (NToBinNatC n) +NToBinNatC : ℕ → Canonicalised +NToBinNatC zero = [] , refl +NToBinNatC (succ n) = incrC (NToBinNatC n) - incrInj : {x y : BinNat} → incr x ≡ incr y → canonical x ≡ canonical y +incrInj : {x y : BinNat} → incr x ≡ incr y → canonical x ≡ canonical y - incrNonzero' : (x : BinNat) → (incr x) ≡ [] → False - incrNonzero' (zero :: xs) () - incrNonzero' (one :: xs) () +incrNonzero' : (x : BinNat) → (incr x) ≡ [] → False +incrNonzero' (zero :: xs) () +incrNonzero' (one :: xs) () - canonicalRespectsIncr' : {x y : BinNat} → canonical (incr x) ≡ canonical (incr y) → canonical x ≡ canonical y +canonicalRespectsIncr' : {x y : BinNat} → canonical (incr x) ≡ canonical (incr y) → canonical x ≡ canonical y - binNatToNSucc : (n : BinNat) → binNatToN (incr n) ≡ succ (binNatToN n) - NToBinNatSucc : (n : ℕ) → incr (NToBinNat n) ≡ NToBinNat (succ n) +binNatToNSucc : (n : BinNat) → binNatToN (incr n) ≡ succ (binNatToN n) +NToBinNatSucc : (n : ℕ) → incr (NToBinNat n) ≡ NToBinNat (succ n) - binNatToNZero : (x : BinNat) → binNatToN x ≡ 0 → canonical x ≡ [] - binNatToNZero' : (x : BinNat) → canonical x ≡ [] → binNatToN x ≡ 0 +binNatToNZero : (x : BinNat) → binNatToN x ≡ 0 → canonical x ≡ [] +binNatToNZero' : (x : BinNat) → canonical x ≡ [] → binNatToN x ≡ 0 - NToBinNatZero : (n : ℕ) → NToBinNat n ≡ [] → n ≡ 0 - NToBinNatZero zero pr = refl - NToBinNatZero (succ n) pr with NToBinNat n - NToBinNatZero (succ n) pr | zero :: bl = exFalso (nonEmptyNotEmpty pr) - NToBinNatZero (succ n) pr | one :: bl = exFalso (nonEmptyNotEmpty pr) +NToBinNatZero : (n : ℕ) → NToBinNat n ≡ [] → n ≡ 0 +NToBinNatZero zero pr = refl +NToBinNatZero (succ n) pr with NToBinNat n +NToBinNatZero (succ n) pr | zero :: bl = exFalso (nonEmptyNotEmpty pr) +NToBinNatZero (succ n) pr | one :: bl = exFalso (nonEmptyNotEmpty pr) - canonicalAscends : {i : Bit} → (a : BinNat) → 0