open import Function using (_$_)
open import Algebra.Bundles

module Algebra.Module.Instances.AllVecLeftModule
  {c } (ring : Ring c ) where

open import Data.Nat using ()
open import Data.Vec.Functional
open import Data.Product
open import Vector.Structures

open import Algebra.Core
open import Algebra.Module
open import Algebra.Structures
open import Algebra.Module.Instances.FunctionalVector ring
  using (_+ᴹ_; -ᴹ_; -ᴹ‿cong; -ᴹ‿inverse; +ᴹ-comm; isMonoid)
import Algebra.Module.Definitions.Left as DLeft′

open Ring ring
open VRing rawRing renaming (1ⱽ to 𝟙)

open import Data.Vec.Functional.Relation.Binary.Equality.Setoid setoid
open module DLeft {n} = DLeft′ (Vector Carrier n) (_≋_ {n})

private variable
  n : 


_*ₗ_ : Op₂ $ Vector Carrier n
_*ₗ_ = _*ⱽ_

𝟘 : Vector Carrier n
𝟘 _ = 0#

*ₗ-cong : Congruent _≋_ (_*ₗ_ {n})
*ₗ-cong x≈y u≈v i = *-cong (x≈y i) (u≈v i)

*ₗ-zeroˡ : LeftZero {n = n} 𝟘 𝟘 _*ₗ_
*ₗ-zeroˡ xs i = zeroˡ (xs i)

*ₗ-distribʳ : _*ₗ_ DistributesOverʳ _+ᴹ_  _+ᴹ_ {n}
*ₗ-distribʳ xs m n i = distribʳ _ _ _

*ₗ-identityˡ : LeftIdentity 𝟙 (_*ₗ_ {n})
*ₗ-identityˡ xs i = *-identityˡ (xs i)

*ₗ-assoc : Associative _*ₗ_ (_*ₗ_ {n})
*ₗ-assoc m n xs i = *-assoc _ _ _

*ₗ-zeroʳ : RightZero (𝟘 {n}) _*ₗ_
*ₗ-zeroʳ m _ = zeroʳ _

*ₗ-distribˡ : _*ₗ_ DistributesOverˡ (_+ᴹ_ {n})
*ₗ-distribˡ m xs ys i = distribˡ _ _ _

+ᴹ-isCommutativeMonoid : IsCommutativeMonoid (_≋_ {n}) _+ᴹ_ 𝟘
+ᴹ-isCommutativeMonoid = record
  { isMonoid = record { isSemigroup =
  record { isMagma = record
      { isEquivalence = record { refl = λ i  refl
                              ; sym = λ x i  sym (x i)
                              ; trans = λ a b i  trans (a i) (b i) }
      ; ∙-cong = λ a b i  +-cong (a i) (b i)
      }
  ; assoc = λ x y z i  +-assoc _ _ _ }
  ; identity =  x i  +-identityˡ _) , λ x i  +-identityʳ _ }
  ; comm     = λ x y i  +-comm _ _
  }


v-isSemiWAZ : IsSemiringWithoutAnnihilatingZero (_≋_ {n}) _+ᴹ_ _*ⱽ_ 𝟘 𝟙
v-isSemiWAZ = record
               { +-isCommutativeMonoid = +ᴹ-isCommutativeMonoid
               ; *-cong = *ₗ-cong
               ; *-assoc = *ₗ-assoc
               ; *-identity = *ₗ-identityˡ ,  _ _  *-identityʳ _)
               ; distrib = *ₗ-distribˡ ,  x y z i  distribʳ _ _ _)
               }

v-isSemiring : IsSemiring (_≋_ {n}) _+ᴹ_ _*ⱽ_ 𝟘 𝟙
v-isSemiring = record
  { isSemiringWithoutAnnihilatingZero = v-isSemiWAZ
  ; zero = *ₗ-zeroˡ , *ₗ-zeroʳ
  }

v-semiring : (n : )  Semiring _ _
v-semiring n = record { isSemiring = v-isSemiring {n} }

v-isRing : IsRing (_≋_ {n}) _+ᴹ_ _*ⱽ_ -ᴹ_ 𝟘 𝟙
v-isRing = record
  { +-isAbelianGroup = record
    { isGroup = record
      { isMonoid = isMonoid
      ; inverse = -ᴹ‿inverse
      ; ⁻¹-cong = -ᴹ‿cong
      }
    ; comm = +ᴹ-comm
    }
  ; *-cong = *ₗ-cong
  ; *-assoc = *ₗ-assoc
  ; *-identity = *ₗ-identityˡ ,  _ _  *-identityʳ _)
  ; distrib = *ₗ-distribˡ ,  x y z i  distribʳ _ _ _)
  }


v-ring : (n : )  Ring _ _
v-ring n = record { isRing = v-isRing {n} }

isPreleftSemimodule : IsPreleftSemimodule (v-semiring n) _≋_ _+ᴹ_ 𝟘 _*ₗ_
isPreleftSemimodule = record
  { *ₗ-cong = *ₗ-cong
  ; *ₗ-zeroˡ = *ₗ-zeroˡ
  ; *ₗ-distribʳ = *ₗ-distribʳ
  ; *ₗ-identityˡ = *ₗ-identityˡ
  ; *ₗ-assoc = *ₗ-assoc
  ; *ₗ-zeroʳ = *ₗ-zeroʳ
  ; *ₗ-distribˡ = *ₗ-distribˡ
  }

isLeftSemimodule : IsLeftSemimodule (v-semiring n) _≋_ _+ᴹ_ 𝟘 _*ₗ_
isLeftSemimodule = record
  { +ᴹ-isCommutativeMonoid = +ᴹ-isCommutativeMonoid
  ; isPreleftSemimodule    = isPreleftSemimodule
  }

isLeftModule : IsLeftModule (v-ring n) _≋_ _+ᴹ_ 𝟘 -ᴹ_ _*ₗ_
isLeftModule = record
  { isLeftSemimodule = isLeftSemimodule
  ; -ᴹ‿cong = -ᴹ‿cong
  ; -ᴹ‿inverse = -ᴹ‿inverse
  }

leftModule : (n : )  LeftModule (v-ring n) _ _
leftModule n = record { isLeftModule = isLeftModule }