前の記事:Pythonで部分群・正規部分群・交換子部分群を扱う
前の記事では、部分群、正規部分群、交換子部分群を包含写像を含む構造として表しました。今回は、正規部分群による剰余群を実装し、最後に第一同型定理を具体例で確認します。
コード例は Python 3.12 以降を前提にしています。
剰余類の定義
群 $G$ の正規部分群 $N$ に対して、$a \in G$ の左剰余類を次で定義します。
aN = \{an \mid n \in N\}
正規性によって左剰余類と右剰余類が一致し、剰余類の積を
(aN)(bN) = (ab)N
と定義できます。この演算が代表元の選び方に依存しないことが、正規性の重要な役割です。
剰余群を実装する
剰余類を frozenset[G] として表すため、G の要素はハッシュ可能であるとします。正規性は Subgroup に設定された前提として受け取り、関数の中で一般に証明することはしません。
from __future__ import annotations
from collections.abc import Hashable, Iterable
from group import Group
from subgroup import Subgroup
def quotient_group[G: Hashable, H: Hashable](
normal_subgroup: Subgroup[G, H],
subgroup_elements: Iterable[H],
) -> Group[frozenset[G]]:
base = normal_subgroup.inclusion.target
subgroup_image = {
normal_subgroup.inclusion(element)
for element in subgroup_elements
}
def quotient_class(value: G) -> frozenset[G]:
return frozenset(base.op(value, element) for element in subgroup_image)
def representative(coset: frozenset[G]) -> G:
return next(iter(coset))
return Group(
identity=quotient_class(base.identity),
inv=lambda coset: quotient_class(base.inv(representative(coset))),
op=lambda left, right: quotient_class(
base.op(representative(left), representative(right))
),
)
normal_subgroup の包含写像による像から剰余類を作っています。subgroup_elements は、有限モデルで剰余類を列挙するために渡す要素集合です。Subgroup[G, H] 自体は有限集合を保持しません。
正規性を確認せずにこの関数を使うと、代表元によって演算結果が変わる構造を作る可能性があります。正規部分群であることと、剰余類の演算が well-defined であることは、別途検証が必要です。
Z/4Z の剰余群
まず、可換群の例を計算します。$\mathbb{Z}/4\mathbb{Z}$ の部分群
N = \{0, 2\}
による剰余群には、次の2つの剰余類があります。
0 + N = \{0, 2\},\qquad 1 + N = \{1, 3\}
from cyclic import Cyclic, cyclic_group
from quotient_group import quotient_group
from homomorphism import InjectiveGroupHomomorphism
from subgroup import Subgroup
z4 = cyclic_group(4)
z4_elements = frozenset(Cyclic(4, value) for value in range(4))
normal_subgroup = Subgroup(
inclusion=InjectiveGroupHomomorphism(
f=lambda element: element,
source=z4,
target=z4,
),
)
normal_subgroup_elements = frozenset({Cyclic(4, 0), Cyclic(4, 2)})
normal_subgroup.assert_normal(z4_elements, normal_subgroup_elements)
quotient = quotient_group(normal_subgroup, normal_subgroup_elements)
zero_class = quotient.identity
one_class = frozenset({Cyclic(4, 1), Cyclic(4, 3)})
assert quotient.op(one_class, one_class) == zero_class
第一同型定理
群準同型 $f : G \to H$ に対して、第一同型定理は次の同型を述べます。
G / \ker f \cong \operatorname{im} f
ここでは、符号写像
\operatorname{sgn}: S_3 \to \{ -1, 1 \}
を使い、$\ker(\operatorname{sgn}) = A_3$ であることを利用します。
from group import Group
from homomorphism import GroupHomomorphism
from permutation import Permutation
from subgroup_example import A3, A3_elements, S3, S3_group, sign
from quotient_group import quotient_group
source = S3_group
target = Group[int](
identity=1,
inv=lambda value: value,
op=lambda left, right: left * right,
)
sign_homomorphism = GroupHomomorphism(sign, source, target)
quotient = quotient_group(A3, A3_elements)
def quotient_to_image(coset: frozenset[Permutation]) -> int:
representative = next(iter(coset))
return sign_homomorphism(representative)
quotient_homomorphism = GroupHomomorphism(
quotient_to_image,
quotient,
target,
)
subgroup_image = {A3.inclusion(element) for element in A3_elements}
cosets = {
frozenset(source.op(element, subgroup_element) for subgroup_element in subgroup_image)
for element in S3
}
quotient_homomorphism.assert_preserves_identity()
for left in cosets:
for right in cosets:
quotient_homomorphism.assert_preserves_operation(left, right)
image = {quotient_homomorphism(coset) for coset in cosets}
assert len(cosets) == len(image) == 2
assert image == {-1, 1}
quotient_to_image は、剰余類から代表元を選んで符号を計算します。代表元を変えても符号が変わらないため、この写像は well-defined です。コードでは、剰余類の組について演算保存を確認し、像と剰余群の要素数が一致することから全単射性を観察しています。
この具体例から、次の対応を確認できます。
S_3 / A_3 \cong \{ -1, 1 \}
Pythonで定理を扱う限界
ここで確認したのは、有限群の具体的な要素を列挙したモデルにおける計算です。任意の群と準同型について第一同型定理が成り立つことを、Pythonの実行だけで証明したわけではありません。
まとめ
- 正規部分群の剰余類から剰余群を構成した
- $S_3 / A_3$ の剰余群を計算した
- 剰余群から符号の像への写像を作った
- 第一同型定理に現れる同型を有限モデルで検証した
次の記事では、2つの群から直積群を構成します。