-
Notifications
You must be signed in to change notification settings - Fork 0
/
QuotientGroup.jl
133 lines (114 loc) · 3.26 KB
/
QuotientGroup.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
function Cosets(g::CGroup, h::CGroup)::Set{Set{Elt}}
if !(issubset(h.elements, g.elements))
throw(GroupException(NotSubGroupEx))
end
cosets = Set{Set{Elt}}()
for x in g.elements
xi = Invert(g, x)
xH = Set{Elt}([Op(g, x, he) for he in h.elements])
xHxi = Set([Op(g, xh, xi) for xh in xH])
if !issetequal(h.elements, xHxi)
throw(GroupException(NotNormalEx))
end
if all(s -> !issetequal(s, xH), cosets)
push!(cosets, xH)
end
end
return cosets
end
function DisplayCosets(cosets::Set{Set{Elt}})
println("Cosets")
sets = sort([cosets...], by=minimum)
n = length(sets)
for i = 1:n
s = sets[i]
e = minimum(s)
v = sort([s...])
println("($i) = $e")
for ei in v
println(" $ei")
end
end
println()
nothing
end
function Representants(cosets::Set{Set{Elt}})::Dict{Elt,Elt}
repr = Dict{Elt,Elt}()
for s in cosets
r = minimum(s) # FIXME To make the set of representants a SubGroup
for e in s
push!(repr, e => r)
end
end
return repr
end
mutable struct QuotientGroup <: CGroup
baseGroup::FGroup
superGroup::CGroup
normSubGroup::CGroup
cosets::Set{Set{Elt}}
representants::Dict{Elt,Elt}
elements::Vector{Elt}
groupType::GroupType
monogenics::Dict{Elt,Dict{Elt,Int}}
orders::Dict{Elt,Int}
cgHash::UInt
function QuotientGroup(G::CGroup, H::CGroup)
if G.baseGroup != H.baseGroup
throw(GroupException(BaseGroupEx))
end
bgr = G.baseGroup
sgr = G
ngr = H
cst = Cosets(G, H)
rep = Representants(cst)
n = Neutral(bgr)
elts = Vector{Elt}([n])
mg = Dict{Elt,Dict{Elt,Int}}(n => Dict{Elt,Int}(n => 1))
orders = Dict{Elt,Int}(n => 1)
return new(bgr, sgr, ngr, cst, rep, elts, NonAbelianGroup, mg, orders, hash(uuid1()))
end
end
function GetHash(g::QuotientGroup)::UInt
g.cgHash
end
function GetString(g::QuotientGroup)::String
return "NoName" # TODO
end
function Neutral(g::QuotientGroup)::Elt
Neutral(g.superGroup)
end
function Invert(g::QuotientGroup, e::Elt)::Elt
e0 = Invert(g.superGroup, e)
return g.representants[e0]
end
# FIXME
function Op(g::QuotientGroup, e1::Elt, e2::Elt)::Elt
e0 = Op(g.superGroup, e1, e2)
r = g.representants[e0]
if r != e0
@show e0, r # FIXME
# coset representant is actually the minimum for lexical order but
# nothing is done to check if the set of these representants
# is a subGroup
end
return r
end
function (g::QuotientGroup)(v::Vararg{Int,1})::Elt
g.elements[v[1]]
end
function CreateQuotientGroup(G::CGroup, H::CGroup)::CGroup
quo = QuotientGroup(G, H)
elements = Set{Elt}(values(quo.representants))
monogenics = Generators(quo, elements)
grouptype = IsAbelian(quo, collect(keys(monogenics))) ? AbelianGroup : NonAbelianGroup
orders = ElementOrder(monogenics)
SetElements(quo, Vector{Elt}([elements...]))
SetMonogenics(quo, monogenics)
SetOrders(quo, orders)
SetGroupType(quo, grouptype)
return quo
end
function DisplayCosets(quo::QuotientGroup)
DisplayCosets(quo.cosets)
end