module Algebra.Instances.VecAbGroup where open import Function open import Data.Unit.Polymorphic open import Data.Nat open import Data.Vec open import Data.Product using (_×_; _,_; proj₁; proj₂) open import Relation.Binary.Core open import Relation.Binary.Structures open import Algebra module _ {ℓ ℓ'} (GAb : AbelianGroup ℓ ℓ') where module AG = AbelianGroup GAb renaming (Carrier to G) open AG private variable n : ℕ _∙v_ : Op₂ $ Vec G n _∙v_ = zipWith _∙_ εv : Vec G n εv = replicate _ ε _⁻¹v : Op₁ $ Vec G n _⁻¹v = map _⁻¹ _≈v_ : Rel (Vec G n) ℓ' [] ≈v [] = ⊤ (x ∷ xs) ≈v (y ∷ ys) = (x ≈ y) × (xs ≈v ys) open IsAbelianGroup hiding (refl) open IsEquivalence open IsGroup open IsMonoid open IsSemigroup open IsMagma IsVecAbGroup : IsAbelianGroup {A = Vec G n} _≈v_ _∙v_ εv _⁻¹v comm IsVecAbGroup [] [] = _ comm IsVecAbGroup (x ∷ xs) (y ∷ ys) = AG.comm _ _ , comm IsVecAbGroup xs ys refl (isEquivalence (isMagma (isSemigroup (isMonoid (isGroup IsVecAbGroup))))) {[]} = _ refl (isEquivalence (isMagma (isSemigroup (isMonoid (isGroup IsVecAbGroup))))) {x ∷ xs} = AG.refl , (refl (isEquivalence (isMagma (isSemigroup (isMonoid (isGroup IsVecAbGroup)))))) sym (isEquivalence (isMagma (isSemigroup (isMonoid (isGroup IsVecAbGroup))))) {[]} {[]} x≡y = _ sym (isEquivalence (isMagma (isSemigroup (isMonoid (isGroup IsVecAbGroup))))) {x ∷ xs} {y ∷ ys} (x≡y , xs≡ys) = AG.sym x≡y , sym (isEquivalence (isMagma (isSemigroup (isMonoid (isGroup IsVecAbGroup))))) xs≡ys trans (isEquivalence (isMagma (isSemigroup (isMonoid (isGroup IsVecAbGroup))))) {[]} {[]} {[]} i≡j j≡k = _ trans (isEquivalence (isMagma (isSemigroup (isMonoid (isGroup IsVecAbGroup))))) {x ∷ xs} {y ∷ ys} {z ∷ zs} (x≡y , xs≡ys) (y≡z , ys≡zs) = (AG.trans x≡y y≡z) , trans (isEquivalence (isMagma (isSemigroup (isMonoid (isGroup IsVecAbGroup))))) xs≡ys ys≡zs ∙-cong (isMagma (isSemigroup (isMonoid (isGroup IsVecAbGroup)))) {[]} {[]} {[]} {[]} eq1 eq2 = _ ∙-cong (isMagma (isSemigroup (isMonoid (isGroup IsVecAbGroup)))) {x ∷ xs} {y ∷ ys} {u ∷ us} {v ∷ vs} (x≡y , xs≡ys) (u≡v , us≡vs) = (AG.∙-cong x≡y u≡v) , ∙-cong (isMagma (isSemigroup (isMonoid (isGroup IsVecAbGroup)))) xs≡ys us≡vs assoc (isSemigroup (isMonoid (isGroup IsVecAbGroup))) [] [] [] = _ assoc (isSemigroup (isMonoid (isGroup IsVecAbGroup))) (x ∷ xs) (y ∷ ys) (z ∷ zs) = AG.assoc x y z , assoc (isSemigroup (isMonoid (isGroup IsVecAbGroup))) xs ys zs proj₁ (identity (isMonoid (isGroup IsVecAbGroup))) [] = _ proj₁ (identity (isMonoid (isGroup IsVecAbGroup))) (x ∷ xs) = proj₁ AG.identity x , proj₁ (identity (isMonoid (isGroup IsVecAbGroup))) xs proj₂ (identity (isMonoid (isGroup IsVecAbGroup))) [] = _ proj₂ (identity (isMonoid (isGroup IsVecAbGroup))) (x ∷ xs) = proj₂ AG.identity x , proj₂ (identity (isMonoid (isGroup IsVecAbGroup))) xs proj₁ (inverse (isGroup IsVecAbGroup)) [] = _ proj₁ (inverse (isGroup IsVecAbGroup)) (x ∷ xs) = proj₁ AG.inverse _ , proj₁ (inverse (isGroup IsVecAbGroup)) xs proj₂ (inverse (isGroup IsVecAbGroup)) [] = _ proj₂ (inverse (isGroup IsVecAbGroup)) (x ∷ xs) = proj₂ AG.inverse _ , proj₂ (inverse (isGroup IsVecAbGroup)) xs ⁻¹-cong (isGroup IsVecAbGroup) {[]} {[]} eq = _ ⁻¹-cong (isGroup IsVecAbGroup) {x ∷ xs} {y ∷ ys} (eqx , eqxs) = (AG.⁻¹-cong eqx) , ⁻¹-cong (isGroup IsVecAbGroup) eqxs VecAbGroup : ∀ {n} → AbelianGroup ℓ ℓ' VecAbGroup {n} = record { Carrier = _ ; _≈_ = _ ; _∙_ = _ ; ε = _ ; _⁻¹ = _ ; isAbelianGroup = IsVecAbGroup {n = n} }