From 8377c23613954171ef7ef99c6d5d05598a3c5f60 Mon Sep 17 00:00:00 2001 From: Patrick Stevens Date: Sun, 17 Nov 2019 17:37:10 +0000 Subject: [PATCH] Polynomial ring (#76) --- Everything/Safe.agda | 4 + Fields/FieldOfFractions/Lemmas.agda | 1 + Groups/Polynomials/Addition.agda | 61 +++++ Groups/Polynomials/Definition.agda | 131 +++++++++ Groups/Polynomials/Examples.agda | 35 +++ Groups/Polynomials/Group.agda | 81 ++++++ Lists/Lists.agda | 254 ++++++++++-------- Numbers/Integers/Definition.agda | 16 ++ Numbers/Integers/Integers.agda | 4 +- Numbers/Integers/Multiplication.agda | 173 ------------ Numbers/Integers/Order.agda | 4 +- .../RingStructure/IntegralDomain.agda | 23 ++ Numbers/Integers/RingStructure/Ring.agda | 179 ++++++++++++ Numbers/Naturals/Definition.agda | 8 + Numbers/Rationals/Lemmas.agda | 1 + Rings/Definition.agda | 67 ++--- Rings/Homomorphisms/Definition.agda | 26 ++ Rings/Ideals/Definition.agda | 20 ++ Rings/Isomorphisms/Definition.agda | 22 ++ Rings/Polynomial/Definition.agda | 33 +++ Rings/Polynomial/Multiplication.agda | 123 +++++++++ Rings/Polynomial/Ring.agda | 45 ++++ Vectors.agda | 14 +- 23 files changed, 984 insertions(+), 341 deletions(-) create mode 100644 Groups/Polynomials/Addition.agda create mode 100644 Groups/Polynomials/Definition.agda create mode 100644 Groups/Polynomials/Examples.agda create mode 100644 Groups/Polynomials/Group.agda create mode 100644 Numbers/Integers/RingStructure/IntegralDomain.agda create mode 100644 Numbers/Integers/RingStructure/Ring.agda create mode 100644 Rings/Homomorphisms/Definition.agda create mode 100644 Rings/Ideals/Definition.agda create mode 100644 Rings/Isomorphisms/Definition.agda create mode 100644 Rings/Polynomial/Definition.agda create mode 100644 Rings/Polynomial/Multiplication.agda create mode 100644 Rings/Polynomial/Ring.agda diff --git a/Everything/Safe.agda b/Everything/Safe.agda index fc6500e..1440529 100644 --- a/Everything/Safe.agda +++ b/Everything/Safe.agda @@ -29,6 +29,7 @@ open import Groups.SymmetricGroups.Lemmas open import Groups.ActionIsSymmetry open import Groups.Cyclic.Definition open import Groups.Cyclic.DefinitionLemmas +open import Groups.Polynomials.Examples open import Fields.Fields open import Fields.Orders.Partial.Definition @@ -45,6 +46,9 @@ open import Rings.Orders.Total.Lemmas open import Rings.Orders.Partial.Lemmas open import Rings.IntegralDomains open import Rings.DirectSum +open import Rings.Polynomial.Ring +open import Rings.Ideals.Definition +open import Rings.Isomorphisms.Definition open import Setoids.Setoids open import Setoids.DirectSum diff --git a/Fields/FieldOfFractions/Lemmas.agda b/Fields/FieldOfFractions/Lemmas.agda index 021ad2d..979d4e0 100644 --- a/Fields/FieldOfFractions/Lemmas.agda +++ b/Fields/FieldOfFractions/Lemmas.agda @@ -7,6 +7,7 @@ open import Groups.Definition open import Groups.Lemmas open import Rings.Definition open import Rings.Lemmas +open import Rings.Homomorphisms.Definition open import Rings.IntegralDomains open import Fields.Fields open import Functions diff --git a/Groups/Polynomials/Addition.agda b/Groups/Polynomials/Addition.agda new file mode 100644 index 0000000..c977e77 --- /dev/null +++ b/Groups/Polynomials/Addition.agda @@ -0,0 +1,61 @@ +{-# OPTIONS --safe --warning=error --without-K #-} + +open import LogicalFormulae +open import Groups.Groups +open import Groups.Homomorphisms.Definition +open import Groups.Definition +open import Numbers.Naturals.Definition +open import Setoids.Orders +open import Setoids.Setoids +open import Functions +open import Sets.EquivalenceRelations +open import Vectors +open import Lists.Lists +open import Maybe + +open import Agda.Primitive using (Level; lzero; lsuc; _⊔_) + +module Groups.Polynomials.Addition {a b : _} {A : Set a} {S : Setoid {a} {b} A} {_+_ : A → A → A} (G : Group S _+_) where + +open import Groups.Polynomials.Definition G +open Setoid S +open Equivalence eq +open Group G + +_+P_ : NaivePoly → NaivePoly → NaivePoly +_+P_ = listZip _+_ id id + +PidentRight : {m : NaivePoly} → polysEqual (m +P []) m +PidentRight {[]} = record {} +PidentRight {x :: m} = reflexive ,, identityOfIndiscernablesLeft polysEqual (Equivalence.reflexive (Setoid.eq naivePolySetoid)) (equalityCommutative (mapId m)) + ++PwellDefined : {m n x y : NaivePoly} → polysEqual m x → polysEqual n y → polysEqual (m +P n) (x +P y) ++PwellDefined {[]} {[]} {[]} {[]} m=x n=y = record {} ++PwellDefined {[]} {[]} {[]} {x :: y} m=x (fst ,, snd) = fst ,, identityOfIndiscernablesRight polysEqual snd (equalityCommutative (mapId y)) ++PwellDefined {[]} {[]} {x :: xs} {[]} (fst ,, snd) n=y = fst ,, identityOfIndiscernablesRight polysEqual snd (equalityCommutative (mapId xs)) ++PwellDefined {[]} {[]} {x :: xs} {y :: ys} (fst ,, snd) (fst2 ,, snd2) = transitive (+WellDefined fst fst2) identRight ,, +PwellDefined {[]} {[]} {xs} {ys} snd snd2 ++PwellDefined {[]} {n :: ns} {[]} {[]} m=x (fst ,, snd) = fst ,, identityOfIndiscernablesLeft polysEqual snd (equalityCommutative (mapId ns)) ++PwellDefined {[]} {n :: ns} {[]} {y :: ys} m=x (fst ,, snd) = fst ,, +PwellDefined m=x snd ++PwellDefined {[]} {n :: ns} {x :: xs} {[]} (fst ,, snd) (fst2 ,, snd2) = transitive fst2 (symmetric fst) ,, ans + where + ans : polysEqual (map (λ z → z) ns) (map (λ z → z) xs) + ans rewrite mapId ns | mapId xs = Equivalence.transitive (Setoid.eq naivePolySetoid) snd2 snd ++PwellDefined {[]} {n :: ns} {x :: xs} {y :: ys} (fst ,, snd) (fst2 ,, snd2) = transitive (symmetric identLeft) (+WellDefined (symmetric fst) fst2) ,, (+PwellDefined snd snd2) ++PwellDefined {m :: ms} {[]} {[]} {[]} (fst ,, snd) _ = fst ,, identityOfIndiscernablesLeft polysEqual snd (equalityCommutative (mapId ms)) ++PwellDefined {m :: ms} {[]} {[]} {x :: ys} (fst ,, snd) (fst2 ,, snd2) = transitive fst (symmetric fst2) ,, ans + where + ans : polysEqual (map (λ z → z) ms) (map (λ z → z) ys) + ans rewrite mapId ms | mapId ys = Equivalence.transitive (Setoid.eq naivePolySetoid) snd snd2 ++PwellDefined {m :: ms} {[]} {x :: xs} {[]} (fst ,, snd) n=y = fst ,, ans + where + ans : polysEqual (map (λ z → z) ms) (map (λ z → z) xs) + ans rewrite mapId ms | mapId xs = snd ++PwellDefined {m :: ms} {[]} {x :: xs} {y :: ys} (fst ,, snd) (fst2 ,, snd2) = transitive (symmetric identRight) (+WellDefined fst (symmetric fst2)) ,, identityOfIndiscernablesLeft polysEqual (Equivalence.transitive (Setoid.eq naivePolySetoid) (Equivalence.symmetric (Setoid.eq naivePolySetoid) PidentRight) (+PwellDefined snd snd2)) (equalityCommutative (mapId ms)) ++PwellDefined {m :: ms} {n :: ns} {[]} {[]} (fst ,, snd) (fst2 ,, snd2) = transitive (+WellDefined fst fst2) identLeft ,, +PwellDefined snd snd2 ++PwellDefined {m :: ms} {n :: ns} {[]} {y :: ys} (fst ,, snd) (fst2 ,, snd2) = transitive (+WellDefined fst fst2) identLeft ,, +PwellDefined snd snd2 ++PwellDefined {m :: ms} {n :: ns} {x :: xs} {[]} (fst ,, snd) (fst2 ,, snd2) = transitive (+WellDefined fst fst2) identRight ,, identityOfIndiscernablesRight polysEqual (Equivalence.transitive (Setoid.eq naivePolySetoid) (+PwellDefined snd snd2) PidentRight) (equalityCommutative (mapId xs)) ++PwellDefined {m :: ms} {n :: ns} {x :: xs} {y :: ys} (fst ,, snd) (fst2 ,, snd2) = +WellDefined fst fst2 ,, +PwellDefined snd snd2 + +PidentLeft : {m : NaivePoly} → polysEqual ([] +P m) m +PidentLeft {[]} = record {} +PidentLeft {x :: m} = reflexive ,, identityOfIndiscernablesLeft polysEqual (Equivalence.reflexive (Setoid.eq naivePolySetoid)) (equalityCommutative (mapId m)) diff --git a/Groups/Polynomials/Definition.agda b/Groups/Polynomials/Definition.agda new file mode 100644 index 0000000..6694035 --- /dev/null +++ b/Groups/Polynomials/Definition.agda @@ -0,0 +1,131 @@ +{-# OPTIONS --safe --warning=error --without-K #-} + +open import LogicalFormulae +open import Groups.Groups +open import Groups.Homomorphisms.Definition +open import Groups.Definition +open import Numbers.Naturals.Definition +open import Setoids.Orders +open import Setoids.Setoids +open import Functions +open import Sets.EquivalenceRelations +open import Vectors +open import Lists.Lists +open import Maybe + +open import Agda.Primitive using (Level; lzero; lsuc; _⊔_) + +module Groups.Polynomials.Definition {a b : _} {A : Set a} {S : Setoid {a} {b} A} {_+_ : A → A → A} (G : Group S _+_) where + +open Setoid S +open Equivalence eq +open Group G + +NaivePoly : Set a +NaivePoly = List A + +0P : NaivePoly +0P = [] + +polysEqual : NaivePoly → NaivePoly → Set (a ⊔ b) +polysEqual [] [] = True' +polysEqual [] (x :: b) = (x ∼ 0G) && polysEqual [] b +polysEqual (x :: a) [] = (x ∼ 0G) && polysEqual a [] +polysEqual (x :: a) (y :: b) = (x ∼ y) && polysEqual a b + +polysReflexive : {x : NaivePoly} → polysEqual x x +polysReflexive {[]} = record {} +polysReflexive {x :: y} = reflexive ,, polysReflexive + +polysSymmetricZero : {x : NaivePoly} → polysEqual [] x → polysEqual x [] +polysSymmetricZero {[]} 0=x = record {} +polysSymmetricZero {x :: y} (fst ,, snd) = fst ,, polysSymmetricZero snd + +polysSymmetricZero' : {x : NaivePoly} → polysEqual x [] → polysEqual [] x +polysSymmetricZero' {[]} 0=x = record {} +polysSymmetricZero' {x :: y} (fst ,, snd) = fst ,, polysSymmetricZero' snd + +polysSymmetric : {x y : NaivePoly} → polysEqual x y → polysEqual y x +polysSymmetric {[]} {y} x=y = polysSymmetricZero x=y +polysSymmetric {x :: xs} {[]} x=y = polysSymmetricZero' {x :: xs} x=y +polysSymmetric {x :: xs} {y :: ys} (fst ,, snd) = symmetric fst ,, polysSymmetric {xs} {ys} snd + +polysTransitive : {x y z : NaivePoly} → polysEqual x y → polysEqual y z → polysEqual x z +polysTransitive {[]} {[]} {[]} x=y y=z = record {} +polysTransitive {[]} {[]} {x :: z} x=y y=z = y=z +polysTransitive {[]} {x :: y} {[]} (fst ,, snd) y=z = record {} +polysTransitive {[]} {x :: y} {x₁ :: z} (fst ,, snd) (fst2 ,, snd2) = transitive (symmetric fst2) fst ,, polysTransitive snd snd2 +polysTransitive {x :: xs} {[]} {[]} x=y y=z = x=y +polysTransitive {x :: xs} {[]} {z :: zs} (fst ,, snd) (fst2 ,, snd2) = transitive fst (symmetric fst2) ,, polysTransitive snd snd2 +polysTransitive {x :: xs} {y :: ys} {[]} (fst ,, snd) (fst2 ,, snd2) = transitive fst fst2 ,, polysTransitive snd snd2 +polysTransitive {x :: xs} {y :: ys} {z :: zs} (fst ,, snd) (fst2 ,, snd2) = transitive fst fst2 ,, polysTransitive snd snd2 + +naivePolySetoid : Setoid NaivePoly +Setoid._∼_ naivePolySetoid = polysEqual +Equivalence.reflexive (Setoid.eq naivePolySetoid) = polysReflexive +Equivalence.symmetric (Setoid.eq naivePolySetoid) = polysSymmetric +Equivalence.transitive (Setoid.eq naivePolySetoid) = polysTransitive + +polyInjection : A → NaivePoly +polyInjection a = a :: [] + +polyInjectionIsInj : SetoidInjection S naivePolySetoid polyInjection +SetoidInjection.wellDefined polyInjectionIsInj x=y = x=y ,, record {} +SetoidInjection.injective polyInjectionIsInj {x} {y} (fst ,, snd) = fst + +-- the zero polynomial has no degree +-- all other polynomials have a degree + +degree : ((x : A) → (x ∼ 0G) || ((x ∼ 0G) → False)) → NaivePoly → Maybe ℕ +degree decide [] = no +degree decide (x :: poly) with decide x +degree decide (x :: poly) | inl x=0 with degree decide poly +degree decide (x :: poly) | inl x=0 | no = no +degree decide (x :: poly) | inl x=0 | yes deg = yes (succ deg) +degree decide (x :: poly) | inr x!=0 with degree decide poly +degree decide (x :: poly) | inr x!=0 | no = yes 0 +degree decide (x :: poly) | inr x!=0 | yes n = yes (succ n) + +degreeWellDefined : (decide : ((x : A) → (x ∼ 0G) || ((x ∼ 0G) → False))) {x y : NaivePoly} → polysEqual x y → degree decide x ≡ degree decide y +degreeWellDefined decide {[]} {[]} x=y = refl +degreeWellDefined decide {[]} {x :: y} (fst ,, snd) with decide x +degreeWellDefined decide {[]} {x :: y} (fst ,, snd) | inl x=0 with inspect (degree decide y) +degreeWellDefined decide {[]} {x :: y} (fst ,, snd) | inl x=0 | no with≡ pr rewrite pr = refl +degreeWellDefined decide {[]} {x :: y} (fst ,, snd) | inl x=0 | yes bad with≡ pr rewrite pr = exFalso (noNotYes (transitivity (degreeWellDefined decide {[]} {y} snd) pr)) +degreeWellDefined decide {[]} {x :: y} (fst ,, snd) | inr x!=0 with inspect (degree decide y) +degreeWellDefined decide {[]} {x :: y} (fst ,, snd) | inr x!=0 | no with≡ pr rewrite pr = exFalso (x!=0 fst) +degreeWellDefined decide {[]} {x :: y} (fst ,, snd) | inr x!=0 | yes deg with≡ pr rewrite pr = exFalso (x!=0 fst) +degreeWellDefined decide {x :: xs} {[]} x=y with decide x +degreeWellDefined decide {x :: xs} {[]} (fst ,, snd) | inl x=0 with inspect (degree decide xs) +degreeWellDefined decide {x :: xs} {[]} (fst ,, snd) | inl x=0 | no with≡ pr rewrite pr = refl +degreeWellDefined decide {x :: xs} {[]} (fst ,, snd) | inl x=0 | yes bad with≡ pr rewrite pr = exFalso (noNotYes (transitivity (equalityCommutative (degreeWellDefined decide snd)) pr)) +degreeWellDefined decide {x :: xs} {[]} (fst ,, snd) | inr x!=0 = exFalso (x!=0 fst) +degreeWellDefined decide {x :: xs} {y :: ys} (fst ,, snd) with decide x +degreeWellDefined decide {x :: xs} {y :: ys} (fst ,, snd) | inl x=0 with decide y +degreeWellDefined decide {x :: xs} {y :: ys} (fst ,, snd) | inl x=0 | inl y=0 with inspect (degree decide ys) +degreeWellDefined decide {x :: xs} {y :: ys} (fst ,, snd) | inl x=0 | inl y=0 | no with≡ pr rewrite degreeWellDefined decide {xs} {ys} snd | pr = refl +degreeWellDefined decide {x :: xs} {y :: ys} (fst ,, snd) | inl x=0 | inl y=0 | (yes th) with≡ pr rewrite degreeWellDefined decide {xs} {ys} snd | pr = refl +degreeWellDefined decide {x :: xs} {y :: ys} (fst ,, snd) | inl x=0 | inr y!=0 = exFalso (y!=0 (transitive (symmetric fst) x=0)) +degreeWellDefined decide {x :: xs} {y :: ys} (fst ,, snd) | inr x!=0 with decide y +degreeWellDefined decide {x :: xs} {y :: ys} (fst ,, snd) | inr x!=0 | inl y=0 = exFalso (x!=0 (transitive fst y=0)) +degreeWellDefined decide {x :: xs} {y :: ys} (fst ,, snd) | inr x!=0 | inr y!=0 with inspect (degree decide ys) +degreeWellDefined decide {x :: xs} {y :: ys} (fst ,, snd) | inr x!=0 | inr y!=0 | no with≡ pr rewrite degreeWellDefined decide {xs} {ys} snd | pr = refl +degreeWellDefined decide {x :: xs} {y :: ys} (fst ,, snd) | inr x!=0 | inr y!=0 | yes x₁ with≡ pr rewrite degreeWellDefined decide {xs} {ys} snd | pr = refl + +degreeNoImpliesZero : (decide : ((x : A) → (x ∼ 0G) || ((x ∼ 0G) → False))) → (a : NaivePoly) → degree decide a ≡ no → polysEqual a [] +degreeNoImpliesZero decide [] not = record {} +degreeNoImpliesZero decide (x :: a) not with decide x +degreeNoImpliesZero decide (x :: a) not | inl x=0 with inspect (degree decide a) +degreeNoImpliesZero decide (x :: a) not | inl x=0 | no with≡ pr rewrite pr = x=0 ,, degreeNoImpliesZero decide a pr +degreeNoImpliesZero decide (x :: a) not | inl x=0 | (yes deg) with≡ pr rewrite pr = exFalso (noNotYes (equalityCommutative not)) +degreeNoImpliesZero decide (x :: a) not | inr x!=0 with degree decide a +degreeNoImpliesZero decide (x :: a) () | inr x!=0 | no +degreeNoImpliesZero decide (x :: a) () | inr x!=0 | yes x₁ + +emptyImpliesDegreeZero : (decide : ((x : A) → (x ∼ 0G) || ((x ∼ 0G) → False))) → (a : NaivePoly) → polysEqual a [] → degree decide a ≡ no +emptyImpliesDegreeZero decide [] a=[] = refl +emptyImpliesDegreeZero decide (x :: a) (fst ,, snd) with decide x +emptyImpliesDegreeZero decide (x :: a) (fst ,, snd) | inl x=0 with inspect (degree decide a) +emptyImpliesDegreeZero decide (x :: a) (fst ,, snd) | inl x=0 | no with≡ pr rewrite pr = refl +emptyImpliesDegreeZero decide (x :: a) (fst ,, snd) | inl x=0 | (yes deg) with≡ pr rewrite pr = exFalso (noNotYes (transitivity (equalityCommutative (emptyImpliesDegreeZero decide a snd)) pr)) +emptyImpliesDegreeZero decide (x :: a) (fst ,, snd) | inr x!=0 = exFalso (x!=0 fst) diff --git a/Groups/Polynomials/Examples.agda b/Groups/Polynomials/Examples.agda new file mode 100644 index 0000000..7a59c08 --- /dev/null +++ b/Groups/Polynomials/Examples.agda @@ -0,0 +1,35 @@ +{-# OPTIONS --safe --warning=error --without-K #-} + +open import LogicalFormulae +open import Groups.Groups +open import Groups.Homomorphisms.Definition +open import Groups.Definition +open import Numbers.Naturals.Definition +open import Numbers.Integers.Integers +open import Numbers.Integers.Definition +open import Setoids.Orders +open import Setoids.Setoids +open import Functions +open import Sets.EquivalenceRelations +open import Vectors +open import Lists.Lists +open import Maybe + +open import Agda.Primitive using (Level; lzero; lsuc; _⊔_) + +module Groups.Polynomials.Examples where + +open import Groups.Polynomials.Definition ℤGroup + +private + decide : _ + decide = (λ a → ℤDecideEquality a (nonneg 0)) + + p1 : degree decide [] ≡ no + p1 = refl + + p2 : degree decide (nonneg 0 :: []) ≡ no + p2 = refl + + p3 : degree decide (nonneg 1 :: []) ≡ yes 0 + p3 = refl diff --git a/Groups/Polynomials/Group.agda b/Groups/Polynomials/Group.agda new file mode 100644 index 0000000..c4eb969 --- /dev/null +++ b/Groups/Polynomials/Group.agda @@ -0,0 +1,81 @@ +{-# OPTIONS --safe --warning=error --without-K #-} + +open import LogicalFormulae +open import Groups.Groups +open import Groups.Abelian.Definition +open import Groups.Homomorphisms.Definition +open import Groups.Definition +open import Numbers.Naturals.Definition +open import Setoids.Orders +open import Setoids.Setoids +open import Functions +open import Sets.EquivalenceRelations +open import Vectors +open import Lists.Lists +open import Maybe + +open import Agda.Primitive using (Level; lzero; lsuc; _⊔_) + +module Groups.Polynomials.Group {a b : _} {A : Set a} {S : Setoid {a} {b} A} {_+_ : A → A → A} (G : Group S _+_) where + +open import Groups.Polynomials.Definition G +open import Groups.Polynomials.Addition G public +open Setoid S +open Equivalence eq + +inverse : NaivePoly → NaivePoly +inverse = map (Group.inverse G) + +invLeft : {a : NaivePoly} → polysEqual ((inverse a) +P a) [] +invLeft {[]} = record {} +invLeft {x :: a} = Group.invLeft G ,, invLeft {a} + +invRight : {a : NaivePoly} → polysEqual (a +P (inverse a)) [] +invRight {[]} = record {} +invRight {x :: a} = Group.invRight G ,, invRight {a} + +assoc : {a b c : NaivePoly} → polysEqual (a +P (b +P c)) ((a +P b) +P c) +assoc {[]} {[]} {[]} = record {} +assoc {[]} {[]} {x :: c} = reflexive ,, ans + where + ans : polysEqual (map (λ z → z) (map (λ z → z) c)) (map (λ z → z) c) + ans rewrite mapId c | mapId c = Equivalence.reflexive (Setoid.eq naivePolySetoid) +assoc {[]} {b :: bs} {[]} = reflexive ,, ans + where + ans : polysEqual (map (λ z → z) (map (λ z → z) bs)) (map (λ z → z) (map (λ z → z) bs)) + ans rewrite mapId bs | mapId bs = Equivalence.reflexive (Setoid.eq naivePolySetoid) +assoc {[]} {b :: bs} {c :: cs} = reflexive ,, ans + where + ans : polysEqual (map (λ z → z) (listZip _+_ (λ z → z) (λ z → z) bs cs)) (listZip _+_ (λ z → z) (λ z → z) (map (λ z → z) bs) cs) + ans rewrite mapId bs | mapId (listZip _+_ id id bs cs) = Equivalence.reflexive (Setoid.eq naivePolySetoid) +assoc {a :: as} {[]} {[]} = reflexive ,, ans + where + ans : polysEqual (map (λ z → z) as) (map (λ z → z) (map (λ z → z) as)) + ans rewrite mapId as | mapId as = Equivalence.reflexive (Setoid.eq naivePolySetoid) +assoc {a :: as} {[]} {c :: cs} = reflexive ,, ans + where + ans : polysEqual (listZip _+_ (λ z → z) (λ z → z) as (map (λ z → z) cs)) (listZip _+_ (λ z → z) (λ z → z) (map (λ z → z) as) cs) + ans rewrite mapId cs | mapId as = Equivalence.reflexive (Setoid.eq naivePolySetoid) +assoc {a :: as} {b :: bs} {[]} = reflexive ,, ans + where + ans : polysEqual (listZip _+_ (λ z → z) (λ z → z) as (map (λ z → z) bs)) (map (λ z → z) (listZip _+_ (λ z → z) (λ z → z) as bs)) + ans rewrite mapId (listZip _+_ id id as bs) | mapId bs = Equivalence.reflexive (Setoid.eq naivePolySetoid) +assoc {a :: as} {b :: bs} {c :: cs} = Group.+Associative G ,, assoc {as} {bs} {cs} + +polyGroup : Group naivePolySetoid _+P_ +Group.+WellDefined polyGroup = +PwellDefined +Group.0G polyGroup = [] +Group.inverse polyGroup = inverse +Group.+Associative polyGroup {a} {b} {c} = assoc {a} {b} {c} +Group.identRight polyGroup = PidentRight +Group.identLeft polyGroup = PidentLeft +Group.invLeft polyGroup {a} = invLeft {a} +Group.invRight polyGroup {a} = invRight {a} + +comm : AbelianGroup G → {x y : NaivePoly} → polysEqual (x +P y) (y +P x) +comm com {[]} {y} = Equivalence.transitive (Setoid.eq naivePolySetoid) (Group.identLeft polyGroup) (Equivalence.symmetric (Setoid.eq naivePolySetoid) (Group.identRight polyGroup)) +comm com {x :: xs} {[]} = reflexive ,, Equivalence.reflexive (Setoid.eq naivePolySetoid) +comm com {x :: xs} {y :: ys} = AbelianGroup.commutative com ,, comm com {xs} {ys} + +abelian : AbelianGroup G → AbelianGroup polyGroup +AbelianGroup.commutative (abelian ab) {x} {y} = comm ab {x} {y} diff --git a/Lists/Lists.agda b/Lists/Lists.agda index 82152b5..cfe637c 100644 --- a/Lists/Lists.agda +++ b/Lists/Lists.agda @@ -5,155 +5,177 @@ open import Functions open import Numbers.Naturals.Semiring -- for length open import Numbers.Naturals.Order open import Semirings.Definition +open import Maybe module Lists.Lists where - data List {a} (A : Set a) : Set a where - [] : List A - _::_ : (x : A) (xs : List A) → List A - infixr 10 _::_ - [_] : {a : _} → {A : Set a} → (a : A) → List A - [ a ] = a :: [] +data List {a} (A : Set a) : Set a where + [] : List A + _::_ : (x : A) (xs : List A) → List A +infixr 10 _::_ - _++_ : {a : _} → {A : Set a} → List A → List A → List A - [] ++ m = m - (x :: l) ++ m = x :: (l ++ m) +[_] : {a : _} → {A : Set a} → (a : A) → List A +[ a ] = a :: [] - appendEmptyList : {a : _} → {A : Set a} → (l : List A) → (l ++ [] ≡ l) - appendEmptyList [] = refl - appendEmptyList (x :: l) = applyEquality (_::_ x) (appendEmptyList l) +_++_ : {a : _} → {A : Set a} → List A → List A → List A +[] ++ m = m +(x :: l) ++ m = x :: (l ++ m) - concatAssoc : {a : _} → {A : Set a} → (x : List A) → (y : List A) → (z : List A) → ((x ++ y) ++ z) ≡ x ++ (y ++ z) - concatAssoc [] m n = refl - concatAssoc (x :: l) m n = applyEquality (_::_ x) (concatAssoc l m n) +appendEmptyList : {a : _} → {A : Set a} → (l : List A) → (l ++ [] ≡ l) +appendEmptyList [] = refl +appendEmptyList (x :: l) = applyEquality (_::_ x) (appendEmptyList l) - canMovePrepend : {a : _} → {A : Set a} → (l : A) → {m n : ℕ} → (x : List A) (y : List A) → ((l :: x) ++ y ≡ l :: (x ++ y)) - canMovePrepend l [] n = refl - canMovePrepend l (x :: m) n = refl +concatAssoc : {a : _} → {A : Set a} → (x : List A) → (y : List A) → (z : List A) → ((x ++ y) ++ z) ≡ x ++ (y ++ z) +concatAssoc [] m n = refl +concatAssoc (x :: l) m n = applyEquality (_::_ x) (concatAssoc l m n) - rev : {a : _} → {A : Set a} → List A → List A - rev [] = [] - rev (x :: l) = (rev l) ++ [ x ] +canMovePrepend : {a : _} → {A : Set a} → (l : A) → {m n : ℕ} → (x : List A) (y : List A) → ((l :: x) ++ y ≡ l :: (x ++ y)) +canMovePrepend l [] n = refl +canMovePrepend l (x :: m) n = refl - revIsHom : {a : _} → {A : Set a} → (l1 : List A) → (l2 : List A) → (rev (l1 ++ l2) ≡ (rev l2) ++ (rev l1)) - revIsHom l1 [] = applyEquality rev (appendEmptyList l1) - revIsHom [] (x :: l2) with (rev l2 ++ [ x ]) - ... | r = equalityCommutative (appendEmptyList r) - revIsHom (w :: l1) (x :: l2) = transitivity t (equalityCommutative s) - where - s : ((rev l2 ++ [ x ]) ++ (rev l1 ++ [ w ])) ≡ (((rev l2 ++ [ x ]) ++ rev l1) ++ [ w ]) - s = equalityCommutative (concatAssoc (rev l2 ++ (x :: [])) (rev l1) ([ w ])) - t' : rev (l1 ++ (x :: l2)) ≡ rev (x :: l2) ++ rev l1 - t' = revIsHom l1 (x :: l2) - t : (rev (l1 ++ (x :: l2)) ++ [ w ]) ≡ ((rev l2 ++ [ x ]) ++ rev l1) ++ [ w ] - t = applyEquality (λ r → r ++ [ w ]) {rev (l1 ++ (x :: l2))} {((rev l2) ++ [ x ]) ++ rev l1} (transitivity t' (applyEquality (λ r → r ++ rev l1) {rev l2 ++ (x :: [])} {rev l2 ++ (x :: [])} refl)) +rev : {a : _} → {A : Set a} → List A → List A +rev [] = [] +rev (x :: l) = (rev l) ++ [ x ] - revRevIsId : {a : _} → {A : Set a} → (l : List A) → (rev (rev l) ≡ l) - revRevIsId [] = refl - revRevIsId (x :: l) = t - where - s : rev (rev l ++ [ x ] ) ≡ [ x ] ++ rev (rev l) - s = revIsHom (rev l) [ x ] - t : rev (rev l ++ [ x ] ) ≡ [ x ] ++ l - t = identityOfIndiscernablesRight _≡_ s (applyEquality (λ n → [ x ] ++ n) (revRevIsId l)) +revIsHom : {a : _} → {A : Set a} → (l1 : List A) → (l2 : List A) → (rev (l1 ++ l2) ≡ (rev l2) ++ (rev l1)) +revIsHom l1 [] = applyEquality rev (appendEmptyList l1) +revIsHom [] (x :: l2) with (rev l2 ++ [ x ]) +... | r = equalityCommutative (appendEmptyList r) +revIsHom (w :: l1) (x :: l2) = transitivity t (equalityCommutative s) + where + s : ((rev l2 ++ [ x ]) ++ (rev l1 ++ [ w ])) ≡ (((rev l2 ++ [ x ]) ++ rev l1) ++ [ w ]) + s = equalityCommutative (concatAssoc (rev l2 ++ (x :: [])) (rev l1) ([ w ])) + t' : rev (l1 ++ (x :: l2)) ≡ rev (x :: l2) ++ rev l1 + t' = revIsHom l1 (x :: l2) + t : (rev (l1 ++ (x :: l2)) ++ [ w ]) ≡ ((rev l2 ++ [ x ]) ++ rev l1) ++ [ w ] + t = applyEquality (λ r → r ++ [ w ]) {rev (l1 ++ (x :: l2))} {((rev l2) ++ [ x ]) ++ rev l1} (transitivity t' (applyEquality (λ r → r ++ rev l1) {rev l2 ++ (x :: [])} {rev l2 ++ (x :: [])} refl)) - fold : {a b : _} {A : Set a} {B : Set b} (f : A → B → B) → B → List A → B - fold f default [] = default - fold f default (x :: l) = f x (fold f default l) +revRevIsId : {a : _} → {A : Set a} → (l : List A) → (rev (rev l) ≡ l) +revRevIsId [] = refl +revRevIsId (x :: l) = t + where + s : rev (rev l ++ [ x ] ) ≡ [ x ] ++ rev (rev l) + s = revIsHom (rev l) [ x ] + t : rev (rev l ++ [ x ] ) ≡ [ x ] ++ l + t = identityOfIndiscernablesRight _≡_ s (applyEquality (λ n → [ x ] ++ n) (revRevIsId l)) - map : {a : _} → {b : _} → {A : Set a} → {B : Set b} → (f : A → B) → List A → List B - map f [] = [] - map f (x :: list) = (f x) :: (map f list) +fold : {a b : _} {A : Set a} {B : Set b} (f : A → B → B) → B → List A → B +fold f default [] = default +fold f default (x :: l) = f x (fold f default l) - map' : {a : _} → {b : _} → {A : Set a} → {B : Set b} → (f : A → B) → List A → List B - map' f = fold (λ a → (f a) ::_ ) [] +map : {a : _} → {b : _} → {A : Set a} → {B : Set b} → (f : A → B) → List A → List B +map f [] = [] +map f (x :: list) = (f x) :: (map f list) - map=map' : {a : _} → {b : _} → {A : Set a} → {B : Set b} → (f : A → B) → (l : List A) → (map f l ≡ map' f l) - map=map' f [] = refl - map=map' f (x :: l) with map=map' f l - ... | bl = applyEquality (f x ::_) bl +map' : {a : _} → {b : _} → {A : Set a} → {B : Set b} → (f : A → B) → List A → List B +map' f = fold (λ a → (f a) ::_ ) [] - flatten : {a : _} {A : Set a} → (l : List (List A)) → List A - flatten [] = [] - flatten (l :: ls) = l ++ flatten ls +map=map' : {a : _} → {b : _} → {A : Set a} → {B : Set b} → (f : A → B) → (l : List A) → (map f l ≡ map' f l) +map=map' f [] = refl +map=map' f (x :: l) with map=map' f l +... | bl = applyEquality (f x ::_) bl - flatten' : {a : _} {A : Set a} → (l : List (List A)) → List A - flatten' = fold _++_ [] +flatten : {a : _} {A : Set a} → (l : List (List A)) → List A +flatten [] = [] +flatten (l :: ls) = l ++ flatten ls - flatten=flatten' : {a : _} {A : Set a} (l : List (List A)) → flatten l ≡ flatten' l - flatten=flatten' [] = refl - flatten=flatten' (l :: ls) = applyEquality (l ++_) (flatten=flatten' ls) +flatten' : {a : _} {A : Set a} → (l : List (List A)) → List A +flatten' = fold _++_ [] - length : {a : _} {A : Set a} (l : List A) → ℕ - length [] = zero - length (x :: l) = succ (length l) +flatten=flatten' : {a : _} {A : Set a} (l : List (List A)) → flatten l ≡ flatten' l +flatten=flatten' [] = refl +flatten=flatten' (l :: ls) = applyEquality (l ++_) (flatten=flatten' ls) - length' : {a : _} {A : Set a} → (l : List A) → ℕ - length' = fold (λ _ → succ) 0 +length : {a : _} {A : Set a} (l : List A) → ℕ +length [] = zero +length (x :: l) = succ (length l) - length=length' : {a : _} {A : Set a} (l : List A) → length l ≡ length' l - length=length' [] = refl - length=length' (x :: l) = applyEquality succ (length=length' l) +length' : {a : _} {A : Set a} → (l : List A) → ℕ +length' = fold (λ _ → succ) 0 - total : List ℕ → ℕ - total [] = zero - total (x :: l) = x +N total l +length=length' : {a : _} {A : Set a} (l : List A) → length l ≡ length' l +length=length' [] = refl +length=length' (x :: l) = applyEquality succ (length=length' l) - total' : List ℕ → ℕ - total' = fold _+N_ 0 +total : List ℕ → ℕ +total [] = zero +total (x :: l) = x +N total l - lengthConcat : {a : _} {A : Set a} (l1 l2 : List A) → length (l1 ++ l2) ≡ length l1 +N length l2 - lengthConcat [] l2 = refl - lengthConcat (x :: l1) l2 = applyEquality succ (lengthConcat l1 l2) +total' : List ℕ → ℕ +total' = fold _+N_ 0 - lengthFlatten : {a : _} {A : Set a} (l : List (List A)) → length (flatten l) ≡ total (map length l) - lengthFlatten [] = refl - lengthFlatten (l :: ls) rewrite lengthConcat l (flatten ls) | lengthFlatten ls = refl +lengthConcat : {a : _} {A : Set a} (l1 l2 : List A) → length (l1 ++ l2) ≡ length l1 +N length l2 +lengthConcat [] l2 = refl +lengthConcat (x :: l1) l2 = applyEquality succ (lengthConcat l1 l2) - lengthMap : {a b : _} {A : Set a} {B : Set b} → (l : List A) → {f : A → B} → length l ≡ length (map f l) - lengthMap [] {f} = refl - lengthMap (x :: l) {f} rewrite lengthMap l {f} = refl +lengthFlatten : {a : _} {A : Set a} (l : List (List A)) → length (flatten l) ≡ total (map length l) +lengthFlatten [] = refl +lengthFlatten (l :: ls) rewrite lengthConcat l (flatten ls) | lengthFlatten ls = refl - mapMap : {a b c : _} {A : Set a} {B : Set b} {C : Set c} → (l : List A) → {f : A → B} {g : B → C} → map g (map f l) ≡ map (g ∘ f) l - mapMap [] = refl - mapMap (x :: l) {f = f} {g} rewrite mapMap l {f} {g} = refl +lengthMap : {a b : _} {A : Set a} {B : Set b} → (l : List A) → {f : A → B} → length l ≡ length (map f l) +lengthMap [] {f} = refl +lengthMap (x :: l) {f} rewrite lengthMap l {f} = refl - mapExtension : {a b : _} {A : Set a} {B : Set b} (l : List A) (f g : A → B) → ({x : A} → (f x ≡ g x)) → map f l ≡ map g l - mapExtension [] f g pr = refl - mapExtension (x :: l) f g pr rewrite mapExtension l f g pr | pr {x} = refl +mapMap : {a b c : _} {A : Set a} {B : Set b} {C : Set c} → (l : List A) → {f : A → B} {g : B → C} → map g (map f l) ≡ map (g ∘ f) l +mapMap [] = refl +mapMap (x :: l) {f = f} {g} rewrite mapMap l {f} {g} = refl - replicate : {a : _} {A : Set a} (n : ℕ) (x : A) → List A - replicate zero x = [] - replicate (succ n) x = x :: replicate n x +mapExtension : {a b : _} {A : Set a} {B : Set b} (l : List A) (f g : A → B) → ({x : A} → (f x ≡ g x)) → map f l ≡ map g l +mapExtension [] f g pr = refl +mapExtension (x :: l) f g pr rewrite mapExtension l f g pr | pr {x} = refl - allTrue : {a b : _} {A : Set a} (f : A → Set b) (l : List A) → Set b - allTrue f [] = True' - allTrue f (x :: l) = f x && allTrue f l +replicate : {a : _} {A : Set a} (n : ℕ) (x : A) → List A +replicate zero x = [] +replicate (succ n) x = x :: replicate n x - allTrueConcat : {a b : _} {A : Set a} (f : A → Set b) (l m : List A) → allTrue f l → allTrue f m → allTrue f (l ++ m) - allTrueConcat f [] m fl fm = fm - allTrueConcat f (x :: l) m (fst ,, snd) fm = fst ,, allTrueConcat f l m snd fm +allTrue : {a b : _} {A : Set a} (f : A → Set b) (l : List A) → Set b +allTrue f [] = True' +allTrue f (x :: l) = f x && allTrue f l - allTrueFlatten : {a b : _} {A : Set a} (f : A → Set b) (l : List (List A)) → allTrue (λ i → allTrue f i) l → allTrue f (flatten l) - allTrueFlatten f [] pr = record {} - allTrueFlatten f ([] :: ls) pr = allTrueFlatten f ls (_&&_.snd pr) - allTrueFlatten f ((x :: l) :: ls) ((fx ,, fl) ,, snd) = fx ,, allTrueConcat f l (flatten ls) fl (allTrueFlatten f ls snd) +allTrueConcat : {a b : _} {A : Set a} (f : A → Set b) (l m : List A) → allTrue f l → allTrue f m → allTrue f (l ++ m) +allTrueConcat f [] m fl fm = fm +allTrueConcat f (x :: l) m (fst ,, snd) fm = fst ,, allTrueConcat f l m snd fm - allTrueMap : {a b c : _} {A : Set a} {B : Set b} (pred : B → Set c) (f : A → B) (l : List A) → allTrue (pred ∘ f) l → allTrue pred (map f l) - allTrueMap pred f [] pr = record {} - allTrueMap pred f (x :: l) pr = _&&_.fst pr ,, allTrueMap pred f l (_&&_.snd pr) +allTrueFlatten : {a b : _} {A : Set a} (f : A → Set b) (l : List (List A)) → allTrue (λ i → allTrue f i) l → allTrue f (flatten l) +allTrueFlatten f [] pr = record {} +allTrueFlatten f ([] :: ls) pr = allTrueFlatten f ls (_&&_.snd pr) +allTrueFlatten f ((x :: l) :: ls) ((fx ,, fl) ,, snd) = fx ,, allTrueConcat f l (flatten ls) fl (allTrueFlatten f ls snd) - allTrueExtension : {a b : _} {A : Set a} (f g : A → Set b) (l : List A) → ({x : A} → f x → g x) → allTrue f l → allTrue g l - allTrueExtension f g [] pred t = record {} - allTrueExtension f g (x :: l) pred (fg ,, snd) = pred {x} fg ,, allTrueExtension f g l pred snd +allTrueMap : {a b c : _} {A : Set a} {B : Set b} (pred : B → Set c) (f : A → B) (l : List A) → allTrue (pred ∘ f) l → allTrue pred (map f l) +allTrueMap pred f [] pr = record {} +allTrueMap pred f (x :: l) pr = _&&_.fst pr ,, allTrueMap pred f l (_&&_.snd pr) - allTrueTail : {a b : _} {A : Set a} (pred : A → Set b) (x : A) (l : List A) → allTrue pred (x :: l) → allTrue pred l - allTrueTail pred x l (fst ,, snd) = snd +allTrueExtension : {a b : _} {A : Set a} (f g : A → Set b) (l : List A) → ({x : A} → f x → g x) → allTrue f l → allTrue g l +allTrueExtension f g [] pred t = record {} +allTrueExtension f g (x :: l) pred (fg ,, snd) = pred {x} fg ,, allTrueExtension f g l pred snd - head : {a : _} {A : Set a} (l : List A) (pr : 0 Set a where [] : Vec X zero @@ -38,6 +39,9 @@ vecLast {a} {X} {zero} v () vecLast {a} {X} {succ zero} (x ,- []) _ = x vecLast {a} {X} {succ (succ m)} (x ,- v) _ = vecLast v (succIsPositive m) +vecLast' : {a : _} {X : Set a} {m : ℕ} → Vec X (succ m) → X +vecLast' {m = m} v = vecLast v (le m (applyEquality succ (Semiring.sumZeroRight ℕSemiring m))) + vecAppend : {a : _} {X : Set a} {m : ℕ} → Vec X m → (x : X) → Vec X (succ m) vecAppend {a} {X} {zero} [] x = x ,- [] vecAppend {a} {X} {succ m} (y ,- v) x = y ,- vecAppend v x @@ -54,9 +58,9 @@ vecMoveAppend : {a : _} {X : Set a} {m : ℕ} → (x : X) → (v : Vec X m) → vecMoveAppend {a} {X} {.0} x [] = refl vecMoveAppend {a} {X} {.(succ _)} x (y ,- v) rewrite vecMoveAppend x v = refl -revRevIsId : {a : _} {X : Set a} {m : ℕ} → (v : Vec X m) → (vecRev (vecRev v)) ≡ v -revRevIsId {a} {X} {zero} [] = refl -revRevIsId {a} {X} {succ m} (x ,- v) rewrite vecMoveAppend x (vecRev v) = applyEquality (λ i → x ,- i) (revRevIsId v) +vecRevRevIsId : {a : _} {X : Set a} {m : ℕ} → (v : Vec X m) → (vecRev (vecRev v)) ≡ v +vecRevRevIsId {a} {X} {zero} [] = refl +vecRevRevIsId {a} {X} {succ m} (x ,- v) rewrite vecMoveAppend x (vecRev v) = applyEquality (λ i → x ,- i) (vecRevRevIsId v) record vecContains {a : _} {X : Set a} {m : ℕ} (vec : Vec X m) (x : X) : Set a where field @@ -153,6 +157,10 @@ vecComposition : {a b c : _} {X : Set a} {Y : Set b} {Z : Set c} {n : ℕ} (fs : vecComposition [] [] [] = refl vecComposition (f ,- fs) (g ,- gs) (x ,- xs) rewrite vecComposition fs gs xs = refl +vecToList : {a : _} {A : Set a} {n : ℕ} → (v : Vec A n) → List A +vecToList [] = [] +vecToList (x ,- v) = x :: vecToList v + ------------ data _<=_ : ℕ → ℕ → Set where