\import Algebra.Group
\import Algebra.Group.SubGroup
\import Algebra.Module
\import Algebra.Module.LinearMap
\import Algebra.Monoid
\import Algebra.Monoid.SubMonoid
\import Algebra.Pointed
\import Algebra.Pointed.SubPointed
\import Algebra.Ring
\import Algebra.Ring.Ideal
\import Data.Array
\import Logic
\import Logic.Meta
\import Meta
\import Order.Lattice
\import Paths
\import Paths.Meta
\class SubLModule (R : Ring) \extends SubAddGroup {
\override S : LModule R
| contains_*c {a : R} {b : S} : contains b -> contains (a *c b)
}
\instance IModule (S : SubLModule {}) : LModule S.R
| AddGroup => IAddGroup S
| +-comm => ext +-comm
| *c r p => (r *c p.1, contains_*c p.2)
| *c-assoc => ext *c-assoc
| *c-ldistr => ext *c-ldistr
| *c-rdistr => ext *c-rdistr
| ide_*c => ext ide_*c
\where
\func embed : LinearMap (IModule S) S.S \cowith
| AddGroupHom => IAddGroup.embed
| func-*c => idp
\func topSubLModule {R : Ring} (M : LModule R) : SubLModule R M \cowith
| contains _ => \Sigma
| contains_zro => ()
| contains_+ _ _ => ()
| contains_negative _ => ()
| contains_*c _ => ()
\instance SubLModuleSemilattice (R : Ring) (M : LModule R) : TopMeetSemilattice (SubLModule { | R => R | S => M })
| <= U V => \Pi {a : M} -> U a -> V a
| <=-refl c => c
| <=-transitive f g c => g (f c)
| <=-antisymmetric f g => exts \lam _ => ext (f,g)
| meet (U V : SubLModule { | R => R | S => M }) : SubLModule { | R => R | S => M } \cowith {
| contains a => \Sigma (U a) (V a)
| contains_zro => (contains_zro, contains_zro)
| contains_+ s t => (contains_+ s.1 t.1, contains_+ s.2 t.2)
| contains_negative s => (contains_negative s.1, contains_negative s.2)
| contains_*c s => (contains_*c s.1, contains_*c s.2)
}
| meet-left => __.1
| meet-right => __.2
| meet-univ f g c => (f c, g c)
| top => topSubLModule M
| top-univ _ => ()
\func \infixl 7 *m {R : Ring} (I : LIdeal R) {M : LModule R} (S : SubLModule { | R => R | S => M }) : SubLModule { | R => R | S => M } \cowith
| contains a => ∃ (l : Array (\Sigma (x : R) (I x) M)) (a = M.BigSum (map (\lam s => s.1 *c s.3) l))
| contains_zro => inP (nil,idp)
| contains_+ (inP s) (inP t) => inP (s.1 ++ t.1, pmap2 (+) s.2 t.2 *> inv M.BigSum_++ *> pmap M.BigSum (inv (map_++ (\lam s => s.1 *c s.3))))
| contains_negative (inP s) => inP (map (later \lam t => (negative t.1, contains_negative t.2, t.3)) s.1, pmap negative s.2 *> M.BigSum_negative *> pmap M.BigSum (exts \lam _ => inv M.*c_negative-left))
| contains_*c {a} {_} (inP s) => inP (map (later \lam t => (a * t.1, ideal-left t.2, t.3)) s.1, pmap (a *c) s.2 *> M.*c_BigSum-ldistr *> pmap M.BigSum (exts \lam _ => inv M.*c-assoc))
\func OneDimSubmod {R : Ring} {L : LModule R} (v : L) : SubLModule R L \cowith
| contains u => ∃ (r : R) (r *c v = u)
| contains_zro => inP (0, L.*c_zro-left)
| contains_+ p q => \case \elim p, \elim q \with {
| inP r1, inP r2 => inP (r1.1 + r2.1, rewrite (*c-rdistr, r1.2, r2.2) idp)
}
| contains_negative p => \case \elim p \with {
| inP r => inP (negative r.1, rewrite (L.*c_negative-left, pmap negative r.2) idp)
}
| contains_*c {a} p => \case \elim p \with {
| inP r => inP (a * r.1, rewrite (*c-assoc, r.2) idp)
}
\func KernelLModule (f : LinearMap {}) : SubLModule f.R f.Dom \cowith
| SubAddGroup => KernelAddGroup f
| contains_*c fb=0 => func-*c *> pmap (_ *c) fb=0 *> LModule.*c_zro-right
\func ImageLModule (f : LinearMap {}) : SubLModule f.R f.Cod \cowith
| SubAddGroup => ImageAddGroup f
| contains_*c {r} (inP (a,fa=b)) => inP (r *c a, func-*c *> pmap (r *c) fa=b)
\func ImLModule (f : LinearMap {}) : LModule
=> IModule (ImageLModule f)
\func ImLModuleLeftHom (f : LinearMap {}) : LinearMap f.Dom (ImLModule f) \cowith
| AddGroupHom => ImAddGroupLeftHom f
| func-*c => ext func-*c