# Documentation

Mathlib.Order.JordanHolder

# Jordan-Hölder Theorem #

This file proves the Jordan Hölder theorem for a JordanHolderLattice, a class also defined in this file. Examples of JordanHolderLattice include Subgroup G if G is a group, and Submodule R M if M is an R-module. Using this approach the theorem need not be proved separately for both groups and modules, the proof in this file can be applied to both.

## Main definitions #

The main definitions in this file are JordanHolderLattice and CompositionSeries, and the relation Equivalent on CompositionSeries

A JordanHolderLattice is the class for which the Jordan Hölder theorem is proved. A Jordan Hölder lattice is a lattice equipped with a notion of maximality, IsMaximal, and a notion of isomorphism of pairs Iso. In the example of subgroups of a group, IsMaximal H K means that H is a maximal normal subgroup of K, and Iso (H₁, K₁) (H₂, K₂) means that the quotient H₁ / K₁ is isomorphic to the quotient H₂ / K₂. Iso must be symmetric and transitive and must satisfy the second isomorphism theorem Iso (H, H ⊔ K) (H ⊓ K, K).

A CompositionSeries X is a finite nonempty series of elements of the lattice X such that each element is maximal inside the next. The length of a CompositionSeries X is one less than the number of elements in the series. Note that there is no stipulation that a series start from the bottom of the lattice and finish at the top. For a composition series s, s.top is the largest element of the series, and s.bot is the least element.

Two CompositionSeries X, s₁ and s₂ are equivalent if there is a bijection e : Fin s₁.length ≃ Fin s₂.length such that for any i, Iso (s₁ i, s₁ i.succ) (s₂ (e i), s₂ (e i.succ))

## Main theorems #

The main theorem is CompositionSeries.jordan_holder, which says that if two composition series have the same least element and the same largest element, then they are Equivalent.

## TODO #

Provide instances of JordanHolderLattice for both submodules and subgroups, and potentially for modular lattices.

It is not entirely clear how this should be done. Possibly there should be no global instances of JordanHolderLattice, and the instances should only be defined locally in order to prove the Jordan-Hölder theorem for modules/groups and the API should be transferred because many of the theorems in this file will have stronger versions for modules. There will also need to be an API for mapping composition series across homomorphisms. It is also probably possible to provide an instance of JordanHolderLattice for any ModularLattice, and in this case the Jordan-Hölder theorem will say that there is a well defined notion of length of a modular lattice. However an instance of JordanHolderLattice for a modular lattice will not be able to contain the correct notion of isomorphism for modules, so a separate instance for modules will still be required and this will clash with the instance for modular lattices, and so at least one of these instances should not be a global instance.

class JordanHolderLattice (X : Type u) [] :
• IsMaximal : XXProp
• lt_of_isMaximal : ∀ {x y : X}, x < y
• sup_eq_of_isMaximal : ∀ {x y z : X}, x yx y = z
• isMaximal_inf_left_of_isMaximal_sup : ∀ {x y : X},
• Iso : X × XX × XProp
• iso_symm : ∀ {x y : X × X},
• iso_trans : ∀ {x y z : X × X},
• second_iso : ∀ {x y : X}, JordanHolderLattice.Iso (x, x y) (x y, y)

A JordanHolderLattice is the class for which the Jordan Hölder theorem is proved. A Jordan Hölder lattice is a lattice equipped with a notion of maximality, IsMaximal, and a notion of isomorphism of pairs Iso. In the example of subgroups of a group, IsMaximal H K means that H is a maximal normal subgroup of K, and Iso (H₁, K₁) (H₂, K₂) means that the quotient H₁ / K₁ is isomorphic to the quotient H₂ / K₂. Iso must be symmetric and transitive and must satisfy the second isomorphism theorem Iso (H, H ⊔ K) (H ⊓ K, K). Examples include Subgroup G if G is a group, and Submodule R M if M is an R-module.

Instances
theorem JordanHolderLattice.isMaximal_inf_right_of_isMaximal_sup {X : Type u} [] {x : X} {y : X} (hxz : ) (hyz : ) :
theorem JordanHolderLattice.isMaximal_of_eq_inf {X : Type u} [] (x : X) (b : X) {a : X} {y : X} (ha : x y = a) (hxy : x y) (hxb : ) (hyb : ) :
theorem JordanHolderLattice.second_iso_of_eq {X : Type u} [] {x : X} {y : X} {a : X} {b : X} (hm : ) (ha : x y = a) (hb : x y = b) :
theorem JordanHolderLattice.IsMaximal.iso_refl {X : Type u} [] {x : X} {y : X} (h : ) :
structure CompositionSeries (X : Type u) [] :
• length :
• series : Fin (s.length + 1)X
• step' : ∀ (i : Fin s.length),

A CompositionSeries X is a finite nonempty series of elements of a JordanHolderLattice such that each element is maximal inside the next. The length of a CompositionSeries X is one less than the number of elements in the series. Note that there is no stipulation that a series start from the bottom of the lattice and finish at the top. For a composition series s, s.top is the largest element of the series, and s.bot is the least element.

Instances For
instance CompositionSeries.coeFun {X : Type u} [] :
CoeFun () fun x => Fin (x.length + 1)X
instance CompositionSeries.inhabited {X : Type u} [] [] :
theorem CompositionSeries.step {X : Type u} [] (s : ) (i : Fin s.length) :
theorem CompositionSeries.coeFn_mk {X : Type u} [] (length : ) (series : Fin (length + 1)X) (step : ∀ (i : Fin length), JordanHolderLattice.IsMaximal (series ()) (series ())) :
{ length := length, series := series, step' := step }.series = series
theorem CompositionSeries.lt_succ {X : Type u} [] (s : ) (i : Fin s.length) :
theorem CompositionSeries.strictMono {X : Type u} [] (s : ) :
StrictMono s.series
theorem CompositionSeries.injective {X : Type u} [] (s : ) :
@[simp]
theorem CompositionSeries.inj {X : Type u} [] (s : ) {i : Fin (Nat.succ s.length)} {j : Fin (Nat.succ s.length)} :
i = j
theorem CompositionSeries.mem_def {X : Type u} [] {x : X} {s : } :
x s x Set.range s.series
theorem CompositionSeries.total {X : Type u} [] {s : } {x : X} {y : X} (hx : x s) (hy : y s) :
x y y x
def CompositionSeries.toList {X : Type u} [] (s : ) :

The ordered List X of elements of a CompositionSeries X.

Instances For
theorem CompositionSeries.ext_fun {X : Type u} [] {s₁ : } {s₂ : } (hl : s₁.length = s₂.length) (h : ∀ (i : Fin (s₁.length + 1)), = CompositionSeries.series s₂ (Fin.cast (_ : Nat.succ s₁.length = Nat.succ s₂.length) i)) :
s₁ = s₂

Two CompositionSeries are equal if they are the same length and have the same ith element for every i

@[simp]
theorem CompositionSeries.length_toList {X : Type u} [] (s : ) :
= s.length + 1
theorem CompositionSeries.toList_ne_nil {X : Type u} [] (s : ) :
theorem CompositionSeries.toList_injective {X : Type u} [] :
Function.Injective CompositionSeries.toList
theorem CompositionSeries.chain'_toList {X : Type u} [] (s : ) :
List.Chain' JordanHolderLattice.IsMaximal ()
theorem CompositionSeries.toList_sorted {X : Type u} [] (s : ) :
List.Sorted (fun x x_1 => x < x_1) ()
theorem CompositionSeries.toList_nodup {X : Type u} [] (s : ) :
@[simp]
theorem CompositionSeries.mem_toList {X : Type u} [] {s : } {x : X} :
x s
def CompositionSeries.ofList {X : Type u} [] (l : List X) (hl : l []) (hc : List.Chain' JordanHolderLattice.IsMaximal l) :

Make a CompositionSeries X from the ordered list of its elements.

Instances For
theorem CompositionSeries.length_ofList {X : Type u} [] (l : List X) (hl : l []) (hc : List.Chain' JordanHolderLattice.IsMaximal l) :
().length = - 1
theorem CompositionSeries.ofList_toList {X : Type u} [] (s : ) :
CompositionSeries.ofList () (_ : ) (_ : List.Chain' JordanHolderLattice.IsMaximal ()) = s
@[simp]
theorem CompositionSeries.ofList_toList' {X : Type u} [] (s : ) :
CompositionSeries.ofList () (_ : ) (_ : List.Chain' JordanHolderLattice.IsMaximal ()) = s
@[simp]
theorem CompositionSeries.toList_ofList {X : Type u} [] (l : List X) (hl : l []) (hc : List.Chain' JordanHolderLattice.IsMaximal l) :
theorem CompositionSeries.ext {X : Type u} [] {s₁ : } {s₂ : } (h : ∀ (x : X), x s₁ x s₂) :
s₁ = s₂

Two CompositionSeries are equal if they have the same elements. See also ext_fun.

def CompositionSeries.top {X : Type u} [] (s : ) :
X

The largest element of a CompositionSeries

Instances For
theorem CompositionSeries.top_mem {X : Type u} [] (s : ) :
@[simp]
theorem CompositionSeries.le_top {X : Type u} [] {s : } (i : Fin (s.length + 1)) :
theorem CompositionSeries.le_top_of_mem {X : Type u} [] {s : } {x : X} (hx : x s) :
def CompositionSeries.bot {X : Type u} [] (s : ) :
X

The smallest element of a CompositionSeries

Instances For
theorem CompositionSeries.bot_mem {X : Type u} [] (s : ) :
@[simp]
theorem CompositionSeries.bot_le {X : Type u} [] {s : } (i : Fin (s.length + 1)) :
theorem CompositionSeries.bot_le_of_mem {X : Type u} [] {s : } {x : X} (hx : x s) :
theorem CompositionSeries.length_pos_of_mem_ne {X : Type u} [] {s : } {x : X} {y : X} (hx : x s) (hy : y s) (hxy : x y) :
0 < s.length
theorem CompositionSeries.forall_mem_eq_of_length_eq_zero {X : Type u} [] {s : } (hs : s.length = 0) {x : X} {y : X} (hx : x s) (hy : y s) :
x = y
@[simp]
theorem CompositionSeries.eraseTop_series {X : Type u} [] (s : ) (i : Fin (s.length - 1 + 1)) :
= CompositionSeries.series s { val := i, isLt := (_ : i < s.length + 1) }
@[simp]
theorem CompositionSeries.eraseTop_length {X : Type u} [] (s : ) :
().length = s.length - 1
def CompositionSeries.eraseTop {X : Type u} [] (s : ) :

Remove the largest element from a CompositionSeries. If the series s has length zero, then s.eraseTop = s

Instances For
theorem CompositionSeries.top_eraseTop {X : Type u} [] (s : ) :
= CompositionSeries.series s { val := s.length - 1, isLt := (_ : s.length - 1 < s.length + 1) }
theorem CompositionSeries.eraseTop_top_le {X : Type u} [] (s : ) :
@[simp]
theorem CompositionSeries.bot_eraseTop {X : Type u} [] (s : ) :
theorem CompositionSeries.mem_eraseTop_of_ne_of_mem {X : Type u} [] {s : } {x : X} (hx : ) (hxs : x s) :
theorem CompositionSeries.mem_eraseTop {X : Type u} [] {s : } {x : X} (h : 0 < s.length) :
x s
theorem CompositionSeries.lt_top_of_mem_eraseTop {X : Type u} [] {s : } {x : X} (h : 0 < s.length) (hx : ) :
theorem CompositionSeries.isMaximal_eraseTop_top {X : Type u} [] {s : } (h : 0 < s.length) :
theorem CompositionSeries.append_castAdd_aux {α : Type u_1} {m : } {n : } (a : Fin ()α) (b : Fin ()α) (i : Fin m) :
Matrix.vecAppend (_ : Nat.succ (m + n) = m + ) (a Fin.castSucc) b (Fin.castSucc ()) = a ()
theorem CompositionSeries.append_succ_castAdd_aux {α : Type u_1} {m : } {n : } (a : Fin ()α) (b : Fin ()α) (i : Fin m) (h : a () = b 0) :
Matrix.vecAppend (_ : Nat.succ (m + n) = m + ) (a Fin.castSucc) b (Fin.succ ()) = a ()
theorem CompositionSeries.append_natAdd_aux {α : Type u_1} {m : } {n : } (a : Fin ()α) (b : Fin ()α) (i : Fin n) :
Matrix.vecAppend (_ : Nat.succ (m + n) = m + ) (a Fin.castSucc) b (Fin.castSucc ()) = b ()
theorem CompositionSeries.append_succ_natAdd_aux {α : Type u_1} {m : } {n : } (a : Fin ()α) (b : Fin ()α) (i : Fin n) :
Matrix.vecAppend (_ : Nat.succ (m + n) = m + ) (a Fin.castSucc) b (Fin.succ ()) = b ()
@[simp]
theorem CompositionSeries.append_length {X : Type u} [] (s₁ : ) (s₂ : ) (h : ) :
().length = s₁.length + s₂.length
def CompositionSeries.append {X : Type u} [] (s₁ : ) (s₂ : ) (h : ) :

Append two composition series s₁ and s₂ such that the least element of s₁ is the maximum element of s₂.

Instances For
theorem CompositionSeries.coe_append {X : Type u} [] (s₁ : ) (s₂ : ) (h : ) :
().series = Matrix.vecAppend (_ : Nat.succ (s₁.length + s₂.length) = s₁.length + Nat.succ s₂.length) (s₁.series Fin.castSucc) s₂.series
@[simp]
theorem CompositionSeries.append_castAdd {X : Type u} [] {s₁ : } {s₂ : } (h : ) (i : Fin s₁.length) :
@[simp]
theorem CompositionSeries.append_succ_castAdd {X : Type u} [] {s₁ : } {s₂ : } (h : ) (i : Fin s₁.length) :
@[simp]
theorem CompositionSeries.append_natAdd {X : Type u} [] {s₁ : } {s₂ : } (h : ) (i : Fin s₂.length) :
@[simp]
theorem CompositionSeries.append_succ_natAdd {X : Type u} [] {s₁ : } {s₂ : } (h : ) (i : Fin s₂.length) :
@[simp]
theorem CompositionSeries.snoc_length {X : Type u} [] (s : ) (x : X) (hsat : ) :
(CompositionSeries.snoc s x hsat).length = s.length + 1
def CompositionSeries.snoc {X : Type u} [] (s : ) (x : X) (hsat : ) :

Add an element to the top of a CompositionSeries

Instances For
@[simp]
theorem CompositionSeries.top_snoc {X : Type u} [] (s : ) (x : X) (hsat : ) :
@[simp]
theorem CompositionSeries.snoc_last {X : Type u} [] (s : ) (x : X) (hsat : ) :
@[simp]
theorem CompositionSeries.snoc_castSucc {X : Type u} [] (s : ) (x : X) (hsat : ) (i : Fin (s.length + 1)) :
@[simp]
theorem CompositionSeries.bot_snoc {X : Type u} [] (s : ) (x : X) (hsat : ) :
theorem CompositionSeries.mem_snoc {X : Type u} [] {s : } {x : X} {y : X} {hsat : } :
y CompositionSeries.snoc s x hsat y s y = x
theorem CompositionSeries.eq_snoc_eraseTop {X : Type u} [] {s : } (h : 0 < s.length) :
@[simp]
theorem CompositionSeries.snoc_eraseTop_top {X : Type u} [] {s : } :
def CompositionSeries.Equivalent {X : Type u} [] (s₁ : ) (s₂ : ) :

Two CompositionSeries X, s₁ and s₂ are equivalent if there is a bijection e : Fin s₁.length ≃ Fin s₂.length such that for any i, Iso (s₁ i) (s₁ i.succ) (s₂ (e i), s₂ (e i.succ))

Instances For
theorem CompositionSeries.Equivalent.refl {X : Type u} [] (s : ) :
theorem CompositionSeries.Equivalent.symm {X : Type u} [] {s₁ : } {s₂ : } (h : ) :
theorem CompositionSeries.Equivalent.trans {X : Type u} [] {s₁ : } {s₂ : } {s₃ : } (h₁ : ) (h₂ : ) :
theorem CompositionSeries.Equivalent.append {X : Type u} [] {s₁ : } {s₂ : } {t₁ : } {t₂ : } (hs : ) (ht : ) (h₁ : ) (h₂ : ) :
theorem CompositionSeries.Equivalent.snoc {X : Type u} [] {s₁ : } {s₂ : } {x₁ : X} {x₂ : X} {hsat₁ : } {hsat₂ : } (hequiv : ) (htop : JordanHolderLattice.Iso (, x₁) (, x₂)) :
theorem CompositionSeries.Equivalent.length_eq {X : Type u} [] {s₁ : } {s₂ : } (h : ) :
s₁.length = s₂.length
theorem CompositionSeries.Equivalent.snoc_snoc_swap {X : Type u} [] {s : } {x₁ : X} {x₂ : X} {y₁ : X} {y₂ : X} {hsat₁ : } {hsat₂ : } {hsaty₁ : JordanHolderLattice.IsMaximal (CompositionSeries.top (CompositionSeries.snoc s x₁ hsat₁)) y₁} {hsaty₂ : JordanHolderLattice.IsMaximal (CompositionSeries.top (CompositionSeries.snoc s x₂ hsat₂)) y₂} (hr₁ : JordanHolderLattice.Iso (, x₁) (x₂, y₂)) (hr₂ : JordanHolderLattice.Iso (x₁, y₁) (, x₂)) :
theorem CompositionSeries.length_eq_zero_of_bot_eq_bot_of_top_eq_top_of_length_eq_zero {X : Type u} [] {s₁ : } {s₂ : } (hb : ) (ht : ) (hs₁ : s₁.length = 0) :
s₂.length = 0
theorem CompositionSeries.length_pos_of_bot_eq_bot_of_top_eq_top_of_length_pos {X : Type u} [] {s₁ : } {s₂ : } (hb : ) (ht : ) :
0 < s₁.length0 < s₂.length
theorem CompositionSeries.eq_of_bot_eq_bot_of_top_eq_top_of_length_eq_zero {X : Type u} [] {s₁ : } {s₂ : } (hb : ) (ht : ) (hs₁0 : s₁.length = 0) :
s₁ = s₂
theorem CompositionSeries.exists_top_eq_snoc_equivalant {X : Type u} [] (s : ) (x : X) (hm : ) (hb : ) :
t, t.length + 1 = s.length htx, CompositionSeries.Equivalent s ()

Given a CompositionSeries, s, and an element x such that x is maximal inside s.top there is a series, t, such that t.top = x, t.bot = s.bot and snoc t s.top _ is equivalent to s.

theorem CompositionSeries.jordan_holder {X : Type u} [] (s₁ : ) (s₂ : ) (hb : ) (ht : ) :

The Jordan-Hölder theorem, stated for any JordanHolderLattice. If two composition series start and finish at the same place, they are equivalent.