Algebra.quotGroup
import Core.id (Id, eqToId)
import Algebra.monoid (IsMonoid)
import Algebra.group (IsGroup)
import Algebra.groupTheory (gop, ge, ginv, gAssoc, gUnitL, gUnitR, gInvL, gInvR, gCancelInner, gCancelInnerInv, gCancelOuter, gCancelOuterInv, gInvUniq, gInvInv, gInvUnit, gOpInv, gCancelL, gCancelR)
import Algebra.subgroup (IsSubgroup, IsNormal, sgUnit, sgOp, sgInv, nmConj, nmConjInv, cosetRel, cosetRefl, cosetSymm, cosetTrans, cosetFlip, cosetSplice)
import Core.quotEffective (classEqOfRel, effectiveAtEquiv)
import Core.equality (transportP, sym, trans, cong)
QGroup : (G : 𝕌) (g : IsGroup G) (N : G → Ω) → 𝕌
QGroup = λG g N. G / (x y. cosetRel g N x y)
qcls : {G : 𝕌} (g : IsGroup G) (N : G → Ω) → G → QGroup _ g N using (QGroup.unfold)
qcls = λG g N a. class a
qclsEq : {G : 𝕌}
{g : IsGroup G}
{N : G → Ω}
→ IsSubgroup g N → (a b : G) → cosetRel g N a b → qcls g N a ≡ qcls _ _ b
using (qcls.eq)
qclsEq = λG g N s a b h. classEqOfRel (cosetRel g N) _ _ h
qclsEffective : (G : 𝕌)
(g : IsGroup G)
(N : G → Ω)
→ IsSubgroup g N → (a b : G) → (qcls g N a ≡ qcls _ _ b) → cosetRel g N a b
using (qcls.eq)
qclsEffective = λG g N s. effectiveAtEquiv (cosetRel g N) (cosetRefl s) (cosetTrans s) (cosetSymm s)
qMulInnerAlg : {G : 𝕌}
{g : IsGroup G}
{a b b' : G}
→ gop g a (gop g (gop g b (ginv g b')) (ginv g a)) ≡ gop g (gop g a b) (ginv g (gop g a b'))
qMulInnerAlg =
λG g a b b'. gop g a (gop g (gop g b (ginv g b')) (ginv g a))
≡⟨ cong (λw. G) (λw. gop g a w) (gAssoc g b (ginv g b') (ginv g a)) ⟩
gop g a (gop g b (gop g (ginv g b') (ginv g a)))
≡⟨ sym _ _ (gAssoc g a b (gop g (ginv g b') (ginv g a))) ⟩
gop g (gop g a b) (gop g (ginv g b') (ginv g a))
≡⟨ cong (λw. G) (λw. gop g (gop g a b) w) (sym _ _ (gOpInv g a b')) ⟩
gop g (gop g a b) (ginv g (gop g a b'))
qMulOuterAlg : (G : 𝕌)
(g : IsGroup G)
(a a' b : G)
→ gop g (gop g a b) (ginv g (gop g a' b)) ≡ gop g a (ginv g a')
qMulOuterAlg =
λG g a a' b. gop g (gop g a b) (ginv g (gop g a' b))
≡⟨ cong (λw. G) (λw. gop g (gop g a b) w) (gOpInv g a' b) ⟩
gop g (gop g a b) (gop g (ginv g b) (ginv g a'))
≡⟨ gAssoc g a b (gop g (ginv g b) (ginv g a')) ⟩
gop g a (gop g b (gop g (ginv g b) (ginv g a')))
≡⟨ cong (λw. G) (λw. gop g a w) (gCancelInner g b (ginv g a')) ⟩ gop g a (ginv g a')
qMulWDInner : {G : 𝕌}
{g : IsGroup G}
{N : G → Ω}
→ IsNormal g N → {a b b' : G} → cosetRel g N b b' → cosetRel g N (gop g a b) (gop g a b')
using (cosetRel.eq)
qMulWDInner =
λG g N nn a b b' h. transportP
N
{gop g a (gop g (gop g b (ginv g b')) (ginv g a))}
{gop g (gop g a b) (ginv g (gop g a b'))}
qMulInnerAlg
nmConj _ _ _ nn a (gop g b (ginv g b')) h
qMulWDOuter : {G : 𝕌}
{g : IsGroup G}
{N : G → Ω}
{a a' b : G}
→ cosetRel g N a a' → cosetRel g N (gop g a b) (gop g a' b)
using (cosetRel.eq)
qMulWDOuter = λG g N a a' b h. transportP N (sym _ _ (qMulOuterAlg _ g a a' b)) h
qMulWDInnerCls : (G : 𝕌)
(g : IsGroup G)
(N : G → Ω)
→ IsNormal g N → (a b b' : G) → cosetRel g N b b' → qcls g N (gop g a b) ≡ qcls _ _ (gop g a b')
using (qcls.eq)
qMulWDInnerCls =
λG g N nn a b b' h. classEqOfRel (cosetRel g N) (gop g a b) (gop g a b') (qMulWDInner nn h)
qMulWDOuterCls : {G : 𝕌}
{g : IsGroup G}
{N : G → Ω}
{a a' b : G}
→ cosetRel g N a a' → qcls g N (gop g a b) ≡ qcls _ _ (gop g a' b)
using (qcls.eq)
qMulWDOuterCls =
λG g N a a' b h. classEqOfRel (cosetRel g N) (gop g a b) (gop g a' b) (qMulWDOuter h)
qMulWDOuterElim : (G : 𝕌)
(g : IsGroup G)
(N : G → Ω)
→ IsNormal g N
→ (x x' : G)
→ cosetRel g N x x'
→ (v : QGroup _ g N)
→ quot-elim (w. QGroup _ g N) (q. qcls _ _ (gop g x q)) v
≡ quot-elim (q. qcls _ _ (gop g x' q)) v
using (QGroup.unfold, qMulWDInnerCls)
qMulWDOuterElim =
λG g N nn x x' h v. quot-elim
w. quot-elim (z. QGroup _ g N) (q. qcls _ _ (gop g x q)) w
≡ quot-elim (q. qcls _ _ (gop g x' q)) w
c. qMulWDOuterCls h
v
qMul : (G : 𝕌)
(g : IsGroup G)
(N : G → Ω)
→ IsNormal g N → QGroup _ g N → QGroup _ g N → QGroup _ g N
using (QGroup.unfold, qMulWDInnerCls, qMulWDOuterElim)
qMul = λG g N nn u v. quot-elim (p. quot-elim (q. qcls _ _ (gop g p q)) v) u
qMulCls : (G : 𝕌)
(g : IsGroup G)
(N : G → Ω)
(nn : IsNormal g N)
(a b : G)
→ qMul _ _ _ nn (class a) (class b) ≡ class (gop g a b)
using (QGroup.unfold, qcls.eq, qMul.eq)
qMulCls = λG g N nn a b. ⋆
qInvAlg : {G : 𝕌}
{g : IsGroup G}
{a a' : G}
→ gop g (ginv g a) (gop g (gop g a' (ginv g a)) a) ≡ gop g (ginv g a) (ginv g (ginv g a'))
qInvAlg =
λG g a a'. gop g (ginv g a) (gop g (gop g a' (ginv g a)) a)
≡⟨ cong (λw. G) (λw. gop g (ginv g a) w) (gCancelOuterInv g a a') ⟩ gop g (ginv g a) a'
≡⟨ cong (λw. G) (λw. gop g (ginv g a) w) (sym _ _ (gInvInv g a')) ⟩
gop g (ginv g a) (ginv g (ginv g a'))
qInvWD : {G : 𝕌}
{g : IsGroup G}
{N : G → Ω}
→ IsSubgroup g N
→ IsNormal g N → {a a' : G} → cosetRel g N a a' → cosetRel g N (ginv g a) (ginv g a')
using (cosetRel.eq)
qInvWD =
λG g N s nn a a' h. transportP
N
{gop g (ginv g a) (gop g (gop g a' (ginv g a)) a)}
{gop g (ginv g a) (ginv g (ginv g a'))}
qInvAlg
nmConjInv _ _ _ nn a (gop g a' (ginv g a)) (cosetSymm s _ _ h)
qInvWDCls : (G : 𝕌)
(g : IsGroup G)
(N : G → Ω)
→ IsSubgroup g N
→ IsNormal g N → (a a' : G) → cosetRel g N a a' → qcls g N (ginv g a) ≡ qcls _ _ (ginv g a')
using (qcls.eq)
qInvWDCls = λG g N s nn a a' h. classEqOfRel (cosetRel g N) _ _ (qInvWD s nn h)
qInv : (G : 𝕌)
(g : IsGroup G)
(N : G → Ω)
→ IsSubgroup g N → IsNormal g N → QGroup _ g N → QGroup _ g N
using (QGroup.unfold, qInvWDCls)
qInv = λG g N s nn u. quot-elim (a. qcls _ _ (ginv g a)) u
qInvCls : (G : 𝕌)
(g : IsGroup G)
(N : G → Ω)
(s : IsSubgroup g N)
(nn : IsNormal g N)
(a : G)
→ qInv _ _ _ s nn (class a) ≡ class (ginv g a)
using (QGroup.unfold, qcls.eq, qInv.eq)
qInvCls = λG g N s nn a. ⋆
qUnit : (G : 𝕌) (g : IsGroup G) (N : G → Ω) → QGroup _ g N using (QGroup.unfold)
qUnit = λG g N. class (ge g)
qAssoc : (G : 𝕌)
(g : IsGroup G)
(N : G → Ω)
(nn : IsNormal g N)
(u v w : QGroup _ g N)
→ qMul _ _ _ nn (qMul _ _ _ nn u v) w ≡ qMul _ _ _ nn u (qMul _ _ _ nn v w)
using (QGroup.unfold, qMulCls.rw)
qAssoc =
λG g N nn u v w. quot-elim
a. quot-elim
b. quot-elim
c. trans
_
_
_
⋆
trans
_
_
qMul _ _ _ nn (class a) (qMul _ _ _ nn (class b) (class c))
cong (λw. QGroup _ g N) (λw. class w) (gAssoc g a b c)
⋆
w
v
u
qUnitL : (G : 𝕌)
(g : IsGroup G)
(N : G → Ω)
(nn : IsNormal g N)
(u : QGroup _ g N)
→ qMul _ _ _ nn (qUnit _ g N) u ≡ u
using (QGroup.unfold, qUnit.eq, qMulCls.rw)
qUnitL =
λG g N nn u. quot-elim (a. trans _ _ _ ⋆ (cong (λw. QGroup _ g N) (λw. class w) (gUnitL g a))) u
qUnitR : (G : 𝕌)
(g : IsGroup G)
(N : G → Ω)
(nn : IsNormal g N)
(u : QGroup _ g N)
→ qMul _ _ _ nn u (qUnit _ g N) ≡ u
using (QGroup.unfold, qUnit.eq, qMulCls.rw)
qUnitR =
λG g N nn u. quot-elim (a. trans _ _ _ ⋆ (cong (λw. QGroup _ g N) (λw. class w) (gUnitR g a))) u
qInvLaw : (G : 𝕌)
(g : IsGroup G)
(N : G → Ω)
(s : IsSubgroup g N)
(nn : IsNormal g N)
(u : QGroup _ g N)
→ qMul _ _ _ nn (qInv _ _ _ s nn u) u ≡ qUnit _ _ _
using (QGroup.unfold, qUnit.eq, qInvCls.rw, qMulCls.rw)
qInvLaw =
λG g N s nn u. quot-elim (a. trans _ _ _ ⋆ (cong (λw. QGroup _ g N) (λw. class w) (gInvL g a))) u
qInvLawR : (G : 𝕌)
(g : IsGroup G)
(N : G → Ω)
(s : IsSubgroup g N)
(nn : IsNormal g N)
(u : QGroup _ g N)
→ qMul _ _ _ nn u (qInv _ _ _ s nn u) ≡ qUnit _ _ _
using (QGroup.unfold, qUnit.eq, qInvCls.rw, qMulCls.rw)
qInvLawR =
λG g N s nn u. quot-elim (a. trans _ _ _ ⋆ (cong (λw. QGroup _ g N) (λw. class w) (gInvR g a))) u
qIsGroup : (G : 𝕌)
(g : IsGroup G)
(N : G → Ω)
→ IsSubgroup g N → IsNormal g N → IsGroup (QGroup _ g N)
using (Algebra.group.IsGroup.unfold, Algebra.monoid.IsMonoid.unfold)
qIsGroup =
λG g N s nn. (,)
(,)
qMul _ _ _ nn
qUnit _ _ _
λx y z. eqToId _ _ (qAssoc _ _ _ nn x y z)
λx. eqToId _ _ (qUnitL _ _ _ nn x)
λx. eqToId _ _ (qUnitR _ _ _ nn x)
qInv _ _ _ s nn
λx. eqToId _ _ (qInvLaw _ _ _ s nn x)
λx. eqToId _ _ (qInvLawR _ _ _ s nn x)
qMonoid : (G : 𝕌)
(g : IsGroup G)
(N : G → Ω)
→ IsSubgroup g N → IsNormal g N → IsMonoid (QGroup _ g N)
using (Algebra.group.IsGroup.unfold)
qMonoid = λG g N s nn. qIsGroup _ _ _ s nn .π₁
qFactor : (G : 𝕌)
(g : IsGroup G)
(N : G → Ω)
{H : 𝕌}
(k : G → H)
(c : (a a' : G) → cosetRel g N a a' → k a ≡ k a')
(u : QGroup _ g N)
→ H
using (QGroup.unfold)
qFactor = λG g N H k c u. quot-elim (a. k a) u
qFactorCls : (G : 𝕌)
(g : IsGroup G)
(N : G → Ω)
(H : 𝕌)
(k : G → H)
(c : (a a' : G) → cosetRel g N a a' → k a ≡ k a')
(a : G)
→ qFactor _ _ _ k c (class a) ≡ k a
using (QGroup.unfold, qFactor.eq)
qFactorCls = λG g N H k c a. ⋆
qFactorEta : (G : 𝕌)
(g : IsGroup G)
(N : G → Ω)
(H : 𝕌)
(phi : QGroup _ g N → H)
(c : (a a' : G) → cosetRel g N a a' → phi (class a) ≡ phi (class a'))
(u : QGroup _ g N)
→ qFactor _ _ _ (λa. phi (class a)) c u ≡ phi u
using (QGroup.unfold, qFactor.eq)
qFactorEta = λG g N H phi c u. quot-elim (a. ⋆) u
qFactorUnique : (G : 𝕌)
(g : IsGroup G)
(N : G → Ω)
(H : 𝕌)
(phi psi : QGroup _ g N → H)
→ ((a : G) → phi (class a) ≡ psi (class a)) → (u : QGroup _ g N) → phi u ≡ psi u
using (QGroup.unfold)
qFactorUnique = λG g N H phi psi e u. quot-elim (a. e a) u