\import Algebra.Group
\import Algebra.Group.Sub
\import Algebra.Module
\import Algebra.Monoid
\import Algebra.Monoid.Sub
\import Algebra.Pointed
\import Algebra.Pointed.Sub
\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)
\func IModule : LModule R \cowith
| AddGroup => IAddGroup
| +-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
}
\func topSubLModule {R : Ring} (M : LModule R) : SubLModule { | R => R | S => 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)
}